@ludecker/aaac 1.1.5 → 1.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/README.md +27 -12
  2. package/package.json +1 -1
  3. package/src/cli.mjs +19 -7
  4. package/src/generators/generate-commands.mjs +25 -1
  5. package/src/generators/generate-graph.mjs +9 -1
  6. package/src/lib/install.mjs +13 -1
  7. package/src/lib/sweep-project-docs.mjs +348 -0
  8. package/src/run-engine/advance-phase.mjs +23 -0
  9. package/src/run-engine/gate-write.mjs +13 -0
  10. package/src/run-engine/lib.mjs +153 -5
  11. package/templates/cursor/aaac/enforcement.json +14 -4
  12. package/templates/cursor/aaac/graph.project.yaml +16 -5
  13. package/templates/cursor/aaac/lifecycle/lifecycle.json +12 -0
  14. package/templates/cursor/aaac/lifecycle/phases.json +2 -0
  15. package/templates/cursor/aaac/scripts/run-engine/advance-phase.mjs +23 -0
  16. package/templates/cursor/aaac/scripts/run-engine/gate-write.mjs +13 -0
  17. package/templates/cursor/aaac/scripts/run-engine/lib.mjs +153 -5
  18. package/templates/cursor/agents/doc-conformance.md +25 -0
  19. package/templates/cursor/agents/implementation-review.md +21 -0
  20. package/templates/cursor/agents/test-author.md +27 -0
  21. package/templates/cursor/rules/aaac-enforcement.mdc +10 -3
  22. package/templates/cursor/skills/shared/execution/SKILL.md +7 -3
  23. package/templates/cursor/skills/shared/governance/implementation/SKILL.md +396 -28
  24. package/templates/cursor/skills/shared/implementation-review/SKILL.md +49 -0
  25. package/templates/cursor/skills/shared/planning/SKILL.md +5 -0
  26. package/templates/cursor/skills/shared/test-authoring/SKILL.md +58 -0
  27. package/templates/cursor/skills/shared/testing/SKILL.md +6 -0
  28. package/templates/cursor/skills/shared/verbs/create/orchestrator/SKILL.md +5 -3
  29. package/templates/cursor/skills/shared/verbs/fix/orchestrator/SKILL.md +5 -3
  30. package/templates/cursor/skills/shared/verbs/update/orchestrator/SKILL.md +5 -3
  31. package/templates/cursor/skills/shared/verification/SKILL.md +5 -3
  32. package/templates/docs/agentic_architecture.md +168 -97
