feat: add per-project delivery modes - #14
Merged
Merged
Conversation
vipentti
pushed a commit
to vipentti/firstmate
that referenced
this pull request
Aug 5, 2026
* feat: per-project delivery modes (no-mistakes|direct-PR|local-only) + yolo flag * no-mistakes(review): Fix local-only safety defaults * no-mistakes(test): Guard optional harness config reads * no-mistakes(document): Document project delivery modes * no-mistakes: apply CI fixes
This was referenced Aug 7, 2026
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
Add a per-project delivery mode plus an orthogonal yolo autonomy flag to firstmate, per the captain-approved plan at data/project-modes-p2/plan.md. Each project in data/projects.md gets a mode - no-mistakes (default), direct-PR, or local-only - chosen at project-add and recorded as '- [] - ' with optional '+yolo'. A new reader bin/fm-project-mode.sh parses it (legacy un-annotated lines and unknown modes/projects default safely to 'no-mistakes off' with a stderr warning). fm-spawn resolves and records mode= and yolo= into state/.meta alongside harness=/kind=. fm-brief shapes the ship definition-of-done by mode: no-mistakes -> /no-mistakes pipeline; direct-PR -> crewmate pushes + opens PR via gh-axi, no pipeline; local-only -> crewmate stops at 'ready in branch', firstmate reviews and merges to local main. fm-teardown gains a local-only carve-out: since local-only has no remote, the safety check requires the branch merged into the local default branch instead of 'on a remote'. New bin/fm-merge-local.sh performs the approved local-only merge as a clean fast-forward only (firstmate's merge gate-action; a deliberate, documented, narrowly-scoped exception to hard rule #1, only after captain/yolo approval). AGENTS.md sections 1, 2, 6, 7, 11 document the modes, the meta/registry format, conditional init (direct-PR/local-only skip no-mistakes init; local-only needs no remote), the per-mode lifecycle, and the yolo approval matrix (yolo on = firstmate approves routine decisions itself but still escalates destructive/irreversible/security-sensitive ones, never merges a red PR, and posts a post-hoc FYI). Deliberate decisions the captain made: yolo is orthogonal to mode (not a 4th mode) and offered-but-not-recommended; for local-only, firstmate (not the crewmate) performs the merge, hence the rule-#1 carve-out. Shell-only change; no test suite in this repo.
What Changed
+yoloautonomy, and recordsmode=/yolo=in task metadata during spawn.no-mistakes,direct-PR, andlocal-onlydelivery paths, including local-only teardown safety.Risk Assessment
✅ Low: The remaining changes are bounded to documented delivery-mode handling and fail closed in the local-only merge/teardown paths, with no material merge-blocking issues found.
Testing
Bootstrap was silent, no automated test suite was present, and manual CLI-level validation showed registry parsing, brief shaping, spawn metadata, local-only merge safety, and local-only teardown behavior working as intended; all transient worktree fixtures were removed and the worktree ended clean.
Evidence: Clean project-mode CLI transcript
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 3 issues found → auto-fixed ✅
bin/fm-project-mode.sh:60- Unknown modes do not fully fall back to the documented safe default: a registry entry like[typo +yolo]becomesno-mistakes on, enabling autonomous approvals even though the comment and requirements say unknown modes/projects default tono-mistakes off. Resetyolo=offin this fallback path.bin/fm-merge-local.sh:27-DEFAULTis derived from the project checkout's current branch, sofm-merge-local.shwill fast-forward whatever branch happens to be checked out instead of verifying and merging into the real default branch/main. Ifprojects/<repo>is on a feature branch, this silently lands the local-only task in the wrong place.bin/fm-teardown.sh:43- The local-only teardown safety check also treats the project checkout's current branch as the default branch, so it can allow teardown after commits are merged into an arbitrary checked-out branch rather than local main/default. Resolve the actual default branch and fail closed if that ref cannot be determined.🔧 Fix: Fix local-only safety defaults
✅ Re-checked - no issues remain.
🔧 **Test** - 1 issue found → auto-fixed ✅
bin/fm-bootstrap.sh:41- Running the documented bootstrap command in a fresh worktree whereconfig/crew-harnessis absent prints/config/crew-harness: No such file or directoryinstead of staying silent.AGENTS.mddocuments the file as optional, so first-time users hit an erroneous bootstrap warning before any project-mode work can be dispatched.bin/fm-bootstrap.shin the checked-out worktree with noconfig/crew-harnessfile presentWith temporarydata/projects.mdfixtures:bin/fm-project-mode.sh nmproj,bin/fm-project-mode.sh directproj,bin/fm-project-mode.sh localproj,bin/fm-project-mode.sh missingproj, andbin/fm-project-mode.sh badprojWith temporary registry fixtures:bin/fm-brief.sh brief-nm nmproj,bin/fm-brief.sh brief-direct directproj, andbin/fm-brief.sh brief-local localproj, then verified the generated user-facing brief text for each delivery modeWith a temporary git project and harmless raw launcher:bin/fm-spawn.sh spawntask projects/spawnproj "printf crewmate-spawned", then verifiedstate/spawntask.metarecordedmode=direct-PRandyolo=onWith a temporary local git project and sibling worktree:bin/fm-teardown.sh localtaskbefore merge,bin/fm-merge-local.sh localtask, thenbin/fm-teardown.sh localtaskafter merge using a faketreehouseshimgit status --shortafter cleanup to confirm transient worktree fixtures were removed🔧 Fix: Guard optional harness config reads
✅ Re-checked - no issues remain.
bin/fm-bootstrap.shCreated a temporarydata/projects.mdregistry and ranbin/fm-project-mode.sh legacyapp gateapp directapp localapp typoapp missingappto verify defaults, direct-PR +yolo, local-only, unknown-mode fallback, and missing-project fallback.Ranbin/fm-brief.sh <id> <repo>forno-mistakes,direct-PR, andlocal-onlyregistry entries and inspected the generated Definition of done sections.Ranbin/fm-spawn.sh spawn-task projects/directapp 'sh -c sleep' --scoutwith worktree-local faketmuxto verifymode=direct-PRandyolo=onare recorded in task meta.Created a temporary local git repo and worktree, ranbin/fm-teardown.sh local-taskbefore merge to verify local-only teardown refusal, then ranbin/fm-merge-local.sh local-taskand reranbin/fm-teardown.sh local-taskwith worktree-local faketreehouseto verify fast-forward merge then successful teardown.Searched for existing test runner/test files withGlob **/*test*,Glob Makefile, andGlob package.json; none were present.git status --short✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.