Skip to content

feat: add scout task lifecycle - #7

Merged
kunchenguid merged 3 commits into
mainfrom
feat/scout-tasks
Jun 12, 2026
Merged

kunchenguid merged 3 commits into
mainfrom
feat/scout-tasks

Conversation

@kunchenguid

Copy link
Copy Markdown
Owner

Intent

Extend firstmate so crewmates handle ALL project-specific work, not just coding that ends in a PR. The captain asked for this and approved the proposed design including the rule-3 carve-out and promotion. New task shape 'scout' (investigations, planning, bug reproductions, audits): deliverable is a standalone report at data//report.md instead of a PR; the worktree is declared scratch from the start. Changes: (1) AGENTS.md - identity broadened from coding tasks to all project work, intake now classifies shape (ship vs scout) before readiness, scout flow documented (no validate/PR/merge stages; report -> relay to captain -> immediate teardown), promotion documented, hard rule 3 gets the deliberate scout carve-out, backlog format gains a report-link Done variant, brief section mentions --scout; (2) bin/fm-brief.sh - --scout flag writes a scout contract scaffold (never push, report definition of done, worktree-is-scratch framing); (3) bin/fm-spawn.sh - --scout flag records kind=scout in the task meta, default kind=ship for backward compatibility (absent kind in old meta files is treated as ship by teardown); (4) bin/fm-teardown.sh - scout tasks skip the unpushed-work refusal once data//report.md exists, refuse with a clear message when the report is missing, ship tasks keep the full protection unchanged; (5) new bin/fm-promote.sh - flips kind=scout to ship in meta so a scout crewmate can be promoted in place (keeping worktree and context) when its findings reveal shippable work, restoring full teardown protection. Deliberate decisions: --scout flags are parsed positionally-tolerant (filtered from args) on both fm-brief and fm-spawn; scout briefs forbid pushing to ANY remote (stronger than ship's never-push-to-default) because nothing from a scout worktree should ever leave the machine; the report-missing teardown refusal deliberately mirrors the existing refusal wording style; all scripts were smoke-tested locally (both scaffolds, promote happy/error paths, teardown refusal and carve-out paths).

What Changed

  • Added a scout task shape for investigations, plans, reproductions, and audits, with report-based completion at data/<id>/report.md instead of PR validation.
  • Extended task scaffolding and spawning with --scout, persisted task kind metadata, and documented scout intake, supervision, teardown, and Done backlog entries.
  • Added in-place scout promotion via bin/fm-promote.sh and updated teardown protections so scout scratch work can only be discarded after a report exists while ship tasks retain unpushed-work safeguards.

Risk Assessment

✅ Low: The change is well-bounded to firstmate task orchestration scripts and documentation, and the previously flagged promotion handoff risk is addressed with explicit cleanup-before-branch guidance.

Testing

Exercised the scout flow through the actual firstmate shell scripts and treehouse-backed spawn/teardown path, captured reviewer-visible CLI transcripts, verified documented edge cases, and confirmed no transient test files remained in the working tree; all tested behavior passed.

Evidence: Scout lifecycle transcript

Shows scout brief scaffolding, fm-spawn recording kind=scout, teardown refusing before data/e2e-scout/report.md, teardown succeeding after the report despite an unpushed scratch commit, and fm-promote changing meta to kind=ship with ship teardown protection restored.

## Scout lifecycle end-to-end transcript
workspace=/Users/kunchen/.no-mistakes/worktrees/016d88035d58/01KTYK46X0ZFACSPFS8HBDMCKP

### Scaffold scout brief
scaffolded: /Users/kunchen/.no-mistakes/worktrees/016d88035d58/01KTYK46X0ZFACSPFS8HBDMCKP/data/e2e-scout/brief.md (scout; replace {TASK})
brief contains scout contract: yes

### Spawn scout with raw inert crewmate command
spawned e2e-scout harness=sh kind=scout window=firstmate:fm-e2e-scout worktree=/Users/kunchen/.treehouse/project-9d4b21/1/project

