Conversation
added 7 commits
September 5, 2026 11:13
Re-implements fork commit 5bb9217 against current upstream code. fm_backend_cmux_surface_exists piped list-panes straight into jq without checking the CLI succeeded or returned output. With pipefail off, a list-panes that exited nonzero but still printed a matching pane was read as a confirmed live surface (a false positive on liveness). Capture the CLI output first, fail on a nonzero exit or empty output, then feed jq. Adds a behavioral regression to tests/fm-backend-cmux.test.sh driving the surface_exists interface with a stub that prints a matching pane and exits nonzero; it fails against the old pipe and passes with the guard. Claude-Session: https://claude.ai/code/session_0174SML661zGCCJueePCzpY5
…oise Re-implements the still-needed core of fork PR #6 (7a2b1c4) against current upstream code. The bundled fm-pr-lib.sh GitLab-MR regex tweak is dropped: that pattern is already byte-identical in upstream. fm_backend_herdr_events_capable piped the ~220KB `herdr api schema --json` payload into `grep -Fq`. grep exits on the first match and closes the pipe while printf is still writing, so every TTY-attached watcher probe printed "printf: write error: Broken pipe" twice. The gate still returned capable, so the noise trained operators to ignore real errors on that stream. Match the two event needles with in-process `case` substring matching instead: no pipe, no early-exit consumer, no SIGPIPE. Adds test_events_capable_* to tests/fm-backend-herdr.test.sh, which drive the gate against a large synthetic schema (needles mid-body) under a PTY and fail on any broken-pipe write error. The fork's source-byte-shape lock test is intentionally omitted per the repo's no-source-assertion test rule; the PTY cases prove the behavior instead. Documents the rationale in docs/herdr-backend.md. Claude-Session: https://claude.ai/code/session_0174SML661zGCCJueePCzpY5
… injected claude settings
rega10
force-pushed
the
fm/firstmate-fork-reconciliation-option-a
branch
from
September 5, 2026 16:31
aa8edae to
b2a87a8
Compare
Owner
Author
|
Superseded by #22. The no-mistakes pipeline's CI step automatically rebased this branch onto the old |
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
Rebuild the captain's fork's main as current upstream/main plus the re-implemented fork patch set (the approved Option A). This branch is built from current upstream/main (86ff1bf) and carries, as fresh hand-written commits (one unit per commit, each naming the fork PR/commit it replaces), everything the fork still needs; it is a strict descendant of upstream/main.
Units re-implemented against current upstream (not mechanical cherry-picks - upstream rewrote several of these files, so each was relocated/reworked by hand):
Deliberate exclusions/decisions the reviewer must not flag as mistakes:
Constraints: only the task branch is pushed; origin/main is never force-updated or touched. Because the two histories diverged (291 upstream vs 19 fork commits), merging this PR via a normal merge is impossible; landing requires the captain's SEPARATE main-replacement sign-off, and the PR description carries the updated inventory, the diff-size summary against upstream/main, and the non-destructive re-tracking command sequence for the running install. Keep the total diff small and reviewable.
What Changed
--settingsarguments so Claude receives one authoritative credential-scrubbing configuration while preserving unrelated worker arguments.Risk Assessment
✅ Low: The changed logic is bounded, fail-closed, and the strengthened behavioral regression exercises both supported duplicate-settings forms while validating the complete authoritative settings contract.
Testing
Focused Automic Vault, cmux, and Herdr behavioral tests passed. Executable argv evidence reproduces the base commit's duplicate settings failure and shows the target emitting exactly one authoritative settings object with
apiKeyHelper, every claimed credential environment key set to null, andfeedbackDraftsset to off; both worker settings spellings are absent, adjacent arguments remain intact, and the worktree is clean.Evidence: Automic Vault injected Claude argv: base failure and fixed behavior
Source: Automic Vault injected Claude argv: base failure and fixed behavior
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
⏭️ **Rebase** - skipped
.agents/skills/bearings/SKILL.md- branch carries 242 commit(s) that exist on your local main branch but were never pushed to origin/main; rebasing would bundle this unrelated work (162 file(s)) into the PR:Push main to origin, or rebase your branch onto origin/main, before gating.
🔧 **Review** - 2 issues found → auto-fixed ✅
ℹ️
bin/fm-project-posture.sh:367- In bin/fm-project-posture.sh theclearsubcommand (lines 363-371) goes straight towrite_registry "$project" activewithout running theline_posturemulti-lifecycle-token guard thatget(line 323) andset(line 344) both enforce.write_registry'sfind_lifecycleremoves only the FIRST lifecycle token, so on a corrupt line like- foo [parked archived] - desc (added 2026-01-01)clear foosucceeds and rewrites to- foo [archived] - desc ..., leaving a residual token and masking the corruption, whereasget foo/set foo activecorrectly refuse. Only reachable via a manually hand-edited registry (the posture writer never emits multi-token lines), hence low impact. Remedy: run the sameline_posturerefusal in theclearpath (or makewrite_registrystrip every lifecycle token). Corrects existing internal-tool behavior mechanically; does not extend scope.ℹ️
bin/fm-bitwarden-ceremony.sh:504- In bin/fm-bitwarden-ceremony.sh line 504,stamp=$(today)is an unguarded command-substitution assignment underset -eu. Iftoday()(date -u +%Y-%m-%d) fails, the shell exits immediately with bare code 1 and never reaches the intended diagnostic on line 505 (is_date "$stamp" || die '...'). The two othertoday()call sites guard it explicitly (cmd_init at line 385if ! stamp=$(today); then die ..., and parse_record), so cmd_mark is the sole inconsistent site. Impact is limited: it fails safe (no record is written or corrupted); the only defect is a message-less exit-1 instead of the intended refusal diagnostic. Remedy: mirror the guardedif ! stamp=$(today); then die ...form used at the other two sites.tests/fm-claude-automic-vault.test.sh:596- This regression check is vacuous for the duplicate-settings failure: the exercised worker template supplies no second--settings, so the test still passes if the new stripping loop is removed. It also validates onlyANTHROPIC_API_KEY, not the complete credential-key nulling contract claimed in the verification document. Exercise the injected launch with worker--settings <json>and--settings=<json>inputs, assert only the authoritative settings reach fake Claude, and validate every credential key.🔧 Fix: Strengthen Automic Vault settings filtering regression
✅ Re-checked - no issues remain.
✅ **Test** - passed
✅ No issues found.
bash tests/fm-claude-automic-vault.test.sh— all 6 behavioral suites passed, includingtest_enabled_disabled_and_non_claude_launches, which exercises the spawn→launch path and asserts the effective injected exec argv carries exactly one --settings nulling the credential keys and setting feedbackDrafts off, with no worker-template --settings survivingManual end-to-end exercise of the realbin/fm-claude-automic-vault-launch.sh --injectedexec-composition path with a fake claude recording its argv: confirmed exactly one authoritative --settings reaches the worker and the template's own --settings (space form and inline--settings=form) plus --dangerously-skip-permissions are stripped✅ No issues found.
Inspectedgit diff 89e550aa38c9f6fab217eeb1649aac65b9b2bbbe..718b452516e8d8f2d84c0c1ecf055b0a782dfad4to identify the affected behavioral surfaces.bash tests/fm-claude-automic-vault.test.shbash tests/fm-backend-cmux.test.shbash tests/fm-backend-herdr.test.shExecutedbin/fm-claude-automic-vault-launch.sh --injectedwith separated--settings <json>and inline--settings=<json>worker inputs and captured the fake Claude argv.Executed the base-commit launcher from89e550awith the same separated settings input to reproduce the duplicate-settings failure.Verifiedgit status --shortwas empty after removing transient test files.✅ **Document** - passed
✅ No issues found.
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ No issues found.
✅ **Push** - passed
✅ No issues found.
✅ No issues found.