* Move raw transcript from system to user prompt to protect provenance.
* Type fix.
* fix(voice-call): harden transcript context handling
* fix(voice-call): initialize inbound Twilio control state
* test(voice-call): align runtime coordinator fixture
---------
Co-authored-by: joshavant <830519+joshavant@users.noreply.github.com>
The model catalog abort test waited for pid-file existence, but the
catalog child's writeFileSync exposes an open-truncate window: the
test could read the file empty and fail on a NaN pid assertion
(CI run 32231699569, checks-node-changed-extensions-config-37).
Add a qa-lab-local process-wait test helper that waits for the
asserted state (a parseable pid) with generous 10s deadlines and
self-diagnosing timeout errors, and consolidate the two hand-rolled
helper copies in model-catalog.runtime.test.ts and
test-file-scenario-command-lifecycle.test.ts onto it. Also retire
the stale 1.7s abort-settle ceiling (calibrated against a removed
1.5s in-plugin kill grace) in favor of a 5s bound with the contract
documented.
* fix(line): deliver a location LINE cannot render instead of dropping it
A location whose title or address is blank makes LINE reject the whole
request, so every delivery path filtered it out before sending. The reply
then arrived without the pin, and nothing told the user or the operator that
a part of the message had been removed: the coordinates the sender supplied
were discarded silently.
The location builder now answers with the values the sender wrote — the
non-blank label plus the coordinates — as a text message, so an unrenderable
pin degrades into something the chat can show instead of disappearing. Both
delivery paths inherit that from the single builder, and the three call sites
that used to skip a null result no longer have a branch to take.
Live validation against the Messaging API confirms the shape: the authored
location is rejected with "May not be empty" on messages[0].address, the same
rejection kills an entire batch that also carries valid text, and both
degraded forms validate cleanly.
* fix(line): bound the location fallback to LINE's text limit
Nothing caps the location labels at the schema, so a long title with a blank
address produced one raw text message past LINE's 5,000-character limit — the
provider rejected it and the location was lost exactly as silently as before.
The pin path already caps each label at 100 characters. Name that limit and
apply it in the fallback too, so both forms carry the same bound instead of
one of them re-deriving the provider's rules.
* test(line): merge the duplicate send.js imports
* feat(ui): unify focused presentation routes
/focus/<target> replaces unshipped standalone query links across dashboard, terminal, desktop, and native apps.
Gateway-served index assets are anchored so nested documents resolve their bundles from the Control UI base path.
* test(gateway): narrow emitted asset URLs
Fixes check:test-types TS18048/TS2322 by dropping unmatched optional captures before comparing emitted asset URLs.
* test(docs): follow centralized cloud secret guidance
Fixes the stale current-main docs test after #126132 centralized GCP and Hetzner setup in docker-vm-runtime.
* test(ui): retry missing locator reads
The 500ms locator text read can time out while the menu label is still rendering, causing expect.poll to reject instead of using its owning 10s retry window. Treat only Playwright TimeoutError as a missing value so the outer poll retries while page-closure and arbitrary failures still surface.
* test(android): capture TLS probe coroutine
The TLS probe test inferred its coroutine from mutable scope children, racing unrelated child startup and teardown in CI. Capture the exact Job from inside the probe coroutine and join that owner before asserting the stale-attempt guard.
* fix(gateway): preserve plugin focus routes
Keep approval handling ahead of plugin dispatch, but treat focus documents as an unclaimed Control UI fallback after plugin authentication and routing. Exact and prefix plugin routes therefore retain ownership, while unclaimed reads serve the focus document and other methods return 404.
* fix(ui): migrate released terminal links
Preserve stable v2026.7.1 terminal query compatibility by rewriting the root/base ?view=terminal URL once to the canonical /focus/terminal path with history.replace. Keep URL parsing path-only, and leave the removed desktop and dashboard query forms as a hard cut.
* test(codex): assign run-attempt tools shard
Cached filtered configs caused duplicate ownership, and the test lacked a canonical full-suite owner.
* test(ui): keep cloud recovery proof state-owned
The recovery test should assert owner state and reload identity, while dedicated tests own transient alert visibility.
* test(qa): wait for outbound bus state
* fix(qa): reserve gateway ports through staging
* refactor(qa): keep socket creation in gateway owner
* fix: capture GitHub identity from authenticated sign-in
Automatically persist verified GitHub identities from Cloudflare Access and Tailscale Serve while keeping public Git co-author credit as a separate opt-in.
* test: stabilize cleanup and activity capture
* fix(security): bind GitHub profiles by account id
* test: scope activity capture to route
* fix(security): gate profile requests on identity sync
* fix(security): close pending profile authorization gaps
* test(ui): stabilize terminal continuation menu
* test: stabilize startup recovery timing
* test: keep one Codex attempt tools owner
* fix(plugins): allow profile-independent gateway reads
* fix(qa): mark partial suite artifacts as running
Isolated QA suite progress artifacts now identify themselves as running in JSON and Markdown, so completed-prefix results cannot be mistaken for terminal teardown. Final artifacts keep their existing completed shape, with process regression coverage for clean exit and closed Gateway listeners.
* test(qa): decouple suite runtime from teardown deadline
Allow the real QA scenario to finish under a contended extension shard while keeping the post-summary process exit requirement fixed at 45 seconds.
* test(qa): keep lifecycle proof observable
Emit a bounded progress heartbeat while the real QA child is still producing its terminal summary so the extension shard watchdog does not mistake a long, active process proof for a stalled Vitest run.
* test(qa): isolate lifecycle process environment
Run the real QA child outside Vitest and shared compile-cache markers, and fail fast with bounded process output when it exits before publishing a terminal summary.
* test(qa): run lifecycle proof on repo gateway
Build and launch the real repository Gateway when dist is absent, avoid package-candidate auth bootstrap, and keep the teardown regression bounded and observable in unbuilt extension-test jobs.
* test(qa): terminate Windows lifecycle process trees
* fix(qa): reject running confidence summaries
Keep the writer-owned idempotency key stable across transcript redaction so final Codex snapshots replay against the admitted SQLite row instead of dropping mirrored history.\n\nCloses #126244
* fix: stop Full access sessions from requesting exec approval
* fix: propagate Full access policy to compaction
* fix: source compaction permissions from session state
* feat(discord): auto-join occupied voice rooms
Add opt-in voice.autoJoin[].whenOccupied residency so Discord voice bots join for the first human and leave when the room becomes empty while preserving existing always-on, manual, transcript, and follow-user behavior.\n\nCloses #125973
* test(discord): isolate process runtime mocks
Use stable hoisted runtime-env mocks so isolate=false Discord test ordering cannot turn sleepWithAbort back into an unmocked function.
* fix(discord): defer unknown voice occupancy
Treat memberless voice states as unresolved instead of human so bot-only rooms cannot trigger occupancy-managed auto-join. Add cache-to-listener and manager regressions.\n\nCloses #125973
* test: isolate shared module mocks
Replace ineffective non-isolated module spies with stable hoisted mocks and a child-process SQLite connection-reuse probe so gateway and Discord shards are order-independent.
* test(gateway): inline connection reuse probe
Keep the child-process SQLite ownership probe in its owning Vitest file so Knip sees the full test surface without weakening process isolation or the original order regression.
* fix(codex): preserve model effort capabilities
Keep public model identities separate from app-server execution routing, and retain provider-owned complete effort metadata when account discovery is partial.
Fixes#126005
* refactor(codex): avoid redundant thread rotation
* fix(codex): preserve model fallbacks without leaking wire ids
* fix(msteams): preserve replies across ingress replay
Recovered Teams channel and group-chat responses now preserve reply and quote context across durable ingress replay. Discovery metadata also advertises the existing group and reaction capabilities.
* chore(msteams): document replay assertion safety
* test(msteams): normalize replay delivery errors
* perf(gateway): remove repeated logging and delivery scans
Exact session-delivery retries no longer scan the full queue. Logging and diagnostics reuse lifecycle-owned settings and listener interest so uninterested projections are skipped, while outbound WebSocket summaries are built only after recipient admission.
* fix(infra): break diagnostic listener import cycle
Keep event-type validation at the diagnostic dispatcher while the process-wide listener presence counter remains a leaf module.
* test(cli): use logging override owner
Exercise late one-shot JSON diagnostics through the canonical logger override setter so lifecycle-cached console settings are invalidated as they are in production.
* test(auth): use logging override owner
Configure the locked-update warning test through the canonical logger override setter so lifecycle-cached console settings are invalidated before assertion.
* test(gateway): normalize redacted media fixture
Compare durable inbound media facts against the public redaction contract so random identifiers that resemble sensitive text do not make the Gateway suite flaky.
* fix(workboard): recover interrupted worker launches
Persist prepared, accepted, and failed launch phases so Gateway restart reconciliation cannot leave cards permanently running between launch preparation and worker acceptance.
* fix(workboard): require durable terminal evidence
Do not synthesize terminal-session acceptance timing during restart reconciliation; stale same-key terminal rows without updatedAt now fail the prepared launch instead of being adopted.