fix([issue-5622]): corroborate CoS runner listings before treating agents as live - #5633
Merged
Conversation
…5622) GET /agents now reports TUI processActive from onExit bookkeeping so a Windows ConPTY pid of 0 is no longer read as dead. Both zombie and orphan sweeps require that signal (or a live pid) before a runner handle can keep a durable running record, and sync no longer re-adopts stale listings.
Leftover runnerAgents ownership no longer shields a durable running record once GET /agents says the handle is dead. The pre-fix TUI fallback now applies only to ConPTY pid 0, so a mixed-version POSIX TUI with a real dead pid can be retired.
A failed GET /agents is not an empty live set — runner-owned pid-0 TUIs were being archived as never-started during a runner outage. onExit now drops the handle before awaiting disk I/O so a dying TUI is not advertised as a stale listing that can beat agent:completed to completeAgent.
…nto #5624 still tests the finalized-record gate Bare CLI listings without processActive/liveness now go through the pid probe, so pid 1/2/3 no longer look live. Keep those rows tagged live so the test still covers ignoring finalized/missing records rather than the liveness skip.
… nested ownership guard Un-nesting leftover runnerAgents ownership left the reap path indented as if it were still inside the old if. Behavior is unchanged.
…tions (#5595) Add a user-actions.query semantic tool (readPortos-gated, agent/mind/MCP scoped, 100-event cap, credential-scrubbed output), a deterministic last-24h operator-action snippet in the mind's wake prompt, and an opt-in install-wide user-action-review scheduled task (on-demand, fileIssues by default) whose generator hook skips silently when the ledger is empty. Reads the user_action_events ledger shipped in #5594. Part of #5593.
Fable 5.1 shipped 2026-09-01 with the same $10/$50 per-1M input/output rate as Fable 5, but a 75% cheaper cache-read rate ($1.00 -> $0.25/1M, i.e. 0.1x -> 0.025x its input rate) while cache-write stays at the standard 1.25x. Adds a dedicated modelPricing.js row plus a scoped cache-multiplier override rather than touching the existing claude-fable-5 row, so /devtools/usage keeps accurate historical rates for both generations. The bare "fable" family-match fallback now resolves to the newest generation, matching the existing opus-bump convention.
PRICING_AS_OF advanced to 2026-09-01, past the documented 2026-08-31 intro-pricing cutoff, but claude-sonnet-5 still priced at the $2/$10 intro rate instead of the $3/$15 standard rate its own comment names — understating post-cutoff usage estimates.
The prior commit (address review (codex)) bumped claude-sonnet-5 to the $3/$15 rate the stale comment described as taking effect 2026-09-01. Anthropic cancelled that increase on 2026-08-10 and confirmed the $2/$10 intro rate is now the permanent standard price (verified against platform.claude.com/docs/en/about-claude/pricing). Restores the correct rate and updates the comment instead of the number.
## Summary - add a reusable provider/model/effort selection policy for security-sensitive pickers - restrict the pr-reviewer Security Scan to canonical local HTTP providers and explicitly tool-free installed models - run the scan as a direct read-only local preflight, fail closed on unverifiable input, and require human approval before external PRs reach review or merge ## Validation - client focused Vitest: 319 passed - server focused Vitest: 530 passed - client lint - client production build The preflight reads public GitHub PR metadata and diffs only; it never checks out or executes contributor code and never posts reviews, comments, approvals, or merges.
## Summary - centralize managed-app target requirements in the task registry - reject global on-demand PR-review requests before they can be queued - guard the global generator as a second fail-closed boundary ## Test plan - npm test (server) - focused task schedule and CoS generator tests This prevents a PR-review task from bypassing its direct local tool-free security preflight when no managed app is supplied.
## Summary - require the shared tool-free local selection policy to expose a text-capable model - reject embedding-only and unknown-capability models in both UI and server preflight validation - keep the existing no-tools and local-provider boundary fail-closed ## Validation - client focused tests: 295 passed - server focused scheduler/security tests: 408 passed - client lint and production build passed - full server suite: 36,899 passed; unrelated image/sprite suites timed out under full-suite load No contributor branches are checked out or executed by this change.
Add Gemma 3 27B as the featured Security Scan recommendation, correct GPT-OSS capability metadata, and cover the Gemma 4 tool-capability distinction.
## Summary - continue the read-only Security Scan across every external open PR - aggregate pass/fail tokens before deciding whether Stage 2 may start - keep the pipeline fail-closed when any PR has findings ## Validation - `cd server && npm test -- --run services/prReviewerSecurity.test.js services/cosTaskGenerator.test.js` - live local replay reviewed all three external PRs without checkout or execution; all returned non-clean verdicts No contributor branch was checked out or executed.
…5622) GET /agents now reports TUI processActive from onExit bookkeeping so a Windows ConPTY pid of 0 is no longer read as dead. Both zombie and orphan sweeps require that signal (or a live pid) before a runner handle can keep a durable running record, and sync no longer re-adopts stale listings.
Leftover runnerAgents ownership no longer shields a durable running record once GET /agents says the handle is dead. The pre-fix TUI fallback now applies only to ConPTY pid 0, so a mixed-version POSIX TUI with a real dead pid can be retired.
A failed GET /agents is not an empty live set — runner-owned pid-0 TUIs were being archived as never-started during a runner outage. onExit now drops the handle before awaiting disk I/O so a dying TUI is not advertised as a stale listing that can beat agent:completed to completeAgent.
…nto #5624 still tests the finalized-record gate Bare CLI listings without processActive/liveness now go through the pid probe, so pid 1/2/3 no longer look live. Keep those rows tagged live so the test still covers ignoring finalized/missing records rather than the liveness skip.
… nested ownership guard Un-nesting leftover runnerAgents ownership left the reap path indented as if it were still inside the old if. Behavior is unchanged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
/agents" as proof the agent is alive. A runner row now has to corroborate with a live pid or alivenesstag (ptyfrom TUI onExit bookkeeping,pidfrom a CLI probe) before it can keep a durablerunningrecord.processActivefrom its ownonExitflag instead of a pid probe, so Windows ConPTYpid: 0no longer makes every runner-owned TUI look dead. Pre-fix TUI rows with nolivenesstag still count as live so a newer sweep cannot reap a live Windows TUI against an older runner.runnerAgentsadopts. A failed runner probe is not treated as an empty live set.Closes #5622
Test plan
cd server && npx vitest run lib/runnerAgentLiveness.test.js lib/index.test.js cos-runner/index.test.js services/agentManagement.test.js services/agentRunnerSync.test.js services/cosAgentLifecycle.test.js(176 passing)runningacross a PortOS restart; a durablerunningrecord whose runner handle is stale is reaped on the next sweep instead of pinning the agent card forever