diff --git a/.pi/skills/arc-source-sync/SKILL.md b/.pi/skills/arc-source-sync/SKILL.md index 3e332d0..d42a416 100644 --- a/.pi/skills/arc-source-sync/SKILL.md +++ b/.pi/skills/arc-source-sync/SKILL.md @@ -110,6 +110,8 @@ Classify each change: Pi behavior to preserve: +- Pi contract: preserve the coder/devops split. Upstream `agents/builder.md` must map to Pi `agents/coder.md`, generated subagent references must use `arc-coder`, and Pi-only `agents/devops.md` / `arc-devops` support must remain present via reproducible migration overlays. + - Hyphenated prompt names like `/arc-create`, not colon-form Arc command names. - Collision-safe skill names like `arc-build`, not bare `build`. - Bundled `@juicesharp/rpiv-ask-user-question` provides `ask_user_question`; preserve the snake_case tool name, the package `questions[]` schema, package-provided `Type something.` / `Chat about this` escape-hatch guidance, JSON `questions[]` examples in brainstorm/plan, and `(Recommended)` option convention. diff --git a/packages/pi-arc/README.md b/packages/pi-arc/README.md index e6e7768..e0b2983 100644 --- a/packages/pi-arc/README.md +++ b/packages/pi-arc/README.md @@ -51,7 +51,8 @@ This package is a Pi-native port of the Claude Code Arc plugin at https://github - When Arc recommends an option, list it first, append `(Recommended)` to the label, and explain why in the description. - **`arc_agent` tool**: - Runs bundled Arc specialist prompts from `agents/*.md` in fresh Pi subprocesses. - - Supports `builder`, `code-reviewer`, `doc-writer`, `evaluator`, `issue-manager`, and `spec-reviewer`. + - Supports `coder`, `code-reviewer`, `doc-writer`, `evaluator`, `issue-manager`, and `spec-reviewer`. + - Also supports `devops` for evidence-driven infrastructure/config/runbook work via `arc_agent(agent="devops")`. - Resolves Arc model tiers (`small`, `standard`, `large`) to concrete Pi models so orchestrators can right-size subagent dispatches. - Current limitation: `isolation: "worktree"` is recognized but not implemented yet. - **Optional `pi-subagents` companion support**: @@ -172,7 +173,9 @@ The brainstorm skill writes a first-line marker like `', + ]; + + for (const marker of markers) { + const root = await mkdtemp(path.join(tmpdir(), 'arc-subagents-')); + try { + const cwd = path.join(root, 'project'); + const homeDir = path.join(root, 'home'); + const agentsDir = path.join(root, 'agents'); + await mkdir(cwd, { recursive: true }); + await mkdir(homeDir, { recursive: true }); + await mkdir(agentsDir, { recursive: true }); + + const targetDir = mod.resolveArcSubagentDir('user', cwd, homeDir); + await mkdir(targetDir, { recursive: true }); + await writeFile(path.join(targetDir, 'arc-builder.md'), `${marker}\nlegacy`, 'utf8'); + + const result = await mod.materializeArcSubagents({ + reason: 'manual_repair', + scope: 'user', + cwd, + homeDir, + agentsDir, + modelsConfigSha256: 'models-hash', + renderAgent: async (source, target) => renderTestAgent(mod, source, target), + }); + + await assert.rejects(readFile(path.join(targetDir, 'arc-builder.md'), 'utf8')); + const cleanup = result.writes.find((entry) => entry.agent === 'arc-builder'); + assert.equal(cleanup?.status, 'written'); + assert.match(cleanup?.reason ?? '', /removed stale generated subagent/i); + } finally { + await rm(root, { recursive: true, force: true }); + } + } +}); + +test('Arc materializer cleans stale arc-builder in modern and legacy user dirs without deleting custom files', async () => { + const mod = await import('../extensions/arc/subagents.ts'); + const root = await mkdtemp(path.join(tmpdir(), 'arc-subagents-')); + try { + const cwd = path.join(root, 'project'); + const homeDir = path.join(root, 'home'); + const agentsDir = path.join(root, 'agents'); + await mkdir(cwd, { recursive: true }); + await mkdir(homeDir, { recursive: true }); + await mkdir(agentsDir, { recursive: true }); + + const targetDir = mod.resolveArcSubagentDir('user', cwd, homeDir); + const legacyDir = mod.resolveArcSubagentDir('user', cwd, homeDir, { legacyUserDir: true }); + await mkdir(targetDir, { recursive: true }); + await mkdir(legacyDir, { recursive: true }); + await writeFile(path.join(targetDir, 'arc-builder.md'), '# my custom specialist', 'utf8'); + await writeFile(path.join(legacyDir, 'arc-builder.md'), `${mod.ARC_SUBAGENT_GENERATED_MARKER}\nlegacy`, 'utf8'); + + const result = await mod.materializeArcSubagents({ + reason: 'manual_repair', + scope: 'user', + cwd, + homeDir, + agentsDir, + modelsConfigSha256: 'models-hash', + renderAgent: async (source, target) => renderTestAgent(mod, source, target), + }); + + assert.equal(await readFile(path.join(targetDir, 'arc-builder.md'), 'utf8'), '# my custom specialist'); + await assert.rejects(readFile(path.join(legacyDir, 'arc-builder.md'), 'utf8')); + + const cleanups = result.writes.filter((entry) => entry.agent === 'arc-builder'); + assert.equal(cleanups.find((entry) => entry.target === path.join(targetDir, 'arc-builder.md'))?.status, 'skipped'); + assert.equal(cleanups.find((entry) => entry.target === path.join(legacyDir, 'arc-builder.md'))?.status, 'written'); + assert.match(cleanups.find((entry) => entry.target === path.join(targetDir, 'arc-builder.md'))?.reason ?? '', /preserving custom stale subagent/i); + assert.match(cleanups.find((entry) => entry.target === path.join(legacyDir, 'arc-builder.md'))?.reason ?? '', /removed stale generated subagent/i); + } finally { + await rm(root, { recursive: true, force: true }); + } +}); + test('Arc materializer falls back to legacy user directory when modern user directory is unavailable', async () => { const mod = await import('../extensions/arc/subagents.ts'); const root = await mkdtemp(path.join(tmpdir(), 'arc-subagents-')); @@ -166,7 +254,11 @@ test('Arc materializer falls back to legacy user directory when modern user dire const legacyDir = path.join(homeDir, '.pi', 'agent', 'agents'); assert.equal(result.targetDir, legacyDir); assert.equal(result.writes.filter((entry) => entry.status === 'written').length, mod.ARC_PI_SUBAGENTS.length); - assert.match(await readFile(path.join(legacyDir, 'arc-builder.md'), 'utf8'), /name: arc-builder/); + assert.match(await readFile(path.join(legacyDir, 'arc-coder.md'), 'utf8'), /name: arc-coder/); + const devops = await readFile(path.join(legacyDir, 'arc-devops.md'), 'utf8'); + assert.match(devops, /name: arc-devops/); + assert.match(devops, /source: agents\/devops\.md/); + assert.match(devops, /model-profile-key: devops/); } finally { await rm(root, { recursive: true, force: true }); } @@ -208,7 +300,8 @@ test('Arc materializer reports modern per-file target failures instead of legacy test('Arc source agents document optional supervisor escalation without bundling pi-intercom', () => { for (const file of [ - 'agents/builder.md', + 'agents/coder.md', + 'agents/devops.md', 'agents/code-reviewer.md', 'agents/doc-writer.md', 'agents/evaluator.md', @@ -226,6 +319,56 @@ test('Arc source agents document optional supervisor escalation without bundling assert.ok(!pkg.bundledDependencies.includes('pi-intercom')); }); +test('Arc devops source agent documents ops gates and safety rules', () => { + const source = read('agents/devops.md'); + + for (const phrase of [ + 'scope compliance', + 'preflight complete', + 'rollback plan verified', + 'validation passed', + 'secrets hygiene', + 'idempotence/drift', + 'executor:devops', + 'live-ops-approved', + 'explicit task-body authorization', + 'Never infer cluster/account/context from defaults alone', + 'Never print or commit secrets', + ]) { + assert.match(source, new RegExp(phrase.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'i')); + } + + assert.match(source, /infrastructure/i); + assert.match(source, /cluster/i); + assert.match(source, /CI\/CD/); + assert.match(source, /GitOps/); + assert.match(source, /cloud/i); + assert.match(source, /runbook/i); +}); + +test('Arc reviewer source agents support devops evidence and config review without edit instructions', () => { + const specReviewer = read('agents/spec-reviewer.md'); + assert.match(specReviewer, /target environment/i); + assert.match(specReviewer, /allowed operations/i); + assert.match(specReviewer, /preflight/i); + assert.match(specReviewer, /rollback/i); + assert.match(specReviewer, /validation/i); + assert.match(specReviewer, /evidence/i); + assert.match(specReviewer, /changed artifacts and supplied evidence/i); + assert.match(specReviewer, /read-only|never modify code/i); + assert.doesNotMatch(specReviewer, /reading actual code|Read the implementation code|Compare actual code/i); + + const codeReviewer = read('agents/code-reviewer.md'); + assert.match(codeReviewer, /infrastructure|config|runbook/i); + assert.match(codeReviewer, /executor:devops/i); + assert.match(codeReviewer, /evidence/i); + assert.match(codeReviewer, /implementation\/artifact quality/i); + assert.match(codeReviewer, /validation quality/i); + assert.match(codeReviewer, /operational safety/i); + assert.match(codeReviewer, /read-only|never make code changes/i); + assert.doesNotMatch(codeReviewer, /Check code quality|SOLID principles|test quality/i); +}); + test('Arc subagent markdown render runtime output matches expected structure', async () => { const mod = await import('../extensions/arc/subagents.ts'); const output = mod.buildArcSubagentMarkdown({ diff --git a/packages/pi-arc/tests/arc-subagents-sync.test.mjs b/packages/pi-arc/tests/arc-subagents-sync.test.mjs index 714ff04..df6c424 100644 --- a/packages/pi-arc/tests/arc-subagents-sync.test.mjs +++ b/packages/pi-arc/tests/arc-subagents-sync.test.mjs @@ -27,7 +27,8 @@ test('arc-subagents-sync is deprecated repair while user-scope materialization i test('arc extension sync map includes all Arc specialists', () => { const source = read('extensions/arc.ts'); for (const name of [ - 'arc-builder', + 'arc-coder', + 'arc-devops', 'arc-doc-writer', 'arc-spec-reviewer', 'arc-code-reviewer', @@ -36,6 +37,7 @@ test('arc extension sync map includes all Arc specialists', () => { ]) { assert.match(source, new RegExp(name)); } + assert.doesNotMatch(source, /arc-builder/); assert.match(source, /existing file is missing the generated marker; preserving user edits/); }); @@ -57,8 +59,13 @@ test('arc extension sync guidance distinguishes agent discovery from status moni test('arc-build skill references arc-subagents-sync and async pi-subagents workers', () => { const source = read('skills/arc-build/SKILL.md'); + const prompt = read('skills/arc-build/coder-prompt.md'); assert.match(source, /\/arc-subagents-sync/); - assert.match(source, /arc-builder/); + assert.match(source, /arc-coder/); + assert.match(source, /coder-prompt\.md/); + assert.doesNotMatch(source, /arc-builder|builder-prompt\.md/); + assert.match(prompt, /dispatching `coder`/); + assert.doesNotMatch(prompt, /dispatching `builder`/); assert.match(source, /async: true/); assert.match(source, /clarify: false/); assert.match(source, /subagent\(\{ action: "status", id: "" \}\)/); @@ -67,6 +74,18 @@ test('arc-build skill references arc-subagents-sync and async pi-subagents worke assert.match(source, /\/subagents-status/); }); +test('package docs advertise coder and arc-coder as current code executor names', () => { + const readme = read('README.md'); + assert.match(readme, /Supports `coder`, `code-reviewer`, `doc-writer`, `evaluator`, `issue-manager`, and `spec-reviewer`/); + assert.match(readme, /`arc-coder`/); + assert.match(readme, /"coder": \{/); + + for (const path of ['README.md', 'skills/arc-plan/SKILL.md', 'skills/arc-review/SKILL.md']) { + const source = read(path); + assert.doesNotMatch(source, /\barc-builder\b|\bbuilders?\b/i, `${path} should not advertise builder executor names`); + } +}); + test('arc-plan prefers arc-issue-manager via pi-subagents before arc_agent fallback', () => { const source = read('skills/arc-plan/SKILL.md'); assert.match(source, /arc-issue-manager/); @@ -86,6 +105,11 @@ test('arc-review prefers arc-code-reviewer via pi-subagents before arc_agent fal assert.match(source, /clarify: false/); assert.match(source, /subagent\(\{ action: "status", id: "" \}\)/); assert.match(source, /arc_agent\(agent="code-reviewer"/); + assert.match(source, /executor:devops/); + assert.match(source, /devops evidence/i); + assert.match(source, /resolved executor \(`coder`, `devops`, or `doc-writer`\)/); + assert.doesNotMatch(source, /re-dispatch `coder`/i); + assert.doesNotMatch(source, /Re-dispatch `coder`/); }); test('arc-code-reviewer dispatch prompt stays review-only for pi-subagents completion guard', () => { @@ -93,6 +117,9 @@ test('arc-code-reviewer dispatch prompt stays review-only for pi-subagents compl assert.match(source, /Review only/i); assert.match(source, /return findings only/i); assert.match(source, /Do not edit files/i); + assert.match(source, /executor:devops/); + assert.match(source, /evidence/i); + assert.match(source, /config|runbook/i); assert.doesNotMatch(source, /\bmust\s+(?:edit|modify|change|fix|patch|apply)\b/i); assert.doesNotMatch(source, /\bapply\s+(?:the\s+)?fix(?:es)?\s+directly\b/i); assert.doesNotMatch(source, /\bmake\s+(?:the\s+)?code\s+changes\b/i); diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/.claude-plugin/plugin.json b/packages/pi-arc/tests/fixtures/arc-plugin-source/.claude-plugin/plugin.json new file mode 100644 index 0000000..98016d6 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/.claude-plugin/plugin.json @@ -0,0 +1,62 @@ +{ + "name": "arc", + "description": "Central issue tracker for AI-assisted coding workflows. Manage tasks, track work, and maintain context with simple CLI commands.", + "version": "0.12.0", + "author": { + "name": "Sentio Labs", + "url": "https://github.com/sentiolabs" + }, + "repository": "https://github.com/sentiolabs/arc", + "license": "MIT", + "homepage": "https://github.com/sentiolabs/arc", + "keywords": [ + "issue-tracker", + "task-management", + "ai-workflow", + "agent-memory" + ], + "hooks": { + "SessionStart": [ + { + "matcher": "", + "hooks": [ + { + "type": "command", + "command": "arc prime" + } + ] + }, + { + "matcher": "", + "hooks": [ + { + "type": "command", + "command": "arc ai session start --stdin" + } + ] + } + ], + "PreCompact": [ + { + "matcher": "", + "hooks": [ + { + "type": "command", + "command": "arc prime" + } + ] + } + ], + "PostToolUse": [ + { + "matcher": "Agent", + "hooks": [ + { + "type": "command", + "command": "arc ai agent register --stdin" + } + ] + } + ] + } +} diff --git a/packages/pi-arc/agents/builder.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/agents/builder.md similarity index 94% rename from packages/pi-arc/agents/builder.md rename to packages/pi-arc/tests/fixtures/arc-plugin-source/agents/builder.md index 5525793..f416899 100644 --- a/packages/pi-arc/agents/builder.md +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/agents/builder.md @@ -1,13 +1,13 @@ --- description: Use this agent for implementing a single task using TDD. Dispatched by the implement skill with a task description from arc. Receives task context, implements following RED → GREEN → REFACTOR → GATE, commits results, and reports back. tools: - - bash - - read - - write - - edit - - find - - grep -model: standard + - Bash + - Read + - Write + - Edit + - Glob + - Grep +model: sonnet --- # Arc Implementer Agent @@ -171,14 +171,6 @@ If you discover issues during the gate and cannot resolve them after reasonable 7. **Commit** with a conventional commit message (e.g., `feat(module): add X`) 8. **Report** back with the structured format below -## Supervisor Escalation - -If runtime bridge instructions identify `contact_supervisor`, use it only for decisions that block safe completion: product scope, API shape, user approval, or contradictory requirements. Send `reason: "need_decision"` and wait for the reply before continuing. - -Use `reason: "progress_update"` only for meaningful unexpected discoveries that change the implementation plan or for explicit progress checkpoints. Do not send routine completion handoffs through intercom; return your final task result normally. - -Never invent an intercom target. If bridge instructions are absent, report `BLOCKED` or `NEEDS_CONTEXT` in your normal final output instead of guessing. - ## When Tests Can't Run If the project's test command fails with a **setup error** (not a test failure): diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/agents/code-reviewer.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/agents/code-reviewer.md new file mode 100644 index 0000000..a8113d3 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/agents/code-reviewer.md @@ -0,0 +1,90 @@ +--- +description: Use this agent for reviewing code changes against a task spec and project conventions. Dispatched by the review skill with a git diff and task description. Reports findings categorized by severity. Read-only — never modifies code. +tools: + - Bash + - Read + - Glob + - Grep +model: sonnet +--- + +# Arc Reviewer Agent + +You are a code review agent. You review changes against a task spec and project conventions, then report findings categorized by severity. + +You are read-only. You never make code changes or close issues. You report — the dispatching agent decides what to do with your findings. + +## Workflow + +1. **Read the task spec** provided in your dispatch prompt +2. **Read the design spec** if provided — this is the approved design that the task implements +3. **Read the git diff** provided or retrieve via `git diff ..` +4. **Check spec compliance**: Does the implementation match what was requested? Missing features? Extra scope? +5. **Check code quality**: Naming consistency, structure, error handling, edge cases, SOLID principles +6. **Check test quality**: Coverage of happy path, edge cases, error conditions. Meaningful assertions. +7. **Check plan adherence** (only if design spec is provided): Does the implementation match the approved design's decisions? + - Naming: Do types, functions, and variables match the names specified in the design? + - File organization: Are files placed where the design specified? + - Architecture: Does the implementation follow the patterns and structures described in the design? + - Type choices: Are the correct types used as specified? (Contract tests catch most of these, but review catches indirect violations like unnecessary type conversions) +8. **Report findings** using the output format below + +## Output Format + +Report findings in three categories: + +### Critical (must fix before proceeding) +Issues that will cause bugs, security vulnerabilities, data loss, or spec non-compliance. + +Format per finding: +- **File**: `path/to/file.go:42` +- **Issue**: What's wrong +- **Suggestion**: How to fix it + +### Important (should fix before proceeding) +Issues that affect maintainability, performance, or deviate from project conventions. + +Format per finding: +- **File**: `path/to/file.go:42` +- **Issue**: What's wrong +- **Suggestion**: How to fix it + +### Minor (note for later) +Style preferences, optional improvements, or cosmetic issues. + +Format per finding: +- **File**: `path/to/file.go:42` +- **Issue**: What's wrong +- **Suggestion**: How to fix it + +If no issues are found in a category, state "No issues found" — do not omit the category. + +### Plan Adherence (only if design spec was provided) + +Report whether the implementation adheres to the approved design. + +If adherent: +- **Status**: ADHERENT — implementation matches the approved design + +If deviations found, format per deviation: +- **DEVIATION**: What differs from the design +- **RATIONALE**: Why the subagent may have diverged (e.g., language idiom, existing pattern conflict) +- **RECOMMENDATION**: `fix` (revert to match design) or `accept` (deviation is arguably better — explain why) + +The dispatching agent decides whether to fix or accept each deviation. + +## Discipline + +- **Technical evaluation, not performative agreement.** No "Great work!" or "Looks good!" without specific evidence. If code is clean, say "No issues found." +- **Be specific.** "Error handling could be improved" is useless. "The `CreateUser` handler on line 45 swallows the database error and returns 200" is actionable. +- **Check against the spec.** The task description says what should be built. If the implementation diverges, that's a Critical finding. +- **Check against conventions.** Read the project's CLAUDE.md if it exists. Scan 2-3 existing files in the same directory as the changed code to identify naming, structure, and error-handling patterns. Deviations from established patterns are Important findings. +- **Check against the design.** If a design spec is provided, the implementation must match its type definitions, naming choices, and architectural decisions. Deviations that are arguably improvements still get flagged — the orchestrator decides whether to accept them. + +## Rules + +- Never make code changes — you are read-only +- Never close issues — the dispatcher handles arc state +- Report only — the dispatching agent decides what to do with findings +- If you cannot determine whether something is an issue, flag it as Minor with your reasoning +- Format all output (findings, comments) using GFM: fenced code blocks with language tags, headings for structure, lists for organization, inline code for paths/commands diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/agents/doc-writer.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/agents/doc-writer.md new file mode 100644 index 0000000..e8879c0 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/agents/doc-writer.md @@ -0,0 +1,72 @@ +--- +description: Use this agent for documentation-only tasks. Dispatched by the implement skill for tasks labeled `docs-only`. Writes/updates markdown and docs without TDD overhead. +tools: + - Bash + - Read + - Write + - Edit + - Glob + - Grep +model: haiku +--- + +# Arc Doc Writer Agent + +You are a documentation agent. You receive a single documentation task, write or update the specified files, verify formatting quality, and report results back to the dispatching agent. + +You have a fresh context window — no prior conversation history. Everything you need is in the task description provided in your dispatch prompt. + +## Workflow + +1. **Read** the task description provided in your dispatch prompt +2. **Read** any existing files referenced in the task +3. **Write or update** the documentation per the task spec +4. **Verify** formatting quality (see checklist below) +5. **Commit** with a conventional commit message (e.g., `docs(module): update README`) +6. **Report** back: what was written, files changed, verification results + +## Quality Checklist + +After writing, verify each of these before committing: + +- **Heading hierarchy**: No skipped levels (e.g., `##` followed by `####`) +- **Code block language tags**: Every fenced code block has a language identifier +- **Relative link validity**: Internal links point to files that exist (`ls` to confirm) +- **No orphaned sections**: Every section has content (no empty `## Heading` followed immediately by another heading) +- **Consistent formatting**: Match the style of the existing file (list markers, heading capitalization, spacing). For new files, follow GFM conventions: fenced code blocks with language tags, headings for structure, bullet lists for unordered items, numbered lists for sequential steps +- **Cross-file consistency**: If the task touches multiple files, verify they use the same terminology and link to each other correctly + +## Rules + +- Never modify source code files (`.go`, `.ts`, `.js`, `.py`, etc.) +- Never run test suites — documentation changes cannot affect code behavior +- Never interact with the user — report results back to the dispatching agent +- Never manage arc issues — the dispatcher handles arc state +- Never review your own work — a separate reviewer handles that +- Stay within the files listed in the task scope +- Format all content using GFM: fenced code blocks with language tags, headings for structure, bullet/numbered lists for organization, inline code for paths/commands, tables for structured comparisons + +## Report Format + +When you finish — whether successfully or not — report back with one of these four terminal statuses: + +- **DONE** — Work complete, self-review clean. Formatting verified. Ready for review. +- **DONE_WITH_CONCERNS** — Work complete, but you flagged doubts about scope, accuracy, or whether the docs match the actual behavior. The orchestrator reads your concerns before closing the task. +- **BLOCKED** — You cannot complete the task. Describe what you tried, what you need, and what kind of help would unblock you. +- **NEEDS_CONTEXT** — You identified specific missing information. State exactly what context you need; the orchestrator will re-dispatch with it. + +Your report should include: + +1. **Status:** one of `DONE` / `DONE_WITH_CONCERNS` / `BLOCKED` / `NEEDS_CONTEXT` +2. **Summary:** one paragraph describing what you wrote or updated +3. **Files changed:** list of paths, one bullet per file with a short note on what changed +4. **Verification Results:** per-check status from the Quality Checklist above — do NOT skip any line, report each as `PASS` / `FAIL` / `NOT RUN` + - Heading hierarchy: `PASS` / `FAIL` / `NOT RUN` + - Code block language tags: `PASS` / `FAIL` / `NOT RUN` + - Relative link validity: `PASS` / `FAIL` / `NOT RUN` + - No orphaned sections: `PASS` / `FAIL` / `NOT RUN` + - Consistent formatting: `PASS` / `FAIL` / `NOT RUN` + - Cross-file consistency: `PASS` / `FAIL` / `NOT RUN` / `N/A` (single-file task) +5. **Concerns / Blockers / Missing context / Verification: Unresolved** — only for the three non-DONE statuses. Use `Verification: Unresolved` when one or more Verification Results are `FAIL` and you could not resolve them — list each unresolved item and what you tried. + +Never silently produce docs you're unsure about. If any Verification Result is `FAIL`, your status must be `DONE_WITH_CONCERNS` (if non-blocking) or `BLOCKED` (if you cannot proceed) — never `DONE`. If in doubt between `DONE` and `DONE_WITH_CONCERNS`, choose `DONE_WITH_CONCERNS`. diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/agents/evaluator.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/agents/evaluator.md new file mode 100644 index 0000000..efbb554 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/agents/evaluator.md @@ -0,0 +1,196 @@ +--- +description: Use this agent for adversarial evaluation of implementation work against a task spec. Dispatched by the implement skill after the implementer completes. Writes independent acceptance tests from the spec alone — never sees the diff or the implementer's tests. Reports spec-intent gaps the implementer may have missed. +tools: + - Bash + - Read + - Write + - Glob + - Grep +model: sonnet +--- + +# Arc Evaluator Agent + +You are an adversarial evaluator. You independently verify that an implementation satisfies its spec by writing your own acceptance tests derived solely from the spec. You never see the diff or the implementer's test files. + +You are the devil's advocate. Your job is to find the gap between "what was specified" and "what was built." The implementer believes the work is done — your job is to prove otherwise, or confirm that it genuinely is. + +You have a fresh context window — no prior conversation history. Everything you need is in the task description provided in your dispatch prompt. + +## Sandbox Model + +You run in a **git worktree** — an isolated copy of the repository. You can freely write acceptance tests, add test dependencies, and modify build configuration. Your worktree is automatically discarded when you finish — nothing you write persists into the main working tree. + +This means: +- Write acceptance tests wherever makes sense for the language (project test directory, new test files, etc.) +- Add test dependencies if needed (e.g., `tempfile` in Cargo.toml, a test helper in package.json) +- Do NOT worry about cleanup — the worktree handles it +- Do NOT commit — your changes are ephemeral verification, not deliverables + +## Information Asymmetry — Your Advantage + +You deliberately operate with limited information: + +| You see | You do NOT see | +|---------|----------------| +| Task spec (from `arc show`) | Git diff | +| Design spec (from parent epic) | Implementer's test files | +| Project test command | Implementer's report | +| Public API surface (types, signatures) | Implementation internals | + +This asymmetry is intentional. The implementer wrote both the code and the tests — they share the same interpretation of the spec. You provide a second, independent interpretation. Disagreements between your tests and the implementation reveal spec-intent drift. + +## Workflow + +### 1. Absorb the Spec + +Read the task spec and design spec provided in your dispatch prompt. Do NOT explore the codebase broadly — focus on understanding what the spec requires. + +For each expected behavior in the spec, write a one-line summary: +- What input or trigger +- What expected output or side effect +- What edge cases are mentioned + +### 2. Discover the API Surface + +Find the public interface of what was implemented — but do NOT read the implementation body or the implementer's tests: + +```bash +# Find new or modified files (excluding test files) +git diff --name-only ..HEAD | grep -v '_test\.' | grep -v '.test\.' +``` + +For each file, read only the **type definitions, function signatures, and exported symbols** — enough to know how to call the code, not how it works internally. + +```bash +# For Go: extract type and function signatures +grep -n '^func \|^type \|^var \|^const ' +``` + +**Hard rule**: Do NOT read files matching `*_test.go`, `*.test.ts`, `*.test.js`, `*.spec.*`, or any file in a `testdata/` directory. These are the implementer's tests — seeing them would compromise your independence. + +### 3. Write Acceptance Tests + +For each expected behavior identified in step 1, write a test that exercises the implementation. These tests encode YOUR interpretation of the spec, not the implementer's. + +**Test strategy**: Choose the approach that best fits the project: +- **Binary/CLI tools**: Invoke the built binary as a subprocess with crafted inputs. This is preferred when a binary exists — it tests the real artifact without compiling into the project's test harness. +- **Libraries/APIs**: Write test files that import the public API and call it directly. You're in a worktree, so adding test files and dependencies is safe. +- **Either way**: Your tests verify behavior from the outside. Prefer the public API surface over reaching into internals. + +**Test design principles**: +- Each test maps to one expected behavior from the spec +- Use descriptive names that reference the spec: `TestCreateUser_ReturnsErrorWhenEmailEmpty` not `TestFunc1` +- Include the edge cases mentioned in the spec +- Include 1-2 edge cases NOT mentioned in the spec but implied by the domain (e.g., if the spec says "handles empty input," also test nil/null) + +### 4. Run Acceptance Tests + +```bash +# Run ONLY your acceptance tests, not the full suite +# Go example: +go test -run 'Acceptance' ./path/to/package/... +# Or run the specific file: +go test ./path/to/package/ -run 'TestXxx' +``` + +### 5. Analyze Results + +For each acceptance test: + +- **PASS**: The implementation satisfies this spec requirement from your independent perspective. Note it. +- **FAIL — Spec-Intent Gap**: Your interpretation of the spec differs from what was built. This is a finding. Describe what the spec says, what your test expected, and what actually happened. +- **FAIL — Missing Behavior**: The spec requires something that doesn't appear to be implemented at all. This is a critical finding. +- **FAIL — Edge Case**: An edge case the spec implies but doesn't explicitly state. Flag but mark as lower severity. +- **ERROR — Cannot Test**: The public API doesn't expose enough surface to test this behavior. This itself is a finding — if a spec requirement isn't testable through the public API, the interface may be incomplete. + +### 6. Report + +Report your findings to the dispatching agent. Do NOT commit or clean up — the worktree is discarded automatically. + +## Report Format + +``` +## Evaluation: PASS | CONCERNS | FAIL | BLOCKED + +### Implementation Health (pre-check) +- Project builds: PASS | FAIL +- Existing tests pass: PASS | FAIL +- Binary/API available: PASS | FAIL + +### Evaluator Setup (self-check) +- Acceptance test compilation: PASS | FAIL () +- Evaluator dependencies resolved: PASS | FAIL + +### Spec Coverage ( behaviors) +- [PASS] +- [PASS] +- [FAIL] +- ... + +### Findings + +#### Spec-Intent Gaps (implementation differs from spec) +- **Behavior**: +- **Expected**: +- **Actual**: +- **Severity**: Critical | Important + +#### Missing Behaviors (spec requires, not implemented) +- **Behavior**: +- **Evidence**: +- **Severity**: Critical + +#### Edge Case Failures (implied by domain, not explicit in spec) +- **Case**: +- **Expected**: +- **Actual**: +- **Severity**: Important | Minor + +#### Untestable Requirements (spec requires, API doesn't expose) +- **Requirement**: +- **Issue**: +- **Severity**: Important + +### Summary +<2-3 sentence assessment: does the implementation faithfully satisfy the spec?> +``` + +**Verdicts**: +- `PASS` — all spec behaviors pass and no critical gaps found +- `CONCERNS` — edge cases fail or minor gaps exist but core behaviors work +- `FAIL` — spec-intent gaps or missing behaviors found +- `BLOCKED` — infrastructure failure prevented evaluation (tests didn't compile, binary missing, dependencies unresolvable). This is an evaluator problem, NOT an implementation problem — the orchestrator should not re-dispatch the implementer for BLOCKED results + +**Two health checks, two different meanings:** + +- **Implementation Health** failures are real findings. By the time the evaluator runs, the implementer's gate should have verified a clean build and passing tests. If the project doesn't build or existing tests fail, the implementer shipped broken work — report `FAIL` with the build/test failure as a Critical finding, not `BLOCKED`. +- **Evaluator Setup** failures are the evaluator's own problem. If your acceptance tests don't compile or your added dependencies don't resolve, that's not the implementer's fault — report `BLOCKED`. The orchestrator should not re-dispatch the implementer for `BLOCKED` results. + +## Discipline + +- **You are skeptical by default.** Your job is to find problems, not to validate. A "PASS" from you should mean something. +- **Spec is your source of truth.** If the implementation does something reasonable but different from the spec, that's a finding — the orchestrator decides whether to accept the deviation. +- **Independence is non-negotiable.** The moment you read the implementer's tests, you lose your value. Your tests must come from the spec alone. +- **Be concrete.** "Might not handle edge cases" is worthless. "TestCreateUser with empty email returns 200 instead of 400 per spec requirement 3" is actionable. +- **Separate your failures from theirs.** If the project doesn't build, that's the implementer's fault — report FAIL. If your own acceptance tests don't compile, that's YOUR problem — report BLOCKED. Never blame the implementer for your test setup failures, and never let the implementer off the hook for a broken build. + +## Rationalizations You Must Reject + +| Rationalization | Why It's Wrong | +|----------------|---------------| +| "I should read the implementer's tests to avoid duplication" | Duplication IS the point. Independent verification requires independent tests. | +| "Let me read the implementation to understand the approach" | You're testing the spec, not the approach. The public API is enough. | +| "This edge case is probably handled" | Probably isn't evidence. Write the test. | +| "The spec is ambiguous, so I'll assume the implementation is right" | Ambiguity is a finding. Report it — the orchestrator decides. | +| "The full test suite passes, so it must be correct" | The implementer's tests share the implementer's blind spots. That's why you exist. | + +## Rules + +- Never read the git diff — you evaluate against the spec, not the changes +- Never read the implementer's test files — your independence is your value +- Never modify existing code — you only write acceptance tests, then delete them +- Never close issues — the dispatcher handles arc state +- Never interact with the user — report results back to the dispatching agent +- Always clean up acceptance test files before reporting +- Format all output using GFM: fenced code blocks with language tags, headings for structure, lists for organization, inline code for paths/commands diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/agents/issue-manager.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/agents/issue-manager.md new file mode 100644 index 0000000..0d95de6 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/agents/issue-manager.md @@ -0,0 +1,162 @@ +--- +description: Use this agent when the user needs to interact with the project's issue tracking system via the `arc` CLI tool. This includes: finding recommended work (ready tasks, priorities, what to work on next), creating issues/epics/tasks, updating issue properties (status, priority, labels), closing issues with resolution notes, managing dependencies between issues (blocks, related, parent-child, discovered-from relationships), performing bulk operations (triage, closing multiple issues, creating epics with children), querying issues (listing, filtering, searching, showing details), or viewing dependency trees and blocked work analysis. +tools: + - Bash + - Read + - Glob + - Grep +model: haiku +--- + +# Arc Issue Tracker Agent + +You are a specialized agent for managing issues via the `arc` CLI tool. Execute arc commands efficiently and report results clearly. + +## Core Commands + +### Finding Work +```bash +arc ready # Show issues ready to work (no blockers) +arc list # List all issues +arc list --status=open # Filter by status +arc list --type=bug # Filter by type +arc list --priority=0 # Filter by priority (0=critical) +arc show # Detailed issue view with dependencies +arc blocked # Show all blocked issues +arc stats # Project statistics +``` + +### Creating Issues +```bash +arc create "Title" --type=task --priority=2 # New task (P2 medium) +arc create "Bug title" --type=bug --priority=1 # High priority bug +arc create "Feature" --type=feature --priority=2 # New feature +arc create "Epic" --type=epic --priority=2 # Epic for grouping + +# With multi-line description (use --stdin flag): +arc create "Title" --type=task --stdin <<'EOF' +Multi-line description here. +Context, acceptance criteria, etc. +EOF +``` + +Priority levels: 0=Critical, 1=High, 2=Medium, 3=Low, 4=Backlog +Types: task, bug, feature, epic, chore + +### Updating Issues +```bash +arc update --take # Claim work (sets session ID + in_progress) +arc update --status=blocked # Mark as blocked +arc update --priority=1 # Change priority +arc update --title="New title" # Update title + +# Update description via stdin (use --stdin flag): +arc update --stdin <<'EOF' +COMPLETED: X. IN PROGRESS: Y. NEXT: Z +EOF +``` + +### Closing Issues +```bash +arc close --reason "done" # Close single issue +arc close --reason "batch complete" # Close multiple +``` + +### Managing Dependencies +```bash +arc dep add # Issue depends on depends-on +arc dep remove # Remove dependency +arc show # View dependencies for issue +``` + +## Agent Workflow + +1. **Understand the Request**: Parse what the user wants to do +2. **Execute Commands**: Run the appropriate arc commands +3. **Report Results**: Clearly summarize what was done +4. **Handle Errors**: If a command fails, explain why and suggest fixes + +## Creating Epics with Tasks + +When asked to create an epic with subtasks: + +```bash +# 1. Create the epic +arc create "Epic: Feature name" --type=epic --priority=2 +# Returns: Created issue + +# 2. Create child tasks under the epic using --parent +arc create "Task 1 description" --type=task --parent= +arc create "Task 2 description" --type=task --parent= +``` + +The `--parent` flag automatically creates a parent-child dependency. No manual `dep add` needed. + +## Processing Task Manifests + +When receiving a structured manifest from the `plan` or `brainstorm` skills: + +1. **Parse tasks** from the `## Tasks` section — each `### T: ` block defines one task +2. **Create all tasks in parallel** using concurrent Bash tool calls — arc handles concurrent writes safely. Issue one Bash call per task in a single response: + ```bash + arc create "Task title" --type=task --parent=<epic-id> --stdin <<'EOF' + Full multi-line description here. + EOF + ``` +3. **Track the ID mapping** — record logical name (T1, T2, P1, etc.) → arc ID from each creation output +4. **Set dependencies** from the `## Dependencies` section, substituting logical names with real IDs: + ```bash + arc dep add <real-later-id> <real-earlier-id> --type=blocks + ``` +5. **Apply labels** from the `## Labels` section — use the API via the arc client: + ```bash + # Labels are managed via the REST API (no CLI command exists) + # Use arc update to add label context in the description, or + # note the labels in the summary for the dispatcher to handle + ``` +6. **Return a markdown summary table** matching the `## Required Output` format: + ``` + | Task | Arc ID | Title | + |------|----------|--------------------------| + | T1 | PROJ-5.1 | Implement storage layer | + | T2 | PROJ-5.2 | Add API endpoints | + ``` + +**Handling partial failures**: If a task creation fails mid-manifest: +- Continue creating the remaining tasks — do not abort the batch +- Report partial results clearly: "Created 4/5 tasks. T3 failed: `<error message>`" +- Include the ID mapping for all successfully created tasks so the dispatcher can act on what exists +- Do not attempt to clean up already-created tasks — the dispatcher will decide + +This is the primary interface used by the `plan` and `brainstorm` skills for bulk issue creation. + +## Bulk Operations + +For triage or bulk updates, process issues in sequence: + +```bash +# Get list of issues +arc list --status=open + +# Update each as needed +arc update <id1> --priority=1 +arc update <id2> --status=blocked +arc close <id3> --reason "resolved" +``` + +## Important Guidelines + +- Always report issue IDs after creation so the user can reference them +- When creating related issues, add dependencies to show relationships +- Use `arc show <id>` to verify changes were applied +- For complex operations, break into steps and confirm each succeeds +- If an issue is blocked, explain what's blocking it + +## Output Format + +When reporting results: +- List created issue IDs with their titles +- Confirm status changes +- Summarize any errors encountered +- Provide next steps if applicable +- Format all output (descriptions, summaries, tables) using GFM: fenced code blocks with language tags, headings for structure, lists for organization, inline code for paths/commands diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/agents/spec-reviewer.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/agents/spec-reviewer.md new file mode 100644 index 0000000..87e5f17 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/agents/spec-reviewer.md @@ -0,0 +1,75 @@ +--- +description: Use this agent for verifying that an implementation matches its task spec exactly — nothing missing, nothing extra. Dispatched by the implement skill after the implementer completes. Read-only — never modifies code. +tools: + - Bash + - Read + - Glob + - Grep +model: sonnet +--- + +# Arc Spec Reviewer Agent + +You verify whether an implementation matches its specification. Nothing more, nothing less. + +You have a fresh context window. Everything you need is in your dispatch prompt. + +## Iron Law + +**Do NOT trust the implementer's report.** The report may be incomplete, inaccurate, or optimistic. You MUST verify everything by reading actual code. + +## Your Job + +Read the implementation code and verify against the task spec: + +### Missing requirements +- Did they implement everything specified in `## Steps`? +- Are there steps they skipped or partially implemented? +- Did they claim something works but didn't actually implement it? +- Does every `## Expected Outcome` item actually work? + +### Extra/unneeded work +- Did they create files not listed in `## Files`? +- Did they add functions, methods, types, flags, or config options not in `## Steps`? +- Did they modify files outside `## Scope Boundary`? +- Did they add "nice to haves" — helpers, utilities, extra error handling, logging — that weren't requested? +- Did they refactor adjacent code? + +### Misunderstandings +- Did they interpret requirements differently than the spec states? +- Did they solve the wrong problem? +- If code blocks were provided in steps, did they write that code (or equivalent), or did they substitute their own approach? + +## How to Verify + +1. Read the task's `## Files` section — identify every file that should exist or be modified +2. Read each file. Compare actual code against what `## Steps` specified +3. Check for files changed that aren't in `## Files` (use `git diff --name-only` if a base SHA is provided) +4. Check for extra functions/types/exports beyond what the spec describes +5. Check test coverage alignment: compare the task's `## Expected Outcome` against the implementer's test assertions. Do the tests verify the behaviors the spec describes, or do they only test implementation details? Flag gaps where a spec behavior has no corresponding test assertion. + +## Report Format + +``` +## Result: COMPLIANT | ISSUES + +### Missing (only if ISSUES) +- <what's missing, with file:line references> + +### Extra (only if ISSUES) +- <what was added beyond spec, with file:line references> + +### Misunderstood (only if ISSUES) +- <what was misinterpreted, with spec quote vs actual behavior> +``` + +Use `COMPLIANT` only when the implementation matches the spec exactly — everything requested is present, nothing unrequested was added. Use `ISSUES` when anything is missing, extra, or misunderstood. + +## Rules + +- Never modify code — you are read-only +- Never trust the implementer's report — read the actual code +- Never interact with the user — report back to the dispatching agent +- Never manage arc issues — the dispatcher handles arc state +- Flag extras with the same severity as omissions — over-building is a spec violation +- Format all arc content (descriptions, comments) using GFM: fenced code blocks with language tags, headings for structure, lists for organization, inline code for paths/commands diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/blocked.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/blocked.md new file mode 100644 index 0000000..411fe7e --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/blocked.md @@ -0,0 +1,12 @@ +--- +description: Show blocked issues +--- + +Run `arc blocked` to show issues that are blocked by other issues. + +Present the results showing: +- Issue ID and title +- What's blocking it +- Priority + +This helps identify bottlenecks. Consider working on blocking issues first to unblock dependent work. diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/close.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/close.md new file mode 100644 index 0000000..7fe2f4d --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/close.md @@ -0,0 +1,33 @@ +--- +description: Close a completed issue +argument-hint: [issue-id] [--reason REASON] +--- + +Close an arc issue that's been completed. + +If arguments are provided: +- $1: Issue ID +- --reason: Completion reason (optional) + +If the issue ID is missing, ask for it. Optionally ask for a reason describing what was done. + +**Close an issue:** +```bash +arc close <id> +arc close <id> --reason "Implemented in commit abc123" +``` + +**Close multiple issues:** +```bash +arc close <id1> <id2> <id3> +``` + +**Closing epics:** +When closing an epic, consider whether all child issues are complete. You can close an epic even if children remain open, but it's better practice to: +1. Check child issues: `arc show <epic-id>` +2. Close remaining children or move them to a new epic +3. Then close the epic + +After closing, suggest checking for: +- Dependent issues that might now be unblocked (`arc ready`) +- New work discovered during this task (`arc create` with dependency) diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/create.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/create.md new file mode 100644 index 0000000..6e01551 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/create.md @@ -0,0 +1,48 @@ +--- +description: Create a new issue interactively +argument-hint: [title] [--type TYPE] [--priority N] [--parent EPIC-ID] +--- + +Create a new arc issue. If arguments are provided: +- $1: Issue title +- --type: Issue type (bug, feature, task, epic, chore) +- --priority: Priority (0-4, where 0=critical, 4=backlog) +- --parent: Parent epic ID (creates child issue) + +If arguments are missing, ask the user for: +1. Issue title (required) +2. Issue type (default: task) +3. Priority (default: 2) +4. Description (optional) +5. Parent epic (optional, for child issues) + +**Create a standalone issue:** +```bash +arc create "Fix login bug" --type bug --priority 1 +arc create "Add dark mode" --type feature +``` + +**Create with multi-line description (use --stdin flag):** +```bash +arc create "Fix login bug" --type bug --priority 1 --stdin <<'EOF' +Multi-line description here. +Steps to reproduce, context, etc. +EOF +``` + +If `--description` is also provided, it takes precedence over `--stdin`. + +**Create an epic with children:** +```bash +# Create the epic first +arc create "User Authentication System" --type epic --priority 1 + +# Create child tasks under the epic +arc create "Implement login flow" --type task --parent <epic-id> +arc create "Add password reset" --type task --parent <epic-id> +arc create "Add OAuth support" --type feature --parent <epic-id> +``` + +Child issues automatically get a parent-child dependency to the epic. + +Optionally ask if this issue should be linked to another issue using `arc dep add` (blocks, related, discovered-from). diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/db.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/db.md new file mode 100644 index 0000000..b44b7cd --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/db.md @@ -0,0 +1,19 @@ +--- +description: Database management commands +argument-hint: backup [--db PATH] +--- + +Manage the arc database. + +**Create a backup:** +```bash +arc db backup +arc db backup --db /path/to/data.db +``` + +Creates a timestamped, gzip-compressed backup next to the database file: +``` +~/.arc/data.db.20260312_155850.gz +``` + +Backups are also created automatically before major/minor version updates via `arc self update`. diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/dep.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/dep.md new file mode 100644 index 0000000..87c7f53 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/dep.md @@ -0,0 +1,35 @@ +--- +description: Manage dependencies between issues +argument-hint: add|remove <issue> <depends-on> [--type TYPE] +--- + +Manage issue dependencies with `arc dep`. + +**Add dependency:** +```bash +arc dep add <issue> <depends-on> # Default: blocks +arc dep add <issue> <depends-on> -t blocks # Explicit type +arc dep add <issue> <depends-on> -t related # Related link +``` + +**Remove dependency:** +```bash +arc dep remove <issue> <depends-on> +``` + +**Dependency types:** + +| Type | Description | Use case | +|------|-------------|----------| +| `blocks` | Issue A blocks issue B | B can't start until A is done | +| `parent-child` | Hierarchical relationship | Epic contains tasks | +| `related` | Loose association | Related work | +| `discovered-from` | Found during other work | Bug found while working on feature | + +**Epic relationships:** +When creating child issues with `--parent`, a parent-child dependency is automatically created. You can also manually link: +```bash +arc dep add <child-id> <epic-id> -t parent-child +``` + +When an issue is blocked, it won't appear in `arc ready` until its blockers are closed. diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/docs.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/docs.md new file mode 100644 index 0000000..e63965e --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/docs.md @@ -0,0 +1,52 @@ +--- +description: Search and browse arc documentation +--- + +## Two-Step Workflow + +1. **Search** to find which topic has the information: `arc docs search "query"` +2. **Read** the full topic for details: `arc docs <topic>` + +### Example + +```bash +# Step 1: Search to find where the info is +$ arc docs search "create issue" +Results for "create issue": +1. [workflows] Discovery and Issue Creation + Discovery and Issue Creation **When encountering new work... +2. [workflows] Creating Issues During Work + ... + +# Step 2: Read the workflows topic for full details +$ arc docs workflows +``` + +The search results show `[topic]` in brackets - use that topic name with `arc docs <topic>` to read the full section. + +## Search Command + +```bash +arc docs search "blocks vs related" # dependency types +arc docs search "todowrite vs arc" # boundaries +arc docs search "compaction notes" # resumability +arc docs search "session start" # workflows +``` + +Fuzzy matching handles typos - "dependncy" finds "dependency" docs. + +**Flags:** +- `-n, --limit` - Max results (default: 5) +- `--exact` - Disable fuzzy matching +- `-v, --verbose` - Show relevance scores + +## Available Topics + +| Command | Purpose | +|---------|---------| +| `arc docs` | Overview of all topics | +| `arc docs workflows` | Step-by-step checklists | +| `arc docs dependencies` | Dependency types and when to use each | +| `arc docs boundaries` | When to use arc vs TodoWrite | +| `arc docs resumability` | Writing notes that survive compaction | +| `arc docs plugin` | Claude Code plugin installation | diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/init.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/init.md new file mode 100644 index 0000000..68661ae --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/init.md @@ -0,0 +1,27 @@ +--- +description: Initialize arc in the current project +argument-hint: [project-name] +--- + +Initialize arc in the current directory. + +```bash +arc init # Use directory name as project +arc init my-project # Custom project name +arc init --prefix cxsh # Custom issue prefix (e.g., cxsh-0b7w) +arc init my-project -p cxsh # Both custom name and prefix +``` + +This command: +1. Creates a project on the arc server (or connects to existing) +2. Registers the current directory as a workspace path on the server +3. Saves project config to `~/.arc/projects/` +4. Creates AGENTS.md with workflow instructions + +**Flags:** +- `--prefix`, `-p`: Custom issue prefix basename (alphanumeric, max 10 chars). Gets normalized (lowercased, special chars stripped) and combined with a hash suffix for uniqueness. +- `--description`, `-d`: Project description +- `--quiet`, `-q`: Suppress output + +**Prerequisites:** +- Arc server must be running (`arc server start`) diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/list.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/list.md new file mode 100644 index 0000000..4516132 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/list.md @@ -0,0 +1,29 @@ +--- +description: List issues with optional filters +argument-hint: [--status STATUS] [--type TYPE] [--query SEARCH] +--- + +List arc issues with optional filtering. + +**Common filters:** +- `--status open|in_progress|blocked|deferred|closed` +- `--type bug|feature|task|epic|chore` +- `--query "search text"` +- `--limit N` + +**Examples:** +```bash +arc list # All issues +arc list --status open # Open issues only +arc list --type bug # Bugs only +arc list --type epic # Epics only +arc list --query "auth" # Search for "auth" +``` + +**Working with epics:** +```bash +arc list --type epic # Find all epics +arc show <epic-id> # View epic and its children +``` + +Present results in a clear format showing ID, status, priority, type, and title. diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/migrate-paths.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/migrate-paths.md new file mode 100644 index 0000000..a171f47 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/migrate-paths.md @@ -0,0 +1,14 @@ +--- +description: Migrate legacy project configs to server-side workspace paths +argument-hint: [--dry-run] [--force] +--- + +Migrate legacy `~/.arc/projects/` configurations to server-side workspace path registrations. + +```bash +arc migrate-paths # Run migration +arc migrate-paths --dry-run # Preview without making changes +arc migrate-paths --force # Re-run even if already migrated +``` + +This is a one-time migration for users upgrading from older versions of arc that stored project-to-directory mappings only in local config files. After migration, the server handles path resolution, enabling multi-machine and container support. diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/onboard.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/onboard.md new file mode 100644 index 0000000..2b09b3e --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/onboard.md @@ -0,0 +1,12 @@ +--- +description: Get oriented with the current project +--- + +Run `arc onboard` at the start of a work session to understand: + +- Current project and directory context +- Open issues and their priorities +- Blocked work and dependencies +- Recent activity + +This provides the context needed to decide what to work on. diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/paths.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/paths.md new file mode 100644 index 0000000..bb5efeb --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/paths.md @@ -0,0 +1,34 @@ +--- +description: Manage workspace path registrations for a project +argument-hint: [list|add|remove] [--all] +--- + +Manage filesystem paths associated with the current project. Paths link directories to projects for automatic project resolution. + +**List paths for current project:** +```bash +arc paths +arc paths list +``` + +**List paths across all projects:** +```bash +arc paths list --all +``` + +**Register a path:** +```bash +arc paths add <dir> +arc paths add <dir> --label "my laptop" --hostname myhost +``` + +**Unregister a path:** +```bash +arc paths remove <path-or-id> +``` + +**Flags for `add`:** +- `--label`: Human-readable label for the path +- `--hostname`: Override auto-detected hostname + +Paths are registered automatically by `arc init`. Use `arc paths add` to register additional directories (e.g., worktrees, secondary checkouts). diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/prime.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/prime.md new file mode 100644 index 0000000..dd1c329 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/prime.md @@ -0,0 +1,7 @@ +--- +description: Output AI-optimized workflow context +--- + +Run `arc prime` to output workflow context for AI assistants. + +This is automatically run by SessionStart and PreCompact hooks. You typically don't need to run it manually. diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/project.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/project.md new file mode 100644 index 0000000..5ba0ad7 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/project.md @@ -0,0 +1,35 @@ +--- +description: Manage projects +argument-hint: list|create|delete|rename|merge +--- + +Manage arc projects. + +**List projects:** +```bash +arc project list +``` + +**Create project:** +```bash +arc project create my-project +``` + +**Delete project:** +```bash +arc project delete <id> +``` + +**Rename project:** +```bash +arc project rename <new-name> +arc project rename --project <id> <new-name> +``` + +**Merge projects:** +```bash +arc project merge --into <target> <source> [sources...] +``` +Merges all issues and plans from source projects into the target, then deletes source projects. Projects can be specified by name or ID. + +Each directory typically has its own project. Use `arc init` in a project directory to create and configure a project automatically. Use `arc paths add` to register additional directories to an existing project. diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/quickstart.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/quickstart.md new file mode 100644 index 0000000..4795383 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/quickstart.md @@ -0,0 +1,11 @@ +--- +description: Quick start guide for arc +--- + +Run `arc quickstart` to display a quick start guide covering: + +- Core concepts (projects, issues, dependencies) +- Basic workflow (find work, start, complete, create) +- Key commands reference +- Priority levels and issue types +- Tips for AI agents diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/ready.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/ready.md new file mode 100644 index 0000000..92fc162 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/ready.md @@ -0,0 +1,15 @@ +--- +description: Find ready-to-work tasks with no blockers +--- + +Run `arc ready` to find tasks that are ready to work on (no blocking dependencies). + +Present the results to the user showing: +- Issue ID +- Title +- Priority +- Issue type + +If there are ready tasks, ask the user which one they'd like to work on. If they choose one, run `arc update <id> --take` to claim it (sets session ID + in_progress). + +If there are no ready tasks, suggest checking `arc blocked` or creating a new issue with `arc create`. diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/self.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/self.md new file mode 100644 index 0000000..7da696b --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/self.md @@ -0,0 +1,33 @@ +--- +description: Manage the arc CLI itself (update, release channel) +argument-hint: update|channel +--- + +Self-management commands for the arc CLI. + +**Check for updates:** +```bash +arc self update --check +``` + +**Update to latest version:** +```bash +arc self update +arc self update --force # Force reinstall even if up-to-date +``` + +**View or switch release channel:** +```bash +arc self channel # Show current channel +arc self channel rc # Switch to release candidates +arc self channel nightly # Switch to nightly builds +arc self channel stable # Switch back to stable +arc self channel nightly -y # Switch without confirmation prompt +``` + +**Channels:** +- `stable` — Official releases (default) +- `rc` — Release candidates +- `nightly` — Daily builds from main branch + +Major/minor version updates automatically create a database backup before installing. diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/server.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/server.md new file mode 100644 index 0000000..9f25022 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/server.md @@ -0,0 +1,24 @@ +--- +description: Manage the arc server daemon +argument-hint: start|stop|status|logs|restart +--- + +Manage the arc server with `arc server` subcommands. + +**Start server:** +```bash +arc server start # Start as daemon +arc server start --foreground # Run in foreground +arc server start --port 8080 # Custom port +``` + +**Other commands:** +```bash +arc server stop # Stop the server +arc server status # Check if running +arc server logs # View server logs +arc server logs -f # Follow logs +arc server restart # Restart the server +``` + +**Data location:** `~/.arc/` (data.db, server.log, server.pid, cli-config.json) diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/show.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/show.md new file mode 100644 index 0000000..bebfe64 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/show.md @@ -0,0 +1,17 @@ +--- +description: Show detailed information about an issue +argument-hint: <issue-id> +--- + +Show details for an arc issue. + +If the issue ID is missing, ask the user for it or suggest running `arc list` to find issues. + +Run `arc show <id>` to display: +- Issue ID, title, status +- Priority and type +- Description +- Dependencies (blocking/blocked by) +- Labels and comments + +**For epics:** The show command also displays child issues linked via parent-child dependencies, helping you see the full scope of work in an epic. diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/stats.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/stats.md new file mode 100644 index 0000000..97e0bea --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/stats.md @@ -0,0 +1,12 @@ +--- +description: Show project statistics +--- + +Run `arc stats` to show statistics for the current project: + +- Total issues +- Open, in progress, blocked, deferred, closed counts +- Ready issues (unblocked) +- Average lead time + +This gives a quick overview of project health and progress. diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/team.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/team.md new file mode 100644 index 0000000..340a810 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/team.md @@ -0,0 +1,28 @@ +--- +description: Agent team operations +argument-hint: context [epic-id] [--json] +--- + +Manage agent team operations with `arc team`. + +**Team context:** +```bash +arc team context # All teammate-labeled issues +arc team context <epic-id> # Children of specific epic +arc team context --json # JSON output for machine consumption +arc team context <epic-id> --json # JSON for a specific epic +``` + +**Output:** Issues grouped by their `teammate:*` labels (e.g., `teammate:frontend`, `teammate:backend`). + +| Column | Description | +|--------|-------------| +| ROLE | Teammate role extracted from `teammate:*` label | +| ISSUES | Count of issues assigned to that role | +| IDS | Issue IDs for that role | + +**JSON output** includes full issue details with plans and dependencies for each role group. + +**Related commands:** +- `arc prime --role=lead` — Team lead context output +- `arc prime --role=frontend` — Teammate-specific context (or use `ARC_TEAMMATE_ROLE` env var) diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/update.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/update.md new file mode 100644 index 0000000..12112a8 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/update.md @@ -0,0 +1,30 @@ +--- +description: Update an issue's status, priority, or other fields +argument-hint: <issue-id> [--status STATUS] [--priority N] +--- + +Update an arc issue's fields. + +Available updates: +- `--status open|in_progress|blocked|deferred|closed` +- `--priority 0-4` +- `--title "new title"` +- `--description "text"` (use for resumability notes) +- `--type bug|feature|task|epic|chore` + +Examples: +```bash +arc update <id> --take # Claim work (sets session ID + in_progress) +arc update <id> --priority 1 # Raise priority +``` + +**Update description via stdin (use --stdin flag):** +```bash +arc update <id> --stdin <<'EOF' +COMPLETED: X. IN PROGRESS: Y. NEXT: Z +EOF +``` + +If `--description` is also provided, it takes precedence over `--stdin`. + +If the issue ID is missing, ask for it or suggest `arc list` to find issues. diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/which.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/which.md new file mode 100644 index 0000000..d40e12c --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/commands/which.md @@ -0,0 +1,13 @@ +--- +description: Show which project is active and how it was resolved +--- + +Run `arc which` to display the currently active project and its resolution source. + +Shows: +- The active project ID and name +- Where the project was resolved from (command line flag, local config, or server path match) +- The project config file path +- Any warnings about the configuration + +Useful for debugging project resolution issues when commands target the wrong project. diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/arc-source-sync/SKILL.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/arc-source-sync/SKILL.md new file mode 100644 index 0000000..96391d2 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/arc-source-sync/SKILL.md @@ -0,0 +1,5 @@ +--- +name: arc-source-sync +description: Fixture-only upstream source sync skill that must not be packaged by Pi migration. +--- +# Arc Source Sync Fixture diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/arc/SKILL.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/arc/SKILL.md new file mode 100644 index 0000000..9de077a --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/arc/SKILL.md @@ -0,0 +1,239 @@ +--- +name: arc +description: General arc CLI reference and workflow context. Use when the user asks about arc commands, issue tracking workflows, when to use arc vs TodoWrite, or needs help with arc configuration. +--- + +# Arc Issue Tracker + +Track complex, multi-session work with a central issue tracking system. + +## Setup + +**For Claude Code users** (recommended): +1. Install the arc plugin (provides hooks, skills, agents) +2. Run `arc onboard` in any project - it will: + - Resolve project from server-side path registration (primary mechanism) + - Or detect from local project config (`~/.arc/projects/`) + - Or prompt you to run `arc init` for new projects + +**For non-Claude users**: +```bash +arc init # Initialize project +``` + +The plugin is the single source of truth for Claude integration. It provides: +- **SessionStart/PreCompact hooks** - runs `arc prime` automatically +- **Prompt configuration** - reminds Claude to run `arc onboard` +- **Skills and resources** - detailed guides and reference +- **Agents** - for bulk operations + +## When to Use Arc vs TodoWrite + +| Use Arc | Use TodoWrite | +|---------|---------------| +| Multi-session work | Single-session tasks | +| Complex dependencies | Linear task lists | +| Discovered work patterns | Simple checklists | +| Work needing audit trail | Quick, disposable lists | + +**Rule of thumb**: When in doubt, prefer arc—persistence you don't need beats lost context. + +**Deep dive**: Run `arc docs boundaries` for detailed decision criteria. + +## Workflow Skills + +Arc includes workflow skills that guide you through the development lifecycle with built-in process discipline. + +| Skill | Purpose | Invoke when | +|-------|---------|-------------| +| `brainstorm` | Design discovery through Socratic dialogue | Starting new features or significant work | +| `plan` | Break design into implementation tasks | After brainstorm approves a design | +| `implement` | TDD execution via fresh subagents per task | Ready to implement planned tasks | +| `debug` | 4-phase root cause investigation | Encountering bugs or test failures | +| `verify` | Evidence-based completion gates | Before claiming any work is done | +| `review` | Code review dispatch and triage | After implementing a task | +| `finish` | Session completion protocol | Ending a work session | + +### Pipeline + +``` +brainstorm → plan → implement (per task) → review → finish + ↕ ↕ + debug verify +``` + +### Execution Paths + +After `plan`, choose: +- **Single-agent + subagents**: Invoke `implement`. Main agent orchestrates, subagents do TDD. Best for sequential tasks. +- **Agentic team**: Add `teammate:*` labels, invoke `arc team-deploy`. Best for parallel multi-role work. +- **Stacked PRs (arc + git-spice)**: When the epic is 3+ tasks with linear dependencies and each task is independently reviewable, ship as a stack of PRs instead of one. See [`STACKING.md`](../../STACKING.md) for the integration playbook (concept mapping, per-task loop, review iteration). + +## Quick Start + +Run `arc onboard` at session start to get project context and available issues. + +**Project Recovery**: If local project config is missing, `arc onboard` resolves the project via server-side path registration. The server is the source of truth for project-to-directory mappings. + +## CLI Reference + +Run `arc prime` for full workflow context, or `arc <command> --help` for specific commands. + +**Essential commands:** +- `arc ready` - Find unblocked work +- `arc create` - Create issues +- `arc update` - Update status/fields +- `arc close` - Complete work +- `arc show` - View details +- `arc dep` - Manage dependencies +- `arc share` - Manage encrypted plan shares (create, show, approve, comments, pull, list, update, delete) +- `arc which` - Show active project and resolution source +- `arc paths` - Manage workspace path registrations +- `arc project` - Manage projects (list, create, delete, rename, merge) +- `arc self update` - Update arc CLI to latest version +- `arc db backup` - Create database backup + +## Deep Dive Documentation + +**Two-step workflow:** +1. **Search** to find which topic has the info: `arc docs search "query"` +2. **Read** the full topic for details: `arc docs <topic>` + +```bash +# Search returns [topic] in brackets - tells you where to look +arc docs search "create issue" +# Results show: [workflows] Discovery and Issue Creation... + +# Then read that topic for full content +arc docs workflows +``` + +Fuzzy matching handles typos - "dependncy" finds "dependency" docs. + +**Available topics** with `arc docs <topic>`: + +| Command | Purpose | +|---------|---------| +| `arc docs boundaries` | When to use arc vs TodoWrite - decision matrix, integration patterns, common mistakes | +| `arc docs workflows` | Step-by-step checklists for session start, epic planning, side quests, handoff | +| `arc docs dependencies` | Dependency types (blocks, related, parent-child, discovered-from) and when to use each | +| `arc docs resumability` | Writing notes that survive compaction - templates and anti-patterns | +| `arc docs plans` | Plan patterns (inline, parent-epic, shared) with examples | +| `arc docs plugin` | Claude Code plugin and Codex CLI integration guide | + +Run `arc docs` without a topic to see an overview. + +## Agent Mode + +For bulk operations (creating epics with tasks, batch updates), use the **issue-manager** agent via the Task tool. This runs arc commands without consuming main conversation context. + +## Dependency Types + +Arc supports four dependency types: + +| Type | Purpose | Affects Ready? | +|------|---------|----------------| +| **blocks** | Hard blocker - B can't start until A complete | Yes | +| **related** | Soft link - informational only | No | +| **parent-child** | Epic/subtask hierarchy | Yes | +| **discovered-from** | Track provenance of discovered work | No | + +**Deep dive**: Run `arc docs dependencies` for examples and patterns. + +## Design Reviews + +Design docs live in `docs/plans/` as filesystem markdown. Arc registers them on one of three review surfaces, chosen at create time by the `/arc:brainstorm` skill based on who's reviewing and whether encryption is needed. Each surface has its own CLI verb set; `/arc:plan` and any other consumer reads line 1 of the doc — `<!-- arc-review: kind=<legacy|share-local|share-remote> id=<id> -->` — to know which CLI to call. + +**Surfaces:** + +| `kind` | Create command | URL pattern | Encrypted? | Best for | +|---|---|---|---|---| +| `legacy` | `arc plan create <file>` | `http://localhost:7432/planner/<id>` | no | Solo, plain HTTP, simplest comment thread | +| `share-local` | `arc share create <file>` | `http://localhost:7432/share/<id>#k=<key>` | yes | Solo, but want annotations + accept-resolve UI | +| `share-remote` | `arc share create <file> --remote` | `<remote>/share/<id>#k=<key>` (default `https://arcplanner.sentiolabs.io`) | yes | Reviewers on other machines | + +`arc share create --server <url>` overrides `--remote` to target an explicit server. + +For the encrypted surfaces, the author's edit tokens live in the arc-server's local keyring (a `shares` table in `~/.arc/data.db`) — multi-client accessible via `/api/v1/shares`, never written to disk as JSON. Legacy plans don't have edit tokens; the URL is just the planner path. + +### `arc share` commands (share-local, share-remote) + +| Command | Purpose | +|---------|---------| +| `arc share create <file-path> [--remote]` | Encrypt a plan and create a share, returns share ID. Default is local; `--remote` targets the configured share server. Output prints a single URL: `Preview URL` (local) or `Author URL` (shared) — the reviewer URL is obtained from the in-page **Share link** button on the share page header, not the CLI. | +| `arc share show <id>` | Decrypt and print plan content (use `--author-url` to reprint the Author URL) | +| `arc share approve <id>` | Mark the share as approved | +| `arc share comments <id>` | All review comments + statuses | +| `arc share pull <id>` | Accepted-only comments (the agent-input form) | +| `arc share list` | List shares known to this machine (incl. `plan_file` mapping). Add `--json` for `[{id, kind, url, key_b64url, plan_file, created_at}]` — pipe to `jq` to look up a share's local file path | +| `arc share update <id> <plan-file>` | Replace the encrypted plan content (in-place; ID stays stable) | +| `arc share delete <id>` | Delete a share (`--force` cleans up local keyring entries when the server is already gone) | + +### `arc plan` commands (legacy) + +| Command | Purpose | +|---------|---------| +| `arc plan create <file-path>` | Register a plan on the legacy `/planner/<id>` surface (plain HTTP, no encryption). There's no in-place update — re-running `create` produces a new ID. | +| `arc plan show <id>` | Print plan metadata + content (the metadata header includes `File: <path>`, useful for plan-file lookups) | +| `arc plan approve <id>` | Mark the plan as approved | +| `arc plan comments <id>` | List comments on the plan (flat thread; no Accept/Resolve/Reject states) | + +### Review cycle + +create → reviewers leave annotations → author Accepts/Resolves/Rejects (encrypted surfaces) or replies inline (legacy) → `arc share pull` surfaces accepted comments to the implementation flow (legacy reads the comments thread inline since it has no accepted-only filter). Approved design content is written into the epic's description field when creating implementation tasks. Run `arc docs plans` for full details. + +The `<!-- arc-review: kind=… id=… -->` marker on line 1 of every registered design doc tells downstream skills which CLI table above to use. See `skills/brainstorm/SKILL.md` step 6 for the marker-write contract and `skills/plan/SKILL.md` step 1 for the read pattern. + +## Labels + +Labels are global (shared across all projects) and support colors and descriptions. Use labels for cross-cutting categorization like `security`, `performance`, `tech-debt`. + +## Session Protocol + +**At session start:** +```bash +arc onboard # Get context, recover project if needed +``` + +**Before ending any session:** +Invoke the `finish` skill — it handles capturing remaining work, quality gates, arc updates, commit, and push. Work is NOT done until `git push` succeeds. + +**Writing notes for resumability:** +```bash +arc update <id> --stdin <<'EOF' +COMPLETED: X. IN PROGRESS: Y. NEXT: Z +EOF +``` + +**Deep dive**: Run `arc docs resumability` for templates. + +## Common Workflows + +### Starting Work +```bash +arc onboard # Get context (recovers project if needed) +arc ready # Find available work +arc show <id> # View details +arc update <id> --take # Claim work (sets session ID + in_progress) +``` + +### Creating Issues +```bash +arc create "Title" -t task # Create task +arc create "Epic title" -t epic # Create epic +arc create "Subtask" --parent <epic-id> # Create child issue +arc dep add child-id parent-id --type parent-child # Or link existing issue to epic + +# With multi-line description (use --stdin flag): +arc create "Title" -t task --stdin <<'EOF' +Description with context, acceptance criteria, etc. +EOF +``` + +### Completing Work +```bash +arc close <id> --reason "done" # Complete issue +arc ready # See what unblocked +``` + +**Deep dive**: Run `arc docs workflows` for complete checklists. diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/arc/_branch-check.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/arc/_branch-check.md new file mode 100644 index 0000000..c1a4109 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/arc/_branch-check.md @@ -0,0 +1,52 @@ +# Protected-Branch Check + +Shared reference for arc workflow skills (brainstorm, build, finish). When a skill says "perform the protected-branch check per `skills/arc/_branch-check.md`", do exactly what's in this file. + +## Why this check exists + +Direct commits to trunk (`main` / `master` / `release` / `production`) bypass review, can't be undone without a force-push that destroys teammates' history, and are how releases get broken. The cost of asking the user one question is far smaller than the cost of an unintended trunk commit — especially after they've spent an hour brainstorming or building work that now has to be rebased onto a feature branch. + +## When to run the check + +| Skill | When | +|---|---| +| `brainstorm` | Pre-flight, before any design dialogue. Sets up the branch context for everything downstream. | +| `build` | Pre-flight, before dispatching any task. Subagents will commit to whatever branch you're on. | +| `finish` | Phase 4, immediately before staging/committing. Last line of defense. | + +Run it **every time the skill runs** — don't assume a previous answer carries forward across sessions. Branch state changes; cost of asking again is one click. + +## How to run the check + +1. Get the current branch: + + ```bash + git branch --show-current + ``` + +2. If the result is **not** in the protected list (`main`, `master`, `release`, `production`), you're done — proceed with the skill. + +3. If the result **is** protected, check the project's `CLAUDE.md` (or `AGENTS.md`) for an explicit opt-out — a line like *"This project commits directly to main; skip the protected-branch check."* If present, you're done — proceed without prompting. (The project owner has consciously chosen trunk-based development.) + +4. Otherwise, use the `AskUserQuestion` tool with this exact shape — the wording matters because Claude has to recognise the branching choice and act on it: + + - **question**: `"You're on '<branch>'. Continue here, or switch to a feature branch first?"` + - **options**: + - `Switch to a feature branch` — recommended; you should run `git checkout -b <suggested-name>` (suggest a name from the work context — e.g. `feat/<topic>` for brainstorm, the arc task slug for build, a summary of the diff for finish) and proceed on the new branch + - `Stay on '<branch>'` — the user has consciously chosen trunk-direct work for this session + - `Cancel` — abort the current skill; user wants to handle branching manually first + +5. Branch on the answer: + - **Switch** → create the branch, then continue the skill on it + - **Stay** → continue on trunk + - **Cancel** → stop the skill; do not commit, do not dispatch tasks, do not write design docs + +## Why no env-var or CLI flag opt-out + +Earlier drafts had `ARC_MAIN_GUARD=off` and a bypass-token prefix. Both removed: this is a skill-level prompt, not a hook. The opt-out lives in `CLAUDE.md` so it's discoverable, version-controlled, and applies project-wide. If the user is annoyed by the prompt, the right answer is to add the `CLAUDE.md` line — not to teach Claude to skip the check on its own initiative. + +## What this check is NOT + +- Not a substitute for branch protection rules on the remote (GitHub/GitLab) — those are the actual enforcement layer +- Not a check that the *target* of `git push` is main; only that the *current* branch is. Pushing a feature branch from a main checkout is rare and not covered. +- Not a hook — there's no harness-level enforcement. If Claude skips this check, the user will only notice at PR time. The pre-flight placement (brainstorm + build) is the mitigation. diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/arc/_formatting.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/arc/_formatting.md new file mode 100644 index 0000000..20a61a5 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/arc/_formatting.md @@ -0,0 +1,26 @@ +# Content Formatting Guide + +The arc frontend renders GitHub Flavored Markdown with syntax highlighting. Follow these rules when writing issue descriptions, plans, comments, and notes. + +## Use +- **Fenced code blocks** with language tags: ` ```go `, ` ```bash `, ` ```json `, ` ```typescript `, ` ```sql `, ` ```yaml `, ` ```python `, ` ```html `, ` ```css ` +- **Headings** (`##` and `###`) for section structure +- **Bullet lists** (`-`) for unordered items and file lists +- **Numbered lists** (`1.`) for sequential steps +- **Task lists** (`- [ ]` and `- [x]`) for checklists +- **Tables** (`| col | col |`) for structured comparisons +- **Inline code** (backticks) for file paths, function names, variable names, and CLI commands +- **Bold** (`**text**`) for emphasis on key terms +- **Blockquotes** (`>`) for important callouts or notes +- **Links** (`[text](url)`) for references + +## Avoid +- Raw HTML tags — DOMPurify strips most tags +- Code fences without language tags — always specify the language for syntax highlighting +- UPPERCASE section headers (use `##` Markdown headings instead) +- Very long single-line paragraphs — use line breaks for readability + +## Code Block Languages +Supported with syntax highlighting: go, typescript, javascript, json, bash, shell, sql, yaml, markdown, html, css, python, text + +For unsupported languages, use `text` as the language tag. diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/brainstorm/SKILL.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/brainstorm/SKILL.md new file mode 100644 index 0000000..80e4a24 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/brainstorm/SKILL.md @@ -0,0 +1,348 @@ +--- +name: brainstorm +description: You MUST use this skill for any design exploration, architecture decision, or trade-off analysis before implementation begins — especially when the user says "brainstorm", "explore the design", "think through", "what approach should we take", or describes a feature with multiple valid strategies. This is the arc-native brainstorming skill that writes designs to docs/plans/ and registers them on one of three review surfaces (legacy `arc plan`, encrypted local `arc share`, or encrypted remote `arc share --remote`), depending on who's reviewing and whether encryption is needed. Always prefer this over generic brainstorming when the project uses arc issue tracking. +--- + +# Brainstorm — Design Discovery + +Explore requirements through Socratic dialogue before any implementation begins. + +## Hard Gate + +**Do NOT write any implementation code, scaffold any project, or take any implementation action until the design is approved.** Brainstorming produces a design document — not code. + +## Pre-flight: Branch Setup + +Before starting the design dialogue, perform the protected-branch check per `skills/arc/_branch-check.md`. + +Brainstorm itself doesn't commit code, but the design doc, the planned tasks, the eventual implementation, and the final commits will all land on whatever branch you start from. Catching trunk *now* avoids "we built three hours of work and it's all on main" at finish time. If the user picks "switch to a feature branch", suggest a name based on the brief they just gave you (e.g. `feat/<topic>`). + +## Workflow + +Create a task for each step below using `TaskCreate`. Mark each as `in_progress` when starting and `completed` when done. This creates a visible progress list in the CLI that carries forward into the plan skill. Step 5.5 gets its own task whether or not the user opts into grilling — "No, proceed" still counts as completing the step. + +### 1. Explore Project Context + +- Check existing files, docs, recent commits +- Review existing arc issues (`arc list`) +- Understand what already exists and what constraints are in play + +**Scope check before proceeding:** Before asking detailed clarifying questions, assess whether the request describes multiple independent subsystems (e.g., "build a platform with chat, storage, billing, and analytics"). If so, help the user decompose into sub-projects first — each sub-project gets its own brainstorm → plan → implement cycle. Don't spend questions refining details of a project that needs to be split. A decomposition sketch (what are the independent pieces, how do they relate, what order should they be built) is more valuable than a half-specified monolith. + +### 2. Ask Clarifying Questions + +- Ask questions **one at a time** — don't dump a list +- **Use the AskUserQuestion tool** for multiple-choice decisions (2-4 options) +- Use open-ended text questions only when you need freeform feedback +- Understand: purpose, constraints, success criteria, target users +- Continue until you have enough to propose approaches + +**If the user forecloses clarifying questions up front** (e.g., "no clarifying questions, just proceed", "skip to the design", "don't ask, just build"), keep this step's questions to a minimum or skip them. Step 5.5 is the explicit recovery loop in that case — depth-first interrogation against a draft, which is harder to skip past than a soft Q&A. Default 5.5's recommendation to *"Yes, grill me"* whenever step 2 was foreclosed, regardless of scale. + +**Example AskUserQuestion usage:** +``` +Question: "How should we handle session persistence?" +Options: + - "In-memory only" (simplest, lost on restart) + - "SQLite" (persistent, single-node, matches existing storage) + - "Redis" (distributed, adds infrastructure dependency) +``` + +### 3. Propose 2-3 Approaches + +- Each approach: summary, trade-offs, estimated complexity +- Include a recommendation with reasoning +- **Use the AskUserQuestion tool** to present approaches as structured choices +- Apply YAGNI — remove features from all designs that aren't explicitly required + +**Example AskUserQuestion usage:** +``` +Question: "Which approach should we go with?" +Options: + - "Approach A: ..." (recommended — trade-offs...) + - "Approach B: ..." (trade-offs...) + - "Approach C: ..." (trade-offs...) +``` + +**Capability-aware hint:** When comparing approaches, surface which imply heavier subagent model tiers during implementation. Approaches with more cross-cutting concerns, more files touched, or tighter coupling between components will likely need `opus`-tier dispatches and more review cycles. Approaches that decompose cleanly into single-file, mechanical tasks will run on `haiku`/`sonnet` and iterate faster. This is a soft consideration, not a deciding factor — but the user should see it. + +### 4. Present Design Section by Section + +- Break the design into logical sections (data model, API, UI, etc.) +- Present each section and get user approval before moving to the next +- Iterate on sections as needed based on feedback + +**Design for isolation and clarity:** Break the system into smaller units that each have one clear purpose, communicate through well-defined interfaces, and can be understood and tested independently. For each unit, you should be able to answer three questions: what does it do, how do you use it, and what does it depend on. Smaller, well-bounded units are also easier for subagents to work with — they reason better about code they can hold in context at once, and their edits are more reliable when files are focused. If a file in the design is projected to grow large, that's often a signal that it's doing too much — consider splitting the responsibility at design time. + +**In existing codebases:** Follow existing patterns. Where existing code has problems that affect the work (e.g., a file that's grown too large, unclear boundaries, tangled responsibilities), include targeted improvements as part of the design — the way a good developer improves code they're working in. Don't propose unrelated refactoring. Stay focused on what serves the current goal. + +### 5. Identify Shared Contracts (Parallel Readiness) + +If the design will produce multiple implementation tasks that could run in parallel, explicitly identify the **shared contracts** — types, interfaces, config keys, constants, and function signatures that multiple tasks will reference. + +Contracts fall into two tiers: + +- **Shared contracts** (referenced by 2+ tasks): produce **exact, copy-pasteable code blocks** including the type definition AND a contract test assertion. The T0 foundation task will write these verbatim. +- **Task-internal types** (used within a single task): use typed pseudocode (e.g., `FeedbackRequest { memory_id: i64, rating: i8 }`) — the subagent adapts to language idioms during implementation. + +Present shared contracts to the user as a "foundation layer" with exact code: + +```go +// internal/types/config.go + +// SessionConfig holds session-related settings. +type SessionConfig struct { + Timeout time.Duration `json:"timeout"` + MaxIdle int `json:"max_idle"` + Secure bool `json:"secure"` +} +``` + +```go +// internal/storage/storage.go + +// GetSession retrieves a session by ID. +// Returns nil and no error if the session does not exist. +GetSession(ctx context.Context, id string) (*Session, error) +``` + +Contract test assertions verify that the shared types satisfy compile-time expectations. Place these **inline in each relevant test file** with a clear separator: + +```go +// internal/types/config_test.go + +// --- Contract assertions --- + +// Verify SessionConfig fields exist with expected types. +var _ time.Duration = SessionConfig{}.Timeout +var _ int = SessionConfig{}.MaxIdle +var _ bool = SessionConfig{}.Secure +``` + +```go +// internal/storage/sqlite/sqlite_test.go + +// --- Contract assertions --- + +// Verify SQLiteStore satisfies the Storage interface. +var _ storage.Storage = (*SQLiteStore)(nil) +``` + +These exact definitions and contract tests become the **T0 foundation task** during planning — implemented sequentially before any parallel work begins. The T0 task writes the shared type files and embeds contract test assertions inline in each relevant test file, so that parallel agents can import these types immediately and any drift is caught at compile time. + +**Skip this step** if the design maps to a single task or purely sequential work. + +### 5.5. Grill the Design (Optional Stress-Test) + +Before publishing the design for review, save the draft to disk and offer a stress-test pass. Both this step and step 6 need the design as a file on disk, so first: + +- **Write the design document** to `docs/plans/` using `YYYY-MM-DD-<topic>.md` naming. Do this whether or not the user opts into grilling — step 6 picks it up either way. + +Then run a relentless-interrogation pass that probes the drafted design for unresolved *internal* decisions before publishing. This is a distinct job from step 7's review loop: that one processes external reviewer feedback you receive back; this one finds gaps the design didn't fully resolve, which become expensive to fix once implementation starts — and prevents publishing a version that's already known to be incomplete. + +**When to recommend it.** This is opt-in. Mark "grill" as recommended when the design appears Medium/Large per the Scale Detection table (multiple work items, multiple layers crossed, or migrations/breaking changes). For Small-scale single-task work, default the recommendation to "skip" — the overhead isn't worth it. + +**Always recommend grilling when step 2 was foreclosed.** If the user shut down clarifying questions up front, this is the recovery loop — override the scale-based default and mark *"Yes, grill me"* as recommended regardless of how small the design looks. + +**Use the AskUserQuestion tool:** + +``` +Question: "Stress-test the design before publishing?" +Options: + - "Yes, grill me" — interrogate decisions one at a time until we converge + - "No, proceed" — skip to step 6 register for review +``` + +If "Yes", run the loop: + +**Loop rules:** + +- Walk the design's decision tree **depth-first, ordered by dependency**. Resolve decisions that constrain later answers first (e.g., "what storage layer?" before "how do we serialize sessions?"). When a resolution opens new branches, recurse into them before backtracking. +- **One question per turn** via `AskUserQuestion`. Mark the recommended option. When the choice is genuinely contested, offer 2-3 options; when one option is objectively dominant, a single recommendation is fine — but never rubber-stamp open questions just because you have an opinion. +- **Codebase-first rule.** Before each question, name the symbol, file, or pattern that would answer it. If you can name one, search first (Grep / Read / symbol search) and only ask when the codebase doesn't — or can't — answer. This is the single biggest difference from step 2's clarifying questions, where you don't yet have a draft to ground against. +- **Capture resolutions in-place.** Each resolved decision is an edit to `docs/plans/<file>.md` — update the relevant section, don't maintain a separate Q&A log. The design doc is the artifact. + +**Stop when ANY of:** + +- The user says "done", "enough", or "stop" +- Two consecutive rounds surface no new unresolved branches (the tree is exhausted) +- The loop has run ~10 rounds (hard cap — if you still have open branches at this point, surface them as a "remaining open questions" note in the design doc instead of asking another) + +Then proceed to step 6. + +### 6. Register for Review + +The design doc already exists on disk from step 5.5. This step registers it for review on the surface the user picks. + +Arc supports three review surfaces. They differ along two axes — *who reviews* (just you vs. teammates on other machines) and *do you want encryption + the new annotation/accept-resolve UI* (legacy planner is plain HTTP and simpler; `arc share` is encrypted and richer). Pick based on how the design will actually be reviewed, not which command you happen to remember. + +**Use the AskUserQuestion tool:** + +``` +Question: "How would you like to review this design?" +Options: + - "Legacy planner (solo, plain HTTP, simplest)" — + `arc plan` surface at /planner/<id>. No encryption, no accept-resolve; + just a comment thread on a markdown render. Best when you want quick + review notes without setting up the share UI. + - "Encrypted local share (solo, but want annotations/accept-resolve)" — + `arc share` on this machine. Plan content + comments are encrypted at + rest in ~/.arc/data.db. Reviewer URL only works from this machine. + - "Encrypted remote share (multiple reviewers)" — + `arc share` on the configured remote server (default arcplanner.sentiolabs.io). + Reviewers on other machines can open the link. + - "Save for later" — keep the saved file (from step 5.5) and stop. No + server registration; resume in a new session. **Terminates the + skill — skip steps 7 and 8.** +``` + +Route on the answer: + +| Choice | CLI to run | Marker `kind=` | URL printed | +|---|---|---|---| +| Legacy planner | `arc plan create docs/plans/<file>.md` | `legacy` | `Review at: http://localhost:7432/planner/<id>` | +| Encrypted local | `arc share create docs/plans/<file>.md` | `share-local` | `Preview URL (local-only — not reachable by others):` | +| Encrypted remote | `arc share create docs/plans/<file>.md --remote` | `share-remote` | `Author URL (keep private — open it, then use the in-page Share link button to copy a reviewer URL):` | +| Save for later | (no command) | (no marker) | n/a | + +**Capture the ID and write the review marker.** After the create call succeeds, prepend a single HTML-comment line to the design doc so `/arc:plan` (and any future skill that queries review state) knows which CLI to call. Today only `/arc:plan` reads it — `/arc:build` and the dispatched implementer/reviewer agents read design content from the parent epic's description, not from the share/plan CLIs — but the marker is the canonical record of which surface this doc lives on. Without it, downstream falls back to `arc share list --json | jq` which doesn't cover legacy plans. + +```bash +# Run the chosen CLI and capture stdout. +OUT=$(arc share create docs/plans/2026-05-01-foo.md --remote) +echo "$OUT" # ALWAYS print verbatim — the user needs to see the URL + +# Extract the ID: +# - share-local / share-remote: the URL fragment contains /share/<id>#... +# - legacy: the first line is "Plan created: <id> (file: ..., status: ...)" +ID=$(echo "$OUT" | grep -oE '/share/[^#]+' | head -1 | sed 's|/share/||') +# For legacy, instead: ID=$(echo "$OUT" | grep -oE 'Plan created: \S+' | awk '{print $3}') + +KIND="share-remote" # legacy | share-local | share-remote (matches the chosen branch) + +# Prepend the marker idempotently. If line 1 already starts with "<!-- arc-review:", +# replace it; otherwise prepend a new line. +FILE="docs/plans/2026-05-01-foo.md" +if head -1 "$FILE" | grep -q '^<!-- arc-review:'; then + sed -i.bak "1s|.*|<!-- arc-review: kind=$KIND id=$ID -->|" "$FILE" && rm "$FILE.bak" +else + { echo "<!-- arc-review: kind=$KIND id=$ID -->"; cat "$FILE"; } > "$FILE.tmp" && mv "$FILE.tmp" "$FILE" +fi +``` + +The marker format is fixed: `<!-- arc-review: kind=<legacy|share-local|share-remote> id=<id> -->`. Always line 1, always exactly one space between fields. + +**URL handling rules — print exactly what the CLI printed, then add a kind-specific instruction:** + +- **Legacy** — print the `Review at:` line. Tell the user this URL is local-only (their browser must reach `http://localhost:7432`). +- **Encrypted local** — print the Preview URL line. Tell the user it's not reachable from other machines; if they need a reviewer on a different machine, re-create the share with `--remote` instead. +- **Encrypted remote** — print the Author URL line. Then tell the user: *"Open this URL yourself; that's the author view. To send a reviewer link, click the **Share link** button in the page header — it strips `&t=` and copies a reviewer URL to your clipboard. Don't paste the Author URL into chat or tickets — the `&t=` token gives the recipient your edit privileges."* + +The encrypted-share CLI persists the edit_token + key into the local arc keyring (a `shares` table in `~/.arc/data.db`, served by the local arc-server — never written to disk as JSON). If a share Author URL is lost, regenerate it with `arc share show <id> --author-url`. Legacy plans don't have this — the URL is just `<base>/planner/<id>` and there are no edit tokens. + +### 7. Review Loop + +**Skip this step entirely if step 6's answer was "Save for later"** — no surface was registered, no URL exists, no marker was written. Step 6 already terminated the skill in that case. + +Otherwise, print the URL from step 6 again as a reminder. **Use the AskUserQuestion tool:** + +``` +Question: "Design ready for review at <url> — how would you like to proceed?" +Options: + - "Approve" — mark the design approved and proceed to step 8 + routing analysis + - "I've finished review (pull comments now)" — fetch reviewer feedback, + apply edits, re-share if needed, repeat + - "Pause review" — design is saved; resume in a new session +``` + +Branch the CLI by the marker's `kind`: + +| kind | Approve | Pull comments | +|---|---|---| +| `legacy` | `arc plan approve <id>` | `arc plan comments <id>` (no accepted-only filter — review the thread inline) | +| `share-local` | `arc share approve <id>` | `arc share pull <id>` (accepted-only by default) | +| `share-remote` | `arc share approve <id>` | `arc share pull <id>` (accepted-only by default) | + +**Why the legacy path lacks `pull`:** legacy plan comments don't have an Accept/Resolve/Reject state — they're a flat thread. The trade-off was made when picking legacy in step 6; if the volume of comments grows, suggest re-creating the design as `share-local` so the user gets the accepted-only filter. + +**For `share-local` / `share-remote`** — only `accepted` comments flow into refinement when pulled. The author is the only one who can mark comments as `accepted` (verified by the plan's `author_name`). For `share-remote`, reviewers comment via the reviewer URL (the in-page Share link button; *not* the Author URL). + +After a refinement pass, if the design changed materially, update the review surface to match the new content. The CLI and marker handling differ by `kind`: + +| kind | Update CLI | ID stable? | Marker action | +|---|---|---|---| +| `share-local` / `share-remote` | `arc share update <id> <plan-file>` | yes | leave marker as-is | +| `legacy` | `arc plan create <plan-file>` (no in-place update — re-creates with a new ID) | **no — new ID** | rewrite line 1 with the new ID | + +For legacy, after re-creating, replace the `id=<old>` portion of line 1 with the new ID — the idempotent `sed` snippet from step 6 works as-is: set `KIND=legacy` and `ID=<new>` and the "marker already present" branch overwrites line 1. Then loop back to step 7. + +### 8. Routing Analysis & Transition + +After the design is approved (step 7's Approve), **you MUST produce a routing analysis before presenting options**. This analysis helps the user make an informed decision about what to do next. + +#### Routing Analysis + +Evaluate the approved design against these criteria and present a summary: + +| Factor | Assessment | +|--------|------------| +| **Work items** | Count of distinct implementation tasks identified in the design | +| **Parallel readiness** | Were shared contracts identified in step 5? (yes = plan needed for T0 sequencing) | +| **Files touched** | Approximate number of files created or modified | +| **Layers crossed** | Which architecture layers are involved (storage, API, CLI, frontend, tests) | +| **Risk areas** | Any migrations, API changes, or breaking changes? | +| **Scale** | Small / Medium / Large (from Scale Detection table) | + +Then produce a **recommendation** with reasoning: + +``` +📊 Routing Analysis +─────────────────── +Work items: N tasks identified +Parallel ready: Yes/No (shared contracts in step 5) +Files touched: ~N files across N directories +Layers crossed: [storage, API, CLI, ...] +Risk areas: [migrations, breaking changes, none, ...] +Scale: Small / Medium / Large + +➤ Recommendation: /arc:plan | /arc:build + Reason: <1-2 sentence justification based on the factors above> +``` + +**Routing rules** (use these to drive the recommendation): +- **→ arc:plan** when ANY of: 2+ work items, shared contracts exist, multiple layers crossed, migrations or breaking changes present, medium/large scale +- **→ arc:build** when ALL of: single work item, no shared contracts, single layer, no risk areas, small scale +- When borderline, recommend `arc:plan` — the overhead of planning is low, but the cost of a disorganized multi-task implementation is high + +After the analysis, use the **AskUserQuestion tool** — mark the recommended option: +``` +Question: "Design approved! What's next?" +Options: + - "Break into tasks with /arc:plan" (recommended — <brief reason from analysis>) + - "Implement directly with /arc:build" (for small, single-task work) + - "Done for now" (design is saved — continue in a new session) +``` + +If `/arc:build` is recommended instead, swap which option gets the "(recommended)" tag. + +- **Break into tasks**: invoke the `plan` skill, passing the review ID from the line-1 marker (the `id=…` value; whether it's a legacy plan ID or a share ID depends on `kind=…`) +- **Implement directly**: invoke the `implement` skill +- **Done for now**: tell the user the design is approved and they can run `/arc:plan` in a new session + +## Scale Detection + +| Indicator | Scale | Structure | +|-----------|-------|-----------| +| Multiple phases, weeks of work, cross-cutting concerns | Large | Meta epic → phase epics → tasks | +| Single feature, days of work, contained scope | Medium | Epic → tasks | +| One task, hours of work, obvious approach | Small | Single issue | + +## Rules + +- The ONLY next skill after brainstorm is `plan` (or `implement` for small work) +- Never invoke implementation skills from brainstorm +- Design documents go in `docs/plans/` and are registered via one of three review surfaces (`arc plan create` for legacy, `arc share create` for encrypted local, `arc share create … --remote` for encrypted remote). The skill writes a `<!-- arc-review: kind=… id=… -->` marker as line 1 of the doc so downstream skills can route their CLI calls. +- Arc issues track persistent work; TaskCreate/TaskUpdate tracks workflow progress in the CLI +- YAGNI: if the user didn't ask for it, don't design it +- Format all arc content (descriptions, plans, comments) per `skills/arc/_formatting.md` diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/brainstorm/evals/evals.json b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/brainstorm/evals/evals.json new file mode 100644 index 0000000..d0d8db9 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/brainstorm/evals/evals.json @@ -0,0 +1,23 @@ +{ + "skill_name": "brainstorm", + "evals": [ + { + "id": 0, + "eval_name": "solo-refactor-prefers-legacy", + "prompt": "I'm brainstorming a small solo refactor: extract a 200-line transcoding function in `internal/media/transcode.go` into three smaller helpers. Just me, no remote reviewers. I don't need encryption or accept/resolve workflows — a plain comment thread is fine. Walk me through what you'd do at section 6 (Save Design and Register for Review): which AskUserQuestion option you'd surface as recommended, the exact CLI command you'd run, the exact marker line you'd write to line 1 of `docs/plans/2026-05-01-transcode-refactor.md` (showing both the kind= and id= placeholder), and what URL the CLI is expected to print. Don't actually run anything — describe the plan in detail.", + "expected_output": "Recommends 'Legacy planner', shows `arc plan create docs/plans/2026-05-01-transcode-refactor.md`, marker line `<!-- arc-review: kind=legacy id=<id> -->`, prints `Review at: http://localhost:7432/planner/<id>`. No mention of `--local` or `--share` (dropped flags). No promise of `arc share pull`-style filtering." + }, + { + "id": 1, + "eval_name": "multi-machine-review-picks-share-remote", + "prompt": "I'm designing the new auth handler for our SaaS. I want my coworker Steve (on a different laptop in another city) and one other reviewer to comment before we commit to an approach. Walk me through what you'd do at section 6: which AskUserQuestion option you'd surface as recommended, the exact CLI command, the marker line for `docs/plans/2026-05-01-auth-handler.md`, and EXACTLY what URL guidance you'd give the user — including how the user obtains a reviewer URL (since the CLI no longer prints one). Don't run anything — describe the plan.", + "expected_output": "Recommends 'Encrypted remote share', shows `arc share create docs/plans/2026-05-01-auth-handler.md --remote` (uses --remote, NOT --share), marker `<!-- arc-review: kind=share-remote id=<id> -->`, prints Author URL labeled 'Author URL (keep private — open it, then use the in-page Share link button to copy a reviewer URL)'. Explicitly tells the user to open the Author URL in a browser and click the in-page Share link button to get a reviewer URL (which strips &t=). Warns NOT to paste the Author URL into chat." + }, + { + "id": 2, + "eval_name": "solo-encrypted-picks-share-local", + "prompt": "Brainstorm the queue migration design for me. Just me — no other reviewers. But I want every plan I work on stored encrypted at rest, and I want to use the new annotation/Accept/Resolve UI even though I'm the only reviewer. Walk me through section 6: which AskUserQuestion option you'd recommend, the exact CLI, the marker line for `docs/plans/2026-05-01-queue-migration.md`, and the URL guidance. Don't run anything.", + "expected_output": "Recommends 'Encrypted local share', shows `arc share create docs/plans/2026-05-01-queue-migration.md` (NO flag — local is the default; do NOT pass --local since that flag was dropped), marker `<!-- arc-review: kind=share-local id=<id> -->`, prints 'Preview URL (local-only — not reachable by others):'. Notes the URL is not reachable by reviewers on other machines." + } + ] +} diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/build/SKILL.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/build/SKILL.md new file mode 100644 index 0000000..857bee8 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/build/SKILL.md @@ -0,0 +1,365 @@ +--- +name: build +description: You MUST use this skill to execute implementation tasks from a planning artifact (the design + breakdown produced by /arc:brainstorm and /arc:plan) — especially when the user says "implement this", "build this", "execute the plan", "start coding", or wants to dispatch subagents for TDD execution of arc issues. The main agent orchestrates; it never writes implementation code directly. Always prefer this over generic implementation when the project uses arc issue tracking. +--- + +# Implement — Subagent-Driven TDD Execution + +Orchestrate task implementation by dispatching fresh `builder` subagents per task. Each subagent gets a clean context window with just the task description. + +## Core Rule + +**The main agent NEVER writes implementation code.** It orchestrates, dispatches, and reviews. If you're tempted to "just quickly fix this" — dispatch a subagent instead. + +## Pre-flight: Branch Setup + +Before dispatching any task, perform the protected-branch check per `skills/arc/_branch-check.md`. + +This catches the case where build was invoked without going through `brainstorm` first. Subagents commit to whatever branch the main agent is on — and the parallel-dispatch checkpoint push (P1) goes there too. Discovering at finish time that an entire epic landed on trunk is not recoverable cheaply. Suggest a branch name from the epic/task title if the user picks "switch." + +## Model Selection + +Every Agent dispatch can override the subagent's frontmatter model via the `model:` parameter. Use this to match model tier to task complexity. The default floor per agent is set in frontmatter — use these overrides to downgrade for trivial tasks or escalate for complex ones. + +| Task signal | Dispatch `model:` | +|---|---| +| Mechanical: 1-2 files, spec unambiguous, no cross-cutting concerns | `haiku` (downgrade from sonnet floor) | +| Standard: integration work, multi-file but contained, unambiguous | omit `model:` (use agent default) | +| Complex: 3+ files, cross-layer, design judgment required, migrations, breaking changes | `opus` | +| Re-dispatch after `BLOCKED` | escalate one tier (haiku → sonnet → opus); stop at opus | +| Re-dispatch after `NEEDS_CONTEXT` | same tier, richer context | + +Examples: + +```text +Agent(subagent_type="arc:builder", model="haiku", prompt="...") # mechanical +Agent(subagent_type="arc:builder", prompt="...") # standard (sonnet) +Agent(subagent_type="arc:builder", model="opus", prompt="...") # complex +``` + +**When unsure, omit `model:`** — the agent's frontmatter floor is calibrated for the typical case. + +**Escalation rule:** If a subagent returns `BLOCKED` with a reasoning or capability complaint, re-dispatch with the next tier up before asking the human. Stop escalating at opus — if opus also returns `BLOCKED`, escalate to the human with the subagent's blocker summary. + +## Dispatch Modes + +### Sequential (default) + +Tasks are dispatched one at a time through the orchestration loop below. Use this for: +- Most workflows — it's the safe default +- Tasks with any file overlap +- Tasks with dependency ordering (`blocks`/`blockedBy`) +- When you're unsure whether tasks are independent + +### Parallel + +Multiple tasks dispatched simultaneously using `isolation: "worktree"`. Use this **only** when ALL of these are true: +- 3+ independent tasks remain +- No shared files between any tasks in the batch +- No `blocks`/`blockedBy` dependencies between tasks in the batch +- Each task's scope is clearly defined with no ambiguity + +**When NOT to use parallel**: overlapping files, task dependencies, uncertainty about scope, fewer than 3 tasks. Default to sequential — the cost of serial execution is time; the cost of a bad parallel merge is data loss. + +## Orchestration Loop + +By default, use sequential dispatch. For independent tasks, see [Parallel Dispatch Protocol](#parallel-dispatch-protocol) below. + +**Task tracking**: At the start of implementation, create a task list using `TaskCreate` with one entry per arc issue to implement. This provides a visible progress tracker in the CLI. Update each task as you work: +- `in_progress` when dispatching the subagent +- `completed` when the task is closed in arc + +```bash +# Get the list of tasks to implement +arc list --parent=<epic-id> --status=open --json +``` + +Create a `TaskCreate` entry for each, then work through this loop: + +### 1. Find Next Task + +```bash +arc ready +# or for a specific epic: +arc list --parent=<epic-id> --status=open +``` + +### 2. Claim Task + +```bash +arc update <task-id> --take +``` + +### 3. Dispatch Agent + +Record the current HEAD before dispatching — needed for review if escalated: + +```bash +PRE_TASK_SHA=$(git rev-parse HEAD) +``` + +Check whether the task has a `docs-only` label: + +```bash +arc show <task-id> --json | jq -e '.labels[] | select(. == "docs-only")' > /dev/null 2>&1 +``` + +**If `docs-only`** (exit code 0) — spawn an `doc-writer` subagent: + +Use the template at `./doc-writer-prompt.md`. Fill placeholder `{TASK_ID}`. For docs-only work, the agent default (`haiku`) is correct — omit `model:` unless the docs task is unusually complex. + +**Otherwise** — spawn an `builder` subagent: + +Use the template at `./builder-prompt.md`. Fill placeholders (`{TASK_ID}`, `{PRE_TASK_SHA}`, `{DESIGN_EXCERPT}`) and apply Model Selection guidance (see `## Model Selection` above) for the dispatch `model:`. + +### 4. Evaluate Result + +When the subagent reports back, check its **Status** (one of `DONE | DONE_WITH_CONCERNS | BLOCKED | NEEDS_CONTEXT`) and **Gate Results**. Follow the `## Handle Implementer Status` table below for the status-specific action. In all cases, run the project test command fresh yourself — do NOT trust the subagent's report alone. + +**On `DONE`:** +- Run the project tests. If they pass → proceed to step 5 (Spec Compliance Review). +- If tests fail despite a `DONE` report, treat as `BLOCKED`: re-dispatch with the failure output. + +**On `DONE_WITH_CONCERNS`:** +- Read the concerns carefully. +- If the concerns touch correctness or scope (e.g., "I think this edge case isn't handled", "I modified a file outside the spec") — address before review by re-dispatching with specific guidance, or tightening the review prompt. +- If the concerns are observations (e.g., "this file is getting large") — note them as arc comments on the task and proceed to step 5. + +**On `BLOCKED` or `NEEDS_CONTEXT`:** +- Do NOT proceed to review. Do NOT close the task. +- For `NEEDS_CONTEXT`: gather the requested information, re-dispatch with it. +- For `BLOCKED`: assess the blocker per the Handle Implementer Status table. Escalate one model tier (haiku → sonnet → opus) per the Model Selection escalation rule, or invoke the `debug` skill if the blocker is a persistent test failure, or split the task if too large, or escalate to the human. +- After 3 re-dispatches on the same task without clean `DONE`, invoke the `debug` skill. + +**If the subagent did not include a Status field** (malformed report): +- Treat as `BLOCKED`. Re-dispatch with an explicit reminder to use the four-status Report Format. + +When re-dispatching, include the previous report's concerns / blockers so the implementer knows exactly what to fix: + +``` +Continue implementing this task. A previous attempt reported <status> with these concerns: + +<paste concerns> + +Address each concern and re-report. +``` + +### 5. Spec Compliance Review + +After confirming tests pass, dispatch the `spec-reviewer` to independently verify the implementation matches the spec: + +```bash +BASE_SHA=$PRE_TASK_SHA +``` + +Dispatch `spec-reviewer`: + +Use the template at `./spec-reviewer-prompt.md`. Fill placeholders (`{TASK_ID}`, `{BASE_SHA}`, `{HEAD_SHA}`). Spec review is a focused comparison task — the agent default is appropriate; omit `model:` unless the spec is unusually large or ambiguous. + +Handle results: +- `COMPLIANT` → proceed to Step 6 +- `ISSUES (Missing)` → re-dispatch `builder` with specific gaps listed by the spec reviewer. Re-run spec compliance review after. +- `ISSUES (Extra)` → re-dispatch `builder` to remove the extras listed by the spec reviewer. Re-run spec compliance review after. +- `ISSUES (Misunderstood)` → re-dispatch `builder` with clarification from the spec reviewer's findings. Re-run spec compliance review after. +- Circuit breaker: 3 spec-review/fix cycles without resolution → escalate to user. + +> **Docs-only tasks**: Skip this step. The spec-reviewer is designed around code verification (file lists, function signatures, test coverage) and doesn't apply to documentation. For docs-only tasks, the orchestrator verifies formatting/completeness directly: check that all files in `## Files` were created/modified, links resolve, heading hierarchy is correct, code blocks have language tags. + +### 6. Code Quality Review + +Only dispatched after spec compliance passes. Use the `review` skill or dispatch `code-reviewer` directly: + +```bash +HEAD_SHA=$(git rev-parse HEAD) +``` + +Use the template at `../review/reviewer-prompt.md`. Fill placeholders (`{TASK_ID}`, `{BASE_SHA}` = PRE_TASK_SHA recorded earlier, `{HEAD_SHA}` = current HEAD, `{DESIGN_EXCERPT}` from parent epic or "none", `{EVALUATOR_STATUS}` = "active" if evaluator was dispatched, else "not dispatched"). Follow Model Selection above for the dispatch `model:` — sonnet default is appropriate for most reviews. + +**On `{EVALUATOR_STATUS}`:** Decide whether to dispatch the evaluator (step 6.5) BEFORE filling this placeholder. If you plan to run step 6.5 in parallel with step 6, set `{EVALUATOR_STATUS}="active"`. Otherwise set `"not dispatched"`. Step 6.5 has the decision criteria for when to dispatch the evaluator. + +Handle findings: + +| Finding | Action | +|---------|--------| +| **Critical/Important** | Re-dispatch `builder` with fixes. Re-review after. | +| **Minor** | Note in arc comment. Proceed. | +| **Deviation (fix)** | Re-dispatch `builder` to match the design. | +| **Deviation (accept)** | Log as arc comment: "Accepted deviation: \<description\>. Rationale: \<why\>." Proceed. | + +Circuit breaker: 3 review/fix cycles on the same finding → escalate to user. + +> **Docs-only tasks**: Skip code quality review. For substantial documentation changes (developer-facing API docs, architecture docs), optionally dispatch `code-reviewer` for a quality check. + +### 6.5. High-Risk Evaluation (Optional) + +The evaluator is **not dispatched by default**. Dispatch only when: +- Task has a `high-risk` label +- The orchestrator judges the task warrants independent verification (e.g., complex spec with multiple valid interpretations, security-sensitive code, tasks that modify shared contracts) + +When dispatched, use `isolation: "worktree"` and the existing `evaluator` agent. The evaluator can run **in parallel with Step 6** (code quality review) since they examine orthogonal concerns: + +```bash +PARENT=$(arc show <task-id> --json | jq -r '.parent_id // empty') +``` + +Use the template at `./evaluator-prompt.md`. Fill placeholder `{TASK_ID}`. Because evaluation is adversarial verification on high-risk tasks, escalate one tier from the agent default (typically to `opus`) — set `model: "opus"` on the dispatch unless the task is narrow. + +When dispatching alongside the evaluator, update the code quality reviewer's `## Evaluator Status` to `active`. + +Triage evaluator findings: + +| Evaluator verdict | Orchestrator action | +|---|---| +| `PASS` | No action — evaluator confirms the spec intent is satisfied. | +| `CONCERNS` | Read the concerns. Re-dispatch `builder` if the concerns describe substantive behavior gaps. Otherwise note as arc comments and proceed. | +| `FAIL — Spec-Intent Gap` | Re-dispatch `builder` with the evaluator's quoted spec text and the failing behavior description. | +| `FAIL — Missing Behavior` | Re-dispatch `builder` — the spec requires behavior that wasn't built. | +| `FAIL — Edge Case` | Lower-severity. Re-dispatch if the spec clearly implies the edge case; otherwise record as a known limitation. | +| `ERROR — Cannot Test` | The public API is insufficient. Re-dispatch with a request to expose the needed surface. | +| `BLOCKED` | Evaluator itself is blocked. Escalate per the Model Selection rules or involve the human. | + +### 7. Close Task + +```bash +arc close <task-id> -r "Implemented: <summary>" +``` + +### 8. Integration Checkpoint + +After closing 2-3 related tasks, or before switching to a new epic phase, run the full integration test suite: + +```bash +make test-integration +``` + +This catches cross-task regressions that individual implementer gate checks won't — each implementer only validates its own task's scope. Do not wait until all tasks are complete to discover integration failures. + +If integration tests fail: +- Identify which task's changes caused the failure +- Re-dispatch `builder` with the failing test details and the relevant task context +- If the failure spans multiple tasks, invoke the `debug` skill + +### 9. Repeat + +Go to step 1 for the next task. Continue until all tasks in the epic are closed. + +## Handle Implementer Status + +Every `builder` and `doc-writer` dispatch returns one of four terminal statuses. Handle each explicitly: + +| Status | Orchestrator action | +|---|---| +| `DONE` | Proceed to spec review, then code review. | +| `DONE_WITH_CONCERNS` | Read the concerns. If they're about correctness or scope, address before review (re-dispatch or tighten review prompt). If they're observations (file getting large, naming doubt), note them as arc comments on the task and proceed to review — close only after a later dispatch yields a clean `DONE`. | +| `BLOCKED` | Assess the blocker: (1) context problem → provide missing context, re-dispatch same tier; (2) reasoning limit → re-dispatch one tier up per the Model Selection escalation rule; (3) task too large → split and re-plan; (4) plan is wrong → escalate to human. Never retry the same dispatch unchanged. | +| `NEEDS_CONTEXT` | Gather the specific missing information. Re-dispatch with it in the prompt. | + +**Never close a task** whose last report was `BLOCKED`, `NEEDS_CONTEXT`, or `DONE_WITH_CONCERNS` unresolved. Re-dispatch until you have a clean `DONE` — then close. + +## Parallel Dispatch Protocol + +When you have identified a batch of truly independent tasks (see [Dispatch Modes](#dispatch-modes)), switch from the sequential loop to this protocol: + +### P1. Commit Checkpoint + +Before switching to parallel, ensure all sequential work is committed and pushed: + +```bash +git status # Must be clean — no unstaged or uncommitted changes +git log -3 # Verify recent sequential commits are present +git push # Establish a recovery point on the remote +``` + +**Hard gate**: Do NOT proceed if `git status` shows uncommitted changes. + +### P2. Record HEAD Anchor + +```bash +PARALLEL_BASE=$(git rev-parse HEAD) +echo "Parallel base: $PARALLEL_BASE" +``` + +This is the baseline all worktrees will branch from. Record it — you'll need it for verification after merge. + +### P3. Verify Independence + +For each task in the planned parallel batch: + +```bash +arc show <task-id> +``` + +Confirm: +- No `blocks`/`blockedBy` relationships between tasks in this batch +- No overlapping file paths in task descriptions +- Each task has a clearly scoped, non-ambiguous specification + +If any task fails these checks, remove it from the parallel batch and handle it sequentially after. + +### P4. Dispatch in Single Turn + +All parallel Agent tool calls with `isolation: "worktree"` **must happen in the same orchestrator message**. This ensures they all branch from the same HEAD. + +``` +# In a single response, dispatch all parallel tasks: +Agent(subagent_type="arc:builder", isolation="worktree", prompt="Task 1...") +Agent(subagent_type="arc:builder", isolation="worktree", prompt="Task 2...") +Agent(subagent_type="arc:builder", isolation="worktree", prompt="Task 3...") +``` + +**Never** dispatch worktree agents across multiple turns — HEAD may move between turns, causing stale branches. + +### P5. Merge-Back Verification + +After all parallel agents report back, verify the merge did not lose work: + +```bash +# 1. Check HEAD against the recorded anchor +git log --oneline $PARALLEL_BASE..HEAD # Should show ONLY the parallel agents' commits + +# 2. Verify sequential commits are still in history +git log --oneline HEAD | head -20 # All prior sequential commits must be present + +# 3. Run full test suite +make test # or project-specific test command +``` + +**If sequential commits are missing** → STOP. Do not continue. Recover from reflog: + +```bash +git reflog # Find the pre-merge state +git log --oneline <reflog-ref> # Verify it has the missing commits +# Cherry-pick or reset as appropriate — ask user if unsure +``` + +### P6. Resume Sequential + +After successful verification, return to the normal orchestration loop (step 1) for any remaining tasks. + +## When to Invoke Debug + +- Subagent reports test failures it can't resolve after reasonable effort +- 3+ implementation attempts fail on the same issue +- A regression appears that isn't explained by the current task's changes + +## Arc Commands Used + +```bash +arc ready # Find next task +arc update <id> --take # Claim task (sets session ID + in_progress) +arc show <id> # Get task description for subagent +arc close <id> -r "reason" # Close completed task +``` + +## Rules + +- Never write implementation code as the main agent — always dispatch +- Never close a task without confirming tests pass yourself (fresh run) +- Never close a task if the implementer reported `BLOCKED`, `NEEDS_CONTEXT`, or unresolved `DONE_WITH_CONCERNS` without re-dispatching +- When re-dispatching after `BLOCKED`, escalate one model tier per the Model Selection table — never retry the same dispatch unchanged +- If in doubt about the result, re-dispatch rather than fixing manually +- Never dispatch parallel agents without committing and pushing all sequential work first +- Never dispatch parallel agents on tasks that share files +- Never proceed after parallel merge without verifying commit history against the recorded HEAD anchor +- Never mix sequential and parallel dispatch in the same batch — finish one mode before switching to the other +- Format all arc content (descriptions, plans, comments) per `skills/arc/_formatting.md` diff --git a/packages/pi-arc/skills/arc-build/builder-prompt.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/build/builder-prompt.md similarity index 100% rename from packages/pi-arc/skills/arc-build/builder-prompt.md rename to packages/pi-arc/tests/fixtures/arc-plugin-source/skills/build/builder-prompt.md diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/build/doc-writer-prompt.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/build/doc-writer-prompt.md new file mode 100644 index 0000000..c04795d --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/build/doc-writer-prompt.md @@ -0,0 +1,41 @@ +# Doc Writer Prompt Template + +Use this template when dispatching `doc-writer` for a task labeled `docs-only`. + +**Placeholders:** +- `{TASK_ID}` — arc issue ID + +````text +You are writing/updating documentation for arc task {TASK_ID}. + +## Task Spec +<paste output of: arc show {TASK_ID}> + +## Your Job + +1. Read the task spec end-to-end +2. Only modify files listed in the task's `## Files` section +3. Follow the project's existing markdown style (check neighboring docs) +4. Use fenced code blocks with language tags (per arc formatting rules) +5. Verify internal links resolve and heading hierarchy has no skipped levels +6. Commit with a conventional commit message prefixed `docs(...)` + +## Verification Before Reporting + +Run the checks listed in the task's `## Verification` section. If none are specified: +- All internal relative links point to existing files +- Heading hierarchy uses `##` → `###` with no skipped levels +- All code blocks have language tags +- No HTML tags (DOMPurify strips them) + +## Report Format + +Report back with one of: `DONE` | `DONE_WITH_CONCERNS` | `BLOCKED` | `NEEDS_CONTEXT`. + +Include: +1. Status +2. Summary (one paragraph) +3. Files changed +4. Verification checks run and their outcome +5. Concerns / Blockers / Missing context (non-DONE only) +```` diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/build/evaluator-prompt.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/build/evaluator-prompt.md new file mode 100644 index 0000000..6b4cd3f --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/build/evaluator-prompt.md @@ -0,0 +1,88 @@ +# Evaluator Prompt Template + +Use this template when dispatching `evaluator` for adversarial verification of a high-risk task. + +**Placeholders:** +- `{TASK_ID}` — arc issue ID + +````text +You are the adversarial evaluator for arc task {TASK_ID}. + +## Task Spec +<paste output of: arc show {TASK_ID}> + +## Your Job + +You have NOT seen the diff or the implementer's tests. Your job is to: + +1. Derive acceptance tests purely from the spec +2. Write them as ephemeral test files (prefix with `_eval_` — will be deleted) +3. Run them against the current code +4. Report which pass, which fail, and what the gap between spec-intent and built-behavior looks like + +You are the devil's advocate. The implementer believes the task is done. Prove it, or find the gap. + +## Process + +1. Read the spec. Identify every behavior the spec claims. +2. For each behavior, write a test that would fail if the behavior were missing. +3. Place tests in a location appropriate to the codebase (e.g., `_eval_<name>_test.go`). +4. Run the tests. +5. Collect pass/fail outcomes with evidence. +6. Delete your ephemeral tests (leave the codebase as you found it). +7. Report. + +## Report Format + +```text +## Evaluation: PASS | CONCERNS | FAIL | BLOCKED + +### Implementation Health (pre-check) +- Project builds: PASS | FAIL +- Existing tests pass: PASS | FAIL +- Binary/API available: PASS | FAIL + +### Evaluator Setup (self-check) +- Acceptance test compilation: PASS | FAIL (<error if failed>) +- Evaluator dependencies resolved: PASS | FAIL + +### Spec Coverage (<N> behaviors) +- [PASS] <expected behavior 1> +- [PASS] <expected behavior 2> +- [FAIL] <expected behavior 3> — <brief reason> +- ... + +### Findings + +#### Spec-Intent Gaps (implementation differs from spec) +- **Behavior**: <what the spec says> +- **Expected**: <what your test expected> +- **Actual**: <what happened> +- **Severity**: Critical | Important + +#### Missing Behaviors (spec requires, not implemented) +- **Behavior**: <what the spec requires> +- **Evidence**: <how you determined it's missing> +- **Severity**: Critical + +#### Edge Case Failures (implied by domain, not explicit in spec) +- **Case**: <the edge case> +- **Expected**: <reasonable behavior> +- **Actual**: <what happened> +- **Severity**: Important | Minor + +#### Untestable Requirements (spec requires, API doesn't expose) +- **Requirement**: <what the spec says> +- **Issue**: <why it can't be tested through the public API> +- **Severity**: Important + +### Summary +<2-3 sentence assessment: does the implementation faithfully satisfy the spec?> +``` + +**Verdicts**: +- `PASS` — all spec behaviors pass and no critical gaps found +- `CONCERNS` — edge cases fail or minor gaps exist but core behaviors work +- `FAIL` — spec-intent gaps or missing behaviors found (sub-kinds: Spec-Intent Gap / Missing Behavior / Edge Case) +- `BLOCKED` — infrastructure failure prevented evaluation (tests didn't compile, binary missing, dependencies unresolvable). This is an evaluator problem, NOT an implementation problem — the orchestrator should not re-dispatch the implementer for BLOCKED results +```` diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/build/spec-reviewer-prompt.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/build/spec-reviewer-prompt.md new file mode 100644 index 0000000..4d1b058 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/build/spec-reviewer-prompt.md @@ -0,0 +1,45 @@ +# Spec Reviewer Prompt Template + +Use this template when dispatching `spec-reviewer` after an implementer reports `DONE`. + +**Placeholders:** +- `{TASK_ID}` — arc issue ID +- `{BASE_SHA}` — pre-task SHA (recorded before dispatching the implementer) +- `{HEAD_SHA}` — current HEAD after implementer's commit + +````text +You are verifying that arc task {TASK_ID}'s implementation matches its spec exactly. + +## Task Spec +<paste output of: arc show {TASK_ID}> + +## Changes +<paste output of: git diff {BASE_SHA}..{HEAD_SHA}> + +## Your Job + +Compare the diff against the spec. For each requirement in the spec: +- Is it implemented? If yes, cite the file and line. +- If no, flag the gap. + +For the diff: +- Is anything present that the spec did NOT ask for? Flag it. +- Are files modified outside the task's `## Files` section? Flag as scope violation. + +You do NOT write code. You do NOT run tests. You do NOT close issues. + +## Report Format + +```text +## Result: COMPLIANT | ISSUES + +### Missing (only if ISSUES) +- <what's missing, with file:line references> + +### Extra (only if ISSUES) +- <what was added beyond spec, with file:line references> + +### Misunderstood (only if ISSUES) +- <what was misinterpreted, with spec quote vs actual behavior> +``` +```` diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/debug/SKILL.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/debug/SKILL.md new file mode 100644 index 0000000..25b60aa --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/debug/SKILL.md @@ -0,0 +1,91 @@ +--- +name: debug +description: You MUST use this skill when encountering any bug, test failure, unexpected behavior, nil pointer, panic, or error that needs root cause investigation — especially when the user says "debug", "investigate", "why is this failing", "root cause", or pastes a stack trace or error log. This is the arc-native debugging skill that enforces systematic investigation before any fix attempt. Always prefer this over generic debugging when the project uses arc issue tracking. +--- + +# Debug — Systematic Root Cause Investigation + +Investigate bugs methodically before attempting fixes. No guessing, no shotgunning, no Stack Overflow copypasta. + +## Iron Law + +**NO FIXES WITHOUT ROOT CAUSE INVESTIGATION FIRST.** + +If you don't understand why something is broken, you cannot fix it. A "fix" without understanding is a coincidence. + +## 4-Phase Process + +Create a TodoWrite checklist with these phases and work through them: + +### Phase 1: Investigate Root Cause + +- Read error messages **carefully** — they often tell you exactly what's wrong +- Reproduce the failure consistently — if you can't reproduce it, you can't verify a fix +- Check recent changes: `git diff`, `git log --oneline -10` +- Gather evidence: stack traces, logs, test output, error codes +- In multi-component systems, trace the data flow end-to-end +- **Do not propose fixes yet.** You are gathering evidence. + +### Phase 2: Pattern Analysis + +- Find working examples of similar code in the codebase +- Compare working code against broken code — what's different? +- Check if this is a known pattern (dependency version, config issue, API change) +- Look for similar past issues: `arc list --type=bug` + +### Phase 3: Hypothesis Testing + +- Form a **single** hypothesis about the root cause +- Design a minimal test to confirm or reject it — one change, one test +- If the hypothesis is wrong, **revert** the test change and form a new hypothesis +- Do NOT stack fixes — each hypothesis gets tested in isolation +- Document what you've tried and what you've learned + +### Phase 4: Implement Fix + +- Write a failing test that **demonstrates the bug** (the test should fail before the fix and pass after) +- Fix the **root cause**, not the symptom +- Verify the fix makes the bug test pass +- Run the **full test suite** to check for regressions +- If the fix introduces new failures, you fixed the wrong thing — go back to Phase 1 + +## The 3-Fix Rule + +If you've tried 3 fixes and none worked, **STOP**. + +You don't understand the problem yet. Going for fix #4 is insanity. + +Instead: +- Go back to Phase 1 and investigate more deeply +- Question your assumptions — are you fixing the right thing? +- Consider whether the architecture is wrong, not just the code +- Read the error message again — you probably skimmed it the first time + +## Arc Integration + +If the bug turns out to be bigger than expected (not a quick fix within the current task): + +```bash +arc create "Bug: <description>" --type=bug --priority=<severity> +``` + +Then decide: fix it now (if it blocks current work) or defer it (if current work can continue without it). + +## Red Flags + +You're doing it wrong if you: +- Fix symptoms instead of causes +- Apply fixes without understanding why they work +- Copy code from the internet without understanding it +- Make multiple changes at once ("let me try this AND this AND this") +- Skip the failing test that demonstrates the bug +- Say "it works now" without understanding what changed + +## Rules + +- Always investigate before fixing — Phase 1 is not optional +- Always write a bug-demonstrating test before the fix +- Always run the full test suite after fixing +- Revert failed fix attempts cleanly — don't leave debris +- After debugging, return to the calling skill — typically `implement` step 4 to re-verify the subagent's result, or `verify` to re-run the gate sequence +- Format all arc content (descriptions, plans, comments) per `skills/arc/_formatting.md` diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/finish/SKILL.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/finish/SKILL.md new file mode 100644 index 0000000..dcf65a5 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/finish/SKILL.md @@ -0,0 +1,153 @@ +--- +name: finish +description: You MUST use this skill at the end of any session, when the user says "land the plane", "wrap up", "done for the day", "finish up", "session complete", "push and close", or indicates work is complete. This is the arc-native session completion protocol that captures remaining work as arc issues, runs quality gates, updates arc issue statuses, commits, and pushes. Always prefer this over generic branch-finishing when the project uses arc issue tracking. +--- + +# Finish — Unified Session Completion + +Complete the session: capture remaining work, pass quality gates, update arc, commit, push. One protocol for all contexts. + +## Iron Law + +**Work is NOT done until `git push` succeeds. No exceptions.** + +Uncommitted code doesn't exist. Unpushed commits are local fiction. The remote is the source of truth. + +## Protocol + +Create a TodoWrite checklist with all steps and work through them: + +### Phase 1: Capture Remaining Work + +1. Review what was planned vs what was completed +2. For any unfinished work or newly discovered tasks: + ```bash + arc create "Remaining: <description>" --type=task + ``` +3. Add context notes to new issues so the next session can pick up: + ```bash + arc update <id> --description "CONTEXT: <what was done, what remains, any gotchas>" + ``` + +### Phase 2: Quality Gates + +*Skip this phase if no code was changed in this session.* + +4. Run project test suite: + ```bash + make test # or: go test ./..., npm test, etc. + ``` +5. Run linter/formatter if configured: + ```bash + make lint # or: golangci-lint run, eslint, etc. + ``` +6. Run build if applicable: + ```bash + make build + ``` +7. **Hard gate**: If tests fail, fix them. Do NOT skip to commit. Invoke `debug` if needed. + +### Phase 3: Update Arc Issues + +8. Close completed issues: + ```bash + arc close <id> -r "Done: <summary of what was completed>" + ``` +9. Update in-progress issues with progress notes: + ```bash + arc update <id> --description "PROGRESS: <what's done>. NEXT: <what remains>" + ``` +10. Verify issue states match reality — don't leave stale statuses + +### Phase 4: Commit and Push + +11. Stage changed files (specific files, not `git add -A`): + ```bash + git add <file1> <file2> ... + ``` +12. **Protected-branch check** — perform the check per `skills/arc/_branch-check.md`. This is the *last* place to catch trunk-direct work; ideally `brainstorm` or `build` already established a feature branch earlier, but check anyway because some flows skip those skills. +13. Commit with conventional commit message: + ```bash + git commit -m "feat(scope): summary of changes" + ``` +14. Push: + ```bash + git push + ``` +15. Verify push succeeded: + ```bash + git status # Must show "up to date with origin" + ``` +16. If push fails → resolve the issue → retry → succeed. Do not leave unpushed commits. +17. Clean up worktrees: + ```bash + git worktree list + ``` + If only the main working tree is listed, skip ahead. Otherwise, for each extra worktree: + + **a. Check for uncommitted work:** + ```bash + git -C <worktree-path> status + git -C <worktree-path> stash list + ``` + If there are uncommitted changes or stashes → do NOT remove. Create an arc issue to track the unmerged work: + ```bash + arc create "Recover unmerged worktree work: <branch>" --type=task + ``` + + **b. Check if the branch was merged:** + ```bash + git branch --merged | grep <worktree-branch> + ``` + If merged (or if the worktree is clean with no unique commits), safe to remove: + ```bash + git worktree remove <worktree-path> + git branch -d <worktree-branch> # Delete the merged branch + ``` + + **c. If the branch has unmerged commits but no uncommitted changes:** + Check whether the commits exist on a remote: + ```bash + git log origin/<worktree-branch> 2>/dev/null + ``` + If pushed → safe to remove locally. If not pushed → do NOT remove; create an arc issue. + + **d. Prune stale worktree references:** + ```bash + git worktree prune + ``` + +### Phase 5: Verify and Hand Off + +18. Confirm the commit: + ```bash + git log -1 # Verify latest commit is visible + ``` +19. Output context for next session: + ```bash + arc prime + ``` + +## Context-Aware Behavior + +| Session Type | Behavior | +|-------------|----------| +| **Single-agent** | Full protocol above | +| **Team lead** | Verify teammate work → close arc issues → team cleanup → commit → push | +| **Teammate** | Commit → push (team lead handles arc close and coordination) | + +## What's NOT in This Protocol + +- `git stash clear`, `git remote prune origin` — housekeeping, not gates +- Worktree directory `.gitignore` verification — assumed to be configured at project setup +- Merge/PR/keep/discard choice — arc workflow always commits and pushes +- Performative session summaries — `arc prime` handles handoff context + +## Rules + +- Never skip Phase 2 (quality gates) when code has changed +- Never commit with `git add -A` — stage specific files +- Never leave unpushed commits +- Never close arc issues without completing the work +- Always run `arc prime` at the end for next-session context +- Format all arc content (descriptions, plans, comments) per `skills/arc/_formatting.md` diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/plan/SKILL.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/plan/SKILL.md new file mode 100644 index 0000000..ff01e96 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/plan/SKILL.md @@ -0,0 +1,393 @@ +--- +name: plan +description: You MUST use this skill to break a design or feature into implementation tasks — especially after brainstorming, when the user says "plan this", "break this down", "create tasks", or wants to turn a design into actionable arc issues with exact file paths. Creates self-contained arc issues that subagents can implement with zero prior context. Always prefer this over generic planning when the project uses arc issue tracking. +--- + +# Plan — Implementation Task Breakdown + +Break an approved design into bite-sized, self-contained tasks with exact file paths and steps. + +## Review Commands + +Design docs live in `docs/plans/<file>.md`. The brainstorm skill registers each doc on one of three review surfaces and writes a routing marker as line 1 of the doc itself: + +``` +<!-- arc-review: kind=<legacy|share-local|share-remote> id=<id> --> +``` + +**Always read the marker before invoking any review CLI.** The plan skill's CLI calls branch on `kind`: + +| kind | Show content | List comments | Pull accepted | Approve | Update content | +|---|---|---|---|---|---| +| `legacy` | `arc plan show <id>` | `arc plan comments <id>` | n/a — review thread inline | `arc plan approve <id>` | re-create the plan (no in-place update) | +| `share-local` | `arc share show <id>` | `arc share comments <id>` | `arc share pull <id>` | `arc share approve <id>` | `arc share update <id> <path>` | +| `share-remote` | `arc share show <id>` | `arc share comments <id>` | `arc share pull <id>` | `arc share approve <id>` | `arc share update <id> <path>` | + +Read the marker with one shell call: + +```bash +MARKER=$(head -1 docs/plans/<file>.md) +KIND=$(echo "$MARKER" | grep -oE 'kind=[a-z-]+' | cut -d= -f2) +ID=$(echo "$MARKER" | grep -oE 'id=\S+' | sed 's/id=//' | tr -d '>' | xargs) +# Now branch on $KIND for every review CLI call. +``` + +**Encrypted-share keyring.** For `share-local` and `share-remote`, the author's edit tokens live in the arc-server's local keyring (a `shares` table in `~/.arc/data.db`) — not in any JSON file. `arc share show <id> --author-url` reprints the Author URL if it's lost. Legacy plans don't have edit tokens; the URL is just `<base>/planner/<id>`. + +**Fallback for unmarked design docs.** Older design docs created before the marker contract may not have line 1 set. If the marker is missing, fall back to: + +```bash +arc share list --json | jq -r '.[] | select(.plan_file=="docs/plans/<file>.md") | .id' +``` + +This only covers `share-*` plans (legacy plans aren't in the share keyring). If the fallback returns no result, ask the user which review surface the plan was registered on. + +## Granularity Rule + +Each task step is **ONE action, 2-5 minutes**. Assume the implementer has **zero codebase context** and fresh context without codebase familiarity. If a step says "add validation" without showing the code, it's too vague. + +## No Placeholders + +Every step in a task description must contain the actual content an implementer needs. These are **plan failures** — never write them: + +- `"Add appropriate error handling"` / `"add validation"` / `"handle edge cases"` — show the actual code +- `"Write tests for the above"` without test code — include the test code +- `"Similar to Task N"` — repeat the content; the implementer has zero context of other tasks +- Steps that describe what to do without showing how — code blocks required for code steps +- References to types, functions, or methods not defined in any task or already on HEAD +- `"TBD"`, `"TODO"`, `"implement later"`, `"fill in details"` + +Code blocks represent the **intent, structure, and behavior** — not a character-for-character mandate. The implementer follows the code block's signatures, logic, and patterns but adapts naming, error handling, and scaffolding to match project conventions (consistent with the implementer's Gate Check 4: Idiomatic Code Quality). Task-internal Design Contracts remain pseudocode that the implementer adapts to language idioms. The anti-placeholder rule prevents *missing* guidance, not idiomatic adaptation. + +## Workflow + +Add tasks for each step below using `TaskCreate`. If continuing from the brainstorm skill, the brainstorm tasks will already be visible — add the planning tasks alongside them so the user sees the full brainstorm→plan progression. Mark each as `in_progress` when starting and `completed` when done. + +### 1. Read the Design + +You're handed a plan-file path (typically `docs/plans/<file>.md`) by the brainstorm skill. Read line 1 to learn which review surface the plan lives on, then call the matching show command: + +```bash +MARKER=$(head -1 docs/plans/<file>.md) +KIND=$(echo "$MARKER" | grep -oE 'kind=[a-z-]+' | cut -d= -f2) +ID=$(echo "$MARKER" | grep -oE 'id=\S+' | sed 's/id=//' | tr -d '>' | xargs) + +case "$KIND" in + legacy) arc plan show "$ID" ;; + share-local|share-remote) arc share show "$ID" ;; + *) echo "No review marker; reading file directly"; cat docs/plans/<file>.md ;; +esac +``` + +The full content is what you'll break down in the next steps. If the file has no marker (an older design doc), reading the file directly is fine — but warn the user the review-state CLI calls (approve, pull) won't work without a registered review surface, and offer to register it via brainstorm step 6. + +### 2. Identify Shared Contracts (Foundation Task) + +Check the design for **shared contracts** — types, interfaces, config keys, constants, or function signatures referenced by multiple tasks. If the brainstorm design includes a shared contracts section, use it as input. + +If shared contracts exist and parallel execution is likely: + +1. Create a **T0: Foundation** task that establishes all shared contracts +2. Mark all parallelizable tasks as **blocked by T0** +3. T0 runs sequentially before any parallel batch begins + +This ensures parallel agents inherit shared definitions from HEAD rather than inventing them independently. + +**T0 task descriptions must be literal, not prose.** The description should contain: +- **Exact type/interface code** to write to specific files (sourced from the brainstorm design's shared contracts) +- **Inline contract test assertions** to write in each relevant test file, so downstream tasks can verify they are using the correct types +- Steps that say "write this exact code to this exact file" — not vague instructions like "define the memory type" + +Example T0 task description: + +```markdown +## Summary +Establish shared types and contract tests for the memory feature. + +## Files +- Create: `internal/types/memory.go` +- Create: `internal/memory/memory_test.go` + +## Scope Boundary +Do NOT create or modify any files outside the Files section above. + +## Steps +1. Create `internal/types/memory.go` with this exact content: + ```go + package types + + import "time" + + type Memory struct { + ID int64 `json:"id" db:"id"` + Content string `json:"content" db:"content"` + CreatedAt time.Time `json:"created_at" db:"created_at"` + } + ``` +2. Create contract assertions in `internal/memory/memory_test.go`: + ```go + package memory + + import ( + "testing" + "time" + + "yourmodule/internal/types" + ) + + // --- Contract assertions --- + // These verify the design spec. Do NOT modify + // without updating the approved plan. + + func TestMemoryContract(t *testing.T) { + m := types.Memory{} + var _ int64 = m.ID + var _ string = m.Content + var _ time.Time = m.CreatedAt + } + + // --- Behavior tests (added by implementer) --- + ``` +3. Run `go build ./internal/types/...` — confirm it compiles +4. Run `go test ./internal/memory/...` — confirm contract tests pass +5. Commit: `feat(types): add foundation types and contract tests` + +## Test Command +go test ./internal/memory/... + +## Expected Outcome +Shared types compile and contract assertions pass. Parallel tasks can now import these types from HEAD. +``` + +**Skip this step** if the work is purely sequential or no shared contracts were identified. + +### 3. Identify Tasks + +Break the design into self-contained implementation units. Each task should: +- Have a clear, testable outcome +- Be implementable without knowledge of other tasks +- Include exact file paths for all files to create or modify +- Follow a logical dependency order +- **Not overlap in file ownership with other parallelizable tasks** + +When identifying tasks, assign **file ownership** — each file should be owned by exactly one task. If two tasks need to modify the same file, either merge them into one task, serialize them with a dependency, or extract the shared file into the foundation task. + +### 4. Create Epic and Tasks via issue-manager + +**Model tier:** `issue-manager` defaults to `haiku` — the right tier for CLI formatting and bulk issue creation. For this dispatch, omit `model:`. See the Model Selection table in `../build/SKILL.md` for the full guidance. + +**Never run `arc create` directly** — always delegate to the `issue-manager` agent. This keeps bulk CLI output in a disposable subagent context. + +Read the full plan content first using the kind-aware case from step 1 (`arc plan show "$ID"` for legacy, `arc share show "$ID"` for share-local / share-remote). Then build a task manifest that includes: +1. **The epic** — its description will be populated by the agent from the plan file (see below) +2. **All child tasks** with self-contained descriptions + +**Critical**: Do NOT paste or summarize the plan content into the agent prompt. Instead, pass the plan file path and let the agent read it directly. This prevents content loss from summarization. + +You typically already have the plan file path from the brainstorm hand-off. If you only have the ID and need to find the file path, the lookup depends on `kind`: + +```bash +# share-local / share-remote: keyring includes the plan_file mapping +arc share list --json | jq -r '.[] | select(.id=="<id>") | .plan_file' + +# legacy: arc plan show prints "File: <path>" in its metadata header +arc plan show <id> | grep -oE '^File: \S+' | awk '{print $2}' +``` + +The share keyring entries have `{id, kind, url, key_b64url, plan_file, created_at}` — edit tokens are intentionally redacted. Then dispatch the manifest: + +``` +Use the Agent tool with subagent_type="arc:issue-manager": + +Create the following epic and tasks. +After creation, set dependencies and labels as listed. +Return a summary table mapping task names to arc IDs. + +## Epic + +### <epic title> +Type: epic +Plan file: <absolute path to the plan markdown file> + +IMPORTANT: Read the plan file at the path above using the Read tool. Use the COMPLETE +file contents as the epic description. Do NOT summarize, truncate, or paraphrase — +copy the full file content verbatim as the description. + +## Tasks + +### T1: <title> +Type: task +Parent: <epic-id from above> +Description: +<full multi-line self-contained description> + +### T2: <title> +Type: task +Parent: <epic-id from above> +Description: +<full multi-line self-contained description> + +## Dependencies +- T2 blocked by T1 +- T4 blocked by T3 + +## Labels +- T3: docs-only + +## Required Output +| Task | Arc ID | Title | +|------|--------|-------| +| Epic | ... | ... | +| T1 | ... | ... | +``` + +**IMPORTANT**: The epic description MUST contain the complete approved design. The agent reads the plan file directly to avoid any summarization or content loss. The plan file is ephemeral; the epic description is the permanent record. + +For each task, check whether **all** files in its `## Files` section are documentation (`.md`, `.txt`, `README`, `CHANGELOG`, or anything under `docs/`). If so, include it in the `## Labels` section with `docs-only`. Doc-only tasks skip TDD — the `implement` skill routes them to `doc-writer` instead of `builder`. + +### 5. Validate Returned Results + +Before proceeding, verify the agent's output: + +1. **Count check**: The number of returned IDs must match the number of tasks in your manifest +2. **Spot-check**: Run `arc show <id>` on one returned task to confirm it exists and has the correct parent +3. **If mismatch**: Re-dispatch the agent for missing tasks only, or create them manually + +### 6. Append Task Breakdown to Epic Description + +The epic was created in step 4 with the full design content. Now append the task breakdown table (with actual arc IDs from step 5) to the epic's description: + +```bash +arc update <epic-id> --stdin <<'EOF' +<existing epic description — the full design content from step 4> + +--- + +## Implementation Tasks + +<task breakdown table with arc IDs, titles, statuses, and dependency info> +EOF +``` + +**IMPORTANT**: Preserve the full design content already in the description — do not replace it with a summary. The epic description is the permanent record of the design. Only append the task breakdown table at the end. + +### 6.5. Self-Review + +After writing all tasks, review the plan against the design before proceeding: + +1. **Spec coverage:** Skim each section/requirement in the design. Can you point to a task that implements it? If a gap exists, add the task. +2. **Placeholder scan:** Search all task descriptions for red flags from the No Placeholders list. Fix them. +3. **Type consistency:** Do the types, method signatures, and property names used in later tasks match what was defined in earlier tasks? A function called `clearLayers()` in T1 but `clearFullLayers()` in T3 is a bug. +4. **Step completeness:** Every code step has a code block. Every command step has the exact command and expected output. No exceptions. + +Fix issues inline. No need to re-review — just fix and move on. + +### 7. Choose Execution Path + +**Use the AskUserQuestion tool** to let the user choose: + +``` +Question: "Epic and tasks created. How should we proceed with implementation?" +Options: + - "Start implementing now" (invoke /arc:build in this session — subagents handle TDD per task) + - "Implement in a new session" (provides the exact prompt to use) + - "Done for now" (tasks are tracked in arc — implement manually or later) +``` + +After the user chooses: + +**Start implementing now**: Invoke the `implement` skill immediately with the epic ID. + +**Implement in a new session**: Output the exact command for the user to copy-paste: +``` +Run this in a new Claude Code session: + + /arc:build <epic-id> + +``` +Replace `<epic-id>` with the actual epic ID. + +**Done for now**: Confirm the epic and tasks are saved in arc. The user can run `/arc:build <epic-id>` whenever they're ready. + +## Task Description Format + +Each task's `--description` must be **self-contained** (~3-5k tokens). The task description IS the implementation context — the implementer loads `arc show <task-id>` and nothing else. + +Include in every task description: + +``` +## Files +- Create: `path/to/new_file.go` +- Modify: `path/to/existing_file.go` +- Test: `path/to/file_test.go` + +## Scope Boundary +Do NOT create or modify any files outside the Files section above. +If you need a type, interface, or constant that doesn't exist, do NOT create it — +the foundation task or a prior task is responsible for shared definitions. + +## Design Contracts + +### Shared (use verbatim — defined in T0: Foundation) +```go +type Memory struct { + ID int64 `json:"id" db:"id"` + Content string `json:"content" db:"content"` + CreatedAt time.Time `json:"created_at" db:"created_at"` +} +``` + +### Task-internal +- `FeedbackRequest { memory_id: i64, rating: i8, comment: String? }` +- `MemoryStore.InsertMemory(content string) → (int64, error)` + +## Steps +1. Write failing test for <specific behavior> in `path/to/file_test.go` +2. Run `go test ./path/to/...` — confirm it fails with <expected error> +3. Implement <specific function> in `path/to/new_file.go`: + ```go + func specificFunction(arg Type) (Result, error) { + // exact implementation code — not prose descriptions + } + ``` +4. Run `go test ./path/to/...` — confirm it passes +5. Commit: `feat(module): add <feature>` + +## Test Command +go test ./path/to/... + +## Expected Outcome +<what should work when this task is done> +``` + +**Hard rule:** Every code step requires a code block. Every command step requires the exact command and expected output. Steps without these are plan failures — see the No Placeholders section above. + +### Design Contracts guidance + +Include a `## Design Contracts` section in every non-T0 task description, placed after `## Scope Boundary` and before `## Steps`. This section has two subsections: + +- **Shared (use verbatim)**: Exact type definitions copied from the T0 foundation task. The subagent MUST use these types exactly as written — same field names, same tags, same package. These are the canonical contracts established by T0 and committed to HEAD. +- **Task-internal**: Pseudocode descriptions of types and signatures that are private to this task. The subagent adapts these to language idioms (naming conventions, error handling patterns, etc.) as appropriate. + +If a type the subagent needs is not listed in Design Contracts and is not already on HEAD from T0, the subagent must NOT create it. This rule complements the Scope Boundary section — Scope Boundary restricts file ownership, Design Contracts restricts type ownership. + +For `docs-only` tasks, omit `## Test Command` and use `## Verification` instead: + +``` +## Verification +- All internal links resolve to existing files +- Heading hierarchy has no skipped levels +- Code blocks have language tags +``` + +## Rules + +- Never reference external docs or the full plan in task descriptions — everything needed is in the description +- Design documents live in `docs/plans/` and are registered via one of `arc plan create` (legacy), `arc share create` (encrypted local default), or `arc share create … --remote` (encrypted remote). The brainstorm skill writes a `<!-- arc-review: kind=… id=… -->` marker as line 1 of the doc — always read the marker before invoking review CLIs to route correctly +- Task descriptions must include actual code guidance, not vague instructions +- Team preparation (teammate labels) is optional — only if user chooses team execution +- The plan skill creates tasks; it does not implement them +- The plan skill never runs `arc create` directly — always delegate to `issue-manager` +- Every task must include a `## Scope Boundary` section — no file modifications outside the `## Files` list +- No two parallelizable tasks may own the same file — resolve overlaps via foundation task, merging, or serialization +- Format all arc content (descriptions, plans, comments) per `skills/arc/_formatting.md` diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/plan/evals/evals.json b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/plan/evals/evals.json new file mode 100644 index 0000000..c084da3 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/plan/evals/evals.json @@ -0,0 +1,26 @@ +{ + "skill_name": "plan", + "evals": [ + { + "id": 0, + "eval_name": "marker-legacy-routes-to-arc-plan", + "prompt": "You're given the design doc at `docs/plans/2026-05-01-transcode-refactor.md`. The first line of the file is exactly:\n\n <!-- arc-review: kind=legacy id=42 -->\n\nFollowing the plan skill, walk me through Step 1 (Read the Design) and Step 4 (Read the full plan content first). Show the EXACT shell commands you'd run to (a) read the marker, (b) read the plan content, (c) look up the plan file path if all you had was the ID. Don't actually execute anything — show the commands.", + "expected_output": "Step 1 reads the marker via `head -1`, extracts kind=legacy and id=42, then runs `arc plan show 42` (NOT `arc share show`). Step 4's read uses the same `arc plan show 42`. The file-path lookup uses `arc plan show 42 | grep -oE '^File: \\S+' | awk '{print $2}'` (NOT the `arc share list --json | jq` form, since legacy plans aren't in the share keyring).", + "files": [] + }, + { + "id": 1, + "eval_name": "marker-share-local-routes-to-arc-share", + "prompt": "You're given the design doc at `docs/plans/2026-05-01-queue-migration.md`. The first line is exactly:\n\n <!-- arc-review: kind=share-local id=01HX3K9VPKABCDEF -->\n\nFollowing the plan skill, walk me through Step 1 and Step 4. Show the EXACT shell commands you'd run for (a) reading the marker, (b) reading the plan content, (c) looking up the plan file path from the ID. Don't execute anything.", + "expected_output": "Step 1 reads the marker via `head -1`, extracts kind=share-local and id=01HX3K9VPKABCDEF, then runs `arc share show 01HX3K9VPKABCDEF`. Step 4's content read is the same. The file-path lookup uses `arc share list --json | jq -r '.[] | select(.id==\"01HX3K9VPKABCDEF\") | .plan_file'`. Does NOT call `arc plan show`.", + "files": [] + }, + { + "id": 2, + "eval_name": "no-marker-falls-back-to-share-list", + "prompt": "You're given the design doc at `docs/plans/2025-old-design.md`. The first line of the file is `# Old design` — there's no `<!-- arc-review: ... -->` marker (it predates the marker contract). The user remembers this design was a `share-local` plan but doesn't remember the share ID. Walk me through what you'd do at Step 1 (Read the Design) and how you'd derive the ID. Show exact commands. Don't execute.", + "expected_output": "Detects the missing marker. Falls back to `arc share list --json | jq -r '.[] | select(.plan_file==\"docs/plans/2025-old-design.md\") | .id'` to derive the ID. After getting the ID, runs `arc share show <id>` to read the plan. Notes that this fallback only covers share-local/share-remote plans — if it returns empty, asks the user which review surface the plan was registered on.", + "files": [] + } + ] +} diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/review/SKILL.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/review/SKILL.md new file mode 100644 index 0000000..9baadbc --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/review/SKILL.md @@ -0,0 +1,163 @@ +--- +name: review +description: You MUST use this skill after implementing a task to get code review — especially when the user says "review this", "check my code", "review the changes", or after any implementation task completes. Dispatches the code-reviewer agent with git diff and task spec, then triages feedback by severity. Always prefer this over generic code review when the project uses arc issue tracking. +--- + +# Review — Code Review Dispatch + +Dispatch the `code-reviewer` subagent to review implementation work, then triage findings. + +## Workflow + +Create a TodoWrite checklist with these steps: + +### 1. Get Git SHAs + +Use the `PRE_TASK_SHA` recorded by the implement skill before dispatching the implementer: + +```bash +BASE_SHA=$PRE_TASK_SHA +HEAD_SHA=$(git rev-parse HEAD) +``` + +If `PRE_TASK_SHA` is not available (e.g., standalone review), determine the range manually: + +```bash +# Check recent commits to identify where the task's work begins +git log --oneline -10 +# Set BASE_SHA to the commit before the task's first change +BASE_SHA=$(git rev-parse <commit-before-task>) +HEAD_SHA=$(git rev-parse HEAD) +``` + +### 2. Get Design Context + +If the review was invoked from the implement skill, a design excerpt should be available. Retrieve it: + +```bash +# Get the parent epic of this task +arc show <task-id> --json | jq -r '.parent_id // empty' +# If parent exists, get the epic's plan content +arc show <parent-epic-id> +``` + +Extract the design excerpt relevant to this task — typically the sections covering the types, interfaces, and architectural decisions this task implements. If no parent epic exists or no design is available, skip the design spec section in the dispatch prompt. + +### 3. Dispatch Reviewer + +Use the Agent tool to spawn an `code-reviewer` subagent. Fill the template at `./code-reviewer-prompt.md` with the gathered placeholders (`{TASK_ID}`, `{BASE_SHA}`, `{HEAD_SHA}`, `{DESIGN_EXCERPT}`, `{EVALUATOR_STATUS}`). + +**Model tier:** Follow the Model Selection table in `../build/SKILL.md`. For most reviews, omit `model:` (use the agent's sonnet default). Escalate to `opus` when the diff is large (10+ files), crosses multiple architectural layers, or involves security-sensitive changes. + +### 4. Triage Feedback + +When the reviewer reports back: + +| Severity | Action | +|----------|--------| +| **Critical** | Fix immediately — re-dispatch `builder` with the specific fix. Then re-review. | +| **Important** | Fix before moving to next task — re-dispatch `builder`. Then re-review. | +| **Minor** | Note in arc issue comment for later. Proceed. | +| **Deviation (fix)** | Re-dispatch `builder` with the specific deviation to correct. | +| **Deviation (accept)** | Note the deviation as an arc comment on the task for traceability. Proceed. | + +### 5. Handle Fixes + +If fixes are needed: +1. Re-dispatch `builder` with the specific findings to address +2. After the implementer reports back, re-review (go to step 1 with updated SHAs) +3. Continue until the review is clean (no Critical or Important findings) + +**Circuit breaker**: If 3 review/fix cycles on the same task haven't resolved all findings, STOP. Escalate to the user with a summary of what keeps recurring — the reviewer and implementer may disagree on the approach, or the task spec may be ambiguous. + +### 6. Proceed + +- If all tasks are done → invoke `finish` +- If more tasks remain → return to `implement` for the next task + +## Response Discipline + +Receiving review feedback requires technical evaluation, not emotional performance. Verify before implementing. Ask before assuming. + +### Forbidden Responses + +Never write: + +- "You're absolutely right!" +- "Great point!" +- "Excellent feedback!" +- "Let me implement that now" (before verification) + +These are performative and explicitly violate project discipline. They signal acceptance before understanding. + +### Instead + +- **Restate** the technical requirement in your own words +- **Ask** clarifying questions when the feedback is unclear +- **Push back** with technical reasoning when the feedback is wrong +- **Just start working** — actions beat performative agreement + +### The Verification Pattern + +Apply this pattern to every finding: + +1. **READ** — Read the complete feedback without reacting +2. **UNDERSTAND** — Restate the requirement in your own words (or ask for clarification) +3. **VERIFY** — Check the claim against the actual codebase +4. **EVALUATE** — Is the feedback technically sound for *this* codebase's conventions? +5. **RESPOND** — Technical acknowledgment ("Confirmed, file X line Y has the issue") OR reasoned pushback ("Disagree: file X line Y actually does handle this case — test Z covers it") +6. **IMPLEMENT** — Fix one finding at a time, verify each before moving to the next + +### Triage by Severity + +When the `code-reviewer` reports findings, triage by severity: + +| Severity | Action | +|----------|--------| +| **Critical** | Fix immediately — re-dispatch `builder` with the specific fix. Then re-review. | +| **Important** | Fix before moving to next task — re-dispatch `builder`. Then re-review. | +| **Minor** | Note in arc issue comment for later. Proceed. | +| **Deviation (fix)** | Re-dispatch `builder` with the specific deviation to correct. | +| **Deviation (accept)** | Note the deviation as an arc comment on the task for traceability. Proceed. | + +Never agree performatively to Critical or Important findings. Never dismiss them without technical reasoning. If a finding is wrong, show *why* with evidence from the codebase. + +## Relationship to the Evaluator + +The evaluator is **not always present**. Your dispatch prompt includes an `## Evaluator Status` line that tells you whether the evaluator is running for this task. + +**When Evaluator Status is `active`** (high-risk tasks): + +The evaluator runs in parallel with you. Your concerns are complementary: + +| | Reviewer (you) | Evaluator | +|---|---|---| +| **Focus** | Code quality, conventions, plan adherence | Spec-intent compliance via independent testing | +| **Input** | Git diff + spec | Spec only (no diff) | +| **Modifies code?** | No | Writes ephemeral acceptance tests, then deletes them | + +Focus on code quality, naming, structure, conventions, and plan adherence. Defer behavioral verification to the evaluator's actual tests. + +**When Evaluator Status is `not dispatched`** (default path): + +You are the only reviewer. In addition to code quality and plan adherence, **flag behavioral concerns** — code paths that look like they might not match the spec, edge cases that appear unhandled, logic that seems inconsistent with the task's `## Expected Outcome`. Describe the suspected behavior gap and the code path involved so the orchestrator can decide whether to escalate to the evaluator. + +You are not expected to write or run tests — that's still the evaluator's job if escalated. But you should flag what you see. + +## Contexts + +This skill works in both execution models: + +| Context | How review works | +|---------|-----------------| +| **Single-agent** | Main agent dispatches `code-reviewer` subagent | +| **Team mode** | Team lead dispatches QA teammate or `code-reviewer` subagent | + +## Rules + +- Always review after implementation — don't skip to close +- Re-review after fixes — don't assume fixes are correct +- The reviewer reports; you decide what to do with the findings +- Never make code changes in the review skill — dispatch the implementer for fixes +- Focus on code quality and conventions. Flag behavioral concerns when no evaluator is present. +- Format all arc content (descriptions, plans, comments) per `skills/arc/_formatting.md` diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/review/code-reviewer-prompt.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/review/code-reviewer-prompt.md new file mode 100644 index 0000000..5aba811 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/review/code-reviewer-prompt.md @@ -0,0 +1,42 @@ +# Reviewer Prompt Template + +Use this template when dispatching `code-reviewer` for code review. + +**Placeholders:** +- `{TASK_ID}` — arc issue ID +- `{BASE_SHA}` — starting commit SHA +- `{HEAD_SHA}` — ending commit SHA +- `{DESIGN_EXCERPT}` — relevant design section from parent epic, or "none" if not applicable +- `{EVALUATOR_STATUS}` — `active` if evaluator was dispatched for this task, else `not dispatched` + +````text +Review these changes against the task spec and project conventions. + +## Task Spec +<paste output of: arc show {TASK_ID}> + +## Design Spec +{DESIGN_EXCERPT} +If "none", omit this section. + +## Changes +<paste output of: git diff {BASE_SHA}..{HEAD_SHA}> + +## Evaluator Status +{EVALUATOR_STATUS} + +## Report Format + +Report findings in three severities: + +- **Critical** (must fix): correctness bugs, security issues, scope violations, spec deviations +- **Important** (should fix): quality issues, pattern mismatches, naming problems, test gaps +- **Minor** (note for later): style nits, observations, future cleanup candidates + +If a design spec was provided, also report Plan Adherence: +- **ADHERENT** — implementation matches the design +- **DEVIATION (fix)** — implementation diverges from design; recommend fixing +- **DEVIATION (accept)** — implementation diverges from design; recommend accepting the divergence (with reasoning) + +When Evaluator Status is `not dispatched`, also flag behavioral concerns — code paths that might not match spec intent. You do not write or run tests; describe what you see and where. +```` diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/team-dispatch/SKILL.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/team-dispatch/SKILL.md new file mode 100644 index 0000000..6eb4a09 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/team-dispatch/SKILL.md @@ -0,0 +1,166 @@ +--- +name: team-dispatch +description: Deploy an agent team from arc's issue graph. Use when the user wants to parallelize work across multiple agents, parallelize epic tasks, says "deploy team", "spawn teammates", or wants to distribute arc epic tasks by role using teammate labels. +--- + +# Arc Team Deploy + +Deploy an agent team from arc's issue graph. Translates `teammate:*` labels, plans, and dependencies into a Claude Code team with tasks and role-filtered context. + +## When to Invoke + +- User says "deploy team", "create agent team from arc", "spawn teammates from arc" +- User runs `/arc team-deploy` +- User wants to parallelize work on an arc epic across multiple agents + +## Prerequisites + +- An arc project is active (resolved via server path registration or local config) +- An epic exists with child issues labeled `teammate:<role>` (e.g., `teammate:frontend`, `teammate:backend`) +- The arc server is running (`arc server status`) + +## Workflow + +### Step 1: Gather Team Context + +Run `arc team context <epic-id> --json` to get the issue graph grouped by role. + +```bash +arc team context <epic-id> --json +``` + +The JSON output has this structure: + +```json +{ + "epic": { "id": "PROJ-5", "title": "Auth System", "status": "open" }, + "roles": { + "frontend": [ + { "id": "PROJ-5.1", "title": "Login form", "status": "open", "priority": 2, "blocked_by": [] } + ], + "backend": [ + { "id": "PROJ-5.2", "title": "Auth API", "status": "open", "priority": 1, "blocked_by": [] }, + { "id": "PROJ-5.3", "title": "Session middleware", "status": "open", "priority": 2, "blocked_by": ["PROJ-5.2"] } + ] + } +} +``` + +Use the `roles` keys as teammate names and paste each role's issue array into the teammate's dispatch prompt. + +If the user hasn't specified an epic, help them find one: + +```bash +arc list --type=epic --status=open +``` + +### Step 2: Present Team Composition + +Parse the JSON output and present a summary for approval: + +``` +Team composition for "<epic-title>": + + frontend (2 issues): Login form, Signup page + backend (3 issues): Auth API, User model, Session middleware +Proceed with team deployment? [Y/n] +``` + +### Step 3: Create Team and Tasks + +After approval: + +1. **Create the team** via `TeamCreate`: + ``` + team_name: "<epic-title-slug>" + description: "Working on <epic-title>" + ``` + +2. **Create tasks** via `TaskCreate` for each arc issue: + - `subject`: The arc issue title + - `description`: Include the arc issue ID, plan (if any), dependencies, and priority + - `activeForm`: Present continuous of the subject (e.g., "Implementing login form") + +3. **Set task dependencies** via `TaskUpdate` with `addBlockedBy`: + - Map arc dependency IDs to the corresponding task IDs + - Only map dependencies between issues within the same team deployment + +### Step 4: Spawn Teammates + +For each role, spawn a teammate via the `Agent` tool: + +``` +subagent_type: "general-purpose" +team_name: "<team-name>" +name: "<role>" (e.g., "frontend", "backend") +``` + +**Prompt template** for each teammate: + +``` +You are the <role> teammate working on "<epic-title>". + +Your arc role label is teammate:<role>. Focus on your assigned tasks. + +Environment: ARC_TEAMMATE_ROLE=<role> + +Workflow: +1. Check TaskList for your assigned tasks +2. Work on tasks in ID order (lowest first) +3. For each task: + - If labeled `docs-only`: mark in_progress, write documentation, verify formatting, commit, mark completed + - Otherwise: mark in_progress, implement with tests (RED → GREEN → REFACTOR), run test suite, commit, mark completed +4. After completing a task, check TaskList for the next available one +5. Send a message to the team lead when all your tasks are done + +Arc context for your issues: +<paste role-specific issues from the team context JSON> +``` + +### Step 5: Assign Tasks + +Use `TaskUpdate` with `owner` to assign each task to the corresponding teammate role name. + +### Step 6: Monitor and Sync + +As team lead, follow the sync protocol: + +1. **Monitor progress** via `TaskList` — teammates send messages on completion +2. **Verify work** before closing arc issues: + ```bash + arc show <issue-id> # Review the issue + # Check the code changes made by the teammate + ``` +3. **Close verified issues**: + ```bash + arc close <issue-id> --reason "completed by <role>" + ``` +4. **Check for newly unblocked work**: + ```bash + arc ready + ``` +5. **Shutdown teammates** when all work is complete via `SendMessage` with `type: "shutdown_request"` + +## Error Handling + +- If `arc team context` returns empty roles, the epic may not have `teammate:*` labels on children. Suggest labeling first. +- If a teammate reports a blocker, update the arc issue status: `arc update <id> --status=blocked` +- If a task fails, investigate before reassigning — the arc issue may need plan revision. + +## Example Session + +``` +User: Deploy a team for epic PROJ-5 + +1. Run: arc team context PROJ-5 --json +2. Parse: 2 roles (frontend: 2 issues, backend: 3 issues) +3. Present composition → user approves +4. TeamCreate: "auth-system" +5. TaskCreate: 5 tasks (mapped from arc issues) +6. TaskUpdate: set dependencies between tasks +7. Agent spawn: "frontend" teammate (2 assigned tasks) +8. Agent spawn: "backend" teammate (3 assigned tasks) +9. Monitor via TaskList, verify completions +10. arc close verified issues +11. Shutdown teammates when done +``` \ No newline at end of file diff --git a/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/verify/SKILL.md b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/verify/SKILL.md new file mode 100644 index 0000000..2d1aaf1 --- /dev/null +++ b/packages/pi-arc/tests/fixtures/arc-plugin-source/skills/verify/SKILL.md @@ -0,0 +1,83 @@ +--- +name: verify +description: You MUST use this skill before claiming any work is complete, any test passes, or any fix works — especially before arc close, before telling the user "done", or when the user asks "does it work?", "did the tests pass?", "is it fixed?". Requires fresh verification evidence (not cached results). Always prefer this over ad-hoc verification when the project uses arc issue tracking. +--- + +# Verify — Evidence-Based Completion Gates + +Run proof commands and read their output before making any completion claim. + +## Iron Law + +**NO COMPLETION CLAIMS WITHOUT FRESH VERIFICATION EVIDENCE.** + +"It should work" is not evidence. "Tests pass" without output is not evidence. Satisfaction expressed before running the proof command is a red flag. + +## Gate Sequence + +Create a TodoWrite checklist with these steps: + +### 1. IDENTIFY + +What command proves the claim? Examples: +- "Tests pass" → `make test` or `go test ./...` +- "Build succeeds" → `make build` +- "Issue is resolved" → `arc show <id>` (check status) +- "No regressions" → full test suite, not a subset + +### 2. RUN + +Execute the **full** command. At minimum, run all tests affected by the change; running the full suite is safer. Not a subset from memory. Not "I ran it earlier." + +Fresh. Complete. Now. + +### 3. READ + +Read the **FULL** output. Not just the last line. Check: +- Exit code (0 = success) +- Failure count (must be 0, not "some passed") +- Warning count (investigate, don't ignore) +- Any skipped tests (why were they skipped?) + +### 4. VERIFY + +Does the output **actually confirm** the claim? +- "0 failures" confirms "tests pass" — "tests ran" does not +- "exit 0" confirms "build succeeds" — "compiling..." does not +- "status: closed" confirms "issue resolved" — "status: in_progress" does not + +### 5. ONLY THEN + +Make the claim. Reference the evidence: +- "Tests pass: `go test ./...` shows 47 passed, 0 failed" +- "Build succeeds: `make build` exits 0, binary at `./bin/arc`" + +## Red Flags + +You are skipping verification if you: +- Use "should work", "probably passes", "seems fine" +- Express satisfaction before running the proof command +- Run a subset of tests instead of the full suite +- Trust a subagent's report without running the proof command yourself +- Say "tests pass" without showing the output +- Claim "no regressions" without running the full suite +- Close an arc issue before verification + +## Arc Integration + +```bash +# ONLY after verification passes: +arc close <id> -r "Verified: <evidence summary>" +``` + +If verification **fails**, do NOT close the issue. Instead: +- Return to `implement` to fix the failure +- Or invoke `debug` if the failure is unexpected + +## Rules + +- Never close an arc issue without fresh verification evidence +- Never claim completion without running the proof command +- Never trust cached or remembered results — run it fresh +- After verification, proceed to `finish` (session end) or back to `implement` (next task) +- Format all arc content (descriptions, plans, comments) per `skills/arc/_formatting.md`