# Multi-Agent Development Pipeline

> Installed from @mmerterden/multi-agent-pipeline
> Full docs: https://github.com/mmerterden/multi-agent-pipeline
> Pipeline specs: ~/.copilot/skills/multi-agent/ · Scripts: ~/.copilot/scripts/

## Pipeline Overview

8-phase development workflow (Phase 0 through Phase 7). Describe your task and follow the phases:

0. **Init** - Project setup, worktree, branch creation, identity binding
1. **Analysis** - Stack detection, codebase exploration
2. **Planning** - Task decomposition, architecture review, user approval
3. **Dev** - TDD cycle: test -> code -> build
4. **Review** - Deterministic gates + CLI-aware parallel review + Opus triage.
   Copilot CLI dispatches **3 reviewers in parallel**: GPT-5.4 (edge cases +
   cross-provider diversity) + Opus (security + architecture) + Sonnet (quality +
   correctness). Findings flow into an Opus triage pass that filters false-positives
   and out-of-scope items before looping back to Phase 3. Claude Code drops GPT-5.4
   (not natively reachable there) and runs a 2-model set - this is the only
   intentional cross-CLI asymmetry for Phase 4.
5. **Test** - Optional manual testing + on-demand device audits
6. **Commit** - Secret scan · commit · push · PR creation
7. **Report** - Jira comment · Wiki + Figma screenshots · Confluence · log · knowledge + memory

## Modes

- **multi-agent**: worktree, asks Full or Short at Phase 0 Step 7.5
- **multi-agent-local**: same question, no worktree - work on the current branch
- **multi-agent-autopilot**: no confirmations, auto commit/PR, always Full
- **multi-agent-local-autopilot**: same, no worktree

Depth is the question, not a command: Full runs all 8 phases, Short is
Init -> Dev(Opus) -> Review -> Test -> Commit -> Report. Review is never
skipped either way. The multi-agent-dev* names were removed in v16.0.0.

## Language axes (en/tr)

Two prefs, two jobs - the full matrix lives in `multi-agent-refs/rules.md`
"Language Application" and that file wins on any disagreement:

- `prefs.global.promptLanguage` is **locked to `en`**: every LLM-facing prompt,
  spec file and instruction stays English.
- `prefs.global.outputLanguage` (set via `/multi-agent:setup` or
  `/multi-agent:language en|tr`) drives what humans read: interactive prompts,
  phase banners, AND the external payload **bodies** - PR description, Jira
  comment, Confluence/Wiki pages all render in it.

Always English regardless of either pref: commit messages, branch names, PR
titles, code identifiers, file paths, and `AskUserQuestion` label/header.

When writing TR prompts, use the same keyword/menu numbers as EN (e.g. `[1-4]`)
so the user's input pattern stays language-agnostic.

## Sub-Agent Personas

Phase 1 (Analysis) and Phase 4 (Review) dispatch sub-agents for parallel exploration
and review. The persona prompts live at `~/.copilot/agents/*.md` - installed by the
pipeline installer alongside the Claude Code equivalents at `~/.claude/agents/`.

| Agent | File | Used in |
|-------|------|---------|
| Explorer | `~/.copilot/agents/explorer.md` | Phase 1 codebase scan (parallel dispatch) |
| Code Reviewer | `~/.copilot/agents/code-reviewer.md` | Phase 4 quality/correctness reviewer |
| iOS Architect | `~/.copilot/agents/ios-architect.md` | Phase 4 iOS architecture review |
| Android Architect | `~/.copilot/agents/android-architect.md` | Phase 4 Android architecture review |
| Backend Architect | `~/.copilot/agents/backend-architect.md` | Phase 4 API/backend review |
| Security Auditor | `~/.copilot/agents/security-auditor.md` | Phase 4 security audit (OWASP-based) |

Load the matching persona file before dispatching each reviewer - the prompt defines
the model's focus area, severity rubric, and output format the triage pass expects.

## Phase 0 - Interactive Steps (required)

