[{"name":"regressions","kind":"directory","size":0,"lastCommitHash":"7e70aea03dcf78c97aa65cc2a8e1aeb2a068e5fe","lastCommitWhen":"2026-08-31T22:05:28+09:00","lastCommitMessage":"complete guarded RLM results and background completion wakeups\n"},{"name":"acp-features.test.ts","kind":"file","size":32853,"lastCommitHash":"d98d0762c0dea0e4d176233c03965dc05a8b33bf","lastCommitWhen":"2026-08-20T10:52:30+02:00","lastCommitMessage":"feat(acp): harden resident session lifecycle (#1494)\n\n* feat(acp): harden resident session lifecycle\n\n* test(daemon): align recovery fixtures with durable context\n\n* fix(acp): validate durable host settings\n\n* fix(daemon): clean up failed resident resources\n\n* fix(daemon): recover owned workers from fresh context\n\n* fix(acp): verify authoritative completion state\n\n* fix(daemon): refresh requested child roster\n\n* fix(acp): read child roster without reattaching\n\n* fix(daemon): preserve telemetry opt-out on recovery\n\n* fix(daemon): scope resident path conflicts\n\n* test(acp): remove runtime publish hook\n\n* fix(acp): drain admitted updates on close\n\n* fix(daemon): merge fresh supervisor defaults\n\n* fix(acp): await autonomous lifecycle settlement\n\n* fix(acp): preserve daemon input fences\n\n* fix(acp): serialize terminal lifecycle turns\n\n* fix(acp): reacquire daemon fences after reconnect\n\n* fix(acp): fail closed across abort cuts\n\n* fix(acp): resume queued input after pause\n\n* fix(acp): invalidate pending pumps on pause\n\n* fix(acp): preserve pause ownership through supervisor\n\n* fix(acp): fail closed on pause cleanup loss\n\n* test(daemon): initialize pause ownership harness\n\n* fix(acp): fence detach pause cleanup\n\n* fix(daemon): preserve detach-all cleanup\n\n* test(daemon): initialize worker pause registry\n\n* fix(daemon): reacquire pauses across release\n\n* fix(daemon): clear stable detach selectors\n\n* fix(daemon): retain detach fences on attach failure\n\n* refactor(daemon): keep descriptor validation private\n\n* docs(changelog): describe ACP lifecycle fencing\n\n* fix(acp): settle restart and failed close lifecycle\n\n* fix(acp): serialize cancel after failed close\n\n* fix(acp): preserve lifecycle reconciliation ordering\n\n* fix(acp): settle deleted child runtimes\n\n* test(acp): consolidate child deletion regressions\n\n* fix(acp): rearm settled child deletion\n\n* fix(acp): preserve recursive terminal settlement\n\n* test(acp): update terminal notice regression"},{"name":"acp-mode.test.ts","kind":"file","size":51777,"lastCommitHash":"a9b5d88b50db50860088772a408e867f8071b507","lastCommitWhen":"2026-08-24T13:30:05-07:00","lastCommitMessage":"fix: preserve ACP quiescence and Chat reasoning lineage (#1612)\n\n* fix(acp): await terminal quiescence before prompt completion\n\n* docs(changelog): add ACP quiescence fragment\n\n* fix(ai): preserve chat reasoning details on replay\n\n* fix(ai): emit valid reasoning-only chat messages\n\n* fix: preserve streamed reasoning and ACP cancellation\n\nFixes #1612.\n\n* fix(acp): retain ownership through terminal publication\n\nFixes #1612."},{"name":"agent-session-action-contracts.test.ts","kind":"file","size":4075,"lastCommitHash":"941576dbec6d388de6b9f3cb61bce90cce3f55c4","lastCommitWhen":"2026-08-03T09:56:37+02:00","lastCommitMessage":"refactor(coding-agent): publish session action protocol (#575)\n\n* refactor(coding-agent): publish session action protocol\n\n* fix(coding-agent): restore queue projection guards and recovery validation\n\n* fix(coding-agent): repair test migrations for session action snapshots\n\n* correcting when multiple messages are sent, how it's counted\n\n* fix(coding-agent): await update supervisor teardown (fixes #575)\n\n---------\n\nCo-authored-by: Alex Zhang <alex.lx.zhang@gmail.com>"},{"name":"agent-session-action-races.test.ts","kind":"file","size":14928,"lastCommitHash":"b030f3938463c2a9f5767c93e861a2d5d57b5d92","lastCommitWhen":"2026-08-05T04:46:52+02:00","lastCommitMessage":"feat(coding-agent): intra-tree child session passivation (#589)\n\n* feat(coding-agent): intra-tree child session passivation\n\nTrack A PR 7 (final) of the recursive-agent-harness plan (D5, shape 2):\n\n- idle child sessions inside a LIVE worker passivate individually: graceful\n  closeSession (kernel snapshot + JSONL flush + lease release), sessions-map\n  removal, registry/catalog rows preserved - the child becomes exactly a\n  lazy-hydration passive row (attach/message/observe/list all work)\n- pure canPassivateSession() beside canEvictWorker(), sharing its per-\n  session clauses; additionally requires a parent edge, no non-passive\n  descendants, and no mid-hydration descendant (passive children's\n  sessionFiles checked against openingSessions - hydration blocks parent\n  passivation); roots remain shape-1 territory; passivation never cascades\n- complete-then-rehydrate: touches mid-passivation join the passivation\n  promise (keyed by resolved sessionFile - stable across sessions-map\n  removal) then flow through the normal hydration machinery; deterministic\n  gated race tests for a2a delivery and grandchild hydration\n- supervisor sweep extension: capped worker command (2 children/worker/\n  sweep), one snapshot per state per sweep, fresh-snapshot fence recheck\n  before dispose; whole-tree-evictable workers excluded (owned by shape 1)\n- same idleEvictionMinutes setting governs both shapes; #548 doctrine\n  inversion deferred (prompts out of scope this run)\n\n* fix(coding-agent): harden passivation against new admission fences and reap dedupe\n\nPost-rebase semantic fixes after moving the stack onto the hardened\nscheduler base (cb8f53e15):\n\n- passivation predicate treats admission-in-flight as busy: agent-message\n  accepting/preparing/target-lock states and AgentSession's pending\n  admission-fence waiters (70aeb9c49/2d97dbb4f made prompt paths await the\n  direct-turn admission fence before any session action exists, so a target\n  mid-admission looked idle to the sweep); deterministic gated-admission\n  regression test\n- deleteRlmSubagentRuntime cancels scheduled jobs by session file even when\n  its close joins an in-flight passivation close via closingSessions (the\n  joined 'shutdown' close skipped 'killed'-close job cleanup; #547 reap race)\n\n* fix(coding-agent): harden passive-child hydration, resolution, and deletion races\n\n- Finding 0: heartbeat restore could return a concurrently hydrating child before binding; fence resident fallback with waitForBoundSession and treat unavailable binding as a skipped dispatch. origin: PR #583\n- Finding 1: supervisor child lookup accepted only exact selectors after worker suffix matching; add the same session-ID suffix fallback within the selected worker. origin: PR #583\n- Finding 3: passive create hydration skipped explicit name and client environment bookkeeping; apply both before returning the hydrated state. origin: PR #583\n- Finding 4: concurrent passive deletions raced through asynchronous resolution and started duplicate host deletes; defer deletion behind an atomic in-flight map check and coalesce callers. origin: PR #583\n- Finding 5: concurrent hydration could make a passive lookup stale for advertised IDs and paths; retry normal bound-session resolution before rethrowing the original unknown-session error. origin: PR #583\n- Finding 6: ambiguous live selectors fell through to passive lookup and could misroute; introduce a dedicated ambiguity error and rethrow it before passive resolution. origin: PR #583\n- Finding 7: passive open skipped name and client-env bookkeeping (cron rebinding already occurred in addRuntime); apply only the missing bookkeeping. origin: PR #583\n- Finding 30: rlmChildId traffic treated a resident passivating child as closing; join passivation and rehydrate in both bound lookup and direct message hydration branches. origin: PR #589\n\n* fix(coding-agent): restore attach/catch-up ordering invariants and sweep snapshot atomicity\n\n- Finding 22: async snapshot creation exposed clients before attach initialization; publish client attachment only after the snapshot resolves. origin: PR #587\n- Finding 23: catch-up validity was checked only before async snapshot creation; revalidate session and client attachment after the await. origin: PR #587\n- Finding 25: deterministic ambiguous selectors entered the 30-second remote-send retry loop; fail fast for Ambiguous errors. origin: PR #588\n- Finding 28: active rows ignored stable file-keyed schedule pins during active-id rebinding; consult both id- and file-keyed heartbeat/cron sets. origin: PR #588\n- Finding 29: passivation sampled activity before an asynchronous passive-registry walk; complete the walk before atomically sampling summary and admission markers. origin: PR #589\n\n* fix(coding-agent): correct rlmDepth semantics on reference edges, env parsing, and legacy fallbacks\n\n- Finding 8: new-session parent links were deriving spawn depth; copy the source header depth across the reference edge and add a runtime regression test (origin: PR #584).\n- Finding 9: first-entry forks of legacy sessions discarded effective runtime depth; fall back to session.rlmDepth in persisted and in-memory branches and test both (origin: PR #584).\n- Finding 10: root RLM_DEPTH parsing accepted malformed and unsafe values; require decimal digits and a valid safe non-negative integer, with probe cases as tests (origin: PR #584).\n- Finding 11: child-depth derivation could overflow MAX_SAFE_INTEGER; guard the increment and test the boundary (origin: PR #584).\n- Finding 12: daemon children of in-memory parents skipped explicit depth persistence; always create the child header with explicit depth and test --no-session ancestry (origin: PR #584).\n- Finding 13: legacy completed subagents rehydrated at root depth; restore the depth-one fallback and test a registry/header pair without depth (origin: PR #584).\n\n* fix(coding-agent): make /rlm-max-depth persistence honest and unblock stale kernel gate\n\n- /rlm-max-depth --global could claim persistence after deferred settings write failures; drain and surface global errors before reporting success (origin: PR #585)\n- /rlm-max-depth mutated live state before chat persistence and left failed entries indexed; persist first through rollback-safe custom-entry append, then mutate state and prompt (origin: PR #585)\n- invalid persisted global rlmMaxDepth could abort branch navigation after the leaf moved; ignore invalid global reads and fall through to env/default (origin: PR #585)\n- the kernel-side recursion pre-filter used stale one-shot RLM_MAX_DEPTH and blocked raises before the authoritative host gate; remove the duplicated Python gate (origin: PR #585)\n\n* fix(coding-agent): agents-view scope stability, crash-path backSession, summary refresh, pulse, and settings cycling\n\n- Finding 18: stale saved-catalog readiness could destructively drop scope during refresh; reset readiness when refresh starts. origin: PR #586\n- Finding 19: resolved scope roots were lost across view remounts, swallowing early Left navigation; persist and restore the root summary. origin: PR #586\n- Finding 20: post-attach crashes left backSession pointing at the prior session; assign the opened summary before interactive mode runs. origin: PR #586\n- Findings 21 and 24: startup seeding could leave subagent counts stale and background subagents drove an unused render pulse; refresh every seed and pulse only while streaming. origin: PR #587\n- Finding 27: custom idle-eviction values cycled directly to off; include custom numeric values in the sorted cycle. origin: PR #588\n\n* fix(coding-agent): attach reservation vs passivation, binding join on retry, hydration env, settings error scoping, fractional eviction values\n\n- reserve in-flight attaches and revalidate session liveness before attachment (origin: round-1 fix a342ca23d)\n- join concurrent child binding on the final passive resolution retry (origin: round-1 fix ae3ed4571)\n- adopt create-command client env before passive child hydration (origin: round-1 fix ae3ed4571)\n- isolate max-depth write errors while preserving project diagnostics (origin: round-1 fix 9e738f38f)\n- preserve fractional idle eviction values through settings cycling (origin: round-1 fix 721f45b59; stack commit aa98c9aca)\n\n* fix(coding-agent): post-rebase hardening of passive hydration, snapshots, and depth ingestion\n\n- preserve daemon routable IDs for passive children (origin: PR #583)\n- recheck guarded passive hydration and heartbeat restores (origin: PR #583)\n- repair wrong-kind pending hydration joins (origin: PR #583)\n- fence passive hydration during update restart preparation (origin: PR #583)\n- validate persisted RLM depth before constructor ingestion (origin: PR #584)\n- retry attach child snapshots across session replacement (origin: PR #587)\n- retain effective depth for legacy parented new sessions (origin: PR #589)\n- coordinate parent passivation with child hydration publication (origin: PR #589)\n\n* fix(coding-agent): leave shared passive hydration resident on guard cancellation\n\nThe ownership-blind close closed shared hydrations out from under concurrent wakes (both interleavings); the idle sweep is the ownership-free arbiter.\n\norigin: round-4 fix b95640046 / PR #583\n\n* fix(coding-agent): prefer persisted header depth for legacy rehydration entries\n\nThe legacy-entry rehydration fallback (entry.rlmDepth ?? 1) is passed as\nconfig, which outranks the opened transcript header in AgentSession — so a\nnested legacy child whose header carried a deeper persisted depth woke at\ndepth 1, weakening the host recursion gate. Registry depth stays\nauthoritative when present; otherwise the validated header depth wins and 1\nremains the last-resort default for fully legacy children.\n\norigin: PR #584 fallback restored in round-1 triage; surfaced by post-rebase\nbot review of PR #589.\n\n* fix(coding-agent): fence chain hydration against parent passivation; invalidate stale scope roots\n\n* fix(coding-agent): bound the session snapshot stabilization loop\n\n* fix(coding-agent): restore child event forwarder when passivation close fails\n\nPassivation teardown invoked the retained child's event-forwarder\nunsubscribe before closing the session. When the close failed and the\nchild was re-adopted, the forwarder was gone, so a still-resident child\nstopped emitting rlm_child_update to its parent. Teardown now returns\nthe unsubscribe so the passivation path only invokes it after a\nsuccessful close and restores it on the failed-close re-adopt path.\n\n* fix(coding-agent): close child passivation races\n\n- Keep snapshot messages aligned with the final runtime session summary after stabilization exhaustion.\n- Retry passive child hydration when the child starts passivating inside the hydration window.\n- Apply archive and scheduled-job cancellation when kill joins a resume-preserving close.\n\n* fix(coding-agent): upgrade cascading close reasons\n\n- Track the applied close reason and resident descendant states through cascading teardown.\n- Apply stronger joined close effects uniformly to parents and captured descendants.\n- Cover shutdown-to-killed descendant cleanup and completed-to-killed idempotency.\n\n* fix(coding-agent): preserve passive child id on hydration retry\n\n- Forward the restored active-session ID when retrying after a mismatched pending open.\n- Cover the pending-open race through passive-child hydration.\n\n* fix(coding-agent): recover passivation waiters\n\n- Treat failed passivation settlement as a join signal before retrying resident sessions.\n- Cover concurrent open, message delivery, and hydration after passivation rejection.\n\n* fix(coding-agent): harden passivation close races\n\n- Preserve stronger close-reason upgrades when the joined close fails.\n- Run child passivation outside the supervisor-wide eviction fence.\n- Complete reason-upgrade persistence across targets and record the stronger reason before propagating errors.\n\n* fix(coding-agent): preserve passive opener state across races\n\n- Defer root parent client env adoption until passive hydration and its open guard succeed.\n- Join opening or resident passive targets when parent-change restart resolution races hydration."},{"name":"agent-session-autonomous.test.ts","kind":"file","size":22124,"lastCommitHash":"941576dbec6d388de6b9f3cb61bce90cce3f55c4","lastCommitWhen":"2026-08-03T09:56:37+02:00","lastCommitMessage":"refactor(coding-agent): publish session action protocol (#575)\n\n* refactor(coding-agent): publish session action protocol\n\n* fix(coding-agent): restore queue projection guards and recovery validation\n\n* fix(coding-agent): repair test migrations for session action snapshots\n\n* correcting when multiple messages are sent, how it's counted\n\n* fix(coding-agent): await update supervisor teardown (fixes #575)\n\n---------\n\nCo-authored-by: Alex Zhang <alex.lx.zhang@gmail.com>"},{"name":"agent-session-bash-persistence.test.ts","kind":"file","size":21644,"lastCommitHash":"853041ec88f550f4e8d07e523cad82fbbb7e44f9","lastCommitWhen":"2026-08-29T11:08:24+02:00","lastCommitMessage":"fix(coding-agent): abort every in-flight bash command with its own controller (#1882)\n\n* fix(coding-agent): give each executeBash invocation its own abort controller\n\nConcurrent execute_bash_and_wait daemon commands shared the single _bashAbortController field: the first finisher cleared the second command's controller and abortBash could only target the most recent command, leaving earlier still-running commands unabortable. Track per-invocation controllers in a set; abortBash aborts all in-flight commands. Fixes ENG-5752.\n\n* fix(coding-agent): flag pending user bash abort while other bash commands run\n\nabortBash only set _userBashAbortRequested when no abort controllers were registered, so an abort arriving during user_bash extension dispatch was lost when a concurrent executeBash occupied the controller set and the user bash still started. Set the flag whenever a user bash is running; runUserBash clears it at each start. Also reword the per-invocation controller comments to present-tense behavior.\n\n* test(coding-agent): update fake REPLs to protocol 3\n\n---------\n\nCo-authored-by: Xeophon <46377542+xeophon@users.noreply.github.com>"},{"name":"agent-session-compact-skill.test.ts","kind":"file","size":11832,"lastCommitHash":"461bae098e0eec5cd03c3d63453ddd86222ed03a","lastCommitWhen":"2026-07-13T16:37:22-07:00","lastCommitMessage":"Autonomous Eval (#278)\n\n* feat(coding-agent): add auto refine review hook\n\n* fix(coding-agent): keep auto refine model stable\n\n* fix(coding-agent): defer auto refine during compaction continuations\n\n* fix(coding-agent): keep auto refine reviews pending safely\n\n* Add user orchestrator agent messaging and observe\n\n* Add orchestration heartbeat skill\n\n* fix(coding-agent): guard pending auto refine application\n\n* fix(coding-agent): clear auto refine state on branch navigation\n\n* Address user orchestrator PR review comments\n\n* Tighten agent message rate limiting\n\n* Harden agent message queue safety\n\n* Preserve agent message reservations on queue clear\n\n* Serialize agent messages per target\n\n* Handle queued agent message edge cases\n\n* Preserve orchestration heartbeat schedule on refresh\n\n* docs(coding-agent): guide refine scope decisions\n\n* feat(coding-agent): split harness state into local and global scopes\n\n* fix(coding-agent): target refine rollback scope from history\n\n* fix(coding-agent): record auto refine cooldown after branch changes\n\n* fix(coding-agent): harden auto refine scope handling\n\n* feat: add autonomous continuation mode\n\n* feat: require autonomous terminal evidence\n\n* Clarify refine as continual harness state\n\n* Strengthen continual harness refine language\n\n* Balance continual harness and RLM wording\n\n* Fix auto-refine review comments\n\n* Fix refine scope status label\n\n* Address follow-up auto-refine comments\n\n* Preserve refine scope defaults across clients\n\n* Preserve refine scope defaults in servers\n\n* Normalize refine display ids by scope\n\n* Use original local harness for refine rollback\n\n* Harden auto-refine state routing\n\n* Preserve explicit harness dir on cache hits\n\n* Defer heartbeat cron jobs while sessions are active\n\n* feat(coding-agent): default thinking to xhigh\n\n* fix: keep print autonomous gates running\n\n* fix: avoid autonomous gate rerun without workspace changes\n\n* fix: ignore generated lockfile for autonomous gate rerun guard\n\n* fix: keep autonomous evals under verifier control\n\n* fix: let verifier gates complete autonomous evals\n\n* test: update rlm prompt expectation\n\n* fix: keep print-mode autonomous gates progressing\n\n* fix: advance unchanged autonomous gate retries\n\n* fix: keep print-mode gates alive on repeated status\n\n* fix: report print-mode autonomous limit reasons\n\n* fix: ignore failed turns in autonomous usage\n\n* fix: clear queued autonomous continuations\n\n* fix: preserve autonomous continuations on retry\n\n* fix: verify gates before autonomous limits\n\n* fix: keep queued continuations cancellable\n\n* fix: stop print gate loop on assistant errors\n\n* fix: clear autonomous queue on skipped compaction\n\n* fix: restore autonomous state on skipped compaction\n\n* fix: preserve queued autonomous continuations\n\n* fix: keep autonomous print gates alive after transient errors\n\n* fix: count print-mode autonomous gate continuations\n\n* fix: wait for queued autonomous gate retries\n\n* fix: bypass input handlers for autonomous gate retries\n\n* fix(coding-agent): bypass input handlers for internal prompts\n\n* fix(coding-agent): address autonomous review findings\n\n* fix(coding-agent): respect autonomous prompt backpressure\n\n* fix(coding-agent): suppress host gate auto continuations\n\n* fix(coding-agent): preserve queued host gate suppression\n\n* fix(coding-agent): refresh print-mode autonomous gates\n\n* fix(coding-agent): address autonomous review blockers\n\n* fix(coding-agent): harden autonomous gate verification\n\nfixes #278\n\n* fix(coding-agent): kill autonomous gate process trees\n\nfixes #278\n\n---------\n\nCo-authored-by: Kevin Thomas <kevin.jt2007@gmail.com>"},{"name":"agent-session-compaction-continuation.test.ts","kind":"file","size":16160,"lastCommitHash":"ab3db326d161bc31f6dbf2491a1a4e9201e6b965","lastCommitWhen":"2026-08-20T15:57:13+02:00","lastCommitMessage":"fix(coding-agent): reject headless idle waiters when a post-compaction continuation cannot start (#1583)\n\n* fix(coding-agent): reject headless idle waiters when a post-compaction continuation cannot start\n\nA continuation that fails to start settled headless idle as a clean finish,\nso ACP and print-mode callers reported a turn as completed that never ran.\nThe settlement is now one-shot with reject support: non-retryable start\nfailures reject waiters, cancellation and the benign nothing-to-continue\nrace still resolve, a settled failure is never re-exposed to later waiters,\nand interactive waitForIdle is unchanged.\n\nPorts the failure semantics from #881 onto the resident-lifecycle settlement\nfrom #1494. Co-authored-by: Parker Pettit <parkerpettit@users.noreply.github.com>\n\n* docs: cut comments down to single-line load-bearing invariants\n\n* test: keep only the two tests that pin new behavior"},{"name":"agent-session-compaction.test.ts","kind":"file","size":68624,"lastCommitHash":"bee1dc826360b82ca9d943ca856cd2863f597297","lastCommitWhen":"2026-09-01T22:34:13+09:00","lastCommitMessage":"feat(coding-agent): add loss-bounded compaction projection\n"},{"name":"agent-session-goal.test.ts","kind":"file","size":37747,"lastCommitHash":"1793cbc783fab25ac8041103e2a04b2c686d3108","lastCommitWhen":"2026-08-03T16:03:37+02:00","lastCommitMessage":"fix(coding-agent): surface seeded --goal objective to the model (#593)\n\n* fix(coding-agent): surface seeded --goal objective to the model\n\nCLI --goal seeding called _startGoal (persist + accounting) but never\ninjected the goal-context message, which is the model's only source of\ngoal visibility - there is no goal block in the system prompt. The goal\nwas active (accounting ran, budgets fired, footer showed it) while the\nmodel had no idea it existed, on the first turn and on every -c\ncontinuation.\n\nSeed the goal-context message through _pendingNextTurnMessages, the\nexisting next-turn context bucket: construction-safe, delivered with the\nfirst turn, persisted to the transcript for continuations - matching\nwhat /goal does via _runOrQueueGoalContext.\n\n* docs(coding-agent): trim goal-seeding comments to the essentials\n\n* fix(coding-agent): sweep seeded goal context on goal mutations\n\nBot review follow-up: the seeded context lived in\n_pendingNextTurnMessages, which _clearQueuedGoalContexts did not sweep,\nso /goal clear, pause, replace, or host completion before the first\nprompt still delivered the stale objective. Filter it there too."},{"name":"agent-session-model-extension.test.ts","kind":"file","size":24853,"lastCommitHash":"3fc0ac54fad747871c0d2797bce5b21530aecffc","lastCommitWhen":"2026-07-30T17:38:19+02:00","lastCommitMessage":"feat: canonical session-input scheduling with durable, queueable commands (#540)\n\n* feat(agent): stop before scheduling another turn\n\n* test(agent): remove redundant option forwarding coverage\n\n* test(agent): consolidate turn-boundary coverage\n\n* test(coding-agent): skip staged temp files in 4606 status scan\n\n* test(coding-agent): stabilize process-suite cleanup races\n\n* test(process): allow exact supervisor cleanup to settle\n\n* feat(daemon): checkpoint session inputs for restart\n\n* fix(daemon): harden restart checkpoint transactions\n\n* feat(daemon): unify session input admission\n\n* fix(daemon): complete restart transactions safely\n\n* fix(headless): surface command outcomes\n\n* fix(daemon): fence restart manifest capture\n\n* test(process): isolate daemon client environment\n\n* fix(daemon): restore checkpoint handoff state\n\n* fix(daemon): preserve admission completion contracts\n\n* fix(daemon): fence full queued turns before restart\n\n* fix(daemon): settle queued input outcomes\n\n* fix(daemon): preserve restart transaction ownership\n\n* fix(daemon): report prompt admission rejection\n\n* refactor(daemon): collapse update restart state machines\n\n* feat(coding-agent): unify session input scheduling\n\n* test(daemon): consolidate cron admission coverage\n\n* fix(daemon): bound prepare deadline and fence direct prompt acceptance\n\n* fix(headless): drain session-owned inputs before exit\n\n* fix(daemon): settle queued prompt completions\n\n* fix(daemon): fence stale commit clients and injected prompt sections\n\n* test(coding-agent): remove scheduler implementation assertions\n\n* fix(daemon): keep cleared prompts cancelled\n\n* fix(daemon): fence injected dispatch on delivery and env adoption\n\n* fix(coding-agent): harden session input admission\n\n* refactor(coding-agent): unify agent message outcomes\n\n* fix(daemon): fence injected prompts until target handoff\n\n* fix(coding-agent): align command dispatch parsing\n\n* fix(coding-agent): reject re-armed completions for delivered message ids\n\n* fix(daemon): fence admitted work during restart\n\n* fix(coding-agent): serialize command admission\n\n* fix(coding-agent): drop generated prompt-wait outcomes after completion\n\n* fix(daemon): cancel stalled restart checkpoints\n\n* fix(coding-agent): preserve queued continuation semantics\n\n* fix(daemon): preserve scheduled input contracts\n\n* fix(daemon): close restart admission before checkpoint\n\n* fix(coding-agent): avoid redundant continuation turns\n\n* fix(daemon): settle command delivery outcomes\n\n* fix(daemon): preserve merged queue checkpoints\n\n* fix(coding-agent): serialize all turn admission\n\n* test(daemon): preserve merged delivery coverage\n\n* fix(daemon): make drain cancellation terminal\n\n* fix(tui): unify durable compaction presentation\n\n* test(coding-agent): consolidate scheduler coverage\n\n* refactor(coding-agent): route TUI inputs through session admission\n\n* fix(daemon): bound message delivery outcomes\n\n* fix(daemon): preserve restart checkpoint semantics\n\n* test(tui): consolidate compaction presentation coverage\n\n* test(coding-agent): synchronize scheduler integration coverage\n\n* fix(tui): preserve admission ordering\n\n* fix(daemon): cancel pending prompt admission\n\n* fix(daemon): align admission restart integration\n\n* fix(tui): retain successful context usage\n\n* fix(coding-agent): harden queued input lifecycle\n\n* fix(tui): preserve admission errors and retry spacing\n\n* style(daemon): format combined protocol\n\n* fix(daemon): clear restart-rejected admission\n\n* fix(coding-agent): disclose non-durable compaction outcomes\n\n* refactor(coding-agent): consolidate scheduler predicates and coverage\n\n* fix(tui): preserve editor input during startup\n\n* fix(daemon): close prompt admission edge cases\n\n* fix(daemon): release stale parsed admissions\n\n* refactor(coding-agent): simplify compaction outcome handling\n\n* fix(coding-agent): harden queued prompt handoff and refine parsing\n\n* fix(tui): retry startup prompts until admitted\n\n* fix(daemon): close prompt admission races\n\n* fix(daemon): revoke late stale claims\n\n* fix(coding-agent): restore the session file after a torn outcome append\n\n* fix(coding-agent): snapshot prepared prompts adjacent to handoff\n\n* fix(tui): bound startup and follow-up admission\n\n* test(daemon): ignore private handler arity\n\n* fix(daemon): serialize replay admission\n\n* fix(compaction): preserve durable outcomes in headless mode\n\n* fix(coding-agent): suspend the input pump for update-restart aborts\n\n* refactor(tui): simplify startup prompt delivery\n\n* fix(daemon): reconcile prompt admission outcomes\n\n* test(daemon): extend fixture cleanup retries\n\n* fix(session): preserve symlinked atomic rewrites\n\n* fix(scheduler): cancel continuations at abort boundaries\n\n* fix(tui): drop superseded command paths and stop startup prompts at run exit\n\n* fix(daemon): observe cancelled admission work\n\n* fix(daemon): clear restart-rejected admission\n\n* fix(compaction): preserve merged event handling\n\n* fix(scheduler): preserve queued input ownership\n\n* fix(tui): drop submits resumed by run teardown\n\n* fix(daemon): settle admission-only work once\n\n* test(daemon): assert cron admission completion\n\n* feat(coding-agent): add session command primitives\n\n* fix(session): preserve atomic rewrite ownership\n\n* fix(scheduler): derive steering stop from live queue\n\n* fix(tui): preserve stash on lifecycle cancellation\n\n* fix(daemon): preserve steer and follow-up lanes\n\n* fix(daemon): wake checkpoint at prompt handoff\n\n* test(coding-agent): consolidate command message coverage\n\n* fix(tui): preserve transcript on rebuild failure\n\n* fix(scheduler): run checkpoints before steering stop\n\n* fix(tui): cancel startup admission on lifecycle exit\n\n* fix(daemon): preserve definitive prompt failures\n\n* fix(daemon): finish publish after owner loss\n\n* fix(coding-agent): validate command metadata consistency\n\n* fix(compaction): persist outcomes before events\n\n* fix(scheduler): hand off injected follow-ups\n\n* fix(tui): integrate side conversations with admission\n\n* test(daemon): model idle lane insertion\n\n* fix(daemon): adopt deferred attach env on rollback\n\n* fix(coding-agent): align command dispatch parsing\n\n* fix(headless): skip malformed outcome suffix entries\n\n* fix(scheduler): preserve ordered input ownership\n\n* fix(tui): retain rejected rich drafts\n\n* fix(scheduler): observe pre-aborted admission waits\n\n* fix(daemon): reserve update shutdown for publish\n\n* fix(coding-agent): keep multiline slash input literal\n\n* fix(compaction): order equal-time legacy messages after summary\n\n* test(process): sweep late supervisor owners before cleanup\n\n* test(process): terminate late exact supervisor owners\n\n* fix(agent): recheck stop after steering poll\n\n* fix(scheduler): recheck pause at direct admission\n\n* fix(tui): retain lifecycle drafts in submission order\n\n* fix(daemon): preserve client identity and safe markers\n\n* fix(agent): never drop steering drained by the stop-window poll\n\nA stop that flips during the post-tool-batch steering poll no longer ends\nthe loop when that poll returned messages; drained steering owns the turn\nboundary and is injected before the loop can stop.\n\n* fix(scheduler): invalidate queued prompt preparation on branch navigation\n\nCached before_agent_start preparation survives a deferral requeue, so a\nbranch switch during the pause could deliver extension messages prepared\nagainst the old branch. Clear queued prompt preparation when tree\nnavigation rebuilds the session context.\n\n* fix(tui): honor cancellation in pause waits and pin deferred stash release\n\n- forward the abort signal into the queued-work admission wait taken when\n  a pause appears between admission acquire and the ownership commit, so\n  a cancelled prompt rejects instead of blocking until the pause clears\n- capture the stash session id and state when a release is deferred by\n  in-flight submissions, so a /new rebind cannot redirect the deferred\n  release at the new session's state\n- align the prompt-stash submit harness with the submission fields so the\n  draft-retention paths run instead of throwing on missing state\n\n* fix(daemon): keep cancelled admissions definitive across repeated cancels\n\nA second cancel_prompt_admission for an already-cancelled admission now\nshort-circuits with cancelled instead of forwarding to the worker, and a\nworker unknown response can no longer downgrade a cancellation that\nraced in during the round-trip.\n\n* fix(coding-agent): require dispatch proof before releasing the prompt fence\n\nAgent.prompt() resolves even when a lifecycle listener failure produced a\nsynthetic error turn without the injected message ever reaching agent\nstate. Treat a resolved prompt as dispatched only when the dispatch\nobserver fired or the message is present in agent state, so the direct-\nprompt checkpoint section cannot release with the accepted input missing\nfrom both the queue and the run.\n\n* chore(scheduler): tighten fix comments\n\n* chore(tui): tighten fix comments\n\n* chore(agent): tighten fix comments\n\n* chore(daemon): tighten fix comments\n\n* chore(coding-agent): tighten fix comment\n\n* test(agent): flip the stop only on the post-tool-batch steering poll\n\nThe pre-loop poll also set stopRequested, so the pre-steering check\nstopped the loop and the post-empty-poll recheck under test never ran.\nVerified the test now fails when the recheck is removed.\n\n* fix(scheduler): treat pump-owned work as busy for post-compaction continue\n\nThe continuation timer only checked pendingMessageCount, but the pump\nmoves items into _activeSessionInput before handoff, so the timer could\ncall agent.continue() and forget continuations the pump still owned.\nIdle now also requires no active input, no running pump, and no pump\nrequest.\n\n* fix(tui): bind barrier-paused submissions to their original session\n\nA submit paused on the startup-prompt barrier could resume after /new\nrebound the live stash fields, delivering the prompt to and stashing the\ndraft in the wrong session. The submission now captures its session and\nstash state up front, bails out of prompting when the session changed,\nand retains drafts in the captured state.\n\n* fix(scheduler): let queueIfBusy join pending work at direct admission\n\nDirect-turn admission drained queued work before queueIfBusy callers\ncould see it, so heartbeats and accepted agent messages blocked until\nthe queue emptied and then started direct turns. Admission now returns\nimmediately for queueIfBusy callers (allowPendingQueue) and preflight\nenqueues behind the pending work, which also removes the pump-reschedule\nspin while the queue is blocked by bash/compaction/retry.\n\n* chore(agent): tighten test comment\n\n* chore(tui): tighten fix comments\n\n* chore(scheduler): tighten fix comments\n\n* fix(compaction): retain unpersisted outcome disclosures across rebuilds\n\nAn outcome whose session-file append failed lived only in live agent\nstate, so transcript rebuilds from buildSessionContext dropped the\ndisclosure. Failed appends are now retained and appended to rebuilt\ncontexts.\n\n* fix(tui): observe admission cancellation on the streaming prompt path\n\nWhile streaming, _prompt skips direct-turn admission, so an aborted\nadmission signal was never checked and a cancelled startup prompt could\nstill enqueue into a session the user already left. The streaming path\nnow treats its entry as the commit point and rejects already-aborted\nprompts.\n\n* fix(compaction): keep unpersisted outcome disclosures in transcript order\n\nRebuilds appended retained disclosures after every persisted message, so\nturns persisted after the failed append rendered above the notice. The\ndisclosures now merge into the rebuilt context by timestamp.\n\n* fix(daemon): gate admission cancellation on a minimum schema revision\n\nschemaRevision is monotonic, but the admission gates compared it with\nexact equality, so a newer daemon failed signal-backed prompt\ncancellation against an older client even while still advertising\nprompt_admission_cancellation. Both gates now require a minimum\nrevision, matching the protocol.version check.\n\n* fix(compaction): keep unpersisted outcome disclosures across state reloads\n\nSuccessful compaction and tree navigation reload agent.state.messages\nfrom the session file, which dropped disclosures that only exist in\nmemory after a failed append. The timestamp merge now runs on every\nrebuild path via a shared helper.\n\n* chore(tui): tighten fix comment\n\n* chore(daemon): drop redundant gate comment\n\n* chore(compaction): tighten fix comments\n\n* fix(scheduler): treat a skipped compaction as benign in queued commands\n\nA too-short or already-compacted /compact throws CompactionSkippedError,\nwhich compaction_end already surfaces as a warning; the queued-command\nexecutor also recorded a durable 'Command failed' error row for the same\nskip. The executor now ignores the skip.\n\n* fix(daemon): re-validate field-gated requests before reconnect replay\n\nA prompt carrying admissionId that was pending across a reconnect was\nreplayed without re-checking the new daemon_hello, so a replaced or\ndowngraded daemon would silently ignore the admission field and take\nownership of an uncancellable prompt. Pending requests now remember\ntheir schema requirement and reject with the capability error when the\nnew hello no longer satisfies it. Also awaits the newer-revision test's\nrequest so closing the client cannot leak an unhandled rejection.\n\n* fix(tui): keep every deferred prompt-stash release across rebinds\n\nA teardown release after a /new rebind overwrote the pending release\npair captured at the original deferral, so the first session's stash\nstate was never released. Deferred releases now accumulate per session\nand all drain once pending submissions settle.\n\n* fix(tui): restore the compaction loader without a start-event edge\n\nThe compaction spinner was created only on the compaction_start event,\nso a compaction already running when the client attached or returned to\nthe chat (e.g. a /compact queued from the agents view) showed no\nprogress at all until it finished. syncWorkingLoader now restores the\nloader from the connection's isCompacting state, and the loader\ncreation is shared with the event path. Adds core coverage proving the\ncompaction lifecycle events fire for /compact queued behind a running\nturn on both lanes.\n\n* test: consolidate scheduler tests into e2e scenario journeys\n\nReplace ~50 fine-grained scheduler test cases with 7 end-to-end scenario\ntests (S1-S7) that drive the real AgentSession through gated faux-model\nruns with staged, phase-labeled assertions:\n\n- S1: mid-run steering/follow-up/command/custom input ordering\n- S2: queue editing (coalescing, removal APIs, steering-stop reconciliation)\n- S3: pause-lease preparation with anchor re-preparation and direct handoff\n- S4: update-restart abort snapshots and envelope-vs-literal restore\n- S5: queued command delivery vs gated completion outcomes\n- S6: auto-refine via real turns (interval review, busy deferral, branch\n  navigation invalidation) instead of _maybeAutoRefine internals\n- S7: accepted agent-message lifecycle (busy queueing, delivery-before-\n  completion, literal slash commands, cleared-during-admission cleanup)\n\nAlso shrink the 300-iteration outcome-leak loop to 3, drop a typeof-only\nassertion, redundant whitespace-variant and duplicate guard tests.\n\nWhite-box tests for admission-boundary races, cooldown stamping, and\nfault-injection windows are kept; those interleavings have no public\ntrigger. Coverage on agent-session.ts is unchanged (59.7% lines before\nand after) at -516 net test lines.\n\n* fix: close session-input scheduler race windows around admission and restart checkpoints\n\nThree bugbot findings on the scheduler plus one hardening pass:\n\n- promptUntilAccepted no longer waits for the session-input pump after\n  admission: it resolves at ownership commit while queued work (including\n  slash commands) executes, restoring its documented contract.\n- waitForSessionInputCheckpoint now waits for an executing queued session\n  command; the pump shifts commands off the queue before running them, so\n  a restart snapshot could otherwise proceed mid-/compact or /refine and\n  drop the command from durable queued input.\n- The queued-prompt handoff holds a checkpoint section until dispatch is\n  observed. The phase flipped to handedOff (notifying checkpoint waiters)\n  before agent.prompt() ran, so a checkpoint could drain a stale event\n  queue snapshot and flush before the accepted messages persisted.\n- waitForPromiseOrAbort rechecks signal.aborted after registering its\n  abort listener, matching waitForPromptAdmission.\n\nEach fix has a regression test verified to fail against the unfixed code.\n\n* chore: trim comments in scheduler scenarios and race fixes\n\n* fix: fence triggerTurn custom messages for restart checkpoints\n\nsendCustomMessage with triggerTurn took direct-turn admission but never\nentered a direct prompt section, so waitForSessionInputCheckpoint could\nsnapshot between admission and dispatch and miss the in-flight turn.\nHold a checkpoint section from admission until the message dispatches,\nmirroring the queued-handoff fence.\n\n* fix: keep pump-owned session inputs visible as pending\n\nWhen the session-input pump moved prompts or commands into\n_activeSessionInput, they left the typed queues before delivery, so\npendingMessageCount, queue previews, snapshots, and queue_update briefly\nreported an empty queue during preparation and long-running queued\ncommands, and agent-message backpressure undercounted.\n\nCount still-preparing prompts and executing commands as pending, emit\nqueue updates at prompt handoff and command completion, and clear\nownership before the deferred-requeue emit so items are not\ndouble-counted.\n\n* fix: harden durable command persistence and cleared-input accounting\n\nTwo bugbot findings on the queued session-command path:\n\n- _appendDurableSessionCommandMessage now persists through\n  appendCustomMessageEntryWithRollback before touching live state, so a\n  failed write cannot leave an unsaved leaf or a transcript/file\n  divergence; the failure-row append no longer masks the original\n  command error.\n\n- clearQueue marks the preparing active input cancelled;\n  _undeliveredActiveSessionInputs now excludes cancelled items so\n  pendingMessageCount, previews, and queue updates drop cleared work\n  immediately instead of waiting for the pump to unwind.\n\n* fix: stop coalescing follow-up keys against handed-off prompts\n\nFollow-up queueKey coalescing treated all _activeSessionInput prompt\nitems as pending owners. After handoff the prompt is committed to the\nrunning turn, so a later same-key follow-up (e.g. a heartbeat) was\nrejected for the rest of that turn instead of queueing behind it.\nCoalesce only against a preparing, non-cancelled active input, shared by\n_enqueueSessionInput and hasQueuedFollowUp.\n\n* fix: count session-owned queues as queued work after compaction\n\nPost-compaction decisions only consulted agent.hasQueuedMessages(), but\nqueued prompts and commands now live in the session-owned steer and\nfollow-up queues. Include pendingMessageCount so auto-refine defers to\nthe next turn boundary instead of running before queued input turns,\nand post-compaction continue is scheduled when only session-owned work\nis waiting (manual, auto, and failure-resume paths).\n\n* fix(daemon): centralize prompt admission compatibility\n\n* fix(daemon): recheck command compatibility on replay"},{"name":"agent-session-observe.test.ts","kind":"file","size":3544,"lastCommitHash":"941576dbec6d388de6b9f3cb61bce90cce3f55c4","lastCommitWhen":"2026-08-03T09:56:37+02:00","lastCommitMessage":"refactor(coding-agent): publish session action protocol (#575)\n\n* refactor(coding-agent): publish session action protocol\n\n* fix(coding-agent): restore queue projection guards and recovery validation\n\n* fix(coding-agent): repair test migrations for session action snapshots\n\n* correcting when multiple messages are sent, how it's counted\n\n* fix(coding-agent): await update supervisor teardown (fixes #575)\n\n---------\n\nCo-authored-by: Alex Zhang <alex.lx.zhang@gmail.com>"},{"name":"agent-session-prompt.test.ts","kind":"file","size":73344,"lastCommitHash":"9e49b73dd46908b3e400f4780b46a90daef69052","lastCommitWhen":"2026-08-24T01:44:54-07:00","lastCommitMessage":"feat(coding-agent): default RLM max depth to 2 (#1493)\n\n* feat(coding-agent): default RLM max depth to 2\n\n* test(coding-agent): pin max depth in prompt update case\n\n---------\n\nCo-authored-by: Sebastian <sebastian@primeintellect.ai>"},{"name":"agent-session-queue.test.ts","kind":"file","size":141274,"lastCommitHash":"dab03c00c45e474186a3c6d6d654adb33c848fb3","lastCommitWhen":"2026-08-29T10:54:41+02:00","lastCommitMessage":"refactor(coding-agent): wake RLM quiescence on activity changes instead of polling (#1859)\n\n* fix(coding-agent): serialize post-compaction continuation on run settlement\n\n* refactor(coding-agent): wake RLM quiescence on activity changes instead of polling\n\n* fix(coding-agent): guard post-compaction continue against auto-compaction and stale runners\n\n- Publish _compactionOperation from _runAutoCompaction so the\n  post-compaction continuation runner (and other waiters) serialize\n  against auto/threshold/overflow/requested compaction, not just\n  manual compact().\n- Identity-guard the success path of the continuation runner so a\n  cancelled runner cannot forget continuation messages that a\n  replacement settlement still owns (busy/error paths already did).\n\n* fix(coding-agent): recheck refine apply before dispatching post-compaction continue\n\nA refine() call could enter its apply phase (which disconnects the agent\nevent listener) between the runner's top-of-loop _waitForRefineIdle() and\nagent.continue(), losing the continuation's messages. Recheck\n_refineInFlight under the commit fence like pauses/_compactionOperation;\nthe path from that recheck to agent.continue() is synchronous, mirroring\nthe final refine barrier used by normal turn dispatch.\n\n* fix(coding-agent): release the continuation runner's idle wait on cancel\n\nA cancelled post-compaction continuation left its runner parked inside\nwaitForIdle when the pump was suspended with queued actions: the wait\nwas not raced against the settlement like its neighbors, so the runner\nre-registered a session-input checkpoint waiter on every notify. The\nleaked waiter kept hasPendingAdmissionWaiters true and blocked daemon\npassivation until an unrelated resume.\n\nwaitForIdle's loop now takes an optional settlement: the suspended-queue\npark races the settlement promise, deregisters its waiter on loss, and\nthe loop exits once the settlement is superseded. The runner uses the\nsettlement-scoped variant; public waitForIdle is unchanged."},{"name":"agent-session-refine-extension.test.ts","kind":"file","size":8970,"lastCommitHash":"108eff32ea843baf4337e1de9d9ccb3cec6d97fa","lastCommitWhen":"2026-08-21T10:59:31-07:00","lastCommitMessage":"feat(coding-agent): session_before_refine extension hook (#1558)\n\n* feat(coding-agent): session_before_refine extension hook\n\nLet extensions customize continual-harness refinement the same way\nsession_before_compact customizes compaction. The hook fires before the\nplanning LLM call for /refine and auto-refine with the planning inputs\n(trigger, instructions, scope, planning harness state, refinement\nhistory, serialized conversation). An extension can return a\nRefinementProposal to replace the built-in planner (edits still pass\napply-time validation and baseline conflict rejection), return\n{ skip: true } to suppress the round, or return nothing to fall back to\nthe default planner. Rollback refinements bypass the hook.\n\nIncludes examples/extensions/custom-refinement.ts (planning with a\ncheaper model, covering discussion #1464) and documents the existing\nrefine_complete event.\n\n* Update queue-test refine call assertions for the trigger argument\n\n* Propagate the auto trigger and skip semantics through serialized refine paths\n\nSerialized auto-refine now reaches session_before_refine with trigger\n\"auto\", an extension skip there stamps the cooldown without emitting\nrefine_failed, and a skipped explicit refine.run surfaces the\nRefineSkippedError instead of passing as a silent reviewer decline. The\nexample planner now labels entry ids with their scope and tells the\nmodel other-scope entries are read-only.\n\n* fix(coding-agent): consume skipped auto-refine rounds\n\n* fix(coding-agent): report skipped refine during disposal\n\n* fix(coding-agent): normalize extension refine proposals\n\n---------\n\nCo-authored-by: Seth <seth@primeintellect.ai>"},{"name":"agent-session-refine-skill.test.ts","kind":"file","size":11858,"lastCommitHash":"42ea9046ab9f75bc0fcf9f455d853f530cc15ae7","lastCommitWhen":"2026-07-23T17:52:00-07:00","lastCommitMessage":"feat(coding-agent): agent-callable refine skill (#504)\n\n* feat(coding-agent): background refine planning to not block conversation\n\nSplit the synchronous _refine() flow into two phases:\n- Planning (background): LLM call via completeSimple without\n  disconnecting from agent events or aborting the agent\n- Application (synchronous, fast): waits for agent idle, then\n  disconnects briefly, applies proposal, saves harness state,\n  rebuilds system prompt, emits refine_complete event\n\nrefine() public method signature unchanged. _waitForRefineIdle()\nonly blocks for the application phase. Interactive mode\nhandleRefineCommand fires refine without blocking the UI.\n\nRace condition fixes found by Macroscope and Cursor Bugbot:\n- Serialize concurrent refine calls via _refineApplyPending flag\n- Remove abort() from apply phase to preserve concurrent work\n- Narrow _refineInFlight to only cover disconnect+apply+reconnect\n- Re-check _refineApplyPending at turn handoff guards\n- Block turns during apply transition window\n- Clear _refineApplyPending on dispose\n- Re-sync systemPrompt after refine completes at handoff\n\n* fix(coding-agent): harden refine error paths and in-flight guard\n\n- Schedule pending message resume on planning failure and cancellation\n  so queued turns started during background planning are not stranded\n- Set _refineInFlight before calling _applyRefine so synchronous\n  listeners on refine_complete see the guard\n- Wrap refine_complete _emit in try/catch so listener failures do not\n  flip a successful refinement into a reported failure\n\nFound by Cursor Bugbot and Macroscope.\n\n* fix(coding-agent): preserve extension systemPrompt at handoff re-sync\n\nRestore extensionResult?.systemPrompt ?? this._baseSystemPrompt at\nline 3056 which was accidentally changed to just this._baseSystemPrompt\nduring the handoff re-sync refactor. Without this, heartbeat and other\nextension-modified system prompts were clobbered.\n\n* fix(coding-agent): preserve extension systemPrompt at handoff re-sync\n\nLift extensionResult declaration outside the try block so it can be\nreferenced at the handoff re-sync point. After _waitForRefineIdle,\nre-apply extensionResult?.systemPrompt ?? this._baseSystemPrompt\ninstead of just this._baseSystemPrompt so extension-modified prompts\nsurvive a concurrent refine.\n\nFound by Macroscope.\n\n* fix(coding-agent): harden background refinement (fixes #497)\n\n* feat(coding-agent): agent-callable refine skill\n\nAdd a  Python skill (SKILL.md + kernel package) that lets the\nmodel schedule continual harness refinement from IPython via\n, mirroring how the compact skill works as both an\nagent-callable tool and a user command.\n\nChanges:\n- New  skill with  and  API\n  in packages/coding-agent/skills/refine/\n- Add  to AgentSession:  stores a\n  pending request and returns immediately (non-blocking);\n  reports pending/in-flight state\n- Register  and  handlers in the kernel host\n  bridge, gated by\n- Add  fired at the turn boundary after\n  compaction checks; calls  fire-and-forget so it cannot\n  deadlock the active tool call\n- Filter the  skill from  when auto-refine\n  is not available (non-persisted sessions, subagent depth > 0)\n- Clean up  in the dispose path\n- Update RLM prompt and harness state instructions to reference\n   instead of\n- Add  constant to refinement module\n- 16 tests covering scheduling, status, turn-boundary consumption,\n  validation, gating, and dispose cleanup\n\n* test(coding-agent): align refine skill prompt assertions\n\n* feat(coding-agent): serialize refinement and persist initial goals\n\nSerialize automatic refinement at turn boundaries, abort stale branch work,\nprotect concurrent harness writes with baseline conflict checks, and preserve\nsubagent model selection across daemon rehydration.\n\nAdd durable top-level initial goals, daemon/SDK plumbing, immediate session\nflushes, inherited daemon-worker environment scrubbing, refine_complete\nevents, and real JSON CLI/socket/supervisor/worker process coverage.\n\n* fix: preserve serialized refine and snapshot catch-up\n\n* fix: guard agent_end auto-refine scheduling in serialized mode\n\nIn serialized mode, _scheduleAutoRefineAfterAgentEnd was called\nunconditionally at agent_end. When a background plan failed at the\nshouldStopAfterTurn boundary (cooldownMs=0, turn threshold met),\n_maybeAutoRefine fired from the interactive path via setTimeout(0),\nrunning a duplicate review+refine the boundary explicitly skipped.\n\nGuard _scheduleAutoRefineAfterAgentEnd behind the existing\n!this._serializedRefine check at the agent_end handler, matching\nthe _consumePendingRequestedRefine guard one line above.\n\nRegression test proves agent_end does not schedule _maybeAutoRefine\nafter a checkpoint failure (cooldownMs=0, turnInterval=1).\n\n* test: drive agent_end event path in serialized auto-refine guard regression\n\nThe previous test only waited after the checkpoint without actually\ninvoking the agent_end code path, so it passed even with the guard\nreverted. Now sets _lastAssistantMessage, spies\n_scheduleAutoRefineAfterAgentEnd, mocks _checkCompaction(false), and\ndrives _handleAgentEvent({type:'agent_end'}) through\n_processAgentEvent → _agentEventQueue. Verified the test fails when\nthe guard is temporarily reverted and passes when restored.\n\n* fix: re-queue explicit refine.run on serialized background plan failure\n\nWhen serialized background planning for an explicit refine.run fails\nat the turn boundary, the consumed request was silently dropped — the\nagent received 'scheduled: true' but no refinement ran.\n\nSerializedBackgroundPlanResult failure now carries explicit, options,\nand branchVersion. At the checkpoint, when the failure was for an\nexplicit request (skipReview=true), branchVersion is still current,\nand no newer _pendingRequestedRefine exists, the original options are\nrestored to _pendingRequestedRefine and fall through to the existing\nsynchronous pending path. Newer requests retain priority; interval\nfailures keep no-retry cooldown semantics; stale branch failures never\nrequeue.\n\nTests: (1) explicit bg plan fails then boundary replan/apply succeeds,\n(2) interval bg failure does not retry, (3) stale branch failure does\nnot requeue, (4) newer pending supersedes failed older request.\n\n* fix: prevent disposal double-refine after explicit drain\n\nIn _drainPendingRefinementForDisposal, after draining a pending\nrefine.run via _runSerializedRefine, _assistantTurnsSinceAutoRefine\nand _lastAutoRefineReviewAt were not reset. The subsequent interval\ncheck could trigger a second refinement during teardown.\n\nStamp cooldown and reset counter immediately after the explicit\ndrain, mirroring the background-plan drain path above.\n\nRegression test proves: one explicit plan/apply and zero subsequent\ninterval review/apply during disposal when the turn counter was due.\nTest verified to fail (2 planCalls) when the bookkeeping is reverted\nand pass (1 planCall) when restored.\n\nNote: public refine() vs _serializedPlanInFlight coordination deferred\npending independent design review — that hunk was reverted.\n\n* fix: coordinate public refine with serialized background planning\n\nPublic refine() now waits for _serializedPlanInFlight in its\nserialization loop. When a serialized background plan is in flight\n(started during an active turn at message_end), public refine first\nawaits the plan promise (no overlapping model calls), then waits for\nagent idle so the active turn's shouldStopAfterTurn checkpoint\nconsumes and applies the plan. Only then does public planning start.\n\nThis prevents: (1) overlapping _planRefine model calls, (2) mid-turn\n_applyRefine via _applySerializedPlan, (3) duplicate consumers of\nthe same serialized plan promise.\n\nRegression test uses a real active turn with a blocking gate tool:\nwhile the tool executes, an explicit refine.run starts bg planning,\nthen public refine() is called concurrently. Asserts max _planRefine\nconcurrency=1, bg plan applied once, public plan applied once.\nVerified mutant-sensitive: fails (planCalls=2, concurrent) without\nthe guard, passes (planCalls sequential) with it.\n\nAlso fixes disposal double-refine: after draining a pending\nrefine.run via _runSerializedRefine, stamps cooldown and resets\n_assistantTurnsSinceAutoRefine so the interval check doesn't trigger\na second refinement during teardown.\n\n* test: strengthen public-refine concurrency regression\n\nGate tool now signals from execute entry; asserts isStreaming===true\nbefore calling handleRefineHostRequest (no manual isStreaming\nfalsification). Replaces Promise.allSettled with Promise.race against\na bounded 10s timeout so failures surface. Captures plan objects and\noptions on _applyRefine, asserts apply order/identity: bg plan-1\nwith instructions 'bg' first, then public plan-2 with instructions\n'public'. Mutant-sensitive: fails (planCalls=2, concurrent) on\npre-fix source, passes with the guard.\n\n* Fix quiescence, aborted-refine, and prompt race in refine apply\n\nSnapshot _baseSystemPrompt before extension hooks so a refine that\ncompletes during the hook is detected and its stale extension prompt\ndiscarded. Replace bare waitForIdle in _applyRefine with requestAbort +\nPromise.allSettled over agent, event queue, compaction, and branch\nsummary to ensure full session quiescence without cancelling child\nruns. Clear _pendingRequestedRefine on aborted turns so stale requests\ndo not leak to subsequent checkpoints. Force pending message resume\nafter refine to re-arm queue drained by requestAbort.\n\n* fix(coding-agent): preserve refine completion event wiring\n\n* fix(coding-agent): defer serialized compaction refinement\n\n* fix(coding-agent): finish headless stack review fixes\n\nfixes #497\n\n* fix(coding-agent): cancel queued refinement on abort\n\nfixes #514\n\n* fix(coding-agent): harden refinement lifecycle (fixes #514)\n\n* fix(coding-agent): resolve serialized refine races (fixes #514)\n\n* fix(coding-agent): guard serialized planning (fixes #514)\n\n* fix(coding-agent): preserve injected prompt extensions (fixes #514)\n\n* fix(coding-agent): preserve empty injected prompts (fixes #514)\n\n* fix(coding-agent): harden combined refine stack (fixes #504)\n\n* fix(coding-agent): clear aborted refine options (fixes #504)\n\n* fix(coding-agent): make latest refine request win (fixes #504)\n\n* fix(coding-agent): record stale refine cooldown (fixes #504)\n\n* fix(coding-agent): prioritize explicit refine (fixes #504)\n\n* fix(coding-agent): close final refine races (fixes #504)\n\n* fix(coding-agent): invalidate superseded refine plans (fixes #504)\n\n---------\n\nCo-authored-by: Kevin Thomas <kevin.jt2007@gmail.com>"},{"name":"agent-session-retry-events.test.ts","kind":"file","size":20498,"lastCommitHash":"941576dbec6d388de6b9f3cb61bce90cce3f55c4","lastCommitWhen":"2026-08-03T09:56:37+02:00","lastCommitMessage":"refactor(coding-agent): publish session action protocol (#575)\n\n* refactor(coding-agent): publish session action protocol\n\n* fix(coding-agent): restore queue projection guards and recovery validation\n\n* fix(coding-agent): repair test migrations for session action snapshots\n\n* correcting when multiple messages are sent, how it's counted\n\n* fix(coding-agent): await update supervisor teardown (fixes #575)\n\n---------\n\nCo-authored-by: Alex Zhang <alex.lx.zhang@gmail.com>"},{"name":"agent-session-runtime.test.ts","kind":"file","size":31648,"lastCommitHash":"7e70aea03dcf78c97aa65cc2a8e1aeb2a068e5fe","lastCommitWhen":"2026-08-31T22:05:28+09:00","lastCommitMessage":"complete guarded RLM results and background completion wakeups\n"},{"name":"agent-session-serialized-refine.test.ts","kind":"file","size":104032,"lastCommitHash":"941576dbec6d388de6b9f3cb61bce90cce3f55c4","lastCommitWhen":"2026-08-03T09:56:37+02:00","lastCommitMessage":"refactor(coding-agent): publish session action protocol (#575)\n\n* refactor(coding-agent): publish session action protocol\n\n* fix(coding-agent): restore queue projection guards and recovery validation\n\n* fix(coding-agent): repair test migrations for session action snapshots\n\n* correcting when multiple messages are sent, how it's counted\n\n* fix(coding-agent): await update supervisor teardown (fixes #575)\n\n---------\n\nCo-authored-by: Alex Zhang <alex.lx.zhang@gmail.com>"},{"name":"daemon-serialized-refine-process.test.ts","kind":"file","size":12764,"lastCommitHash":"61eb64748eb077e2a084432db92d101a2a83e146","lastCommitWhen":"2026-08-26T15:24:10-07:00","lastCommitMessage":"Minimal CPython REPL runtime (rlm.repl) (#1685)\n\n* feat(coding-agent): add async-by-default bash() to the kernel runtime\n\n* chore(coding-agent): tighten bash() comments and changelog fragment\n\n* feat(coding-agent): add a standalone CPython REPL runtime speaking JSON lines over stdio\n\n* chore(coding-agent): tighten REPL runtime comments\n\n* feat(coding-agent): run the kernel on the REPL runtime over stdio\n\n* fix(coding-agent): reject pending host requests on kernel teardown\n\nThe runtime now fails pending host_request futures when stdin hits EOF or\na shutdown request arrives, so a cell awaiting a host reply can no longer\nblock _serve from consuming the shutdown and wedge the process. Startup\nand busy-kernel messages plus the ipython tool description now say Python\nkernel, matching the default REPL runtime client.\n\n* chore(coding-agent): describe the kernel-heavy test tag client-neutrally\n\n* feat(coding-agent): make the REPL runtime the only kernel\n\nRemoves the Jupyter/ipykernel/ZMQ kernel client, the fork server, the\nPRIME_AGENT_KERNEL escape hatch, and the %%bash/%cd/%env cell rewriting.\nMagic-style cells (%/%%/!) return a one-line error naming the Python or\nbash() replacement. The kernel venv no longer installs ipykernel;\nexisting venvs are rebuilt once via the bootstrap schema bump. Old\nsnapshot artifacts still restore through the runtime's pickle compat.\n\n* fix(coding-agent): close MCP transports in REPL shutdown\n\n* fix(coding-agent): address bash() review findings — exact tail retention, foreground-status lifecycle with group anchoring, post-kill forkserver reap, Windows start-id parity, executor-free await\n\n* fix(coding-agent): tree-kill bash() process trees on Windows and make running reflect group liveness\n\n* fix(runtime): address repl runtime review findings\n\n- revalidate targeted interrupts through SIGINT delivery so a stale signal\n  cannot cancel a later request\n- preserve a parked untargeted interrupt while another request is inflight\n- reject non-string interrupt ids and validate snapshot options\n  (prune_oversized bool, max_bytes/max_variable_bytes present => int)\n- guard str(exc) in error/skip/fail reasons so a broken __str__ cannot\n  kill the runtime\n- fail the snapshot when the manifest write fails (before any pruning)\n- report 'snapshot not found' reason on restore of a missing path\n- wait unbounded for the output-pump drain marker so done never precedes\n  captured output and marker bytes never leak\n- document that aggregate-cap skips are not pruned\n\n* fix(coding-agent): carry bash() status pipe as stdin so strict-POSIX shells accept single-digit fd redirections\n\n* fix(coding-agent): address host-swap review findings — runtime-neutral kernel wording, %cd/%env rewrite fidelity, linear-time magic regexes, restart supersession guard\n\n* fix(coding-agent): reject stale column-0 line magics on any cell line, not just the first\n\n* fix(coding-agent): close status fds when wake-pipe creation fails and gate bash() commands on orphan-journal registration\n\n* fix(coding-agent): strip quoted %cd targets, use UTF-16-safe %env parsing, and expand $var/${var} values PEP-215-style\n\n* fix(coding-agent): fail rlm.run fast outside a live kernel so vitest workers cannot hang on a comm that never replies\n\n* fix(coding-agent): clear the active cell id before terminal events so late background output is never tagged with a finished cell\n\n* fix(coding-agent): update legacy IPython-era tests to assert cutover behavior\n\n* fix(coding-agent): describe the column-0 magic scan without referencing the removed rewrite backend\n\n* fix(coding-agent): consume parked interrupts on compile failures and survive user-closed stdio in the drain path\n\n* fix(coding-agent): redact bare %env listings, prefer '=' in %env parsing, echo %cd targets, and keep graceful shutdowns owning their cleanup\n\n* fix(coding-agent): reject kernel startup promptly on spawn errors and commit %cd previous-dir tracking only after chdir succeeds\n\n* fix(coding-agent): trim ParsedIpythonBashCell to the body field its callers use\n\n* fix(coding-agent): kill full process trees in the Windows orphan reaper via taskkill /T\n\n* fix(coding-agent): survive compile-phase crashes and fd-reuse drain hangs in the REPL runtime\n\n* fix(coding-agent): shield snapshot prune deletions from interrupts and pin the host comm probe to its real seam\n\n* fix(coding-agent): route list_names through the per-request backstop and skip non-string namespace keys\n\n* fix(coding-agent): reject snapshot requests whose manifest path aliases the payload path\n\n* fix(coding-agent): reject negative snapshot size caps that would prune every user variable\n\n* fix(coding-agent): kill one-shot await bash() on cancel, resolve Windows helpers via System32, retry taskkill after reap, and fail closed on orphan-journal enrollment\n\n* fix(coding-agent): attribute REPL stream output at write time so raw fd and user-thread bytes never carry another cell's id\n\n* fix(coding-agent): surface unattributed REPL stream output as separate background output instead of dropping or merging it\n\n* fix(coding-agent): confirm group exit before a cancelled one-shot bash() await propagates and complete-write orphan-journal records\n\n* fix(coding-agent): expose a working sys.stdout.buffer on the tagged REPL writer routing bytes through the null-attributed raw channel\n\n* fix(coding-agent): mark between-cell background output truncated when the pending buffer cap is hit\n\n* fix(coding-agent): shield the cancelled-await bash() confirm-exit from re-cancellation, fail clearly without bash on Windows, and fence slow pumps out of result assembly\n\n* fix(coding-agent): survive hostile protocol lines in the REPL reader thread and interrupt without pthread_kill on Windows\n\n* fix(coding-agent): send the protocol shutdown from dispose() so the runtime closes MCP servers and kills live bash groups before the hard kill\n\n* fix(coding-agent): flag the pump's read-to-commit window so the bash() drain fence cannot miss an in-flight chunk\n\n* fix(coding-agent): guard the whole REPL request line against hostile input, reject duplicate in-flight ids, complete short buffer-pipe writes, and clean the snapshot temp file on KeyboardInterrupt\n\n* fix(coding-agent): drop stale between-cell background output on kernel teardown so it cannot surface after a restart\n\n* fix(coding-agent): assert the tagged channel only in the large buffer-write REPL test since cross-channel ordering is not guaranteed\n\n* fix(coding-agent): resolve taskkill via absolute System32 path in the host orphan reaper\n\n* fix(coding-agent): write the inactive orphan-journal record only after a delivered kill so undelivered signals leave the host reaper in charge\n\n* fix(coding-agent): keep a REPL request interrupt-targetable through its trailing-expression repr and output drain until done is emitted\n\n* fix(coding-agent): count an already-exited leader as delivered in the Windows bash() reap so clean exits still journal inactive\n\n* fix(coding-agent): reject NaN and Infinity in emit() payloads before they corrupt REPL protocol framing\n\n* chore(coding-agent): correct the stale ipykernel requirement on the python override doc\n\n* chore(coding-agent): drop migration-era wording from kernel comments\n\n* fix(coding-agent): resolve trusted absolute shell host-side and close Windows journal/reap gaps\n\n* fix(coding-agent): best-effort-kill pid-only orphan records in daemon force-stop and recovery reaps\n\n* refactor(coding-agent): drop the magic-cell rejection gate\n\n%-prefixed and !-prefixed cells now reach CPython and fail with its own\nSyntaxError, which names the offending line. The rejection layer guarded\nagainst model-produced IPython syntax, but with the shipped prompt fresh\nsessions do not produce it, and the plain SyntaxError is protection enough.\nparseIpythonBashCell stays: transcripts from ipykernel-era sessions render\n%%bash cells with shell highlighting forever.\n\n* fix(coding-agent): report a committed destructive snapshot as success even when an interrupt was parked\n\n* chore(ai): drop stray live-regen drift in models.generated.ts\n\nad657d7ec accidentally committed generate-models output produced by a local\nbuild; the catalog belongs to its own regen PRs.\n\n* test(coding-agent): expect a plain SyntaxError for legacy %%bash cells after the magic-rejection gate removal\n\n* fix(coding-agent): consume a finishing-targeted interrupt after a completed state request instead of failing the done\n\n* fix(coding-agent): exit the REPL runtime when its owner dies even during a busy cell\n\n* fix(coding-agent): resolve the kernel bash shell only from trusted absolute paths on Windows\n\n* fix(coding-agent): contain Windows bash children with kill-on-close job objects\n\n* test(coding-agent): cover owner death during a non-yielding REPL cell\n\n* fix(coding-agent): skip concurrently deleted names during snapshot instead of aborting\n\n* fix(coding-agent): fall back to taskkill when job termination fails\n\n* fix(coding-agent): stop telling REPL-default users they need ipykernel\n\n* fix(coding-agent): clear the SIGINT target when its request finishes\n\n* test(coding-agent): drop migration-era wording from the %%bash rejection comment\n\n* fix(coding-agent): start Windows bash children suspended and fail closed when job containment cannot be established\n\n* fix(coding-agent): re-assert the kernel SIGINT handler between cells so a cell rebinding SIGINT cannot break interrupts\n\n* fix(coding-agent): kill the whole tree for enriched orphan records on Windows force-stop\n\nstopTrackedProcess signals only the shell pid on Windows; use killOrphanProcess (taskkill /T) after the identity check, matching the owned-session-worker and daemon-supervisor reapers.\n\n* docs(coding-agent): describe current magic-cell behavior in release notes\n\nMagic-style cells fail with a plain SyntaxError; the migration error and %cd/%env rewrites were removed, so the notes stop claiming them.\n\n* fix(coding-agent): skip the liveness check when the orphan identity is stale\n\nA reused pid looked like a failed kill after the identity re-check skipped taskkill, blocking worker cleanup with a spurious failure.\n\n* fix(coding-agent): journal Windows bash() children before job assignment so a kernel kill mid-spawn cannot leak an unjournaled suspended process\n\n* fix(coding-agent): pre-create the Windows bash() job before spawn and contain the child before the journal start-id query\n\n* fix(coding-agent): create Windows bash() children atomically inside the kill-on-close job via PROC_THREAD_ATTRIBUTE_JOB_LIST, closing the Popen-to-assignment leak window\n\n* chore(coding-agent): compress the atomic-job-association comments to one-line rationale\n\n* fix(coding-agent): send duplicate-id protocol errors outside the interrupt lock and reject int payloads in the captured stdout buffer\n\n* docs(coding-agent): update the kernel provisioner docstring for the REPL/IPython split\n\n* fix(coding-agent): retain the Windows bash() process handle through job cleanup and taskkill fallbacks so a recycled pid can never be killed\n\n* fix(coding-agent): serialize Windows bash() abort cleanup under the kill lock so shutdown taskkill can never race the process-handle close\n\n* fix(coding-agent): commit REPL snapshot payload and manifest atomically via unique temp files with guaranteed cleanup and parked-SIGINT restore\n\n* fix(coding-agent): stage REPL restore before an interrupt-parked apply and recover committed snapshot/restore results from protocol interrupts so a committed operation is never misreported as failed\n\n* chore(coding-agent): compress restore-shield rationale comments to one line each\n\n* fix(coding-agent): surface unattributed background output in IPython cell details and render it after the traceback in the expanded cell view\n\n* docs(coding-agent): replace stale Jupyter comm vocabulary in rlm-runtime failure modes and focused validation with stdio-transport equivalents\n\n* docs(coding-agent): describe the REPL trust boundary and runtime-bootstrap failure in stdio terms and drop the removed TokenUsage export\n\n* fix(runtime): address REPL review findings\n\n* fix(runtime): preserve near-cap snapshots\n\n---------\n\nCo-authored-by: Seth <seth@primeintellect.ai>"},{"name":"daemon-serialized-refine.test.ts","kind":"file","size":7930,"lastCommitHash":"42ea9046ab9f75bc0fcf9f455d853f530cc15ae7","lastCommitWhen":"2026-07-23T17:52:00-07:00","lastCommitMessage":"feat(coding-agent): agent-callable refine skill (#504)\n\n* feat(coding-agent): background refine planning to not block conversation\n\nSplit the synchronous _refine() flow into two phases:\n- Planning (background): LLM call via completeSimple without\n  disconnecting from agent events or aborting the agent\n- Application (synchronous, fast): waits for agent idle, then\n  disconnects briefly, applies proposal, saves harness state,\n  rebuilds system prompt, emits refine_complete event\n\nrefine() public method signature unchanged. _waitForRefineIdle()\nonly blocks for the application phase. Interactive mode\nhandleRefineCommand fires refine without blocking the UI.\n\nRace condition fixes found by Macroscope and Cursor Bugbot:\n- Serialize concurrent refine calls via _refineApplyPending flag\n- Remove abort() from apply phase to preserve concurrent work\n- Narrow _refineInFlight to only cover disconnect+apply+reconnect\n- Re-check _refineApplyPending at turn handoff guards\n- Block turns during apply transition window\n- Clear _refineApplyPending on dispose\n- Re-sync systemPrompt after refine completes at handoff\n\n* fix(coding-agent): harden refine error paths and in-flight guard\n\n- Schedule pending message resume on planning failure and cancellation\n  so queued turns started during background planning are not stranded\n- Set _refineInFlight before calling _applyRefine so synchronous\n  listeners on refine_complete see the guard\n- Wrap refine_complete _emit in try/catch so listener failures do not\n  flip a successful refinement into a reported failure\n\nFound by Cursor Bugbot and Macroscope.\n\n* fix(coding-agent): preserve extension systemPrompt at handoff re-sync\n\nRestore extensionResult?.systemPrompt ?? this._baseSystemPrompt at\nline 3056 which was accidentally changed to just this._baseSystemPrompt\nduring the handoff re-sync refactor. Without this, heartbeat and other\nextension-modified system prompts were clobbered.\n\n* fix(coding-agent): preserve extension systemPrompt at handoff re-sync\n\nLift extensionResult declaration outside the try block so it can be\nreferenced at the handoff re-sync point. After _waitForRefineIdle,\nre-apply extensionResult?.systemPrompt ?? this._baseSystemPrompt\ninstead of just this._baseSystemPrompt so extension-modified prompts\nsurvive a concurrent refine.\n\nFound by Macroscope.\n\n* fix(coding-agent): harden background refinement (fixes #497)\n\n* feat(coding-agent): agent-callable refine skill\n\nAdd a  Python skill (SKILL.md + kernel package) that lets the\nmodel schedule continual harness refinement from IPython via\n, mirroring how the compact skill works as both an\nagent-callable tool and a user command.\n\nChanges:\n- New  skill with  and  API\n  in packages/coding-agent/skills/refine/\n- Add  to AgentSession:  stores a\n  pending request and returns immediately (non-blocking);\n  reports pending/in-flight state\n- Register  and  handlers in the kernel host\n  bridge, gated by\n- Add  fired at the turn boundary after\n  compaction checks; calls  fire-and-forget so it cannot\n  deadlock the active tool call\n- Filter the  skill from  when auto-refine\n  is not available (non-persisted sessions, subagent depth > 0)\n- Clean up  in the dispose path\n- Update RLM prompt and harness state instructions to reference\n   instead of\n- Add  constant to refinement module\n- 16 tests covering scheduling, status, turn-boundary consumption,\n  validation, gating, and dispose cleanup\n\n* test(coding-agent): align refine skill prompt assertions\n\n* feat(coding-agent): serialize refinement and persist initial goals\n\nSerialize automatic refinement at turn boundaries, abort stale branch work,\nprotect concurrent harness writes with baseline conflict checks, and preserve\nsubagent model selection across daemon rehydration.\n\nAdd durable top-level initial goals, daemon/SDK plumbing, immediate session\nflushes, inherited daemon-worker environment scrubbing, refine_complete\nevents, and real JSON CLI/socket/supervisor/worker process coverage.\n\n* fix: preserve serialized refine and snapshot catch-up\n\n* fix: guard agent_end auto-refine scheduling in serialized mode\n\nIn serialized mode, _scheduleAutoRefineAfterAgentEnd was called\nunconditionally at agent_end. When a background plan failed at the\nshouldStopAfterTurn boundary (cooldownMs=0, turn threshold met),\n_maybeAutoRefine fired from the interactive path via setTimeout(0),\nrunning a duplicate review+refine the boundary explicitly skipped.\n\nGuard _scheduleAutoRefineAfterAgentEnd behind the existing\n!this._serializedRefine check at the agent_end handler, matching\nthe _consumePendingRequestedRefine guard one line above.\n\nRegression test proves agent_end does not schedule _maybeAutoRefine\nafter a checkpoint failure (cooldownMs=0, turnInterval=1).\n\n* test: drive agent_end event path in serialized auto-refine guard regression\n\nThe previous test only waited after the checkpoint without actually\ninvoking the agent_end code path, so it passed even with the guard\nreverted. Now sets _lastAssistantMessage, spies\n_scheduleAutoRefineAfterAgentEnd, mocks _checkCompaction(false), and\ndrives _handleAgentEvent({type:'agent_end'}) through\n_processAgentEvent → _agentEventQueue. Verified the test fails when\nthe guard is temporarily reverted and passes when restored.\n\n* fix: re-queue explicit refine.run on serialized background plan failure\n\nWhen serialized background planning for an explicit refine.run fails\nat the turn boundary, the consumed request was silently dropped — the\nagent received 'scheduled: true' but no refinement ran.\n\nSerializedBackgroundPlanResult failure now carries explicit, options,\nand branchVersion. At the checkpoint, when the failure was for an\nexplicit request (skipReview=true), branchVersion is still current,\nand no newer _pendingRequestedRefine exists, the original options are\nrestored to _pendingRequestedRefine and fall through to the existing\nsynchronous pending path. Newer requests retain priority; interval\nfailures keep no-retry cooldown semantics; stale branch failures never\nrequeue.\n\nTests: (1) explicit bg plan fails then boundary replan/apply succeeds,\n(2) interval bg failure does not retry, (3) stale branch failure does\nnot requeue, (4) newer pending supersedes failed older request.\n\n* fix: prevent disposal double-refine after explicit drain\n\nIn _drainPendingRefinementForDisposal, after draining a pending\nrefine.run via _runSerializedRefine, _assistantTurnsSinceAutoRefine\nand _lastAutoRefineReviewAt were not reset. The subsequent interval\ncheck could trigger a second refinement during teardown.\n\nStamp cooldown and reset counter immediately after the explicit\ndrain, mirroring the background-plan drain path above.\n\nRegression test proves: one explicit plan/apply and zero subsequent\ninterval review/apply during disposal when the turn counter was due.\nTest verified to fail (2 planCalls) when the bookkeeping is reverted\nand pass (1 planCall) when restored.\n\nNote: public refine() vs _serializedPlanInFlight coordination deferred\npending independent design review — that hunk was reverted.\n\n* fix: coordinate public refine with serialized background planning\n\nPublic refine() now waits for _serializedPlanInFlight in its\nserialization loop. When a serialized background plan is in flight\n(started during an active turn at message_end), public refine first\nawaits the plan promise (no overlapping model calls), then waits for\nagent idle so the active turn's shouldStopAfterTurn checkpoint\nconsumes and applies the plan. Only then does public planning start.\n\nThis prevents: (1) overlapping _planRefine model calls, (2) mid-turn\n_applyRefine via _applySerializedPlan, (3) duplicate consumers of\nthe same serialized plan promise.\n\nRegression test uses a real active turn with a blocking gate tool:\nwhile the tool executes, an explicit refine.run starts bg planning,\nthen public refine() is called concurrently. Asserts max _planRefine\nconcurrency=1, bg plan applied once, public plan applied once.\nVerified mutant-sensitive: fails (planCalls=2, concurrent) without\nthe guard, passes (planCalls sequential) with it.\n\nAlso fixes disposal double-refine: after draining a pending\nrefine.run via _runSerializedRefine, stamps cooldown and resets\n_assistantTurnsSinceAutoRefine so the interval check doesn't trigger\na second refinement during teardown.\n\n* test: strengthen public-refine concurrency regression\n\nGate tool now signals from execute entry; asserts isStreaming===true\nbefore calling handleRefineHostRequest (no manual isStreaming\nfalsification). Replaces Promise.allSettled with Promise.race against\na bounded 10s timeout so failures surface. Captures plan objects and\noptions on _applyRefine, asserts apply order/identity: bg plan-1\nwith instructions 'bg' first, then public plan-2 with instructions\n'public'. Mutant-sensitive: fails (planCalls=2, concurrent) on\npre-fix source, passes with the guard.\n\n* Fix quiescence, aborted-refine, and prompt race in refine apply\n\nSnapshot _baseSystemPrompt before extension hooks so a refine that\ncompletes during the hook is detected and its stale extension prompt\ndiscarded. Replace bare waitForIdle in _applyRefine with requestAbort +\nPromise.allSettled over agent, event queue, compaction, and branch\nsummary to ensure full session quiescence without cancelling child\nruns. Clear _pendingRequestedRefine on aborted turns so stale requests\ndo not leak to subsequent checkpoints. Force pending message resume\nafter refine to re-arm queue drained by requestAbort.\n\n* fix(coding-agent): preserve refine completion event wiring\n\n* fix(coding-agent): defer serialized compaction refinement\n\n* fix(coding-agent): finish headless stack review fixes\n\nfixes #497\n\n* fix(coding-agent): cancel queued refinement on abort\n\nfixes #514\n\n* fix(coding-agent): harden refinement lifecycle (fixes #514)\n\n* fix(coding-agent): resolve serialized refine races (fixes #514)\n\n* fix(coding-agent): guard serialized planning (fixes #514)\n\n* fix(coding-agent): preserve injected prompt extensions (fixes #514)\n\n* fix(coding-agent): preserve empty injected prompts (fixes #514)\n\n* fix(coding-agent): harden combined refine stack (fixes #504)\n\n* fix(coding-agent): clear aborted refine options (fixes #504)\n\n* fix(coding-agent): make latest refine request win (fixes #504)\n\n* fix(coding-agent): record stale refine cooldown (fixes #504)\n\n* fix(coding-agent): prioritize explicit refine (fixes #504)\n\n* fix(coding-agent): close final refine races (fixes #504)\n\n* fix(coding-agent): invalidate superseded refine plans (fixes #504)\n\n---------\n\nCo-authored-by: Kevin Thomas <kevin.jt2007@gmail.com>"},{"name":"harness.ts","kind":"file","size":8386,"lastCommitHash":"c2ec4d249b118d0d4a58ab42fecf522260610014","lastCommitWhen":"2026-08-05T00:25:09-07:00","lastCommitMessage":"fix(coding-agent): attribute subagent terminal notices (#619)\n\n* fix(coding-agent): attribute subagent terminal notices\n\nFixes #617\n\n* fix(coding-agent): keep the injected fallback reachable for child notices\n\nReview follow-up on #619. deliverTerminalMessageToParent swallowed the\nsendAgentMessage rejection and returned, so the injected-message fallback below\nit could never run: a controller that fails to deliver meant the parent lost the\nterminal notice entirely. Catch and fall through instead, since an unattributed\nnotice beats no notice.\n\nAlso corrects the changelog entry, which described the fix backwards.\n\nThe new regression test fails when the fallback is short-circuited and passes\nwhen it is reachable.\n\n* fix(coding-agent): steer subagent terminal notices into busy parents\n\nThe terminal dispatcher forced deliveryMode: \"follow_up\" when handing a\nchild's completion, failure, or cancellation notice to the parent. That\nvalue carried over from the previous _promptInjectedMessage call rather\nthan being a deliberate choice, and it opts out of the \"auto\" default\nevery other child-to-parent message uses.\n\nresolveAgentSessionMessageStreamingBehavior maps auto to \"steer\" for a\nstreaming target and \"follow_up\" to \"followUp\", and ActionStore.selectFirst\ndrains nextTurnBoundary before whenRunIdle. Forcing follow_up therefore put\nthe one signal that a child will never report into the lower-priority lane,\nwhere a parent that keeps taking turns can defer it indefinitely.\n\nOmit deliveryMode so terminal notices inherit the same default: delivered\nimmediately to an idle parent, steered at the next turn boundary into a\nbusy one. The injected fallback for the inline/no-controller case is\nunchanged.\n\n* docs(coding-agent): tighten terminal-notice delivery comments"},{"name":"manual-continuation.test.ts","kind":"file","size":1345,"lastCommitHash":"b0023ef6c0a260b08f9c00d08e81f4106da7430e","lastCommitWhen":"2026-09-01T21:18:22+09:00","lastCommitMessage":"feat(coding-agent): add dot continuation shortcut\n"},{"name":"README.md","kind":"file","size":773,"lastCommitHash":"5292a74648e643786cf450c4992cfcd92ce32cb3","lastCommitWhen":"2026-07-22T21:13:23+02:00","lastCommitMessage":"test(coding-agent): remove unused legacy harness (#498)"},{"name":"scheduling.ts","kind":"file","size":3068,"lastCommitHash":"3fc0ac54fad747871c0d2797bce5b21530aecffc","lastCommitWhen":"2026-07-30T17:38:19+02:00","lastCommitMessage":"feat: canonical session-input scheduling with durable, queueable commands (#540)\n\n* feat(agent): stop before scheduling another turn\n\n* test(agent): remove redundant option forwarding coverage\n\n* test(agent): consolidate turn-boundary coverage\n\n* test(coding-agent): skip staged temp files in 4606 status scan\n\n* test(coding-agent): stabilize process-suite cleanup races\n\n* test(process): allow exact supervisor cleanup to settle\n\n* feat(daemon): checkpoint session inputs for restart\n\n* fix(daemon): harden restart checkpoint transactions\n\n* feat(daemon): unify session input admission\n\n* fix(daemon): complete restart transactions safely\n\n* fix(headless): surface command outcomes\n\n* fix(daemon): fence restart manifest capture\n\n* test(process): isolate daemon client environment\n\n* fix(daemon): restore checkpoint handoff state\n\n* fix(daemon): preserve admission completion contracts\n\n* fix(daemon): fence full queued turns before restart\n\n* fix(daemon): settle queued input outcomes\n\n* fix(daemon): preserve restart transaction ownership\n\n* fix(daemon): report prompt admission rejection\n\n* refactor(daemon): collapse update restart state machines\n\n* feat(coding-agent): unify session input scheduling\n\n* test(daemon): consolidate cron admission coverage\n\n* fix(daemon): bound prepare deadline and fence direct prompt acceptance\n\n* fix(headless): drain session-owned inputs before exit\n\n* fix(daemon): settle queued prompt completions\n\n* fix(daemon): fence stale commit clients and injected prompt sections\n\n* test(coding-agent): remove scheduler implementation assertions\n\n* fix(daemon): keep cleared prompts cancelled\n\n* fix(daemon): fence injected dispatch on delivery and env adoption\n\n* fix(coding-agent): harden session input admission\n\n* refactor(coding-agent): unify agent message outcomes\n\n* fix(daemon): fence injected prompts until target handoff\n\n* fix(coding-agent): align command dispatch parsing\n\n* fix(coding-agent): reject re-armed completions for delivered message ids\n\n* fix(daemon): fence admitted work during restart\n\n* fix(coding-agent): serialize command admission\n\n* fix(coding-agent): drop generated prompt-wait outcomes after completion\n\n* fix(daemon): cancel stalled restart checkpoints\n\n* fix(coding-agent): preserve queued continuation semantics\n\n* fix(daemon): preserve scheduled input contracts\n\n* fix(daemon): close restart admission before checkpoint\n\n* fix(coding-agent): avoid redundant continuation turns\n\n* fix(daemon): settle command delivery outcomes\n\n* fix(daemon): preserve merged queue checkpoints\n\n* fix(coding-agent): serialize all turn admission\n\n* test(daemon): preserve merged delivery coverage\n\n* fix(daemon): make drain cancellation terminal\n\n* fix(tui): unify durable compaction presentation\n\n* test(coding-agent): consolidate scheduler coverage\n\n* refactor(coding-agent): route TUI inputs through session admission\n\n* fix(daemon): bound message delivery outcomes\n\n* fix(daemon): preserve restart checkpoint semantics\n\n* test(tui): consolidate compaction presentation coverage\n\n* test(coding-agent): synchronize scheduler integration coverage\n\n* fix(tui): preserve admission ordering\n\n* fix(daemon): cancel pending prompt admission\n\n* fix(daemon): align admission restart integration\n\n* fix(tui): retain successful context usage\n\n* fix(coding-agent): harden queued input lifecycle\n\n* fix(tui): preserve admission errors and retry spacing\n\n* style(daemon): format combined protocol\n\n* fix(daemon): clear restart-rejected admission\n\n* fix(coding-agent): disclose non-durable compaction outcomes\n\n* refactor(coding-agent): consolidate scheduler predicates and coverage\n\n* fix(tui): preserve editor input during startup\n\n* fix(daemon): close prompt admission edge cases\n\n* fix(daemon): release stale parsed admissions\n\n* refactor(coding-agent): simplify compaction outcome handling\n\n* fix(coding-agent): harden queued prompt handoff and refine parsing\n\n* fix(tui): retry startup prompts until admitted\n\n* fix(daemon): close prompt admission races\n\n* fix(daemon): revoke late stale claims\n\n* fix(coding-agent): restore the session file after a torn outcome append\n\n* fix(coding-agent): snapshot prepared prompts adjacent to handoff\n\n* fix(tui): bound startup and follow-up admission\n\n* test(daemon): ignore private handler arity\n\n* fix(daemon): serialize replay admission\n\n* fix(compaction): preserve durable outcomes in headless mode\n\n* fix(coding-agent): suspend the input pump for update-restart aborts\n\n* refactor(tui): simplify startup prompt delivery\n\n* fix(daemon): reconcile prompt admission outcomes\n\n* test(daemon): extend fixture cleanup retries\n\n* fix(session): preserve symlinked atomic rewrites\n\n* fix(scheduler): cancel continuations at abort boundaries\n\n* fix(tui): drop superseded command paths and stop startup prompts at run exit\n\n* fix(daemon): observe cancelled admission work\n\n* fix(daemon): clear restart-rejected admission\n\n* fix(compaction): preserve merged event handling\n\n* fix(scheduler): preserve queued input ownership\n\n* fix(tui): drop submits resumed by run teardown\n\n* fix(daemon): settle admission-only work once\n\n* test(daemon): assert cron admission completion\n\n* feat(coding-agent): add session command primitives\n\n* fix(session): preserve atomic rewrite ownership\n\n* fix(scheduler): derive steering stop from live queue\n\n* fix(tui): preserve stash on lifecycle cancellation\n\n* fix(daemon): preserve steer and follow-up lanes\n\n* fix(daemon): wake checkpoint at prompt handoff\n\n* test(coding-agent): consolidate command message coverage\n\n* fix(tui): preserve transcript on rebuild failure\n\n* fix(scheduler): run checkpoints before steering stop\n\n* fix(tui): cancel startup admission on lifecycle exit\n\n* fix(daemon): preserve definitive prompt failures\n\n* fix(daemon): finish publish after owner loss\n\n* fix(coding-agent): validate command metadata consistency\n\n* fix(compaction): persist outcomes before events\n\n* fix(scheduler): hand off injected follow-ups\n\n* fix(tui): integrate side conversations with admission\n\n* test(daemon): model idle lane insertion\n\n* fix(daemon): adopt deferred attach env on rollback\n\n* fix(coding-agent): align command dispatch parsing\n\n* fix(headless): skip malformed outcome suffix entries\n\n* fix(scheduler): preserve ordered input ownership\n\n* fix(tui): retain rejected rich drafts\n\n* fix(scheduler): observe pre-aborted admission waits\n\n* fix(daemon): reserve update shutdown for publish\n\n* fix(coding-agent): keep multiline slash input literal\n\n* fix(compaction): order equal-time legacy messages after summary\n\n* test(process): sweep late supervisor owners before cleanup\n\n* test(process): terminate late exact supervisor owners\n\n* fix(agent): recheck stop after steering poll\n\n* fix(scheduler): recheck pause at direct admission\n\n* fix(tui): retain lifecycle drafts in submission order\n\n* fix(daemon): preserve client identity and safe markers\n\n* fix(agent): never drop steering drained by the stop-window poll\n\nA stop that flips during the post-tool-batch steering poll no longer ends\nthe loop when that poll returned messages; drained steering owns the turn\nboundary and is injected before the loop can stop.\n\n* fix(scheduler): invalidate queued prompt preparation on branch navigation\n\nCached before_agent_start preparation survives a deferral requeue, so a\nbranch switch during the pause could deliver extension messages prepared\nagainst the old branch. Clear queued prompt preparation when tree\nnavigation rebuilds the session context.\n\n* fix(tui): honor cancellation in pause waits and pin deferred stash release\n\n- forward the abort signal into the queued-work admission wait taken when\n  a pause appears between admission acquire and the ownership commit, so\n  a cancelled prompt rejects instead of blocking until the pause clears\n- capture the stash session id and state when a release is deferred by\n  in-flight submissions, so a /new rebind cannot redirect the deferred\n  release at the new session's state\n- align the prompt-stash submit harness with the submission fields so the\n  draft-retention paths run instead of throwing on missing state\n\n* fix(daemon): keep cancelled admissions definitive across repeated cancels\n\nA second cancel_prompt_admission for an already-cancelled admission now\nshort-circuits with cancelled instead of forwarding to the worker, and a\nworker unknown response can no longer downgrade a cancellation that\nraced in during the round-trip.\n\n* fix(coding-agent): require dispatch proof before releasing the prompt fence\n\nAgent.prompt() resolves even when a lifecycle listener failure produced a\nsynthetic error turn without the injected message ever reaching agent\nstate. Treat a resolved prompt as dispatched only when the dispatch\nobserver fired or the message is present in agent state, so the direct-\nprompt checkpoint section cannot release with the accepted input missing\nfrom both the queue and the run.\n\n* chore(scheduler): tighten fix comments\n\n* chore(tui): tighten fix comments\n\n* chore(agent): tighten fix comments\n\n* chore(daemon): tighten fix comments\n\n* chore(coding-agent): tighten fix comment\n\n* test(agent): flip the stop only on the post-tool-batch steering poll\n\nThe pre-loop poll also set stopRequested, so the pre-steering check\nstopped the loop and the post-empty-poll recheck under test never ran.\nVerified the test now fails when the recheck is removed.\n\n* fix(scheduler): treat pump-owned work as busy for post-compaction continue\n\nThe continuation timer only checked pendingMessageCount, but the pump\nmoves items into _activeSessionInput before handoff, so the timer could\ncall agent.continue() and forget continuations the pump still owned.\nIdle now also requires no active input, no running pump, and no pump\nrequest.\n\n* fix(tui): bind barrier-paused submissions to their original session\n\nA submit paused on the startup-prompt barrier could resume after /new\nrebound the live stash fields, delivering the prompt to and stashing the\ndraft in the wrong session. The submission now captures its session and\nstash state up front, bails out of prompting when the session changed,\nand retains drafts in the captured state.\n\n* fix(scheduler): let queueIfBusy join pending work at direct admission\n\nDirect-turn admission drained queued work before queueIfBusy callers\ncould see it, so heartbeats and accepted agent messages blocked until\nthe queue emptied and then started direct turns. Admission now returns\nimmediately for queueIfBusy callers (allowPendingQueue) and preflight\nenqueues behind the pending work, which also removes the pump-reschedule\nspin while the queue is blocked by bash/compaction/retry.\n\n* chore(agent): tighten test comment\n\n* chore(tui): tighten fix comments\n\n* chore(scheduler): tighten fix comments\n\n* fix(compaction): retain unpersisted outcome disclosures across rebuilds\n\nAn outcome whose session-file append failed lived only in live agent\nstate, so transcript rebuilds from buildSessionContext dropped the\ndisclosure. Failed appends are now retained and appended to rebuilt\ncontexts.\n\n* fix(tui): observe admission cancellation on the streaming prompt path\n\nWhile streaming, _prompt skips direct-turn admission, so an aborted\nadmission signal was never checked and a cancelled startup prompt could\nstill enqueue into a session the user already left. The streaming path\nnow treats its entry as the commit point and rejects already-aborted\nprompts.\n\n* fix(compaction): keep unpersisted outcome disclosures in transcript order\n\nRebuilds appended retained disclosures after every persisted message, so\nturns persisted after the failed append rendered above the notice. The\ndisclosures now merge into the rebuilt context by timestamp.\n\n* fix(daemon): gate admission cancellation on a minimum schema revision\n\nschemaRevision is monotonic, but the admission gates compared it with\nexact equality, so a newer daemon failed signal-backed prompt\ncancellation against an older client even while still advertising\nprompt_admission_cancellation. Both gates now require a minimum\nrevision, matching the protocol.version check.\n\n* fix(compaction): keep unpersisted outcome disclosures across state reloads\n\nSuccessful compaction and tree navigation reload agent.state.messages\nfrom the session file, which dropped disclosures that only exist in\nmemory after a failed append. The timestamp merge now runs on every\nrebuild path via a shared helper.\n\n* chore(tui): tighten fix comment\n\n* chore(daemon): drop redundant gate comment\n\n* chore(compaction): tighten fix comments\n\n* fix(scheduler): treat a skipped compaction as benign in queued commands\n\nA too-short or already-compacted /compact throws CompactionSkippedError,\nwhich compaction_end already surfaces as a warning; the queued-command\nexecutor also recorded a durable 'Command failed' error row for the same\nskip. The executor now ignores the skip.\n\n* fix(daemon): re-validate field-gated requests before reconnect replay\n\nA prompt carrying admissionId that was pending across a reconnect was\nreplayed without re-checking the new daemon_hello, so a replaced or\ndowngraded daemon would silently ignore the admission field and take\nownership of an uncancellable prompt. Pending requests now remember\ntheir schema requirement and reject with the capability error when the\nnew hello no longer satisfies it. Also awaits the newer-revision test's\nrequest so closing the client cannot leak an unhandled rejection.\n\n* fix(tui): keep every deferred prompt-stash release across rebinds\n\nA teardown release after a /new rebind overwrote the pending release\npair captured at the original deferral, so the first session's stash\nstate was never released. Deferred releases now accumulate per session\nand all drain once pending submissions settle.\n\n* fix(tui): restore the compaction loader without a start-event edge\n\nThe compaction spinner was created only on the compaction_start event,\nso a compaction already running when the client attached or returned to\nthe chat (e.g. a /compact queued from the agents view) showed no\nprogress at all until it finished. syncWorkingLoader now restores the\nloader from the connection's isCompacting state, and the loader\ncreation is shared with the event path. Adds core coverage proving the\ncompaction lifecycle events fire for /compact queued behind a running\nturn on both lanes.\n\n* test: consolidate scheduler tests into e2e scenario journeys\n\nReplace ~50 fine-grained scheduler test cases with 7 end-to-end scenario\ntests (S1-S7) that drive the real AgentSession through gated faux-model\nruns with staged, phase-labeled assertions:\n\n- S1: mid-run steering/follow-up/command/custom input ordering\n- S2: queue editing (coalescing, removal APIs, steering-stop reconciliation)\n- S3: pause-lease preparation with anchor re-preparation and direct handoff\n- S4: update-restart abort snapshots and envelope-vs-literal restore\n- S5: queued command delivery vs gated completion outcomes\n- S6: auto-refine via real turns (interval review, busy deferral, branch\n  navigation invalidation) instead of _maybeAutoRefine internals\n- S7: accepted agent-message lifecycle (busy queueing, delivery-before-\n  completion, literal slash commands, cleared-during-admission cleanup)\n\nAlso shrink the 300-iteration outcome-leak loop to 3, drop a typeof-only\nassertion, redundant whitespace-variant and duplicate guard tests.\n\nWhite-box tests for admission-boundary races, cooldown stamping, and\nfault-injection windows are kept; those interleavings have no public\ntrigger. Coverage on agent-session.ts is unchanged (59.7% lines before\nand after) at -516 net test lines.\n\n* fix: close session-input scheduler race windows around admission and restart checkpoints\n\nThree bugbot findings on the scheduler plus one hardening pass:\n\n- promptUntilAccepted no longer waits for the session-input pump after\n  admission: it resolves at ownership commit while queued work (including\n  slash commands) executes, restoring its documented contract.\n- waitForSessionInputCheckpoint now waits for an executing queued session\n  command; the pump shifts commands off the queue before running them, so\n  a restart snapshot could otherwise proceed mid-/compact or /refine and\n  drop the command from durable queued input.\n- The queued-prompt handoff holds a checkpoint section until dispatch is\n  observed. The phase flipped to handedOff (notifying checkpoint waiters)\n  before agent.prompt() ran, so a checkpoint could drain a stale event\n  queue snapshot and flush before the accepted messages persisted.\n- waitForPromiseOrAbort rechecks signal.aborted after registering its\n  abort listener, matching waitForPromptAdmission.\n\nEach fix has a regression test verified to fail against the unfixed code.\n\n* chore: trim comments in scheduler scenarios and race fixes\n\n* fix: fence triggerTurn custom messages for restart checkpoints\n\nsendCustomMessage with triggerTurn took direct-turn admission but never\nentered a direct prompt section, so waitForSessionInputCheckpoint could\nsnapshot between admission and dispatch and miss the in-flight turn.\nHold a checkpoint section from admission until the message dispatches,\nmirroring the queued-handoff fence.\n\n* fix: keep pump-owned session inputs visible as pending\n\nWhen the session-input pump moved prompts or commands into\n_activeSessionInput, they left the typed queues before delivery, so\npendingMessageCount, queue previews, snapshots, and queue_update briefly\nreported an empty queue during preparation and long-running queued\ncommands, and agent-message backpressure undercounted.\n\nCount still-preparing prompts and executing commands as pending, emit\nqueue updates at prompt handoff and command completion, and clear\nownership before the deferred-requeue emit so items are not\ndouble-counted.\n\n* fix: harden durable command persistence and cleared-input accounting\n\nTwo bugbot findings on the queued session-command path:\n\n- _appendDurableSessionCommandMessage now persists through\n  appendCustomMessageEntryWithRollback before touching live state, so a\n  failed write cannot leave an unsaved leaf or a transcript/file\n  divergence; the failure-row append no longer masks the original\n  command error.\n\n- clearQueue marks the preparing active input cancelled;\n  _undeliveredActiveSessionInputs now excludes cancelled items so\n  pendingMessageCount, previews, and queue updates drop cleared work\n  immediately instead of waiting for the pump to unwind.\n\n* fix: stop coalescing follow-up keys against handed-off prompts\n\nFollow-up queueKey coalescing treated all _activeSessionInput prompt\nitems as pending owners. After handoff the prompt is committed to the\nrunning turn, so a later same-key follow-up (e.g. a heartbeat) was\nrejected for the rest of that turn instead of queueing behind it.\nCoalesce only against a preparing, non-cancelled active input, shared by\n_enqueueSessionInput and hasQueuedFollowUp.\n\n* fix: count session-owned queues as queued work after compaction\n\nPost-compaction decisions only consulted agent.hasQueuedMessages(), but\nqueued prompts and commands now live in the session-owned steer and\nfollow-up queues. Include pendingMessageCount so auto-refine defers to\nthe next turn boundary instead of running before queued input turns,\nand post-compaction continue is scheduled when only session-owned work\nis waiting (manual, auto, and failure-resume paths).\n\n* fix(daemon): centralize prompt admission compatibility\n\n* fix(daemon): recheck command compatibility on replay"},{"name":"serialized-refine-config-integration.test.ts","kind":"file","size":10697,"lastCommitHash":"42ea9046ab9f75bc0fcf9f455d853f530cc15ae7","lastCommitWhen":"2026-07-23T17:52:00-07:00","lastCommitMessage":"feat(coding-agent): agent-callable refine skill (#504)\n\n* feat(coding-agent): background refine planning to not block conversation\n\nSplit the synchronous _refine() flow into two phases:\n- Planning (background): LLM call via completeSimple without\n  disconnecting from agent events or aborting the agent\n- Application (synchronous, fast): waits for agent idle, then\n  disconnects briefly, applies proposal, saves harness state,\n  rebuilds system prompt, emits refine_complete event\n\nrefine() public method signature unchanged. _waitForRefineIdle()\nonly blocks for the application phase. Interactive mode\nhandleRefineCommand fires refine without blocking the UI.\n\nRace condition fixes found by Macroscope and Cursor Bugbot:\n- Serialize concurrent refine calls via _refineApplyPending flag\n- Remove abort() from apply phase to preserve concurrent work\n- Narrow _refineInFlight to only cover disconnect+apply+reconnect\n- Re-check _refineApplyPending at turn handoff guards\n- Block turns during apply transition window\n- Clear _refineApplyPending on dispose\n- Re-sync systemPrompt after refine completes at handoff\n\n* fix(coding-agent): harden refine error paths and in-flight guard\n\n- Schedule pending message resume on planning failure and cancellation\n  so queued turns started during background planning are not stranded\n- Set _refineInFlight before calling _applyRefine so synchronous\n  listeners on refine_complete see the guard\n- Wrap refine_complete _emit in try/catch so listener failures do not\n  flip a successful refinement into a reported failure\n\nFound by Cursor Bugbot and Macroscope.\n\n* fix(coding-agent): preserve extension systemPrompt at handoff re-sync\n\nRestore extensionResult?.systemPrompt ?? this._baseSystemPrompt at\nline 3056 which was accidentally changed to just this._baseSystemPrompt\nduring the handoff re-sync refactor. Without this, heartbeat and other\nextension-modified system prompts were clobbered.\n\n* fix(coding-agent): preserve extension systemPrompt at handoff re-sync\n\nLift extensionResult declaration outside the try block so it can be\nreferenced at the handoff re-sync point. After _waitForRefineIdle,\nre-apply extensionResult?.systemPrompt ?? this._baseSystemPrompt\ninstead of just this._baseSystemPrompt so extension-modified prompts\nsurvive a concurrent refine.\n\nFound by Macroscope.\n\n* fix(coding-agent): harden background refinement (fixes #497)\n\n* feat(coding-agent): agent-callable refine skill\n\nAdd a  Python skill (SKILL.md + kernel package) that lets the\nmodel schedule continual harness refinement from IPython via\n, mirroring how the compact skill works as both an\nagent-callable tool and a user command.\n\nChanges:\n- New  skill with  and  API\n  in packages/coding-agent/skills/refine/\n- Add  to AgentSession:  stores a\n  pending request and returns immediately (non-blocking);\n  reports pending/in-flight state\n- Register  and  handlers in the kernel host\n  bridge, gated by\n- Add  fired at the turn boundary after\n  compaction checks; calls  fire-and-forget so it cannot\n  deadlock the active tool call\n- Filter the  skill from  when auto-refine\n  is not available (non-persisted sessions, subagent depth > 0)\n- Clean up  in the dispose path\n- Update RLM prompt and harness state instructions to reference\n   instead of\n- Add  constant to refinement module\n- 16 tests covering scheduling, status, turn-boundary consumption,\n  validation, gating, and dispose cleanup\n\n* test(coding-agent): align refine skill prompt assertions\n\n* feat(coding-agent): serialize refinement and persist initial goals\n\nSerialize automatic refinement at turn boundaries, abort stale branch work,\nprotect concurrent harness writes with baseline conflict checks, and preserve\nsubagent model selection across daemon rehydration.\n\nAdd durable top-level initial goals, daemon/SDK plumbing, immediate session\nflushes, inherited daemon-worker environment scrubbing, refine_complete\nevents, and real JSON CLI/socket/supervisor/worker process coverage.\n\n* fix: preserve serialized refine and snapshot catch-up\n\n* fix: guard agent_end auto-refine scheduling in serialized mode\n\nIn serialized mode, _scheduleAutoRefineAfterAgentEnd was called\nunconditionally at agent_end. When a background plan failed at the\nshouldStopAfterTurn boundary (cooldownMs=0, turn threshold met),\n_maybeAutoRefine fired from the interactive path via setTimeout(0),\nrunning a duplicate review+refine the boundary explicitly skipped.\n\nGuard _scheduleAutoRefineAfterAgentEnd behind the existing\n!this._serializedRefine check at the agent_end handler, matching\nthe _consumePendingRequestedRefine guard one line above.\n\nRegression test proves agent_end does not schedule _maybeAutoRefine\nafter a checkpoint failure (cooldownMs=0, turnInterval=1).\n\n* test: drive agent_end event path in serialized auto-refine guard regression\n\nThe previous test only waited after the checkpoint without actually\ninvoking the agent_end code path, so it passed even with the guard\nreverted. Now sets _lastAssistantMessage, spies\n_scheduleAutoRefineAfterAgentEnd, mocks _checkCompaction(false), and\ndrives _handleAgentEvent({type:'agent_end'}) through\n_processAgentEvent → _agentEventQueue. Verified the test fails when\nthe guard is temporarily reverted and passes when restored.\n\n* fix: re-queue explicit refine.run on serialized background plan failure\n\nWhen serialized background planning for an explicit refine.run fails\nat the turn boundary, the consumed request was silently dropped — the\nagent received 'scheduled: true' but no refinement ran.\n\nSerializedBackgroundPlanResult failure now carries explicit, options,\nand branchVersion. At the checkpoint, when the failure was for an\nexplicit request (skipReview=true), branchVersion is still current,\nand no newer _pendingRequestedRefine exists, the original options are\nrestored to _pendingRequestedRefine and fall through to the existing\nsynchronous pending path. Newer requests retain priority; interval\nfailures keep no-retry cooldown semantics; stale branch failures never\nrequeue.\n\nTests: (1) explicit bg plan fails then boundary replan/apply succeeds,\n(2) interval bg failure does not retry, (3) stale branch failure does\nnot requeue, (4) newer pending supersedes failed older request.\n\n* fix: prevent disposal double-refine after explicit drain\n\nIn _drainPendingRefinementForDisposal, after draining a pending\nrefine.run via _runSerializedRefine, _assistantTurnsSinceAutoRefine\nand _lastAutoRefineReviewAt were not reset. The subsequent interval\ncheck could trigger a second refinement during teardown.\n\nStamp cooldown and reset counter immediately after the explicit\ndrain, mirroring the background-plan drain path above.\n\nRegression test proves: one explicit plan/apply and zero subsequent\ninterval review/apply during disposal when the turn counter was due.\nTest verified to fail (2 planCalls) when the bookkeeping is reverted\nand pass (1 planCall) when restored.\n\nNote: public refine() vs _serializedPlanInFlight coordination deferred\npending independent design review — that hunk was reverted.\n\n* fix: coordinate public refine with serialized background planning\n\nPublic refine() now waits for _serializedPlanInFlight in its\nserialization loop. When a serialized background plan is in flight\n(started during an active turn at message_end), public refine first\nawaits the plan promise (no overlapping model calls), then waits for\nagent idle so the active turn's shouldStopAfterTurn checkpoint\nconsumes and applies the plan. Only then does public planning start.\n\nThis prevents: (1) overlapping _planRefine model calls, (2) mid-turn\n_applyRefine via _applySerializedPlan, (3) duplicate consumers of\nthe same serialized plan promise.\n\nRegression test uses a real active turn with a blocking gate tool:\nwhile the tool executes, an explicit refine.run starts bg planning,\nthen public refine() is called concurrently. Asserts max _planRefine\nconcurrency=1, bg plan applied once, public plan applied once.\nVerified mutant-sensitive: fails (planCalls=2, concurrent) without\nthe guard, passes (planCalls sequential) with it.\n\nAlso fixes disposal double-refine: after draining a pending\nrefine.run via _runSerializedRefine, stamps cooldown and resets\n_assistantTurnsSinceAutoRefine so the interval check doesn't trigger\na second refinement during teardown.\n\n* test: strengthen public-refine concurrency regression\n\nGate tool now signals from execute entry; asserts isStreaming===true\nbefore calling handleRefineHostRequest (no manual isStreaming\nfalsification). Replaces Promise.allSettled with Promise.race against\na bounded 10s timeout so failures surface. Captures plan objects and\noptions on _applyRefine, asserts apply order/identity: bg plan-1\nwith instructions 'bg' first, then public plan-2 with instructions\n'public'. Mutant-sensitive: fails (planCalls=2, concurrent) on\npre-fix source, passes with the guard.\n\n* Fix quiescence, aborted-refine, and prompt race in refine apply\n\nSnapshot _baseSystemPrompt before extension hooks so a refine that\ncompletes during the hook is detected and its stale extension prompt\ndiscarded. Replace bare waitForIdle in _applyRefine with requestAbort +\nPromise.allSettled over agent, event queue, compaction, and branch\nsummary to ensure full session quiescence without cancelling child\nruns. Clear _pendingRequestedRefine on aborted turns so stale requests\ndo not leak to subsequent checkpoints. Force pending message resume\nafter refine to re-arm queue drained by requestAbort.\n\n* fix(coding-agent): preserve refine completion event wiring\n\n* fix(coding-agent): defer serialized compaction refinement\n\n* fix(coding-agent): finish headless stack review fixes\n\nfixes #497\n\n* fix(coding-agent): cancel queued refinement on abort\n\nfixes #514\n\n* fix(coding-agent): harden refinement lifecycle (fixes #514)\n\n* fix(coding-agent): resolve serialized refine races (fixes #514)\n\n* fix(coding-agent): guard serialized planning (fixes #514)\n\n* fix(coding-agent): preserve injected prompt extensions (fixes #514)\n\n* fix(coding-agent): preserve empty injected prompts (fixes #514)\n\n* fix(coding-agent): harden combined refine stack (fixes #504)\n\n* fix(coding-agent): clear aborted refine options (fixes #504)\n\n* fix(coding-agent): make latest refine request win (fixes #504)\n\n* fix(coding-agent): record stale refine cooldown (fixes #504)\n\n* fix(coding-agent): prioritize explicit refine (fixes #504)\n\n* fix(coding-agent): close final refine races (fixes #504)\n\n* fix(coding-agent): invalidate superseded refine plans (fixes #504)\n\n---------\n\nCo-authored-by: Kevin Thomas <kevin.jt2007@gmail.com>"}]