Immutable. This exact content is served forever at /api/v1/blob/00f6e12d6e76e75a.
# AGENTS.md mARC (**Multi-Agent Relay Control**) is a Claude Code **plugin + self-marketplace** that packages a portable, cross-repo AI engineering team: `@techlead` (channel operator) convenes specialists `@dev`, `@sre`, `@design`, `@sec`, `@research`. The team's *governance* travels via one plugin; each consuming repo keeps its own facts. **This repo is special: it is BOTH the product's source AND where the team dogfoods on itself.** Self-improvement lessons legitimately flush to source *here* — the one context where that is allowed (see Constraints). ## Architecture - **Plugin** lives at `harnesses/claude-code/marc/`; the **marketplace** manifest is at repo root `.claude-plugin/marketplace.json` (name `nexaduo`, plugin `marc` → install `marc@nexaduo`, invoke `/marc:tech-lead`). - **Leaders = skills** (`skills/<leader>/`, invoked `/marc:<leader>`); **specialists = a shared flat pool** (`agents/*.md`). Any leader convenes any specialist. - Nesting under `harnesses/<harness>/` reserves the namespace for future non–Claude-Code harnesses. The growth model is in [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) — don't duplicate it here. - **`core/` is the editable source; `harnesses/*/marc/` (skills, agents) is compiled output — never hand-edit it.** Run `scripts/compile_prompts.py` to regenerate from `core/` + each harness's `compile.json`, and commit the regenerated files. ## Operating principles These distill a comparative study of agent-orchestration frameworks (OpenHands, MetaGPT, CrewAI, Claude Code Agent Teams) down to what holds for mARC: - **Stateless dispatch / context hygiene.** Specialists run fresh per task; durable state lives in git, the board/issues, and this file — not in long conversations. - **Spec-driven leverage.** A vague task propagates destructively across parallel agents. The tech-lead's main leverage is spec clarity + acceptance criteria *before* dispatch (the sufficiency gate). - **Dispatch in the background; isolate parallel writers.** Synchronous dispatch blocks the operator channel — fan out in background and track via notifications. When specialists edit files concurrently, isolate them (git worktrees) to avoid clobbering. - **Bounded loops.** Cap runaway debugging; stop and surface rather than burn tokens in an infinite fix loop. - **Tiered, size-capped memory with absolute decay.** Local/session memory is bounded (≤ 200 lines / ~2 KB) and organized as a lightweight recall index separating permanent invariants (`[PINNED]`) from time-bound entries with absolute dates (`[EXPIRES: YYYY-MM-DD]`). Substantive findings or oversized bodies spill into PR-gated artifacts (`docs/marc/` or consumer workspace) and are fetched on demand, never loaded unconditionally. - **No self-merge; independent review.** Every PR gets a security pass; the author can't self-approve. ## Concurrent operators on one clone Harnesses are **board-mediated peers** (#202) — two `@techlead` operators (different harnesses, or two sessions) may run against the same clone at once, with no supervisor between them. The coordination protocol is authored once, in `core/skills/tech-lead/SKILL.md`'s `#### Concurrent operators (claim before you dispatch)` — read it there, not here; a second full copy in this file is what let it drift out of sync with the source of truth (the defect #213/#214 exist to fix). What a reader of this file alone needs, restated: <!-- rules:origin-required --> - **The claim lives in a `## @techlead claim` issue comment, not the assignee field or Status.** An issue with no such comment is not claimed, regardless of who is assigned to it — the assignee is a human-visible label only and carries no operator identity, precisely because a shared `gh` token makes every operator on a machine authenticate as the same login. (origin: #213 · 2026-08-25) - **`git worktree list --porcelain` is free, cross-harness ground truth** — one `.git` registers every operator's checkout. Read it before dispatching mutating work; a branch already checked out elsewhere means another operator owns it, don't re-cut it. A worktree that's `locked`/gone, at the base SHA, with no commits and no linked PR is a **dead worktree** (not a squat) — surface the concrete remedy to the user, never run it autonomously, since it may hold uncommitted work. (origin: #214 · 2026-08-25) - **Isolate-parallel-writers extends to the operators themselves**, not just to the specialists they dispatch: any operator that will mutate files takes its own worktree, and two of them never share a branch or working tree — see the SKILL.md section for the `.gitignore` placement lesson this produced. (origin: #206 · 2026-08-25) <!-- /rules:origin-required --> ## Constraints - **Anti-anchoring / genericization (hard gate):** everything under `harnesses/` must stay **stack-agnostic** — zero references to any consuming repo's stack. CI enforces this with a grep gate. Repo-specific facts belong in the *consuming* repo's `AGENTS.md`/`.agents/team.toml`, read at runtime — never hardcoded here. - **Keep this file minimal.** Record only what isn't discoverable by reading the repo. If agents repeat a mistake, tighten the linter/CI/test — don't grow prose here. LLMs anchor on whatever sits in context, including deprecated caveats. - **An installed plugin is immutable from the user's side.** Product changes flow only through releases: bump `harnesses/claude-code/marc/.claude-plugin/plugin.json` `version` + `CHANGELOG.md`; users get it via `claude plugin update marc@nexaduo`. Never edit the plugin cache; auto-update is OFF for third-party marketplaces. - **Self-improvement is context-gated:** flush-to-source is allowed ONLY in this repo. When mARC runs *installed* in a user's repo, lessons persist **locally** (their `AGENTS.md`/`team.toml`/memory); product-level lessons become **opt-in, human-approved, sanitized** upstream PRs — never autonomous, never leaking user context. This machinery lives in a dedicated `@scribe` agent, not the tech-lead skill. - **No silent file writes** in any repo. Onboarding (`/marc:init`) is opt-in and shows content before writing. - **Durable team artifacts (PEF, #46): `docs/marc/`, operator-materialized, PR-gated.** `@research` briefs / `@sec` reports / decision records worth keeping land in `docs/marc/` per its README (`YYYY-MM-DD-<type>-<slug>.md`). That folder is served **publicly** by GitHub Pages — nothing sensitive goes there, ever. `@sec`/`@research` stay strictly comment-only; the operator (`@techlead`) copies the issue comment into the file and lands it via a reviewed PR — never a direct commit, never a write carve-out for read-only agents. This binding is THIS repo's; consumer repos pin their own via `team.toml` (`workspace_dir`) / their `AGENTS.md`. - **Zero-config is a feature:** the team must work in any repo with no `team.toml` (runtime discovery via `gh` + session memory). Don't regress that. ## Release phases There is **no staging/prod deploy pipeline** — mARC is a distributable plugin, not a hosted stack. Don't fake staging/prod phases. "Done" here means: 1. PR with **green CI** (`.github/workflows/ci.yml`: Tier 1 structural + Tier 2 install/cross-repo — deterministic, no secret, no token cost). 2. **Security review before merge** (`@sec`); **no self-merge**. Skill/agent changes carry a high review bar (injection surface). 3. **Version bumped + CHANGELOG** updated. 4. For user-facing behavior, **dogfood in a real repo** and confirm the *terminal* state (PR/CI/logs), not the "enqueued" step. - Validate locally with `claude plugin validate harnesses/claude-code/marc` (a benign `minimumVersion` "unknown field" warning is expected — don't "fix" it away). - The landing page (`docs/` → GitHub Pages → marc.nexaduo.com) is served DNS-only; a `SessionStart` hook injects `team.toml` and nudges on outdated versions. ## Lessons - **Base freshness — branch from freshly-fetched `origin/main`.** Local `main` does NOT advance when PRs merge on the remote; a stale base makes already-merged work reappear as conflicts. For a stale open PR, run `gh pr update-branch`. (This bites humans too: always `git fetch` before reasoning about what's merged.) - **Never delete flagged code on a stale base.** A security review on a stale base once nearly recommended *reverting live merged code*. Re-sync the base (the three-dot PR diff is authoritative), don't strip the flagged lines. - **The self-improvement loop can bug itself.** Dogfooding surfaced that the improvement machinery misbehaves installed-vs-in-source — hence the context gating. Trust the gate, not the instinct to "just flush to source." - **Don't fabricate work.** On a quiet channel, ask for the demand or triage the board; never invent tasks to look busy.