Shell-only signal traps could leave browser descendants writing sensitive state after cleanup, and simultaneous runs shared the same cookie cache. Give the Linux qualification runner an invocation-owned cookie root and a child-subreaper supervisor so catchable interruption waits for writers before removing owned artifacts. Preserve normal reports for inspection and fail closed if writers cannot be reaped. Focused fixtures cover all three signals, late detached writers, concurrent isolation and forced termination; no real-browser cleanup or release readiness is claimed.
Change-source: pulse-maintainer
The shell multi-tenant suite previously selected a spec ignored by every project, preventing real backend diagnosis. Add an explicit desktop-only configuration that rejects tier identity, while retaining the normal quarantine. Cover discovery and tier refusal and document the evidence boundaries. A local source-built diagnostic returned five passes, one failure at organisation-switch login, and one skip; this is not release qualification.
Change-source: pulse-maintainer
Concurrent qualification runs could overwrite shared browser artifacts and authentication state, while an inherited PLAYWRIGHT_BASE_URL could send browser traffic outside the shell-owned stack. Scope outputs and fixture credentials to each invocation and clear that endpoint override so isolation evidence refers to the intended stack.
Focused runner checks cover inherited overrides and cleanup. Recorded concurrent Docker diagnostics reached healthy stacks but browser execution remained blocked by the existing multi-tenant quarantine; this test-only repair does not claim browser or release qualification and changes no user-visible application surface.
Change-source: pulse-maintainer
Integrate the reviewed source-stage selection and run-owned entitlement targeting on top of the existing teardown-failure guard. The merge preserves the candidate commit unchanged and combines compatible qualification harness repairs.
Change-source: pulse-maintainer
The integration runner otherwise selects the final prebuilt-agent Docker stage, which requires release payload inputs and prevents source-server qualification. Entitlement helpers also use a legacy container variable and inherited overrides that can target an unrelated runtime. Select the source-server stage explicitly and bind the managed shell path to its run-owned server, with regression assertions for both behaviours.
Contract-Neutral: integration harness and regression tests only; no product surface or runtime contract changes.
Change-source: pulse-maintainer
Reproduced startup, health and entitlement failures continuing through all ten suites despite failed teardown. Use the same fatal teardown guard on setup and port discovery failures so later scenarios cannot inherit dirty state.
Contract-Neutral: qualification harness only; no user-visible product surface. Focused stubbed runner tests and bash syntax checks pass; no runtime qualification claimed.
Change-source: pulse-maintainer
Shared image tags, container names and host ports let concurrent checkout qualification collide or inspect another runtime. Give each shell integration invocation its own identities and allocated listeners, and scope failure cleanup to those resources so results cannot silently qualify unrelated bytes.
Contract-Neutral: Integration harness isolation and documentation only; no user-visible frontend, product contract or release surface changes.
Change-source: pulse-maintainer
Prevent a successful test command from hiding failed Docker cleanup and letting subsequent suites inherit dirty state. Stubbed core/all regressions fail on the original runner and pass with explicit termination.
Contract-Neutral: qualification harness correction only; no product surface changes.
Change-source: pulse-maintainer
Existing local test tags could silently run older server or mock API bytes. Always invoke cached Docker builds and stop on build failure. Three stubbed runner regressions fail before this repair and pass after it; no installed or browser qualification is claimed.
Contract-Neutral: Integration harness freshness only; no product or release surface changes.
Change-source: pulse-maintainer
Every main push since the v6 branch flip was cancelled at the 45-minute
job timeout with no verdict. The flip brought the full 94-spec suite onto
main (the last green run, 2026-06-29, ran only 2 specs on the v5 main),
and it runs sequentially against a release-tagged image whose mock-fixture
gate returns 403 without a demo entitlement. Dozens of specs fail, retry
twice each, and burn the budget: of the 31 minutes of suite time in run
28907574469, 18.8 minutes were failing attempts.
- Add GO_BUILD_TAGS build arg (default release) and build the pulse:test
e2e image with it empty, matching the dev harness the suite is green
under. Shipped images keep the release tag; release-gate behavior keeps
its dedicated -tags release Go tests.
- Shard Playwright 4 ways across a CI matrix (214/202/205/203 tests per
shard) with per-shard report artifacts and an aggregate verdict job.
- Cap CI at 20 failures so an env-broken run reports red in minutes
instead of grinding into a no-verdict cancellation.
Backend:
- Add smart provider fallback when selected model's provider isn't configured
- Automatically switch to a model from a configured provider instead of failing
- Log warning when fallback occurs for visibility
Frontend (AISettings.tsx):
- Add helper functions to check if model's provider is configured
- Group model dropdown: configured providers first, unconfigured marked with ⚠️
- Add inline warning when selecting model from unconfigured provider
- Validate on save that model's provider is configured (or being added)
- Warn before clearing last configured provider (would disable AI)
- Warn before clearing provider that current model uses
- Add patrol interval validation (must be 0 or >= 10 minutes)
- Show red border + inline error for invalid patrol intervals 1-9
- Update patrol interval hint: '(0=off, 10+ to enable)'
These changes prevent confusing '500 Internal Server Error' and
'AI is not enabled or configured' errors when model/provider mismatch.