Repository navigation
feat: close finished Herdr task panes after delivery receipt - #285
Merged
Merged
Conversation
Finished brief and scout panes accumulated because pane closure only ran at teardown, so work that ended in a delivery receipt kept its pane open forever. deliver now hands its newest covered status endpoint and status identity to the new bin/fm-pane-autoclose.sh, which owns one gate: the covered line is the live standing done: claim with the artifact its kind/mode requires, no keyed decision, blocker, linked external request, routed reply, custom check, public commitment, or held board row remains, and the recorded endpoint resolves from ordinary task metadata alone. A failed:, paused:, or unkeyed decision receipt keeps the pane, and so does a later status event, a rotated status identity, an already-closed endpoint, or a secondmate home. The close is teardown's guarded exact-pane path: the named session's presentation lock, then the focus-preserving pane close that refuses the captain's active tab and never calls workspace close. It closes the pane view only: the Herdr session, its other panes, transcripts, and every durable task record stay intact. Coverage: tests/fm-pane-autoclose.test.sh pins sixteen gate decisions against a stateful fake herdr, including a rotated status identity that must not close a replacement pane; tests/fm-pane-autoclose-herdr-e2e.test.sh drives a real guarded lab session for close-after-receipt with the board row still In flight, every keep exclusion, the active-tab refusal, transcript survival, and the ambiguous-endpoint refusal.
A receipt recorded after teardown removed the task record has no live claim left to judge, so the walk keeps silently instead of reporting a refusal on a normal reconciliation path. An unsafe status path still refuses.
…ifecycle regressions
Finished brief and scout panes accumulated because pane closure only ran at teardown, so work that ended in a delivery receipt kept its pane open forever. deliver now hands its newest covered status endpoint and status identity to the new bin/fm-pane-autoclose.sh, which owns one gate: the covered line is the live standing done: claim with the artifact its kind/mode requires, no keyed decision, blocker, linked external request, routed reply, custom check, public commitment, or held board row remains, and the recorded endpoint resolves from ordinary task metadata alone. A failed:, paused:, or unkeyed decision receipt keeps the pane, and so does a later status event, a rotated status identity, an already-closed endpoint, or a secondmate home. The close is teardown's guarded exact-pane path: the named session's presentation lock, then the focus-preserving pane close that refuses the captain's active tab and never calls workspace close. It closes the pane view only: the Herdr session, its other panes, transcripts, and every durable task record stay intact. Coverage: tests/fm-pane-autoclose.test.sh pins sixteen gate decisions against a stateful fake herdr, including a rotated status identity that must not close a replacement pane; tests/fm-pane-autoclose-herdr-e2e.test.sh drives a real guarded lab session for close-after-receipt with the board row still In flight, every keep exclusion, the active-tab refusal, transcript survival, and the ambiguous-endpoint refusal.
A receipt recorded after teardown removed the task record has no live claim left to judge, so the walk keeps silently instead of reporting a refusal on a normal reconciliation path. An unsafe status path still refuses.
…ifecycle regressions
The lint gate flagged the review-1 output globals as unused; annotate them the way the rest of the repo marks sourcing-caller outputs. Add the guarded-lab case the supervisor required: a promise registered in the primary home for secondmate:alice keeps the secondmate task's pane, proven against real Herdr and real tasks-axi.
The suite's setup_home assigns fixture globals in the parent shell while the backgrounded and substituted helpers only read them, so pin that intent once at the file head rather than fifteen per-line directives.
…rebase The pipeline rebased the two task commits onto current main; the remote still carries their original copies. Merging them keeps every prior commit reachable without changing the tree.
Its content was revised by the later review rounds, so this merge changes no files; it only keeps the pre-rebase commit reachable for the private mirror.
* fix(spawn): refuse a fresh brief that duplicates another task's content A brief filled with another task's stale Task or acceptance text launched a worker against the wrong work. A fresh ship or scout spawn now compares its normalized Task section and acceptance-criteria block with live and recently written briefs in this home and refuses an exact match, naming the other task. --allow-duplicate-brief <other-task-id> permits deliberate reuse; --relaunch reuses its own brief and skips the check. * no-mistakes(review): Forward duplicate brief overrides through batch spawn dispatch * no-mistakes(document): Clarify duplicate brief comparison help * no-mistakes(lint): Fix SC2181 status checks in task delivery tests
…vides The previous assertion required Herdr to retain a closed pane in session-history.json. Measured on 0.9.3 that is false: the file is written on a periodic flush, a close leaves the existing text intact, and the next flush rewrites it with live panes only, so a closed pane leaves the persisted history. The test now proves what closure does and does not touch: it waits for Herdr's own capture of both the target and a sibling pane before the close, asserts both survive the close immediately, then waits for one flush and asserts the surviving pane's history persists and the session is still running. It does not pin when a closed pane's text disappears.
Finished brief and scout panes accumulated because pane closure only ran at teardown, so work that ended in a delivery receipt kept its pane open forever. deliver now hands its newest covered status endpoint and status identity to the new bin/fm-pane-autoclose.sh, which owns one gate: the covered line is the live standing done: claim with the artifact its kind/mode requires, no keyed decision, blocker, linked external request, routed reply, custom check, public commitment, or held board row remains, and the recorded endpoint resolves from ordinary task metadata alone. A failed:, paused:, or unkeyed decision receipt keeps the pane, and so does a later status event, a rotated status identity, an already-closed endpoint, or a secondmate home. The close is teardown's guarded exact-pane path: the named session's presentation lock, then the focus-preserving pane close that refuses the captain's active tab and never calls workspace close. It closes the pane view only: the Herdr session, its other panes, transcripts, and every durable task record stay intact. Coverage: tests/fm-pane-autoclose.test.sh pins sixteen gate decisions against a stateful fake herdr, including a rotated status identity that must not close a replacement pane; tests/fm-pane-autoclose-herdr-e2e.test.sh drives a real guarded lab session for close-after-receipt with the board row still In flight, every keep exclusion, the active-tab refusal, transcript survival, and the ambiguous-endpoint refusal.
A receipt recorded after teardown removed the task record has no live claim left to judge, so the walk keeps silently instead of reporting a refusal on a normal reconciliation path. An unsafe status path still refuses.
…ifecycle regressions
The lint gate flagged the review-1 output globals as unused; annotate them the way the rest of the repo marks sourcing-caller outputs. Add the guarded-lab case the supervisor required: a promise registered in the primary home for secondmate:alice keeps the secondmate task's pane, proven against real Herdr and real tasks-axi.
The suite's setup_home assigns fixture globals in the parent shell while the backgrounded and substituted helpers only read them, so pin that intent once at the file head rather than fifteen per-line directives.
Finished brief and scout panes accumulated because pane closure only ran at teardown, so work that ended in a delivery receipt kept its pane open forever. deliver now hands its newest covered status endpoint and status identity to the new bin/fm-pane-autoclose.sh, which owns one gate: the covered line is the live standing done: claim with the artifact its kind/mode requires, no keyed decision, blocker, linked external request, routed reply, custom check, public commitment, or held board row remains, and the recorded endpoint resolves from ordinary task metadata alone. A failed:, paused:, or unkeyed decision receipt keeps the pane, and so does a later status event, a rotated status identity, an already-closed endpoint, or a secondmate home. The close is teardown's guarded exact-pane path: the named session's presentation lock, then the focus-preserving pane close that refuses the captain's active tab and never calls workspace close. It closes the pane view only: the Herdr session, its other panes, transcripts, and every durable task record stay intact. Coverage: tests/fm-pane-autoclose.test.sh pins sixteen gate decisions against a stateful fake herdr, including a rotated status identity that must not close a replacement pane; tests/fm-pane-autoclose-herdr-e2e.test.sh drives a real guarded lab session for close-after-receipt with the board row still In flight, every keep exclusion, the active-tab refusal, transcript survival, and the ambiguous-endpoint refusal.
A receipt recorded after teardown removed the task record has no live claim left to judge, so the walk keeps silently instead of reporting a refusal on a normal reconciliation path. An unsafe status path still refuses.
…ifecycle regressions
…vides The previous assertion required Herdr to retain a closed pane in session-history.json. Measured on 0.9.3 that is false: the file is written on a periodic flush, a close leaves the existing text intact, and the next flush rewrites it with live panes only, so a closed pane leaves the persisted history. The test now proves what closure does and does not touch: it waits for Herdr's own capture of both the target and a sibling pane before the close, asserts both survive the close immediately, then waits for one flush and asserts the surviving pane's history persists and the session is still running. It does not pin when a closed pane's text disappears.
The recovered pipeline head carries the shipped inventory fix; merging the last published head keeps its commits reachable for the private mirror without changing the validated content.
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
bin/fm-branch-outcome.sh delivernow hands its newest covered endpoint and status identity to a new gate, so a finished task's pane closes when its delivery receipt lands and nothing else is owed.Everything else keeps the pane: a
failed:,paused:, or unkeyed-decision receipt, a later status event, a rotated status identity, a local-only completion, a secondmate home, or any follow-on work above. A missing or ambiguous endpoint refuses loudly (exit 2); an absent metadata record means no managed pane exists and nothing is judged. No durable task record is removed.Files:
bin/fm-pane-autoclose.sh(new, owns the gate),bin/fm-branch-outcome.sh(calls it after the receipt is durable),bin/fm-public-followup-lib.sh(teardown's promise-owner resolution extracted so the gate can reuse it),bin/fm-test-run.sh(family map), docs.Evidence
After: the exact pane closes on the receipt, verified against real Herdr.
d1e7bf99(labfm-lab-fm-pane-autoclos-1696283-27260)tests/fm-pane-autoclose.test.sh)bin/fm-herdr-lab.shhelper (named non-default lab session, default-session tripwire verified before and after): the pipeline sandbox cannot provision the lab because it redirects Herdr storage inside its worktree and the tripwire requires the captain's running default session.session-history.jsonintact, and Herdr's next periodic flush rewrites it with live panes only, so a closed pane leaves Herdr's persisted history then. Auto-closed panes therefore do not keep their transcript in Herdr history; the test asserts what the close path controls (history intact at close, surviving pane durable, session still running) and deliberately does not pin that flush.Merge Danger
Door: two-way. Reverting removes one call site and one script; no data migration, no schema, and no record is deleted by the change.
Blast Radius: medium. Every task delivery receipt now evaluates the gate, and the promise-owner resolution moved into a shared library that teardown also uses.
Pipeline
Updates from git push no-mistakes
✅ **Intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 2 issues found → auto-fixed ✅
tests/fm-pane-autoclose-herdr-e2e.test.sh:250- The intent says: "Close-after-receipt is proven end to end for a scout whose row is still In flight and for a ship PR completion with no inventory." The guarded real-Herdr lab proves only the scout close (section 1, lines 207-250). Every later lab case is a keep or a refusal. The ship-PR-without-inventory close is covered only in tests/fm-pane-autoclose.test.sh:245 (test_ship_pr_receipt_without_inventory_closes), which runs deliver against a fakeherdr. The round-1 review-1 decision put that regression in the unit suite. It is unclear whether "end to end" also requires a real-Herdr lab case. If it does, add a lab case: a kind=ship, mode=no-mistakes task with no decisions_reviewed, statusdone: PR https://.../pull/N, delivered throughdeliver, assertingclosed:and that the pane is gone.tests/fm-pane-autoclose-herdr-e2e.test.sh:27- Simplification: the lab test adds an optional FM_PANE_AUTOCLOSE_ARTIFACT_DIR export knob (header line 27, copy block around lines 285-291). It copies the transcript and history snapshots outside the scratch root. No intent requirement asks for exported review artifacts, and no other repo file sets this variable. The persisted-history assertions run without it. Recommended remedy: remove the knob and its copy block.🔧 Fix applied.
✅ Re-checked - no issues remain.
✅ **Test** - passed
✅ No issues found.
bash tests/fm-pane-autoclose-herdr-e2e.test.sh(real Herdr lab: 16 cases, rc=0)bash ~/.no-mistakes/evidence/01M6391HD956G8X2HCJKEGK0H6/extra-lab-driver.sh(one-off real Herdr lab driver: superseded byte endpoint, latest endpoint closes, unkeyed decision delivered, done: without an artifact, secondmate home, absent metadata; rc=0)bash tests/fm-pane-autoclose.test.sh(targeted suite with a fake herdr, which covers the presentation-lock recheck; rc=0)herdr session list --jsonbefore and after, diffing the default session's record to check the tripwire✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.