17 added, 1 removed. Audit A to A.
---
description: "When executing session plan waves via /go command — task sequencing, quality checks, progress tracking"
globs: ""
alwaysApply: false
---
# Wave Execution (Cursor Adaptation)
> **CRITICAL**: Cursor does NOT have an `Agent()` tool. All wave tasks execute **sequentially in the current Composer session**. You are both the coordinator AND the implementer. Agent dispatch (3-tier resolution: project > plugin > general-purpose) is NOT applicable — follow the role's agent-prompt patterns directly.
> **State directory**: All state files live in `.cursor/` (STATE.md, wave-scope.json).
## Pre-Execution
Before starting Wave 1:
1. `git status --short` — commit or stash any uncommitted changes
2. Capture baseline: `SESSION_START_REF=$(git rev-parse HEAD)` — keep for the whole session
3. Confirm the agreed plan is still valid
4. Read `persistence` from Session Config (default: `true`)
### Initialize STATE.md (if persistence enabled)
Create `.cursor/STATE.md` (`mkdir -p .cursor` if needed):
```yaml
---
schema-version: 1
session-type: feature|deep|housekeeping
branch: <current branch>
issues: [<issue numbers from plan>]
started_at: <ISO 8601 timestamp>
status: active
current-wave: 0
total-waves: <from session plan>
---
```
```markdown
## Current Wave
Wave 0 — Initializing
## Wave History
(none yet)
## Deviations
(none yet)
```
## Wave Loop
For each wave in the session plan:
### Step 1: Write Scope Manifest
Write `.cursor/wave-scope.json` before each wave. Set `enforcement: warn` — Cursor's afterFileEdit hook is post-hoc (warns only, cannot block):
```json
{
"wave": 1,
"role": "<role>",
"enforcement": "warn",
"allowedPaths": ["<union of all task file scopes for this wave>"],
"blockedCommands": ["rm -rf", "git push --force", "DROP TABLE", "git reset --hard", "git checkout -- ."]
}
```
Role-specific scope rules:
- **Discovery**: `allowedPaths: []` — READ-ONLY, do not edit files
- **Quality Phase 1 (Simplification)**: production files changed this session only (no test files)
- **Quality Phase 2 (Tests)**: test file patterns only (`**/*.test.*`, `**/*.spec.*`, `**/__tests__/**`)
- Validate with: `bash "$CURSOR_RULES_DIR/../scripts/validate-wave-scope.sh"` — fix JSON if it exits 1.
+ **Test-sibling expansion (#970):** a scope entry naming a production file but not its test sibling makes the task's own regression test unwritable — the guard then enforces exactly the inconsistency the quality gate exists to catch. Before writing `allowedPaths`, expand the union through the shared helper — do not hand-derive the paths:
+
+ ```js
+ import { expandTestSiblings } from '$CURSOR_RULES_DIR/../scripts/lib/scope-gate.mjs';
+ // Pass this wave's role verbatim — the helper GATES on it.
+ const allowedPaths = expandTestSiblings(unionScopes, { role });
+ ```
+
+ It emits a **glob** from the production basename (`foo.mjs` → `tests/**/foo*.test.mjs`), skips absolute entries, and is a strict no-op on Discovery's `[]`. **Which roles it fires for is decided inside the helper** — `TEST_SIBLING_EXPANSION_ROLES` in `scripts/lib/scope-gate.mjs` (currently Impl-Core / Impl-Polish; Quality Phase 1 is off, Phase 2 inert). Pass the role; do not pre-filter by role here. An absent or unrecognised role does **not** expand (fail-closed). Expand before the overlap check and before the file is written, in one pass. Full rule, the measured hit-rate and its ~15% residual, and the per-repo configurability: `skills/wave-executor/wave-loop.md` § Scope Manifest #3.
+
+ Validate with: `node "$CURSOR_RULES_DIR/../scripts/validate-wave-scope.mjs" < .cursor/wave-scope.json` — fix JSON if it exits 1. Before each task batch, also assert the task's file scope against the manifest, carrying the mechanical half of the rule above (gated on the manifest's `role`, so it self-skips where expansion does not fire):
+
+ ```bash
+ node "$CURSOR_RULES_DIR/../scripts/validate-wave-scope.mjs" \
+ --assert-subset "$TASK_FILESCOPE_JSON" --expand-test-siblings \
+ < .cursor/wave-scope.json
+ ```
### Step 2: Execute Tasks Sequentially
For each task in the wave:
1. Read the task description and acceptance criteria
2. Implement the task fully (you are the implementer)
3. Report status after each task:
```
Task "[description]": done|partial|failed — [1-line summary]
```
4. If stuck, note the blocker and move to the next task
**DO NOT commit during wave execution** — `/close` handles commits.
### Step 3: Run Incremental Quality Checks
After ALL tasks in the wave complete:
| Role | Quality check |
|------|--------------|
| Discovery | None (read-only) |
| Impl-Core | typecheck + test changed files |
| Impl-Polish | typecheck + test changed files + integration verification |
| Quality | Full Gate: typecheck + test + lint — all must pass |
| Finalization | `git status` — verify clean state |
### Step 4: Quality Wave — Simplification Pass
At the START of the Quality wave, before running tests:
1. `git diff --name-only $SESSION_START_REF..HEAD` — list files changed this session
2. Filter to production files (exclude `*.test.*`, `*.spec.*`, `__tests__/`). If none, skip.
3. Review each production file for AI-generated patterns and apply targeted cleanup:
- Remove unnecessary try-catch around non-throwing operations
- Delete over-documentation (params that restate the name, returns that say "the result")
- Replace re-implemented stdlib functions with standard alternatives
- Simplify redundant boolean logic (if/else returning true/false, double negation)
- **Do NOT change functionality**
4. After simplification, run Full Gate quality checks (typecheck + test + lint)
**Note:** Session-reviewer cannot be dispatched as a subagent on Cursor. Quality review is deferred to session-end Phase 1.8. In-wave quality relies on incremental checks + this simplification pass.
### Step 5: Update STATE.md (if persistence enabled)
After each wave:
1. **Frontmatter**: update `current-wave` to the completed wave number
2. **`## Current Wave`**: replace with next wave info
3. **`## Wave History`**: append:
```
### Wave N — <Role>
- Task "[description]": done|partial|failed — [files changed] — [1-line note]
```
4. **`## Deviations`**: if plan was adapted, append:
```
- [<ISO timestamp>] Wave N: <what changed and why>
```
### Step 6: Capture Wave Metrics (if persistence enabled)
Record after each wave:
- `wave_number`, `role`, `agent_count` (always 1 on Cursor), `files_changed`
- Per-task results: `{description, status: done|partial|failed}`
- `quality_check`: pass/fail/skipped
This data is written to `.orchestrator/metrics/sessions.jsonl` by session-end.
### Step 7: Report Wave Status
```
## Wave [N] ([Role]) Complete
- Task 1: [done/partial/failed] — [1-line summary]
- Task 2: [done/partial/failed] — [1-line summary]
- Tests: [passing/failing] | TypeScript: [0 errors / N errors]
- Adaptations for Wave [N+1] ([NextRole]): [none / list changes]
```
### Step 8: Adapt Plan (if needed)
- **On track**: proceed to next wave as planned
- **Minor issues**: add fix tasks to the next wave
- **Major blocker**: STOP — inform the user, propose revised plan
- **Scope change**: document WHY, adjust remaining waves, inform user
## Agent-Mapping Config (Reference Only)
If Session Config includes `agent-mapping`, use it to determine which role's prompt patterns to follow for each task type (e.g., `db-specialist` patterns for DB tasks). On Cursor this is reference only — no actual agent dispatch occurs.
## Circuit Breaker
**If the same error appears 3+ times:**
1. STOP immediately
2. Report:
```
CIRCUIT BREAKER: Stuck on [error description].
Attempted [N] times. Same error persists.
Options:
1. Narrow scope and retry with a different approach
2. Skip this task and continue with remaining waves
3. Abort session
```
3. Wait for user decision
**Spiral indicators**: same file edited 3+ times without progress, same error repeating, reverting own changes.
## Session Type Behavior
| Type | Behavior |
|------|----------|
| Housekeeping | Serial tasks, no wave-scope.json, Baseline QC at end, single commit via /close |
| Feature | Full 5-role wave execution, incremental QC |
| Deep | Full 5-role wave execution, extra emphasis on Discovery and Quality roles |
## Completion
After the final (Finalization) wave:
1. Delete `.cursor/wave-scope.json`
2. Report final status to the user
3. Suggest running `/close` — do NOT auto-commit
## Error Recovery
| Situation | Action |
|-----------|--------|
| Tests fail after wave | Diagnose and fix, don't skip |
| TypeScript errors introduced | Track count, fix by Quality wave |
| New critical issue discovered | Inform user, add to remaining waves if in scope |
| Edits to wrong files | Revert via git, redo with correct scope |
| Stuck in loop | Trigger circuit breaker (see above) |
## Anti-Patterns
- **NEVER** skip inter-wave review — quality degrades exponentially
- **NEVER** commit during wave execution — `/close` handles that
- **NEVER** continue to next wave with unresolved failures
- **NEVER** execute without reporting progress to the user
- **NEVER** modify files outside the wave's `allowedPaths`