Base directory for this skill: /Users/steve.briggs/.claude/plugins/cache/claude-plugins-official/superpowers/5.1.0/skills/subagent-driven-development

# Subagent-Driven Development

Execute plan by dispatching fresh subagent per task, with two-stage review after each: spec compliance review first, then code quality review.

**Why subagents:** You delegate tasks to specialized agents with isolated context. By precisely crafting their instructions and context, you ensure they stay focused and succeed at their task. They should never inherit your session's context or history — you construct exactly what they need. This also preserves your own context for coordination work.

**Core principle:** Fresh subagent per task + two-stage review (spec then quality) = high quality, fast iteration

**Continuous execution:** Do not pause to check in with your human partner between tasks. Execute all tasks from the plan without stopping. The only reasons to stop are: BLOCKED status you cannot resolve, ambiguity that genuinely prevents progress, or all tasks complete. "Should I continue?" prompts and progress summaries waste their time — they asked you to execute the plan, so execute it.

## When to Use

```dot
digraph when_to_use {
    "Have implementation plan?" [shape=diamond];
    "Tasks mostly independent?" [shape=diamond];
    "Stay in this session?" [shape=diamond];
    "subagent-driven-development" [shape=box];
    "executing-plans" [shape=box];
    "Manual execution or brainstorm first" [shape=box];

    "Have implementation plan?" -> "Tasks mostly independent?" [label="yes"];
    "Have implementation plan?" -> "Manual execution or brainstorm first" [label="no"];
    "Tasks mostly independent?" -> "Stay in this session?" [label="yes"];
    "Tasks mostly independent?" -> "Manual execution or brainstorm first" [label="no - tightly coupled"];
    "Stay in this session?" -> "subagent-driven-development" [label="yes"];
    "Stay in this session?" -> "executing-plans" [label="no - parallel session"];
}
```

**vs. Executing Plans (parallel session):**
- Same session (no context switch)
- Fresh subagent per task (no context pollution)
- Two-stage review after each task: spec compliance first, then code quality
- Faster iteration (no human-in-loop between tasks)

## The Process

```dot
digraph process {
    rankdir=TB;

    subgraph cluster_per_task {
        label="Per Task";
        "Dispatch implementer subagent (./implementer-prompt.md)" [shape=box];
        "Implementer subagent asks questions?" [shape=diamond];
        "Answer questions, provide context" [shape=box];
        "Implementer subagent implements, tests, commits, self-reviews" [shape=box];
        "Dispatch spec reviewer subagent (./spec-reviewer-prompt.md)" [shape=box];
        "Spec reviewer subagent confirms code matches spec?" [shape=diamond];
        "Implementer subagent fixes spec gaps" [shape=box];
        "Dispatch code quality reviewer subagent (./code-quality-reviewer-prompt.md)" [shape=box];
        "Code quality reviewer subagent approves?" [shape=diamond];
        "Implementer subagent fixes quality issues" [shape=box];
        "Mark task complete in TodoWrite" [shape=box];
    }

    "Read plan, extract all tasks with full text, note context, create TodoWrite" [shape=box];
    "More tasks remain?" [shape=diamond];
    "Dispatch final code reviewer subagent for entire implementation" [shape=box];
    "Use superpowers:finishing-a-development-branch" [shape=box style=filled fillcolor=lightgreen];

    "Read plan, extract all tasks with full text, note context, create TodoWrite" -> "Dispatch implementer subagent (./implementer-prompt.md)";
    "Dispatch implementer subagent (./implementer-prompt.md)" -> "Implementer subagent asks questions?";
    "Implementer subagent asks questions?" -> "Answer questions, provide context" [label="yes"];
    "Answer questions, provide context" -> "Dispatch implementer subagent (./implementer-prompt.md)";
    "Implementer subagent asks questions?" -> "Implementer subagent implements, tests, commits, self-reviews" [label="no"];
    "Implementer subagent implements, tests, commits, self-reviews" -> "Dispatch spec reviewer subagent (./spec-reviewer-prompt.md)";
    "Dispatch spec reviewer subagent (./spec-reviewer-prompt.md)" -> "Spec reviewer subagent confirms code matches spec?";
    "Spec reviewer subagent confirms code matches spec?" -> "Implementer subagent fixes spec gaps" [label="no"];
    "Implementer subagent fixes spec gaps" -> "Dispatch spec reviewer subagent (./spec-reviewer-prompt.md)" [label="re-review"];
    "Spec reviewer subagent confirms code matches spec?" -> "Dispatch code quality reviewer subagent (./code-quality-reviewer-prompt.md)" [label="yes"];
    "Dispatch code quality reviewer subagent (./code-quality-reviewer-prompt.md)" -> "Code quality reviewer subagent approves?";
    "Code quality reviewer subagent approves?" -> "Implementer subagent fixes quality issues" [label="no"];
    "Implementer subagent fixes quality issues" -> "Dispatch code quality reviewer subagent (./code-quality-reviewer-prompt.md)" [label="re-review"];
    "Code quality reviewer subagent approves?" -> "Mark task complete in TodoWrite" [label="yes"];
    "Mark task complete in TodoWrite" -> "More tasks remain?";
    "More tasks remain?" -> "Dispatch implementer subagent (./implementer-prompt.md)" [label="yes"];
    "More tasks remain?" -> "Dispatch final code reviewer subagent for entire implementation" [label="no"];
    "Dispatch final code reviewer subagent for entire implementation" -> "Use superpowers:finishing-a-development-branch";
}
```

## Model Selection

Use the least powerful model that can handle each role to conserve cost and increase speed.

**Mechanical implementation tasks** (isolated functions, clear specs, 1-2 files): use a fast, cheap model. Most implementation tasks are mechanical when the plan is well-specified.

**Integration and judgment tasks** (multi-file coordination, pattern matching, debugging): use a standard model.

**Architecture, design, and review tasks**: use the most capable available model.

**Task complexity signals:**
- Touches 1-2 files with a complete spec → cheap model
- Touches multiple files with integration concerns → standard model
- Requires design judgment or broad codebase understanding → most capable model

## Handling Implementer Status

Implementer subagents report one of four statuses. Handle each appropriately:

**DONE:** Proceed to spec compliance review.

**DONE_WITH_CONCERNS:** The implementer completed the work but flagged doubts. Read the concerns before proceeding. If the concerns are about correctness or scope, address them before review. If they're observations (e.g., "this file is getting large"), note them and proceed to review.

**NEEDS_CONTEXT:** The implementer needs information that wasn't provided. Provide the missing context and re-dispatch.

**BLOCKED:** The implementer cannot complete the task. Assess the blocker:
1. If it's a context problem, provide more context and re-dispatch with the same model
2. If the task requires more reasoning, re-dispatch with a more capable model
3. If the task is too large, break it into smaller pieces
4. If the plan itself is wrong, escalate to the human

**Never** ignore an escalation or force the same model to retry without changes. If the implementer said it's stuck, something needs to change.

## Prompt Templates

- `./implementer-prompt.md` - Dispatch implementer subagent
- `./spec-reviewer-prompt.md` - Dispatch spec compliance reviewer subagent
- `./code-quality-reviewer-prompt.md` - Dispatch code quality reviewer subagent

## Example Workflow

```
You: I'm using Subagent-Driven Development to execute this plan.

[Read plan file once: docs/superpowers/plans/feature-plan.md]
[Extract all 5 tasks with full text and context]
[Create TodoWrite with all tasks]

Task 1: Hook installation script

[Get Task 1 text and context (already extracted)]
[Dispatch implementation subagent with full task text + context]

Implementer: "Before I begin - should the hook be installed at user or system level?"

You: "User level (~/.config/superpowers/hooks/)"

Implementer: "Got it. Implementing now..."
[Later] Implementer:
  - Implemented install-hook command
  - Added tests, 5/5 passing
  - Self-review: Found I missed --force flag, added it
  - Committed

[Dispatch spec compliance reviewer]
Spec reviewer: ✅ Spec compliant - all requirements met, nothing extra

[Get git SHAs, dispatch code quality reviewer]
Code reviewer: Strengths: Good test coverage, clean. Issues: None. Approved.

[Mark Task 1 complete]

Task 2: Recovery modes

[Get Task 2 text and context (already extracted)]
[Dispatch implementation subagent with full task text + context]

Implementer: [No questions, proceeds]
Implementer:
  - Added verify/repair modes
  - 8/8 tests passing
  - Self-review: All good
  - Committed

[Dispatch spec compliance reviewer]
Spec reviewer: ❌ Issues:
  - Missing: Progress reporting (spec says "report every 100 items")
  - Extra: Added --json flag (not requested)

[Implementer fixes issues]
Implementer: Removed --json flag, added progress reporting

[Spec reviewer reviews again]
Spec reviewer: ✅ Spec compliant now

[Dispatch code quality reviewer]
Code reviewer: Strengths: Solid. Issues (Important): Magic number (100)

[Implementer fixes]
Implementer: Extracted PROGRESS_INTERVAL constant

[Code reviewer reviews again]
Code reviewer: ✅ Approved

[Mark Task 2 complete]

...

[After all tasks]
[Dispatch final code-reviewer]
Final reviewer: All requirements met, ready to merge

Done!
```

## Advantages

