Skip to content

Feature 013: unattended work continuity — resolved-or-unresolved halts - #1

Merged
E-G-C merged 1 commit into
copilot/statusfrom
e-g-c-special-funicular
Aug 6, 2026
Merged

Feature 013: unattended work continuity — resolved-or-unresolved halts#1
E-G-C merged 1 commit into
copilot/statusfrom
e-g-c-special-funicular

Conversation

@E-G-C

@E-G-C E-G-C commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Why

During an explicitly unattended (--policy autonomous) run, dude-work sometimes ended a turn just to summarize progress, which read as a stop, so work idled with no legitimate basis while ready work remained. Worse, some halts named no reason from the closed stop set, so an unnameable halt looked exactly like a legitimate one after the fact, and a legitimately-named halt could still be undiagnosable without reading runtime internals.

What this does

Under an explicit unattended run, the loop now keeps working through ready work and ends only on a genuine stop. Every work-loop halt carries a report that is one of two structurally distinct forms:

  • resolved: exactly one reason from the existing closed stop set, plus actionable detail (affected target, specific causing subject or condition, next owner action), or
  • explicitly unresolved: names the fields that could not be established and presents no reason outside the closed set.

A halt that cannot be attributed to a closed-set reason takes the unresolved form rather than masquerading as a named one. Progress reporting is decoupled from stopping, and every safety floor (destructive operations, spending, credentials, external authorization, ownership ambiguity), hard stop, verification gate, and independent review is preserved unchanged. Guarded and non-unattended behavior is byte-for-byte identical.

Approach

The deterministic autonomous runner attaches the report at its single terminal chokepoint finish(row): a hard-stop terminal carries describeUnattendedHalt(...), a clean settlement (ended) carries null. It reuses two landed primitives (endsUnattendedLoop, describeUnattendedHalt) unchanged.

The key design decision, worth calling out: the runner is the sole production driver of the host adapter and the model submits no protocol operations, so having the deterministic runner decide continuation is exactly what FR-010 requires. That single insight let us delete an entire earlier design (a session gate, per-operation gating, checkpoint/handoff/resume threading, and a lane-disposition chain) as machinery guarding a threat the production topology does not contain. The result is one bounded field on the terminal row: no new stop reason, lane, board, command, persistent store, or gate, and no halt attribution persisted anywhere.

Non-obvious notes for reviewers

  • The hard-stop-only gate is necessary, not just an optimization: endsUnattendedLoop fails closed to "halt" for any non-authorized/completed reason, so calling the reporter on ended rows would misclassify a clean settlement.
  • The named safety-floor category reasons are not reachable as end-to-end runner terminals (completionDispositionV2 emits only accepted/verification-failed/review-rejected; ownership ambiguity is preempted earlier). Their exhaustive per-category coverage lives at the reporter level; the runner wiring is reason-agnostic and proven on every reachable terminal, so the split composes without a gap.
  • One decode-failure fallback branch is a deliberate, unreachable defense-in-depth guard that only upholds finish's never-throw contract; it is honestly left uncovered per the "an unreachable guard cannot be honestly covered" rule.

Verification

Full discovered suite 2261 pass / 0 fail (4 pre-existing platform skips); focused runner+recovery 557/0; prompt-contract 117/0; dude-lint 0/0; compose verify all packs OK; pristine release build clean; .github regenerated with src parity. Independent Tester and Code Reviewer both signed off on the runner wiring (T006) and on the complete feature (T005).

… reporting

Under an explicit unattended (--policy autonomous) run, dude-work now keeps
working through ready work and ends only on a genuine stop; every work-loop
halt carries a report that either resolves to exactly one closed-set reason
with actionable detail (affected target, specific causing subject, next owner
action) or is explicitly unresolved (names the fields that could not be
established and presents no out-of-set reason). Progress reporting never stops
the loop, and every safety floor, hard stop, verification gate, and independent
review is preserved unchanged.

The deterministic autonomous runner attaches the report at its single terminal
chokepoint finish(row) — hard-stop -> describeUnattendedHalt(...), ended ->
null — reusing the landed endsUnattendedLoop / describeUnattendedHalt
primitives. Because the runner is the sole production adapter driver and the
model submits no protocol operations, the runtime (not the model) owns the stop
decision, resolving the FR-010 wired-versus-unwired dilemma without a session
gate, checkpoint threading, or any new stop reason, lane, board, command, or
persistent store. Guarded and non-unattended behavior is byte-for-byte
unchanged.

Tasks T001-T006 complete. Verification: full discovered suite 2261 pass / 0
fail (4 pre-existing skips); focused runner+recovery 557/0; prompt-contract
117/0; dude-lint 0 warnings / 0 failures; compose verify all packs OK;
pristine release build clean; .github regenerated with src parity.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 74c629fd-d370-4111-b399-2d1d6b90c152
@E-G-C
E-G-C merged commit 938c842 into copilot/status Aug 6, 2026
2 checks passed
@E-G-C
E-G-C deleted the e-g-c-special-funicular branch August 6, 2026 01:26
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.

1 participant