English | Français
One harness for Claude Code, OpenCode, and Cursor. Formerly settings-opencode; that URL redirects here. You install one variant. Monolith is the default. Conductor is opt-in. Skills are one shared tree either way.
MIT licensed. Fork it. The tree moves with the workflow, so treat it as a living reference.
Un harness pour Claude Code, OpenCode et Cursor. Anciennement settings-opencode. Monolith est le défaut, Conductor est opt-in. Les schémas sont en anglais et partagés. Choisir une variante et Comment une demande avance reprennent le même choix en français. L'installation est dans Public install.
Open the comparison (one HTML file, no network). La même page en français, plus bas.
Three hosts, one install tree:
| Host | Where it lands |
|---|---|
| OpenCode | ~/.config/opencode/. Hub file: opencode.jsonc. Entry: install.sh or bootstrap.sh. |
| Claude Code | Optional ~/.claude/ mirror: settings, hooks, rules, agents, synced skills. Same variant as OpenCode when you install both. |
| Cursor | Plugin fmflurry-harness via install-cursor.sh. Version 0.4.36 in scripts/cursor-plugin/config.json. Agents are marked readonly or not. This host has no per-agent write allowlist. |
Monolith is variants/monolith/. These install it when you omit the variant: ./install.sh --yes, ./install.sh --local, bootstrap.ps1, settings-sync, and ./install-cursor.sh. install.sh copies the Conductor tree, then scripts/variants/apply-monolith.mjs overlays the lean roster onto that copy. The source checkout stays as it is.
The primary agent writes, plans, and implements in the same session. Nothing has to run before the first edit. /orchestrate loads the conductor skill and stays optional.
Nine agents are installed, for review and noisy output: code-reviewer, security-reviewer, database-reviewer, ecosystem-auditor, e2e-runner, why-investigator, build-error-resolver, cop, comment-judge. Folded roles are skills (planner, coder, tdd, git-workflow, writer, and the rest named in variants/monolith/AGENTS.md). Live Postgres goes to database-reviewer or the main agent. The installed roster leaves out postgres-dba.
Conductor is the repository root: .claude/, opencode.jsonc, prompts/agents/, instructions/. variants/conductor/manifest.json sets "default": true because that root is the Conductor source. Installers still select Monolith when the variant is omitted. Choose Conductor with ./install.sh conductor, ./install-cursor.sh --variant conductor, or the alias orchestration.
A read-only conductor routes every change. In opencode.jsonc its write and edit tools are off, and the Task allowlist names every legal specialist. instructions/subagent-routing.md is the first-tool gate: when a specialist matches, the first tool call is that Task. Before coder, writer, or tdd-guide, the conductor emits the 6-field brief (brief-contract). The roster is 1 conductor plus 25 specialists: 26 files in prompts/agents/ and 26 in .claude/agents/.
planner → (tdd-guide → coder) or coder → code-reviewer → verify → git-specialist
On Cursor, the same conductor agent is marked readonly (scripts/cursor-plugin/lib.mjs). Delegation on that host is the readonly mark plus the prompt.
Switching variants removes the other variant's agents, commands, and rules. Returning to Conductor runs scripts/variants/prune-foreign.mjs.
| Monolith | Conductor | |
|---|---|---|
| Who writes application code | The primary agent, through skills such as coder and tdd |
Writable specialists (coder, writer, tdd-guide, and the other writable names in instructions/subagent-routing.md) |
| Who coordinates | The primary agent. /orchestrate is optional |
The conductor agent |
| Installed agents | 9 | 26 (conductor + 25) |
| Skills | Shared skills/ tree |
Shared skills/ tree |
| Source in this repo | Overlay variants/monolith/ on the install copy |
Repository root. "default": true marks that source |
| Install | ./install.sh --yes, ./install.sh --local, ./install-cursor.sh |
./install.sh conductor, ./install-cursor.sh --variant conductor. orchestration is an alias |
./install.sh # interactive; default Monolith
./install.sh --yes # Monolith on OpenCode + Claude Code
./install.sh conductor # Conductor on OpenCode + Claude Code
./install.sh monolith
./install.sh --local # project files; default Monolith
./install.sh --variant orchestration # alias of Conductor
./install-cursor.sh # Cursor plugin, default Monolith
./install-cursor.sh --variant conductorWindows: bootstrap.ps1 with no variant is Monolith. bootstrap.ps1 conductor selects Conductor. orchestration is the same alias.
Monolith est le défaut : ./install.sh --yes, ./install.sh --local, bootstrap.ps1, settings-sync, ./install-cursor.sh. L'agent principal écrit, planifie et implémente. Neuf agents restent pour la revue et la sortie bruyante. Les rôles repliés sont des skills, listés dans variants/monolith/AGENTS.md. /orchestrate charge le skill conductor et reste optionnel. Postgres en direct va à database-reviewer ou à l'agent principal.
Conductor se choisit avec ./install.sh conductor ou ./install-cursor.sh --variant conductor. orchestration est un alias. Le conducteur route chaque changement. Le roster fait 1 conducteur + 25 spécialistes. variants/conductor/manifest.json porte "default": true parce que la racine du dépôt est l'arbre source Conductor. Les installeurs choisissent Monolith quand la variante est omise.
Le schéma au-dessus et la page HTML montrent les trois hôtes et le tableau des différences. Changer de variante retire les agents, commandes et règles de l'autre.
Open the statechart. Visual vocabulary adapted from @poteto's /statechart in backnotprop/pstack (MIT · Lauren Tan).
The rails are the same on OpenCode, Claude Code, and Cursor. The fork is the variant. Conductor routes, and a writable specialist edits. Monolith writes in the main session and spawns a specialist for review, parallel fan-out, or noisy output. After a source edit, the verification gate wants the project build, lint, and the tests that cover the change, with the real output pasted. Two failed fix passes on the same error stop. Independent review is code-reviewer and security-reviewer, plus cop or the stack reviewer when it applies. A confirmed Important finding blocks. Nit and Pre-existing do not. An interactive run stops when the PR is open. /ship continues through CI and merges only with agent-harness ship-merge.
The chart leaves out hook internals and the full /ship retry loop. Those are shared once review has passed. The contract is Autonomous mode and Mode autonome.
Shared on both variants and all three hosts:
- Verification gate. "Done" waits on fresh command output.
- Tool budget. Verification commands are uncapped. Exploratory shell is budgeted.
- Secret-file guard, autonomy and
/ship, worktree destruction safety, and a PR visual report underdocs/pr-reports/. - KPI journal at
~/.agent-harness/kpi/events.jsonl. - CodeMemory when it is on. Cloud and remote sessions skip it unless
FMFLURRY_CODEMEMORY=on.
Mêmes rails sur OpenCode, Claude Code et Cursor. Conductor délègue. Monolith écrit dans la session principale. Le schéma et la page HTML suivent la demande : routage ou écriture, porte de vérification, revue, PR, ou escalade vers vous. Le vocabulaire visuel est adapté de /statechart de @poteto dans backnotprop/pstack (MIT, Lauren Tan).
Open the statechart. Visual vocabulary adapted from @poteto's /statechart in backnotprop/pstack (MIT · Lauren Tan).
The chart follows a Monolith install. Control flow lives in the gates, not in the prompt. On OpenCode the secret guard, the git guard, and the tool budget are plugins. On Claude Code the git guard and the tool budget are hooks, and the secret guard is the permissions.deny list in .claude/settings.json, which covers Write and Edit only. The subagent allow-list is the permission.task block in opencode.jsonc. Autonomy state lives in .claude/state/. A hard gate denies and the model reroutes. A soft gate only steers. Autonomous mode adds the goal lifecycle: one worktree, one branch, one goal file, and a stop gate that blocks until the PR merges or the run escalates. The last panel lists three places where the config holds together in theory and slips in practice.
Le schéma suit une installation Monolith. Avec la page HTML, il suit une session entière : démarrage, appel d'outil, arrêt, puis le cycle d'un objectif en mode autonome. Les gardes décident. Un garde dur refuse et le modèle change de route. Un garde souple ne fait qu'aiguiller. Le vocabulaire visuel est adapté de /statechart de @poteto dans backnotprop/pstack (MIT, Lauren Tan).
- Variants · Choisir une variante
- How a request moves · Comment une demande avance
- The harness as a state machine · Le harness comme machine à états
- Public install
- Measure the variants · Mesurer les variantes
- What's inside
- English — recent changes, layout, Conductor mechanics, catalogs, autonomous mode
- Français — mode autonome
The repo is designed to merge into ~/.config/opencode/, plus an optional ~/.claude/ mirror. There are three paths: a one-line install (recommended — nothing to clone by hand), a one-shot script if you already have the repo, and a manual walk-through if you want to see every step.
You don't need to clone anything first. The command below downloads harness-manifesto. bootstrap.sh still clones https://github.com/fmflurry/settings-opencode.git (that URL redirects here) into ~/.local/share/settings-opencode (override with SETTINGS_OPENCODE_SRC), then runs the installer. That directory name, and the shell-rc fence # >>> settings-opencode >>>, are still what bootstrap.sh and install.sh write. Re-running the exact same command is also how you update — it pulls the latest and re-applies it.
macOS / Linux / WSL (bash):
curl -fsSL https://raw.githubusercontent.com/fmflurry/harness-manifesto/master/bootstrap.sh | bashOn WSL it installs to the Windows side (/mnt/c/Users/<you>/.config/opencode), matching install.sh's WSL behaviour. Pass installer flags through after -s --:
curl -fsSL https://raw.githubusercontent.com/fmflurry/harness-manifesto/master/bootstrap.sh | bash -s -- --local
curl -fsSL https://raw.githubusercontent.com/fmflurry/harness-manifesto/master/bootstrap.sh | bash -s -- --no-claude
curl -fsSL https://raw.githubusercontent.com/fmflurry/harness-manifesto/master/bootstrap.sh | bash -s -- --uninstallNative Windows (PowerShell — no WSL):
irm https://raw.githubusercontent.com/fmflurry/harness-manifesto/master/bootstrap.ps1 | iexMerges into %USERPROFILE%\.config\opencode and \.claude, runs npm install (or bun install), and writes the OPENCODE_* defaults as persistent User environment variables. Open a new terminal afterwards so they take effect. Variants:
# project-scoped install
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/fmflurry/harness-manifesto/master/bootstrap.ps1))) -Local
# skip the Claude mirror
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/fmflurry/harness-manifesto/master/bootstrap.ps1))) -NoClaude
# skip OpenCode (install Claude only)
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/fmflurry/harness-manifesto/master/bootstrap.ps1))) -NoOpencode
# uninstall (removes the OPENCODE_* env vars; leaves copied config in place)
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/fmflurry/harness-manifesto/master/bootstrap.ps1))) -Uninstall- macOS, Linux, WSL, or native Windows.
- OpenCode CLI installed and on your
PATH(unless installing Claude Code only via--no-opencode). - Claude Code installed if you want the
.claude/mirror (unless skipped via--no-claude). - Either Bun (recommended —
bun.lockis what's checked in) or Node.js >=22.6 withnpm. git.
This repo stores no API keys. If you use the myMistral provider in opencode.jsonc, set MISTRAL_API_KEY by:
- Copying
.env.example→.envand filling in your key, OR - Exporting
MISTRAL_API_KEYin your shell rc.
Other providers (Anthropic, OpenAI, GitHub Copilot, OpenCode Go) need their own keys set the same way if you select their profiles. All local .env* files are git-ignored; only .env.example is tracked.
Already have the repo cloned? Run the installer directly:
git clone https://github.com/fmflurry/harness-manifesto.git ~/Workspace/harness-manifesto
cd ~/Workspace/harness-manifesto
./install.shinstall.sh is interactive by default. It asks which harness to install (Claude Code, OpenCode, or both), which variant (Conductor or Monolith), and whether the scope is global or local. The variant question comes first. Monolith is the default. conductor selects Conductor:
- Verify your prerequisites (
git,bun/npm). - OpenCode (if selected): merge repo files into
~/.config/opencode(or./.opencodeif--local) without removing existing user config. - Run
bun install(ornpm ciif Bun isn't available). - Sync skills from the canonical set into both harnesses via
scripts/sync-skills.sh. - Seed personal config files (
settings.json,settings.local.json,policy-limits.json) only on first install; preserve user edits on reinstall. - Write a marker-fenced shell block that records
SETTINGS_OPENCODE_REPO(OpenCode only, skipped if--local). A re-run replaces the block and drops retiredOPENCODE_MODEL_*andOPENCODE_REASONING_*exports. The block does not set a model. - Claude Code (if selected): merge
.claude/into~/.claude(or./.claudeif--local). - Print a smoke-test command and the locations to tweak afterwards.
Useful flags:
| Flag | Behaviour |
|---|---|
| (none) | Interactive walk-through: prompt [Y/n] for OpenCode (default Y) and Claude Code (default Y). |
--yes, -y |
Non-interactive — accept all defaults: OpenCode ✓, Claude Code ✓. Monolith is the default, including a global install. Existing normal directories are merged, not removed or backed up. |
--variant |
monolith (default) or conductor. orchestration is an alias of conductor. Same as HARNESS_VARIANT. The flag wins over the env. With neither set, Monolith is the default, including global --yes. conductor selects Conductor. |
--status |
Print the installed variant for OpenCode and Claude Code, then exit. --local also prints ./.cursor, ./.agents, the .harness-local overlay, exclude entries, and domain-rules state. A marker of orchestration is reported as Conductor. |
--local |
Project-scoped install into the current directory (./.opencode, ./.claude as independent siblings) and vendors ./AGENTS.md, ./.cursor/rules, and ./.agents. Applies .harness-local/ on top and prunes .harness-local/exclude. Skips the global shell-rc env block and prints the repo-path block instead. That block does not set a model. Default variant is Monolith. |
--opencode |
Allow-list: install OpenCode only (if combined with other flags, only those are installed). |
--claude |
Allow-list: install Claude Code only. |
--no-opencode |
Deny: skip OpenCode entirely (repo copy, deps, and env block). Can be combined with other targets. |
--no-claude |
Deny: skip the Claude Code mirror. Can be combined with other targets. |
--uninstall |
Remove the env-var block and optionally remove copied local/global dirs after confirmation. Never deletes the cloned repo or your data without confirmation. |
--help, -h |
Print usage. |
Conductor is the conductor-led tree at the repo root. Monolith (variants/monolith/) is a lean overlay applied to the install copy: the primary agent writes, /orchestrate is optional, and OpenCode and Claude Code get the same roster. Skills stay one shared tree. ./install.sh --yes with no variant installs Monolith. install-cursor.sh builds that Monolith plugin unless --variant conductor or HARNESS_VARIANT=conductor is set. ./install.sh --local vendors the same variant into the project. ./install.sh conductor and ./install.sh monolith switch without the menu and remove the other variant's leftovers.
./install.sh --local (Conductor or Monolith) reads a project-owned directory and never creates, edits, or deletes it. A symlink such as macOS /tmp still applies that overlay, and a skipped root prints why. Local settings record ./.claude/mods/autonomy-status. Monolith records .opencode/instructions/monolith.md. Layout, exclude format, and the off-by-default domain-rules hook are in docs/harness-local.md.
.harness-local/exclude # skill ids and harness paths to prune
.harness-local/domain-rules.json # {"enabled": false, "script": "scripts/check-domain-rules.sh"}
.harness-local/AGENTS.md # wins over the vendored AGENTS.md
.harness-local/.claude/ # copied onto ./.claude
.harness-local/.opencode/ # copied onto ./.opencode
.harness-local/.cursor/ # copied onto ./.cursor
.harness-local/.agents/ # copied onto ./.agents
A line in exclude that is a skill id (angular-ddd or skills/angular-ddd) is removed from .claude/skills/, .opencode/skills/, and .agents/skills/ on every run. ./install.sh --local --status prints the overlay and the exclude list. The domain-rules hook does nothing until domain-rules.json sets "enabled": true.
./install.sh conductor
./install.sh monolith
./install.sh --status
./install.sh --variant orchestration
HARNESS_VARIANT=monolith ./install.sh --yesThe script writes a fenced block to your shell rc (~/.zshrc, ~/.bashrc, or ~/.config/fish/config.fish) that looks like this:
# >>> settings-opencode >>>
# Added by settings-opencode installer.
# To remove this block, run: settings-sync --uninstall
# OpenCode agents inherit the session model. This block does not set one.
export SETTINGS_OPENCODE_REPO="/path/to/harness-manifesto"
# <<< settings-opencode <<<Re-running ./install.sh rewrites the block. ./install.sh --uninstall removes it. OpenCode does not read a model from it.
If your shell isn't bash/zsh/fish, the script prints the env block for you to paste manually and continues with the rest of the install.
Click to expand the step-by-step manual walk-through (same outcome as the script).
OpenCode loads ~/.config/opencode/opencode.jsonc at startup. Keep the repo wherever you like, then copy it additively into the config dir.
# Clone
git clone https://github.com/fmflurry/harness-manifesto.git ~/Workspace/harness-manifesto
mkdir -p ~/.config/opencode
rsync -a --exclude node_modules --exclude .git ~/Workspace/harness-manifesto/ ~/.config/opencode/
cd ~/.config/opencodebun install # uses bun.lock
# or
npm ciThe harness does not set an OpenCode model. A primary agent with no model uses the model selected for the session, or your OpenCode default. A subagent with no model uses the model of the agent that invoked it. See OpenCode agents.
To pin one agent, set model on that agent in your own OpenCode config. Do not expect OPENCODE_MODEL_* or OPENCODE_REASONING_*. The installer no longer writes them, and opencode.jsonc never interpolated the reasoning variables. The myMistral block remains a provider definition. Nothing selects it unless you do.
opencode.jsonc declares six MCP servers: one enabled by default (code-memory) and five disabled (context7, blender, wallaby, Figma, smartbear-swagger). CodeMemory is strongly recommended — the codebase-exploration skill routes repo orientation through it before falling back to grep/read. The others are optional but documented here so you know what you're opting into.
| Server | Install | Status |
|---|---|---|
| code-memory | uvx --from flurryx-code-memory@latest code-memory-mcp (auto-installed on first use) |
Recommended. Enabled. Semantic repo orientation; code-memory_* tools are pre-allowlisted for every subagent. Pairs with the codebase-exploration skill. |
| context7 | nothing — npx -y @upstash/context7-mcp@latest |
Disabled by default. Live docs lookup. |
| blender | uv --directory $HOME/dev/blender_mcp/mcp run blender-mcp |
Disabled by default. Blender scene tooling; drives the gaudi agent when enabled. |
| wallaby | install Wallaby.js and run wallaby update-mcp |
Disabled by default. Runtime-test introspection. |
| Figma | remote — https://mcp.figma.com/mcp |
Disabled by default. Flip enabled: true and set up Figma MCP for design-system tools. |
| smartbear-swagger | remote — https://swagger.mcp.smartbear.com/mcp |
Disabled by default. OpenAPI/Swagger tooling for api-spec-architect. |
The repo ships a .claude/ subtree. OpenCode and Claude Code can be installed separately and never nest inside one another.
Claude Code:
mkdir -p ~/.claude
rsync -a ~/.config/opencode/.claude/ ~/.claude/What this installs:
.claude/CLAUDE.md— global user instructions Claude Code reads on every session..claude/settings.json— permissions, hooks, env vars (API_TIMEOUT_MS, autocompact threshold, etc.), and"model": "opus"for the Claude Code main agent (Conductor and Monolith). Seeded on first install. Amodelvalue already in the file is left as written..claude/hooks/*.sh— pre-tool-use security warnings + stop hook..claude/rules/{common,typescript}/*.md— coding-style/testing/security rule packs..claude/commands/*.md— extra slash commands (/create-pull-request,/update-codemaps, and the Claude-only arena commands)..claude/skills/**— the skill mirror, synced from the canonical set byscripts/sync-skills.shon install.
opencodeYou should see:
- The panda banner shows up.
Then drop a slash command:
/plan add a TODO list to my homepage
On Conductor it dispatches the planner subagent and returns a plan. On Monolith, the install default, the same command loads the planner skill in the main session.
OpenCode uses the session model for every agent. Select it in OpenCode, or set your default in your own OpenCode config. To pin one agent, add model to that agent in your own config. This harness does not set one, and a reinstall does not put one back. See OpenCode agents. Claude Code reads .claude/settings.json. Cursor reads its tier files.
Claude Code: the main agent (the session default) is "model": "opus" in .claude/settings.json, for Conductor and Monolith. Subagent tiers stay as they are. A fresh global ~/.claude install and a fresh project .claude install both receive that alias. If model is already set, the installer leaves that value alone when it merges hooks.
Cursor: tier files stay Cursor models. This change does not edit ~/.cursor/rules/fmflurry-harness-models.mdc or ~/.agents/fmflurry-harness-models.md.
If you installed via the one-liner, re-run the exact same command — it pulls the latest and re-applies it:
# macOS / Linux / WSL
curl -fsSL https://raw.githubusercontent.com/fmflurry/harness-manifesto/master/bootstrap.sh | bash# native Windows
irm https://raw.githubusercontent.com/fmflurry/harness-manifesto/master/bootstrap.ps1 | iexIf you cloned the repo by hand instead:
cd ~/.config/opencode
git pull
./install.sh --yes # refreshes deps + env block; idempotent
# or, if you want to do it by hand:
# bun install (or: npm ci)If a new plugin shows up, OpenCode picks it up on the next restart. If an env var is added to opencode.jsonc, this README will mention it.
Conductor and Monolith share one local journal. OpenCode, Claude Code, and Cursor write the same events.
Session, stop, and subagent hooks, PreToolUse guards, PostToolUse, ship-stop-gate, and the review verdict append one JSON line to ~/.agent-harness/kpi/events.jsonl. AGENT_HARNESS_KPI_LOG changes the path. AGENT_HARNESS_KPI=0 turns writing off. Each line carries the variant from .harness-variant (orchestration counts as Conductor), the harness version, the host (opencode, claude, or cursor), the repo, the branch, the session, and the time. A Skill tool adds skill. A Task or Agent tool, and a subagent stop, add agent. tool_result carries tool_name, duration_ms, and ok. Tokens come from message.updated (OpenCode) or the stop transcript (Claude). Cursor leaves them null. The field list is docs/kpi-events.md. The journal has no prompt, no secret, and no absolute path.
agent-harness kpi report --since 30d --by variant
agent-harness kpi report --json
agent-harness kpi report --html > /tmp/kpi.html
agent-harness kpi feature
agent-harness kpi feature --pr 53 --jsonagent-harness kpi feature summarizes one branch (repo, branch, and the PR number once an event carries it): wall time, active time with gaps over 5 minutes removed, sessions per host, tools and skills, calls per agent (main and each subagent), failures and durations, guard blocks, review and fix rounds, and tokens when the host sent them (n/a otherwise). It writes docs/pr-reports/<slug>.metrics.json with no prompt, argument, or absolute path. Both variants run this before the PR report HTML. pr-report inserts a Metrics panel. pr-report-check warns when the metrics are missing or partial, and the visual check still passes.
The comparison table puts Conductor next to Monolith: tasks, tokens per task when known, duration, tool calls, review rounds per PR, first-pass CI, Important findings per PR, guard blocks, 7-day revert rate, time to merge. Counts are shown. Under 5 tasks or under 3 PRs the report says the sample is too small to conclude. PR columns come from read-only git and gh. If gh does not answer, those columns stay empty (--no-live skips the call).
agent-harness eval
agent-harness eval --run-modelagent-harness eval replays evals/tasks/*.yaml (bugfix, feature, refactor, test add, CI, docs, and the fix-ci skill trigger) in an isolated worktree and HOME, once per variant. The default mode calls no model: it checks the checkers and skill routing. --run-model requires AGENT_HARNESS_EVAL_CMD and runs one Cursor agent per task per variant (grok-4.7-medium, or AGENT_HARNESS_EVAL_MODEL). The shipped suite is 10 tasks × 2 variants, 20 sessions. Results join the same journal.
Conductor et Monolith s'observent avec le même journal. Le détail des champs est ci-dessus et dans docs/kpi-events.md. Les commandes sont les mêmes : agent-harness kpi report, agent-harness kpi feature, agent-harness eval.
Counts below were recounted from this tree on 2026-11-06. The agent, command, and skill catalogs further down are the Conductor source. Monolith installs 9 agents and the same skills/ tree.
Powered by CodeMemory
CodeMemory indexes the repo into files, symbols, and episodes. One
code-memory_codememory_retrievecall surfaces paths, symbols, and prior decisions.grepandreadrun afterwards for the exact lines.Episodes persist across sessions. The
codebase-explorationskill is the rule.code-memory_*tools are pre-allowlisted for the conductor and the specialist subagents in the Conductor tree. On Monolith the main agent and the installed reviewers use the same tools when CodeMemory is on. Cloud and remote agents skip it (docs/codememory-cloud.md).FMFLURRY_CODEMEMORY=onkeeps it on.
| Thing | Count | Notes |
|---|---|---|
| Agents (Conductor source) | 26 | 1 conductor + 25 specialists. build and plan overrides ship with "disable": true |
| Agents (Monolith install) | 9 | Review and noisy output. See Variants |
| Skills | 80 | skills/*/SKILL.md. skill-creator/ is git-ignored and outside this count |
| Command templates | 53 | commands/*.md. 37 pinned in the opencode.jsonc command block |
| Instructions loaded | 6 | The instructions array in opencode.jsonc. 13 files sit in instructions/. caveman-ultra.md is not in the array |
.claude rule files |
17 | 6 pathless under rules/common/, 6 path-scoped under rules/common/, 5 under rules/typescript/ |
| Hook scripts | 21 | .claude/hooks/*.sh |
| MCP servers | 6 | 1 enabled (code-memory), 5 disabled by default |
| Custom tool files | 4 | run-tests, check-coverage, security-audit, plus the index.ts barrel |
| TUI plugins | 2 | Enabled in tui.json: panda-banner, autonomy-status. caveman.tsx.disabled is not loaded |
Highlighted subagents. Full Conductor roster in Agents. On Monolith, names other than the nine installed agents are skills.
| Name | What it does | Why it's good |
|---|---|---|
conductor |
Primary orchestrator. write and edit denied on OpenCode |
Routing is in the permission block, and on Cursor the agent is readonly |
planner |
Turns requests into phased plans | Surfaces dependencies and risks before code is written |
coder |
Writes and edits source code | Application code stays inside a brief |
tdd-guide |
Drives test-first cycles | RED-GREEN-REFACTOR. Implementation goes to coder |
code-reviewer |
Reviews diffs before merge | Catches regressions and convention drift |
security-reviewer |
Audits auth, secrets, and input | Read-only findings. Fixes go to coder on Conductor, or to the main agent on Monolith |
git-specialist |
Sequences atomic commits and PRs | Cohesion-first splits, Conventional Commits |
scout |
Maps the repo before a dispatch | File manifests so briefs stay precise |
comment-judge |
Judges added comments by rubric | Flags false, stale, and noisy comments |
postgres-dba |
Live PostgreSQL diagnostics | Read-only advisory. Conductor only. Monolith uses database-reviewer or the main agent |
Highlighted skills. Full catalog in Skills.
| Name | What it does | Why it's good |
|---|---|---|
socratic-design |
Spikes a short question, otherwise asks one | Gates a decision before a plan |
caveman |
Ultra-terse replies | Keeps the technical content and spends fewer tokens |
verify-this |
Falsifiable verification of a claim | Green means fresh evidence |
blast-radius |
Traces what a change can break | Proves safety with real code |
why |
Cites design rationale from history | Searches source control and evidence MCPs in parallel |
chimera |
Runs parallel candidates, grafts the best | Avoids locking in the wrong shape early |
humanizer |
Strips AI tells from prose | Keeps writing sounding like a person wrote it |
test-behavior-not-implementation |
Detects tests that cannot fail | Catches mock-only and self-referential assertions |
show-your-work |
Keeps a per-decision log | Gives reviewers a trail for unattended runs |
fix-ci |
Finds failing checks and fixes them | Routes by failure type: build, test, or security |
config-sync |
Propagates harness config changes | Keeps the repo and the live directories in step |
openspec |
OpenSpec workflow, one skill | Propose, apply, archive, and the rest live under references/ |
Highlighted commands. Full list in Slash commands. On Monolith a folded agent name in a command is remapped: postgres-dba becomes database-reviewer, and every other folded name becomes main, which loads the matching skill (scripts/variants/dangling-agents.mjs).
| Name | What it does | Why it's good |
|---|---|---|
/plan |
Plan before code | On Conductor this dispatches planner. On Monolith it loads the planner skill |
/tdd |
Test-first cycle, or /tdd refactor to pin behavior |
Characterization tests pass immediately and stay frozen |
/cop-review |
Pre-merge review of the branch | Stack checklists, then lint |
/security |
Security audit of the change | Read-only findings |
/git |
Branch and commit operations | Keeps git work on the git rules |
/build-fix |
Resolves build and type errors | Loop until the build is green |
/orchestrate |
Multi-agent coordination | On Monolith this loads the conductor skill. It is optional |
/verify |
Verification loop | Checks the goal against concrete criteria |
/db-health |
Read-only PostgreSQL health check | Vacuum, wraparound, and connections. Conductor routes it to postgres-dba |
/api-spec |
Generates OpenAPI 3.1 specs | One spec per bounded context, Zalando-style |
These catalogs describe the Conductor source tree at the repo root, unless a line says Monolith. The install default is Monolith. The cross-host picture is One harness, two variants, three hosts and How a request moves. Conductor ships a read-only conductor and 25 specialists. Monolith keeps 9 review agents and folds the other roles into skills.
Shipped on master through fa50d8e (2026-10-18). The plugin number is version in scripts/cursor-plugin/config.json. History is scripts/cursor-plugin/CHANGELOG.md.
| PR | Plugin | What landed |
|---|---|---|
| #25 | 0.2.0 | Semver guard in scripts/cursor-plugin/check.mjs. A plugin-source change must carry a version strictly above the base. |
| #27 | 0.3.0 | CodeMemory stays off in cloud and remote sessions unless overridden. Ship review/fix rounds stop at 3. |
| #28 | 0.4.0 | Review findings are Important, Nit, or Pre-existing. Only Important blocks. The verdict is Approve or Block. |
| #29 | 0.4.1 | Enforcement ladder: code, then lint, tests, or static analysis, then a prose rule, then human review. |
| #30 | 0.4.2 | A project's REVIEW.md is the tag reference when it exists. The PR template adds Risk, How to revert, and Tier. |
| #32 | 0.4.3 | Always-applied Cursor rules drop from 21 files (1438 lines) to 7 files (502 lines). The rest load by path glob or by skill. |
| #33 | 0.4.4 | create-verification-skill writes a project verify-this override from the repository's build, test, and e2e commands. |
| #35 | 0.4.6 | socratic-design spikes a question a prototype under 30 minutes can settle, and presents that result. An L-sized task is restated in the agent's own words before planning. |
Semver (#25, policy note in #29). scripts/cursor-plugin/check.mjs diffs plugin sources against the merge-base with the base branch (origin/master, origin/$GITHUB_BASE_REF in GitHub Actions, or CURSOR_PLUGIN_BASE). The version must be MAJOR.MINOR.PATCH and strictly greater, and the changelog needs a heading for it. The build copies scripts/cursor-plugin/config.json into plugins/fmflurry-harness/.cursor-plugin/plugin.json. A root README.md edit is not a plugin source. #25 shipped that guard at 0.2.0, with patch, minor, and major as the suggested bumps. From 0.4.1, scripts/cursor-plugin/CHANGELOG.md says later plugin changes bump the patch only. The guard does not enforce that: it still accepts a minor or major bump, and it still prints those suggestions.
CodeMemory (#27). FMFLURRY_CODEMEMORY=on|off|auto wins. Unset, auto, or any other value detects. Detection order is in docs/codememory-cloud.md, implemented in plugins/code-memory-lib/mode.ts and .claude/hooks/codememory-mode.sh:
CLAUDE_CODE_REMOTEtruthy (true,1, oryes), orCLAUDE_CODE_REMOTE_SESSION_IDnon-empty: off.- Cursor metadata
agent/runtimeequal tomanaged, read withGET /v1/meta-data/agent/runtimeonCURSOR_AGENT_SOCKET(default/run/cursor/api.sock): off. - CI: truthy
GITHUB_ACTIONS,GITLAB_CI,CIRCLECI, orBUILDKITE, or a setTF_BUILDorJENKINS_URL: off.CI=truealone is ignored, because.claude/settings.jsonsetsCIfor every Claude Code session. - macOS (
unameDarwin), and none of the signals above: on, even when the local services are down. - Otherwise both FalkorDB
127.0.0.1:6379and Qdrant127.0.0.1:6333must accept a TCP connection, or CodeMemory stays off. A failed probe is "down", not an error.
Hooks and the OpenCode code-memory plugins no-op when the decision is off. FMFLURRY_CODEMEMORY=on keeps it on in the cloud. off keeps it off on a laptop.
Project memory. On by default. /memory-init (skill project-memory) scaffolds a short root AGENTS.md (about 80 lines at most) and docs/memory/: INDEX.md, contexts/<bounded-context>.md, immutable ADRs in decisions/NNNN-<slug>.md, and glossary.md. Each doc carries owner, reviewed, and refs frontmatter. A context file is read only when the task touches that bounded context (instructions/project-memory.md). agent-harness memory-lint (.claude/hooks/memory-lint.sh) fails on a missing owner or reviewed, a reviewed date older than 90 days, or a dead ref path or symbol. The ship stop gate adds its findings to the block reason. pr-report-check and the gh pr create hook run it, and require mémoire : màj or mémoire : aucun changement in the PR body when docs/memory exists. FMFLURRY_MEMORY=off turns it off.
Review tags (#28, #30). The default mapping is Finding tags in .claude/agents/code-reviewer.md. Important blocks the merge. Nit does not. Pre-existing does not, at any gravity. Approve means no Important finding is open (lint passes, and no forbidden comments). Block means at least one Important finding is open. There is no Warning verdict. scripts/cursor-plugin/check.mjs rejects the old uppercase review-severity words in harness sources. The allowlist for non-review uses (GDPR, database health, plan risk lines, npm audit, CVE) is scripts/cursor-plugin/review-tags.mjs. When the repository under review has a root REVIEW.md, that file is the only tag mapping. The reviewer cites it and does not apply the default table as a second mapping. This repo ships REVIEW.md.
Enforcement ladder (#29). .claude/rules/common/enforcement-ladder.md (Cursor copy plugins/fmflurry-harness/rules/enforcement-ladder.mdc) and instructions/enforcement-ladder.md (loaded from opencode.jsonc). Put the fix at the first level that can hold it: code, then lint, tests, or static analysis, then a prose rule, then human review. A prose rule carries why-not-tooled:. Adding always-on prose means deleting or shortening other always-on prose in the same change.
PR template (#30). .github/pull_request_template.md has Summary, Risk, How to revert, and Tier. Tier is T1, T2, or T3, from blast radius, protected paths, and diff size. It is not a finding tag. /setup-harness writes that template when .github/pull_request_template.md is missing and leaves an existing file alone (scripts/cursor-plugin/templates/setup-harness.md, built to plugins/fmflurry-harness/skills/setup-harness/SKILL.md). commands/pr.md and commands/create-pull-request.md fill the template when it exists. From 0.4.18 the template also has ## Visual report. The harness commits a show-me HTML file and a PNG at docs/pr-reports/<branch-slug>.html and .png, embeds the PNG, and links the HTML. .claude/hooks/pr-visual-report.sh blocks a gh or az body that omits the section. A docs typo or a version bump only may check Skip and state the reason. Conductor and Monolith share the pr-visual-report skill. agent-harness pr-report writes the files, agent-harness pr-report-links prints the section with absolute links pinned to the report commit (a relative link opens a compare page and is rejected from 0.4.33), and agent-harness pr-report-check checks a body.
Rules diet (#32). Plugin 0.4.3 (fa50d8e). plugins/fmflurry-harness/rules/ has 7 files with alwaysApply: true, 502 lines, down from 21 files and 1438 lines at 62aa030. At 0.4.3 they were autonomy.mdc, conductor.mdc, enforcement-ladder.mdc, orchestration.mdc, question-handling.mdc, tool-budget.mdc, and verification-gate.mdc. scripts/cursor-plugin/config.json rules.always lists the six common/ rules. The Conductor build adds rules/conductor.mdc. Plugin 0.4.19's default Monolith build replaces that file with rules/monolith.mdc and stubs the first-tool gate. There is no rules/always__harness.mdc in this build. The always-on count stays 7. File-bound rules stay in that directory with alwaysApply: false and globs: code-comments, coding-style, security, testing, and the five typescript-* packs. These left the always-on set and are skills: agent-roster, brief-contract, codebase-exploration, git-workflow, harness-parity, hooks, open-pr-check, patterns, performance, worktree-destruction-safety. skills/ai-ecosystem-audit/SKILL.md (Always-on budget) counts session-global rules. More than 8 alwaysApply: true Cursor rules is a confirmed finding.
- Reproducibility: same agent behavior across machines/sessions.
- Quality: on-demand TDD, frequent verification, centralized conventions.
- Security:
security-reviewskill available on demand + pre-tool-use hooks.
- Configs:
opencode.jsonc,dcp.jsonc(dynamic context pruning),tui.json(TUI theme). - Profiles:
profiles/<name>/(per-profile overrides +AGENTS.md). - Skills:
skills/*/SKILL.md(plus auxiliary docs) — canonical set, shared with Claude Code viasync-skills.sh. - Agent prompts:
prompts/agents/*.txt(26 files). - Slash commands:
commands/*.md(53 templates; 37 pinned inopencode.jsonc, recounted 2026-11-06). - OpenCode plugins:
plugins/<name>/index.ts+plugins/code-memory-lib/+plugins/lib/(withplugins/lib/kdco-primitives/). - TUI plugins:
tui-plugins/*.tsx(registered intui.json;autonomy-status.tsxis the autonomy sidebar panel). - Custom tools:
tools/*.ts. - Mode notes:
contexts/*.md. - Global instructions:
instructions/*.md(6 loaded at session start; file-bound and situational docs are skills or unloaded instruction files). - Scripts:
scripts/setup-package-manager.js,scripts/codemaps/generate.ts,scripts/settings-sync.sh,scripts/sync-skills.sh(sync canonical skill set to both harnesses),scripts/skill-drift-check.sh(read-only drift detector). - Install entry points:
bootstrap.sh,bootstrap.ps1,install.sh,install-cursor.sh../install.sh --yes,settings-sync, andbootstrap.ps1install Monolith when no variant is set../install.sh --localand./install-cursor.shdefault to Monolith.conductorselects Conductor.--variantandHARNESS_VARIANToverride the default.orchestrationis an alias of Conductor. A remote Claude Code session runs.claude/hooks/cloud-session-bootstrap.shonSessionStartwhenCLAUDE_CODE_REMOTE=trueand the project does not vendor the harness. - Claude mirror:
.claude/CLAUDE.md,.claude/settings.json,.claude/hooks/,.claude/rules/,.claude/agents/,.claude/skills/(synced from the canonical set on install),.claude/commands/. - Intentional exclusions (
.gitignore):node_modules/,antigravity-*,.DS_Store, local.env*files except.env.example, runtime dirskills/skill-creator/(not synced).
Six concerns wired in one file:
instructions: always-on docs loaded at session start. Currently 6:instructions/subagent-routing.md— Task-first subagent delegation gate.instructions/question-handling.md— blocking vs non-blocking question protocol.instructions/verification-gate.md— independent build/test verification before "done".instructions/autonomy.md— destructive-action and autonomous-mode limits.instructions/tool-budget.md— verification-vs-exploration budget.instructions/enforcement-ladder.md— code, then lint or tests, then a prose rule, then review. File-bound guidance stays on disk and off this array:instructions/code-comments.md,instructions/coding-style.md,instructions/testing.md,instructions/security.md(the coder or tdd-guide prompt points at them). Situational guidance is a skill:open-pr-check,codebase-exploration,harness-parity,brief-contract,git-workflow,worktree-destruction-safety,performance,patterns,hooks,agent-roster.
instructions/caveman-ultra.mdsits in the repo but is not in theinstructionsarray, so it isn't loaded at session start.default_agent:conductor(orchestrator-only — cannot write/edit).agent: 26 definitions (prompt + tool allowlist). No agent setsmodel, and the file sets no top-levelmodel. Each agent uses the session model — see Changing models.command: maps/<name>-> template + sub-agent +subtask; 21 entries are pinned here.mcp: six servers —code-memoryenabled;context7,blender,wallaby,Figma,smartbear-swaggerdisabled by default.code-memory_*perms are pre-allowlisted for every subagent.plugins: the npm pluginopencode-skill-creator. OpenCode 2 loads the local plugin folders underplugins/on its own.
dcp.jsonc is the config stub for the optional external Dynamic Context Pruning plugin.
This section describes Conductor. On Monolith the primary agent may write on the first edit, and /orchestrate loads the conductor skill. The picture for all three hosts is How a request moves. The interesting part of Conductor is the machinery that keeps a literal model on rails. Each rule lives in an instructions/ file loaded at startup.
conductor has tools.write: false, tools.edit: false, and permission.edit/write: deny in opencode.jsonc. Its Task allowlist enumerates every legal specialist; *: deny blocks the rest. The orchestrator has no file-mutation tool — it must dispatch a task to coder, writer, tdd-guide, or git-specialist. instructions/subagent-routing.md adds a first-tool gate: if the request matches a specialist, the very first tool call must be that dispatch.
| You want… | Route to |
|---|---|
| A plan, risk list, or phased breakdown | planner |
| Architecture / scalability / module boundaries | architect |
| Non-test implementation | coder |
| Docs, README, markdown, HTML, release notes | writer |
| Diff / PR / current-change review | code-reviewer |
| Tests and coverage | tdd-guide (delegates impl to coder) |
| Build, typecheck, lint, or TS errors | build-error-resolver |
| Git, commits, branches, pushes, PRs | git-specialist |
| Security / auth / secrets / user input | security-reviewer |
| GDPR / privacy / cookies / PII | gdpr-specialist |
| Angular or .NET pre-merge review | angular-cop / dotnet-cop |
| SQL / schema / migrations / RLS | database-reviewer |
| Live PostgreSQL instance diagnostics | postgres-dba |
| OpenAPI specs | api-spec-architect |
| Unknown file scope for a brief | scout |
| Dead code / duplication cleanup | refactor-cleaner |
| Generated docs / codemaps | doc-updater |
| E2E browser journeys | e2e-runner |
| Harness / skill / agent parity audit | ecosystem-auditor |
| Comment judging / purge | comment-judge (purge via haruspex-commentorum) |
| Blender / 3D art | gaudi (triggered-only) |
Most non-trivial work follows a fixed order, so planning, implementation, and review never collapse into one agent:
planner → (tdd-guide → coder) or coder → code-reviewer → verify → git-specialist
A feature goes planner → /tdd (RED) → coder (GREEN) → /verify → /pr → /cop-review → ship-merge.
A behavior-preserving refactor goes planner → /tdd refactor (characterization tests that pass immediately, then freeze) → coder (the restructure does not edit those tests) → /blast-radius → /verify (baseline against treatment on the same pin) → /pr → /cop-review → ship-merge.
A test-first variant routes tdd-guide first (RED), then tdd-guide delegates the GREEN implementation to coder, then code-reviewer, then the verification gate, then git-specialist. Docs-only work short-circuits to writer. A refactor routes tdd-guide in /tdd refactor mode first, so the characterization pin is green before any restructure.
Before dispatching coder, writer, or tdd-guide, the conductor emits a 6-field brief (the brief-contract skill): TASK (one imperative outcome), FILES (authoritative path + line ranges), CHANGE (named target state), DONE-WHEN (an executable command that must exit 0), OUT OF SCOPE, and CONTEXT ALREADY RESOLVED — plus a BUDGET. Precise briefs cost roughly 4× fewer tokens than open-ended ones, so this is enforced, not advice.
Subagents that hit an ambiguity must tag their question [BLOCKING] or [NON-BLOCKING] (instructions/question-handling.md). Blocking questions stop the agent; the conductor tries to answer from the repo first, then asks the human. Non-blocking questions let work continue with a stated default and are batched and reported at the end of the job.
Nobody says "done" without fresh evidence (instructions/verification-gate.md). After any source edit, the agent detects the project type from manifests, runs the matching build/typecheck/lint command itself (subagent self-reports are not proof), runs the tests if behavior changed, and pastes the tail of the real output. Two failed fix passes on the same error → stop and escalate.
instructions/tool-budget.md separates verification commands (build, test, git state — uncapped) from exploratory shell (listing, grepping, file inspection — default 3 per dispatch). It nudges the model toward CodeMemory and targeted read ranges instead of full-file reads, and requires a one-line justification when the exploratory ratio runs high.
Removing a worktree is treated like rm -rf, not bookkeeping (the worktree-destruction-safety skill). The only removal path is agent-harness worktree-rm <path> --confirmed; without --confirmed it is a dry run that exits 3. It runs the pre-removal checks: git status --porcelain, commits not on the base branch, activity (fails closed when unknown; with the Orca app closed, lsof must show that no process has its working directory in the worktree, then removal goes through git), and every other checkout of the repo (main and sibling worktrees) clean or snapshotted. It lists the target's ignored files before removing. Snapshots are recoverable refs under refs/harness/snapshots/<ts>-<n> that capture tracked content, file modes, index state, and untracked files. In Orca-managed repos the removal goes through Orca, never with --force. The command then waits for the removal to finish, settles, and re-scans every other checkout; a change is reported as changed during removal. A changed checkout is restored only if its HEAD is unchanged and it is clean. Otherwise exit 4 with inspect and restore commands, refs kept. On success each snapshot sha is printed before its ref is released. Not covered: ignored files, untracked nested git repositories (reported as a note), and submodule contents. Any failed check is a hard stop reported to the human. The guard denies raw orca worktree rm, git worktree remove|prune|move (including global options and aliases), and recursive rm/mv/trash/rsync --delete/find -delete on a worktree or its parent, in every mode. It is text matching and cannot catch commands assembled at run time; the script's checks are the real boundary. git worktree prune -n stays allowed. In autonomous mode, agent-harness worktree-rm <path> --confirmed removes a worktree that is clean and whose branch is merged into the default branch (tip reachable, trees equal, or gh pr view --json state is MERGED). It refuses a dirty worktree, unmerged work, the main checkout, and a path that is not a worktree of the repo, and the message names the reason. Raw git worktree remove stays denied. With autonomy off, a squash-merged branch that is still ahead of origin/<base> is still refused. agent-harness teardown-merged-worktree <pr> removes the registered goal worktree of a MERGED PR in autonomous mode and also deletes that goal's branches and registry. It re-runs the checks against the PR head (not an origin/<base>..HEAD count, because squash merges rewrite history), never uses --force, and keeps the registry when a step is partial. Goal worktrees are created by agent-harness ship-init and registered in <git-common-dir>/agent-harness/goals/<slug>.json.
When the code-memory MCP server is connected and CodeMemory is on, its tools are the mandatory first choice for search, callers, definitions, importers, and dependencies (the codebase-exploration skill). grep/glob/bash are fallbacks only — raw listing, filename globs, or a known path region. Cloud and remote agents skip CodeMemory (docs/codememory-cloud.md). This is the rule that makes orientation cheap for every other agent.
Delegation is enforced at two layers, so the same behavior holds whether the primary model is Claude, GPT, DeepSeek, or any open-weight runner that ignores prose hints:
- Permissions —
conductorhastools.write: false,tools.edit: false, andpermission.edit/write: denyinopencode.jsonc. The Task allowlist enumerates every legal specialist;*: denyblocks anything else. The orchestrator literally has no file-mutation tool. - Guard plugins + front-loaded prompt —
plugins/secret-file-guard/index.tsaborts anyread/bashaccess to a secret-bearing.envfile;plugins/tool-budget/index.tsnudges verification over exploration (it never blocks a call).prompts/agents/conductor.txtputs hard rules in the first lines, the routing table second, and six worked few-shot examples showing User →taskcalls with explicit wrong-way contrasts;instructions/subagent-routing.mdenforces a Task-first gate before direct inspection.
Use these paths depending on how much control you want:
- Plain request:
conductorconsults the routing table and dispatches the matching specialist via Task. @agentmention: manually invokes a specific subagent in the conversation.- Slash command: forces a subtask with a configured template, e.g.
/plan,/tdd,/security.
Why this exists: GPT/Claude often infer delegation from short descriptions, but open-source/open-weight models are more literal and tend to inspect or edit first. Permissions + the front-loaded gate make delegation mechanically enforced rather than instruction-dependent.
This table is the Conductor roster, defined in opencode.jsonc under agent — 26 entries: the primary plus 25 subagents. build and plan are built-in overrides and ship disabled.
Monolith does not install this roster. It keeps 9 agents. The main agent coordinates and may write. /orchestrate loads the conductor skill.
| Agent | Access | Role | Trigger notes |
|---|---|---|---|
conductor |
read-only | Primary orchestrator. write/edit denied; every change routed via Task. |
Default agent — always on |
planner |
read-only | Plan + risks + phased order before large changes. No edit. | Complex features, unclear order |
architect |
read-only | System design, scalability, cross-module boundaries. | High-impact design decisions |
coder |
writable | Pure non-test implementation. Build+lint+standards self-check before reporting. Socratic ambiguity gate. | Any source-code change |
writer |
writable | Docs/markdown/HTML/text artifacts. Refuses source files. | Prose, README, ADRs, reports |
code-reviewer |
read-only | General diff/PR review. Findings only; fixes go to coder. Owns /cop-review. |
Review requests |
comment-judge |
read-only | Rubric verdict on added/changed comments; REVIEW (diff) or PURGE (directory). Emits JSON. | Comment review / purge |
haruspex-commentorum |
writable | Comment-deleting purge agent. Applies agreed verdicts. | Triggered-only by purge flow |
ecosystem-auditor |
read-only | Evidence-first audit of OpenCode/Claude parity and harness coherence. | /ecosystem-audit, parity checks |
angular-cop |
read-only | Angular + TypeScript pre-merge review (signals, RxJS, flurryx, TS strict). Runs tsc + lint. |
Angular PR review |
dotnet-cop |
read-only | .NET 10 Minimal API review (ports/adapters, modular isolation, EF Core). Runs build + dotnet format. |
.NET PR review |
gdpr-specialist |
read-only | GDPR/CNIL compliance review (consent, cookies, PII, retention, transfers, 72h breach). | Privacy-sensitive features |
security-reviewer |
read-only | OWASP/secrets/deps review. Reports vulnerabilities; fixes routed to coder. |
Auth, input, endpoints, secrets |
tdd-guide |
writable (tests) | RED → GREEN → REFACTOR + 80% coverage. /tdd refactor pins current behavior with characterization tests that already pass. Delegates impl to coder. |
New features, bug fixes, refactors |
build-error-resolver |
writable | Fixes build/typecheck/lint/TS errors with minimal diffs. | Red build or lint |
e2e-runner |
writable | E2E tests from the project override or a discovered runner. | Browser journeys |
doc-updater |
writable | Generated docs + codemaps. | /update-docs, /update-codemaps |
refactor-cleaner |
writable | Dead-code removal + consolidation, behavior preserved. | Cleanup requests |
database-reviewer |
read-only | PostgreSQL/Supabase schema, query perf, RLS, migrations. | SQL/migration/schema review |
postgres-dba |
read-only | Live instance ops: health, vacuum/bloat, WAL, backups/PITR, pooling, upgrades. Emits human-confirmed commands. | /db-health, /db-backup-check |
api-spec-architect |
writable | Zalando-compliant OpenAPI 3.1 specs; optional SwaggerHub publish. | /api-spec |
git-specialist |
writable (git) | Branches, staged commits, pushes, PRs. | Git/commit/PR tasks |
scout |
read-only | Emits a file manifest for an unknown scope before a brief. | Triggered-only by conductor |
why-investigator |
read-only | Investigates one evidence category for design rationale. | Triggered-only by why skill |
why-synthesizer |
read-only | Merges investigator findings into one evidence-weighted answer. | Triggered-only by why skill |
gaudi |
writable | Blender / 3D art: modeling, materials, lighting, render, glTF export. Drives the Blender MCP. | Triggered-only (3D work) |
Session model. No agent in opencode.jsonc sets model, and the file sets no top-level model. A primary agent uses the model selected for the session. A subagent uses the model of the agent that invoked it (OpenCode agents). A Monolith install is the same: the generator does not write model.
OPENCODE_REASONING_* is not written either. Those variables were only exported to the shell. opencode.jsonc never interpolated them. Reasoning fields on a myMistral model entry describe that provider. They do not select a model for the session.
To pin one agent, set model on that agent in your own OpenCode config. A reinstall of this harness does not add a pin.
53 templates live in commands/ (recounted 2026-11-06). 37 are pinned in the opencode.jsonc command block. That block is the Conductor set. Monolith remaps a folded agent: postgres-dba becomes database-reviewer, and every other folded name becomes main, which loads the matching skill (scripts/variants/dangling-agents.mjs). Many pinned commands set subtask: true. OpenCode reads the pinned block; whether it additionally auto-discovers commands/ is something this repo cannot prove, so treat unpinned entries as Claude-side or discovery-dependent.
Pinned (37):
| Command | Sub-agent | Purpose |
|---|---|---|
/git |
git-specialist | Bounded git ops (branches, commits). |
/push-changes |
git-specialist | Commit + push with upstream guard. |
/plan |
planner | Implementation plan. |
/tdd |
tdd-guide | TDD cycle. /tdd refactor pins current behavior. |
/api-spec |
api-spec-architect | OpenAPI 3.1 spec generation. |
/cop-review |
code-reviewer | Direct pre-merge review; selects stack guidance. |
/security |
security-reviewer | Security audit. |
/gdpr-review |
gdpr-specialist | GDPR/CNIL compliance audit. |
/build-fix |
build-error-resolver | Build/TS error resolution. |
/e2e |
e2e-runner | E2E tests from the project override or discovered runner. |
/refactor-clean |
refactor-cleaner | Dead-code cleanup. |
/orchestrate |
planner | Multi-agent orchestration. |
/verify |
(conductor) | Verification loop. |
/eval |
(conductor) | Evaluate against criteria. |
/update-docs |
doc-updater | Doc updates. |
/update-codemaps |
doc-updater | Generates docs/CODEMAPS/. |
/test-coverage |
tdd-guide | Coverage analysis. |
/skill-create |
no agent key |
Generate a skill from git history. Runs as the default agent. |
/db-health |
postgres-dba | Read-only PostgreSQL health battery. |
/dependabot-friday |
git-specialist | Dependabot PR triage (report-only). |
/db-backup-check |
postgres-dba | Backup/PITR posture audit. |
/ship |
conductor | One goal from clarify through merge. |
/autonomous |
conductor | Turn autonomous mode on, off, or show status. |
/pr |
git-specialist | Open a pull request from the repo template. |
/memory-init |
writer | Scaffold split project memory. |
/show-me |
writer | Offline HTML diagram and PNG screenshots. |
/show-your-work |
conductor | TSV decision trail. |
/comment-judge |
comment-judge | Rubric verdict on comments. |
/interfectio-commentarum |
conductor | Haruspex comment-purge flow. |
/for-real |
conductor | Restate the last message in plain language. |
/why |
conductor | Cited design rationale. |
/blast-radius |
conductor | What a change can break, from running code. |
/chimera |
conductor | Parallel candidates, then graft. |
/fix-ci |
conductor | Fix failing pull-request checks. |
/loop-on-ci |
conductor | Watch checks and iterate fixes. |
/get-pr-comments |
git-specialist | Summarize review comments on the active PR. |
/fix-merge-conflicts |
git-specialist | Rebase through conflicts. |
Unpinned templates (16) — available in commands/, plus Claude-side/OpenSpec helpers:
/checkpoint, /pm2, /setup-pm, /ecosystem-audit, /create-pull-request, and the OpenSpec family /opsx-{new,ff,continue,apply,verify,archive,bulk-archive,sync,explore,propose,onboard}.
Claude-only: .claude/commands/ adds arena.md and arena-new-prompt.md (the arena/chimera flow) plus the OpenSpec command dir — those are not pinned for OpenCode.
Recounted 2026-11-06: skills/*/SKILL.md is 80 skills. The groups below name that set. Twelve of them sit in the last bullet, outside the older groups. skill-creator/ is git-ignored and outside the 80. scripts/sync-skills.sh computes the canonical union (root skills/ ∪ .claude/skills/, root wins on conflicts), excludes the runtime dir skills/skill-creator/, and copies into both harness targets. Attribution for vendored skills lives in skills/THIRD_PARTY_NOTICES.md. Attack-class references in skills/security-review/references/ are verbatim copies from cloudflare/security-audit-skill at c1c8a8c1471069fb0e188eeaff69b8e8db6564a8 (MIT, Copyright (c) 2025-2026 Cloudflare, Inc.). The license text is LICENSE-cloudflare-security-audit.
- Planning & design (5):
socratic-design,chimera,api-spec-openapi,why,blast-radius. - Review & quality (6):
comment-judge,interfectio-commentarum,verify-this,create-verification-skill,test-behavior-not-implementation,ai-ecosystem-audit. - TDD & testing (3):
tdd-workflow,tdd,e2e. - CI & git (5):
fix-ci,fix-merge-conflicts,get-pr-comments,loop-on-ci,git-workflow. - Angular (4):
angular-clean-architecture,angular-ddd,angular-cop,angular-accessibility. - .NET (3):
dotnet-clean-architecture,dotnet-ddd,dotnet-cop. - Three.js / 3D (1):
threejs, with the ten topics underreferences/. - PostgreSQL playbooks (4):
postgres-health-check,postgres-performance-tuning,postgres-backup-restore,postgres-container-ops. - Playwright E2E (2):
playwright-e2e-authoring,playwright-e2e-review. - OpenSpec workflow (1):
openspec, with the eleven workflows underreferences/. - Writing & communication (7):
humanizer,for-real,caveman,caveman-commit,caveman-review,show-me,show-your-work. - Harness & config (5):
config-sync,harness-parity,skill-authoring,treetopia,strategic-compact. - Security (1):
security-review. - Compliance (1):
gdpr-compliance. - Domain (2):
flurryx,transloco. - Universal standards (1):
coding-standards. - On-demand role skills:
planner,coder,writer,doc-updater,architect,refactor-cleaner,scout,gaudi,testing,security,coding-style,code-comments,autonomy,question-handling,enforcement-ladder,tool-budget,verification-gate. Monolith loads these in the main loop. Conductor still has the matching agents. - Also in the tree (12):
agent-roster,autonomous,brief-contract,codebase-exploration,hooks,open-pr-check,patterns,performance,project-memory,pr-visual-report,ship,worktree-destruction-safety.
The PostgreSQL and Playwright sets are gc.platform-specific project playbooks, not general-purpose skills — read them alongside the postgres-dba agent. /e2e and e2e-runner do not assume that stack. They read e2e.json or discover the start command, ports, and runner (skills/e2e). Load playwright-e2e-authoring and playwright-e2e-review only when that override names them. A project sets "enabled": false to opt out. Consumers that do not want the playbooks omit those two skills when vendoring.
skill-creator is a runtime-only skill: it is git-ignored (skills/skill-creator/) and never synced. opencode-skill-creator (npm) provides the same capability at runtime.
6 session-start instructions (listed in Configuration) are the operating rules every agent loads: subagent routing, question handling, the verification gate, autonomy, the tool budget, and the enforcement ladder.
The Claude Code side keeps the same six as pathless rules under .claude/rules/common/, plus path-scoped rules for code comments, coding style, security, and testing, and five rules/typescript/ packs. Domain text that is not file-bound lives in skills (codebase-exploration, brief-contract, git-workflow, worktree-destruction-safety, performance, patterns, hooks, agent-roster, open-pr-check, harness-parity).
Two top-level instruction files, distinct jobs:
- Root
CLAUDE.md— behavioral guidelines for Claude Code agents (think before coding, simplicity, surgical changes, goal-driven execution, verification gate, delegation, destructive-action safety, tool hygiene). Project rule packs feed into it via@rules/...imports. .claude/CLAUDE.md— the global user instructions installed into~/.claude, carrying the cross-project essentials (no any, facade-not-UseCase).
The plugins are OpenCode 2 folder plugins built with @opencode/plugin@2.2.7 (plugins/<name>/index.ts, Plugin.define). OpenCode loads every folder in plugins/; plugins in opencode.jsonc names only the npm plugin opencode-skill-creator.
plugins/secret-file-guard/index.ts— hard-blocksread/bashaccess to secret-bearing.envfiles;.env.example/.sample/.templatestay readable.plugins/mistral-affinity/index.ts— attaches a stablex-affinityheader to Mistral / Mistral-compatible provider calls for cache affinity.plugins/tool-budget/index.ts— nudges the model toward verification over exploration via the system prompt (never blocks a tool call).plugins/code-memory/index.ts+plugins/code-memory-lib/— CodeMemory auto-retrieve / auto-learn nudges (no-op when thecode-memoryCLI is absent).plugins/lib/(withplugins/lib/kdco-primitives/) — shared utilities (mutex, shell, terminal-detect, project-id resolver, types).opencode-skill-creator(external npm, declared inopencode.jsonc › plugin) — skill scaffolding and benchmarking.plugins/kpi/index.ts— OpenCode side of the KPI journal. Records session boundaries, skill names, subagent types, and tool results.plugins/autonomy/index.ts— OpenCode side of autonomous mode. See Autonomous mode.plugins/domain-rules/index.ts— off unless.harness-local/domain-rules.jsonopts in. Runs before write, edit, patch, and multiedit.- Not loaded:
plugins/ecc-hooks.ts.disabled,plugins/worktree.disabled,plugins/figma-rag.md, andtui-plugins/caveman.tsx.disabledship disabled and are skipped by the loader.
Claude-side hooks (.claude/hooks/, 21 scripts, recounted 2026-11-06): notification.sh, pre-tool-use.sh, prefer-code-memory.sh, rtk-rewrite.sh, stop.sh, subagent-stop.sh, tool-budget.sh, autonomy-ask-guard.sh, autonomy-context.sh, autonomy-git-guard.sh, cache-invalidation.sh, cloud-session-bootstrap.sh, codememory-mode.sh, commit-provenance.sh, domain-rules.sh, goal-state.sh, kpi-emit.sh, memory-lint.sh, orca-notify.sh, pr-visual-report.sh, ship-stop-gate.sh.
Reusable OpenCode tools exposed via tools/index.ts:
tools/run-tests.ts— detects package manager + framework and builds the test command.tools/check-coverage.ts— reads coverage reports and compares against a threshold.tools/security-audit.ts— scans deps + secrets + risky patterns.
(tools/index.ts is the barrel that re-exports them.)
tui-plugins/panda-banner.tsx— SolidJS banner that renders a panda ASCII/block-art header.tui-plugins/autonomy-status.tsx— sidebar capsule for autonomous mode, registered intui.json. Behaviour is under Autonomous mode.
CLAUDE.md— global user instructions (noany, facade != UseCase).settings.json— allow/deny permissions, env (API_TIMEOUT_MS=3000000,CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1,CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=80),"model": "opus"for the Claude Code main agent, andPreToolUse/PostToolUse/Stophooks. Conductor and Monolith share this file. Seeded on first install into~/.claudeand into a project's.claude. Amodelvalue already set is preserved on reinstall.hooks/*.sh— 21 scripts. The names are under Plugins & hooks.rules/common/*.md+rules/typescript/*.md— 17 files (recounted 2026-11-06). Six underrules/common/have nopaths:key. Six underrules/common/are path-scoped (code-comments,coding-style,security,testing,cache-invalidation,project-memory). Fiverules/typescript/packs stay path-scoped. Patterns, hooks, and the agent roster are skills.agents/*.md— 26 agent definitions mirroring the OpenCode roster.commands/*.md— Claude commands (/create-pull-request,/update-codemaps, arena, OpenSpec).skills/**— the skill mirror, synced from the canonical set byscripts/sync-skills.shon install. It is not guaranteed to equal today'sskills/(the canonical set grows between syncs), so treatskills/as the source of truth and runsettings-sync --skills-onlyto catch the mirror up.
Two directories, one source of truth. The lab is wherever you cloned this repo; the live config dirs are ~/.config/opencode and ~/.claude. Nothing here watches the filesystem — you pull, then sync.
install.shmerges additively and never deletes user config. Re-running is safe and idempotent: it refreshes deps, re-merges repo files, and rewrites the marker-fenced env block.scripts/settings-sync.shis the "from anywhere" command —settings-syncresolves the repo (viaSETTINGS_OPENCODE_REPOor well-known clone paths) and runs a full install;settings-sync --skills-onlyruns the fast skills path;--whereprints the resolved repo path.scripts/sync-skills.shcomputes the canonical skill union and copies it into every active harness target. installers call it; you can run it standalone.scripts/skill-drift-check.shis a read-only drift detector: it hashes every copy of a skill across the known roots (repo.claude/skills,.opencode/skills,~/.config/opencode/skills,~/.claude/skills) and exits non-zero when two copies of the same skill diverge. Also compares the kept-overlap instruction topics.- The
config-syncskill is the agent-facing version of the same job: edit an agent/rule/skill here, and it propagates the change across harness dirs. install-cursor.shbuilds the Cursor plugin (node scripts/build-cursor-plugin.mjs->plugins/fmflurry-harness/) and copies it to~/.cursor/plugins/local/fmflurry-harness; then run Developer: Reload Window in Cursor. The default build is Monolith: the primary agent may write, there is no first-tool gate, and/orchestrateis optional../install-cursor.sh --variant conductor(orHARNESS_VARIANT=conductor ./install-cursor.sh) builds Conductor../install-cursor.sh --statusprints the variant stored in the plugin's.harness-variant. It also installs theagent-harnessCLI, using the same helper asinstall.sh: scripts go to~/.local/share/fmflurry-harness/scripts/agent-harnessand the wrapper is~/.local/bin/agent-harness. Re-running prints those paths and does not add a second command. Flags:--yes,--link(symlink instead of copy),--migrate-legacy(back up then remove what the old installer copied into~/.cursor, keeping your own entries),--uninstall,--no-backup,--variant,--status. Limits: no per-agent tool allowlist, delegation by instruction only, Notification hooks unsupported. Tier defaults stay Cursor models:grok-4.7,grok-4.6, andcomposer-2.5.
Parity phrasing: the two harnesses are synced on install. Recounted 2026-11-06, skills/ holds 80 skills and the shipped .claude/skills/ mirror holds 41. Run settings-sync --skills-only (or scripts/sync-skills.sh) to reconcile, and scripts/skill-drift-check.sh to confirm.
The installed manifest version is version in scripts/cursor-plugin/config.json (0.4.36 in this tree). node scripts/build-cursor-plugin.mjs copies it into plugins/fmflurry-harness/.cursor-plugin/plugin.json and copies scripts/cursor-plugin/CHANGELOG.md into the plugin. node scripts/cursor-plugin/check.mjs fails if those version fields differ or if the changelog has no heading for the current version. The marketplace entry has no version field. Root package.json versions the settings repo (GitHub releases), not this plugin.
Bump that version by hand in each PR that changes plugin content or its build inputs:
- patch — fixes, chores, and doc tweaks to plugin content
- minor — new agents, skills, commands, rules, or behavior
- major — breaking changes: renamed or removed agents or skills, changed tier keys, installer contract changes
From plugin 0.4.1, scripts/cursor-plugin/CHANGELOG.md asks for a patch bump on every later plugin change. The check still only requires a version strictly above the base. It does not reject a minor or major bump.
The check diffs the working tree against the merge-base with the base branch, so a root README edit does not need a bump. The version it must exceed is the base branch tip: origin/master locally, origin/$GITHUB_BASE_REF in GitHub Actions (the workflow fetches that ref), or CURSOR_PLUGIN_BASE when set. If none of those refs exist, the check prints a skip message and continues.
Plugin sources are plugins/fmflurry-harness/, the .claude agents, commands, rules, skills, CLAUDE.md, settings.json, and the hook scripts named in hooks.include, plus skills/, commands/, opencode.jsonc, scripts/build-cursor-plugin.mjs, scripts/sync-skills.sh, and the cursor-plugin config, library, changelog, README template, adapter, setup-harness template, and logo. scripts/cursor-plugin/check.mjs does not ship in the plugin.
bump the plugin version + changelog in any PR touching plugin sources.
The lifecycle for both variants is How a request moves. The four steps below are the OpenCode startup path when the installed variant is Conductor.
- Startup: OpenCode loads
opencode.jsonc-> 6 always-on instructions -> auto-loads every plugin inplugins/plus the TUI plugins registered intui.json. Skills load when their description matches. - Dev:
conductorexecutes — it cannot write files; it dispatches Task calls to specialists.secret-file-guardblocks.envaccess;tool-budgetnudges verification over exploration. - Workflow:
conductorroutes to specialists through Task (perm-enforced);/plan,/tdd,/security, etc. force the same routing explicitly. The brief contract, question protocol, and verification gate bracket each hand-off. - Idle: the
autonomyplugin runs the stop gate and sends the idle notification.
Autonomous mode lets the agent take one goal from clarification to a merged PR. Turn it on, then run /ship <goal>.
With the flag off, the agent asks before each irreversible step, and a merge needs --confirmed. Turning the flag
on does not start work (skills/autonomous/SKILL.md).
The run is a loop, owned by skills/ship/SKILL.md: implement, verify, local review, push and open the PR, CI, then
agent-harness ship-merge. A blocker the agent can fix (a confirmed Important finding, a failing check, a
conflict, a stale branch, an unresolved thread, a merge refusal) sends it back to fix, then local review again, then
push, CI and the merge retry. It ends as done (the PR is merged and the goal worktree is torn down) or escalated.
How to launch it. The goal text is the argument of /ship. The flag is also
agent-harness autonomy on|off|status (scripts/agent-harness/autonomy.sh). install.sh installs that wrapper
at ~/.local/bin/agent-harness when Claude Code or OpenCode is an install target. install-cursor.sh installs that same wrapper, pointing at ~/.local/share/fmflurry-harness.
- Claude Code. There is no
.claude/commands/ship.md./ship <goal>is theshipskill,skills/ship/SKILL.md.install.shrunsscripts/sync-skills.sh, which copies it to~/.claude/skills/ship./autonomous on|off|statusisskills/autonomous/SKILL.md(disable-model-invocation: true, so it stays user-invoked). The behaviour rule is.claude/rules/common/autonomy.md. The Stop hook is.claude/hooks/ship-stop-gate.sh, wired from.claude/settings.json. - OpenCode.
/shipand/autonomousare pinned inopencode.jsonc(command.ship,command.autonomous), both onconductor, templatescommands/ship.mdandcommands/autonomous.md. The startup rule isinstructions/autonomy.md.plugins/autonomy/index.tsblocks thequestiontool, injects autonomy context, denies forbidden git commands, and re-prompts the root session when the stop gate blocks. The sidebar toggle istui-plugins/autonomy-status.tsx(registered intui.json): command palette "Toggle autonomous mode",/autonomy-toggle, or<leader>u. - Cursor.
/ship <goal>isplugins/fmflurry-harness/commands/ship.md(built fromcommands/ship.mdbyscripts/build-cursor-plugin.mjs). It loadsplugins/fmflurry-harness/skills/ship/SKILL.md./autonomousisplugins/fmflurry-harness/commands/autonomous.mdandplugins/fmflurry-harness/skills/autonomous/SKILL.md. The always-on rule isplugins/fmflurry-harness/rules/autonomy.mdc. Thestopentry inplugins/fmflurry-harness/hooks/hooks.jsonrunshooks/scripts/ship-stop-gate.sh. That hook callsagent-harnessfromPATH.install-cursor.shinstalls that command at~/.local/bin/agent-harness.
Review loop. Stage 6 of skills/ship/SKILL.md reviews git diff <base>...HEAD with code-reviewer,
security-reviewer, and the stack cop when it applies (angular-cop or dotnet-cop; database-reviewer when
SQL changed). The agent confirms each finding against the code. Only a confirmed Important finding blocks. Nit
and Pre-existing do not. Tags come from the repo's REVIEW.md when it exists, otherwise from Finding tags in
.claude/agents/code-reviewer.md. Each verdict is recorded with agent-harness goal review code|security pass|fail.
The push guard (.claude/hooks/autonomy-git-guard.sh) denies git push and gh pr create while an active goal has no
passing code and security verdict for the exact diff (a hash of the diff against origin/<base>, ignoring
docs/agent-reports/); pushes to backup/* and the report commit are not gated. After the PR is opened it posts one
summary comment (skills/ship/references/review-format.md). That comment is an audit trail. ship-merge does not read
it. Every later CI or comment fix is reviewed locally before its push.
Repeated findings. Before each fix round the skill pipes the confirmed findings (<reviewer>:<path> or
ci:<check>, one per line) to agent-harness goal bump. It normalises them (lowercase, line numbers stripped,
sorted, deduplicated) and fingerprints the set. When the fingerprint equals the previous round's, the command marks the
goal escalated (no progress), runs agent-harness notify failure, and exits 3. goal.sh and ship-init.sh also
set a safety ceiling of max_fix_iterations 10. Empty stdin exits 2. The same bump is used before a CI fix round
(stage 9 of skills/ship/SKILL.md).
No-progress rule. Two checks share the name. They are not the same test.
skills/ship/SKILL.md(Stop conditions) treats a full loop iteration as no progress when the same Important finding and the same failure remain, or the same non-review blocker fails the same way. A new failure, a new finding, or a green check counts as progress. The agent then runsagent-harness goal escalate. For review findingsgoal bumpalso compares a fingerprint of the findings between rounds..claude/hooks/ship-stop-gate.sh(Cursor copy:plugins/fmflurry-harness/hooks/scripts/ship-stop-gate.sh) counts a stop as no progress only when nothing moved: the PR head, the registered worktree branch tip,.reviews, andfix_iterations. Five consecutive empty stops escalate withno progress after 5 stop blocks. Any of those changes resetsstop_blocksto 0. Every counted stop incrementstotal_blocks, and 30 total blocks escalate even when the last stop was progress. Stops are not counted duringagent-harness goal wait "<reason>" --ttl 30m(max 24h), or while the hook input, a live pid, an inflight marker, or a test or review process in the worktree shows background work. Before both verdicts pass for the current local tip, the block says to finish local review. After both pass and there is no PR, it says to push and open the PR. While the goal is active and the PR is unmerged, the hook blocks an early stop. If GitHub cannot be read, the hook exits 0 and does not count the stop. OpenCode has no Stop hook.plugins/autonomy/index.tsruns the same script onsession.idleof a root session, passes running child sessions, and re-prompts with the reason (instructions/autonomy.md). Conductor and Monolith use this hook.
When it escalates. skills/ship/SKILL.md (Human-only) stops for missing credentials, account limits or
billing, an external outage, a product decision the repo cannot answer, or an action on the forbidden list.
It also stops on the skill's no-progress rule, on goal bump exit 3, and on the stop-gate caps above. A
gitleaks finding or a secret exposure stops the run for security-reviewer and rotation. An open-PR outcome
of Wait or cancel escalates (skills/open-pr-check/SKILL.md). The blocked path keeps the worktree,
the branch, and the registry (skills/ship/SKILL.md, Blocked path).
What it never does. Hard limits in skills/ship/SKILL.md, and rule (d) in .claude/rules/common/autonomy.md:
- Merge only through
agent-harness ship-merge. Nevergh pr merge, and never a push to the base branch. - Never
git push --mirror,git push --all, or--no-verify. Never weaken a check: skip a test, a job, or a required check, setcontinue-on-error, delete a check, or lower a threshold. - Never remove a worktree with raw
git worktree remove.agent-harness worktree-rm <path> --confirmedremoves a clean worktree whose branch is merged (including a squash merge detected bygh pr view --json state).agent-harness teardown-merged-worktree <pr>removes the registered goal worktree after that PR is MERGED, in autonomous mode, and deletes its branches and registry. Never delete a branch except through that teardown,agent-harness cleanup,agent-harness prune-backupsfor leftoverbackup/*branches, oragent-harness prune-branchesfor merged local branches nothing claims. - Never merge a PR that matches
protectedPathswhile the flag is on. A human passes--confirmed. - Never add a label, post a comment, or create a status to get past a
ship-mergerefusal. - Never notify for progress. The run does not trigger builds or releases.
- Never tear down a blocked or escalated goal.
agent-harness autonomy on|off|status # toggle .claude/state/autonomy.on (gitignored, per machine)
/ship <goal> # clarify, implement, PR, review, CI, merge
agent-harness ship-merge <pr> [--method squash|rebase|merge] # the only merge path; add --confirmed in interactive mode
agent-harness notify done "<msg>" <pr> # notify on question, waiting, done, failure only
agent-harness ship-init <type> <scope> <desc> --goal "<text>" # first action of /ship: goal worktree + registry (or --adopt <pr>)
agent-harness goal decisions-path # this checkout's decision log: .claude/state/decisions/<slug>.tsv per goal (created by ship-init, archived to decisions/archive/ by teardown), else .claude/state/decisions.tsv
agent-harness teardown-merged-worktree <pr> # after MERGED: remove the registered goal worktree, branches and registry (run by ship-merge)
agent-harness cleanup <pr> [--keep-branch] [--no-checkout] # after MERGED: delete the PR's head branch and goal backups (unregistered PRs; also run by ship-merge; teardown passes --no-checkout)
agent-harness prune-backups [--confirmed] # leftover backup/* branches no goal or registry lists: delete those in origin/<base>, archive the rest under refs/harness/backups/ (dry run without --confirmed)
agent-harness prune-branches [--confirmed] # local non-backup branches already in origin/<base> that no goal, registry entry, worktree or HEAD claims: delete them; never remotes (dry run without --confirmed)Another repo. ship-init, ship-merge, cleanup, teardown-merged-worktree, worktree-rm and goal take a trailing --repo <absolute path>, so a session whose working directory is repo A can manage a goal of repo B without Orca: agent-harness ship-init feat ui x --goal "..." --repo /abs/path/to/B. The path must be the top level of a git checkout: B's main checkout, or a goal worktree of B for goal. A relative path, a subdirectory, a non-git directory, or --repo anywhere but last is refused. The goal registry and goal state are B's. The calling session's stop gate still reads its own checkout, so it neither blocks on nor binds to B's goal. ship-init --repo leaves a per-user marker under ~/.agent-harness/goals-foreign/. While B keeps goal files, every session's git guard sends every push through the full check, which gates a push into B's goal worktree by B's own reviews. The guard allows exactly that trailing shape as one plain command. A cd prefix, an env prefix such as CLAUDE_PROJECT_DIR=, and substitution stay denied.
The ship skill (skills/ship/) owns the stages, and the autonomous skill runs the toggle. The behaviour rules are
in .claude/rules/common/autonomy.md (Claude Code) and instructions/autonomy.md (OpenCode).
OpenCode. plugins/autonomy/index.ts enforces the flag: it blocks the question tool, injects autonomy context, denies forbidden git commands, and re-prompts the session when the stop gate blocks. The toggle state (.claude/state/autonomy.on, goal.json) is shared with Claude Code, so toggling in either harness toggles both. Toggle from the command palette ("Toggle autonomous mode"), with /autonomy-toggle, or with <leader>u.
Status panel. tui-plugins/autonomy-status.tsx (registered in tui.json) shows an ● AUTONOMOUS or ○ manual capsule in the session sidebar, then the goal with PR #n, fix i/max, and the status (escalated: <reason>; omitted while active). It refreshes every 3 s and raises a toast on each transition.
Per-repo config. Each repo can set .claude/agent-harness.json. Every key is optional:
| Key | Default when absent | Purpose |
|---|---|---|
base |
the repo default branch (gh repo view) |
PR base and the only merge target |
requiredChecks |
[] |
check-run names that must conclude success, skipped or neutral on the head |
reviewStatus |
unset (no rail) | optional. Set it only when the repo has an external status check. The commit status context that must be success on the head |
reviewStatusCreator |
unset (any creator) | optional, used with reviewStatus. Login that must have posted the status |
verify |
unset (verification-gate detection) | commands the ship verify step runs |
protectedPaths |
unset (no rail) | optional regexes. When set, a PR touching a match needs a human merge (--confirmed, which prompts) |
mergeMethod |
unset (repo's first allowed: squash, rebase, merge) | optional squash, rebase or merge; overridden by ship-merge --method |
{
"base": "main",
"requiredChecks": ["build", "test"],
"reviewStatus": "ci-review",
"reviewStatusCreator": "github-actions[bot]",
"verify": ["npm run lint", "npm test"],
"protectedPaths": ["^\\.github/"]
}Merge gate. agent-harness ship-merge is the merge step of the loop and the only merge path. It checks hard facts,
not opinions. A refusal is input to the loop: the agent fixes the cause and retries. It refuses unless all of these hold:
- the autonomy flag is on, or
--confirmedis passed - the PR targets the base branch and is not a draft
- every
requiredChecksentry passed on the head - zero unresolved review threads
- the branch is up to date with the base branch
- no changed path matches
protectedPaths, unless--confirmedis passed (a human merges such a PR) - only when
reviewStatusis configured: the newest status with that context on the head issuccess, and its creator matchesreviewStatusCreatorwhen set
It then merges pinned to the head SHA. For a goal registered by ship-init, it runs agent-harness teardown-merged-worktree <pr>, which removes the goal worktree, the remote and local head branch, and the registry file, under the checks in the worktree destruction rule. It never touches the main checkout (cleanup --no-checkout), and the goal state (goal.json, autonomy.on) lives in the main checkout whichever worktree runs the command. For an unregistered PR it runs agent-harness cleanup <pr>: that deletes the PR's head branch on the remote and locally (the local branch only when fully merged), deletes the goal's recorded backup branches that the merge contains, moves the others (every pre-rebase snapshot after a squash merge) to refs/harness/backups/<name>, and switches the checkout to the updated base. Cleanup never removes a worktree; it reports one that holds the branch. In autonomous mode cleanup needs the goal to track the PR; once the goal worktree is gone, the registry entry is that proof only when it is the one entry for the PR, records the PR's head branch, is not escalated or blocked, its worktree path no longer exists, and no worktree has the branch checked out. An unregistered PR is refused. --keep-branch keeps the head branch. The merge method is chosen with --method squash|rebase|merge; without it the script uses mergeMethod from .claude/agent-harness.json, else the repo's first allowed method (squash, rebase, merge). A method the repo disallows is refused.
Review. Ship stage 6 runs a thorough local review before any push: code-reviewer, security-reviewer, and the stack cop
(angular-cop or dotnet-cop) on the diff. The agent fixes confirmed Important findings and re-runs the
review after each fix (the loop stops when the same findings repeat, with a safety ceiling of 10 rounds; it then escalates with the remaining Important findings). The push guard denies a push or gh pr create without a recorded pass. The agent posts one summary comment for a human to audit after opening the PR. That review is a quality step, not a merge
rail. No GitHub status is created, and ship-merge does not trust the comment.
Push rules. Pushes to the base branch are forbidden in every mode, with or without force. git push --mirror, --all, and --no-verify are forbidden too. Force pushes (--force, --force-with-lease, -f, +refspec) are allowed on other branches.
Notifications. The run notifies only when a human needs to act, or when the goal ends: question when it must stop for an answer, waiting on a permission or idle prompt, failure on escalation, and done when the PR is merged. No progress notifications.
Limits.
- These are client-side guardrails, not a security boundary. An agent with shell access can call
ghdirectly. - Branch protection on the base branch (required reviews, required checks, restricted pushes) is the real enforcement. Set it on the host.
- A PR that matches
protectedPathsneeds a human merge (--confirmed), when that key is set. Without the key, autonomous mode merges every PR that passes the gate. - OpenCode does not register Claude Code hooks.
plugins/autonomy/index.tsrunsautonomy-git-guard.shbefore each shell call andship-stop-gate.shwhen a root session goes idle (instructions/autonomy.md).
Parity. The autonomy-status mod (.claude/mods/, status line and band) is Claude Code only. OpenCode has no equivalent.
Ces catalogues décrivent l'arbre Conductor à la racine, sauf mention de Monolith. Le défaut d'installation est Monolith. Le schéma partagé est Choisir une variante et Comment une demande avance. Conductor embarque un conductor en lecture seule et 25 spécialistes. Monolith garde 9 agents de revue et replie les autres rôles dans des skills.
Chiffres recomptés le 2026-11-06 : 26 agents (1 conductor + 25 spécialistes) · 80 skills (skills/*/SKILL.md) · 53 modèles de commandes (dont 37 épinglés dans opencode.jsonc) · 6 instructions chargées au démarrage (13 fichiers dans instructions/) · 17 fichiers .claude/rules/ · 21 scripts dans .claude/hooks/ · 6 serveurs MCP · 4 fichiers d'outils custom · 3 plugins TUI activés dans tui.json.
Livré sur master jusqu'à fa50d8e (2026-10-18). Le numéro du plugin est version dans scripts/cursor-plugin/config.json. L'historique est scripts/cursor-plugin/CHANGELOG.md.
| PR | Plugin | Ce qui est livré |
|---|---|---|
| #25 | 0.2.0 | Garde semver dans scripts/cursor-plugin/check.mjs. Une modification des sources du plugin doit porter une version strictement supérieure à la base. |
| #27 | 0.3.0 | CodeMemory reste éteint dans les sessions cloud et distantes, sauf override. Les tours revue/correctif de ship s'arrêtent à 3. |
| #28 | 0.4.0 | Les findings sont Important, Nit ou Pre-existing. Seul Important bloque. Le verdict est Approve ou Block. |
| #29 | 0.4.1 | Échelle d'application : code, puis lint, tests ou analyse statique, puis une règle en prose, puis la revue humaine. |
| #30 | 0.4.2 | Le REVIEW.md d'un projet est la référence des tags quand il existe. Le modèle de PR ajoute Risk, How to revert et Tier. |
| #32 | 0.4.3 | Les règles Cursor toujours appliquées passent de 21 fichiers (1438 lignes) à 7 fichiers (502 lignes). Le reste se charge par glob de chemin ou par skill. |
| #33 | 0.4.4 | create-verification-skill écrit l'override projet de verify-this à partir des commandes build, test et e2e du dépôt. |
| #35 | 0.4.6 | socratic-design fait un spike lorsqu'un essai de moins de 30 minutes peut trancher la question, et présente ce résultat. Une tâche L est reformulée dans les mots de l'agent avant le plan. |
Semver (#25, note de politique dans #29). scripts/cursor-plugin/check.mjs compare les sources du plugin au merge-base avec la branche de base (origin/master, origin/$GITHUB_BASE_REF en GitHub Actions, ou CURSOR_PLUGIN_BASE). La version doit être MAJOR.MINOR.PATCH, strictement supérieure, et le changelog doit avoir un titre pour elle. Le build copie scripts/cursor-plugin/config.json dans plugins/fmflurry-harness/.cursor-plugin/plugin.json. Un edit du README.md racine n'est pas une source du plugin. #25 a livré cette garde en 0.2.0, avec patch, minor et major comme suggestions. Depuis 0.4.1, scripts/cursor-plugin/CHANGELOG.md demande un bump de patch pour les changements de plugin suivants. La garde ne l'impose pas : elle accepte encore un bump minor ou major, et elle affiche toujours ces suggestions.
CodeMemory (#27). FMFLURRY_CODEMEMORY=on|off|auto gagne. Absent, auto, ou toute autre valeur : détection. L'ordre est dans docs/codememory-cloud.md, implémenté dans plugins/code-memory-lib/mode.ts et .claude/hooks/codememory-mode.sh :
CLAUDE_CODE_REMOTEvrai (true,1ouyes), ouCLAUDE_CODE_REMOTE_SESSION_IDnon vide : éteint.- Métadonnée Cursor
agent/runtimeégale àmanaged, lue parGET /v1/meta-data/agent/runtimesurCURSOR_AGENT_SOCKET(défaut/run/cursor/api.sock) : éteint. - CI :
GITHUB_ACTIONS,GITLAB_CI,CIRCLECIouBUILDKITEvrais, ouTF_BUILDouJENKINS_URLdéfini : éteint.CI=trueseul est ignoré, parce que.claude/settings.jsonposeCIpour chaque session Claude Code. - macOS (
unameDarwin), et aucun signal ci-dessus : allumé, même si les services locaux sont arrêtés. - Sinon FalkorDB
127.0.0.1:6379et Qdrant127.0.0.1:6333doivent tous les deux accepter une connexion TCP, sinon CodeMemory reste éteint. Une sonde en échec veut dire « down », pas une erreur.
Les hooks et les plugins OpenCode code-memory ne font rien quand la décision est éteinte. FMFLURRY_CODEMEMORY=on le garde allumé dans le cloud. off le garde éteint sur un portable.
Mémoire projet. Activée par défaut. /memory-init (skill project-memory) crée un AGENTS.md racine court (80 lignes environ au plus) et docs/memory/ : INDEX.md, contexts/<bounded-context>.md, des ADR immuables dans decisions/NNNN-<slug>.md, et glossary.md. Chaque doc porte un frontmatter owner, reviewed et refs. Un fichier de contexte n'est lu que si la tâche touche ce bounded context (instructions/project-memory.md). agent-harness memory-lint (.claude/hooks/memory-lint.sh) échoue sur un owner ou un reviewed manquant, une date reviewed de plus de 90 jours, ou une ref morte (chemin ou symbole). Le stop gate de ship ajoute ses constats à la raison du blocage. pr-report-check et le hook gh pr create le lancent, et exigent mémoire : màj ou mémoire : aucun changement dans le corps de la PR quand docs/memory existe. FMFLURRY_MEMORY=off la désactive.
Tags de revue (#28, #30). Le mapping par défaut est Finding tags dans .claude/agents/code-reviewer.md. Important bloque la fusion. Nit ne bloque pas. Pre-existing ne bloque pas, quelle que soit la gravité. Approve veut dire qu'aucun finding Important n'est ouvert (lint vert, et aucun commentaire interdit). Block veut dire qu'au moins un finding Important est ouvert. Il n'y a pas de verdict Warning. scripts/cursor-plugin/check.mjs rejette les anciens mots de sévérité de revue en capitales dans les sources du harness. La liste d'exceptions pour les usages hors revue (GDPR, santé base de données, lignes de risque de /plan, npm audit, CVE) est scripts/cursor-plugin/review-tags.mjs. Quand le dépôt en revue a un REVIEW.md à la racine, ce fichier est le seul mapping. Le reviewer le cite et n'applique pas la table par défaut en second mapping. Ce dépôt livre REVIEW.md.
Échelle d'application (#29). .claude/rules/common/enforcement-ladder.md (copie Cursor plugins/fmflurry-harness/rules/enforcement-ladder.mdc) et instructions/enforcement-ladder.md (chargée depuis opencode.jsonc). Placer le correctif au premier niveau qui peut le tenir : code, puis lint, tests ou analyse statique, puis une règle en prose, puis la revue humaine. Une règle en prose porte why-not-tooled:. Ajouter de la prose toujours chargée suppose d'en supprimer ou d'en raccourcir d'autre dans le même changement.
Modèle de PR (#30). .github/pull_request_template.md contient Summary, Risk, How to revert et Tier. Tier vaut T1, T2 ou T3, selon le blast radius, les chemins protégés et la taille du diff. Ce n'est pas un tag de finding. /setup-harness écrit ce modèle quand .github/pull_request_template.md manque, et laisse un fichier existant (scripts/cursor-plugin/templates/setup-harness.md, construit vers plugins/fmflurry-harness/skills/setup-harness/SKILL.md). commands/pr.md et commands/create-pull-request.md remplissent le modèle quand il existe. Depuis 0.4.18 le modèle a aussi ## Visual report. Le harness commit un HTML show-me et un PNG dans docs/pr-reports/<branch-slug>.html et .png, intègre le PNG et lie le HTML. .claude/hooks/pr-visual-report.sh bloque un corps gh ou az sans cette section. Une coquille de doc ou un bump de version seul peut cocher Skip et écrire la raison. Conductor et Monolith partagent le skill pr-visual-report. agent-harness pr-report écrit les fichiers, agent-harness pr-report-links imprime la section avec des liens absolus épinglés au commit du rapport (un lien relatif ouvre une page de comparaison et est refusé depuis 0.4.33), et agent-harness pr-report-check vérifie le corps.
Rules diet (#32). Plugin 0.4.3 (fa50d8e). plugins/fmflurry-harness/rules/ compte 7 fichiers alwaysApply: true, 502 lignes, contre 21 fichiers et 1438 lignes à 62aa030. En 0.4.3 c'étaient autonomy.mdc, conductor.mdc, enforcement-ladder.mdc, orchestration.mdc, question-handling.mdc, tool-budget.mdc et verification-gate.mdc. rules.always dans scripts/cursor-plugin/config.json liste les six règles common/. Le build Conductor ajoute rules/conductor.mdc. Le build Monolith par défaut du plugin 0.4.19 remplace ce fichier par rules/monolith.mdc et retire la first-tool gate. Ce build n'a pas de rules/always__harness.mdc. Le compte toujours chargé reste 7. Les règles liées à des fichiers restent dans ce répertoire avec alwaysApply: false et globs : code-comments, coding-style, security, testing, et les cinq packs typescript-*. Celles-ci ont quitté l'ensemble toujours chargé et sont des skills : agent-roster, brief-contract, codebase-exploration, git-workflow, harness-parity, hooks, open-pr-check, patterns, performance, worktree-destruction-safety. skills/ai-ecosystem-audit/SKILL.md (Always-on budget) compte les règles globales de session. Plus de 8 règles Cursor alwaysApply: true est un finding confirmé.
- Reproductibilite: meme comportement entre machines/sessions.
- Qualite: TDD a la demande, verification reguliere, conventions centralisees.
- Securite: skill
security-reviewdisponible à la demande + hooks pre-tool-use (security warnings).
- Configs:
opencode.jsonc,dcp.jsonc(dynamic context pruning),tui.json(theme TUI). - Profils:
profiles/<name>/(overrideopencode.jsonc+AGENTS.mdpar profil). - Skills:
skills/*/SKILL.md(+ ressources auxiliaires) — ensemble canonical, partage avec Claude Code viasync-skills.sh. - Prompts agents:
prompts/agents/*.txt. - Commandes slash:
commands/*.md. - Plugins OpenCode:
plugins/<name>/index.ts(+plugins/code-memory-lib/+plugins/lib/, avecplugins/lib/kdco-primitives/). - TUI plugins:
tui-plugins/*.tsx(registered intui.json;autonomy-status.tsxis the autonomy sidebar panel). - Outils custom:
tools/*.ts. - Contextes (memos de mode):
contexts/*.md. - Instructions globales:
instructions/*.md(6 chargees au demarrage; le reste est un skill ou un fichier non charge). - Scripts:
scripts/setup-package-manager.js,scripts/codemaps/generate.ts,scripts/settings-sync.sh,scripts/sync-skills.sh,scripts/skill-drift-check.sh. - Installeurs:
bootstrap.sh,bootstrap.ps1,install.sh,install-cursor.sh../install.shdemande Conductor ou Monolith (defaut Monolith);./install.sh --yesetsettings-syncinstallent Monolith sans variante../install.sh conductor,./install.sh monolith,--variantetHARNESS_VARIANTfont le meme choix sans prompt.orchestrationest un alias de Conductor../install.sh --localet./install-cursor.shsont Monolith par defaut. Une session Claude Code distante (CLAUDE_CODE_REMOTE=true) lance.claude/hooks/cloud-session-bootstrap.shauSessionStartsi le projet ne vendore pas le harness../install.sh --statuset./install-cursor.sh --statusaffichent la variante installee../install.sh --localapplique aussi.harness-local/(jamais modifié par l'installeur) par-dessus.claude/,.opencode/,AGENTS.md,.cursor/et.agents/, y compris quand le clone est atteint par un lien symbolique. Un répertoire ignoré affiche la raison. Le mode local écrit./.claude/mods/autonomy-status, et Monolith écrit.opencode/instructions/monolith.md..harness-local/excludeliste les skills et chemins à ne pas réinstaller. Le hook domain-rules reste éteint tant que.harness-local/domain-rules.jsonne contient pas"enabled": true. Détail:docs/harness-local.md../install.sh --local --statusaffiche l'overlay et les exclusions. - Mirror Claude Code:
.claude/CLAUDE.md,.claude/settings.json,.claude/hooks/,.claude/rules/,.claude/agents/,.claude/skills/,.claude/commands/. - Exclusions volontaires (
.gitignore):node_modules/,antigravity-*,.DS_Store, fichiers locaux.env*sauf.env.example, répertoire runtimeskills/skill-creator/.
Le fichier orchestre six choses:
instructions: docs toujours chargees au demarrage (6) — routing sous-agent, question handling, verification gate, autonomie, tool budget, enforcement ladder. Le reste est un skill ou une instruction hors tableau (code-comments,coding-style,testing,security).default_agent:conductor(orchestrateur sans droit d'ecriture).agent: definitions des sous-agents (prompt + outils autorises). Aucun agent ne posemodel, et le fichier n'a pas demodelau niveau racine. Chacun utilise le modele de la session.command: mappe/<name>-> template + sous-agent +subtask; 21 entrees epinglees.mcp: six serveurs —code-memoryactif;context7,blender,wallaby,Figma,smartbear-swaggerdesactives par defaut. Permscode-memory_*pre-allowlistees pour chaque sous-agent.plugins: le plugin npmopencode-skill-creator. OpenCode 2 charge seul les dossiers de plugins locaux sousplugins/.
dcp.jsonc est le stub de config du plugin externe optionnel Dynamic Context Pruning.
Ce tableau est le roster Conductor, defini dans opencode.jsonc (champ agent) — 26 entrees: le primary plus 25 sous-agents. build et plan sont des overrides built-in, livres desactives.
Monolith n'installe pas ce roster. Il garde 9 agents. L'agent principal coordonne et peut ecrire. /orchestrate charge le skill conductor.
| Agent | Acces | Role | Declencheur |
|---|---|---|---|
conductor |
read-only | Orchestrateur. write/edit interdits; chaque modif via Task. |
Agent par defaut |
planner |
read-only | Plan + risques + ordre des phases. | Features complexes |
architect |
read-only | Design systeme, scalabilite, frontieres de modules. | Decisions structurantes |
coder |
writable | Implementation pure (hors tests). Self-check build+lint+standards. Gate socratique. | Toute modif de code |
writer |
writable | Docs/markdown/HTML/texte. Refuse le code source. | Prose, README, ADR, rapports |
code-reviewer |
read-only | Revue diff/PR. Findings seulement; fixes vers coder. Possede /cop-review. |
Demandes de revue |
comment-judge |
read-only | Verdict rubric sur commentaires; REVIEW (diff) ou PURGE (dossier). JSON. | Revue/purge commentaires |
haruspex-commentorum |
writable | Purge des commentaires selon verdicts. | Triggered-only (purge) |
ecosystem-auditor |
read-only | Audit evidence-first parite OpenCode/Claude. | /ecosystem-audit |
angular-cop |
read-only | Revue pre-merge Angular + TypeScript. | Revue PR Angular |
dotnet-cop |
read-only | Revue pre-merge .NET 10 Minimal API. | Revue PR .NET |
gdpr-specialist |
read-only | Conformite GDPR/CNIL (consent, cookies, PII, retention, transferts, breach 72h). | Features sensibles |
security-reviewer |
read-only | Revue OWASP/secrets/deps. Remediation vers coder. |
Auth, input, endpoints, secrets |
tdd-guide |
writable (tests) | RED → GREEN → REFACTOR + 80%. /tdd refactor pose des characterization tests deja verts. Delegue l'implementation au coder. |
Features, fixes, refactors |
build-error-resolver |
writable | Fix build/typecheck/lint/TS, diff minimal. | Build ou lint rouge |
e2e-runner |
writable | Tests E2E depuis l'override projet ou un runner decouvert. | Parcours navigateur |
doc-updater |
writable | Docs generees + codemaps. | /update-docs, /update-codemaps |
refactor-cleaner |
writable | Suppression code mort + consolidation. | Demandes de nettoyage |
database-reviewer |
read-only | PostgreSQL/Supabase: schema, perfs, RLS, migrations. | Revue SQL/migration/schema |
postgres-dba |
read-only | Ops instance live: health, vacuum/bloat, WAL, backups/PITR, pooling, upgrades. | /db-health, /db-backup-check |
api-spec-architect |
writable | Specs OpenAPI 3.1 Zalando; publication SwaggerHub optionnelle. | /api-spec |
git-specialist |
writable (git) | Branches, commits, push, PRs. | Taches git/commit/PR |
scout |
read-only | Manifeste de fichiers pour un scope inconnu. | Triggered-only (conductor) |
why-investigator |
read-only | Enquete une categorie de preuve. | Triggered-only (skill why) |
why-synthesizer |
read-only | Fusionne les findings en une reponse ponderee. | Triggered-only (skill why) |
gaudi |
writable | Blender / art 3D: modelisation, materiaux, lumiere, render, export glTF. | Triggered-only (3D) |
Modele de session. Aucun agent de opencode.jsonc ne pose model, et le fichier n'en pose pas au niveau racine. L'agent principal utilise le modele choisi pour la session. Un sous-agent utilise le modele de l'agent qui l'a lance (agents OpenCode). Une install Monolith fait de meme: le generateur n'ecrit pas model.
OPENCODE_REASONING_* n'est plus ecrit. Ces variables n'etaient exportees que dans le shell. opencode.jsonc ne les interpolait pas. Les champs de raisonnement d'une entree myMistral decrivent ce fournisseur. Ils ne choisissent pas le modele de la session.
Pour epingler un agent, posez model sur cet agent dans votre propre config OpenCode. Une reinstallation de ce harness n'ajoute pas d'epingle.
Cette section décrit Conductor. Sur Monolith l'agent principal peut écrire dès la première édition, et /orchestrate charge le skill conductor. Le parcours des trois hôtes est Comment une demande avance.
- Le conductor n'ecrit pas.
tools.write: false,tools.edit: false,permission.edit/write: deny; sa Task allowlist enumere chaque specialiste,*: denybloque le reste.instructions/subagent-routing.mdimpose un Task-first gate. - Flux canonique:
planner → (tdd-guide → coder) ou coder → code-reviewer → verify → git-specialist.- Fonctionnalite:
planner→/tdd(RED) →coder(GREEN) →/verify→/pr→/cop-review→ship-merge. - Refactor:
planner→/tdd refactor(characterization tests, verts immediatement, puis geles) →coder(restructure sans modifier ces tests) →/blast-radius→/verify(baseline contre treatment sur le meme pin) →/pr→/cop-review→ship-merge.
- Fonctionnalite:
- Brief contract (6 champs):
TASK,FILES,CHANGE,DONE-WHEN(commande executable),OUT OF SCOPE,CONTEXT ALREADY RESOLVED+BUDGET. - Questions: chaque ambiguite taggee
[BLOCKING]ou[NON-BLOCKING]; le conductor tente de resoudre depuis le repo avant de demander. - Verification gate: aucun "done" sans preuve fraiche (build/lint/tests executes, sortie collee).
- Tool budget: commandes de verification illimitees; exploration shell limitee (defaut 3/dispatch).
- Worktree safety: seul chemin de suppression
agent-harness worktree-rm <path> --confirmed(sans--confirmed: dry run, exit 3). Checks obligatoires : status, commits non poussés, activité (échec fermé si inconnue ; app Orca fermée :lsofdoit montrer qu'aucun processus n'a son répertoire courant dans le worktree, puis la suppression passe par git), autres checkouts du dépôt propres ou snapshotés (refsrefs/harness/snapshots/: contenu, modes, index, fichiers non suivis). Les fichiers ignorés, les dépôts git imbriqués non suivis (signalés en note) et le contenu des submodules ne sont pas couverts. Après suppression : re-scan des autres checkouts ; un checkout modifié n'est restauré que si son HEAD est inchangé et qu'il est propre, sinon exit 4 avec commandes d'inspection et de restauration, refs conservées. Chaque sha de snapshot est affiché avant la libération de sa ref. Lesgit worktree remove|prune|move(options globales et alias compris),orca worktree rmdirect etrm/mv/trash/rsync --delete/find -deleterécursifs sur un worktree ou son parent sont refusés par le guard, dans tous les modes. C'est une détection textuelle qui ne voit pas les commandes assemblées à l'exécution : la frontière réelle reste les checks du script.git worktree prune -nreste autorisé. En mode autonome,agent-harness worktree-rm <path> --confirmedretire un worktree propre dont la branche est fusionnée (pointe atteignable, arbres égaux, ough pr view --json stateàMERGED) et refuse un worktree sale, du travail non fusionné, le checkout principal, et un chemin qui n'est pas un worktree du dépôt.agent-harness teardown-merged-worktree <pr>retire le worktree d'un goal enregistré dont la PR est MERGED, en mode autonome, avec les checks relancés sur la tête de la PR ; il n'utilise jamais--forceet conserve le registre si une étape est partielle. Les worktrees de goal sont créés paragent-harness ship-initet enregistrés dans<git-common-dir>/agent-harness/goals/<slug>.json. - Codememory-first: les outils
code-memory_*d'abord;grep/readen repli seulement.
La delegation est imposee sur deux couches, donc le comportement reste identique que le primary soit Claude, GPT, DeepSeek ou un modele open-weight qui ignore les instructions en prose:
- Permissions —
conductoratools.write: false,tools.edit: false, etpermission.edit/write: denydansopencode.jsonc. L'allowlist Task enumere chaque specialiste legal;*: denybloque le reste. L'orchestrateur n'a litteralement aucun outil pour modifier des fichiers. - Guard plugins + prompt front-loaded —
plugins/secret-file-guard/index.tsavorte tout accesread/basha un fichier.envporteur de secret;plugins/tool-budget/index.tspousse la verification plutot que l'exploration (ne bloque jamais un appel).prompts/agents/conductor.txtplace les regles dures dans les premieres lignes, la table de routage en second, et six exemples few-shot User ->taskavec contre-exemples explicites;instructions/subagent-routing.mdimpose un Task-first gate avant inspection directe.
Chemins possibles: requete normale (routage via Task), mention @agent, commande slash (/plan, /tdd, /security).
53 modèles dans commands/ (recomptés le 2026-11-06) ; 37 épinglés dans le bloc command de opencode.jsonc. Ce bloc est le set Conductor. Monolith remap une valeur agent repliée : postgres-dba devient database-reviewer, et tout autre nom replié devient main, qui charge le skill correspondant (scripts/variants/dangling-agents.mjs). Beaucoup sont subtask: true. Le bloc épinglé est l'ensemble garanti ; l'auto-découverte éventuelle de commands/ n'est pas vérifiable ici, donc considérer les autres comme Claude-side ou dépendantes de la découverte.
| Commande | Sous-agent | But |
|---|---|---|
/git |
git-specialist | Operations git encadrees (branche/commit). |
/push-changes |
git-specialist | Commit + push (avec garde sur upstream). |
/plan |
planner | Plan d'implementation. |
/tdd |
tdd-guide | Cycle TDD. /tdd refactor fige le comportement actuel. |
/api-spec |
api-spec-architect | Generation de specs OpenAPI 3.1. |
/cop-review |
code-reviewer | Revue pre-merge directe; selectionne le guide du stack. |
/security |
security-reviewer | Audit securite. |
/gdpr-review |
gdpr-specialist | Audit conformite GDPR/CNIL. |
/build-fix |
build-error-resolver | Resolution build/TS errors. |
/e2e |
e2e-runner | Tests E2E depuis l'override projet ou le runner decouvert. |
/refactor-clean |
refactor-cleaner | Nettoyage code mort. |
/orchestrate |
planner | Orchestration multi-agents. |
/verify |
(conductor) | Boucle de verification. |
/eval |
(conductor) | Evaluation contre criteres. |
/update-docs |
doc-updater | Mise a jour de la doc. |
/update-codemaps |
doc-updater | Genere docs/CODEMAPS/. |
/test-coverage |
tdd-guide | Analyse coverage. |
/skill-create |
pas de clé agent |
Génère une skill depuis l'historique git. Tourne comme l'agent par défaut. |
/db-health |
postgres-dba | Bilan sante PostgreSQL read-only. |
/dependabot-friday |
git-specialist | Triage PR Dependabot (rapport seulement). |
/db-backup-check |
postgres-dba | Audit backup/PITR. |
/ship |
conductor | Un objectif, de la clarification à la fusion. |
/autonomous |
conductor | Active, coupe, ou affiche le mode autonome. |
/pr |
git-specialist | Ouvre une PR selon le modèle du dépôt. |
/memory-init |
writer | Échafaude la mémoire projet. |
/show-me |
writer | Schéma HTML hors ligne et captures PNG. |
/show-your-work |
conductor | Journal TSV des décisions. |
/comment-judge |
comment-judge | Verdict de rubric sur les commentaires. |
/interfectio-commentarum |
conductor | Purge de commentaires Haruspex. |
/for-real |
conductor | Reformule le dernier message en langage clair. |
/why |
conductor | Justification de conception, avec citations. |
/blast-radius |
conductor | Ce qu'un changement peut casser, en exécutant le code. |
/chimera |
conductor | Candidats parallèles, puis greffe. |
/fix-ci |
conductor | Corrige les checks de PR en échec. |
/loop-on-ci |
conductor | Surveille les checks et itère les correctifs. |
/get-pr-comments |
git-specialist | Résume les commentaires de revue. |
/fix-merge-conflicts |
git-specialist | Rebase à travers les conflits. |
Non epinglees (16): /checkpoint, /pm2, /setup-pm, /ecosystem-audit, /create-pull-request, et la famille OpenSpec /opsx-*. Claude-only: arena.md, arena-new-prompt.md.
Recomptés le 2026-11-06 : skills/*/SKILL.md compte 80 skills. Les groupes ci-dessous nomment cet ensemble. Douze d'entre eux sont dans la dernière puce, hors des groupes plus anciens. skill-creator/ est git-ignoré et hors des 80. scripts/sync-skills.sh calcule l'union canonique (root skills/ ∪ .claude/skills/, root gagne), exclut le runtime skills/skill-creator/, et copie vers chaque cible. Attribution dans skills/THIRD_PARTY_NOTICES.md. Les références de classes d'attaque dans skills/security-review/references/ sont des copies conformes de cloudflare/security-audit-skill au commit c1c8a8c1471069fb0e188eeaff69b8e8db6564a8 (MIT, Copyright (c) 2025-2026 Cloudflare, Inc.). Le texte de licence est LICENSE-cloudflare-security-audit.
- Planification & design (5):
socratic-design,chimera,api-spec-openapi,why,blast-radius. - Revue & qualite (6):
comment-judge,interfectio-commentarum,verify-this,create-verification-skill,test-behavior-not-implementation,ai-ecosystem-audit. - TDD & tests (3):
tdd-workflow,tdd,e2e. - CI & git (5):
fix-ci,fix-merge-conflicts,get-pr-comments,loop-on-ci,git-workflow. - Angular (4):
angular-clean-architecture,angular-ddd,angular-cop,angular-accessibility. - .NET (3):
dotnet-clean-architecture,dotnet-ddd,dotnet-cop. - Three.js / 3D (1):
threejs, dix sujets sousreferences/. - Playbooks PostgreSQL (4):
postgres-{health-check,performance-tuning,backup-restore,container-ops}. - Playwright E2E (2):
playwright-e2e-authoring,playwright-e2e-review. - Workflow OpenSpec (1):
openspec, onze workflows sousreferences/. - Ecriture & communication (7):
humanizer,for-real,caveman,caveman-commit,caveman-review,show-me,show-your-work. - Harness & config (5):
config-sync,harness-parity,skill-authoring,treetopia,strategic-compact. - Securite (1):
security-review. Conformite (1):gdpr-compliance. Domaine (2):flurryx,transloco. Standards (1):coding-standards. - Skills de role a la demande:
planner,coder,writer,doc-updater,architect,refactor-cleaner,scout,gaudi,testing,security,coding-style,code-comments,autonomy,question-handling,enforcement-ladder,tool-budget,verification-gate. Monolith les charge dans la boucle principale. Conductor garde les agents correspondants. - Aussi dans l'arbre (12) :
agent-roster,autonomous,brief-contract,codebase-exploration,hooks,open-pr-check,patterns,performance,project-memory,pr-visual-report,ship,worktree-destruction-safety.
Les ensembles PostgreSQL et Playwright sont des playbooks projet specifiques a gc.platform. /e2e et e2e-runner ne supposent pas cette stack : ils lisent e2e.json ou decouvrent la commande de demarrage, les ports et le runner (skills/e2e). Les playbooks Playwright ne se chargent que si l'override les nomme. "enabled": false desactive /e2e. Un consommateur qui n'en veut pas omet playwright-e2e-authoring et playwright-e2e-review au vendoring. skill-creator est runtime-only, git-ignore et jamais synchronise.
6 instructions de demarrage (instructions/*.md): routage, questions, verification, autonomie, budget d'outils, enforcement ladder. Le reste est un skill ou une regle bornee par paths:.
Le cote Claude Code garde ces six regles sans paths:, plus les regles bornees (commentaires, style, securite, tests) et 5 packs rules/typescript/.
Deux fichiers d'instructions distincts: le CLAUDE.md racine (guidelines comportementales, alimente par les packs via @rules/...) et .claude/CLAUDE.md (instructions globales installees dans ~/.claude, avec l'essentiel cross-projet).
Les plugins sont des dossiers OpenCode 2 construits avec @opencode/plugin@2.2.7 (plugins/<nom>/index.ts, Plugin.define). OpenCode charge chaque dossier de plugins/ ; plugins dans opencode.jsonc ne nomme que le plugin npm opencode-skill-creator.
plugins/secret-file-guard/index.ts— bloque l'accesread/bashaux.envporteurs de secret;.env.example/.sample/.templaterestent lisibles.plugins/mistral-affinity/index.ts— headerx-affinitystable pour l'affinite de cache Mistral.plugins/tool-budget/index.ts— pousse la verification plutot que l'exploration (ne bloque jamais).plugins/code-memory/index.ts+plugins/code-memory-lib/— nudges auto-retrieve / auto-learn CodeMemory (no-op sans CLI).plugins/lib/(withplugins/lib/kdco-primitives/) — utilities partages.opencode-skill-creator(npm externe) — scaffolding et benchmark de skills.plugins/kpi/index.ts— côté OpenCode du journal KPI.plugins/autonomy/index.ts— côté OpenCode du mode autonome. Voir Mode autonome.plugins/domain-rules/index.ts— éteint tant que.harness-local/domain-rules.jsonne l'active pas.- Non charges:
plugins/ecc-hooks.ts.disabled,plugins/worktree.disabled,plugins/figma-rag.md,tui-plugins/caveman.tsx.disabled.
Hooks Claude (.claude/hooks/, 21 scripts, recomptés le 2026-11-06) : notification.sh, pre-tool-use.sh, prefer-code-memory.sh, rtk-rewrite.sh, stop.sh, subagent-stop.sh, tool-budget.sh, autonomy-ask-guard.sh, autonomy-context.sh, autonomy-git-guard.sh, cache-invalidation.sh, cloud-session-bootstrap.sh, codememory-mode.sh, commit-provenance.sh, domain-rules.sh, goal-state.sh, kpi-emit.sh, memory-lint.sh, orca-notify.sh, pr-visual-report.sh, ship-stop-gate.sh.
Outils OpenCode reutilisables exposes via tools/index.ts:
tools/run-tests.ts— detecte package manager + framework et construit la commande de test.tools/check-coverage.ts— lit les rapports coverage et compare a un seuil.tools/security-audit.ts— scan deps + secrets + patterns a risque.
tui-plugins/panda-banner.tsx— banniere SolidJS affichant un en-tete panda en art ASCII/blocs.tui-plugins/autonomy-status.tsx— capsule de la barre latérale pour le mode autonome, enregistrée danstui.json. Le comportement est dans Mode autonome.
CLAUDE.md— instructions globales (noany, facade != UseCase).settings.json— permissions allow/deny, env vars (API_TIMEOUT_MS=3000000,CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1,CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=80),"model": "opus"pour l'agent principal Claude Code, hooksPreToolUse/PostToolUse/Stop. Conductor et Monolith partagent ce fichier. Initialisé à la première install dans~/.claudeet dans le.claudedu projet. Une valeurmodeldéjà présente est conservée.hooks/*.sh— 21 scripts. La liste est sous Plugins & hooks.rules/common/*.md+rules/typescript/*.md— 17 fichiers (recomptés le 2026-11-06). Six sousrules/common/n'ont pas de clépaths:. Six sousrules/common/sont bornés (code-comments,coding-style,security,testing,cache-invalidation,project-memory). Cinq packstypescript/restent bornés.agents/*.md— 26 agents mirroir du roster OpenCode.commands/*.md— commandes Claude (/create-pull-request,/update-codemaps, arena, OpenSpec).skills/**— miroir des skills, synchronisé viascripts/sync-skills.shà l'install. Pas garanti identique àskills/du jour (le set canonical grandit entre les syncs):skills/reste la source de verite;settings-sync --skills-onlypour reconcilier.
Deux repertoires, une source de verite: le lab (ton clone de ce repo) et le live (~/.config/opencode, ~/.claude). Rien ne surveille le filesystem — tu pull, puis tu sync.
install.shmerge additivement, ne supprime jamais la config utilisateur; re-executable et idempotent.settings-sync(scripts/settings-sync.sh) resout le repo et lance l'install;--skills-only= chemin rapide skills;--whereaffiche le chemin.scripts/sync-skills.shcalcule l'union canonique et copie vers chaque harness.scripts/skill-drift-check.sh— detecteur read-only de drift entre copies de skills; sort non-zero en cas de divergence.- Le skill
config-syncfait la meme propagation cote agent. install-cursor.shgénère un plugin Cursor (node scripts/build-cursor-plugin.mjs->plugins/fmflurry-harness/) et le copie dans~/.cursor/plugins/local/fmflurry-harness, puis Developer: Reload Window dans Cursor. Le build par défaut est Monolith : l'agent principal peut écrire, il n'y a pas de first-tool gate, et/orchestrateest optionnel../install-cursor.sh --variant conductor(ouHARNESS_VARIANT=conductor ./install-cursor.sh) construit Conductor../install-cursor.sh --statusaffiche la variante lue dans.harness-variant. Il installe aussi le CLIagent-harness, avec le même helper queinstall.sh: scripts dans~/.local/share/fmflurry-harness/scripts/agent-harness, wrapper~/.local/bin/agent-harness. Un second passage affiche ces chemins et n'ajoute pas une seconde commande. Options :--yes,--link(symlink au lieu de copie),--migrate-legacy(sauvegarde puis supprime ce que l'ancien installeur a copié dans~/.cursor, en gardant vos propres entrées),--uninstall,--no-backup,--variant,--status. Limites : pas de liste d'outils par agent, délégation par instruction uniquement, hooks Notification non supportés. Les tiers restent des modèles Cursor :grok-4.7,grok-4.6etcomposer-2.5.
Parité : les harnesses sont synchronisés à l'install. Recomptés le 2026-11-06, skills/ = 80 et le miroir .claude/skills/ = 41. Lancer settings-sync --skills-only pour réconcilier.
Le numéro installé est version dans scripts/cursor-plugin/config.json (0.4.36 dans cet arbre). node scripts/build-cursor-plugin.mjs le copie dans plugins/fmflurry-harness/.cursor-plugin/plugin.json et copie scripts/cursor-plugin/CHANGELOG.md dans le plugin. node scripts/cursor-plugin/check.mjs echoue si ces deux versions divergent ou si le changelog n'a pas de titre pour la version courante. L'entree marketplace n'a pas de version. Le package.json racine versionne le depot settings (releases GitHub), pas ce plugin.
Monter la version a la main dans chaque PR qui touche le contenu du plugin ou ses entrees de build :
- patch — correctifs, chores, retouches de doc du plugin
- minor — nouveaux agents, skills, commandes, regles, ou comportement
- major — ruptures : agents ou skills renommes ou retires, cles de tier changees, contrat de l'installeur change
Depuis le plugin 0.4.1, scripts/cursor-plugin/CHANGELOG.md demande un bump de patch pour chaque changement de plugin suivant. Le check exige seulement une version strictement supérieure à la base. Il ne refuse pas un bump minor ou major.
Le check compare l'arbre de travail au merge-base avec la branche de base : un edit du README racine n'exige pas de bump. La version a depasser est la pointe de la branche de base (origin/master, origin/$GITHUB_BASE_REF en CI, ou CURSOR_PLUGIN_BASE). Sans aucune de ces refs, le check affiche un message et continue.
bump the plugin version + changelog in any PR touching plugin sources.
Le parcours des deux variantes est Comment une demande avance. Les quatre étapes ci-dessous sont le démarrage OpenCode quand la variante installée est Conductor.
- Demarrage: OpenCode charge
opencode.jsonc-> 6 instructions globales -> auto-charge chaque plugin deplugins/plus les plugins TUI enregistres danstui.json. Les skills se chargent selon leur description. - Dev:
conductorexecute — il n'a pas le droit d'ecrire; il dispatche des Task vers les specialistes.secret-file-guardbloque l'acces.env;tool-budgetpousse la verification. - Workflow: routage via Task (impose par permissions);
/plan,/tdd,/security, etc. forcent explicitement le meme routage. Brief contract, question protocol et verification gate encadrent chaque passage. - Idle : le plugin
autonomylance le stop gate et envoie la notification d'inactivité.
Le mode autonome permet à l'agent de mener un objectif de la clarification jusqu'à une PR fusionnée. Activez-le, puis lancez /ship <goal>. Avec le flag désactivé, l'agent demande avant chaque étape irréversible, et une fusion nécessite --confirmed. Activer le flag ne démarre aucun travail (skills/autonomous/SKILL.md).
Le run est une boucle, tenue par skills/ship/SKILL.md : implémenter, vérifier, revue locale, pousser et ouvrir la PR, CI, puis agent-harness ship-merge. Un blocage que l'agent peut corriger (un finding Important confirmé, un check en échec, un conflit, une branche en retard, un fil non résolu, un refus de fusion) le renvoie vers la correction, puis vers une nouvelle revue locale, puis vers le push, la CI et une nouvelle tentative de fusion. Il se termine en done (PR fusionnée et worktree du goal retiré) ou escaladé.
Comment le lancer. Le texte du goal est l'argument de /ship. Le flag est aussi agent-harness autonomy on|off|status (scripts/agent-harness/autonomy.sh). install.sh installe ce wrapper dans ~/.local/bin/agent-harness quand Claude Code ou OpenCode est une cible d'install. install-cursor.sh installe le même wrapper, qui pointe vers ~/.local/share/fmflurry-harness.
- Claude Code. Il n'y a pas de
.claude/commands/ship.md./ship <goal>est le skillship,skills/ship/SKILL.md.install.shlancescripts/sync-skills.sh, qui le copie vers~/.claude/skills/ship./autonomous on|off|statusestskills/autonomous/SKILL.md(disable-model-invocation: true, donc invoqué par l'utilisateur). La règle de comportement est.claude/rules/common/autonomy.md. Le hook Stop est.claude/hooks/ship-stop-gate.sh, branché depuis.claude/settings.json. - OpenCode.
/shipet/autonomoussont épinglés dansopencode.jsonc(command.ship,command.autonomous), tous deux surconductor, templatescommands/ship.mdetcommands/autonomous.md. La règle chargée au démarrage estinstructions/autonomy.md.plugins/autonomy/index.tsbloque l'outilquestion, injecte le contexte d'autonomie, refuse les commandes git interdites, et relance la session racine quand le stop gate bloque. La bascule de la barre latérale esttui-plugins/autonomy-status.tsx(enregistrée danstui.json) : palette « Toggle autonomous mode »,/autonomy-toggle, ou<leader>u. - Cursor.
/ship <goal>estplugins/fmflurry-harness/commands/ship.md(construit depuiscommands/ship.mdparscripts/build-cursor-plugin.mjs). Il chargeplugins/fmflurry-harness/skills/ship/SKILL.md./autonomousestplugins/fmflurry-harness/commands/autonomous.mdetplugins/fmflurry-harness/skills/autonomous/SKILL.md. La règle toujours active estplugins/fmflurry-harness/rules/autonomy.mdc. L'entréestopdeplugins/fmflurry-harness/hooks/hooks.jsonlancehooks/scripts/ship-stop-gate.sh. Ce hook appelleagent-harnessdepuis lePATH.install-cursor.shinstalle cette commande dans~/.local/bin/agent-harness.
Boucle de revue. L'étape 6 de skills/ship/SKILL.md relit git diff <base>...HEAD avec code-reviewer, security-reviewer, et le cop du stack quand il s'applique (angular-cop ou dotnet-cop ; database-reviewer si le SQL a changé). L'agent confirme chaque finding contre le code. Seul un finding Important confirmé bloque. Nit et Pre-existing ne bloquent pas. Les tags viennent du REVIEW.md du dépôt quand il existe, sinon de Finding tags dans .claude/agents/code-reviewer.md. Chaque verdict est enregistré avec agent-harness goal review code|security pass|fail. Le garde de push (.claude/hooks/autonomy-git-guard.sh) refuse git push et gh pr create tant qu'un goal actif n'a pas de verdicts code et sécurité positifs pour le diff exact (un hash du diff contre origin/<base>, hors docs/agent-reports/) ; les pushes vers backup/* et le commit de rapport ne sont pas gardés. Une fois la PR ouverte, un commentaire de synthèse est publié (skills/ship/references/review-format.md). Ce commentaire est une trace d'audit. ship-merge ne le lit pas. Chaque correctif CI ou de commentaire ultérieur est relu localement avant son push.
Findings répétés. Avant chaque tour de correctif, le skill envoie les findings confirmés (<reviewer>:<path> ou ci:<check>, un par ligne) sur l'entrée standard de agent-harness goal bump. La commande les normalise (minuscules, numéros de ligne retirés, tri, dédoublonnage) et en calcule une empreinte. Quand l'empreinte égale celle du tour précédent, elle marque le goal escalated (no progress), lance agent-harness notify failure, et sort avec le code 3. goal.sh et ship-init.sh posent aussi un plafond de sécurité max_fix_iterations à 10. Une entrée vide sort avec le code 2. Le même bump est utilisé avant un tour de correctif CI (étape 9 de skills/ship/SKILL.md).
Règle d'absence de progrès. Deux contrôles portent ce nom. Ce n'est pas le même test.
skills/ship/SKILL.md(Stop conditions) traite une itération complète comme sans progrès quand le même finding Important et le même échec restent, ou quand le même blocage hors revue échoue de la même façon. Un nouvel échec, un nouveau finding, ou un check vert compte comme un progrès. L'agent lance alorsagent-harness goal escalate. Pour les findings de revue,goal bumpcompare aussi une empreinte des findings entre deux tours..claude/hooks/ship-stop-gate.sh(copie Cursor :plugins/fmflurry-harness/hooks/scripts/ship-stop-gate.sh) compte un arrêt comme sans progrès seulement quand rien n'a bougé : la tête de la PR, la pointe de branche du worktree enregistré,.reviews, etfix_iterations. Cinq arrêts vides consécutifs escaladent avecno progress after 5 stop blocks. Un de ces changements remetstop_blocksà 0. Chaque arrêt compté incrémentetotal_blocks, et 30 blocs au total escaladent même si le dernier arrêt était un progrès. Les arrêts ne sont pas comptés pendantagent-harness goal wait "<reason>" --ttl 30m(24 h maximum), ni tant que l'entrée du hook, un pid vivant, un marqueur inflight, ou un processus de test ou de revue dans le worktree montre un travail en arrière-plan. Avant que les deux verdicts passent pour la pointe locale, le blocage dit de finir la revue locale. Après les deux verdicts, sans PR, il dit de pousser et d'ouvrir la PR. Tant que le goal est actif et que la PR n'est pas fusionnée, le hook bloque un arrêt anticipé. Si GitHub est illisible, le hook sort 0 et ne compte pas l'arrêt. OpenCode n'a pas de hook Stop.plugins/autonomy/index.tslance le même script sursession.idled'une session racine, transmet les sessions enfants en cours, et relance avec la raison (instructions/autonomy.md). Conductor et Monolith utilisent ce hook.
Quand ça escalade. skills/ship/SKILL.md (Human-only) s'arrête pour des identifiants manquants, des limites de compte ou de facturation, une panne externe, une décision produit que le dépôt ne peut pas trancher, ou une action de la liste interdite. Il s'arrête aussi sur la règle d'absence de progrès du skill, sur la sortie 3 de goal bump, et sur les plafonds du stop gate ci-dessus. Un finding gitleaks ou une exposition de secret arrête le run pour security-reviewer et une rotation. Un résultat Wait or cancel du contrôle des PR ouvertes escalade (skills/open-pr-check/SKILL.md). Le chemin bloqué conserve le worktree, la branche et le registre (skills/ship/SKILL.md, Blocked path).
Ce qu'il ne fait jamais. Hard limits de skills/ship/SKILL.md, et règle (d) de .claude/rules/common/autonomy.md :
- Fusion uniquement par
agent-harness ship-merge. Jamaisgh pr merge, et jamais un push vers la branche de base. - Jamais
git push --mirror,git push --all, ni--no-verify. Jamais affaiblir un check : sauter un test, un job ou un check requis, posercontinue-on-error, supprimer un check, ou baisser un seuil. - Jamais retirer un worktree avec
git worktree removebrut.agent-harness worktree-rm <path> --confirmedretire un worktree propre dont la branche est fusionnée (y compris un squash détecté pargh pr view --json state).agent-harness teardown-merged-worktree <pr>retire le worktree du goal enregistré après que cette PR est MERGED, en mode autonome, et supprime ses branches et son registre. Jamais supprimer une branche sauf par ce teardown ouagent-harness cleanup. - Jamais fusionner une PR qui correspond à
protectedPathstant que le flag est actif. Un humain passe--confirmed. - Jamais ajouter un label, publier un commentaire, ou créer un status pour passer un refus de
ship-merge. - Jamais notifier un progrès. Le run ne déclenche ni build ni release.
- Jamais retirer un goal bloqué ou escaladé.
agent-harness autonomy on|off|status # bascule .claude/state/autonomy.on (gitignored, par machine)
/ship <goal> # clarifier, implémenter, PR, revue, CI, fusion
agent-harness ship-merge <pr> [--method squash|rebase|merge] # seul chemin de fusion; ajouter --confirmed en mode interactif
agent-harness notify done "<msg>" <pr> # notifier uniquement sur question, waiting, done, failure
agent-harness ship-init <type> <scope> <desc> --goal "<text>" # première action de /ship : worktree du goal + registre (ou --adopt <pr>)
agent-harness goal decisions-path # journal de décisions de ce checkout : .claude/state/decisions/<slug>.tsv par goal (créé par ship-init, archivé dans decisions/archive/ par le teardown), sinon .claude/state/decisions.tsv
agent-harness teardown-merged-worktree <pr> # après MERGED : retire le worktree enregistré, les branches et le registre (lancé par ship-merge)
agent-harness cleanup <pr> [--keep-branch] # après MERGED : supprime la branche de la PR et les backups du goal, archive sous `refs/harness/backups/` ceux que la fusion ne contient pas (PR non enregistrées ; aussi lancé par ship-merge)
agent-harness prune-backups [--confirmed] # branches backup/* orphelines (aucun goal ni registre) : supprime celles déjà dans origin/<base>, archive les autres sous refs/harness/backups/ (simulation sans --confirmed)
agent-harness prune-branches [--confirmed] # branches locales hors backup déjà dans origin/<base>, qu'aucun goal, registre, worktree ni HEAD ne réclame : les supprime ; jamais les branches distantes (simulation sans --confirmed)Autre dépôt. ship-init, ship-merge, cleanup, teardown-merged-worktree, worktree-rm et goal acceptent un --repo <chemin absolu> final : une session dont le répertoire de travail est le dépôt A gère un goal du dépôt B sans Orca, par exemple agent-harness ship-init feat ui x --goal "..." --repo /chemin/abs/vers/B. Le chemin doit être la racine d'un checkout git : le checkout principal de B, ou un worktree de goal de B pour goal. Un chemin relatif, un sous-répertoire, un répertoire hors git, ou un --repo ailleurs qu'en dernier sont refusés. Le registre et l'état du goal sont ceux de B. Le stop gate de la session appelante lit toujours son propre checkout : il ne bloque pas sur le goal de B et ne s'y lie pas. ship-init --repo laisse un marqueur par utilisateur dans ~/.agent-harness/goals-foreign/. Tant que B garde des fichiers de goal, le git guard de chaque session fait passer chaque push par la vérification complète, qui soumet un push dans le worktree du goal de B aux revues de B. Le guard autorise exactement cette forme finale, en une commande simple. Un préfixe cd, un préfixe d'environnement comme CLAUDE_PROJECT_DIR=, et toute substitution restent refusés.
Le skill ship (skills/ship/) gère les étapes, et le skill autonomous pilote la bascule. Les règles de comportement sont dans .claude/rules/common/autonomy.md (Claude Code) et instructions/autonomy.md (OpenCode).
Configuration par repo. Chaque repo peut définir .claude/agent-harness.json. Toutes les clés sont optionnelles :
| Clé | Valeur par défaut (absente) | Rôle |
|---|---|---|
base |
la branche par défaut du repo (gh repo view) |
branche cible de la PR, et seule cible de fusion |
requiredChecks |
[] |
noms de check-runs qui doivent conclure success, skipped ou neutral sur la tête |
reviewStatus |
non défini (pas de garde-fou) | optionnel. À définir seulement si le repo a un status check externe. Contexte du commit status qui doit valoir success sur la tête |
reviewStatusCreator |
non défini (tout créateur) | optionnel, utilisé avec reviewStatus. Login qui doit avoir publié le status |
verify |
non défini (détection verification-gate) | commandes lancées par l'étape verify du ship |
protectedPaths |
non défini (pas de garde-fou) | expressions régulières optionnelles. Quand la clé est définie, une PR qui touche une correspondance nécessite une fusion humaine (--confirmed, qui demande confirmation) |
mergeMethod |
non défini (première méthode autorisée par le dépôt : squash, rebase, merge) | squash, rebase ou merge optionnel ; remplacé par ship-merge --method |
{
"base": "main",
"requiredChecks": ["build", "test"],
"reviewStatus": "ci-review",
"reviewStatusCreator": "github-actions[bot]",
"verify": ["npm run lint", "npm test"],
"protectedPaths": ["^\\.github/"]
}Garde-fous de fusion. agent-harness ship-merge est l'étape de fusion de la boucle et le seul chemin de fusion. Il vérifie des faits concrets, pas des avis. Un refus est une entrée de la boucle : l'agent corrige la cause et relance. Il refuse, sauf si toutes ces conditions sont vraies :
- le flag autonome est activé, ou
--confirmedest passé - la PR cible la branche de base et n'est pas un brouillon
- chaque entrée de
requiredChecksa réussi sur la tête - zéro fil de revue non résolu
- la branche est à jour par rapport à la branche de base
- aucun chemin modifié ne correspond à
protectedPaths, sauf si--confirmedest passé (un humain fusionne alors la PR) - seulement si
reviewStatusest défini : le status le plus récent portant ce contexte sur la tête estsuccess, et son créateur correspond àreviewStatusCreatorsi la clé est définie
Ensuite, la fusion est épinglée au SHA de la tête, puis agent-harness teardown-merged-worktree <pr> s'exécute pour un goal enregistré (sinon agent-harness cleanup <pr>). Le nettoyage supprime la branche de la PR sur le remote et en local (la branche locale seulement si elle est entièrement fusionnée), supprime les branches de backup enregistrées pour le goal, et place le checkout sur la base mise à jour. Le cleanup ne retire jamais de worktree ; il signale celui qui porte la branche. En mode autonome, le cleanup exige que le goal suive la PR ; une fois le worktree du goal retiré, l'entrée du registre en tient lieu seulement si c'est l'unique entrée de la PR, qu'elle enregistre la branche de tête de la PR, qu'elle n'est ni escalated ni blocked, que son chemin de worktree n'existe plus, et qu'aucun worktree n'a la branche extraite. Une PR non enregistrée est refusée. Le teardown retire le worktree du goal, ses branches et son registre, sous les checks de la règle de destruction des worktrees, sans toucher au checkout principal (cleanup --no-checkout). --keep-branch conserve la branche de la PR. La méthode se choisit avec --method squash|rebase|merge ; sans option, le script utilise mergeMethod de .claude/agent-harness.json, sinon la première méthode autorisée par le dépôt (squash, rebase, merge). Une méthode interdite par le dépôt est refusée.
Règles de push. Les pushes vers la branche de base sont interdits dans tous les modes, avec ou sans force. git push --mirror, --all et --no-verify sont aussi interdits. Les force pushes (--force, --force-with-lease, -f, +refspec) sont autorisés sur les autres branches.
Revue. L'étape 6 du ship lance une revue locale approfondie avant tout push : code-reviewer, security-reviewer, et le cop du stack (angular-cop ou dotnet-cop) sur le diff. L'agent corrige les findings Important confirmés, relance la revue après chaque correction (la boucle s'arrête quand les mêmes findings reviennent, avec un plafond de sécurité de 10 tours ; l'agent escalade alors avec les findings Important restants). Le garde de push refuse un push ou gh pr create sans verdict positif enregistré. L'agent publie, après l'ouverture de la PR, un commentaire de synthèse que l'humain peut auditer. Cette revue est une étape de qualité, pas un garde-fou de fusion. Aucun status GitHub n'est créé, et ship-merge ne fait pas confiance à ce commentaire.
Notifications. Le run notifie seulement quand un humain doit agir, ou quand l'objectif se termine : question quand il doit s'arrêter pour une réponse, waiting sur un prompt de permission ou d'inactivité, failure en cas d'escalade, et done quand la PR est fusionnée. Aucune notification de progression.
Limites.
- Ce sont des garde-fous côté client, pas une frontière de sécurité. Un agent avec accès shell peut appeler
ghdirectement. - La protection de branche sur la branche de base (reviews requises, checks requis, push restreints) est le vrai mécanisme d'application. À configurer sur l'hébergeur.
- Une PR qui correspond à
protectedPathsnécessite une fusion humaine (--confirmed), quand la clé est définie. Sans cette clé, le mode autonome fusionne toute PR qui passe les garde-fous. - OpenCode n'enregistre pas les hooks Claude Code.
plugins/autonomy/index.tslanceautonomy-git-guard.shavant chaque appel shell etship-stop-gate.shquand une session racine passe idle (instructions/autonomy.md).
Parité. Le mod de statut autonome (.claude/mods/, barre d'état et bandeau) est réservé à Claude Code. OpenCode n'a pas d'équivalent.


