@ludecker/aaac 1.0.0
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.
- package/README.md +60 -0
- package/package.json +38 -0
- package/src/cli.mjs +138 -0
- package/src/generators/generate-commands.mjs +165 -0
- package/src/generators/generate-graph-commands.mjs +63 -0
- package/src/generators/generate-graph.mjs +242 -0
- package/src/lib/copy.mjs +36 -0
- package/src/lib/install.mjs +76 -0
- package/src/lib/paths.mjs +54 -0
- package/templates/cursor/aaac/capabilities/registry.json +106 -0
- package/templates/cursor/aaac/contract-schema.md +66 -0
- package/templates/cursor/aaac/contracts/commands/create-module.yaml +28 -0
- package/templates/cursor/aaac/contracts/commands/fix-bug.yaml +32 -0
- package/templates/cursor/aaac/contracts/commands/update-module.yaml +28 -0
- package/templates/cursor/aaac/contracts/skills/impact-analysis.yaml +17 -0
- package/templates/cursor/aaac/contracts/skills/investigation-lite.yaml +17 -0
- package/templates/cursor/aaac/contracts/skills/investigation.yaml +17 -0
- package/templates/cursor/aaac/contracts/skills/validation.yaml +14 -0
- package/templates/cursor/aaac/dependencies.yaml +14 -0
- package/templates/cursor/aaac/dispatch.md +135 -0
- package/templates/cursor/aaac/fitness-functions.yaml +34 -0
- package/templates/cursor/aaac/governance/gates.json +39 -0
- package/templates/cursor/aaac/graph.project.yaml +161 -0
- package/templates/cursor/aaac/layers.md +93 -0
- package/templates/cursor/aaac/lifecycle/lifecycle.json +78 -0
- package/templates/cursor/aaac/lifecycle/phases.json +19 -0
- package/templates/cursor/aaac/ontology.json +219 -0
- package/templates/cursor/aaac/ontology.md +90 -0
- package/templates/cursor/aaac/project.config.json +3 -0
- package/templates/cursor/aaac/run/RUN.md +72 -0
- package/templates/cursor/aaac/run/schema.json +83 -0
- package/templates/cursor/aaac/state/checkpoints/README.md +20 -0
- package/templates/cursor/agents/boundary-review.md +11 -0
- package/templates/cursor/agents/check-capability-trace.md +18 -0
- package/templates/cursor/agents/dependency-analysis.md +11 -0
- package/templates/cursor/agents/discovery-boundaries.md +11 -0
- package/templates/cursor/agents/discovery-inventory.md +14 -0
- package/templates/cursor/agents/discovery-ssot.md +11 -0
- package/templates/cursor/agents/fallow-check-changed.md +9 -0
- package/templates/cursor/agents/impact-analysis.md +22 -0
- package/templates/cursor/agents/plan-layer-map.md +11 -0
- package/templates/cursor/agents/plan-state-machines.md +11 -0
- package/templates/cursor/agents/release-git.md +36 -0
- package/templates/cursor/agents/system-decomposition.md +11 -0
- package/templates/cursor/agents/unit-test-run.md +19 -0
- package/templates/cursor/policies/implementation.md +8 -0
- package/templates/cursor/policies/master-rules.md +7 -0
- package/templates/cursor/skills/shared/api/SKILL.md +26 -0
- package/templates/cursor/skills/shared/architecture/SKILL.md +25 -0
- package/templates/cursor/skills/shared/architecture/orchestrator/SKILL.md +21 -0
- package/templates/cursor/skills/shared/architecture/refactor-analysis.md +302 -0
- package/templates/cursor/skills/shared/check/SKILL.md +47 -0
- package/templates/cursor/skills/shared/component/SKILL.md +24 -0
- package/templates/cursor/skills/shared/dependency-graph/SKILL.md +38 -0
- package/templates/cursor/skills/shared/discovery/SKILL.md +29 -0
- package/templates/cursor/skills/shared/documentation/SKILL.md +21 -0
- package/templates/cursor/skills/shared/documentation/orchestrator/SKILL.md +26 -0
- package/templates/cursor/skills/shared/documentation/orchestrator/contract.yaml +20 -0
- package/templates/cursor/skills/shared/documentation/write-arch-doc.md +168 -0
- package/templates/cursor/skills/shared/domain/SKILL.md +24 -0
- package/templates/cursor/skills/shared/execution/SKILL.md +34 -0
- package/templates/cursor/skills/shared/fitness-functions/SKILL.md +42 -0
- package/templates/cursor/skills/shared/governance/implementation/SKILL.md +424 -0
- package/templates/cursor/skills/shared/impact-analysis/SKILL.md +44 -0
- package/templates/cursor/skills/shared/integration/SKILL.md +22 -0
- package/templates/cursor/skills/shared/investigation/SKILL.md +46 -0
- package/templates/cursor/skills/shared/investigation/orchestrator/SKILL.md +22 -0
- package/templates/cursor/skills/shared/investigation-lite/SKILL.md +38 -0
- package/templates/cursor/skills/shared/migration/SKILL.md +22 -0
- package/templates/cursor/skills/shared/model/SKILL.md +22 -0
- package/templates/cursor/skills/shared/module-authoring/SKILL.md +29 -0
- package/templates/cursor/skills/shared/module-authoring/authoring-template.md +9 -0
- package/templates/cursor/skills/shared/planning/SKILL.md +30 -0
- package/templates/cursor/skills/shared/platform-release/SKILL.md +46 -0
- package/templates/cursor/skills/shared/platform-release/orchestrator/SKILL.md +51 -0
- package/templates/cursor/skills/shared/platform-release/orchestrator/contract.yaml +29 -0
- package/templates/cursor/skills/shared/platform-release/ship-procedure.md +31 -0
- package/templates/cursor/skills/shared/remove/SKILL.md +28 -0
- package/templates/cursor/skills/shared/reporting/SKILL.md +43 -0
- package/templates/cursor/skills/shared/rollback/SKILL.md +46 -0
- package/templates/cursor/skills/shared/root-cause/SKILL.md +24 -0
- package/templates/cursor/skills/shared/run/SKILL.md +64 -0
- package/templates/cursor/skills/shared/schema/SKILL.md +24 -0
- package/templates/cursor/skills/shared/testing/SKILL.md +24 -0
- package/templates/cursor/skills/shared/testing/orchestrator/SKILL.md +22 -0
- package/templates/cursor/skills/shared/validation/SKILL.md +56 -0
- package/templates/cursor/skills/shared/verbs/_dispatch-utils.md +90 -0
- package/templates/cursor/skills/shared/verbs/_lifecycle.md +87 -0
- package/templates/cursor/skills/shared/verbs/_object-skills.md +60 -0
- package/templates/cursor/skills/shared/verbs/check/orchestrator/SKILL.md +22 -0
- package/templates/cursor/skills/shared/verbs/check/orchestrator/contract.yaml +24 -0
- package/templates/cursor/skills/shared/verbs/create/orchestrator/SKILL.md +39 -0
- package/templates/cursor/skills/shared/verbs/create/orchestrator/contract.yaml +34 -0
- package/templates/cursor/skills/shared/verbs/fix/orchestrator/SKILL.md +33 -0
- package/templates/cursor/skills/shared/verbs/fix/orchestrator/contract.yaml +38 -0
- package/templates/cursor/skills/shared/verbs/release/orchestrator/SKILL.md +29 -0
- package/templates/cursor/skills/shared/verbs/release/orchestrator/contract.yaml +25 -0
- package/templates/cursor/skills/shared/verbs/remove/orchestrator/SKILL.md +25 -0
- package/templates/cursor/skills/shared/verbs/remove/orchestrator/contract.yaml +32 -0
- package/templates/cursor/skills/shared/verbs/review/orchestrator/SKILL.md +24 -0
- package/templates/cursor/skills/shared/verbs/review/orchestrator/contract.yaml +25 -0
- package/templates/cursor/skills/shared/verbs/test/orchestrator/SKILL.md +24 -0
- package/templates/cursor/skills/shared/verbs/test/orchestrator/contract.yaml +25 -0
- package/templates/cursor/skills/shared/verbs/update/orchestrator/SKILL.md +34 -0
- package/templates/cursor/skills/shared/verbs/update/orchestrator/contract.yaml +34 -0
- package/templates/cursor/skills/shared/verification/SKILL.md +28 -0
- package/templates/cursor/skills/shared/workflow/SKILL.md +25 -0
- package/templates/docs/agentic_architecture.md +131 -0
- package/templates/docs/architecture.md +5 -0
- package/templates/docs/master_rules.md +5 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: shared-domain
|
|
3
|
+
description: >-
|
|
4
|
+
Bounded context — cms, auth, requirement-engine. Object domain (system layer).
|
|
5
|
+
Not user-facing.
|
|
6
|
+
disable-model-invocation: true
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Shared domain
|
|
10
|
+
|
|
11
|
+
## Scope
|
|
12
|
+
|
|
13
|
+
- `domains/<slug>/` inventory, orchestrators, architecture docs
|
|
14
|
+
- Cross-module boundaries inside one product area
|
|
15
|
+
- AAAC domain argument = this slug
|
|
16
|
+
|
|
17
|
+
## Execution focus
|
|
18
|
+
|
|
19
|
+
- Load inventory before changes; sync after
|
|
20
|
+
- New domain → inventory + graph resolver map entry
|
|
21
|
+
|
|
22
|
+
## Check focus
|
|
23
|
+
|
|
24
|
+
- In/out of scope vs neighboring domains
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: shared-execution
|
|
3
|
+
description: >-
|
|
4
|
+
Applies code changes for AAAC orchestrators. Must load governance/implementation.
|
|
5
|
+
Migrations via Supabase MCP. Not user-facing.
|
|
6
|
+
disable-model-invocation: true
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Shared execution
|
|
10
|
+
|
|
11
|
+
## When
|
|
12
|
+
|
|
13
|
+
Orchestrator phase `execute` after approved plan.
|
|
14
|
+
|
|
15
|
+
## Mandatory
|
|
16
|
+
|
|
17
|
+
1. Read [governance/implementation/SKILL.md](../governance/implementation/SKILL.md)
|
|
18
|
+
2. Read domain [inventory](../../../domains/) constraints
|
|
19
|
+
3. Read [policies/](../../../policies/)
|
|
20
|
+
|
|
21
|
+
## Actions
|
|
22
|
+
|
|
23
|
+
- Edit files per plan and implementation skill
|
|
24
|
+
- `apply_migration` for new/changed `supabase/migrations/` (project `hjadkzfemzuvhpwbixbt`)
|
|
25
|
+
- `track()` for user-facing mutations
|
|
26
|
+
- Structured logging on server async paths
|
|
27
|
+
|
|
28
|
+
## Must not
|
|
29
|
+
|
|
30
|
+
- Invent plan during execution
|
|
31
|
+
- Race guards or useEffect-driven mutations (implementation ban)
|
|
32
|
+
- Skip schema validation at boundaries
|
|
33
|
+
|
|
34
|
+
Git commit only when orchestrator/release phase explicitly requires it.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: shared-fitness-functions
|
|
3
|
+
description: >-
|
|
4
|
+
Score architecture fitness functions before execute; re-check in verify.
|
|
5
|
+
Not user-facing.
|
|
6
|
+
disable-model-invocation: true
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Architecture fitness functions
|
|
10
|
+
|
|
11
|
+
**When:** Verb lifecycle phase `fitness_functions` — before execute.
|
|
12
|
+
|
|
13
|
+
## SSOT
|
|
14
|
+
|
|
15
|
+
[fitness-functions.yaml](../../../aaac/fitness-functions.yaml)
|
|
16
|
+
|
|
17
|
+
## Procedure
|
|
18
|
+
|
|
19
|
+
1. Filter `functions` where command `object` ∈ `applies_to`
|
|
20
|
+
2. Load linked skill per function (e.g. `ludecker-api-first`, `ludecker-design-system`)
|
|
21
|
+
3. Score each: `pass` | `warning` | `fail` against planned changes
|
|
22
|
+
|
|
23
|
+
## Output
|
|
24
|
+
|
|
25
|
+
```yaml
|
|
26
|
+
score:
|
|
27
|
+
api_first: pass | warning | fail
|
|
28
|
+
design_system: pass | warning | fail
|
|
29
|
+
accessibility: pass | warning | fail
|
|
30
|
+
security: pass | warning | fail
|
|
31
|
+
layer_boundaries: pass | warning | fail
|
|
32
|
+
performance: pass | warning | fail
|
|
33
|
+
blocking_failures: [function names — empty if none]
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Gates
|
|
37
|
+
|
|
38
|
+
- Any **fail** on `security` or `layer_boundaries` → **STOP** before execute
|
|
39
|
+
- **warning** → document in report; may proceed if validation passed
|
|
40
|
+
- Re-run abbreviated score in [verification](../verification/SKILL.md) after execute
|
|
41
|
+
|
|
42
|
+
Turns "read architecture.md" into enforceable checks.
|
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: implementation
|
|
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
|
+
---
|
|
5
|
+
|
|
6
|
+
# Implementation
|
|
7
|
+
|
|
8
|
+
All code changes in this repo must comply with three authoritative documents. **If implementation conflicts with these docs, the docs win.**
|
|
9
|
+
|
|
10
|
+
| Document | Path | Governs |
|
|
11
|
+
|----------|------|---------|
|
|
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 |
|
|
15
|
+
|
|
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.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Before You Write Code
|
|
29
|
+
|
|
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 at appropriate level (unit / integration / e2e)
|
|
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()`.
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
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. **Self-review** against the checklist above.
|
|
377
|
+
2. **Run Fallow on changed files** — MCP `check_changed` or `npx fallow health --changed-since HEAD --file-scores`. Fix any new budget violations before finishing.
|
|
378
|
+
3. **Read lints** on edited files; fix introduced issues.
|
|
379
|
+
4. **Run relevant tests** if they exist for the touched area.
|
|
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
|
+
---
|
|
384
|
+
|
|
385
|
+
## Common Violations to Avoid
|
|
386
|
+
|
|
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 |
|
|
406
|
+
|
|
407
|
+
---
|
|
408
|
+
|
|
409
|
+
## Related Skills
|
|
410
|
+
|
|
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)
|
|
415
|
+
|
|
416
|
+
---
|
|
417
|
+
|
|
418
|
+
## References
|
|
419
|
+
|
|
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,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: shared-impact-analysis
|
|
3
|
+
description: >-
|
|
4
|
+
Pre-execute impact analysis — what can break, risk tags. Required for update and
|
|
5
|
+
fix; recommended for create on critical/protected objects. Not user-facing.
|
|
6
|
+
disable-model-invocation: true
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Impact analysis
|
|
10
|
+
|
|
11
|
+
**When:** Verb lifecycle phase `impact_analysis` — after validate, before execute.
|
|
12
|
+
|
|
13
|
+
## Question
|
|
14
|
+
|
|
15
|
+
```text
|
|
16
|
+
What can break?
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Procedure
|
|
20
|
+
|
|
21
|
+
1. Read planned file/route/migration list from plan
|
|
22
|
+
2. Cross-reference [dependencies.yaml](../../../aaac/dependencies.yaml) `risk_tags` and domain `depends_on`
|
|
23
|
+
3. Invoke [impact-analysis.md](../../../agents/impact-analysis.md) agent pattern (readonly)
|
|
24
|
+
|
|
25
|
+
## Output (mandatory)
|
|
26
|
+
|
|
27
|
+
```yaml
|
|
28
|
+
affected:
|
|
29
|
+
- cms | ui | database | integration | ...
|
|
30
|
+
risk:
|
|
31
|
+
- migrations
|
|
32
|
+
- breaking_contracts
|
|
33
|
+
- auth
|
|
34
|
+
- deployment
|
|
35
|
+
blast_radius: low | medium | high
|
|
36
|
+
proceed: yes | no — if high blast_radius on protected object without rollback → no
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
If `proceed: no` → **STOP, REQUEST CLARIFICATION** or require completed [rollback](../rollback/SKILL.md) plan.
|
|
40
|
+
|
|
41
|
+
## Maturity
|
|
42
|
+
|
|
43
|
+
- **protected** / **critical** objects: always run full analysis
|
|
44
|
+
- **stable** / **evolving**: run; may downgrade to brief bullet list if blast_radius low
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: shared-integration
|
|
3
|
+
description: >-
|
|
4
|
+
API routes, MCP, webhooks, OAuth — product-layer external surface. Not user-facing.
|
|
5
|
+
disable-model-invocation: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Shared integration
|
|
9
|
+
|
|
10
|
+
## Scope
|
|
11
|
+
|
|
12
|
+
- `apps/website/app/api/`, Supabase MCP, Render deploy policies
|
|
13
|
+
- Project rules: [deploy.mdc](../../../../rules/deploy.mdc), [supabase-mcp.mdc](../../../../rules/supabase-mcp.mdc)
|
|
14
|
+
|
|
15
|
+
## Execution focus
|
|
16
|
+
|
|
17
|
+
- Adapter at infrastructure boundary; validate at boundary
|
|
18
|
+
- One route family or integration per change
|
|
19
|
+
|
|
20
|
+
## Release focus
|
|
21
|
+
|
|
22
|
+
- Smoke: auth, callbacks, CORS, rate limits
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: shared-investigation
|
|
3
|
+
description: >-
|
|
4
|
+
Deep investigation for fix paths and review-incident. Not user-facing.
|
|
5
|
+
disable-model-invocation: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Shared investigation (deep)
|
|
9
|
+
|
|
10
|
+
**When:** fix verb lifecycle, `fix_mode` domain orchestrators, `review-incident`.
|
|
11
|
+
|
|
12
|
+
For create/update use [investigation-lite](../investigation-lite/SKILL.md) instead.
|
|
13
|
+
|
|
14
|
+
Adapted from legacy swarm-check. **Default: readonly.**
|
|
15
|
+
|
|
16
|
+
## Frame
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
Issue: one line
|
|
20
|
+
Symptoms: user-visible
|
|
21
|
+
Expected: if known
|
|
22
|
+
Scope: files/features
|
|
23
|
+
Questions: 3–5
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Swarm
|
|
27
|
+
|
|
28
|
+
3–6 parallel readonly agents: code path, recent changes, tests, CI (`ci-investigator` if `--ci`), logs, state flow.
|
|
29
|
+
|
|
30
|
+
Use [discovery](../discovery/SKILL.md) agent specs where overlapping.
|
|
31
|
+
|
|
32
|
+
## Confidence output
|
|
33
|
+
|
|
34
|
+
Include `confidence.architecture`, `confidence.requirements`, `confidence.scope` for [validation](../validation/SKILL.md).
|
|
35
|
+
|
|
36
|
+
## Report
|
|
37
|
+
|
|
38
|
+
[reporting](../reporting/SKILL.md) — layman first, <250 words unless user asked for detail.
|
|
39
|
+
|
|
40
|
+
## Next phase (fix only)
|
|
41
|
+
|
|
42
|
+
Hand off to [root-cause](../root-cause/SKILL.md) before planning.
|
|
43
|
+
|
|
44
|
+
## Fix path execution
|
|
45
|
+
|
|
46
|
+
If intent includes fix or `fix-bug` command: after full lifecycle gates pass, orchestrator invokes `execution` + `testing` + `verification`.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: review-incident-orchestrator
|
|
3
|
+
description: >-
|
|
4
|
+
Orchestrates review-incident. Investigate; fix only when intent requests it.
|
|
5
|
+
disable-model-invocation: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# review-incident orchestrator
|
|
9
|
+
|
|
10
|
+
## Parse
|
|
11
|
+
|
|
12
|
+
- **Intent:** primary (quoted or full `$ARGUMENTS`)
|
|
13
|
+
- **Domain:** optional
|
|
14
|
+
- Internal only: `--fix`, `--pr`, `--ci` if present in args
|
|
15
|
+
|
|
16
|
+
## Phases
|
|
17
|
+
|
|
18
|
+
1. [investigation](../SKILL.md) — layman report
|
|
19
|
+
2. If fix requested: discovery → planning → execution → testing → verification
|
|
20
|
+
3. [reporting](../reporting/SKILL.md)
|
|
21
|
+
|
|
22
|
+
Stop after report unless fix path active.
|