@ludecker/aaac 1.1.0 → 1.1.2

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 (40) hide show
  1. package/package.json +1 -1
  2. package/src/generators/generate-commands.mjs +17 -9
  3. package/src/run-engine/advance-phase.mjs +152 -1
  4. package/src/run-engine/capability-evidence.mjs +460 -0
  5. package/src/run-engine/gate-write.mjs +14 -2
  6. package/src/run-engine/init-run.mjs +92 -1
  7. package/src/run-engine/lib.mjs +38 -0
  8. package/src/run-engine/record-task.mjs +7 -1
  9. package/src/run-engine/stop-check.mjs +7 -1
  10. package/src/run-engine/verify-website-build.mjs +185 -0
  11. package/templates/cursor/aaac/capabilities/promotion-rules.json +64 -0
  12. package/templates/cursor/aaac/capabilities/registry.json +11 -11
  13. package/templates/cursor/aaac/dispatch.md +2 -2
  14. package/templates/cursor/aaac/enforcement.json +6 -3
  15. package/templates/cursor/aaac/governance/gates.json +3 -1
  16. package/templates/cursor/aaac/graph.project.yaml +4 -204
  17. package/templates/cursor/aaac/layers.md +3 -0
  18. package/templates/cursor/aaac/observability/telemetry.yaml +3 -0
  19. package/templates/cursor/aaac/ontology.md +17 -32
  20. package/templates/cursor/aaac/project.config.json +4 -1
  21. package/templates/cursor/aaac/run/schema.json +5 -1
  22. package/templates/cursor/aaac/scripts/run-engine/advance-phase.mjs +152 -1
  23. package/templates/cursor/aaac/scripts/run-engine/capability-evidence.mjs +460 -0
  24. package/templates/cursor/aaac/scripts/run-engine/gate-write.mjs +14 -2
  25. package/templates/cursor/aaac/scripts/run-engine/init-run.mjs +92 -1
  26. package/templates/cursor/aaac/scripts/run-engine/lib.mjs +38 -0
  27. package/templates/cursor/aaac/scripts/run-engine/record-task.mjs +7 -1
  28. package/templates/cursor/aaac/scripts/run-engine/stop-check.mjs +7 -1
  29. package/templates/cursor/aaac/scripts/run-engine/verify-website-build.mjs +185 -0
  30. package/templates/cursor/aaac/state/capability-stats.json +5 -0
  31. package/templates/cursor/agents/playwright-check-run.md +8 -26
  32. package/templates/cursor/agents/release-git.md +2 -2
  33. package/templates/cursor/agents/unit-test-run.md +3 -7
  34. package/templates/cursor/skills/shared/governance/implementation/SKILL.md +25 -396
  35. package/templates/cursor/skills/shared/platform-release/SKILL.md +22 -19
  36. package/templates/cursor/skills/shared/platform-release/orchestrator/contract.yaml +27 -7
  37. package/templates/cursor/skills/shared/testing/SKILL.md +5 -0
  38. package/templates/cursor/skills/shared/verbs/check/orchestrator/SKILL.md +1 -1
  39. package/templates/cursor/skills/shared/verification/SKILL.md +2 -1
  40. package/templates/docs/agentic_architecture.md +163 -60
@@ -1,424 +1,53 @@
1
1
  ---
2
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.
3
+ description: Enforces project master rules and architecture when implementing code. Read {{DOCS_ROOT}}/master_rules.md and {{DOCS_ROOT}}/architecture.md before any code change.
4
4
  ---
5
5
 
6
6
  # Implementation
7
7
 
8
- All code changes in this repo must comply with three authoritative documents. **If implementation conflicts with these docs, the docs win.**
8
+ All code changes must comply with your project docs. **If implementation conflicts with those docs, the docs win.**
9
9
 
10
10
  | Document | Path | Governs |
11
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 |
12
+ | Master Rules | [{{DOCS_ROOT}}/master_rules.md](../../../../{{DOCS_ROOT}}/master_rules.md) | Architecture, layers, SSOT, testing |
13
+ | Architecture | [{{DOCS_ROOT}}/architecture.md](../../../../{{DOCS_ROOT}}/architecture.md) | System shape, modules, data flow, deploy |
15
14
 
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.
15
+ 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.
25
16
 
26
17
  ---
27
18
 
28
19
  ## Before You Write Code