meta after spawn:
window=firstmate:fm-e2e-scout
worktree=/Users/kunchen/.treehouse/project-9d4b21/1/project
project=/Users/kunchen/.no-mistakes/worktrees/016d88035d58/01KTYK46X0ZFACSPFS8HBDMCKP/.tmp-scout-lifecycle/project
harness=sh
kind=scout

worktree path=/Users/kunchen/.treehouse/project-9d4b21/1/project

### Add scratch work that would block ship teardown
scratch status after commit:
unpushed commit visible: f97b47b scratch scout work

### Teardown refuses when report is missing
REFUSED: scout task e2e-scout has no report at /Users/kunchen/.no-mistakes/worktrees/016d88035d58/01KTYK46X0ZFACSPFS8HBDMCKP/data/e2e-scout/report.md.
The report is the work product. Have the crewmate write it (or get the captain's explicit OK to discard, then --force).
missing-report refusal observed

### Report unlocks scout teardown despite unpushed scratch commit
🌳 Terminated lingering processes: zsh (19087), sleep (19317)
🌳 Worktree returned to pool.
teardown e2e-scout complete (window firstmate:fm-e2e-scout, worktree /Users/kunchen/.treehouse/project-9d4b21/1/project)
meta removed after teardown: yes
report preserved after teardown: yes

### Promotion restores ship protection
promoted e2e-promote to ship (teardown protection restored)
next: bin/fm-send.sh fm-e2e-promote '<ship instructions: review scratch state with git status and git log; reset to a clean default-branch base; carry over only intended fix changes; create branch fm/e2e-promote; implement; report done>'
meta after promote:
window=firstmate:fm-e2e-promote
worktree=/Users/kunchen/.no-mistakes/worktrees/016d88035d58/01KTYK46X0ZFACSPFS8HBDMCKP/.tmp-scout-lifecycle/promote-wt
project=/Users/kunchen/.no-mistakes/worktrees/016d88035d58/01KTYK46X0ZFACSPFS8HBDMCKP/.tmp-scout-lifecycle/promote-project
harness=raw
kind=ship
ship teardown now refuses unpushed local commit: REFUSED: worktree /Users/kunchen/.no-mistakes/worktrees/016d88035d58/01KTYK46X0ZFACSPFS8HBDMCKP/.tmp-scout-lifecycle/promote-wt has work not on any remote.
unpushed commits:
996cb0f base
Push the branch (or get the captain's explicit OK to discard, then --force).
yes

cleanup complete
Evidence: Scout edge-case transcript

Shows fm-brief.sh accepting --scout before positional args and fm-teardown.sh treating legacy meta without kind= as ship-protected.

## Scout edge cases transcript

### fm-brief parses --scout before positional args
scaffolded: /Users/kunchen/.no-mistakes/worktrees/016d88035d58/01KTYK46X0ZFACSPFS8HBDMCKP/data/e2e-edge-brief/brief.md (scout; replace {TASK})
scout brief created with front-position flag: yes

### legacy meta without kind= defaults to ship protection
legacy meta contents:
window=firstmate:fm-e2e-legacy
worktree=/Users/kunchen/.no-mistakes/worktrees/016d88035d58/01KTYK46X0ZFACSPFS8HBDMCKP/.tmp-scout-edge-cases/project
project=/Users/kunchen/.no-mistakes/worktrees/016d88035d58/01KTYK46X0ZFACSPFS8HBDMCKP/.tmp-scout-edge-cases/project
harness=raw
legacy teardown refuses unpushed commit: REFUSED: worktree /Users/kunchen/.no-mistakes/worktrees/016d88035d58/01KTYK46X0ZFACSPFS8HBDMCKP/.tmp-scout-edge-cases/project has work not on any remote.
unpushed commits:
4d07e57 base
Push the branch (or get the captain's explicit OK to discard, then --force).
yes

cleanup complete

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 1 issue found → auto-fixed ✅
  • ⚠️ bin/fm-promote.sh:22 - The promoted task instructions tell firstmate to have the crewmate create fm/&lt;id&gt; from the current scout worktree state. Scout briefs explicitly allow arbitrary scratch edits and commits, so this can put exploratory work on the shipping branch unless promotion first requires an inventory/cleanup step or a reset/cherry-pick of only intended changes.

🔧 Fix: Require clean promotion handoff
✅ Re-checked - no issues remain.

✅ **Test** - passed

✅ No issues found.

  • Inspected changed files with git diff --name-only 8b6f11ad5518e345fd84e022d4caa0dbbabcbdee..45d4b1666643557641983374db58d046cad1c248 and read AGENTS.md, bin/fm-brief.sh, bin/fm-spawn.sh, bin/fm-teardown.sh, and bin/fm-promote.sh.
  • Ran an end-to-end scout lifecycle smoke using ./bin/fm-brief.sh e2e-scout .tmp-scout-lifecycle/project --scout, ./bin/fm-spawn.sh e2e-scout .tmp-scout-lifecycle/project &#34;sh -c &#39;sleep 300&#39;&#34; --scout, scratch commit creation in the treehouse worktree, missing-report teardown refusal, report creation, successful scout teardown, and ./bin/fm-promote.sh e2e-promote.
  • Ran edge-case smoke checks for ./bin/fm-brief.sh --scout e2e-edge-brief .tmp-scout-edge-cases/project and ./bin/fm-teardown.sh e2e-legacy with a legacy meta file lacking kind=.
  • Checked for leftover working-tree artifacts with git status --short plus glob checks for .tmp-scout-*, data/e2e-*, and state/e2e-*.
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

@kunchenguid
kunchenguid merged commit d3f8a1c into main Jun 12, 2026
3 checks passed
@kunchenguid
kunchenguid deleted the feat/scout-tasks branch June 12, 2026 19:34
vipentti pushed a commit to vipentti/firstmate that referenced this pull request Aug 5, 2026
* feat: scout tasks - delegate investigations and repros with report deliverables

* no-mistakes(review): Require clean promotion handoff

* no-mistakes(document): Sync scout task documentation
@kyokosawada

Copy link
Copy Markdown

Resolved. The middleman's surface settled as its four calls - greet, send, sendImage, press - plus the held /updates WebSocket stream carrying the fleet and a watched pane, with every failure surfaced as a typed Trouble. That shape was specced in #12 and is built and running on main. Closing as answered and superseded by #12.

notno referenced this pull request in nathan-rosquist/firstmate Sep 8, 2026
hooliooo pushed a commit to hooliooo/firstmate that referenced this pull request Sep 14, 2026
…r-report-compact (kunchenguid#7)

* fix(pr-report): repost findings for new attestations

* no-mistakes(document): document no-attestation skip in pr-report docstring

---------

Co-authored-by: johannesr <johannes.redgard@tuvsud.com>
hooliooo added a commit to hooliooo/firstmate that referenced this pull request Sep 14, 2026
…zation

Upstream PR kunchenguid#7 made the review-findings comment idempotence attestation-
round-aware: the comment carries a hidden attestation-head marker, a newer
attestation posts a new closed thread, and a legacy markerless comment does
not suppress the current round. Port that behavior into the CI-green
normalization design, reusing ATTESTATION_RE as the single owner of the
attestation pattern.
hooliooo added a commit to hooliooo/firstmate that referenced this pull request Sep 14, 2026
…zation

Upstream PR kunchenguid#7 made the review-findings comment idempotence attestation-
round-aware: the comment carries a hidden attestation-head marker, a newer
attestation posts a new closed thread, and a legacy markerless comment does
not suppress the current round. Port that behavior into the CI-green
normalization design, reusing ATTESTATION_RE as the single owner of the
attestation pattern.
cachemoney added a commit to cachemoney/firstmate that referenced this pull request Sep 18, 2026
NewAiCoder referenced this pull request in NewAiCoder/firstmate Sep 26, 2026
fix: sync fork main with upstream (55+ commits) via merge
@nissan

nissan commented Sep 28, 2026

Copy link
Copy Markdown

Completed/superseded on current main: the guard now emits the foreign-owner diagnostic on every stand-down, with repeated-stop and distinct-session regression coverage in tests/fm-turnend-guard.test.sh.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants