Skip to content

feat: add Devin CLI harness support - #1

Open
codeatspeed wants to merge 115 commits into
mainfrom
feat_add_devin
Open

feat: add Devin CLI harness support#1
codeatspeed wants to merge 115 commits into
mainfrom
feat_add_devin

Conversation

@codeatspeed

Copy link
Copy Markdown
Owner

Intent

Add Devin CLI as a fully supported and empirically verified Firstmate harness alongside Claude Code, Codex, Pi, OpenCode, and Grok. Support primary sessions, crewmates, scouts, and secondmates with detection, unattended permission and workspace-trust handling, model selection, compositional task-local hooks that preserve repository Devin configuration and safety hooks, process liveness, bounded foreground supervision, dispatch validation, teardown cleanup, documentation, and regression coverage. Use conservative foreground checkpoints because Devin background completion auto-wake behavior has not been verified. Preserve all fixes from prior no-mistakes review, test, documentation, and lint rounds.

What Changed

Captain, this branch:

  • Adds Devin CLI as a supported harness for primary sessions, crewmates, scouts, and secondmates, including detection, model selection, unattended launches, and liveness handling.
  • Integrates Devin safety and turn-end hooks while preserving user and repository configuration, with bounded foreground checkpoint supervision.
  • Documents Devin workflows and adds regression coverage for detection, spawning, configuration layering, hooks, supervision, and recovery behavior.

Risk Assessment

✅ Low: Captain, this is a bounded harness addition with documented config layering, consistent supervision behavior, cleanup and liveness integration, and focused regression coverage.

Testing

The successful full-suite baseline was supplemented with controlled CLI-level Devin validation covering detection, autonomous and trust-free spawning, model selection, task-hook composition without modifying user or repository configuration, safety-hook blocking, invalid-config recovery, foreground supervision, process liveness, and secondmate behavior; reviewer-visible transcripts were captured, no UI screenshot was applicable because this is a terminal-only integration, and all checks passed.

Evidence: Devin focused validation transcript
$ command -v devin
/Users/muralinunna/.local/bin/devin

$ bash tests/fm-devin-harness.test.sh
ok - fm-harness detects the verified Devin launch marker
ok - tracked Devin primary hooks wire both seatbelts and the turn-end guard
ok - tracked Devin PreToolUse adapter blocks unsafe watcher commands with stderr-only output
ok - fm-spawn composes user config with one task hook and leaves repository config native
ok - invalid Devin user configs leave endpoints and worktrees recoverable
ok - fm-lock recognizes Devin harness processes

$ bash tests/fm-supervision-instructions.test.sh
ok - renderer prints exactly the selected harness block
ok - renderer falls back to unknown.md for unverified harness names
ok - renderer includes read-only, afk, and effective x-mode current-state stanzas
ok - renderer repair-line mode is harness-aware and honors conditional state
ok - grok supervision is Claude-shaped background notify with passive Stop-hook backstop
ok - grok rendered command sources the effective x-mode config
ok - devin supervision uses bounded foreground checkpoints
ok - pi supervision snippet renders the effective extension path

$ bash tests/fm-secondmate-liveness.test.sh
ok - fm_backend_tmux_agent_alive: alive/dead/unknown classification
ok - fm_backend_herdr_agent_alive: dead/no-agent->dead, live->alive, unknown->unknown
ok - fm_backend_agent_alive: routes tmux/herdr correctly, unknown for an unverified backend
ok - sweep: a confirmed-dead secondmate endpoint is killed and respawned
ok - sweep: an already-live secondmate is left untouched (no kill, no respawn)
ok - sweep: a transient/unknown probe reading is reported but never acted on
ok - sweep: an unverified harness makes a dead-looking probe inconclusive
ok - sweep: idempotent by construction - a live secondmate is never re-touched on a later run
ok - sweep: skipped entirely under FM_BOOTSTRAP_DETECT_ONLY=1, exactly like the other mutating sweeps
ok - sweep: a silent no-op with no kind=secondmate meta present (a secondmate home's own natural scoping)
# all fm-secondmate-liveness tests passed
Evidence: Rendered Devin user-facing supervision and hook configuration
$ DEVIN_CLI=1 bin/fm-harness.sh
devin

$ FM_CODEX_WATCH_CHECKPOINT=7 bin/fm-supervision-instructions.sh --harness devin
================================================================================
SUPERVISION OPERATING INSTRUCTIONS - primary harness: devin
================================================================================
Current state:
- Lock: held by this session; this session owns normal supervision unless away mode says otherwise.
- Away mode: inactive.
- X mode: inactive; use the default watcher cadence.
- After every handled wake, resume this emitted harness protocol instead of following a hardcoded background-arm recipe.

Mode: Devin foreground checkpoint.

When this session owns supervision and away mode is not active:
1. Drain first with `bin/fm-wake-drain.sh`.
2. Source `/Users/muralinunna/.no-mistakes/worktrees/7a17be65de34/01KXF7YEPHGNP1MSHEVT0G6BAH/config/x-mode.env` first when X mode is active.
3. Run `bin/fm-watch-checkpoint.sh --seconds 7` as one foreground tool call.
4. Never bundle the checkpoint with unrelated commands.
5. Never use shell `&` for watcher supervision.
   A shell `&`, a truncating pipe, or bundling is denied automatically by the PreToolUse seatbelt registered in `.devin/config.json`.
6. When the checkpoint returns with `signal:`, `stale:`, `check:`, or `heartbeat`, drain queued wakes, handle them, then run one fresh checkpoint.
7. A timeout is only a bounded control return.
   If work remains in flight, run another checkpoint after handling user input and queued wakes.
8. Treat any failed checkpoint as an alarm and repair it before ending the turn.
9. Do not send idle progress while a checkpoint is running.

Devin has no verified background-task completion wake contract in Firstmate.
The bounded foreground checkpoint is the conservative supported mechanism, matching Codex's supervision shape while retaining Devin's native blocking Stop-hook backstop.


$ jq primary Devin hook summary
{
  "pretool_matcher": "exec",
  "pretool_commands": [
    "bash -lc 'root=$(pwd -P); [ -f \"$root/.devin/config.json\" ] && [ -x \"$root/bin/fm-arm-pretool-check.sh\" ] || exit 0; exec \"$root/bin/fm-arm-pretool-check.sh\" --claude'",
    "bash -lc 'root=$(pwd -P); [ -f \"$root/.devin/config.json\" ] && [ -x \"$root/bin/fm-cd-pretool-check.sh\" ] || exit 0; exec \"$root/bin/fm-cd-pretool-check.sh\" --claude'"
  ],
  "stop_command": "bash -lc 'root=$(pwd -P); [ -f \"$root/.devin/config.json\" ] && [ -x \"$root/bin/fm-turnend-guard.sh\" ] || exit 0; exec \"$root/bin/fm-turnend-guard.sh\"'"
}
- Outcome: 🔧 1 issue found → auto-fixed (2) ✅ across 3 runs (58m2s)

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 1 issue found → auto-fixed (2) ✅
  • 🚨 bin/fm-spawn.sh:1057 - Captain, devin --config overrides Devin’s user configuration, but the generated task config contains only the repository config plus Firstmate’s Stop hook. Every Devin crewmate can therefore lose user-level settings/hooks, while the repository config may also be applied twice because Devin loads it automatically. Confirm the CLI’s layering behavior and preserve both native config layers without duplication before merging.

🔧 Fix: Captain, preserve Devin config layering
1 warning still open:

  • ⚠️ docs/supervision-protocols/devin.md:6 - The Devin session-start protocol hardcodes a 180-second checkpoint, while Devin's repair path uses FM_CODEX_WATCH_CHECKPOINT. When overridden, the same session receives contradictory supervision commands. Parameterize the rendered Devin snippet like Codex, or introduce a Devin-specific setting and use it consistently.

🔧 Fix: Captain, align Devin checkpoint override rendering
✅ Re-checked - no issues remain.

🔧 **Test** - 1 issue found → auto-fixed (2) ✅
  • 🚨 tests failed with exit code 1
  • command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; for t in tests/*.test.sh; do echo "== $t =="; bash "$t" || rc=1; done; exit "$rc"

🔧 Fix: Captain, preserve Herdr lab failure status
1 error still open:

  • 🚨 tests failed with exit code 1
  • command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; for t in tests/*.test.sh; do echo "== $t =="; bash "$t" || rc=1; done; exit "$rc"

🔧 Fix: Captain, release watcher lock on checkpoint timeout
✅ Re-checked - no issues remain.

  • command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; for t in tests/*.test.sh; do echo "== $t =="; bash "$t" || rc=1; done; exit "$rc"
  • Baseline previously passed: command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; for t in tests/*.test.sh; do echo "== $t =="; bash "$t" || rc=1; done; exit "$rc"
  • command -v devin
  • bash tests/fm-devin-harness.test.sh
  • bash tests/fm-supervision-instructions.test.sh
  • bash tests/fm-secondmate-liveness.test.sh
  • DEVIN_CLI=1 bin/fm-harness.sh
  • FM_CODEX_WATCH_CHECKPOINT=7 bin/fm-supervision-instructions.sh --harness devin
  • Inspected primary Devin hook wiring with jq against .devin/config.json
  • git status --short
✅ **Document** - passed

✅ No issues found.

⚠️ **Lint** - 1 warning
  • ⚠️ linter found issues (exit code 127)

🔧 Fix: Captain: verify clean ShellCheck lint
1 warning still open:

  • ⚠️ linter found issues (exit code 127)

🔧 Fix: Captain, ShellCheck unavailable; no source changes made
1 warning still open:

  • ⚠️ linter found issues (exit code 127)

🔧 Fix: Captain: lint blocked by missing ShellCheck 0.11.0
1 warning still open:

  • ⚠️ linter found issues (exit code 127)
✅ **Push** - passed

✅ No issues found.

kunchenguid and others added 2 commits July 13, 2026 14:20
…id#533)

* fix: preserve secondmate routing markers

* no-mistakes(review): Captain, preserve trailing newlines in marked secondmate sends

* no-mistakes(test): Captain, tolerate bootstrap timeout elapsed drift

* no-mistakes(document): Refresh Herdr marker documentation
* fix: align grok effort docs and spawn with 0.2.99 ceiling

grok 0.2.99 accepts only low|medium|high for --reasoning-effort and
rejects both xhigh and max. Omit unsupported values on spawn, flag them
in crew-dispatch validation, and update harness-adapters.

* no-mistakes(test): Captain: refresh gotmp teardown fixture dependencies

* no-mistakes(document): Clarify Grok effort documentation ownership
kunchenguid and others added 5 commits July 14, 2026 02:47
…#555)

* fix: make bearings use secondmate home state

* test: anonymize bearings fixtures

* no-mistakes(review): Bound parent activity evidence scans, captain

* no-mistakes(review): Preserve structured secondmate authority and bounds, captain

* no-mistakes(review): Preserve registry completeness and child inventory, captain

* no-mistakes(review): Reconcile parent evidence by verb and key, captain

* no-mistakes(review): Treat unkeyed parent evidence as inconclusive, captain

* no-mistakes(document): Document bearings local snapshot and PR opt-in

* no-mistakes(lint): Fix fleet snapshot ShellCheck findings

* no-mistakes: apply CI fixes
* fix: restore stock macOS snapshot parsing

* no-mistakes(document): Clarify Linux gate and macOS CI coverage
…d#587)

* fix: close away-mode blocker supervision gap

* no-mistakes(review): Gate teardown retries and verify U+2063 dedupe

* no-mistakes(test): Fail closed on incomplete Pi composer separators

* no-mistakes(document): Document Pi composer recognition and return gating
* support Pi max thinking profiles

* no-mistakes(review): Captain, allow Pi max dispatch profiles
…nguid#595)

* Clarify validation response ownership

* no-mistakes(document): Clarify yolo response ownership
* Add instruction owners foundation

* no-mistakes(document): Refresh project-management owner pointers
…kunchenguid#626)

* docs: compress firstmate operating contract

* docs: make delivery rigor single-owner

PR B already removed personal and stacked review requirements, but it did not explicitly assign rigor to the selected delivery path or forbid risk-based manual clean gates. That gap still permitted the Hi Bit inversion.

* no-mistakes(review): Honor configured merge authority across faster delivery paths

* no-mistakes(document): Align docs with compressed operating contract
* Add durable captain decision holds

* no-mistakes(review): Validate decision hold retries and origin paths

* no-mistakes(review): Enforce durable decision lifecycle boundaries

* no-mistakes(review): Harden decision display and partial retry recovery

* no-mistakes(test): Update scout teardown fixtures for decision inventory

* no-mistakes(document): Align decision lifecycle and scout teardown documentation

* no-mistakes: apply CI fixes

* no-mistakes(review): Reconcile terminal decision holds

* no-mistakes(document): Align captain decision-hold documentation
* fix: harden PR check artifacts

* fix: close PR check migration gaps

* fix: close PR check retry gaps

* fix: clarify migration outcomes and ESM boundary

* fix: keep failed migrations authoritative

* test: use inert PR validation fixtures

* no-mistakes(review): Reserve noncanonical PR quarantine namespace

* no-mistakes(review): Prevalidate final PR-check teardown artifacts

* no-mistakes(review): Preserve X metadata and validate teardown IDs

* no-mistakes(review): Initialize migration state before watcher exclusion

* no-mistakes(review): Isolate failed poll migrations from bootstrap recovery

* no-mistakes(review): Allow safe polling during incomplete private repairs

* no-mistakes(review): Authenticate watcher checks at execution time

* no-mistakes(review): Preserve custom checks with hash-bound registration

* no-mistakes(review): Clean custom check snapshots on watcher signals

* no-mistakes(review): Stop watcher checks promptly on signals

* no-mistakes(review): Terminate watcher check groups before cleanup

* no-mistakes(document): Correct stale X-mode watcher documentation

* fix: drain returned watcher check groups

* no-mistakes(review): Harden quarantine links and recover validated replacement polls

* no-mistakes(review): Preserve X mode across shim version transitions

* no-mistakes(review): Refresh legacy X shims before marker short-circuits

* no-mistakes(document): Correct persisted PR-check artifact documentation

* no-mistakes(document): Correct stale PR-check documentation

* fix: bind PR poll repair provenance

* no-mistakes(review): Enforce single-link ownership for custom check artifacts

* no-mistakes(review): Preserve private checks, X polling, and lifecycle IDs

* no-mistakes(review): Separate task creation and legacy teardown validation

* no-mistakes(review): Restore safe legacy operations and teardown validation

* no-mistakes(review): Disambiguate migration obligations and preserve legacy retries

* no-mistakes(review): Preserve fail-closed diagnostics and legacy quarantine evidence

* no-mistakes(review): Reconcile legacy migration retries and teardown collisions

* no-mistakes(review): Force legacy namespace reconciliation before marker short-circuits

* no-mistakes(document): Document private poll artifact safety contracts

* no-mistakes(lint): Suppress intentional literal-dollar lint finding

* fix: migrate historical X poll identity

* fix: harden PR check artifacts

* no-mistakes(review): Preserve fail-closed diagnostics and legacy quarantine evidence

* no-mistakes(review): Reconcile legacy migration retries and teardown collisions

* fix: migrate historical X poll identity

* no-mistakes(review): Harden X-mode artifact publication against symlink corruption

* no-mistakes(review): Guard X artifact publication

* no-mistakes(review): Enforce private X artifact reads

* no-mistakes(test): Fix backend compatibility fixture dependencies

* no-mistakes(document): Refresh PR-check documentation

* no-mistakes(lint): Remove unused x-mode test locals

* no-mistakes: apply CI fixes
* fix: compact session-start backlog digest

* no-mistakes(test): Fix legacy backend fixture helper

* no-mistakes(test): Fix watcher exit wait helper

* no-mistakes(document): Document compact backlog digest
* fix: dedupe stale watcher guard banner

* no-mistakes(review): Keep read-only guard state nonmutating

* no-mistakes(document): Clarify stale watcher docs
* fix: balance bearings landed defaults

* no-mistakes(document): Document balanced landed baseline

* no-mistakes: apply CI fixes
* docs: clarify captain-facing translation contract

* no-mistakes(review): Restore runtime fallback mandate

* no-mistakes(document): Align Bearings translation wording
…#646)

* fix: make bootstrap nudges deterministic

* no-mistakes(review): Honor state override for bootstrap nudges

* no-mistakes(review): Update benign bootstrap documentation labels

* no-mistakes(review): Validate bootstrap nudge retry markers

* no-mistakes(document): Align bootstrap nudge documentation

* no-mistakes: apply CI fixes
…nchenguid#649)

* Clarify concise secondmate registry contract

* no-mistakes(review): Expand secondmate registry boilerplate coverage

* no-mistakes(document): Point route docs to owner
…kunchenguid#654)

* fix(bin): strip quotes on blocked_by in decision-hold resolve

tasks-axi quotes multi-entry blocked_by as "a,b,c", so the comma-boundary
membership test only matched middle elements. Strip surrounding quotes
before matching so first and last hold ids resolve correctly.

* no-mistakes(document): Refresh decision-hold regression evidence
* feat(secondmate): inherit shared captain preferences

* no-mistakes(review): Honor shared captain data overrides

* no-mistakes(review): Honor bootstrap data override registry

* no-mistakes(document): Refresh shared inheritance docs

* no-mistakes(document): Clarify inherited local-material docs
* feat(spawn): gate local agent secret injection

* fix(spawn): align final Keychain slot

* no-mistakes: apply CI fixes
* test: isolate herdr autodetect smoke session

* no-mistakes(review): Restored autodetect smoke gate bypass

* no-mistakes(test): Harden Herdr lab provisioning

* no-mistakes(document): Refresh Herdr lab docs
* fix(pi): distinguish stale locks when arming watcher

* no-mistakes(test): Stabilize watcher extension async waits

* no-mistakes(document): Document Pi lock recovery
* fix: accept secondmate as house vocabulary

* no-mistakes(test): Update captain vocabulary contract test

* no-mistakes(document): Align secondmate documentation vocabulary
…uid#686)

* fix: parse secondmate home after pre-field parentheses

Registry summaries often include parentheticals before the structured
(home: ...) field. Match that field with a greedy prefix so handoff
no longer reports "has no home" for those entries.

* no-mistakes(document): Refresh handoff test comments
* feat: add native session-start nudges

* no-mistakes(document): Document nudge script inventory
…nguid#688)

Relabel absent-captain and related domain defaults wording so it names
the firstmate repo rather than treating "template" as this domain's
identity label. Keep the design-tenet "shared template" statements and
unrelated launch/PR-poll template uses unchanged.
kunchenguid and others added 29 commits July 25, 2026 18:12
…unchenguid#1049)

* fix(tmux): scope Claude busy detection by harness

* no-mistakes(review): Separate verified and fallback busy signatures

* no-mistakes(test): Scope busy signatures to supplied harnesses

* no-mistakes(document): Document harness-scoped busy detection
* Add verified Kimi crewmate harness adapter

* no-mistakes(review): Scope Kimi moon detection to spinner lines

* no-mistakes(review): Match only complete Kimi spinner rows

* no-mistakes(review): Resolve Kimi binary portably before pane creation

* no-mistakes(document): Align Kimi adapter documentation

* no-mistakes(lint): Suppress false-positive ShellCheck warning for sourced watcher override

* Fix Kimi busy spinner detection

* no-mistakes(review): Recognize Kimi session-lock ancestry and holders

* no-mistakes(review): Scope pending-reply Kimi busy detection by harness

* no-mistakes(document): Correct Kimi spinner capture documentation

* no-mistakes(document): Clarify optional Kimi spinner whitespace

* no-mistakes(lint): Silence intentional pending-reply test stub warnings

* test: align rebased Kimi busy fixtures

* no-mistakes: apply CI fixes

* Reconcile Kimi busy detection after per-harness scoping

* no-mistakes(review): Clarify observed Kimi spinner whitespace contract

* no-mistakes(document): Clarify Kimi harness documentation
* fix kimi pointer submission and spinner conformance

* no-mistakes(review): Preserve Kimi submit target ownership guard
* Add guarded Kimi turn-end hook

* no-mistakes(review): Require jq before installing Kimi turn-end hook

* no-mistakes(review): Expose jq inside isolated Kimi test fixtures

* no-mistakes(review): Preserve Kimi config boundaries during hook removal

* no-mistakes(review): Document Kimi removal newline safeguard

* no-mistakes(document): Document Kimi shared-home preservation
)

* Fix structural tmux composer reading

* Verify Calm compatibility with Pi 0.82

* no-mistakes(review): Harden structural composer classification boundaries

* no-mistakes(review): Refresh composer and Kimi regression fixtures

* no-mistakes(review): Fail closed on unbounded composer edges

* no-mistakes(review): Enforce aligned composer geometry safely

* no-mistakes(review): Make composer ambiguity locale-safe

* no-mistakes(review): Preserve ambiguity through composer submission

* no-mistakes(review): Carry composer proof through retries

* no-mistakes(document): Document structural tmux composer delivery guarantees

* no-mistakes: apply CI fixes
* feat: add verified pi-signed adapter

* no-mistakes(review): Correct pi-signed maintainer verification date

* no-mistakes(review): Correct remaining pi-signed verification dates

* no-mistakes(review): Preserve authoritative pi-signed runtime identity

* no-mistakes(document): Document pi-signed shared adapter semantics

* no-mistakes: apply CI fixes
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.