fix: honor the journal command seam throughout bosun - #110
Merged
Conversation
added 2 commits
August 16, 2026 14:25
fm_bosun_pass() advertised a journal-read command override in its signature comment and never read $1. Nothing ever passed one, and the module reached the journal by absolute path in four places instead - the retention horizon and the batch on the pass's path, and both readings status takes for the health record and the gap count. A caller could believe it could substitute the journal underneath the bosun, and could not. Introduce FM_BOSUN_JOURNAL_CMD alongside FM_BOSUN_JUDGE_CMD, on the same idiom: a command prefix, expanded unquoted so a caller may configure one carrying its own arguments, with each call site appending its own subcommand and flags. All four reaches go through it, and the dead positional is gone rather than kept beside the variable. Partial adoption would be worse than the uniform hard-wiring it replaces: a pass reading one journal while status reads another has the two halves of the module reporting against each other. So the seam is proven by a SECOND adapter, not asserted - tests/fm-bosun.test.sh gains a deterministic fake journal that answers status and read from scripted files, and drives every reach through it against content the real journal in that home cannot produce. Each of the four reaches was mutation-checked by hard-wiring it back on its own; each is caught by its own assertion. The existing guarantees are re-asserted through the fake: the cursor does not advance past a verdict that failed to reach disk, a retention-horizon gap escalates naming the missed range, and an unreadable retained journal still produces a stream-level escalation ahead of the seam. Behaviour is unchanged for every existing caller; the default is the path the four reaches used before. docs/bosun-observer.md records the seam and the mutation evidence.
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.
Intent
Make the bosun's journal-read seam real in bin/fm-bosun-lib.sh. The seam was announced in the interface and absent from the implementation, which is worse than not having it: fm_bosun_pass() declared '# []' in its signature comment and never read $1, nothing ever passed one (bin/fm-bosun.sh's fm_bosun_pass call was the only call site in the tree), and meanwhile the module reached the journal by absolute path in FOUR places, none of them the documented override: the retention-horizon 'status' read and the 'read --since --limit' batch read on the pass's path, plus fm_bosun_journal_last and fm_bosun_journal_gaps, both of which shell out to 'status' for the health record and the status gap count. A caller could believe it could substitute the journal underneath the bosun, and could not.
The design was SETTLED by the requester and explicitly not to be re-scoped: (1) introduce a module-level FM_BOSUN_JOURNAL_CMD defaulting to $FM_BOSUN_LIB_DIR/fm-journal.sh, declared alongside FM_BOSUN_JUDGE_CMD and following that idiom EXACTLY - a command PREFIX, expanded UNQUOTED on purpose so a caller may configure one carrying its own arguments, with each call site appending its own subcommand and flags, mirroring the existing '# shellcheck disable=SC2086' treatment the judge seam already uses. The deliberate word-splitting is therefore intended, matches the established pattern in this same file, and is not a quoting defect. The module was to gain no new pattern because it already had the right one. (2) ALL FOUR reaches go through it; partial adoption is the defect being repaired, not an acceptable outcome, because a pass honouring the seam while status does not would have the two halves of the module reporting against different journals - strictly worse than the uniform hard-wiring it replaces. (3) DELETE the dead positional from fm_bosun_pass's signature comment rather than keeping both a positional and a variable: a documented parameter that does nothing is exactly the defect being fixed, and two ways to do one thing re-creates it in a new place.
Acceptance required the seam to be real rather than hypothetical: a seam with one adapter is a guess, so the task was not done until a SECOND adapter existed. Ship a deterministic fake journal - a small script answering 'status' and 'read' with fixed scripted content - and drive the tests through it; without it nothing proves the seam is honoured and the change has only moved a string. tests/fm-bosun.test.sh had to cover, at minimum: every journal read honours the override INCLUDING the two that status performs (a test exercising only fm_bosun_pass would pass while the defect survived in status); and the existing guarantees still holding when driven through the fake - the cursor does not advance past a verdict that failed to reach disk, a retention-horizon gap produces a 'journal' escalation naming the missed range, and an unreadable journal produces a stream-level escalation. shellcheck clean.
Explicitly OUT OF SCOPE and deliberately not touched: widening the interface, any new configuration knob (FM_BOSUN_JOURNAL_CMD deliberately has NO config/ file, unlike the judge seam, because unlike the model choice this is not a live choice a home makes), the judge seam, verdicts, watch, the health states, the record format, and the escalation bias. Those were separate findings in the same review and none of them was authorised here. Behaviour had to be unchanged for every existing caller, and the default preserves exactly the path the four reaches used before.
Decisions made while doing the work: the fake journal is written inline into the test's own tmp case dir via a quoted heredoc, following the existing JUDGE_SANE fake-judge idiom in that same suite rather than adding a new fixtures directory. The fake takes its fixture directory as its OWN first argument, which additionally proves the seam accepts a command prefix and not a bare path. Every fixture deliberately states something the real journal in that home CANNOT say (a retention horizon above an absent stream, a last sequence of 42, a gap count of 39) so a still-hard-wired reach reads the empty real journal and fails the assertion rather than passing by coincidence; the odd-looking fixture numbers are load-bearing for that reason. Each of the four reaches was mutation-checked individually by hard-wiring it back to bin/fm-journal.sh and rerunning the suite, and each is caught by its own distinct assertion, so partial adoption cannot land. fm_bosun_journal_unreadable was intentionally LEFT reading the FM_JOURNAL_* paths directly: it inspects the retained files' readability, which is not a journal-command reach, it was not among the four the settled design named, and new test case (e) pins that the guard still fires ahead of the substituted stream rather than leaving the ordering implicit. docs/bosun-observer.md gained a short note recording the seam beside the judge seam plus a dated mutation-evidence table, following that doc's established evidence-not-narrative convention; AGENTS.md was deliberately left alone because this is module-local knowledge, not something every session needs, and that file is under strict size discipline.
Verification already run locally: full tests/fm-bosun.test.sh green (22 cases), tests/fm-instruction-owners.test.sh green, bin/fm-lint.sh over the whole tracked tree exit 0 with the pinned ShellCheck 0.11.0, and the extracted fake-journal script independently shellcheck-clean. Repo style rules apply: one full sentence per line in tracked Markdown, plain dash never an em dash, no agent name as commit co-author.
What Changed
FM_BOSUN_JOURNAL_CMDcommand prefix, including pass, health, and status queries.Risk Assessment
✅ Low: The change is narrowly scoped, routes all four journal command reaches through the required command-prefix seam, preserves the default behavior, and adds behavioral coverage for the specified invariants without source-content-only assertions.
Testing
Ran the focused 22-case bosun behavioral suite and instruction-owner regression suite, verified the command-prefix fake journal drives batch, horizon, health-last, and status-gap reads plus key failure modes, and captured the CLI transcript as reviewer-visible evidence. No visual UI evidence applies because this is a shell CLI/module change.
Evidence: Bosun behavioral CLI transcript
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
✅ **Review** - passed
✅ No issues found.
✅ **Test** - passed
✅ No issues found.
bash tests/fm-bosun.test.shbash tests/fm-instruction-owners.test.shManual inspection of the executable seam paths and clean-worktree verification after testing✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.