Skip to content

fix: require typed veto-window terminal closes - #932

Merged
BunsDev merged 20 commits into
mainfrom
fix/886-terminal-close
Sep 12, 2026
Merged

BunsDev merged 20 commits into
mainfrom
fix/886-terminal-close

Conversation

@BunsDev

@BunsDev BunsDev commented Sep 6, 2026

Copy link
Copy Markdown
Member

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

  • Require typed close evidence exactly when an opened window exists; reject duplicate terminal audit appends.
  • Preserve typed rejection for failed/divergent replay, unavailable familiar/Ward authority, live protected promotion, and inconsistent human/window history. Human approval without a window still works without fabricated close evidence.
  • Reuse persisted opened-window context during recovery rather than requiring unavailable current authority to reconstruct it. Early rejection paths also close when live replay itself fails, with replay_hash_matched = false.
  • Classify legacy/no-veto pending history with an existing window during scheduler startup and route it through the same durable refusal boundary. Do not wait for an explicit human approval to repair that inconsistency.
  • Preserve protected classification before decision semantics, durable decision-request verbs, explicit clock timestamps, and a single Uuid-based reservation cleanup path.
  • Keep unverifiable interrupted applies quarantined with their evidence. Quarantine is not a typed terminal close.

Verification

Local evidence:

  • cargo fmt --check
  • strict all-target coven-cli Clippy in default and threads-test-clock configurations
  • 166 focused default and 177 clock-feature Threads/intake tests
  • existing protected-daemon target: 18 tests (nine journeys and nine fixture tests)
  • new terminal-daemon target: 13 tests (four journeys and nine fixture tests)
  • strict Windows-GNU Clippy for the new integration target
  • secret, privacy, documentation ownership, and diff guards

The 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 serve child, 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 real daemon 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

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>

BunsDev commented Sep 7, 2026

Copy link
Copy Markdown
Member Author

Integration review and execution handoff — 2026-09-07

Source reviewed: 28e21e1e99277c18883a602173e6df6152911ea8. Current Actions CI is green, including dependency audit and PR gate. Empty legacy commit statuses are not missing Actions checks. This run does not contain the #931 threads_e2e target and does not close #886.

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 dependencies

The 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 ScheduledProposal objects or expose an unguarded clock/approval hook to make the tests pass.

Retain all nine #886 terminal/human-path scenarios as open acceptance obligations, including superseded, and exact pre-fix red/post-fix green daemon evidence. Deadline expiry means revalidation, never an expired close for an opened window.

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.

@BunsDev

BunsDev commented Sep 9, 2026

Copy link
Copy Markdown
Member Author

Cody agent review checkpoint - 2026-09-09 (local, unpublished)

The remote head is unchanged. The local fix/886-terminal-close follow-up
changes only crates/coven-cli/src/api.rs and preserves the existing checkpoint.

The follow-up prevents retention expiry from replacing veto-window replay;
checks the internal proposal ID before corrupt-review terminalization; preserves
and quarantines ambiguous applied recovery rather than falsely rejecting or
hot-looping; and recognizes terminal HTTP 409 scheduler responses only when the
pending artifact has actually gone. Terminalized work no longer gets the
misleading retained-for-retry log.

Lower-level evidence:

  • Four focused regressions executed for internal-ID mismatch, inconsistent
    human/window recovery, corrupt applied-claim quarantine, and unknown review-kind
    terminalization.
  • The complete locked Coven binary suite passed: 2,776 passed, 3 ignored,
    zero failures. Exact run/output is retained in the execution handoff.
  • cargo clippy -p coven-cli --all-targets -- -D warnings,
    cargo fmt --check, git diff --check, python3 scripts/check-secrets.py,
    and the existing privacy guard for crates/coven-cli/src/api.rs passed.

Quarantine is explicitly not a typed terminal close. It preserves applied
intent and recovery/reservation evidence for manual resolution and must not be
used to close the broader issue. Supported publication, superseded,
deterministic time, and the real-daemon terminal matrix remain outstanding.

Authority/privacy/compatibility impact: fail-closed recovery/logging changes;
no new protected-write path, public Rust contract, schema/migration, or audit
store. Synthetic fixtures only. Sources consulted include the Phase-5 approval
decision, typed close/replay contracts, E2E contract, store reservation behavior,
and this PR's handoff. Rollback is the isolated API delta, retaining quarantined
evidence rather than deleting it.

No #933 production code was imported. The eventual integration must reconcile
one release_terminal_proposal_reservations implementation and preserve early
protected/identity rejection plus typed opened-window handling. Independent
branch results do not prove that combination.

Changes are uncommitted/unpushed; this comment does not claim the remote diff
contains them. threads-980 remains open; execution evidence is in
threads-av3.2 and threads-980.

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>
@BunsDev

BunsDev commented Sep 11, 2026

Copy link
Copy Markdown
Member Author

#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.

@BunsDev

BunsDev commented Sep 12, 2026

Copy link
Copy Markdown
Member Author

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.

BunsDev and others added 8 commits September 11, 2026 19:16
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>
@BunsDev
BunsDev marked this pull request as ready for review September 12, 2026 00:53
Copilot AI lite review requested due to automatic review settings September 12, 2026 00:53
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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: the Ok(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 the applying_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.

Comment thread crates/coven-cli/src/api.rs
Comment thread crates/coven-cli/src/api.rs
Comment thread crates/coven-cli/src/api.rs
@BunsDev
BunsDev disabled auto-merge September 12, 2026 01:07
BunsDev and others added 2 commits September 11, 2026 20:22
…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>
@BunsDev

BunsDev commented Sep 12, 2026

Copy link
Copy Markdown
Member Author

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>
@BunsDev

BunsDev commented Sep 12, 2026

Copy link
Copy Markdown
Member Author

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.

@BunsDev
BunsDev enabled auto-merge September 12, 2026 01:50
@BunsDev
BunsDev disabled auto-merge September 12, 2026 02:06
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>
@BunsDev

BunsDev commented Sep 12, 2026

Copy link
Copy Markdown
Member Author

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>
@BunsDev

BunsDev commented Sep 12, 2026

Copy link
Copy Markdown
Member Author

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>
@BunsDev

BunsDev commented Sep 12, 2026

Copy link
Copy Markdown
Member Author

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>
@BunsDev
BunsDev enabled auto-merge September 12, 2026 03:19
@BunsDev
BunsDev disabled auto-merge September 12, 2026 03:42
@BunsDev
BunsDev merged commit aa527d2 into main Sep 12, 2026
20 checks passed
@BunsDev
BunsDev deleted the fix/886-terminal-close branch September 12, 2026 04:05
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.

2 participants