Skip to content

fix([issue-5622]): corroborate CoS runner listings before treating agents as live - #5633

Merged
atomantic merged 20 commits into
mainfrom
claim/issue-5622
Sep 1, 2026
Merged

fix([issue-5622]): corroborate CoS runner listings before treating agents as live#5633
atomantic merged 20 commits into
mainfrom
claim/issue-5622

Conversation

@atomantic

Copy link
Copy Markdown
Owner

Summary

  • CoS zombie/orphan sweeps no longer treat "listed by GET /agents" as proof the agent is alive. A runner row now has to corroborate with a live pid or a liveness tag (pty from TUI onExit bookkeeping, pid from a CLI probe) before it can keep a durable running record.
  • The runner reports TUI processActive from its own onExit flag instead of a pid probe, so Windows ConPTY pid: 0 no longer makes every runner-owned TUI look dead. Pre-fix TUI rows with no liveness tag still count as live so a newer sweep cannot reap a live Windows TUI against an older runner.
  • A genuinely live runner-owned agent still survives a PortOS restart. A stale listing (advertised handle, process gone) is retired on the next sweep, including leftover runnerAgents adopts. 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)
  • CI green on this PR
  • After merge, a Windows runner-owned TUI stays running across a PortOS restart; a durable running record whose runner handle is stale is reaped on the next sweep instead of pinning the agent card forever

atomantic and others added 20 commits September 1, 2026 19:06
…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.
@atomantic
atomantic merged commit 1ed339d into main Sep 1, 2026
7 checks passed
@atomantic
atomantic deleted the claim/issue-5622 branch September 1, 2026 22:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CoS sweeps trust the runner's agent list as proof of liveness

1 participant