**vs. Manual execution:**
- Subagents follow TDD naturally
- Fresh context per task (no confusion)
- Parallel-safe (subagents don't interfere)
- Subagent can ask questions (before AND during work)

**vs. Executing Plans:**
- Same session (no handoff)
- Continuous progress (no waiting)
- Review checkpoints automatic

**Efficiency gains:**
- No file reading overhead (controller provides full text)
- Controller curates exactly what context is needed
- Subagent gets complete information upfront
- Questions surfaced before work begins (not after)

**Quality gates:**
- Self-review catches issues before handoff
- Two-stage review: spec compliance, then code quality
- Review loops ensure fixes actually work
- Spec compliance prevents over/under-building
- Code quality ensures implementation is well-built

**Cost:**
- More subagent invocations (implementer + 2 reviewers per task)
- Controller does more prep work (extracting all tasks upfront)
- Review loops add iterations
- But catches issues early (cheaper than debugging later)

## Red Flags

**Never:**
- Start implementation on main/master branch without explicit user consent
- Skip reviews (spec compliance OR code quality)
- Proceed with unfixed issues
- Dispatch multiple implementation subagents in parallel (conflicts)
- Make subagent read plan file (provide full text instead)
- Skip scene-setting context (subagent needs to understand where task fits)
- Ignore subagent questions (answer before letting them proceed)
- Accept "close enough" on spec compliance (spec reviewer found issues = not done)
- Skip review loops (reviewer found issues = implementer fixes = review again)
- Let implementer self-review replace actual review (both are needed)
- **Start code quality review before spec compliance is ✅** (wrong order)
- Move to next task while either review has open issues

**If subagent asks questions:**
- Answer clearly and completely
- Provide additional context if needed
- Don't rush them into implementation

**If reviewer finds issues:**
- Implementer (same subagent) fixes them
- Reviewer reviews again
- Repeat until approved
- Don't skip the re-review

**If subagent fails task:**
- Dispatch fix subagent with specific instructions
- Don't try to fix manually (context pollution)

## Integration

**Required workflow skills:**
- **superpowers:using-git-worktrees** - Ensures isolated workspace (creates one or verifies existing)
- **superpowers:writing-plans** - Creates the plan this skill executes
- **superpowers:requesting-code-review** - Code review template for reviewer subagents
- **superpowers:finishing-a-development-branch** - Complete development after all tasks

**Subagents should use:**
- **superpowers:test-driven-development** - Subagents follow TDD for each task

**Alternative workflow:**
- **superpowers:executing-plans** - Use for parallel session instead of same-session execution


I'm using Subagent-Driven Development to execute this plan. Before dispatching the first implementer, I need an isolated workspace — we're currently on `master`, and the skill is explicit about not starting implementation on master without consent. Invoking the worktree skill.


Launching skill: superpowers:using-git-worktrees


Base directory for this skill: /Users/steve.briggs/.claude/plugins/cache/claude-plugins-official/superpowers/5.1.0/skills/using-git-worktrees

# Using Git Worktrees

## Overview

Ensure work happens in an isolated workspace. Prefer your platform's native worktree tools. Fall back to manual git worktrees only when no native tool is available.

**Core principle:** Detect existing isolation first. Then use native tools. Then fall back to git. Never fight the harness.

**Announce at start:** "I'm using the using-git-worktrees skill to set up an isolated workspace."

## Step 0: Detect Existing Isolation

**Before creating anything, check if you are already in an isolated workspace.**

```bash
GIT_DIR=$(cd "$(git rev-parse --git-dir)" 2>/dev/null && pwd -P)
GIT_COMMON=$(cd "$(git rev-parse --git-common-dir)" 2>/dev/null && pwd -P)
BRANCH=$(git branch --show-current)
```

**Submodule guard:** `GIT_DIR != GIT_COMMON` is also true inside git submodules. Before concluding "already in a worktree," verify you are not in a submodule:

```bash
# If this returns a path, you're in a submodule, not a worktree — treat as normal repo
git rev-parse --show-superproject-working-tree 2>/dev/null
```

**If `GIT_DIR != GIT_COMMON` (and not a submodule):** You are already in a linked worktree. Skip to Step 3 (Project Setup). Do NOT create another worktree.

Report with branch state:
- On a branch: "Already in isolated workspace at `<path>` on branch `<name>`."
- Detached HEAD: "Already in isolated workspace at `<path>` (detached HEAD, externally managed). Branch creation needed at finish time."

**If `GIT_DIR == GIT_COMMON` (or in a submodule):** You are in a normal repo checkout.

Has the user already indicated their worktree preference in your instructions? If not, ask for consent before creating a worktree:

> "Would you like me to set up an isolated worktree? It protects your current branch from changes."

Honor any existing declared preference without asking. If the user declines consent, work in place and skip to Step 3.

## Step 1: Create Isolated Workspace

**You have two mechanisms. Try them in this order.**

### 1a. Native Worktree Tools (preferred)

The user has asked for an isolated workspace (Step 0 consent). Do you already have a way to create a worktree? It might be a tool with a name like `EnterWorktree`, `WorktreeCreate`, a `/worktree` command, or a `--worktree` flag. If you do, use it and skip to Step 3.

Native tools handle directory placement, branch creation, and cleanup automatically. Using `git worktree add` when you have a native tool creates phantom state your harness can't see or manage.

Only proceed to Step 1b if you have no native worktree tool available.

### 1b. Git Worktree Fallback

**Only use this if Step 1a does not apply** — you have no native worktree tool available. Create a worktree manually using git.

#### Directory Selection

Follow this priority order. Explicit user preference always beats observed filesystem state.

1. **Check your instructions for a declared worktree directory preference.** If the user has already specified one, use it without asking.

2. **Check for an existing project-local worktree directory:**
   ```bash
   ls -d .worktrees 2>/dev/null     # Preferred (hidden)
   ls -d worktrees 2>/dev/null      # Alternative
   ```
   If found, use it. If both exist, `.worktrees` wins.

3. **Check for an existing global directory:**
   ```bash
   project=$(basename "$(git rev-parse --show-toplevel)")
   ls -d ~/.config/superpowers/worktrees/$project 2>/dev/null
   ```
   If found, use it (backward compatibility with legacy global path).

4. **If there is no other guidance available**, default to `.worktrees/` at the project root.

#### Safety Verification (project-local directories only)

**MUST verify directory is ignored before creating worktree:**

```bash
git check-ignore -q .worktrees 2>/dev/null || git check-ignore -q worktrees 2>/dev/null
```

**If NOT ignored:** Add to .gitignore, commit the change, then proceed.

**Why critical:** Prevents accidentally committing worktree contents to repository.

Global directories (`~/.config/superpowers/worktrees/`) need no verification.

#### Create the Worktree

```bash
project=$(basename "$(git rev-parse --show-toplevel)")

# Determine path based on chosen location
# For project-local: path="$LOCATION/$BRANCH_NAME"
# For global: path="~/.config/superpowers/worktrees/$project/$BRANCH_NAME"

git worktree add "$path" -b "$BRANCH_NAME"
cd "$path"
```

**Sandbox fallback:** If `git worktree add` fails with a permission error (sandbox denial), tell the user the sandbox blocked worktree creation and you're working in the current directory instead. Then run setup and baseline tests in place.

## Step 3: Project Setup

Auto-detect and run appropriate setup:

```bash
# Node.js
if [ -f package.json ]; then npm install; fi

# Rust
if [ -f Cargo.toml ]; then cargo build; fi

# Python
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
if [ -f pyproject.toml ]; then poetry install; fi

# Go
if [ -f go.mod ]; then go mod download; fi
```

## Step 4: Verify Clean Baseline

Run tests to ensure workspace starts clean:

```bash
# Use project-appropriate command
npm test / cargo test / pytest / go test ./...
```

**If tests fail:** Report failures, ask whether to proceed or investigate.

**If tests pass:** Report ready.

### Report

```
Worktree ready at <full-path>
Tests passing (<N> tests, 0 failures)
Ready to implement <feature-name>
```

## Quick Reference

| Situation | Action |
|-----------|--------|
| Already in linked worktree | Skip creation (Step 0) |
| In a submodule | Treat as normal repo (Step 0 guard) |
| Native worktree tool available | Use it (Step 1a) |
| No native tool | Git worktree fallback (Step 1b) |
| `.worktrees/` exists | Use it (verify ignored) |
| `worktrees/` exists | Use it (verify ignored) |
| Both exist | Use `.worktrees/` |
| Neither exists | Check instruction file, then default `.worktrees/` |
| Global path exists | Use it (backward compat) |
| Directory not ignored | Add to .gitignore + commit |
| Permission error on create | Sandbox fallback, work in place |
| Tests fail during baseline | Report failures + ask |
| No package.json/Cargo.toml | Skip dependency install |

## Common Mistakes

### Fighting the harness

- **Problem:** Using `git worktree add` when the platform already provides isolation
- **Fix:** Step 0 detects existing isolation. Step 1a defers to native tools.

### Skipping detection

- **Problem:** Creating a nested worktree inside an existing one
- **Fix:** Always run Step 0 before creating anything

### Skipping ignore verification

- **Problem:** Worktree contents get tracked, pollute git status
- **Fix:** Always use `git check-ignore` before creating project-local worktree

### Assuming directory location

- **Problem:** Creates inconsistency, violates project conventions
- **Fix:** Follow priority: existing > global legacy > instruction file > default

### Proceeding with failing tests

- **Problem:** Can't distinguish new bugs from pre-existing issues
- **Fix:** Report failures, get explicit permission to proceed

## Red Flags

**Never:**
- Create a worktree when Step 0 detects existing isolation
- Use `git worktree add` when you have a native worktree tool (e.g., `EnterWorktree`). This is the #1 mistake — if you have it, use it.
- Skip Step 1a by jumping straight to Step 1b's git commands
- Create worktree without verifying it's ignored (project-local)
- Skip baseline test verification
- Proceed with failing tests without asking

**Always:**
- Run Step 0 detection first
- Prefer native tools over git fallback
- Follow directory priority: existing > global legacy > instruction file > default
- Verify directory is ignored for project-local
- Auto-detect and run project setup
- Verify clean test baseline


Build birdseye CLI for Terraform module diffing


I'm using the using-git-worktrees skill to set up an isolated workspace.

Step 0: detect existing isolation.


Bash

GIT_DIR=$(cd "$(git rev-parse --git-dir)" 2>/dev/null && pwd -P)
GIT_COMMON=$(cd "$(git rev-parse --git-common-dir)" 2>/dev/null && pwd -P)
BRANCH=$(git branch --show-current)
SUB=$(git rev-parse --show-superproject-working-tree 2>/dev/null)
echo "GIT_DIR=$GIT_DIR"
echo "GIT_COMMON=$GIT_COMMON"
echo "BRANCH=$BRANCH"
echo "SUBMODULE=$SUB"
echo "TOPLEVEL=$(git rev-parse --show-toplevel)"

Detect existing isolation


GIT_DIR=/Users/steve.briggs/projects/operations/.git
GIT_COMMON=/Users/steve.briggs/projects/operations/.git
BRANCH=master
SUBMODULE=
TOPLEVEL=/Users/steve.briggs/projects/operations


Normal repo on `master`. Per the skill, I shouldn't start implementation here without consent. There's also a native `EnterWorktree` tool available, which I'd prefer over manual git fallback.


AskUserQuestion

Question: We're currently on `master`. The subagent-driven flow shouldn't implement directly on master. How would you like to isolate this work?

Choices:
Use the harness's native worktree tool to spin up an isolated workspace on a feature branch. Cleanest — cleanup is automatic if nothing changes.
I create + check out a feature branch (e.g., `feature/birdseye`) right here. No worktree, but we leave master untouched.
Override the safety rail — implementer subagents commit straight to master. Quickest, riskiest.


User has answered your questions: "We're currently on `master`. The subagent-driven flow shouldn't implement directly on master. How would you like to isolate this work?"="Native EnterWorktree (Recommended)". You can now continue with the user's answers in mind.

Question: We're currently on `master`. The subagent-driven flow shouldn't implement directly on master. How would you like to isolate this work?

Choices:
Use the harness's native worktree tool to spin up an isolated workspace on a feature branch. Cleanest — cleanup is automatic if nothing changes.
I create + check out a feature branch (e.g., `feature/birdseye`) right here. No worktree, but we leave master untouched.
Override the safety rail — implementer subagents commit straight to master. Quickest, riskiest.


ToolSearch

Question: select:EnterWorktree


Question: select:EnterWorktree


Created worktree at /Users/steve.briggs/projects/operations/.claude/worktrees/birdseye on branch worktree-birdseye. The session is now working in the worktree. Use ExitWorktree to leave mid-session, or exit the session to be prompted.


Worktree ready. Let me read the prompt templates and verify baseline before dispatching.


Bash

pwd && git branch --show-current && git status -s | head -20 && go version

Verify worktree baseline


1	# Implementer Subagent Prompt Template
2
3	Use this template when dispatching an implementer subagent.
4
5	```
6	Task tool (general-purpose):
7	  description: "Implement Task N: [task name]"
8	  prompt: |
9	    You are implementing Task N: [task name]
10
11	    ## Task Description
12
13	    [FULL TEXT of task from plan - paste it here, don't make subagent read file]
14
15	    ## Context
16
17	    [Scene-setting: where this fits, dependencies, architectural context]
18
19	    ## Before You Begin
20
21	    If you have questions about:
22	    - The requirements or acceptance criteria
23	    - The approach or implementation strategy
24	    - Dependencies or assumptions
25	    - Anything unclear in the task description
26
27	    **Ask them now.** Raise any concerns before starting work.
28
29	    ## Your Job
30
31	    Once you're clear on requirements:
32	    1. Implement exactly what the task specifies
33	    2. Write tests (following TDD if task says to)
34	    3. Verify implementation works
35	    4. Commit your work
36	    5. Self-review (see below)
37	    6. Report back
38
39	    Work from: [directory]
40
41	    **While you work:** If you encounter something unexpected or unclear, **ask questions**.
42	    It's always OK to pause and clarify. Don't guess or make assumptions.
43
44	    ## Code Organization
45
46	    You reason best about code you can hold in context at once, and your edits are more
47	    reliable when files are focused. Keep this in mind:
48	    - Follow the file structure defined in the plan
49	    - Each file should have one clear responsibility with a well-defined interface
50	    - If a file you're creating is growing beyond the plan's intent, stop and report
51	      it as DONE_WITH_CONCERNS — don't split files on your own without plan guidance
52	    - If an existing file you're modifying is already large or tangled, work carefully
53	      and note it as a concern in your report
54	    - In existing codebases, follow established patterns. Improve code you're touching
55	      the way a good developer would, but don't restructure things outside your task.
56
57	    ## When You're in Over Your Head
58
59	    It is always OK to stop and say "this is too hard for me." Bad work is worse than
60	    no work. You will not be penalized for escalating.
61
62	    **STOP and escalate when:**
63	    - The task requires architectural decisions with multiple valid approaches
64	    - You need to understand code beyond what was provided and can't find clarity
65	    - You feel uncertain about whether your approach is correct
66	    - The task involves restructuring existing code in ways the plan didn't anticipate
67	    - You've been reading file after file trying to understand the system without progress
68
69	    **How to escalate:** Report back with status BLOCKED or NEEDS_CONTEXT. Describe
70	    specifically what you're stuck on, what you've tried, and what kind of help you need.
71	    The controller can provide more context, re-dispatch with a more capable model,
72	    or break the task into smaller pieces.
73
74	    ## Before Reporting Back: Self-Review
75
76	    Review your work with fresh eyes. Ask yourself:
77
78	    **Completeness:**
79	    - Did I fully implement everything in the spec?
80	    - Did I miss any requirements?
81	    - Are there edge cases I didn't handle?
82
83	    **Quality:**
84	    - Is this my best work?
85	    - Are names clear and accurate (match what things do, not how they work)?
86	    - Is the code clean and maintainable?
87
88	    **Discipline:**
89	    - Did I avoid overbuilding (YAGNI)?
90	    - Did I only build what was requested?
91	    - Did I follow existing patterns in the codebase?
92
93	    **Testing:**
94	    - Do tests actually verify behavior (not just mock behavior)?
95	    - Did I follow TDD if required?
96	    - Are tests comprehensive?
97
98	    If you find issues during self-review, fix them now before reporting.
99
100	    ## Report Format
101
102	    When done, report:
103	    - **Status:** DONE | DONE_WITH_CONCERNS | BLOCKED | NEEDS_CONTEXT
104	    - What you implemented (or what you attempted, if blocked)
105	    - What you tested and test results
106	    - Files changed
107	    - Self-review findings (if any)
108	    - Any issues or concerns
109
110	    Use DONE_WITH_CONCERNS if you completed the work but have doubts about correctness.
111	    Use BLOCKED if you cannot complete the task. Use NEEDS_CONTEXT if you need
112	    information that wasn't provided. Never silently produce work you're unsure about.
113	```
114

# Implementer Subagent Prompt Template

Use this template when dispatching an implementer subagent.

```
Task tool (general-purpose):
  description: "Implement Task N: [task name]"
  prompt: |
    You are implementing Task N: [task name]

    ## Task Description

    [FULL TEXT of task from plan - paste it here, don't make subagent read file]

    ## Context

    [Scene-setting: where this fits, dependencies, architectural context]

    ## Before You Begin

    If you have questions about:
    - The requirements or acceptance criteria
    - The approach or implementation strategy
    - Dependencies or assumptions
    - Anything unclear in the task description

    **Ask them now.** Raise any concerns before starting work.

    ## Your Job

    Once you're clear on requirements:
    1. Implement exactly what the task specifies
    2. Write tests (following TDD if task says to)
    3. Verify implementation works
    4. Commit your work
    5. Self-review (see below)
    6. Report back

    Work from: [directory]

    **While you work:** If you encounter something unexpected or unclear, **ask questions**.
    It's always OK to pause and clarify. Don't guess or make assumptions.

    ## Code Organization

    You reason best about code you can hold in context at once, and your edits are more
    reliable when files are focused. Keep this in mind:
    - Follow the file structure defined in the plan
    - Each file should have one clear responsibility with a well-defined interface
    - If a file you're creating is growing beyond the plan's intent, stop and report
      it as DONE_WITH_CONCERNS — don't split files on your own without plan guidance
    - If an existing file you're modifying is already large or tangled, work carefully
      and note it as a concern in your report
    - In existing codebases, follow established patterns. Improve code you're touching
      the way a good developer would, but don't restructure things outside your task.

    ## When You're in Over Your Head

    It is always OK to stop and say "this is too hard for me." Bad work is worse than
    no work. You will not be penalized for escalating.

    **STOP and escalate when:**
    - The task requires architectural decisions with multiple valid approaches
    - You need to understand code beyond what was provided and can't find clarity
    - You feel uncertain about whether your approach is correct
    - The task involves restructuring existing code in ways the plan didn't anticipate
    - You've been reading file after file trying to understand the system without progress

    **How to escalate:** Report back with status BLOCKED or NEEDS_CONTEXT. Describe
    specifically what you're stuck on, what you've tried, and what kind of help you need.
    The controller can provide more context, re-dispatch with a more capable model,
    or break the task into smaller pieces.

    ## Before Reporting Back: Self-Review

    Review your work with fresh eyes. Ask yourself:

    **Completeness:**
    - Did I fully implement everything in the spec?
    - Did I miss any requirements?
    - Are there edge cases I didn't handle?

    **Quality:**
    - Is this my best work?
    - Are names clear and accurate (match what things do, not how they work)?
    - Is the code clean and maintainable?

    **Discipline:**
    - Did I avoid overbuilding (YAGNI)?
    - Did I only build what was requested?
    - Did I follow existing patterns in the codebase?

    **Testing:**
    - Do tests actually verify behavior (not just mock behavior)?
    - Did I follow TDD if required?
    - Are tests comprehensive?

    If you find issues during self-review, fix them now before reporting.

    ## Report Format

    When done, report:
    - **Status:** DONE | DONE_WITH_CONCERNS | BLOCKED | NEEDS_CONTEXT
    - What you implemented (or what you attempted, if blocked)
    - What you tested and test results
    - Files changed
    - Self-review findings (if any)
    - Any issues or concerns

    Use DONE_WITH_CONCERNS if you completed the work but have doubts about correctness.
    Use BLOCKED if you cannot complete the task. Use NEEDS_CONTEXT if you need
    information that wasn't provided. Never silently produce work you're unsure about.
```


1	# Spec Compliance Reviewer Prompt Template
2
3	Use this template when dispatching a spec compliance reviewer subagent.
4
5	**Purpose:** Verify implementer built what was requested (nothing more, nothing less)
6
7	```
8	Task tool (general-purpose):
9	  description: "Review spec compliance for Task N"
10	  prompt: |
11	    You are reviewing whether an implementation matches its specification.
12
13	    ## What Was Requested
14
15	    [FULL TEXT of task requirements]
16
17	    ## What Implementer Claims They Built
18
19	    [From implementer's report]
20
21	    ## CRITICAL: Do Not Trust the Report
22
23	    The implementer finished suspiciously quickly. Their report may be incomplete,
24	    inaccurate, or optimistic. You MUST verify everything independently.
25
26	    **DO NOT:**
27	    - Take their word for what they implemented
28	    - Trust their claims about completeness
29	    - Accept their interpretation of requirements
30
31	    **DO:**
32	    - Read the actual code they wrote
33	    - Compare actual implementation to requirements line by line
34	    - Check for missing pieces they claimed to implement
35	    - Look for extra features they didn't mention
36
37	    ## Your Job
38
39	    Read the implementation code and verify:
40
41	    **Missing requirements:**
42	    - Did they implement everything that was requested?
43	    - Are there requirements they skipped or missed?
44	    - Did they claim something works but didn't actually implement it?
45
46	    **Extra/unneeded work:**
47	    - Did they build things that weren't requested?
48	    - Did they over-engineer or add unnecessary features?
49	    - Did they add "nice to haves" that weren't in spec?
50
51	    **Misunderstandings:**
52	    - Did they interpret requirements differently than intended?
53	    - Did they solve the wrong problem?
54	    - Did they implement the right feature but wrong way?
55
56	    **Verify by reading code, not by trusting report.**
57
58	    Report:
59	    - ✅ Spec compliant (if everything matches after code inspection)
60	    - ❌ Issues found: [list specifically what's missing or extra, with file:line references]
61	```
62

# Spec Compliance Reviewer Prompt Template

Use this template when dispatching a spec compliance reviewer subagent.

**Purpose:** Verify implementer built what was requested (nothing more, nothing less)

```
Task tool (general-purpose):
  description: "Review spec compliance for Task N"
  prompt: |
    You are reviewing whether an implementation matches its specification.

    ## What Was Requested

    [FULL TEXT of task requirements]

    ## What Implementer Claims They Built

    [From implementer's report]

    ## CRITICAL: Do Not Trust the Report

    The implementer finished suspiciously quickly. Their report may be incomplete,
    inaccurate, or optimistic. You MUST verify everything independently.

    **DO NOT:**
    - Take their word for what they implemented
    - Trust their claims about completeness
    - Accept their interpretation of requirements

    **DO:**
    - Read the actual code they wrote
    - Compare actual implementation to requirements line by line
    - Check for missing pieces they claimed to implement
    - Look for extra features they didn't mention

    ## Your Job

    Read the implementation code and verify:

    **Missing requirements:**
    - Did they implement everything that was requested?
    - Are there requirements they skipped or missed?
    - Did they claim something works but didn't actually implement it?

    **Extra/unneeded work:**
    - Did they build things that weren't requested?
    - Did they over-engineer or add unnecessary features?
    - Did they add "nice to haves" that weren't in spec?

    **Misunderstandings:**
    - Did they interpret requirements differently than intended?
    - Did they solve the wrong problem?
    - Did they implement the right feature but wrong way?

    **Verify by reading code, not by trusting report.**

    Report:
    - ✅ Spec compliant (if everything matches after code inspection)
    - ❌ Issues found: [list specifically what's missing or extra, with file:line references]
```


1	# Code Quality Reviewer Prompt Template
2
3	Use this template when dispatching a code quality reviewer subagent.
4
5	**Purpose:** Verify implementation is well-built (clean, tested, maintainable)
6
7	**Only dispatch after spec compliance review passes.**
8
9	```
10	Task tool (general-purpose):
11	  Use template at requesting-code-review/code-reviewer.md
12
13	  DESCRIPTION: [task summary, from implementer's report]
14	  PLAN_OR_REQUIREMENTS: Task N from [plan-file]
15	  BASE_SHA: [commit before task]
16	  HEAD_SHA: [current commit]
17	```
18
19	**In addition to standard code quality concerns, the reviewer should check:**
20	- Does each file have one clear responsibility with a well-defined interface?
21	- Are units decomposed so they can be understood and tested independently?
22	- Is the implementation following the file structure from the plan?
23	- Did this implementation create new files that are already large, or significantly grow existing files? (Don't flag pre-existing file sizes — focus on what this change contributed.)
24
25	**Code reviewer returns:** Strengths, Issues (Critical/Important/Minor), Assessment
26

# Code Quality Reviewer Prompt Template

Use this template when dispatching a code quality reviewer subagent.

**Purpose:** Verify implementation is well-built (clean, tested, maintainable)

**Only dispatch after spec compliance review passes.**

```
Task tool (general-purpose):
  Use template at requesting-code-review/code-reviewer.md

  DESCRIPTION: [task summary, from implementer's report]
  PLAN_OR_REQUIREMENTS: Task N from [plan-file]
  BASE_SHA: [commit before task]
  HEAD_SHA: [current commit]
```

**In addition to standard code quality concerns, the reviewer should check:**
- Does each file have one clear responsibility with a well-defined interface?
- Are units decomposed so they can be understood and tested independently?
- Is the implementation following the file structure from the plan?
- Did this implementation create new files that are already large, or significantly grow existing files? (Don't flag pre-existing file sizes — focus on what this change contributed.)

**Code reviewer returns:** Strengths, Issues (Critical/Important/Minor), Assessment


/Users/steve.briggs/projects/operations/.claude/worktrees/birdseye
worktree-birdseye
?? .claude/mind.mv2.lock
go version go1.26.2 darwin/arm64


git check-ignore -v .claude/mind.mv2.lock; git ls-files --error-unmatch .claude 2>&1 | head -3

Check if .claude is gitignored


.claude/skills/app-infra-generate/SKILL.md
.claude/skills/app-infra-spec/SKILL.md
.claude/skills/migrate-flux-app/SKILL.md


Setting up tracking for all 19 implementation tasks. Creating them in parallel.


TaskCreate

Task 1: Bootstrap birdseye module skeleton</subject>
<parameter name="description">go.mod, Makefile, main.go, .gitignore in apps/birdseye/


<tool_use_error>InputValidationError: TaskCreate failed due to the following issue:
The required parameter `description` is missing</tool_use_error>

InputValidationError: [
  {
    "expected": "string",
    "code": "invalid_type",
    "path": [
      "description"
    ],
    "message": "Invalid input: expected string, received undefined"
  }
]


Task 2: Cobra root + exit-code helper</subject>
<parameter name="description">NewRootCmd, GlobalFlags, ExitCode mapping with tests


Task 3: Add Download to Crow client</subject>
<parameter name="description">Extend services/crow/pkg/client with Download method + tests


Task 4: archive.Extract happy path</subject>
<parameter name="description">Module type + Extract with happy-path tests


Task 5: archive hardening tests</subject>
<parameter name="description">Zip-slip, size cap, symlink rejection coverage


Task 6: Cache interface + MemCache</subject>
<parameter name="description">internal/registry/cache.go with in-memory impl + tests


Task 7: DiskCache with atomic writes</subject>
<parameter name="description">DiskCache backed by ~/.cache/birdseye/ with temp+rename


Task 8: Registry Fetch + FetchPair</subject>
<parameter name="description">Cache-first fetch with concurrent FetchPair


Task 9: Textual diff + types</subject>
<parameter name="description">FileDiff, Result, Textual() using gotextdiff


Task 10: cmd diff --plain integration</subject>
<parameter name="description">diff subcommand wired end-to-end with plain output


Task 11: versions subcommand</subject>
<parameter name="description">birdseye versions ns/n/p that lists module versions


Task 12: TUI Browser scaffold</subject>
<parameter name="description">Styles + Browser model with file tree + viewport


Task 13: Browser tea.Model + cmd integration</subject>
<parameter name="description">Update/View key handling + cmd diff TTY launch


Task 14: Interactive Picker state machine</subject>
<parameter name="description">Module textinput, version pickers, loading spinner


Task 15: Wire picker into cmd diff (no-args)</subject>
<parameter name="description">Two-stage runner: picker -> extract -> browser


Task 16: Semantic diff (HCL)</subject>
<parameter name="description">ModuleSummary + Semantic() using hclparse


Task 17: Wire --semantic flag</subject>
<parameter name="description">Flag plus semantic section in plain renderer


Task 18: JSON output mode</subject>
<parameter name="description">--json renders diff.Result as structured JSON


Task 19: README + final polish</subject>
<parameter name="description">apps/birdseye/README.md with usage, flags, exit codes


XML mishap. Let me create a leaner set of phase-level tracking tasks instead (the per-task detail lives in the plan itself).


Phase A: Bootstrap + Crow client (Tasks 1-3)

go.mod/Makefile/main.go, cobra root, ExitCode, client.Download


Task #8 created successfully: Phase A: Bootstrap + Crow client (Tasks 1-3)


Phase B: Archive + Registry (Tasks 4-8)

archive.Extract w/ hardening, MemCache+DiskCache, Registry.FetchPair


Task #9 created successfully: Phase B: Archive + Registry (Tasks 4-8)

Phase B: Archive + Registry (Tasks 4-8)


Phase C: Textual diff + plain CLI (Tasks 9-11)

FileDiff types, gotextdiff, cmd diff --plain, versions subcommand


Task #10 created successfully: Phase C: Textual diff + plain CLI (Tasks 9-11)


Phase D: TUI browser + picker (Tasks 12-15)

Bubbletea browser, picker state machine, integration into cmd diff


Task #11 created successfully: Phase D: TUI browser + picker (Tasks 12-15)


Phase E: Semantic + JSON + README (Tasks 16-19)

HCL semantic diff, --semantic wiring, --json output, README


Task #12 created successfully: Phase E: Semantic + JSON + README (Tasks 16-19)


Final code review + finishing-a-development-branch

Dispatch final reviewer on the full implementation, then invoke finishing-a-development-branch skill


Task #13 created successfully: Final code review + finishing-a-development-branch


Updated task #8 status


Dispatching implementer for **Task 1 — Bootstrap birdseye module skeleton**. Sonnet model per your token-saving preference.


Agent

Implement Task 1: bootstrap birdseye

Prompt:
You are implementing Task 1 of the birdseye CLI implementation plan.

## Working Environment

- **Worktree path:** `/Users/steve.briggs/projects/operations/.claude/worktrees/birdseye`
- **Git branch (current):** `worktree-birdseye` (already checked out)
- **Local Go version:** 1.26.2 (the go.mod directive below is 1.25.5 — that is the project standard from sibling apps; do not change it)
- All commands must use absolute paths or `cd` into the worktree path above. **Do not** operate against the main repo at `/Users/steve.briggs/projects/operations`.
- **NEVER push.** Commits stay local. **NEVER use `git add .` or `git add -A`.** Always `git add` specific paths.

## Context

This is the very first task building a new CLI tool called `birdseye` that diffs two versions of a Terraform module hosted in Immuta's private Crow registry. The full spec is at `docs/superpowers/specs/2026-05-12-birdseye-design.md`, and the full implementation plan is at `docs/superpowers/plans/2026-05-12-birdseye.md` — but you should NOT need to read them. Everything you need is below.

The sibling apps `apps/crowctl` and `apps/immanager` already exist with similar patterns. `apps/birdseye/` exists as an empty directory waiting for content. The crow service this CLI talks to lives at `services/crow/`.

Subsequent tasks (Task 2 onwards) will create `apps/birdseye/cmd/` and add subcommands. Your job is the skeleton only.

## Task Description

### Task 1: Bootstrap `apps/birdseye/` module skeleton

**Files:**
- Create: `apps/birdseye/go.mod`
- Create: `apps/birdseye/Makefile`
- Create: `apps/birdseye/main.go`
- Create: `apps/birdseye/.gitignore`

- [ ] **Step 1: Create `apps/birdseye/go.mod`**

```
module github.com/immuta/operations/apps/birdseye

go 1.25.5

require (
	github.com/charmbracelet/bubbles v0.21.0
	github.com/charmbracelet/bubbletea v1.3.4
	github.com/charmbracelet/lipgloss v1.1.0
	github.com/hashicorp/hcl/v2 v2.23.0
	github.com/hexops/gotextdiff v1.0.3
	github.com/immuta/operations/libs/clog v0.0.0
	github.com/immuta/operations/services/crow v0.0.0
	github.com/spf13/cobra v1.9.1
	golang.org/x/sync v0.10.0
)

replace github.com/immuta/operations/services/crow => ../../services/crow

replace github.com/immuta/operations/libs/clog => ../../libs/clog
```

- [ ] **Step 2: Create `apps/birdseye/Makefile`**

```makefile
.PHONY: build test test-race lint clean

BIN := bin/birdseye

build:
	@mkdir -p bin
	go build -o $(BIN) .

test:
	go test ./...

test-race:
	go test -race ./...

lint:
	go vet ./...

clean:
	rm -rf bin

.DEFAULT_GOAL := build
```

- [ ] **Step 3: Create `apps/birdseye/.gitignore`**

```
/bin/
```

- [ ] **Step 4: Create `apps/birdseye/main.go`**

```go
// Command birdseye diffs two versions of a Terraform module hosted in
// Crow, Immuta's private module registry. See cmd/diff.go for the diff
// subcommand and cmd/versions.go for the versions subcommand.
package main

import (
	"context"
	"fmt"
	"os"
	"os/signal"
	"syscall"

	"github.com/immuta/operations/apps/birdseye/cmd"
)

func main() {
	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
	defer stop()

	root := cmd.NewRootCmd()
	if err := root.ExecuteContext(ctx); err != nil {
		fmt.Fprintln(os.Stderr, "birdseye:", err)
		os.Exit(cmd.ExitCode(err))
	}
}
```

- [ ] **Step 5: Run `go mod tidy`**

Run: `cd /Users/steve.briggs/projects/operations/.claude/worktrees/birdseye/apps/birdseye && go mod tidy`
Expected: `go.sum` is created. NOTE: `go mod tidy` may complain that `cmd` package is missing — that is EXPECTED because Task 2 creates it. If `go mod tidy` errors on the missing `cmd` import, that is fine; if it succeeds, even better. Do NOT add the `cmd` package yourself.

If `go mod tidy` refuses to write go.sum due to the missing import, run `go mod download` instead to populate go.sum. The goal is to produce a valid go.sum file with all third-party deps resolved.

- [ ] **Step 6: Commit**

```bash
cd /Users/steve.briggs/projects/operations/.claude/worktrees/birdseye && git add apps/birdseye/go.mod apps/birdseye/go.sum apps/birdseye/Makefile apps/birdseye/main.go apps/birdseye/.gitignore && git commit -m "feat(birdseye): bootstrap module skeleton"
```

## Notes & Style

- Project uses Go 1.25.5 directive in go.mod (matches `apps/crowctl/go.mod`). Do not change it even though local Go is newer.
- Use `replace` directives for local modules exactly as shown.
- The package comment in `main.go` references files that don't exist yet (cmd/diff.go etc.). That's intentional — the comment describes the target architecture.
- The compile may fail because `cmd` package doesn't exist yet. That's expected at this stage; `go build` will succeed only after Task 2. **You are NOT required to make `go build` succeed at the end of Task 1.** You ARE required to produce a clean `go.sum` and commit the files.

## Before You Begin

If you have questions about the requirements or approach, **ask them now**. Otherwise proceed.

## Your Job

1. Implement exactly what the task specifies
2. No tests required for this task (it's pure scaffolding)
3. Verify go.sum is created and contains the listed third-party deps
4. Commit the files
5. Self-review
6. Report back

**While you work:** If you encounter something unexpected, ask. Don't guess.

## Self-Review Checklist

- [ ] go.mod has all 9 require lines + 2 replace directives, exactly as shown
- [ ] go.sum exists and is non-empty
- [ ] Makefile has `.PHONY` line and all 5 targets (build, test, test-race, lint, clean)
- [ ] main.go imports look clean (no unused imports)
- [ ] .gitignore contains `/bin/`
- [ ] No extra files created (no go.work, no README, no cmd/ stubs)
- [ ] Commit message exactly: `feat(birdseye): bootstrap module skeleton`
- [ ] `git status` is clean inside the worktree after commit

## Report Format

When done, report:
- **Status:** DONE | DONE_WITH_CONCERNS | BLOCKED | NEEDS_CONTEXT
- What you implemented
- Output of `go mod tidy` / `go mod download` (whether it succeeded or what error it gave)
- Files committed (filenames)
- Commit SHA
- Self-review findings (if any)
- Any issues or concerns


Clean. The commit landed at `ae477d5`. The only untracked file is `.claude/mind.mv2.lock` which is not part of this task.

---

**Status: DONE_WITH_CONCERNS**

**What was implemented:**

Created 4 files + generated go.sum (5 files total) under `apps/birdseye/`:

- `/Users/steve.briggs/projects/operations/.claude/worktrees/birdseye/apps/birdseye/go.mod` — 9 require lines + 2 replace directives, exactly as specified
- `/Users/steve.briggs/projects/operations/.claude/worktrees/birdseye/apps/birdseye/Makefile` — `.PHONY` line + all 5 targets (build, test, test-race, lint, clean)
- `/Users/steve.briggs/projects/operations/.claude/worktrees/birdseye/apps/birdseye/.gitignore` — contains `/bin/`
- `/Users/steve.briggs/projects/operations/.claude/worktrees/birdseye/apps/birdseye/main.go` — package comment, signal context, `cmd.NewRootCmd()` + `cmd.ExitCode()` usage
- `/Users/steve.briggs/projects/operations/.claude/worktrees/birdseye/apps/birdseye/go.sum` — generated, 13 entries, non-empty

**go mod tidy / go mod download output:**

- `go mod tidy` failed as expected: `github.com/immuta/operations/apps/birdseye/cmd` package not found (Task 2 creates it)
- `go mod download` succeeded silently and produced go.sum

**Files committed:** `apps/birdseye/.gitignore`, `apps/birdseye/Makefile`, `apps/birdseye/go.mod`, `apps/birdseye/go.sum`, `apps/birdseye/main.go`

**Commit SHA:** `ae477d5`

**Self-review findings:**

- go.mod has all 9 require lines + 2 replace directives — PASS
- go.sum exists, 13 non-empty lines — PASS
- Makefile has `.PHONY` + 5 targets — PASS
- main.go imports are correct (no unused imports, `cmd` package referenced as per spec) — PASS
- .gitignore contains `/bin/` — PASS
- No extra files created — PASS
- Commit message is exactly `feat(birdseye): bootstrap module skeleton` — PASS
- git status is clean (only `.claude/mind.mv2.lock` untracked, which is not part of this task) — PASS

**Concern:** The Go toolchain resolved `golang.org/x/sync` to `v0.11.0` instead of the spec's `v0.10.0`. The spec listed `v0.10.0` but `go mod download` updated it to the actual available version (`v0.11.0`). This is normal Go toolchain behavior — it selects the minimum compatible version that satisfies transitive requirements. If the spec requires a hard pin to `v0.10.0`, go.mod would need a manual override, but that may cause resolution issues. Recommend leaving it at `v0.11.0` unless Sir Charles of St Cheese explicitly needs `v0.10.0`.

agentId: ada10285da55c796c (use SendMessage with to: 'ada10285da55c796c' to continue this agent)
<usage>total_tokens: 29106
tool_uses: 18
duration_ms: 10554803</usage>

Prompt:
You are implementing Task 1 of the birdseye CLI implementation plan.

## Working Environment

- **Worktree path:** `/Users/steve.briggs/projects/operations/.claude/worktrees/birdseye`
- **Git branch (current):** `worktree-birdseye` (already checked out)
- **Local Go version:** 1.26.2 (the go.mod directive below is 1.25.5 — that is the project standard from sibling apps; do not change it)
- All commands must use absolute paths or `cd` into the worktree path above. **Do not** operate against the main repo at `/Users/steve.briggs/projects/operations`.
- **NEVER push.** Commits stay local. **NEVER use `git add .` or `git add -A`.** Always `git add` specific paths.

## Context

This is the very first task building a new CLI tool called `birdseye` that diffs two versions of a Terraform module hosted in Immuta's private Crow registry. The full spec is at `docs/superpowers/specs/2026-05-12-birdseye-design.md`, and the full implementation plan is at `docs/superpowers/plans/2026-05-12-birdseye.md` — but you should NOT need to read them. Everything you need is below.

The sibling apps `apps/crowctl` and `apps/immanager` already exist with similar patterns. `apps/birdseye/` exists as an empty directory waiting for content. The crow service this CLI talks to lives at `services/crow/`.

Subsequent tasks (Task 2 onwards) will create `apps/birdseye/cmd/` and add subcommands. Your job is the skeleton only.

## Task Description

### Task 1: Bootstrap `apps/birdseye/` module skeleton

**Files:**
- Create: `apps/birdseye/go.mod`
- Create: `apps/birdseye/Makefile`
- Create: `apps/birdseye/main.go`
- Create: `apps/birdseye/.gitignore`

- [ ] **Step 1: Create `apps/birdseye/go.mod`**

```
module github.com/immuta/operations/apps/birdseye

go 1.25.5

require (
	github.com/charmbracelet/bubbles v0.21.0
	github.com/charmbracelet/bubbletea v1.3.4
	github.com/charmbracelet/lipgloss v1.1.0
	github.com/hashicorp/hcl/v2 v2.23.0
	github.com/hexops/gotextdiff v1.0.3
	github.com/immuta/operations/libs/clog v0.0.0
	github.com/immuta/operations/services/crow v0.0.0
	github.com/spf13/cobra v1.9.1
	golang.org/x/sync v0.10.0
)

replace github.com/immuta/operations/services/crow => ../../services/crow

replace github.com/immuta/operations/libs/clog => ../../libs/clog
```

- [ ] **Step 2: Create `apps/birdseye/Makefile`**

```makefile
.PHONY: build test test-race lint clean

BIN := bin/birdseye

build:
	@mkdir -p bin
	go build -o $(BIN) .

test:
	go test ./...

test-race:
	go test -race ./...

lint:
	go vet ./...

clean:
	rm -rf bin

.DEFAULT_GOAL := build
```

- [ ] **Step 3: Create `apps/birdseye/.gitignore`**

```
/bin/
```

- [ ] **Step 4: Create `apps/birdseye/main.go`**

```go
// Command birdseye diffs two versions of a Terraform module hosted in
// Crow, Immuta's private module registry. See cmd/diff.go for the diff
// subcommand and cmd/versions.go for the versions subcommand.
package main

import (
	"context"
	"fmt"
	"os"
	"os/signal"
	"syscall"

	"github.com/immuta/operations/apps/birdseye/cmd"
)

func main() {
	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
	defer stop()

	root := cmd.NewRootCmd()
	if err := root.ExecuteContext(ctx); err != nil {
		fmt.Fprintln(os.Stderr, "birdseye:", err)
		os.Exit(cmd.ExitCode(err))
	}
}
```

- [ ] **Step 5: Run `go mod tidy`**

Run: `cd /Users/steve.briggs/projects/operations/.claude/worktrees/birdseye/apps/birdseye && go mod tidy`
Expected: `go.sum` is created. NOTE: `go mod tidy` may complain that `cmd` package is missing — that is EXPECTED because Task 2 creates it. If `go mod tidy` errors on the missing `cmd` import, that is fine; if it succeeds, even better. Do NOT add the `cmd` package yourself.

If `go mod tidy` refuses to write go.sum due to the missing import, run `go mod download` instead to populate go.sum. The goal is to produce a valid go.sum file with all third-party deps resolved.

- [ ] **Step 6: Commit**

```bash
cd /Users/steve.briggs/projects/operations/.claude/worktrees/birdseye && git add apps/birdseye/go.mod apps/birdseye/go.sum apps/birdseye/Makefile apps/birdseye/main.go apps/birdseye/.gitignore && git commit -m "feat(birdseye): bootstrap module skeleton"
```

## Notes & Style

- Project uses Go 1.25.5 directive in go.mod (matches `apps/crowctl/go.mod`). Do not change it even though local Go is newer.
- Use `replace` directives for local modules exactly as shown.
- The package comment in `main.go` references files that don't exist yet (cmd/diff.go etc.). That's intentional — the comment describes the target architecture.
- The compile may fail because `cmd` package doesn't exist yet. That's expected at this stage; `go build` will succeed only after Task 2. **You are NOT required to make `go build` succeed at the end of Task 1.** You ARE required to produce a clean `go.sum` and commit the files.

## Before You Begin

If you have questions about the requirements or approach, **ask them now**. Otherwise proceed.

## Your Job

1. Implement exactly what the task specifies
2. No tests required for this task (it's pure scaffolding)
3. Verify go.sum is created and contains the listed third-party deps
4. Commit the files
5. Self-review
6. Report back

**While you work:** If you encounter something unexpected, ask. Don't guess.

## Self-Review Checklist

- [ ] go.mod has all 9 require lines + 2 replace directives, exactly as shown
- [ ] go.sum exists and is non-empty
- [ ] Makefile has `.PHONY` line and all 5 targets (build, test, test-race, lint, clean)
- [ ] main.go imports look clean (no unused imports)
- [ ] .gitignore contains `/bin/`
- [ ] No extra files created (no go.work, no README, no cmd/ stubs)
- [ ] Commit message exactly: `feat(birdseye): bootstrap module skeleton`
- [ ] `git status` is clean inside the worktree after commit

## Report Format

When done, report:
- **Status:** DONE | DONE_WITH_CONCERNS | BLOCKED | NEEDS_CONTEXT
- What you implemented
- Output of `go mod tidy` / `go mod download` (whether it succeeded or what error it gave)
- Files committed (filenames)
- Commit SHA
- Self-review findings (if any)
- Any issues or concerns


Implementer reports DONE_WITH_CONCERNS — the only concern is `golang.org/x/sync v0.11.0` vs spec's `v0.10.0` due to Go's MVS resolution. That's a normal observation, not a correctness issue. Proceeding to spec compliance review.


Bash

git log --oneline -3 && echo "---" && git show --stat ae477d5 | head -20

Confirm SHAs and Task 1 commit


ae477d5 feat(birdseye): bootstrap module skeleton
c040bf3 feat(SRE-2727): stdb-proxy config generator service (#295)
edbc76f chore(SRE-2806): remove default cpu limit (#300)
---
commit ae477d5d23f04e00ef24ab9ab62fc5af1fe34958
Author: mr0xb <47467008+mr0xb@users.noreply.github.com>
Date:   Tue May 12 21:15:08 2026 -0400

    feat(birdseye): bootstrap module skeleton

 apps/birdseye/.gitignore |  1 +
 apps/birdseye/Makefile   | 21 +++++++++++++++++++++
 apps/birdseye/go.mod     | 19 +++++++++++++++++++
 apps/birdseye/go.sum     | 13 +++++++++++++
 apps/birdseye/main.go    | 25 +++++++++++++++++++++++++
 5 files changed, 79 insertions(+)


Agent

Spec review Task 1

Prompt:
You are reviewing whether the Task 1 implementation matches its specification.

## Working Directory

`/Users/steve.briggs/projects/operations/.claude/worktrees/birdseye`

Compare commit `ae477d5` (Task 1) against its parent `c040bf3`.

## What Was Requested (Full Task Text)

### Task 1: Bootstrap `apps/birdseye/` module skeleton

**Files:**
- Create: `apps/birdseye/go.mod`
- Create: `apps/birdseye/Makefile`
- Create: `apps/birdseye/main.go`
- Create: `apps/birdseye/.gitignore`

**Step 1: `apps/birdseye/go.mod`** must contain:
```
module github.com/immuta/operations/apps/birdseye

go 1.25.5

require (
	github.com/charmbracelet/bubbles v0.21.0
	github.com/charmbracelet/bubbletea v1.3.4
	github.com/charmbracelet/lipgloss v1.1.0
	github.com/hashicorp/hcl/v2 v2.23.0
	github.com/hexops/gotextdiff v1.0.3
	github.com/immuta/operations/libs/clog v0.0.0
	github.com/immuta/operations/services/crow v0.0.0
	github.com/spf13/cobra v1.9.1
	golang.org/x/sync v0.10.0
)

replace github.com/immuta/operations/services/crow => ../../services/crow

replace github.com/immuta/operations/libs/clog => ../../libs/clog
```

**Step 2: `apps/birdseye/Makefile`** must contain:
```makefile
.PHONY: build test test-race lint clean

BIN := bin/birdseye

build:
	@mkdir -p bin
	go build -o $(BIN) .

test:
	go test ./...

test-race:
	go test -race ./...

lint:
	go vet ./...

clean:
	rm -rf bin

.DEFAULT_GOAL := build
```

**Step 3: `apps/birdseye/.gitignore`** must contain:
```
/bin/
```

**Step 4: `apps/birdseye/main.go`** must contain:
```go
// Command birdseye diffs two versions of a Terraform module hosted in
// Crow, Immuta's private module registry. See cmd/diff.go for the diff
// subcommand and cmd/versions.go for the versions subcommand.
package main

import (
	"context"
	"fmt"
	"os"
	"os/signal"
	"syscall"

	"github.com/immuta/operations/apps/birdseye/cmd"
)

func main() {
	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
	defer stop()

	root := cmd.NewRootCmd()
	if err := root.ExecuteContext(ctx); err != nil {
		fmt.Fprintln(os.Stderr, "birdseye:", err)
		os.Exit(cmd.ExitCode(err))
	}
}
```

**Step 5: Run `go mod tidy`** — go.sum should be produced (may use `go mod download` instead because the `cmd` import is missing in this task; that fallback is allowed per the task notes).

**Step 6: Commit** with message exactly: `feat(birdseye): bootstrap module skeleton` and only the four created files + go.sum staged.

## What Implementer Claims They Built

- All 5 files created (4 + go.sum)
- go.mod with 9 require lines + 2 replace directives
- Makefile with `.PHONY` + 5 targets
- main.go imports cmd package
- .gitignore contains `/bin/`
- Commit message exact
- `go mod tidy` failed as expected, `go mod download` succeeded
- Concern: `golang.org/x/sync` resolved to `v0.11.0` instead of spec's `v0.10.0`

## CRITICAL: Do Not Trust the Report

The implementer's report may be inaccurate. You MUST verify by reading the actual files.

**DO:**
- `cat` (use Read tool) each of the four files in the worktree path above
- Read `go.sum` to confirm it's non-empty and references the listed modules
- Run `git show --stat ae477d5` to confirm exactly which files landed
- Run `git log -1 --pretty=format:%s ae477d5` to confirm commit message verbatim
- Run `git diff c040bf3..ae477d5 -- apps/birdseye/` to view the full diff

## Your Job

Verify the implementation against the spec. Specifically check:

**Missing requirements:**
- Are all four required files present with the exact content specified?
- Did the implementer skip anything (e.g., omit a Makefile target, omit a replace directive)?
- Did the implementer use the EXACT module path / package comment / imports?

**Extra/unneeded work:**
- Are there any files in the commit beyond the four created + go.sum?
- Did the implementer add anything not in the spec (an extra Makefile target, an extra import, a README)?

**Misunderstandings:**
- Is the package name `main` in `main.go`?
- Does `main.go` use `cmd.NewRootCmd()` and `cmd.ExitCode()` (the symbols Task 2 will define)?
- Does go.mod use the `replace` directives with relative paths `../../services/crow` and `../../libs/clog`?

**The `golang.org/x/sync v0.11.0` vs `v0.10.0` discrepancy:** This is a known minor concern; flag it but do NOT fail the review for it. The minimum-version-selection drift is normal Go behavior; we can pin later if needed.

## Report

Use one of:
- ✅ Spec compliant — note the x/sync version drift but mark as passing
- ❌ Issues found: list specifically what's missing, extra, or wrong, with `file:line` references

Be terse. Just the verdict and any issues. Do not re-paste files.


✅ Spec compliant

All checks pass:

- **Commit message**: exact match — `feat(birdseye): bootstrap module skeleton`
- **Files in commit**: exactly the 5 expected files (4 created + go.sum), nothing extra
- **.gitignore**: `/bin/` — correct
- **Makefile**: all 5 targets (`build`, `test`, `test-race`, `lint`, `clean`), `.PHONY`, `BIN` variable, `.DEFAULT_GOAL := build` — exact match
- **go.mod**: correct module path, `go 1.25.5`, all 9 require lines, both `replace` directives with correct relative paths `../../services/crow` and `../../libs/clog`
- **main.go**: correct package comment, `package main`, all required imports, `cmd.NewRootCmd()`, `cmd.ExitCode(err)` — exact match
- **go.sum**: non-empty, references expected modules

**Known drift**: `golang.org/x/sync` resolved to `v0.11.0` (spec says `v0.10.0`). This is normal Go MVS behavior — flagged but not a failure.

agentId: a0c2135a8066322cd (use SendMessage with to: 'a0c2135a8066322cd' to continue this agent)
<usage>total_tokens: 15575
tool_uses: 3
duration_ms: 36115</usage>

Prompt:
You are reviewing whether the Task 1 implementation matches its specification.

## Working Directory

`/Users/steve.briggs/projects/operations/.claude/worktrees/birdseye`

Compare commit `ae477d5` (Task 1) against its parent `c040bf3`.

## What Was Requested (Full Task Text)

### Task 1: Bootstrap `apps/birdseye/` module skeleton

**Files:**
- Create: `apps/birdseye/go.mod`
- Create: `apps/birdseye/Makefile`
- Create: `apps/birdseye/main.go`
- Create: `apps/birdseye/.gitignore`

**Step 1: `apps/birdseye/go.mod`** must contain:
```
module github.com/immuta/operations/apps/birdseye

go 1.25.5

require (
	github.com/charmbracelet/bubbles v0.21.0
	github.com/charmbracelet/bubbletea v1.3.4
	github.com/charmbracelet/lipgloss v1.1.0
	github.com/hashicorp/hcl/v2 v2.23.0
	github.com/hexops/gotextdiff v1.0.3
	github.com/immuta/operations/libs/clog v0.0.0
	github.com/immuta/operations/services/crow v0.0.0
	github.com/spf13/cobra v1.9.1
	golang.org/x/sync v0.10.0
)

replace github.com/immuta/operations/services/crow => ../../services/crow

replace github.com/immuta/operations/libs/clog => ../../libs/clog
```

**Step 2: `apps/birdseye/Makefile`** must contain:
```makefile
.PHONY: build test test-race lint clean

BIN := bin/birdseye

build:
	@mkdir -p bin
	go build -o $(BIN) .

test:
	go test ./...

test-race:
	go test -race ./...

lint:
	go vet ./...

clean:
	rm -rf bin

.DEFAULT_GOAL := build
```

**Step 3: `apps/birdseye/.gitignore`** must contain:
```
/bin/
```

**Step 4: `apps/birdseye/main.go`** must contain:
```go
// Command birdseye diffs two versions of a Terraform module hosted in
// Crow, Immuta's private module registry. See cmd/diff.go for the diff
// subcommand and cmd/versions.go for the versions subcommand.
package main

import (
	"context"
	"fmt"
	"os"
	"os/signal"
	"syscall"

	"github.com/immuta/operations/apps/birdseye/cmd"
)

func main() {
	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
	defer stop()

	root := cmd.NewRootCmd()
	if err := root.ExecuteContext(ctx); err != nil {
		fmt.Fprintln(os.Stderr, "birdseye:", err)
		os.Exit(cmd.ExitCode(err))
	}
}
```

**Step 5: Run `go mod tidy`** — go.sum should be produced (may use `go mod download` instead because the `cmd` import is missing in this task; that fallback is allowed per the task notes).

**Step 6: Commit** with message exactly: `feat(birdseye): bootstrap module skeleton` and only the four created files + go.sum staged.

## What Implementer Claims They Built

- All 5 files created (4 + go.sum)
- go.mod with 9 require lines + 2 replace directives
- Makefile with `.PHONY` + 5 targets
- main.go imports cmd package
- .gitignore contains `/bin/`
- Commit message exact
- `go mod tidy` failed as expected, `go mod download` succeeded
- Concern: `golang.org/x/sync` resolved to `v0.11.0` instead of spec's `v0.10.0`

## CRITICAL: Do Not Trust the Report

The implementer's report may be inaccurate. You MUST verify by reading the actual files.

**DO:**
- `cat` (use Read tool) each of the four files in the worktree path above
- Read `go.sum` to confirm it's non-empty and references the listed modules
- Run `git show --stat ae477d5` to confirm exactly which files landed
- Run `git log -1 --pretty=format:%s ae477d5` to confirm commit message verbatim
- Run `git diff c040bf3..ae477d5 -- apps/birdseye/` to view the full diff

## Your Job

Verify the implementation against the spec. Specifically check:

**Missing requirements:**
- Are all four required files present with the exact content specified?
- Did the implementer skip anything (e.g., omit a Makefile target, omit a replace directive)?
- Did the implementer use the EXACT module path / package comment / imports?

**Extra/unneeded work:**
- Are there any files in the commit beyond the four created + go.sum?
- Did the implementer add anything not in the spec (an extra Makefile target, an extra import, a README)?

**Misunderstandings:**
- Is the package name `main` in `main.go`?
- Does `main.go` use `cmd.NewRootCmd()` and `cmd.ExitCode()` (the symbols Task 2 will define)?
- Does go.mod use the `replace` directives with relative paths `../../services/crow` and `../../libs/clog`?

**The `golang.org/x/sync v0.11.0` vs `v0.10.0` discrepancy:** This is a known minor concern; flag it but do NOT fail the review for it. The minimum-version-selection drift is normal Go behavior; we can pin later if needed.

## Report

Use one of:
- ✅ Spec compliant — note the x/sync version drift but mark as passing
- ❌ Issues found: list specifically what's missing, extra, or wrong, with `file:line` references

Be terse. Just the verdict and any issues. Do not re-paste files.


Spec ✓. Dispatching code quality reviewer.


Code quality review Task 1

Prompt:
You are reviewing the code quality of Task 1: birdseye bootstrap module skeleton.

## Working Directory

`/Users/steve.briggs/projects/operations/.claude/worktrees/birdseye`

## Diff to Review

```
BASE_SHA: c040bf3
HEAD_SHA: ae477d5
```

Run `git diff c040bf3..ae477d5 -- apps/birdseye/` in the worktree to inspect the change. Five files were added: go.mod, go.sum, Makefile, main.go, .gitignore.

## Context

This is the bootstrap commit for a brand-new Go CLI under `apps/birdseye/`. Sibling apps `apps/crowctl` and `apps/immanager` exist with similar patterns; you may reference them at `/Users/steve.briggs/projects/operations/.claude/worktrees/birdseye/apps/crowctl/` for comparison if useful.

Spec compliance has already been verified separately — DO NOT re-verify spec compliance. Your job is code quality only.

## Review Focus

This is intentionally a thin scaffolding commit (no logic, no tests). Code quality assessment is therefore narrow:

**File organization & responsibility:**
- Does each file have one clear responsibility?
- Are the imports in `main.go` minimal and well-organized (stdlib first, third-party last per Go convention)?
- Is the Makefile's variable / target structure clean?

**Idioms & style:**
- Is the package comment in `main.go` informative and accurately describes the package?
- Are signal handling and error reporting in `main.go` idiomatic? (Look at `signal.NotifyContext` + cleanup, exit-code propagation.)
- Does go.mod follow standard layout?

**Anti-patterns:**
- Unused imports?
- Dead code?
- Overbuilt scaffolding (e.g., feature flags, config flags that aren't needed yet)?
- Missing standard targets in Makefile (the spec listed 5 targets; verify they're sensible)?

**Per-task plan checks:**
- Does each new file have one clear responsibility with a well-defined interface? Yes/no.
- Did this change create new files that are already large or significantly grow existing files? (Should be no — all files are tiny scaffolding.)

## Report Format

Be brief. Use this structure:

**Strengths:** (1-3 bullets)

**Issues:**
- Critical: (anything blocking — likely none here)
- Important: (anything worth fixing now)
- Minor: (nice-to-haves)

**Assessment:** APPROVED | NEEDS_CHANGES


I now have everything I need for the review. Let me analyze the findings:

1. `main.go` references `cmd.NewRootCmd()` and `cmd.ExitCode(err)` but the `cmd/` package does not exist in this commit — the go.sum only has `.go.mod` hashes (no `h1:` hashes), confirming the code cannot build as-is.
2. `go.mod` specifies `go 1.25.5` — same as the crowctl sibling, so that's intentional for the workspace.
3. The go.sum only contains `go.mod` hash lines (no `h1:` source hashes), meaning dependencies aren't actually downloaded — consistent with a non-buildable bootstrap.
4. The package doc comment refers to `cmd/diff.go` and `cmd/versions.go` which don't exist yet.
5. Signal handling with `signal.NotifyContext` + `defer stop()` is idiomatic.
6. Error output to `os.Stderr` with program name prefix is idiomatic.
7. `cmd.ExitCode(err)` implies a custom exit-code type exists in the `cmd` package — forward reference to something not yet committed.
8. Makefile has all 5 expected targets (build, test, test-race, lint, clean), `.PHONY` declared, `BIN` variable, `.DEFAULT_GOAL`.
9. No overbuilt scaffolding, no dead code, no unused imports in what's visible.
10. The comment doc mentions specific files (`cmd/diff.go`, `cmd/versions.go`) that don't exist — premature specificity.

---

**Strengths:**

- Signal handling is textbook Go idiom: `signal.NotifyContext` with `defer stop()` cleanly unblocks the context and prevents the goroutine from leaking, and stderr error output with a program-name prefix matches stdlib tool conventions.
- Makefile is clean and complete: all five expected targets declared, single `BIN` variable, `.PHONY` list accurate, `.DEFAULT_GOAL` set — nothing extraneous.
- File sizes are appropriate for scaffolding; each file has exactly one responsibility with no bloat.

**Issues:**

- Critical: None that block merging as an intentional non-buildable bootstrap skeleton.

- Important: The package doc comment in `main.go` references `cmd/diff.go` and `cmd/versions.go` by filename — these files don't exist in this commit and may not reflect the final file layout. Doc comments on `package main` get picked up by `go doc` and any future tooling; forward-referencing concrete filenames that don't exist yet is misleading. The comment should either drop the file references or say "see the `cmd` subpackage" without naming specific files.

- Important: `cmd.ExitCode(err)` is called but the `cmd` package doesn't exist in this commit. This is presumably intentional (the package arrives in a follow-on commit), but it means `go build ./...` fails today. If the CI pipeline tries to build this branch in isolation, it will fail. Worth confirming the CI runs against individual commits or only the final branch state before merging.

- Minor: The go.sum contains only `go.mod` hashes (no `h1:` source hashes) for all dependencies. This is consistent with `go mod download` not having been run, meaning the module graph is declared but nothing is actually vendored or cached. A follow-up commit that adds real source should run `go mod tidy` and commit the full go.sum.

**Assessment:** APPROVED

The two "important" items are things Sir Charles should be aware of but neither blocks merging this as a bootstrap scaffold — the missing `cmd` package is clearly by design, and the doc comment nit is cosmetic. The CI build concern is the only thing worth a quick sanity-check before the branch lands.

agentId: afe32546bc1ac289e (use SendMessage with to: 'afe32546bc1ac289e' to continue this agent)
<usage>total_tokens: 24633
tool_uses: 12
duration_ms: 67344</usage>

Prompt:
You are reviewing the code quality of Task 1: birdseye bootstrap module skeleton.

## Working Directory

`/Users/steve.briggs/projects/operations/.claude/worktrees/birdseye`

## Diff to Review

```
BASE_SHA: c040bf3
HEAD_SHA: ae477d5
```

Run `git diff c040bf3..ae477d5 -- apps/birdseye/` in the worktree to inspect the change. Five files were added: go.mod, go.sum, Makefile, main.go, .gitignore.

## Context

This is the bootstrap commit for a brand-new Go CLI under `apps/birdseye/`. Sibling apps `apps/crowctl` and `apps/immanager` exist with similar patterns; you may reference them at `/Users/steve.briggs/projects/operations/.claude/worktrees/birdseye/apps/crowctl/` for comparison if useful.

Spec compliance has already been verified separately — DO NOT re-verify spec compliance. Your job is code quality only.

## Review Focus

This is intentionally a thin scaffolding commit (no logic, no tests). Code quality assessment is therefore narrow:

**File organization & responsibility:**
- Does each file have one clear responsibility?
- Are the imports in `main.go` minimal and well-organized (stdlib first, third-party last per Go convention)?
- Is the Makefile's variable / target structure clean?

**Idioms & style:**
- Is the package comment in `main.go` informative and accurately describes the package?
- Are signal handling and error reporting in `main.go` idiomatic? (Look at `signal.NotifyContext` + cleanup, exit-code propagation.)
- Does go.mod follow standard layout?

**Anti-patterns:**
- Unused imports?
- Dead code?
- Overbuilt scaffolding (e.g., feature flags, config flags that aren't needed yet)?
- Missing standard targets in Makefile (the spec listed 5 targets; verify they're sensible)?

**Per-task plan checks:**
- Does each new file have one clear responsibility with a well-defined interface? Yes/no.
- Did this change create new files that are already large or significantly grow existing files? (Should be no — all files are tiny scaffolding.)

## Report Format

Be brief. Use this structure:

**Strengths:** (1-3 bullets)

**Issues:**
- Critical: (anything blocking — likely none here)
- Important: (anything worth fixing now)
- Minor: (nice-to-haves)

**Assessment:** APPROVED | NEEDS_CHANGES


Task 1 ✓ (APPROVED with two non-blocking notes — package comment references future files, and `cmd` package doesn't exist yet by design). Moving to Task 2 immediately.


Implement Task 2: cobra root + ExitCode

Prompt:
You are implementing Task 2 of the birdseye CLI implementation plan.

## Working Environment

- **Worktree path:** `/Users/steve.briggs/projects/operations/.claude/worktrees/birdseye`
- **Git branch:** `worktree-birdseye`
- Most recent commit: `ae477d5 feat(birdseye): bootstrap module skeleton` (Task 1 — provides go.mod, Makefile, main.go)
- All paths in this prompt are relative to the worktree. Use absolute paths or `cd` into the worktree path above.
- **NEVER push.** **NEVER use `git add .` or `git add -A`.** Always `git add` specific paths.
- Local Go: 1.26.2 (go.mod directive is 1.25.5 — fine).

## Context

Task 1 created the module skeleton with `main.go` that imports a `cmd` package and calls `cmd.NewRootCmd()` and `cmd.ExitCode()`. Right now the build is broken because the `cmd` package doesn't exist. Your job is to create it.

This is the cobra root command for the `birdseye` CLI. Subcommands (`diff`, `versions`) are added in later tasks — your job is JUST the root command plus the exit-code helper used by `main.go`. Do NOT add subcommands yourself.

You'll create 4 files: `cmd/root.go`, `cmd/root_test.go`, `cmd/errors.go`, `cmd/errors_test.go`. Use strict TDD: write the failing test, run it, implement, run again.

## Task Description (Verbatim)

### Task 2: Cobra root command + exit-code helper

**Files:**
- Create: `apps/birdseye/cmd/root.go`
- Create: `apps/birdseye/cmd/root_test.go`
- Create: `apps/birdseye/cmd/errors.go`
- Create: `apps/birdseye/cmd/errors_test.go`

- [ ] **Step 1: Write failing test for `NewRootCmd`** at `apps/birdseye/cmd/root_test.go`:

```go
package cmd

import (
	"bytes"
	"strings"
	"testing"
)

func TestNewRootCmdHelp(t *testing.T) {
	root := NewRootCmd()
	var buf bytes.Buffer
	root.SetOut(&buf)
	root.SetErr(&buf)
	root.SetArgs([]string{"--help"})
	if err := root.Execute(); err != nil {
		t.Fatalf("execute: %v", err)
	}
	out := buf.String()
	for _, want := range []string{"birdseye", "--crow-url", "--timeout"} {
		if !strings.Contains(out, want) {
			t.Errorf("help output missing %q\n---\n%s", want, out)
		}
	}
}

func TestNewRootCmdDefaults(t *testing.T) {
	root := NewRootCmd()
	if got, _ := root.PersistentFlags().GetString("crow-url"); got != "https://crow.infrastructure.immuta.io" {
		t.Errorf("crow-url default = %q", got)
	}
}
```

- [ ] **Step 2: Run test, expect FAIL** (`undefined: NewRootCmd`)

Run: `cd /Users/steve.briggs/projects/operations/.claude/worktrees/birdseye/apps/birdseye && go test ./cmd/... -run TestNewRootCmd -v`
Expected: compile error or undefined symbol.

- [ ] **Step 3: Implement `apps/birdseye/cmd/root.go`**

```go
// Package cmd wires up the cobra command tree for birdseye. Functions
// return *cobra.Command (rather than using package-level vars) so each
// test builds a fresh tree and flag state does not leak between cases.
package cmd

import (
	"time"

	"github.com/spf13/cobra"
)

// GlobalFlags are the cross-subcommand options exposed on the root command.
type GlobalFlags struct {
	CrowURL string
	Timeout time.Duration
	JSON    bool
}

const defaultCrowURL = "https://crow.infrastructure.immuta.io"

// NewRootCmd returns the configured root command. Subcommands are wired
// in here.
func NewRootCmd() *cobra.Command {
	g := &GlobalFlags{}
	root := &cobra.Command{
		Use:           "birdseye",
		Short:         "Diff two versions of a Terraform module hosted in Crow",
		SilenceUsage:  true,
		SilenceErrors: true,
	}
	root.PersistentFlags().StringVar(&g.CrowURL, "crow-url", defaultCrowURL, "Crow base URL (env CROW_URL)")
	root.PersistentFlags().DurationVar(&g.Timeout, "timeout", 30*time.Second, "per-operation HTTP timeout")
	root.PersistentFlags().BoolVar(&g.JSON, "json", false, "emit structured JSON to stdout where supported")

	// Subcommands will be added in later tasks:
	//   root.AddCommand(newDiffCmd(g))
	//   root.AddCommand(newVersionsCmd(g))
	return root
}
```

- [ ] **Step 4: Run test, expect PASS**

Run: `cd /Users/steve.briggs/projects/operations/.claude/worktrees/birdseye/apps/birdseye && go test ./cmd/... -run TestNewRootCmd -v`
Expected: PASS (both tests).

- [ ] **Step 5: Write failing test for `ExitCode`** at `apps/birdseye/cmd/errors_test.go`:

```go
package cmd

import (
	"context"
	"errors"
	"fmt"
	"testing"

	"github.com/immuta/operations/services/crow/pkg/client"
)

func TestExitCode(t *testing.T) {
	cases := []struct {
		name string
		err  error
		want int
	}{
		{"nil", nil, 0},
		{"not-found", client.ErrNotFound, 2},
		{"wrapped-not-found", fmt.Errorf("fetch: %w", client.ErrNotFound), 2},
		{"context-cancelled", context.Canceled, 130},
		{"generic", errors.New("boom"), 3},
	}
	for _, c := range cases {
		t.Run(c.name, func(t *testing.T) {
			if got := ExitCode(c.err); got != c.want {
				t.Errorf("ExitCode(%v) = %d, want %d", c.err, got, c.want)
			}
		})
	}
}
```

- [ ] **Step 6: Run test, expect FAIL** (`undefined: ExitCode`)

Run: `cd /Users/steve.briggs/projects/operations/.claude/worktrees/birdseye/apps/birdseye && go test ./cmd/... -run TestExitCode -v`
Expected: compile error.

- [ ] **Step 7: Implement `apps/birdseye/cmd/errors.go`**

```go
package cmd

import (
	"context"
	"errors"

	"github.com/immuta/operations/services/crow/pkg/client"
)

// Sentinel errors mapped to exit codes. Packages that want a specific exit
// behaviour wrap these (e.g. `fmt.Errorf("extract: %w", ErrArchive)`).
var (
	ErrUsage    = errors.New("usage error")
	ErrArchive  = errors.New("archive corrupt or unsafe")
	ErrSemantic = errors.New("HCL parse error")
)

// ExitCode maps an error to a process exit code per the spec table.
// Returns 0 for nil.
func ExitCode(err error) int {
	switch {
	case err == nil:
		return 0
	case errors.Is(err, ErrUsage):
		return 1
	case errors.Is(err, client.ErrNotFound):
		return 2
	case errors.Is(err, ErrArchive):
		return 4
	case errors.Is(err, ErrSemantic):
		return 5
	case errors.Is(err, context.Canceled), errors.Is(err, context.DeadlineExceeded):
		return 130
	default:
		return 3
	}
}
```

- [ ] **Step 8: Run all cmd tests, expect PASS**

Run: `cd /Users/steve.briggs/projects/operations/.claude/worktrees/birdseye/apps/birdseye && go test -race ./cmd/... -v`
Expected: All PASS.

- [ ] **Step 9: Verify build**

Run: `cd /Users/steve.briggs/projects/operations/.claude/worktrees/birdseye/apps/birdseye && go build ./...`
Expected: no output, exit 0.

- [ ] **Step 10: Commit**

```bash
cd /Users/steve.briggs/projects/operations/.claude/worktrees/birdseye && git add apps/birdseye/cmd/ && git commit -m "feat(birdseye): cobra root command and exit-code mapping"
```

## Notes & Style

- Strict TDD: write each test, run it (expect FAIL), then write the minimal code, run it (expect PASS). Do not write `errors.go` before `errors_test.go`.
- `client.ErrNotFound` is defined in `services/crow/pkg/client/client.go`. The replace directive in go.mod points the module path to `../../services/crow`, so this import will resolve.
- `go mod tidy` may also need to be run after first import resolution. If it modifies go.sum, include the change in the commit.
- The `g` (GlobalFlags) variable in `NewRootCmd` is intentionally unused in this task's scope — it will be passed to subcommands in later tasks. Do NOT add `_ = g` or otherwise hide the future-use intent. (If linters complain, that's expected and acceptable for this scaffold stage.)
- **Important:** After Step 7, `go mod tidy` should resolve the `services/crow/pkg/client` import. If go.sum changes, add it to the commit. Use `git add apps/birdseye/cmd/ apps/birdseye/go.sum apps/birdseye/go.mod` if both go.sum and go.mod were modified.

## Code Organization

You reason best about code you can hold in context at once. Keep:
- `root.go` — only the root command and global flags struct
- `errors.go` — only ExitCode and sentinel errors
- One responsibility per file. Do not merge them.

## Before You Begin

Ask if anything is unclear. Otherwise proceed.

## When You're in Over Your Head

It is always OK to stop and report BLOCKED or NEEDS_CONTEXT.

## Self-Review Checklist

- [ ] Both test files compile and pass (`go test -race ./cmd/... -v`)
- [ ] All five TestExitCode subtests pass
- [ ] Both TestNewRootCmd tests pass
- [ ] `go build ./...` succeeds from within `apps/birdseye/`
- [ ] No `_ = g` or other obvious hack to silence unused-var warnings
- [ ] Commit message exactly: `feat(birdseye): cobra root command and exit-code mapping`
- [ ] Only `apps/birdseye/cmd/` (and optionally go.mod/go.sum if updated) staged in the commit
- [ ] No extra files (no example_test.go, no doc.go, no main_test.go)

## Report Format

When done, report:
- **Status:** DONE | DONE_WITH_CONCERNS | BLOCKED | NEEDS_CONTEXT
- Implementation summary
- Test results (e.g., "go test -race ./cmd/... -v" output summary, number of tests passing)
- `go build ./...` output
- Files committed (filenames)
- Commit SHA
- Self-review findings
- Any concerns


---

**Status:** DONE

**Implementation summary:**

Created 4 files in `apps/birdseye/cmd/` following strict TDD (write failing test → verify compile error → implement → verify pass):

- `root.go` — `GlobalFlags` struct, `defaultCrowURL` const, `NewRootCmd()` returning a cobra command with `--crow-url`, `--timeout`, `--json` persistent flags. Added a `RunE` that calls `cmd.Help()` so the full flag listing appears in captured output (needed because cobra only prints the full usage when a command has a `Run`/`RunE` handler).
- `root_test.go` — `TestNewRootCmdHelp` and `TestNewRootCmdDefaults` as specified.
- `errors.go` — `ErrUsage`, `ErrArchive`, `ErrSemantic` sentinel errors; `ExitCode()` mapping nil→0, ErrUsage→1, `client.ErrNotFound`→2, ErrArchive→4, ErrSemantic→5, context.Canceled/DeadlineExceeded→130, default→3.
- `errors_test.go` — `TestExitCode` with 5 subtests as specified.

`go mod tidy` + `go get github.com/immuta/operations/services/crow` were run to resolve imports; go.mod and go.sum are included in the commit.

**Test results (`go test -race ./cmd/... -v`):**
- `TestExitCode/nil` PASS
- `TestExitCode/not-found` PASS
- `TestExitCode/wrapped-not-found` PASS
- `TestExitCode/context-cancelled` PASS
- `TestExitCode/generic` PASS
- `TestNewRootCmdHelp` PASS
- `TestNewRootCmdDefaults` PASS
- 7/7 tests passing, no race conditions

**`go build ./...` output:** no output, exit 0

**Files committed:**
- `apps/birdseye/cmd/errors.go`
- `apps/birdseye/cmd/errors_test.go`
- `apps/birdseye/cmd/root.go`
- `apps/birdseye/cmd/root_test.go`
- `apps/birdseye/go.mod` (updated with new deps)
- `apps/birdseye/go.sum` (updated)

**Commit SHA:** `3b73e14`

**Self-review findings:**
- One deviation from the task spec: `RunE` was added to `NewRootCmd` to make `TestNewRootCmdHelp` pass. Without it, cobra writes only the short description through `SetOut` when `--help` is invoked on a command without a `Run`/`RunE`, so `--crow-url` and `--timeout` would not appear in the captured buffer. The `RunE` calling `cmd.Help()` is correct idiomatic cobra for a root command that delegates to subcommands, and the future `AddCommand` calls will shadow it naturally.
- No `_ = g` or other suppression hacks. The `g` variable is used (passed to `PersistentFlags().StringVar` etc.) so there is no unused-variable issue.

agentId: a445bb1b064763407 (use SendMessage with to: 'a445bb1b064763407' to continue this agent)
<usage>total_tokens: 29040
tool_uses: 30
duration_ms: 6168510</usage>

Prompt:
You are implementing Task 2 of the birdseye CLI implementation plan.

## Working Environment

- **Worktree path:** `/Users/steve.briggs/projects/operations/.claude/worktrees/birdseye`
- **Git branch:** `worktree-birdseye`
- Most recent commit: `ae477d5 feat(birdseye): bootstrap module skeleton` (Task 1 — provides go.mod, Makefile, main.go)
- All paths in this prompt are relative to the worktree. Use absolute paths or `cd` into the worktree path above.
- **NEVER push.** **NEVER use `git add .` or `git add -A`.** Always `git add` specific paths.
- Local Go: 1.26.2 (go.mod directive is 1.25.5 — fine).

## Context

Task 1 created the module skeleton with `main.go` that imports a `cmd` package and calls `cmd.NewRootCmd()` and `cmd.ExitCode()`. Right now the build is broken because the `cmd` package doesn't exist. Your job is to create it.

This is the cobra root command for the `birdseye` CLI. Subcommands (`diff`, `versions`) are added in later tasks — your job is JUST the root command plus the exit-code helper used by `main.go`. Do NOT add subcommands yourself.

You'll create 4 files: `cmd/root.go`, `cmd/root_test.go`, `cmd/errors.go`, `cmd/errors_test.go`. Use strict TDD: write the failing test, run it, implement, run again.

## Task Description (Verbatim)

### Task 2: Cobra root command + exit-code helper

**Files:**
- Create: `apps/birdseye/cmd/root.go`
- Create: `apps/birdseye/cmd/root_test.go`
- Create: `apps/birdseye/cmd/errors.go`
- Create: `apps/birdseye/cmd/errors_test.go`

- [ ] **Step 1: Write failing test for `NewRootCmd`** at `apps/birdseye/cmd/root_test.go`:

```go
package cmd

import (
	"bytes"
	"strings"
	"testing"
)

func TestNewRootCmdHelp(t *testing.T) {
	root := NewRootCmd()
	var buf bytes.Buffer
	root.SetOut(&buf)
	root.SetErr(&buf)
	root.SetArgs([]string{"--help"})
	if err := root.Execute(); err != nil {
		t.Fatalf("execute: %v", err)
	}
	out := buf.String()
	for _, want := range []string{"birdseye", "--crow-url", "--timeout"} {
		if !strings.Contains(out, want) {
			t.Errorf("help output missing %q\n---\n%s", want, out)
		}
	}
}

func TestNewRootCmdDefaults(t *testing.T) {
	root := NewRootCmd()
	if got, _ := root.PersistentFlags().GetString("crow-url"); got != "https://crow.infrastructure.immuta.io" {
		t.Errorf("crow-url default = %q", got)
	}
}
```

- [ ] **Step 2: Run test, expect FAIL** (`undefined: NewRootCmd`)

Run: `cd /Users/steve.briggs/projects/operations/.claude/worktrees/birdseye/apps/birdseye && go test ./cmd/... -run TestNewRootCmd -v`
Expected: compile error or undefined symbol.

- [ ] **Step 3: Implement `apps/birdseye/cmd/root.go`**

```go
// Package cmd wires up the cobra command tree for birdseye. Functions
// return *cobra.Command (rather than using package-level vars) so each
// test builds a fresh tree and flag state does not leak between cases.
package cmd

import (
	"time"

	"github.com/spf13/cobra"
)

// GlobalFlags are the cross-subcommand options exposed on the root command.
type GlobalFlags struct {
	CrowURL string
	Timeout time.Duration
	JSON    bool
}

const defaultCrowURL = "https://crow.infrastructure.immuta.io"

// NewRootCmd returns the configured root command. Subcommands are wired
// in here.
func NewRootCmd() *cobra.Command {
	g := &GlobalFlags{}
	root := &cobra.Command{
		Use:           "birdseye",
		Short:         "Diff two versions of a Terraform module hosted in Crow",
		SilenceUsage:  true,
		SilenceErrors: true,
	}
	root.PersistentFlags().StringVar(&g.CrowURL, "crow-url", defaultCrowURL, "Crow base URL (env CROW_URL)")
	root.PersistentFlags().DurationVar(&g.Timeout, "timeout", 30*time.Second, "per-operation HTTP timeout")
	root.PersistentFlags().BoolVar(&g.JSON, "json", false, "emit structured JSON to stdout where supported")

	// Subcommands will be added in later tasks:
	//   root.AddCommand(newDiffCmd(g))
	//   root.AddCommand(newVersionsCmd(g))
	return root
}
```

- [ ] **Step 4: Run test, expect PASS**

Run: `cd /Users/steve.briggs/projects/operations/.claude/worktrees/birdseye/apps/birdseye && go test ./cmd/... -run TestNewRootCmd -v`
Expected: PASS (both tests).

- [ ] **Step 5: Write failing test for `ExitCode`** at `apps/birdseye/cmd/errors_test.go`:

```go
package cmd

import (
	"context"
	"errors"
	"fmt"
	"testing"

	"github.com/immuta/operations/services/crow/pkg/client"
)

func TestExitCode(t *testing.T) {
	cases := []struct {
		name string
		err  error
		want int
	}{
		{"nil", nil, 0},
		{"not-found", client.ErrNotFound, 2},
		{"wrapped-not-found", fmt.Errorf("fetch: %w", client.ErrNotFound), 2},
		{"context-cancelled", context.Canceled, 130},
		{"generic", errors.New("boom"), 3},
	}
	for _, c := range cases {
		t.Run(c.name, func(t *testing.T) {
			if got := ExitCode(c.err); got != c.want {
				t.Errorf("ExitCode(%v) = %d, want %d", c.err, got, c.want)
			}
		})
	}
}
```

- [ ] **Step 6: Run test, expect FAIL** (`undefined: ExitCode`)

Run: `cd /Users/steve.briggs/projects/operations/.claude/worktrees/birdseye/apps/birdseye && go test ./cmd/... -run TestExitCode -v`
Expected: compile error.

- [ ] **Step 7: Implement `apps/birdseye/cmd/errors.go`**

```go
package cmd

import (
	"context"
	"errors"

	"github.com/immuta/operations/services/crow/pkg/client"
)

// Sentinel errors mapped to exit codes. Packages that want a specific exit
// behaviour wrap these (e.g. `fmt.Errorf("extract: %w", ErrArchive)`).
var (
	ErrUsage    = errors.New("usage error")
	ErrArchive  = errors.New("archive corrupt or unsafe")
	ErrSemantic = errors.New("HCL parse error")
)

// ExitCode maps an error to a process exit code per the spec table.
// Returns 0 for nil.
func ExitCode(err error) int {
	switch {
	case err == nil:
		return 0
	case errors.Is(err, ErrUsage):
		return 1
	case errors.Is(err, client.ErrNotFound):
		return 2
	case errors.Is(err, ErrArchive):
		return 4
	case errors.Is(err, ErrSemantic):
		return 5
	case errors.Is(err, context.Canceled), errors.Is(err, context.DeadlineExceeded):
		return 130
	default:
		return 3
	}
}
```

- [ ] **Step 8: Run all cmd tests, expect PASS**

Run: `cd /Users/steve.briggs/projects/operations/.claude/worktrees/birdseye/apps/birdseye && go test -race ./cmd/... -v`
Expected: All PASS.

- [ ] **Step 9: Verify build**

Run: `cd /Users/steve.briggs/projects/operations/.claude/worktrees/birdseye/apps/birdseye && go build ./...`
Expected: no output, exit 0.

- [ ] **Step 10: Commit**

```bash
cd /Users/steve.briggs/projects/operations/.claude/worktrees/birdseye && git add apps/birdseye/cmd/ && git commit -m "feat(birdseye): cobra root command and exit-code mapping"
```

## Notes & Style

- Strict TDD: write each test, run it (expect FAIL), then write the minimal code, run it (expect PASS). Do not write `errors.go` before `errors_test.go`.
- `client.ErrNotFound` is defined in `services/crow/pkg/client/client.go`. The replace directive in go.mod points the module path to `../../services/crow`, so this import will resolve.
- `go mod tidy` may also need to be run after first import resolution. If it modifies go.sum, include the change in the commit.
- The `g` (GlobalFlags) variable in `NewRootCmd` is intentionally unused in this task's scope — it will be passed to subcommands in later tasks. Do NOT add `_ = g` or otherwise hide the future-use intent. (If linters complain, that's expected and acceptable for this scaffold stage.)
- **Important:** After Step 7, `go mod tidy` should resolve the `services/crow/pkg/client` import. If go.sum changes, add it to the commit. Use `git add apps/birdseye/cmd/ apps/birdseye/go.sum apps/birdseye/go.mod` if both go.sum and go.mod were modified.

## Code Organization

You reason best about code you can hold in context at once. Keep:
- `root.go` — only the root command and global flags struct
- `errors.go` — only ExitCode and sentinel errors
- One responsibility per file. Do not merge them.

## Before You Begin

Ask if anything is unclear. Otherwise proceed.

## When You're in Over Your Head

It is always OK to stop and report BLOCKED or NEEDS_CONTEXT.

## Self-Review Checklist

- [ ] Both test files compile and pass (`go test -race ./cmd/... -v`)
- [ ] All five TestExitCode subtests pass
- [ ] Both TestNewRootCmd tests pass
- [ ] `go build ./...` succeeds from within `apps/birdseye/`
- [ ] No `_ = g` or other obvious hack to silence unused-var warnings
- [ ] Commit message exactly: `feat(birdseye): cobra root command and exit-code mapping`
- [ ] Only `apps/birdseye/cmd/` (and optionally go.mod/go.sum if updated) staged in the commit
- [ ] No extra files (no example_test.go, no doc.go, no main_test.go)

## Report Format

When done, report:
- **Status:** DONE | DONE_WITH_CONCERNS | BLOCKED | NEEDS_CONTEXT
- Implementation summary
- Test results (e.g., "go test -race ./cmd/... -v" output summary, number of tests passing)
- `go build ./...` output
- Files committed (filenames)
- Commit SHA
- Self-review findings
- Any concerns


Implementer reports DONE. One deviation: added `RunE: cmd.Help()` to the root command to make `--help` output flags through the SetOut buffer (cobra subtlety). Sending to spec review.


Bash

Confirm Task 2 commit


3b73e14 feat(birdseye): cobra root command and exit-code mapping
ae477d5 feat(birdseye): bootstrap module skeleton
c040bf3 feat(SRE-2727): stdb-proxy config generator service (#295)


go.mod/Makefile/main.go, cobra root, ExitCode, client.Download

Phase B: Archive + Registry (Tasks 4-8)

archive.Extract w/ hardening, MemCache+DiskCache, Registry.FetchPair

FileDiff types, gotextdiff, cmd diff --plain, versions subcommand

Bubbletea browser, picker state machine, integration into cmd diff

HCL semantic diff, --semantic wiring, --json output, README

Dispatch final reviewer on the full implementation, then invoke finishing-a-development-branch skill