@@ -19,7 +19,7 @@ Every AAAC slash command (`/fix-module`, `/update-module`, `/write-article`, …
19
19
  | Hook | Effect |
20
20
  |------|--------|
21
21
  | `beforeSubmitPrompt` | Detects `/command` → creates Run scoped to **`conversation_id`** (this chat only) |
22
- | `preToolUse` | **Denies** Write/StrReplace/Delete for **this chat only** until execute phase |
22
+ | `preToolUse` | **Denies** edits outside allowed phases; **phase-scoped paths** — `execute` = prod only, `test_execute` = tests only |
23
23
  | `subagentStart` | Counts Task launches for swarm phase validation |
24
24
  | `stop` | Follow-up if Run not `completed` |
25
25
 
@@ -34,12 +34,19 @@ Every AAAC slash command (`/fix-module`, `/update-module`, `/write-article`, …
34
34
  - `discover`: 4 Task agents (check verbs: `check_swarm` 3)
35
35
  - `investigate_swarm`: 7 Task agents
36
36
  - `research_swarm`: 6 Task agents
37
- 4. **Verify gate (create / update / fix):** before advancing past `verify`, run:
37
+ - `test_execute`: 1 test-author Task agent (mutating verbs)
38
+ - `verify`: 3 Task agents (all create/update/fix — not fix-only)
39
+ - `review_swarm`: 3 readonly reviewers (mutating verbs)
40
+ 4. **Agent separation (mutating verbs):**
41
+ - **Writer** — parent in `execute` only (no test files)
42
+ - **Tester** — test-author subagent in `test_execute` only
43
+ - **Reviewer** — readonly swarm in `review_swarm` (not the execute agent)
44
+ 5. **Verify gate (create / update / fix):** before advancing past `verify`, run:
38
45
  ```bash
39
46
  node .cursor/aaac/scripts/run-engine/verify-website-build.mjs --run-id <run_id>
40
47
  ```
41
48
  `advance-phase.mjs verify` runs this automatically and blocks on missing static assets or failed `vite build` (catches favicon/path regressions).
42
- 5. **Code edits only in `execute`** (hook-enforced). Before execute: artifacts only under `.cursor/aaac/state/runs/`.
49
+ 5. **Edits:** prod code in `execute`; test files in `test_execute` only. Run artifacts under `.cursor/aaac/state/runs/` anytime.
43
50
  6. **Complete the Run** — advance through `report`, set status completed.
44
51
 
45
52
  ## If edit is denied
@@ -15,18 +15,22 @@ Orchestrator phase `execute` after approved plan.
15
15
  ## Mandatory
16
16
 
17
17
  1. Read [governance/implementation/SKILL.md](../governance/implementation/SKILL.md)
18
- 2. Read domain inventory when present (`domains/<slug>/update/inventory/`)
18
+ 2. Read domain [inventory](../../../domains/) constraints
19
19
  3. Read [policies/](../../../policies/)
20
20
 
21
21
  ## Actions
22
22
 
23
- - Edit files per plan and implementation skill
24
- - Apply database migrations via configured MCP when your project uses one (see [mcp-and-deploy.md](../../../policies/mcp-and-deploy.md) and `{{DOCS_ROOT}}/project_context.md`)
23
+ - Edit **production/source** files per plan and implementation skill
24
+ - **Do not** create or edit test files (`*.test.*`, `*.spec.*`, `__tests__/`) deferred to `test_execute` / [test-authoring](../test-authoring/SKILL.md)
25
+ - `apply_migration` for new/changed `supabase/migrations/` (project `anseivwusnyiwopihnqu` — see [supabase-mcp.mdc](../../../rules/supabase-mcp.mdc))
26
+ - `track()` for user-facing mutations
25
27
  - Structured logging on server async paths
26
28
 
27
29
  ## Must not
28
30
 
29
31
  - Invent plan during execution
32
+ - Write or edit test files (hooks block in `execute`; use `test_execute`)
33
+ - Self-review implementation (use [implementation-review](../implementation-review/SKILL.md) in `review_swarm`)
30
34
  - Race guards or useEffect-driven mutations (implementation ban)
31
35
  - Skip schema validation at boundaries
32
36
 
@@ -1,56 +1,424 @@
1
1
  ---
2
2
  name: implementation
3
- description: Enforces project master rules and architecture when implementing code. Read {{DOCS_ROOT}}/master_rules.md, {{DOCS_ROOT}}/ui_design.md (UI/CSS), {{DOCS_ROOT}}/project_context.md, and {{DOCS_ROOT}}/architecture.md before any code change.
3
+ description: Enforces Lüdecker master rules, architecture patterns, and design system when implementing, editing, or refactoring code. Use for any code change — new features, bug fixes, UI work, API routes, migrations, or refactors. Read docs/master_rules.md, docs/architecture.md, and packages/ui tokens before writing code.
4
4
  ---
5
5
 
6
6
  # Implementation
7
7
 
8
- All code changes must comply with your project docs. **If implementation conflicts with those docs, the docs win.**
8
+ All code changes in this repo must comply with three authoritative documents. **If implementation conflicts with these docs, the docs win.**
9
9
 
10
10
  | Document | Path | Governs |
11
11
  |----------|------|---------|
12
- | Master Rules | [{{DOCS_ROOT}}/master_rules.md](../../../../{{DOCS_ROOT}}/master_rules.md) | Architecture, layers, SSOT, testing |
13
- | UI Design | [{{DOCS_ROOT}}/ui_design.md](../../../../{{DOCS_ROOT}}/ui_design.md) | CSS discipline, selectors, layout, a11y |
14
- | Project Context | [{{DOCS_ROOT}}/project_context.md](../../../../{{DOCS_ROOT}}/project_context.md) | Repo paths, SSOT anchors, tooling |
15
- | Architecture | [{{DOCS_ROOT}}/architecture.md](../../../../{{DOCS_ROOT}}/architecture.md) | System shape, modules, data flow, deploy |
12
+ | Master Rules | [docs/master_rules.md](../../../../docs/master_rules.md) | Architecture, layers, SSOT, async, testing, logging |
13
+ | Architecture | [docs/architecture.md](../../../../docs/architecture.md) | System shape, routing, state, API, DB, integrations |
14
+ | Design System | [packages/ui/src/tokens.css](../../../../packages/ui/src/tokens.css), [skills/ludecker/design-system/SKILL.md](../../../ludecker/design-system/SKILL.md) | Tokens, base components, typography |
16
15
 
17
- Read the relevant sections **before** implementing. Add project-specific object skills under `.cursor/skills/<project>/` and wire them in `capabilities/registry.json` when you outgrow the generic defaults.
16
+ Read the relevant sections **before** implementing. Use this skill as the workflow and checklist; use the docs as the full specification.
17
+
18
+ ---
19
+
20
+ ## Why God Files Still Happen
21
+
22
+ The skill enforces **layer placement** (UI vs store vs routes) but historically did **not** enforce **size budgets** or **split-before-add**. Combined with "minimal diff" in File Conventions, agents default to **appending** to existing files — which complies with layer rules while violating Rule 2 ("if a file does more than one thing, it is doing too much").
23
+
24
+ **Fix:** treat size budgets as hard gates (Master Rules §19). When a touched file is near its limit, extraction is **part of the task**, not a follow-up refactor.
18
25
 
19
26
  ---
20
27
 
21
28
  ## Before You Write Code
22
29
 
23
- 1. **Identify the layer** you are touching (UI, state, domain, infrastructure).
24
- 2. **Read** the matching section in master rules and architecture docs.
25
- 3. **UI/CSS work:** read [ui_design.md](../../../../{{DOCS_ROOT}}/ui_design.md) shallow CSS, no premature token architecture (Rules §5, §41).
26
- 4. **Check reuse** — extend existing modules before adding new ones.
27
- 5. **Respect boundaries** — UI renders only; domain owns rules; infrastructure persists.
30
+ 1. **Identify the layer** you are touching (UI, state, domain, infrastructure, server route).
31
+ 2. **Read** the matching sections in the three docs above — do not rely on memory.
32
+ 3. **Find existing patterns** in the same layer (grep/read neighbors; match conventions).
33
+ 4. **Plan the SSOT** — where does this data live? Who owns this state? What schema validates it?
34
+ 5. **Check file budgets** — run `wc -l` on files you will edit. If any file is ≥80% of its budget (see [Size Budgets](#size-budgets)), plan extraction **before** adding code.
35
+ 6. **If an AAAC domain exists** for this area (`.cursor/domains/<slug>/update/inventory/`), read it for inventory, boundaries, and invariants before planning.
36
+ 7. **If editing a legacy god file** (>300 lines or Fallow flagged), read [.cursor/skills/shared/architecture/refactor-analysis.md](../architecture/refactor-analysis.md) and split as part of this change unless the user scoped a hotfix only.
37
+
38
+ ---
39
+
40
+ ## Layer Placement (Architecture)
41
+
42
+ | Change type | Location | Must NOT |
43
+ |-------------|----------|----------|
44
+ | UI rendering | `src/app/components/` | Fetch, business logic, state orchestration |
45
+ | Global state | `src/app/store/slices/` | UI knowledge, rendering |
46
+ | Business rules | `src/app/domain/` or `shared/domain/` | React, HTTP, DB |
47
+ | Client HTTP | `src/app/api/` (domain modules) | Business decisions |
48
+ | Server routes | `server/routes/` | Business logic beyond validation + orchestration |
49
+ | Server workflows | `server/lib/` or `server/services/` | Express req/res, route registration |
50
+ | Shared validation | `shared/schemas/` | Layer-specific logic |
51
+ | Marketing site UI | `src/site/components/` | Dashboard app patterns |
52
+ | OpenRouter / LLM | `server/openrouter/` | Supabase, auth, DB (see [openrouter.md](../../../../docs/openrouter.md)) |
53
+
54
+ **URL is SSOT for navigation.** Path construction lives in `src/app/domain/paths.ts`. Store reflects URL; it does not own it.
55
+
56
+ **Data loading state machine:** `idle → loading → ready | error`. Derived data via `useMemo`, never stored separately.
57
+
58
+ ---
59
+
60
+ ## Size Budgets
61
+
62
+ Authoritative limits: [docs/master_rules.md §19](../../../../docs/master_rules.md#19-module-size-budgets). Architecture patterns: [docs/architecture.md § Module Composition](../../../../docs/architecture.md#module-composition-size-budgets).
63
+
64
+ | File kind | Max lines | When adding code |
65
+ |-----------|-----------|------------------|
66
+ | React component / hook | 250 | Extract subcomponents + `use<Feature>*.ts` hooks |
67
+ | Route file | 200 | Move logic to `server/lib/`; keep handler ≤15 lines |
68
+ | Domain / lib | 300 | Split by capability |
69
+ | OpenRouter module | 350 | New file per AI capability |
70
+
71
+ **Split-before-add:** at ≥80% of budget, extract first. **Never** grow `ImportFromFiles`-style monoliths.
72
+
73
+ ### Extend vs new file
74
+
75
+ ```
76
+ Adding to existing file?
77
+ └─ File under 80% budget AND same single responsibility → extend
78
+ └─ File at/above 80% budget → extract module first, then wire
79
+ └─ New capability domain (new endpoint, new import source, new AI feature) → new file always
80
+ └─ Touching route file with inline DB/LLM logic → move logic to server/lib/ as part of this task
81
+ ```
82
+
83
+ ---
84
+
85
+ ## Implementation Checklist
86
+
87
+ Copy and track before finishing:
88
+
89
+ ```
90
+ Implementation Progress:
91
+ - [ ] Layer placement correct (UI / state / domain / infrastructure)
92
+ - [ ] SSOT identified — no duplicated state or constants
93
+ - [ ] Size budgets respected (Master Rules §19) — split before add if near limit
94
+ - [ ] Zod schema at boundaries (shared/schemas/)
95
+ - [ ] No hardcoded values (IDs, strings, sizes, flags)
96
+ - [ ] No inline styles or style objects (except --depth / --progress)
97
+ - [ ] No inline or nested components — each in its own file
98
+ - [ ] Base components: data props only, no className
99
+ - [ ] Async logic cancellable and lifecycle-scoped via explicit state machine transitions — not guards
100
+ - [ ] Complex multi-step/async coordination modeled as a state machine (not booleans + useEffect)
101
+ - [ ] Errors explicit — logged with context, never swallowed
102
+ - [ ] Structured logging on async paths (server)
103
+ - [ ] PostHog track() if user-facing action (store action or handler)
104
+ - [ ] Tests planned in `tests_to_add[]` — authored in `test_execute`, not here
105
+ - [ ] Realtime vs fetch-on-action chosen correctly
106
+ - [ ] Fallow check_changed on touched files — no new budget violations
107
+ ```
108
+
109
+ ---
110
+
111
+ ## Master Rules — Quick Reference
112
+
113
+ Non-negotiables. Full detail: [docs/master_rules.md](../../../../docs/master_rules.md).
114
+
115
+ | # | Rule | Implementation implication |
116
+ |---|------|---------------------------|
117
+ | 1 | SSOT | One owner for each piece of state/config. Derive, don't duplicate. |
118
+ | 2 | Separation of concerns | One responsibility per file/module. |
119
+ | 4 | No hardcoding | Constants, schemas, config, tokens — never inline literals. |
120
+ | 5–6 | No inline styling/components | Token classes; named components in separate files. |
121
+ | 8 | Unidirectional flow | Input → State → Logic → Output. No magic. |
122
+ | 9 | Explicit state machines | Named states and transitions for complex flows. |
123
+ | 10 | Race avoidance | Cancellable async, no overlapping uncoordinated requests. |
124
+ | 13 | Validation at boundaries | Zod on ingress and client responses. |
125
+ | 16 | Explicit errors | Visible, traceable, actionable. Log before propagate. |
126
+ | 19 | Debug logging | `[level] [module:operation] message { context }` |
127
+ | 18 | Scalability | Size budgets §19; split before add. |
128
+ | 19 | Module size budgets | Numeric limits; Fallow gate after changes. |
129
+ | 20 | Testing | Behavior tests at unit/integration/e2e as appropriate. |
130
+ | 21 | Documented exceptions | If a rule must break, document why in code. |
131
+ | 22 | Prime directive | Clarity > cleverness. Predictability > shortcuts. |
132
+
133
+ ---
134
+
135
+ ## No Race Guards, Fallbacks, or Quick Fixes (Hard Ban)
136
+
137
+ When async work overlaps (delete during suggest, navigation during load, overlapping API calls), **do not** paper over timing with:
138
+
139
+ - **Race guards** — `if (!stillExists) return`, “discard stale response”, `useEffect` re-firing side effects, duplicate-request Sets without a owning machine
140
+ - **Fallback branches** — silent defaults that hide invalid state instead of preventing the transition
141
+ - **Quick fixes** — reordering `await` without modeling the flow, extra booleans, or comment-only “fixes”
142
+
143
+ These patterns hide bugs and violate Rules 9–10. They are **never** acceptable, including for regressions or hotfixes.
144
+
145
+ ### Required approach
146
+
147
+ 1. **Name the flow** — finite states, finite events, explicit transitions (XState machine or pure `transition*` domain module + store dispatch).
148
+ 2. **One owner** — the machine owns coordination; UI reads derived selectors only.
149
+ 3. **Cancel by generation/token** — bump a generation when the machine emits `CANCEL_*`; in-flight work checks generation **once** at completion to dispatch `*_ABORTED` / `*_COMPLETE`, not to silently drop data.
150
+ 4. **Enter blocking phases before I/O** — e.g. `REMOVE_BEGIN` synchronously before `await api.delete…` so dependent UI cannot start new work.
151
+ 5. **No reactive orchestration** — do not start mutations from `useEffect` watching derived emptiness; start only from valid machine transitions or user/store actions.
152
+
153
+ **Examples in this repo:** `requirementFocusMachine` + `requirementFocus` slice (selection + suggestion + removal), `deleteEntity.machine`, `routerResolver.machine`.
154
+
155
+ ```
156
+ WRONG: useEffect(() => { if (selected && questions.length === 0) suggest(); }, [...])
157
+ WRONG: if (!requirements.find(r => r.id)) { discard suggestions; return; }
158
+ RIGHT: REMOVE_BEGIN → CANCEL_SUGGESTION → API → graph cleanup → REMOVE_END
159
+ RIGHT: SYNC_SELECTION → (machine decides) RUN_SUGGESTION effect → runQuestionSuggestion(generation)
160
+ ```
161
+
162
+ ---
163
+
164
+ ## useState vs XState (and Pure Transition Modules)
165
+
166
+ **Pragmatic rule:**
167
+
168
+ > **Use `useState` when the state can be fully understood by reading a single component.**
169
+ >
170
+ > **Use a state machine when the state represents a process, workflow, or lifecycle with multiple valid states and transitions.**
171
+
172
+ For agentic applications: **default toward state machines for orchestration and workflows**; use hooks only for local UI state.
173
+
174
+ ### `useState` — local, single-component UI
175
+
176
+ State is obvious from one file; no async coordination; no cross-system coupling.
177
+
178
+ | Example | Why hooks |
179
+ |---------|-----------|
180
+ | Modal open/closed | Binary, scoped to one component |
181
+ | Selected tab | Local presentation |
182
+ | Search input | Controlled field |
183
+ | Dropdown expanded/collapsed | Ephemeral UI |
184
+ | Local form fields | Pre-submit draft in one form |
185
+
186
+ ### State machine — process, workflow, lifecycle
187
+
188
+ Multiple named states; explicit transitions; async, side effects, or coordination across store/router/API/AI.
189
+
190
+ | Example | Why a machine |
191
+ |---------|----------------|
192
+ | Authentication flow | Multi-step, errors, redirects |
193
+ | Multi-step wizard / import | Ordered steps, back/next, validation gates |
194
+ | Routing resolution | URL ↔ workspace ↔ project ↔ selection |
195
+ | Data loading with retries | `idle → loading → ready \| error` |
196
+ | AI agent / suggestion workflows | In-flight work, cancel, completion |
197
+ | Requirement → Question → Answer → Summary | Cross-column coordination |
198
+ | Delete/deactivate during async work | Blocking phases, cancellation |
199
+
200
+ **Implementation forms (pick one per flow):**
201
+
202
+ 1. **XState + `useMachine`** — React lifecycle integration (e.g. `routerResolver.machine`, `deleteEntity.machine`).
203
+ 2. **Pure `transition*` module + store dispatch** — Zustand-owned coordination without React actor (e.g. `requirementFocusMachine` + `requirementFocus` slice).
204
+
205
+ Both are state machines. Do not substitute a pile of booleans for either form.
206
+
207
+ ### Smell test
208
+
209
+ > If you're adding flags like `isLoading`, `isFetching`, `isSaving`, `isRetrying`, `hasError`, `isReady`, `hasInitialized`, `shouldRefetch` — you're probably describing a state machine already.
210
+
211
+ Replace the flags with named states and events. One owner; UI reads derived selectors.
212
+
213
+ ```
214
+ WRONG: isSuggesting + isRemoving + useEffect(() => suggest(), [selected, questions.length])
215
+ RIGHT: phase: 'selected' | 'removing', suggestion: 'idle' | 'requesting' | 'complete'
216
+ ```
217
+
218
+ ---
219
+
220
+ ## Architecture Patterns
221
+
222
+ Full detail: [docs/architecture.md](../../../../docs/architecture.md).
223
+
224
+ ### Server (BFF)
225
+
226
+ - Dashboard CRUD: `createUserClient(jwt)` — RLS enforced.
227
+ - OAuth callbacks, webhooks, background jobs: `supabaseAdmin` — no user JWT.
228
+ - Validate `req.body` with Zod middleware. Parse responses with domain schemas.
229
+ - Bind to `0.0.0.0:$PORT`. Secrets via `process.env` only.
230
+
231
+ ### Client (Dashboard)
232
+
233
+ - Auth: Supabase Auth → Bearer JWT on `/api/*` calls.
234
+ - Zustand slices per domain. Store actions are SSOT for API-backed mutations.
235
+ - `track()` in store actions (API flows) or component handlers (pure UI events). Never in render.
236
+ - Realtime for externally-modified data; fetch-on-action for user's own mutations.
237
+
238
+ ### Schemas
239
+
240
+ `shared/schemas/` — row schema (snake_case), domain schema (camelCase), mutation schemas. Consumed by client and server.
241
+
242
+ ### New API endpoint
243
+
244
+ 1. Zod mutation schema in `shared/schemas/`
245
+ 2. Workflow logic in `server/lib/<feature>.ts` (if >15 lines or reusable)
246
+ 3. Thin route in `server/routes/` with `requireAuth` + `validateBody` — delegate to lib
247
+ 4. Client method in `src/app/api/<domain>Api.ts` with response parsing
248
+ 5. Store action in appropriate slice
249
+ 6. UI calls store action only
250
+
251
+ If `server/routes/<resource>.ts` exceeds **200 lines**, new endpoints must not be added inline — extract handlers to `server/lib/` first (see `requirementsRouteHelpers.ts` for error-mapping pattern).
252
+
253
+ ### AI / OpenRouter feature
254
+
255
+ Read [docs/openrouter.md](../../../../docs/openrouter.md) first.
256
+
257
+ 1. Context loading in `server/context.ts` or `server/lib/*Context*.ts`
258
+ 2. Prompt + LLM I/O in new `server/openrouter/<feature>.ts` (one capability per file)
259
+ 3. Route/job calls openrouter with context as arguments
260
+ 4. Schema validation on LLM output at module boundary
261
+ 5. Unit tests for schemas and pure helpers — no live OpenRouter calls
262
+
263
+ ### Multi-step UI (modals, import flows, wizards)
264
+
265
+ Use a **feature folder** (see architecture doc). Step flow must be an **explicit state machine** (XState or pure `transition*` module) — not ad-hoc step booleans.
266
+
267
+ 1. `<Feature>.tsx` — thin shell (~100 lines max)
268
+ 2. `<feature>.machine.ts` or `use<Feature>State.ts` — step machine (finite states + transitions)
269
+ 3. `use<Feature>Actions.ts` — store mutations and side effects triggered by machine effects
270
+ 4. One subcomponent per step/section
271
+
272
+ Do not add steps to a 300+ line modal component.
273
+
274
+ ### New integration
275
+
276
+ Follow OAuth pattern in architecture doc. Store slice in `store/slices/<provider>.ts`. Connection table with RLS `user_id = auth.uid()`.
28
277
 
29
278
  ---
30
279
 
31
- ## Layer placement (generic)
280
+ ## Design System
281
+
282
+ Full detail: [docs/design_system.md](../../../../docs/design_system.md). Component specs: [docs/design_components.md](../../../../docs/design_components.md).
283
+
284
+ ### Token SSOT
285
+
286
+ All visual values from `src/styles/theme.css` via Tailwind utilities. **No** hardcoded hex/rgba, arbitrary `rounded-[Npx]`, `font-[N]`, or `shadow-[...]`.
287
+
288
+ ### Base Component Architecture (CRITICAL)
289
+
290
+ Base components (`src/app/components/ui/`) own **all** visual styling.
291
+
292
+ ```
293
+ CORRECT: <DropdownPanel variant="attached" position="above">...</DropdownPanel>
294
+ WRONG: <DropdownPanel className="absolute bottom-full ...">...</DropdownPanel>
295
+ ```
296
+
297
+ - Consumers pass **data props only** (`variant`, `label`, `icon`, `onClick`).
298
+ - Base components do **not** accept `className`. Zero exceptions.
299
+ - New visual variation → new prop on base, styled internally.
300
+ - Use typography presets (`.text-h1`, `.text-caption`, `.text-label`) — do not override with extra `font-*` / `tracking-*` / `uppercase`.
301
+
302
+ ### Only permitted inline styles
303
+
304
+ `style={{ '--depth': N }}` and `style={{ '--progress': 'N%' }}` for tree indentation and progress bars.
305
+
306
+ ### New UI component workflow
307
+
308
+ 1. Check for existing base component or pattern.
309
+ 2. If reusable visual pattern → extend or create base in `ui/`.
310
+ 3. Consumer component imports base; passes props only.
311
+ 4. New tokens → add to `theme.css` `:root` + `@theme inline` + document in design_system.md.
312
+
313
+ ---
314
+
315
+ ## Decision Trees
316
+
317
+ ### Where does this logic go?
318
+
319
+ ```
320
+ User clicked something?
321
+ └─ Pure UI event (modal open, palette) → component handler + track()
322
+ └─ Mutates app data → store action → api.ts → server route
323
+
324
+ Business rule or invariant?
325
+ └─ src/app/domain/ or shared/domain/
326
+
327
+ Validation?
328
+ └─ shared/schemas/ (Zod)
329
+
330
+ Visual styling?
331
+ └─ Base component in ui/ (tokens only)
332
+
333
+ Navigation?
334
+ └─ paths.ts + URL params → routerResolver.machine → store
335
+
336
+ Async workflow or multi-system coordination?
337
+ └─ XState (React) or transition* module + store dispatch — never useState flags + useEffect
338
+ ```
339
+
340
+ ### Realtime or fetch-on-action?
341
+
342
+ ```
343
+ Data changed by external system (webhook, other user, job)?
344
+ └─ Supabase Realtime → silent store refresh
345
+
346
+ Data changed by current user's action?
347
+ └─ Use API response / store update from action (no Realtime needed)
348
+ ```
349
+
350
+ ### Which Supabase client?
351
+
352
+ ```
353
+ User-initiated dashboard CRUD?
354
+ └─ createUserClient(jwt)
355
+
356
+ OAuth callback, webhook, background job?
357
+ └─ supabaseAdmin
358
+ ```
359
+
360
+ ---
361
+
362
+ ## File Conventions
363
+
364
+ Match existing code in the target directory:
365
+
366
+ - **Naming:** intent over implementation. No vague abbreviations.
367
+ - **Imports:** explicit interfaces between modules. No circular deps.
368
+ - **Components:** one named export per file. No render helpers inside component bodies.
369
+ - **Scope:** minimal *behavioral* diff — but **structural extraction is in scope** when size budgets require it. Do not append to god files to avoid file churn.
370
+ - **Comments:** only for non-obvious business logic.
371
+
372
+ ---
373
+
374
+ ## After Implementation
375
+
376
+ 1. **Do not self-review** — [implementation-review](../implementation-review/SKILL.md) runs in `review_swarm` with separate readonly agents.
377
+ 2. **Do not write tests here** — [test-authoring](../test-authoring/SKILL.md) runs in `test_execute` with a separate agent.
378
+ 3. **Run Fallow on changed files** — MCP `check_changed` or `npx fallow health --changed-since HEAD --file-scores`. Fix any new budget violations before finishing.
379
+ 4. **Read lints** on edited files; fix introduced issues.
380
+ 5. **Verify layer boundaries** — no fetch in UI, no business logic in routes beyond orchestration.
381
+ 6. **Verify design system** — grep edited files for hardcoded colors, `className` on base components, inline `style={{}}`.
382
+
383
+ ---
32
384
 
33
- | Layer | Responsibility | Must not |
34
- |-------|----------------|----------|
35
- | UI | Render + interaction | Fetch, business rules, direct DB |
36
- | State | Transitions | UI markup, persistence |
37
- | Domain | Rules, invariants | Framework imports where avoidable |
38
- | Infrastructure | APIs, DB, adapters | Business decisions |
385
+ ## Common Violations to Avoid
39
386
 
40
- Direction: **Input State → Logic → Output**. No circular imports across layers.
387
+ | Violation | Fix |
388
+ |-----------|-----|
389
+ | Fetch in component | Move to store action or dedicated hook that delegates to store |
390
+ | Duplicated constant | Centralize in `constants.ts`, schema, or config |
391
+ | Local state mirroring server data | Store owns it; derive in render |
392
+ | `className` on `DropdownPanel`, `IconButton`, etc. | Add/use variant prop on base |
393
+ | `#10b981` or `rgba(...)` in className | Use token class (`bg-indicator-high`, etc.) |
394
+ | Nested component in parent file | Extract to own file |
395
+ | Unvalidated API body | Add Zod schema + validateBody middleware |
396
+ | `console.log` in server code | Use structured logger |
397
+ | New user action without `track()` | Add to store action or handler |
398
+ | Ad-hoc boolean flags for multi-step flow | Explicit state machine (XState or `transition*` module) |
399
+ | `isLoading` / `isSaving` / `shouldRefetch` flag pile | Named machine states + transitions |
400
+ | Race guard / stale-response discard | Machine phase + generation token + explicit abort/complete events |
401
+ | useEffect-driven auto-mutations | Store action or machine effect from a valid transition |
402
+ | Appending to file over size budget | Extract to `server/lib/`, feature folder, or new openrouter module |
403
+ | 500-line modal/import component | Feature folder + hooks + step subcomponents |
404
+ | God route file with inline DB/LLM | Thin route + `server/lib/` workflow |
405
+ | Skipping Fallow after edit | Run `check_changed`; fix new violations |
41
406
 
42
407
  ---
43
408
 
44
- ## Checklist (execute phase)
409
+ ## Related Skills
45
410
 
46
- - [ ] Values from config/constants no unexplained literals
47
- - [ ] Class-based CSS per ui_design.md no inline styles; shallow selectors
48
- - [ ] One component per file; named exports
49
- - [ ] Async ops: cancellable, logged at boundaries
50
- - [ ] Tests appropriate to the change (unit for domain, integration for boundaries)
411
+ - **AAAC commands:** [docs/agentic_architecture.md](../../../../docs/agentic_architecture.md) `/update-module`, `/create-feature`, `/fix-bug`, etc.; sync `domains/<slug>/update/inventory` after changes
412
+ - **Refactoring analysis (required when editing files >300 lines):** [.cursor/skills/shared/architecture/refactor-analysis.md](../architecture/refactor-analysis.md) via `/review-module`
413
+ - **Code health gate:** Fallow MCP `check_changed` after every implementation when Fallow is configured
414
+ - **MDA demos (marketing site):** [.cursor/skills/mda-director/SKILL.md](../../../mda-director/SKILL.md), [.cursor/skills/mda-scriptwriter/SKILL.md](../../../mda-scriptwriter/SKILL.md)
51
415
 
52
416
  ---
53
417
 
54
- ## Project overlay (optional)
418
+ ## References
55
419
 
56
- Generic rules ship in `{{DOCS_ROOT}}/master_rules.md` and work without edits. Put repo-specific paths and SSOT anchors in `{{DOCS_ROOT}}/project_context.md`. When you outgrow defaults, extend those docs or add a `skills/<project>/implementation/` skill and wire it in `graph.project.yaml`.
420
+ - [docs/master_rules.md](../../../../docs/master_rules.md)
421
+ - [docs/architecture.md](../../../../docs/architecture.md)
422
+ - [docs/design_system.md](../../../../docs/design_system.md)
423
+ - [docs/design_components.md](../../../../docs/design_components.md)
424
+ - [docs/openrouter.md](../../../../docs/openrouter.md) — LLM adapter patterns (when touching AI features)
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: shared-implementation-review
3
+ description: >-
4
+ Phase review_swarm — readonly agents review diff against docs and plan.
5
+ Independent from execute agent. Not user-facing.
6
+ disable-model-invocation: true
7
+ ---
8
+
9
+ # Implementation review (review_swarm phase)
10
+
11
+ ## When
12
+
13
+ After `verify`, before `report`, on **create / update / fix / remove**.
14
+
15
+ **Hard rule:** The agent that ran `execute` must **not** perform this review — launch separate readonly Task subagents only.
16
+
17
+ ## Swarm (mandatory)
18
+
19
+ Launch **3** parallel `Task` subagents (`explore`, `readonly: true`) in **one message**:
20
+
21
+ | Agent spec | Angle |
22
+ |------------|-------|
23
+ | [boundary-review.md](../../../agents/boundary-review.md) | Layer boundaries, fetch-in-UI, coupling |
24
+ | [doc-conformance.md](../../../agents/doc-conformance.md) | master_rules, policies, inventory |
25
+ | [implementation-review.md](../../../agents/implementation-review.md) | Plan scope, defects, budgets |
26
+
27
+ Every prompt **must** include [_task-prompt-policy.md](../_task-prompt-policy.md) plus: plan path, verify artifact, git diff summary or changed file list.
28
+
29
+ ## Merge
30
+
31
+ Parent synthesizes Run `artifacts/review.yaml`:
32
+
33
+ ```yaml
34
+ findings:
35
+ - agent: boundary-review | doc-conformance | implementation-review
36
+ severity: critical | suggestion
37
+ finding: "<one line>"
38
+ evidence: "<path:line>"
39
+ blocking_critical: <count>
40
+ pass: true | false
41
+ ```
42
+
43
+ ## Fail
44
+
45
+ If `blocking_critical` > 0 → return to `execute` or `test_execute` to fix, then re-run verify + review_swarm. Do **not** advance to `report` with open critical findings.
46
+
47
+ ## Replaces
48
+
49
+ Self-review checklist in [governance/implementation](../governance/implementation/SKILL.md) — independent review happens here, not in execute.
@@ -66,6 +66,10 @@ rejected_alternatives:
66
66
  complexity_score: <number>
67
67
  rejected_because: "<no requirement / reuse suffices>"
68
68
  paths_to_touch: ["<concrete file paths>"]
69
+ tests_to_add:
70
+ - behavior: "<from requirement_map>"
71
+ kind: unit | integration | e2e
72
+ target_path: "<test file path>"
69
73
  rollback_notes: "<when protected/critical object>"
70
74
  ```
71
75
 
@@ -74,6 +78,7 @@ Also include:
74
78
  - SSOT owner for new state
75
79
  - Extract before add if any file ≥80% budget
76
80
  - Named machine states/events **only** if user requirement demands async coordination
81
+ - **`tests_to_add[]`** — behaviors needing new tests (see [test-authoring](../test-authoring/SKILL.md)); empty array with reason when docs-only
77
82
 
78
83
  ## Complexity score
79
84
 
@@ -0,0 +1,58 @@
1
+ ---
2
+ name: shared-test-authoring
3
+ description: >-
4
+ Phase test_execute — separate Task agent authors tests after execute.
5
+ Parent must not write test files. Not user-facing.
6
+ disable-model-invocation: true
7
+ ---
8
+
9
+ # Test authoring (test_execute phase)
10
+
11
+ ## When
12
+
13
+ After `execute`, before `verify`, on **create / update / fix / remove** (mutating verbs).
14
+
15
+ **Hard rule:** Parent orchestrator must **not** Write/StrReplace test paths in `execute` — hooks deny them. Only `test_execute` phase (or test-author Task subagent in that phase) may author tests.
16
+
17
+ ## Swarm (mandatory)
18
+
19
+ Launch **1** `Task` subagent in **one message**:
20
+
21
+ | Agent spec | `subagent_type` | Role |
22
+ |------------|-----------------|------|
23
+ | [test-author.md](../../../agents/test-author.md) | `generalPurpose` | Author tests from plan |
24
+
25
+ Every Task prompt **must** include [_task-prompt-policy.md](../_task-prompt-policy.md) plus: Run `artifacts/plan.yaml` path, list of files changed in execute, domain inventory test paths.
26
+
27
+ ## Plan input
28
+
29
+ Run `artifacts.plan` must include:
30
+
31
+ ```yaml
32
+ tests_to_add:
33
+ - behavior: "<from requirement_map>"
34
+ kind: unit | integration | e2e
35
+ target_path: "<package test file path>"
36
+ ```
37
+
38
+ If `tests_to_add` is empty and no tests are required, record on artifact:
39
+
40
+ ```yaml
41
+ tests_to_add: []
42
+ skipped_reason: "<why no new tests — e.g. docs-only change>"
43
+ ```
44
+
45
+ Store merged result on Run `artifacts/test_plan.yaml` before advancing.
46
+
47
+ ## Output
48
+
49
+ ```yaml
50
+ files_written: ["<test paths>"]
51
+ behaviors_covered: ["<strings>"]
52
+ gaps: ["<untested behaviors>"]
53
+ author_agent: test-author
54
+ ```
55
+
56
+ ## Fail
57
+
58
+ Do not advance if tests were required by plan but `files_written` is empty.