[{"name":"data","kind":"directory","size":0,"lastCommitHash":"796e48b80ed3c652068653e6eae3647cf6a0994b","lastCommitWhen":"2025-08-30T18:37:17+02:00","lastCommitMessage":"feat(ai): Add image input tests for vision-capable models\n\n- Added image tests to OpenAI Completions (gpt-4o-mini)\n- Added image tests to Anthropic (claude-sonnet-4-0)\n- Added image tests to Google (gemini-2.5-flash)\n- Tests verify models can process and describe the red circle test image\n"},{"name":"anthropic-minimum-thinking-budget.test.ts","kind":"file","size":1686,"lastCommitHash":"81cd5390dbc871afb87be0d2012d205dd633bae3","lastCommitWhen":"2026-09-10T13:50:11+02:00","lastCommitMessage":"preserve reasoning in refinement and side questions (#2130)\n\n* fix(ci): accept engineering and research Linear tickets\n\n* fix(ci): clarify the Research ticket project\n\nfixes #2124\n\n* fix(coding-agent): preserve reasoning in auxiliary calls\n\nRefs ENG-6010 and discussions #1482 and #2081.\n\n* fix(ci): clarify Prime Agent board routing\n\nfixes #2124\n\n* fix(coding-agent): reserve refinement reasoning output budget\n\nRemove fixed output caps when reasoning is enabled and reserve prompt context within the model limit. Keep truncation failures bounded without retrying.\n\nfixes #2130\n\n* fix: preserve refinement context and valid thinking budgets\n\nEstimate refinement tokens and shorten only older trajectory content when space is tight. Enforce valid minimum thinking budgets for budget-based Claude requests.\n\nfixes #2130\n\n* fix(ci): isolate Ubuntu package sources\n\n(cherry picked from commit 7656902c301c5d9c26d8646f66461bf75dba5a9f)\n\n* test(coding-agent): allow context before literal prompts\n\n(cherry picked from commit 59e97147e4f559e969f629da9430be4613cc7898)\n\n* fix(coding-agent): bound dense refinement context (fixes #2130)"},{"name":"anthropic-sse-parsing.test.ts","kind":"file","size":8635,"lastCommitHash":"844e85545af6858dcb3d6cfe42bbfcf2ca0be4e5","lastCommitWhen":"2026-09-06T21:56:32-04:00","lastCommitMessage":"Harden session persistence, worker recovery, and daemon refreshes (#2028)\n\n* refactor(coding-agent): move the semantic-edge ledger onto the event-log substrate\n\nThe recorder's private append/replay/repair IO is deleted; EventLog owns it, the same move #1987 made for the RLM spawn ledger. One durability rule is unified in the substrate rather than dropped: an unterminated final line is an uncommitted append, skipped on read and truncated before the next append — never newline-completed and never surfaced to a consumer whose next append destroys it.\n\n* fix(coding-agent): make the explicit ledger reader's ENOENT contract atomic\n\nreadSemanticEdgeLedger probed with statSync before reading through EventLog, which swallows ENOENT; a ledger deleted between the two returned [] instead of throwing. The missing-file decision now lives at the single open (replaySync missingFileThrows), so no check-then-read window exists.\n\n* docs(coding-agent): state the event-log tail rule once\n\nThe unterminated-tail contract was restated four times (module doc, replaySync doc, two test comments). It now lives once in the module doc; the method doc keeps only its own parse/missing-file semantics and the test comments reference the contract.\n\n* fix(coding-agent): write event-log appends fully and gate appends on tail repair\n\nwriteSync may write short (ENOSPC after a prefix); appendSync now loops until the payload is fully on disk so write-before-action callers never act on a torn record reported as success. A tail-repair failure (e.g. append-only ACL permitting O_APPEND but not r+) now propagates instead of being swallowed: writing through an unrepaired torn tail would weld it to the new record as permanent interior corruption. ENOENT and the concurrent-writer instability path keep their existing semantics.\n\n* fix(coding-agent): reclaim short event-log writes instead of completing them\n\nThe rlm spawn ledger is multi-writer by documented design (supervisor plus each worker over one file), so completing a short O_APPEND write with a second write could interleave with a rival append and weld two records. A short write now truncates its own torn prefix back off (only while this writer still owns the tail) and fails the append; a torn tail is read-tolerated, a weld is permanent corruption. The append fd opens a+ so the ownership check can read the tail.\n\n* fix(coding-agent): leave the torn tail on a short write instead of reclaiming it\n\nThe tail-match reclaim could truncate a rival's committed record whose final bytes coincide with our torn prefix - committed-data loss, strictly worse than the torn tail it prevented. A short write now just fails the append: the torn tail is the one tolerated shape, skipped on read and truncated by any writer's next repair (verified for both topologies: a resumed single-writer recorder repairs on its first append; every rlm-ledger writer repairs before each append).\n\n* refactor(coding-agent): compress event-log comments\n\n* fix(ai): omit the default service tier, reprice cache writes from message_delta, repoint the zai default\n\nIncorporates #2032 at f82c7fa3688b7e25cef80e2663fe77ed153c5cd9.\n\n* fix(tui,coding-agent): survive lone surrogates in table cells and terminate the WebP EXIF scan\n\nIncorporates #2033 at a3d1139ee6e1f77337ab134b0f0c0cede8c942af.\n\n* fix(coding-agent): restart dead kernels on ensure() and read mcp>=2 tool schemas\n\nIncorporates #2034 at 749e216e901304b310ead9f46c3813a032608d7b.\n\n* fix: one crash-safe owner for durable state writes\n\nIncorporates #2035 at f0f02d2fb090ec427307a65b9e9578ae3c8fc783.\n\n* fix(coding-agent): one zombie-aware process-liveness probe\n\nIncorporates #2041 at 92a0eacf47efc831444b0b4e412f35bd17ac3f28.\n\n* fix(coding-agent): snapshot transfer ids from the materialized cursor; mismatches settle the transfer, not the worker channel\n\nIncorporates #2044 at 5af3bbe8090240507d6b0297d0da007159e15305.\n\n* fix(coding-agent): failed workers recover on touch; roster gaps answer a structured recovering error\n\nIncorporates #2047 at 77b747afab402a9e2f5eada227ffe6fed626a634.\n\n* fix(coding-agent): seven session and IO correctness defects\n\nIncorporates #2037 at 41b5d72d7758723f22ba07f8738d217868ed7baf.\n\n* fix(coding-agent): coalesce child-usage attribution and gate agent-status persistence on real changes\n\nIncorporates #2050 at 6b0af5d2679ddff987ef3b4d43235a872fe2b315.\n\n* fix(coding-agent): incremental single-flight session metadata scans\n\nIncorporates #2043 at df032c1192dd2e38d35fcbaca589db7194f26b6c.\n\n* fix(coding-agent): memoize the passive RLM topology derivation\n\nIncorporates #2051 at 0ee114ce77942d9298136ca193ddc2c0b5d27d58.\n\n* fix(coding-agent): preserve accounting and metadata across deferred updates\n\nKeep durable child-usage aggregates separate from pending sibling usage. Retry optional topology metadata after transient reads. Completes #2050 and #2051 integration.\n\n* fix: preserve session accounting and read-only persistence boundaries\n\n---------\n\nCo-authored-by: Seth <seth@primeintellect.ai>"},{"name":"anthropic-thinking-disable.test.ts","kind":"file","size":11026,"lastCommitHash":"cf07c5a3f5eca98e7744f2df83050044c920252a","lastCommitWhen":"2026-09-16T16:28:13-04:00","lastCommitMessage":"delete dead tests and fix the races the flaky ones were hiding (#2336)\n\n* add an objective testing policy to AGENTS.md\n\n* fix flaky daemon supervisor monitor test\n\nThe supervisor availability check is a real async chain (registry stat,\nsocket probe, replacement launch) started from a timer callback, so the\ntest drove a bounded fake-timer pump and asserted on a probe counter.\nUnder a loaded CI shard the chain did not finish inside the iteration\nbudget, and the variant mixing fake timers with a real probe promise\ncould deadlock for the full 30s test timeout.\n\nExpose a settled promise per armed availability check and await it in\nthe tests, so each assertion runs after the check finished instead of\nafter an arbitrary number of clock advances.\n\n* remove vitest retry masking from ai and attach-image tests\n\nDeleted all 548 `retry:` options in packages/ai/test and the 2 in\nkernel-attach-image-skill.test.ts. Retries hid non-determinism instead of\nfixing it, so a broken code path could still go green.\n\n- Deleted 17 live-only cross-provider E2E matrices whose every case sits behind\n  skipIf(!API_KEY) and never runs in CI; stream.test.ts stays as the survivor\n  that owns the provider table.\n- Stripped the retry option from the 198 stream.test.ts cases and dropped the\n  live E2E describe (plus its now-unused helpers) from\n  anthropic-thinking-disable.test.ts, keeping its mocked payload contract.\n- Removed retry: 1 from the two attach-image kernel cases; they pass without it.\n\nMocked wire/SSE contract tests are untouched. Tests only, no product code.\n\n* make agent trace upload tests deterministic\n\nThe suite pumped a synthetic clock with advanceTimersUntil() and hoped real\nfs and promise work settled inside a 200-step budget, asserted schedule\ndelays through a global setTimeout spy whose fake clock had drifted, and\nremoved its temp dir while catch-up and cursor writers were still running.\nUnder a loaded CI shard that produced \"Timed out advancing fake timers\",\n\"expected 1000 to be 60000\" and \"ENOTEMPTY rmdir /tmp/agent-traces-test-*\".\n\nThe upload scheduler now reports the delay it arms and the outcome of each\ncycle, the upload reports every wait it arms before the next request, and\ninstallAgentTraceUpload returns a handle that resolves when the startup\ncatch-up and any in-flight upload have finished writing. Tests await those\nsignals and advance the fake clock by the exact reported delay, and teardown\nwaits for in-flight writers before removing the temp dir.\n\nThe ~15 retry, backoff and Retry-After variants collapse into one\ntable-driven it.each, per the MERGE verdict: 1569 -> 1141 lines, 44 -> 27\ntest blocks, with no lost coverage.\n\n* make the compiled artifact and installer probe tests deterministic\n\nThe compiled-artifact afterEach polled for supervisor exit with the same\n10s budget as vitest's hook timeout, so the poll could never report on the\nslower standalone runners. The teardown now escalates to SIGKILL and every\ninner deadline stays below the surrounding hook and test budgets.\n\nnative-probe-timeout decided pass/fail from wall-clock deadlines around a\nreal 10s installer probe. The installer probe deadline is now injectable\nthrough PRIME_AGENT_PROBE_TIMEOUT_SECONDS, the blocked probe records the\ninstall lock itself, and the spawn deadlines are gone.\n\n* fix daemon shutdown admission loss during slow scans\n\nshutdown --force holds a 5s admission lease refreshed by a 1s timer, but it\nblocks its own event loop in synchronous ps/lsof/ss scans. On a loaded runner a\nscan outlasts the lease, the elapsed record is treated as abandoned, and the\nholder's next assertOrRenew throws \"Daemon shutdown admission was lost\".\n\n- A late renew re-arms a record that is still ours; only a missing or foreign\n  record ends the admission.\n- A renew that could not read the registry no longer retires the lease.\n- isDaemonShutdownAdmissionActive is read-only, so a bystander probe cannot\n  delete a live holder's record.\n- stopHiddenSupervisors renews before the blocking scan.\n\nThe 4603 regression drops its 11s sleep for a post-shutdown listener assertion\nand uses mkdtemp for the child TMPDIR.\n\n* delete 148 dead test files\n\nRemoves test files judged CUT by a full 480-file audit: duplicates of a named survivor, mock-asserting tests, rendered-copy assertions, private-internals casts, and live-API matrices behind skipIf(!API_KEY) that never ran in CI.\n\n* merge interactive-mode and agents-view test suites\n\n* merge tui render, overlay and helper test suites\n\n* test: slim daemon-mode and agent-connection-daemon suites\n\ndaemon-mode: keep passive hydration/passivation, delete_subagent durability, agent-message concurrency and rate limits, attach-snapshot backpressure; drop per-race internal regressions already covered process-level by daemon-supervisor-process.\nagent-connection-daemon: keep reconnect, update-restart, chunked-snapshot assembly and disposal races; drop tautological daemon-protocol pass-through cases.\n\n* merge tui editor, markdown and autocomplete test suites\n\n* test: merge audited session-core test bloat\n\nExecute MERGE verdicts from the 480-file test audit for the agent-session\ncore suites: collapse near-identical blocks into it.each tables, drop\nmock-return/rendered-copy assertions and private-cast white-box cases,\nand fold one-off files into the owning suite.\n\nDeleted (folded into their owning suite):\n- agent-session-concurrent.test.ts, suite/agent-session-action-races.test.ts,\n  suite/agent-session-action-contracts.test.ts -> suite/agent-session-queue.test.ts\n- suite/agent-session-compaction-continuation.test.ts,\n  suite/agent-session-compact-skill.test.ts -> suite/agent-session-compaction.test.ts\n- agent-session-runtime-events.test.ts -> suite/agent-session-runtime.test.ts\n\nPreserved: process boundaries (daemon RPC, ACP), on-disk formats,\nconcurrency/ordering, crash/restart/resume and load coverage.\n\n* address review: octal probe timeout, truncated deadline, dead schedule field\n\n* test: merge redundant coding-agent test cases into case tables\n\nExecutes the MERGE verdicts from the 480-file test-bloat audit for the\nmisc lanes. Repeated near-identical blocks collapse into single it.each\ncase tables, and ticket-numbered one-off files fold into the owning\nmodule suite.\n\nRemoved throughout the touched files: assertions on mock return values,\nassertions on rendered text/copy, `as unknown as` casts into privates,\nand suites gated behind skipIf(!API_KEY) (which never ran in CI).\n\nPreserved: process boundaries (daemon RPC, ACP), on-disk formats,\nconcurrency and ordering, crash/restart/resume, and load.\n\nDeleted files, folded into their module suite:\n- compaction-extensions -> deleted outright (whole file behind skipIf(!API_KEY))\n- compaction-serialization -> compaction\n- heartbeat-catalog -> daemon-client\n- child-process -> exec\n- edit-tool-legacy-input -> tools\n- kernel-goal-skill, kernel-rlm-heartbeat-skill -> kernel-agent-message-skill\n- kernel-agent-observe-skill -> kernel-attach-image-skill\n- kernel-windows-process -> kernel-bootstrap-windows\n- extensions-input-event -> extensions-runner\n- sdk-skills -> sdk-session-manager\n- session-manager/{agent-status,has-user-content} -> session-manager/session-state\n- session-manager/migration -> session-manager/file-operations\n- session-manager/custom-session-id -> session-manager/tree-traversal\n\n* slim ai + regression tests (lanes A/B/D/E)\n\nExecute MERGE verdicts from the test audit for packages/ai and the\nupdate-restart / snapshot / session-view regression files.\n\n- fold ticket-numbered regression cases into the owning suites\n- collapse near-identical blocks into it.each tables\n- drop mock-return, rendered-copy and live-API-gated assertions\n\n* test: collapse package-manager tables and fold small daemon selector suites\n\npackage-manager: git-URL parsing, top-level/manifest/package glob filters and npm install-argv cases are now table-driven.\ndaemon-session-id: absorbs daemon-catalog-process selector case, drops display-id formatting trivia.\ndaemon-worker-windows-timeouts: absorbs the connection-deadline budget cases from daemon-worker-connect.\ndaemon-catalog-startup: drops the src-directory one-off.\n\n* test: collapse refinement, settings and config suites into case tables\n\nFinal misc lane of the test-bloat audit.\n\n- refinement: per-kind create/update/delete becomes one it.each lifecycle;\n  8 rejection suites become one 18-row invalid-edit table that also asserts\n  state and the refinement log stay untouched; truncation/parse errors,\n  scope permutations, ranking and the tokenizer each become one table.\n  System-prompt and user-prompt copy assertions removed.\n- settings-manager: per-setting default getters removed; unknown-key\n  preservation, invalid-file guards and project-vs-global precedence kept.\n- config: install-method detection becomes one table; session-dir env\n  permutations collapse into one precedence test.\n- builtin-skills, repl-kernel-abort, session-cwd, truncate: repeated blocks\n  collapsed; one ReplInternals reach-in dropped.\n- child-process folds into exec as one process lifecycle suite.\n\n* slim regression tests (lane C)\n\nFold the remaining ticket-numbered regression files into the owning\nmodule suites and collapse duplicate cases into it.each tables.\n\n- 19 regression files deleted after their kept cases moved into\n  agent-session-queue, auth-storage, acp-features, resource-loader,\n  agent-session-runtime/compaction/retry-events/recursion,\n  model-registry, slash-commands, daemon-supervisor-process\n- 3 files slimmed in place where the named target no longer exists\n- drop rendered-copy, mock-return and private-cast assertions\n\n* test: collapse daemon protocol, command, list, ps and package-command suites\n\ndaemon-protocol: two gating tables replace 16 near-identical capability/schema cases.\ndaemon-command: table-driven argv parsing plus the --goal leak guards; drops help/usage copy assertions.\ndaemon-session-list: activity, recap and model-fallback projections are table-driven.\ndaemon-ps: keeps planReap/planShutdownAll safety rules, drops ss/lsof parsers, sorting and uptime trivia.\ndaemon-stop-confirm: one busy-guard table, no prompt copy.\npackage-command-paths: one shared self-update fixture for the install-spec cases; drops help and removed-flag copy.\nacp-events: keeps only the cases the ACP suite does not cover end to end.\ndaemon-session-summarizer: one recap/status parse table.\ndaemon-extension-binding: keeps the duplicated-partial-message strip.\n\n* test: tighten the daemon stop-confirm busy-guard table\n\n* fix ci: biome forEach body, vacuous autocomplete case, missing prompt before second compaction\n\n* fix ci: restore escaped template literals in prompt-template cases\n\n* fix codeql: single-pass path escaping in test helpers\n\n* address review: flush debounced trace uploads, restore probe timeout guards, drop dead test scaffolding\n\n* respect retry-after and throttle window when flushing trace uploads\n\n* await in-flight trace uploads before a drain returns\n\n* extend deterministic test policy to python\n\n* harden deterministic test policy checks\n\n* close test policy edge cases\n\n* finish deterministic policy edge coverage\n\n* fix policy lexer and macos signature setup\n\n* mask regex literals in test policy checks\n\n* distinguish postfix division in policy lexer\n\n* close native migration signal race\n\n* keep native migration force timer owned\n\n---------\n\nCo-authored-by: prime-agent <agent@local>"},{"name":"azure-openai-base-url.test.ts","kind":"file","size":3394,"lastCommitHash":"cf07c5a3f5eca98e7744f2df83050044c920252a","lastCommitWhen":"2026-09-16T16:28:13-04:00","lastCommitMessage":"delete dead tests and fix the races the flaky ones were hiding (#2336)\n\n* add an objective testing policy to AGENTS.md\n\n* fix flaky daemon supervisor monitor test\n\nThe supervisor availability check is a real async chain (registry stat,\nsocket probe, replacement launch) started from a timer callback, so the\ntest drove a bounded fake-timer pump and asserted on a probe counter.\nUnder a loaded CI shard the chain did not finish inside the iteration\nbudget, and the variant mixing fake timers with a real probe promise\ncould deadlock for the full 30s test timeout.\n\nExpose a settled promise per armed availability check and await it in\nthe tests, so each assertion runs after the check finished instead of\nafter an arbitrary number of clock advances.\n\n* remove vitest retry masking from ai and attach-image tests\n\nDeleted all 548 `retry:` options in packages/ai/test and the 2 in\nkernel-attach-image-skill.test.ts. Retries hid non-determinism instead of\nfixing it, so a broken code path could still go green.\n\n- Deleted 17 live-only cross-provider E2E matrices whose every case sits behind\n  skipIf(!API_KEY) and never runs in CI; stream.test.ts stays as the survivor\n  that owns the provider table.\n- Stripped the retry option from the 198 stream.test.ts cases and dropped the\n  live E2E describe (plus its now-unused helpers) from\n  anthropic-thinking-disable.test.ts, keeping its mocked payload contract.\n- Removed retry: 1 from the two attach-image kernel cases; they pass without it.\n\nMocked wire/SSE contract tests are untouched. Tests only, no product code.\n\n* make agent trace upload tests deterministic\n\nThe suite pumped a synthetic clock with advanceTimersUntil() and hoped real\nfs and promise work settled inside a 200-step budget, asserted schedule\ndelays through a global setTimeout spy whose fake clock had drifted, and\nremoved its temp dir while catch-up and cursor writers were still running.\nUnder a loaded CI shard that produced \"Timed out advancing fake timers\",\n\"expected 1000 to be 60000\" and \"ENOTEMPTY rmdir /tmp/agent-traces-test-*\".\n\nThe upload scheduler now reports the delay it arms and the outcome of each\ncycle, the upload reports every wait it arms before the next request, and\ninstallAgentTraceUpload returns a handle that resolves when the startup\ncatch-up and any in-flight upload have finished writing. Tests await those\nsignals and advance the fake clock by the exact reported delay, and teardown\nwaits for in-flight writers before removing the temp dir.\n\nThe ~15 retry, backoff and Retry-After variants collapse into one\ntable-driven it.each, per the MERGE verdict: 1569 -> 1141 lines, 44 -> 27\ntest blocks, with no lost coverage.\n\n* make the compiled artifact and installer probe tests deterministic\n\nThe compiled-artifact afterEach polled for supervisor exit with the same\n10s budget as vitest's hook timeout, so the poll could never report on the\nslower standalone runners. The teardown now escalates to SIGKILL and every\ninner deadline stays below the surrounding hook and test budgets.\n\nnative-probe-timeout decided pass/fail from wall-clock deadlines around a\nreal 10s installer probe. The installer probe deadline is now injectable\nthrough PRIME_AGENT_PROBE_TIMEOUT_SECONDS, the blocked probe records the\ninstall lock itself, and the spawn deadlines are gone.\n\n* fix daemon shutdown admission loss during slow scans\n\nshutdown --force holds a 5s admission lease refreshed by a 1s timer, but it\nblocks its own event loop in synchronous ps/lsof/ss scans. On a loaded runner a\nscan outlasts the lease, the elapsed record is treated as abandoned, and the\nholder's next assertOrRenew throws \"Daemon shutdown admission was lost\".\n\n- A late renew re-arms a record that is still ours; only a missing or foreign\n  record ends the admission.\n- A renew that could not read the registry no longer retires the lease.\n- isDaemonShutdownAdmissionActive is read-only, so a bystander probe cannot\n  delete a live holder's record.\n- stopHiddenSupervisors renews before the blocking scan.\n\nThe 4603 regression drops its 11s sleep for a post-shutdown listener assertion\nand uses mkdtemp for the child TMPDIR.\n\n* delete 148 dead test files\n\nRemoves test files judged CUT by a full 480-file audit: duplicates of a named survivor, mock-asserting tests, rendered-copy assertions, private-internals casts, and live-API matrices behind skipIf(!API_KEY) that never ran in CI.\n\n* merge interactive-mode and agents-view test suites\n\n* merge tui render, overlay and helper test suites\n\n* test: slim daemon-mode and agent-connection-daemon suites\n\ndaemon-mode: keep passive hydration/passivation, delete_subagent durability, agent-message concurrency and rate limits, attach-snapshot backpressure; drop per-race internal regressions already covered process-level by daemon-supervisor-process.\nagent-connection-daemon: keep reconnect, update-restart, chunked-snapshot assembly and disposal races; drop tautological daemon-protocol pass-through cases.\n\n* merge tui editor, markdown and autocomplete test suites\n\n* test: merge audited session-core test bloat\n\nExecute MERGE verdicts from the 480-file test audit for the agent-session\ncore suites: collapse near-identical blocks into it.each tables, drop\nmock-return/rendered-copy assertions and private-cast white-box cases,\nand fold one-off files into the owning suite.\n\nDeleted (folded into their owning suite):\n- agent-session-concurrent.test.ts, suite/agent-session-action-races.test.ts,\n  suite/agent-session-action-contracts.test.ts -> suite/agent-session-queue.test.ts\n- suite/agent-session-compaction-continuation.test.ts,\n  suite/agent-session-compact-skill.test.ts -> suite/agent-session-compaction.test.ts\n- agent-session-runtime-events.test.ts -> suite/agent-session-runtime.test.ts\n\nPreserved: process boundaries (daemon RPC, ACP), on-disk formats,\nconcurrency/ordering, crash/restart/resume and load coverage.\n\n* address review: octal probe timeout, truncated deadline, dead schedule field\n\n* test: merge redundant coding-agent test cases into case tables\n\nExecutes the MERGE verdicts from the 480-file test-bloat audit for the\nmisc lanes. Repeated near-identical blocks collapse into single it.each\ncase tables, and ticket-numbered one-off files fold into the owning\nmodule suite.\n\nRemoved throughout the touched files: assertions on mock return values,\nassertions on rendered text/copy, `as unknown as` casts into privates,\nand suites gated behind skipIf(!API_KEY) (which never ran in CI).\n\nPreserved: process boundaries (daemon RPC, ACP), on-disk formats,\nconcurrency and ordering, crash/restart/resume, and load.\n\nDeleted files, folded into their module suite:\n- compaction-extensions -> deleted outright (whole file behind skipIf(!API_KEY))\n- compaction-serialization -> compaction\n- heartbeat-catalog -> daemon-client\n- child-process -> exec\n- edit-tool-legacy-input -> tools\n- kernel-goal-skill, kernel-rlm-heartbeat-skill -> kernel-agent-message-skill\n- kernel-agent-observe-skill -> kernel-attach-image-skill\n- kernel-windows-process -> kernel-bootstrap-windows\n- extensions-input-event -> extensions-runner\n- sdk-skills -> sdk-session-manager\n- session-manager/{agent-status,has-user-content} -> session-manager/session-state\n- session-manager/migration -> session-manager/file-operations\n- session-manager/custom-session-id -> session-manager/tree-traversal\n\n* slim ai + regression tests (lanes A/B/D/E)\n\nExecute MERGE verdicts from the test audit for packages/ai and the\nupdate-restart / snapshot / session-view regression files.\n\n- fold ticket-numbered regression cases into the owning suites\n- collapse near-identical blocks into it.each tables\n- drop mock-return, rendered-copy and live-API-gated assertions\n\n* test: collapse package-manager tables and fold small daemon selector suites\n\npackage-manager: git-URL parsing, top-level/manifest/package glob filters and npm install-argv cases are now table-driven.\ndaemon-session-id: absorbs daemon-catalog-process selector case, drops display-id formatting trivia.\ndaemon-worker-windows-timeouts: absorbs the connection-deadline budget cases from daemon-worker-connect.\ndaemon-catalog-startup: drops the src-directory one-off.\n\n* test: collapse refinement, settings and config suites into case tables\n\nFinal misc lane of the test-bloat audit.\n\n- refinement: per-kind create/update/delete becomes one it.each lifecycle;\n  8 rejection suites become one 18-row invalid-edit table that also asserts\n  state and the refinement log stay untouched; truncation/parse errors,\n  scope permutations, ranking and the tokenizer each become one table.\n  System-prompt and user-prompt copy assertions removed.\n- settings-manager: per-setting default getters removed; unknown-key\n  preservation, invalid-file guards and project-vs-global precedence kept.\n- config: install-method detection becomes one table; session-dir env\n  permutations collapse into one precedence test.\n- builtin-skills, repl-kernel-abort, session-cwd, truncate: repeated blocks\n  collapsed; one ReplInternals reach-in dropped.\n- child-process folds into exec as one process lifecycle suite.\n\n* slim regression tests (lane C)\n\nFold the remaining ticket-numbered regression files into the owning\nmodule suites and collapse duplicate cases into it.each tables.\n\n- 19 regression files deleted after their kept cases moved into\n  agent-session-queue, auth-storage, acp-features, resource-loader,\n  agent-session-runtime/compaction/retry-events/recursion,\n  model-registry, slash-commands, daemon-supervisor-process\n- 3 files slimmed in place where the named target no longer exists\n- drop rendered-copy, mock-return and private-cast assertions\n\n* test: collapse daemon protocol, command, list, ps and package-command suites\n\ndaemon-protocol: two gating tables replace 16 near-identical capability/schema cases.\ndaemon-command: table-driven argv parsing plus the --goal leak guards; drops help/usage copy assertions.\ndaemon-session-list: activity, recap and model-fallback projections are table-driven.\ndaemon-ps: keeps planReap/planShutdownAll safety rules, drops ss/lsof parsers, sorting and uptime trivia.\ndaemon-stop-confirm: one busy-guard table, no prompt copy.\npackage-command-paths: one shared self-update fixture for the install-spec cases; drops help and removed-flag copy.\nacp-events: keeps only the cases the ACP suite does not cover end to end.\ndaemon-session-summarizer: one recap/status parse table.\ndaemon-extension-binding: keeps the duplicated-partial-message strip.\n\n* test: tighten the daemon stop-confirm busy-guard table\n\n* fix ci: biome forEach body, vacuous autocomplete case, missing prompt before second compaction\n\n* fix ci: restore escaped template literals in prompt-template cases\n\n* fix codeql: single-pass path escaping in test helpers\n\n* address review: flush debounced trace uploads, restore probe timeout guards, drop dead test scaffolding\n\n* respect retry-after and throttle window when flushing trace uploads\n\n* await in-flight trace uploads before a drain returns\n\n* extend deterministic test policy to python\n\n* harden deterministic test policy checks\n\n* close test policy edge cases\n\n* finish deterministic policy edge coverage\n\n* fix policy lexer and macos signature setup\n\n* mask regex literals in test policy checks\n\n* distinguish postfix division in policy lexer\n\n* close native migration signal race\n\n* keep native migration force timer owned\n\n---------\n\nCo-authored-by: prime-agent <agent@local>"},{"name":"azure-utils.ts","kind":"file","size":897,"lastCommitHash":"032e3ee74574ca16efaf8745a1394b821256a5d0","lastCommitWhen":"2026-08-18T12:17:35+02:00","lastCommitMessage":"chore: remove redundant comments and unused internals (#1505)\n\n* chore: remove redundant comments\n\n* chore(tui): remove redundant export comments\n\n* chore(coding-agent): remove redundant example comments\n\n* chore(ai): remove redundant comments\n\n* chore(coding-agent): remove obsolete core comments\n\n* chore(coding-agent): remove redundant test comments\n\n* chore(coding-agent): remove redundant test comments\n\n* chore(coding-agent): remove redundant rpc test comments\n\n* chore(coding-agent): remove redundant CLI comments\n\n* chore(agent): remove redundant comments\n\n* chore(tui): remove redundant source comments\n\n* chore(coding-agent): remove redundant mode comments\n\n* chore(coding-agent): remove redundant mode comments\n\n* chore(coding-agent): remove redundant test comments\n\n* chore(ai): remove redundant source comments\n\n* chore(coding-agent): remove redundant session comments\n\n* chore(coding-agent): remove redundant core comments\n\n* chore(coding-agent): remove redundant test comments\n\n* chore(tests): remove redundant test comments\n\n* chore: remove unused internal helpers\n\n* docs: restore public API contracts\n\n* chore(coding-agent): restore invariant documentation\n\n* chore(coding-agent): clarify agent family contracts\n\n* style(coding-agent): format restored contracts\n\n* fix: restore intentional catch explanations"},{"name":"bedrock-thinking-payload.test.ts","kind":"file","size":11287,"lastCommitHash":"cf07c5a3f5eca98e7744f2df83050044c920252a","lastCommitWhen":"2026-09-16T16:28:13-04:00","lastCommitMessage":"delete dead tests and fix the races the flaky ones were hiding (#2336)\n\n* add an objective testing policy to AGENTS.md\n\n* fix flaky daemon supervisor monitor test\n\nThe supervisor availability check is a real async chain (registry stat,\nsocket probe, replacement launch) started from a timer callback, so the\ntest drove a bounded fake-timer pump and asserted on a probe counter.\nUnder a loaded CI shard the chain did not finish inside the iteration\nbudget, and the variant mixing fake timers with a real probe promise\ncould deadlock for the full 30s test timeout.\n\nExpose a settled promise per armed availability check and await it in\nthe tests, so each assertion runs after the check finished instead of\nafter an arbitrary number of clock advances.\n\n* remove vitest retry masking from ai and attach-image tests\n\nDeleted all 548 `retry:` options in packages/ai/test and the 2 in\nkernel-attach-image-skill.test.ts. Retries hid non-determinism instead of\nfixing it, so a broken code path could still go green.\n\n- Deleted 17 live-only cross-provider E2E matrices whose every case sits behind\n  skipIf(!API_KEY) and never runs in CI; stream.test.ts stays as the survivor\n  that owns the provider table.\n- Stripped the retry option from the 198 stream.test.ts cases and dropped the\n  live E2E describe (plus its now-unused helpers) from\n  anthropic-thinking-disable.test.ts, keeping its mocked payload contract.\n- Removed retry: 1 from the two attach-image kernel cases; they pass without it.\n\nMocked wire/SSE contract tests are untouched. Tests only, no product code.\n\n* make agent trace upload tests deterministic\n\nThe suite pumped a synthetic clock with advanceTimersUntil() and hoped real\nfs and promise work settled inside a 200-step budget, asserted schedule\ndelays through a global setTimeout spy whose fake clock had drifted, and\nremoved its temp dir while catch-up and cursor writers were still running.\nUnder a loaded CI shard that produced \"Timed out advancing fake timers\",\n\"expected 1000 to be 60000\" and \"ENOTEMPTY rmdir /tmp/agent-traces-test-*\".\n\nThe upload scheduler now reports the delay it arms and the outcome of each\ncycle, the upload reports every wait it arms before the next request, and\ninstallAgentTraceUpload returns a handle that resolves when the startup\ncatch-up and any in-flight upload have finished writing. Tests await those\nsignals and advance the fake clock by the exact reported delay, and teardown\nwaits for in-flight writers before removing the temp dir.\n\nThe ~15 retry, backoff and Retry-After variants collapse into one\ntable-driven it.each, per the MERGE verdict: 1569 -> 1141 lines, 44 -> 27\ntest blocks, with no lost coverage.\n\n* make the compiled artifact and installer probe tests deterministic\n\nThe compiled-artifact afterEach polled for supervisor exit with the same\n10s budget as vitest's hook timeout, so the poll could never report on the\nslower standalone runners. The teardown now escalates to SIGKILL and every\ninner deadline stays below the surrounding hook and test budgets.\n\nnative-probe-timeout decided pass/fail from wall-clock deadlines around a\nreal 10s installer probe. The installer probe deadline is now injectable\nthrough PRIME_AGENT_PROBE_TIMEOUT_SECONDS, the blocked probe records the\ninstall lock itself, and the spawn deadlines are gone.\n\n* fix daemon shutdown admission loss during slow scans\n\nshutdown --force holds a 5s admission lease refreshed by a 1s timer, but it\nblocks its own event loop in synchronous ps/lsof/ss scans. On a loaded runner a\nscan outlasts the lease, the elapsed record is treated as abandoned, and the\nholder's next assertOrRenew throws \"Daemon shutdown admission was lost\".\n\n- A late renew re-arms a record that is still ours; only a missing or foreign\n  record ends the admission.\n- A renew that could not read the registry no longer retires the lease.\n- isDaemonShutdownAdmissionActive is read-only, so a bystander probe cannot\n  delete a live holder's record.\n- stopHiddenSupervisors renews before the blocking scan.\n\nThe 4603 regression drops its 11s sleep for a post-shutdown listener assertion\nand uses mkdtemp for the child TMPDIR.\n\n* delete 148 dead test files\n\nRemoves test files judged CUT by a full 480-file audit: duplicates of a named survivor, mock-asserting tests, rendered-copy assertions, private-internals casts, and live-API matrices behind skipIf(!API_KEY) that never ran in CI.\n\n* merge interactive-mode and agents-view test suites\n\n* merge tui render, overlay and helper test suites\n\n* test: slim daemon-mode and agent-connection-daemon suites\n\ndaemon-mode: keep passive hydration/passivation, delete_subagent durability, agent-message concurrency and rate limits, attach-snapshot backpressure; drop per-race internal regressions already covered process-level by daemon-supervisor-process.\nagent-connection-daemon: keep reconnect, update-restart, chunked-snapshot assembly and disposal races; drop tautological daemon-protocol pass-through cases.\n\n* merge tui editor, markdown and autocomplete test suites\n\n* test: merge audited session-core test bloat\n\nExecute MERGE verdicts from the 480-file test audit for the agent-session\ncore suites: collapse near-identical blocks into it.each tables, drop\nmock-return/rendered-copy assertions and private-cast white-box cases,\nand fold one-off files into the owning suite.\n\nDeleted (folded into their owning suite):\n- agent-session-concurrent.test.ts, suite/agent-session-action-races.test.ts,\n  suite/agent-session-action-contracts.test.ts -> suite/agent-session-queue.test.ts\n- suite/agent-session-compaction-continuation.test.ts,\n  suite/agent-session-compact-skill.test.ts -> suite/agent-session-compaction.test.ts\n- agent-session-runtime-events.test.ts -> suite/agent-session-runtime.test.ts\n\nPreserved: process boundaries (daemon RPC, ACP), on-disk formats,\nconcurrency/ordering, crash/restart/resume and load coverage.\n\n* address review: octal probe timeout, truncated deadline, dead schedule field\n\n* test: merge redundant coding-agent test cases into case tables\n\nExecutes the MERGE verdicts from the 480-file test-bloat audit for the\nmisc lanes. Repeated near-identical blocks collapse into single it.each\ncase tables, and ticket-numbered one-off files fold into the owning\nmodule suite.\n\nRemoved throughout the touched files: assertions on mock return values,\nassertions on rendered text/copy, `as unknown as` casts into privates,\nand suites gated behind skipIf(!API_KEY) (which never ran in CI).\n\nPreserved: process boundaries (daemon RPC, ACP), on-disk formats,\nconcurrency and ordering, crash/restart/resume, and load.\n\nDeleted files, folded into their module suite:\n- compaction-extensions -> deleted outright (whole file behind skipIf(!API_KEY))\n- compaction-serialization -> compaction\n- heartbeat-catalog -> daemon-client\n- child-process -> exec\n- edit-tool-legacy-input -> tools\n- kernel-goal-skill, kernel-rlm-heartbeat-skill -> kernel-agent-message-skill\n- kernel-agent-observe-skill -> kernel-attach-image-skill\n- kernel-windows-process -> kernel-bootstrap-windows\n- extensions-input-event -> extensions-runner\n- sdk-skills -> sdk-session-manager\n- session-manager/{agent-status,has-user-content} -> session-manager/session-state\n- session-manager/migration -> session-manager/file-operations\n- session-manager/custom-session-id -> session-manager/tree-traversal\n\n* slim ai + regression tests (lanes A/B/D/E)\n\nExecute MERGE verdicts from the test audit for packages/ai and the\nupdate-restart / snapshot / session-view regression files.\n\n- fold ticket-numbered regression cases into the owning suites\n- collapse near-identical blocks into it.each tables\n- drop mock-return, rendered-copy and live-API-gated assertions\n\n* test: collapse package-manager tables and fold small daemon selector suites\n\npackage-manager: git-URL parsing, top-level/manifest/package glob filters and npm install-argv cases are now table-driven.\ndaemon-session-id: absorbs daemon-catalog-process selector case, drops display-id formatting trivia.\ndaemon-worker-windows-timeouts: absorbs the connection-deadline budget cases from daemon-worker-connect.\ndaemon-catalog-startup: drops the src-directory one-off.\n\n* test: collapse refinement, settings and config suites into case tables\n\nFinal misc lane of the test-bloat audit.\n\n- refinement: per-kind create/update/delete becomes one it.each lifecycle;\n  8 rejection suites become one 18-row invalid-edit table that also asserts\n  state and the refinement log stay untouched; truncation/parse errors,\n  scope permutations, ranking and the tokenizer each become one table.\n  System-prompt and user-prompt copy assertions removed.\n- settings-manager: per-setting default getters removed; unknown-key\n  preservation, invalid-file guards and project-vs-global precedence kept.\n- config: install-method detection becomes one table; session-dir env\n  permutations collapse into one precedence test.\n- builtin-skills, repl-kernel-abort, session-cwd, truncate: repeated blocks\n  collapsed; one ReplInternals reach-in dropped.\n- child-process folds into exec as one process lifecycle suite.\n\n* slim regression tests (lane C)\n\nFold the remaining ticket-numbered regression files into the owning\nmodule suites and collapse duplicate cases into it.each tables.\n\n- 19 regression files deleted after their kept cases moved into\n  agent-session-queue, auth-storage, acp-features, resource-loader,\n  agent-session-runtime/compaction/retry-events/recursion,\n  model-registry, slash-commands, daemon-supervisor-process\n- 3 files slimmed in place where the named target no longer exists\n- drop rendered-copy, mock-return and private-cast assertions\n\n* test: collapse daemon protocol, command, list, ps and package-command suites\n\ndaemon-protocol: two gating tables replace 16 near-identical capability/schema cases.\ndaemon-command: table-driven argv parsing plus the --goal leak guards; drops help/usage copy assertions.\ndaemon-session-list: activity, recap and model-fallback projections are table-driven.\ndaemon-ps: keeps planReap/planShutdownAll safety rules, drops ss/lsof parsers, sorting and uptime trivia.\ndaemon-stop-confirm: one busy-guard table, no prompt copy.\npackage-command-paths: one shared self-update fixture for the install-spec cases; drops help and removed-flag copy.\nacp-events: keeps only the cases the ACP suite does not cover end to end.\ndaemon-session-summarizer: one recap/status parse table.\ndaemon-extension-binding: keeps the duplicated-partial-message strip.\n\n* test: tighten the daemon stop-confirm busy-guard table\n\n* fix ci: biome forEach body, vacuous autocomplete case, missing prompt before second compaction\n\n* fix ci: restore escaped template literals in prompt-template cases\n\n* fix codeql: single-pass path escaping in test helpers\n\n* address review: flush debounced trace uploads, restore probe timeout guards, drop dead test scaffolding\n\n* respect retry-after and throttle window when flushing trace uploads\n\n* await in-flight trace uploads before a drain returns\n\n* extend deterministic test policy to python\n\n* harden deterministic test policy checks\n\n* close test policy edge cases\n\n* finish deterministic policy edge coverage\n\n* fix policy lexer and macos signature setup\n\n* mask regex literals in test policy checks\n\n* distinguish postfix division in policy lexer\n\n* close native migration signal race\n\n* keep native migration force timer owned\n\n---------\n\nCo-authored-by: prime-agent <agent@local>"},{"name":"bedrock-utils.ts","kind":"file","size":211,"lastCommitHash":"032e3ee74574ca16efaf8745a1394b821256a5d0","lastCommitWhen":"2026-08-18T12:17:35+02:00","lastCommitMessage":"chore: remove redundant comments and unused internals (#1505)\n\n* chore: remove redundant comments\n\n* chore(tui): remove redundant export comments\n\n* chore(coding-agent): remove redundant example comments\n\n* chore(ai): remove redundant comments\n\n* chore(coding-agent): remove obsolete core comments\n\n* chore(coding-agent): remove redundant test comments\n\n* chore(coding-agent): remove redundant test comments\n\n* chore(coding-agent): remove redundant rpc test comments\n\n* chore(coding-agent): remove redundant CLI comments\n\n* chore(agent): remove redundant comments\n\n* chore(tui): remove redundant source comments\n\n* chore(coding-agent): remove redundant mode comments\n\n* chore(coding-agent): remove redundant mode comments\n\n* chore(coding-agent): remove redundant test comments\n\n* chore(ai): remove redundant source comments\n\n* chore(coding-agent): remove redundant session comments\n\n* chore(coding-agent): remove redundant core comments\n\n* chore(coding-agent): remove redundant test comments\n\n* chore(tests): remove redundant test comments\n\n* chore: remove unused internal helpers\n\n* docs: restore public API contracts\n\n* chore(coding-agent): restore invariant documentation\n\n* chore(coding-agent): clarify agent family contracts\n\n* style(coding-agent): format restored contracts\n\n* fix: restore intentional catch explanations"},{"name":"cache-retention.test.ts","kind":"file","size":24492,"lastCommitHash":"44a9c620bd70d31cef41464861ec307ee8a104a2","lastCommitWhen":"2026-09-17T06:40:47+03:00","lastCommitMessage":"ai,coding-agent: route compaction and refinement by session identity\n"},{"name":"cloudflare-utils.ts","kind":"file","size":339,"lastCommitHash":"a45577bd0020a89ba6f14d744b287b5a998b02b7","lastCommitWhen":"2026-05-01T00:56:05+02:00","lastCommitMessage":"fix(ai): finalize cloudflare gateway provider support\n"},{"name":"codex-websocket-cached-probe.ts","kind":"file","size":10354,"lastCommitHash":"032e3ee74574ca16efaf8745a1394b821256a5d0","lastCommitWhen":"2026-08-18T12:17:35+02:00","lastCommitMessage":"chore: remove redundant comments and unused internals (#1505)\n\n* chore: remove redundant comments\n\n* chore(tui): remove redundant export comments\n\n* chore(coding-agent): remove redundant example comments\n\n* chore(ai): remove redundant comments\n\n* chore(coding-agent): remove obsolete core comments\n\n* chore(coding-agent): remove redundant test comments\n\n* chore(coding-agent): remove redundant test comments\n\n* chore(coding-agent): remove redundant rpc test comments\n\n* chore(coding-agent): remove redundant CLI comments\n\n* chore(agent): remove redundant comments\n\n* chore(tui): remove redundant source comments\n\n* chore(coding-agent): remove redundant mode comments\n\n* chore(coding-agent): remove redundant mode comments\n\n* chore(coding-agent): remove redundant test comments\n\n* chore(ai): remove redundant source comments\n\n* chore(coding-agent): remove redundant session comments\n\n* chore(coding-agent): remove redundant core comments\n\n* chore(coding-agent): remove redundant test comments\n\n* chore(tests): remove redundant test comments\n\n* chore: remove unused internal helpers\n\n* docs: restore public API contracts\n\n* chore(coding-agent): restore invariant documentation\n\n* chore(coding-agent): clarify agent family contracts\n\n* style(coding-agent): format restored contracts\n\n* fix: restore intentional catch explanations"},{"name":"cross-provider-handoff.test.ts","kind":"file","size":1384,"lastCommitHash":"cf07c5a3f5eca98e7744f2df83050044c920252a","lastCommitWhen":"2026-09-16T16:28:13-04:00","lastCommitMessage":"delete dead tests and fix the races the flaky ones were hiding (#2336)\n\n* add an objective testing policy to AGENTS.md\n\n* fix flaky daemon supervisor monitor test\n\nThe supervisor availability check is a real async chain (registry stat,\nsocket probe, replacement launch) started from a timer callback, so the\ntest drove a bounded fake-timer pump and asserted on a probe counter.\nUnder a loaded CI shard the chain did not finish inside the iteration\nbudget, and the variant mixing fake timers with a real probe promise\ncould deadlock for the full 30s test timeout.\n\nExpose a settled promise per armed availability check and await it in\nthe tests, so each assertion runs after the check finished instead of\nafter an arbitrary number of clock advances.\n\n* remove vitest retry masking from ai and attach-image tests\n\nDeleted all 548 `retry:` options in packages/ai/test and the 2 in\nkernel-attach-image-skill.test.ts. Retries hid non-determinism instead of\nfixing it, so a broken code path could still go green.\n\n- Deleted 17 live-only cross-provider E2E matrices whose every case sits behind\n  skipIf(!API_KEY) and never runs in CI; stream.test.ts stays as the survivor\n  that owns the provider table.\n- Stripped the retry option from the 198 stream.test.ts cases and dropped the\n  live E2E describe (plus its now-unused helpers) from\n  anthropic-thinking-disable.test.ts, keeping its mocked payload contract.\n- Removed retry: 1 from the two attach-image kernel cases; they pass without it.\n\nMocked wire/SSE contract tests are untouched. Tests only, no product code.\n\n* make agent trace upload tests deterministic\n\nThe suite pumped a synthetic clock with advanceTimersUntil() and hoped real\nfs and promise work settled inside a 200-step budget, asserted schedule\ndelays through a global setTimeout spy whose fake clock had drifted, and\nremoved its temp dir while catch-up and cursor writers were still running.\nUnder a loaded CI shard that produced \"Timed out advancing fake timers\",\n\"expected 1000 to be 60000\" and \"ENOTEMPTY rmdir /tmp/agent-traces-test-*\".\n\nThe upload scheduler now reports the delay it arms and the outcome of each\ncycle, the upload reports every wait it arms before the next request, and\ninstallAgentTraceUpload returns a handle that resolves when the startup\ncatch-up and any in-flight upload have finished writing. Tests await those\nsignals and advance the fake clock by the exact reported delay, and teardown\nwaits for in-flight writers before removing the temp dir.\n\nThe ~15 retry, backoff and Retry-After variants collapse into one\ntable-driven it.each, per the MERGE verdict: 1569 -> 1141 lines, 44 -> 27\ntest blocks, with no lost coverage.\n\n* make the compiled artifact and installer probe tests deterministic\n\nThe compiled-artifact afterEach polled for supervisor exit with the same\n10s budget as vitest's hook timeout, so the poll could never report on the\nslower standalone runners. The teardown now escalates to SIGKILL and every\ninner deadline stays below the surrounding hook and test budgets.\n\nnative-probe-timeout decided pass/fail from wall-clock deadlines around a\nreal 10s installer probe. The installer probe deadline is now injectable\nthrough PRIME_AGENT_PROBE_TIMEOUT_SECONDS, the blocked probe records the\ninstall lock itself, and the spawn deadlines are gone.\n\n* fix daemon shutdown admission loss during slow scans\n\nshutdown --force holds a 5s admission lease refreshed by a 1s timer, but it\nblocks its own event loop in synchronous ps/lsof/ss scans. On a loaded runner a\nscan outlasts the lease, the elapsed record is treated as abandoned, and the\nholder's next assertOrRenew throws \"Daemon shutdown admission was lost\".\n\n- A late renew re-arms a record that is still ours; only a missing or foreign\n  record ends the admission.\n- A renew that could not read the registry no longer retires the lease.\n- isDaemonShutdownAdmissionActive is read-only, so a bystander probe cannot\n  delete a live holder's record.\n- stopHiddenSupervisors renews before the blocking scan.\n\nThe 4603 regression drops its 11s sleep for a post-shutdown listener assertion\nand uses mkdtemp for the child TMPDIR.\n\n* delete 148 dead test files\n\nRemoves test files judged CUT by a full 480-file audit: duplicates of a named survivor, mock-asserting tests, rendered-copy assertions, private-internals casts, and live-API matrices behind skipIf(!API_KEY) that never ran in CI.\n\n* merge interactive-mode and agents-view test suites\n\n* merge tui render, overlay and helper test suites\n\n* test: slim daemon-mode and agent-connection-daemon suites\n\ndaemon-mode: keep passive hydration/passivation, delete_subagent durability, agent-message concurrency and rate limits, attach-snapshot backpressure; drop per-race internal regressions already covered process-level by daemon-supervisor-process.\nagent-connection-daemon: keep reconnect, update-restart, chunked-snapshot assembly and disposal races; drop tautological daemon-protocol pass-through cases.\n\n* merge tui editor, markdown and autocomplete test suites\n\n* test: merge audited session-core test bloat\n\nExecute MERGE verdicts from the 480-file test audit for the agent-session\ncore suites: collapse near-identical blocks into it.each tables, drop\nmock-return/rendered-copy assertions and private-cast white-box cases,\nand fold one-off files into the owning suite.\n\nDeleted (folded into their owning suite):\n- agent-session-concurrent.test.ts, suite/agent-session-action-races.test.ts,\n  suite/agent-session-action-contracts.test.ts -> suite/agent-session-queue.test.ts\n- suite/agent-session-compaction-continuation.test.ts,\n  suite/agent-session-compact-skill.test.ts -> suite/agent-session-compaction.test.ts\n- agent-session-runtime-events.test.ts -> suite/agent-session-runtime.test.ts\n\nPreserved: process boundaries (daemon RPC, ACP), on-disk formats,\nconcurrency/ordering, crash/restart/resume and load coverage.\n\n* address review: octal probe timeout, truncated deadline, dead schedule field\n\n* test: merge redundant coding-agent test cases into case tables\n\nExecutes the MERGE verdicts from the 480-file test-bloat audit for the\nmisc lanes. Repeated near-identical blocks collapse into single it.each\ncase tables, and ticket-numbered one-off files fold into the owning\nmodule suite.\n\nRemoved throughout the touched files: assertions on mock return values,\nassertions on rendered text/copy, `as unknown as` casts into privates,\nand suites gated behind skipIf(!API_KEY) (which never ran in CI).\n\nPreserved: process boundaries (daemon RPC, ACP), on-disk formats,\nconcurrency and ordering, crash/restart/resume, and load.\n\nDeleted files, folded into their module suite:\n- compaction-extensions -> deleted outright (whole file behind skipIf(!API_KEY))\n- compaction-serialization -> compaction\n- heartbeat-catalog -> daemon-client\n- child-process -> exec\n- edit-tool-legacy-input -> tools\n- kernel-goal-skill, kernel-rlm-heartbeat-skill -> kernel-agent-message-skill\n- kernel-agent-observe-skill -> kernel-attach-image-skill\n- kernel-windows-process -> kernel-bootstrap-windows\n- extensions-input-event -> extensions-runner\n- sdk-skills -> sdk-session-manager\n- session-manager/{agent-status,has-user-content} -> session-manager/session-state\n- session-manager/migration -> session-manager/file-operations\n- session-manager/custom-session-id -> session-manager/tree-traversal\n\n* slim ai + regression tests (lanes A/B/D/E)\n\nExecute MERGE verdicts from the test audit for packages/ai and the\nupdate-restart / snapshot / session-view regression files.\n\n- fold ticket-numbered regression cases into the owning suites\n- collapse near-identical blocks into it.each tables\n- drop mock-return, rendered-copy and live-API-gated assertions\n\n* test: collapse package-manager tables and fold small daemon selector suites\n\npackage-manager: git-URL parsing, top-level/manifest/package glob filters and npm install-argv cases are now table-driven.\ndaemon-session-id: absorbs daemon-catalog-process selector case, drops display-id formatting trivia.\ndaemon-worker-windows-timeouts: absorbs the connection-deadline budget cases from daemon-worker-connect.\ndaemon-catalog-startup: drops the src-directory one-off.\n\n* test: collapse refinement, settings and config suites into case tables\n\nFinal misc lane of the test-bloat audit.\n\n- refinement: per-kind create/update/delete becomes one it.each lifecycle;\n  8 rejection suites become one 18-row invalid-edit table that also asserts\n  state and the refinement log stay untouched; truncation/parse errors,\n  scope permutations, ranking and the tokenizer each become one table.\n  System-prompt and user-prompt copy assertions removed.\n- settings-manager: per-setting default getters removed; unknown-key\n  preservation, invalid-file guards and project-vs-global precedence kept.\n- config: install-method detection becomes one table; session-dir env\n  permutations collapse into one precedence test.\n- builtin-skills, repl-kernel-abort, session-cwd, truncate: repeated blocks\n  collapsed; one ReplInternals reach-in dropped.\n- child-process folds into exec as one process lifecycle suite.\n\n* slim regression tests (lane C)\n\nFold the remaining ticket-numbered regression files into the owning\nmodule suites and collapse duplicate cases into it.each tables.\n\n- 19 regression files deleted after their kept cases moved into\n  agent-session-queue, auth-storage, acp-features, resource-loader,\n  agent-session-runtime/compaction/retry-events/recursion,\n  model-registry, slash-commands, daemon-supervisor-process\n- 3 files slimmed in place where the named target no longer exists\n- drop rendered-copy, mock-return and private-cast assertions\n\n* test: collapse daemon protocol, command, list, ps and package-command suites\n\ndaemon-protocol: two gating tables replace 16 near-identical capability/schema cases.\ndaemon-command: table-driven argv parsing plus the --goal leak guards; drops help/usage copy assertions.\ndaemon-session-list: activity, recap and model-fallback projections are table-driven.\ndaemon-ps: keeps planReap/planShutdownAll safety rules, drops ss/lsof parsers, sorting and uptime trivia.\ndaemon-stop-confirm: one busy-guard table, no prompt copy.\npackage-command-paths: one shared self-update fixture for the install-spec cases; drops help and removed-flag copy.\nacp-events: keeps only the cases the ACP suite does not cover end to end.\ndaemon-session-summarizer: one recap/status parse table.\ndaemon-extension-binding: keeps the duplicated-partial-message strip.\n\n* test: tighten the daemon stop-confirm busy-guard table\n\n* fix ci: biome forEach body, vacuous autocomplete case, missing prompt before second compaction\n\n* fix ci: restore escaped template literals in prompt-template cases\n\n* fix codeql: single-pass path escaping in test helpers\n\n* address review: flush debounced trace uploads, restore probe timeout guards, drop dead test scaffolding\n\n* respect retry-after and throttle window when flushing trace uploads\n\n* await in-flight trace uploads before a drain returns\n\n* extend deterministic test policy to python\n\n* harden deterministic test policy checks\n\n* close test policy edge cases\n\n* finish deterministic policy edge coverage\n\n* fix policy lexer and macos signature setup\n\n* mask regex literals in test policy checks\n\n* distinguish postfix division in policy lexer\n\n* close native migration signal race\n\n* keep native migration force timer owned\n\n---------\n\nCo-authored-by: prime-agent <agent@local>"},{"name":"faux-provider.test.ts","kind":"file","size":11239,"lastCommitHash":"cf07c5a3f5eca98e7744f2df83050044c920252a","lastCommitWhen":"2026-09-16T16:28:13-04:00","lastCommitMessage":"delete dead tests and fix the races the flaky ones were hiding (#2336)\n\n* add an objective testing policy to AGENTS.md\n\n* fix flaky daemon supervisor monitor test\n\nThe supervisor availability check is a real async chain (registry stat,\nsocket probe, replacement launch) started from a timer callback, so the\ntest drove a bounded fake-timer pump and asserted on a probe counter.\nUnder a loaded CI shard the chain did not finish inside the iteration\nbudget, and the variant mixing fake timers with a real probe promise\ncould deadlock for the full 30s test timeout.\n\nExpose a settled promise per armed availability check and await it in\nthe tests, so each assertion runs after the check finished instead of\nafter an arbitrary number of clock advances.\n\n* remove vitest retry masking from ai and attach-image tests\n\nDeleted all 548 `retry:` options in packages/ai/test and the 2 in\nkernel-attach-image-skill.test.ts. Retries hid non-determinism instead of\nfixing it, so a broken code path could still go green.\n\n- Deleted 17 live-only cross-provider E2E matrices whose every case sits behind\n  skipIf(!API_KEY) and never runs in CI; stream.test.ts stays as the survivor\n  that owns the provider table.\n- Stripped the retry option from the 198 stream.test.ts cases and dropped the\n  live E2E describe (plus its now-unused helpers) from\n  anthropic-thinking-disable.test.ts, keeping its mocked payload contract.\n- Removed retry: 1 from the two attach-image kernel cases; they pass without it.\n\nMocked wire/SSE contract tests are untouched. Tests only, no product code.\n\n* make agent trace upload tests deterministic\n\nThe suite pumped a synthetic clock with advanceTimersUntil() and hoped real\nfs and promise work settled inside a 200-step budget, asserted schedule\ndelays through a global setTimeout spy whose fake clock had drifted, and\nremoved its temp dir while catch-up and cursor writers were still running.\nUnder a loaded CI shard that produced \"Timed out advancing fake timers\",\n\"expected 1000 to be 60000\" and \"ENOTEMPTY rmdir /tmp/agent-traces-test-*\".\n\nThe upload scheduler now reports the delay it arms and the outcome of each\ncycle, the upload reports every wait it arms before the next request, and\ninstallAgentTraceUpload returns a handle that resolves when the startup\ncatch-up and any in-flight upload have finished writing. Tests await those\nsignals and advance the fake clock by the exact reported delay, and teardown\nwaits for in-flight writers before removing the temp dir.\n\nThe ~15 retry, backoff and Retry-After variants collapse into one\ntable-driven it.each, per the MERGE verdict: 1569 -> 1141 lines, 44 -> 27\ntest blocks, with no lost coverage.\n\n* make the compiled artifact and installer probe tests deterministic\n\nThe compiled-artifact afterEach polled for supervisor exit with the same\n10s budget as vitest's hook timeout, so the poll could never report on the\nslower standalone runners. The teardown now escalates to SIGKILL and every\ninner deadline stays below the surrounding hook and test budgets.\n\nnative-probe-timeout decided pass/fail from wall-clock deadlines around a\nreal 10s installer probe. The installer probe deadline is now injectable\nthrough PRIME_AGENT_PROBE_TIMEOUT_SECONDS, the blocked probe records the\ninstall lock itself, and the spawn deadlines are gone.\n\n* fix daemon shutdown admission loss during slow scans\n\nshutdown --force holds a 5s admission lease refreshed by a 1s timer, but it\nblocks its own event loop in synchronous ps/lsof/ss scans. On a loaded runner a\nscan outlasts the lease, the elapsed record is treated as abandoned, and the\nholder's next assertOrRenew throws \"Daemon shutdown admission was lost\".\n\n- A late renew re-arms a record that is still ours; only a missing or foreign\n  record ends the admission.\n- A renew that could not read the registry no longer retires the lease.\n- isDaemonShutdownAdmissionActive is read-only, so a bystander probe cannot\n  delete a live holder's record.\n- stopHiddenSupervisors renews before the blocking scan.\n\nThe 4603 regression drops its 11s sleep for a post-shutdown listener assertion\nand uses mkdtemp for the child TMPDIR.\n\n* delete 148 dead test files\n\nRemoves test files judged CUT by a full 480-file audit: duplicates of a named survivor, mock-asserting tests, rendered-copy assertions, private-internals casts, and live-API matrices behind skipIf(!API_KEY) that never ran in CI.\n\n* merge interactive-mode and agents-view test suites\n\n* merge tui render, overlay and helper test suites\n\n* test: slim daemon-mode and agent-connection-daemon suites\n\ndaemon-mode: keep passive hydration/passivation, delete_subagent durability, agent-message concurrency and rate limits, attach-snapshot backpressure; drop per-race internal regressions already covered process-level by daemon-supervisor-process.\nagent-connection-daemon: keep reconnect, update-restart, chunked-snapshot assembly and disposal races; drop tautological daemon-protocol pass-through cases.\n\n* merge tui editor, markdown and autocomplete test suites\n\n* test: merge audited session-core test bloat\n\nExecute MERGE verdicts from the 480-file test audit for the agent-session\ncore suites: collapse near-identical blocks into it.each tables, drop\nmock-return/rendered-copy assertions and private-cast white-box cases,\nand fold one-off files into the owning suite.\n\nDeleted (folded into their owning suite):\n- agent-session-concurrent.test.ts, suite/agent-session-action-races.test.ts,\n  suite/agent-session-action-contracts.test.ts -> suite/agent-session-queue.test.ts\n- suite/agent-session-compaction-continuation.test.ts,\n  suite/agent-session-compact-skill.test.ts -> suite/agent-session-compaction.test.ts\n- agent-session-runtime-events.test.ts -> suite/agent-session-runtime.test.ts\n\nPreserved: process boundaries (daemon RPC, ACP), on-disk formats,\nconcurrency/ordering, crash/restart/resume and load coverage.\n\n* address review: octal probe timeout, truncated deadline, dead schedule field\n\n* test: merge redundant coding-agent test cases into case tables\n\nExecutes the MERGE verdicts from the 480-file test-bloat audit for the\nmisc lanes. Repeated near-identical blocks collapse into single it.each\ncase tables, and ticket-numbered one-off files fold into the owning\nmodule suite.\n\nRemoved throughout the touched files: assertions on mock return values,\nassertions on rendered text/copy, `as unknown as` casts into privates,\nand suites gated behind skipIf(!API_KEY) (which never ran in CI).\n\nPreserved: process boundaries (daemon RPC, ACP), on-disk formats,\nconcurrency and ordering, crash/restart/resume, and load.\n\nDeleted files, folded into their module suite:\n- compaction-extensions -> deleted outright (whole file behind skipIf(!API_KEY))\n- compaction-serialization -> compaction\n- heartbeat-catalog -> daemon-client\n- child-process -> exec\n- edit-tool-legacy-input -> tools\n- kernel-goal-skill, kernel-rlm-heartbeat-skill -> kernel-agent-message-skill\n- kernel-agent-observe-skill -> kernel-attach-image-skill\n- kernel-windows-process -> kernel-bootstrap-windows\n- extensions-input-event -> extensions-runner\n- sdk-skills -> sdk-session-manager\n- session-manager/{agent-status,has-user-content} -> session-manager/session-state\n- session-manager/migration -> session-manager/file-operations\n- session-manager/custom-session-id -> session-manager/tree-traversal\n\n* slim ai + regression tests (lanes A/B/D/E)\n\nExecute MERGE verdicts from the test audit for packages/ai and the\nupdate-restart / snapshot / session-view regression files.\n\n- fold ticket-numbered regression cases into the owning suites\n- collapse near-identical blocks into it.each tables\n- drop mock-return, rendered-copy and live-API-gated assertions\n\n* test: collapse package-manager tables and fold small daemon selector suites\n\npackage-manager: git-URL parsing, top-level/manifest/package glob filters and npm install-argv cases are now table-driven.\ndaemon-session-id: absorbs daemon-catalog-process selector case, drops display-id formatting trivia.\ndaemon-worker-windows-timeouts: absorbs the connection-deadline budget cases from daemon-worker-connect.\ndaemon-catalog-startup: drops the src-directory one-off.\n\n* test: collapse refinement, settings and config suites into case tables\n\nFinal misc lane of the test-bloat audit.\n\n- refinement: per-kind create/update/delete becomes one it.each lifecycle;\n  8 rejection suites become one 18-row invalid-edit table that also asserts\n  state and the refinement log stay untouched; truncation/parse errors,\n  scope permutations, ranking and the tokenizer each become one table.\n  System-prompt and user-prompt copy assertions removed.\n- settings-manager: per-setting default getters removed; unknown-key\n  preservation, invalid-file guards and project-vs-global precedence kept.\n- config: install-method detection becomes one table; session-dir env\n  permutations collapse into one precedence test.\n- builtin-skills, repl-kernel-abort, session-cwd, truncate: repeated blocks\n  collapsed; one ReplInternals reach-in dropped.\n- child-process folds into exec as one process lifecycle suite.\n\n* slim regression tests (lane C)\n\nFold the remaining ticket-numbered regression files into the owning\nmodule suites and collapse duplicate cases into it.each tables.\n\n- 19 regression files deleted after their kept cases moved into\n  agent-session-queue, auth-storage, acp-features, resource-loader,\n  agent-session-runtime/compaction/retry-events/recursion,\n  model-registry, slash-commands, daemon-supervisor-process\n- 3 files slimmed in place where the named target no longer exists\n- drop rendered-copy, mock-return and private-cast assertions\n\n* test: collapse daemon protocol, command, list, ps and package-command suites\n\ndaemon-protocol: two gating tables replace 16 near-identical capability/schema cases.\ndaemon-command: table-driven argv parsing plus the --goal leak guards; drops help/usage copy assertions.\ndaemon-session-list: activity, recap and model-fallback projections are table-driven.\ndaemon-ps: keeps planReap/planShutdownAll safety rules, drops ss/lsof parsers, sorting and uptime trivia.\ndaemon-stop-confirm: one busy-guard table, no prompt copy.\npackage-command-paths: one shared self-update fixture for the install-spec cases; drops help and removed-flag copy.\nacp-events: keeps only the cases the ACP suite does not cover end to end.\ndaemon-session-summarizer: one recap/status parse table.\ndaemon-extension-binding: keeps the duplicated-partial-message strip.\n\n* test: tighten the daemon stop-confirm busy-guard table\n\n* fix ci: biome forEach body, vacuous autocomplete case, missing prompt before second compaction\n\n* fix ci: restore escaped template literals in prompt-template cases\n\n* fix codeql: single-pass path escaping in test helpers\n\n* address review: flush debounced trace uploads, restore probe timeout guards, drop dead test scaffolding\n\n* respect retry-after and throttle window when flushing trace uploads\n\n* await in-flight trace uploads before a drain returns\n\n* extend deterministic test policy to python\n\n* harden deterministic test policy checks\n\n* close test policy edge cases\n\n* finish deterministic policy edge coverage\n\n* fix policy lexer and macos signature setup\n\n* mask regex literals in test policy checks\n\n* distinguish postfix division in policy lexer\n\n* close native migration signal race\n\n* keep native migration force timer owned\n\n---------\n\nCo-authored-by: prime-agent <agent@local>"},{"name":"github-copilot-oauth.test.ts","kind":"file","size":9511,"lastCommitHash":"cf07c5a3f5eca98e7744f2df83050044c920252a","lastCommitWhen":"2026-09-16T16:28:13-04:00","lastCommitMessage":"delete dead tests and fix the races the flaky ones were hiding (#2336)\n\n* add an objective testing policy to AGENTS.md\n\n* fix flaky daemon supervisor monitor test\n\nThe supervisor availability check is a real async chain (registry stat,\nsocket probe, replacement launch) started from a timer callback, so the\ntest drove a bounded fake-timer pump and asserted on a probe counter.\nUnder a loaded CI shard the chain did not finish inside the iteration\nbudget, and the variant mixing fake timers with a real probe promise\ncould deadlock for the full 30s test timeout.\n\nExpose a settled promise per armed availability check and await it in\nthe tests, so each assertion runs after the check finished instead of\nafter an arbitrary number of clock advances.\n\n* remove vitest retry masking from ai and attach-image tests\n\nDeleted all 548 `retry:` options in packages/ai/test and the 2 in\nkernel-attach-image-skill.test.ts. Retries hid non-determinism instead of\nfixing it, so a broken code path could still go green.\n\n- Deleted 17 live-only cross-provider E2E matrices whose every case sits behind\n  skipIf(!API_KEY) and never runs in CI; stream.test.ts stays as the survivor\n  that owns the provider table.\n- Stripped the retry option from the 198 stream.test.ts cases and dropped the\n  live E2E describe (plus its now-unused helpers) from\n  anthropic-thinking-disable.test.ts, keeping its mocked payload contract.\n- Removed retry: 1 from the two attach-image kernel cases; they pass without it.\n\nMocked wire/SSE contract tests are untouched. Tests only, no product code.\n\n* make agent trace upload tests deterministic\n\nThe suite pumped a synthetic clock with advanceTimersUntil() and hoped real\nfs and promise work settled inside a 200-step budget, asserted schedule\ndelays through a global setTimeout spy whose fake clock had drifted, and\nremoved its temp dir while catch-up and cursor writers were still running.\nUnder a loaded CI shard that produced \"Timed out advancing fake timers\",\n\"expected 1000 to be 60000\" and \"ENOTEMPTY rmdir /tmp/agent-traces-test-*\".\n\nThe upload scheduler now reports the delay it arms and the outcome of each\ncycle, the upload reports every wait it arms before the next request, and\ninstallAgentTraceUpload returns a handle that resolves when the startup\ncatch-up and any in-flight upload have finished writing. Tests await those\nsignals and advance the fake clock by the exact reported delay, and teardown\nwaits for in-flight writers before removing the temp dir.\n\nThe ~15 retry, backoff and Retry-After variants collapse into one\ntable-driven it.each, per the MERGE verdict: 1569 -> 1141 lines, 44 -> 27\ntest blocks, with no lost coverage.\n\n* make the compiled artifact and installer probe tests deterministic\n\nThe compiled-artifact afterEach polled for supervisor exit with the same\n10s budget as vitest's hook timeout, so the poll could never report on the\nslower standalone runners. The teardown now escalates to SIGKILL and every\ninner deadline stays below the surrounding hook and test budgets.\n\nnative-probe-timeout decided pass/fail from wall-clock deadlines around a\nreal 10s installer probe. The installer probe deadline is now injectable\nthrough PRIME_AGENT_PROBE_TIMEOUT_SECONDS, the blocked probe records the\ninstall lock itself, and the spawn deadlines are gone.\n\n* fix daemon shutdown admission loss during slow scans\n\nshutdown --force holds a 5s admission lease refreshed by a 1s timer, but it\nblocks its own event loop in synchronous ps/lsof/ss scans. On a loaded runner a\nscan outlasts the lease, the elapsed record is treated as abandoned, and the\nholder's next assertOrRenew throws \"Daemon shutdown admission was lost\".\n\n- A late renew re-arms a record that is still ours; only a missing or foreign\n  record ends the admission.\n- A renew that could not read the registry no longer retires the lease.\n- isDaemonShutdownAdmissionActive is read-only, so a bystander probe cannot\n  delete a live holder's record.\n- stopHiddenSupervisors renews before the blocking scan.\n\nThe 4603 regression drops its 11s sleep for a post-shutdown listener assertion\nand uses mkdtemp for the child TMPDIR.\n\n* delete 148 dead test files\n\nRemoves test files judged CUT by a full 480-file audit: duplicates of a named survivor, mock-asserting tests, rendered-copy assertions, private-internals casts, and live-API matrices behind skipIf(!API_KEY) that never ran in CI.\n\n* merge interactive-mode and agents-view test suites\n\n* merge tui render, overlay and helper test suites\n\n* test: slim daemon-mode and agent-connection-daemon suites\n\ndaemon-mode: keep passive hydration/passivation, delete_subagent durability, agent-message concurrency and rate limits, attach-snapshot backpressure; drop per-race internal regressions already covered process-level by daemon-supervisor-process.\nagent-connection-daemon: keep reconnect, update-restart, chunked-snapshot assembly and disposal races; drop tautological daemon-protocol pass-through cases.\n\n* merge tui editor, markdown and autocomplete test suites\n\n* test: merge audited session-core test bloat\n\nExecute MERGE verdicts from the 480-file test audit for the agent-session\ncore suites: collapse near-identical blocks into it.each tables, drop\nmock-return/rendered-copy assertions and private-cast white-box cases,\nand fold one-off files into the owning suite.\n\nDeleted (folded into their owning suite):\n- agent-session-concurrent.test.ts, suite/agent-session-action-races.test.ts,\n  suite/agent-session-action-contracts.test.ts -> suite/agent-session-queue.test.ts\n- suite/agent-session-compaction-continuation.test.ts,\n  suite/agent-session-compact-skill.test.ts -> suite/agent-session-compaction.test.ts\n- agent-session-runtime-events.test.ts -> suite/agent-session-runtime.test.ts\n\nPreserved: process boundaries (daemon RPC, ACP), on-disk formats,\nconcurrency/ordering, crash/restart/resume and load coverage.\n\n* address review: octal probe timeout, truncated deadline, dead schedule field\n\n* test: merge redundant coding-agent test cases into case tables\n\nExecutes the MERGE verdicts from the 480-file test-bloat audit for the\nmisc lanes. Repeated near-identical blocks collapse into single it.each\ncase tables, and ticket-numbered one-off files fold into the owning\nmodule suite.\n\nRemoved throughout the touched files: assertions on mock return values,\nassertions on rendered text/copy, `as unknown as` casts into privates,\nand suites gated behind skipIf(!API_KEY) (which never ran in CI).\n\nPreserved: process boundaries (daemon RPC, ACP), on-disk formats,\nconcurrency and ordering, crash/restart/resume, and load.\n\nDeleted files, folded into their module suite:\n- compaction-extensions -> deleted outright (whole file behind skipIf(!API_KEY))\n- compaction-serialization -> compaction\n- heartbeat-catalog -> daemon-client\n- child-process -> exec\n- edit-tool-legacy-input -> tools\n- kernel-goal-skill, kernel-rlm-heartbeat-skill -> kernel-agent-message-skill\n- kernel-agent-observe-skill -> kernel-attach-image-skill\n- kernel-windows-process -> kernel-bootstrap-windows\n- extensions-input-event -> extensions-runner\n- sdk-skills -> sdk-session-manager\n- session-manager/{agent-status,has-user-content} -> session-manager/session-state\n- session-manager/migration -> session-manager/file-operations\n- session-manager/custom-session-id -> session-manager/tree-traversal\n\n* slim ai + regression tests (lanes A/B/D/E)\n\nExecute MERGE verdicts from the test audit for packages/ai and the\nupdate-restart / snapshot / session-view regression files.\n\n- fold ticket-numbered regression cases into the owning suites\n- collapse near-identical blocks into it.each tables\n- drop mock-return, rendered-copy and live-API-gated assertions\n\n* test: collapse package-manager tables and fold small daemon selector suites\n\npackage-manager: git-URL parsing, top-level/manifest/package glob filters and npm install-argv cases are now table-driven.\ndaemon-session-id: absorbs daemon-catalog-process selector case, drops display-id formatting trivia.\ndaemon-worker-windows-timeouts: absorbs the connection-deadline budget cases from daemon-worker-connect.\ndaemon-catalog-startup: drops the src-directory one-off.\n\n* test: collapse refinement, settings and config suites into case tables\n\nFinal misc lane of the test-bloat audit.\n\n- refinement: per-kind create/update/delete becomes one it.each lifecycle;\n  8 rejection suites become one 18-row invalid-edit table that also asserts\n  state and the refinement log stay untouched; truncation/parse errors,\n  scope permutations, ranking and the tokenizer each become one table.\n  System-prompt and user-prompt copy assertions removed.\n- settings-manager: per-setting default getters removed; unknown-key\n  preservation, invalid-file guards and project-vs-global precedence kept.\n- config: install-method detection becomes one table; session-dir env\n  permutations collapse into one precedence test.\n- builtin-skills, repl-kernel-abort, session-cwd, truncate: repeated blocks\n  collapsed; one ReplInternals reach-in dropped.\n- child-process folds into exec as one process lifecycle suite.\n\n* slim regression tests (lane C)\n\nFold the remaining ticket-numbered regression files into the owning\nmodule suites and collapse duplicate cases into it.each tables.\n\n- 19 regression files deleted after their kept cases moved into\n  agent-session-queue, auth-storage, acp-features, resource-loader,\n  agent-session-runtime/compaction/retry-events/recursion,\n  model-registry, slash-commands, daemon-supervisor-process\n- 3 files slimmed in place where the named target no longer exists\n- drop rendered-copy, mock-return and private-cast assertions\n\n* test: collapse daemon protocol, command, list, ps and package-command suites\n\ndaemon-protocol: two gating tables replace 16 near-identical capability/schema cases.\ndaemon-command: table-driven argv parsing plus the --goal leak guards; drops help/usage copy assertions.\ndaemon-session-list: activity, recap and model-fallback projections are table-driven.\ndaemon-ps: keeps planReap/planShutdownAll safety rules, drops ss/lsof parsers, sorting and uptime trivia.\ndaemon-stop-confirm: one busy-guard table, no prompt copy.\npackage-command-paths: one shared self-update fixture for the install-spec cases; drops help and removed-flag copy.\nacp-events: keeps only the cases the ACP suite does not cover end to end.\ndaemon-session-summarizer: one recap/status parse table.\ndaemon-extension-binding: keeps the duplicated-partial-message strip.\n\n* test: tighten the daemon stop-confirm busy-guard table\n\n* fix ci: biome forEach body, vacuous autocomplete case, missing prompt before second compaction\n\n* fix ci: restore escaped template literals in prompt-template cases\n\n* fix codeql: single-pass path escaping in test helpers\n\n* address review: flush debounced trace uploads, restore probe timeout guards, drop dead test scaffolding\n\n* respect retry-after and throttle window when flushing trace uploads\n\n* await in-flight trace uploads before a drain returns\n\n* extend deterministic test policy to python\n\n* harden deterministic test policy checks\n\n* close test policy edge cases\n\n* finish deterministic policy edge coverage\n\n* fix policy lexer and macos signature setup\n\n* mask regex literals in test policy checks\n\n* distinguish postfix division in policy lexer\n\n* close native migration signal race\n\n* keep native migration force timer owned\n\n---------\n\nCo-authored-by: prime-agent <agent@local>"},{"name":"google-shared-convert-tools.test.ts","kind":"file","size":12466,"lastCommitHash":"cf07c5a3f5eca98e7744f2df83050044c920252a","lastCommitWhen":"2026-09-16T16:28:13-04:00","lastCommitMessage":"delete dead tests and fix the races the flaky ones were hiding (#2336)\n\n* add an objective testing policy to AGENTS.md\n\n* fix flaky daemon supervisor monitor test\n\nThe supervisor availability check is a real async chain (registry stat,\nsocket probe, replacement launch) started from a timer callback, so the\ntest drove a bounded fake-timer pump and asserted on a probe counter.\nUnder a loaded CI shard the chain did not finish inside the iteration\nbudget, and the variant mixing fake timers with a real probe promise\ncould deadlock for the full 30s test timeout.\n\nExpose a settled promise per armed availability check and await it in\nthe tests, so each assertion runs after the check finished instead of\nafter an arbitrary number of clock advances.\n\n* remove vitest retry masking from ai and attach-image tests\n\nDeleted all 548 `retry:` options in packages/ai/test and the 2 in\nkernel-attach-image-skill.test.ts. Retries hid non-determinism instead of\nfixing it, so a broken code path could still go green.\n\n- Deleted 17 live-only cross-provider E2E matrices whose every case sits behind\n  skipIf(!API_KEY) and never runs in CI; stream.test.ts stays as the survivor\n  that owns the provider table.\n- Stripped the retry option from the 198 stream.test.ts cases and dropped the\n  live E2E describe (plus its now-unused helpers) from\n  anthropic-thinking-disable.test.ts, keeping its mocked payload contract.\n- Removed retry: 1 from the two attach-image kernel cases; they pass without it.\n\nMocked wire/SSE contract tests are untouched. Tests only, no product code.\n\n* make agent trace upload tests deterministic\n\nThe suite pumped a synthetic clock with advanceTimersUntil() and hoped real\nfs and promise work settled inside a 200-step budget, asserted schedule\ndelays through a global setTimeout spy whose fake clock had drifted, and\nremoved its temp dir while catch-up and cursor writers were still running.\nUnder a loaded CI shard that produced \"Timed out advancing fake timers\",\n\"expected 1000 to be 60000\" and \"ENOTEMPTY rmdir /tmp/agent-traces-test-*\".\n\nThe upload scheduler now reports the delay it arms and the outcome of each\ncycle, the upload reports every wait it arms before the next request, and\ninstallAgentTraceUpload returns a handle that resolves when the startup\ncatch-up and any in-flight upload have finished writing. Tests await those\nsignals and advance the fake clock by the exact reported delay, and teardown\nwaits for in-flight writers before removing the temp dir.\n\nThe ~15 retry, backoff and Retry-After variants collapse into one\ntable-driven it.each, per the MERGE verdict: 1569 -> 1141 lines, 44 -> 27\ntest blocks, with no lost coverage.\n\n* make the compiled artifact and installer probe tests deterministic\n\nThe compiled-artifact afterEach polled for supervisor exit with the same\n10s budget as vitest's hook timeout, so the poll could never report on the\nslower standalone runners. The teardown now escalates to SIGKILL and every\ninner deadline stays below the surrounding hook and test budgets.\n\nnative-probe-timeout decided pass/fail from wall-clock deadlines around a\nreal 10s installer probe. The installer probe deadline is now injectable\nthrough PRIME_AGENT_PROBE_TIMEOUT_SECONDS, the blocked probe records the\ninstall lock itself, and the spawn deadlines are gone.\n\n* fix daemon shutdown admission loss during slow scans\n\nshutdown --force holds a 5s admission lease refreshed by a 1s timer, but it\nblocks its own event loop in synchronous ps/lsof/ss scans. On a loaded runner a\nscan outlasts the lease, the elapsed record is treated as abandoned, and the\nholder's next assertOrRenew throws \"Daemon shutdown admission was lost\".\n\n- A late renew re-arms a record that is still ours; only a missing or foreign\n  record ends the admission.\n- A renew that could not read the registry no longer retires the lease.\n- isDaemonShutdownAdmissionActive is read-only, so a bystander probe cannot\n  delete a live holder's record.\n- stopHiddenSupervisors renews before the blocking scan.\n\nThe 4603 regression drops its 11s sleep for a post-shutdown listener assertion\nand uses mkdtemp for the child TMPDIR.\n\n* delete 148 dead test files\n\nRemoves test files judged CUT by a full 480-file audit: duplicates of a named survivor, mock-asserting tests, rendered-copy assertions, private-internals casts, and live-API matrices behind skipIf(!API_KEY) that never ran in CI.\n\n* merge interactive-mode and agents-view test suites\n\n* merge tui render, overlay and helper test suites\n\n* test: slim daemon-mode and agent-connection-daemon suites\n\ndaemon-mode: keep passive hydration/passivation, delete_subagent durability, agent-message concurrency and rate limits, attach-snapshot backpressure; drop per-race internal regressions already covered process-level by daemon-supervisor-process.\nagent-connection-daemon: keep reconnect, update-restart, chunked-snapshot assembly and disposal races; drop tautological daemon-protocol pass-through cases.\n\n* merge tui editor, markdown and autocomplete test suites\n\n* test: merge audited session-core test bloat\n\nExecute MERGE verdicts from the 480-file test audit for the agent-session\ncore suites: collapse near-identical blocks into it.each tables, drop\nmock-return/rendered-copy assertions and private-cast white-box cases,\nand fold one-off files into the owning suite.\n\nDeleted (folded into their owning suite):\n- agent-session-concurrent.test.ts, suite/agent-session-action-races.test.ts,\n  suite/agent-session-action-contracts.test.ts -> suite/agent-session-queue.test.ts\n- suite/agent-session-compaction-continuation.test.ts,\n  suite/agent-session-compact-skill.test.ts -> suite/agent-session-compaction.test.ts\n- agent-session-runtime-events.test.ts -> suite/agent-session-runtime.test.ts\n\nPreserved: process boundaries (daemon RPC, ACP), on-disk formats,\nconcurrency/ordering, crash/restart/resume and load coverage.\n\n* address review: octal probe timeout, truncated deadline, dead schedule field\n\n* test: merge redundant coding-agent test cases into case tables\n\nExecutes the MERGE verdicts from the 480-file test-bloat audit for the\nmisc lanes. Repeated near-identical blocks collapse into single it.each\ncase tables, and ticket-numbered one-off files fold into the owning\nmodule suite.\n\nRemoved throughout the touched files: assertions on mock return values,\nassertions on rendered text/copy, `as unknown as` casts into privates,\nand suites gated behind skipIf(!API_KEY) (which never ran in CI).\n\nPreserved: process boundaries (daemon RPC, ACP), on-disk formats,\nconcurrency and ordering, crash/restart/resume, and load.\n\nDeleted files, folded into their module suite:\n- compaction-extensions -> deleted outright (whole file behind skipIf(!API_KEY))\n- compaction-serialization -> compaction\n- heartbeat-catalog -> daemon-client\n- child-process -> exec\n- edit-tool-legacy-input -> tools\n- kernel-goal-skill, kernel-rlm-heartbeat-skill -> kernel-agent-message-skill\n- kernel-agent-observe-skill -> kernel-attach-image-skill\n- kernel-windows-process -> kernel-bootstrap-windows\n- extensions-input-event -> extensions-runner\n- sdk-skills -> sdk-session-manager\n- session-manager/{agent-status,has-user-content} -> session-manager/session-state\n- session-manager/migration -> session-manager/file-operations\n- session-manager/custom-session-id -> session-manager/tree-traversal\n\n* slim ai + regression tests (lanes A/B/D/E)\n\nExecute MERGE verdicts from the test audit for packages/ai and the\nupdate-restart / snapshot / session-view regression files.\n\n- fold ticket-numbered regression cases into the owning suites\n- collapse near-identical blocks into it.each tables\n- drop mock-return, rendered-copy and live-API-gated assertions\n\n* test: collapse package-manager tables and fold small daemon selector suites\n\npackage-manager: git-URL parsing, top-level/manifest/package glob filters and npm install-argv cases are now table-driven.\ndaemon-session-id: absorbs daemon-catalog-process selector case, drops display-id formatting trivia.\ndaemon-worker-windows-timeouts: absorbs the connection-deadline budget cases from daemon-worker-connect.\ndaemon-catalog-startup: drops the src-directory one-off.\n\n* test: collapse refinement, settings and config suites into case tables\n\nFinal misc lane of the test-bloat audit.\n\n- refinement: per-kind create/update/delete becomes one it.each lifecycle;\n  8 rejection suites become one 18-row invalid-edit table that also asserts\n  state and the refinement log stay untouched; truncation/parse errors,\n  scope permutations, ranking and the tokenizer each become one table.\n  System-prompt and user-prompt copy assertions removed.\n- settings-manager: per-setting default getters removed; unknown-key\n  preservation, invalid-file guards and project-vs-global precedence kept.\n- config: install-method detection becomes one table; session-dir env\n  permutations collapse into one precedence test.\n- builtin-skills, repl-kernel-abort, session-cwd, truncate: repeated blocks\n  collapsed; one ReplInternals reach-in dropped.\n- child-process folds into exec as one process lifecycle suite.\n\n* slim regression tests (lane C)\n\nFold the remaining ticket-numbered regression files into the owning\nmodule suites and collapse duplicate cases into it.each tables.\n\n- 19 regression files deleted after their kept cases moved into\n  agent-session-queue, auth-storage, acp-features, resource-loader,\n  agent-session-runtime/compaction/retry-events/recursion,\n  model-registry, slash-commands, daemon-supervisor-process\n- 3 files slimmed in place where the named target no longer exists\n- drop rendered-copy, mock-return and private-cast assertions\n\n* test: collapse daemon protocol, command, list, ps and package-command suites\n\ndaemon-protocol: two gating tables replace 16 near-identical capability/schema cases.\ndaemon-command: table-driven argv parsing plus the --goal leak guards; drops help/usage copy assertions.\ndaemon-session-list: activity, recap and model-fallback projections are table-driven.\ndaemon-ps: keeps planReap/planShutdownAll safety rules, drops ss/lsof parsers, sorting and uptime trivia.\ndaemon-stop-confirm: one busy-guard table, no prompt copy.\npackage-command-paths: one shared self-update fixture for the install-spec cases; drops help and removed-flag copy.\nacp-events: keeps only the cases the ACP suite does not cover end to end.\ndaemon-session-summarizer: one recap/status parse table.\ndaemon-extension-binding: keeps the duplicated-partial-message strip.\n\n* test: tighten the daemon stop-confirm busy-guard table\n\n* fix ci: biome forEach body, vacuous autocomplete case, missing prompt before second compaction\n\n* fix ci: restore escaped template literals in prompt-template cases\n\n* fix codeql: single-pass path escaping in test helpers\n\n* address review: flush debounced trace uploads, restore probe timeout guards, drop dead test scaffolding\n\n* respect retry-after and throttle window when flushing trace uploads\n\n* await in-flight trace uploads before a drain returns\n\n* extend deterministic test policy to python\n\n* harden deterministic test policy checks\n\n* close test policy edge cases\n\n* finish deterministic policy edge coverage\n\n* fix policy lexer and macos signature setup\n\n* mask regex literals in test policy checks\n\n* distinguish postfix division in policy lexer\n\n* close native migration signal race\n\n* keep native migration force timer owned\n\n---------\n\nCo-authored-by: prime-agent <agent@local>"},{"name":"google-vertex-api-key-resolution.test.ts","kind":"file","size":6407,"lastCommitHash":"65a6472bdd372d3cce51c99830a33f778f0127c7","lastCommitWhen":"2026-04-24T00:05:43+02:00","lastCommitMessage":"fix(ai): forward google vertex base url\n\ncloses #3619\n"},{"name":"kimi-test-model.ts","kind":"file","size":797,"lastCommitHash":"8454794b4878895ec85d60c41b57febcf938ee65","lastCommitWhen":"2026-07-17T09:46:43-07:00","lastCommitMessage":"test(ai): follow live Kimi coding catalog (#465)"},{"name":"lazy-module-load.test.ts","kind":"file","size":3055,"lastCommitHash":"3e7ffff184e805930e23c7440fa9571407a485ee","lastCommitWhen":"2026-04-25T16:57:03+02:00","lastCommitMessage":"fix(ai): ignore unknown anthropic sse events\n\ncloses #3708\n"},{"name":"log.test.ts","kind":"file","size":2339,"lastCommitHash":"189bb1466836a474ba98a25a0c3b43751f08fd43","lastCommitWhen":"2026-07-02T13:00:08-07:00","lastCommitMessage":"make provider failures diagnosable from logs (#313)\n\n* add structured logging and provider stream-failure classification\n\n* address review: reserved log keys, sink fallback, body request_id\n\n* address review: never auto-retry structured auth/invalid_request failures\n\n* address review: log serialization must survive circular refs and bigints\n\n* show users a concise classified error, keep the raw cause in the log"},{"name":"mcp-catalog.test.ts","kind":"file","size":62768,"lastCommitHash":"b6ac5d014d99401b55820835a4966584271e9a3c","lastCommitWhen":"2026-09-16T16:20:18-07:00","lastCommitMessage":"mcp service catalog and oauth engine (#2330)\n\n* add a shared service catalog and generic mcp connections (#2256)\n\n* style(coding-agent): apply biome formatting to daemon-mode.ts\n\n* feat(coding-agent): add /plugins service catalog with verified MCP connections (ENG-6108)\n\n- Add /plugins and bare /mcp as the same searchable external-service picker with\n  honest states (Connect, Connected with verified tool counts, Reconnect,\n  Verifying, Requires setup, Disabled) and connect/disconnect actions\n- Add mcp.list_plugins, mcp.search_plugins, and mcp.list_connections host\n  requests with strict status filters, bounded limits, and honest nextCursor\n- Add local connection records (connectionId distinct from catalog serviceId);\n  verify every login with a real MCP handshake so token presence alone is\n  pending, never Connected; rejected credentials recover via Reconnect\n- Serve connected catalog services (Linear, Notion) through the generic mcp\n  runtime route: system-prompt inventory and mcp.config, no per-service wrappers\n- Drop the McpIntegration import from the kernel ready check ahead of the\n  Linear/Notion wrapper-package removal\n- mcp.connect is registered only behind an explicit UI-approved callback and\n  stays unregistered in daemon-hosted sessions (honest \"no handler\")\n\nTests: mcp-service-catalog, mcp-manager handlers, service-catalog-picker, and\nthe eng-6108 activation regression covering login -> verify -> session reload ->\nprompt inventory in the real services path without a restart.\n\n* fix(coding-agent): harden MCP verification, activation, and connection records (ENG-6108)\n\nReview follow-ups on the /plugins service catalog slice:\n\n- Verification now runs through the official @modelcontextprotocol/sdk\n  client (negotiated protocol version header, CRLF SSE support, explicit\n  session termination via HTTP DELETE) instead of a handwritten transport\n- Failures persist as fixed safe categories only; endpoint URLs,\n  server-controlled text, and tokens never reach records or messages\n- Connection records use the auth.json file-lock read-modify-write pattern\n  with unique temp files; concurrent UI/daemon writers no longer lose\n  records, and pending operations queue while a flush is in flight\n- Every verification result is bound to the exact grant it verified\n  (credential hash); stale probes after logout or token rotation are\n  discarded, never marking a newer or removed account Connected\n- An OAuth connection without a usable token is never probed anonymously\n- A login made while streaming or compacting queues automatic activation\n  at the next safe boundary (agent end / compaction end); the UI never\n  instructs the user to run /reload for MCP changes\n- /plugins and config-menu connect paths share the queue; failure categories\n  render as fixed user-readable wording\n- metadata-reviewed / legacyBuiltin rename absorbed from the catalog lane\n\nTests: probe (SDK fake server incl. CRLF/401/timeout/secret-leak), store\n(two-writer races, guard discard, mid-flight queueing), service catalog\n(stale verify after logout/rotation, non-connectable transports), manager,\nactivation queue (streaming/compaction/tool boundaries), regression suite.\n\n* fix(coding-agent): bind MCP credentials to endpoints, reconcile providers, honest connect (ENG-6108)\n\n- Endpoint binding everywhere a stored grant is consulted: catalog services and\n  user-declared servers require cred.endpoint === current URL before any token\n  fetch or probe (views, verify, dispatch inventory, demand-driven listing);\n  unbound legacy grants surface as Reconnect with the fixed credential-unbound\n  category and are recorded once on demand-driven verification\n- Provider ownership is one atomic reconciliation: legacy built-ins, eligible\n  catalog services, and user-declared OAuth servers are re-registered first and\n  only previously-owned ids unregister; the ModelRegistry reset hook calls the\n  full reconciliation, so catalog providers survive refresh and a removed user\n  override restores the catalog provider after a single manager.refresh()\n- Flush-time verification guards re-read fresh credential-source state\n  (authStorage.reload() under the backend lock), so probes that finish after\n  another client logged out or rotated the grant are discarded — no stale\n  Connected record survives across clients\n- mcp.connect (explicit-approver seam) verifies the real handshake before\n  reporting connected (tool count included) and reports fixed failure\n  categories on rejected handshakes\n- /plugins stdio user servers get a real management action: Enter disables the\n  server in global settings, refreshes providers, and reloads; already-disabled\n  and vanished entries report honest status\n- Catalog views keep the Reconnect action on error rows and add unverified/\n  unbound view tests; all oauth test fixtures now carry bound endpoints\n\nMinimal type-only addition in connection-probe.ts (lifecycle lane owns the file):\nMCP_PROBE_ERRORS.UNBOUND_CREDENTIAL.\n\nTests: manager 29, service-catalog 23, activation-queue 8 (incl. stdio\nmanagement), probe 7, store 6, picker 4, regression 2, slash-commands 18 —\n97/97; reviewer's mcp-service-safety suite verified 12/12 green against this\ntree (their file, their branch).\n\n* feat(ai): merged MCP service catalog with deterministic importer (ENG-6108)\n\n* feat(ai): metadata-reviewed catalog status, legacy builtins, local JSON sources, literal endpoint checks (ENG-6108)\n\n* fix(ai): harden local catalog loader and endpoint checks (ENG-6108)\n\n* feat(coding-agent): shared catalog resolver, local sources, per-account connections (ENG-6108)\n\n- resolveMcpServiceCatalog merges the built-in SERVICE_CATALOG with\n  settings-declared local sources (Settings.mcpCatalogSources): ~-expanded\n  before loadLocalServiceCatalog (which does no expansion), declared-but-missing\n  files and cross-source duplicate ids surface as visible diagnostics, first\n  source wins, total capped at 500 entries\n- The SAME resolution feeds the /plugins UI and the mcp host handlers; the UI\n  re-reads connection records from disk before rendering (no stale cache) and\n  shows resolver diagnostics on open\n- One-click Connect is metadata-reviewed-only (plus user-placed local files,\n  which still go through the login dialog's explicit approval); unreviewed\n  imported entries stay candidates with an honest setup hint\n- Per-account connections: \"Add another account\" allocates a distinct\n  connectionId (mcp:<serviceId>-N) with its own credential key, record, and\n  OAuth provider; the account picker lists accounts with per-account\n  Reconnect/Disconnect; alias ids join integrations, dispatch inventory,\n  mcp.config, and demand-driven verification through the same machinery; the\n  record's serviceId keeps the parent catalog id\n- test/mcp-service-catalog.test.ts settles the theme's cli-highlight preload\n  in beforeAll (deterministic fix for the pre-existing initTheme fire-and-forget\n  teardown race, evidence in ENG-6108 notes); ServiceCatalogPickerComponent\n  gains title/subtitle/hideSearch options for the account listing\n\nCatalog commits f8a4cf61a -> 50b79c3af -> be7445c3c integrated via authorized\nlocal cherry-picks; no catalog-source files modified.\n\nTests: manager 31 (alias integrations/provider lifecycle, demand-driven unbound\nrecord, reconciliation), service-catalog 29 (resolver, candidates, allocator),\nactivation-queue 9 (stdio management, add-account), probe 7, store 6, picker 4,\nregression 2, slash-commands 18 — 105/105; npm run check EXIT=0; 10/10\nconsecutive scoped runs with zero unhandled rejections, exit 0 each.\n\n* mcp: generic discovery surface, drop linear/notion wrappers (ENG-6108)\n\nAdd a bounded discovery surface to the kernel MCP module:\nlist_plugins, search_plugins, list_connections, search_tools and\ndescribe_tool, backed by host-owned catalog/connection handlers,\nwith cursor-safe tools/list pagination, explicit search scopes and\ndefensive secret scrubbing of inventory metadata only.\n\nReplace the bespoke Linear/Notion Python wrapper packages with one\ngeneric bundled mcp skill; remove the McpIntegration base class after\nauditing consumers, moving its shared helpers into rlm.mcp. Connecting\na service is a user action (/plugins or /mcp login), never an install\nor a per-service Python module.\n\n* mcp: fail-closed tool discovery, isolated schemas, redacted inventory errors (ENG-6108)\n\nFollow-up to 6514cbe6f per review:\n\n- discover() now publishes a tool map only when tools/list pagination\n  completes; a repeated or malformed continuation cursor, or exceeding\n  the page cap, raises McpDiscoveryError instead of a silent partial\n  inventory. Malformed cursors are rejected rather than read as done.\n- list_tools/describe_tool return deep copies, so caller mutations can\n  never reach the cached canonical schemas.\n- Per-connection search failures report a fixed exception type + hint\n  (McpCredentialsUnavailable and friends) instead of raw exception text;\n  host_request error text echoed by inventory calls is scrubbed of\n  credential-bearing URLs, query strings and auth headers and bounded.\n\n* mcp: never chain raw host errors in inventory wrappers (ENG-6108)\n\nFollow-up to ff738187e per review. _host_inventory raises a fixed\n\"MCP <request-type> request failed/timed out\" wrapper outside the\nexception handler, so arbitrary host/bridge error text (which can\nembed credential-bearing URLs, query strings, headers and HTTP\nbodies) is never echoed and cannot be reached through __cause__ or\n__context__ either; format_exception prints stay secret-free. The\nnow-unused redaction regex helper and bound constant are removed.\n\nRegression uses traceback.format_exception, not only str(exc), to\nassert the original exception is fully absent. Skill updated for the\nhost status vocabulary (pending, verified handshake) and PluginView\nfields (setupHint, unverified, verifiedAt/toolCount, connectionIds).\n\n* fix(coding-agent): bound MCP probe lifetime and connection-store races (ENG-6108)\n\nRoot review fixes on the lifecycle lane:\n\n- probeMcpEndpoint: the SDK passes its own controller's signal to every\n  fetch (including the cleanup DELETE and its body cancel), and the SDK\n  request timeouts only race the JSON-RPC promise, so an unresponsive\n  DELETE could hang the probe forever. One lifecycle AbortController now\n  bounds the probe: a fetch wrapper merges its signal into every\n  transport fetch, terminateSession/close are each raced against a\n  cleanup grace deadline whose expiry aborts the signal, an absolute\n  deadline timer plus a final abort end lingering body reads, and every\n  timer is cleared. Failure categories stay fixed and safe.\n- McpConnectionStore: the pre-lock exists-then-write-empty create could\n  rename an empty file over records another process just wrote; the file\n  is now created exclusively (wx, never truncating) before the canonical\n  realpath lock, with mode 0600. A failed atomic write no longer drops\n  queued mutations: the batch is unshifted back to the front of the\n  queue and retried by the next flush (ops are idempotent; verify\n  guards re-evaluate under the lock).\n- MCP_PROBE_ERRORS gains UNBOUND_CREDENTIAL (\"credential-unbound\") for\n  grants not bound to the endpoint, consumed by the service catalog.\n\nOffline regressions: never-returning cleanup DELETE, hanging response\nbody, exclusive first-create race with mode 0600, injected atomic-write\nfailure with in-order retry and stale-guard discard, plus the existing\nsuites. All fetch stubs; no live credentials or provider calls.\n\n* test(coding-agent): multi-PID first-create regression for MCP connection store (ENG-6108)\n\nRoot review follow-up: in-process instances cannot reproduce the\nfirst-create exists/write race because their pre-await work is\nserialized on one event loop. The store test file now also spawns four\nreal first-writer processes (temporary .mts worker imported through the\nproject tsx loader, no production entry point), aligned by ready\nmarkers + a file barrier, racing the first create and the locked flush\non the shared store path. Asserts distinct PIDs, all children exit\ncleanly, every record survives, and the file keeps mode 0600; children\nare terminated in a finally on every path.\n\nTest-only: no production files touched.\n\n* test(coding-agent): Windows-portable multi-PID store regression (ENG-6108)\n\nTest-only portability follow-up: the generated first-create worker\nimported the store module by resolved absolute OS path, which is not a\nvalid ESM specifier on Windows; it now imports by file URL, and the\nexact 0600 mode assertions are POSIX-only (Windows mode bits do not\nmap meaningfully). No production changes.\n\n* test(coding-agent): add service-safety adversarial regressions for MCP credentials and providers (ENG-6108)\n\nAdversarial regression suite for the ENG-6108 service-catalog safety\ncontract, red on the 4bd8abc12 baseline and green on the wave-2 fixes:\n\n- Credential binding before probe/token access: a stored credential bound\n  to a different endpoint, or unbound, is rejected before any probe call\n  and before authStorage.getApiKey - for user-declared servers and\n  catalog services, through direct verifyConnection and the demand-driven\n  mcp.list_plugins background verification; never a connected record.\n- Cross-client stale probes: two AuthStorage instances share one\n  auth.json; a probe finishing after a second client logs the grant out\n  or replaces it mid-flight must not persist a connected record or\n  verifiedAt for the current grant.\n- OAuth provider lifecycle: a full OAuth registry reset (through the\n  real createAgentSessionServices + modelRegistry.refresh seam)\n  preserves non-bundled catalog providers, and removing a user override\n  restores the catalog provider after one refresh.\n\nOffline-only: injected probes, denied fetch, per-test temp credential\nand connection stores, no live endpoints or real credentials.\n\n* fix(coding-agent): durable account reservations, per-account views, honest actions (ENG-6108)\n\nFinal-review wave 4:\n\n- Account allocation is a durable reservation under the connection-store file\n  lock: reserveConnectionId applies atomically on disk (exactly one winner in\n  a cross-process race; the loser allocates the next id), pending markers are\n  visible to every client, and removeReservation is ownership-validated (id +\n  still-pending + same createdAt) so a late callback never removes or resurrects\n  another client's account. Allocation consults store records, credentials,\n  configured user servers, and catalog ids; configured names are never taken.\n- Views aggregate every account of a service: connectionIds lists all accounts,\n  each account's status reflects its own bound credential, the service card\n  survives on a remaining account after the default disconnects, and the\n  inventory emits one row per account (no phantom primary row). Alias account\n  ids are searchable (search_plugins alias contract). Connections whose local\n  catalog source vanished keep a pinned descriptor at the recorded endpoint —\n  credentials are never retargeted.\n- Explicit state actions: pending accounts retry verification without a\n  relogin (the \"retry from /plugins\" path works), error accounts keep\n  Reconnect (catalog and user rows), each account gets an explicit Remove\n  row, and a verification result that could not be saved reports pending —\n  never a false Connected.\n- resolveMcpServiceCatalog isolates local-source failures per source: one\n  unreadable or invalid file becomes a bounded visible diagnostic while the\n  built-in catalog and every other source keep resolving.\n\nTests: two-client simultaneous reservation race with barrier, ownership\nvalidation, full add-second -> reload -> inventory -> disconnect-default ->\nsecond-still-manageable regression, per-account view aggregation, vanished-\nsource pinning, per-source failure isolation, state-based action tests, and\nallocation that skips configured ids.\n\nOwnership: bootstrap.ts untouched (delegated lane).\n\n* fix(coding-agent): require MCP discovery methods in the kernel ready check (ENG-6108)\n\nThe runtime ready check only asserted mcp.list_tools/mcp.call_tool; the\nfive new discovery methods were validated once by the bootstrap import\nscan, so a cached kernel venv with an old prime-agent-runtime could\npass readiness. The check now requires callables for list_plugins,\nsearch_plugins, list_connections, search_tools and describe_tool, and\nfails with an actionable message so the venv is rebuilt instead of\nsilently reused.\n\nRUNTIME_READY_CHECK is exported so the new regression executes the\nexact shipped check against a real project runtime: it accepts the\ncurrent runtime, and rejects a runtime simulated as old by deleting\neach discovery method in-process (not a text-grep test). No provider\ncalls, credentials, or real daemon involved.\n\n* fix(coding-agent): guarded account credential commits and computed account status (ENG-6108)\n\nFinal-review wave 5:\n\n- Reservations resolve only after the durable record write COMMITS: the\n  store defers reserve/remove/finalize callbacks past writeFileAtomicSync,\n  resolves them false on write failure, and drops the one-shot ops instead\n  of requeueing them — a failed write can never produce a ghost reservation\n  a login could start on (injected-write-failure regression: no marker, no\n  requeue surprise, retry works)\n- Ownership is an opaque random attempt nonce (not createdAt): cancel and\n  the NEW successful-commit guard both validate it under the same store\n  lock. Add-account logins stage the OAuth credential under\n  mcp:<id>--<attempt> and move it to the real account key only inside a\n  guarded finalizeAttempt commit — a late login success after remove or\n  replacement discards the staged credential and never touches the\n  account (regressions: late-success-after-remove and same-id-new-owner,\n  both assert the final credentials)\n- Per-account status is one computed helper (accountStateFor): credential\n  binding, expiry, and the record combine through httpConnectionStatus, and\n  the plugin aggregate, connection inventory, and account picker all use\n  it — previously-connected records with unbound, retargeted, or\n  expired-no-refresh credentials report Reconnect everywhere (6\n  regressions across default and alias accounts)\n- Catalog metadata aliases ride the view DTO and are searchable again\n  (regression: an alias absent from label/id/description matches)\n- Vanished-source pins are their own trust path (never localSource trust;\n  never one-click connectable)\n\nTests: 147/147 across 10 files; npm run check EXIT=0; 10/10 consecutive\nscoped runs with zero unhandled rejections, exit 0 each.\n\n* fix(coding-agent): exactly-once account transactions and locked disconnects (ENG-6108)\n\nFinal-review wave 6 (transaction issues):\n\n- Every one-shot store callback (reserve/removeReservation/finalizeAttempt/\n  removeAccount) settles EXACTLY once: deferred callbacks resolve with the\n  commit outcome (not `didCommit && resolve(true)`), losing and throwing\n  branches resolve false inline, one-shot ops are dropped on write failure,\n  and trailing ops in a failed batch can never hang — batched-two-reserves\n  write-failure regression included\n- Account removal runs credential deletion AND record removal under the SAME\n  store lock (new store.removeAccount; disconnect, remove-action, and\n  /mcp logout all use it): a concurrent finalize can never re-add an orphan\n  credential after a disconnect — interleaving regression on real stores\n  covers both orders (remove-then-finalize loses ownership; finalize-then-\n  remove clears record AND credential)\n- finalizeAttempt compensates: if the RECORD write fails after the credential\n  move, the compensate callback runs under the same lock and restores the\n  staged credential (the real key was empty before the attempt), so a failed\n  finalize is all-or-nothing; the flow then releases the reservation and\n  reports honestly — UI regression asserts the real key untouched, staged\n  restored+discarded, reservation released, and the honest message\n\nTests: 151/151 across 10 files; npm run check EXIT=0; 10/10 consecutive\nscoped runs with zero unhandled rejections, exit 0 each.\n\n* fix: honest MCP account recovery edges (ENG-6108)\n\n- removeAccount logs a credential-only integration out even when no\n  connection record exists; outcomes are typed (removed, credential-only,\n  missing, failed) and every UI route maps them honestly.\n- finalizeAttempt registers its rollback BEFORE any side effect: a\n  throwing or partial commit is compensated under the same lock, and a\n  FAILED rollback surfaces an explicit recovery-required state with the\n  credential retained instead of a silent false.\n- the guarded commit refuses to clobber a credential an ordinary login\n  wrote at the account key mid-flight, and the rollback only ever undoes\n  its own write; a bystander credential survives byte-for-byte.\n- one-shot store operations settle cleanly when the file lock itself\n  cannot be acquired; durable operations requeue (pre-splice).\n\n* fix: atomic MCP credential moves and honest partial logouts (ENG-6108)\n\n- staged logins move their credential to the account key with a new\n  disk-authoritative compare-and-set under the auth backend's own file\n  lock: moveStagedCredential (set-if-absent, returns the exact moved\n  credential), restoreCredentialIfAbsent, and removeIfCredentialMatches\n  (exact full-object own check, not access-token equality). A bystander\n  credential written by another process can no longer be clobbered by a\n  get/set race across AuthStorage instances.\n- the finalize compensation restores ours only into an empty staged slot\n  and deletes only its own exact credential from the account key.\n- removeAccount now reports \"logged-out\" when the credential logout\n  committed but the record save failed: the logout is preserved, the UI\n  wording says so and never claims the account is still connected; plain\n  \"failed\" wording is state-neutral.\n- two-real-storage-instance regressions: a bystander login written after\n  staging survives byte-for-byte; a generic /logout in another client\n  before/after the finalize races atomically (last-writer-wins under the\n  backend lock, record shows an honest unbound state); an injected\n  record-write failure after the logout reports the honest partial state.\n\n* fix: disk-verified MCP logouts and logout-cancelled login attempts (ENG-6108)\n\n- the three removeAccount authCleanup paths now use removeVerified\n  (extended to return whether a credential was actually removed from\n  disk): a failed auth-file write can no longer report Removed/\n  Disconnected while the credential persists; the honest \"failed\"\n  wording is state-neutral.\n- a real generic /logout of an MCP account now cancels that account's\n  pending login attempts: runLogout calls the new\n  ProviderAuthFlowsHost.onMcpCredentialRemoved hook, and the host\n  invalidates the pending reservation under the connection store's lock\n  (new invalidatePendingAttempts), so a stale in-flight OAuth attempt\n  resolves denied and can never re-activate the logged-out account.\n  Non-MCP logouts are unchanged.\n- regressions: auth-file write failure with a fresh disk reader (the\n  credential survives, nothing claims success), a route-exact\n  cross-client pending-finalize vs real /logout test driven through the\n  selector, store-level invalidation semantics, and stale\n  interactive-mode-status fixtures repaired to the current seams.\n\n* fix: one shared store-locked MCP logout op for the generic /logout route (ENG-6108)\n\n- the route delegates the ENTIRE MCP logout before touching auth: the new\n  exported logoutMcpAccount(providerId, store, authStorage) performs\n  verified credential deletion (removeVerified) AND pending-attempt\n  cancellation in one store-locked removeAccount with the new\n  preserveCompletedRecord semantics (pending attempts cancelled,\n  completed records kept for the honest unbound/Reconnect state).\n- removeAccount now runs the verified cleanup BEFORE mutating the\n  working records map: a failed auth-file write resolves \"failed\" with\n  the record intact in memory AND on disk (no half-applied deletion),\n  and a partially-saved logout still reports the honest \"logged-out\"\n  state.\n- the id resolution is exported as resolveMcpAccountLogoutTarget:\n  exact ids win (service ids may contain \"--\"), and staged keys map\n  back only through their actually recorded attempt nonce.\n- regressions: a barrier test fires the REAL generic route inside the\n  finalize's locked commit (verified deterministically red against the\n  old logout-first ordering); store-level half-applied-deletion and\n  preserve-semantics tests; route delegation/wording tests; handler\n  tests for double-hyphen ids, staged-key mapping, and preservation.\n\n* fix: fail-closed refusal for stale staged-key MCP logouts (ENG-6108)\n\n- a staged-key logout that races a completing finalize now refuses\n  fail-closed instead of orphaning the moved credential: the shared\n  handler resolves the account from CURRENT records and CURRENT on-disk\n  auth state under the store lock (never a pre-lock cache snapshot), and\n  when the staged credential already moved onto the account key it\n  returns \"refused\" — the record and the newer credential both survive,\n  and the route reports the completed login explicitly instead of\n  claiming Logged out.\n- new removeAccountForProvider store op (one critical section: resolve\n  under lock -> disk-verified refusal checks -> verified cleanup ->\n  cancel pending / preserve completed); resolveMcpAccountLogoutTarget\n  now returns a stale variant for nonce-matched non-pending records.\n- new disk-authoritative AuthStorage.hasVerified existence check used\n  for the current-state refusal decisions.\n- regressions: the staged-key race queued behind a finalize-first move\n  (refused, record + credential survive), resolver stale semantics, and\n  the route-level refused wording.\n\n* fix: staged-key MCP logouts cancel the attempt and preserve the account shell (ENG-6108)\n\n- removeAccountForProvider no longer gates record deletion on an auth\n  existence snapshot (not atomic with another client's ordinary login):\n  a staged-key logout removes only the staged credential, INVALIDATES the\n  attempt nonce on the pending record (so the in-flight login's denied\n  path can neither finalize nor removeReservation-delete it), and\n  PRESERVES the account record — deletion stays the explicit Remove\n  action's job; a bystander credential on the real key can never be\n  orphaned.\n- the \"refused\" outcome is now state-neutral (\"This login attempt is no\n  longer current; manage the account from /plugins\") — no Logged out or\n  Connected claim from token presence; failed verified auth deletion\n  still changes no record.\n- the interim AuthStorage.hasVerified helper is removed (no auth-state\n  snapshot decisions remain); regressions pin the both-exist contract\n  (staged removed, bystander byte-for-byte, record + nonce-invalidated\n  shell preserved, old-nonce finalize denied, removeReservation no-op)\n  and the finalize-first race with the same invariants.\n\n* feat: one guarded connect operation for every MCP OAuth login route (ENG-6108)\n\n- new one-shot store ops claimConnectionId/releaseClaim: a guarded login\n  claims an EXISTING account record (any status) under the store lock and\n  cancel releases it — the record, its status, and any credential survive\n  untouched; finalizeAttempt ownership is now the EXPLICIT nonce on any\n  record status.\n- every user-facing MCP OAuth login (initial connect, error-state\n  reconnect, add account, /mcp login, generic /login service options,\n  config menu) routes through the guarded flow: claim/reserve, staged\n  OAuth, guarded finalize. The raw dialog remains internal.\n- the finalize commit is a full-identity compare-and-swap on the auth\n  backend lock: set-if-absent for fresh accounts, replace-only-if-matching\n  for intentional replacements (reconnects and credential-only legacy\n  grants); it consumes the nonce and marks the record pending-verification\n  so an old Connected status never carries onto a replaced grant; the\n  compensate RESTORES the previous credential (never delete-only, never\n  clobbering a newer writer).\n- every preserving logout clears the ACTIVE claim nonce regardless of\n  record status, so a logout cancels an in-flight reconnect too; a nonce\n  match in the resolver is always a LIVE attempt (finalizes consume\n  nonces, so the stale variant is gone).\n- new AuthStorage primitives: getVerified (disk-authoritative identity\n  capture) and replaceStagedCredential / replaceCredentialIfMatches\n  (full-identity CAS move and restore).\n- regressions: error-state reconnect (CAS, pending-verification, nonce\n  consumed, old verification state cleared), cancelled reconnect\n  preservation, late-reconnect-after-logout discard, claim/release one-shot\n  settlement on failed batch writes, rollback-restores-previous via CAS,\n  and the generic /login + config-menu delegation to the guarded hook.\n\n* fix: preserve MCP login intent and cancelled account settings (ENG-6108)\n\n* test: cover MCP account lifecycle commit safety (ENG-6108)\n\n* fix: merge-main regressions and secret-free grant binding (ENG-6108)\n\n* fix: fail closed on unproven MCP catalog entries and expired grants (ENG-6108)\n\n* fix: keep built-ins in the catalog cap and harden grant-type regressions (ENG-6108)\n\n* fix: match MCP connectors to the inline configuration pickers (ENG-6108)\n\n* fix: make MCP picker actions match settings-backed targets (ENG-6108)\n\n* feat(ai): complete the generic MCP OAuth engine (ENG-6108)\n\nThe MCP OAuth engine only handled public-client dynamic registration and\nexact endpoint/protected-resource matches: it discarded all registration\nresponse fields beyond client_id, requested every AS-advertised scope,\nissued unbounded uncancellable requests, and rejected the official\nNotion/Slack metadata shape (pathful endpoint, origin-level PRM resource)\nat discovery, so those servers could not log in or refresh at all.\n\nThe engine now follows the SDK 1.30 auth standards via pure helper/schema\nimports from @modelcontextprotocol/sdk (never the auth() orchestrator,\nwhose redirect model does not fit the staged consent UI):\n\n- Client auth-method negotiation (client_secret_basic > post > none,\n  DCR hint honored, RFC 8414 defaults) applied to exchange and refresh,\n  with a compatibility gate: a secret-only server never receives a doomed\n  no-auth request; it fails early with typed setup guidance.\n- Full RFC 7591 registration responses: persisted DCR client identity,\n  issued secret and expiry (respected on refresh), and registration-mode\n  binding. Config-supplied secrets are never persisted or embedded.\n- CIMD/SEP-991: a configured Prime-controlled client-metadata URL becomes\n  the client id when the server advertises\n  client_id_metadata_document_supported; no URL is invented or deployed.\n- SEP-835 scope precedence: configured > protected-resource > omitted;\n  authorization-server-wide scope lists are never blindly joined.\n- Narrow audience policy: the PRM resource must equal the canonical\n  endpoint or its exact HTTPS origin (URL-component compared); refresh\n  pins both values and the audience mode, fail-closed on any change, and\n  legacy exact grants never refresh against origin audiences.\n- Every request is bounded (10/15s deadlines, 256KiB bodies) and login\n  honors the host abort signal, including callback-server cleanup.\n- Token errors are typed and sanitized: whitelisted RFC error codes only,\n  fixed guidance, never raw server-controlled descriptions.\n\nAll flows run against offline fake OAuth/MCP servers in\npackages/ai/test/mcp-oauth.test.ts (39 tests: official Notion/Linear\nfixtures, Slack post-only negotiation, CIMD, refresh binding and\nrotation, abort/cancellation); no live endpoints or credentials.\n\n* feat(ai): read-only catalog metadata audit with readiness evidence (ENG-6108)\n\nAdd a reproducible read-only public metadata audit of all 103 remote catalog endpoints (public unauthenticated GETs only, bounded, DNS-pinned per request through an undici dispatcher lookup) and merge the committed evidence into the catalog offline. New additive, optional interface: setup.readiness (informational, never a Connect gate), setup.requirement, setup.fields[].kind, auth.alternatives[] per-path alternatives, and the observational auth.metadata evidence block. Placeholder-only OAuth blockers are cleared with evidence (Airtable, Shopify stay Connect-attemptable); genuine documented requirements stay hard (API keys, bearer tokens, tenant config, registered clients, transport and local-runtime limits). CIMD alone is never oauth-ready, audience-mismatched PRM documents stay unknown with notes until the approved engine audience policy lands, and local sources cannot self-assert readiness, alternatives or evidence.\n\n* docs(ai): correct stale oauth-marker consumer comment (ENG-6108)\n\nThe host keys OAuth support off authStrategy, not entry.oauth?.kind; the comment now points consumers at auth.strategy. Comment-only change.\n\n* fix(coding-agent): guard mcp account ownership and capability policy (ENG-6108)\n\n* fix(ai): adopt engine component comparison for readiness re-derivation (ENG-6108)\n\nThe importer audience rule now uses the engine component comparison: a protected-resource document must match the exact canonical endpoint or the exact origin (root-slash normalized). notion plus the 9 DCR-capable origin-mismatched entries (airtable, amplitude, appwrite, lovable, miro, rootly, vercel, windsor-ai, zoominfo) re-derive to oauth-ready and their stale not-yet-landed notes are gone; logrocket stays unknown (its resource drops the ?toolsets=all query, failing closed under the component rule); slack and hubspot stay unflipped (no dynamic client registration). Counts re-derive to 72 oauth-ready / 53 user-setup / 5 prime-restricted / 10 unknown. Catalog oauth validation now rejects client secrets explicitly instead of silently dropping them, symmetric with the client-id rejection.\n\n* feat(coding-agent): wire oauth client identity through shared mcp provider factory (ENG-6108)\n\n* fix(ai): mirror engine PRM selection in the metadata audit (ENG-6108)\n\nBugbot PRRT_kwDOSXZbXs6hvVZP + PRRT_kwDOSXZbXs6hvVZS: auditEndpoint now mirrors oauth.ts exactly - a WWW-Authenticate resource_metadata pointer is followed alone and any failure fails closed with no well-known fall-through; absent a pointer the pathful well-known is tried then the origin-level root location (SDK parity, 4xx continues); a candidate is selectable only when its document passes the engine audience component comparison and carries authorization servers. protectedResourceUrl is used at the call site instead of an inline construction. The bounded read-only audit was re-run (public GETs only, DNS-pinned, all bounds unchanged) and readiness re-derived: the reviewer obligation flips stay intact; codspeed and resend flip to oauth-ready via the SDK-parity origin-level fallback (valid documents, DCR, coherent AS); confidence-docs/-flags stay unknown with fail-closed notes (served-but-invalid documents); logrocket stays unknown with the precise fail-closed reason; slack/hubspot stay unflipped (DCR-less); shopify metadata is now available but DCR-less. Counts: 72 oauth-ready / 53 user-setup / 5 prime-restricted / 10 unknown; metadata 97 available / 6 unavailable.\n\n* fix(ai): require the exact engine fallback condition for oauth-ready (ENG-6108)\n\nBugbot PRRT_kwDOSXZbXs6hva2k: evidenceSupportsStandardOauth granted oauth-ready via origin-AS evidence for ANY no-served-JSON state, but the engine reaches its origin-level AS fallback ONLY when no resource_metadata pointer was followed and every tried well-known candidate returned exactly a 4xx (5xx, fetch errors, 2xx/3xx non-JSON bodies and served-but-invalid documents all throw with no fallback). A precise engineFallsBackToOriginAs predicate is now derived from the recorded attempts (followed or rejected pointer, served document, and per-attempt httpStatus), so fail-closed discovery stays honestly unknown. The audit script selectionNote now fires only for true fail-closed states; the all-4xx state is the engine honest fallback and records no note. The bounded read-only audit was re-run to match the corrected note semantics (aggregates stable: 103 audited, AS 97/6, DCR 78, CIMD 25, PKCE 97). Zero readiness flips - pure hardening; 7 all-4xx entries lose stale generic notes; new regression assertions pin intercom (oauth-ready via the legitimate origin-AS fallback, no note) and adobe-for-creativity (unknown, unavailable AS, no note). Counts unchanged: 72 oauth-ready / 53 user-setup / 5 prime-restricted / 10 unknown.\n\n* fix(ai): classify figma as registered-client after live DCR 403 evidence (ENG-6108)\n\nDogfooding PR #2256 head 8e77f0cc1 surfaced what the read-only audit could\nnot observe: Figma's advertised dynamic-client-registration endpoint returned\nHTTP 403 to the engine's anonymous registration POST during a real\n/mcp login figma attempt (2026-09-13), while its AS metadata still advertises\nthe endpoint with confidential-only client auth. A public metadata-only GET\nof the register endpoint returns 404, and public reports corroborate the 403\nfor anonymous DCR requests; whether self-registered Figma apps can obtain\nmcp:connect is publicly unresolved.\n\n- Audit store: the live attempt is recorded as an authorizationServer\n  registrationAttempt block with explicit provenance (the audit script never\n  POSTs registration endpoints); the script now preserves these blocks\n  verbatim on re-runs, and the $comment sanctions exactly this supplement.\n- Importer: an advertised registration endpoint whose live anonymous\n  registration was rejected (401/403) is gated evidence —\n  auth.metadata.dynamicClientRegistration flips to an explicit false (gated,\n  distinguishable from omitted \"not advertised\"), the gated finding becomes\n  the default metadata note, and the entry can never be oauth-ready\n  (fail-closed, the same honest class as DCR-less Slack/HubSpot).\n- overrides.json: figma mirrors the Slack precedent — pre-registered client,\n  registered-client requirement, prime-restricted readiness, requires-setup\n  with the 403-documented reason and FIGMA_MCP_CLIENT_ID / FIGMA_MCP_CLIENT_SECRET\n  setup fields.\n- Regenerated catalog.json + catalog.data.generated.ts via the importer;\n  counts: ready 82 -> 81, requires-setup 58 -> 59, oauth-ready 72 -> 71,\n  prime-restricted 5 -> 6 (user-setup 53, unknown 10 unchanged; sum 140).\n\nOffline verification: catalog suite 25/25, coding-agent catalog eligibility\n12/12, tsgo --noEmit clean, and both catalog scripts typechecked under the\nrepo base config.\n\n* drop the revert changelog fragments\n\nthe reland makes the \"removed\" entries moot before any release cut them;\nthe release notes should only describe the additions.\n\n* feat(ai): cut the service catalog to zero-app self-serve only (ENG-6108)\n\n2026-09-14 product decision: Prime maintains ZERO provider OAuth apps, so\nthe catalog advertises only what works self-serve — dynamic client\nregistration (readiness \"oauth-ready\") or user-supplied tokens/keys\n(\"user-setup\"). Every entry classified prime-restricted (needs a\nprovider-registered client) or unknown (no verified self-serve path) is cut\nfrom the shipped catalog; audit/engine parity, the readiness vocabulary and\nthe fail-closed classification machinery are unchanged.\n\n- overrides.json: the 16 cut providers (figma, gmail, google-calendar,\n  google-drive, mongodb-atlas, slack, adobe-for-creativity,\n  confidence-docs, confidence-flags, hubspot, logrocket, mapbox-docs,\n  shopify, sumup, synthflow, synthflow-docs) are excluded via the documented\n  excludedServers list — one entry per upstream record (18 keys: figma and\n  slack are merged from both upstreams, so both sides are cut and no ghost\n  entry can re-enter), each with a per-entry reason citing the decision and\n  the specific audit evidence. The now-dead servers overrides for excluded\n  identities were removed; their honesty content lives on in the exclusion\n  reasons.\n- Importer: the cut is enforced structurally — buildCatalog refuses to emit\n  an entry whose readiness classifies prime-restricted or unknown and fails\n  with a curation prompt (exclude with a documented reason, or curate\n  readiness with evidence), so an unverified provider can never ship\n  silently again. The gated-DCR honesty machinery (advertisedRegistrationGated,\n  explicit-false dynamicClientRegistration semantics) is kept and now\n  exported for direct unit tests, since the live case (figma) is excluded\n  rather than classified; the predicate still guards future entries.\n- Audit store: untouched — the pinned source snapshots and metadata-audit\n  results for the excluded endpoints stay committed as evidence (including\n  figma's live 403 registrationAttempt). The audit script now also retires,\n  never drops, registration-attempt evidence for servers that leave the\n  audit target set via the new top-level retiredRegistrationAttempts array,\n  so a re-run can never silently delete the figma evidence.\n- Regenerated catalog.json + catalog.data.generated.ts via the importer;\n  counts: total 140 -> 124 (http 102 -> 86; stdio 32, templated 5, sse 1\n  unchanged), ready 81 -> 71, requires-setup 59 -> 53, oauth-ready 71,\n  user-setup 53, prime-restricted 6 -> 0, unknown 10 -> 0 (sum exact).\n- Tests: mcp-catalog.test.ts now asserts the cut (all 16 ids absent, both\n  upstream sides of merged providers excluded, all 18 keys documented in the\n  import report with zero-app reasons, source snapshots and audit evidence\n  kept incl. figma's 403 attempt), pins the gated-DCR machinery directly\n  with synthetic evidence, updates the count assertions (124/71/53/0/0) and\n  keeps the byte-for-byte regeneration pin; the figma assertions now assert\n  exclusion instead of prime-restricted-in-catalog.\n\nOffline verification: catalog suite 27/27, coding-agent catalog eligibility\n12/12 (plus all 13 coding-agent mcp test files: 281 passed, 1 skipped),\ntsgo --noEmit clean at the repo root, both catalog scripts typechecked\nclean under the repo base config, biome clean on the changed files.\n\n* test(coding-agent): adapt activation-queue route host to the inline auth panel host surface\n\n* test(coding-agent): drive logout route assertions through the inline auth panel surface\n\n* fix(ai): demote confidential-only AS providers to the user-setup OAuth path (ENG-6108)\n\nLive gap found in dogfooding: Hugging Face /mcp login failed at connect with\n\"no compatible client authentication method (advertised: client_secret_basic,\nclient_secret_post)\" because the catalog classified the entry oauth-ready\nwithout ever checking token_endpoint_auth_methods_supported; the engine checks\nit at runtime and fails closed.\n\n- Extract the engine's fail-closed client-auth decision from\n  negotiateAuthMethod into the exported decideClientAuthMethod and add the\n  catalog predicates tokenAuthMethodsSupportPublicClient /\n  tokenAuthMethodsSupportConfiguredClient in packages/ai/src/mcp/oauth.ts —\n  the importer runs the SAME decision, so classification and the connect-time\n  gate share one source of truth.\n- Wire the gate into importer readiness: coherent DCR evidence with\n  confidential-only advertised methods now demotes honestly to the user-setup\n  OAuth path (requires your own OAuth app reason, registered-client\n  requirement, client-id/client-secret setup fields) instead of oauth-ready —\n  the user's own registered app, zero-app compliant, never an exclusion.\n  Advertised methods that serve not even a configured secret-bearing client\n  (mTLS-only) keep failing closed as today; omitted lists stay oauth-ready\n  per the engine's public-client spec default.\n- Regenerate catalog.json, catalog.data.generated.ts and import-report.json:\n  14 entries demote (airwallex, airwallex-sandbox, atlan, gitlab,\n  hugging-face, legalzoom, lusha, miro, monday-com, planetscale, supabase,\n  vercel, windsor-ai, zoominfo) — readiness counts move 71->57 oauth-ready and\n  53->67 user-setup; total 124 and zero prime-restricted/unknown invariants\n  hold, each entry carrying its confidential-only evidence and note.\n- Document tokenAuthMethods as required engine-compatibility capture in the\n  audit script and catalog README so future audits keep the check.\n- Tests: pin the hugging-face demotion with its confidential-only evidence and\n  the full demoted set, add the synthetic classification matrix\n  (confidential-only demotes, none/omitted stay one-click, mTLS-only stays\n  unknown) and direct predicate tests; update readiness count pins. The\n  byte-for-byte regeneration pin and the coding-agent eligibility thresholds\n  pass unchanged.\n\n* test(coding-agent): pin the MCP auth routes to the inline auth panel surface\n\nthe guarded-credential race test kept an unobserved showOverlay stub on the\nfake route TUI; it now asserts the generic /logout service selector never\nmounts an overlay popup, so MCP auth can only render through showAuthPanel\nlike #2331 provider logins. adds the changelog fragment documenting that\nevery MCP auth surface (guarded staged OAuth dialog, /login and /logout\nservice selectors, mcp-connections tab, /mcp login) mounts inline under\nthe chat with stacked closers, focus restore, and rows-aware sizing.\n\n* feat(ai): cut the catalog to one-click DCR or user token/key only (ENG-6108)\n\n2026-09-15 product decision (\"remove everything that's not one-click auth\nor api key\"): the shipped catalog advertises only one-click dynamic client\nregistration (readiness \"oauth-ready\") and user token/key entries; the\nclassification machinery and audit/engine parity are unchanged.\n\n- overrides.json: the 49 non-token/key entries — the 14 registered-client\n  entries whose authorization servers accept only secret-bearing client auth\n  (airwallex, airwallex-sandbox, atlan, gitlab, huggingface-skills,\n  legalzoom, lusha, miro, monday-com, planetscale, supabase, vercel,\n  windsor-ai, zoominfo), the 32 local-runtime stdio adapters and the 3\n  url-only tenant templates (activecampaign, jfrog, pigment) — are excluded\n  via the documented excludedServers list: one entry per upstream record\n  (64 keys: monday-com/supabase/vercel are merged from both upstreams, so\n  both sides are cut; every stdio server of the multi-server adapter plugins\n  is excluded), each with a per-entry reason citing the decision and the\n  specific evidence. The now-dead servers overrides for excluded identities\n  were removed; their honesty content lives on in the exclusion reasons.\n- Importer: the cut is enforced structurally — buildCatalog refuses to emit\n  a user-setup entry whose requirement is not token/key-shaped\n  (bearer-token/api-key credentials, a tenant config with a genuine non-url\n  field, or a legacy-transport entry that still collects a token/key) and\n  fails with a curation prompt, so a registered-client demotion, a\n  local-runtime adapter or a url-only template can never silently re-derive.\n  The auth-methods honesty machinery (decideClientAuthMethod parity,\n  confidential-only demotion, tokenAuthMethods capture) is unchanged and\n  stays active for the survivors.\n- Audit store and source snapshots: untouched — evidence for the excluded\n  endpoints stays committed as history.\n- Regenerated catalog.json + catalog.data.generated.ts + import-report.json\n  via the importer; counts: total 124 -> 75 (http 86 -> 72, templated 5 -> 2,\n  sse 1 unchanged, stdio 32 -> 0), ready 57 unchanged, requires-setup 67 ->\n  18, oauth-ready 57, user-setup 18, prime-restricted 0, unknown 0 (sum\n  exact); api-key strategy 32 -> 16.\n- Tests: mcp-catalog.test.ts pins the cut (all 49 ids absent, both upstream\n  sides of merged providers excluded, all 64 keys documented in the import\n  report with 2026-09-15 reasons, source snapshots and audit evidence kept,\n  the shipped user-setup set is exactly the 18 token/key entries), keeps the\n  confidential-only machinery matrix (now pinned on the committed\n  huggingface-skills audit evidence plus the synthetic matrix), adds the\n  structural invariant regression (lifting the gitlab exclusion fails the\n  import with the curation prompt), updates the count assertions (75/57/18/\n  0/0) and keeps the byte-for-byte regeneration pin; coding-agent\n  mcp-service-catalog count comment + eligibility sweep thresholds updated\n  for the 75-entry catalog (api_key >= 10 still holds at 16; unknown 53).\n\nOffline verification: ai catalog suite 29/29, ai mcp-oauth 40/40, all 13\ncoding-agent mcp test files 276 passed 1 skipped (catalog eligibility 12/12,\nservice catalog 63/63), tsgo --noEmit clean at the repo root, biome clean on\nthe changed files.\n\n* fix(tui): separate the oauth url from the browser-step text with a blank line\n\n* fix(tui): keep the service-catalog picker at one description line with stable frames\n\n* feat(tui): persist MCP connect outcomes as refinement-style chat entries (ENG-6108)\n\nConnect outcomes (\"Connected Linear (12 tools verified)\" and its\nsaved-but-unverified variants) were transient status lines that vanished;\nthey now persist in the chat transcript like harness refinement notices.\n\n- Add the mcp_connection_outcome custom message with structured details\n  (label, login/retry source, connected/unverified/unsaved verification\n  state, tool count, account id, activation) and the exact legacy wording\n  as its content; keep it out of LLM context like refinement outcomes.\n- Render it with a purple refinementHeader \"◆ Connected <service> · N\n  tools verified\" header over a refinementSummary body via the\n  ExpandableEventMessage base; register live rendering and transcript\n  replay (malformed entries included) and gate both on display.\n- Route both emit sites (pending-account retry verification and the\n  guarded login completion) and their failure/partial variants through\n  completeMcpConnectionOutcome: reload, then append the durable entry via\n  the new AgentConnection.appendCustomMessage (in-process sendCustomMessage,\n  daemon legacy append_custom_message RPC). Mid-turn connects keep the\n  transient \"will activate automatically\" line and record the durable\n  entry at the next safe boundary; a failed reload marks the entry\n  \"not active in this session\". Pre-outcome login failures (eligibility,\n  claim, finalize, incomplete login) remain transient warnings.\n- Focused tests: component rendering/replay, formatter wording parity,\n  and both emit sites including queued-boundary, inactive, and\n  append-failure fallback paths.\n\n* fix(tui): flatten multi-line catalog copy before it becomes a picker line\n\n* fix(tui): repair /mcp picker chrome nits and search ranking (ENG-6108)\n\nFive chrome nits from Kevin's live testing plus the picker search:\n\n- The scroll counter aligns with the row indent (rows render their label\n  at column 2; the counter and the empty-state message now do too).\n- Enter on an accounts-picker row 1 (the account name) re-verifies the\n  account instead of disconnecting it; only the explicit Remove row\n  removes. connectServiceFromPicker's connected branch now re-verifies\n  exactly like the pending branch.\n- One blank line between the last row and the description line in both\n  catalog and accounts mode, budgeted in updateLayout so frames stay\n  height-stable.\n- Accounts search matches identity only (account label + connection\n  id): every account row shares the same description/setup hint, so\n  matching that text could never filter anything.\n- Every inline MenuPanel opens with exactly one separator rule between\n  the chat view and the picker: a titled panel draws the rule above its\n  title; a headerless panel keeps the bordered search's top border as\n  that rule, never both. Model/provider/oauth/extension/prime-team\n  pickers budget the rule through the shared inlineMenuPanelTopRuleRows\n  helper.\n- Search ranking rewritten: exact/prefix/word-start/substring matches on\n  label, service id, and aliases rank far above description/setup-hint\n  text; the identity-only subsequence fallback requires a consecutive\n  run of half the query (minimum two); descriptions match only as\n  word-start/substring. Searching vercel against a catalog without\n  Vercel now yields the No-matching-services empty state instead of\n  eight unrelated rows matched through setup-hint boilerplate.\n\n* fix(mcp): cut non-token catalog survivors and say what to paste\n\n2026-09-16 product decision, from live picker testing: the catalog ships\none-click DCR connectors and simple paste-an-API-key/token services only.\n\nCut 5 survivors with documented per-entry reasons in overrides.json:\n- cockroachdb (cockroach-labs): tenant config, only input is the\n  per-cluster `mcp-cluster-id` header, no key/token field\n- dynatrace, sourcegraph: tenant instance URL next to the token\n- paypal-sandbox: legacy SSE, the runtime cannot connect to it at all\n- render: api-key requirement with zero setup fields, nothing to paste\n\nThe importer now enforces the narrower rule structurally: a user-setup\nentry ships only when its requirement is bearer-token or api-key AND it\ncollects at least one bearer-token/api-key field. An entry the readiness\npass never classified also fails closed instead of slipping past every\nshipping guard.\n\nAll 13 surviving setup reasons are now picker copy for a human: one line,\nstarting with \"paste\", naming the entry's real field. \"requires provider\ncredentials supplied as headers\" and \"requires an auth token supplied via\nenvironment variable\" are gone; github no longer stutters the same clause\ntwice; zoom-meetings drops the upstream placeholder note that never\nchanged what the user does. A test pins the shape.\n\nCatalog: 75 -> 70 entries (57 oauth-ready, 13 user-setup), all plain\nstreamable-http. Evidence, source snapshots and audit store unchanged.\n\nENG-6108\n\n* fix(tui): drop the restated MCP connect body and add disconnect feedback\n\nKevin saw the durable connect entry print the same sentence twice: the\nheader and the body both said \"Connected Granola (6 tools verified)\".\nThe header is the outcome line, so the body now carries ONLY what the\nheader omits - added account, verification issue plus next step, deferred\nactivation - and a plain success renders as the header alone. The\npersisted `content` keeps the full legacy sentence, because the transient\nfallback and status lines still need a whole sentence.\n\nDisconnects had no durable feedback at all. A successful disconnect from\n/plugins, `/mcp logout <name>`, or the generic `/logout` route now leaves\nthe same kind of entry, in the muted theme key: not the connect purple (a\ndisconnect is no refinement) and not the error red (it succeeded) - the\ngrey /plugins already uses for \"Not connected\". Only outcomes that really\nremoved the credential (removed, credential-only, preserved) get an\nentry; \"logged-out\" (partial save failure), \"failed\", \"missing\", and the\nstate-neutral \"refused\" keep their honest warnings and record nothing, so\nno entry can claim a disconnect that did not finish.\n\nThe generic /logout route still runs ONE store op and ONE reload: the\nhost records the outcome under its existing delegation and the selector\nappends it after the reload it already did.\n\nENG-6108\n\n* fix(tui): record the picker disconnect entry on the remove row\n\n* fix(tui): rebuild the /mcp accounts menu as a choice list (ENG-6108)\n\nKevin's live-testing redesign: the accounts menu drops its no-op search box\nand account-name row, renders '<service> MCP' with the muted description\n(wrapped, capped at three lines) above the options, and lists Reconnect /\nDisconnect <id> / Add another account in the PR #2340 selection language\n(mirrored locally until #2340 lands). Reconnect keeps the existing re-verify\npath and never disconnects; Disconnect keeps the store-locked removal and\nits durable disconnected entry.\n\nCatalog picker nits: the Connect trailing status reads in the text colour\ninstead of the accent purple, and the empty state gains one blank row above\nthe shortcuts line, aligned with the row labels (pinned at width 120).\n\n* fix(tui): stop inline pickers doubling the separator rule\n\n* feat(mcp): connect paste-a-key catalog services through an inline masked paste panel (ENG-6108)\n\n* fix(mcp): collapse the paste flow to ONE credential per service, cut named-header pairs (ENG-6108)\n\nTwo Bugbot findings, one root cause: the generic MCP runtime sends exactly\none Authorization: Bearer per connection, but the paste flow treated every\nrequired credential field as a separate mandatory prompt, and GitHub's two\nsetup fields (GITHUB_PAT_TOKEN / GITHUB_PERSONAL_ACCESS_TOKEN) were presented\nas two required tokens when they are alternative names for one PAT.\n\n- Curate GitHub's fields as alternatives via a shared field-level\n  credentialSet (\"github-pat\") in mcp-catalog/overrides.json; the paste flow\n  now prompts ONCE, labels honestly (\"GitHub personal access token\") and\n  stores the value under the first alternative's id.\n- Cut datadog and cloudinary-mediaflows from the catalog (documented\n  excludedServers reasons citing the named-header evidence: DD_API_KEY +\n  DD_APPLICATION_KEY, cld-api-key + cld-secret - one bearer can never\n  authenticate them). Catalog: 68 entries = 57 one-click DCR + 11 paste.\n- The importer now throws when a shipped requires-setup entry collects more\n  than one distinct required credential, so an unmarked multi-credential\n  entry can never silently re-derive; tests pin the guard by lifting the\n  datadog and cloudinary exclusions.\n- Simplify the host flow to one prompt/one value (no multi-field loop, no\n  per-field checkmark rows); masking, Esc-cancels-nothing-stored, the\n  empty-value guard, verification and the durable Connected outcome are\n  kept; services with genuinely distinct credentials stay honest\n  setup_required and are not pasteable.\n\n* fix(mcp): drop the dead paste-credential branch and trim the importer comment\n\n* fix(tui): render paste outcomes honestly and polish the accounts menu\n\n* fix(tui): budget the accounts frame for the trailing blank row\n\n* fix(tui): keep the /mcp picker chain open after connect, disconnect, and paste actions\n\nSelecting a row no longer drops the user back to the prompt after the action: the picker chain re-enters the right surface, rebuilt from the live catalog and connection store. Disconnecting one account reopens that service accounts menu without the removed row; disconnecting the last account, or a cancel that stored nothing, reopens the catalog; reconnect/re-verify, add-account, and paste re-enter the accounts menu with refreshed state. Esc closes the whole chain, and actions blocked before they start (login in progress, guidance, target drift) end the chain with their status line instead of re-opening, so there is no re-entry loop.\n\n* fix(tui): drop the accounts description instead of overflowing tight viewports\n\n* fix(tui): one reconnect/disconnect row per service with an account sub-picker, and left-arrow back to the catalog\n\nA service's accounts menu is now exactly three rows — Reconnect, Disconnect, Add another account — instead of a reconnect/disconnect pair per connection id. With one account, Enter acts on it directly with the existing re-verify and remove semantics. With several accounts, Enter on Reconnect or Disconnect opens a second inline picker in the same choice-list shape that lists the account ids; picking one runs the action on that connection id only, and Esc or left there returns to the accounts menu without acting. The sub-picker never nests deeper, and after an action the existing re-entry table decides the next surface (the accounts menu while an account survives, the catalog otherwise).\n\nLeft arrow from the accounts page now navigates back to the /mcp catalog — the picker chain's parent surface — remounted fresh, using the same app.modal.back binding the dialogs share; Esc still closes the whole chain, and left in the catalog stays inert. The accounts frame budget is unchanged (the option count is the only thing that grows), the budget test now pins the three-row count, and the multi-account re-entry tests drive the sub-picker end to end.\n\n* fix(tui): colour mcp outcome entries by outcome, warning for non-success\n\n* fix(mcp): keep alias OAuth providers behind the parent service catalog classification (ENG-6108)\n\n* fix(mcp): probe the origin-level oauth-protected-resource document without the endpoint query\n\n* test: bring ENG-6108 suites into the main-branch testing policy (#2336)\n\nShrink the branch's test additions from a net 16,514 to 16,610? -> net 11,610\ntest lines (the same as the branch's source additions), clear all 46 new\ntest-policy pattern violations, and consolidate per the policy's \"one file\nper module, regressions live in the owning suite\" rules. No test survives\non a timer, poll, sleep, skip, or env gate; every wait resolves on a\nconcrete deferred signal (mount hooks, probe gates, store flushes).\n\nFolded per-issue regression files into the owning module suites:\n- suite/regressions/eng-6108-inline-picker.test.ts -> the picker-chain\n  describe in test/service-catalog-picker.test.ts (mount/stale/replacement\n  settling, action routing, re-entry, settings-actions freeze, paste flow,\n  blocked actions) with vi.waitFor replaced by ui.setFocus-mount and\n  action-start deferred signals; the pure row-shape/menu layout pins\n  already covered by the component tests were deleted.\n- suite/regressions/eng-6108-service-catalog-activation.test.ts -> the\n  connect-then-activate end-to-end test in test/agent-session-services\n  .test.ts; the stored-token-pending duplicate died (already pinned in\n  mcp-service-catalog).\n\nDissolved test/mcp-account-commit-safety.test.ts; its unique invariants\nmoved to the owning suites and the rest were duplicates:\n- store->auth gap interleave + finalize nonce ownership + no-resurrection\n  -> test/mcp-connection-store.test.ts\n- CAS-absence replaceStagedCredential -> test/auth-storage.test.ts\n- /mcp login on a PENDING account, vanished-source repair (record+grant\n  evidence; bare shell refuses), and the paste-flow seam (single-credential\n  static token, cancelled/empty value, login-in-progress and target-changed\n  refusals) -> test/mcp-activation-queue.test.ts.\n\nConsolidated near-identical seams (surviving test -> invariant it owns):\n- grant-state matrix pinned ONCE in mcp-catalog-eligibility (predicate +\n  prompt + dispatch + view parity); manager's copy deleted.\n- reserved-name ownership pinned at dispatch level in mcp-manager; the\n  view-level copy and mcp-service-safety's provider-lifecycle duplicate\n  deleted.\n- cap protection pinned in mcp-service-catalog (resolver's own module);\n  mcp-catalog-eligibility's copy deleted.\n- remove/logout-vs-finalize races pinned once at the REAL route seam in\n  mcp-activation-queue; the store-level interleave duplicate deleted.\n- exact rendered copy kept only where it is a durable protocol contract\n  (outcome notice wording); component render pins made structural.\n- oauth client-auth negotiation + PRM-mismatch refusals + python discover\n  cursor/table families -> it.each/subTest tables.\n\nViolation conversions (all 46 cleared):\n- wall-clock-timer/poll/sleep: setFocus-mount signals, action-start\n  deferreds, queueVerifyResult+flush chains, an asyncio.Event hang, and\n  fs.watch for the multi-process ready barrier.\n- environment-gated-path: the 11 false positives in mcp-oauth (mock route\n  conditions carrying token/credential substrings) renamed via aliases;\n  the rest made unconditional.\n- explicit-test-timeout: allowed with policy comments only where the\n  probe's own timeout bound IS the behavior under test (probe hang tests,\n  real multi-process spawn).\n- conditional-or-disabled-test: kernel-bootstrap made unconditional\n  (file-scoped venv resolution, no cwd dependence; merge of main's #2336\n  had dropped the branch's theme bootstrap in menu-panel too - restored).\n\nVerified: every modified suite passes standalone and under 6 shuffle\nseeds; npm run check (biome + check:test-policy + tsgo + installer +\nbrowser-smoke) is green; spot-reverts of the chain re-entry rule and the\nstore finalize-ownership guard both fail the consolidated tests.\n\n* fix(mcp): mirror the engine audience rule and first-issuer selection in the audit\n\n* fix(mcp): fail closed on a malformed advertised issuer and fix the notion URL substring check"},{"name":"mcp-oauth.test.ts","kind":"file","size":48640,"lastCommitHash":"b6ac5d014d99401b55820835a4966584271e9a3c","lastCommitWhen":"2026-09-16T16:20:18-07:00","lastCommitMessage":"mcp service catalog and oauth engine (#2330)\n\n* add a shared service catalog and generic mcp connections (#2256)\n\n* style(coding-agent): apply biome formatting to daemon-mode.ts\n\n* feat(coding-agent): add /plugins service catalog with verified MCP connections (ENG-6108)\n\n- Add /plugins and bare /mcp as the same searchable external-service picker with\n  honest states (Connect, Connected with verified tool counts, Reconnect,\n  Verifying, Requires setup, Disabled) and connect/disconnect actions\n- Add mcp.list_plugins, mcp.search_plugins, and mcp.list_connections host\n  requests with strict status filters, bounded limits, and honest nextCursor\n- Add local connection records (connectionId distinct from catalog serviceId);\n  verify every login with a real MCP handshake so token presence alone is\n  pending, never Connected; rejected credentials recover via Reconnect\n- Serve connected catalog services (Linear, Notion) through the generic mcp\n  runtime route: system-prompt inventory and mcp.config, no per-service wrappers\n- Drop the McpIntegration import from the kernel ready check ahead of the\n  Linear/Notion wrapper-package removal\n- mcp.connect is registered only behind an explicit UI-approved callback and\n  stays unregistered in daemon-hosted sessions (honest \"no handler\")\n\nTests: mcp-service-catalog, mcp-manager handlers, service-catalog-picker, and\nthe eng-6108 activation regression covering login -> verify -> session reload ->\nprompt inventory in the real services path without a restart.\n\n* fix(coding-agent): harden MCP verification, activation, and connection records (ENG-6108)\n\nReview follow-ups on the /plugins service catalog slice:\n\n- Verification now runs through the official @modelcontextprotocol/sdk\n  client (negotiated protocol version header, CRLF SSE support, explicit\n  session termination via HTTP DELETE) instead of a handwritten transport\n- Failures persist as fixed safe categories only; endpoint URLs,\n  server-controlled text, and tokens never reach records or messages\n- Connection records use the auth.json file-lock read-modify-write pattern\n  with unique temp files; concurrent UI/daemon writers no longer lose\n  records, and pending operations queue while a flush is in flight\n- Every verification result is bound to the exact grant it verified\n  (credential hash); stale probes after logout or token rotation are\n  discarded, never marking a newer or removed account Connected\n- An OAuth connection without a usable token is never probed anonymously\n- A login made while streaming or compacting queues automatic activation\n  at the next safe boundary (agent end / compaction end); the UI never\n  instructs the user to run /reload for MCP changes\n- /plugins and config-menu connect paths share the queue; failure categories\n  render as fixed user-readable wording\n- metadata-reviewed / legacyBuiltin rename absorbed from the catalog lane\n\nTests: probe (SDK fake server incl. CRLF/401/timeout/secret-leak), store\n(two-writer races, guard discard, mid-flight queueing), service catalog\n(stale verify after logout/rotation, non-connectable transports), manager,\nactivation queue (streaming/compaction/tool boundaries), regression suite.\n\n* fix(coding-agent): bind MCP credentials to endpoints, reconcile providers, honest connect (ENG-6108)\n\n- Endpoint binding everywhere a stored grant is consulted: catalog services and\n  user-declared servers require cred.endpoint === current URL before any token\n  fetch or probe (views, verify, dispatch inventory, demand-driven listing);\n  unbound legacy grants surface as Reconnect with the fixed credential-unbound\n  category and are recorded once on demand-driven verification\n- Provider ownership is one atomic reconciliation: legacy built-ins, eligible\n  catalog services, and user-declared OAuth servers are re-registered first and\n  only previously-owned ids unregister; the ModelRegistry reset hook calls the\n  full reconciliation, so catalog providers survive refresh and a removed user\n  override restores the catalog provider after a single manager.refresh()\n- Flush-time verification guards re-read fresh credential-source state\n  (authStorage.reload() under the backend lock), so probes that finish after\n  another client logged out or rotated the grant are discarded — no stale\n  Connected record survives across clients\n- mcp.connect (explicit-approver seam) verifies the real handshake before\n  reporting connected (tool count included) and reports fixed failure\n  categories on rejected handshakes\n- /plugins stdio user servers get a real management action: Enter disables the\n  server in global settings, refreshes providers, and reloads; already-disabled\n  and vanished entries report honest status\n- Catalog views keep the Reconnect action on error rows and add unverified/\n  unbound view tests; all oauth test fixtures now carry bound endpoints\n\nMinimal type-only addition in connection-probe.ts (lifecycle lane owns the file):\nMCP_PROBE_ERRORS.UNBOUND_CREDENTIAL.\n\nTests: manager 29, service-catalog 23, activation-queue 8 (incl. stdio\nmanagement), probe 7, store 6, picker 4, regression 2, slash-commands 18 —\n97/97; reviewer's mcp-service-safety suite verified 12/12 green against this\ntree (their file, their branch).\n\n* feat(ai): merged MCP service catalog with deterministic importer (ENG-6108)\n\n* feat(ai): metadata-reviewed catalog status, legacy builtins, local JSON sources, literal endpoint checks (ENG-6108)\n\n* fix(ai): harden local catalog loader and endpoint checks (ENG-6108)\n\n* feat(coding-agent): shared catalog resolver, local sources, per-account connections (ENG-6108)\n\n- resolveMcpServiceCatalog merges the built-in SERVICE_CATALOG with\n  settings-declared local sources (Settings.mcpCatalogSources): ~-expanded\n  before loadLocalServiceCatalog (which does no expansion), declared-but-missing\n  files and cross-source duplicate ids surface as visible diagnostics, first\n  source wins, total capped at 500 entries\n- The SAME resolution feeds the /plugins UI and the mcp host handlers; the UI\n  re-reads connection records from disk before rendering (no stale cache) and\n  shows resolver diagnostics on open\n- One-click Connect is metadata-reviewed-only (plus user-placed local files,\n  which still go through the login dialog's explicit approval); unreviewed\n  imported entries stay candidates with an honest setup hint\n- Per-account connections: \"Add another account\" allocates a distinct\n  connectionId (mcp:<serviceId>-N) with its own credential key, record, and\n  OAuth provider; the account picker lists accounts with per-account\n  Reconnect/Disconnect; alias ids join integrations, dispatch inventory,\n  mcp.config, and demand-driven verification through the same machinery; the\n  record's serviceId keeps the parent catalog id\n- test/mcp-service-catalog.test.ts settles the theme's cli-highlight preload\n  in beforeAll (deterministic fix for the pre-existing initTheme fire-and-forget\n  teardown race, evidence in ENG-6108 notes); ServiceCatalogPickerComponent\n  gains title/subtitle/hideSearch options for the account listing\n\nCatalog commits f8a4cf61a -> 50b79c3af -> be7445c3c integrated via authorized\nlocal cherry-picks; no catalog-source files modified.\n\nTests: manager 31 (alias integrations/provider lifecycle, demand-driven unbound\nrecord, reconciliation), service-catalog 29 (resolver, candidates, allocator),\nactivation-queue 9 (stdio management, add-account), probe 7, store 6, picker 4,\nregression 2, slash-commands 18 — 105/105; npm run check EXIT=0; 10/10\nconsecutive scoped runs with zero unhandled rejections, exit 0 each.\n\n* mcp: generic discovery surface, drop linear/notion wrappers (ENG-6108)\n\nAdd a bounded discovery surface to the kernel MCP module:\nlist_plugins, search_plugins, list_connections, search_tools and\ndescribe_tool, backed by host-owned catalog/connection handlers,\nwith cursor-safe tools/list pagination, explicit search scopes and\ndefensive secret scrubbing of inventory metadata only.\n\nReplace the bespoke Linear/Notion Python wrapper packages with one\ngeneric bundled mcp skill; remove the McpIntegration base class after\nauditing consumers, moving its shared helpers into rlm.mcp. Connecting\na service is a user action (/plugins or /mcp login), never an install\nor a per-service Python module.\n\n* mcp: fail-closed tool discovery, isolated schemas, redacted inventory errors (ENG-6108)\n\nFollow-up to 6514cbe6f per review:\n\n- discover() now publishes a tool map only when tools/list pagination\n  completes; a repeated or malformed continuation cursor, or exceeding\n  the page cap, raises McpDiscoveryError instead of a silent partial\n  inventory. Malformed cursors are rejected rather than read as done.\n- list_tools/describe_tool return deep copies, so caller mutations can\n  never reach the cached canonical schemas.\n- Per-connection search failures report a fixed exception type + hint\n  (McpCredentialsUnavailable and friends) instead of raw exception text;\n  host_request error text echoed by inventory calls is scrubbed of\n  credential-bearing URLs, query strings and auth headers and bounded.\n\n* mcp: never chain raw host errors in inventory wrappers (ENG-6108)\n\nFollow-up to ff738187e per review. _host_inventory raises a fixed\n\"MCP <request-type> request failed/timed out\" wrapper outside the\nexception handler, so arbitrary host/bridge error text (which can\nembed credential-bearing URLs, query strings, headers and HTTP\nbodies) is never echoed and cannot be reached through __cause__ or\n__context__ either; format_exception prints stay secret-free. The\nnow-unused redaction regex helper and bound constant are removed.\n\nRegression uses traceback.format_exception, not only str(exc), to\nassert the original exception is fully absent. Skill updated for the\nhost status vocabulary (pending, verified handshake) and PluginView\nfields (setupHint, unverified, verifiedAt/toolCount, connectionIds).\n\n* fix(coding-agent): bound MCP probe lifetime and connection-store races (ENG-6108)\n\nRoot review fixes on the lifecycle lane:\n\n- probeMcpEndpoint: the SDK passes its own controller's signal to every\n  fetch (including the cleanup DELETE and its body cancel), and the SDK\n  request timeouts only race the JSON-RPC promise, so an unresponsive\n  DELETE could hang the probe forever. One lifecycle AbortController now\n  bounds the probe: a fetch wrapper merges its signal into every\n  transport fetch, terminateSession/close are each raced against a\n  cleanup grace deadline whose expiry aborts the signal, an absolute\n  deadline timer plus a final abort end lingering body reads, and every\n  timer is cleared. Failure categories stay fixed and safe.\n- McpConnectionStore: the pre-lock exists-then-write-empty create could\n  rename an empty file over records another process just wrote; the file\n  is now created exclusively (wx, never truncating) before the canonical\n  realpath lock, with mode 0600. A failed atomic write no longer drops\n  queued mutations: the batch is unshifted back to the front of the\n  queue and retried by the next flush (ops are idempotent; verify\n  guards re-evaluate under the lock).\n- MCP_PROBE_ERRORS gains UNBOUND_CREDENTIAL (\"credential-unbound\") for\n  grants not bound to the endpoint, consumed by the service catalog.\n\nOffline regressions: never-returning cleanup DELETE, hanging response\nbody, exclusive first-create race with mode 0600, injected atomic-write\nfailure with in-order retry and stale-guard discard, plus the existing\nsuites. All fetch stubs; no live credentials or provider calls.\n\n* test(coding-agent): multi-PID first-create regression for MCP connection store (ENG-6108)\n\nRoot review follow-up: in-process instances cannot reproduce the\nfirst-create exists/write race because their pre-await work is\nserialized on one event loop. The store test file now also spawns four\nreal first-writer processes (temporary .mts worker imported through the\nproject tsx loader, no production entry point), aligned by ready\nmarkers + a file barrier, racing the first create and the locked flush\non the shared store path. Asserts distinct PIDs, all children exit\ncleanly, every record survives, and the file keeps mode 0600; children\nare terminated in a finally on every path.\n\nTest-only: no production files touched.\n\n* test(coding-agent): Windows-portable multi-PID store regression (ENG-6108)\n\nTest-only portability follow-up: the generated first-create worker\nimported the store module by resolved absolute OS path, which is not a\nvalid ESM specifier on Windows; it now imports by file URL, and the\nexact 0600 mode assertions are POSIX-only (Windows mode bits do not\nmap meaningfully). No production changes.\n\n* test(coding-agent): add service-safety adversarial regressions for MCP credentials and providers (ENG-6108)\n\nAdversarial regression suite for the ENG-6108 service-catalog safety\ncontract, red on the 4bd8abc12 baseline and green on the wave-2 fixes:\n\n- Credential binding before probe/token access: a stored credential bound\n  to a different endpoint, or unbound, is rejected before any probe call\n  and before authStorage.getApiKey - for user-declared servers and\n  catalog services, through direct verifyConnection and the demand-driven\n  mcp.list_plugins background verification; never a connected record.\n- Cross-client stale probes: two AuthStorage instances share one\n  auth.json; a probe finishing after a second client logs the grant out\n  or replaces it mid-flight must not persist a connected record or\n  verifiedAt for the current grant.\n- OAuth provider lifecycle: a full OAuth registry reset (through the\n  real createAgentSessionServices + modelRegistry.refresh seam)\n  preserves non-bundled catalog providers, and removing a user override\n  restores the catalog provider after one refresh.\n\nOffline-only: injected probes, denied fetch, per-test temp credential\nand connection stores, no live endpoints or real credentials.\n\n* fix(coding-agent): durable account reservations, per-account views, honest actions (ENG-6108)\n\nFinal-review wave 4:\n\n- Account allocation is a durable reservation under the connection-store file\n  lock: reserveConnectionId applies atomically on disk (exactly one winner in\n  a cross-process race; the loser allocates the next id), pending markers are\n  visible to every client, and removeReservation is ownership-validated (id +\n  still-pending + same createdAt) so a late callback never removes or resurrects\n  another client's account. Allocation consults store records, credentials,\n  configured user servers, and catalog ids; configured names are never taken.\n- Views aggregate every account of a service: connectionIds lists all accounts,\n  each account's status reflects its own bound credential, the service card\n  survives on a remaining account after the default disconnects, and the\n  inventory emits one row per account (no phantom primary row). Alias account\n  ids are searchable (search_plugins alias contract). Connections whose local\n  catalog source vanished keep a pinned descriptor at the recorded endpoint —\n  credentials are never retargeted.\n- Explicit state actions: pending accounts retry verification without a\n  relogin (the \"retry from /plugins\" path works), error accounts keep\n  Reconnect (catalog and user rows), each account gets an explicit Remove\n  row, and a verification result that could not be saved reports pending —\n  never a false Connected.\n- resolveMcpServiceCatalog isolates local-source failures per source: one\n  unreadable or invalid file becomes a bounded visible diagnostic while the\n  built-in catalog and every other source keep resolving.\n\nTests: two-client simultaneous reservation race with barrier, ownership\nvalidation, full add-second -> reload -> inventory -> disconnect-default ->\nsecond-still-manageable regression, per-account view aggregation, vanished-\nsource pinning, per-source failure isolation, state-based action tests, and\nallocation that skips configured ids.\n\nOwnership: bootstrap.ts untouched (delegated lane).\n\n* fix(coding-agent): require MCP discovery methods in the kernel ready check (ENG-6108)\n\nThe runtime ready check only asserted mcp.list_tools/mcp.call_tool; the\nfive new discovery methods were validated once by the bootstrap import\nscan, so a cached kernel venv with an old prime-agent-runtime could\npass readiness. The check now requires callables for list_plugins,\nsearch_plugins, list_connections, search_tools and describe_tool, and\nfails with an actionable message so the venv is rebuilt instead of\nsilently reused.\n\nRUNTIME_READY_CHECK is exported so the new regression executes the\nexact shipped check against a real project runtime: it accepts the\ncurrent runtime, and rejects a runtime simulated as old by deleting\neach discovery method in-process (not a text-grep test). No provider\ncalls, credentials, or real daemon involved.\n\n* fix(coding-agent): guarded account credential commits and computed account status (ENG-6108)\n\nFinal-review wave 5:\n\n- Reservations resolve only after the durable record write COMMITS: the\n  store defers reserve/remove/finalize callbacks past writeFileAtomicSync,\n  resolves them false on write failure, and drops the one-shot ops instead\n  of requeueing them — a failed write can never produce a ghost reservation\n  a login could start on (injected-write-failure regression: no marker, no\n  requeue surprise, retry works)\n- Ownership is an opaque random attempt nonce (not createdAt): cancel and\n  the NEW successful-commit guard both validate it under the same store\n  lock. Add-account logins stage the OAuth credential under\n  mcp:<id>--<attempt> and move it to the real account key only inside a\n  guarded finalizeAttempt commit — a late login success after remove or\n  replacement discards the staged credential and never touches the\n  account (regressions: late-success-after-remove and same-id-new-owner,\n  both assert the final credentials)\n- Per-account status is one computed helper (accountStateFor): credential\n  binding, expiry, and the record combine through httpConnectionStatus, and\n  the plugin aggregate, connection inventory, and account picker all use\n  it — previously-connected records with unbound, retargeted, or\n  expired-no-refresh credentials report Reconnect everywhere (6\n  regressions across default and alias accounts)\n- Catalog metadata aliases ride the view DTO and are searchable again\n  (regression: an alias absent from label/id/description matches)\n- Vanished-source pins are their own trust path (never localSource trust;\n  never one-click connectable)\n\nTests: 147/147 across 10 files; npm run check EXIT=0; 10/10 consecutive\nscoped runs with zero unhandled rejections, exit 0 each.\n\n* fix(coding-agent): exactly-once account transactions and locked disconnects (ENG-6108)\n\nFinal-review wave 6 (transaction issues):\n\n- Every one-shot store callback (reserve/removeReservation/finalizeAttempt/\n  removeAccount) settles EXACTLY once: deferred callbacks resolve with the\n  commit outcome (not `didCommit && resolve(true)`), losing and throwing\n  branches resolve false inline, one-shot ops are dropped on write failure,\n  and trailing ops in a failed batch can never hang — batched-two-reserves\n  write-failure regression included\n- Account removal runs credential deletion AND record removal under the SAME\n  store lock (new store.removeAccount; disconnect, remove-action, and\n  /mcp logout all use it): a concurrent finalize can never re-add an orphan\n  credential after a disconnect — interleaving regression on real stores\n  covers both orders (remove-then-finalize loses ownership; finalize-then-\n  remove clears record AND credential)\n- finalizeAttempt compensates: if the RECORD write fails after the credential\n  move, the compensate callback runs under the same lock and restores the\n  staged credential (the real key was empty before the attempt), so a failed\n  finalize is all-or-nothing; the flow then releases the reservation and\n  reports honestly — UI regression asserts the real key untouched, staged\n  restored+discarded, reservation released, and the honest message\n\nTests: 151/151 across 10 files; npm run check EXIT=0; 10/10 consecutive\nscoped runs with zero unhandled rejections, exit 0 each.\n\n* fix: honest MCP account recovery edges (ENG-6108)\n\n- removeAccount logs a credential-only integration out even when no\n  connection record exists; outcomes are typed (removed, credential-only,\n  missing, failed) and every UI route maps them honestly.\n- finalizeAttempt registers its rollback BEFORE any side effect: a\n  throwing or partial commit is compensated under the same lock, and a\n  FAILED rollback surfaces an explicit recovery-required state with the\n  credential retained instead of a silent false.\n- the guarded commit refuses to clobber a credential an ordinary login\n  wrote at the account key mid-flight, and the rollback only ever undoes\n  its own write; a bystander credential survives byte-for-byte.\n- one-shot store operations settle cleanly when the file lock itself\n  cannot be acquired; durable operations requeue (pre-splice).\n\n* fix: atomic MCP credential moves and honest partial logouts (ENG-6108)\n\n- staged logins move their credential to the account key with a new\n  disk-authoritative compare-and-set under the auth backend's own file\n  lock: moveStagedCredential (set-if-absent, returns the exact moved\n  credential), restoreCredentialIfAbsent, and removeIfCredentialMatches\n  (exact full-object own check, not access-token equality). A bystander\n  credential written by another process can no longer be clobbered by a\n  get/set race across AuthStorage instances.\n- the finalize compensation restores ours only into an empty staged slot\n  and deletes only its own exact credential from the account key.\n- removeAccount now reports \"logged-out\" when the credential logout\n  committed but the record save failed: the logout is preserved, the UI\n  wording says so and never claims the account is still connected; plain\n  \"failed\" wording is state-neutral.\n- two-real-storage-instance regressions: a bystander login written after\n  staging survives byte-for-byte; a generic /logout in another client\n  before/after the finalize races atomically (last-writer-wins under the\n  backend lock, record shows an honest unbound state); an injected\n  record-write failure after the logout reports the honest partial state.\n\n* fix: disk-verified MCP logouts and logout-cancelled login attempts (ENG-6108)\n\n- the three removeAccount authCleanup paths now use removeVerified\n  (extended to return whether a credential was actually removed from\n  disk): a failed auth-file write can no longer report Removed/\n  Disconnected while the credential persists; the honest \"failed\"\n  wording is state-neutral.\n- a real generic /logout of an MCP account now cancels that account's\n  pending login attempts: runLogout calls the new\n  ProviderAuthFlowsHost.onMcpCredentialRemoved hook, and the host\n  invalidates the pending reservation under the connection store's lock\n  (new invalidatePendingAttempts), so a stale in-flight OAuth attempt\n  resolves denied and can never re-activate the logged-out account.\n  Non-MCP logouts are unchanged.\n- regressions: auth-file write failure with a fresh disk reader (the\n  credential survives, nothing claims success), a route-exact\n  cross-client pending-finalize vs real /logout test driven through the\n  selector, store-level invalidation semantics, and stale\n  interactive-mode-status fixtures repaired to the current seams.\n\n* fix: one shared store-locked MCP logout op for the generic /logout route (ENG-6108)\n\n- the route delegates the ENTIRE MCP logout before touching auth: the new\n  exported logoutMcpAccount(providerId, store, authStorage) performs\n  verified credential deletion (removeVerified) AND pending-attempt\n  cancellation in one store-locked removeAccount with the new\n  preserveCompletedRecord semantics (pending attempts cancelled,\n  completed records kept for the honest unbound/Reconnect state).\n- removeAccount now runs the verified cleanup BEFORE mutating the\n  working records map: a failed auth-file write resolves \"failed\" with\n  the record intact in memory AND on disk (no half-applied deletion),\n  and a partially-saved logout still reports the honest \"logged-out\"\n  state.\n- the id resolution is exported as resolveMcpAccountLogoutTarget:\n  exact ids win (service ids may contain \"--\"), and staged keys map\n  back only through their actually recorded attempt nonce.\n- regressions: a barrier test fires the REAL generic route inside the\n  finalize's locked commit (verified deterministically red against the\n  old logout-first ordering); store-level half-applied-deletion and\n  preserve-semantics tests; route delegation/wording tests; handler\n  tests for double-hyphen ids, staged-key mapping, and preservation.\n\n* fix: fail-closed refusal for stale staged-key MCP logouts (ENG-6108)\n\n- a staged-key logout that races a completing finalize now refuses\n  fail-closed instead of orphaning the moved credential: the shared\n  handler resolves the account from CURRENT records and CURRENT on-disk\n  auth state under the store lock (never a pre-lock cache snapshot), and\n  when the staged credential already moved onto the account key it\n  returns \"refused\" — the record and the newer credential both survive,\n  and the route reports the completed login explicitly instead of\n  claiming Logged out.\n- new removeAccountForProvider store op (one critical section: resolve\n  under lock -> disk-verified refusal checks -> verified cleanup ->\n  cancel pending / preserve completed); resolveMcpAccountLogoutTarget\n  now returns a stale variant for nonce-matched non-pending records.\n- new disk-authoritative AuthStorage.hasVerified existence check used\n  for the current-state refusal decisions.\n- regressions: the staged-key race queued behind a finalize-first move\n  (refused, record + credential survive), resolver stale semantics, and\n  the route-level refused wording.\n\n* fix: staged-key MCP logouts cancel the attempt and preserve the account shell (ENG-6108)\n\n- removeAccountForProvider no longer gates record deletion on an auth\n  existence snapshot (not atomic with another client's ordinary login):\n  a staged-key logout removes only the staged credential, INVALIDATES the\n  attempt nonce on the pending record (so the in-flight login's denied\n  path can neither finalize nor removeReservation-delete it), and\n  PRESERVES the account record — deletion stays the explicit Remove\n  action's job; a bystander credential on the real key can never be\n  orphaned.\n- the \"refused\" outcome is now state-neutral (\"This login attempt is no\n  longer current; manage the account from /plugins\") — no Logged out or\n  Connected claim from token presence; failed verified auth deletion\n  still changes no record.\n- the interim AuthStorage.hasVerified helper is removed (no auth-state\n  snapshot decisions remain); regressions pin the both-exist contract\n  (staged removed, bystander byte-for-byte, record + nonce-invalidated\n  shell preserved, old-nonce finalize denied, removeReservation no-op)\n  and the finalize-first race with the same invariants.\n\n* feat: one guarded connect operation for every MCP OAuth login route (ENG-6108)\n\n- new one-shot store ops claimConnectionId/releaseClaim: a guarded login\n  claims an EXISTING account record (any status) under the store lock and\n  cancel releases it — the record, its status, and any credential survive\n  untouched; finalizeAttempt ownership is now the EXPLICIT nonce on any\n  record status.\n- every user-facing MCP OAuth login (initial connect, error-state\n  reconnect, add account, /mcp login, generic /login service options,\n  config menu) routes through the guarded flow: claim/reserve, staged\n  OAuth, guarded finalize. The raw dialog remains internal.\n- the finalize commit is a full-identity compare-and-swap on the auth\n  backend lock: set-if-absent for fresh accounts, replace-only-if-matching\n  for intentional replacements (reconnects and credential-only legacy\n  grants); it consumes the nonce and marks the record pending-verification\n  so an old Connected status never carries onto a replaced grant; the\n  compensate RESTORES the previous credential (never delete-only, never\n  clobbering a newer writer).\n- every preserving logout clears the ACTIVE claim nonce regardless of\n  record status, so a logout cancels an in-flight reconnect too; a nonce\n  match in the resolver is always a LIVE attempt (finalizes consume\n  nonces, so the stale variant is gone).\n- new AuthStorage primitives: getVerified (disk-authoritative identity\n  capture) and replaceStagedCredential / replaceCredentialIfMatches\n  (full-identity CAS move and restore).\n- regressions: error-state reconnect (CAS, pending-verification, nonce\n  consumed, old verification state cleared), cancelled reconnect\n  preservation, late-reconnect-after-logout discard, claim/release one-shot\n  settlement on failed batch writes, rollback-restores-previous via CAS,\n  and the generic /login + config-menu delegation to the guarded hook.\n\n* fix: preserve MCP login intent and cancelled account settings (ENG-6108)\n\n* test: cover MCP account lifecycle commit safety (ENG-6108)\n\n* fix: merge-main regressions and secret-free grant binding (ENG-6108)\n\n* fix: fail closed on unproven MCP catalog entries and expired grants (ENG-6108)\n\n* fix: keep built-ins in the catalog cap and harden grant-type regressions (ENG-6108)\n\n* fix: match MCP connectors to the inline configuration pickers (ENG-6108)\n\n* fix: make MCP picker actions match settings-backed targets (ENG-6108)\n\n* feat(ai): complete the generic MCP OAuth engine (ENG-6108)\n\nThe MCP OAuth engine only handled public-client dynamic registration and\nexact endpoint/protected-resource matches: it discarded all registration\nresponse fields beyond client_id, requested every AS-advertised scope,\nissued unbounded uncancellable requests, and rejected the official\nNotion/Slack metadata shape (pathful endpoint, origin-level PRM resource)\nat discovery, so those servers could not log in or refresh at all.\n\nThe engine now follows the SDK 1.30 auth standards via pure helper/schema\nimports from @modelcontextprotocol/sdk (never the auth() orchestrator,\nwhose redirect model does not fit the staged consent UI):\n\n- Client auth-method negotiation (client_secret_basic > post > none,\n  DCR hint honored, RFC 8414 defaults) applied to exchange and refresh,\n  with a compatibility gate: a secret-only server never receives a doomed\n  no-auth request; it fails early with typed setup guidance.\n- Full RFC 7591 registration responses: persisted DCR client identity,\n  issued secret and expiry (respected on refresh), and registration-mode\n  binding. Config-supplied secrets are never persisted or embedded.\n- CIMD/SEP-991: a configured Prime-controlled client-metadata URL becomes\n  the client id when the server advertises\n  client_id_metadata_document_supported; no URL is invented or deployed.\n- SEP-835 scope precedence: configured > protected-resource > omitted;\n  authorization-server-wide scope lists are never blindly joined.\n- Narrow audience policy: the PRM resource must equal the canonical\n  endpoint or its exact HTTPS origin (URL-component compared); refresh\n  pins both values and the audience mode, fail-closed on any change, and\n  legacy exact grants never refresh against origin audiences.\n- Every request is bounded (10/15s deadlines, 256KiB bodies) and login\n  honors the host abort signal, including callback-server cleanup.\n- Token errors are typed and sanitized: whitelisted RFC error codes only,\n  fixed guidance, never raw server-controlled descriptions.\n\nAll flows run against offline fake OAuth/MCP servers in\npackages/ai/test/mcp-oauth.test.ts (39 tests: official Notion/Linear\nfixtures, Slack post-only negotiation, CIMD, refresh binding and\nrotation, abort/cancellation); no live endpoints or credentials.\n\n* feat(ai): read-only catalog metadata audit with readiness evidence (ENG-6108)\n\nAdd a reproducible read-only public metadata audit of all 103 remote catalog endpoints (public unauthenticated GETs only, bounded, DNS-pinned per request through an undici dispatcher lookup) and merge the committed evidence into the catalog offline. New additive, optional interface: setup.readiness (informational, never a Connect gate), setup.requirement, setup.fields[].kind, auth.alternatives[] per-path alternatives, and the observational auth.metadata evidence block. Placeholder-only OAuth blockers are cleared with evidence (Airtable, Shopify stay Connect-attemptable); genuine documented requirements stay hard (API keys, bearer tokens, tenant config, registered clients, transport and local-runtime limits). CIMD alone is never oauth-ready, audience-mismatched PRM documents stay unknown with notes until the approved engine audience policy lands, and local sources cannot self-assert readiness, alternatives or evidence.\n\n* docs(ai): correct stale oauth-marker consumer comment (ENG-6108)\n\nThe host keys OAuth support off authStrategy, not entry.oauth?.kind; the comment now points consumers at auth.strategy. Comment-only change.\n\n* fix(coding-agent): guard mcp account ownership and capability policy (ENG-6108)\n\n* fix(ai): adopt engine component comparison for readiness re-derivation (ENG-6108)\n\nThe importer audience rule now uses the engine component comparison: a protected-resource document must match the exact canonical endpoint or the exact origin (root-slash normalized). notion plus the 9 DCR-capable origin-mismatched entries (airtable, amplitude, appwrite, lovable, miro, rootly, vercel, windsor-ai, zoominfo) re-derive to oauth-ready and their stale not-yet-landed notes are gone; logrocket stays unknown (its resource drops the ?toolsets=all query, failing closed under the component rule); slack and hubspot stay unflipped (no dynamic client registration). Counts re-derive to 72 oauth-ready / 53 user-setup / 5 prime-restricted / 10 unknown. Catalog oauth validation now rejects client secrets explicitly instead of silently dropping them, symmetric with the client-id rejection.\n\n* feat(coding-agent): wire oauth client identity through shared mcp provider factory (ENG-6108)\n\n* fix(ai): mirror engine PRM selection in the metadata audit (ENG-6108)\n\nBugbot PRRT_kwDOSXZbXs6hvVZP + PRRT_kwDOSXZbXs6hvVZS: auditEndpoint now mirrors oauth.ts exactly - a WWW-Authenticate resource_metadata pointer is followed alone and any failure fails closed with no well-known fall-through; absent a pointer the pathful well-known is tried then the origin-level root location (SDK parity, 4xx continues); a candidate is selectable only when its document passes the engine audience component comparison and carries authorization servers. protectedResourceUrl is used at the call site instead of an inline construction. The bounded read-only audit was re-run (public GETs only, DNS-pinned, all bounds unchanged) and readiness re-derived: the reviewer obligation flips stay intact; codspeed and resend flip to oauth-ready via the SDK-parity origin-level fallback (valid documents, DCR, coherent AS); confidence-docs/-flags stay unknown with fail-closed notes (served-but-invalid documents); logrocket stays unknown with the precise fail-closed reason; slack/hubspot stay unflipped (DCR-less); shopify metadata is now available but DCR-less. Counts: 72 oauth-ready / 53 user-setup / 5 prime-restricted / 10 unknown; metadata 97 available / 6 unavailable.\n\n* fix(ai): require the exact engine fallback condition for oauth-ready (ENG-6108)\n\nBugbot PRRT_kwDOSXZbXs6hva2k: evidenceSupportsStandardOauth granted oauth-ready via origin-AS evidence for ANY no-served-JSON state, but the engine reaches its origin-level AS fallback ONLY when no resource_metadata pointer was followed and every tried well-known candidate returned exactly a 4xx (5xx, fetch errors, 2xx/3xx non-JSON bodies and served-but-invalid documents all throw with no fallback). A precise engineFallsBackToOriginAs predicate is now derived from the recorded attempts (followed or rejected pointer, served document, and per-attempt httpStatus), so fail-closed discovery stays honestly unknown. The audit script selectionNote now fires only for true fail-closed states; the all-4xx state is the engine honest fallback and records no note. The bounded read-only audit was re-run to match the corrected note semantics (aggregates stable: 103 audited, AS 97/6, DCR 78, CIMD 25, PKCE 97). Zero readiness flips - pure hardening; 7 all-4xx entries lose stale generic notes; new regression assertions pin intercom (oauth-ready via the legitimate origin-AS fallback, no note) and adobe-for-creativity (unknown, unavailable AS, no note). Counts unchanged: 72 oauth-ready / 53 user-setup / 5 prime-restricted / 10 unknown.\n\n* fix(ai): classify figma as registered-client after live DCR 403 evidence (ENG-6108)\n\nDogfooding PR #2256 head 8e77f0cc1 surfaced what the read-only audit could\nnot observe: Figma's advertised dynamic-client-registration endpoint returned\nHTTP 403 to the engine's anonymous registration POST during a real\n/mcp login figma attempt (2026-09-13), while its AS metadata still advertises\nthe endpoint with confidential-only client auth. A public metadata-only GET\nof the register endpoint returns 404, and public reports corroborate the 403\nfor anonymous DCR requests; whether self-registered Figma apps can obtain\nmcp:connect is publicly unresolved.\n\n- Audit store: the live attempt is recorded as an authorizationServer\n  registrationAttempt block with explicit provenance (the audit script never\n  POSTs registration endpoints); the script now preserves these blocks\n  verbatim on re-runs, and the $comment sanctions exactly this supplement.\n- Importer: an advertised registration endpoint whose live anonymous\n  registration was rejected (401/403) is gated evidence —\n  auth.metadata.dynamicClientRegistration flips to an explicit false (gated,\n  distinguishable from omitted \"not advertised\"), the gated finding becomes\n  the default metadata note, and the entry can never be oauth-ready\n  (fail-closed, the same honest class as DCR-less Slack/HubSpot).\n- overrides.json: figma mirrors the Slack precedent — pre-registered client,\n  registered-client requirement, prime-restricted readiness, requires-setup\n  with the 403-documented reason and FIGMA_MCP_CLIENT_ID / FIGMA_MCP_CLIENT_SECRET\n  setup fields.\n- Regenerated catalog.json + catalog.data.generated.ts via the importer;\n  counts: ready 82 -> 81, requires-setup 58 -> 59, oauth-ready 72 -> 71,\n  prime-restricted 5 -> 6 (user-setup 53, unknown 10 unchanged; sum 140).\n\nOffline verification: catalog suite 25/25, coding-agent catalog eligibility\n12/12, tsgo --noEmit clean, and both catalog scripts typechecked under the\nrepo base config.\n\n* drop the revert changelog fragments\n\nthe reland makes the \"removed\" entries moot before any release cut them;\nthe release notes should only describe the additions.\n\n* feat(ai): cut the service catalog to zero-app self-serve only (ENG-6108)\n\n2026-09-14 product decision: Prime maintains ZERO provider OAuth apps, so\nthe catalog advertises only what works self-serve — dynamic client\nregistration (readiness \"oauth-ready\") or user-supplied tokens/keys\n(\"user-setup\"). Every entry classified prime-restricted (needs a\nprovider-registered client) or unknown (no verified self-serve path) is cut\nfrom the shipped catalog; audit/engine parity, the readiness vocabulary and\nthe fail-closed classification machinery are unchanged.\n\n- overrides.json: the 16 cut providers (figma, gmail, google-calendar,\n  google-drive, mongodb-atlas, slack, adobe-for-creativity,\n  confidence-docs, confidence-flags, hubspot, logrocket, mapbox-docs,\n  shopify, sumup, synthflow, synthflow-docs) are excluded via the documented\n  excludedServers list — one entry per upstream record (18 keys: figma and\n  slack are merged from both upstreams, so both sides are cut and no ghost\n  entry can re-enter), each with a per-entry reason citing the decision and\n  the specific audit evidence. The now-dead servers overrides for excluded\n  identities were removed; their honesty content lives on in the exclusion\n  reasons.\n- Importer: the cut is enforced structurally — buildCatalog refuses to emit\n  an entry whose readiness classifies prime-restricted or unknown and fails\n  with a curation prompt (exclude with a documented reason, or curate\n  readiness with evidence), so an unverified provider can never ship\n  silently again. The gated-DCR honesty machinery (advertisedRegistrationGated,\n  explicit-false dynamicClientRegistration semantics) is kept and now\n  exported for direct unit tests, since the live case (figma) is excluded\n  rather than classified; the predicate still guards future entries.\n- Audit store: untouched — the pinned source snapshots and metadata-audit\n  results for the excluded endpoints stay committed as evidence (including\n  figma's live 403 registrationAttempt). The audit script now also retires,\n  never drops, registration-attempt evidence for servers that leave the\n  audit target set via the new top-level retiredRegistrationAttempts array,\n  so a re-run can never silently delete the figma evidence.\n- Regenerated catalog.json + catalog.data.generated.ts via the importer;\n  counts: total 140 -> 124 (http 102 -> 86; stdio 32, templated 5, sse 1\n  unchanged), ready 81 -> 71, requires-setup 59 -> 53, oauth-ready 71,\n  user-setup 53, prime-restricted 6 -> 0, unknown 10 -> 0 (sum exact).\n- Tests: mcp-catalog.test.ts now asserts the cut (all 16 ids absent, both\n  upstream sides of merged providers excluded, all 18 keys documented in the\n  import report with zero-app reasons, source snapshots and audit evidence\n  kept incl. figma's 403 attempt), pins the gated-DCR machinery directly\n  with synthetic evidence, updates the count assertions (124/71/53/0/0) and\n  keeps the byte-for-byte regeneration pin; the figma assertions now assert\n  exclusion instead of prime-restricted-in-catalog.\n\nOffline verification: catalog suite 27/27, coding-agent catalog eligibility\n12/12 (plus all 13 coding-agent mcp test files: 281 passed, 1 skipped),\ntsgo --noEmit clean at the repo root, both catalog scripts typechecked\nclean under the repo base config, biome clean on the changed files.\n\n* test(coding-agent): adapt activation-queue route host to the inline auth panel host surface\n\n* test(coding-agent): drive logout route assertions through the inline auth panel surface\n\n* fix(ai): demote confidential-only AS providers to the user-setup OAuth path (ENG-6108)\n\nLive gap found in dogfooding: Hugging Face /mcp login failed at connect with\n\"no compatible client authentication method (advertised: client_secret_basic,\nclient_secret_post)\" because the catalog classified the entry oauth-ready\nwithout ever checking token_endpoint_auth_methods_supported; the engine checks\nit at runtime and fails closed.\n\n- Extract the engine's fail-closed client-auth decision from\n  negotiateAuthMethod into the exported decideClientAuthMethod and add the\n  catalog predicates tokenAuthMethodsSupportPublicClient /\n  tokenAuthMethodsSupportConfiguredClient in packages/ai/src/mcp/oauth.ts —\n  the importer runs the SAME decision, so classification and the connect-time\n  gate share one source of truth.\n- Wire the gate into importer readiness: coherent DCR evidence with\n  confidential-only advertised methods now demotes honestly to the user-setup\n  OAuth path (requires your own OAuth app reason, registered-client\n  requirement, client-id/client-secret setup fields) instead of oauth-ready —\n  the user's own registered app, zero-app compliant, never an exclusion.\n  Advertised methods that serve not even a configured secret-bearing client\n  (mTLS-only) keep failing closed as today; omitted lists stay oauth-ready\n  per the engine's public-client spec default.\n- Regenerate catalog.json, catalog.data.generated.ts and import-report.json:\n  14 entries demote (airwallex, airwallex-sandbox, atlan, gitlab,\n  hugging-face, legalzoom, lusha, miro, monday-com, planetscale, supabase,\n  vercel, windsor-ai, zoominfo) — readiness counts move 71->57 oauth-ready and\n  53->67 user-setup; total 124 and zero prime-restricted/unknown invariants\n  hold, each entry carrying its confidential-only evidence and note.\n- Document tokenAuthMethods as required engine-compatibility capture in the\n  audit script and catalog README so future audits keep the check.\n- Tests: pin the hugging-face demotion with its confidential-only evidence and\n  the full demoted set, add the synthetic classification matrix\n  (confidential-only demotes, none/omitted stay one-click, mTLS-only stays\n  unknown) and direct predicate tests; update readiness count pins. The\n  byte-for-byte regeneration pin and the coding-agent eligibility thresholds\n  pass unchanged.\n\n* test(coding-agent): pin the MCP auth routes to the inline auth panel surface\n\nthe guarded-credential race test kept an unobserved showOverlay stub on the\nfake route TUI; it now asserts the generic /logout service selector never\nmounts an overlay popup, so MCP auth can only render through showAuthPanel\nlike #2331 provider logins. adds the changelog fragment documenting that\nevery MCP auth surface (guarded staged OAuth dialog, /login and /logout\nservice selectors, mcp-connections tab, /mcp login) mounts inline under\nthe chat with stacked closers, focus restore, and rows-aware sizing.\n\n* feat(ai): cut the catalog to one-click DCR or user token/key only (ENG-6108)\n\n2026-09-15 product decision (\"remove everything that's not one-click auth\nor api key\"): the shipped catalog advertises only one-click dynamic client\nregistration (readiness \"oauth-ready\") and user token/key entries; the\nclassification machinery and audit/engine parity are unchanged.\n\n- overrides.json: the 49 non-token/key entries — the 14 registered-client\n  entries whose authorization servers accept only secret-bearing client auth\n  (airwallex, airwallex-sandbox, atlan, gitlab, huggingface-skills,\n  legalzoom, lusha, miro, monday-com, planetscale, supabase, vercel,\n  windsor-ai, zoominfo), the 32 local-runtime stdio adapters and the 3\n  url-only tenant templates (activecampaign, jfrog, pigment) — are excluded\n  via the documented excludedServers list: one entry per upstream record\n  (64 keys: monday-com/supabase/vercel are merged from both upstreams, so\n  both sides are cut; every stdio server of the multi-server adapter plugins\n  is excluded), each with a per-entry reason citing the decision and the\n  specific evidence. The now-dead servers overrides for excluded identities\n  were removed; their honesty content lives on in the exclusion reasons.\n- Importer: the cut is enforced structurally — buildCatalog refuses to emit\n  a user-setup entry whose requirement is not token/key-shaped\n  (bearer-token/api-key credentials, a tenant config with a genuine non-url\n  field, or a legacy-transport entry that still collects a token/key) and\n  fails with a curation prompt, so a registered-client demotion, a\n  local-runtime adapter or a url-only template can never silently re-derive.\n  The auth-methods honesty machinery (decideClientAuthMethod parity,\n  confidential-only demotion, tokenAuthMethods capture) is unchanged and\n  stays active for the survivors.\n- Audit store and source snapshots: untouched — evidence for the excluded\n  endpoints stays committed as history.\n- Regenerated catalog.json + catalog.data.generated.ts + import-report.json\n  via the importer; counts: total 124 -> 75 (http 86 -> 72, templated 5 -> 2,\n  sse 1 unchanged, stdio 32 -> 0), ready 57 unchanged, requires-setup 67 ->\n  18, oauth-ready 57, user-setup 18, prime-restricted 0, unknown 0 (sum\n  exact); api-key strategy 32 -> 16.\n- Tests: mcp-catalog.test.ts pins the cut (all 49 ids absent, both upstream\n  sides of merged providers excluded, all 64 keys documented in the import\n  report with 2026-09-15 reasons, source snapshots and audit evidence kept,\n  the shipped user-setup set is exactly the 18 token/key entries), keeps the\n  confidential-only machinery matrix (now pinned on the committed\n  huggingface-skills audit evidence plus the synthetic matrix), adds the\n  structural invariant regression (lifting the gitlab exclusion fails the\n  import with the curation prompt), updates the count assertions (75/57/18/\n  0/0) and keeps the byte-for-byte regeneration pin; coding-agent\n  mcp-service-catalog count comment + eligibility sweep thresholds updated\n  for the 75-entry catalog (api_key >= 10 still holds at 16; unknown 53).\n\nOffline verification: ai catalog suite 29/29, ai mcp-oauth 40/40, all 13\ncoding-agent mcp test files 276 passed 1 skipped (catalog eligibility 12/12,\nservice catalog 63/63), tsgo --noEmit clean at the repo root, biome clean on\nthe changed files.\n\n* fix(tui): separate the oauth url from the browser-step text with a blank line\n\n* fix(tui): keep the service-catalog picker at one description line with stable frames\n\n* feat(tui): persist MCP connect outcomes as refinement-style chat entries (ENG-6108)\n\nConnect outcomes (\"Connected Linear (12 tools verified)\" and its\nsaved-but-unverified variants) were transient status lines that vanished;\nthey now persist in the chat transcript like harness refinement notices.\n\n- Add the mcp_connection_outcome custom message with structured details\n  (label, login/retry source, connected/unverified/unsaved verification\n  state, tool count, account id, activation) and the exact legacy wording\n  as its content; keep it out of LLM context like refinement outcomes.\n- Render it with a purple refinementHeader \"◆ Connected <service> · N\n  tools verified\" header over a refinementSummary body via the\n  ExpandableEventMessage base; register live rendering and transcript\n  replay (malformed entries included) and gate both on display.\n- Route both emit sites (pending-account retry verification and the\n  guarded login completion) and their failure/partial variants through\n  completeMcpConnectionOutcome: reload, then append the durable entry via\n  the new AgentConnection.appendCustomMessage (in-process sendCustomMessage,\n  daemon legacy append_custom_message RPC). Mid-turn connects keep the\n  transient \"will activate automatically\" line and record the durable\n  entry at the next safe boundary; a failed reload marks the entry\n  \"not active in this session\". Pre-outcome login failures (eligibility,\n  claim, finalize, incomplete login) remain transient warnings.\n- Focused tests: component rendering/replay, formatter wording parity,\n  and both emit sites including queued-boundary, inactive, and\n  append-failure fallback paths.\n\n* fix(tui): flatten multi-line catalog copy before it becomes a picker line\n\n* fix(tui): repair /mcp picker chrome nits and search ranking (ENG-6108)\n\nFive chrome nits from Kevin's live testing plus the picker search:\n\n- The scroll counter aligns with the row indent (rows render their label\n  at column 2; the counter and the empty-state message now do too).\n- Enter on an accounts-picker row 1 (the account name) re-verifies the\n  account instead of disconnecting it; only the explicit Remove row\n  removes. connectServiceFromPicker's connected branch now re-verifies\n  exactly like the pending branch.\n- One blank line between the last row and the description line in both\n  catalog and accounts mode, budgeted in updateLayout so frames stay\n  height-stable.\n- Accounts search matches identity only (account label + connection\n  id): every account row shares the same description/setup hint, so\n  matching that text could never filter anything.\n- Every inline MenuPanel opens with exactly one separator rule between\n  the chat view and the picker: a titled panel draws the rule above its\n  title; a headerless panel keeps the bordered search's top border as\n  that rule, never both. Model/provider/oauth/extension/prime-team\n  pickers budget the rule through the shared inlineMenuPanelTopRuleRows\n  helper.\n- Search ranking rewritten: exact/prefix/word-start/substring matches on\n  label, service id, and aliases rank far above description/setup-hint\n  text; the identity-only subsequence fallback requires a consecutive\n  run of half the query (minimum two); descriptions match only as\n  word-start/substring. Searching vercel against a catalog without\n  Vercel now yields the No-matching-services empty state instead of\n  eight unrelated rows matched through setup-hint boilerplate.\n\n* fix(mcp): cut non-token catalog survivors and say what to paste\n\n2026-09-16 product decision, from live picker testing: the catalog ships\none-click DCR connectors and simple paste-an-API-key/token services only.\n\nCut 5 survivors with documented per-entry reasons in overrides.json:\n- cockroachdb (cockroach-labs): tenant config, only input is the\n  per-cluster `mcp-cluster-id` header, no key/token field\n- dynatrace, sourcegraph: tenant instance URL next to the token\n- paypal-sandbox: legacy SSE, the runtime cannot connect to it at all\n- render: api-key requirement with zero setup fields, nothing to paste\n\nThe importer now enforces the narrower rule structurally: a user-setup\nentry ships only when its requirement is bearer-token or api-key AND it\ncollects at least one bearer-token/api-key field. An entry the readiness\npass never classified also fails closed instead of slipping past every\nshipping guard.\n\nAll 13 surviving setup reasons are now picker copy for a human: one line,\nstarting with \"paste\", naming the entry's real field. \"requires provider\ncredentials supplied as headers\" and \"requires an auth token supplied via\nenvironment variable\" are gone; github no longer stutters the same clause\ntwice; zoom-meetings drops the upstream placeholder note that never\nchanged what the user does. A test pins the shape.\n\nCatalog: 75 -> 70 entries (57 oauth-ready, 13 user-setup), all plain\nstreamable-http. Evidence, source snapshots and audit store unchanged.\n\nENG-6108\n\n* fix(tui): drop the restated MCP connect body and add disconnect feedback\n\nKevin saw the durable connect entry print the same sentence twice: the\nheader and the body both said \"Connected Granola (6 tools verified)\".\nThe header is the outcome line, so the body now carries ONLY what the\nheader omits - added account, verification issue plus next step, deferred\nactivation - and a plain success renders as the header alone. The\npersisted `content` keeps the full legacy sentence, because the transient\nfallback and status lines still need a whole sentence.\n\nDisconnects had no durable feedback at all. A successful disconnect from\n/plugins, `/mcp logout <name>`, or the generic `/logout` route now leaves\nthe same kind of entry, in the muted theme key: not the connect purple (a\ndisconnect is no refinement) and not the error red (it succeeded) - the\ngrey /plugins already uses for \"Not connected\". Only outcomes that really\nremoved the credential (removed, credential-only, preserved) get an\nentry; \"logged-out\" (partial save failure), \"failed\", \"missing\", and the\nstate-neutral \"refused\" keep their honest warnings and record nothing, so\nno entry can claim a disconnect that did not finish.\n\nThe generic /logout route still runs ONE store op and ONE reload: the\nhost records the outcome under its existing delegation and the selector\nappends it after the reload it already did.\n\nENG-6108\n\n* fix(tui): record the picker disconnect entry on the remove row\n\n* fix(tui): rebuild the /mcp accounts menu as a choice list (ENG-6108)\n\nKevin's live-testing redesign: the accounts menu drops its no-op search box\nand account-name row, renders '<service> MCP' with the muted description\n(wrapped, capped at three lines) above the options, and lists Reconnect /\nDisconnect <id> / Add another account in the PR #2340 selection language\n(mirrored locally until #2340 lands). Reconnect keeps the existing re-verify\npath and never disconnects; Disconnect keeps the store-locked removal and\nits durable disconnected entry.\n\nCatalog picker nits: the Connect trailing status reads in the text colour\ninstead of the accent purple, and the empty state gains one blank row above\nthe shortcuts line, aligned with the row labels (pinned at width 120).\n\n* fix(tui): stop inline pickers doubling the separator rule\n\n* feat(mcp): connect paste-a-key catalog services through an inline masked paste panel (ENG-6108)\n\n* fix(mcp): collapse the paste flow to ONE credential per service, cut named-header pairs (ENG-6108)\n\nTwo Bugbot findings, one root cause: the generic MCP runtime sends exactly\none Authorization: Bearer per connection, but the paste flow treated every\nrequired credential field as a separate mandatory prompt, and GitHub's two\nsetup fields (GITHUB_PAT_TOKEN / GITHUB_PERSONAL_ACCESS_TOKEN) were presented\nas two required tokens when they are alternative names for one PAT.\n\n- Curate GitHub's fields as alternatives via a shared field-level\n  credentialSet (\"github-pat\") in mcp-catalog/overrides.json; the paste flow\n  now prompts ONCE, labels honestly (\"GitHub personal access token\") and\n  stores the value under the first alternative's id.\n- Cut datadog and cloudinary-mediaflows from the catalog (documented\n  excludedServers reasons citing the named-header evidence: DD_API_KEY +\n  DD_APPLICATION_KEY, cld-api-key + cld-secret - one bearer can never\n  authenticate them). Catalog: 68 entries = 57 one-click DCR + 11 paste.\n- The importer now throws when a shipped requires-setup entry collects more\n  than one distinct required credential, so an unmarked multi-credential\n  entry can never silently re-derive; tests pin the guard by lifting the\n  datadog and cloudinary exclusions.\n- Simplify the host flow to one prompt/one value (no multi-field loop, no\n  per-field checkmark rows); masking, Esc-cancels-nothing-stored, the\n  empty-value guard, verification and the durable Connected outcome are\n  kept; services with genuinely distinct credentials stay honest\n  setup_required and are not pasteable.\n\n* fix(mcp): drop the dead paste-credential branch and trim the importer comment\n\n* fix(tui): render paste outcomes honestly and polish the accounts menu\n\n* fix(tui): budget the accounts frame for the trailing blank row\n\n* fix(tui): keep the /mcp picker chain open after connect, disconnect, and paste actions\n\nSelecting a row no longer drops the user back to the prompt after the action: the picker chain re-enters the right surface, rebuilt from the live catalog and connection store. Disconnecting one account reopens that service accounts menu without the removed row; disconnecting the last account, or a cancel that stored nothing, reopens the catalog; reconnect/re-verify, add-account, and paste re-enter the accounts menu with refreshed state. Esc closes the whole chain, and actions blocked before they start (login in progress, guidance, target drift) end the chain with their status line instead of re-opening, so there is no re-entry loop.\n\n* fix(tui): drop the accounts description instead of overflowing tight viewports\n\n* fix(tui): one reconnect/disconnect row per service with an account sub-picker, and left-arrow back to the catalog\n\nA service's accounts menu is now exactly three rows — Reconnect, Disconnect, Add another account — instead of a reconnect/disconnect pair per connection id. With one account, Enter acts on it directly with the existing re-verify and remove semantics. With several accounts, Enter on Reconnect or Disconnect opens a second inline picker in the same choice-list shape that lists the account ids; picking one runs the action on that connection id only, and Esc or left there returns to the accounts menu without acting. The sub-picker never nests deeper, and after an action the existing re-entry table decides the next surface (the accounts menu while an account survives, the catalog otherwise).\n\nLeft arrow from the accounts page now navigates back to the /mcp catalog — the picker chain's parent surface — remounted fresh, using the same app.modal.back binding the dialogs share; Esc still closes the whole chain, and left in the catalog stays inert. The accounts frame budget is unchanged (the option count is the only thing that grows), the budget test now pins the three-row count, and the multi-account re-entry tests drive the sub-picker end to end.\n\n* fix(tui): colour mcp outcome entries by outcome, warning for non-success\n\n* fix(mcp): keep alias OAuth providers behind the parent service catalog classification (ENG-6108)\n\n* fix(mcp): probe the origin-level oauth-protected-resource document without the endpoint query\n\n* test: bring ENG-6108 suites into the main-branch testing policy (#2336)\n\nShrink the branch's test additions from a net 16,514 to 16,610? -> net 11,610\ntest lines (the same as the branch's source additions), clear all 46 new\ntest-policy pattern violations, and consolidate per the policy's \"one file\nper module, regressions live in the owning suite\" rules. No test survives\non a timer, poll, sleep, skip, or env gate; every wait resolves on a\nconcrete deferred signal (mount hooks, probe gates, store flushes).\n\nFolded per-issue regression files into the owning module suites:\n- suite/regressions/eng-6108-inline-picker.test.ts -> the picker-chain\n  describe in test/service-catalog-picker.test.ts (mount/stale/replacement\n  settling, action routing, re-entry, settings-actions freeze, paste flow,\n  blocked actions) with vi.waitFor replaced by ui.setFocus-mount and\n  action-start deferred signals; the pure row-shape/menu layout pins\n  already covered by the component tests were deleted.\n- suite/regressions/eng-6108-service-catalog-activation.test.ts -> the\n  connect-then-activate end-to-end test in test/agent-session-services\n  .test.ts; the stored-token-pending duplicate died (already pinned in\n  mcp-service-catalog).\n\nDissolved test/mcp-account-commit-safety.test.ts; its unique invariants\nmoved to the owning suites and the rest were duplicates:\n- store->auth gap interleave + finalize nonce ownership + no-resurrection\n  -> test/mcp-connection-store.test.ts\n- CAS-absence replaceStagedCredential -> test/auth-storage.test.ts\n- /mcp login on a PENDING account, vanished-source repair (record+grant\n  evidence; bare shell refuses), and the paste-flow seam (single-credential\n  static token, cancelled/empty value, login-in-progress and target-changed\n  refusals) -> test/mcp-activation-queue.test.ts.\n\nConsolidated near-identical seams (surviving test -> invariant it owns):\n- grant-state matrix pinned ONCE in mcp-catalog-eligibility (predicate +\n  prompt + dispatch + view parity); manager's copy deleted.\n- reserved-name ownership pinned at dispatch level in mcp-manager; the\n  view-level copy and mcp-service-safety's provider-lifecycle duplicate\n  deleted.\n- cap protection pinned in mcp-service-catalog (resolver's own module);\n  mcp-catalog-eligibility's copy deleted.\n- remove/logout-vs-finalize races pinned once at the REAL route seam in\n  mcp-activation-queue; the store-level interleave duplicate deleted.\n- exact rendered copy kept only where it is a durable protocol contract\n  (outcome notice wording); component render pins made structural.\n- oauth client-auth negotiation + PRM-mismatch refusals + python discover\n  cursor/table families -> it.each/subTest tables.\n\nViolation conversions (all 46 cleared):\n- wall-clock-timer/poll/sleep: setFocus-mount signals, action-start\n  deferreds, queueVerifyResult+flush chains, an asyncio.Event hang, and\n  fs.watch for the multi-process ready barrier.\n- environment-gated-path: the 11 false positives in mcp-oauth (mock route\n  conditions carrying token/credential substrings) renamed via aliases;\n  the rest made unconditional.\n- explicit-test-timeout: allowed with policy comments only where the\n  probe's own timeout bound IS the behavior under test (probe hang tests,\n  real multi-process spawn).\n- conditional-or-disabled-test: kernel-bootstrap made unconditional\n  (file-scoped venv resolution, no cwd dependence; merge of main's #2336\n  had dropped the branch's theme bootstrap in menu-panel too - restored).\n\nVerified: every modified suite passes standalone and under 6 shuffle\nseeds; npm run check (biome + check:test-policy + tsgo + installer +\nbrowser-smoke) is green; spot-reverts of the chain re-entry rule and the\nstore finalize-ownership guard both fail the consolidated tests.\n\n* fix(mcp): mirror the engine audience rule and first-issuer selection in the audit\n\n* fix(mcp): fail closed on a malformed advertised issuer and fix the notion URL substring check"},{"name":"mistral-reasoning-mode.test.ts","kind":"file","size":3994,"lastCommitHash":"cf07c5a3f5eca98e7744f2df83050044c920252a","lastCommitWhen":"2026-09-16T16:28:13-04:00","lastCommitMessage":"delete dead tests and fix the races the flaky ones were hiding (#2336)\n\n* add an objective testing policy to AGENTS.md\n\n* fix flaky daemon supervisor monitor test\n\nThe supervisor availability check is a real async chain (registry stat,\nsocket probe, replacement launch) started from a timer callback, so the\ntest drove a bounded fake-timer pump and asserted on a probe counter.\nUnder a loaded CI shard the chain did not finish inside the iteration\nbudget, and the variant mixing fake timers with a real probe promise\ncould deadlock for the full 30s test timeout.\n\nExpose a settled promise per armed availability check and await it in\nthe tests, so each assertion runs after the check finished instead of\nafter an arbitrary number of clock advances.\n\n* remove vitest retry masking from ai and attach-image tests\n\nDeleted all 548 `retry:` options in packages/ai/test and the 2 in\nkernel-attach-image-skill.test.ts. Retries hid non-determinism instead of\nfixing it, so a broken code path could still go green.\n\n- Deleted 17 live-only cross-provider E2E matrices whose every case sits behind\n  skipIf(!API_KEY) and never runs in CI; stream.test.ts stays as the survivor\n  that owns the provider table.\n- Stripped the retry option from the 198 stream.test.ts cases and dropped the\n  live E2E describe (plus its now-unused helpers) from\n  anthropic-thinking-disable.test.ts, keeping its mocked payload contract.\n- Removed retry: 1 from the two attach-image kernel cases; they pass without it.\n\nMocked wire/SSE contract tests are untouched. Tests only, no product code.\n\n* make agent trace upload tests deterministic\n\nThe suite pumped a synthetic clock with advanceTimersUntil() and hoped real\nfs and promise work settled inside a 200-step budget, asserted schedule\ndelays through a global setTimeout spy whose fake clock had drifted, and\nremoved its temp dir while catch-up and cursor writers were still running.\nUnder a loaded CI shard that produced \"Timed out advancing fake timers\",\n\"expected 1000 to be 60000\" and \"ENOTEMPTY rmdir /tmp/agent-traces-test-*\".\n\nThe upload scheduler now reports the delay it arms and the outcome of each\ncycle, the upload reports every wait it arms before the next request, and\ninstallAgentTraceUpload returns a handle that resolves when the startup\ncatch-up and any in-flight upload have finished writing. Tests await those\nsignals and advance the fake clock by the exact reported delay, and teardown\nwaits for in-flight writers before removing the temp dir.\n\nThe ~15 retry, backoff and Retry-After variants collapse into one\ntable-driven it.each, per the MERGE verdict: 1569 -> 1141 lines, 44 -> 27\ntest blocks, with no lost coverage.\n\n* make the compiled artifact and installer probe tests deterministic\n\nThe compiled-artifact afterEach polled for supervisor exit with the same\n10s budget as vitest's hook timeout, so the poll could never report on the\nslower standalone runners. The teardown now escalates to SIGKILL and every\ninner deadline stays below the surrounding hook and test budgets.\n\nnative-probe-timeout decided pass/fail from wall-clock deadlines around a\nreal 10s installer probe. The installer probe deadline is now injectable\nthrough PRIME_AGENT_PROBE_TIMEOUT_SECONDS, the blocked probe records the\ninstall lock itself, and the spawn deadlines are gone.\n\n* fix daemon shutdown admission loss during slow scans\n\nshutdown --force holds a 5s admission lease refreshed by a 1s timer, but it\nblocks its own event loop in synchronous ps/lsof/ss scans. On a loaded runner a\nscan outlasts the lease, the elapsed record is treated as abandoned, and the\nholder's next assertOrRenew throws \"Daemon shutdown admission was lost\".\n\n- A late renew re-arms a record that is still ours; only a missing or foreign\n  record ends the admission.\n- A renew that could not read the registry no longer retires the lease.\n- isDaemonShutdownAdmissionActive is read-only, so a bystander probe cannot\n  delete a live holder's record.\n- stopHiddenSupervisors renews before the blocking scan.\n\nThe 4603 regression drops its 11s sleep for a post-shutdown listener assertion\nand uses mkdtemp for the child TMPDIR.\n\n* delete 148 dead test files\n\nRemoves test files judged CUT by a full 480-file audit: duplicates of a named survivor, mock-asserting tests, rendered-copy assertions, private-internals casts, and live-API matrices behind skipIf(!API_KEY) that never ran in CI.\n\n* merge interactive-mode and agents-view test suites\n\n* merge tui render, overlay and helper test suites\n\n* test: slim daemon-mode and agent-connection-daemon suites\n\ndaemon-mode: keep passive hydration/passivation, delete_subagent durability, agent-message concurrency and rate limits, attach-snapshot backpressure; drop per-race internal regressions already covered process-level by daemon-supervisor-process.\nagent-connection-daemon: keep reconnect, update-restart, chunked-snapshot assembly and disposal races; drop tautological daemon-protocol pass-through cases.\n\n* merge tui editor, markdown and autocomplete test suites\n\n* test: merge audited session-core test bloat\n\nExecute MERGE verdicts from the 480-file test audit for the agent-session\ncore suites: collapse near-identical blocks into it.each tables, drop\nmock-return/rendered-copy assertions and private-cast white-box cases,\nand fold one-off files into the owning suite.\n\nDeleted (folded into their owning suite):\n- agent-session-concurrent.test.ts, suite/agent-session-action-races.test.ts,\n  suite/agent-session-action-contracts.test.ts -> suite/agent-session-queue.test.ts\n- suite/agent-session-compaction-continuation.test.ts,\n  suite/agent-session-compact-skill.test.ts -> suite/agent-session-compaction.test.ts\n- agent-session-runtime-events.test.ts -> suite/agent-session-runtime.test.ts\n\nPreserved: process boundaries (daemon RPC, ACP), on-disk formats,\nconcurrency/ordering, crash/restart/resume and load coverage.\n\n* address review: octal probe timeout, truncated deadline, dead schedule field\n\n* test: merge redundant coding-agent test cases into case tables\n\nExecutes the MERGE verdicts from the 480-file test-bloat audit for the\nmisc lanes. Repeated near-identical blocks collapse into single it.each\ncase tables, and ticket-numbered one-off files fold into the owning\nmodule suite.\n\nRemoved throughout the touched files: assertions on mock return values,\nassertions on rendered text/copy, `as unknown as` casts into privates,\nand suites gated behind skipIf(!API_KEY) (which never ran in CI).\n\nPreserved: process boundaries (daemon RPC, ACP), on-disk formats,\nconcurrency and ordering, crash/restart/resume, and load.\n\nDeleted files, folded into their module suite:\n- compaction-extensions -> deleted outright (whole file behind skipIf(!API_KEY))\n- compaction-serialization -> compaction\n- heartbeat-catalog -> daemon-client\n- child-process -> exec\n- edit-tool-legacy-input -> tools\n- kernel-goal-skill, kernel-rlm-heartbeat-skill -> kernel-agent-message-skill\n- kernel-agent-observe-skill -> kernel-attach-image-skill\n- kernel-windows-process -> kernel-bootstrap-windows\n- extensions-input-event -> extensions-runner\n- sdk-skills -> sdk-session-manager\n- session-manager/{agent-status,has-user-content} -> session-manager/session-state\n- session-manager/migration -> session-manager/file-operations\n- session-manager/custom-session-id -> session-manager/tree-traversal\n\n* slim ai + regression tests (lanes A/B/D/E)\n\nExecute MERGE verdicts from the test audit for packages/ai and the\nupdate-restart / snapshot / session-view regression files.\n\n- fold ticket-numbered regression cases into the owning suites\n- collapse near-identical blocks into it.each tables\n- drop mock-return, rendered-copy and live-API-gated assertions\n\n* test: collapse package-manager tables and fold small daemon selector suites\n\npackage-manager: git-URL parsing, top-level/manifest/package glob filters and npm install-argv cases are now table-driven.\ndaemon-session-id: absorbs daemon-catalog-process selector case, drops display-id formatting trivia.\ndaemon-worker-windows-timeouts: absorbs the connection-deadline budget cases from daemon-worker-connect.\ndaemon-catalog-startup: drops the src-directory one-off.\n\n* test: collapse refinement, settings and config suites into case tables\n\nFinal misc lane of the test-bloat audit.\n\n- refinement: per-kind create/update/delete becomes one it.each lifecycle;\n  8 rejection suites become one 18-row invalid-edit table that also asserts\n  state and the refinement log stay untouched; truncation/parse errors,\n  scope permutations, ranking and the tokenizer each become one table.\n  System-prompt and user-prompt copy assertions removed.\n- settings-manager: per-setting default getters removed; unknown-key\n  preservation, invalid-file guards and project-vs-global precedence kept.\n- config: install-method detection becomes one table; session-dir env\n  permutations collapse into one precedence test.\n- builtin-skills, repl-kernel-abort, session-cwd, truncate: repeated blocks\n  collapsed; one ReplInternals reach-in dropped.\n- child-process folds into exec as one process lifecycle suite.\n\n* slim regression tests (lane C)\n\nFold the remaining ticket-numbered regression files into the owning\nmodule suites and collapse duplicate cases into it.each tables.\n\n- 19 regression files deleted after their kept cases moved into\n  agent-session-queue, auth-storage, acp-features, resource-loader,\n  agent-session-runtime/compaction/retry-events/recursion,\n  model-registry, slash-commands, daemon-supervisor-process\n- 3 files slimmed in place where the named target no longer exists\n- drop rendered-copy, mock-return and private-cast assertions\n\n* test: collapse daemon protocol, command, list, ps and package-command suites\n\ndaemon-protocol: two gating tables replace 16 near-identical capability/schema cases.\ndaemon-command: table-driven argv parsing plus the --goal leak guards; drops help/usage copy assertions.\ndaemon-session-list: activity, recap and model-fallback projections are table-driven.\ndaemon-ps: keeps planReap/planShutdownAll safety rules, drops ss/lsof parsers, sorting and uptime trivia.\ndaemon-stop-confirm: one busy-guard table, no prompt copy.\npackage-command-paths: one shared self-update fixture for the install-spec cases; drops help and removed-flag copy.\nacp-events: keeps only the cases the ACP suite does not cover end to end.\ndaemon-session-summarizer: one recap/status parse table.\ndaemon-extension-binding: keeps the duplicated-partial-message strip.\n\n* test: tighten the daemon stop-confirm busy-guard table\n\n* fix ci: biome forEach body, vacuous autocomplete case, missing prompt before second compaction\n\n* fix ci: restore escaped template literals in prompt-template cases\n\n* fix codeql: single-pass path escaping in test helpers\n\n* address review: flush debounced trace uploads, restore probe timeout guards, drop dead test scaffolding\n\n* respect retry-after and throttle window when flushing trace uploads\n\n* await in-flight trace uploads before a drain returns\n\n* extend deterministic test policy to python\n\n* harden deterministic test policy checks\n\n* close test policy edge cases\n\n* finish deterministic policy edge coverage\n\n* fix policy lexer and macos signature setup\n\n* mask regex literals in test policy checks\n\n* distinguish postfix division in policy lexer\n\n* close native migration signal race\n\n* keep native migration force timer owned\n\n---------\n\nCo-authored-by: prime-agent <agent@local>"},{"name":"oauth.ts","kind":"file","size":1887,"lastCommitHash":"032e3ee74574ca16efaf8745a1394b821256a5d0","lastCommitWhen":"2026-08-18T12:17:35+02:00","lastCommitMessage":"chore: remove redundant comments and unused internals (#1505)\n\n* chore: remove redundant comments\n\n* chore(tui): remove redundant export comments\n\n* chore(coding-agent): remove redundant example comments\n\n* chore(ai): remove redundant comments\n\n* chore(coding-agent): remove obsolete core comments\n\n* chore(coding-agent): remove redundant test comments\n\n* chore(coding-agent): remove redundant test comments\n\n* chore(coding-agent): remove redundant rpc test comments\n\n* chore(coding-agent): remove redundant CLI comments\n\n* chore(agent): remove redundant comments\n\n* chore(tui): remove redundant source comments\n\n* chore(coding-agent): remove redundant mode comments\n\n* chore(coding-agent): remove redundant mode comments\n\n* chore(coding-agent): remove redundant test comments\n\n* chore(ai): remove redundant source comments\n\n* chore(coding-agent): remove redundant session comments\n\n* chore(coding-agent): remove redundant core comments\n\n* chore(coding-agent): remove redundant test comments\n\n* chore(tests): remove redundant test comments\n\n* chore: remove unused internal helpers\n\n* docs: restore public API contracts\n\n* chore(coding-agent): restore invariant documentation\n\n* chore(coding-agent): clarify agent family contracts\n\n* style(coding-agent): format restored contracts\n\n* fix: restore intentional catch explanations"},{"name":"openai-codex-stream.test.ts","kind":"file","size":61181,"lastCommitHash":"79ad21b7e0b08ad3c0c3bdee2691e259ce86bfa7","lastCommitWhen":"2026-09-17T07:01:56+03:00","lastCommitMessage":"fix(ai,coding-agent): stop retrying a depleted account and refuse the spawn (R2, R1)\n\n429 quota exhaustion was classified as a transient hiccup, so swarms looped 70+\ntimes into a hard wall (01a08f07, 01a0a1ab produced 405 turn stop errors\nagainst exhausted accounts) and 8 children were stillborn at turn 0.\n\n- a 429 whose provider text names account depletion (quota, credit, billing)\n  is now the permanent kind `quota_exhausted`; a keyword-free 429 stays\n  `rate_limit` and keeps its backoff. The keyword test runs only inside the\n  rate-limit branch, so a 400 that merely says \"quota\" stays invalid_request\n- `isPermanentProviderFailureKind` treats it as permanent, so the retry loop\n  stops instead of hammering depletion\n- a draining response trips a rolling in-memory provider breaker\n  (`blockedUntilMs` from the provider's retry hint, else 60s), and\n  `ModelRegistry.assertRlmSpawnAdmission` refuses a child at turn 0 with a\n  typed `RlmSpawnAdmissionError` (reason `quota_exhausted` or\n  `auth_unconfigured`) before any child directory, session, or provider request\n- `rlm.models()` reports tripped providers under the reserved `exhausted` key,\n  keeping its `Record<string, string[]>` contract; the runtime shim degrades to\n  [] when the key is absent\n- in-stream provider error paths (anthropic SSE, responses error/response.failed)\n  now pass the provider's own text to the classifier; they previously passed\n  only the error type, which hid the audited Alibaba-style exhaustion message\n\nLocal state only: no new daemon command, event, or payload shape, and no\nnetwork request in the preflight. Tests: packages/coding-agent/test/suite/\nprovider-quota-circuit-breaker.test.ts (10) and subagent-admission-preflight.test.ts\n(6, including a turn-0 refusal through runRlmChild); packages/ai stream-failure\nand openai-codex-stream (78).\n"},{"name":"openai-completions-cache-control-format.test.ts","kind":"file","size":6764,"lastCommitHash":"cf07c5a3f5eca98e7744f2df83050044c920252a","lastCommitWhen":"2026-09-16T16:28:13-04:00","lastCommitMessage":"delete dead tests and fix the races the flaky ones were hiding (#2336)\n\n* add an objective testing policy to AGENTS.md\n\n* fix flaky daemon supervisor monitor test\n\nThe supervisor availability check is a real async chain (registry stat,\nsocket probe, replacement launch) started from a timer callback, so the\ntest drove a bounded fake-timer pump and asserted on a probe counter.\nUnder a loaded CI shard the chain did not finish inside the iteration\nbudget, and the variant mixing fake timers with a real probe promise\ncould deadlock for the full 30s test timeout.\n\nExpose a settled promise per armed availability check and await it in\nthe tests, so each assertion runs after the check finished instead of\nafter an arbitrary number of clock advances.\n\n* remove vitest retry masking from ai and attach-image tests\n\nDeleted all 548 `retry:` options in packages/ai/test and the 2 in\nkernel-attach-image-skill.test.ts. Retries hid non-determinism instead of\nfixing it, so a broken code path could still go green.\n\n- Deleted 17 live-only cross-provider E2E matrices whose every case sits behind\n  skipIf(!API_KEY) and never runs in CI; stream.test.ts stays as the survivor\n  that owns the provider table.\n- Stripped the retry option from the 198 stream.test.ts cases and dropped the\n  live E2E describe (plus its now-unused helpers) from\n  anthropic-thinking-disable.test.ts, keeping its mocked payload contract.\n- Removed retry: 1 from the two attach-image kernel cases; they pass without it.\n\nMocked wire/SSE contract tests are untouched. Tests only, no product code.\n\n* make agent trace upload tests deterministic\n\nThe suite pumped a synthetic clock with advanceTimersUntil() and hoped real\nfs and promise work settled inside a 200-step budget, asserted schedule\ndelays through a global setTimeout spy whose fake clock had drifted, and\nremoved its temp dir while catch-up and cursor writers were still running.\nUnder a loaded CI shard that produced \"Timed out advancing fake timers\",\n\"expected 1000 to be 60000\" and \"ENOTEMPTY rmdir /tmp/agent-traces-test-*\".\n\nThe upload scheduler now reports the delay it arms and the outcome of each\ncycle, the upload reports every wait it arms before the next request, and\ninstallAgentTraceUpload returns a handle that resolves when the startup\ncatch-up and any in-flight upload have finished writing. Tests await those\nsignals and advance the fake clock by the exact reported delay, and teardown\nwaits for in-flight writers before removing the temp dir.\n\nThe ~15 retry, backoff and Retry-After variants collapse into one\ntable-driven it.each, per the MERGE verdict: 1569 -> 1141 lines, 44 -> 27\ntest blocks, with no lost coverage.\n\n* make the compiled artifact and installer probe tests deterministic\n\nThe compiled-artifact afterEach polled for supervisor exit with the same\n10s budget as vitest's hook timeout, so the poll could never report on the\nslower standalone runners. The teardown now escalates to SIGKILL and every\ninner deadline stays below the surrounding hook and test budgets.\n\nnative-probe-timeout decided pass/fail from wall-clock deadlines around a\nreal 10s installer probe. The installer probe deadline is now injectable\nthrough PRIME_AGENT_PROBE_TIMEOUT_SECONDS, the blocked probe records the\ninstall lock itself, and the spawn deadlines are gone.\n\n* fix daemon shutdown admission loss during slow scans\n\nshutdown --force holds a 5s admission lease refreshed by a 1s timer, but it\nblocks its own event loop in synchronous ps/lsof/ss scans. On a loaded runner a\nscan outlasts the lease, the elapsed record is treated as abandoned, and the\nholder's next assertOrRenew throws \"Daemon shutdown admission was lost\".\n\n- A late renew re-arms a record that is still ours; only a missing or foreign\n  record ends the admission.\n- A renew that could not read the registry no longer retires the lease.\n- isDaemonShutdownAdmissionActive is read-only, so a bystander probe cannot\n  delete a live holder's record.\n- stopHiddenSupervisors renews before the blocking scan.\n\nThe 4603 regression drops its 11s sleep for a post-shutdown listener assertion\nand uses mkdtemp for the child TMPDIR.\n\n* delete 148 dead test files\n\nRemoves test files judged CUT by a full 480-file audit: duplicates of a named survivor, mock-asserting tests, rendered-copy assertions, private-internals casts, and live-API matrices behind skipIf(!API_KEY) that never ran in CI.\n\n* merge interactive-mode and agents-view test suites\n\n* merge tui render, overlay and helper test suites\n\n* test: slim daemon-mode and agent-connection-daemon suites\n\ndaemon-mode: keep passive hydration/passivation, delete_subagent durability, agent-message concurrency and rate limits, attach-snapshot backpressure; drop per-race internal regressions already covered process-level by daemon-supervisor-process.\nagent-connection-daemon: keep reconnect, update-restart, chunked-snapshot assembly and disposal races; drop tautological daemon-protocol pass-through cases.\n\n* merge tui editor, markdown and autocomplete test suites\n\n* test: merge audited session-core test bloat\n\nExecute MERGE verdicts from the 480-file test audit for the agent-session\ncore suites: collapse near-identical blocks into it.each tables, drop\nmock-return/rendered-copy assertions and private-cast white-box cases,\nand fold one-off files into the owning suite.\n\nDeleted (folded into their owning suite):\n- agent-session-concurrent.test.ts, suite/agent-session-action-races.test.ts,\n  suite/agent-session-action-contracts.test.ts -> suite/agent-session-queue.test.ts\n- suite/agent-session-compaction-continuation.test.ts,\n  suite/agent-session-compact-skill.test.ts -> suite/agent-session-compaction.test.ts\n- agent-session-runtime-events.test.ts -> suite/agent-session-runtime.test.ts\n\nPreserved: process boundaries (daemon RPC, ACP), on-disk formats,\nconcurrency/ordering, crash/restart/resume and load coverage.\n\n* address review: octal probe timeout, truncated deadline, dead schedule field\n\n* test: merge redundant coding-agent test cases into case tables\n\nExecutes the MERGE verdicts from the 480-file test-bloat audit for the\nmisc lanes. Repeated near-identical blocks collapse into single it.each\ncase tables, and ticket-numbered one-off files fold into the owning\nmodule suite.\n\nRemoved throughout the touched files: assertions on mock return values,\nassertions on rendered text/copy, `as unknown as` casts into privates,\nand suites gated behind skipIf(!API_KEY) (which never ran in CI).\n\nPreserved: process boundaries (daemon RPC, ACP), on-disk formats,\nconcurrency and ordering, crash/restart/resume, and load.\n\nDeleted files, folded into their module suite:\n- compaction-extensions -> deleted outright (whole file behind skipIf(!API_KEY))\n- compaction-serialization -> compaction\n- heartbeat-catalog -> daemon-client\n- child-process -> exec\n- edit-tool-legacy-input -> tools\n- kernel-goal-skill, kernel-rlm-heartbeat-skill -> kernel-agent-message-skill\n- kernel-agent-observe-skill -> kernel-attach-image-skill\n- kernel-windows-process -> kernel-bootstrap-windows\n- extensions-input-event -> extensions-runner\n- sdk-skills -> sdk-session-manager\n- session-manager/{agent-status,has-user-content} -> session-manager/session-state\n- session-manager/migration -> session-manager/file-operations\n- session-manager/custom-session-id -> session-manager/tree-traversal\n\n* slim ai + regression tests (lanes A/B/D/E)\n\nExecute MERGE verdicts from the test audit for packages/ai and the\nupdate-restart / snapshot / session-view regression files.\n\n- fold ticket-numbered regression cases into the owning suites\n- collapse near-identical blocks into it.each tables\n- drop mock-return, rendered-copy and live-API-gated assertions\n\n* test: collapse package-manager tables and fold small daemon selector suites\n\npackage-manager: git-URL parsing, top-level/manifest/package glob filters and npm install-argv cases are now table-driven.\ndaemon-session-id: absorbs daemon-catalog-process selector case, drops display-id formatting trivia.\ndaemon-worker-windows-timeouts: absorbs the connection-deadline budget cases from daemon-worker-connect.\ndaemon-catalog-startup: drops the src-directory one-off.\n\n* test: collapse refinement, settings and config suites into case tables\n\nFinal misc lane of the test-bloat audit.\n\n- refinement: per-kind create/update/delete becomes one it.each lifecycle;\n  8 rejection suites become one 18-row invalid-edit table that also asserts\n  state and the refinement log stay untouched; truncation/parse errors,\n  scope permutations, ranking and the tokenizer each become one table.\n  System-prompt and user-prompt copy assertions removed.\n- settings-manager: per-setting default getters removed; unknown-key\n  preservation, invalid-file guards and project-vs-global precedence kept.\n- config: install-method detection becomes one table; session-dir env\n  permutations collapse into one precedence test.\n- builtin-skills, repl-kernel-abort, session-cwd, truncate: repeated blocks\n  collapsed; one ReplInternals reach-in dropped.\n- child-process folds into exec as one process lifecycle suite.\n\n* slim regression tests (lane C)\n\nFold the remaining ticket-numbered regression files into the owning\nmodule suites and collapse duplicate cases into it.each tables.\n\n- 19 regression files deleted after their kept cases moved into\n  agent-session-queue, auth-storage, acp-features, resource-loader,\n  agent-session-runtime/compaction/retry-events/recursion,\n  model-registry, slash-commands, daemon-supervisor-process\n- 3 files slimmed in place where the named target no longer exists\n- drop rendered-copy, mock-return and private-cast assertions\n\n* test: collapse daemon protocol, command, list, ps and package-command suites\n\ndaemon-protocol: two gating tables replace 16 near-identical capability/schema cases.\ndaemon-command: table-driven argv parsing plus the --goal leak guards; drops help/usage copy assertions.\ndaemon-session-list: activity, recap and model-fallback projections are table-driven.\ndaemon-ps: keeps planReap/planShutdownAll safety rules, drops ss/lsof parsers, sorting and uptime trivia.\ndaemon-stop-confirm: one busy-guard table, no prompt copy.\npackage-command-paths: one shared self-update fixture for the install-spec cases; drops help and removed-flag copy.\nacp-events: keeps only the cases the ACP suite does not cover end to end.\ndaemon-session-summarizer: one recap/status parse table.\ndaemon-extension-binding: keeps the duplicated-partial-message strip.\n\n* test: tighten the daemon stop-confirm busy-guard table\n\n* fix ci: biome forEach body, vacuous autocomplete case, missing prompt before second compaction\n\n* fix ci: restore escaped template literals in prompt-template cases\n\n* fix codeql: single-pass path escaping in test helpers\n\n* address review: flush debounced trace uploads, restore probe timeout guards, drop dead test scaffolding\n\n* respect retry-after and throttle window when flushing trace uploads\n\n* await in-flight trace uploads before a drain returns\n\n* extend deterministic test policy to python\n\n* harden deterministic test policy checks\n\n* close test policy edge cases\n\n* finish deterministic policy edge coverage\n\n* fix policy lexer and macos signature setup\n\n* mask regex literals in test policy checks\n\n* distinguish postfix division in policy lexer\n\n* close native migration signal race\n\n* keep native migration force timer owned\n\n---------\n\nCo-authored-by: prime-agent <agent@local>"},{"name":"openai-completions-reasoning-replay.test.ts","kind":"file","size":5994,"lastCommitHash":"03c3ca484fbaa7f610a185df65fd73b05599651a","lastCommitWhen":"2026-09-17T05:52:15+03:00","lastCommitMessage":"feat(coding-agent,runtime): rebase minimal runtime extensions on upstream 0.9.3\n"},{"name":"openai-completions-tool-choice.test.ts","kind":"file","size":43392,"lastCommitHash":"988e4f41dd25a6f3df9cfc66f45496d630be1969","lastCommitWhen":"2026-09-17T08:25:36+03:00","lastCommitMessage":"fix: reconcile the rebased fork with upstream's refactors\n\nSecond pass over the residue the rebase left behind: the tree now\ntypechecks and lints clean, and the touched suites pass.\n\n- finish the credential reconciliation (firstCredential readers, MCP\n  static tokens, prime-cli config read/write helpers and the private\n  prime-cli accessors the fork's call sites need)\n- restore dropped wiring: the bash.consumed host request, the MCP\n  discovery assertions in the kernel ready check, and the snapshot\n  extras (activity, tool use, previews, labels, staleness) on kernel\n  roster entries next to the fork's turn/token accounting\n- rebuild the interactive-mode class fields and the /reload + /usage +\n  /context dispatch, and restore the async-bash header snippet\n- re-merge the agents view on upstream's newer file instead of the\n  per-commit resolutions, so the fork's view model survives: the\n  actions pane and its renderSessionRows early return, compactSessionRows\n  over the raw allRows, the pinned/expanded row markers and the\n  completed/needs-input icons, the running-subagent rows, and the\n  model-plus-host row label. upstream's timer-batched catalog reconcile\n  and its rebuild-free tick loop are kept, with a live cache ttl counted\n  as work so the ttl keeps counting down; the tray label providers dropped\n  upstream's redundant inline-picker guard\n- skip the quota wait when an unblocked sibling credential exists, so\n  the fork's quick account rotation still wins over a long Retry-After\n- restore real timers in the compaction regression suite, which the\n  preceding fake-timer test left mocked, and hold the fork's contracts in\n  the queue suite (200-message ceiling, batched steering) and the 4649\n  name-reservation test\n- drop upstream's subagentDefaultModel suite and its inherit-parent case:\n  this fork keeps an explicit model= on every spawn\n- move the deferred-session-event tests back to top level and wait on\n  the connection's own status sequence instead of a wall-clock poll\n- keep the fork's lazy session-open and sqlite catalog paths as the\n  session-loading fast path\n"},{"name":"openai-responses-copilot-provider.test.ts","kind":"file","size":6627,"lastCommitHash":"cf07c5a3f5eca98e7744f2df83050044c920252a","lastCommitWhen":"2026-09-16T16:28:13-04:00","lastCommitMessage":"delete dead tests and fix the races the flaky ones were hiding (#2336)\n\n* add an objective testing policy to AGENTS.md\n\n* fix flaky daemon supervisor monitor test\n\nThe supervisor availability check is a real async chain (registry stat,\nsocket probe, replacement launch) started from a timer callback, so the\ntest drove a bounded fake-timer pump and asserted on a probe counter.\nUnder a loaded CI shard the chain did not finish inside the iteration\nbudget, and the variant mixing fake timers with a real probe promise\ncould deadlock for the full 30s test timeout.\n\nExpose a settled promise per armed availability check and await it in\nthe tests, so each assertion runs after the check finished instead of\nafter an arbitrary number of clock advances.\n\n* remove vitest retry masking from ai and attach-image tests\n\nDeleted all 548 `retry:` options in packages/ai/test and the 2 in\nkernel-attach-image-skill.test.ts. Retries hid non-determinism instead of\nfixing it, so a broken code path could still go green.\n\n- Deleted 17 live-only cross-provider E2E matrices whose every case sits behind\n  skipIf(!API_KEY) and never runs in CI; stream.test.ts stays as the survivor\n  that owns the provider table.\n- Stripped the retry option from the 198 stream.test.ts cases and dropped the\n  live E2E describe (plus its now-unused helpers) from\n  anthropic-thinking-disable.test.ts, keeping its mocked payload contract.\n- Removed retry: 1 from the two attach-image kernel cases; they pass without it.\n\nMocked wire/SSE contract tests are untouched. Tests only, no product code.\n\n* make agent trace upload tests deterministic\n\nThe suite pumped a synthetic clock with advanceTimersUntil() and hoped real\nfs and promise work settled inside a 200-step budget, asserted schedule\ndelays through a global setTimeout spy whose fake clock had drifted, and\nremoved its temp dir while catch-up and cursor writers were still running.\nUnder a loaded CI shard that produced \"Timed out advancing fake timers\",\n\"expected 1000 to be 60000\" and \"ENOTEMPTY rmdir /tmp/agent-traces-test-*\".\n\nThe upload scheduler now reports the delay it arms and the outcome of each\ncycle, the upload reports every wait it arms before the next request, and\ninstallAgentTraceUpload returns a handle that resolves when the startup\ncatch-up and any in-flight upload have finished writing. Tests await those\nsignals and advance the fake clock by the exact reported delay, and teardown\nwaits for in-flight writers before removing the temp dir.\n\nThe ~15 retry, backoff and Retry-After variants collapse into one\ntable-driven it.each, per the MERGE verdict: 1569 -> 1141 lines, 44 -> 27\ntest blocks, with no lost coverage.\n\n* make the compiled artifact and installer probe tests deterministic\n\nThe compiled-artifact afterEach polled for supervisor exit with the same\n10s budget as vitest's hook timeout, so the poll could never report on the\nslower standalone runners. The teardown now escalates to SIGKILL and every\ninner deadline stays below the surrounding hook and test budgets.\n\nnative-probe-timeout decided pass/fail from wall-clock deadlines around a\nreal 10s installer probe. The installer probe deadline is now injectable\nthrough PRIME_AGENT_PROBE_TIMEOUT_SECONDS, the blocked probe records the\ninstall lock itself, and the spawn deadlines are gone.\n\n* fix daemon shutdown admission loss during slow scans\n\nshutdown --force holds a 5s admission lease refreshed by a 1s timer, but it\nblocks its own event loop in synchronous ps/lsof/ss scans. On a loaded runner a\nscan outlasts the lease, the elapsed record is treated as abandoned, and the\nholder's next assertOrRenew throws \"Daemon shutdown admission was lost\".\n\n- A late renew re-arms a record that is still ours; only a missing or foreign\n  record ends the admission.\n- A renew that could not read the registry no longer retires the lease.\n- isDaemonShutdownAdmissionActive is read-only, so a bystander probe cannot\n  delete a live holder's record.\n- stopHiddenSupervisors renews before the blocking scan.\n\nThe 4603 regression drops its 11s sleep for a post-shutdown listener assertion\nand uses mkdtemp for the child TMPDIR.\n\n* delete 148 dead test files\n\nRemoves test files judged CUT by a full 480-file audit: duplicates of a named survivor, mock-asserting tests, rendered-copy assertions, private-internals casts, and live-API matrices behind skipIf(!API_KEY) that never ran in CI.\n\n* merge interactive-mode and agents-view test suites\n\n* merge tui render, overlay and helper test suites\n\n* test: slim daemon-mode and agent-connection-daemon suites\n\ndaemon-mode: keep passive hydration/passivation, delete_subagent durability, agent-message concurrency and rate limits, attach-snapshot backpressure; drop per-race internal regressions already covered process-level by daemon-supervisor-process.\nagent-connection-daemon: keep reconnect, update-restart, chunked-snapshot assembly and disposal races; drop tautological daemon-protocol pass-through cases.\n\n* merge tui editor, markdown and autocomplete test suites\n\n* test: merge audited session-core test bloat\n\nExecute MERGE verdicts from the 480-file test audit for the agent-session\ncore suites: collapse near-identical blocks into it.each tables, drop\nmock-return/rendered-copy assertions and private-cast white-box cases,\nand fold one-off files into the owning suite.\n\nDeleted (folded into their owning suite):\n- agent-session-concurrent.test.ts, suite/agent-session-action-races.test.ts,\n  suite/agent-session-action-contracts.test.ts -> suite/agent-session-queue.test.ts\n- suite/agent-session-compaction-continuation.test.ts,\n  suite/agent-session-compact-skill.test.ts -> suite/agent-session-compaction.test.ts\n- agent-session-runtime-events.test.ts -> suite/agent-session-runtime.test.ts\n\nPreserved: process boundaries (daemon RPC, ACP), on-disk formats,\nconcurrency/ordering, crash/restart/resume and load coverage.\n\n* address review: octal probe timeout, truncated deadline, dead schedule field\n\n* test: merge redundant coding-agent test cases into case tables\n\nExecutes the MERGE verdicts from the 480-file test-bloat audit for the\nmisc lanes. Repeated near-identical blocks collapse into single it.each\ncase tables, and ticket-numbered one-off files fold into the owning\nmodule suite.\n\nRemoved throughout the touched files: assertions on mock return values,\nassertions on rendered text/copy, `as unknown as` casts into privates,\nand suites gated behind skipIf(!API_KEY) (which never ran in CI).\n\nPreserved: process boundaries (daemon RPC, ACP), on-disk formats,\nconcurrency and ordering, crash/restart/resume, and load.\n\nDeleted files, folded into their module suite:\n- compaction-extensions -> deleted outright (whole file behind skipIf(!API_KEY))\n- compaction-serialization -> compaction\n- heartbeat-catalog -> daemon-client\n- child-process -> exec\n- edit-tool-legacy-input -> tools\n- kernel-goal-skill, kernel-rlm-heartbeat-skill -> kernel-agent-message-skill\n- kernel-agent-observe-skill -> kernel-attach-image-skill\n- kernel-windows-process -> kernel-bootstrap-windows\n- extensions-input-event -> extensions-runner\n- sdk-skills -> sdk-session-manager\n- session-manager/{agent-status,has-user-content} -> session-manager/session-state\n- session-manager/migration -> session-manager/file-operations\n- session-manager/custom-session-id -> session-manager/tree-traversal\n\n* slim ai + regression tests (lanes A/B/D/E)\n\nExecute MERGE verdicts from the test audit for packages/ai and the\nupdate-restart / snapshot / session-view regression files.\n\n- fold ticket-numbered regression cases into the owning suites\n- collapse near-identical blocks into it.each tables\n- drop mock-return, rendered-copy and live-API-gated assertions\n\n* test: collapse package-manager tables and fold small daemon selector suites\n\npackage-manager: git-URL parsing, top-level/manifest/package glob filters and npm install-argv cases are now table-driven.\ndaemon-session-id: absorbs daemon-catalog-process selector case, drops display-id formatting trivia.\ndaemon-worker-windows-timeouts: absorbs the connection-deadline budget cases from daemon-worker-connect.\ndaemon-catalog-startup: drops the src-directory one-off.\n\n* test: collapse refinement, settings and config suites into case tables\n\nFinal misc lane of the test-bloat audit.\n\n- refinement: per-kind create/update/delete becomes one it.each lifecycle;\n  8 rejection suites become one 18-row invalid-edit table that also asserts\n  state and the refinement log stay untouched; truncation/parse errors,\n  scope permutations, ranking and the tokenizer each become one table.\n  System-prompt and user-prompt copy assertions removed.\n- settings-manager: per-setting default getters removed; unknown-key\n  preservation, invalid-file guards and project-vs-global precedence kept.\n- config: install-method detection becomes one table; session-dir env\n  permutations collapse into one precedence test.\n- builtin-skills, repl-kernel-abort, session-cwd, truncate: repeated blocks\n  collapsed; one ReplInternals reach-in dropped.\n- child-process folds into exec as one process lifecycle suite.\n\n* slim regression tests (lane C)\n\nFold the remaining ticket-numbered regression files into the owning\nmodule suites and collapse duplicate cases into it.each tables.\n\n- 19 regression files deleted after their kept cases moved into\n  agent-session-queue, auth-storage, acp-features, resource-loader,\n  agent-session-runtime/compaction/retry-events/recursion,\n  model-registry, slash-commands, daemon-supervisor-process\n- 3 files slimmed in place where the named target no longer exists\n- drop rendered-copy, mock-return and private-cast assertions\n\n* test: collapse daemon protocol, command, list, ps and package-command suites\n\ndaemon-protocol: two gating tables replace 16 near-identical capability/schema cases.\ndaemon-command: table-driven argv parsing plus the --goal leak guards; drops help/usage copy assertions.\ndaemon-session-list: activity, recap and model-fallback projections are table-driven.\ndaemon-ps: keeps planReap/planShutdownAll safety rules, drops ss/lsof parsers, sorting and uptime trivia.\ndaemon-stop-confirm: one busy-guard table, no prompt copy.\npackage-command-paths: one shared self-update fixture for the install-spec cases; drops help and removed-flag copy.\nacp-events: keeps only the cases the ACP suite does not cover end to end.\ndaemon-session-summarizer: one recap/status parse table.\ndaemon-extension-binding: keeps the duplicated-partial-message strip.\n\n* test: tighten the daemon stop-confirm busy-guard table\n\n* fix ci: biome forEach body, vacuous autocomplete case, missing prompt before second compaction\n\n* fix ci: restore escaped template literals in prompt-template cases\n\n* fix codeql: single-pass path escaping in test helpers\n\n* address review: flush debounced trace uploads, restore probe timeout guards, drop dead test scaffolding\n\n* respect retry-after and throttle window when flushing trace uploads\n\n* await in-flight trace uploads before a drain returns\n\n* extend deterministic test policy to python\n\n* harden deterministic test policy checks\n\n* close test policy edge cases\n\n* finish deterministic policy edge coverage\n\n* fix policy lexer and macos signature setup\n\n* mask regex literals in test policy checks\n\n* distinguish postfix division in policy lexer\n\n* close native migration signal race\n\n* keep native migration force timer owned\n\n---------\n\nCo-authored-by: prime-agent <agent@local>"},{"name":"openai-responses-foreign-toolcall-id.test.ts","kind":"file","size":2650,"lastCommitHash":"b21b42d032919de2f2e6920a76fa9a37c3920c0a","lastCommitWhen":"2026-03-22T05:40:26+01:00","lastCommitMessage":"fix(ai): hash foreign responses tool item ids\n"},{"name":"overflow.test.ts","kind":"file","size":4666,"lastCommitHash":"55ade48b73f636d992855b7cab797d71dc1f6f1c","lastCommitWhen":"2026-09-09T10:37:39+02:00","lastCommitMessage":"recognize litellm maximum-context rejections (#2129)\n\n* fix(ci): accept engineering and research Linear tickets\n\n* fix(ci): clarify the Research ticket project\n\nfixes #2124\n\n* fix(ai): recognize LiteLLM context limit rejections\n\nRefs: ENG-6011. Reported in discussion #2088.\n\n* fix(ci): clarify Prime Agent board routing\n\nfixes #2124"},{"name":"prime-inference-model-catalog.test.ts","kind":"file","size":4284,"lastCommitHash":"cf07c5a3f5eca98e7744f2df83050044c920252a","lastCommitWhen":"2026-09-16T16:28:13-04:00","lastCommitMessage":"delete dead tests and fix the races the flaky ones were hiding (#2336)\n\n* add an objective testing policy to AGENTS.md\n\n* fix flaky daemon supervisor monitor test\n\nThe supervisor availability check is a real async chain (registry stat,\nsocket probe, replacement launch) started from a timer callback, so the\ntest drove a bounded fake-timer pump and asserted on a probe counter.\nUnder a loaded CI shard the chain did not finish inside the iteration\nbudget, and the variant mixing fake timers with a real probe promise\ncould deadlock for the full 30s test timeout.\n\nExpose a settled promise per armed availability check and await it in\nthe tests, so each assertion runs after the check finished instead of\nafter an arbitrary number of clock advances.\n\n* remove vitest retry masking from ai and attach-image tests\n\nDeleted all 548 `retry:` options in packages/ai/test and the 2 in\nkernel-attach-image-skill.test.ts. Retries hid non-determinism instead of\nfixing it, so a broken code path could still go green.\n\n- Deleted 17 live-only cross-provider E2E matrices whose every case sits behind\n  skipIf(!API_KEY) and never runs in CI; stream.test.ts stays as the survivor\n  that owns the provider table.\n- Stripped the retry option from the 198 stream.test.ts cases and dropped the\n  live E2E describe (plus its now-unused helpers) from\n  anthropic-thinking-disable.test.ts, keeping its mocked payload contract.\n- Removed retry: 1 from the two attach-image kernel cases; they pass without it.\n\nMocked wire/SSE contract tests are untouched. Tests only, no product code.\n\n* make agent trace upload tests deterministic\n\nThe suite pumped a synthetic clock with advanceTimersUntil() and hoped real\nfs and promise work settled inside a 200-step budget, asserted schedule\ndelays through a global setTimeout spy whose fake clock had drifted, and\nremoved its temp dir while catch-up and cursor writers were still running.\nUnder a loaded CI shard that produced \"Timed out advancing fake timers\",\n\"expected 1000 to be 60000\" and \"ENOTEMPTY rmdir /tmp/agent-traces-test-*\".\n\nThe upload scheduler now reports the delay it arms and the outcome of each\ncycle, the upload reports every wait it arms before the next request, and\ninstallAgentTraceUpload returns a handle that resolves when the startup\ncatch-up and any in-flight upload have finished writing. Tests await those\nsignals and advance the fake clock by the exact reported delay, and teardown\nwaits for in-flight writers before removing the temp dir.\n\nThe ~15 retry, backoff and Retry-After variants collapse into one\ntable-driven it.each, per the MERGE verdict: 1569 -> 1141 lines, 44 -> 27\ntest blocks, with no lost coverage.\n\n* make the compiled artifact and installer probe tests deterministic\n\nThe compiled-artifact afterEach polled for supervisor exit with the same\n10s budget as vitest's hook timeout, so the poll could never report on the\nslower standalone runners. The teardown now escalates to SIGKILL and every\ninner deadline stays below the surrounding hook and test budgets.\n\nnative-probe-timeout decided pass/fail from wall-clock deadlines around a\nreal 10s installer probe. The installer probe deadline is now injectable\nthrough PRIME_AGENT_PROBE_TIMEOUT_SECONDS, the blocked probe records the\ninstall lock itself, and the spawn deadlines are gone.\n\n* fix daemon shutdown admission loss during slow scans\n\nshutdown --force holds a 5s admission lease refreshed by a 1s timer, but it\nblocks its own event loop in synchronous ps/lsof/ss scans. On a loaded runner a\nscan outlasts the lease, the elapsed record is treated as abandoned, and the\nholder's next assertOrRenew throws \"Daemon shutdown admission was lost\".\n\n- A late renew re-arms a record that is still ours; only a missing or foreign\n  record ends the admission.\n- A renew that could not read the registry no longer retires the lease.\n- isDaemonShutdownAdmissionActive is read-only, so a bystander probe cannot\n  delete a live holder's record.\n- stopHiddenSupervisors renews before the blocking scan.\n\nThe 4603 regression drops its 11s sleep for a post-shutdown listener assertion\nand uses mkdtemp for the child TMPDIR.\n\n* delete 148 dead test files\n\nRemoves test files judged CUT by a full 480-file audit: duplicates of a named survivor, mock-asserting tests, rendered-copy assertions, private-internals casts, and live-API matrices behind skipIf(!API_KEY) that never ran in CI.\n\n* merge interactive-mode and agents-view test suites\n\n* merge tui render, overlay and helper test suites\n\n* test: slim daemon-mode and agent-connection-daemon suites\n\ndaemon-mode: keep passive hydration/passivation, delete_subagent durability, agent-message concurrency and rate limits, attach-snapshot backpressure; drop per-race internal regressions already covered process-level by daemon-supervisor-process.\nagent-connection-daemon: keep reconnect, update-restart, chunked-snapshot assembly and disposal races; drop tautological daemon-protocol pass-through cases.\n\n* merge tui editor, markdown and autocomplete test suites\n\n* test: merge audited session-core test bloat\n\nExecute MERGE verdicts from the 480-file test audit for the agent-session\ncore suites: collapse near-identical blocks into it.each tables, drop\nmock-return/rendered-copy assertions and private-cast white-box cases,\nand fold one-off files into the owning suite.\n\nDeleted (folded into their owning suite):\n- agent-session-concurrent.test.ts, suite/agent-session-action-races.test.ts,\n  suite/agent-session-action-contracts.test.ts -> suite/agent-session-queue.test.ts\n- suite/agent-session-compaction-continuation.test.ts,\n  suite/agent-session-compact-skill.test.ts -> suite/agent-session-compaction.test.ts\n- agent-session-runtime-events.test.ts -> suite/agent-session-runtime.test.ts\n\nPreserved: process boundaries (daemon RPC, ACP), on-disk formats,\nconcurrency/ordering, crash/restart/resume and load coverage.\n\n* address review: octal probe timeout, truncated deadline, dead schedule field\n\n* test: merge redundant coding-agent test cases into case tables\n\nExecutes the MERGE verdicts from the 480-file test-bloat audit for the\nmisc lanes. Repeated near-identical blocks collapse into single it.each\ncase tables, and ticket-numbered one-off files fold into the owning\nmodule suite.\n\nRemoved throughout the touched files: assertions on mock return values,\nassertions on rendered text/copy, `as unknown as` casts into privates,\nand suites gated behind skipIf(!API_KEY) (which never ran in CI).\n\nPreserved: process boundaries (daemon RPC, ACP), on-disk formats,\nconcurrency and ordering, crash/restart/resume, and load.\n\nDeleted files, folded into their module suite:\n- compaction-extensions -> deleted outright (whole file behind skipIf(!API_KEY))\n- compaction-serialization -> compaction\n- heartbeat-catalog -> daemon-client\n- child-process -> exec\n- edit-tool-legacy-input -> tools\n- kernel-goal-skill, kernel-rlm-heartbeat-skill -> kernel-agent-message-skill\n- kernel-agent-observe-skill -> kernel-attach-image-skill\n- kernel-windows-process -> kernel-bootstrap-windows\n- extensions-input-event -> extensions-runner\n- sdk-skills -> sdk-session-manager\n- session-manager/{agent-status,has-user-content} -> session-manager/session-state\n- session-manager/migration -> session-manager/file-operations\n- session-manager/custom-session-id -> session-manager/tree-traversal\n\n* slim ai + regression tests (lanes A/B/D/E)\n\nExecute MERGE verdicts from the test audit for packages/ai and the\nupdate-restart / snapshot / session-view regression files.\n\n- fold ticket-numbered regression cases into the owning suites\n- collapse near-identical blocks into it.each tables\n- drop mock-return, rendered-copy and live-API-gated assertions\n\n* test: collapse package-manager tables and fold small daemon selector suites\n\npackage-manager: git-URL parsing, top-level/manifest/package glob filters and npm install-argv cases are now table-driven.\ndaemon-session-id: absorbs daemon-catalog-process selector case, drops display-id formatting trivia.\ndaemon-worker-windows-timeouts: absorbs the connection-deadline budget cases from daemon-worker-connect.\ndaemon-catalog-startup: drops the src-directory one-off.\n\n* test: collapse refinement, settings and config suites into case tables\n\nFinal misc lane of the test-bloat audit.\n\n- refinement: per-kind create/update/delete becomes one it.each lifecycle;\n  8 rejection suites become one 18-row invalid-edit table that also asserts\n  state and the refinement log stay untouched; truncation/parse errors,\n  scope permutations, ranking and the tokenizer each become one table.\n  System-prompt and user-prompt copy assertions removed.\n- settings-manager: per-setting default getters removed; unknown-key\n  preservation, invalid-file guards and project-vs-global precedence kept.\n- config: install-method detection becomes one table; session-dir env\n  permutations collapse into one precedence test.\n- builtin-skills, repl-kernel-abort, session-cwd, truncate: repeated blocks\n  collapsed; one ReplInternals reach-in dropped.\n- child-process folds into exec as one process lifecycle suite.\n\n* slim regression tests (lane C)\n\nFold the remaining ticket-numbered regression files into the owning\nmodule suites and collapse duplicate cases into it.each tables.\n\n- 19 regression files deleted after their kept cases moved into\n  agent-session-queue, auth-storage, acp-features, resource-loader,\n  agent-session-runtime/compaction/retry-events/recursion,\n  model-registry, slash-commands, daemon-supervisor-process\n- 3 files slimmed in place where the named target no longer exists\n- drop rendered-copy, mock-return and private-cast assertions\n\n* test: collapse daemon protocol, command, list, ps and package-command suites\n\ndaemon-protocol: two gating tables replace 16 near-identical capability/schema cases.\ndaemon-command: table-driven argv parsing plus the --goal leak guards; drops help/usage copy assertions.\ndaemon-session-list: activity, recap and model-fallback projections are table-driven.\ndaemon-ps: keeps planReap/planShutdownAll safety rules, drops ss/lsof parsers, sorting and uptime trivia.\ndaemon-stop-confirm: one busy-guard table, no prompt copy.\npackage-command-paths: one shared self-update fixture for the install-spec cases; drops help and removed-flag copy.\nacp-events: keeps only the cases the ACP suite does not cover end to end.\ndaemon-session-summarizer: one recap/status parse table.\ndaemon-extension-binding: keeps the duplicated-partial-message strip.\n\n* test: tighten the daemon stop-confirm busy-guard table\n\n* fix ci: biome forEach body, vacuous autocomplete case, missing prompt before second compaction\n\n* fix ci: restore escaped template literals in prompt-template cases\n\n* fix codeql: single-pass path escaping in test helpers\n\n* address review: flush debounced trace uploads, restore probe timeout guards, drop dead test scaffolding\n\n* respect retry-after and throttle window when flushing trace uploads\n\n* await in-flight trace uploads before a drain returns\n\n* extend deterministic test policy to python\n\n* harden deterministic test policy checks\n\n* close test policy edge cases\n\n* finish deterministic policy edge coverage\n\n* fix policy lexer and macos signature setup\n\n* mask regex literals in test policy checks\n\n* distinguish postfix division in policy lexer\n\n* close native migration signal race\n\n* keep native migration force timer owned\n\n---------\n\nCo-authored-by: prime-agent <agent@local>"},{"name":"render-models.test.ts","kind":"file","size":992,"lastCommitHash":"b9cf467edf8bbbd8e607991cf770407d62daa8ec","lastCommitWhen":"2026-09-07T02:15:35-04:00","lastCommitMessage":"Improve session navigation, model discovery, and background commands (#2068)\n\n* feat(coding-agent): show the model label on every agents-view row\n\nResident summaries carry model info for all session kinds; only the\nrenderer restricted the label to subagent rows. Drop the special case so\nany row whose summary has a model renders provider/id[:thinkingLevel] in\nthe suffix region, still suppressed while pending delete/kill.\n\n* fix(coding-agent): open visible sessions without waiting for selection anchors\n\nConsolidates #2079 at d5b49266b5829a4ea8f46ad76b525e0e560ace03.\n\n* feat(tui): open local file links\n\nConsolidates #2073 at b6e83f0f2db71c705d48ef14b499a513c1506f4d.\n\n* feat(coding-agent): highlight file references and command options\n\nConsolidates #1145 at 285ccf457c2f94508b5764d0ab1cc1b4b79a6d61.\n\n* feat: refresh Prime Inference models from the live catalog\n\nConsolidates #1928 at 24d3413c304cefbb063e86a7e41c85207916d90e.\n\n* feat(coding-agent): let root agents create sibling sessions\n\nConsolidates #1996 at 0c9c883c951097183664cf82453856cca21c8ac3.\n\n* feat(coding-agent): wake agents when asynchronous bash finishes\n\nConsolidates #2053 at 1bb4d43a0a64366217f8fec38d574e3917fa550d.\n\n* feat(coding-agent): simplify the agents view while retaining model details\n\nConsolidates #2087 at dc67428af10b1b2fbe63d996e52ede6116bb4d62.\nRetains #2068 model visibility and #2079 immediate opening and query ownership.\n\n* fix(coding-agent): preserve background work and sibling-session credentials\n\nKeep managed shell commands active until completion delivery is accepted.\nForward only effective same-provider transient auth when creating root sessions.\nIntegration fixes for #2053 and #1996.\n\n* fix(coding-agent): address session lifecycle and rendering regressions\n\nPreserve sibling PATH and reject root creation after disposal.\nTreat background completions as new runs without duplicate as_completed wakes.\nKeep table delimiters visible and sanitize live catalog display metadata.\nScope the stale-auth regression fixture to its cached Prime team.\n\n* fix(coding-agent): forward the selected provider environment credentials\n\nPreserve alias priority and runtime credential identity when creating sibling sessions.\nPin that a create timeout never dispatches the task prompt.\n\n* fix(runtime): recheck creating-cell waits when shell commands settle\n\nPreserve late as_completed consumers without suppressing detached completion notices.\nDocument the cached-wrapper result limitation.\n\n* fix(runtime): preserve background bash completion lifecycle\n\nWait for process-group cleanup before releasing residency. Defer paused admission within the original request and report terminal rejection.\nPreserve notices after cancelled non-owning waits and clean up interrupted task construction.\n\n* fix(runtime): use a portable signal for construction cleanup\n\nKeep immediate POSIX cleanup and use the existing Windows job cleanup path without referencing SIGKILL.\n\n* fix(coding-agent): steer shell messages and stop losing supervisor launches\n\nDeliver labeled shell completion messages at the next safe turn boundary.\nStop only an owned replacement child that loses to a current authenticated supervisor.\n\n---------\n\nCo-authored-by: Seth <seth@primeintellect.ai>"},{"name":"stream-failure.test.ts","kind":"file","size":12728,"lastCommitHash":"d0913ca17f0784abfa2ae053d365fe7f9e9a4051","lastCommitWhen":"2026-09-17T10:01:48+03:00","lastCommitMessage":"fix(coding-agent): honor provider quota deadlines and preflight lane health\n"},{"name":"stream.test.ts","kind":"file","size":47452,"lastCommitHash":"db7ff1c1e8f8f3f3db17285b028f8e4c872e3638","lastCommitWhen":"2026-09-17T07:01:44+03:00","lastCommitMessage":"fix(ai): update deepseek flash model to deepseek/deepseek-flash\n"},{"name":"structured-output.test.ts","kind":"file","size":11507,"lastCommitHash":"db7ff1c1e8f8f3f3db17285b028f8e4c872e3638","lastCommitWhen":"2026-09-17T07:01:44+03:00","lastCommitMessage":"fix(ai): update deepseek flash model to deepseek/deepseek-flash\n"},{"name":"transform-messages-interrupted-tools.test.ts","kind":"file","size":7831,"lastCommitHash":"988e4f41dd25a6f3df9cfc66f45496d630be1969","lastCommitWhen":"2026-09-17T08:25:36+03:00","lastCommitMessage":"fix: reconcile the rebased fork with upstream's refactors\n\nSecond pass over the residue the rebase left behind: the tree now\ntypechecks and lints clean, and the touched suites pass.\n\n- finish the credential reconciliation (firstCredential readers, MCP\n  static tokens, prime-cli config read/write helpers and the private\n  prime-cli accessors the fork's call sites need)\n- restore dropped wiring: the bash.consumed host request, the MCP\n  discovery assertions in the kernel ready check, and the snapshot\n  extras (activity, tool use, previews, labels, staleness) on kernel\n  roster entries next to the fork's turn/token accounting\n- rebuild the interactive-mode class fields and the /reload + /usage +\n  /context dispatch, and restore the async-bash header snippet\n- re-merge the agents view on upstream's newer file instead of the\n  per-commit resolutions, so the fork's view model survives: the\n  actions pane and its renderSessionRows early return, compactSessionRows\n  over the raw allRows, the pinned/expanded row markers and the\n  completed/needs-input icons, the running-subagent rows, and the\n  model-plus-host row label. upstream's timer-batched catalog reconcile\n  and its rebuild-free tick loop are kept, with a live cache ttl counted\n  as work so the ttl keeps counting down; the tray label providers dropped\n  upstream's redundant inline-picker guard\n- skip the quota wait when an unblocked sibling credential exists, so\n  the fork's quick account rotation still wins over a long Retry-After\n- restore real timers in the compaction regression suite, which the\n  preceding fake-timer test left mocked, and hold the fork's contracts in\n  the queue suite (200-message ceiling, batched steering) and the 4649\n  name-reservation test\n- drop upstream's subagentDefaultModel suite and its inherit-parent case:\n  this fork keeps an explicit model= on every spawn\n- move the deferred-session-event tests back to top level and wait on\n  the connection's own status sequence instead of a wall-clock poll\n- keep the fork's lazy session-open and sqlite catalog paths as the\n  session-loading fast path\n"},{"name":"usage-feeds-alibaba.test.ts","kind":"file","size":9971,"lastCommitHash":"988e4f41dd25a6f3df9cfc66f45496d630be1969","lastCommitWhen":"2026-09-17T08:25:36+03:00","lastCommitMessage":"fix: reconcile the rebased fork with upstream's refactors\n\nSecond pass over the residue the rebase left behind: the tree now\ntypechecks and lints clean, and the touched suites pass.\n\n- finish the credential reconciliation (firstCredential readers, MCP\n  static tokens, prime-cli config read/write helpers and the private\n  prime-cli accessors the fork's call sites need)\n- restore dropped wiring: the bash.consumed host request, the MCP\n  discovery assertions in the kernel ready check, and the snapshot\n  extras (activity, tool use, previews, labels, staleness) on kernel\n  roster entries next to the fork's turn/token accounting\n- rebuild the interactive-mode class fields and the /reload + /usage +\n  /context dispatch, and restore the async-bash header snippet\n- re-merge the agents view on upstream's newer file instead of the\n  per-commit resolutions, so the fork's view model survives: the\n  actions pane and its renderSessionRows early return, compactSessionRows\n  over the raw allRows, the pinned/expanded row markers and the\n  completed/needs-input icons, the running-subagent rows, and the\n  model-plus-host row label. upstream's timer-batched catalog reconcile\n  and its rebuild-free tick loop are kept, with a live cache ttl counted\n  as work so the ttl keeps counting down; the tray label providers dropped\n  upstream's redundant inline-picker guard\n- skip the quota wait when an unblocked sibling credential exists, so\n  the fork's quick account rotation still wins over a long Retry-After\n- restore real timers in the compaction regression suite, which the\n  preceding fake-timer test left mocked, and hold the fork's contracts in\n  the queue suite (200-message ceiling, batched steering) and the 4649\n  name-reservation test\n- drop upstream's subagentDefaultModel suite and its inherit-parent case:\n  this fork keeps an explicit model= on every spawn\n- move the deferred-session-event tests back to top level and wait on\n  the connection's own status sequence instead of a wall-clock poll\n- keep the fork's lazy session-open and sqlite catalog paths as the\n  session-loading fast path\n"},{"name":"usage-feeds-antigravity-hyper.test.ts","kind":"file","size":11081,"lastCommitHash":"679395e8c07ce99ffc3053299de4d4d1dce6a572","lastCommitWhen":"2026-09-17T07:09:26+03:00","lastCommitMessage":"feat(usage): read alibaba's token plan through the official CLI, not only a scraped session\n\ndawn's token-plan keys are inference-only, so we reverse-engineered the console endpoint from a\nbrowser HAR. That worked, but it was the wrong shape of solution: the provider ships a supported CLI,\nand CodexBar's docs (MIT, read as reference only — dawn does not want us depending on it) name both it\nand the `quota-config` endpoint we had missed.\n\n- `UsageRequest` is now a union: `{kind:\"http\",...}` or `{kind:\"command\", command, args, timeoutMs}`.\n  The core still spawns nothing; it asks, and the host answers. A host that will not run commands\n  replies `status: 127` and the feed routes around it into the captured-session path.\n- a new credential kind, `cli`: no secret, because the provider's own CLI is already signed in.\n- the alibaba feed tries `bl usage token-plan --console-region <id> --console-site <site> --output\n  json` first, over the four region variants (`intl`/`cn`/`intl-personal`/`cn-personal`), and falls\n  back to the console session. One parser reads both payloads, because the CLI answers with the same\n  field names the console wraps in `data.DataV2.data.data`: `per*Percentage` is a FRACTION and\n  `per*ResetTime` is epoch MILLISECONDS.\n- two corrections from the reference: `sec_token` is optional (some accounts are not given one, and\n  the console proceeds without it — ours used to fail), and `quota-config` reports per-tier\n  allowances, so the report now says \"Token plan pro: weekly 40000, 5h 12000 credits\" beside the\n  percentage. Remaining days and reset cards become notes.\n- the coding-agent host runs only allowlisted command names (`bl`), with the environment narrowed to\n  PATH/HOME/locale/timezone/proxies, a timeout and a 64 KiB stdout cap; a refusal or a missing binary\n  comes back as a status the feed treats as data.\n- the Zig core and the Swift driver mirror all of it, including the command request in the Swift\n  decoder and a `runCommand` that applies the same allowlist, timeout and cap.\n\nVerified: zig unit + C ABI tests, the twelve-case parity suite, the Swift smoke test (which now shows\n`alibaba=4 calls`), 71 pi-ai usage tests, 45 coding-agent usage tests, and `npm run check` end to end.\nThe child proved the new surface bites: dropping `kind` from command requests fails parity and the\nSwift smoke immediately.\n\nCaveat, stated rather than papered over: `bl` is not installed on this machine, so the CLI path is\ntested against recorded payloads and scripted hosts, not live.\n"},{"name":"usage-feeds-opencode-zai-deepseek.test.ts","kind":"file","size":10572,"lastCommitHash":"679395e8c07ce99ffc3053299de4d4d1dce6a572","lastCommitWhen":"2026-09-17T07:09:26+03:00","lastCommitMessage":"feat(usage): read alibaba's token plan through the official CLI, not only a scraped session\n\ndawn's token-plan keys are inference-only, so we reverse-engineered the console endpoint from a\nbrowser HAR. That worked, but it was the wrong shape of solution: the provider ships a supported CLI,\nand CodexBar's docs (MIT, read as reference only — dawn does not want us depending on it) name both it\nand the `quota-config` endpoint we had missed.\n\n- `UsageRequest` is now a union: `{kind:\"http\",...}` or `{kind:\"command\", command, args, timeoutMs}`.\n  The core still spawns nothing; it asks, and the host answers. A host that will not run commands\n  replies `status: 127` and the feed routes around it into the captured-session path.\n- a new credential kind, `cli`: no secret, because the provider's own CLI is already signed in.\n- the alibaba feed tries `bl usage token-plan --console-region <id> --console-site <site> --output\n  json` first, over the four region variants (`intl`/`cn`/`intl-personal`/`cn-personal`), and falls\n  back to the console session. One parser reads both payloads, because the CLI answers with the same\n  field names the console wraps in `data.DataV2.data.data`: `per*Percentage` is a FRACTION and\n  `per*ResetTime` is epoch MILLISECONDS.\n- two corrections from the reference: `sec_token` is optional (some accounts are not given one, and\n  the console proceeds without it — ours used to fail), and `quota-config` reports per-tier\n  allowances, so the report now says \"Token plan pro: weekly 40000, 5h 12000 credits\" beside the\n  percentage. Remaining days and reset cards become notes.\n- the coding-agent host runs only allowlisted command names (`bl`), with the environment narrowed to\n  PATH/HOME/locale/timezone/proxies, a timeout and a 64 KiB stdout cap; a refusal or a missing binary\n  comes back as a status the feed treats as data.\n- the Zig core and the Swift driver mirror all of it, including the command request in the Swift\n  decoder and a `runCommand` that applies the same allowlist, timeout and cap.\n\nVerified: zig unit + C ABI tests, the twelve-case parity suite, the Swift smoke test (which now shows\n`alibaba=4 calls`), 71 pi-ai usage tests, 45 coding-agent usage tests, and `npm run check` end to end.\nThe child proved the new surface bites: dropping `kind` from command requests fails parity and the\nSwift smoke immediately.\n\nCaveat, stated rather than papered over: `bl` is not installed on this machine, so the CLI path is\ntested against recorded payloads and scripted hosts, not live.\n"},{"name":"usage-feeds.test.ts","kind":"file","size":9160,"lastCommitHash":"679395e8c07ce99ffc3053299de4d4d1dce6a572","lastCommitWhen":"2026-09-17T07:09:26+03:00","lastCommitMessage":"feat(usage): read alibaba's token plan through the official CLI, not only a scraped session\n\ndawn's token-plan keys are inference-only, so we reverse-engineered the console endpoint from a\nbrowser HAR. That worked, but it was the wrong shape of solution: the provider ships a supported CLI,\nand CodexBar's docs (MIT, read as reference only — dawn does not want us depending on it) name both it\nand the `quota-config` endpoint we had missed.\n\n- `UsageRequest` is now a union: `{kind:\"http\",...}` or `{kind:\"command\", command, args, timeoutMs}`.\n  The core still spawns nothing; it asks, and the host answers. A host that will not run commands\n  replies `status: 127` and the feed routes around it into the captured-session path.\n- a new credential kind, `cli`: no secret, because the provider's own CLI is already signed in.\n- the alibaba feed tries `bl usage token-plan --console-region <id> --console-site <site> --output\n  json` first, over the four region variants (`intl`/`cn`/`intl-personal`/`cn-personal`), and falls\n  back to the console session. One parser reads both payloads, because the CLI answers with the same\n  field names the console wraps in `data.DataV2.data.data`: `per*Percentage` is a FRACTION and\n  `per*ResetTime` is epoch MILLISECONDS.\n- two corrections from the reference: `sec_token` is optional (some accounts are not given one, and\n  the console proceeds without it — ours used to fail), and `quota-config` reports per-tier\n  allowances, so the report now says \"Token plan pro: weekly 40000, 5h 12000 credits\" beside the\n  percentage. Remaining days and reset cards become notes.\n- the coding-agent host runs only allowlisted command names (`bl`), with the environment narrowed to\n  PATH/HOME/locale/timezone/proxies, a timeout and a 64 KiB stdout cap; a refusal or a missing binary\n  comes back as a status the feed treats as data.\n- the Zig core and the Swift driver mirror all of it, including the command request in the Swift\n  decoder and a `runCommand` that applies the same allowlist, timeout and cap.\n\nVerified: zig unit + C ABI tests, the twelve-case parity suite, the Swift smoke test (which now shows\n`alibaba=4 calls`), 71 pi-ai usage tests, 45 coding-agent usage tests, and `npm run check` end to end.\nThe child proved the new surface bites: dropping `kind` from command requests fails parity and the\nSwift smoke immediately.\n\nCaveat, stated rather than papered over: `bl` is not installed on this machine, so the CLI path is\ntested against recorded payloads and scripted hosts, not live.\n"},{"name":"usage-zig-parity.test.ts","kind":"file","size":13682,"lastCommitHash":"4587c66e060893526c37e8b6e38c1bac3e0d2d37","lastCommitWhen":"2026-09-17T07:09:26+03:00","lastCommitMessage":"fix(native): point the core submodule at its remote, and pin the cases that drifted\n\nThe core now lives at git@knot.gaze.systems:did:plc:2lf7buutfnfcucljnmaypf7u, so the submodule\nURL is real and a recursive clone works.\n\nThe parity suite grew two cases, both aimed at holes the review found rather than at new\nbehaviour:\n\n- hyper, two rounds in one process. The team travels from the teams round to the billing round,\n  which is exactly the path that read freed memory on the Zig side before the ABI-3 state handle,\n  and exactly the path the old one-round-per-process harness could not reach. It also compares an\n  HTTP request step for the first time, which is the one place the two representations differ on\n  purpose: ordered pairs here, a record in TS. The team name carries a quote and a backslash, so a\n  writer that forgets to escape ends the JSON string early and the case stops parsing.\n- a reset already in the past, which pins the window label to the reference's `Math.max(1, …)`\n  instead of letting it disappear.\n\nReading that diff found three real divergences in the Zig core, fixed upstream in 7104b97:\nquotes emitted unescaped, the past-reset label dropped, and hyper classifying its round by\nresponse count instead of by body shape (so a caller handing in a billing body alone got \"no\nhyper teams found\"). All three were invisible to the old suite and are now pinned by it.\n"},{"name":"validation.test.ts","kind":"file","size":3873,"lastCommitHash":"35ff2689ee0a74009db73c697025de88ad86f6fb","lastCommitWhen":"2026-04-22T19:59:33+02:00","lastCommitMessage":"fix(typebox): migrate to v1 with extension compat (#3474)\n\n* fix(typebox): migrate to v1 with extension compat\n\nReplace AJV-based validation with TypeBox-native validation, keep legacy extension imports working (including @sinclair/typebox/compiler), and restore coercion for serialized/plain JSON schemas.\n\nThis change closes #3112.\n\n* fix(typebox): use canonical imports and harden coercion\n\nSwitch first-party code to canonical typebox imports while retaining legacy extension aliases in the loader.\n\nRemove obsolete runtime codegen guards, expand serialized JSON-schema coercion coverage, and update related tests and fixtures.\n\nFixes #3112.\n\n---------\n\nCo-authored-by: Mario Zechner <badlogicgames@gmail.com>"},{"name":"xai-oauth.test.ts","kind":"file","size":5152,"lastCommitHash":"ca67580b524800a971f92420d4c665bd83df1dfa","lastCommitWhen":"2026-09-11T23:36:41-07:00","lastCommitMessage":"add grok subscription authentication (#2252)\n\n* add grok subscription authentication\n\nFixes ENG-6059\n\n* trim redundant grok authentication tests\n\nRefs ENG-6059\n\n* keep xai authentication in the existing login modal\n\nFixes ENG-6059\n\n* return false for unsupported xai model availability\n\nFixes ENG-6059\n\n* refresh daemon model state after authentication changes\n\nFixes ENG-6059\n\n* use keyed fingerprints for credential-scoped model caches\n\nFixes ENG-6059\n\n* clean up credential rotation test formatting\n\nFixes ENG-6059\n\n* show all grok models and improve provider search"},{"name":"xai-responses.test.ts","kind":"file","size":7803,"lastCommitHash":"ca67580b524800a971f92420d4c665bd83df1dfa","lastCommitWhen":"2026-09-11T23:36:41-07:00","lastCommitMessage":"add grok subscription authentication (#2252)\n\n* add grok subscription authentication\n\nFixes ENG-6059\n\n* trim redundant grok authentication tests\n\nRefs ENG-6059\n\n* keep xai authentication in the existing login modal\n\nFixes ENG-6059\n\n* return false for unsupported xai model availability\n\nFixes ENG-6059\n\n* refresh daemon model state after authentication changes\n\nFixes ENG-6059\n\n* use keyed fingerprints for credential-scoped model caches\n\nFixes ENG-6059\n\n* clean up credential rotation test formatting\n\nFixes ENG-6059\n\n* show all grok models and improve provider search"},{"name":"zai-test-model.ts","kind":"file","size":916,"lastCommitHash":"8c0b90eea8f6ea2a7123746dd40b4a000e725947","lastCommitWhen":"2026-07-31T19:53:55-07:00","lastCommitMessage":"fix(ai): keep z.ai provider tests compatible with live catalogs (#568)\n\n* fix(ai): select live z.ai test models\n\n* fix(ai): bound z.ai overflow test payload"}]