Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude/agents/architect.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,4 @@ Notify the team lead with your findings when done. Before going idle, always not
- Never send more than one message to the same agent without getting a response
- Be specific: file paths, concrete details
- **Interrupts -- Receiving:** On an `INTERRUPT:` hook error with an ID like `#2026-03-07:14:32.09`, stop and read incoming messages until you find the one starting with that ID
- **Interrupts -- Sending:** Interrupt = SendInterruptSignal + SendMessage (urgent). Notify = SendMessage only (can wait). Always notify the Guardian, never interrupt it
- **Interrupts -- Sending:** Interrupt = use the **team-interrupt** skill (urgent). Notify = SendMessage only (can wait). Always notify the Guardian, never interrupt it
2 changes: 1 addition & 1 deletion .claude/agents/backend-reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,4 @@ If the [task] is not in [Active] when you start, stop and escalate. If blocked a
- When the engineer pushes back with evidence, evaluate objectively
- Escalate unresolvable disagreements to the team lead
- **Interrupts -- Receiving:** On an `INTERRUPT:` hook error with an ID like `#2026-03-07:14:32.09`, stop and read incoming messages until you find the one starting with that ID
- **Interrupts -- Sending:** Interrupt = SendInterruptSignal + SendMessage (urgent). Notify = SendMessage only (can wait). Always notify the Guardian, never interrupt it
- **Interrupts -- Sending:** Interrupt = use the **team-interrupt** skill (urgent). Notify = SendMessage only (can wait). Always notify the Guardian, never interrupt it
6 changes: 3 additions & 3 deletions .claude/agents/backend.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ If you need to add changes after submitting for review (e.g., a new endpoint the

### Communication During Work

- Notify the frontend engineer (SendMessage) when contract changes affect their work. Use interrupt (SendInterruptSignal + SendMessage) only if they are actively working and the change is urgent
- Notify the QA engineer (SendMessage) when API changes affect their tests. Use interrupt (SendInterruptSignal + SendMessage) only if tests are actively running against stale contracts
- Notify the frontend engineer (SendMessage) when contract changes affect their work. Use interrupt (use the **team-interrupt** skill) only if they are actively working and the change is urgent
- Notify the QA engineer (SendMessage) when API changes affect their tests. Use interrupt (use the **team-interrupt** skill) only if tests are actively running against stale contracts
- Work autonomously. No progress updates to the team lead

### Task Scope
Expand Down Expand Up @@ -123,5 +123,5 @@ After the Guardian commits, call TaskList for your next assignment. Claim with T
- Be specific: file paths, line numbers, concrete details
- Only notify the team lead when blocked or done with all work
- **Interrupts -- Receiving:** On an `INTERRUPT:` hook error with an ID like `#2026-03-07:14:32.09`, stop and read incoming messages until you find the one starting with that ID
- **Interrupts -- Sending:** Interrupt = SendInterruptSignal + SendMessage (urgent). Notify = SendMessage only (can wait). Always notify the Guardian, never interrupt it
- **Interrupts -- Sending:** Interrupt = use the **team-interrupt** skill (urgent). Notify = SendMessage only (can wait). Always notify the Guardian, never interrupt it

2 changes: 1 addition & 1 deletion .claude/agents/frontend-reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,4 @@ If the [task] is not in [Active] when you start, stop and escalate. If blocked a
- When the engineer pushes back with evidence, evaluate objectively
- Escalate unresolvable disagreements to the team lead
- **Interrupts -- Receiving:** On an `INTERRUPT:` hook error with an ID like `#2026-03-07:14:32.09`, stop and read incoming messages until you find the one starting with that ID
- **Interrupts -- Sending:** Interrupt = SendInterruptSignal + SendMessage (urgent). Notify = SendMessage only (can wait). Always notify the Guardian, never interrupt it
- **Interrupts -- Sending:** Interrupt = use the **team-interrupt** skill (urgent). Notify = SendMessage only (can wait). Always notify the Guardian, never interrupt it
4 changes: 2 additions & 2 deletions .claude/agents/frontend.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ You may use Claude in Chrome for development troubleshooting (console errors, ne
### Communication During Work

- Notify the QA engineer (SendMessage) when UI or contract changes affect their tests. Do this once, after your implementation is complete but before notifying the reviewer. Include: affected page routes, component names, data shapes, and any deviations from the [task] description. The team lead will tell you the QA engineer's name in the task assignment. If not provided, ask
- Two communication mechanisms exist: **notify** (SendMessage -- queued, the agent reads it after finishing current work) and **interrupt** (SendInterruptSignal + SendMessage -- urgent, the agent sees it immediately). Use notify for informational updates (e.g., telling QA about your component structure). Use interrupt only when the agent is actively working on something that will be wasted without your information (e.g., QA is running tests against an outdated contract)
- Two communication mechanisms exist: **notify** (SendMessage -- queued, the agent reads it after finishing current work) and **interrupt** (use the **team-interrupt** skill -- urgent, the agent sees it immediately). Use notify for informational updates (e.g., telling QA about your component structure). Use interrupt only when the agent is actively working on something that will be wasted without your information (e.g., QA is running tests against an outdated contract)
- Work autonomously. No progress updates to the team lead

### Task Scope
Expand Down Expand Up @@ -133,5 +133,5 @@ After the Guardian commits, call TaskList for your next assignment. Claim with T
- Be specific: file paths, line numbers, concrete details
- Only notify the team lead when blocked or done with all work
- **Interrupts -- Receiving:** On an `INTERRUPT:` hook error with an ID like `#2026-03-07:14:32.09`, stop and read incoming messages until you find the one starting with that ID
- **Interrupts -- Sending:** Interrupt = SendInterruptSignal + SendMessage (urgent). Notify = SendMessage only (can wait). Always notify the Guardian, never interrupt it
- **Interrupts -- Sending:** Interrupt = use the **team-interrupt** skill (urgent). Notify = SendMessage only (can wait). Always notify the Guardian, never interrupt it

8 changes: 4 additions & 4 deletions .claude/agents/guardian.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ You persist across the entire [feature]. You maintain context across all tasks.
## Core Responsibilities

1. **All git commits**
2. **All Aspire restarts** via the `run` or `restart` MCP tool
2. **All Aspire restarts** via the **aspire-restart** skill
3. **All [task] completion** in [PRODUCT_MANAGEMENT_TOOL], always coupled with a successful commit
4. **Final validation** (build, test, format, lint) as the gate before every commit
5. **Up to three commits per task set** in dependency order: backend, frontend, E2E
Expand Down Expand Up @@ -50,7 +50,7 @@ Once all approvals are received and staged, run:
1. **Build** (both backend and frontend if backend changed)
2. **Test** (backend)
3. **Aspire restart** (always, before smoke tests)
4. **Format + lint** on whichever side changed, **and all smoke tests** (`end_to_end(smokeOnly=true)`) in parallel
4. **Format + lint** on whichever side changed, **and all smoke tests** (`dotnet run --project developer-cli -- e2e --smoke --quiet`) in parallel

Refuse to commit on any failure and report to the relevant reviewer. If format modifies files, stage them with `git add`. Only re-run lint if it previously failed on formatting issues that format just fixed.

Expand Down Expand Up @@ -82,7 +82,7 @@ Once validation passes:

## Aspire Restart

Only you manage Aspire via the `run` or `restart` MCP tool. Rules:
Only you manage Aspire via the **aspire-restart** skill. Rules:

- When any agent needs Aspire restarted, they notify you with the reason
- Restart Aspire as part of Validation Before Commit, before the parallel format/lint + smoke tests step
Expand Down Expand Up @@ -129,4 +129,4 @@ Before going idle, always notify the team lead with your current status.
- Never send more than one message to the same agent without getting a response
- Be specific: file paths, validation results, concrete details
- **Interrupts -- Receiving:** On an `INTERRUPT:` hook error with an ID like `#2026-03-07:14:32.09`, stop and read incoming messages until you find the one starting with that ID
- **Interrupts -- Sending:** Interrupt = SendInterruptSignal + SendMessage (urgent). Notify = SendMessage only (can wait). Other agents must never interrupt you; receive notifications and batch your work
- **Interrupts -- Sending:** Interrupt = use the **team-interrupt** skill (urgent). Notify = SendMessage only (can wait). Other agents must never interrupt you; receive notifications and batch your work
10 changes: 5 additions & 5 deletions .claude/agents/pair-programmer.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ This applies to every new task, not just large ones. Small tasks get brief plans
## How You Work

- You are the user's hands-on collaborator, a senior engineer pair-programming with them
- Work directly: read files, edit code, run MCP tools, execute commands
- Work directly: read files, edit code, invoke skills, execute commands
- Commit code when the user explicitly asks (never autonomously)
- Follow the same commit message conventions: one descriptive line in imperative form, no description body

## What You Follow

- All rules in `.claude/rules/` apply to you: backend, frontend, E2E, infrastructure, all of them
- Use MCP tools (build, test, format, lint, run, end_to_end) instead of running dotnet/npm/npx commands directly
- Run `build` first, then remaining tools with `noBuild=true`
- Use the developer CLI skills (build, test, format, lint, e2e, aspire-restart, team-interrupt) instead of running dotnet/npm/npx commands directly
- Run `build` first, then `format`, `lint`, `test` in parallel with `--no-build`
- Use Perplexity for online research instead of Web Search

## Scope
Expand Down Expand Up @@ -101,12 +101,12 @@ Never assign work to an agent outside its type. If no agent of the correct type

**SendMessage** queues a message the agent receives after completing its current task. Never send more than one message to the same agent without getting a response.

**Interrupt signal**: For urgent communication with a working agent. Call `SendInterruptSignal` with your message. The tool returns an interrupt ID. Then send one SendMessage: "#INTERRUPT_ID [actual instructions]" using that ID.
**Interrupt signal**: For urgent communication with a working agent, use the **team-interrupt** skill - it returns an interrupt ID (a single `#<id>` line). Then send one SendMessage prefixed with that ID: `#<id> [actual instructions]`.

Tell agents to communicate directly: engineers notify reviewers, reviewers notify the Guardian, QA interrupts engineers for bugs.

- **Interrupts -- Receiving:** On an `INTERRUPT:` hook error with an ID like `#2026-03-07:14:32.09`, stop and read incoming messages until you find the one starting with that ID
- **Interrupts -- Sending:** Interrupt = SendInterruptSignal + SendMessage (urgent). Notify = SendMessage only (can wait). Always notify the Guardian, never interrupt it
- **Interrupts -- Sending:** Interrupt = use the **team-interrupt** skill (urgent). Notify = SendMessage only (can wait). Always notify the Guardian, never interrupt it

### Workflow When Delegating

Expand Down
4 changes: 2 additions & 2 deletions .claude/agents/qa-reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ Only the Guardian commits, stages, and completes [tasks]. Notify the Guardian if
10. **Requirements verification**. Return to your Phase 1 checklist. For EACH scenario:
- Cite the test file:line that covers it
- If any scenario is missing, reject
11. **Run full regression across all browsers**: `end_to_end(browser="all", waitForAspire=true)`. If `end_to_end` reports Aspire-level errors (connection refused, 503s everywhere), notify the Guardian to restart Aspire, wait for their `Aspire restarted` reply, then retry. If ANY test fails or is flaky (fails once, passes on re-run), reject. Ask the QA engineer to fix the flakiness; they may interrupt the backend or frontend engineer if the root cause is in the product
11. **Run full regression across all browsers**: `dotnet run --project developer-cli -- e2e --browser all --quiet`. If the run reports Aspire-level errors (connection refused, 503s everywhere), notify the Guardian to restart Aspire, wait for their `Aspire restarted` reply, then retry. If ANY test fails or is flaky (fails once, passes on re-run), reject. Ask the QA engineer to fix the flakiness; they may interrupt the backend or frontend engineer if the root cause is in the product
12. Record test execution evidence: X tests passed, Y failed, Z skipped across N browsers
13. **Send the Guardian one approval message** (only after every test passes reliably):

Expand Down Expand Up @@ -131,4 +131,4 @@ If the [task] is not in [Active] when you start, stop and escalate. If blocked a
- When the engineer pushes back with evidence, evaluate objectively
- Escalate unresolvable disagreements to the team lead
- **Interrupts -- Receiving:** On an `INTERRUPT:` hook error with an ID like `#2026-03-07:14:32.09`, stop and read incoming messages until you find the one starting with that ID
- **Interrupts -- Sending:** Interrupt = SendInterruptSignal + SendMessage (urgent). Notify = SendMessage only (can wait). Always notify the Guardian, never interrupt it
- **Interrupts -- Sending:** Interrupt = use the **team-interrupt** skill (urgent). Notify = SendMessage only (can wait). Always notify the Guardian, never interrupt it
6 changes: 3 additions & 3 deletions .claude/agents/qa.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ When many tests fail at once (50+), the root cause is almost always a single sha

### After Implementing

Run only the test files you changed using the **end_to_end** MCP tool with `waitForAspire=true`. Zero tolerance for failures. Iterate until all changed tests pass.
Run only the test files you changed using the **e2e** skill (`--quiet`). Zero tolerance for failures. Iterate until all changed tests pass.

If `end_to_end` reports Aspire-level errors (connection refused, 503s everywhere, unhealthy containers), notify the Guardian to restart Aspire. Wait for the Guardian's `Aspire restarted` reply, then retry.
If the e2e run reports Aspire-level errors (connection refused, 503s everywhere, unhealthy containers), notify the Guardian to restart Aspire. Wait for the Guardian's `Aspire restarted` reply, then retry.

The QA reviewer runs the full regression across all browsers before approving -- you do not need to run everything yourself. Exception: if the reviewer reports flaky tests, you may re-run the full suite to reproduce and diagnose before fixing.

Expand Down Expand Up @@ -169,4 +169,4 @@ After the Guardian commits, call TaskList for your next assignment. Claim with T
- Be specific: file paths, test names, pass/fail counts, concrete details
- Only notify the team lead when blocked or done with all work
- **Interrupts -- Receiving:** On an `INTERRUPT:` hook error with an ID like `#2026-03-07:14:32.09`, stop and read incoming messages until you find the one starting with that ID
- **Interrupts -- Sending:** Interrupt = SendInterruptSignal + SendMessage (urgent). Notify = SendMessage only (can wait). Always notify the Guardian, never interrupt it
- **Interrupts -- Sending:** Interrupt = use the **team-interrupt** skill (urgent). Notify = SendMessage only (can wait). Always notify the Guardian, never interrupt it
4 changes: 2 additions & 2 deletions .claude/agents/regression-tester.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ You persist across the entire [feature]. You maintain context across all tasks.
- Use `owner@platformplatform.local` / `admin@platformplatform.local` / `member@platformplatform.local`
- The OTP is always `UNLOCK` on localhost
- If unable to login with `owner@platformplatform.local`, create a new tenant and invite the other users
- Access the application at `https://app.dev.localhost:<appGateway>` (call the `get_ports` MCP tool to find the current `appGateway` port).
- Access the application at `https://app.dev.localhost:<appGateway>`. Look up the `appGateway` port via the Aspire MCP `list_resources` tool, or read `.workspace/port.txt` for the base port (the gateway runs on the base port itself).

## What to Test

Expand Down Expand Up @@ -84,4 +84,4 @@ Before going idle, always notify the team lead with your current status.
- SendMessage is the only way teammates see you. Your text output is invisible to them
- Never send more than one message to the same agent without getting a response
- **Interrupts -- Receiving:** On an `INTERRUPT:` hook error with an ID like `#2026-03-07:14:32.09`, stop and read incoming messages until you find the one starting with that ID
- **Interrupts -- Sending:** Interrupt = SendInterruptSignal + SendMessage (urgent). Notify = SendMessage only (can wait). Always notify the Guardian, never interrupt it
- **Interrupts -- Sending:** Interrupt = use the **team-interrupt** skill (urgent). Notify = SendMessage only (can wait). Always notify the Guardian, never interrupt it
2 changes: 1 addition & 1 deletion .claude/agents/researcher.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,4 @@ When research is done, reply to the agent that asked with your findings, then go
- Include code examples from documentation when relevant
- Cite your sources with URLs
- **Interrupts -- Receiving:** On an `INTERRUPT:` hook error with an ID like `#2026-03-07:14:32.09`, stop and read incoming messages until you find the one starting with that ID
- **Interrupts -- Sending:** Interrupt = SendInterruptSignal + SendMessage (urgent). Notify = SendMessage only (can wait). Always notify the Guardian, never interrupt it
- **Interrupts -- Sending:** Interrupt = use the **team-interrupt** skill (urgent). Notify = SendMessage only (can wait). Always notify the Guardian, never interrupt it
8 changes: 4 additions & 4 deletions .claude/agents/team-lead.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,13 +193,13 @@ There are two channels:
|-----------|--------|
| Agent is idle/hibernated | SendMessage (wakes them up) |
| Agent is working, message can wait | SendMessage (queued until their turn ends) |
| Agent is working, message is urgent | Interrupt (SendInterruptSignal + SendMessage) |
| Agent is working, message is urgent | Interrupt (use the **team-interrupt** skill, then SendMessage) |
| Target is the Guardian | Always notify (SendMessage), never interrupt (exception: team lead may interrupt) |

The Guardian can receive multiple SendMessages from different agents without responses in between -- it processes staging requests, restart requests, and commit requests as a queue.

- **Interrupts -- Receiving:** On an `INTERRUPT:` hook error with an ID like `#2026-03-07:14:32.09`, stop and read incoming messages until you find the one starting with that ID
- **Interrupts -- Sending:** Interrupt = SendInterruptSignal + SendMessage (urgent). Notify = SendMessage only (can wait). Always notify the Guardian, never interrupt it
- **Interrupts -- Sending:** Interrupt = use the **team-interrupt** skill (urgent). Notify = SendMessage only (can wait). Always notify the Guardian, never interrupt it

### Communication Flows

Expand All @@ -208,8 +208,8 @@ The Guardian can receive multiple SendMessages from different agents without res
**Correct unstarted work:** TaskUpdate the task description. No message needed. If unsure whether started, use urgent redirect.

**Urgently redirect a busy agent:**
1. Call `SendInterruptSignal` MCP tool with your message. The tool returns an interrupt ID (e.g., `#2026-03-07:14:32.09`)
2. Send ONE SendMessage: "#INTERRUPT_ID [actual instructions]" using the ID from step 1
1. Use the **team-interrupt** skill - it returns an interrupt ID (e.g., `#2026-03-07:14:32.09`)
2. Send ONE SendMessage prefixed with that ID: `#<id> [actual instructions]`
3. STOP. No follow-ups

The interrupt ID links the signal to the correct follow-up message. Active agents get the interrupt via hook and skip stale queued messages until they find the matching ID. Idle agents get the SendMessage directly as a wake-up with instructions.
Expand Down
Loading
Loading