Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
fe30ee2
fix(spawn): stop passing the removed --tui-mode flag on Pi launches (#2)
tiago-peixoto Aug 11, 2026
067881f
feat(fork): sync upstream into live fork main (#3)
tiago-peixoto Aug 14, 2026
2def68d
fix(bin): make supervision recovery owner-aware and durable (#5)
tiago-peixoto Aug 15, 2026
d0a5f5a
fix(bin): restore upstream ancestry and preserve wake status output (#7)
tiago-peixoto Aug 15, 2026
cb61bd3
Merge upstream/main into fork main
tiago-peixoto Aug 15, 2026
00e17f6
no-mistakes(document): Document regular upstream merge requirement
tiago-peixoto Aug 15, 2026
18e95c7
Merge pull request #8 from tiago-peixoto/fm/fork-upstream-ancestry-redo
tiago-peixoto Aug 17, 2026
86df18c
Merge upstream/main into fork main
tiago-peixoto Aug 17, 2026
d51c708
no-mistakes(document): Refresh upstream-sync documentation contracts
tiago-peixoto Aug 17, 2026
1e24af6
Merge pull request #9 from tiago-peixoto/fm/fork-upstream-sync-aug17
tiago-peixoto Aug 17, 2026
3c9a985
Merge upstream/main into fork main
tiago-peixoto Aug 17, 2026
aee6c2e
no-mistakes(document): Document actionlint workflow coverage accurately
tiago-peixoto Aug 17, 2026
fb41f2e
Merge pull request #10 from tiago-peixoto/fm/fork-upstream-sync-actio…
tiago-peixoto Aug 17, 2026
579c661
Merge upstream/main into fork main
tiago-peixoto Aug 17, 2026
09f4537
Merge pull request #11 from tiago-peixoto/fm/fork-upstream-sync-3
tiago-peixoto Aug 17, 2026
33ec044
Merge upstream/main into fork main
tiago-peixoto Aug 17, 2026
4efa5da
Merge pull request #12 from tiago-peixoto/fm/fork-upstream-sync-4
tiago-peixoto Aug 17, 2026
75441c6
Merge upstream/main into fork main
tiago-peixoto Aug 18, 2026
39d18f2
Merge pull request #13 from tiago-peixoto/fm/fork-upstream-sync-5
tiago-peixoto Aug 18, 2026
06925cf
feat(fork): add permanent fork-main integration
tiago-peixoto Aug 18, 2026
c4f48b2
Merge divergence fork-main-integration
tiago-peixoto Aug 18, 2026
d257ba1
fix(bin): make supervision recovery owner-aware and durable
tiago-peixoto Aug 18, 2026
5ab8af3
Merge pull request #14 from tiago-peixoto/fm/reg-fork-machinery
tiago-peixoto Aug 18, 2026
1c3ae04
Merge divergence supervision-owner-aware-recovery
tiago-peixoto Aug 18, 2026
12e5d2a
Merge pull request #15 from tiago-peixoto/fm/reg-supervision-guard
tiago-peixoto Aug 18, 2026
72715df
Trim generated brief scaffolds
tiago-peixoto Aug 18, 2026
957afe0
Merge divergence firstmate-brief-scaffold-trim-v2
tiago-peixoto Aug 18, 2026
0abbc69
Merge pull request #16 from tiago-peixoto/fm/fork-integrate-brief-sca…
tiago-peixoto Aug 18, 2026
d6420c3
Merge upstream/main into fork main
tiago-peixoto Aug 18, 2026
2ab1d93
Merge pull request #17 from tiago-peixoto/fm/fork-upstream-sync-befor…
tiago-peixoto Aug 18, 2026
ba92ac4
docs: progressively disclose firstmate instructions
tiago-peixoto Aug 18, 2026
232cc65
Merge divergence firstmate-progressive-disclosure-restructure
tiago-peixoto Aug 18, 2026
5fd4685
no-mistakes(document): Align Cursor unread-status supervision guidance
tiago-peixoto Aug 18, 2026
1b15d8b
no-mistakes(lint): Restore submitted Cursor supervision guidance
tiago-peixoto Aug 18, 2026
c88b1ff
Merge pull request #18 from tiago-peixoto/fm/fork-integrate-progressi…
tiago-peixoto Aug 18, 2026
41a7819
Merge upstream/main into fork main
tiago-peixoto Aug 18, 2026
d852238
no-mistakes(document): Document Grok prompt ownership and formatting
tiago-peixoto Aug 18, 2026
1ee9557
Merge pull request #19 from tiago-peixoto/fm/fork-upstream-integratio…
tiago-peixoto Aug 19, 2026
4900101
Merge upstream/main into fork main
tiago-peixoto Aug 20, 2026
f8e4348
no-mistakes(review): Fix heartbeat streak across full wait window
tiago-peixoto Aug 20, 2026
3fe4b62
no-mistakes(document): Align merged documentation with upstream behavior
tiago-peixoto Aug 20, 2026
77cd123
Merge pull request #20 from tiago-peixoto/fm/fork-upstream-2026-08-20
tiago-peixoto Aug 20, 2026
97f8388
feat(fork): accept an upstream issue as a divergence's upstream route
tiago-peixoto Aug 20, 2026
85ed5a7
no-mistakes(review): tighten upstream route validation and refresh ro…
tiago-peixoto Aug 20, 2026
563bb70
feat(bin): report reclaimable Next.js build output in pooled worktrees
tiago-peixoto Aug 20, 2026
6ff6759
no-mistakes(document): Document issue-first fork divergence routing
tiago-peixoto Aug 20, 2026
b8b049b
no-mistakes(review): preserve issue closure reasons during refresh
tiago-peixoto Aug 20, 2026
2392aff
no-mistakes(document): Document issue-route refresh semantics
tiago-peixoto Aug 20, 2026
fa8e188
no-mistakes(document): Clarify upstream review diagnostics
tiago-peixoto Aug 20, 2026
9609f26
no-mistakes(review): Distinguish duplicate issue closures during refresh
tiago-peixoto Aug 20, 2026
1a8e1fd
no-mistakes(review): Correct duplicate issue closure guidance
tiago-peixoto Aug 20, 2026
ae712fd
no-mistakes(document): Update fork review terminology
tiago-peixoto Aug 20, 2026
8a4d432
Merge pull request #22 from tiago-peixoto/fm/firstmate-fork-issue-fir…
tiago-peixoto Aug 21, 2026
36933b0
feat(bin): report Next.js build output in pooled worktrees (#23)
tiago-peixoto Aug 21, 2026
a0b7425
Merge divergence firstmate-next-cache-reclaim to restore its integrat…
tiago-peixoto Aug 21, 2026
83b5181
Merge pull request #24 from tiago-peixoto/fm/fork-repair-next-cache-m…
tiago-peixoto Aug 21, 2026
7091205
Merge upstream/main into fork main
tiago-peixoto Aug 21, 2026
9b9d1a1
no-mistakes(document): Refresh merged documentation contracts
tiago-peixoto Aug 21, 2026
67483a4
no-mistakes(lint): Preserve dedicated fm-brief test routing
tiago-peixoto Aug 21, 2026
4ac485d
no-mistakes: apply CI fixes
tiago-peixoto Aug 21, 2026
8c02504
no-mistakes: apply CI fixes
tiago-peixoto Aug 21, 2026
8892efe
no-mistakes: apply CI fixes
tiago-peixoto Aug 21, 2026
510cdd5
Merge pull request #25 from tiago-peixoto/fm/fork-upstream-2026-08-21
tiago-peixoto Aug 22, 2026
df87ec2
Merge upstream/main into fork main
tiago-peixoto Aug 24, 2026
2edb210
no-mistakes(review): Harden handoff, inbox, SSH, and tool boundaries
tiago-peixoto Aug 24, 2026
2b07803
no-mistakes(document): Confirm integrated documentation remains accurate
tiago-peixoto Aug 25, 2026
59cfd85
no-mistakes(document): Refresh portable shard documentation
tiago-peixoto Aug 25, 2026
2e29079
Merge pull request #26 from tiago-peixoto/fm/fork-upstream-2026-08-24
tiago-peixoto Aug 26, 2026
c50a877
fix(bin): require exact CI evidence for active monitors
tiago-peixoto Aug 28, 2026
fb256af
no-mistakes(review): Bound forge evidence reads and clarify mixed CI …
tiago-peixoto Aug 28, 2026
74a0fa1
no-mistakes(document): Clarify active CI terminal evidence ownership
tiago-peixoto Aug 28, 2026
200d2b4
no-mistakes(lint): Captain, fix overlapping forge timeout status patt…
tiago-peixoto Aug 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .agents/skills/bearings/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Board answers are acted on later under the normal authority rules; this skill's
This is the only file-mode write allowed by the skill.
The detailed report includes:
- **Title** - `# Bearings - <day> <YYYY-MM-DD>` (use "Morning status" only when the captain specifically asks for a morning brief), followed by two or three sentences framing where things stand.
- **Captain's Call** - every open decision summarized with its options from the structured decision record, plus each PR ready to merge and each needed credential or login, every PR with the full `https://...` URL, never a bare `#number`.
- **Captain's Call** - every actionable captain-held task summarized with the question and options from its hold reason, plus each PR ready to merge and each needed credential or login, every PR with the full `https://...` URL, never a bare `#number`.
- **Recently Landed** - the bounded current recent-completions baseline from structured state across the main fleet and every registered secondmate home, rendered in full on every run.
- **Underway** - each live direct report making progress, with its current state, and the plans or main pickup pointers worth reopening (`data/<id>/report.md` files, `.lavish/*.html` boards).
- **Charted Next** - queued or gated work, including any main-inventory integrity warning, with each item's blocker, date, or integrity reason.
Expand Down
125 changes: 125 additions & 0 deletions .agents/skills/fork-main-integration/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
---
name: fork-main-integration
description: >-
Agent-only procedure for operating Firstmate from a permanent personal-fork main.
Use before configuring or reversing Firstmate code remotes, briefing a Firstmate divergence topic, provisioning or using the isolated fork validation registration, integrating or discarding a divergence, responding to UPSTREAM_SYNC output or an upstream-integration required/failed result, preparing an upstream merge, re-justifying its conflicts, or deciding what the fork still carries.
user-invocable: false
metadata:
internal: true
---

# fork-main-integration

Load this procedure only when the Firstmate code repository itself uses permanent fork-main integration.
[`docs/fork-main.md`](../../../docs/fork-main.md) is the operator-current owner of the mechanics, the manifest schema, and the health criteria.
The script headers own exact mechanics and arguments.
This file keeps what binds you at the point of action - the prohibitions, the order of operations, and the judgements no report can make for you - and points at that owner for everything descriptive.

## Safety boundaries

- `origin` is the personal fork and `upstream` is official.
- Never migrate the captain's operating checkout as a side effect.
Run `bin/fm-fork-remotes.sh plan`, show the reverse command, and obtain concrete captain confirmation before the live `apply` command.
- Never reconfigure the ordinary no-mistakes registration to target fork main.
- Normal live-home remote migration must prove that registration before and after the Git change.
The `--no-registration` exception belongs only to provisioned remote code roots that never validate changes, and is never a retry or bypass after a registration error.
- Provision a separate private integration clone only through `bin/fm-fork-integration.sh`.
Stop if ordinary-registration isolation cannot be proven before and after init.
- Never restart or update the shared no-mistakes service from this workflow.
- Live homes remain fast-forward-only consumers of validated fork main.
Real upstream and topic merges happen only in isolated candidates.
- Keep `rerere.autoupdate=false`.
A replayed resolution must remain unstaged and reviewable.
- Never force-push or rewrite a published topic or pull-request branch.
- Never habitually merge upstream or fork main into a divergence topic.
Do so only for a concrete API dependency, a real merge conflict, or an upstream maintainer request.
- Every fork-main PR still requires the captain's explicit merge approval.

## New divergence intake

Follow the issue-first contribution order and its current validation-lane limit in [`docs/fork-main.md`](../../../docs/fork-main.md) before beginning this pull-request-producing intake.

1. Scaffold the Firstmate ship brief with `--start-ref upstream/main` so unrelated fork divergences cannot enter the upstream pull request.
That generated brief loads this procedure for the worker and directly carries the no-rewrite, no-routine-merge, and official-upstream validation rules through the typed launch input.
2. Run the ordinary no-mistakes path against the official-upstream registration.
3. Preserve the upstream pull request as the delivery and review artifact.
4. Before fork integration, ensure the canonical `fm/divergence/<id>` topic contains one aggregate non-merge patch commit relative to upstream.
`git cherry` is patch-by-patch and cannot prove that a multi-commit topic equals one upstream squash commit.
5. Never rewrite a published multi-commit PR branch to satisfy step 4.
Create a fresh one-commit canonical divergence topic and retain the original head as the manifest-linked delivery artifact.
6. Create an isolated candidate from fetched fork main in the private integration clone.
7. Run `bin/fm-fork-topic.sh integrate` with a concrete retirement condition and complete path list.
On exit 3, settle the retain decision, resolve and stage the product conflict, and run receipt-bound `bin/fm-fork-topic.sh continue` with the complete decision file.
8. Drive no-mistakes from that integration clone, run health against the post-pipeline head, open the fork-main PR, and require fork CI green.
9. Tell the captain the full fork PR URL and concise local outcome.
10. Merge only after the captain says so, using the regular merge method so the inner topic merge remains reachable.
11. Run `/updatefirstmate` after landing so safe homes fast-forward from validated fork main.

A vague retirement reminder is not a valid manifest condition.
Use a falsifiable statement such as "Upstream ships equivalent endpoint identity validation" or "This compatibility path is no longer reachable on every supported backend".

## Upstream review disposition

Only a genuine upstream decline permits reclassifying a pending divergence to `rejected-but-retained`.
A duplicate issue closure means review moved, so repoint the recorded route without reclassifying it.
Follow the full outcome mapping and operator actions in [`docs/fork-main.md`](../../../docs/fork-main.md#upstream-review-after-local-adoption).
For a genuine decline, choose one of two outcomes in the next validated fork integration:

- Reclassify it to `rejected-but-retained` through `bin/fm-fork-topic.sh disposition` because current evidence still justifies the behavior.
- Discard it because its retirement condition is true or the evidence no longer supports carrying it.

Upstream rejection does not automatically remove useful running behavior.
A correctness or security finding that applies locally is stronger evidence than the earlier green run and requires an immediate fix or discard.

## Upstream integration

Handle `UPSTREAM_SYNC: required` or `upstream-integration: required` as work for the main primary, never a secondmate or remote code root.
Coalesce duplicate notifications behind one open integration task.

`UPSTREAM_SYNC: fork topology is not validated: <requirement>` is a different problem and never starts a merge.
This home has an `upstream` remote but has not completed the explicit migration, so the upstream movement probe was skipped and the line repeats on every startup until it is fixed.
Report the named requirement to the captain and, once they confirm, complete the migration through `plan` then the live `apply` command, or reverse it - never migrate `origin` silently to clear the line.

1. Ensure the private fork registration passes `bin/fm-fork-integration.sh check`.
2. Create an isolated candidate branch at fetched `origin/main` from the private integration clone.
3. Run `bin/fm-fork-merge.sh prepare`.
4. On a clean result, inspect the emitted `git range-diff --remerge-diff` review and health result before starting no-mistakes.
5. On exit 3, treat every named conflict as a divergence re-justification decision before resolving files.
6. Load `ask-user-authority` before deciding whether routine authority can answer a re-justification.
A material behavior expansion, destructive choice, security-sensitive choice, or captain-owned product trade-off still goes to the captain.
7. Resolve files only after the decision is settled, write the complete `firstmate.fork-rejustify.v1` decision file outside the candidate working tree, and run `continue`.
If the settled decision is complete removal, use the receipt-bound upstream `abort`, then the independent topic `discard` path, land that candidate, and retry upstream preparation instead of continuing the conflict.
8. Drive no-mistakes through the private fork registration and process every gate.
9. Require fork CI green and captain merge approval.
10. Use the regular merge method, then run `/updatefirstmate`.

A replayed rerere result supplies only the previously accepted file resolution, never the answer to whether the divergence is still worth carrying; the unmerged index is the barrier that keeps that decision explicit, so never let a replay stand in for it.

## Health and relevance

Use `bin/fm-fork-status.sh` for the local answer and add `--refresh` only when live remote and upstream review evidence is needed.
After no-mistakes, use the post-pipeline candidate command in [`docs/fork-main.md`](../../../docs/fork-main.md); a bare invocation reads the fork remote rather than proving candidate `HEAD`.
Its own errors, signals, and exit status are the machine verdict, and [`docs/fork-main.md`](../../../docs/fork-main.md) states how it classifies raw `git cherry` facts and what makes it unhealthy.

Never describe the fork as healthy when that report is not.
The one judgement the report cannot make is yours: a pending unit that is aging without action is not a healthy fork, however clean the machine verdict.

Run the `git range-diff --remerge-diff` command the report prints for every unit the latest upstream merge touched.
It is a human review surface, not machine state.

## Discard

Prepare discard only from an isolated branch at fetched fork main:

```sh
bin/fm-fork-topic.sh discard --id <id> --repo <isolated-worktree>
```

Any product-file conflict reopens re-justification and leaves a receipt-bound merge or revert operation.
Resolve the decision and files, write the complete `firstmate.fork-rejustify.v1` decision outside the candidate, then run `bin/fm-fork-topic.sh continue --decisions <file> --repo <isolated-worktree>`.
Validate the actual post-pipeline candidate through the private fork registration and require captain approval for its fork-main PR.
Never reset or rewrite fork main to remove a divergence.

Git remembers a reverted merge as unwanted ancestry.
To restore discarded behavior, revert the revert or introduce a genuinely new topic version.
Do not merge the old topic blindly.
8 changes: 5 additions & 3 deletions .agents/skills/harness-adapters/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,13 +202,15 @@ Its broader dark-TRUECOLOR placeholder handling and dark-theme tradeoff are docu
That styled capture is internal to the boolean detector only.
`fm-peek` and every other human or LLM-facing capture path stays plain `tmux capture-pane` with no escape codes.

**Primary-session guard fact (verified 2026-07-04, Claude Code 2.1.201; preserved 2026-07-08, Claude Code 2.1.204; Stop-owned auto-arm revalidated 2026-07-24, Claude Code 2.1.219).**
**Primary-session guard fact.**
[`docs/turnend-guard.md`](../../../docs/turnend-guard.md) owns the current mechanism, and [`docs/verification/supervision.md`](../../../docs/verification/supervision.md#turn-end-guard) owns dated evidence.
This is separate from the per-task crewmate turn-end hook above (that one just `touch`es a marker file in a task's own `.claude/settings.local.json`).
The firstmate PRIMARY's own `.claude/settings.json` registers two Stop hooks: `bin/fm-turnend-guard.sh --claude` and the Stop-owned auto-arm `bin/fm-claude-stop-autoarm.sh` (`asyncRewake: true`, `timeout: 28800`), and exiting the guard with status 2 plus stderr reliably forces the model to continue.
Claude Code's stdin payload to a Stop hook carries a `stop_hook_active` boolean that is `true` when the current stop attempt follows ANY stop-hook-driven continuation, including `asyncRewake` rewakes; the primary guard therefore ignores it in `--claude` mode and uses the cooperative claim/epoch check plus a bounded re-block budget instead, while the codex-mode default still treats it as a one-block loop guard.
Claude Code's stdin payload to a Stop hook carries a `stop_hook_active` boolean that is `true` when the current stop attempt follows ANY stop-hook-driven continuation, including `asyncRewake` rewakes; the primary guard therefore ignores it in `--claude` mode.
The current owner above defines its shared session-ownership boundary, one-shot escalation after two identical no-claim blocks, and separate bounded progression for verified automatic failures; the codex-mode default still treats `stop_hook_active` as a one-block loop guard.
A project-level `.claude/settings.json` only takes effect when Claude Code's project root is that exact directory - it does not walk up from a subdirectory looking for one, so firstmate launches the primary from the repo root.
After those settings are loaded, hook command resolution is still cwd-sensitive because Claude Code runs commands through `/bin/sh` against the session's current cwd; keep the tracked commands anchored through `"$CLAUDE_PROJECT_DIR"/bin/...` and see `docs/turnend-guard.md` for the verified Stop-hook details.
Claude Code's primary watcher protocol is Stop-owned: the auto-arm hook fires on every Stop and foregrounds `bin/fm-watch-arm.sh` when the home is eligible and still needs supervision, and its exit-2 `asyncRewake` rewake is the wake; the model drains and handles wakes but never runs a routine re-arm command.
Claude Code's primary watcher protocol is Stop-owned: the auto-arm hook fires on every Stop and foregrounds `bin/fm-watch-arm.sh` when the home is eligible and still needs supervision, and its exit-2 `asyncRewake` rewake is the wake; the model presents and handles wakes, runs the drain's printed post-handling acknowledgement, and never runs a routine re-arm command.

## codex (VERIFIED 2026-06-11, codex-cli 0.139.0)

Expand Down
5 changes: 5 additions & 0 deletions .agents/skills/secondmate-provisioning/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ Because this resolves from the file on every spawn, the pin is durable across ev
This is secondmate-only: crewmate/scout model resolution is untouched by this file.

This section is the single owner of the secondmate sync and inherited-local-material propagation contract; `AGENTS.md` sections 3 and 4 point here.
When the primary uses validated fork-main topology, also load `fork-main-integration` before provisioning.
A standalone local home inherits the primary's exact fork `origin`, official `upstream`, local main tracking branch, and reviewable rerere settings; a linked home already shares those Git facts.
Before inheritance mutates an existing standalone home, local seeding snapshots its complete Git config and remote-ref topology and restores both if any later seed step fails.
A remote provision receives those validated URLs explicitly and establishes the same topology in its code root before the persistent home is attached.
The helpers refuse a partial or contradictory source topology rather than guessing, and `/updatefirstmate` leaves remote code roots as independent fast-forward consumers rather than upstream integrators.
Before a local launch, `fm-spawn.sh --secondmate` locally fast-forwards the home to the primary firstmate checkout's current default-branch commit when it is safe; dirty, diverged, or in-flight homes launch unchanged with a warning.
The locked session-start deferred network stage runs the same bootstrap sweep for every live local secondmate home, discovered from `state/<id>.meta` records with `kind=secondmate` (`data/secondmates.md` only backfills `home=` for older records).
That no-fetch path is a purely local fast-forward of tracked files, never an origin fetch, and it never touches the gitignored operational dirs, so a secondmate's backlog, projects, and in-flight work are never disturbed; a linked worktree advances immediately, while a standalone clone that lacks the target receives firstmate updates through `/updatefirstmate`'s origin refresh.
Expand Down
Loading