feat: improve supervision and operational workflows - #13
Merged
Conversation
* fix(bin): handle dash-leading harness process names (#2) * fix: handle dash-leading harness process names * no-mistakes(review): Make dash-leading harness regression hermetic * fix: preserve secondmate reply routes across relative homes Resolve relative home, data, and state inputs before durable charter generation, and fail when caller-relative directories cannot be resolved. Use absolute paths at the related spawn, AFK daemon, and X-mode cross-process handoffs so later processes cannot reinterpret them from another working directory. * no-mistakes(review): Preserve absolute overrides and normalize relative durable paths * no-mistakes(review): Normalize relative home before deriving durable paths * no-mistakes(document): Document relative durable-path normalization * no-mistakes(review): Captain: Ignore inherited CDPATH during relative path normalization * no-mistakes(lint): Fix empty CDPATH assignments for ShellCheck
* Add internal status skill * no-mistakes(document): register /status skill in documentation-audiences inventory * no-mistakes(lint): replace grep|wc -l with grep -c in status skill test * test: silence literal status skill patterns * Refactor bearings default to chat-only --------- Co-authored-by: Kun Chen <3233006+kunchenguid@users.noreply.github.com>
* docs: add captain-approved project operation exception to hard rule 1 Firstmate stays read-only over projects by default, but when the captain clearly approves a concrete project operation and scope in the moment, firstmate may perform exactly that approved operation with its own tools. The approval is never inferred, broadened, or standing, and it does not relax the existing force, discard, unlanded-work, or merge-authority boundaries. * no-mistakes(review): Clarify captain-approved project operation boundaries * no-mistakes(document): Clarify captain-approved project operation scope * docs: cover directories and preserve the operation-or-scope alternative Widen the captain-approved project operation exception in AGENTS.md to files or directories, and restore the explicit operation-or-scope alternative that a prior pipeline auto-fix had collapsed into "and". Rework project-management SKILL.md's Remove section, which previously told firstmate to refuse project removal until a guarded helper existed; that helper was never built, so the text directly contradicted the new instruction-only exception. It now points at the exception plus the existing removal preflight it still requires unchanged. Update the one instruction-owners test assertion that hard-coded the sentence removed above, so the suite tracks current, not obsolete, text. * docs: add captain-approved project operation exception to hard rule 1 Firstmate stays read-only over projects by default, but when the captain clearly approves a concrete project operation and scope in the moment, firstmate may perform exactly that approved operation with its own tools. The approval is never inferred, broadened, or standing, and it does not relax the existing force, discard, unlanded-work, or merge-authority boundaries. * no-mistakes(review): Clarify captain-approved project operation boundaries * no-mistakes(document): Clarify captain-approved project operation scope * docs: cover directories and preserve the operation-or-scope alternative Widen the captain-approved project operation exception in AGENTS.md to files or directories, and restore the explicit operation-or-scope alternative that a prior pipeline auto-fix had collapsed into "and". Rework project-management SKILL.md's Remove section, which previously told firstmate to refuse project removal until a guarded helper existed; that helper was never built, so the text directly contradicted the new instruction-only exception. It now points at the exception plus the existing removal preflight it still requires unchanged. Update the one instruction-owners test assertion that hard-coded the sentence removed above, so the suite tracks current, not obsolete, text. * no-mistakes(review): Align project removal preflight with approved exception * no-mistakes(document): Align project removal documentation with approved exception * fix: restore removal test byte-for-byte and preserve the default sentence tests/fm-instruction-owners.test.sh had been changed to assert different text; restore it byte-for-byte to origin/main. project-management SKILL.md's Remove section now keeps the exact default "Never issue a raw removal command from Firstmate." sentence that test still asserts, immediately followed by the already-approved captain-operation-or-scope exception, so the default and the exception both stay explicit and consistent. * no-mistakes(document): Align project-write boundary documentation
…henguid#1275) * Route project intake through secondmate scopes * no-mistakes(test): Guard all main-home project registry mutations * no-mistakes(document): Consolidate secondmate routing documentation * no-mistakes: apply CI fixes * Restore new-project routing scope * no-mistakes(document): Clarify secondmate routing for new-project intake * no-mistakes: apply CI fixes
…#1282) * test: remove source-content assertions * no-mistakes(review): Replace source assertions with runtime behavior coverage * no-mistakes(review): Isolate Kimi task temp runtime coverage * no-mistakes(document): Refresh test cleanup documentation * no-mistakes: apply CI fixes
…#1286) * fix(watch): bound how long a busy pane may run with no completed turn A busy pane (backend busy state or the harness's rendered footer) was unconditional, unbounded proof of liveness in every escalation path, so a hung foreground tool call behind a busy signature could run for hours undetected (2026-07 hibit-agent-focus-nonsteal-r1 incident: a catastrophic- backtracking regex hung one bash call for 25h behind an unchanging "Working..." footer). FM_BUSY_TURN_MAX_SECS (default 3600s) now bounds how long a busy pane may run with no completed turn (state/<id>.turn-ended, or its spawn record before any turn has completed). Past the bound, busy_turn_over_age routes the pane through the existing wedge_timer_check, reusing the identical stale reason, escalation counter, and demand-deep-inspection marker for human inspection only - never an automatic interrupt, signal, or restart of the worker or its tool process. A completed turn resets the age. Reproduced end-to-end against the real installed Pi TUI: a foreground `sleep 999999` bash call with no timeout renders the actual busy footer, and two captures ~15s apart show the elapsed counter changing the pane hash while the same turn stays unfinished. Running the pre-fix watcher against the real captures showed it never starts a wedge timer no matter how long the pane stays busy; the fixed watcher starts and escalates the timer through the same mechanism, while the real hung process remained untouched and alive throughout. * no-mistakes(review): fix: parse enriched AFK stale reasons * no-mistakes(review): fix: preserve enriched wedges during AFK supervision * no-mistakes(review): fix: route all enriched AFK wedges * no-mistakes(document): Clarify busy-turn age supervision documentation
…unchenguid#1261) A name-by-name list of config/ entries silently stops ignoring any new or home-local file placed there, which makes the working tree read as dirty and blocks guarded sync paths that refuse to touch a dirty home. AGENTS.md already documents config/ as captain-private and gitignored as a category; this makes .gitignore match that contract.
…-20260730 Pulls the upstream firstmate delta (99533c5..e595611): upstream kunchenguid#1286 busy-worker escalation, kunchenguid#1282 test hygiene, kunchenguid#1281 and kunchenguid#1277 validation-scope discipline, kunchenguid#1275 intake routing, and kunchenguid#1272 project-write consent exception, plus kunchenguid#1261, kunchenguid#1256, and kunchenguid#1136 carried along by the merge. Conflict resolutions preserve local divergences and adopt upstream intent: - fm-session-lock-lib.sh: keeps the local dash-leading process-name session-lock fix (parameter expansion), not upstream's basename reversion. - AGENTS.md: keeps the local delivery-gate state-file lines and adopts upstream's hard-rule-1 project-operation consent exception wording. - fm-brief.sh: keeps both the local escalation-format line and upstream's resolve_directory_input helper. - Adopts kunchenguid#1282's test-hygiene deletions of shared source-assertion tests while keeping fork-only coverage (dash-comm session-lock regression tests, herdr presentation-lock, pi-watch, turnend plugins). - fm-kimi-harness.test.sh: adapts upstream's new tasktmp assertion to the fork's home-scoped task-temp path (/tmp/fm-$HOME_TAG/$ID).
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
Pull the upstream firstmate delta (kunchenguid/firstmate main, 99533c5..e595611) into this fork as ONE sync merge commit that pauses for the captain advisor review; do NOT merge it. This is a two-parent merge commit (upstream provenance intentionally preserved; landing method will be a merge commit per the captain standing order for upstream syncs). In-scope upstream PRs pulled: kunchenguid#1286 busy-worker escalation, kunchenguid#1282 test hygiene (replace source-assertion tests with behavioral coverage), kunchenguid#1281 and kunchenguid#1277 validation-scope discipline, kunchenguid#1275 intake routing, kunchenguid#1272 project-write consent exception; plus kunchenguid#1261, kunchenguid#1256, kunchenguid#1136 carried along by the merge. Deliberate conflict resolutions (not mistakes): (1) fm-session-lock-lib.sh keeps the fork's dash-leading process-name session-lock fix using parameter expansion (bc=${comm##*/}), intentionally rejecting upstream's basename reversion which reintroduces the -zsh option-parse bug; (2) AGENTS.md keeps the fork's delivery-gate state-file lines (delivered.md, delivery-override.md) AND adopts upstream's new hard-rule-1 concrete captain-approved project-operation consent exception wording; (3) fm-brief.sh keeps BOTH the fork's ESCALATION_FORMAT line and upstream's new resolve_directory_input helper; (4) adopted kunchenguid#1282's deletions of shared source-assertion test files/functions while deliberately KEEPING fork-only tests (dash-comm session-lock regression tests guarding the fix above, herdr presentation-lock, pi-watch, turnend plugins); (5) fm-kimi-harness.test.sh: adapted upstream's newly added tasktmp assertion to read the fork's home-scoped task-temp path (/tmp/fm-$HOME_TAG/$ID) instead of upstream's flat /tmp/fm-$ID, because the fork intentionally home-scopes TASK_TMP for multi-home isolation. All merge-affected tests pass locally. A pre-existing fork-only test (fm-reap-browsers) hangs only in this local macOS sandbox due to process/cwd inspection limits; it is unchanged by the merge and green in CI.
What Changed
Risk Assessment
✅ Low: The relative root, explicit and fallback home, and state override paths are now normalized consistently across X-mode production, migration, validation, and polling, while the upstream merge provenance and deliberate conflict resolutions remain intact.
Testing
Targeted topology checks, behavioral suites, retained/deleted test inventory, generated CLI artifacts, and manual lock/Kimi demonstrations validated the sync intent; all deterministic checks passed, one unchanged Pi timing case failed once and passed twice on retry, the external-state-mutating real-Herdr E2E was not run under the workspace boundary, and no UI surface existed requiring screenshots.
Evidence: Two-parent sync merge provenance and imported upstream commits
Evidence: Dash-leading session-lock behavior demonstration
Evidence: Generated Firstmate brief showing structured escalation format
Evidence: AGENTS consent and delivery-gate conflict-resolution evidence
Evidence: Kimi home-scoped task-temp execution trace
Evidence: Initial flaky Pi watcher run
Evidence: Successful Pi watcher retry
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 1 issue found → auto-fixed (4) ✅
bin/fm-bootstrap.sh:693- WhenFM_ROOT_OVERRIDEis relative, onlyshim_homeis normalized;$FM_ROOTis embedded unchanged in the durable X-mode shim. If the watcher later runs from another directory, itsexecpath resolves incorrectly and X polling fails. NormalizeFM_ROOTbefore durable handoffs; the same issue affects paths embedded byfm-brief.shandfm-afk-launch.sh.🔧 Fix: Captain: normalize durable Firstmate root paths
1 warning still open:
bin/fm-bootstrap.sh:700- The producer now writes an absolute root intox-watch.check.sh, but the watcher still validates that file and locatesfm-x-poll.shusing its unnormalized$FM_ROOT. When the watcher inherits the same relativeFM_ROOT_OVERRIDEfrom a different working directory, byte validation fails or the poll path resolves incorrectly, so X mode reports the authenticated shim as rejected. Apply the same root normalization in the watcher consumer, and cover the bootstrap-to-watcher handoff rather than only inspecting the generated file.🔧 Fix: Captain: normalize X-mode consumer root paths
1 warning still open:
bin/fm-watch.sh:62- Root normalization occurs afterFM_HOMEis derived from the rawFM_ROOT_OVERRIDE. In the documented legacy mode whereFM_HOMEis unset, the producer embeds an absolute home in the shim but the watcher retains a relative home, so byte validation fails across working directories even when both relative roots resolve to the same checkout;STATEis also derived from that relative value. The new regression test masks this by explicitly setting an absoluteFM_HOME. NormalizeFM_ROOTbefore deriving the fallback home, or normalize the derived home consistently, in the watcher, migration, and poll entry points.🔧 Fix: Captain: normalize legacy X-mode fallback homes
1 warning still open:
bin/fm-watch.sh:74- The reordered fallback fixes unsetFM_HOME, but an explicitly relativeFM_HOMEis still preserved verbatim. Bootstrap writes the shim using its absolute physical home, while the watcher and migration validate it using the relative spelling, so X mode rejects the authenticated shim even when the consumer runs from the same directory. Normalize an explicit relativeFM_HOMEbefore derivingSTATEand validating the shim in the watcher, migration, and poll entry points; preserve already-absolute spellings as the producer does.🔧 Fix: Captain: normalize all X-mode durable paths
✅ Re-checked - no issues remain.
tests/fm-pi-watch-extension.test.sh:961- The retained Pi watcher suite failed once at its session-transition generation-owner scenario, then passed under trace and on a normal retry. The case predates this merge, identifying a timing flake rather than a deterministic sync regression.git show -s --format='commit=%H%nparents=%P%nsubject=%s' 836218bbc392851159cbce23ad54309d3fbc8504andgit rev-list --merges --parents ea645fb..02dbd6fgit log --reverse --format='%h %s' 99533c5..e595611bash tests/fm-claude-stop-autoarm.test.shbash tests/fm-brief.test.shbash tests/fm-kimi-harness.test.shbash tests/fm-turnend-guard.test.shbash tests/fm-pi-watch-extension.test.sh- failed once, then passed underbash -xand on a normal retrybash tests/fm-watch-triage.test.shbash tests/fm-ask-user-authority.test.shbash tests/fm-spawn-dispatch-profile.test.shbash tests/fm-gitignore-config.test.shbash tests/fm-bearings-snapshot.test.shManual dash-leading-zshprocess-chain exercise againstbin/fm-session-lock-lib.shGenerated a ship brief throughbin/fm-brief.shusing a relativeFM_HOMEand inspected its structured escalation contentTracedtests/fm-kimi-harness.test.shto verify/tmp/fm-$HOME_TAG/$IDmetadata andGOTMPDIRpropagationVerified the fork-only session-lock, Herdr presentation, Pi watcher, and turn-end tests remain while the shared source-assertion files are deletedCheckedgit status --short --untracked-files=alland evidence size for transient-artifact cleanup✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.