29
20
 
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()`.
21
+ 1. **Identify the layer** you are touching (UI, state, domain, infrastructure).
22
+ 2. **Read** the matching section in master rules and architecture docs.
23
+ 3. **Check reuse** extend existing modules before adding new ones.
24
+ 4. **Respect boundaries** — UI renders only; domain owns rules; infrastructure persists.
277
25
 
278
26
  ---
279
27
 
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
- ---
28
+ ## Layer placement (generic)
384
29
 
385
- ## Common Violations to Avoid
30
+ | Layer | Responsibility | Must not |
31
+ |-------|----------------|----------|
32
+ | UI | Render + interaction | Fetch, business rules, direct DB |
33
+ | State | Transitions | UI markup, persistence |
34
+ | Domain | Rules, invariants | Framework imports where avoidable |
35
+ | Infrastructure | APIs, DB, adapters | Business decisions |
386
36
 
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 |
37
+ Direction: **Input State → Logic → Output**. No circular imports across layers.
406
38
 
407
39
  ---
408
40
 
409
- ## Related Skills
41
+ ## Checklist (execute phase)
410
42
 
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)
43
+ - [ ] Values from config/constants no unexplained literals
44
+ - [ ] Token/class-based CSS no inline styles in UI components
45
+ - [ ] One component per file; named exports
46
+ - [ ] Async ops: cancellable, logged at boundaries
47
+ - [ ] Tests appropriate to the change (unit for domain, integration for boundaries)
415
48
 
416
49
  ---
417
50
 
418
- ## References
51
+ ## Project overlay
419
52
 
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)
53
+ After `npx @ludecker/aaac init`, replace this generic skill with project-specific rules, or add a `skills/<project>/implementation/` skill and point `execution` depends in `graph.project.yaml`.
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  name: shared-platform-release
3
3
  description: >-
4
- Phased release swarm coordination for release-app. Wave 1 git (blocking),
5
- Wave 2 Render deploy. Internal only.
4
+ Phased release for release-app: mandatory preflight, git, optional conditional
5
+ package publish, Render poll, verify, report.
6
6
  disable-model-invocation: true
7
7
  ---
8
8
 
@@ -11,36 +11,39 @@ disable-model-invocation: true
11
11
  ## Swarm DAG
12
12
 
13
13
  ```text
14
- Preflight (optional tests)
14
+ Wave 0: pnpm typecheck (mandatory)
15
15
 
16
16
  Wave 1: release-git ← BLOCKING
17
17
 
18
- Wave 2: release-render
18
+ Wave 1.5: conditional package publish ← OPTIONAL (project overlay; blocking when triggered)
19
19
 
20
- Parent: verification + reporting
20
+ Wave 2: release-render BLOCKING (poll until live or fail)
21
+
22
+ Wave 3: verification + reporting
21
23
  ```
22
24
 
23
- ## Wave 1launch one agent
25
+ ## Wave 0preflight
24
26
 
27
+ ```bash
28
+ pnpm typecheck
25
29
  ```
26
- Task (shell or generalPurpose): release-git
27
- Read: agents/release-git.md, ship-procedure.md
28
- Return: commit_sha, commit_message_*
29
- On failure: abort pipeline
30
- ```
31
30
 
32
- ## Wave 2 Render deploy
31
+ Always. Optional extra tests when intent requests them.
32
+
33
+ ## Wave 1 — git
34
+
35
+ Execute [agents/release-git.md](../../../agents/release-git.md) or spawn shell subagent.
36
+
37
+ ## Wave 1.5 — conditional publish (project overlay)
33
38
 
34
- Only after Wave 1 `status: success`. Pass `commit_sha` and messages.
39
+ When the project ships an npm package with the app (e.g. `@ludecker/aaac`), the project overlay supplies a conditional publish agent and detection scripts. Skip when no changes detected.
35
40
 
36
- | Agent spec | Tool |
37
- |------------|------|
38
- | [release-render.md](../../../agents/release-render.md) | generalPurpose or render-assistant MCP |
41
+ ## Wave 2 Render (mandatory)
39
42
 
40
- ## Preflight
43
+ Execute [agents/release-render.md](../../../agents/release-render.md).
41
44
 
42
- If intent contains "test" / "with tests": run `pnpm typecheck` before Wave 1.
45
+ **Never** end ship without polled deploy status.
43
46
 
44
47
  ## Reference
45
48
 
46
- Full step detail: [ship-procedure.md](ship-procedure.md)
49
+ Full steps: [ship-procedure.md](ship-procedure.md)
@@ -1,5 +1,5 @@
1
1
  name: release-app-orchestrator
2
- purpose: Ship to main with phased expert subagents (git, then parallel integrations)
2
+ purpose: Ship to main with preflight, git push, optional conditional package publish, mandatory Render deploy poll, smoke check, report
3
3
  inputs:
4
4
  domain:
5
5
  required: false
@@ -9,21 +9,41 @@ inputs:
9
9
  outputs:
10
10
  commit_sha:
11
11
  type: string
12
+ package_publish_skipped:
13
+ type: boolean
14
+ package_version:
15
+ type: string
16
+ package_tag:
17
+ type: string
18
+ package_publish_status:
19
+ type: string
12
20
  deploy_status:
13
21
  type: string
22
+ deploy_id:
23
+ type: string
24
+ smoke_http_code:
25
+ type: number
14
26
  report:
15
27
  type: markdown
16
28
  success_criteria:
17
- - git push to main succeeded
18
- - render deploy reached live or build failure reported with logs
19
- - posthog and linear agents run after git (parallel wave)
29
+ - pnpm typecheck passed
30
+ - git push to main succeeded (or HEAD already on remote)
31
+ - when package changes detected, ship checks passed and version published
32
+ - render deploy reached live for commit_sha
33
+ - smoke check returned 200
20
34
  failure_conditions:
35
+ - typecheck failed
21
36
  - git push failed
22
- - wave 2 started before commit_sha known
37
+ - wave 1.5 or 2 started before commit_sha known
38
+ - package ship checks failed when triggered
39
+ - package publish monitor timeout when triggered
40
+ - render build_failed or poll timeout
41
+ - smoke check not 200
23
42
  dependencies:
24
43
  skills: [platform-release, testing, verification, reporting]
25
44
  policies: [master-rules, mcp-and-deploy]
26
45
  verification:
46
+ - typecheck_passed
27
47
  - git_pushed
28
- - render_polled
29
- - agent_wave_order_respected
48
+ - render_polled_until_live
49
+ - smoke_200
@@ -18,6 +18,11 @@ Phase `verify` (and `test_only` orchestrators). On **fix** paths, run fix verify
18
18
  2. Invoke [unit-test-run.md](../../../agents/unit-test-run.md) pattern for targeted vitest
19
19
  3. Fallow MCP → `check_changed` on touched files when configured
20
20
  4. `ReadLints` on edited paths
21
+ 5. **App build gate (when enabled):** before advancing `verify`, run:
22
+ ```bash
23
+ node .cursor/aaac/scripts/run-engine/verify-website-build.mjs --run-id <run_id>
24
+ ```
25
+ Reads `verify` from `.cursor/aaac/project.config.json`. Skips when `verify.enabled: false` (default on fresh install). When enabled, checks `index_html` static assets and runs the configured build command. `advance-phase.mjs verify` **blocks** until this passes and writes `artifacts/verify.yaml`.
21
26
 
22
27
  ## Fix verify swarm (mandatory on fix verb / fix_mode)
23
28
 
@@ -17,7 +17,7 @@ Read [_dispatch-utils.md](../_dispatch-utils.md) first.
17
17
  3. **load_inventory** — when domain slug maps to inventory
18
18
  4. **object_skills** — from graph `object_skills.<object>`
19
19
  5. [check](../../check/SKILL.md) — swarm per check skill
20
- 6. **contract_checks** — `pnpm --filter @ludecker/aaac test` and `pnpm --filter @ludecker/aaac test:e2e` (includes `check-verb.check.spec.ts`); launch [playwright-check-run](../../../agents/playwright-check-run.md) at report phase
20
+ 6. **contract_checks** — run project test commands from domain inventory when present; for `@ludecker/aaac` package maintenance use `pnpm --filter @ludecker/aaac test` and `test:e2e`
21
21
  7. [reporting](../../reporting/SKILL.md) — **Answer** (yes/no/partial) then **How**
22
22
 
23
23
  No code changes. For test runs use `test-*`; for fixes use `fix-*`.
@@ -14,7 +14,8 @@ After `testing`. Before `report`.
14
14
 
15
15
  ## Checks
16
16
 
17
- - **Playwright verb checks** (create / update / fix): launch [playwright-check-run](../../../agents/playwright-check-run.md) — `pnpm --filter @ludecker/aaac test:e2e` must pass; set `PLAYWRIGHT_BASE_URL` for public-route smoke
17
+ - **App build gate** (create / update / fix, when `project.config.json` `verify.enabled`): `artifacts/verify.yaml` from [verify-website-build.mjs](../../../aaac/scripts/run-engine/verify-website-build.mjs)
18
+ - **E2E smoke** (optional): launch [playwright-check-run](../../../agents/playwright-check-run.md) when project defines Playwright targets; set `PLAYWRIGHT_BASE_URL` for public-route smoke
18
19
  - Run artifact `artifacts.testing.repro_status` is **fixed** or **partial** with documented follow-up (fix paths)
19
20
  - Orchestrator `contract.yaml` `success_criteria`
20
21
  - Graph `object_skills` / `object_skill_verbs` skills were loaded for command object + verb