fix: require typed veto-window terminal closes - #932
Conversation
Route delayed proposal outcomes through typed terminal audit evidence, reject malformed human/window history before mutation, and recover stale audit reservations idempotently.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Integration review and execution handoff — 2026-09-07Source reviewed: Keep this production fix independent from #933. Both can consume the same harness revision; do not make either consumer branch import the other complete production fix solely to obtain tests. Exact reconciliation work after #933
Harness versus runtime dependenciesThe advisory #931 harness need not wait for the full deterministic scheduler seam. Same-home restart and success provenance are neutral shared mechanics. Deterministic time must control the real daemon's scheduler and replay boundary; a test-process clock or correctness sleeps do not satisfy #884. Supported production scheduled-proposal publication is a distinct prerequisite for end-to-end publication/deadline/supersession journeys, not merely a missing test helper. Persisted-envelope recovery fixtures can prove recovery but must not be described as supported intake/publication evidence. Do not manufacture client-authoritative Retain all nine #886 terminal/human-path scenarios as open acceptance obligations, including Recommended eventual merge sequence: #931, independently completed #933, then this PR rebased onto resulting main. Current CI success does not establish pairwise integration, full #886 acceptance, or merge authorization. Execution status: source implementation is paused because this session lacks the checkout/Rust toolchain/Coven worktree-claim tooling required by AGENTS.md. No source changes, rebases, new test runs, or gate changes were performed. |
Cody agent review checkpoint - 2026-09-09 (local, unpublished)The remote head is unchanged. The local The follow-up prevents retention expiry from replacing veto-window replay; Lower-level evidence:
Quarantine is explicitly not a typed terminal close. It preserves applied Authority/privacy/compatibility impact: fail-closed recovery/logging changes; No #933 production code was imported. The eventual integration must reconcile Changes are uncommitted/unpushed; this comment does not claim the remote diff |
Revalidate old windows, guard proposal identifiers before terminal writes, quarantine corrupt or inconsistent applied claims, and account for terminal 409 scheduler results without retry-loop diagnostics. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: BunsDev <68980965+BunsDev@users.noreply.github.com>
|
#933 is now merged into main as b7b3b4e with green merged-main CI. When integrating this terminal checkpoint, retain the earlier protected classification boundary, the single Uuid-based release_terminal_proposal_reservations implementation, explicit clock timestamps, and the durable-decision-request recovery fix. Open-window protected rejection must keep its typed revalidation_failed detail; no-window rejection must not fabricate a close; interrupted applying claims quarantine without claiming a terminal outcome. The reusable protected real-daemon fixture is now on main, so this branch no longer needs to import the whole #931 production integration for that evidence. |
|
Kitty is adopting this existing checkpoint for the next protected branch-to-merge pass. issue-886 was unclaimed; I have entered a task worktree and acquired the shared claim. I will integrate current main including #933, preserve typed terminal/window and quarantine distinctions, verify the intersection regressions, and keep full #886 acceptance obligations explicit. No duplicate PR or unsupported publication/authority route will be introduced. |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Val Alexander <68980965+BunsDev@users.noreply.github.com> # Conflicts: # crates/coven-cli/src/api.rs
Reuse committed window context only for typed failed revalidation; preserve replay errors and the unapplied/recovery boundary. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>
Classify no-veto pending history with a persisted window and route it through the existing typed refusal boundary before human-only waiting. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>
Use supported human coherence intake and explicitly seeded stopped-daemon legacy history; require startup-only rejection, typed replay failure, single consumption, and no fabricated human window. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
Three critical recovery paths in api.rs can leave claims unclosed or unverifiable evidence unquarantined.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
This PR enforces typed terminal closes for veto windows and adds daemon-level recovery coverage and documentation.
Changes:
- Adds typed terminal validation and recovery handling.
- Adds real-daemon regression tests.
- Documents terminal recovery and quarantine semantics.
File summaries
| File | Summary | Review |
|---|---|---|
docs/design/threads-test-clock.md |
Links deterministic timing guidance to recovery documentation. | No final findings. |
docs/design/threads-terminal-recovery.md |
Documents typed terminal recovery and quarantine policy. | No final findings. |
crates/coven-cli/tests/threads_terminal_recovery.rs |
Adds daemon-level recovery regression coverage. | No final findings. |
crates/coven-cli/src/api.rs |
Implements typed terminalization and scheduler recovery. | Three critical findings: stale window context can leave a newly opened window without typed failure evidence; interrupted applies can bypass quarantine when the familiar is unavailable; and Ward::new failures can leave interrupted claims retrying without quarantine. |
Review details
Suppressed comments (2)
crates/coven-cli/src/api.rs:10005
- The same
applying_state.is_none()guard leaves interrupted applies retryable when Ward configuration is missing or invalid: theOk(None)/error arms below release or retain the claim and return a nonterminal response, rather than preserving the evidence in quarantine. A scheduler can therefore hot-loop on a proposal whose live authority cannot be reconstructed. Quarantine theapplying_state.is_some()case before the unapplied-window recovery branch.
crates/coven-cli/src/api.rs:10043 - This new branch takes precedence over the
applying_state.is_some() && opened_window.is_some()recovery boundary. An interrupted apply for a scheduled veto window can therefore skip quarantine; if live reclassification is blocked without producing a protected target (for example, the blocked-symlink case), recovery falls into refusal/retry handling and can erase the apply intent or leave the claim hot-looping instead of preserving the evidence for manual recovery. Handle applying recovery before this branch, or explicitly quarantine the unverifiable applied claim while keeping normal recoverable applies distinct.
- Files reviewed: 4/4 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…rity Refresh context after opening a window in the same decision. Preserve exact interrupted-apply evidence for manual recovery when familiar or Ward authority disappears or cannot be reconstructed, without inventing a terminal rejection. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>
Capture synthetic fixture startup diagnostics and compare parallel versus serial native execution only after a failed gate. Preserve the failing gate; remove the temporary comparison before merge. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>
|
The three review findings are now published in fe7e65c, with observed failing regressions and 166 default / 177 clock-feature tests passing. Auto-merge remains disabled while I investigate the native Windows failure: the first empty-home startup failed before terminal assertions, whereas the existing protected-daemon target passed. 4658775 adds synthetic fixture diagnostics and a temporary parallel-versus-serial comparison only after a failed Windows gate; it deliberately preserves failure and will be removed before merge. No native tests or production deadlines have been weakened. |
Native Windows workspace and clock suites passed without the conditional diagnostic fallback. Keep fixture error diagnostics; do not change lifecycle deadlines or serialize tests without evidence. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>
|
Native Windows workspace and isolated clock checks passed in run 34664801088, including all 12 terminal-target tests under normal concurrency. The conditional parallel/serial diagnostic step did not run; abcfe82 removes it. The workflow now matches main exactly. Only useful synthetic-fixture failure diagnostics remain. I have not changed production lifecycle budgets, skipped Windows coverage, or serialized tests without evidence. The final source head is back through the full protected gate. |
Match the established Windows lifecycle fixture pattern after repeated cold-start failures before readiness. Keep every authority and transport assertion, normal Unix concurrency, and the strict production lifecycle budget unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>
|
The native startup failure recurred in 34665962430: all four concurrent cold starts failed before readiness with no status or recovery log published. In light of repeated evidence, 9b0db3e now follows the existing windows_daemon_lifecycle fixture admission guard for Windows real-daemon journeys. This changes test admission only: every terminal/protected journey remains enabled, transport tests and Unix journeys stay concurrent, and production lifecycle budgets remain strict. The new native run will decide whether this resolves the startup pressure; auto-merge stays off until it does. |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>
|
The Windows admission guard improved the result, but did not fully solve cold readiness: on current base, one serialized first start still failed at 2.209s before publishing status; the other three terminal journeys passed. I am separating the authority fixture from the dedicated two-second CLI lifecycle-start contract rather than widening that production budget or retrying failed starts. Auto-merge is disabled until the fixture is corrected and native CI passes. The terminal API code and all typed recovery assertions remain unchanged. |
…r SLA Launch the actual foreground production server with an absolute authenticated readiness deadline, exact Child ownership, bounded cleanup, and real daemon stop. Keep lifecycle-contract coverage in its dedicated target; retain all authority and restart-recovery assertions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>
|
b6983c1 separates this fixture from the launcher SLA: on Windows it owns the actual production daemon serve process, authenticates readiness against that Child PID under one bounded deadline, detects early exit, captures stderr, and can clean up the exact child even before status exists. It still uses real daemon stop and replaces the process for durable recovery. All authority assertions remain; dedicated lifecycle tests retain the strict two-second launcher and atomic restart contracts. Unix behavior is unchanged. This avoids treating incidental cold-launch latency as a terminal-recovery failure, without introducing an alternate authority implementation. |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>
Context
Checkpoint for #886, not full issue closure. This adopts the existing typed-terminal PR and integrates current main, including #933 protected intake, #968 deterministic Threads time, and #1018 native lifecycle gates.
Changed surfaces: the Rust proposal decision/scheduler boundary in
crates/coven-cli/src/api.rs, one real-daemon integration target, and source-adjacent recovery documentation. No dependencies, database schema, public publication route, or protected-write authority are added.The shared daemon fixture also includes elapsed startup and synthetic-home failure diagnostics. The final workflow is unchanged from main.
Implementation
replay_hash_matched = false.Verification
Local evidence:
cargo fmt --checkcoven-cliClippy in default andthreads-test-clockconfigurationsThe identical new integration test file was run against unchanged main production at
b7b3b4e17cfe21fd440e0f0429f3e38eae1785aa: nine passed, three failed. All three legacy opened-history cases (ordinary, missing Ward, missing familiar) retained only submitted/opened audit rows and pending artifacts after the 120-second hang guard, with unchanged bytes and no decision POST. On this checkpoint: 12 passed. Repeated decisions/restarts preserve one typed rejection, no file mutation, and consumed pending/reservation state.The legacy opened-window rows are explicitly synthetic stopped-daemon recovery history appended after real public coherence intake. This is not evidence of supported scheduled publication.
An additional focused regression reproduced early protected rejection failing to close when a protected baseline became nonregular. The fix covers both protected promotion and Unix blocked-symlink adjudication with unavailable replay.
Hosted review also reproduced stale in-request opened-window context (new window plus invalid Ward glob) and interrupted applied claims looping after familiar/Ward authority loss. Recovery now refreshes newly committed context and quarantines unavailable applied authority without a false terminal outcome. Five unavailable-authority variants preserve exact claim bytes and recorded apply intent.
An optional whole-crate Windows-GNU strict-Clippy probe also surfaced existing platform-specific warnings outside this scope; it is not claimed as green. The new integration target passes its strict Windows check. Hosted required native CI remains the merge gate.
Native Windows exposed repeated empty-home launcher readiness failures, including one serialized cold start at 2.209s before status publication. These are authority/recovery journeys, not launcher SLA tests. The Windows fixture now owns the actual foreground
coven daemon servechild, retains the real owner-restricted pipe/store/startup recovery, and waits under one 15-second absolute readiness guard with authenticated PID checks and early-exit detection. Only absent/pending transport is retried; identity, permission, and protocol failures surface immediately. Exact child ownership permits bounded cleanup even before status exists. Shutdown still uses realdaemon stop; Windows restart recovery uses stop plus a replacement foreground server, not the atomic CLI restart command. Unix launch/restart behavior, all authority assertions, and dedicated strict two-second lifecycle tests are unchanged. No production deadline or workflow gate was changed.Risk and Rollback
Fail-closed recovery changes affect delayed or inconsistent pending history. Normal human intake, protected rejection, replay semantics, and reservation cleanup remain covered. No new authority path is enabled. Roll back the scoped API/test/documentation delta if needed; preserve quarantined evidence rather than deleting it.
Agent Handoff
This is a mergeable bounded checkpoint, not Phase-5 sign-off. #886 remains open for supported scheduled publication and supersession (#972), the broader selectable real-daemon terminal matrix (#931/#884), revised or superseded OpenCoven/coven-threads#27, and reviewed-pin/human acceptance. No bulk repair of arbitrary corrupted historical audits or ambiguous applied state is claimed.
Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com