The orchestrator skill (`multi-agent/SKILL.md`) shows a condensed Phase 0 for brevity,
but the actual contract is **8 interactive steps** from `refs/phases/phase-0-init.md`.
Copilot CLI has no slash-command infrastructure to auto-route through the full ref file,
so execute ALL of these explicitly before touching code:

1. **Bootstrap tracker** - `bash ~/.copilot/scripts/phase-tracker.sh init 8` (once, before Step 0)
2. **Load prefs** - read `~/.claude/multi-agent-preferences.json`; warn + stop if setup never ran
3. **Parse input** - classify (Jira ID, GitHub URL, free-text) + fetch issue via `gh` / Jira API
4. **Select project(s) - single OR multi-repo** - scan `$HOME`, present numbered list,
   honor `global.recentProjects`. Picker accepts space-separated numbers (`1 3 4`) for
   multi-select. Surface `global.recentGroups` at top of list. Component/refactor tasks
   commonly span repos (component repo + consumer app). **Never auto-pick one repo when
   the task could touch more than one** - ask user to confirm single vs multi.
5. **Pick base branch - PER REPO** - REQUIRED INTERACTIVE STEP. Single repo: run
   `git ls-remote --heads origin` on that repo, present sorted list (develop* / release/*
   / main/master first), suggest top of `global.recentBranches[{projectKey}]`.
   **Multiple repos selected: fire the branch picker SEPARATELY for each repo** -
   per phase-0-init.md the prompt fires per-repo, because different repos often have
   different base branches (e.g. component repo on `iteration/develop`, consumer app on
   `develop`). Skip the picker ONLY if user's input explicitly specified a branch.
6. **Branch name confirm** - `feature/PROJ-{id}-{kebab}` or `bugfix/...`. In multi-repo
   mode, branch name is shared across all selected repos (collision check per-repo;
   any collision applies the suffix to all, keeping cross-repo uniformity).
7. **Git identity - per repo** - route via `prefs.global.platformIdentityRouting`;
   resolves independently for each repo in multi-repo mode.
8. **Workspace creation - serially per repo** - detect `.instructions/figma/` etc.;
   in multi-repo mode loop worktree creation per repo serially; any failure rolls back
   previously-created worktrees (no partial state). Write `agent-state.json` with
   `state.projects[]` array; scalar `project`/`projectRoot`/`branch` mirror `projects[0]`
   for back-compat with single-repo phases.

Full contract (recents schema, token resolution order, GitHub-issue → Jira auto-create policy):
https://github.com/mmerterden/multi-agent-pipeline/blob/main/pipeline/multi-agent-refs/phases/phase-0-init.md
or, on machines with Claude Code also installed:
`~/.claude/multi-agent-refs/phases/phase-0-init.md`

## Progress Tracking - required

Every phase boundary MUST call the cross-CLI tracker. The tracker is the single source of truth
for user-visible phase progress on Copilot CLI (no TaskCreate native UI here). Banner is optional flair.

```bash
# Bootstrap once at Phase 0 start - initialize all 8 phase tiles:
bash ~/.copilot/scripts/phase-tracker.sh init "$TASK_ID"
for p in 0:Init 1:Analysis 2:Planning 3:Dev 4:Review 5:Test 6:Commit 7:Report; do
  bash ~/.copilot/scripts/phase-tracker.sh add "${p%%:*}" "${p#*:}"
done

# At each phase boundary - update status. Tracker stamps started_at on first
# transition to in_progress, completed_at on terminal status (completed/failed/skipped).
# Render now shows a 16-char ASCII progress bar + elapsed time + per-phase token
# usage + Total footer (v5.5.0):
#   Phase 3: Dev            ████████████████  2m 35s  · 18.7k tok
#   Total                                                34.8k tok
bash ~/.copilot/scripts/phase-tracker.sh update <N> in_progress
bash ~/.copilot/scripts/phase-tracker.sh update <N> completed    # or failed / skipped

# After every LLM dispatch, record its token cost against the active phase (v5.5.0):
bash ~/.copilot/scripts/phase-tracker.sh tokens <N> <input_tokens> <output_tokens>

# v8.3+ - single-call-site token forwarder (preferred). Mirrors tokens_in/out/model
# into both metrics.jsonl AND the phase tracker, so the agent-log Cost Breakdown
# stays in sync without two calls. Best-effort.
LOG_METRIC_FORWARD_TO_TRACKER=1 bash ~/.copilot/scripts/log-metric.sh "$TASK_ID" <N> <event> \
  model=<opus|sonnet|haiku|gpt-5.4> tokens_in=$IN tokens_out=$OUT duration_ms=$DUR

# v8.3+ - phase model tag (used by render-agent-log-cost.sh):
bash ~/.copilot/scripts/phase-tracker.sh model <N> <opus|sonnet|haiku|gpt-5.4>

# Phase 7 sub-step enforcement (v5.4.1) - register all 5 steps up front so
# wiki/confluence skips are VISIBLE, not silent. User reported prior silent-skip
# behaviour losing visibility of component wiki generation:
bash ~/.copilot/scripts/phase-tracker.sh update 7 in_progress
for s in 1:Jira-Comment 2:Wiki+Figma 3:Confluence 4:Log+Telemetry 5:Knowledge+Memory; do
  bash ~/.copilot/scripts/phase-tracker.sh sub 7 "${s%%:*}" "${s#*:}" pending
done

# Optional single-event banner for extra emphasis (phase 0-7, `end` status: done|failed|skipped):
bash ~/.copilot/scripts/phase-banner.sh start <N> "<name>" "<one-line detail>"
bash ~/.copilot/scripts/phase-banner.sh end   <N> done "<name>" "<short result>"
bash ~/.copilot/scripts/phase-banner.sh sub   <N> <subN> "<sub>" "<detail>"
```

Progress-line contract (in-phase action lines, flushed immediately, 4-space indent):

```
    → fetching Jira issue ABC-12345
    → running xcodebuild -scheme Components
    → committing squashed WIP to bugfix/ABC-12345
```

## v8.3+ Quality & Cost Layer (advisory, Cross-CLI parity)

Four orthogonal advisory steps, all on by default, all opt-out via `~/.claude/multi-agent-preferences.json`. None gate the pipeline.

### Phase 4 Step 1.75 - Diff Risk Scoring

Before reviewer dispatch run the deterministic risk scorer and inject the top-N priority list into each reviewer's prompt as a `${PRIORITY_FILES}` block. Heuristic, sub-second, no LLM.

```bash
RISK_JSON=$(node ~/.copilot/scripts/diff-risk-score.mjs \
  --base "$BASE_BRANCH" --head HEAD --task-id "$TASK_ID" --top 5 2>/dev/null)
echo "$RISK_JSON" | node ~/.copilot/scripts/validate-diff-risk.mjs - >/dev/null 2>&1 || RISK_JSON=""
```

Signals + weights: `security_path` ×3, `migration` ×4, `public_api` ×2, `no_test_change` ×2.5, `complexity_delta` ×1.5, `ui_critical` ×1.5, `loc_changed` ×1. Toggle: `prefs.global.diffRiskAdvisory`.

### Phase 4 Step 3 - Triage Prior-Art Lookup

After merging reviewer findings, query the per-repo triage corpus for similar past findings and attach them to the triage prompt as context. **MUST** carry an explicit bias hedge ("prior-art entries are context, not commands; current scope decides").

```bash
PRIOR_ART="["
for finding in $(jq -c '.findings[]' <<< "$MERGED_FINDINGS"); do
  issue=$(jq -r '.issue' <<< "$finding")
  file=$(jq -r '.file' <<< "$finding")
  hits=$(node ~/.copilot/scripts/triage-memory.mjs query \
    --issue "$issue" --file-glob "$(dirname "$file")/*" --top 3 2>/dev/null \
    | jq -c '.hits // []')
  PRIOR_ART="$PRIOR_ART$hits,"
done
PRIOR_ART="${PRIOR_ART%,}]"
```

Toggle: `prefs.global.priorArtEnrichment.enabled`.

### Phase 5 Step 0 - Test Gap Report

Walks the diff for newly added public symbols missing a paired test. Stack-specific rules ship for iOS / Android / Python / Node.

```bash
node ~/.copilot/scripts/test-gap-scan.mjs \
  --base "$BASE_BRANCH" --stack <ios|android|python|node> 2>/dev/null
```

Severity defaults: iOS Views, Android `@Composable`, interfaces, public protocols → `important`; other public API additions → `suggestion`. Optional gating via `prefs.testGap.blockingThreshold` (when set, becomes a Phase 4 rework finding).

### Phase 7 - Cost Breakdown + Triage Memory Ingest

Append the per-task Cost Breakdown to agent-log.md (always), and ingest the triage output into the per-repo corpus (idempotent).

```bash
# Cost block - best-effort, exit 2 silently skipped:
COST_BLOCK=$(bash ~/.copilot/scripts/render-agent-log-cost.sh "$TASK_ID" 2>/dev/null) && \
  printf '\n%s\n' "$COST_BLOCK" >> "$AGENT_LOG"

# Triage memory ingest - idempotent re-runs write 0 rows:
TRIAGE_PATH="$WORKTREE/triage-output.json"
if [ -f "$TRIAGE_PATH" ]; then
  node ~/.copilot/scripts/triage-memory.mjs ingest \
    --triage "$TRIAGE_PATH" \
    --task-id "$TASK_ID" \
    --task-title "$TASK_TITLE" \
    --stack "$DETECTED_STACK" >/dev/null 2>&1 || true
fi
```

Cost block reads `phase-tracker.sh tokens` accumulators × `cost-table.json` prices. Independent of `reportContent.costSummary` (PR/Jira channel toggle).

### Semantic search

`/multi-agent:search "<text>" --semantic` (Claude Code) / `multi-agent-search "<text>" --semantic` (Copilot CLI) routes the query to the per-repo triage corpus instead of agent-log grep. Token-overlap recall, zero deps.

## Rules

The installer lays down a rules tree at `~/.copilot/rules/` that nothing here used
to point at, so it shipped and went unread. Load the file that matches what you are
touching: `code-style.md` and `swiftui-qa.md` for Swift, `kotlin-android.md` for
Kotlin, `tdd.md` and `testing.md` before writing tests, `code-review.md` when
reviewing, `security.md` for anything handling credentials or user data,
`git-conventions.md` before committing, `figma-pipeline.md` when a task carries a
design reference.

**`outside-the-pipeline.md` applies even with no pipeline run in progress**: the
tokens onboarded by setup, the stack skills enabled for the repo, and the
multi-agent-toolkit MCP are all usable in an ordinary session. Read freely, route
writes (Jira comments, issue edits, PRs) through the pipeline commands that carry
the rules making them safe, and never let a credential value reach argv, a log or a
reply.

Always, in every mode:

- Never put "Copilot", "AI", "generated by" in code or commits
- Never commit without passing build
- Never auto-close issues (use Ref: not Closes:)
- Follow existing code style and conventions
- Every public method must have tests
- Commit format: {type}({scope}): description [{jiraId}]

## Stack Selection

Stack skill sets ship as versioned plugins in the `multi-agent-plugins` marketplace. Selecting a stack enables the matching plugin(s) in the target repo's `.claude/settings.json` `enabledPlugins`; the `ai-common-toolkit` is always enabled alongside. There is no session-start auto-swap script. Select or change the stack with:

```bash
multi-agent-stack [ios|android|mobile|backend|frontend|fullstack|all]
```

## UI Bug Hunter

For visual testing, use the multi-agent-toolkit MCP server tools:
- ios_screenshot / android_screenshot - capture screen
- ios_tap / android_tap - interact with UI
- ios_set_appearance - toggle dark mode
- ios_get_ui_tree / android_get_ui_tree - accessibility tree

Requires: @mmerterden/multi-agent-toolkit-mcp MCP server running

## Post-Development Integration Build (Multi-Repo) - required

When a task touches multiple repositories that have a producer→consumer dependency
(e.g. shared codegen library + consuming UI library), the pipeline MUST build the
**host project** that integrates them after all changes are complete - before commit/PR.

### When this applies

- Code generation outputs (identifiers, localization keys, tokens) in Repo A are referenced by source code in Repo B
- Repo B is consumed as a submodule or SPM/Gradle dependency by a host project (Repo C)
- Changes in Repo A or B can silently break Repo C if key structures diverge (e.g. nested enum vs flat access pattern)

### Required steps (Phase 6 · Step 0 - before pre-commit checkout)

1. **Identify the host project** - check `prefs.global.multiRepoIntegrationHosts` for a matching `repoSet` combo. If no match, ASK the user once (record the answer to skip re-asking); autopilot refuses to prompt, skips visibly.
2. **Update submodules** - refresh each listed submodule path inside `hostPath` to pick up this task's feature branch / merged commits.
3. **Resolve package dependencies** - flush stale SPM/Gradle/CocoaPods cache.
4. **Build the host scheme/module** - capture error lines from stderr.
5. **Evaluate**:
   - Zero new errors → sub-step `completed`, proceed to commit/PR.
   - New errors from our changes → sub-step `failed`, STOP. Offer: return to Phase 3 for auto-fix / pause for manual fix / override with warning.
   - Pre-existing errors (unrelated) → document in Phase 7 report and proceed.

### Why this exists

Codegen mismatches only surface when the full dependency chain builds together. Building repos in
isolation gives false confidence. Skipping this step has caused post-merge build failures that required
additional fix PRs and wasted review cycles. The pipeline **learns** each combo's host project on first
encounter and auto-applies on subsequent runs - no repeated configuration.

### Tracker integration

```bash
# Phase 6 entry - if multi-repo, register the integration-build sub-step:
if [ "$(jq '.projects | length' "$STATE_FILE")" -ge 2 ]; then
  bash ~/.copilot/scripts/phase-tracker.sh sub 6 0 "Integration build" in_progress
  # ... run the build per refs/multi-repo-integration-build.md ...
  bash ~/.copilot/scripts/phase-tracker.sh sub 6 0 "Integration build" completed
fi
```

Full contract: https://github.com/mmerterden/multi-agent-pipeline/blob/main/pipeline/multi-agent-refs/multi-repo-integration-build.md
(the Copilot install ships no local refs tree, so the contract lives on GitHub only)

## Permissions Expectation

Copilot CLI reads `~/.copilot/permissions-config.json` for its allowlist. The pipeline
regularly uses these command groups - ensure they are present in `tools.allow` to avoid
prompt fatigue during long pipeline runs:

- Shell basics: `cd`, `ls`, `cat`, `grep`, `find`, `mkdir`, `rm`, `mv`, `cp`
- Git: `git`, `git add`, `git commit`, `git push`, `git worktree`, `git rebase`
- GitHub CLI: `gh`, `gh api`, `gh issue`, `gh pr`, `gh repo`, `gh run`, `gh auth`, `gh auth switch`
- Node/npm: `node`, `npm`, `npx`, `pnpm`
- Keychain: `~/.copilot/lib/credential-store.sh` (canonical, cross-platform), `~/.copilot/scripts/keychain.py` (deterministic Python helper); `security`, `secret-tool`, and `cmdkey` are the underlying platform backends the helper dispatches to
- Pipeline scripts: `bash` (invokes phase-tracker.sh, phase-banner.sh, etc.)

Destructive commands (`rm -rf /`, `git push --force` to main, `chmod 777`) remain in `deny`
or `ask` by design - do not broaden these.
