68 Commits

Author SHA1 Message Date
Armen Rohalov f754afff46 annotations v2: redesign
ci/woodpecker/push/build-arm Pipeline failed
Reskin to v2 surface/accent tokens + JetBrains Mono headings to match
_docs/ui_design/v2/plugin/annotations.html. Add scrubber with class-colored
annotation marks, canvas top bar (zoom/cursor/dims), floating AI-detection
banner, multi-band gradient rows in the annotations sidebar, class-distribution
summary footer, and DOM-overlay bbox labels with affiliation icon + readiness
dot. Split VideoPlayer chrome out into the page-level controls row
(transport/frame-step/save/delete/AI-detect/mute/volume) and a new Scrubber
component; player events replace 200ms polling.

Other:
- Auth dev bypass via VITE_DEV_AUTH_BYPASS (gated on import.meta.env.DEV).
- Mount SavedAnnotationsProvider in App so AnnotationsPage doesn't crash.
- Extract hexToRgba to src/class-colors and time helpers to
  src/features/annotations/time.ts (dedup across CanvasEditor / Sidebar /
  AnnotationsPage).
- CanvasEditor: shallow-compare label chips before commit, NaN-guard
  annotation-time parser, cancel cursor RAF on unmount.
- AnnotationsPage: track AI-banner close timer, push initial volume to the
  <video> on media change, drop the duplicate parent muted state.
- Fixed sidebar widths (resize handles removed per design).
2026-05-28 02:28:10 +03:00
Armen Rohalov cfffb4bdd7 settings v2: implement design
ci/woodpecker/push/build-arm Pipeline failed
- Rewrite SettingsPage to 5-panel v2 layout: Tenant, Directories,
  Aircrafts, Language, Session — corner-bracket panels, sticky footer
  pinned to viewport bottom (Cancel + Save Changes), live dirty-state
  indicator.
- Wire try/catch/finally + role="alert" in save handler so AZ-477's
  three it.fails contract tests flip to passing; remove the obsolete
  v1-drift control test and its unhandledRejection harness.
- Add EN/UA language toggle; persist to localStorage('azaion.lang')
  and read on i18n init. Export LANG_STORAGE_KEY from src/i18n.
- Add Add-Aircraft flow (reuses admin Modal) and view-only star
  default toggle.
- Extend the v2 design system with .btn-danger-ghost, .star,
  .path-wrap/.browse classes. Scope settings.html-spec button
  proportions (padding 7px 14px, weight 400, letter-spacing 0.10em,
  line-height 1.5) under .settings-page so the admin spec is unaffected.
- Restore module-scoped bootstrapInflight declaration in
  src/auth/AuthContext.tsx (deleted in 2a62415 while references
  remained — every test using tests/setup.ts was throwing
  ReferenceError).
2026-05-26 00:25:27 +03:00
Armen Rohalov 5c3c06aad8 Merge branch 'feat/admin-page' into dev
ci/woodpecker/push/build-arm Pipeline failed
2026-05-19 02:04:09 +03:00
Armen Rohalov 434854bf3c admin v2: implement design from ui_design/v2/plugin/admin.html
- Design system: v2 CSS variables (surface-0/1/2, border-hair, accent-amber/cyan/red/green/blue)
  and utility classes (.btn, .inp, .pill, .chip, .bracket, .panel, .seg, .swatch,
  .type-sq, .grid-bg, .ibtn, .checkbox, .tab); v1 az-* names aliased to v2 vars
  so other pages still render. Google Fonts (IBM Plex Sans + JetBrains Mono)
  loaded via <link> in index.html <head> to avoid FOUT.
- Header rebuilt to v2: amber wordmark + // divider, amber-bordered flight pill
  with cyan live dot, tab-style nav with amber underline on active, LINK status
  pill, cog + sign-out icon buttons.
- AdminPage rewritten to 3-column layout (340 / flex / 280):
  - Detection Classes: search + ADD button, table with #/Name/Hex/Ops columns,
    name-only inline edit with ringed swatch, sibling-row error alert.
  - AI Recognition Engine + GPS Device Link panels with corner-bracket borders,
    number steppers, segmented protocol control, dashed telemetry footers.
    Hooks (useAiSettings, useGpsSettings) seed factory defaults so the UI is
    interactive when GET fails (no backend).
  - Default Aircrafts: P/C/F type chips, isDefault star toggle, + ADD AIRCRAFT
    modal with model/type/resolution/maxMinutes/default fields.
- Co-located components: Modal (backdrop + ESC + body-scroll-lock),
  NumberStepper (▲▼ with clamp on click but not on typing), ClassEditRow.
- Types: Aircraft extended with FixedWing + optional resolution/maxMinutes;
  new AiRecognitionSettings/Telemetry, GpsDeviceSettings/Telemetry, GpsProtocol.
- Endpoints: /api/admin/ai-settings, /api/admin/gps-settings (+ /ping, /reconnect).
  POST /api/flights/aircrafts (plural REST collection).
- MSW: stateful admin-settings handler with resetAdminSettingsSeed() wired into
  tests/setup.ts. Aircraft seed expanded to 6 entries matching the mockup.
- i18n: full admin.{classes,aiEngine,gpsDevice,aircrafts} key sets in en+ua;
  nav.dataset shortened to "Dataset"; obsolete users-management keys removed.
- Tests: new AdminPage AI/GPS/aircraft test suites; admin_class_edit selectors
  updated for the name-only inline editor and the modal-based add flow.
2026-05-19 02:01:20 +03:00
Oleksandr Bezdieniezhnykh a943b508f6 Merge branch 'dev' of https://github.com/azaion/ui into dev
ci/woodpecker/push/build-arm Pipeline failed
2026-05-17 13:19:30 +03:00
Oleksandr Bezdieniezhnykh 8e90e24f5a [no-ticket] Sync .cursor with suite root
Bring this repo's .cursor/ in line with the suite monorepo root .cursor/
so rules, skills, and autodev artifacts stay consistent across
submodules and sibling repos.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-17 13:11:01 +03:00
Armen Rohalov 2a62415f0c ui_design v2: redesign of all 5 pages
ui_design v2: tactical-ops redesign of all 5 pages

Two parallel takes on visual polish for flights, annotations, dataset
explorer, admin, and settings.

- v2/plugin/ — self-contained HTML produced via the frontend-design
  plugin, adheres to v2/plugin/_design_system.md..
- v2/stitch/ — Google Stitch MCP exports against the same design
  system.

IA from the original wireframes in _docs/ui_design/ is preserved
verbatim — this pass is visual only.
2026-05-16 20:09:16 +03:00
Armen Rohalov 401f43d845 Merge branch 'dev' into feat/dataset-explorer 2026-05-14 20:26:20 +03:00
Oleksandr Bezdieniezhnykh eb1e8a8581 [AZ-512] Cycle 4 closure: deploy + retro + lessons + state
Closes cycle 4 (AZ-512 admin class inline edit).

Steps 16-17 artifacts:
- deploy_cycle4_report.md: ui/ dev pushed (09449bd..8737491, 4 commits,
  fast-forward); stage/main and admin/ dev deferred at the push-scope
  gate (option A; same as cycle 3). AZ-513 admin/ implementation +
  deploy gate stays open as the cross-workspace prerequisite.
- retro_2026-05-13_cycle4.md: PASS_WITH_WARNINGS verdict carries;
  243 PASS / 13 SKIP / 0 FAIL; bundle 291 332 B (+757 B / +0.26%);
  net architecture delta 0; user-action backlog 7 -> 9 (rate
  decelerating from +4 to +2); first cycle where the user explicitly
  overrode a spec-conservative default (AZ-512 Option B).
- structure_2026-05-13_cycle4.md: identity-copy snapshot; no new
  components, no new gates, no new barrels, no new wire-contract
  assertions, no new architecture findings.
- LESSONS.md: top-3 cycle-4 lessons appended (testing/testing/process),
  ring buffer at 12 of 15.
- _autodev_state.md: cycle 4 closed, cycle 5 entered awaiting New Task.

Jira AZ-512: In Testing -> Done with cycle-4 closing comment.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 04:56:42 +03:00
Oleksandr Bezdieniezhnykh 873749197a [AZ-512] Cycle 4 Steps 12-15: test-spec sync + docs + sec + perf
ci/woodpecker/push/build-arm Pipeline failed
Steps 12-15 closure for cycle 4 (AZ-512 admin class inline edit):

- Step 12 (Test-Spec Sync): traceability O9 -> Covered; new FT-P-62
  + FT-N-18 in blackbox-tests.md.
- Step 13 (Update Docs): AdminPage module doc gains the inline-edit
  state slots, four new handlers, PATCH integrations row, expanded
  i18n key list, tests section. architecture.md row 272 now lists
  PATCH /api/admin/classes/{id} with AZ-513 deploy-gate caveat.
- Step 14 (Security Audit): cycle-4 delta report records one new
  LOW finding (F-SAST-CY4-1 lost-update / mid-air-collision on
  PATCH, by design per spec); verdict carries PASS_WITH_WARNINGS;
  bun audit re-run clean.
- Step 15 (Performance Test): NFT-PERF-01 bundle = 291 332 B
  (+757 B / +0.26% vs cycle 3; ~13.89% of 2 MB budget); PASS.

Tests 243 passed / 13 skipped / 0 failed (+12 AZ-512 cases).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 04:51:17 +03:00
Oleksandr Bezdieniezhnykh ecacfa8b43 [AZ-512] Admin class inline edit form + PATCH wiring (cy4 batch 16)
Implements the cycle-3-deferred AZ-512 task under the user-authorized
Option B path (MSW-stubbed; live deploy gates at Step 16 on AZ-513).

Code:
- src/features/admin/AdminPage.tsx — inline edit affordance:
  editingId/editForm state, handleStartEdit/Cancel/Update, Enter+Escape
  keyboard handling, colspan row swap when editing, pencil (✎) button
  per row. Full-body PATCH (Risk 2). Single editingId enforces the
  one-row-at-a-time invariant (Risk 3). Disabled buttons during the
  in-flight PATCH (Risk 4). Inline role="alert" on validation/server
  errors (no alert() per Finding B4 anti-pattern).
- src/i18n/{en,ua}.json — `admin.classes` flat → nested with `title`
  + 6 new keys (edit, save, cancel, nameRequired,
  maxSizeMustBePositive, updateFailed). Parity gate FT-P-22 PASS.

Test infrastructure:
- tests/msw/handlers/admin.ts — PATCH /api/admin/classes/:id
  partial-merge handler.
- tests/admin_class_edit.test.tsx — 12 tests covering AC-1..AC-6
  + AC-8 (AC-7 satisfied by static FT-P-22 gate).
- tests/destructive_ux.test.tsx — adjacent-hygiene selector fix
  at 3 call sites: the new ✎ button moved the first-button
  position; targeting × explicitly preserves the existing
  it.fails()/control semantics.

Docs:
- _docs/02_document/components/08_admin/description.md — recorded
  edit affordance + PATCH wiring + AZ-513 cross-workspace note.
- _docs/03_implementation/batch_16_cycle4_report.md
- _docs/03_implementation/implementation_report_admin_class_edit_cycle4.md
- _docs/02_tasks/todo → done — AZ-512 archived.

Quality gates: 32 files / 243 tests / 13 quarantined skips PASS;
all 35 static checks PASS (FT-P-22/23, STC-ARCH-01/02, STC-SEC*,
banned-deps incl. SEC1B/C/D).

Cross-workspace dependency: admin/ AZ-513 (POST + PATCH + DELETE
/classes routes) NOT yet shipped. Step 11 (Run Tests) passes on
stubs; Step 16 (Deploy) holds until AZ-513 lands live. Leftover
record at _docs/_process_leftovers/2026-05-13_az-512-admin-
classes-prereq.md stays open.

Discovered pre-existing bug (NOT bundled): tests/msw/handlers/
admin.ts returns paginate(seedUsers) for GET /api/admin/users,
but AdminPage consumes as flat User[] → users.map crash. Test
files use the same flat-array workaround
destructive_ux.test.tsx documented. Flagged in batch + impl
reports for separate triage.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 04:35:13 +03:00
Oleksandr Bezdieniezhnykh ef56d9c207 [AZ-512] chore: reactivate for cycle 4 (Option B path)
User authorized Option B from the original AZ-512 Cross-Workspace
Verification gate: implement UI form with MSW-stubbed tests in
parallel with AZ-513 shipping on admin/. Task spec moved from
backlog/ → todo/. STATUS line updated. Leftover record re-opened
until AZ-513 deploys live.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 04:21:32 +03:00
Oleksandr Bezdieniezhnykh eef3bdf7db [AZ-509][AZ-510][AZ-511] Cycle 3 closure: deploy + retro + state
Steps 16 (Deploy) and 17 (Retrospective) outputs for cycle 3.

- 03_implementation/deploy_cycle3_report.md — ui/ dev pushed
  (15838c5..09449bd, 5 commits); stage/prod cutover deferred
  per push-scope gate option A.
- 06_metrics/retro_2026-05-13_cycle3.md — cycle 3 retro: 6/9
  pts shipped (AZ-510, AZ-511); AZ-512 deferred to backlog
  at cross-workspace prereq gate (AZ-513 filed on admin/).
- 06_metrics/structure_2026-05-13.md — structural snapshot
  referenced by retro.
- LESSONS.md — appended 3 cycle-3 lessons (process x2,
  architecture x1).
- _autodev_state.md — cycle 3 closed; cycle 4 Step 9 not
  started.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 04:15:37 +03:00
Oleksandr Bezdieniezhnykh 09449bda2c [AZ-510][AZ-511][AZ-512][AZ-513] Cycle 3 Steps 12-15 + admin prereq
ci/woodpecker/push/build-arm Pipeline failed
Wrap up cycle 3 across the autodev existing-code Phase B steps that
follow Implement (Steps 12-15), plus the cross-workspace prerequisite
ticket filed for AZ-512.

Step 12 - Test-Spec Sync:
- Un-quarantine FT-P-01 in traceability-matrix (closed by AZ-510)
- Add AZ-510 chained /users/me failure-path test reference under AC-23
- Note AZ-512 deferral status under O9 (P12 Phase B target)

Step 13 - Update Docs (task mode):
- Refresh src__auth__AuthContext module doc with AZ-510 wire shape
  (POST refresh + chained /users/me + bootstrapInflight guard)
- Add usersMe() to src__api__endpoints module doc + consumer note
- Rename src__features__annotations__classColors module doc to
  src__class-colors__classColors (matches AZ-511 git mv); refresh header
- Refresh src__components__DetectionClasses + src__features__annotations
  module group doc for the new class-colors barrel import path
- Update components/11_class-colors Module Inventory to point at the
  renamed module doc filename
- Rewrite system-flows.md Flow F2 (Bearer auto-refresh) with the AZ-510
  POST + chained /users/me sequence; close Finding B3 references
- Generate ripple_log_cycle3 documenting all changed source files,
  their reverse-dependency search results, and the docs touched

Step 14 - Security Audit (cycle-3 delta):
- Resume mode against cycle-2 baseline; cycle-2 artifacts untouched
- Re-run bun audit on both roots: clean (cycle-2 inline fix held)
- Re-rate OWASP A06: FAIL -> PASS; A07: PASS_WITH_KNOWN -> PASS (B3
  closed by AZ-510)
- New finding F-SAST-CY3-1 (LOW): __resetBootstrapInflightForTests
  exposed via src/auth public barrel; defer to hygiene cycle
- Verdict: FAIL -> PASS_WITH_WARNINGS; one HIGH (F-SAST-1
  mission-planner git-history key, unchanged) remains
- Add amendment banner to cycle-2 security_report.md

Step 15 - Performance Test:
- Static profile NFT-PERF-01 PASS (290 575 B gzipped vs 2 MB budget;
  ~14% of budget; no regression from AZ-510 surface additions)
- E2E profile SKIP (Playwright perf project still pending AZ-457..AZ-482);
  legitimate skip per test-run skill, gap acknowledged in report
- AZ-510 200ms p95 chain NFR verified at spec level only - no CI gate
  yet (covered by future AZ-457..AZ-482 work)

Cross-workspace prerequisite (AZ-513 just filed):
- Updated _docs/_process_leftovers/2026-05-13_az-512-admin-classes-prereq.md
  to reflect AZ-513 filing on admin/ workspace (parent epic AZ-509,
  Blocks link to AZ-512). Companion task spec added in admin/ repo
  (separate commit there, owned by admin/ workspace).

State file: advanced to Step 16 (Deploy) per autodev existing-code flow.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 03:58:21 +03:00
Oleksandr Bezdieniezhnykh 6c7e29722f [AZ-512] Defer to backlog at cross-workspace BLOCKING gate
AZ-512 (Admin edit detection class) hit its spec-defined Cross-Workspace
Verification gate during cycle 3 batch 15. The admin/ service
(Azaion.AdminApi/Program.cs) exposes /login, /users*, /resources* only — no
/classes routes exist, so neither the PATCH this task needs nor the
POST/DELETE that AdminPage.tsx already calls today are wired end-to-end.

Per the spec's Choose A/B/C (user skipped, defaulted to A): file a
prerequisite ticket on admin/ and pause AZ-512 in backlog/. AZ-510 + AZ-511
already shipped this cycle; cycle 3 closes with 6 of 9 points delivered.

- Move AZ-512 spec from todo/ to backlog/ with a STATUS banner.
- Add Jira comment on AZ-512 documenting the blocker + replay path.
- Write leftover record _docs/_process_leftovers/2026-05-13_az-512-...
  capturing the full prerequisite payload (suggested ticket summary,
  description, ACs, story points) and the side observation that the
  existing add+delete affordances on the Detection Classes table are
  also broken end-to-end against admin/ (pre-existing bug, NOT
  introduced by cycle 3).
- Write batch 15 deferral report.
- Write Product Implementation Completeness Gate report (PASS for
  AZ-510 + AZ-511; AZ-512 deferred is outside the gate's scope).
- Write final cycle 3 implementation report with handoff to Step 11.
- Advance state: step 10 -> step 11 (Run Tests).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 03:16:39 +03:00
Oleksandr Bezdieniezhnykh c368f60853 [AZ-511] classColors carve-out to src/class-colors/ (closes F3)
Move src/features/annotations/classColors.ts to its own component directory
src/class-colors/ with a proper barrel; update the 4 consumer imports to go
through the barrel; remove the F3-pending exemption from STC-ARCH-01 and from
the architecture test fixture; clean up the 5 coupled doc/script touchpoints.
Closes baseline finding F3 and retires the 5-coupled-places carry-over surface
logged in LESSONS.md 2026-05-12.

- Add `class-colors` to scripts/check-arch-imports.mjs COMPONENT_DIRS so deep
  imports past the new barrel are caught symmetric to every other component.
- Replace the architecture test "exemption WORKS" fixture with the stronger
  "deep import into class-colors NOW FAILS" assertion (Risk 4 mitigation).
- module-layout.md: Layout Rules + Per-Component Mapping (11_class-colors,
  06_annotations, 03_shared-ui) + Verification Needed #1 + shared/class-colors
  block all updated to reflect the new home.
- 11_class-colors/description.md: Caveats §7 + Module Inventory updated.
- architecture_compliance_baseline.md: F3 marked CLOSED with full pre-resolution
  context preserved (mirrors AZ-485/F4 + AZ-486/F7 pattern); F4 carry-forward
  exemption note retired.
- 04_verification_log.md: open questions #1 + #8 marked RESOLVED.
- Build passes with no circular-import warnings (AC-4); fast suite 231/13
  skipped green (AC-5); static profile green (AC-3 — zero exemptions remain).

Batch report: _docs/03_implementation/batch_14_cycle3_report.md

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 03:08:36 +03:00
Oleksandr Bezdieniezhnykh 70fb452805 [AZ-510] Auth bootstrap: POST refresh + chained /users/me
Replace the broken `GET /api/admin/auth/refresh` (no `credentials:'include'`)
mount-time bootstrap with `POST /api/admin/auth/refresh` (with credentials)
chained to `GET /api/admin/users/me`. Returning users with a valid HttpOnly
refresh cookie no longer flash through `/login`. Closes Finding B3 / Vision P3.

- Add module-scoped `bootstrapInflight` guard (StrictMode double-mount safety)
  + test-only reset hook exported via the `src/auth` barrel; `tests/setup.ts`
  resets it in `afterEach` to prevent pending-promise leakage between tests.
- Defensive `hasPermission` against legacy `/users/me` payloads omitting
  `permissions`; default MSW handler now seeds `permissions` explicitly.
- Add `endpoints.admin.usersMe()` builder (STC-ARCH-02 forbids the literal).
- Bulk-swap 15 test files from `http.get` -> `http.post` for the refresh
  override so intentional bootstrap-fail tests still fail correctly.
- Update auth component description; mark B3 closed.
- Code review verdict PASS; static + fast suites green (231 / 13 skipped).

Batch report: _docs/03_implementation/batch_13_cycle3_report.md

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 02:59:31 +03:00
Oleksandr Bezdieniezhnykh 098a556460 [AZ-509] [AZ-510] [AZ-511] [AZ-512] Cycle 3 new-task: epic + 3 task specs
Recovers cycle 3 Step 9 (New Task) outputs that were left uncommitted at
the prior session boundary. Adds AZ-509 epic to dependencies table and
the three task specs (AZ-510 auth bootstrap consolidation, AZ-511
classColors carve-out, AZ-512 admin edit detection class). Advances
autodev state to step 10 (Implement) in_progress.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 02:39:21 +03:00
Oleksandr Bezdieniezhnykh 15838c5cc1 Update autodev state and lessons documentation
ci/woodpecker/push/build-arm Pipeline failed
- Changed current step from 15 (Performance Test) to 9 (New Task) in _docs/_autodev_state.md, reflecting the transition to Cycle 3.
- Updated cycle count from 2 to 3 and modified sub-step details to indicate progress in gathering feature descriptions.
- Added new lessons to _docs/LESSONS.md, emphasizing best practices for API key management, dependency handling, and reporting inline fixes during security audits.
- Enhanced CI/CD pipeline documentation in _docs/02_document/deployment/ci_cd_pipeline.md to include new gates for vulnerability scans and SBOM emissions, along with dependency overrides for transitive dependencies.
- Expanded environment strategy documentation in _docs/02_document/deployment/environment_strategy.md to include the new Google Geocode API key management.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 22:49:38 +03:00
Oleksandr Bezdieniezhnykh f7dd6c98d8 [AZ-501] [AZ-502] Cycle 2 Step 14 security audit + inline fixes
ci/woodpecker/push/build-arm Pipeline failed
Security audit (5 phases) → reports under _docs/05_security/.

AZ-501 (F-SAST-1, HIGH): Externalize hardcoded Google Geocode key
from mission-planner/src/config.ts to VITE_GOOGLE_GEOCODE_KEY via
new GeocodeService.ts; fail-soft warn when unset; STC-SEC1D static
deny-list gate; +5 unit tests in tests/mission_planner_geocode.test.ts.

AZ-502 (F-DEP-1, HIGH): Force vite>=6.4.2 and postcss>=8.5.10 via
package.json overrides in both roots; clean reinstall clears all
bun audit advisories.

Test-spec sync (Step 12) + Update Docs (Step 13) deltas: AC-43, AC-44,
NFT-SEC-09b, FT-P-61, FT-N-17, ripple log, batch_12 report.

Pending user actions: revoke Google + OWM keys (AC-6 / AZ-499 AC-7).

229 PASS / 13 SKIP / 0 FAIL on static + fast suites.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 05:31:11 +03:00
Oleksandr Bezdieniezhnykh b016fd8207 [AZ-498] [AZ-499] Cycle 2 batch 11: satellite tiles + OWM hardening
AZ-498 — self-hosted satellite tiles + drop classic/satellite toggle:
- Single TILE_URL via getTileUrl() (mirrors getOwmBaseUrl/getApiBase
  pattern from AZ-449/AZ-450); env-var VITE_SATELLITE_TILE_URL with
  dev default http://localhost:5100/tiles/{z}/{x}/{y}.
- FlightMap + MiniMap render one TileLayer with
  crossOrigin="use-credentials" so Leaflet's <img> tile fetcher
  attaches the same-origin satellite-provider auth cookie.
- ImportMetaEnv + .env.example collapse the prior OSM/Esri pair into
  one var. The flights.planner.satellite i18n key is removed in
  lockstep across en.json + ua.json (parity preserved).
- E2E harness wired end-to-end: compose passes the new var to
  azaion-ui; tile-stub serves /tiles/{z}/{x}/{y} with
  Content-Type=image/jpeg + Cache-Control + ETag matching the
  contract; infrastructure.e2e.ts AC-2 asserts the new path; dead
  OSM defenses removed from EXTERNAL_HOSTS route guard.
- Fast-profile MSW handlers rewritten for the cookie-auth path shape.
- 8 colocated fast tests under src/features/flights/__tests__/.

AZ-499 — mission-planner OWM env-var hardening + AZ-482 source-scan
gap close:
- WeatherService.ts reads VITE_OWM_API_KEY + VITE_OWM_BASE_URL;
  fail-soft null when key unset (mirrors AZ-448 main-SPA contract).
  Public signature getWeatherData(lat, lon) preserved.
- mission-planner/.env.example + vite-env.d.ts declare both vars.
- New owm_key_in_source banned-deps kind scans src/ AND
  mission-planner/ for the rotated literal; STC-SEC1C row added to
  scripts/run-tests.sh; check-banned-deps.mjs dispatch extended.
- 7 fast tests under tests/mission_planner_weather.test.ts cover
  AC-1..AC-4 + trailing-slash + happy path + network-error fail-soft.

Spec drift (recorded in batch_11_report.md, user-approved Choose B
on 2026-05-12):
- AZ-498 AC-8 dropped (named tile_split_zoom* files belong to AZ-474
  image-annotation surface, not map tiles).
- 4 missing files added in-scope (msw tiles handler, tile-stub
  server, compose env, dead VITE_TILE_BASE_URL replaced).
- AZ-499 STC-S6 ID conflict resolved by using STC-SEC1C.

Pending USER ACTION (BLOCKING for AZ-499 close):
- Revoke OpenWeatherMap key 335799082893fad97fa36118b131f919 at
  home.openweathermap.org/api_keys; capture evidence on AZ-499.

Cross-workspace deploy gate (handled at autodev Step 16, not a
Step-10 blocker for AZ-498):
- satellite-provider cookie-auth on GET /tiles/{z}/{x}/{y}
  (separate AZAION ticket on the satellite-provider workspace).

Reports: _docs/03_implementation/batch_11_report.md and
_docs/03_implementation/reviews/batch_11_review.md (verdict
PASS_WITH_WARNINGS — 1 Low, pre-existing trim-trailing-slash
duplication across vite roots).

Static gates: STC-ARCH-01, STC-ARCH-02, STC-T1, STC-FP22, STC-FP23,
STC-SEC1C all PASS post-refactor. +15 fast tests; +1 STC-SEC1C row.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 04:34:39 +03:00
Oleksandr Bezdieniezhnykh 20a39d3d8a [AZ-497] [AZ-498] [AZ-499] Cycle 2 New Task: epic, stories, contract draft
Closes autodev existing-code Step 9 for cycle 2.

- Epic AZ-497 (Self-Hosted Satellite Tiles - SPA Integration) added
  to _docs/02_tasks/_dependencies_table.md as the cycle-2 umbrella.
- AZ-498 (5 pts): self-hosted satellite tiles + drop map-type toggle.
  Cross-workspace prereq: satellite-provider must add cookie-auth on
  GET /tiles/{z}/{x}/{y} before merge (user files separately).
- AZ-499 (2 pts): mission-planner OWM env-var hardening + closes the
  AZ-482 source-scan gap with a new owm_key_in_source banned-deps kind.
- Contract _docs/02_document/contracts/satellite-provider/tiles.md
  v1.0.0 (draft): slippy-tile XYZ shape both sides commit to.
- _docs/_autodev_state.md: Step 9 closure note + advances pointer to
  Step 10 (Implement) for cycle 2.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 03:45:44 +03:00
Oleksandr Bezdieniezhnykh d7fff1374c Update autodev state and lessons documentation
ci/woodpecker/push/build-arm Pipeline was successful
- Changed current step from 16 (Deploy) to 9 (New Task) and updated cycle from 1 to 2 in _docs/_autodev_state.md.
- Closed Cycle 1 (Phase B) and noted that Steps 14, 15, and 16 were skipped due to no changes in auth, wire, or performance surfaces.
- Added new lessons to _docs/LESSONS.md, including insights on architecture gates and handling state discrepancies during session resumes, sourced from recent retrospectives.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 01:07:48 +03:00
Oleksandr Bezdieniezhnykh 17d5bb45e7 [AZ-485] [AZ-486] Cycle 1 docs refresh (Step 13)
ci/woodpecker/push/build-arm Pipeline was successful
Phase B cycle 1 was a structural refactor only: F4 (barrel imports +
STC-ARCH-01) and F7 (endpoint builders + STC-ARCH-02). This commit
brings docs in line with source after the cycle, no code changes.

Module docs (12 consumers): swap every /api/<service>/... literal in
code snippets and integration tables for the matching endpoints.*
builder; note the barrel import migration in Dependencies.

New module doc: src__api__endpoints.md (public surface, F4 barrel
re-export note, STC-ARCH-02 enforcement, contract-test reference).

Architecture compliance baseline: mark F4 + F7 CLOSED with commit
hashes (23746ec, 8a461a2).

01_api-transport component description: add endpoints.ts + barrel to
Internal Interfaces, close the F7 caveat, extend Module Inventory.

ripple_log_cycle1.md: Task Step 0.5 reverse-dep analysis records the
import-graph closure (no extra docs needed beyond the direct set).

Carry-over reports landed alongside the docs:
- test_run_report_phase_b_cycle1.md (Step 11 outcome)
- implementation_report_refactor_phase_b_cycle1.md (cycle summary)

State file: trimmed to the autodev <30-line target; Steps 14 + 15
recorded as SKIPPED with rationale (no security or perf surface
changed in this cycle); pointer moved to Step 16 (Deploy).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-12 00:01:04 +03:00
Oleksandr Bezdieniezhnykh 8a461a2051 [AZ-486] F7 endpoint builders + STC-ARCH-02 (cycle 1 close)
Single source of truth for every /api/<service>/... URL the UI talks to:
src/api/endpoints.ts (25 typed builders) re-exported via the F4 barrel.
Migrates 13 production callsites in admin / annotations / flights /
settings / dataset / auth / api-client / FlightContext / DetectionClasses
to endpoints.* . Adds the STC-ARCH-02 static gate (--mode=api-literals
in scripts/check-arch-imports.mjs, wired into scripts/run-tests.sh)
that fails any new hardcoded /api/<service>/ literal in src/ outside
endpoints.ts and *.test.tsx? files.

Tests: +36 contract assertions in src/api/endpoints.test.ts (every
builder, character-identical), +6 STC-ARCH-02 architecture cases in
tests/architecture_imports.test.ts (single / double / template literal
fail paths, *.test.* exemption, line-comment skip, migrated codebase
pass). Fast profile 167 -> 209 PASS / 13 SKIP / 0 FAIL, +42 new,
0 regressions. Static profile 31 / 31 PASS.

Closes architecture baseline finding F7. Cycle 1 of Phase B closed.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 23:03:45 +03:00
Oleksandr Bezdieniezhnykh 23746ec61d [AZ-485] Add Public API barrels + STC-ARCH-01 (F4 close)
Closes architecture baseline finding F4. Every component now exposes
its Public API through `src/<component>/index.ts`; cross-component
imports go through the barrel. `scripts/check-arch-imports.mjs` plus
`STC-ARCH-01` in the static profile enforce the rule; tests in
`tests/architecture_imports.test.ts` cover AC-4/AC-5 + 2 exemption
cases. One F3-pending exemption (`classColors`) is documented in 5
places (barrel, consumer, script, doc, test) to avoid a circular
import.

Phase B cycle 1 batch 1 of 2 (epic AZ-447). Batch 2 is AZ-486
(endpoint builders) — blocked on this commit landing.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 10:33:30 +03:00
Oleksandr Bezdieniezhnykh 2071a24391 [AZ-485] [AZ-486] Phase B Step 9: F4 barrels + F7 endpoints task specs
ci/woodpecker/push/build-arm Pipeline was successful
Closes Step 9 New Task cycle 1. Two refactor tasks created under epic
AZ-447 to address architecture compliance baseline findings:

- AZ-485 (5 pts) — F4 Public API barrels per component + STC-ARCH-01
- AZ-486 (5 pts) — F7 endpoint builders (endpoints.ts) + STC-ARCH-02
  (depends on AZ-485; Jira "Blocks" link set)

F1 (mission-planner duplication) deliberately deferred. Baseline routes
it through 7+ Phase B port-group cycles requiring decompose pass into
its own Epic; out of scope for new-task.

_autodev_state.md advances to Step 10 (Implement), awaiting invocation
for AZ-485 first.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 10:14:12 +03:00
Oleksandr Bezdieniezhnykh 892654ae93 [AZ-456] Fix playwright-runner Dockerfile: install unzip before bun
ci/woodpecker/push/build-arm Pipeline was successful
The Playwright base image
(mcr.microsoft.com/playwright:v1.49.1-noble) ships without
unzip, which bun's curl|bash installer requires:

  error: unzip is required to install bun
  process "/bin/sh -c curl -fsSL https://bun.sh/install ..."
    did not complete successfully: exit code: 1

Found while user asked the agent to attempt to bring up the
suite-e2e compose stack. Latent bug — the runner image had
never been built successfully in any local workspace before.

Test report (test_run_report.md) updated with the concrete
error trace from the up attempt: the 6 azaion/<S>:test
service images are pull-access-denied (not in any reachable
registry from this host), confirming the legitimate
external-service env block. Local-build half (azaion-ui,
owm-stub, tile-stub, playwright-runner) is healthy.

No e2e tests were executed; Step 7 verdict unchanged
(PASS_WITH_DOCUMENTED_GATE; e2e deferred to CI / merge lane).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 07:13:39 +03:00
Oleksandr Bezdieniezhnykh d696a20ad7 [AZ-455] Step 8 skipped (user choice); enter Step 9 New Task
ci/woodpecker/push/build-arm Pipeline was successful
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 06:45:35 +03:00
Oleksandr Bezdieniezhnykh 9025834c51 [AZ-455] Step 7 Run Tests PASS_WITH_DOCUMENTED_GATE
- static profile: 29/29 PASS (~13s)
- fast profile:   163 PASS / 13 SKIP / 0 FAIL across 26 files (~14.6s)
- e2e profile:    user-approved env-block (suite service :test
  images not available locally, not buildable from sibling
  repos today, registry auth not configured in this workspace).
  Deferred to CI / merge lane with registry access.
- 13 skips: all user-approved as Phase B feature quarantines
  paired with control PASS tests; tracked in F-CUM-3 / F-CUM-5
  drift backlog.
- System-Under-Test Reality Gate: PASS (no internal modules
  faked; only external suite services are stubbed).

Step 7 closes; advance to Step 8 (Refactor — optional).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 06:43:54 +03:00
Oleksandr Bezdieniezhnykh 2ea8d3ebdf [AZ-455] Step 6 close: implementation_report_tests.md + advance to Step 7
ci/woodpecker/push/build-arm Pipeline was successful
Final test-implementation report with handoff to test-run
skill per implement skill Step 16 (next flow step is Run
Tests; let test-run own the full-suite gate to avoid
duplicate runs).

27 test tasks delivered across 8 batches (1 + 4*6 + 4 + 2);
0 production source mutations; 26/26 ACs covered; 23
production drifts pinned to runnable contract tests; 29
commit-time static gates active (up from 13 at baseline).

State: existing-code Step 7 (Run Tests), not_started.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 06:18:10 +03:00
Oleksandr Bezdieniezhnykh c16c9d8bbb [AZ-455] Cumulative review batches 07-08 (cycle close, PASS_WITH_WARNINGS)
ci/woodpecker/push/build-arm Pipeline was successful
K=3 cadence cumulative review for the final 2 batches of
Phase A. Verdict: PASS_WITH_WARNINGS (0 Critical / 0 High;
F-CUM-5 lifts production-drift backlog to 23 entries;
F-CUM-4 long-running soak tagging carries over).

Phase A is now COMPLETE: 25 test tasks delivered across 8
batches; 0 production source mutations; 26/26 ACs covered
in this window; 100% cumulative AC coverage; 29 commit-time
static gates active.

Next autodev action: Step 7 (Run Tests).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 06:15:46 +03:00
Oleksandr Bezdieniezhnykh f2451944fd [AZ-474] [AZ-480] Batch 8 - tile-split + nginx/image static checks (Phase A close)
- AZ-474 tile-split + YOLO parser + auto-zoom + indicator +
  malformed (FT-P-51..55, FT-N-10): 13 fast (6 it.fails for
  AC-1..6 + 7 controls) + 2 e2e (test.fail for FT-P-51 +
  FT-P-53). The split surface is QUARANTINED today (D11) —
  no Split-tile button, no parser, no <TileViewer>; all 6
  ACs are documented drift, every it.fails paired with a
  control PASS pinning current behaviour.
- AZ-480 prod image + nginx routing + RAM (NFT-RES-LIM-02
  /03/08/09/10): 4 new static checks promoted into the
  per-commit profile (STC-RES02 500M cap, STC-RES03
  Dockerfile final-stage nginx:alpine no Node, STC-RES09
  exactly 9 /api/* location blocks, STC-RES10 prefix-strip
  on every route). 3 e2e (docker-no-Node probe, runtime
  prefix-strip, long-running RAM soak — all gated on docker
  availability + image build; RAM soak also on
  RUN_LONG_RUNNING=1).

Phase A — One-time baseline setup is now COMPLETE. The
todo/ directory is empty after this batch's archival.
Cumulative review for batches 07-08 is the next autodev
action; after that, Step 7 (Run Tests) auto-chains.

Code review: PASS (0 findings). Fast: 26/26 files, 163
passed / 13 skipped. Static: 29/29 PASS (incl. 4 new
STC-RES* gates).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 06:12:29 +03:00
Oleksandr Bezdieniezhnykh cdebfccada [AZ-471] [AZ-473] [AZ-478] [AZ-479] Batch 7 - canvas/photo-mode/network/perf tests
ci/woodpecker/push/build-arm Pipeline was successful
- AZ-471 CanvasEditor draw + 8-handle resize PASS (FT-P-39 fast +
  e2e + FT-P-40 8 sub-tests). Three drifts pinned via it.fails():
  Ctrl+click multi-select (FT-P-41), Ctrl+wheel zoom-around-cursor
  (FT-P-42), Ctrl+drag empty-canvas pan (FT-P-43) — all rooted in
  handleMouseDown's early Ctrl-gate and handleWheel's
  pan-not-adjusted bug.
- AZ-473 PhotoMode 3 ACs all PASS in fast + e2e (FT-P-48 switch
  filter, FT-P-49 auto-select, FT-P-50 yoloId wire across modes
  P=0/20/40 — outbound classNum == classId + photoModeOffset).
- AZ-478 fast 7 + e2e 2: AC-1 user-visible offline indicator,
  AC-2 tainted-canvas fallback, AC-3 SSE disconnect banner —
  all drift today (it.fails fast + test.fail e2e + control
  PASS for each). Service-worker negative check passes.
- AZ-479 AC-1 (bundle <= 2 MB gzipped) promoted from
  on-demand perf script to per-commit static profile via new
  STC-PERF01 row + static_check_bundle_size in run-tests.sh.
  AC-2 (mission-planner exclusion) already covered by STC-S5.
  AC-3 FCP /flights <= 3 s median (chromium suite-e2e) and
  AC-4 30-min annotation soak (RUN_LONG_RUNNING=1, chromium)
  scaffolded as e2e tests.

Code review: PASS (0 findings). Fast: 25/25 files, 150 passed
/ 13 skipped. Static: 25/25 PASS (incl. new STC-PERF01).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 05:58:55 +03:00
Oleksandr Bezdieniezhnykh 73e2cfb1eb [autodev] Cumulative review (batches 04-06) — PASS_WITH_WARNINGS
ci/woodpecker/push/build-arm Pipeline was successful
- 38/38 ACs covered across 12 tasks; no silent failures.
- 0 Critical, 0 High, 2 Low (drift backlog F-CUM-3 carried+
  extended; long-running soak gating F-CUM-4 — both bookkeeping
  for Phase B / Step 7).
- Phase 7: no production source mutated outside batch 4 test
  infrastructure; no new cyclic deps; F1-F9 baseline unchanged.
- LESSONS.md entry captures vi.stubGlobal('URL', ...) anti-
  pattern surfaced during AZ-476 debugging.
- Implement skill cleared to batch 7 (AZ-471, AZ-473, AZ-474,
  AZ-478, AZ-479, AZ-480 — 6 tasks remain).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 05:23:53 +03:00
Oleksandr Bezdieniezhnykh bd2b718ddf [AZ-463] [AZ-469] [AZ-476] [AZ-477] Batch 6 - flight/responsive/upload/settings tests
- AZ-463 flight selection persistence (FT-P-16) + rehydration
  on boot (FT-P-17) PASS at the wire; 100-cycle leak guard
  (NFT-RES-LIM-07) and 1h SSE soak (NFT-RES-LIM-06)
  scaffolded as RUN_LONG_RUNNING-gated e2e companions.
- AZ-469 browser-support smoke (FT-P-34) runs in both
  Chromium and Firefox via the existing playwright config;
  responsive variants (FT-P-35 480px / FT-P-36 1024px) PASS
  in fast (Tailwind class shape) and e2e (visibility).
- AZ-476 upload 501 MB -> 413: AC-1 user-visible error is
  drift today (uploadFiles silently falls through to local
  mode); it.fails() + control + e2e test.fail. AC-2 no-alert
  PASS via dialog spy.
- AZ-477 settings save 500 / network drop: AC-1+AC-2+AC-3
  all drift today (no try/finally, no error region, deadline
  unmeasurable); 4 it.fails() + control pinning the stuck-
  disabled drift; e2e companions test.fail mirror it.
- LESSONS.md seeded: vi.stubGlobal('URL', {...URL,...})
  destroys the URL constructor and breaks new URL(...) in
  MSW; patch the methods directly instead.

Code review: PASS (0 findings). Fast: 22/22 files, 120
passed / 13 skipped. Static: 24/24 PASS.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 05:19:35 +03:00
Oleksandr Bezdieniezhnykh 6d03643c2c [AZ-461] [AZ-464] [AZ-470] [AZ-472] Batch 5 - detection/bulk-validate/panel-width/classes tests
ci/woodpecker/push/build-arm Pipeline was successful
- AZ-461 sync image detect URL canary (FT-P-11) PASS;
  async-video QUARANTINE (FT-P-12) + X-Refresh-Token drift
  (FT-P-13) recorded as it.fails() with controls.
- AZ-464 bulk-validate URL + UI sync (≤2 s) PASS;
  body shape drift {annotationIds,status} vs contract
  {ids,targetStatus:30} captured as it.fails().
- AZ-470 panel-width debounce + rehydration: entire task
  is Phase-B target (useResizablePanel has no PUT writer
  / no rehydration); 3 ACs as it.fails() with controls.
- AZ-472 DetectionClasses load + click + fallback PASS;
  hotkey arithmetic P=0 PASS, P=20/P=40 it.fails() for
  classes[idx+P]-against-dense-array drift.

Code review: PASS (0 findings). Fast: 18/18 files,
102 passed / 13 skipped. Static: 21/21 PASS.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 04:38:22 +03:00
Oleksandr Bezdieniezhnykh 1dd25edee3 [AZ-460] [AZ-462] [AZ-466] [AZ-475] Batch 4 - destructive UX/forms/overlay/save
AZ-466 — Destructive UX policy + ConfirmDialog a11y + no-alert (4pts):
  src/components/ConfirmDialog.test.tsx (8 fast),
  tests/destructive_ux.test.tsx (4 fast, AdminPage class-delete drift),
  e2e/tests/destructive_ux.e2e.ts. New static checks STC-SEC7 (alert
  allowlist) + STC-SEC8 (destructive-surfaces gated/drift) wired through
  scripts/check-banned-deps.mjs reading tests/security/banned-deps.json.

AZ-475 — Numeric form input rejection (2pts):
  tests/form_hygiene.test.tsx (3 fast). Documents two SettingsPage drifts:
  silent zero coercion via parseInt(v)||0 and labels missing htmlFor.

AZ-462 — Overlay membership at in-window edges (2pts):
  tests/overlay_membership.test.tsx (6 fast). Documents getTimeWindowDetections
  strict < drift; AC-1 boundary tests are it.fails(); AC-2 / control PASS.
  Mocks HTMLCanvasElement.getContext to capture strokeRect.

AZ-460 — Annotation save URL + payload contract (2pts):
  tests/annotations_endpoint.test.tsx (6 fast),
  e2e/tests/annotations_endpoint.e2e.ts. AC-1 URL canary PASSes; AC-2
  payload missing 4 fields documented as it.fails(); AC-3 manual-draw
  PASS, AI-suggestion-accept + bulk-edit-save QUARANTINE skip.

Test infrastructure:
  - tests/setup.ts: NoopResizeObserver + NoopEventSource JSDOM polyfills.
  - tests/msw/handlers/annotations.ts: doubly-prefixed paths matching
    production calls (e.g. /api/annotations/annotations).
  - tests/msw/handlers/flights.ts: plural /aircrafts paths.

Verification: bun run test:fast → 80 passed, 13 skipped (14 files).
scripts/run-tests.sh --static-only → 24/24 PASS (was 22; +STC-SEC7/SEC8).
Per-batch self-review verdict: PASS_WITH_WARNINGS. Cumulative review
of batches 04-06 due after batch 6 per implement/SKILL.md Step 14.5.
Report: _docs/03_implementation/batch_04_report.md.

Also includes the previously-untracked
_docs/03_implementation/cumulative_review_batches_01-03_report.md
generated at the start of this session before batch 4 began.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 04:15:01 +03:00
Oleksandr Bezdieniezhnykh 2051088706 [AZ-458] [AZ-467] [AZ-468] [AZ-482] Batch 3 - SSE/RBAC/Header/security tests
Implements 4 blackbox-test tasks for AZ-455 Phase A baseline:

- AZ-458 SSE lifecycle + bearer rotation: 9 fast tests (8 pass, 1
  QUARANTINE for annotation-status); 4 e2e scenarios (gated by suite
  stack). Uses tests/helpers/sse-mock.ts with globalThis.EventSource
  monkey-patch per AC-3 (no stub of src/api/sse.ts). AC-2 bearer
  rotation captured as documented drift via it.fails() — FlightsPage
  useEffect deps do not include the token today.

- AZ-467 ProtectedRoute spinner + timeout + RBAC: 9 new fast tests
  extending the AZ-457 file (6 pass, 3 QUARANTINE), plus 3 e2e
  scenarios. FT-P-32 spinner a11y is it.fails() drift; FT-P-33 timeout
  and FT-N-03/05 RBAC redirects are it.skip QUARANTINE (no production
  behavior today). Positive control: admin_carol reaches /admin.

- AZ-468 Header flight-dropdown a11y: 6 fast tests (5 pass, 1
  QUARANTINE). FT-P-30/31 are it.fails() drift (aria-expanded /
  role=listbox / aria-activedescendant currently missing); FT-N-09
  is it.skip QUARANTINE (no document keydown handler exists).

- AZ-482 Secrets + banned-libs + AC-N1 anti-criterion: 3 new static
  checks (STC-SEC13 legacy integrations, STC-SEC14 concurrent-edit,
  STC-SEC1B dist/ OWM key) plus refactor of 4 existing checks
  (STC-N2/N4/S13/S6) to read from tests/security/banned-deps.json
  via scripts/check-banned-deps.mjs per AZ-482 constraint
  ("deny-list lives in tests/security/banned-deps.json so additions
  are visible in code review"). All 22 static checks PASS.

Totals: 57 fast tests pass + 9 skipped; 22/22 static checks pass.
Self-review verdict PASS_WITH_WARNINGS — all five findings are
documented drifts captured by it.fails() / it.skip QUARANTINE +
control tests. See _docs/03_implementation/batch_03_report.md
for the per-task / per-AC matrix and recommended Phase B follow-up
production tasks (Header a11y; ProtectedRoute spinner/timeout/RBAC;
SSE bearer-rotation reconnect; AnnotationsPage SSE).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 03:46:18 +03:00
Oleksandr Bezdieniezhnykh 2e04a01ac9 chore: stop tracking dist/ build artifacts
/dist is already listed in .gitignore but three legacy files
(dist/index.html, dist/assets/index-B-KLvAXK.js,
dist/assets/index-Du68yxJU.css) remained in the index from before
the ignore rule was added. Untrack them so the working tree stays
clean across implement-skill batch cycles. Files remain on disk
where present; future build outputs will be ignored as intended.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 03:33:44 +03:00
Oleksandr Bezdieniezhnykh 13eca1b94a [AZ-455] [autodev] Batch 2 boundary: state pointer for batch 3
ci/woodpecker/push/build-arm Pipeline was successful
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 03:30:36 +03:00
Oleksandr Bezdieniezhnykh ab22223580 [AZ-457] [AZ-459] [AZ-465] [AZ-481] Batch 2 - auth/enum/i18n/CI tests
Implements 22 blackbox test scenarios across the four batch-2 tasks:

AZ-457 - Auth & token handling (11 scenarios, fast + e2e):
- src/api/client.test.ts: FT-P-02, NFT-SEC-04, NFT-PERF-02, NFT-RES-01,
  NFT-RES-08 (apiClient surface)
- src/auth/AuthContext.test.tsx: FT-P-01 (it.fails - Step 4 drift),
  FT-P-03, NFT-SEC-01, NFT-SEC-02
- src/auth/ProtectedRoute.test.tsx: FT-N-04, NFT-RES-08 (router half)
- e2e/tests/auth.e2e.ts: FT-P-02 e2e, NFT-SEC-01/02/03 (cookie attrs
  via Playwright context.cookies(), gated by suite stack)

AZ-459 - Wire-contract enums (4 scenarios):
- tests/wire_contract.test.ts: FT-P-04 (AnnotationStatus, it.fails),
  FT-P-05 (MediaStatus + Affiliation it.fails; CombatReadiness skip
  per verification_pending), FT-P-06 (AnnotationSource control +
  spec value-set membership), FT-N-15 (typed-enum shape + skip for
  value-set verification)
- e2e/tests/wire_contract.e2e.ts: FT-P-06 against real annotations/
  service, drift-gated via AZAION_RUN_DRIFT_E2E
- scripts/run-tests.sh STC-FN15: ripgrep static for MediaType
  magic-literal hygiene

AZ-465 - i18n (4 scenarios, all static + quarantined fast):
- scripts/check-i18n-coverage.mjs: FT-P-22 (en vs ua key parity) +
  FT-P-23 (no raw user strings outside t() in src/**/*.tsx); refined
  JSX text-node regex with negative lookbehind to drop TS generics
  + arrow-function false positives
- tests/i18n-allowlist.json: snapshot of current pre-existing raw
  strings (CI gates growth per AZ-465 Constraints)
- tests/i18n.test.tsx: FT-P-24 + FT-P-25 it.skip (QUARANTINE - i18n
  detector + persistence not wired today; control tests assert the
  gap so the skip flips to a real test once Step 4 lands)

AZ-481 - CI image labels (3 scenarios, static against
  .woodpecker/build-arm.yml):
- scripts/check-ci-image-labels.mjs: NFT-RES-LIM-11 (tag scheme
  ${CI_COMMIT_BRANCH}-arm), NFT-RES-LIM-12 (revision/created/source
  PASS, image.title reported as DRIFT - foundation/CI-CD owns the
  fix), NFT-RES-LIM-13 (revision = $CI_COMMIT_SHA)

Cross-cutting:
- scripts/run-tests.sh: src_grep now excludes *.test.{ts,tsx} +
  *.spec.{ts,tsx} so production-source static checks (STC-SEC4,
  STC-FN15, etc.) don't false-positive on test prose
- tsconfig.json: exclude src/**/*.{test,spec}.{ts,tsx} so production
  tsc -b doesn't see jest-dom matchers
- _docs/03_implementation/batch_02_report.md: full per-task AC
  coverage matrix + drift inventory + verification run
- _docs/_autodev_state.md: 22 tasks remain after batch 2

Verification (host):
  fast    : 7 files, 38 passed | 4 skipped (quarantined)
  static  : 19/19 checks PASS (was 13 in batch 1; +6 from batch 2)
  e2e     : not run on host (Risk 4 - requires suite docker stack)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 03:27:55 +03:00
Oleksandr Bezdieniezhnykh 496b089102 [AZ-456] Clarify Blackbox Tests imports rule (helpers vs test bodies)
ci/woodpecker/push/build-arm Pipeline was successful
Split the "Imports from" entry for the Blackbox Tests cross-cutting
component into two cases:

- Test bodies (*.test.{ts,tsx}, *.spec.{ts,tsx}, e2e specs) keep the
  strict "00_foundation only / src/types only" rule per black-box
  discipline (P9 / environment.md).
- Test infrastructure (tests/setup.ts, tests/msw/**, tests/helpers/**,
  tests/fixtures/**, e2e/playwright.config.ts, e2e/stubs/**, etc.) MAY
  import testability-purpose production accessors from any layer
  (e.g. setToken on 01_api-transport, AuthProvider on 02_auth, i18n
  on 00_foundation) — these helpers ARE the production-equivalent
  composition root for tests.

Surfaced during AZ-456 self-review when render.tsx / auth.ts /
navigate.ts had to import production accessors that the task spec
explicitly mandated. The original rule was unambiguous-but-incomplete;
the doc now matches the practical reality without weakening the
black-box discipline for test bodies themselves.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 03:01:31 +03:00
Oleksandr Bezdieniezhnykh 38eb87fb08 [AZ-456] Test infrastructure: Vitest + MSW + Playwright + scripts
Scaffolds the Blackbox test project per AZ-456 / environment.md across
the three profiles:

- fast  : Vitest 3.x + jsdom + MSW 2.x + RTL/jest-dom; tests/setup.ts
          boots the MSW Node server with onUnhandledRequest:'error',
          afterEach resets handlers, clears bearer + navigate-to-login
          spy. Default handlers ship for every suite service plus OWM
          and tile stand-ins. Fixtures mirror seed_* in test-data.md.
- e2e   : Playwright ^1.49 with chromium + firefox projects against the
          suite docker-compose stack; owm-stub + tile-stub Bun servers,
          playwright-runner image, seeds.sql for the test-db.
- static: scripts/run-tests.sh extended — tsc --noEmit (test config),
          vite build, ripgrep checks (with grep -r fallback), CSV
          report at test-output/static-report.csv per AC-7 columns.

Smoke tests cover AC-3, AC-4 (fast, 5 tests, PASS) and AC-1, AC-2,
AC-5, AC-8 (e2e, gated by Risk 4 docker availability). Static profile
(13 checks) PASS — STC-SEC1 (no literal OWM key) lifted from
QUARANTINE per AZ-447 with a narrowed pattern.

Files:
  +24 tests/**, +10 e2e/**, +vitest.config.ts, +tsconfig.test.json
  ~package.json (test scripts + devDeps for vitest, @testing-library/*,
   msw, @playwright/test, jsdom, @types/node, @vitest/coverage-v8)
  ~scripts/run-tests.sh, scripts/run-performance-tests.sh — switched
   RESULTS_DIR to test-output/, compose path to project-local
  ~.gitignore — added /test-output/

Verification:
  bun run test:fast        → 11 / 11 PASS
  ./scripts/run-tests.sh   → static 13/13 + fast 11/11 PASS, exit 0

Tracker: AZ-456 → In Testing.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 02:57:04 +03:00
Oleksandr Bezdieniezhnykh e5d9276b19 [AZ-456] [autodev] Implement phase 5 → 6 transition checkpoint
Records that batch 1 = [AZ-456] is computed, file-ownership envelope
resolved, and Jira ticket transitioned to In Progress. Next step:
write the test-infrastructure scaffold (~30 files) and run the fast
+ static profiles. Suggests a session boundary here per Context
Management Protocol so phase 6 starts with fresh context.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 01:58:20 +03:00
Oleksandr Bezdieniezhnykh 355317d7c2 [AZ-455] [autodev] Add Blackbox Tests component to module-layout
Adds a cross-cutting "Blackbox Tests" entry to
_docs/02_document/module-layout.md so the implement skill's Step 4
(file ownership) can resolve OWNED / READ-ONLY / FORBIDDEN globs for
every AZ-455 test task (AZ-456..AZ-482). Owns: tests/**, e2e/**,
**/*.{test,spec}.{ts,tsx}, vitest.config.ts, test sections of
package.json, scripts/run-tests.sh + run-performance-tests.sh
(extension only). Imports from src/types/index.ts only (P9 black-box
discipline). Advances Step 6 sub_step to phase 1 (parse).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 01:55:27 +03:00
Oleksandr Bezdieniezhnykh 15a878d6f1 [AZ-455] Decompose Step 3 — test task specs (AZ-457..AZ-482)
Adds 26 blackbox-test task specs under epic AZ-455 plus the matching
rows in _dependencies_table.md. Each task depends on AZ-456 (test
infrastructure). Advances autodev existing-code flow Step 5 → Step 6
(Implement Tests, cycle 1) ready for batch implementation.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 01:49:44 +03:00
Oleksandr Bezdieniezhnykh 83dee6759f [AZ-455] [AZ-456] Decompose Step 1t \u2014 test infrastructure task spec
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 00:59:46 +03:00
Oleksandr Bezdieniezhnykh 729ad1cac8 [AZ-447] Close testability refactor run; advance to Step 5
- Archive Batch 2 task specs (AZ-448, AZ-449, AZ-453) to
  _docs/02_tasks/done/.
- Write testability_changes_summary.md (refactor Phase 4.5; user-acked
  via autodev existing-code Step 4 gate).
- Write FINAL_report.md closing the 01-testability-refactoring run.
- Advance autodev state pointer to Step 5 (Decompose Tests).

Refactor Phases 5/6/7 are no-ops for testability runs (no tests exist
yet; doc updates are deferred to autodev Step 13). Verification axis
for this run is the static-check matrix recorded in
testability_changes_summary.md § Verification snapshot.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 00:50:33 +03:00
Oleksandr Bezdieniezhnykh ed81034511 [AZ-448] [AZ-449] [AZ-453] Externalize OWM config; wrap login redirect
Batch 2 of testability refactor under epic AZ-447. All three changes are
minimal-surgical and preserve production behavior.

AZ-448 (C01) — Externalize OWM API key
- src/features/flights/flightPlanUtils.ts: read VITE_OWM_API_KEY at call
  time; if unset, getWeatherData returns null (matches the existing
  try/catch fallback contract, AC-3).
- Hardcoded literal removed; grep src/ for the old key returns no hits
  (AC-2 / NFT-SEC-09 static-string check now green).
- AC-1 honored: when the key is set, the outbound URL contains
  appid=<key>.

AZ-449 (C02) — Externalize OWM base URL
- Same call site reads VITE_OWM_BASE_URL with trim-trailing-slash
  normalization; falls back to the public api.openweathermap.org/data/2.5
  endpoint when unset (AC-1).
- Stub-friendly: VITE_OWM_BASE_URL=http://owm-stub:8081/data/2.5
  redirects every call to the e2e stub (AC-2).

AZ-453 (C06) — Wrap login redirect in setNavigateToLogin accessor
- src/api/client.ts: navigateToLoginImpl module-level fn defaults to the
  existing window.location.href = '/login' write; setNavigateToLogin(fn)
  lets tests assert "redirect invoked" without globally stubbing
  window.location.
- request() now calls navigateToLoginImpl() instead of writing
  window.location directly.

Batch 1 task specs (AZ-450/451/452/454) moved from
_docs/02_tasks/todo/ to _docs/02_tasks/done/.

State pointer advanced to refactor Phase 4 (implement, batch 2 of 2).

Static checks:
- bun run tsc --noEmit: 0 errors
- grep '335799082893fad97fa36118b131f919' src/: 0 hits
- grep 'window.location.href' src/: 2 hits, both inside the
  navigateToLoginImpl default (jsdoc + the default impl body) — no
  caller writes window.location directly.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 00:44:00 +03:00
Oleksandr Bezdieniezhnykh db181043ca [AZ-450] [AZ-451] [AZ-452] [AZ-454] Externalize URLs + accessors
Refactor batch 1 of 2 for the 01-testability-refactoring epic
(AZ-447). Minimal-surgical edits to make the UI's external
dependencies overridable for the test profiles in
_docs/02_document/tests/environment.md.

- AZ-450 (C03): tile URLs externalized to VITE_OSM_TILE_URL and
  VITE_ESRI_TILE_URL with the production strings as defaults.
  Fixes the AC-N3 / NFT-RES-03 air-gap regression and lets the
  e2e profile's tile-stub serve tiles deterministically.
- AZ-451 (C04): Leaflet marker icon imported from the pinned
  leaflet package as a Vite asset; removes the unpkg.com CDN
  reference (also fixes the leaflet@1.7.1 vs ^1.9.4 mismatch).
- AZ-452 (C05): getApiBase() accessor reading
  VITE_API_BASE_URL. request(), refreshToken(), and createSSE()
  prepend the prefix. Default '' preserves every call site.
- AZ-454 (C07): JSDoc on setToken/getToken documenting the
  test-override intent so future cleanup doesn't delete them.

Also: .env.example documents every VITE_* var; vite-env.d.ts
declares ImportMetaEnv; .gitignore now excludes /dist and
*.tsbuildinfo (tracked-by-mistake cache file removed).

Build verification: `bunx tsc -b --noEmit` passes. No tests in
this run (testability-run exemption per refactor SKILL — tests
land in autodev Step 6).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 00:42:12 +03:00
Oleksandr Bezdieniezhnykh 510df68bcf [AZ-447] autodev Steps 1-4 baseline: docs, tests, refactor specs
Captures the full output of autodev existing-code Phase A through
Step 4 (Code Testability Revision) for the Azaion UI workspace:

- Step 1 Document: _docs/02_document/ (FINAL_report, architecture,
  glossary, components/, modules/, diagrams/, system-flows,
  module-layout) plus _docs/00_problem/ + _docs/01_solution/ +
  _docs/legacy/ + _docs/how_to_test + README.
- Step 2 Architecture Baseline: architecture_compliance_baseline.md.
- Step 3 Test Spec: _docs/02_document/tests/ (environment,
  test-data, blackbox/performance/resilience/security/
  resource-limit tests, traceability-matrix), enum_spec_snapshot,
  expected_results/results_report.md (98 rows), plus the
  run-tests.sh + run-performance-tests.sh runners.
- Step 4 Code Testability Revision: 01-testability-refactoring/
  run dir (list-of-changes C01-C07, deferred_to_refactor,
  analysis/research_findings + refactoring_roadmap) and the 7
  child task specs AZ-448..AZ-454 under _docs/02_tasks/todo/
  plus _dependencies_table.md.
- _docs/_autodev_state.md pins the cursor at Step 4 / refactor
  Phase 4 entry so /autodev resumes cleanly.

Epic AZ-447 (UI testability gates) tracks the 7 child tasks that
will land in subsequent commits.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 00:38:49 +03:00
Oleksandr Bezdieniezhnykh da0a5aa187 chore: sync .cursor from suite
ci/woodpecker/push/build-arm Pipeline was successful
2026-05-09 05:18:10 +03:00
Oleksandr Bezdieniezhnykh 19f4026e55 chore: sync .cursor from suite
ci/woodpecker/push/build-arm Pipeline was successful
2026-05-05 01:08:49 +03:00
Oleksandr Bezdieniezhnykh 7b65c8f5cd chore: sync .cursor skills from suite
ci/woodpecker/push/build-arm Pipeline was successful
2026-05-03 17:43:27 +03:00
Oleksandr Bezdieniezhnykh 87fd90f7da chore: sync .cursor skills from suite
ci/woodpecker/push/build-arm Pipeline was successful
2026-04-29 17:03:57 +03:00
Oleksandr Bezdieniezhnykh 601b11fea6 chore: sync .cursor from suite
ci/woodpecker/push/build-arm Pipeline was successful
Made-with: Cursor
2026-04-25 19:44:42 +03:00
Armen Rohalov b0829b4a90 feat(dataset): per-detection cards, in-browser editor, bulk-validate for local saves 2026-04-24 00:49:08 +03:00
Oleksandr Bezdieniezhnykh f8b214f86f fix build - bun.lock . Fix bun version
ci/woodpecker/push/build-arm Pipeline was successful
2026-04-22 21:03:19 +03:00
Armen Rohalov 1fa749382f Merge branch 'feat/mission-planner-integration' into dev
ci/woodpecker/push/build-arm Pipeline failed
2026-04-22 20:04:48 +03:00
Armen Rohalov 020bd2226b Merge branch 'feat/annotations' into dev 2026-04-22 20:03:04 +03:00
Oleksandr Bezdieniezhnykh e2cbe5556f Update Woodpecker CI configuration for Docker login and image tagging
ci/woodpecker/manual/build-arm Pipeline was successful
Replaced HARBOR_USER and HARBOR_TOKEN with REGISTRY_USER and REGISTRY_TOKEN for Docker login. Adjusted image tagging to include 'azaion' in the registry path, ensuring proper image management in the new TLS-authenticated Harbor registry.
2026-04-21 20:32:40 +03:00
Oleksandr Bezdieniezhnykh e0fef1634d [AZ-205] Authenticate to Harbor before pushing build images
Add HARBOR_USER/HARBOR_TOKEN from Woodpecker secrets and a docker login
step before the existing build/push, so pipelines can push to the new
TLS-authenticated Harbor registry.
2026-04-20 04:10:43 +03:00
Oleksandr Bezdieniezhnykh 47a5bed95b [AZ-204] OCI revision labels + AZAION_REVISION env
Made-with: Cursor
2026-04-20 03:58:48 +03:00
Oleksandr Bezdieniezhnykh 9a3456a421 [AZ-203] Parameterize registry host via REGISTRY_HOST secret
Pipeline reads $REGISTRY_HOST from the Woodpecker global secret
'registry_host' instead of hardcoding 'localhost:5000'. The full
host:port lives in the secret, so Harbor migration (AZ-205) becomes
one secret edit rather than editing every submodule pipeline.

Made-with: Cursor
2026-04-20 03:49:21 +03:00
Oleksandr Bezdieniezhnykh 5b0e53fbdb Sync .cursor from suite (autodev orchestrator + monorepo skills) 2026-04-18 22:04:31 +03:00
Armen Rohalov 63cc18e788 Enhance annotations: save/download, fallback classes, photo mode icons
Add local annotation save fallback, PNG+txt download with drawn boxes,
shared classColors helper, photo mode icon toggles, and react-dropzone
/ react-icons dependencies.
2026-04-17 23:33:00 +03:00
Oleksandr Bezdieniezhnykh f46531fc6d Refine coding standards and testing guidelines
- Updated coding rules to emphasize readability, meaningful comments, and maintainability.
- Adjusted test coverage thresholds to 75% for business logic and clarified expectations for test scenarios.
- Enhanced guidelines for handling skipped tests, emphasizing the need for investigation and resolution.
- Introduced a completeness audit for research decomposition to ensure thoroughness in addressing problem dimensions.

Made-with: Cursor
2026-04-17 20:29:15 +03:00
459 changed files with 56091 additions and 3149 deletions
+12 -12
View File
@@ -1,9 +1,9 @@
## How to Use
Type `/autopilot` to start or continue the full workflow. The orchestrator detects where your project is and picks up from there.
Type `/autodev` to start or continue the full workflow. The orchestrator detects where your project is and picks up from there.
```
/autopilot — start a new project or continue where you left off
/autodev — start a new project or continue where you left off
```
If you want to run a specific skill directly (without the orchestrator), use the individual commands:
@@ -19,13 +19,13 @@ If you want to run a specific skill directly (without the orchestrator), use the
## How It Works
The autopilot is a state machine that persists its state to `_docs/_autopilot_state.md`. On every invocation it reads the state file, cross-checks against the `_docs/` folder structure, shows a status summary with context from prior sessions, and continues execution.
The autodev is a state machine that persists its state to `_docs/_autodev_state.md`. On every invocation it reads the state file, cross-checks against the `_docs/` folder structure, shows a status summary with context from prior sessions, and continues execution.
```
/autopilot invoked
/autodev invoked
Read _docs/_autopilot_state.md → cross-check _docs/ folders
Read _docs/_autodev_state.md → cross-check _docs/ folders
Show status summary (progress, key decisions, last session context)
@@ -37,7 +37,7 @@ Execute current skill (read its SKILL.md, follow its workflow)
Update state file → auto-chain to next skill → loop
```
The state file tracks completed steps, key decisions, blockers, and session context. This makes re-entry across conversations seamless — the autopilot knows not just where you are, but what decisions were made and why.
The state file tracks completed steps, key decisions, blockers, and session context. This makes re-entry across conversations seamless — the autodev knows not just where you are, but what decisions were made and why.
Skills auto-chain without pausing between them. The only pauses are:
- **BLOCKING gates** inside each skill (user must confirm before proceeding)
@@ -49,13 +49,13 @@ A typical project runs in 2-4 conversations:
- Session 3: Implement (may span multiple sessions)
- Session 4: Deploy
Re-entry is seamless: type `/autopilot` in a new conversation and the orchestrator reads the state file to pick up exactly where you left off.
Re-entry is seamless: type `/autodev` in a new conversation and the orchestrator reads the state file to pick up exactly where you left off.
## Skill Descriptions
### autopilot (meta-orchestrator)
### autodev (meta-orchestrator)
Auto-chaining engine that sequences the full BUILD → SHIP workflow. Persists state to `_docs/_autopilot_state.md`, tracks key decisions and session context, and flows through problem → research → plan → decompose → implement → deploy without manual skill invocation. Maximizes work per conversation with seamless cross-session re-entry.
Auto-chaining engine that sequences the full BUILD → SHIP workflow. Persists state to `_docs/_autodev_state.md`, tracks key decisions and session context, and flows through problem → research → plan → decompose → implement → deploy without manual skill invocation. Maximizes work per conversation with seamless cross-session re-entry.
### problem
@@ -136,13 +136,13 @@ Bottom-up codebase documentation. Analyzes existing code from modules through co
7. /retrospective — metrics, trends, improvement actions → _docs/06_metrics/
```
Or just use `/autopilot` to run steps 0-5 automatically.
Or just use `/autodev` to run steps 0-5 automatically.
## Available Skills
| Skill | Triggers | Output |
|-------|----------|--------|
| **autopilot** | "autopilot", "auto", "start", "continue", "what's next" | Orchestrates full workflow |
| **autodev** | "autodev", "auto", "start", "continue", "what's next" | Orchestrates full workflow |
| **problem** | "problem", "define problem", "new project" | `_docs/00_problem/` |
| **research** | "research", "investigate" | `_docs/01_solution/` |
| **plan** | "plan", "decompose solution" | `_docs/02_document/` |
@@ -170,7 +170,7 @@ Or just use `/autopilot` to run steps 0-5 automatically.
```
_project.md — project-specific config (tracker type, project key, etc.)
_docs/
├── _autopilot_state.md — autopilot orchestrator state (progress, decisions, session context)
├── _autodev_state.md — autodev orchestrator state (progress, decisions, session context)
├── 00_problem/ — problem definition, restrictions, AC, input data
├── 00_research/ — intermediate research artifacts
├── 01_solution/ — solution drafts, tech stack, security analysis
+10
View File
@@ -0,0 +1,10 @@
---
description: Rules for installation and provisioning scripts
globs: scripts/**/*.sh
alwaysApply: false
---
# Automation Scripts
- Automate repeatable setup steps in scripts. For dependencies with official package managers (apt, brew, pip, npm), automate installation. For binaries from external URLs, document the download but require user review before execution.
- Use sensible defaults for paths and configuration (e.g. `/opt/` for system-wide tools). Allow overrides via environment variables for users who need non-standard locations.
+21 -11
View File
@@ -1,17 +1,17 @@
---
description: "Enforces concise, comment-free, environment-aware coding standards with strict scope discipline and test verification"
description: "Enforces readable, environment-aware coding standards with scope discipline, meaningful comments, and test verification"
alwaysApply: true
---
# Coding preferences
- Always prefer simple solution
- Prefer the simplest solution that satisfies all requirements, including maintainability. When in doubt between two approaches, choose the one with fewer moving parts — but never sacrifice correctness, error handling, or readability for brevity.
- Follow the Single Responsibility Principle — a class or method should have one reason to change:
- If a method is hard to name precisely from the caller's perspective, its responsibility is misplaced. Vague names like "candidate", "data", or "item" are a signal — fix the design, not just the name.
- Logic specific to a platform, variant, or environment belongs in the class that owns that variant, not in the general coordinator. Passing a dependency through is preferable to leaking variant-specific concepts into shared code.
- Only use static methods for pure, self-contained computations (constants, simple math, stateless lookups). If a static method involves resource access, side effects, OS interaction, or logic that varies across subclasses or environments — use an instance method or factory class instead. Before implementing a non-trivial static method, ask the user.
- Generate concise code
- Avoid boilerplate and unnecessary indirection, but never sacrifice readability for brevity.
- Never suppress errors silently — no `2>/dev/null`, empty `catch` blocks, bare `except: pass`, or discarded error returns. These hide the information you need most when something breaks. If an error is truly safe to ignore, log it or comment why.
- Do not put comments in the code, except in tests: every test must use the Arrange / Act / Assert pattern with language-appropriate comment syntax (`# Arrange` for Python, `// Arrange` for C#/Rust/JS/TS). Omit any section that is not needed (e.g. if there is no setup, skip Arrange; if act and assert are the same line, keep only Assert)
- Do not put logs unless it is an exception, or was asked specifically
- Do not add comments that merely narrate what the code does. Comments are appropriate for: non-obvious business rules, workarounds with references to issues/bugs, safety invariants, and public API contracts. Make comments as short and concise as possible. Exception: every test must use the Arrange / Act / Assert pattern with language-appropriate comment syntax (`# Arrange` for Python, `// Arrange` for C#/Rust/JS/TS). Omit any section that is not needed (e.g. if there is no setup, skip Arrange; if act and assert are the same line, keep only Assert)
- Do not add verbose debug/trace logs by default. Log exceptions, security events (auth failures, permission denials), and business-critical state transitions. Add debug-level logging only when asked.
- Do not put code annotations unless it was asked specifically
- Write code that takes into account the different environments: development, production
- You are careful to make changes that are requested or you are confident the changes are well understood and related to the change being requested
@@ -22,16 +22,26 @@ alwaysApply: true
- When a test fails due to a missing dependency, install it — do not fake or stub the module system. For normal packages, add them to the project's dependency file (requirements-test.txt, package.json devDependencies, test csproj, etc.) and install. Only consider stubbing if the dependency is heavy (e.g. hardware-specific SDK, large native toolchain) — and even then, ask the user first before choosing to stub.
- Do not solve environment or infrastructure problems (dependency resolution, import paths, service discovery, connection config) by hardcoding workarounds in source code. Fix them at the environment/configuration level.
- Before writing new infrastructure or workaround code, check how the existing codebase already handles the same concern. Follow established project patterns.
- If a file, class, or function has no remaining usages — delete it. Do not keep dead code "just in case"; git history preserves everything. Dead code rots: its dependencies drift, it misleads readers, and it breaks when the code it depends on evolves.
- If a file, class, or function has no remaining usages — delete it. Dead code rots: its dependencies drift, it misleads readers, and it breaks when the code it depends on evolves. However, before deletion verify that the symbol is not used via any of the following. If any applies, do NOT delete — leave it or ASK the user:
- Public API surface exported from the package and potentially consumed outside the workspace (see `workspace-boundary.mdc`)
- Reflection, dependency injection, or service registration (scan DI container registrations, `appsettings.json` / equivalent config, attribute-based discovery, plugin manifests)
- Dynamic dispatch from config/data (YAML/JSON references, string-based class lookups, route tables, command dispatchers)
- Test fixtures used only by currently-skipped tests — temporary skips may become active again
- Cross-repo references — if this workspace is part of a multi-repo system, grep sibling repos for shared contracts before deleting
- Focus on the areas of code relevant to the task
- Do not touch code that is unrelated to the task
- Always think about what other methods and areas of code might be affected by the code changes
- When you think you are done with changes, run the full test suite. Every failure — including pre-existing ones, collection errors, and import errors — is a **blocking gate**. Never silently ignore, skip, or proceed past a failing test. On any failure, stop and ask the user to choose one of:
- **Scope discipline**: focus edits on the task scope. The "scope" is:
- Files the task explicitly names
- Files that define interfaces the task changes
- Files that directly call, implement, or test the changed code
- **Adjacent hygiene is permitted** without asking: fixing imports you caused to break, updating obvious stale references within a file you already modify, deleting code that became dead because of your change.
- **Unrelated issues elsewhere**: do not silently fix them as part of this task. Either note them to the user at end of turn and ASK before expanding scope, or record in `_docs/_process_leftovers/` for later handling.
- Always think about what other methods and areas of code might be affected by the code changes, and surface the list to the user before modifying.
- When you think you are done with changes, run the full test suite. Every failure in tests that cover code you modified or that depend on code you modified is a **blocking gate**. For pre-existing failures in unrelated areas, report them to the user but do not block on them. Never silently ignore or skip a failure without reporting it. On any blocking failure, stop and ask the user to choose one of:
- **Investigate and fix** the failing test or source code
- **Remove the test** if it is obsolete or no longer relevant
- **Iterative-skill exception**: when an iterative loop skill is active (e.g. autodev / `implement/SKILL.md` batch loop, `refactor/SKILL.md` batch loop), the skill governs full-suite cadence — typically focused tests per task/batch and a single full-suite gate at the very end of the implementation phase, NOT after each batch. "Done with changes" means done with the entire implementation phase the skill is running, not done with one batch. Do not run the full suite per batch unless the skill explicitly says to.
- Do not rename any databases or tables or table columns without confirmation. Avoid such renaming if possible.
- Make sure we don't commit binaries, create and keep .gitignore up to date and delete binaries after you are done with the task
- Never force-push to main or dev branches
- Place all source code under the `src/` directory; keep project-level config, tests, and tooling at the repo root
- For new projects, place source code under `src/` (this works for all stacks including .NET). For existing projects, follow the established directory structure. Keep project-level config, tests, and tooling at the repo root.
+14
View File
@@ -23,3 +23,17 @@ globs: [".cursor/**"]
## Security
- All `.cursor/` files must be scanned for hidden Unicode before committing (see cursor-security.mdc)
## Quality Thresholds (canonical reference)
All rules and skills must reference the single source of truth below. Do NOT restate different numeric thresholds in individual rule or skill files.
| Concern | Threshold | Enforcement |
|---------|-----------|-------------|
| Test coverage on business logic | 75% | Aim (warn below); 100% on critical paths |
| Test scenario coverage (vs AC + restrictions) | 75% | Blocking in test-spec Phase 1 and Phase 3 |
| CI coverage gate | 75% | Fail build below |
| Lint errors (Critical/High) | 0 | Blocking pre-commit |
| Code-review auto-fix | Low + Medium (Style/Maint/Perf) + High (Style/Scope) | Critical and Security always escalate |
When a skill or rule needs to cite a threshold, link to this table instead of hardcoding a different number.
+1 -1
View File
@@ -5,7 +5,7 @@ globs: ["**/*.cs", "**/*.csproj", "**/*.sln"]
# .NET / C#
- PascalCase for classes, methods, properties, namespaces; camelCase for locals and parameters; prefix interfaces with `I`
- Use `async`/`await` for I/O-bound operations, do not suffix async methods with Async
- Use `async`/`await` for I/O-bound operations; the `Async` suffix on method names is optional — follow the project's existing convention
- Use dependency injection via constructor injection; register services in `Program.cs`
- Use linq2db for small projects, EF Core with migrations for big ones; avoid raw SQL unless performance-critical; prevent N+1 with `.Include()` or projection
- Use `Result<T, E>` pattern or custom error types over throwing exceptions for expected failures
+3 -2
View File
@@ -5,6 +5,7 @@ alwaysApply: true
# Git Workflow
- Work on the `dev` branch
- Commit message format: `[TRACKER-ID-1] [TRACKER-ID-2] Summary of changes`
- Commit message total length must not exceed 30 characters
- Commit message subject line format: `[TRACKER-ID-1] [TRACKER-ID-2] Summary of changes`
- Subject line must not exceed 72 characters (standard Git convention for the first line). The 72-char limit applies to the subject ONLY, not the full commit message.
- A commit message body is optional. Add one when the subject alone cannot convey the why of the change. Wrap the body at 72 chars per line.
- Do NOT push or merge unless the user explicitly asks you to. Always ask first if there is a need.
+33 -11
View File
@@ -4,21 +4,43 @@ alwaysApply: true
---
# Sound Notification on Human Input
Whenever you are about to ask the user a question, request confirmation, present options for a decision, or otherwise pause and wait for human input, you MUST first run the appropriate shell command for the current OS:
## Sound commands per OS
Detect the OS from user system info or `uname -s`:
- **macOS**: `afplay /System/Library/Sounds/Glass.aiff &`
- **Linux**: `paplay /usr/share/sounds/freedesktop/stereo/bell.oga 2>/dev/null || aplay /usr/share/sounds/freedesktop/stereo/bell.oga 2>/dev/null || echo -e '\a' &`
- **Windows (PowerShell)**: `[System.Media.SystemSounds]::Exclamation.Play()`
Detect the OS from the user's system info or by running `uname -s` if unknown.
## When to play (play exactly once per trigger)
This applies to:
- Asking clarifying questions
- Presenting choices (e.g. via AskQuestion tool)
- Requesting approval for destructive actions
- Reporting that you are blocked and need guidance
- Any situation where the conversation will stall without user response
- Completing a task (final answer / deliverable ready for review)
Play the sound when your turn will end in one of these states:
Do NOT play the sound when:
- You are in the middle of executing a multi-step task and just providing a status update
1. You are about to call the AskQuestion tool — sound BEFORE the AskQuestion call
2. Your text ends with a direct question to the user that cannot be answered without their input (e.g., "Which option do you prefer?", "What is the database name?", "Confirm before I push?")
3. You are reporting that you are BLOCKED and cannot continue without user input (missing credentials, conflicting requirements, external approval required)
4. You have just completed a destructive or irreversible action the user asked to review (commit, push, deploy, data migration, file deletion)
## When NOT to play
- You are mid-execution and returning a progress update (the conversation is not stalling)
- You are answering a purely informational or factual question and no follow-up is required
- You have already played the sound once this turn for the same pause point
- Your response only contains text describing what you did or found, with no question, no block, no irreversible action
## "Trivial" definition
A response is trivial (no sound) when ALL of the following are true:
- No explicit question to the user
- No "I am blocked" report
- No destructive/irreversible action that needs review
If any one of those is present, the response is non-trivial — play the sound.
## Ordering
The sound command is a normal Shell tool call. Place it:
- **Immediately before an AskQuestion tool call** in the same message, or
- **As the last Shell call of the turn** if ending with a text-based question, block report, or post-destructive-action review
Do not play the sound as part of routine command execution — only at the pause points listed under "When to play".
+41
View File
@@ -0,0 +1,41 @@
---
description: "Use chunked writes (Write + StrReplace marker pattern) for large generated files, especially after a monolithic Write fails"
alwaysApply: true
---
# Large File Writes — Chunk on Failure
When a `Write` call to a single file fails (timeout, payload limit, "Invalid arguments", or any tool error) and the intended content is large (>~500 lines or >~50 KB), do NOT retry the same monolithic Write. Switch to chunked writes:
1. **First Write** — create the file with header + table of contents (if applicable) + an explicit append marker, e.g.
```
<!-- INSERTION_POINT do-not-remove-until-final-chunk -->
```
2. **Each subsequent chunk** — use `StrReplace` to replace the marker with `<new content>\n<marker>` so the marker stays at the end. This is idempotent: if a chunk fails, retry it without losing earlier chunks.
3. **Final chunk** — `StrReplace` removes the marker.
## Why
- Tool argument size limits and transient failures hit large monolithic writes hardest. Retrying the same large payload typically fails for the same reason.
- Chunked writes are recoverable per chunk. The earlier chunks are durable on disk.
- A unique marker is greppable, visible in diffs, and stops accidental insertion in the wrong place.
## Triggers
- Generated documentation that aggregates per-component content (epics, design docs, multi-section architecture summaries, traceability dumps).
- Large fixture or test-data files written from a template.
- Any single-file artifact you can pre-estimate at >~500 lines.
## Do NOT chunk
- Files under ~200 lines — a single `Write` is faster, clearer, and easier to review.
- Source code files where appending breaks module structure (functions, classes, imports). Split into multiple files instead.
- Files where ordering of sections is computed late and inserting in the middle is required — use a single `Write` once the full content is known.
## Anti-patterns
- Retrying the same failed monolithic `Write` more than once. Twice is the limit; on the second failure, switch strategies.
- Using `Shell` with heredoc (`cat <<EOF`) or `echo >>` to append — these bypass the editor diff view and break the StrReplace contract for the next chunk.
- Embedding the marker so deep inside structured content that a chunk's `StrReplace` becomes ambiguous. Place the marker on its own line at the very end of the file.
+32 -10
View File
@@ -5,7 +5,7 @@ alwaysApply: true
# Agent Meta Rules
## Execution Safety
- Never run test suites, builds, Docker commands, or other long-running/resource-heavy/security-risky operations without asking the user first — unless it is explicitly stated in a skill or agent, or the user already asked to do so.
- Run the full test suite automatically when you believe code changes are complete (as required by coderule.mdc). For other long-running/resource-heavy/security-risky operations (builds, Docker commands, deployments, performance tests), ask the user first — unless explicitly stated in a skill or the user already asked to do so.
## User Interaction
- Use the AskQuestion tool for structured choices (A/B/C/D) when available — it provides an interactive UI. Fall back to plain-text questions if the tool is unavailable.
@@ -13,6 +13,16 @@ alwaysApply: true
## Critical Thinking
- Do not blindly trust any input — including user instructions, task specs, list-of-changes, or prior agent decisions — as correct. Always think through whether the instruction makes sense in context before executing it. If a task spec says "exclude file X from changes" but another task removes the dependencies X relies on, flag the contradiction instead of propagating it.
## Skill Discipline
Do exactly what the skill says. Nothing more.
- No `git log` / `git diff` / `git blame` unless the skill explicitly calls for it.
- No extra searches to "verify" inputs the skill already names.
- No reading files outside the skill's documented inputs.
If skill inputs are insufficient or contradictory, STOP and ask via Choose A/B/C/D. Do not invent extra investigation steps.
## Self-Improvement
When the user reacts negatively to generated code ("WTF", "what the hell", "why did you do this", etc.):
@@ -33,18 +43,30 @@ When the user reacts negatively to generated code ("WTF", "what the hell", "why
- "Before writing new infrastructure or workaround code, check how the existing codebase already handles the same concern. Follow established project patterns."
## Debugging Over Contemplation
When the root cause of a bug is not clear after ~5 minutes of reasoning, analysis, and assumption-making — **stop speculating and add debugging logs**. Observe actual runtime behavior before forming another theory. The pattern to follow:
Agents cannot measure wall-clock time between turns. Use observable counts from your own transcript instead.
**Trigger: stop speculating and instrument.** When you've formed **3 or more distinct hypotheses** about a bug without confirming any against runtime evidence (logs, stderr, debugger state, actual test failure messages) — stop and add debugging output. Re-reading the same code hoping to "spot it this time" counts as a new hypothesis that still has zero evidence.
Steps:
1. Identify the last known-good boundary (e.g., "request enters handler") and the known-bad result (e.g., "callback never fires").
2. Add targeted `print(..., flush=True)` or log statements at each intermediate step to narrow the gap.
3. Read the output. Let evidence drive the next step — not inference chains built on unverified assumptions.
2. Add targeted `print(..., flush=True)`, `console.error`, or logger statements at each intermediate step to narrow the gap.
3. Run the instrumented code. Read the output. Let evidence drive the next hypothesis — not inference chains.
Prolonged mental contemplation without evidence is a time sink. A 15-minute instrumented run beats 45 minutes of "could it be X? but then Y... unless Z..." reasoning.
An instrumented run producing real output beats any amount of "could it be X? but then Y..." reasoning.
## Long Investigation Retrospective
When a problem takes significantly longer than expected (>30 minutes), perform a post-mortem before closing out:
1. **Identify the bottleneck**: Was the delay caused by assumptions that turned out wrong? Missing visibility into runtime state? Incorrect mental model of a framework or language boundary?
2. **Extract the general lesson**: What category of mistake was this? (e.g., "Python cannot call Cython `cdef` methods", "engine errors silently swallowed", "wrong layer to fix the problem")
3. **Propose a preventive rule**: Formulate it as a short, actionable statement. Present it to the user for approval.
4. **Write it down**: Add the approved rule to the appropriate `.mdc` file so it applies to all future sessions.
Trigger a post-mortem when ANY of the following is true (all are observable in your own transcript):
- **10+ tool calls** were used to diagnose a single issue
- **Same file modified 3+ times** without tests going green
- **3+ distinct approaches** attempted before arriving at the fix
- Any phrase like "let me try X instead" appeared **more than twice**
- A fix was eventually found by reading docs/source the agent had dismissed earlier
Post-mortem steps:
1. **Identify the bottleneck**: wrong assumption? missing runtime visibility? incorrect mental model of a framework/language boundary? ignored evidence?
2. **Extract the general lesson**: what category of mistake was this? (e.g., "Python cannot call Cython `cdef` methods", "engine errors silently swallowed", "wrong layer to fix the problem")
3. **Propose a preventive rule**: short, actionable. Present to user for approval.
4. **Write it down**: add approved rule to the appropriate `.mdc` so it applies to future sessions.
+29
View File
@@ -0,0 +1,29 @@
---
description: "Forbid spawning subagents; the main agent must do the work directly"
alwaysApply: true
---
# No Subagents
Do NOT create or delegate to subagents. This includes:
- The `Task` tool with any `subagent_type` (e.g. `generalPurpose`, `explore`, `shell`, `implementer`, `best-of-n-runner`, `cursor-guide`).
- Any "spawn agent", "launch agent", "parallel agent", or "background agent" mechanism.
- Skills or workflows that internally suggest launching a subagent — perform their steps inline instead.
## Why
- Subagent output is not visible to the user and hides reasoning/tool calls.
- Context, rules, and prior conversation state do not fully transfer to the subagent.
- Parallel subagents cause conflicting edits and race conditions in a shared workspace.
- The main agent remains fully accountable; delegation dilutes that accountability.
## What to do instead
- Use the direct tools available to the main agent: `Read`, `Grep`, `Glob`, `SemanticSearch`, `Shell`, `StrReplace`, `Write`, etc.
- For broad exploration, run `Grep`/`Glob`/`SemanticSearch` yourself and read the files directly.
- For multi-step work, use `TodoWrite` to track progress inline.
- For isolated experiments the user explicitly asks for, use a git branch/worktree you manage directly — not a subagent runner.
## Exception
Only spawn a subagent if the user explicitly requests it in the current turn (e.g. "use a subagent to…", "launch an explore agent…"). Even then, confirm once before spawning.
+1 -1
View File
@@ -4,7 +4,7 @@ alwaysApply: true
---
# Quality Gates
- After substantive code edits, run `ReadLints` on modified files and fix introduced errors
- After any code edit that changes logic, adds/removes imports, or modifies function signatures, run `ReadLints` on modified files and fix introduced errors
- Before committing, run the project's formatter if one exists (black, rustfmt, prettier, dotnet format)
- Respect existing `.editorconfig`, `.prettierrc`, `pyproject.toml [tool.black]`, or `rustfmt.toml`
- Do not commit code with Critical or High severity lint errors
+46
View File
@@ -0,0 +1,46 @@
---
description: "Explanation length and reasoning depth calibration"
alwaysApply: true
---
# Response Calibration
Default to concise. Expand only when the content demands it.
## Length target
- **Default**: a direct answer in ~310 lines. Short paragraphs or a tight bullet list.
- **Expand when**: the question involves trade-offs across multiple options, a migration/architectural decision, a security/data-loss risk, or the user explicitly asks for depth ("explain in detail", "walk me through", "why").
- **Shrink when**: the user asks for "shorter", "simpler", "TL;DR", "one line", or similar. Do not re-inflate in later turns unless they ask a new deeper question.
## Completeness floor
Short ≠ incomplete. Every response must still:
- Answer the actual question asked (not a reframed version).
- State the key constraint or reason *once*, not repeatedly.
- Flag a real caveat if one exists (data loss, breaking change, wrong-OS, security). One sentence is enough.
- Not drop a step from an action sequence. If there are 5 steps, list 5 — but without narration between them.
If the honest answer truly needs more space (e.g. trade-off matrix, multi-option decision), write more — but lead with the recommendation or direct answer, then the detail.
## Structure
- One direct sentence first. Then supporting detail.
- Prefer bullets over prose for enumerations, comparisons, or step lists.
- Drop section headers for anything under ~15 lines.
- No "Summary" / "Conclusion" sections unless the response is genuinely long.
## Reasoning depth (internal)
- Match thinking to the problem, not the length of the answer.
- Factual / "where is X used" / single-file edit → minimal thinking, go straight to tools.
- Trade-off / refactor / debugging 3+ hypotheses deep → full thinking budget.
- Do not pad thinking to look thorough. Do not skip thinking on genuinely ambiguous problems to look fast.
## Anti-patterns to avoid
- Restating the question back to the user.
- Multi-paragraph preambles before the answer.
- Exhaustive "alternatives considered" sections when the user didn't ask for alternatives.
- Recapping what was just done at the end of every tool-using turn ("Done. I have edited the file…") — a one-line confirmation is enough.
- Speculative "you might also want to…" paragraphs. Offer follow-ups as a single short sentence, or not at all.
+38
View File
@@ -0,0 +1,38 @@
---
description: "Standards for creating and maintaining Cursor skills"
globs: [".cursor/skills/**"]
---
# Skill Building
## When To Create A Skill
- Create a skill for repeatable, bounded workflows that benefit from a reusable process.
- Do not create a skill for a one-off task, vague goal, or workflow that still needs product decisions.
- Start small; evolve the skill when repeated use reveals clearer steps, constraints, or checks.
## Skill Contract
- `SKILL.md` must define a clear `name` and a proactive `description` that explains when the skill should be used.
- State expected inputs, constraints, workflow steps, and final output shape.
- Make trigger conditions explicit enough that the agent can recognize intent without an exact command.
- Base instructions on observable project evidence; do not invite fabrication or unsupported assumptions.
## Keep The Core Lean
- Keep `SKILL.md` concise and under the repo's `.cursor/` size guidance.
- Move detailed standards, examples, and background knowledge into `references/`.
- Put reusable output shapes in `templates/` or other skill-local assets instead of embedding them in the main instructions.
- Keep one primary responsibility per skill; use an orchestrator skill only when multiple existing skills must run in a defined order.
## Deterministic Work
- Use scripts for mechanical steps that are repeatable, parameterized, and safer outside the model's reasoning.
- Scripts must expose explicit inputs, avoid hidden side effects, and fail loudly on errors.
- Do not use scripts to bypass review, hide destructive behavior, or hardcode secrets.
## Quality Proof
- Include realistic examples, checklists, or eval-style scenarios that define what good output looks like.
- Cover common failure cases such as missing sections, leftover placeholders, hallucinated facts, unsafe actions, or malformed output.
- Review skill changes against those checks before treating the skill as ready.
## Security Review
- Treat third-party skills like untrusted code until reviewed.
- Inspect scripts, dependencies, references, secret handling, network calls, and destructive commands before use.
- Prefer local, project-scoped assets and dependencies; document any external dependency the skill requires.
+1 -1
View File
@@ -4,6 +4,6 @@ alwaysApply: true
---
# Tech Stack
- Prefer Postgres database, but ask user
- Depending on task, for backend prefer .Net or Python. Rust for performance-critical things.
- For new backend projects: use .NET for structured enterprise/API services, Python for data/ML/scripting tasks, Rust for performance-critical components. For existing projects, use the language already established in that project.
- For the frontend, use React with Tailwind css (or even plain css, if it is a simple project)
- document api with OpenAPI
+1 -1
View File
@@ -8,7 +8,7 @@ globs: ["**/*test*", "**/*spec*", "**/*Test*", "**/tests/**", "**/test/**"]
- One assertion per test when practical; name tests descriptively: `MethodName_Scenario_ExpectedResult`
- Test boundary conditions, error paths, and happy paths
- Use mocks only for external dependencies; prefer real implementations for internal code
- Aim for 80%+ coverage on business logic; 100% on critical paths
- Aim for 75%+ coverage on business logic; 100% on critical paths (code paths where a bug would cause data loss, security breaches, financial errors, or system outages — identify from acceptance criteria marked as must-have or from security_approach.md). The 75% threshold is canonical — see `cursor-meta.mdc` Quality Thresholds.
- Integration tests use real database (Postgres testcontainers or dedicated test DB)
- Never use Thread Sleep or fixed delays in tests; use polling or async waits
- Keep test data factories/builders for reusable test setup
+42
View File
@@ -12,3 +12,45 @@ alwaysApply: true
- Project name: AZAION
- All task IDs follow the format `AZ-<number>`
- Issue types: Epic, Story, Task, Bug, Subtask
## Tracker Availability Gate
- If Jira MCP returns **Unauthorized**, **errored**, **connection refused**, **timeout**, a non-2xx status code, an empty body, or any response shape that does not clearly confirm the requested change: **STOP IMMEDIATELY** — no automatic retry, no silent continuation. Surface the full raw error/response to the user verbatim and notify via the Choose A/B/C/D format documented in `.cursor/skills/autodev/protocols.md`.
- A minimal `{"success": true}` body with no echoed issue state is NOT a confirmed transition. When a transition's success matters (status moves, ticket creation, blocking link), follow it with a read-back call (`getJiraIssue` or equivalent) and confirm the new state matches what you asked for. If the read-back disagrees → STOP and ASK.
- Do NOT loop "retry up to N times before asking". One call, one verification. On failure, the user decides whether to retry.
- The user may choose to:
- **Retry the same operation** — once, after the user authorizes it. If it fails again, surface both responses.
- **Retry authentication** — preferred when the failure looks like an auth/credentials problem; the tracker remains the source of truth.
- **Continue in `tracker: local` mode** — only when the user explicitly accepts this option. In that mode all tasks keep numeric prefixes and a `Tracker: pending` marker is written into each task header. The state file records `tracker: local`. The mode is NOT silent — the user has been asked and has acknowledged the trade-off.
- Do NOT auto-fall-back to `tracker: local` without a user decision. Do not pretend a write succeeded. Do not paper over an opaque response by moving on. If the user is unreachable (e.g., non-interactive run), stop and wait.
- When the tracker becomes available again, any `Tracker: pending` tasks should be synced — this is done at the start of the next `/autodev` invocation via the Leftovers Mechanism below.
## Leftovers Mechanism (non-user-input blockers only)
When a **non-user** blocker prevents a tracker write (MCP down, network error, transient failure, ticket linkage recoverable later), record the deferred write in `_docs/_process_leftovers/<YYYY-MM-DD>_<topic>.md` and continue non-tracker work. Each entry must include:
- Timestamp (ISO 8601)
- What was blocked (ticket creation, status transition, comment, link)
- Full payload that would have been written (summary, description, story points, epic, target status) — so the write can be replayed later
- Reason for the blockage (MCP unavailable, auth expired, unknown epic ID pending user clarification, etc.)
### Hard gates that CANNOT be deferred to leftovers
Anything requiring user input MUST still block:
- Clarifications about requirements, scope, or priority
- Approval for destructive actions or irreversible changes
- Choice between alternatives (A/B/C decisions)
- Confirmation of assumptions that change task outcome
If a blocker of this kind appears, STOP and ASK — do not write to leftovers.
### Replay obligation
At the start of every `/autodev` invocation, and before any new tracker write in any skill, check `_docs/_process_leftovers/` for pending entries. For each entry:
1. Attempt to replay the deferred write against the tracker
2. If replay succeeds → delete the leftover entry
3. If replay still fails → update the entry's timestamp and reason, continue
4. If the blocker now requires user input (e.g., MCP still down after N retries) → surface to the user
Autodev must not progress past its own step 0 until all leftovers that CAN be replayed have been replayed.
+7
View File
@@ -0,0 +1,7 @@
# Workspace Boundary
- Only modify files within the current repository (workspace root).
- Never write, edit, or delete files in sibling repositories or parent directories outside the workspace.
- When a task requires changes in another repository (e.g., admin API, flights, UI), **document** the required changes in the task's implementation notes or a dedicated cross-repo doc — do not implement them.
- The mock API at `e2e/mocks/mock_api/` may be updated to reflect the expected contract of external services, but this is a test mock — not the real implementation.
- If a task is entirely scoped to another repository, mark it as out-of-scope for this workspace and note the target repository.
+145
View File
@@ -0,0 +1,145 @@
---
name: autodev
description: |
Auto-chaining orchestrator that drives the full BUILD-SHIP workflow from problem gathering through deployment.
Detects current project state from _docs/ folder, resumes from where it left off, and flows through
problem → research → plan → test specs → decompose → implement → tests → docs sync → deploy without manual skill invocation.
Maximizes work per conversation by auto-transitioning between skills.
Trigger phrases:
- "autodev", "auto", "start", "continue"
- "what's next", "where am I", "project status"
category: meta
tags: [orchestrator, workflow, auto-chain, state-machine, meta-skill]
disable-model-invocation: true
---
# Autodev Orchestrator
Auto-chaining execution engine that drives the full BUILD → SHIP workflow. Detects project state from `_docs/`, resumes from where work stopped, and flows through skills automatically. The user invokes `/autodev` once — the engine handles sequencing, transitions, and re-entry.
## File Index
| File | Purpose |
|------|---------|
| `flows/greenfield.md` | Detection rules, step table, and auto-chain rules for new projects |
| `flows/existing-code.md` | Detection rules, step table, and auto-chain rules for existing codebases |
| `flows/meta-repo.md` | Detection rules, step table, and auto-chain rules for meta-repositories (submodule aggregators, workspace monorepos) |
| `state.md` | State file format, rules, re-entry protocol, session boundaries |
| `protocols.md` | User interaction, tracker auth, choice format, error handling, status summary |
**On every invocation**: read `state.md`, `protocols.md`, and the active flow file before executing any logic. You don't need to read flow files for flows you're not in.
## Core Principles
- **Auto-chain**: when a skill completes, immediately start the next one — no pause between skills
- **Only pause at decision points**: BLOCKING gates inside sub-skills are the natural pause points; do not add artificial stops between steps
- **State from disk**: current step is persisted to `_docs/_autodev_state.md` and cross-checked against `_docs/` folder structure
- **Re-entry**: on every invocation, read the state file and cross-check against `_docs/` folders before continuing
- **Delegate, don't duplicate**: read and execute each sub-skill's SKILL.md; never inline their logic here
- **Sound on pause**: follow `.cursor/rules/human-attention-sound.mdc` — play a notification sound before every pause that requires human input (AskQuestion tool preferred for structured choices; fall back to plain text if unavailable)
- **Minimize interruptions**: only ask the user when the decision genuinely cannot be resolved automatically
- **Single project per workspace**: all `_docs/` paths are relative to workspace root; for multi-component systems, each component needs its own Cursor workspace. **Exception**: a meta-repo workspace (git-submodule aggregator or monorepo workspace) uses the `meta-repo` flow and maintains cross-cutting artifacts via `monorepo-*` skills rather than per-component BUILD-SHIP flows.
## Flow Resolution
Determine which flow to use (check in order — first match wins):
1. If `_docs/_autodev_state.md` exists → read the `flow` field and use that flow. (When a greenfield project completes its final cycle, the Done step rewrites `flow: existing-code` in-band so the next invocation enters the feature-cycle loop — see greenfield "Done".)
2. If the workspace is a **meta-repo****meta-repo flow**. Detected by: presence of `.gitmodules` with ≥2 submodules, OR `package.json` with `workspaces` field, OR `pnpm-workspace.yaml`, OR `Cargo.toml` with `[workspace]` section, OR `go.work`, OR an ad-hoc structure with multiple top-level component folders each containing their own project manifests. Optional tiebreaker: the workspace has little or no source code of its own at the root (just registry + orchestration files).
3. If workspace has **no source code files****greenfield flow**
4. If workspace has source code files **and** `_docs/` does not exist → **existing-code flow**
5. If workspace has source code files **and** `_docs/` exists → **existing-code flow**
After selecting the flow, apply its detection rules (first match wins) to determine the current step.
**Note**: the meta-repo flow uses a different artifact layout — its source of truth is `_docs/_repo-config.yaml`, not `_docs/NN_*/` folders. After Step 2.5 it also produces `_docs/glossary.md` and a `## Architecture Vision` section in the cross-cutting architecture doc identified by `docs.cross_cutting`. Other detection rules assume the BUILD-SHIP artifact layout; they don't apply to meta-repos.
## Execution Loop
Every invocation has three phases: **Bootstrap** (runs once), **Resolve** (runs once), **Execute Loop** (runs per step). Exit conditions are explicit.
```
### Bootstrap (once per invocation)
B1. Process leftovers — delegate to `.cursor/rules/tracker.mdc` → Leftovers Mechanism
(authoritative spec: replay rules, escalation, blocker handling).
B2. Surface Recent Lessons — print top 3 entries from `_docs/LESSONS.md` if present; skip silently otherwise.
B3. Read state — `_docs/_autodev_state.md` (if it exists).
B4. Read File Index — `state.md`, `protocols.md`, and the active flow file.
### Resolve (once per invocation, after Bootstrap)
R1. Reconcile state — verify state file against `_docs/` contents; probe `<workspace-root>/../docs`
(parent suite `docs/` — see `state.md` → "State File Rules" #4); on disagreement,
trust the folders and update the state file (rules: `state.md` → "State File Rules" #4).
After this step, `state.step` / `state.status` are authoritative.
R2. Resolve flow — see §Flow Resolution above.
R3. Resolve current step — when a state file exists, `state.step` drives detection.
When no state file exists, walk the active flow's detection rules in order;
first folder-probe match wins.
R4. Present Status Summary — banner template in `protocols.md` + step-list fragment from the active flow file.
### Execute Loop (per step)
loop:
E1. Delegate to the current skill (see §Skill Delegation below).
E2. On FAILED
→ apply Failure Handling (`protocols.md`): increment retry_count, auto-retry up to 3.
→ if retry_count reaches 3 → set status: failed → EXIT (escalate on next invocation).
E3. On success
→ reset retry_count, update state file (rules: `state.md`).
E4. Re-detect next step from the active flow's detection rules.
E5. If the transition is marked as a session boundary in the flow's Auto-Chain Rules
→ update state, present boundary Choose block, suggest new conversation → EXIT.
E6. If all steps done
→ update state, report completion → EXIT.
E7. Else
→ continue loop (go to E1 with the next skill).
```
## Skill Delegation
For each step, the delegation pattern is:
1. Update state file: set `step` to the autodev step number, status to `in_progress`, set `sub_step` to the sub-skill's current internal phase using the structured `{phase, name, detail}` schema (see `state.md`), reset `retry_count: 0`
2. Announce: "Starting [Skill Name]..."
3. Read the skill file: `.cursor/skills/[name]/SKILL.md`
4. Execute the skill's workflow exactly as written, including all BLOCKING gates, self-verification checklists, save actions, and escalation rules. Update `sub_step.phase`, `sub_step.name`, and optional `sub_step.detail` in state each time the sub-skill advances to a new internal phase.
5. If the skill **fails**: follow Failure Handling in `protocols.md` — increment `retry_count`, auto-retry up to 3 times, then escalate.
6. When complete (success): reset `retry_count: 0`, update state file to the next step with `status: not_started` and `sub_step: {phase: 0, name: awaiting-invocation, detail: ""}`, return to auto-chain rules (from active flow file)
**sub_step read fallback**: when reading `sub_step`, parse the structured form. If parsing fails (legacy free-text value) OR the named phase is not recognized, log a warning and fall back to a folder scan of the sub-skill's artifact directory to infer progress. Do not silently treat a malformed sub_step as phase 0 — that would cause a sub-skill to restart from scratch after each resume.
Do NOT modify, skip, or abbreviate any part of the sub-skill's workflow. The autodev is a sequencer, not an optimizer.
## State File
The state file (`_docs/_autodev_state.md`) is a minimal pointer — only the current step. See `state.md` for the authoritative template, field semantics, update rules, and worked examples. Do not restate the schema here — `state.md` is the single source of truth.
**Conciseness rule (authoritative).** The state file MUST stay short. Acceptable content per field:
- `name` — the step title from the active flow's Step Reference Table. That's it.
- `sub_step.name` — kebab-case identifier from the active sub-skill. That's it.
- `sub_step.detail`**leave empty (`""`) by default.** Add a one-line note ONLY when the next-session resumer cannot infer where to pick up from `phase` + `name` + on-disk artifacts alone (e.g. `"batch 2 of 4"`, `"blocked on D-PROJ-2 reply"`, `"variant 1b"`). NEVER use `detail` as a changelog, recap, or summary of completed work — those facts belong in the relevant `_docs/` artifact (glossary, traceability matrix, leftovers folder, retro report, etc.) and in git history.
- **Total file size target: <30 lines.** If you're tempted to write more, you're using the wrong artifact — write in `_docs/` instead.
Multi-line `detail` blobs that recap what was just completed are a smell. The state file is a *pointer*, not a logbook.
## Trigger Conditions
This skill activates when the user wants to:
- Start a new project from scratch
- Continue an in-progress project
- Check project status
- Let the AI guide them through the full workflow
**Keywords**: "autodev", "auto", "start", "continue", "what's next", "where am I", "project status"
**Invocation model**: this skill is explicitly user-invoked only (`disable-model-invocation: true` in the front matter). The keywords above aid skill discovery and tooling (other skills / agents can reason about when `/autodev` is appropriate), but the model never auto-fires this skill from a keyword match. The user always types `/autodev`.
**Differentiation**:
- User wants only research → use `/research` directly
- User wants only planning → use `/plan` directly
- User wants to document an existing codebase → use `/document` directly
- User wants the full guided workflow → use `/autodev`
## Flow Reference
See `flows/greenfield.md`, `flows/existing-code.md`, and `flows/meta-repo.md` for step tables, detection rules, auto-chain rules, and each flow's Status Summary step-list fragment. The banner that wraps those fragments lives in `protocols.md` → "Banner Template (authoritative)".
@@ -0,0 +1,410 @@
# Existing Code Workflow
Workflow for projects with an existing codebase. Structurally it has **two phases**:
- **Phase A — One-time baseline setup (Steps 18)**: runs exactly once per codebase. Documents the code, produces test specs, makes the code testable, writes and runs the initial test suite, optionally refactors with that safety net.
- **Phase B — Feature cycle (Steps 917, loops)**: runs once per new feature. After Step 17 (Retrospective), the flow loops back to Step 9 (New Task) with `state.cycle` incremented.
A first-time run executes Phase A then Phase B; every subsequent invocation re-enters Phase B.
## Step Reference Table
### Phase A — One-time baseline setup
| Step | Name | Sub-Skill | Internal SubSteps |
|------|------|-----------|-------------------|
| 1 | Document | document/SKILL.md | Steps 07 incl. inline 2.5 (module-layout) and 4.5 (glossary + arch vision) |
| 2 | Architecture Baseline Scan | code-review/SKILL.md (baseline mode) | Phase 1 + Phase 7 |
| 3 | Test Spec | test-spec/SKILL.md | Phases 14 |
| 4 | Code Testability Revision | refactor/SKILL.md (guided mode) | Phases 07 (conditional) |
| 5 | Decompose Tests | decompose/SKILL.md (tests-only) | Step 1t + Step 3 + Step 4 |
| 6 | Implement Tests | implement/SKILL.md | (batch-driven, no fixed sub-steps) |
| 7 | Run Tests | test-run/SKILL.md | Steps 14 |
| 8 | Refactor | refactor/SKILL.md | Phases 07 (optional) |
### Phase B — Feature cycle (loops back to Step 9 after Step 17)
| Step | Name | Sub-Skill | Internal SubSteps |
|------|------|-----------|-------------------|
| 9 | New Task | new-task/SKILL.md | Steps 18 (loop) |
| 10 | Implement | implement/SKILL.md | (batch-driven, no fixed sub-steps) |
| 11 | Run Tests | test-run/SKILL.md | Steps 14 |
| 12 | Test-Spec Sync | test-spec/SKILL.md (cycle-update mode) | Phase 2 + Phase 3 (scoped) |
| 13 | Update Docs | document/SKILL.md (task mode) | Task Steps 05 |
| 14 | Security Audit | security/SKILL.md | Phase 15 (optional) |
| 15 | Performance Test | test-run/SKILL.md (perf mode) | Steps 15 (optional) |
| 16 | Deploy | deploy/SKILL.md | Step 17 |
| 17 | Retrospective | retrospective/SKILL.md (cycle-end mode) | Steps 14 |
After Step 17, the feature cycle completes and the flow loops back to Step 9 with `state.cycle + 1` — see "Re-Entry After Completion" below.
## Detection Rules
**Resolution**: when a state file exists, `state.step` + `state.status` drive detection and the conditions below are not consulted. When no state file exists (cold start), walk the rules in order — first folder-probe match wins. Steps without a folder probe are state-driven only; they can only be reached by auto-chain from a prior step. Cycle-scoped steps (Step 10 onward) always read `state.cycle` to disambiguate current vs. prior cycle artifacts.
---
### Phase A — One-time baseline setup (Steps 18)
**Step 1 — Document**
Condition: `_docs/` does not exist AND the workspace contains source code files (e.g., `*.py`, `*.cs`, `*.rs`, `*.ts`, `src/`, `Cargo.toml`, `*.csproj`, `package.json`)
Action: An existing codebase without documentation was detected. Read and execute `.cursor/skills/document/SKILL.md`. After the document skill completes, re-detect state (the produced `_docs/` artifacts will place the project at Step 2 or later).
The document skill's Step 2.5 produces `_docs/02_document/module-layout.md`, which is required by every downstream step that assigns file ownership (`/implement` Step 4, `/code-review` Phase 7, `/refactor` discovery). If this file is missing after Step 1 completes (e.g., a pre-existing `_docs/` dir predates the 2.5 addition), re-invoke `/document` in resume mode — it will pick up at Step 2.5.
The document skill's Step 4.5 produces `_docs/02_document/glossary.md` and prepends a confirmed `## Architecture Vision` section to `architecture.md`. Both are user-confirmed artifacts; downstream skills (refactor, decompose, new-task) treat them as authoritative for terminology and structural intent. If `glossary.md` is missing after Step 1 (pre-existing `_docs/` dir from before the 4.5 addition), re-invoke `/document` in resume mode — it will pick up at Step 4.5 without redoing module/component analysis.
---
**Step 2 — Architecture Baseline Scan**
Condition: `_docs/02_document/FINAL_report.md` exists AND `_docs/02_document/architecture.md` exists AND `_docs/02_document/architecture_compliance_baseline.md` does not exist.
Action: Invoke `.cursor/skills/code-review/SKILL.md` in **baseline mode** (Phase 1 + Phase 7 only) against the full existing codebase. Phase 7 produces a structural map of the code vs. the just-documented `architecture.md`. Save the output to `_docs/02_document/architecture_compliance_baseline.md`.
Rationale: existing codebases often have pre-existing architecture violations (cycles, cross-component private imports, duplicate logic). Catching them here, before the Testability Revision (Step 4), gives the user a chance to fold structural fixes into the refactor scope.
After completion, if the baseline report contains **High or Critical** Architecture findings:
- Append them to the testability `list-of-changes.md` input in Step 4 (so testability refactor can address the most disruptive ones along with testability fixes), OR
- Surface them to the user via Choose format to defer to Step 8 (optional Refactor).
If the baseline report is clean (no High/Critical findings), auto-chain directly to Step 3.
---
**Step 3 — Test Spec**
Condition (folder fallback): `_docs/02_document/FINAL_report.md` exists AND workspace contains source code files AND `_docs/02_document/tests/traceability-matrix.md` does not exist.
State-driven: reached by auto-chain from Step 2.
Action: Read and execute `.cursor/skills/test-spec/SKILL.md`
This step applies when the codebase was documented via the `/document` skill. Test specifications must be produced before refactoring or further development.
---
**Step 4 — Code Testability Revision**
Condition (folder fallback): `_docs/02_document/tests/traceability-matrix.md` exists AND no test tasks exist yet in `_docs/02_tasks/todo/`.
State-driven: reached by auto-chain from Step 3.
**Purpose**: enable tests to run at all. Without this step, hardcoded URLs, file paths, credentials, or global singletons can prevent the test suite from exercising the code against a controlled environment. The test authors need a testable surface before they can write tests that mean anything.
**Scope — MINIMAL, SURGICAL fixes**: this is not a profound refactor. It is the smallest set of changes (sometimes temporary hacks) required to make code runnable under tests. "Smallest" beats "elegant" here — deeper structural improvements belong in Step 8 (Refactor), not this step.
**Allowed changes** in this phase:
- Replace hardcoded URLs / file paths / credentials / magic numbers with env vars or constructor arguments.
- Extract narrow interfaces for components that need stubbing in tests.
- Add optional constructor parameters for dependency injection; default to the existing hardcoded behavior so callers do not break.
- Wrap global singletons in thin accessors that tests can override (thread-local / context var / setter gate).
- Split a huge function ONLY when necessary to stub one of its collaborators — do not split for clarity alone.
**NOT allowed** in this phase (defer to Step 8 Refactor):
- Renaming public APIs (breaks consumers without a safety net).
- Moving code between files unless strictly required for isolation.
- Changing algorithms or business logic.
- Restructuring module boundaries or rewriting layers.
**Safety**: Phase 3 (Safety Net) of the refactor skill is skipped here **by design** — no tests exist yet to form the safety net. Compensating controls:
- Every change is bounded by the allowed/not-allowed lists above.
- `list-of-changes.md` must be reviewed by the user BEFORE execution (refactor skill enforces this gate).
- After execution, the refactor skill produces `RUN_DIR/testability_changes_summary.md` — a plain-language list of every applied change and why. Present this to the user before auto-chaining to Step 5.
Action: Analyze the codebase against the test specs to determine whether the code can be tested as-is.
1. Read `_docs/02_document/tests/traceability-matrix.md` and all test scenario files in `_docs/02_document/tests/`.
2. Read `_docs/02_document/architecture_compliance_baseline.md` (produced in Step 2). If it contains High/Critical Architecture findings that overlap with testability issues, consider including the lightest structural fixes inline; leave the rest for Step 8.
3. For each test scenario, check whether the code under test can be exercised in isolation. Look for:
- Hardcoded file paths or directory references
- Hardcoded configuration values (URLs, credentials, magic numbers)
- Global mutable state that cannot be overridden
- Tight coupling to external services without abstraction
- Missing dependency injection or non-configurable parameters
- Direct file system operations without path configurability
- Inline construction of heavy dependencies (models, clients)
4. If ALL scenarios are testable as-is:
- Mark Step 4 as `completed` with outcome "Code is testable — no changes needed"
- Auto-chain to Step 5 (Decompose Tests)
5. If testability issues are found:
- Create `_docs/04_refactoring/01-testability-refactoring/`
- Write `list-of-changes.md` in that directory using the refactor skill template (`.cursor/skills/refactor/templates/list-of-changes.md`), with:
- **Mode**: `guided`
- **Source**: `autodev-testability-analysis`
- One change entry per testability issue found (change ID, file paths, problem, proposed change, risk, dependencies). Each entry must fit the allowed-changes list above; reject entries that drift into full refactor territory and log them under "Deferred to Step 8 Refactor" instead.
- Invoke the refactor skill in **guided mode**: read and execute `.cursor/skills/refactor/SKILL.md` with the `list-of-changes.md` as input
- The refactor skill will create RUN_DIR (`01-testability-refactoring`), create tasks in `_docs/02_tasks/todo/`, delegate to implement skill, and verify results
- Phase 3 (Safety Net) is automatically skipped by the refactor skill for testability runs
- After execution, the refactor skill produces `RUN_DIR/testability_changes_summary.md`. Surface this summary to the user via the Choose format (accept / request follow-up) before auto-chaining.
- Mark Step 4 as `completed`
- Auto-chain to Step 5 (Decompose Tests)
---
**Step 5 — Decompose Tests**
Condition (folder fallback): `_docs/02_document/tests/traceability-matrix.md` exists AND workspace contains source code files AND (`_docs/02_tasks/todo/` does not exist or has no test task files).
State-driven: reached by auto-chain from Step 4 (completed or skipped).
Action: Read and execute `.cursor/skills/decompose/SKILL.md` in **tests-only mode** (pass `_docs/02_document/tests/` as input). The decompose skill will:
1. Run Step 1t (test infrastructure bootstrap)
2. Run Step 3 (blackbox test task decomposition)
3. Run Step 4 (cross-verification against test coverage)
If `_docs/02_tasks/` subfolders have some task files already (e.g., refactoring tasks from Step 4), the decompose skill's resumability handles it — it appends test tasks alongside existing tasks.
---
**Step 6 — Implement Tests**
Condition (folder fallback): `_docs/02_tasks/todo/` contains test task files AND `_dependencies_table.md` exists AND `_docs/03_implementation/implementation_report_tests.md` does not exist.
State-driven: reached by auto-chain from Step 5.
Action: Invoke `.cursor/skills/implement/SKILL.md` with task selection context **Test implementation**.
The implement skill reads only test tasks from `_docs/02_tasks/todo/` and implements them.
If `_docs/03_implementation/` has batch reports, the implement skill detects completed tasks and continues.
For folder fallback, **test task files** means `*_test_infrastructure.md` plus task specs whose `**Component**` or `**Epic**` identifies `Blackbox Tests`.
---
**Step 7 — Run Tests**
Condition (folder fallback): `_docs/03_implementation/implementation_report_tests.md` exists.
State-driven: reached by auto-chain from Step 6.
Action: Read and execute `.cursor/skills/test-run/SKILL.md`
Verifies the implemented test suite passes before proceeding to refactoring. The tests form the safety net for all subsequent code changes.
---
**Step 8 — Refactor (optional)**
State-driven: reached by auto-chain from Step 7. (Sanity check: no `_docs/04_refactoring/` run folder should contain a `FINAL_report.md` for a non-testability run when entering this step for the first time.)
Action: Present using Choose format:
```
══════════════════════════════════════
DECISION REQUIRED: Refactor codebase before adding new features?
══════════════════════════════════════
A) Run refactoring (recommended if code quality issues were noted during documentation)
B) Skip — proceed directly to New Task
══════════════════════════════════════
Recommendation: [A or B — base on whether documentation
flagged significant code smells, coupling issues, or
technical debt worth addressing before new development]
══════════════════════════════════════
```
- If user picks A → Read and execute `.cursor/skills/refactor/SKILL.md` in automatic mode. The refactor skill creates a new run folder in `_docs/04_refactoring/` (e.g., `02-coupling-refactoring`), runs the full method using the implemented tests as a safety net. After completion, auto-chain to Step 9 (New Task).
- If user picks B → Mark Step 8 as `skipped` in the state file, auto-chain to Step 9 (New Task).
---
### Phase B — Feature cycle (Steps 917, loops)
**Step 9 — New Task**
State-driven: reached by auto-chain from Step 8 (completed or skipped). This is also the re-entry point after a completed cycle — see "Re-Entry After Completion" below.
Action: Read and execute `.cursor/skills/new-task/SKILL.md`
The new-task skill interactively guides the user through defining new functionality. It loops until the user is done adding tasks. New task files are written to `_docs/02_tasks/todo/`.
---
**Step 10 — Implement**
State-driven: reached by auto-chain from Step 9 in the CURRENT cycle (matching `state.cycle`). Detection is purely state-driven — prior cycles will have left `implementation_report_{feature_slug}_cycle{N-1}.md` artifacts that must not block new cycles.
Action: Read and execute `.cursor/skills/implement/SKILL.md`
The implement skill reads the new tasks from `_docs/02_tasks/todo/` and implements them. Tasks already implemented in Step 6 or prior cycles are skipped (completed tasks have been moved to `done/`).
**Implementation report naming**: the final report for this cycle must be named `implementation_report_{feature_slug}_cycle{N}.md` where `{N}` is `state.cycle`. Batch reports are named `batch_{NN}_cycle{M}_report.md` so the cycle counter survives folder scans.
If `_docs/03_implementation/` has batch reports from the current cycle, the implement skill detects completed tasks and continues.
---
**Step 11 — Run Tests**
State-driven: reached by auto-chain from Step 10.
Action: Read and execute `.cursor/skills/test-run/SKILL.md`
---
**Step 12 — Test-Spec Sync**
State-driven: reached by auto-chain from Step 11. Requires `_docs/02_document/tests/traceability-matrix.md` to exist — if missing, mark Step 12 `skipped` (see Action below).
Action: Read and execute `.cursor/skills/test-spec/SKILL.md` in **cycle-update mode**. Pass the cycle's completed task specs (files in `_docs/02_tasks/done/` moved during this cycle) and the implementation report `_docs/03_implementation/implementation_report_{feature_slug}_cycle{N}.md` as inputs.
The skill appends new ACs, scenarios, and NFRs to the existing test-spec files without rewriting unaffected sections. If `traceability-matrix.md` is missing (e.g., cycle added after a greenfield-only project), mark Step 12 as `skipped` — the next `/test-spec` full run will regenerate it.
After completion, auto-chain to Step 13 (Update Docs).
---
**Step 13 — Update Docs**
State-driven: reached by auto-chain from Step 12 (completed or skipped). Requires `_docs/02_document/` to contain existing documentation — if missing, mark Step 13 `skipped` (see Action below).
Action: Read and execute `.cursor/skills/document/SKILL.md` in **Task mode**. Pass all task spec files from `_docs/02_tasks/done/` that were implemented in the current cycle (i.e., tasks moved to `done/` during Steps 910 of this cycle).
The document skill in Task mode:
1. Reads each task spec to identify changed source files
2. Updates affected module docs, component docs, and system-level docs
3. Does NOT redo full discovery, verification, or problem extraction
If `_docs/02_document/` does not contain existing docs (e.g., documentation step was skipped), mark Step 13 as `skipped`.
After completion, auto-chain to Step 14 (Security Audit).
---
**Step 14 — Security Audit (optional)**
State-driven: reached by auto-chain from Step 13 (completed or skipped).
Action: Apply the **Optional Skill Gate** (`protocols.md` → "Optional Skill Gate") with:
- question: `Run security audit before deploy?`
- option-a-label: `Run security audit (recommended for production deployments)`
- option-b-label: `Skip — proceed directly to deploy`
- recommendation: `A — catches vulnerabilities before production`
- target-skill: `.cursor/skills/security/SKILL.md`
- next-step: Step 15 (Performance Test)
---
**Step 15 — Performance Test (optional)**
State-driven: reached by auto-chain from Step 14 (completed or skipped).
Action: Apply the **Optional Skill Gate** (`protocols.md` → "Optional Skill Gate") with:
- question: `Run performance/load tests before deploy?`
- option-a-label: `Run performance tests (recommended for latency-sensitive or high-load systems)`
- option-b-label: `Skip — proceed directly to deploy`
- recommendation: `A or B — base on whether acceptance criteria include latency, throughput, or load requirements`
- target-skill: `.cursor/skills/test-run/SKILL.md` in **perf mode** (the skill handles runner detection, threshold comparison, and its own A/B/C gate on threshold failures)
- next-step: Step 16 (Deploy)
---
**Step 16 — Deploy**
State-driven: reached by auto-chain from Step 15 (completed or skipped).
Action: Read and execute `.cursor/skills/deploy/SKILL.md`.
After the deploy skill completes successfully, mark Step 16 as `completed` and auto-chain to Step 17 (Retrospective).
---
**Step 17 — Retrospective**
State-driven: reached by auto-chain from Step 16, for the current `state.cycle`.
Action: Read and execute `.cursor/skills/retrospective/SKILL.md` in **cycle-end mode**. Pass cycle context (`cycle: state.cycle`) so the retro report and LESSONS.md entries record which feature cycle they came from.
After retrospective completes, mark Step 17 as `completed` and enter "Re-Entry After Completion" evaluation.
---
**Re-Entry After Completion**
State-driven: `state.step == done` OR Step 17 (Retrospective) is completed for `state.cycle`.
Action: The project completed a full cycle. Print the status banner and automatically loop back to New Task — do NOT ask the user for confirmation:
```
══════════════════════════════════════
PROJECT CYCLE COMPLETE
══════════════════════════════════════
The previous cycle finished successfully.
Starting new feature cycle…
══════════════════════════════════════
```
Set `step: 9`, `status: not_started`, and **increment `cycle`** (`cycle: state.cycle + 1`) in the state file, then auto-chain to Step 9 (New Task). Reset `sub_step` to `phase: 0, name: awaiting-invocation, detail: ""` and `retry_count: 0`.
Note: the loop (Steps 9 → 17 → 9) ensures every feature cycle includes: New Task → Implement → Run Tests → Test-Spec Sync → Update Docs → Security → Performance → Deploy → Retrospective.
## Auto-Chain Rules
### Phase A — One-time baseline setup
| Completed Step | Next Action |
|---------------|-------------|
| Document (1) | Auto-chain → Architecture Baseline Scan (2) |
| Architecture Baseline Scan (2) | Auto-chain → Test Spec (3). If baseline has High/Critical Architecture findings, surface them as inputs to Step 4 (testability) or defer to Step 8 (refactor). |
| Test Spec (3) | Auto-chain → Code Testability Revision (4) |
| Code Testability Revision (4) | Auto-chain → Decompose Tests (5) |
| Decompose Tests (5) | **Session boundary** — suggest new conversation before Implement Tests |
| Implement Tests (6) | Auto-chain → Run Tests (7) |
| Run Tests (7, all pass) | Auto-chain → Refactor choice (8) |
| Refactor (8, done or skipped) | Auto-chain → New Task (9) — enters Phase B |
### Phase B — Feature cycle (loops)
| Completed Step | Next Action |
|---------------|-------------|
| New Task (9) | **Session boundary** — suggest new conversation before Implement |
| Implement (10) | Auto-chain → Run Tests (11) |
| Run Tests (11, all pass) | Auto-chain → Test-Spec Sync (12) |
| Test-Spec Sync (12, done or skipped) | Auto-chain → Update Docs (13) |
| Update Docs (13) | Auto-chain → Security Audit choice (14) |
| Security Audit (14, done or skipped) | Auto-chain → Performance Test choice (15) |
| Performance Test (15, done or skipped) | Auto-chain → Deploy (16) |
| Deploy (16) | Auto-chain → Retrospective (17) |
| Retrospective (17) | **Cycle complete** — loop back to New Task (9) with incremented cycle counter |
## Status Summary — Step List
Flow name: `existing-code`. Render using the banner template in `protocols.md` → "Banner Template (authoritative)".
Flow-specific slot values:
- `<header-suffix>`: ` — Cycle <N>` when `state.cycle > 1`; otherwise empty.
- `<current-suffix>`: ` (cycle <N>)` when `state.cycle > 1`; otherwise empty.
- `<footer-extras>`: empty.
**Phase A — One-time baseline setup**
| # | Step Name | Extra state tokens (beyond the shared set) |
|---|-----------------------------|--------------------------------------------|
| 1 | Document | — |
| 2 | Architecture Baseline | — |
| 3 | Test Spec | — |
| 4 | Code Testability Revision | — |
| 5 | Decompose Tests | `DONE (N tasks)` |
| 6 | Implement Tests | `IN PROGRESS (batch M)` |
| 7 | Run Tests | `DONE (N passed, M failed)` |
| 8 | Refactor | `IN PROGRESS (phase N)` |
**Phase B — Feature cycle (loops)**
| # | Step Name | Extra state tokens (beyond the shared set) |
|---|-----------------------------|--------------------------------------------|
| 9 | New Task | `DONE (N tasks)` |
| 10 | Implement | `IN PROGRESS (batch M of ~N)` |
| 11 | Run Tests | `DONE (N passed, M failed)` |
| 12 | Test-Spec Sync | — |
| 13 | Update Docs | — |
| 14 | Security Audit | — |
| 15 | Performance Test | — |
| 16 | Deploy | — |
| 17 | Retrospective | — |
All rows accept the shared state tokens (`DONE`, `IN PROGRESS`, `NOT STARTED`, `FAILED (retry N/3)`); rows 2, 4, 8, 12, 13, 14, 15 additionally accept `SKIPPED`.
Row rendering format (renders with a phase separator between Step 8 and Step 9):
```
── Phase A: One-time baseline setup ──
Step 1 Document [<state token>]
Step 2 Architecture Baseline [<state token>]
Step 3 Test Spec [<state token>]
Step 4 Code Testability Rev. [<state token>]
Step 5 Decompose Tests [<state token>]
Step 6 Implement Tests [<state token>]
Step 7 Run Tests [<state token>]
Step 8 Refactor [<state token>]
── Phase B: Feature cycle (loops) ──
Step 9 New Task [<state token>]
Step 10 Implement [<state token>]
Step 11 Run Tests [<state token>]
Step 12 Test-Spec Sync [<state token>]
Step 13 Update Docs [<state token>]
Step 14 Security Audit [<state token>]
Step 15 Performance Test [<state token>]
Step 16 Deploy [<state token>]
Step 17 Retrospective [<state token>]
```
+389
View File
@@ -0,0 +1,389 @@
# Greenfield Workflow
Workflow for new projects built from scratch. Flows linearly: Problem → Research → Plan → UI Design (if applicable) → Test Spec → Decompose → Implement + Product Completeness Gate → Code Testability Revision → Decompose Tests → Implement Tests → Run Tests → Test-Spec Sync → Update Docs → Security Audit (optional) → Performance Test (optional) → Deploy → Retrospective.
## Step Reference Table
| Step | Name | Sub-Skill | Internal SubSteps |
|------|------|-----------|-------------------|
| 1 | Problem | problem/SKILL.md | Phase 14 |
| 2 | Research | research/SKILL.md | Mode A: Phase 14 · Mode B: Step 08 |
| 3 | Plan | plan/SKILL.md | Step 16 + Final |
| 4 | UI Design | ui-design/SKILL.md | Phase 08 (conditional — UI projects only) |
| 5 | Test Spec | test-spec/SKILL.md | Phases 14 |
| 6 | Decompose | decompose/SKILL.md (implementation task decomposition) | Step 1 + Step 1.5 + Step 2 + Step 4 |
| 7 | Implement | implement/SKILL.md | Batch loop + Product Implementation Completeness Gate |
| 8 | Code Testability Revision | refactor/SKILL.md (guided mode) | Phases 07 (conditional) |
| 9 | Decompose Tests | decompose/SKILL.md (tests-only) | Step 1t + Step 3 + Step 4 |
| 10 | Implement Tests | implement/SKILL.md | (batch-driven, no fixed sub-steps) |
| 11 | Run Tests | test-run/SKILL.md | Steps 14 |
| 12 | Test-Spec Sync | test-spec/SKILL.md (cycle-update mode) | Phase 2 + Phase 3 (scoped) |
| 13 | Update Docs | document/SKILL.md (task mode) | Task Steps 05 |
| 14 | Security Audit | security/SKILL.md | Phase 15 (optional) |
| 15 | Performance Test | test-run/SKILL.md (perf mode) | Steps 15 (optional) |
| 16 | Deploy | deploy/SKILL.md | Step 17 |
| 17 | Retrospective | retrospective/SKILL.md (cycle-end mode) | Steps 14 |
## Detection Rules
**Resolution**: when a state file exists, `state.step` + `state.status` drive detection and the conditions below are not consulted. When no state file exists (cold start), walk the rules in order — first folder-probe match wins. Steps without a folder probe are state-driven only; they can only be reached by auto-chain from a prior step.
---
**Step 1 — Problem Gathering**
Condition: `_docs/00_problem/` does not exist, OR any of these are missing/empty:
- `problem.md`
- `restrictions.md`
- `acceptance_criteria.md`
- `input_data/` (must contain at least one file)
Action: Read and execute `.cursor/skills/problem/SKILL.md`
---
**Step 2 — Research (Initial)**
Condition: `_docs/00_problem/` is complete AND `_docs/01_solution/` has no `solution_draft*.md` files
Action: Read and execute `.cursor/skills/research/SKILL.md` (will auto-detect Mode A)
---
**Research Decision** (inline gate between Step 2 and Step 3)
Condition: `_docs/01_solution/` contains `solution_draft*.md` files AND `_docs/01_solution/solution.md` does not exist AND `_docs/02_document/architecture.md` does not exist
Action: Present the current research state to the user:
- How many solution drafts exist
- Whether tech_stack.md and security_analysis.md exist
- One-line summary from the latest draft
Then present using the **Choose format**:
```
══════════════════════════════════════
DECISION REQUIRED: Research complete — next action?
══════════════════════════════════════
A) Run another research round (Mode B assessment)
B) Proceed to planning with current draft
══════════════════════════════════════
Recommendation: [A or B] — [reason based on draft quality]
══════════════════════════════════════
```
- If user picks A → Read and execute `.cursor/skills/research/SKILL.md` (will auto-detect Mode B)
- If user picks B → auto-chain to Step 3 (Plan)
---
**Step 3 — Plan**
Condition: `_docs/01_solution/` has `solution_draft*.md` files AND `_docs/02_document/architecture.md` does not exist
Action:
1. The plan skill's Prereq 2 will rename the latest draft to `solution.md` — this is handled by the plan skill itself
2. Read and execute `.cursor/skills/plan/SKILL.md`
If `_docs/02_document/` exists but is incomplete (has some artifacts but no `FINAL_report.md`), the plan skill's built-in resumability handles it.
---
**Step 4 — UI Design (conditional)**
Condition (folder fallback): `_docs/02_document/architecture.md` exists AND `_docs/02_document/tests/traceability-matrix.md` does not exist.
State-driven: reached by auto-chain from Step 3.
Action: Read and execute `.cursor/skills/ui-design/SKILL.md`. The skill runs its own **Applicability Check**, which handles UI project detection and the user's A/B choice. It returns one of:
- `outcome: completed` → mark Step 4 as `completed`, auto-chain to Step 5 (Test Spec).
- `outcome: skipped, reason: not-a-ui-project` → mark Step 4 as `skipped`, auto-chain to Step 5.
- `outcome: skipped, reason: user-declined` → mark Step 4 as `skipped`, auto-chain to Step 5.
The autodev no longer inlines UI detection heuristics — they live in `ui-design/SKILL.md` under "Applicability Check".
---
**Step 5 — Test Spec**
Condition (folder fallback): `_docs/02_document/FINAL_report.md` exists AND `_docs/02_document/architecture.md` exists AND `_docs/02_document/tests/traceability-matrix.md` does not exist.
State-driven: reached by auto-chain from Step 4 (completed or skipped).
Action: Read and execute `.cursor/skills/test-spec/SKILL.md`.
This step converts the greenfield problem statement, acceptance criteria, solution, architecture, component docs, and UI design artifacts (if any) into test specifications before implementation begins. The test spec should cover unit, integration, blackbox, and e2e scenarios where those levels are applicable to the project.
---
**Step 6 — Decompose**
Condition: `_docs/02_document/` contains `architecture.md` AND `_docs/02_document/components/` has at least one component AND `_docs/02_document/tests/traceability-matrix.md` exists AND `_docs/02_tasks/todo/` does not exist or has no implementation task files.
Action: Invoke `.cursor/skills/decompose/SKILL.md` for **implementation task decomposition**. The greenfield flow selects the implementation entrypoint before handing off: Bootstrap Structure, Module Layout, Component Task Decomposition, and Cross-Task Verification.
Do not invoke Blackbox Test Task Decomposition from Step 6. Test tasks are intentionally deferred to Step 9 (Decompose Tests) so the first implementation batch stays focused on product functionality and Step 8 can revise testability before test task files exist.
If `_docs/02_tasks/` subfolders have some task files already, the decompose skill's resumability handles it.
---
**Step 7 — Implement**
Condition: `_docs/02_tasks/todo/` contains implementation task files AND `_dependencies_table.md` exists AND `_docs/03_implementation/` does not contain a valid product implementation report.
Action: Invoke `.cursor/skills/implement/SKILL.md` with task selection context **Product implementation**.
The implement skill must run its **Product Implementation Completeness Gate** before it writes any final product implementation report. This gate compares completed product task specs, architecture/component promises, and actual source code so scaffold-only implementations cannot advance to Step 8. A final product implementation report without `_docs/03_implementation/implementation_completeness_cycle[N]_report.md` is incomplete and must not be treated as Step 7 completion.
If `_docs/03_implementation/` has batch reports, the implement skill detects completed tasks and continues. The FINAL report filename is context-dependent — see implement skill documentation for naming convention.
For folder fallback, **implementation task files** means task specs that are not test-only specs: exclude `*_test_infrastructure.md` and task specs whose `**Component**` or `**Epic**` identifies `Blackbox Tests`.
For folder fallback, a **product implementation report** is any `_docs/03_implementation/implementation_report_*.md` file except `_docs/03_implementation/implementation_report_tests.md` and refactor reports. It is valid for greenfield progression only when:
- the matching `_docs/03_implementation/implementation_completeness_cycle[N]_report.md` exists,
- that completeness report does not contain unresolved `FAIL` classifications, and
- `_docs/02_tasks/todo/` contains no pending implementation task files.
If a product report exists but any of those validity checks fail, treat product implementation as incomplete and stay in Step 7.
---
**Step 8 — Code Testability Revision**
Condition (folder fallback): `_docs/03_implementation/` contains a valid product implementation report, `_docs/03_implementation/implementation_completeness_cycle[N]_report.md` exists without unresolved `FAIL` classifications, `_docs/04_refactoring/01-testability-refactoring/testability_assessment.md` does not exist, `_docs/04_refactoring/01-testability-refactoring/testability_changes_summary.md` does not exist, `_docs/03_implementation/implementation_report_tests.md` does not exist, and `_docs/02_tasks/todo/` does not contain test task files.
State-driven: reached by auto-chain from Step 7.
**Purpose**: verify the newly built code can be exercised by the planned tests before writing the test suite. Greenfield code should be testable by design; this step catches accidental hardcoded paths, singletons, direct external service construction, or other implementation choices that would make meaningful tests impossible.
**Scope — MINIMAL, SURGICAL fixes**: this is not a general refactor. It is the smallest set of changes required to make the implemented code runnable under tests.
**Allowed changes** in this phase:
- Replace hardcoded URLs / file paths / credentials / magic numbers with env vars or constructor arguments.
- Extract narrow interfaces for components that need stubbing in tests.
- Add optional constructor parameters for dependency injection; default to the existing behavior so callers do not break.
- Wrap global singletons in thin accessors that tests can override.
- Split a function ONLY when necessary to stub one of its collaborators — do not split for clarity alone.
**NOT allowed** in this phase (defer to a later refactor task):
- Renaming public APIs.
- Moving code between files unless strictly required for isolation.
- Changing algorithms or business logic.
- Restructuring module boundaries or rewriting layers.
Action: Analyze the codebase against the test specs to determine whether the code can be tested as-is.
1. Read `_docs/02_document/tests/traceability-matrix.md` and all test scenario files in `_docs/02_document/tests/`.
2. For each test scenario, check whether the code under test can be exercised in isolation. Look for:
- Hardcoded file paths or directory references
- Hardcoded configuration values (URLs, credentials, magic numbers)
- Global mutable state that cannot be overridden
- Tight coupling to external services without abstraction
- Missing dependency injection or non-configurable parameters
- Direct file system operations without path configurability
- Inline construction of heavy dependencies (models, clients)
3. If ALL scenarios are testable as-is:
- Create `_docs/04_refactoring/01-testability-refactoring/`
- Write `_docs/04_refactoring/01-testability-refactoring/testability_assessment.md` with the scenarios reviewed and outcome "Code is testable — no changes needed"
- Mark Step 8 as `completed` with outcome "Code is testable — no changes needed"
- Auto-chain to Step 9 (Decompose Tests)
4. If testability issues are found:
- Create `_docs/04_refactoring/01-testability-refactoring/`
- Write `list-of-changes.md` in that directory using the refactor skill template (`.cursor/skills/refactor/templates/list-of-changes.md`), with:
- **Mode**: `guided`
- **Source**: `autodev-greenfield-testability-analysis`
- One change entry per testability issue found (change ID, file paths, problem, proposed change, risk, dependencies). Each entry must fit the allowed-changes list above; reject entries that drift into full refactor territory and log them under "Deferred refactor candidates" instead.
- Invoke the refactor skill in **guided mode**: read and execute `.cursor/skills/refactor/SKILL.md` with the `list-of-changes.md` as input
- Phase 3 (Safety Net) is skipped for this testability run because the test suite has not been implemented yet
- After execution, surface `RUN_DIR/testability_changes_summary.md` to the user via the Choose format (accept / request follow-up) before auto-chaining
- Copy or save the accepted summary as `_docs/04_refactoring/01-testability-refactoring/testability_changes_summary.md` so folder fallback can detect Step 8 completion
- Mark Step 8 as `completed`
- Auto-chain to Step 9 (Decompose Tests)
---
**Step 9 — Decompose Tests**
Condition (folder fallback): `_docs/02_document/tests/traceability-matrix.md` exists AND workspace contains source code files AND `_docs/03_implementation/` contains a valid product implementation report AND `_docs/03_implementation/implementation_completeness_cycle[N]_report.md` exists without unresolved `FAIL` classifications AND (`_docs/04_refactoring/01-testability-refactoring/testability_assessment.md` exists OR `_docs/04_refactoring/01-testability-refactoring/testability_changes_summary.md` exists) AND (`_docs/02_tasks/todo/` does not exist or has no test task files) AND `_docs/03_implementation/implementation_report_tests.md` does not exist.
State-driven: reached by auto-chain from Step 8.
Action: Read and execute `.cursor/skills/decompose/SKILL.md` in **tests-only mode** (pass `_docs/02_document/tests/` as input). The decompose skill will:
1. Run Step 1t (test infrastructure bootstrap)
2. Run Step 3 (blackbox/e2e-capable test task decomposition)
3. Run Step 4 (cross-verification against test coverage)
If `_docs/02_tasks/` subfolders have some task files already, the decompose skill's resumability handles it — it appends test tasks alongside existing completed implementation tasks.
---
**Step 10 — Implement Tests**
Condition (folder fallback): `_docs/02_tasks/todo/` contains test task files AND `_dependencies_table.md` exists AND `_docs/03_implementation/implementation_report_tests.md` does not exist.
State-driven: reached by auto-chain from Step 9.
Action: Invoke `.cursor/skills/implement/SKILL.md` with task selection context **Test implementation**.
The implement skill reads only test tasks from `_docs/02_tasks/todo/` and implements them.
If `_docs/03_implementation/` has batch reports, the implement skill detects completed test tasks and continues.
For folder fallback, **test task files** means `*_test_infrastructure.md` plus task specs whose `**Component**` or `**Epic**` identifies `Blackbox Tests`.
---
**Step 11 — Run Tests**
Condition (folder fallback): `_docs/03_implementation/implementation_report_tests.md` exists.
State-driven: reached by auto-chain from Step 10.
Action: Read and execute `.cursor/skills/test-run/SKILL.md`
Verifies the implemented unit, integration, blackbox, and e2e tests pass before proceeding to spec and documentation sync. This is a hard product gate, not a harness-smoke gate: e2e/blackbox tests must exercise the actual implemented system through public runtime boundaries and compare actual outputs against `_docs/00_problem/input_data/expected_results/results_report.md` or referenced machine-readable expected-result files. Stubs are allowed only for external systems outside the product boundary; missing internal product implementation must fail or block the gate and send the flow back to Implement.
---
**Step 12 — Test-Spec Sync**
State-driven: reached by auto-chain from Step 11. Requires `_docs/02_document/tests/traceability-matrix.md` to exist — if missing, mark Step 12 `skipped` (see Action below).
Action: Read and execute `.cursor/skills/test-spec/SKILL.md` in **cycle-update mode**. Pass the completed implementation task specs, completed test task specs, and implementation reports as inputs.
The skill appends implementation-learned acceptance criteria, scenarios, and NFR updates to the existing test-spec files without rewriting unaffected sections. If `traceability-matrix.md` is missing, mark Step 12 as `skipped` — the next `/test-spec` full run will regenerate it.
After completion, auto-chain to Step 13 (Update Docs).
---
**Step 13 — Update Docs**
State-driven: reached by auto-chain from Step 12 (completed or skipped). Requires `_docs/02_document/` to contain existing documentation — if missing, mark Step 13 `skipped` (see Action below).
Action: Read and execute `.cursor/skills/document/SKILL.md` in **Task mode**. Pass all completed implementation and test task spec files plus the implementation reports.
The document skill in Task mode updates affected module docs, component docs, system-level docs, and test documentation without redoing full discovery, verification, or problem extraction.
If `_docs/02_document/` does not contain existing docs, mark Step 13 as `skipped`.
After completion, auto-chain to Step 14 (Security Audit).
---
**Step 14 — Security Audit (optional)**
State-driven: reached by auto-chain from Step 13 (completed or skipped).
Action: Apply the **Optional Skill Gate** (`protocols.md` → "Optional Skill Gate") with:
- question: `Run security audit before deploy?`
- option-a-label: `Run security audit (recommended for production deployments)`
- option-b-label: `Skip — proceed directly to deploy`
- recommendation: `A — catches vulnerabilities before production`
- target-skill: `.cursor/skills/security/SKILL.md`
- next-step: Step 15 (Performance Test)
---
**Step 15 — Performance Test (optional)**
State-driven: reached by auto-chain from Step 14 (completed or skipped).
Action: Apply the **Optional Skill Gate** (`protocols.md` → "Optional Skill Gate") with:
- question: `Run performance/load tests before deploy?`
- option-a-label: `Run performance tests (recommended for latency-sensitive or high-load systems)`
- option-b-label: `Skip — proceed directly to deploy`
- recommendation: `A or B — base on whether acceptance criteria include latency, throughput, or load requirements`
- target-skill: `.cursor/skills/test-run/SKILL.md` in **perf mode** (the skill handles runner detection, threshold comparison, and its own A/B/C gate on threshold failures)
- next-step: Step 16 (Deploy)
---
**Step 16 — Deploy**
State-driven: reached by auto-chain from Step 15 (after Step 15 is completed or skipped).
Action: Read and execute `.cursor/skills/deploy/SKILL.md`.
After the deploy skill completes successfully, mark Step 16 as `completed` and auto-chain to Step 17 (Retrospective).
---
**Step 17 — Retrospective**
State-driven: reached by auto-chain from Step 16.
Action: Read and execute `.cursor/skills/retrospective/SKILL.md` in **cycle-end mode**. This closes the cycle's feedback loop by folding metrics into `_docs/06_metrics/retro_<date>.md` and appending the top-3 lessons to `_docs/LESSONS.md`.
After retrospective completes, mark Step 17 as `completed` and enter "Done" evaluation.
---
**Done**
State-driven: reached by auto-chain from Step 17. (Sanity check: `_docs/04_deploy/` should contain all expected artifacts — containerization.md, ci_cd_pipeline.md, environment_strategy.md, observability.md, deployment_procedures.md, deploy_scripts.md.)
Action: Report project completion with summary. Then **rewrite the state file** so the next `/autodev` invocation enters the feature-cycle loop in the existing-code flow:
```
flow: existing-code
step: 9
name: New Task
status: not_started
sub_step:
phase: 0
name: awaiting-invocation
detail: ""
retry_count: 0
cycle: 1
```
On the next invocation, Flow Resolution rule 1 reads `flow: existing-code` and re-entry flows directly into existing-code Step 9 (New Task).
## Auto-Chain Rules
| Completed Step | Next Action |
|---------------|-------------|
| Problem (1) | Auto-chain → Research (2) |
| Research (2) | Auto-chain → Research Decision (ask user: another round or proceed?) |
| Research Decision → proceed | Auto-chain → Plan (3) |
| Plan (3) | Auto-chain → UI Design detection (4) |
| UI Design (4, done or skipped) | Auto-chain → Test Spec (5) |
| Test Spec (5) | Auto-chain → Decompose (6) |
| Decompose (6) | **Session boundary** — suggest new conversation before Implement |
| Implement (7) | Auto-chain only after Product Implementation Completeness Gate passes → Code Testability Revision (8) |
| Code Testability Revision (8) | Auto-chain → Decompose Tests (9) |
| Decompose Tests (9) | **Session boundary** — suggest new conversation before Implement Tests |
| Implement Tests (10) | Auto-chain → Run Tests (11) |
| Run Tests (11, all pass) | Auto-chain → Test-Spec Sync (12) |
| Test-Spec Sync (12, done or skipped) | Auto-chain → Update Docs (13) |
| Update Docs (13, done or skipped) | Auto-chain → Security Audit choice (14) |
| Security Audit (14, done or skipped) | Auto-chain → Performance Test choice (15) |
| Performance Test (15, done or skipped) | Auto-chain → Deploy (16) |
| Deploy (16) | Auto-chain → Retrospective (17) |
| Retrospective (17) | Report completion; rewrite state to existing-code flow, step 9 |
## Status Summary — Step List
Flow name: `greenfield`. Render using the banner template in `protocols.md` → "Banner Template (authoritative)". No header-suffix, current-suffix, or footer-extras — all empty for this flow.
| # | Step Name | Extra state tokens (beyond the shared set) |
|---|-----------------------------|--------------------------------------------|
| 1 | Problem | — |
| 2 | Research | `DONE (N drafts)` |
| 3 | Plan | — |
| 4 | UI Design | — |
| 5 | Test Spec | — |
| 6 | Decompose | `DONE (N tasks)` |
| 7 | Implement | `IN PROGRESS (batch M of ~N)` |
| 8 | Code Testability Revision | — |
| 9 | Decompose Tests | `DONE (N tasks)` |
| 10 | Implement Tests | `IN PROGRESS (batch M)` |
| 11 | Run Tests | `DONE (N passed, M failed)` |
| 12 | Test-Spec Sync | — |
| 13 | Update Docs | — |
| 14 | Security Audit | — |
| 15 | Performance Test | — |
| 16 | Deploy | — |
| 17 | Retrospective | — |
All rows also accept the shared state tokens (`DONE`, `IN PROGRESS`, `NOT STARTED`, `FAILED (retry N/3)`); rows 4, 12, 13, 14, 15 additionally accept `SKIPPED`.
Row rendering format (step-number column is right-padded to 2 characters for alignment):
```
Step 1 Problem [<state token>]
Step 2 Research [<state token>]
Step 3 Plan [<state token>]
Step 4 UI Design [<state token>]
Step 5 Test Spec [<state token>]
Step 6 Decompose [<state token>]
Step 7 Implement [<state token>]
Step 8 Code Testability Rev. [<state token>]
Step 9 Decompose Tests [<state token>]
Step 10 Implement Tests [<state token>]
Step 11 Run Tests [<state token>]
Step 12 Test-Spec Sync [<state token>]
Step 13 Update Docs [<state token>]
Step 14 Security Audit [<state token>]
Step 15 Performance Test [<state token>]
Step 16 Deploy [<state token>]
Step 17 Retrospective [<state token>]
```
+489
View File
@@ -0,0 +1,489 @@
# Meta-Repo Workflow
Workflow for **meta-repositories** — repos that aggregate multiple components via git submodules, npm/cargo/pnpm/go workspaces, or ad-hoc conventions. The meta-repo itself has little or no source code of its own; it orchestrates cross-cutting documentation, CI/CD, and component registration.
This flow differs fundamentally from `greenfield` and `existing-code`:
- **No problem/research/plan phases** — meta-repos don't build features, they coordinate existing ones
- **No test spec / run tests** — the meta-repo has no code to test
- **`implement` is scoped to suite-level work only** — cross-repo concerns, repo/folder renames, suite-root infra additions (e.g., `.gitmodules`, `_infra/`, suite `e2e/`). Per-component implementation lives in each component's own workspace `/autodev` cycle. The meta-repo's implement step (Step 3.5) executes only when `_docs/tasks/todo/` is non-empty AND the user explicitly opts in; placement is **before** the sync skills so subsequent Doc/E2E/CICD sync propagates the post-implementation state.
- **No `_docs/00_problem/` artifacts** — documentation target is `_docs/*.md` unified docs, not per-feature `_docs/NN_feature/` folders
- **Primary artifact is `_docs/_repo-config.yaml`** — generated by `monorepo-discover`, read by every other step
## Step Reference Table
| Step | Name | Sub-Skill | Internal SubSteps |
|------|------|-----------|-------------------|
| 1 | Discover | monorepo-discover/SKILL.md | Phase 110 |
| 2 | Config Review | (human checkpoint, no sub-skill) | — |
| 2.5 | Glossary & Architecture Vision | (inline, no sub-skill) | Steps 15 |
| 3 | Status | monorepo-status/SKILL.md | Sections 15 |
| 3.5 | Suite Implement | implement/SKILL.md (suite-level invocation context) | Steps 114 + 16 (Step 14.5 + Step 15 skipped); conditional on `_docs/tasks/todo/` non-empty AND user opt-in |
| 4 | Document Sync | monorepo-document/SKILL.md | Phase 17 (conditional on doc drift) |
| 4.5 | Integration Test Sync | monorepo-e2e/SKILL.md | Phase 16 (conditional on suite-e2e drift; skipped if `suite_e2e:` block absent in config) |
| 5 | CICD Sync | monorepo-cicd/SKILL.md | Phase 17 (conditional on CI drift) |
| 6 | Loop | (auto-return to Step 3 on next invocation) | — |
**Onboarding is NOT in the auto-chain.** Onboarding a new component is always user-initiated (`monorepo-onboard` directly, or answering "yes" to the optional onboard branch at end of Step 5). The autodev does NOT silently onboard components it discovers.
## Detection Rules
**Resolution**: when a state file exists, `state.step` + `state.status` drive detection and the conditions below are not consulted. When no state file exists (cold start), walk the rules in order — first match wins. Meta-repo uses `_docs/_repo-config.yaml` (and its `confirmed_by_user` flag) as its primary folder-probe signal rather than per-step artifact folders.
---
**Step 1 — Discover**
Condition: `_docs/_repo-config.yaml` does NOT exist
Action: Read and execute `.cursor/skills/monorepo-discover/SKILL.md`. After completion, auto-chain to **Step 2 (Config Review)**.
---
**Step 2 — Config Review** (session boundary)
Condition: `_docs/_repo-config.yaml` exists AND top-level `confirmed_by_user: false`
Action: This is a **hard session boundary**. The skill cannot proceed until a human reviews the generated config and sets `confirmed_by_user: true`. Present using Choose format:
```
══════════════════════════════════════
DECISION REQUIRED: Config review pending
══════════════════════════════════════
_docs/_repo-config.yaml was generated by monorepo-discover
but has confirmed_by_user: false.
A) I've reviewed — proceed to Status
B) Pause — I'll review the config and come back later
══════════════════════════════════════
Recommendation: B — review the inferred mappings (tagged
`confirmed: false`), unresolved questions, and assumptions
before flipping confirmed_by_user: true.
══════════════════════════════════════
```
- If user picks A → verify `confirmed_by_user: true` is now set in the config. If still `false`, re-ask. If true, auto-chain to **Step 2.5 (Glossary & Architecture Vision)**.
- If user picks B → mark Step 2 as `in_progress`, update state file, end the session. Tell the user to invoke `/autodev` again after reviewing.
**Do NOT auto-flip `confirmed_by_user`.** Only the human does that.
---
**Step 2.5 — Glossary & Architecture Vision** (one-shot)
Condition (folder fallback): `_docs/_repo-config.yaml` exists AND `confirmed_by_user: true` AND (`_docs/glossary.md` does NOT exist OR the cross-cutting architecture doc identified in `docs.cross_cutting` does NOT contain a `## Architecture Vision` section).
State-driven: reached by auto-chain from Step 2 (user picked A).
**Goal**: Capture meta-repo-wide terminology and the user's architecture vision **once**, after the config is confirmed but before any sync skill runs. Without this, `monorepo-document` will faithfully propagate per-component changes but never surface a unified mental model of the meta-repo to the user, and the AI will keep re-inferring the same project terminology on every invocation.
**Why inline (no sub-skill)**: `monorepo-discover` is hard-guarded to write only `_repo-config.yaml`; `monorepo-document` only edits *existing* docs. Glossary and architecture-vision creation is a first-time, user-confirmed write that crosses both guarantees, so it lives directly in the flow.
**Inputs**:
- `_docs/_repo-config.yaml` (component list, doc map, conventions, assumptions log)
- Cross-cutting docs listed under `docs.cross_cutting` (existing architecture doc, if any)
- Each component's `primary_doc` (read-only, for terminology + responsibility extraction)
- Root `README.md` if `repo.root_readme` is referenced
**Outputs**:
- `_docs/glossary.md` (or `<docs.root>/glossary.md` if `docs.root``_docs/`) — NEW
- The cross-cutting architecture doc updated in place: a `## Architecture Vision` section is prepended (or merged into an existing "Vision" / "Overview" heading)
- One new entry appended to `_docs/_repo-config.yaml` under `assumptions_log:` recording the run
- A new top-level config entry: `glossary_doc: <path>` so future `monorepo-status` and `monorepo-document` runs treat the glossary as a known cross-cutting doc
**Procedure**:
1. **Draft glossary** from `_repo-config.yaml` + each component's primary doc. Include:
- Component codenames as they appear in the config (`name` field) and any rename pairs the user noted in `unresolved:` resolutions
- Domain terms that recur across ≥2 component docs
- Acronyms / abbreviations
- Convention names from `conventions:` (e.g., commit prefix, deployment tier names)
- Stakeholder personas if cross-cutting docs reference them
Each entry: one-line definition + source (`source: components.<name>.primary_doc` or `source: _repo-config.yaml conventions`). Skip generic terms.
2. **Draft architecture vision** from the meta-repo perspective:
- **One paragraph**: what the system as a whole is, what each component contributes, the runtime topology (one binary / N services / N clients + 1 server / hybrid), how components communicate (REST / gRPC / queue / DB-shared / file-shared)
- **Components & responsibilities** (one-line each), pulled directly from `_repo-config.yaml` `components:` list
- **Cross-cutting concerns ownership**: which doc owns which concern (auth, schema, deployment, etc.) — pulled from `docs.cross_cutting[].owns`
- **Architectural principles / non-negotiables** the user has implied across components (e.g., "all components share a single Postgres", "submodules own their own CI", "deployment is per-tier, not per-component")
- **Open questions / structural drift signals**: components missing from `docs.cross_cutting`, components in registry but not in config (registry mismatch), or contradictions between component primary docs
3. **Present condensed view** to the user (NOT the full draft files):
```
══════════════════════════════════════
REVIEW: Meta-Repo Glossary + Architecture Vision
══════════════════════════════════════
Glossary (N terms drafted from config + component docs):
- <Term>: <one-line definition>
- ...
Architecture Vision — meta-repo level:
<one-paragraph synopsis>
Components / responsibilities:
- <component>: <one-line>
- ...
Cross-cutting ownership:
- <concern> → <doc>
- ...
Principles / non-negotiables:
- <principle>
- ...
Open questions / drift signals:
- <q1>
- <q2>
══════════════════════════════════════
A) Looks correct — write the files
B) Add / correct entries (provide diffs)
C) Resolve open questions / drift signals first
══════════════════════════════════════
Recommendation: pick C if drift signals exist;
otherwise B if components or principles
don't match your intent; A only when
the inferred vision is exactly right.
══════════════════════════════════════
```
4. **Iterate**:
- On B → integrate the user's diffs/additions, re-present, loop until A.
- On C → ask the listed open questions in one batch, integrate answers, re-present.
- **Do NOT proceed to step 5 until the user picks A.**
5. **Save**:
- Write `_docs/glossary.md` (alphabetical) with `**Status**: confirmed-by-user` + date.
- Update the cross-cutting architecture doc identified in `docs.cross_cutting` (or create one at `_docs/00_architecture.md` if none exists and the user's option-B input named one): prepend `## Architecture Vision` with the confirmed paragraph + components + ownership + principles. Preserve every existing H2 below verbatim.
- Append to `_docs/_repo-config.yaml`:
- Top-level `glossary_doc: <path-relative-to-repo-root>` (sibling of `docs.root`)
- New `assumptions_log:` entry: `{ date: <today>, skill: autodev-meta-repo Step 2.5, run_notes: "Captured glossary + architecture vision", assumptions: [...] }`
- Do NOT flip any `confirmed: false` → `confirmed: true` in the config; this step writes its own confirmed artifact, it does not retroactively confirm config inferences.
**Self-verification**:
- [ ] Every glossary entry traces to either the config or a component primary doc
- [ ] Every component listed in the vision matches a `components:` entry in the config
- [ ] All open questions are answered or explicitly deferred (with the user's acknowledgement)
- [ ] The cross-cutting architecture doc still contains every H2 it had before this step
- [ ] User picked option A on the latest condensed view
**Idempotency**: if both `_docs/glossary.md` exists AND the architecture doc already has a `## Architecture Vision` section, this step is **skipped on re-invocation**. To refresh, the user invokes `/autodev` after deleting `glossary.md` (or running `monorepo-discover` with structural changes that justify a re-confirmation).
After completion, auto-chain to **Step 3 (Status)**.
---
**Step 3 — Status**
Condition (folder fallback): `_docs/_repo-config.yaml` exists AND `confirmed_by_user: true` AND (`_docs/glossary.md` exists OR `glossary_doc:` is recorded in the config).
State-driven: reached by auto-chain from Step 2.5, or entered on any re-invocation after a completed cycle.
Action: Read and execute `.cursor/skills/monorepo-status/SKILL.md`.
The status report identifies:
- Components with doc drift (commits newer than their mapped docs)
- Components with CI coverage gaps
- Registry/config mismatches
- Unresolved questions
Based on the report, auto-chain branches in this evaluation order (first match wins):
1. **Registry mismatch** (new components not in config, or config component not in registry) → present the Choose format below FIRST. After the user resolves it (A: refresh discover, B: onboard, C: continue with mismatch acknowledged), proceed to the next rule. This rule has priority because a stale config would mislead Step 3.5's ownership-envelope synthesis and any sync skill's component scope.
2. **Pre-routing gate (Step 3.5 detection)** — check `_docs/tasks/todo/` for suite-level task files (`*.md` excluding files starting with `_`). If ≥1 task is present, auto-chain to **Step 3.5 (Suite Implement)**. After Step 3.5 returns (regardless of A/B outcome), the post-implement re-status applies rules 36 below to the post-implementation state.
3. If **doc drift** found → auto-chain to **Step 4 (Document Sync)**
4. Else if **CI drift** (only) found → auto-chain to **Step 5 (CICD Sync)**
5. Else if **suite-e2e drift** (only) found → auto-chain to **Step 4.5 (Integration Test Sync)** (only when `suite_e2e:` block exists in config)
6. Else → **workflow done for this cycle**.
**Registry mismatch Choose format** (rule 1):
```
══════════════════════════════════════
DECISION REQUIRED: Registry drift detected
══════════════════════════════════════
Components in registry but not in config: <list>
Components in config but not in registry: <list>
A) Run monorepo-discover to refresh config
B) Run monorepo-onboard for each new component (interactive)
C) Ignore for now — continue
══════════════════════════════════════
Recommendation: A — safest; re-detect everything, human reviews
══════════════════════════════════════
```
When rule 6 fires (no drift, no todo tasks), report "No drift. Meta-repo is in sync." and end the cycle. Loop waits for next invocation.
---
**Step 3.5 — Suite Implement**
Condition (folder fallback): `_docs/tasks/todo/` exists AND contains ≥1 file matching `*.md` excluding files starting with `_` (e.g., `_dependencies_table.md` is excluded by convention).
State-driven: reached by auto-chain from Step 3 when the pre-routing gate detected todo tasks. Inserted **before** the sync skills (Step 4 / 4.5 / 5) by deliberate design: implementing renames + cross-repo edits first means the subsequent sync skills propagate the actual landed state rather than the pre-change state, avoiding a second cycle to fix downstream drift.
**Skip condition**: `_docs/tasks/todo/` is empty, missing, or contains only `_*` files. In that case Step 3.5 is skipped entirely and the cycle proceeds with Step 3's existing drift-based routing.
**Goal**: Execute suite-level implementation tasks — cross-repo concerns (e.g., `autopilot` + `ui` + suite `e2e/` cutover in a coordinated change-set), folder renames (e.g., `git mv flights missions` + `.gitmodules` edit + `_infra/` path refs), and suite-root infrastructure additions (e.g., `_infra/dev/docker-compose.dev.yml`). Per-component implementation work stays in each component's own workspace `/autodev` cycle.
**Why this exists**: the meta-repo's existing sync skills (`monorepo-document`, `monorepo-cicd`, `monorepo-e2e`) only **propagate** changes that already landed. They cannot **execute** a task spec. Without Step 3.5, suite-level tickets like AZ-543 (B4 repo rename) or AZ-506 (new dev compose) have no flow path forward — they require operator action outside autodev.
**Inputs**:
- `_docs/tasks/todo/*.md` (excluding `_*`) — task specs in the existing format (`Task` / `Component` / `Dependencies` / `Acceptance criteria` headers)
- `_docs/_repo-config.yaml` — `components[].path` list, used to compute the suite-level OWNED envelope (workspace root EXCLUDING any path under a component's folder)
- `_docs/tasks/_dependencies_table.md` — synthesized by this step if missing (see Procedure)
- `_docs/tasks/_suite_module_layout.md` — synthesized by this step if missing (see Procedure)
**Procedure**:
1. **Detection (already done by Step 3 pre-routing gate)**. List task files in `_docs/tasks/todo/` (excluding `_*`). If 0 → skip Step 3.5. If ≥1 → continue.
2. **Present Choose**:
```
══════════════════════════════════════
DECISION REQUIRED: <N> suite-level task(s) in _docs/tasks/todo/
══════════════════════════════════════
Task(s) detected:
- AZ-XXX: <title> (deps: <list or "—">)
- AZ-YYY: <title> (deps: <list or "—">)
...
A) Run implement skill on these task(s) now (then continue to Doc / E2E / CICD sync)
B) Skip implement this cycle — continue to Doc / E2E / CICD sync without executing tasks
C) Pause — review the tasks before deciding (end session, no state changes)
══════════════════════════════════════
Recommendation: A — running implement BEFORE syncs means subsequent
sync skills propagate the post-implementation state.
B is appropriate when tasks are blocked on user input
or external coordination. C when the tasks themselves
need owner clarification before execution.
══════════════════════════════════════
```
3. **On user A — Pre-flight**:
a. **Working tree clean check**. Run `git status --porcelain`. If non-empty, surface to the user with a Choose A/B/C identical to the implement skill's prerequisite gate (commit/stash manually; agent commits as `chore: WIP pre-implement`; abort).
b. **Synthesize `_docs/tasks/_dependencies_table.md`** if missing. Parse each in-scope task's `Dependencies:` field. Write a minimal table of the form:
```markdown
# Suite-Level Task Dependencies
| Task ID | Depends on | Notes |
|---------|------------|-------|
| AZ-XXX | (none) | — |
| AZ-YYY | AZ-XXX | — |
```
If a task lists a dependency that is neither in `todo/` nor `done/`, log a warning in the synthesized file but do not block — implement skill's Step 1 (Parse) will surface the issue if it actually blocks execution.
c. **Synthesize `_docs/tasks/_suite_module_layout.md`** if missing. Default content:
```markdown
# Suite-Level Module Layout (synthetic)
Generated by autodev meta-repo Step 3.5. The suite root has no per-feature decomposition; ownership is defined at the component-boundary level only.
## Per-Component Mapping
| Component | Owns | Imports from |
|-----------|----------------------------------|--------------|
| suite | (workspace root) excluding any path listed under `_repo-config.yaml.components[].path` | (read-only) every component's primary doc + `_docs/*.md` |
Suite-level tasks operate on: `.gitmodules`, `_infra/**`, `_docs/**` (excluding `_docs/tasks/_*` regenerated files), root `README.md`, `e2e/**` (suite e2e harness only).
Forbidden paths for suite-level tasks: `<component>/**` for every component listed in `_repo-config.yaml.components[].path` — those edits live in the component's own workspace `/autodev` cycle.
```
d. **Prepare invocation context**:
```
suite_level: true
TASKS_DIR: _docs/tasks/
module_layout_path: _docs/tasks/_suite_module_layout.md
```
4. **Invoke implement skill**. Read and execute `.cursor/skills/implement/SKILL.md` with the prepared context. The skill's "Suite-level invocation context" subsection (added in tandem with this flow change) honors the three flags above and skips:
- Step 14.5 (cumulative code review) — no `architecture_compliance_baseline.md` exists at the suite level; cross-task drift is captured by the next `monorepo-status` cycle instead.
- Step 15 (Product Implementation Completeness Gate) — the gate's inputs (`_docs/02_document/architecture.md`, `system-flows.md`, `components/*/description.md`) do not exist in the meta-repo artifact layout. Suite tasks are infrastructure / coordination work, not feature implementation.
All other implement skill steps (114, 16) execute unchanged. Tracker integration (Step 5: In Progress, Step 12: In Testing) runs normally.
5. **Post-implement re-status**. After the implement skill completes (last batch committed, all originally-todo tasks moved to `_docs/tasks/done/`), silently re-run Step 3's drift detection logic — do NOT re-render the full Status report; just re-evaluate the drift signals against the post-implementation tree. Then auto-chain per the post-implementation drift findings:
- Doc drift → Step 4 (Document Sync)
- Suite-e2e drift only → Step 4.5
- CI drift only → Step 5
- No drift → cycle complete
Note: the post-implement re-status is exactly why Step 3.5 is placed before sync. A repo rename will typically introduce doc + CI drift; the next invocation of Step 4 / Step 5 catches it on the same cycle.
6. **On user B (skip)** → mark Step 3.5 `skipped` in state file. Apply Step 3's original drift-based routing (compute from the pre-Step-3.5 Status report).
7. **On user C (pause)** → end session. Update state to `step: 3.5, status: in_progress, sub_step: {phase: 0, name: awaiting-task-review, detail: "<N> tasks pending review"}`. Tell the user to invoke `/autodev` again after deciding. **Do NOT modify any files** — pre-flight has not run yet.
**Self-verification** (executed before invoking implement):
- [ ] Working tree is clean (or user explicitly chose B in the WIP-stash sub-Choose)
- [ ] `_docs/tasks/_dependencies_table.md` exists (synthesized if it didn't)
- [ ] `_docs/tasks/_suite_module_layout.md` exists (synthesized if it didn't)
- [ ] All in-scope task files have a `Component:` field (skip + report any that don't — don't guess ownership)
- [ ] Tracker availability gate satisfied per `protocols.md` (or `tracker: local` previously chosen)
**Failure handling**:
- If implement returns FAILED → standard Failure Handling (`protocols.md`): retry up to 3 times, then escalate.
- If implement is interrupted mid-batch → next invocation re-detects via the implement skill's resumability protocol (read latest `_docs/03_implementation/suite_batch_*.md`). Step 3.5 itself is reentrant: on re-entry, if `todo/` still has tasks, it presents the Choose again with the remaining set.
- **Half-applied state risk** (acknowledged): if implement is interrupted between commits, the working tree is clean at the last commit boundary but the in-flight batch is lost. The user is responsible for inspecting and re-invoking. This is intentional — automated rollback of suite-level renames + `.gitmodules` edits is more dangerous than a human-driven recovery.
**Idempotency**: if `_docs/tasks/todo/` becomes empty after this step (all tasks moved to `done/`), the next `/autodev` invocation skips Step 3.5 entirely and proceeds with normal Status → sync flow.
---
**Step 4 — Document Sync**
State-driven: reached by auto-chain from Step 3 when the status report flagged doc drift.
Action: Read and execute `.cursor/skills/monorepo-document/SKILL.md` with scope = components flagged by status.
The skill:
1. Runs its own drift check (M7)
2. Asks user to confirm scope (components it will touch)
3. Applies doc edits
4. Skips any component with unconfirmed mapping (M5), reports
After completion:
- If the status report ALSO flagged suite-e2e drift → auto-chain to **Step 4.5 (Integration Test Sync)**
- Else if the status report ALSO flagged CI drift → auto-chain to **Step 5 (CICD Sync)**
- Else → end cycle, report done
---
**Step 4.5 — Integration Test Sync**
State-driven: reached by auto-chain from Step 3 (when status report flagged suite-e2e drift and no doc drift) or from Step 4 (when both doc and suite-e2e drift were flagged).
**Skip condition**: if `_docs/_repo-config.yaml` has no `suite_e2e:` block, this step is skipped entirely — there's no harness to sync. The status report should not flag suite-e2e drift in that case; if it does, that's a status-skill bug.
Action: Read and execute `.cursor/skills/monorepo-e2e/SKILL.md` with scope = components flagged by status.
The skill:
1. Verifies every path under `suite_e2e.*` exists (binary fixtures excepted — see the skill's Phase 1)
2. Classifies each flagged change against the suite-e2e impact table
3. Applies edits to `e2e/docker-compose.suite-e2e.yml`, `e2e/fixtures/init.sql`, `e2e/fixtures/expected_detections.json` metadata, and `e2e/runner/tests/*.spec.ts` selectors as needed
4. Bumps baseline `fixture_version` with a `-stale` suffix and appends a `_docs/_process_leftovers/` entry whenever the detection model revision changes (binary fixture cannot be regenerated automatically)
5. Reports synced files; does not run the suite e2e itself
After completion:
- If the status report ALSO flagged CI drift → auto-chain to **Step 5 (CICD Sync)**
- Else → end cycle, report done
---
**Step 5 — CICD Sync**
State-driven: reached by auto-chain from Step 3 (when status report flagged CI drift and no doc/suite-e2e drift), Step 4, or Step 4.5.
Action: Read and execute `.cursor/skills/monorepo-cicd/SKILL.md` with scope = components flagged by status.
After completion, end cycle. Report files updated across doc, suite-e2e, and CI sync.
---
**Step 6 — Loop (re-entry on next invocation)**
State-driven: all triggered steps completed; the meta-repo cycle has finished.
Action: Update state file to `step: 3, status: not_started` so that next `/autodev` invocation starts from Status. The meta-repo flow is cyclical — there's no terminal "done" state, because drift can appear at any time as submodules evolve.
On re-invocation:
- If config was updated externally and `confirmed_by_user` flipped back to `false` → go back to Step 2
- Otherwise → Step 3 (Status)
## Explicit Onboarding Branch (user-initiated)
Onboarding is not auto-chained. Two ways to invoke:
**1. During Step 3 registry-mismatch handling** — if user picks option B in the registry-mismatch Choose format, launch `monorepo-onboard` interactively for each new component.
**2. Direct user request** — if the user says "onboard <name>" during any step, pause the current step, save state, run `monorepo-onboard`, then resume.
After onboarding completes, the config is updated. Auto-chain back to **Step 3 (Status)** to catch any remaining drift the new component introduced.
## Auto-Chain Rules
| Completed Step | Next Action |
|---------------|-------------|
| Discover (1) | Auto-chain → Config Review (2) |
| Config Review (2, user picked A, confirmed_by_user: true) | Auto-chain → Glossary & Architecture Vision (2.5) |
| Config Review (2, user picked B) | **Session boundary** — end session, await re-invocation |
| Glossary & Architecture Vision (2.5) | Auto-chain → Status (3) |
| Status (3, todo tasks present) | Auto-chain → Suite Implement (3.5) — pre-routing gate fires before drift-based routing |
| Status (3, no todo tasks, doc drift) | Auto-chain → Document Sync (4) |
| Status (3, no todo tasks, suite-e2e drift only) | Auto-chain → Integration Test Sync (4.5) |
| Status (3, no todo tasks, CI drift only) | Auto-chain → CICD Sync (5) |
| Status (3, no todo tasks, no drift) | **Cycle complete** — end session, await re-invocation |
| Status (3, registry mismatch) | Ask user (A: discover, B: onboard, C: continue) |
| Suite Implement (3.5, user picked A, success) | Silent re-status; auto-chain per post-implementation drift (Step 4 / 4.5 / 5 / cycle complete) |
| Suite Implement (3.5, user picked B) | Mark `skipped`; auto-chain per Step 3's original drift findings |
| Suite Implement (3.5, user picked C) | **Session boundary** — end session, await re-invocation |
| Suite Implement (3.5, FAILED ×3) | Standard Failure Handling escalation (`protocols.md`) |
| Document Sync (4) + suite-e2e drift pending | Auto-chain → Integration Test Sync (4.5) |
| Document Sync (4) + CI drift only pending | Auto-chain → CICD Sync (5) |
| Document Sync (4) + no further drift | **Cycle complete** |
| Integration Test Sync (4.5) + CI drift pending | Auto-chain → CICD Sync (5) |
| Integration Test Sync (4.5) + no CI drift | **Cycle complete** |
| CICD Sync (5) | **Cycle complete** |
## Status Summary — Step List
Flow name: `meta-repo`. Render using the banner template in `protocols.md` → "Banner Template (authoritative)".
Flow-specific slot values:
- `<header-suffix>`: empty.
- `<current-suffix>`: empty.
- `<footer-extras>`: add a single line:
```
Config: _docs/_repo-config.yaml [confirmed_by_user: <true|false>, last_updated: <date>]
```
| # | Step Name | Extra state tokens (beyond the shared set) |
|---|------------------------------------|--------------------------------------------|
| 1 | Discover | — |
| 2 | Config Review | `IN PROGRESS (awaiting human)` |
| 2.5 | Glossary & Architecture Vision | `SKIPPED (already captured)` |
| 3 | Status | `DONE (no drift)`, `DONE (N drifts)` |
| 3.5 | Suite Implement | `DONE (N tasks)`, `SKIPPED (no todo tasks)`, `SKIPPED (user picked B)`, `IN PROGRESS (batch M of ~N)`, `IN PROGRESS (awaiting-task-review)` |
| 4 | Document Sync | `DONE (N docs)`, `SKIPPED (no doc drift)` |
| 4.5 | Integration Test Sync | `DONE (N files)`, `SKIPPED (no suite-e2e drift)`, `SKIPPED (no suite_e2e config block)` |
| 5 | CICD Sync | `DONE (N files)`, `SKIPPED (no CI drift)` |
All rows accept the shared state tokens (`DONE`, `IN PROGRESS`, `NOT STARTED`, `FAILED (retry N/3)`); rows 2.5, 3.5, 4, 4.5, and 5 additionally accept `SKIPPED`.
Row rendering format:
```
Step 1 Discover [<state token>]
Step 2 Config Review [<state token>]
Step 2.5 Glossary & Architecture Vision [<state token>]
Step 3 Status [<state token>]
Step 3.5 Suite Implement [<state token>]
Step 4 Document Sync [<state token>]
Step 4.5 Integration Test Sync [<state token>]
Step 5 CICD Sync [<state token>]
```
## Notes for the meta-repo flow
- **Session boundaries**: Step 2 (Config Review pending), Step 2.5 (one-shot glossary/vision review), and Step 3.5 (when user picks C "Pause"). Step 3.5's A/B picks do NOT cross a session boundary — they auto-chain to syncs in the same session.
- **Cyclical, not terminal**: no "done forever" state. Each invocation completes a drift cycle; next invocation starts fresh.
- **Tracker integration scope**: this flow does NOT create Jira/ADO tickets in its sync skills (Status / Document Sync / E2E / CICD). Step 3.5 (Suite Implement) IS tracker-integrated — it transitions existing tickets In Progress → In Testing per the implement skill's standard tracker handling. Suite-level tickets are authored manually by the operator (typically as children of an Epic that spans multiple components, like AZ-539); the flow doesn't auto-create them.
- **Per-component vs. suite-level work**:
- Tickets that touch component source code (`<component>/src/**`) belong in that component's own workspace `/autodev` cycle. The meta-repo flow does NOT execute them.
- Tickets that touch suite-root paths only (`.gitmodules`, `_infra/**`, suite `e2e/**`, root `README.md`, suite `_docs/**` outside `tasks/_*`) are eligible for Step 3.5.
- Tickets that span both (e.g., AZ-550 B11 consumer cutover, which touches `autopilot/`, `ui/`, AND suite `e2e/`) are NOT executable from a single workspace by design — split the ticket so the suite-level slice can run in Step 3.5 and the component slices run in their owning workspaces.
- **Onboarding is opt-in**: never auto-onboarded. User must explicitly request.
- **Failure handling**: uses the same retry/escalation protocol as other flows (see `protocols.md`).
@@ -1,12 +1,12 @@
# Autopilot Protocols
# Autodev Protocols
## User Interaction Protocol
Every time the autopilot or a sub-skill needs a user decision, use the **Choose A / B / C / D** format. This applies to:
Every time the autodev or a sub-skill needs a user decision, use the **Choose A / B / C / D** format. This applies to:
- State transitions where multiple valid next actions exist
- Sub-skill BLOCKING gates that require user judgment
- Any fork where the autopilot cannot confidently pick the right path
- Any fork where the autodev cannot confidently pick the right path
- Trade-off decisions (tech choices, scope, risk acceptance)
### When to Ask (MUST ask)
@@ -49,55 +49,76 @@ Rules:
5. Play the notification sound (per `.cursor/rules/human-attention-sound.mdc`) before presenting the choice
6. After the user picks, proceed immediately — no follow-up confirmation unless the choice was destructive
## Optional Skill Gate (reusable template)
Several flow steps ask the user whether to run an optional skill (security audit, performance test, etc.) before auto-chaining. Instead of re-stating the Choose block and skip semantics at each such step, flow files invoke this shared template.
### Template shape
```
══════════════════════════════════════
DECISION REQUIRED: <question>
══════════════════════════════════════
A) <option-a-label>
B) <option-b-label>
══════════════════════════════════════
Recommendation: <A|B> — <reason>
══════════════════════════════════════
```
### Semantics (same for every invocation)
- **On A** → read and execute the target skill's `SKILL.md`; after it completes, auto-chain to `<next-step>`.
- **On B** → mark the current step `skipped` in the state file; auto-chain to `<next-step>`.
- **On skill failure** → standard Failure Handling (§Failure Handling) — retry ladder, then escalate via Choose block.
- **Sound before the prompt** — follow `.cursor/rules/human-attention-sound.mdc`.
### How flow files invoke it
Each flow-file step that needs this gate supplies only the variable parts:
```
Action: Apply the **Optional Skill Gate** (protocols.md → "Optional Skill Gate") with:
- question: <Choose-block header>
- option-a-label: <one-line A description>
- option-b-label: <one-line B description>
- recommendation: <A|B> — <short reason, may be dynamic>
- target-skill: <.cursor/skills/<name>/SKILL.md, plus any mode hint>
- next-step: Step <N> (<name>)
```
The resolved Choose block (shape above) is then rendered verbatim by substituting these variables. Do NOT reword the shared scaffolding — reword only the variable parts. If a step needs different semantics (e.g., "re-run same skill" rather than "skip to next step"), it MUST NOT use this template; it writes the Choose block inline with its own semantics.
### When NOT to use this template
- The user choice has **more than two options** (A/B/C/D).
- The choice is **not "run-or-skip-this-skill"** (e.g., "another round of the same skill", "pick tech stack", "proceed vs. rollback").
- The skipped path needs special bookkeeping beyond `status: skipped` (e.g., must also move artifacts, notify tracker, trigger a different skill).
For those cases, write the Choose block inline using the base format in §User Interaction Protocol.
## Work Item Tracker Authentication
Several workflow steps create work items (epics, tasks, links). The system requires some task tracker MCP as interchangeable backend.
All tracker detection, authentication, availability gating, `tracker: local` fallback semantics, and leftovers handling are defined in `.cursor/rules/tracker.mdc`. Follow that rule — do not restate its logic here.
### Tracker Detection
1. If there is no task tracker MCP or it is not authorized, ask the user about it
3. Record the choice in the state file: `tracker: jira` or `tracker: ado`
4. If neither is available, set `tracker: local` and proceed without external tracking
Autodev-specific additions on top of the rule:
### Steps That Require Work Item Tracker
Before entering a step from this table for the first time in a session, verify tracker availability per `.cursor/rules/tracker.mdc`. If the user has already chosen `tracker: local`, skip the gate and proceed.
| Flow | Step | Sub-Step | Tracker Action |
|------|------|----------|----------------|
| greenfield | 3 (Plan) | Step 6 — Epics | Create epics for each component |
| greenfield | 5 (Decompose) | Step 13 — All tasks | Create ticket per task, link to epic |
| existing-code | 3 (Decompose Tests) | Step 1t + Step 3 — All test tasks | Create ticket per task, link to epic |
| existing-code | 7 (New Task) | Step 7 — Ticket | Create ticket per task, link to epic |
| greenfield | Plan | Step 6 — Epics | Create epics for each component |
| greenfield | Decompose | Implementation decomposition Step 1 + Step 2 — Product tasks | Create ticket per product task, link to epic |
| greenfield | Decompose Tests | Step 1t + Step 3 — All test tasks | Create ticket per task, link to epic |
| existing-code | Decompose Tests | Step 1t + Step 3 — All test tasks | Create ticket per task, link to epic |
| existing-code | New Task | Step 7 — Ticket | Create ticket per task, link to epic |
| meta-repo | Suite Implement | Step 3.5 — implement skill Step 5 / Step 12 | Transition existing tickets In Progress → In Testing per implement skill (does NOT create new tickets — operator authors them) |
### Authentication Gate
### State File Marker
Before entering a step that requires work item tracking (see table above) for the first time, the autopilot must:
1. Call `mcp_auth` on the detected tracker's MCP server
2. If authentication succeeds → proceed normally
3. If the user **skips** or authentication fails → present using Choose format:
```
══════════════════════════════════════
Tracker authentication failed
══════════════════════════════════════
A) Retry authentication (retry mcp_auth)
B) Continue without tracker (tasks saved locally only)
══════════════════════════════════════
Recommendation: A — Tracker IDs drive task referencing,
dependency tracking, and implementation batching.
Without tracker, task files use numeric prefixes instead.
══════════════════════════════════════
```
If user picks **B** (continue without tracker):
- Set a flag in the state file: `tracker: local`
- All skills that would create tickets instead save metadata locally in the task/epic files with `Tracker: pending` status
- Task files keep numeric prefixes (e.g., `01_initial_structure.md`) instead of tracker ID prefixes
- The workflow proceeds normally in all other respects
### Re-Authentication
If the tracker MCP was already authenticated in a previous invocation (verify by listing available tools beyond `mcp_auth`), skip the auth gate.
Record the resolved choice in the state file once per session: `tracker: jira` or `tracker: local`. Subsequent steps read this marker instead of re-running the gate.
## Error Handling
@@ -111,41 +132,42 @@ All error situations that require user input MUST use the **Choose A / B / C / D
| User wants to go back to a previous step | Use Choose format: A) re-run (with overwrite warning), B) stay on current step |
| User asks "where am I?" without wanting to continue | Show Status Summary only, do not start execution |
## Skill Failure Retry Protocol
## Failure Handling
Sub-skills can return a **failed** result. Failures are often caused by missing user input, environment issues, or transient errors that resolve on retry. The autopilot auto-retries before escalating.
One retry ladder covers all failure modes: explicit failure returned by a sub-skill, stuck loops detected while monitoring, and persistent failures across conversations. The single counter is `retry_count` in the state file; the single escalation is the Choose block below.
### Retry Flow
### Failure signals
Treat the sub-skill as **failed** when ANY of the following is observed:
- The sub-skill explicitly returns a failed result (including blocked tasks, auto-fix loop exhaustion, prerequisite violations).
- **Stuck signals**: the same artifact is rewritten 3+ times without meaningful change; the sub-skill re-asks a question that was already answered; no new artifact has been saved despite active execution.
### Retry ladder
```
Skill execution → FAILED
Failure observed
├─ retry_count < 3 ?
│ YES → increment retry_count in state file
│ → re-read the sub-skill's SKILL.md
│ → re-execute from the current sub_step
│ → (loop back to check result)
│ → re-read the sub-skill's SKILL.md and _docs/_autodev_state.md
│ → resume from the last recorded sub_step (restart from sub_step 1 only if corruption is suspected)
│ → loop
│ NO (retry_count = 3) →
│ → set status: failed in Current Step
│ → present warning to user (see Escalation below)
│ → do NOT auto-retry again until user intervenes
│ → set status: failed and retry_count: 3 in Current Step
│ → play notification sound (.cursor/rules/human-attention-sound.mdc)
│ → escalate (Choose block below)
│ → do NOT auto-retry until the user intervenes
```
### Retry Rules
Rules:
1. **Auto-retry is immediate** — do not ask before retrying.
2. **Preserve `sub_step`** across retries unless the failure indicates artifact corruption.
3. **Reset `retry_count: 0` on success.**
4. The counter is **per step, per cycle**. It is not cleared by crossing a session boundary — persistence across conversations is intentional; it IS the circuit breaker.
1. **Auto-retry immediately**: when a skill fails, retry it without asking the user — the failure is often transient (missing user confirmation in a prior step, docker not running, file lock, etc.)
2. **Preserve sub_step**: retry from the last recorded `sub_step`, not from the beginning of the skill — unless the failure indicates corruption, in which case restart from sub_step 1
3. **Increment `retry_count`**: update `retry_count` in the state file's `Current Step` section on each retry attempt
4. **Reset on success**: when the skill eventually succeeds, reset `retry_count: 0`
### Escalation (after 3 consecutive failures)
After 3 failed auto-retries of the same skill, the failure is likely not user-related. Stop retrying and escalate:
1. Update the state file: set `status: failed` and `retry_count: 3` in `Current Step`
2. Play notification sound (per `.cursor/rules/human-attention-sound.mdc`)
3. Present using Choose format:
### Escalation
```
══════════════════════════════════════
@@ -164,49 +186,25 @@ After 3 failed auto-retries of the same skill, the failure is likely not user-re
══════════════════════════════════════
```
### Re-Entry After Failure
### Re-entry after escalation
On the next autopilot invocation (new conversation), if the state file shows `status: failed` and `retry_count: 3`:
On the next invocation, if the state file shows `status: failed` AND `retry_count: 3`, do NOT auto-retry. Present the escalation block above first:
- Present the blocker to the user before attempting execution
- If the user chooses to retry → reset `retry_count: 0`, set `status: in_progress`, and re-execute
- If the user chooses to skip → mark step as `skipped`, proceed to next step
- Do NOT silently auto-retry — the user must acknowledge the persistent failure first
- User picks A → reset `retry_count: 0`, set `status: in_progress`, re-execute.
- User picks B → mark step `skipped`, proceed to the next step.
- User picks C → stop; return control to the user.
## Error Recovery Protocol
### Incident retrospective
### Stuck Detection
When executing a sub-skill, monitor for these signals:
- Same artifact overwritten 3+ times without meaningful change
- Sub-skill repeatedly asks the same question after receiving an answer
- No new artifacts saved for an extended period despite active execution
### Recovery Actions (ordered)
1. **Re-read state**: read `_docs/_autopilot_state.md` and cross-check against `_docs/` folders
2. **Retry current sub-step**: re-read the sub-skill's SKILL.md and restart from the current sub-step
3. **Escalate**: after 2 failed retries, present diagnostic summary to user using Choose format:
Immediately after the user has made their A/B/C choice, invoke `.cursor/skills/retrospective/SKILL.md` in **incident mode**:
```
══════════════════════════════════════
RECOVERY: [skill name] stuck at [sub-step]
══════════════════════════════════════
A) Retry with fresh context (new conversation)
B) Skip this sub-step with warning
C) Abort and fix manually
══════════════════════════════════════
Recommendation: A — fresh context often resolves stuck loops
══════════════════════════════════════
mode: incident
failing_skill: <skill name>
failure_summary: <last failure reason string>
```
### Circuit Breaker
If the same autopilot step fails 3 consecutive times across conversations:
- Do NOT auto-retry on next invocation
- Present the failure pattern and ask user for guidance before attempting again
This produces `_docs/06_metrics/incident_<YYYY-MM-DD>_<skill>.md` and appends 13 lessons to `_docs/LESSONS.md` under `process` or `tooling`. The retro runs even if the user picked Abort — the goal is to capture the pattern while it is fresh. If the retrospective skill itself fails, log the failure to `_docs/_process_leftovers/` but do NOT block the user's recovery choice from completing.
## Context Management Protocol
@@ -218,7 +216,7 @@ Disk is memory. Never rely on in-context accumulation — read from `_docs/` art
When re-entering a skill (new conversation or context refresh):
- Always read: `_docs/_autopilot_state.md`
- Always read: `_docs/_autodev_state.md`
- Always read: the active skill's `SKILL.md`
- Conditionally read: only the `_docs/` artifacts the current sub-step requires (listed in each skill's Context Resolution section)
- Never bulk-read: do not load all `_docs/` files at once
@@ -228,7 +226,7 @@ When re-entering a skill (new conversation or context refresh):
If context is filling up during a long skill (e.g., document, implement):
1. Save current sub-step progress to the skill's artifact directory
2. Update `_docs/_autopilot_state.md` with exact sub-step position
2. Update `_docs/_autodev_state.md` with exact sub-step position
3. Suggest a new conversation: "Context is getting long — recommend continuing in a fresh conversation for better results"
4. On re-entry, the skill's resumability protocol picks up from the saved sub-step
@@ -290,12 +288,12 @@ For steps that produce `_docs/` artifacts (problem, research, plan, decompose, d
══════════════════════════════════════
```
3. **Git safety net**: artifacts are committed with each autopilot step completion. To roll back: `git log --oneline _docs/` to find the commit, then `git checkout <commit> -- _docs/<folder>/`
4. **State file rollback**: when rolling back artifacts, also update `_docs/_autopilot_state.md` to reflect the rolled-back step (set it to `in_progress`, clear completed date)
3. **Git safety net**: artifacts are committed with each autodev step completion. To roll back: `git log --oneline _docs/` to find the commit, then `git checkout <commit> -- _docs/<folder>/`
4. **State file rollback**: when rolling back artifacts, also update `_docs/_autodev_state.md` to reflect the rolled-back step (set it to `in_progress`, clear completed date)
## Debug / Error Recovery Protocol
## Debug Protocol
When the implement skill's auto-fix loop fails (code review FAIL after 2 auto-fix attempts) or an implementer subagent reports a blocker, the user is asked to intervene. This protocol guides the recovery process.
When the implement skill's auto-fix loop fails (code review FAIL after 2 auto-fix attempts) or a task reports a blocker, the user is asked to intervene. This protocol guides the debugging process. (Retry budget and escalation are covered by Failure Handling above; this section is about *how* to diagnose once the user has been looped in.)
### Structured Debugging Workflow
@@ -360,6 +358,39 @@ If debugging does not resolve the issue after 2 focused attempts:
## Status Summary
On every invocation, before executing any skill, present a status summary built from the state file (with folder scan fallback). Use the Status Summary Template from the active flow file (`flows/greenfield.md` or `flows/existing-code.md`).
On every invocation, before executing any skill, present a status summary built from the state file (with folder scan fallback). For re-entry (state file exists), cross-check the current step against `_docs/` folder structure and present any `status: failed` state to the user before continuing.
For re-entry (state file exists), cross-check the current step against `_docs/` folder structure and present any `status: failed` state to the user before continuing.
### Banner Template (authoritative)
The banner shell is defined here once. Each flow file contributes only its step-list fragment and any flow-specific header/footer extras. Do not inline a full banner in flow files.
```
═══════════════════════════════════════════════════
AUTODEV STATUS (<flow-name>)<header-suffix>
═══════════════════════════════════════════════════
<step-list from the active flow file>
═══════════════════════════════════════════════════
Current: Step <N> — <Name><current-suffix>
SubStep: <M> — <sub-skill internal step name>
Retry: <N/3> ← omit row if retry_count is 0
Action: <what will happen next>
<footer-extras from the active flow file>
═══════════════════════════════════════════════════
```
### Slot rules
- `<flow-name>``greenfield`, `existing-code`, or `meta-repo`.
- `<header-suffix>` — optional, flow-specific. The existing-code flow appends ` — Cycle <N>` when `state.cycle > 1`; other flows leave it empty.
- `<step-list>` — a fixed-width table supplied by the active flow file (see that file's "Status Summary — Step List" section). Row format is standardized:
```
Step <N> <Step Name> [<state token>]
```
where `<state token>` comes from the state-token set defined per row in the flow's step-list table.
- `<current-suffix>` — optional, flow-specific. The existing-code flow appends ` (cycle <N>)` when `state.cycle > 1`; other flows leave it empty.
- `Retry:` row — omit entirely when `retry_count` is 0. Include it with `<N>/3` otherwise.
- `<footer-extras>` — optional, flow-specific. The meta-repo flow adds a `Config:` line with `_docs/_repo-config.yaml` state; other flows leave it empty unless **parent suite docs** apply: if `<workspace-root>/../docs` exists and is a directory, append `Suite docs (parent): <absolute path>` on its own line (or `Suite docs (parent): absent` is **not** required — omit when missing). This line is orthogonal to flow-specific footer lines; both may appear.
### State token set (shared)
The common tokens all flows may emit are: `DONE`, `IN PROGRESS`, `NOT STARTED`, `SKIPPED`, `FAILED (retry N/3)`. Specific step rows may extend this with parenthetical detail (e.g., `DONE (N drafts)`, `DONE (N tasks)`, `IN PROGRESS (batch M of ~N)`, `DONE (N passed, M failed)`). The flow's step-list table declares which extensions each step supports.
+171
View File
@@ -0,0 +1,171 @@
# Autodev State Management
## State File: `_docs/_autodev_state.md`
The autodev persists its position to `_docs/_autodev_state.md`. This is a lightweight pointer — only the current step. All history lives in `_docs/` artifacts and git log. Folder scanning is the fallback when the state file doesn't exist.
### Template
**Saved at:** `_docs/_autodev_state.md` (workspace-relative, one file per project). Created on the first `/autodev` invocation; updated in place on every state transition; never deleted.
```markdown
# Autodev State
## Current Step
flow: [greenfield | existing-code | meta-repo]
step: [1-17 for greenfield, 1-17 for existing-code, 1-6 for meta-repo (incl. fractional 2.5 and 3.5), or "done"]
name: [step name from the active flow's Step Reference Table]
status: [not_started / in_progress / completed / skipped / failed]
sub_step:
phase: [integer — sub-skill internal phase/step number, or 0 if not started]
name: [kebab-case short identifier from the sub-skill, or "awaiting-invocation"]
detail: [optional free-text note, may be empty]
retry_count: [0-3 — consecutive auto-retry attempts, reset to 0 on success]
cycle: [1-N — feature cycle counter for existing-code flow; increments on each "Re-Entry After Completion" loop; always 1 for greenfield and meta-repo]
```
The `sub_step` field is structured. Every sub-skill must save both `phase` (integer) and `name` (kebab-case token matching the skill's documented phase names). `detail` is optional human-readable context. On re-entry the orchestrator parses `phase` and `name` to resume; if parsing fails, fall back to folder scan and log the parse failure.
### Sub-Skill Phase Persistence — Rules (not a registry)
Each sub-skill is authoritative for its own phase list. Phase names and numbers live inside the sub-skill's own SKILL.md (and any `steps/` / `phases/` files). The orchestrator does not maintain a central phase table — it reads whatever `phase` / `name` the sub-skill last wrote.
Every sub-skill MUST follow these rules when persisting `sub_step`:
1. **`phase`** — a strictly monotonic integer per invocation, starting at 0 (`awaiting-invocation`) and incrementing by 1 at each internal save point. No fractional values are ever persisted. If the skill's own docs use half-step numbering (e.g., "Phase 4.5", decompose's "Step 1.5"), the persisted integer is simply the next integer, and all subsequent phases shift up by one in that skill's own file.
2. **`name`** — a kebab-case short identifier unique within that sub-skill. Use the phase's heading or step title in kebab-case (e.g., `component-decomposition`, `auto-fix-gate`, `cross-task-consistency`). Different modes of the same skill may reuse a `phase` integer with distinct `name` values (e.g., `decompose` phase 1 is `bootstrap-structure` in default mode, `test-infrastructure-bootstrap` in tests-only mode).
3. **`detail`** — optional free-text note (batch index, mode flag, retry hint); may be empty.
4. **Reserved name**`name: awaiting-invocation` with `phase: 0` is the universal "skill was chained but has not started" marker. Every sub-skill implicitly supports it; no sub-skill should reuse the token for anything else.
On re-entry, the orchestrator parses the structured field and resumes at `(phase, name)`. If parsing fails, it falls back to folder scan and logs the parse error — it does NOT guess a phase.
The `cycle` counter is used by existing-code flow Step 10 (Implement) detection and by implementation report naming (`implementation_report_{feature_slug}_cycle{N}.md`). It starts at 1 when a project enters existing-code flow (either by routing from greenfield's Done branch, or by first invocation on an existing codebase). It increments on each completed Retrospective → New Task loop.
### Examples
```
flow: greenfield
step: 3
name: Plan
status: in_progress
sub_step:
phase: 4
name: architecture-review-risk-assessment
detail: ""
retry_count: 0
cycle: 1
```
```
flow: existing-code
step: 3
name: Test Spec
status: failed
sub_step:
phase: 1
name: test-case-generation
detail: "variant 1b"
retry_count: 3
cycle: 1
```
```
flow: meta-repo
step: 2
name: Config Review
status: in_progress
sub_step:
phase: 0
name: awaiting-human-review
detail: "awaiting review of _docs/_repo-config.yaml"
retry_count: 0
cycle: 1
```
```
flow: meta-repo
step: 3.5
name: Suite Implement
status: in_progress
sub_step:
phase: 7
name: batch-loop
detail: "AZ-543 batch 1 of 1; suite-level"
retry_count: 0
cycle: 1
```
```
flow: existing-code
step: 10
name: Implement
status: in_progress
sub_step:
phase: 7
name: batch-loop
detail: "batch 2 of ~4"
retry_count: 0
cycle: 3
```
### State File Rules
1. **Create** on the first autodev invocation (after state detection determines Step 1)
2. **Update** after every change — this includes: batch completion, sub-step progress, step completion, session boundary, failed retry, or any meaningful state transition. The state file must always reflect the current reality.
3. **Read** as the first action on every invocation — before folder scanning
4. **Cross-check**: verify against actual `_docs/` folder contents. If they disagree, trust the folder structure and update the state file. **Parent suite `docs/`**: on every invocation, also probe `<workspace-root>/../docs` (the parent directorys `docs` folder — typical suite-level shared documentation next to a component repo). If it exists, mention it in the Status Summary footer per `protocols.md`; use it only as supplemental reading context unless a flow step explicitly ties detection to it. It never replaces workspace `_docs/` for step detection by default.
5. **Never delete** the state file
6. **Retry tracking**: increment `retry_count` on each failed auto-retry; reset to `0` on success. If `retry_count` reaches 3, set `status: failed`
7. **Failed state on re-entry**: if `status: failed` with `retry_count: 3`, do NOT auto-retry — present the issue to the user first
8. **Skill-internal state**: when the active skill maintains its own state file (e.g., document skill's `_docs/02_document/state.json`), the autodev's `sub_step` field should reflect the skill's internal progress. On re-entry, cross-check the skill's state file against the autodev's `sub_step` for consistency.
## State Detection
Read `_docs/_autodev_state.md` first. If it exists and is consistent with the folder structure, use the `Current Step` from the state file. If the state file doesn't exist or is inconsistent, fall back to folder scanning.
### Folder Scan Rules (fallback)
Scan the workspace and `_docs/` to determine the current workflow position. The detection rules are defined in each flow file (`flows/greenfield.md`, `flows/existing-code.md`, `flows/meta-repo.md`). Resolution order:
1. Apply the Flow Resolution rules in `SKILL.md` to pick the flow first (meta-repo detection takes priority over greenfield/existing-code).
2. Within the selected flow, check its detection rules in order — first match wins.
## Re-Entry Protocol
When the user invokes `/autodev` and work already exists:
1. Read `_docs/_autodev_state.md`
2. Cross-check against `_docs/` folder structure
3. Present Status Summary (render using the banner template in `protocols.md` → "Banner Template", filled in with the active flow's "Status Summary — Step List" fragment)
4. If the detected step has a sub-skill with built-in resumability, the sub-skill handles mid-step recovery
5. Continue execution from detected state
## Session Boundaries
A **session boundary** is a transition that explicitly breaks auto-chain. Which transitions are boundaries is declared **in each flow file's Auto-Chain Rules table** — rows marked `**Session boundary**`. The details live with the steps they apply to; this section defines only the shared mechanism.
**Invariant**: a flow row without the `Session boundary` marker auto-chains unconditionally. Missing marker = missing boundary.
### Orchestrator mechanism at a boundary
1. Update the state file: mark the current step `completed`; set the next step with `status: not_started`; reset `sub_step: {phase: 0, name: awaiting-invocation, detail: ""}`; keep `retry_count: 0`.
2. Present a brief summary of what just finished (tasks produced, batches expected, etc., as relevant to the boundary).
3. Present the shared Choose block (template below) — or a flow-specific override if the flow file supplies one.
4. End the session — do not start the next skill in the same conversation.
### Shared Choose template
```
══════════════════════════════════════
DECISION REQUIRED: <what just completed> — start <next phase>?
══════════════════════════════════════
A) Start a new conversation for <next phase> (recommended for context freshness)
B) Continue in this conversation (NOT recommended — context may degrade)
Warning: if context fills mid-<next phase>, state will be saved and you will
still be asked to resume in a new conversation — option B only delays that.
══════════════════════════════════════
Recommendation: A — <next phase> is long; fresh context helps
══════════════════════════════════════
```
Individual boundaries MAY override this template with a flow-specific Choose block when the pause has different semantics (e.g., `meta-repo.md` Step 2 Config Review pauses for human review of a config flag, not for context freshness). The flow file is authoritative for any such override.
-123
View File
@@ -1,123 +0,0 @@
---
name: autopilot
description: |
Auto-chaining orchestrator that drives the full BUILD-SHIP workflow from problem gathering through deployment.
Detects current project state from _docs/ folder, resumes from where it left off, and flows through
problem → research → plan → decompose → implement → deploy without manual skill invocation.
Maximizes work per conversation by auto-transitioning between skills.
Trigger phrases:
- "autopilot", "auto", "start", "continue"
- "what's next", "where am I", "project status"
category: meta
tags: [orchestrator, workflow, auto-chain, state-machine, meta-skill]
disable-model-invocation: true
---
# Autopilot Orchestrator
Auto-chaining execution engine that drives the full BUILD → SHIP workflow. Detects project state from `_docs/`, resumes from where work stopped, and flows through skills automatically. The user invokes `/autopilot` once — the engine handles sequencing, transitions, and re-entry.
## File Index
| File | Purpose |
|------|---------|
| `flows/greenfield.md` | Detection rules, step table, and auto-chain rules for new projects |
| `flows/existing-code.md` | Detection rules, step table, and auto-chain rules for existing codebases |
| `state.md` | State file format, rules, re-entry protocol, session boundaries |
| `protocols.md` | User interaction, tracker auth, choice format, error handling, status summary |
**On every invocation**: read all four files above before executing any logic.
## Core Principles
- **Auto-chain**: when a skill completes, immediately start the next one — no pause between skills
- **Only pause at decision points**: BLOCKING gates inside sub-skills are the natural pause points; do not add artificial stops between steps
- **State from disk**: current step is persisted to `_docs/_autopilot_state.md` and cross-checked against `_docs/` folder structure
- **Re-entry**: on every invocation, read the state file and cross-check against `_docs/` folders before continuing
- **Delegate, don't duplicate**: read and execute each sub-skill's SKILL.md; never inline their logic here
- **Sound on pause**: follow `.cursor/rules/human-attention-sound.mdc` — play a notification sound before every pause that requires human input (AskQuestion tool preferred for structured choices; fall back to plain text if unavailable)
- **Minimize interruptions**: only ask the user when the decision genuinely cannot be resolved automatically
- **Single project per workspace**: all `_docs/` paths are relative to workspace root; for monorepos, each service needs its own Cursor workspace
## Flow Resolution
Determine which flow to use:
1. If workspace has **no source code files****greenfield flow**
2. If workspace has source code files **and** `_docs/` does not exist → **existing-code flow**
3. If workspace has source code files **and** `_docs/` exists **and** `_docs/_autopilot_state.md` does not exist → **existing-code flow**
4. If workspace has source code files **and** `_docs/_autopilot_state.md` exists → read the `flow` field from the state file and use that flow
After selecting the flow, apply its detection rules (first match wins) to determine the current step.
## Execution Loop
Every invocation follows this sequence:
```
1. Read _docs/_autopilot_state.md (if exists)
2. Read all File Index files above
3. Cross-check state file against _docs/ folder structure (rules in state.md)
4. Resolve flow (see Flow Resolution above)
5. Resolve current step (detection rules from the active flow file)
6. Present Status Summary (template in active flow file)
7. Execute:
a. Delegate to current skill (see Skill Delegation below)
b. If skill returns FAILED → apply Skill Failure Retry Protocol (see protocols.md):
- Auto-retry the same skill (failure may be caused by missing user input or environment issue)
- If 3 consecutive auto-retries fail → set status: failed, warn user, stop auto-retry
c. When skill completes successfully → reset retry counter, update state file (rules in state.md)
d. Re-detect next step from the active flow's detection rules
e. If next skill is ready → auto-chain (go to 7a with next skill)
f. If session boundary reached → update state, suggest new conversation (rules in state.md)
g. If all steps done → update state → report completion
```
## Skill Delegation
For each step, the delegation pattern is:
1. Update state file: set `step` to the autopilot step number, status to `in_progress`, set `sub_step` to the sub-skill's current internal step/phase, reset `retry_count: 0`
2. Announce: "Starting [Skill Name]..."
3. Read the skill file: `.cursor/skills/[name]/SKILL.md`
4. Execute the skill's workflow exactly as written, including all BLOCKING gates, self-verification checklists, save actions, and escalation rules. Update `sub_step` in state each time the sub-skill advances.
5. If the skill **fails**: follow the Skill Failure Retry Protocol in `protocols.md` — increment `retry_count`, auto-retry up to 3 times, then escalate.
6. When complete (success): reset `retry_count: 0`, update state file to the next step with `status: not_started`, return to auto-chain rules (from active flow file)
Do NOT modify, skip, or abbreviate any part of the sub-skill's workflow. The autopilot is a sequencer, not an optimizer.
## State File Template
The state file (`_docs/_autopilot_state.md`) is a minimal pointer — only the current step. Full format rules are in `state.md`.
```markdown
# Autopilot State
## Current Step
flow: [greenfield | existing-code]
step: [number or "done"]
name: [step name]
status: [not_started / in_progress / completed / skipped / failed]
sub_step: [0 or N — sub-skill phase name]
retry_count: [0-3]
```
## Trigger Conditions
This skill activates when the user wants to:
- Start a new project from scratch
- Continue an in-progress project
- Check project status
- Let the AI guide them through the full workflow
**Keywords**: "autopilot", "auto", "start", "continue", "what's next", "where am I", "project status"
**Differentiation**:
- User wants only research → use `/research` directly
- User wants only planning → use `/plan` directly
- User wants to document an existing codebase → use `/document` directly
- User wants the full guided workflow → use `/autopilot`
## Flow Reference
See `flows/greenfield.md` and `flows/existing-code.md` for step tables, detection rules, auto-chain rules, and status summary templates.
@@ -1,297 +0,0 @@
# Existing Code Workflow
Workflow for projects with an existing codebase. Starts with documentation, produces test specs, checks code testability (refactoring if needed), decomposes and implements tests, verifies them, refactors with that safety net, then adds new functionality and deploys.
## Step Reference Table
| Step | Name | Sub-Skill | Internal SubSteps |
|------|------|-----------|-------------------|
| 1 | Document | document/SKILL.md | Steps 18 |
| 2 | Test Spec | test-spec/SKILL.md | Phase 1a1b |
| 3 | Code Testability Revision | refactor/SKILL.md (guided mode) | Phases 07 (conditional) |
| 4 | Decompose Tests | decompose/SKILL.md (tests-only) | Step 1t + Step 3 + Step 4 |
| 5 | Implement Tests | implement/SKILL.md | (batch-driven, no fixed sub-steps) |
| 6 | Run Tests | test-run/SKILL.md | Steps 14 |
| 7 | Refactor | refactor/SKILL.md | Phases 07 (optional) |
| 8 | New Task | new-task/SKILL.md | Steps 18 (loop) |
| 9 | Implement | implement/SKILL.md | (batch-driven, no fixed sub-steps) |
| 10 | Run Tests | test-run/SKILL.md | Steps 14 |
| 11 | Update Docs | document/SKILL.md (task mode) | Task Steps 05 |
| 12 | Security Audit | security/SKILL.md | Phase 15 (optional) |
| 13 | Performance Test | (autopilot-managed) | Load/stress tests (optional) |
| 14 | Deploy | deploy/SKILL.md | Step 17 |
After Step 14, the existing-code workflow is complete.
## Detection Rules
Check rules in order — first match wins.
---
**Step 1 — Document**
Condition: `_docs/` does not exist AND the workspace contains source code files (e.g., `*.py`, `*.cs`, `*.rs`, `*.ts`, `src/`, `Cargo.toml`, `*.csproj`, `package.json`)
Action: An existing codebase without documentation was detected. Read and execute `.cursor/skills/document/SKILL.md`. After the document skill completes, re-detect state (the produced `_docs/` artifacts will place the project at Step 2 or later).
---
**Step 2 — Test Spec**
Condition: `_docs/02_document/FINAL_report.md` exists AND workspace contains source code files (e.g., `*.py`, `*.cs`, `*.rs`, `*.ts`) AND `_docs/02_document/tests/traceability-matrix.md` does not exist AND the autopilot state shows `step >= 2` (Document already ran)
Action: Read and execute `.cursor/skills/test-spec/SKILL.md`
This step applies when the codebase was documented via the `/document` skill. Test specifications must be produced before refactoring or further development.
---
**Step 3 — Code Testability Revision**
Condition: `_docs/02_document/tests/traceability-matrix.md` exists AND the autopilot state shows Test Spec (Step 2) is completed AND the autopilot state does NOT show Code Testability Revision (Step 3) as completed or skipped
Action: Analyze the codebase against the test specs to determine whether the code can be tested as-is.
1. Read `_docs/02_document/tests/traceability-matrix.md` and all test scenario files in `_docs/02_document/tests/`
2. For each test scenario, check whether the code under test can be exercised in isolation. Look for:
- Hardcoded file paths or directory references
- Hardcoded configuration values (URLs, credentials, magic numbers)
- Global mutable state that cannot be overridden
- Tight coupling to external services without abstraction
- Missing dependency injection or non-configurable parameters
- Direct file system operations without path configurability
- Inline construction of heavy dependencies (models, clients)
3. If ALL scenarios are testable as-is:
- Mark Step 3 as `completed` with outcome "Code is testable — no changes needed"
- Auto-chain to Step 4 (Decompose Tests)
4. If testability issues are found:
- Create `_docs/04_refactoring/01-testability-refactoring/`
- Write `list-of-changes.md` in that directory using the refactor skill template (`.cursor/skills/refactor/templates/list-of-changes.md`), with:
- **Mode**: `guided`
- **Source**: `autopilot-testability-analysis`
- One change entry per testability issue found (change ID, file paths, problem, proposed change, risk, dependencies)
- Invoke the refactor skill in **guided mode**: read and execute `.cursor/skills/refactor/SKILL.md` with the `list-of-changes.md` as input
- The refactor skill will create RUN_DIR (`01-testability-refactoring`), create tasks in `_docs/02_tasks/todo/`, delegate to implement skill, and verify results
- Phase 3 (Safety Net) is automatically skipped by the refactor skill for testability runs
- After refactoring completes, mark Step 3 as `completed`
- Auto-chain to Step 4 (Decompose Tests)
---
**Step 4 — Decompose Tests**
Condition: `_docs/02_document/tests/traceability-matrix.md` exists AND workspace contains source code files AND the autopilot state shows Step 3 (Code Testability Revision) is completed or skipped AND (`_docs/02_tasks/todo/` does not exist or has no test task files)
Action: Read and execute `.cursor/skills/decompose/SKILL.md` in **tests-only mode** (pass `_docs/02_document/tests/` as input). The decompose skill will:
1. Run Step 1t (test infrastructure bootstrap)
2. Run Step 3 (blackbox test task decomposition)
3. Run Step 4 (cross-verification against test coverage)
If `_docs/02_tasks/` subfolders have some task files already (e.g., refactoring tasks from Step 3), the decompose skill's resumability handles it — it appends test tasks alongside existing tasks.
---
**Step 5 — Implement Tests**
Condition: `_docs/02_tasks/todo/` contains task files AND `_dependencies_table.md` exists AND the autopilot state shows Step 4 (Decompose Tests) is completed AND `_docs/03_implementation/implementation_report_tests.md` does not exist
Action: Read and execute `.cursor/skills/implement/SKILL.md`
The implement skill reads test tasks from `_docs/02_tasks/todo/` and implements them.
If `_docs/03_implementation/` has batch reports, the implement skill detects completed tasks and continues.
---
**Step 6 — Run Tests**
Condition: `_docs/03_implementation/implementation_report_tests.md` exists AND the autopilot state shows Step 5 (Implement Tests) is completed AND the autopilot state does NOT show Step 6 (Run Tests) as completed
Action: Read and execute `.cursor/skills/test-run/SKILL.md`
Verifies the implemented test suite passes before proceeding to refactoring. The tests form the safety net for all subsequent code changes.
---
**Step 7 — Refactor (optional)**
Condition: the autopilot state shows Step 6 (Run Tests) is completed AND the autopilot state does NOT show Step 7 (Refactor) as completed or skipped AND no `_docs/04_refactoring/` run folder contains a `FINAL_report.md` for a non-testability run
Action: Present using Choose format:
```
══════════════════════════════════════
DECISION REQUIRED: Refactor codebase before adding new features?
══════════════════════════════════════
A) Run refactoring (recommended if code quality issues were noted during documentation)
B) Skip — proceed directly to New Task
══════════════════════════════════════
Recommendation: [A or B — base on whether documentation
flagged significant code smells, coupling issues, or
technical debt worth addressing before new development]
══════════════════════════════════════
```
- If user picks A → Read and execute `.cursor/skills/refactor/SKILL.md` in automatic mode. The refactor skill creates a new run folder in `_docs/04_refactoring/` (e.g., `02-coupling-refactoring`), runs the full method using the implemented tests as a safety net. After completion, auto-chain to Step 8 (New Task).
- If user picks B → Mark Step 7 as `skipped` in the state file, auto-chain to Step 8 (New Task).
---
**Step 8 — New Task**
Condition: the autopilot state shows Step 7 (Refactor) is completed or skipped AND the autopilot state does NOT show Step 8 (New Task) as completed
Action: Read and execute `.cursor/skills/new-task/SKILL.md`
The new-task skill interactively guides the user through defining new functionality. It loops until the user is done adding tasks. New task files are written to `_docs/02_tasks/todo/`.
---
**Step 9 — Implement**
Condition: the autopilot state shows Step 8 (New Task) is completed AND `_docs/03_implementation/` does not contain an `implementation_report_*.md` file other than `implementation_report_tests.md` (the tests report from Step 5 is excluded from this check)
Action: Read and execute `.cursor/skills/implement/SKILL.md`
The implement skill reads the new tasks from `_docs/02_tasks/todo/` and implements them. Tasks already implemented in Step 5 are skipped (completed tasks have been moved to `done/`).
If `_docs/03_implementation/` has batch reports from this phase, the implement skill detects completed tasks and continues.
---
**Step 10 — Run Tests**
Condition: the autopilot state shows Step 9 (Implement) is completed AND the autopilot state does NOT show Step 10 (Run Tests) as completed
Action: Read and execute `.cursor/skills/test-run/SKILL.md`
---
**Step 11 — Update Docs**
Condition: the autopilot state shows Step 10 (Run Tests) is completed AND the autopilot state does NOT show Step 11 (Update Docs) as completed AND `_docs/02_document/` contains existing documentation (module or component docs)
Action: Read and execute `.cursor/skills/document/SKILL.md` in **Task mode**. Pass all task spec files from `_docs/02_tasks/done/` that were implemented in the current cycle (i.e., tasks moved to `done/` during Steps 89 of this cycle).
The document skill in Task mode:
1. Reads each task spec to identify changed source files
2. Updates affected module docs, component docs, and system-level docs
3. Does NOT redo full discovery, verification, or problem extraction
If `_docs/02_document/` does not contain existing docs (e.g., documentation step was skipped), mark Step 11 as `skipped`.
After completion, auto-chain to Step 12 (Security Audit).
---
**Step 12 — Security Audit (optional)**
Condition: the autopilot state shows Step 11 (Update Docs) is completed or skipped AND the autopilot state does NOT show Step 12 (Security Audit) as completed or skipped AND (`_docs/04_deploy/` does not exist or is incomplete)
Action: Present using Choose format:
```
══════════════════════════════════════
DECISION REQUIRED: Run security audit before deploy?
══════════════════════════════════════
A) Run security audit (recommended for production deployments)
B) Skip — proceed directly to deploy
══════════════════════════════════════
Recommendation: A — catches vulnerabilities before production
══════════════════════════════════════
```
- If user picks A → Read and execute `.cursor/skills/security/SKILL.md`. After completion, auto-chain to Step 13 (Performance Test).
- If user picks B → Mark Step 12 as `skipped` in the state file, auto-chain to Step 13 (Performance Test).
---
**Step 13 — Performance Test (optional)**
Condition: the autopilot state shows Step 12 (Security Audit) is completed or skipped AND the autopilot state does NOT show Step 13 (Performance Test) as completed or skipped AND (`_docs/04_deploy/` does not exist or is incomplete)
Action: Present using Choose format:
```
══════════════════════════════════════
DECISION REQUIRED: Run performance/load tests before deploy?
══════════════════════════════════════
A) Run performance tests (recommended for latency-sensitive or high-load systems)
B) Skip — proceed directly to deploy
══════════════════════════════════════
Recommendation: [A or B — base on whether acceptance criteria
include latency, throughput, or load requirements]
══════════════════════════════════════
```
- If user picks A → Run performance tests:
1. If `scripts/run-performance-tests.sh` exists (generated by the test-spec skill Phase 4), execute it
2. Otherwise, check if `_docs/02_document/tests/performance-tests.md` exists for test scenarios, detect appropriate load testing tool (k6, locust, artillery, wrk, or built-in benchmarks), and execute performance test scenarios against the running system
3. Present results vs acceptance criteria thresholds
4. If thresholds fail → present Choose format: A) Fix and re-run, B) Proceed anyway, C) Abort
5. After completion, auto-chain to Step 14 (Deploy)
- If user picks B → Mark Step 13 as `skipped` in the state file, auto-chain to Step 14 (Deploy).
---
**Step 14 — Deploy**
Condition: the autopilot state shows Step 10 (Run Tests) is completed AND (Step 11 is completed or skipped) AND (Step 12 is completed or skipped) AND (Step 13 is completed or skipped) AND (`_docs/04_deploy/` does not exist or is incomplete)
Action: Read and execute `.cursor/skills/deploy/SKILL.md`
After deployment completes, the existing-code workflow is done.
---
**Re-Entry After Completion**
Condition: the autopilot state shows `step: done` OR all steps through 14 (Deploy) are completed
Action: The project completed a full cycle. Print the status banner and automatically loop back to New Task — do NOT ask the user for confirmation:
```
══════════════════════════════════════
PROJECT CYCLE COMPLETE
══════════════════════════════════════
The previous cycle finished successfully.
Starting new feature cycle…
══════════════════════════════════════
```
Set `step: 8`, `status: not_started` in the state file, then auto-chain to Step 8 (New Task).
Note: the loop (Steps 8 → 14 → 8) ensures every feature cycle includes: New Task → Implement → Run Tests → Update Docs → Security → Performance → Deploy.
## Auto-Chain Rules
| Completed Step | Next Action |
|---------------|-------------|
| Document (1) | Auto-chain → Test Spec (2) |
| Test Spec (2) | Auto-chain → Code Testability Revision (3) |
| Code Testability Revision (3) | Auto-chain → Decompose Tests (4) |
| Decompose Tests (4) | **Session boundary** — suggest new conversation before Implement Tests |
| Implement Tests (5) | Auto-chain → Run Tests (6) |
| Run Tests (6, all pass) | Auto-chain → Refactor choice (7) |
| Refactor (7, done or skipped) | Auto-chain → New Task (8) |
| New Task (8) | **Session boundary** — suggest new conversation before Implement |
| Implement (9) | Auto-chain → Run Tests (10) |
| Run Tests (10, all pass) | Auto-chain → Update Docs (11) |
| Update Docs (11) | Auto-chain → Security Audit choice (12) |
| Security Audit (12, done or skipped) | Auto-chain → Performance Test choice (13) |
| Performance Test (13, done or skipped) | Auto-chain → Deploy (14) |
| Deploy (14) | **Workflow complete** — existing-code flow done |
## Status Summary Template
```
═══════════════════════════════════════════════════
AUTOPILOT STATUS (existing-code)
═══════════════════════════════════════════════════
Step 1 Document [DONE / IN PROGRESS / NOT STARTED / FAILED (retry N/3)]
Step 2 Test Spec [DONE / IN PROGRESS / NOT STARTED / FAILED (retry N/3)]
Step 3 Code Testability Rev. [DONE / SKIPPED / IN PROGRESS / NOT STARTED / FAILED (retry N/3)]
Step 4 Decompose Tests [DONE (N tasks) / IN PROGRESS / NOT STARTED / FAILED (retry N/3)]
Step 5 Implement Tests [DONE / IN PROGRESS (batch M) / NOT STARTED / FAILED (retry N/3)]
Step 6 Run Tests [DONE (N passed, M failed) / IN PROGRESS / NOT STARTED / FAILED (retry N/3)]
Step 7 Refactor [DONE / SKIPPED / IN PROGRESS (phase N) / NOT STARTED / FAILED (retry N/3)]
Step 8 New Task [DONE (N tasks) / IN PROGRESS / NOT STARTED / FAILED (retry N/3)]
Step 9 Implement [DONE / IN PROGRESS (batch M of ~N) / NOT STARTED / FAILED (retry N/3)]
Step 10 Run Tests [DONE (N passed, M failed) / IN PROGRESS / NOT STARTED / FAILED (retry N/3)]
Step 11 Update Docs [DONE / SKIPPED / IN PROGRESS / NOT STARTED / FAILED (retry N/3)]
Step 12 Security Audit [DONE / SKIPPED / IN PROGRESS / NOT STARTED / FAILED (retry N/3)]
Step 13 Performance Test [DONE / SKIPPED / IN PROGRESS / NOT STARTED / FAILED (retry N/3)]
Step 14 Deploy [DONE / IN PROGRESS / NOT STARTED / FAILED (retry N/3)]
═══════════════════════════════════════════════════
Current: Step N — Name
SubStep: M — [sub-skill internal step name]
Retry: [N/3 if retrying, omit if 0]
Action: [what will happen next]
═══════════════════════════════════════════════════
```
@@ -1,235 +0,0 @@
# Greenfield Workflow
Workflow for new projects built from scratch. Flows linearly: Problem → Research → Plan → UI Design (if applicable) → Decompose → Implement → Run Tests → Security Audit (optional) → Performance Test (optional) → Deploy.
## Step Reference Table
| Step | Name | Sub-Skill | Internal SubSteps |
|------|------|-----------|-------------------|
| 1 | Problem | problem/SKILL.md | Phase 14 |
| 2 | Research | research/SKILL.md | Mode A: Phase 14 · Mode B: Step 08 |
| 3 | Plan | plan/SKILL.md | Step 16 + Final |
| 4 | UI Design | ui-design/SKILL.md | Phase 08 (conditional — UI projects only) |
| 5 | Decompose | decompose/SKILL.md | Step 14 |
| 6 | Implement | implement/SKILL.md | (batch-driven, no fixed sub-steps) |
| 7 | Run Tests | test-run/SKILL.md | Steps 14 |
| 8 | Security Audit | security/SKILL.md | Phase 15 (optional) |
| 9 | Performance Test | (autopilot-managed) | Load/stress tests (optional) |
| 10 | Deploy | deploy/SKILL.md | Step 17 |
## Detection Rules
Check rules in order — first match wins.
---
**Step 1 — Problem Gathering**
Condition: `_docs/00_problem/` does not exist, OR any of these are missing/empty:
- `problem.md`
- `restrictions.md`
- `acceptance_criteria.md`
- `input_data/` (must contain at least one file)
Action: Read and execute `.cursor/skills/problem/SKILL.md`
---
**Step 2 — Research (Initial)**
Condition: `_docs/00_problem/` is complete AND `_docs/01_solution/` has no `solution_draft*.md` files
Action: Read and execute `.cursor/skills/research/SKILL.md` (will auto-detect Mode A)
---
**Research Decision** (inline gate between Step 2 and Step 3)
Condition: `_docs/01_solution/` contains `solution_draft*.md` files AND `_docs/01_solution/solution.md` does not exist AND `_docs/02_document/architecture.md` does not exist
Action: Present the current research state to the user:
- How many solution drafts exist
- Whether tech_stack.md and security_analysis.md exist
- One-line summary from the latest draft
Then present using the **Choose format**:
```
══════════════════════════════════════
DECISION REQUIRED: Research complete — next action?
══════════════════════════════════════
A) Run another research round (Mode B assessment)
B) Proceed to planning with current draft
══════════════════════════════════════
Recommendation: [A or B] — [reason based on draft quality]
══════════════════════════════════════
```
- If user picks A → Read and execute `.cursor/skills/research/SKILL.md` (will auto-detect Mode B)
- If user picks B → auto-chain to Step 3 (Plan)
---
**Step 3 — Plan**
Condition: `_docs/01_solution/` has `solution_draft*.md` files AND `_docs/02_document/architecture.md` does not exist
Action:
1. The plan skill's Prereq 2 will rename the latest draft to `solution.md` — this is handled by the plan skill itself
2. Read and execute `.cursor/skills/plan/SKILL.md`
If `_docs/02_document/` exists but is incomplete (has some artifacts but no `FINAL_report.md`), the plan skill's built-in resumability handles it.
---
**Step 4 — UI Design (conditional)**
Condition: `_docs/02_document/architecture.md` exists AND the autopilot state does NOT show Step 4 (UI Design) as completed or skipped AND the project is a UI project
**UI Project Detection** — the project is a UI project if ANY of the following are true:
- `package.json` exists in the workspace root or any subdirectory
- `*.html`, `*.jsx`, `*.tsx` files exist in the workspace
- `_docs/02_document/components/` contains a component whose `description.md` mentions UI, frontend, page, screen, dashboard, form, or view
- `_docs/02_document/architecture.md` mentions frontend, UI layer, SPA, or client-side rendering
- `_docs/01_solution/solution.md` mentions frontend, web interface, or user-facing UI
If the project is NOT a UI project → mark Step 4 as `skipped` in the state file and auto-chain to Step 5.
If the project IS a UI project → present using Choose format:
```
══════════════════════════════════════
DECISION REQUIRED: UI project detected — generate mockups?
══════════════════════════════════════
A) Generate UI mockups before decomposition (recommended)
B) Skip — proceed directly to decompose
══════════════════════════════════════
Recommendation: A — mockups before decomposition
produce better task specs for frontend components
══════════════════════════════════════
```
- If user picks A → Read and execute `.cursor/skills/ui-design/SKILL.md`. After completion, auto-chain to Step 5 (Decompose).
- If user picks B → Mark Step 4 as `skipped` in the state file, auto-chain to Step 5 (Decompose).
---
**Step 5 — Decompose**
Condition: `_docs/02_document/` contains `architecture.md` AND `_docs/02_document/components/` has at least one component AND `_docs/02_tasks/todo/` does not exist or has no task files
Action: Read and execute `.cursor/skills/decompose/SKILL.md`
If `_docs/02_tasks/` subfolders have some task files already, the decompose skill's resumability handles it.
---
**Step 6 — Implement**
Condition: `_docs/02_tasks/todo/` contains task files AND `_dependencies_table.md` exists AND `_docs/03_implementation/` does not contain any `implementation_report_*.md` file
Action: Read and execute `.cursor/skills/implement/SKILL.md`
If `_docs/03_implementation/` has batch reports, the implement skill detects completed tasks and continues. The FINAL report filename is context-dependent — see implement skill documentation for naming convention.
---
**Step 7 — Run Tests**
Condition: `_docs/03_implementation/` contains an `implementation_report_*.md` file AND the autopilot state does NOT show Step 7 (Run Tests) as completed AND (`_docs/04_deploy/` does not exist or is incomplete)
Action: Read and execute `.cursor/skills/test-run/SKILL.md`
---
**Step 8 — Security Audit (optional)**
Condition: the autopilot state shows Step 7 (Run Tests) is completed AND the autopilot state does NOT show Step 8 (Security Audit) as completed or skipped AND (`_docs/04_deploy/` does not exist or is incomplete)
Action: Present using Choose format:
```
══════════════════════════════════════
DECISION REQUIRED: Run security audit before deploy?
══════════════════════════════════════
A) Run security audit (recommended for production deployments)
B) Skip — proceed directly to deploy
══════════════════════════════════════
Recommendation: A — catches vulnerabilities before production
══════════════════════════════════════
```
- If user picks A → Read and execute `.cursor/skills/security/SKILL.md`. After completion, auto-chain to Step 9 (Performance Test).
- If user picks B → Mark Step 8 as `skipped` in the state file, auto-chain to Step 9 (Performance Test).
---
**Step 9 — Performance Test (optional)**
Condition: the autopilot state shows Step 8 (Security Audit) is completed or skipped AND the autopilot state does NOT show Step 9 (Performance Test) as completed or skipped AND (`_docs/04_deploy/` does not exist or is incomplete)
Action: Present using Choose format:
```
══════════════════════════════════════
DECISION REQUIRED: Run performance/load tests before deploy?
══════════════════════════════════════
A) Run performance tests (recommended for latency-sensitive or high-load systems)
B) Skip — proceed directly to deploy
══════════════════════════════════════
Recommendation: [A or B — base on whether acceptance criteria
include latency, throughput, or load requirements]
══════════════════════════════════════
```
- If user picks A → Run performance tests:
1. If `scripts/run-performance-tests.sh` exists (generated by the test-spec skill Phase 4), execute it
2. Otherwise, check if `_docs/02_document/tests/performance-tests.md` exists for test scenarios, detect appropriate load testing tool (k6, locust, artillery, wrk, or built-in benchmarks), and execute performance test scenarios against the running system
3. Present results vs acceptance criteria thresholds
4. If thresholds fail → present Choose format: A) Fix and re-run, B) Proceed anyway, C) Abort
5. After completion, auto-chain to Step 10 (Deploy)
- If user picks B → Mark Step 9 as `skipped` in the state file, auto-chain to Step 10 (Deploy).
---
**Step 10 — Deploy**
Condition: the autopilot state shows Step 7 (Run Tests) is completed AND (Step 8 is completed or skipped) AND (Step 9 is completed or skipped) AND (`_docs/04_deploy/` does not exist or is incomplete)
Action: Read and execute `.cursor/skills/deploy/SKILL.md`
---
**Done**
Condition: `_docs/04_deploy/` contains all expected artifacts (containerization.md, ci_cd_pipeline.md, environment_strategy.md, observability.md, deployment_procedures.md, deploy_scripts.md)
Action: Report project completion with summary. If the user runs autopilot again after greenfield completion, Flow Resolution rule 3 routes to the existing-code flow (re-entry after completion) so they can add new features.
## Auto-Chain Rules
| Completed Step | Next Action |
|---------------|-------------|
| Problem (1) | Auto-chain → Research (2) |
| Research (2) | Auto-chain → Research Decision (ask user: another round or proceed?) |
| Research Decision → proceed | Auto-chain → Plan (3) |
| Plan (3) | Auto-chain → UI Design detection (4) |
| UI Design (4, done or skipped) | Auto-chain → Decompose (5) |
| Decompose (5) | **Session boundary** — suggest new conversation before Implement |
| Implement (6) | Auto-chain → Run Tests (7) |
| Run Tests (7, all pass) | Auto-chain → Security Audit choice (8) |
| Security Audit (8, done or skipped) | Auto-chain → Performance Test choice (9) |
| Performance Test (9, done or skipped) | Auto-chain → Deploy (10) |
| Deploy (10) | Report completion |
## Status Summary Template
```
═══════════════════════════════════════════════════
AUTOPILOT STATUS (greenfield)
═══════════════════════════════════════════════════
Step 1 Problem [DONE / IN PROGRESS / NOT STARTED / FAILED (retry N/3)]
Step 2 Research [DONE (N drafts) / IN PROGRESS / NOT STARTED / FAILED (retry N/3)]
Step 3 Plan [DONE / IN PROGRESS / NOT STARTED / FAILED (retry N/3)]
Step 4 UI Design [DONE / SKIPPED / IN PROGRESS / NOT STARTED / FAILED (retry N/3)]
Step 5 Decompose [DONE (N tasks) / IN PROGRESS / NOT STARTED / FAILED (retry N/3)]
Step 6 Implement [DONE / IN PROGRESS (batch M of ~N) / NOT STARTED / FAILED (retry N/3)]
Step 7 Run Tests [DONE (N passed, M failed) / IN PROGRESS / NOT STARTED / FAILED (retry N/3)]
Step 8 Security Audit [DONE / SKIPPED / IN PROGRESS / NOT STARTED / FAILED (retry N/3)]
Step 9 Performance Test [DONE / SKIPPED / IN PROGRESS / NOT STARTED / FAILED (retry N/3)]
Step 10 Deploy [DONE / IN PROGRESS / NOT STARTED / FAILED (retry N/3)]
═══════════════════════════════════════════════════
Current: Step N — Name
SubStep: M — [sub-skill internal step name]
Retry: [N/3 if retrying, omit if 0]
Action: [what will happen next]
═══════════════════════════════════════════════════
```
-92
View File
@@ -1,92 +0,0 @@
# Autopilot State Management
## State File: `_docs/_autopilot_state.md`
The autopilot persists its position to `_docs/_autopilot_state.md`. This is a lightweight pointer — only the current step. All history lives in `_docs/` artifacts and git log. Folder scanning is the fallback when the state file doesn't exist.
### Template
```markdown
# Autopilot State
## Current Step
flow: [greenfield | existing-code]
step: [1-10 for greenfield, 1-13 for existing-code, or "done"]
name: [step name from the active flow's Step Reference Table]
status: [not_started / in_progress / completed / skipped / failed]
sub_step: [0, or sub-skill internal step number + name if interrupted mid-step]
retry_count: [0-3 — consecutive auto-retry attempts, reset to 0 on success]
```
### Examples
```
flow: greenfield
step: 3
name: Plan
status: in_progress
sub_step: 4 — Architecture Review & Risk Assessment
retry_count: 0
```
```
flow: existing-code
step: 2
name: Test Spec
status: failed
sub_step: 1b — Test Case Generation
retry_count: 3
```
### State File Rules
1. **Create** on the first autopilot invocation (after state detection determines Step 1)
2. **Update** after every change — this includes: batch completion, sub-step progress, step completion, session boundary, failed retry, or any meaningful state transition. The state file must always reflect the current reality.
3. **Read** as the first action on every invocation — before folder scanning
4. **Cross-check**: verify against actual `_docs/` folder contents. If they disagree, trust the folder structure and update the state file
5. **Never delete** the state file
6. **Retry tracking**: increment `retry_count` on each failed auto-retry; reset to `0` on success. If `retry_count` reaches 3, set `status: failed`
7. **Failed state on re-entry**: if `status: failed` with `retry_count: 3`, do NOT auto-retry — present the issue to the user first
8. **Skill-internal state**: when the active skill maintains its own state file (e.g., document skill's `_docs/02_document/state.json`), the autopilot's `sub_step` field should reflect the skill's internal progress. On re-entry, cross-check the skill's state file against the autopilot's `sub_step` for consistency.
## State Detection
Read `_docs/_autopilot_state.md` first. If it exists and is consistent with the folder structure, use the `Current Step` from the state file. If the state file doesn't exist or is inconsistent, fall back to folder scanning.
### Folder Scan Rules (fallback)
Scan `_docs/` to determine the current workflow position. The detection rules are defined in each flow file (`flows/greenfield.md` and `flows/existing-code.md`). Check the existing-code flow first (Step 1 detection), then greenfield flow rules. First match wins.
## Re-Entry Protocol
When the user invokes `/autopilot` and work already exists:
1. Read `_docs/_autopilot_state.md`
2. Cross-check against `_docs/` folder structure
3. Present Status Summary (use the active flow's Status Summary Template)
4. If the detected step has a sub-skill with built-in resumability, the sub-skill handles mid-step recovery
5. Continue execution from detected state
## Session Boundaries
After any decompose/planning step completes, **do not auto-chain to implement**. Instead:
1. Update state file: mark the step as completed, set current step to the next implement step with status `not_started`
- Existing-code flow: After Step 4 (Decompose Tests) → set current step to 5 (Implement Tests)
- Existing-code flow: After Step 8 (New Task) → set current step to 9 (Implement)
- Greenfield flow: After Step 5 (Decompose) → set current step to 6 (Implement)
2. Present a summary: number of tasks, estimated batches, total complexity points
3. Use Choose format:
```
══════════════════════════════════════
DECISION REQUIRED: Decompose complete — start implementation?
══════════════════════════════════════
A) Start a new conversation for implementation (recommended for context freshness)
B) Continue implementation in this conversation
══════════════════════════════════════
Recommendation: A — implementation is the longest phase, fresh context helps
══════════════════════════════════════
```
These are the only hard session boundaries. All other transitions auto-chain.
+64 -3
View File
@@ -50,6 +50,18 @@ For each task, verify implementation satisfies every acceptance criterion:
- Flag any AC that is not demonstrably satisfied as a **Spec-Gap** finding (severity: High)
- Flag any scope creep (implementation beyond what the spec asked for) as a **Scope** finding (severity: Low)
**Contract verification** (for shared-models / shared-API tasks — any task with a `## Contract` section):
- Verify the referenced contract file exists at the stated path under `_docs/02_document/contracts/`.
- Verify the implementation's public signatures (types, method shapes, endpoint paths, error variants) match the contract's **Shape** section.
- Verify invariants from the contract's **Invariants** section are enforced in code (either structurally via types or via runtime checks with tests).
- If the implementation and the contract disagree, emit a **Spec-Gap** finding (High severity) and note which side is drifting.
**Consumer-side contract verification** (for tasks whose Dependencies list a contract file):
- Verify the consumer's imports and call sites match the contract's Shape.
- If they diverge, emit a **Spec-Gap** finding (High severity) with a hint that the consumer, the contract, or the producer is drifting.
## Phase 3: Code Quality Review
Check implemented code against quality standards:
@@ -92,6 +104,53 @@ When multiple tasks were implemented in the same batch:
- Shared code is not duplicated across task implementations
- Dependencies declared in task specs are properly wired
## Phase 7: Architecture Compliance
Verify the implemented code respects the architecture documented in `_docs/02_document/architecture.md` and the component boundaries declared in `_docs/02_document/module-layout.md`.
**Inputs**:
- `_docs/02_document/architecture.md` — layering, allowed dependencies, patterns
- `_docs/02_document/module-layout.md` — per-component directories, Public API surface, `Imports from` lists, Allowed Dependencies table
- The cumulative list of changed files (for per-batch invocation) or the full codebase (for baseline invocation)
**Checks**:
1. **Layer direction**: for each import in a changed file, resolve the importer's layer (from the Allowed Dependencies table) and the importee's layer. Flag any import where the importee's layer is strictly higher than the importer's. Severity: High. Category: Architecture.
2. **Public API respect**: for each cross-component import, verify the imported symbol lives in the target component's Public API file list (from `module-layout.md`). Importing an internal file of another component is an Architecture finding. Severity: High.
3. **No new cyclic module dependencies**: build a module-level import graph of the changed files plus their direct dependencies. Flag any new cycle introduced by this batch. Severity: Critical (cycles are structurally hard to undo once wired). Category: Architecture.
4. **Duplicate symbols across components**: scan changed files for class, function, or constant names that also appear in another component's code AND do not share an interface. If a shared abstraction was expected (via cross-cutting epic or shared/*), flag it. Severity: High. Category: Architecture.
5. **Cross-cutting concerns not locally re-implemented**: if a file under a component directory contains logic that should live in `shared/<concern>/` (e.g., custom logging setup, config loader, error envelope), flag it. Severity: Medium. Category: Architecture.
**Detection approach (per language)**:
- Python: parse `import` / `from ... import` statements; optionally AST with `ast` module for reliable symbol resolution.
- TypeScript / JavaScript: parse `import ... from '...'` and `require('...')`; resolve via `tsconfig.json` paths.
- C#: parse `using` directives and fully-qualified type references; respect `.csproj` ProjectReference layering.
- Rust: parse `use <crate>::` and `mod` declarations; respect `Cargo.toml` workspace members.
- Go: parse `import` blocks; respect module path ownership.
If a static analyzer tool is available on the project (ArchUnit, NsDepCop, tach, eslint-plugin-boundaries, etc.), prefer invoking it and parsing its output over hand-rolled analysis.
**Invocation modes**:
- **Full mode** (default when invoked by the implement skill per batch): all 7 phases run.
- **Baseline mode**: Phase 1 + Phase 7 only. Used for one-time architecture scan of an existing codebase (see existing-code flow Step 2 — Architecture Baseline Scan). Produces `_docs/02_document/architecture_compliance_baseline.md` instead of a batch review report.
- **Cumulative mode**: all 7 phases on the union of changed files since the last cumulative review. Used mid-implementation (see implement skill Step 14.5).
**Baseline delta** (cumulative mode + full mode, when `_docs/02_document/architecture_compliance_baseline.md` exists):
After the seven phases produce the current Architecture findings list, partition those findings against the baseline:
- **Carried over**: a finding whose `(file, category, rule)` triple matches an entry in the baseline. Not new; still present.
- **Resolved**: a baseline entry whose `(file, category, rule)` triple is NOT in the current findings AND whose target file is in scope of this review. The team fixed it.
- **Newly introduced**: a current finding that was not in the baseline. The review cycle created this.
Emit a `## Baseline Delta` section in the report with three tables (Carried over, Resolved, Newly introduced) and per-category counts. The verdict logic does not change — Critical / High still drive FAIL. The delta is additional signal for the user and feeds the retrospective's structural metrics.
## Output Format
Produce a structured report with findings deduplicated and sorted by severity:
@@ -136,7 +195,9 @@ Produce a structured report with findings deduplicated and sorted by severity:
## Category Values
Bug, Spec-Gap, Security, Performance, Maintainability, Style, Scope
Bug, Spec-Gap, Security, Performance, Maintainability, Style, Scope, Architecture
`Architecture` findings come from Phase 7. They indicate layering violations, Public API bypasses, new cyclic dependencies, duplicate symbols, or cross-cutting concerns re-implemented locally.
## Verdict Logic
@@ -148,7 +209,7 @@ Bug, Spec-Gap, Security, Performance, Maintainability, Style, Scope
The `/implement` skill invokes this skill after each batch completes:
1. Collects changed files from all implementer agents in the batch
1. Collects changed files from all tasks implemented in the batch
2. Passes task spec paths + changed files to this skill
3. If verdict is FAIL — presents findings to user (BLOCKING), user fixes or confirms
4. If verdict is PASS or PASS_WITH_WARNINGS — proceeds automatically (findings shown as info)
@@ -160,7 +221,7 @@ The `/implement` skill invokes this skill after each batch completes:
| Input | Type | Source | Required |
|-------|------|--------|----------|
| `task_specs` | list of file paths | Task `.md` files from `_docs/02_tasks/todo/` for the current batch | Yes |
| `changed_files` | list of file paths | Files modified by implementer agents (from `git diff` or agent reports) | Yes |
| `changed_files` | list of file paths | Files modified by the tasks in the batch (from `git diff`) | Yes |
| `batch_number` | integer | Current batch number (for report naming) | Yes |
| `project_restrictions` | file path | `_docs/00_problem/restrictions.md` | If exists |
| `solution_overview` | file path | `_docs/01_solution/solution.md` | If exists |
+68 -199
View File
@@ -2,8 +2,8 @@
name: decompose
description: |
Decompose planned components into atomic implementable tasks with bootstrap structure plan.
4-step workflow: bootstrap structure plan, component task decomposition, blackbox test task decomposition, and cross-task verification.
Supports full decomposition (_docs/ structure), single component mode, and tests-only mode.
Workflow entrypoints: implementation task decomposition, single component decomposition, and tests-only decomposition.
The invoking flow decides which entrypoint to run; this skill executes that selected sequence.
Trigger phrases:
- "decompose", "decompose features", "feature decomposition"
- "task decomposition", "break down components"
@@ -20,7 +20,7 @@ Decompose planned components into atomic, implementable task specs with a bootst
## Core Principles
- **Atomic tasks**: each task does one thing; if it exceeds 8 complexity points, split it
- **Atomic tasks**: each task does one thing; if it exceeds 5 complexity points, split it
- **Behavioral specs, not implementation plans**: describe what the system should do, not how to build it
- **Flat structure**: all tasks are tracker-ID-prefixed files in TASKS_DIR — no component subdirectories
- **Save immediately**: write artifacts to disk after each task; never accumulate unsaved work
@@ -30,39 +30,50 @@ Decompose planned components into atomic, implementable task specs with a bootst
## Context Resolution
Determine the operating mode based on invocation before any other logic runs.
Resolve the selected entrypoint from the invocation context before any other logic runs. The caller decides whether this is implementation, single component, or tests-only decomposition; this skill only executes the selected sequence.
**Implementation task decomposition** (default; selected by flows before invoking this skill):
**Default** (no explicit input file provided):
- DOCUMENT_DIR: `_docs/02_document/`
- TASKS_DIR: `_docs/02_tasks/`
- TASKS_TODO: `_docs/02_tasks/todo/`
- Reads from: `_docs/00_problem/`, `_docs/01_solution/`, DOCUMENT_DIR
- Runs Step 1 (bootstrap) + Step 2 (all components) + Step 3 (blackbox tests) + Step 4 (cross-verification)
- Produces only implementation tasks. Blackbox/e2e test task files are produced only when the invoking flow selects tests-only decomposition.
**Single component mode** (provided file is within `_docs/02_document/` and inside a `components/` subdirectory):
- DOCUMENT_DIR: `_docs/02_document/`
- TASKS_DIR: `_docs/02_tasks/`
- TASKS_TODO: `_docs/02_tasks/todo/`
- Derive component number and component name from the file path
- Ask user for the parent Epic ID
- Runs Step 2 (that component only, appending to existing task numbering)
**Tests-only mode** (provided file/directory is within `tests/`, or `DOCUMENT_DIR/tests/` exists and input explicitly requests test decomposition):
- DOCUMENT_DIR: `_docs/02_document/`
- TASKS_DIR: `_docs/02_tasks/`
- TASKS_TODO: `_docs/02_tasks/todo/`
- TESTS_DIR: `DOCUMENT_DIR/tests/`
- Reads from: `_docs/00_problem/`, `_docs/01_solution/`, TESTS_DIR
- Runs Step 1t (test infrastructure bootstrap) + Step 3 (blackbox test decomposition) + Step 4 (cross-verification against test coverage)
- Skips Step 1 (project bootstrap) and Step 2 (component decomposition) — the codebase already exists
Announce the detected mode and resolved paths to the user before proceeding.
Announce the selected entrypoint and resolved paths to the user before proceeding.
### Step Applicability by Mode
| Step | File | Implementation | Single | Tests-only |
|------|------|:--------------:|:------:|:----------:|
| 1 Bootstrap Structure | `steps/01_bootstrap-structure.md` | ✓ | — | — |
| 1t Test Infrastructure | `steps/01t_test-infrastructure.md` | — | — | ✓ |
| 1.5 Module Layout | `steps/01-5_module-layout.md` | ✓ | — | — |
| 2 Task Decomposition | `steps/02_task-decomposition.md` | ✓ | ✓ | — |
| 3 Blackbox Test Tasks | `steps/03_blackbox-test-decomposition.md` | — | — | ✓ |
| 4 Cross-Verification | `steps/04_cross-verification.md` | ✓ | — | ✓ |
## Input Specification
### Required Files
**Default:**
**Implementation task decomposition:**
| File | Purpose |
|------|---------|
@@ -70,10 +81,11 @@ Announce the detected mode and resolved paths to the user before proceeding.
| `_docs/00_problem/restrictions.md` | Constraints and limitations |
| `_docs/00_problem/acceptance_criteria.md` | Measurable acceptance criteria |
| `_docs/01_solution/solution.md` | Finalized solution |
| `DOCUMENT_DIR/architecture.md` | Architecture from plan skill |
| `DOCUMENT_DIR/architecture.md` | Architecture from plan/document skill (must contain a `## Architecture Vision` H2 — confirmed user intent) |
| `DOCUMENT_DIR/glossary.md` | Project terminology (confirmed by user in plan Phase 2a.0 or document Step 4.5). Use it to keep task names, component references, and AC wording consistent with the user's vocabulary |
| `DOCUMENT_DIR/system-flows.md` | System flows from plan skill |
| `DOCUMENT_DIR/components/[##]_[name]/description.md` | Component specs from plan skill |
| `DOCUMENT_DIR/tests/` | Blackbox test specs from plan skill |
| `DOCUMENT_DIR/tests/` | Optional product acceptance context from test-spec skill; do not create test task files from it in this entrypoint |
**Single component mode:**
@@ -100,15 +112,18 @@ Announce the detected mode and resolved paths to the user before proceeding.
### Prerequisite Checks (BLOCKING)
**Default:**
**Implementation task decomposition:**
1. DOCUMENT_DIR contains `architecture.md` and `components/`**STOP if missing**
2. Create TASKS_DIR and TASKS_TODO if they do not exist
3. If TASKS_DIR subfolders (`todo/`, `backlog/`, `done/`) already contain task files, ask user: **resume from last checkpoint or start fresh?**
**Single component mode:**
1. The provided component file exists and is non-empty — **STOP if missing**
**Tests-only mode:**
1. `TESTS_DIR/blackbox-tests.md` exists and is non-empty — **STOP if missing**
2. `TESTS_DIR/environment.md` exists — **STOP if missing**
3. Create TASKS_DIR and TASKS_TODO if they do not exist
@@ -131,11 +146,14 @@ TASKS_DIR/
**Naming convention**: Each task file is initially saved in `TASKS_TODO/` with a temporary numeric prefix (`[##]_[short_name].md`). After creating the work item ticket, rename the file to use the work item ticket ID as prefix (`[TRACKER-ID]_[short_name].md`). For example: `todo/01_initial_structure.md``todo/AZ-42_initial_structure.md`.
If tracker availability fails, follow `.cursor/rules/tracker.mdc` before continuing. Only when the user explicitly chooses `tracker: local` may the numeric prefix remain; in that mode set `Tracker: pending` and `Epic: pending` in the task header and keep the task eligible for later tracker sync.
### Save Timing
| Step | Save immediately after | Filename |
|------|------------------------|----------|
| Step 1 | Bootstrap structure plan complete + work item ticket created + file renamed | `todo/[TRACKER-ID]_initial_structure.md` |
| Step 1.5 | Module layout written | `_docs/02_document/module-layout.md` |
| Step 1t | Test infrastructure bootstrap complete + work item ticket created + file renamed | `todo/[TRACKER-ID]_test_infrastructure.md` |
| Step 2 | Each component task decomposed + work item ticket created + file renamed | `todo/[TRACKER-ID]_[short_name].md` |
| Step 3 | Each blackbox test task decomposed + work item ticket created + file renamed | `todo/[TRACKER-ID]_[short_name].md` |
@@ -151,199 +169,49 @@ If TASKS_DIR subfolders already contain task files:
## Progress Tracking
At the start of execution, create a TodoWrite with all applicable steps. Update status as each step/component completes.
At the start of execution, create a TodoWrite with all applicable steps for the selected entrypoint (see Step Applicability table). Update status as each step/component completes.
## Workflow
### Step 1: Bootstrap Structure Plan (implementation mode only)
Read and follow `steps/01_bootstrap-structure.md`.
---
### Step 1t: Test Infrastructure Bootstrap (tests-only mode only)
**Role**: Professional Quality Assurance Engineer
**Goal**: Produce `01_test_infrastructure.md` — the first task describing the test project scaffold
**Constraints**: This is a plan document, not code. The `/implement` skill executes it.
1. Read `TESTS_DIR/environment.md` and `TESTS_DIR/test-data.md`
2. Read problem.md, restrictions.md, acceptance_criteria.md for domain context
3. Document the test infrastructure plan using `templates/test-infrastructure-task.md`
The test infrastructure bootstrap must include:
- Test project folder layout (`e2e/` directory structure)
- Mock/stub service definitions for each external dependency
- `docker-compose.test.yml` structure from environment.md
- Test runner configuration (framework, plugins, fixtures)
- Test data fixture setup from test-data.md seed data sets
- Test reporting configuration (format, output path)
- Data isolation strategy
**Self-verification**:
- [ ] Every external dependency from environment.md has a mock service defined
- [ ] Docker Compose structure covers all services from environment.md
- [ ] Test data fixtures cover all seed data sets from test-data.md
- [ ] Test runner configuration matches the consumer app tech stack from environment.md
- [ ] Data isolation strategy is defined
**Save action**: Write `todo/01_test_infrastructure.md` (temporary numeric name)
**Tracker action**: Create a work item ticket for this task under the "Blackbox Tests" epic. Write the work item ticket ID and Epic ID back into the task header.
**Rename action**: Rename the file from `todo/01_test_infrastructure.md` to `todo/[TRACKER-ID]_test_infrastructure.md`. Update the **Task** field inside the file to match the new filename.
**BLOCKING**: Present test infrastructure plan summary to user. Do NOT proceed until user confirms.
Read and follow `steps/01t_test-infrastructure.md`.
---
### Step 1: Bootstrap Structure Plan (default mode only)
### Step 1.5: Module Layout (implementation mode only)
**Role**: Professional software architect
**Goal**: Produce `01_initial_structure.md` — the first task describing the project skeleton
**Constraints**: This is a plan document, not code. The `/implement` skill executes it.
1. Read architecture.md, all component specs, system-flows.md, data_model.md, and `deployment/` from DOCUMENT_DIR
2. Read problem, solution, and restrictions from `_docs/00_problem/` and `_docs/01_solution/`
3. Research best implementation patterns for the identified tech stack
4. Document the structure plan using `templates/initial-structure-task.md`
The bootstrap structure plan must include:
- Project folder layout with all component directories
- Shared models, interfaces, and DTOs
- Dockerfile per component (multi-stage, non-root, health checks, pinned base images)
- `docker-compose.yml` for local development (all components + database + dependencies)
- `docker-compose.test.yml` for blackbox test environment (blackbox test runner)
- `.dockerignore`
- CI/CD pipeline file (`.github/workflows/ci.yml` or `azure-pipelines.yml`) with stages from `deployment/ci_cd_pipeline.md`
- Database migration setup and initial seed data scripts
- Observability configuration: structured logging setup, health check endpoints (`/health/live`, `/health/ready`), metrics endpoint (`/metrics`)
- Environment variable documentation (`.env.example`)
- Test structure with unit and blackbox test locations
**Self-verification**:
- [ ] All components have corresponding folders in the layout
- [ ] All inter-component interfaces have DTOs defined
- [ ] Dockerfile defined for each component
- [ ] `docker-compose.yml` covers all components and dependencies
- [ ] `docker-compose.test.yml` enables blackbox testing
- [ ] CI/CD pipeline file defined with lint, test, security, build, deploy stages
- [ ] Database migration setup included
- [ ] Health check endpoints specified for each service
- [ ] Structured logging configuration included
- [ ] `.env.example` with all required environment variables
- [ ] Environment strategy covers dev, staging, production
- [ ] Test structure includes unit and blackbox test locations
**Save action**: Write `todo/01_initial_structure.md` (temporary numeric name)
**Tracker action**: Create a work item ticket for this task under the "Bootstrap & Initial Structure" epic. Write the work item ticket ID and Epic ID back into the task header.
**Rename action**: Rename the file from `todo/01_initial_structure.md` to `todo/[TRACKER-ID]_initial_structure.md` (e.g., `todo/AZ-42_initial_structure.md`). Update the **Task** field inside the file to match the new filename.
**BLOCKING**: Present structure plan summary to user. Do NOT proceed until user confirms.
Read and follow `steps/01-5_module-layout.md`.
---
### Step 2: Task Decomposition (default and single component modes)
### Step 2: Task Decomposition (implementation and single component modes)
**Role**: Professional software architect
**Goal**: Decompose each component into atomic, implementable task specs — numbered sequentially starting from 02
**Constraints**: Behavioral specs only — describe what, not how. No implementation code.
**Numbering**: Tasks are numbered sequentially across all components in dependency order. Start from 02 (01 is initial_structure). In single component mode, start from the next available number in TASKS_DIR.
**Component ordering**: Process components in dependency order — foundational components first (shared models, database), then components that depend on them.
For each component (or the single provided component):
1. Read the component's `description.md` and `tests.md` (if available)
2. Decompose into atomic tasks; create only 1 task if the component is simple or atomic
3. Split into multiple tasks only when it is necessary and would be easier to implement
4. Do not create tasks for other components — only tasks for the current component
5. Each task should be atomic, containing 0 APIs or a list of semantically connected APIs
6. Write each task spec using `templates/task.md`
7. Estimate complexity per task (1, 2, 3, 5, 8 points); no task should exceed 8 points — split if it does
8. Note task dependencies (referencing tracker IDs of already-created dependency tasks, e.g., `AZ-42_initial_structure`)
9. **Immediately after writing each task file**: create a work item ticket, link it to the component's epic, write the work item ticket ID and Epic ID back into the task header, then rename the file from `todo/[##]_[short_name].md` to `todo/[TRACKER-ID]_[short_name].md`.
**Self-verification** (per component):
- [ ] Every task is atomic (single concern)
- [ ] No task exceeds 8 complexity points
- [ ] Task dependencies reference correct tracker IDs
- [ ] Tasks cover all interfaces defined in the component spec
- [ ] No tasks duplicate work from other components
- [ ] Every task has a work item ticket linked to the correct epic
**Save action**: Write each `todo/[##]_[short_name].md` (temporary numeric name), create work item ticket inline, then rename to `todo/[TRACKER-ID]_[short_name].md`. Update the **Task** field inside the file to match the new filename. Update **Dependencies** references in the file to use tracker IDs of the dependency tasks.
Read and follow `steps/02_task-decomposition.md`.
---
### Step 3: Blackbox Test Task Decomposition (default and tests-only modes)
### Step 3: Blackbox Test Task Decomposition (tests-only mode only)
**Role**: Professional Quality Assurance Engineer
**Goal**: Decompose blackbox test specs into atomic, implementable task specs
**Constraints**: Behavioral specs only — describe what, not how. No test code.
**Numbering**:
- In default mode: continue sequential numbering from where Step 2 left off.
- In tests-only mode: start from 02 (01 is the test infrastructure bootstrap from Step 1t).
1. Read all test specs from `DOCUMENT_DIR/tests/` (`blackbox-tests.md`, `performance-tests.md`, `resilience-tests.md`, `security-tests.md`, `resource-limit-tests.md`)
2. Group related test scenarios into atomic tasks (e.g., one task per test category or per component under test)
3. Each task should reference the specific test scenarios it implements and the environment/test-data specs
4. Dependencies:
- In default mode: blackbox test tasks depend on the component implementation tasks they exercise
- In tests-only mode: blackbox test tasks depend on the test infrastructure bootstrap task (Step 1t)
5. Write each task spec using `templates/task.md`
6. Estimate complexity per task (1, 2, 3, 5, 8 points); no task should exceed 8 points — split if it does
7. Note task dependencies (referencing tracker IDs of already-created dependency tasks)
8. **Immediately after writing each task file**: create a work item ticket under the "Blackbox Tests" epic, write the work item ticket ID and Epic ID back into the task header, then rename the file from `todo/[##]_[short_name].md` to `todo/[TRACKER-ID]_[short_name].md`.
**Self-verification**:
- [ ] Every scenario from `tests/blackbox-tests.md` is covered by a task
- [ ] Every scenario from `tests/performance-tests.md`, `tests/resilience-tests.md`, `tests/security-tests.md`, and `tests/resource-limit-tests.md` is covered by a task
- [ ] No task exceeds 8 complexity points
- [ ] Dependencies correctly reference the dependency tasks (component tasks in default mode, test infrastructure in tests-only mode)
- [ ] Every task has a work item ticket linked to the "Blackbox Tests" epic
**Save action**: Write each `todo/[##]_[short_name].md` (temporary numeric name), create work item ticket inline, then rename to `todo/[TRACKER-ID]_[short_name].md`.
Read and follow `steps/03_blackbox-test-decomposition.md`.
---
### Step 4: Cross-Task Verification (default and tests-only modes)
### Step 4: Cross-Task Verification (implementation and tests-only modes)
**Role**: Professional software architect and analyst
**Goal**: Verify task consistency and produce `_dependencies_table.md`
**Constraints**: Review step — fix gaps found, do not add new tasks
1. Verify task dependencies across all tasks are consistent
2. Check no gaps:
- In default mode: every interface in architecture.md has tasks covering it
- In tests-only mode: every test scenario in `traceability-matrix.md` is covered by a task
3. Check no overlaps: tasks don't duplicate work
4. Check no circular dependencies in the task graph
5. Produce `_dependencies_table.md` using `templates/dependencies-table.md`
**Self-verification**:
Default mode:
- [ ] Every architecture interface is covered by at least one task
- [ ] No circular dependencies in the task graph
- [ ] Cross-component dependencies are explicitly noted in affected task specs
- [ ] `_dependencies_table.md` contains every task with correct dependencies
Tests-only mode:
- [ ] Every test scenario from traceability-matrix.md "Covered" entries has a corresponding task
- [ ] No circular dependencies in the task graph
- [ ] Test task dependencies reference the test infrastructure bootstrap
- [ ] `_dependencies_table.md` contains every task with correct dependencies
**Save action**: Write `_dependencies_table.md`
**BLOCKING**: Present dependency summary to user. Do NOT proceed until user confirms.
---
Read and follow `steps/04_cross-verification.md`.
## Common Mistakes
- **Coding during decomposition**: this workflow produces specs, never code
- **Over-splitting**: don't create many tasks if the component is simple — 1 task is fine
- **Tasks exceeding 8 points**: split them; no task should be too complex for a single implementer
- **Tasks exceeding 5 points**: split them; no task should be too complex for a single implementer
- **Cross-component tasks**: each task belongs to exactly one component
- **Skipping BLOCKING gates**: never proceed past a BLOCKING marker without user confirmation
- **Creating git branches**: branch creation is an implementation concern, not a decomposition one
@@ -356,7 +224,7 @@ Tests-only mode:
| Situation | Action |
|-----------|--------|
| Ambiguous component boundaries | ASK user |
| Task complexity exceeds 8 points after splitting | ASK user |
| Task complexity exceeds 5 points after splitting | ASK user |
| Missing component specs in DOCUMENT_DIR | ASK user |
| Cross-component dependency conflict | ASK user |
| Tracker epic not found for a component | ASK user for Epic ID |
@@ -368,25 +236,26 @@ Tests-only mode:
┌────────────────────────────────────────────────────────────────┐
│ Task Decomposition (Multi-Mode) │
├────────────────────────────────────────────────────────────────┤
│ CONTEXT: Resolve mode (default / single component / tests-only)│
│ │
DEFAULT MODE:
│ 1. Bootstrap Structure [TRACKER-ID]_initial_structure.md │
│ [BLOCKING: user confirms structure] │
2. Component Tasks → [TRACKER-ID]_[short_name].md each
3. Blackbox Tests → [TRACKER-ID]_[short_name].md each
4. Cross-Verification → _dependencies_table.md
[BLOCKING: user confirms dependencies]
│ CONTEXT: Invoke the selected entrypoint (implementation / single / tests-only)
IMPLEMENTATION TASK DECOMPOSITION:
│ 1. Bootstrap Structure → steps/01_bootstrap-structure.md │
[BLOCKING: user confirms structure] │
1.5 Module Layout → steps/01-5_module-layout.md
[BLOCKING: user confirms layout]
2. Component Tasks → steps/02_task-decomposition.md
4. Cross-Verification → steps/04_cross-verification.md
[BLOCKING: user confirms dependencies]
│ │
│ TESTS-ONLY MODE: │
│ 1t. Test Infrastructure [TRACKER-ID]_test_infrastructure.md │
│ [BLOCKING: user confirms test scaffold] │
│ 3. Blackbox Tests [TRACKER-ID]_[short_name].md each
│ 4. Cross-Verification _dependencies_table.md
│ [BLOCKING: user confirms dependencies] │
│ │
│ 1t. Test Infrastructure → steps/01t_test-infrastructure.md
[BLOCKING: user confirms test scaffold] │
│ 3. Blackbox Tests → steps/03_blackbox-test-decomposition.md
│ 4. Cross-Verification → steps/04_cross-verification.md
[BLOCKING: user confirms dependencies] │
│ SINGLE COMPONENT MODE: │
│ 2. Component Tasks [TRACKER-ID]_[short_name].md each
│ 2. Component Tasks → steps/02_task-decomposition.md
├────────────────────────────────────────────────────────────────┤
│ Principles: Atomic tasks · Behavioral specs · Flat structure │
│ Tracker inline · Rename to tracker ID · Save now · Ask don't assume│
@@ -0,0 +1,36 @@
# Step 1.5: Module Layout (default mode only)
**Role**: Professional software architect
**Goal**: Produce `_docs/02_document/module-layout.md` — the authoritative file-ownership map used by the implement skill. Separates **behavioral** task specs (no file paths) from **structural** file mapping (no behavior).
**Constraints**: Follow the target language's standard project-layout conventions. Do not invent non-standard directory structures.
## Steps
1. Detect the target language from `DOCUMENT_DIR/architecture.md` and the bootstrap structure plan produced in Step 1.
2. Apply the language's conventional layout (see table in `templates/module-layout.md`):
- Python → `src/<pkg>/<component>/`
- C# → `src/<Component>/`
- Rust → `crates/<component>/`
- TypeScript / React → `src/<component>/` with `index.ts` barrel
- Go → `internal/<component>/` or `pkg/<component>/`
3. Each component owns ONE top-level directory. Shared code goes under `<root>/shared/` (or language equivalent).
4. Public API surface = files in the layout's `public:` list for each component; everything else is internal and MUST NOT be imported from other components.
5. Cross-cutting concerns (logging, error handling, config, telemetry, auth middleware, feature flags, i18n) each get ONE entry under Shared / Cross-Cutting; per-component tasks consume them (see Step 2 cross-cutting rule).
6. Write `_docs/02_document/module-layout.md` using `templates/module-layout.md` format.
## Self-verification
- [ ] Every component in `DOCUMENT_DIR/components/` has a Per-Component Mapping entry
- [ ] Every shared / cross-cutting concern has a Shared section entry
- [ ] Layering table covers every component (shared at the bottom)
- [ ] No component's `Imports from` list points at a higher layer
- [ ] Paths follow the detected language's convention
- [ ] No two components own overlapping paths
## Save action
Write `_docs/02_document/module-layout.md`.
## Blocking
**BLOCKING**: Present layout summary to user. Do NOT proceed to Step 2 until user confirms. The implement skill depends on this file; inconsistencies here cause file-ownership conflicts at batch time.
@@ -0,0 +1,57 @@
# Step 1: Bootstrap Structure Plan (default mode only)
**Role**: Professional software architect
**Goal**: Produce `01_initial_structure.md` — the first task describing the project skeleton.
**Constraints**: This is a plan document, not code. The `/implement` skill executes it.
## Steps
1. Read `architecture.md`, all component specs, `system-flows.md`, `data_model.md`, and `deployment/` from DOCUMENT_DIR
2. Read problem, solution, and restrictions from `_docs/00_problem/` and `_docs/01_solution/`
3. Research best implementation patterns for the identified tech stack
4. Document the structure plan using `templates/initial-structure-task.md`
The bootstrap structure plan must include:
- Project folder layout with all component directories
- Shared models, interfaces, and DTOs
- Dockerfile per component (multi-stage, non-root, health checks, pinned base images)
- `docker-compose.yml` for local development (all components + database + dependencies)
- `docker-compose.test.yml` for blackbox test environment (blackbox test runner)
- `.dockerignore`
- CI/CD pipeline file (`.github/workflows/ci.yml` or `azure-pipelines.yml`) with stages from `deployment/ci_cd_pipeline.md`
- Database migration setup and initial seed data scripts
- Observability configuration: structured logging setup, health check endpoints (`/health/live`, `/health/ready`), metrics endpoint (`/metrics`)
- Environment variable documentation (`.env.example`)
- Test structure with unit and blackbox test locations
## Self-verification
- [ ] All components have corresponding folders in the layout
- [ ] All inter-component interfaces have DTOs defined
- [ ] Dockerfile defined for each component
- [ ] `docker-compose.yml` covers all components and dependencies
- [ ] `docker-compose.test.yml` enables blackbox testing
- [ ] CI/CD pipeline file defined with lint, test, security, build, deploy stages
- [ ] Database migration setup included
- [ ] Health check endpoints specified for each service
- [ ] Structured logging configuration included
- [ ] `.env.example` with all required environment variables
- [ ] Environment strategy covers dev, staging, production
- [ ] Test structure includes unit and blackbox test locations
## Save action
Write `todo/01_initial_structure.md` (temporary numeric name).
## Tracker action
Create a work item ticket for this task under the "Bootstrap & Initial Structure" epic. Write the work item ticket ID and Epic ID back into the task header.
## Rename action
Rename the file from `todo/01_initial_structure.md` to `todo/[TRACKER-ID]_initial_structure.md` (e.g., `todo/AZ-42_initial_structure.md`). Update the **Task** field inside the file to match the new filename.
## Blocking
**BLOCKING**: Present structure plan summary to user. Do NOT proceed until user confirms.
@@ -0,0 +1,45 @@
# Step 1t: Test Infrastructure Bootstrap (tests-only mode only)
**Role**: Professional Quality Assurance Engineer
**Goal**: Produce `01_test_infrastructure.md` — the first task describing the test project scaffold.
**Constraints**: This is a plan document, not code. The `/implement` skill executes it.
## Steps
1. Read `TESTS_DIR/environment.md` and `TESTS_DIR/test-data.md`
2. Read `problem.md`, `restrictions.md`, `acceptance_criteria.md` for domain context
3. Document the test infrastructure plan using `templates/test-infrastructure-task.md`
The test infrastructure bootstrap must include:
- Test project folder layout (`e2e/` directory structure)
- Mock/stub service definitions for each external dependency
- `docker-compose.test.yml` structure from `environment.md`
- Test runner configuration (framework, plugins, fixtures)
- Test data fixture setup from `test-data.md` seed data sets
- Test reporting configuration (format, output path)
- Data isolation strategy
## Self-verification
- [ ] Every external dependency from `environment.md` has a mock service defined
- [ ] Docker Compose structure covers all services from `environment.md`
- [ ] Test data fixtures cover all seed data sets from `test-data.md`
- [ ] Test runner configuration matches the consumer app tech stack from `environment.md`
- [ ] Data isolation strategy is defined
## Save action
Write `todo/01_test_infrastructure.md` (temporary numeric name).
## Tracker action
Create a work item ticket for this task under the "Blackbox Tests" epic. Write the work item ticket ID and Epic ID back into the task header.
## Rename action
Rename the file from `todo/01_test_infrastructure.md` to `todo/[TRACKER-ID]_test_infrastructure.md`. Update the **Task** field inside the file to match the new filename.
## Blocking
**BLOCKING**: Present test infrastructure plan summary to user. Do NOT proceed until user confirms.
@@ -0,0 +1,75 @@
# Step 2: Task Decomposition (default and single component modes)
**Role**: Professional software architect
**Goal**: Decompose each component into atomic, implementable task specs — numbered sequentially starting from 02.
**Constraints**: Behavioral specs only — describe what, not how. No implementation code.
## Numbering
Tasks are numbered sequentially across all components in dependency order. Start from 02 (01 is `initial_structure`). In single component mode, start from the next available number in TASKS_DIR.
## Component ordering
Process components in dependency order — foundational components first (shared models, database), then components that depend on them.
## Consult LESSONS.md once at the start of Step 2
If `_docs/LESSONS.md` exists, read it and note `estimation`, `architecture`, or `dependencies` lessons that may bias task sizing in this pass (e.g., "auth-related changes historically take 2x estimate" → bump any auth task up one complexity tier). Apply the bias when filling the Complexity field in step 7 below. Record which lessons informed estimation in a comment in `_dependencies_table.md` (Step 4).
## Steps
For each component (or the single provided component):
1. Read the component's `description.md` and `tests.md` (if available)
2. Decompose into atomic tasks; create only 1 task if the component is simple or atomic
3. Split into multiple tasks only when it is necessary and would be easier to implement
4. Do not create tasks for other components — only tasks for the current component
5. Each task should be atomic, containing 1 API or a list of semantically connected APIs
6. Write each task spec using `templates/task.md`
7. Estimate complexity per task (1, 2, 3, 5 points); no task should exceed 5 points — split if it does
8. Note task dependencies (referencing tracker IDs of already-created dependency tasks, e.g., `AZ-42_initial_structure`)
9. **Cross-cutting rule**: if a concern spans ≥2 components (logging, config loading, auth/authZ, error envelope, telemetry, feature flags, i18n), create ONE shared task under the cross-cutting epic. Per-component tasks declare it as a dependency and consume it; they MUST NOT re-implement it locally. Duplicate local implementations are an `Architecture` finding (High) in code-review Phase 7 and a `Maintainability` finding in Phase 6.
10. **Shared-models / shared-API rule**: classify the task as shared if ANY of the following is true:
- The component is listed under `shared/*` in `module-layout.md`.
- The task's Scope.Included mentions "public interface", "DTO", "schema", "event", "contract", "API endpoint", or "shared model".
- The task is parented to a cross-cutting epic.
- The task is depended on by ≥2 other tasks across different components.
For every shared task:
- Produce a contract file at `_docs/02_document/contracts/<component>/<name>.md` using `templates/api-contract.md`. Fill Shape, Invariants, Non-Goals, Versioning Rules, and at least 3 Test Cases.
- Add a mandatory `## Contract` section to the task spec pointing at the contract file.
- For every consuming task, add the contract path to its `## Dependencies` section as a document dependency (separate from task dependencies).
Consumers read the contract file, not the producer's task spec. This prevents interface drift when the producer's implementation detail leaks into consumers.
11. **Immediately after writing each task file**: create a work item ticket, link it to the component's epic, write the work item ticket ID and Epic ID back into the task header, then rename the file from `todo/[##]_[short_name].md` to `todo/[TRACKER-ID]_[short_name].md`.
## Runtime Completeness Decomposition Gate
Before Step 2 is considered complete, scan `architecture.md`, `system-flows.md`, component descriptions, and the solution for named internal runtime capabilities and dependencies. Examples include BASALT/OpenVINS/Kimera, FAISS, DINOv2, ONNX/TensorRT, ALIKED/DISK, LightGlue, RANSAC, PostGIS, MAVLink emission, FDR rollover, and any "A-Z" user-visible pipeline.
For every named internal capability:
1. Ensure at least one implementation task explicitly owns the production integration or production algorithm.
2. Do not treat "define protocol", "create adapter boundary", "add deterministic fallback", "create scaffold", or "prepare native bridge" as implementation of the capability unless the architecture explicitly says the real capability is out of scope.
3. If a capability needs external hardware/data to verify, still create the production implementation task. Verification may be hardware-gated later; implementation must not be omitted.
4. Add a `## Runtime Completeness` section to any affected task with:
- named capability/dependency,
- production code that must exist,
- allowed external stubs, if any,
- unacceptable substitutes such as fake/deterministic/internal stubs.
## Self-verification (per component)
- [ ] Every task is atomic (single concern)
- [ ] No task exceeds 5 complexity points
- [ ] Task dependencies reference correct tracker IDs
- [ ] Tasks cover all interfaces defined in the component spec
- [ ] No tasks duplicate work from other components
- [ ] Every task has a work item ticket linked to the correct epic
- [ ] Every shared-models / shared-API task has a contract file at `_docs/02_document/contracts/<component>/<name>.md` and a `## Contract` section linking to it
- [ ] Every cross-cutting concern appears exactly once as a shared task, not N per-component copies
- [ ] Every named internal runtime capability has a production implementation task, not only an interface/scaffold/fallback task
## Save action
Write each `todo/[##]_[short_name].md` (temporary numeric name), create work item ticket inline, then rename to `todo/[TRACKER-ID]_[short_name].md`. Update the **Task** field inside the file to match the new filename. Update **Dependencies** references in the file to use tracker IDs of the dependency tasks.
@@ -0,0 +1,39 @@
# Step 3: Blackbox Test Task Decomposition (tests-only mode only)
**Role**: Professional Quality Assurance Engineer
**Goal**: Decompose blackbox test specs into atomic, implementable task specs.
**Constraints**: Behavioral specs only — describe what, not how. No test code.
## Numbering
- In tests-only mode: start from 02 (01 is the test infrastructure bootstrap from Step 1t).
## Steps
1. Read all test specs from `DOCUMENT_DIR/tests/` (`blackbox-tests.md`, `performance-tests.md`, `resilience-tests.md`, `security-tests.md`, `resource-limit-tests.md`)
2. Group related test scenarios into atomic tasks (e.g., one task per test category or per component under test)
3. Each task should reference the specific test scenarios it implements and the environment/test-data specs
4. Add a **System Under Test Boundary** section to every e2e/blackbox test task:
- The test must drive the product through public runtime boundaries and compare actual outputs to `_docs/00_problem/input_data/expected_results/results_report.md` and any referenced machine-readable expected-result files.
- Stubs are allowed only for external systems outside the product boundary: flight controller/SITL, QGC observer, satellite-provider/Suite service, physical Jetson hardware, physical camera, licensed public datasets, and network services.
- Stubs, fakes, deterministic fallbacks, monkeypatches, or direct imports are not allowed for internal product modules that the scenario is meant to validate, such as VIO, safety/anchor wrapper, satellite retrieval, anchor verification, tile manager, MAVLink output adapter, or FDR.
- If an internal module is not implemented, the test must fail/block as missing product implementation; it must not pass by replacing that module with a test stub.
5. Dependencies:
- In tests-only mode: blackbox test tasks depend on the test infrastructure bootstrap task (Step 1t)
6. Write each task spec using `templates/task.md`
7. Estimate complexity per task (1, 2, 3, 5 points); no task should exceed 5 points — split if it does
8. Note task dependencies (referencing tracker IDs of already-created dependency tasks)
9. **Immediately after writing each task file**: create a work item ticket under the "Blackbox Tests" epic, write the work item ticket ID and Epic ID back into the task header, then rename the file from `todo/[##]_[short_name].md` to `todo/[TRACKER-ID]_[short_name].md`.
## Self-verification
- [ ] Every scenario from `tests/blackbox-tests.md` is covered by a task
- [ ] Every scenario from `tests/performance-tests.md`, `tests/resilience-tests.md`, `tests/security-tests.md`, and `tests/resource-limit-tests.md` is covered by a task
- [ ] No task exceeds 5 complexity points
- [ ] Dependencies correctly reference the test infrastructure task
- [ ] Every task has a work item ticket linked to the "Blackbox Tests" epic
- [ ] Every e2e/blackbox task forbids internal product stubs/fakes and requires comparison against expected-results artifacts
## Save action
Write each `todo/[##]_[short_name].md` (temporary numeric name), create work item ticket inline, then rename to `todo/[TRACKER-ID]_[short_name].md`.
@@ -0,0 +1,43 @@
# Step 4: Cross-Task Verification (implementation and tests-only modes)
**Role**: Professional software architect and analyst
**Goal**: Verify task consistency and produce `_dependencies_table.md`.
**Constraints**: Review step — fix gaps found, do not add new tasks.
## Steps
1. Verify task dependencies across all tasks are consistent
2. Check no gaps:
- In implementation mode: every product interface in `architecture.md` has implementation task coverage
- In tests-only mode: every test scenario in `traceability-matrix.md` is covered by a task
- In implementation mode: every named internal runtime capability/dependency from architecture, solution, system flows, and component descriptions has a production implementation task, not only an interface/scaffold/fallback task
- In tests-only mode: every e2e/blackbox task has a System Under Test Boundary section that forbids stubbing internal product modules and requires comparison to expected-results artifacts
3. Check no overlaps: tasks don't duplicate work
4. Check no circular dependencies in the task graph
5. Produce `_dependencies_table.md` using `templates/dependencies-table.md`
## Self-verification
### Implementation mode
- [ ] Every product interface in `architecture.md` is covered by at least one implementation task
- [ ] Every named internal runtime capability has a production implementation task
- [ ] No circular dependencies in the task graph
- [ ] Cross-component dependencies are explicitly noted in affected task specs
- [ ] `_dependencies_table.md` contains every task with correct dependencies
### Tests-only mode
- [ ] Every test scenario from `traceability-matrix.md` "Covered" entries has a corresponding task
- [ ] Every e2e/blackbox task validates actual product behavior and allows stubs only for external systems
- [ ] No circular dependencies in the task graph
- [ ] Test task dependencies reference the test infrastructure bootstrap
- [ ] `_dependencies_table.md` contains every task with correct dependencies
## Save action
Write `_dependencies_table.md`.
## Blocking
**BLOCKING**: Present dependency summary to user. Do NOT proceed until user confirms.
@@ -0,0 +1,133 @@
# API Contract Template
A contract is the **frozen, reviewed interface** between two or more components. When task A produces a shared model, DTO, schema, event payload, or public API, and task B consumes it, they must not reverse-engineer each other's implementation — they must read the contract.
Save the filled contract at `_docs/02_document/contracts/<component>/<name>.md`. Reference it from the producing task's `## Contract` section and from every consuming task's `## Dependencies` section.
---
```markdown
# Contract: [contract-name]
**Component**: [component-name]
**Producer task**: [TRACKER-ID] — [task filename]
**Consumer tasks**: [list of TRACKER-IDs or "TBD at decompose time"]
**Version**: 1.0.0
**Status**: [draft | frozen | deprecated]
**Last Updated**: [YYYY-MM-DD]
## Purpose
Short statement of what this contract represents and why it is shared (13 sentences).
## Shape
Choose ONE of the following shape forms per the contract type:
### For data models (DTO / schema / event)
```[language]
// language-native type definitions — e.g., Python dataclass, C# record, TypeScript interface, Rust struct, JSON Schema
```
For each field:
| Field | Type | Required | Description | Constraints |
|-------|------|----------|-------------|-------------|
| `id` | `string` (UUID) | yes | Unique identifier | RFC 4122 v4 |
| `created_at` | `datetime` (ISO 8601 UTC) | yes | Creation timestamp | |
| `...` | ... | ... | ... | ... |
### For function / method APIs
| Name | Signature | Throws / Errors | Blocking? |
|------|-----------|-----------------|-----------|
| `do_x` | `(input: InputDto) -> Result<OutputDto, XError>` | `XError::NotFound`, `XError::Invalid` | sync |
| ... | ... | ... | ... |
### For HTTP / RPC endpoints
| Method | Path | Request body | Response | Status codes |
|--------|------|--------------|----------|--------------|
| `POST` | `/api/v1/resource` | `CreateResource` | `Resource` | 201, 400, 409 |
| ... | ... | ... | ... | ... |
## Invariants
Properties that MUST hold for every valid instance or every allowed interaction. These survive refactors.
- Invariant 1: [statement]
- Invariant 2: [statement]
## Non-Goals
Things this contract intentionally does NOT cover. Helps prevent scope creep.
- Not covered: [statement]
## Versioning Rules
- **Breaking changes** (field renamed/removed, type changed, required→optional flipped) require a new major version and a deprecation path for consumers.
- **Non-breaking additions** (new optional field, new error variant consumers already tolerate) require a minor version bump.
## Test Cases
Representative cases that both producer and consumer tests must cover. Keep short — this is the contract test surface, not an exhaustive suite.
| Case | Input | Expected | Notes |
|------|-------|----------|-------|
| valid-minimal | minimal valid instance | accepted | |
| invalid-missing-required | missing `id` | rejected with specific error | |
| edge-case-x | ... | ... | |
## Change Log
| Version | Date | Change | Author |
|---------|------|--------|--------|
| 1.0.0 | YYYY-MM-DD | Initial contract | [agent/user] |
```
---
## Decompose-skill rules for emitting contracts
A task is a **shared-models / shared-API task** when ANY of the following is true:
- The component spec lists it as a shared component (under `shared/*` in `module-layout.md`).
- The task's **Scope.Included** mentions any of: "public interface", "DTO", "schema", "event", "contract", "API endpoint", "shared model".
- The task is parented to a cross-cutting epic (`epic_type: cross-cutting`).
- The task is depended on by ≥2 other tasks across different components.
For every shared-models / shared-API task:
1. Create a contract file at `_docs/02_document/contracts/<component>/<name>.md` using this template.
2. Fill in Shape, Invariants, Non-Goals, Versioning Rules, and at least 3 Test Cases.
3. Add a mandatory `## Contract` section to the task spec that links to the contract file:
```markdown
## Contract
This task produces/implements the contract at `_docs/02_document/contracts/<component>/<name>.md`.
Consumers MUST read that file — not this task spec — to discover the interface.
```
4. For every consuming task, add the contract path to its `## Dependencies` section as a document dependency (not a task dependency):
```markdown
### Document Dependencies
- `_docs/02_document/contracts/<component>/<name>.md` — API contract produced by [TRACKER-ID].
```
5. If the contract changes after it was frozen, the producer task must bump the `Version` and note the change in `Change Log`. Consumers referenced in the contract header must be notified (surface to user via Choose format).
## Code-review-skill rules for verifying contracts
Phase 2 (Spec Compliance) adds a check:
- For every task with a `## Contract` section:
- Verify the referenced contract file exists at the stated path.
- Verify the implementation's public signatures (types, method shapes, endpoint paths) match the contract's Shape section.
- If they diverge, emit a `Spec-Gap` finding with High severity.
- For every consuming task's Document Dependencies that reference a contract:
- Verify the consumer's imports / calls match the contract's Shape.
- If they diverge, emit a `Spec-Gap` finding with High severity and a hint that either the contract or the consumer is drifting.
@@ -28,4 +28,4 @@ Use this template after cross-task verification. Save as `TASKS_DIR/_dependencie
- Dependencies column lists tracker IDs (e.g., "AZ-43, AZ-44") or "None"
- No circular dependencies allowed
- Tasks should be listed in recommended execution order
- The `/implement` skill reads this table to compute parallel batches
- The `/implement` skill reads this table to compute dependency-aware batches; task execution remains sequential
@@ -0,0 +1,107 @@
# Module Layout Template
The module layout is the **authoritative file-ownership map** used by the `/implement` skill to assign OWNED / READ-ONLY / FORBIDDEN files to each task. It is derived from `_docs/02_document/architecture.md` and the component specs at `_docs/02_document/components/`, and it follows the target language's standard project-layout conventions.
Save as `_docs/02_document/module-layout.md`. This file is produced by the decompose skill (Step 1.5 module layout) and consumed by the implement skill (Step 4 file ownership). Task specs remain purely behavioral — they do NOT carry file paths. The layout is the single place where component → filesystem mapping lives.
---
```markdown
# Module Layout
**Language**: [python | csharp | rust | typescript | go | mixed]
**Layout Convention**: [src-layout | crates-workspace | packages-workspace | custom]
**Root**: [src/ | crates/ | packages/ | ./]
**Last Updated**: [YYYY-MM-DD]
## Layout Rules
1. Each component owns ONE top-level directory under the root.
2. Shared code lives under `<root>/shared/` (or language equivalent: `src/shared/`, `crates/shared/`, `packages/shared/`).
3. Cross-cutting concerns (logging, config, error handling, telemetry) live under `<root>/shared/<concern>/`.
4. Public API surface per component = files listed in `public:` below. Everything else is internal — other components MUST NOT import it directly.
5. Tests live outside the component tree in a separate `tests/` or `<component>/tests/` directory per the language's test convention.
## Per-Component Mapping
### Component: [component-name]
- **Epic**: [TRACKER-ID]
- **Directory**: `src/<path>/`
- **Public API**: files in this list are importable by other components
- `src/<path>/public_api.py` (or `mod.rs`, `index.ts`, `PublicApi.cs`, etc.)
- `src/<path>/types.py`
- **Internal (do NOT import from other components)**:
- `src/<path>/internal/*`
- `src/<path>/_helpers.py`
- **Owns (exclusive write during implementation)**: `src/<path>/**`
- **Imports from**: [list of other components whose Public API this component may use]
- **Consumed by**: [list of components that depend on this component's Public API]
### Component: [next-component]
...
## Shared / Cross-Cutting
### shared/models
- **Directory**: `src/shared/models/`
- **Purpose**: DTOs, value types, schemas shared across components
- **Owned by**: whoever implements task `[TRACKER-ID]_shared_models`
- **Consumed by**: all components
### shared/logging
- **Directory**: `src/shared/logging/`
- **Purpose**: structured logging setup
- **Owned by**: cross-cutting task `[TRACKER-ID]_logging`
- **Consumed by**: all components
### shared/[other concern]
...
## Allowed Dependencies (layering)
Read top-to-bottom; an upper layer may import from a lower layer but NEVER the reverse.
| Layer | Components | May import from |
|-------|------------|-----------------|
| 4. API / Entry | [list] | 1, 2, 3 |
| 3. Application | [list] | 1, 2 |
| 2. Domain | [list] | 1 |
| 1. Shared / Foundation | shared/* | (none) |
Violations of this table are **Architecture** findings in code-review Phase 7 and are High severity.
## Layout Conventions (reference)
| Language | Root | Per-component path | Public API file | Test path |
|----------|------|-------------------|-----------------|-----------|
| Python | `src/<pkg>/` | `src/<pkg>/<component>/` | `src/<pkg>/<component>/__init__.py` (re-exports) | `tests/<component>/` |
| C# (.NET) | `src/` | `src/<Component>/` | `src/<Component>/<Component>.cs` (namespace root) | `tests/<Component>.Tests/` |
| Rust | `crates/` | `crates/<component>/` | `crates/<component>/src/lib.rs` | `crates/<component>/tests/` |
| TypeScript / React | `packages/` or `src/` | `src/<component>/` | `src/<component>/index.ts` (barrel) | `src/<component>/__tests__/` or `tests/<component>/` |
| Go | `./` | `internal/<component>/` or `pkg/<component>/` | `internal/<component>/doc.go` + exported symbols | `internal/<component>/*_test.go` |
```
---
## Self-verification for the decompose skill
When writing `_docs/02_document/module-layout.md`, verify:
- [ ] Every component in `_docs/02_document/components/` has a Per-Component Mapping entry.
- [ ] Every shared / cross-cutting epic has an entry in the Shared section.
- [ ] Layering table rows cover every component.
- [ ] No component's `Imports from` list contains a component at a higher layer.
- [ ] Paths follow the detected language's convention.
- [ ] No two components own overlapping paths.
## How the implement skill consumes this
The implement skill's Step 4 (File Ownership) reads this file and, for each task in the batch:
1. Resolve the task's Component field to a Per-Component Mapping entry.
2. Set OWNED = the component's `Owns` glob.
3. Set READ-ONLY = the Public API files of every component listed in `Imports from`, plus `shared/*` Public API files.
4. Set FORBIDDEN = every other component's Owns glob.
Execution inside a batch is already sequential (one task at a time). This mapping is still required because it enforces scope discipline per task — preventing a task from drifting into files that belong to another component.
+13 -3
View File
@@ -11,7 +11,7 @@ Save as `TASKS_DIR/[##]_[short_name].md` initially, then rename to `TASKS_DIR/[T
**Task**: [TRACKER-ID]_[short_name]
**Name**: [short human name]
**Description**: [one-line description of what this task delivers]
**Complexity**: [1|2|3|5|8] points
**Complexity**: [1|2|3|5] points
**Dependencies**: [AZ-43_shared_models, AZ-44_db_migrations] or "None"
**Component**: [component name for context]
**Tracker**: [TASK-ID]
@@ -81,6 +81,17 @@ Then [expected result]
**Risk 1: [Title]**
- *Risk*: [Description]
- *Mitigation*: [Approach]
## Contract
<!--
OMIT this section for behavioral-only tasks.
INCLUDE this section ONLY for shared-models / shared-API / contract tasks.
See decompose/SKILL.md Step 2 shared-models rule and decompose/templates/api-contract.md.
-->
This task produces/implements the contract at `_docs/02_document/contracts/<component>/<name>.md`.
Consumers MUST read that file — not this task spec — to discover the interface.
```
---
@@ -91,8 +102,7 @@ Then [expected result]
- 2 points: Non-trivial, low complexity, minimal coordination
- 3 points: Multi-step, moderate complexity, potential alignment needed
- 5 points: Difficult, interconnected logic, medium-high risk
- 8 points: High difficulty, high ambiguity or coordination, multiple components
- 13 points: Too complex — split into smaller tasks
- 8+ points: Too complex — split into smaller tasks
## Output Guidelines
+21 -303
View File
@@ -115,332 +115,43 @@ At the start of execution, create a TodoWrite with all steps (1 through 7). Upda
### Step 1: Deployment Status & Environment Setup
**Role**: DevOps / Platform engineer
**Goal**: Assess current deployment readiness, identify all required environment variables, and create `.env` files
**Constraints**: Must complete before any other step
1. Read architecture.md, all component specs, and restrictions.md
2. Assess deployment readiness:
- List all components and their current state (planned / implemented / tested)
- Identify external dependencies (databases, APIs, message queues, cloud services)
- Identify infrastructure prerequisites (container registry, cloud accounts, DNS, SSL certificates)
- Check if any deployment blockers exist
3. Identify all required environment variables by scanning:
- Component specs for configuration needs
- Database connection requirements
- External API endpoints and credentials
- Feature flags and runtime configuration
- Container registry credentials
- Cloud provider credentials
- Monitoring/logging service endpoints
4. Generate `.env.example` in project root with all variables and placeholder values (committed to VCS)
5. Generate `.env` in project root with development defaults filled in where safe (git-ignored)
6. Ensure `.gitignore` includes `.env` (but NOT `.env.example`)
7. Produce a deployment status report summarizing readiness, blockers, and required setup
**Self-verification**:
- [ ] All components assessed for deployment readiness
- [ ] External dependencies catalogued
- [ ] Infrastructure prerequisites identified
- [ ] All required environment variables discovered
- [ ] `.env.example` created with placeholder values
- [ ] `.env` created with safe development defaults
- [ ] `.gitignore` updated to exclude `.env`
- [ ] Status report written to `reports/deploy_status_report.md`
**Save action**: Write `reports/deploy_status_report.md` using `templates/deploy_status_report.md`, create `.env` and `.env.example` in project root
**BLOCKING**: Present status report and environment variables to user. Do NOT proceed until confirmed.
Read and follow `steps/01_status-env.md`.
---
### Step 2: Containerization
**Role**: DevOps / Platform engineer
**Goal**: Define Docker configuration for every component, local development, and blackbox test environments
**Constraints**: Plan only — no Dockerfile creation. Describe what each Dockerfile should contain.
1. Read architecture.md and all component specs
2. Read restrictions.md for infrastructure constraints
3. Research best Docker practices for the project's tech stack (multi-stage builds, base image selection, layer optimization)
4. For each component, define:
- Base image (pinned version, prefer alpine/distroless for production)
- Build stages (dependency install, build, production)
- Non-root user configuration
- Health check endpoint and command
- Exposed ports
- `.dockerignore` contents
5. Define `docker-compose.yml` for local development:
- All application components
- Database (Postgres) with named volume
- Any message queues, caches, or external service mocks
- Shared network
- Environment variable files (`.env`)
6. Define `docker-compose.test.yml` for blackbox tests:
- Application components under test
- Test runner container (black-box, no internal imports)
- Isolated database with seed data
- All tests runnable via `docker compose -f docker-compose.test.yml up --abort-on-container-exit`
7. Define image tagging strategy: `<registry>/<project>/<component>:<git-sha>` for CI, `latest` for local dev only
**Self-verification**:
- [ ] Every component has a Dockerfile specification
- [ ] Multi-stage builds specified for all production images
- [ ] Non-root user for all containers
- [ ] Health checks defined for every service
- [ ] docker-compose.yml covers all components + dependencies
- [ ] docker-compose.test.yml enables black-box testing
- [ ] `.dockerignore` defined
**Save action**: Write `containerization.md` using `templates/containerization.md`
**BLOCKING**: Present containerization plan to user. Do NOT proceed until confirmed.
Read and follow `steps/02_containerization.md`.
---
### Step 3: CI/CD Pipeline
**Role**: DevOps engineer
**Goal**: Define the CI/CD pipeline with quality gates, security scanning, and multi-environment deployment
**Constraints**: Pipeline definition only — produce YAML specification, not implementation
1. Read architecture.md for tech stack and deployment targets
2. Read restrictions.md for CI/CD constraints (cloud provider, registry, etc.)
3. Research CI/CD best practices for the project's platform (GitHub Actions / Azure Pipelines)
4. Define pipeline stages:
| Stage | Trigger | Steps | Quality Gate |
|-------|---------|-------|-------------|
| **Lint** | Every push | Run linters per language (black, rustfmt, prettier, dotnet format) | Zero errors |
| **Test** | Every push | Unit tests, blackbox tests, coverage report | 75%+ coverage (see `.cursor/rules/cursor-meta.mdc` Quality Thresholds) |
| **Security** | Every push | Dependency audit, SAST scan (Semgrep/SonarQube), image scan (Trivy) | Zero critical/high CVEs |
| **Build** | PR merge to dev | Build Docker images, tag with git SHA | Build succeeds |
| **Push** | After build | Push to container registry | Push succeeds |
| **Deploy Staging** | After push | Deploy to staging environment | Health checks pass |
| **Smoke Tests** | After staging deploy | Run critical path tests against staging | All pass |
| **Deploy Production** | Manual approval | Deploy to production | Health checks pass |
5. Define caching strategy: dependency caches, Docker layer caches, build artifact caches
6. Define parallelization: which stages can run concurrently
7. Define notifications: build failures, deployment status, security alerts
**Self-verification**:
- [ ] All pipeline stages defined with triggers and gates
- [ ] Coverage threshold enforced (75%+)
- [ ] Security scanning included (dependencies + images + SAST)
- [ ] Caching configured for dependencies and Docker layers
- [ ] Multi-environment deployment (staging → production)
- [ ] Rollback procedure referenced
- [ ] Notifications configured
**Save action**: Write `ci_cd_pipeline.md` using `templates/ci_cd_pipeline.md`
Read and follow `steps/03_ci-cd-pipeline.md`.
---
### Step 4: Environment Strategy
**Role**: Platform engineer
**Goal**: Define environment configuration, secrets management, and environment parity
**Constraints**: Strategy document — no secrets or credentials in output
1. Define environments:
| Environment | Purpose | Infrastructure | Data |
|-------------|---------|---------------|------|
| **Development** | Local developer workflow | docker-compose, local volumes | Seed data, mocks for external APIs |
| **Staging** | Pre-production validation | Mirrors production topology | Anonymized production-like data |
| **Production** | Live system | Full infrastructure | Real data |
2. Define environment variable management:
- Reference `.env.example` created in Step 1
- Per-environment variable sources (`.env` for dev, secret manager for staging/prod)
- Validation: fail fast on missing required variables at startup
3. Define secrets management:
- Never commit secrets to version control
- Development: `.env` files (git-ignored)
- Staging/Production: secret manager (AWS Secrets Manager / Azure Key Vault / Vault)
- Rotation policy
4. Define database management per environment:
- Development: Docker Postgres with named volume, seed data
- Staging: managed Postgres, migrations applied via CI/CD
- Production: managed Postgres, migrations require approval
**Self-verification**:
- [ ] All three environments defined with clear purpose
- [ ] Environment variable documentation complete (references `.env.example` from Step 1)
- [ ] No secrets in any output document
- [ ] Secret manager specified for staging/production
- [ ] Database strategy per environment
**Save action**: Write `environment_strategy.md` using `templates/environment_strategy.md`
Read and follow `steps/04_environment-strategy.md`.
---
### Step 5: Observability
**Role**: Site Reliability Engineer (SRE)
**Goal**: Define logging, metrics, tracing, and alerting strategy
**Constraints**: Strategy document — describe what to implement, not how to wire it
1. Read architecture.md and component specs for service boundaries
2. Research observability best practices for the tech stack
**Logging**:
- Structured JSON to stdout/stderr (no file logging in containers)
- Fields: `timestamp` (ISO 8601), `level`, `service`, `correlation_id`, `message`, `context`
- Levels: ERROR (exceptions), WARN (degraded), INFO (business events), DEBUG (diagnostics, dev only)
- No PII in logs
- Retention: dev = console, staging = 7 days, production = 30 days
**Metrics**:
- Expose Prometheus-compatible `/metrics` endpoint per service
- System metrics: CPU, memory, disk, network
- Application metrics: `request_count`, `request_duration` (histogram), `error_count`, `active_connections`
- Business metrics: derived from acceptance criteria
- Collection interval: 15s
**Distributed Tracing**:
- OpenTelemetry SDK integration
- Trace context propagation via HTTP headers and message queue metadata
- Span naming: `<service>.<operation>`
- Sampling: 100% in dev/staging, 10% in production (adjust based on volume)
**Alerting**:
| Severity | Response Time | Condition Examples |
|----------|---------------|-------------------|
| Critical | 5 min | Service down, data loss, health check failed |
| High | 30 min | Error rate > 5%, P95 latency > 2x baseline |
| Medium | 4 hours | Disk > 80%, elevated latency |
| Low | Next business day | Non-critical warnings |
**Dashboards**:
- Operations: service health, request rate, error rate, response time percentiles, resource utilization
- Business: key business metrics from acceptance criteria
**Self-verification**:
- [ ] Structured logging format defined with required fields
- [ ] Metrics endpoint specified per service
- [ ] OpenTelemetry tracing configured
- [ ] Alert severities with response times defined
- [ ] Dashboards cover operations and business metrics
- [ ] PII exclusion from logs addressed
**Save action**: Write `observability.md` using `templates/observability.md`
Read and follow `steps/05_observability.md`.
---
### Step 6: Deployment Procedures
**Role**: DevOps / Platform engineer
**Goal**: Define deployment strategy, rollback procedures, health checks, and deployment checklist
**Constraints**: Procedures document — no implementation
1. Define deployment strategy:
- Preferred pattern: blue-green / rolling / canary (choose based on architecture)
- Zero-downtime requirement for production
- Graceful shutdown: 30-second grace period for in-flight requests
- Database migration ordering: migrate before deploy, backward-compatible only
2. Define health checks:
| Check | Type | Endpoint | Interval | Threshold |
|-------|------|----------|----------|-----------|
| Liveness | HTTP GET | `/health/live` | 10s | 3 failures → restart |
| Readiness | HTTP GET | `/health/ready` | 5s | 3 failures → remove from LB |
| Startup | HTTP GET | `/health/ready` | 5s | 30 attempts max |
3. Define rollback procedures:
- Trigger criteria: health check failures, error rate spike, critical alert
- Rollback steps: redeploy previous image tag, verify health, rollback database if needed
- Communication: notify stakeholders during rollback
- Post-mortem: required after every production rollback
4. Define deployment checklist:
- [ ] All tests pass in CI
- [ ] Security scan clean (zero critical/high CVEs)
- [ ] Database migrations reviewed and tested
- [ ] Environment variables configured
- [ ] Health check endpoints responding
- [ ] Monitoring alerts configured
- [ ] Rollback plan documented and tested
- [ ] Stakeholders notified
**Self-verification**:
- [ ] Deployment strategy chosen and justified
- [ ] Zero-downtime approach specified
- [ ] Health checks defined (liveness, readiness, startup)
- [ ] Rollback trigger criteria and steps documented
- [ ] Deployment checklist complete
**Save action**: Write `deployment_procedures.md` using `templates/deployment_procedures.md`
**BLOCKING**: Present deployment procedures to user. Do NOT proceed until confirmed.
Read and follow `steps/06_procedures.md`.
---
### Step 7: Deployment Scripts
**Role**: DevOps / Platform engineer
**Goal**: Create executable deployment scripts for pulling Docker images and running services on the remote target machine
**Constraints**: Produce real, executable shell scripts. This is the ONLY step that creates implementation artifacts.
1. Read containerization.md and deployment_procedures.md from previous steps
2. Read `.env.example` for required variables
3. Create the following scripts in `SCRIPTS_DIR/`:
**`deploy.sh`** — Main deployment orchestrator:
- Validates that required environment variables are set (sources `.env` if present)
- Calls `pull-images.sh`, then `stop-services.sh`, then `start-services.sh`, then `health-check.sh`
- Exits with non-zero code on any failure
- Supports `--rollback` flag to redeploy previous image tags
**`pull-images.sh`** — Pull Docker images to target machine:
- Reads image list and tags from environment or config
- Authenticates with container registry
- Pulls all required images
- Verifies image integrity (digest check)
**`start-services.sh`** — Start services on target machine:
- Runs `docker compose up -d` or individual `docker run` commands
- Applies environment variables from `.env`
- Configures networks and volumes
- Waits for containers to reach healthy state
**`stop-services.sh`** — Graceful shutdown:
- Stops services with graceful shutdown period
- Saves current image tags for rollback reference
- Cleans up orphaned containers/networks
**`health-check.sh`** — Verify deployment health:
- Checks all health endpoints
- Reports status per service
- Returns non-zero if any service is unhealthy
4. All scripts must:
- Be POSIX-compatible (#!/bin/bash with set -euo pipefail)
- Source `.env` from project root or accept env vars from the environment
- Include usage/help output (`--help` flag)
- Be idempotent where possible
- Handle SSH connection to remote target (configurable via `DEPLOY_HOST` env var)
5. Document all scripts in `deploy_scripts.md`
**Self-verification**:
- [ ] All five scripts created and executable
- [ ] Scripts source environment variables correctly
- [ ] `deploy.sh` orchestrates the full flow
- [ ] `pull-images.sh` handles registry auth and image pull
- [ ] `start-services.sh` starts containers with correct config
- [ ] `stop-services.sh` handles graceful shutdown
- [ ] `health-check.sh` validates all endpoints
- [ ] Rollback supported via `deploy.sh --rollback`
- [ ] Scripts work for remote deployment via SSH (DEPLOY_HOST)
- [ ] `deploy_scripts.md` documents all scripts
**Save action**: Write scripts to `SCRIPTS_DIR/`, write `deploy_scripts.md` using `templates/deploy_scripts.md`
---
Read and follow `steps/07_scripts.md`.
## Escalation Rules
@@ -473,17 +184,24 @@ At the start of execution, create a TodoWrite with all steps (1 through 7). Upda
├────────────────────────────────────────────────────────────────┤
│ PREREQ: architecture.md + component specs exist │
│ │
│ 1. Status & Env → reports/deploy_status_report.md
│ 1. Status & Env → steps/01_status-env.md
│ → reports/deploy_status_report.md │
│ + .env + .env.example │
│ [BLOCKING: user confirms status & env vars] │
│ 2. Containerization → containerization.md
│ 2. Containerization → steps/02_containerization.md │
│ → containerization.md │
│ [BLOCKING: user confirms Docker plan] │
│ 3. CI/CD Pipeline → ci_cd_pipeline.md
4. Environment → environment_strategy.md
5. Observability → observability.md
6. Proceduresdeployment_procedures.md │
│ 3. CI/CD Pipeline → steps/03_ci-cd-pipeline.md │
→ ci_cd_pipeline.md
4. Environment → steps/04_environment-strategy.md
environment_strategy.md │
│ 5. Observability → steps/05_observability.md │
│ → observability.md │
│ 6. Procedures → steps/06_procedures.md │
│ → deployment_procedures.md │
│ [BLOCKING: user confirms deployment plan] │
│ 7. Scripts deploy_scripts.md + scripts/
│ 7. Scripts → steps/07_scripts.md
│ → deploy_scripts.md + scripts/ │
├────────────────────────────────────────────────────────────────┤
│ Principles: Docker-first · IaC · Observability built-in │
│ Environment parity · Save immediately │
@@ -0,0 +1,45 @@
# Step 1: Deployment Status & Environment Setup
**Role**: DevOps / Platform engineer
**Goal**: Assess current deployment readiness, identify all required environment variables, and create `.env` files.
**Constraints**: Must complete before any other step.
## Steps
1. Read `architecture.md`, all component specs, and `restrictions.md`
2. Assess deployment readiness:
- List all components and their current state (planned / implemented / tested)
- Identify external dependencies (databases, APIs, message queues, cloud services)
- Identify infrastructure prerequisites (container registry, cloud accounts, DNS, SSL certificates)
- Check if any deployment blockers exist
3. Identify all required environment variables by scanning:
- Component specs for configuration needs
- Database connection requirements
- External API endpoints and credentials
- Feature flags and runtime configuration
- Container registry credentials
- Cloud provider credentials
- Monitoring/logging service endpoints
4. Generate `.env.example` in project root with all variables and placeholder values (committed to VCS)
5. Generate `.env` in project root with development defaults filled in where safe (git-ignored)
6. Ensure `.gitignore` includes `.env` (but NOT `.env.example`)
7. Produce a deployment status report summarizing readiness, blockers, and required setup
## Self-verification
- [ ] All components assessed for deployment readiness
- [ ] External dependencies catalogued
- [ ] Infrastructure prerequisites identified
- [ ] All required environment variables discovered
- [ ] `.env.example` created with placeholder values
- [ ] `.env` created with safe development defaults
- [ ] `.gitignore` updated to exclude `.env`
- [ ] Status report written to `reports/deploy_status_report.md`
## Save action
Write `reports/deploy_status_report.md` using `templates/deploy_status_report.md`. Create `.env` and `.env.example` in project root.
## Blocking
**BLOCKING**: Present status report and environment variables to user. Do NOT proceed until confirmed.
@@ -0,0 +1,49 @@
# Step 2: Containerization
**Role**: DevOps / Platform engineer
**Goal**: Define Docker configuration for every component, local development, and blackbox test environments.
**Constraints**: Plan only — no Dockerfile creation. Describe what each Dockerfile should contain.
## Steps
1. Read `architecture.md` and all component specs
2. Read `restrictions.md` for infrastructure constraints
3. Research best Docker practices for the project's tech stack (multi-stage builds, base image selection, layer optimization)
4. For each component, define:
- Base image (pinned version, prefer alpine/distroless for production)
- Build stages (dependency install, build, production)
- Non-root user configuration
- Health check endpoint and command
- Exposed ports
- `.dockerignore` contents
5. Define `docker-compose.yml` for local development:
- All application components
- Database (Postgres) with named volume
- Any message queues, caches, or external service mocks
- Shared network
- Environment variable files (`.env`)
6. Define `docker-compose.test.yml` for blackbox tests:
- Application components under test
- Test runner container (black-box, no internal imports)
- Isolated database with seed data
- All tests runnable via `docker compose -f docker-compose.test.yml up --abort-on-container-exit --exit-code-from e2e-runner`
- See the Woodpecker two-workflow contract in [`../templates/ci_cd_pipeline.md`](../templates/ci_cd_pipeline.md) — the test runner entry point defined here becomes the first step of `.woodpecker/01-test.yml`.
7. Define image tagging strategy: `<registry>/<project>/<component>:<git-sha>` for CI, `latest` for local dev only
## Self-verification
- [ ] Every component has a Dockerfile specification
- [ ] Multi-stage builds specified for all production images
- [ ] Non-root user for all containers
- [ ] Health checks defined for every service
- [ ] `docker-compose.yml` covers all components + dependencies
- [ ] `docker-compose.test.yml` enables black-box testing
- [ ] `.dockerignore` defined
## Save action
Write `containerization.md` using `templates/containerization.md`.
## Blocking
**BLOCKING**: Present containerization plan to user. Do NOT proceed until confirmed.
@@ -0,0 +1,41 @@
# Step 3: CI/CD Pipeline
**Role**: DevOps engineer
**Goal**: Define the CI/CD pipeline with quality gates, security scanning, and multi-environment deployment.
**Constraints**: Pipeline definition only — produce YAML specification, not implementation.
## Steps
1. Read `architecture.md` for tech stack and deployment targets
2. Read `restrictions.md` for CI/CD constraints (cloud provider, registry, etc.)
3. Research CI/CD best practices for the project's platform (GitHub Actions / Azure Pipelines)
4. Define pipeline stages:
| Stage | Trigger | Steps | Quality Gate |
|-------|---------|-------|-------------|
| **Lint** | Every push | Run linters per language (black, rustfmt, prettier, dotnet format) | Zero errors |
| **Test** | Every push | Unit tests, blackbox tests, coverage report | 75%+ coverage (see `.cursor/rules/cursor-meta.mdc` Quality Thresholds) |
| **Security** | Every push | Dependency audit, SAST scan (Semgrep/SonarQube), image scan (Trivy) | Zero critical/high CVEs |
| **Build** | PR merge to dev | Build Docker images, tag with git SHA | Build succeeds |
| **Push** | After build | Push to container registry | Push succeeds |
| **Deploy Staging** | After push | Deploy to staging environment | Health checks pass |
| **Smoke Tests** | After staging deploy | Run critical path tests against staging | All pass |
| **Deploy Production** | Manual approval | Deploy to production | Health checks pass |
5. Define caching strategy: dependency caches, Docker layer caches, build artifact caches
6. Define parallelization: which stages can run concurrently
7. Define notifications: build failures, deployment status, security alerts
## Self-verification
- [ ] All pipeline stages defined with triggers and gates
- [ ] Coverage threshold enforced (75%+)
- [ ] Security scanning included (dependencies + images + SAST)
- [ ] Caching configured for dependencies and Docker layers
- [ ] Multi-environment deployment (staging → production)
- [ ] Rollback procedure referenced
- [ ] Notifications configured
## Save action
Write `ci_cd_pipeline.md` using `templates/ci_cd_pipeline.md`.
@@ -0,0 +1,41 @@
# Step 4: Environment Strategy
**Role**: Platform engineer
**Goal**: Define environment configuration, secrets management, and environment parity.
**Constraints**: Strategy document — no secrets or credentials in output.
## Steps
1. Define environments:
| Environment | Purpose | Infrastructure | Data |
|-------------|---------|---------------|------|
| **Development** | Local developer workflow | docker-compose, local volumes | Seed data, mocks for external APIs |
| **Staging** | Pre-production validation | Mirrors production topology | Anonymized production-like data |
| **Production** | Live system | Full infrastructure | Real data |
2. Define environment variable management:
- Reference `.env.example` created in Step 1
- Per-environment variable sources (`.env` for dev, secret manager for staging/prod)
- Validation: fail fast on missing required variables at startup
3. Define secrets management:
- Never commit secrets to version control
- Development: `.env` files (git-ignored)
- Staging/Production: secret manager (AWS Secrets Manager / Azure Key Vault / Vault)
- Rotation policy
4. Define database management per environment:
- Development: Docker Postgres with named volume, seed data
- Staging: managed Postgres, migrations applied via CI/CD
- Production: managed Postgres, migrations require approval
## Self-verification
- [ ] All three environments defined with clear purpose
- [ ] Environment variable documentation complete (references `.env.example` from Step 1)
- [ ] No secrets in any output document
- [ ] Secret manager specified for staging/production
- [ ] Database strategy per environment
## Save action
Write `environment_strategy.md` using `templates/environment_strategy.md`.
@@ -0,0 +1,60 @@
# Step 5: Observability
**Role**: Site Reliability Engineer (SRE)
**Goal**: Define logging, metrics, tracing, and alerting strategy.
**Constraints**: Strategy document — describe what to implement, not how to wire it.
## Steps
1. Read `architecture.md` and component specs for service boundaries
2. Research observability best practices for the tech stack
## Logging
- Structured JSON to stdout/stderr (no file logging in containers)
- Fields: `timestamp` (ISO 8601), `level`, `service`, `correlation_id`, `message`, `context`
- Levels: ERROR (exceptions), WARN (degraded), INFO (business events), DEBUG (diagnostics, dev only)
- No PII in logs
- Retention: dev = console, staging = 7 days, production = 30 days
## Metrics
- Expose Prometheus-compatible `/metrics` endpoint per service
- System metrics: CPU, memory, disk, network
- Application metrics: `request_count`, `request_duration` (histogram), `error_count`, `active_connections`
- Business metrics: derived from acceptance criteria
- Collection interval: 15s
## Distributed Tracing
- OpenTelemetry SDK integration
- Trace context propagation via HTTP headers and message queue metadata
- Span naming: `<service>.<operation>`
- Sampling: 100% in dev/staging, 10% in production (adjust based on volume)
## Alerting
| Severity | Response Time | Condition Examples |
|----------|---------------|-------------------|
| Critical | 5 min | Service down, data loss, health check failed |
| High | 30 min | Error rate > 5%, P95 latency > 2x baseline |
| Medium | 4 hours | Disk > 80%, elevated latency |
| Low | Next business day | Non-critical warnings |
## Dashboards
- Operations: service health, request rate, error rate, response time percentiles, resource utilization
- Business: key business metrics from acceptance criteria
## Self-verification
- [ ] Structured logging format defined with required fields
- [ ] Metrics endpoint specified per service
- [ ] OpenTelemetry tracing configured
- [ ] Alert severities with response times defined
- [ ] Dashboards cover operations and business metrics
- [ ] PII exclusion from logs addressed
## Save action
Write `observability.md` using `templates/observability.md`.
@@ -0,0 +1,53 @@
# Step 6: Deployment Procedures
**Role**: DevOps / Platform engineer
**Goal**: Define deployment strategy, rollback procedures, health checks, and deployment checklist.
**Constraints**: Procedures document — no implementation.
## Steps
1. Define deployment strategy:
- Preferred pattern: blue-green / rolling / canary (choose based on architecture)
- Zero-downtime requirement for production
- Graceful shutdown: 30-second grace period for in-flight requests
- Database migration ordering: migrate before deploy, backward-compatible only
2. Define health checks:
| Check | Type | Endpoint | Interval | Threshold |
|-------|------|----------|----------|-----------|
| Liveness | HTTP GET | `/health/live` | 10s | 3 failures → restart |
| Readiness | HTTP GET | `/health/ready` | 5s | 3 failures → remove from LB |
| Startup | HTTP GET | `/health/ready` | 5s | 30 attempts max |
3. Define rollback procedures:
- Trigger criteria: health check failures, error rate spike, critical alert
- Rollback steps: redeploy previous image tag, verify health, rollback database if needed
- Communication: notify stakeholders during rollback
- Post-mortem: required after every production rollback
4. Define deployment checklist:
- [ ] All tests pass in CI
- [ ] Security scan clean (zero critical/high CVEs)
- [ ] Database migrations reviewed and tested
- [ ] Environment variables configured
- [ ] Health check endpoints responding
- [ ] Monitoring alerts configured
- [ ] Rollback plan documented and tested
- [ ] Stakeholders notified
## Self-verification
- [ ] Deployment strategy chosen and justified
- [ ] Zero-downtime approach specified
- [ ] Health checks defined (liveness, readiness, startup)
- [ ] Rollback trigger criteria and steps documented
- [ ] Deployment checklist complete
## Save action
Write `deployment_procedures.md` using `templates/deployment_procedures.md`.
## Blocking
**BLOCKING**: Present deployment procedures to user. Do NOT proceed until confirmed.
+70
View File
@@ -0,0 +1,70 @@
# Step 7: Deployment Scripts
**Role**: DevOps / Platform engineer
**Goal**: Create executable deployment scripts for pulling Docker images and running services on the remote target machine.
**Constraints**: Produce real, executable shell scripts. This is the ONLY step that creates implementation artifacts.
## Steps
1. Read `containerization.md` and `deployment_procedures.md` from previous steps
2. Read `.env.example` for required variables
3. Create the following scripts in `SCRIPTS_DIR/`:
### `deploy.sh` — Main deployment orchestrator
- Validates that required environment variables are set (sources `.env` if present)
- Calls `pull-images.sh`, then `stop-services.sh`, then `start-services.sh`, then `health-check.sh`
- Exits with non-zero code on any failure
- Supports `--rollback` flag to redeploy previous image tags
### `pull-images.sh` — Pull Docker images to target machine
- Reads image list and tags from environment or config
- Authenticates with container registry
- Pulls all required images
- Verifies image integrity (digest check)
### `start-services.sh` — Start services on target machine
- Runs `docker compose up -d` or individual `docker run` commands
- Applies environment variables from `.env`
- Configures networks and volumes
- Waits for containers to reach healthy state
### `stop-services.sh` — Graceful shutdown
- Stops services with graceful shutdown period
- Saves current image tags for rollback reference
- Cleans up orphaned containers/networks
### `health-check.sh` — Verify deployment health
- Checks all health endpoints
- Reports status per service
- Returns non-zero if any service is unhealthy
4. All scripts must:
- Be POSIX-compatible (`#!/bin/bash` with `set -euo pipefail`)
- Source `.env` from project root or accept env vars from the environment
- Include usage/help output (`--help` flag)
- Be idempotent where possible
- Handle SSH connection to remote target (configurable via `DEPLOY_HOST` env var)
5. Document all scripts in `deploy_scripts.md`
## Self-verification
- [ ] All five scripts created and executable
- [ ] Scripts source environment variables correctly
- [ ] `deploy.sh` orchestrates the full flow
- [ ] `pull-images.sh` handles registry auth and image pull
- [ ] `start-services.sh` starts containers with correct config
- [ ] `stop-services.sh` handles graceful shutdown
- [ ] `health-check.sh` validates all endpoints
- [ ] Rollback supported via `deploy.sh --rollback`
- [ ] Scripts work for remote deployment via SSH (`DEPLOY_HOST`)
- [ ] `deploy_scripts.md` documents all scripts
## Save action
Write scripts to `SCRIPTS_DIR/`. Write `deploy_scripts.md` using `templates/deploy_scripts.md`.
@@ -85,3 +85,140 @@ Save as `_docs/04_deploy/ci_cd_pipeline.md`.
| Deploy success | [Slack] | [team] |
| Deploy failure | [Slack/email + PagerDuty] | [on-call] |
```
---
## Reference Implementation: Woodpecker CI two-workflow contract
Use this when the project's CI is **Woodpecker** and the test layout follows the autodev e2e contract from [`../../decompose/templates/test-infrastructure-task.md`](../../decompose/templates/test-infrastructure-task.md) (an `e2e/` folder containing `Dockerfile`, `docker-compose.test.yml`, `conftest.py`, `requirements.txt`, `mocks/`, `fixtures/`, `tests/`).
The contract is **two workflows in `.woodpecker/`**, scheduled on the same agent label, with the build workflow gated on a successful test run:
- `.woodpecker/01-test.yml` — runs the e2e contract, publishes `results/report.csv` as an artifact, fails the pipeline on any test failure.
- `.woodpecker/02-build-push.yml``depends_on: [01-test]`. Builds the image, tags it `${CI_COMMIT_BRANCH}-${TAG_SUFFIX}`, pushes it to the registry. Skipped automatically if test failed.
The agent label is parameterized via `matrix:` so a single workflow file fans out across architectures: `labels: platform: ${PLATFORM}` routes each matrix entry to the matching agent. Both workflows for a repo must use the same matrix so test and build run on the same machine and share Docker layer cache. New architectures = new matrix entries; never new files.
### Multi-arch matrix conventions
| Variable | Meaning | Typical values |
|----------|---------|----------------|
| `PLATFORM` | Woodpecker agent label — selects which physical machine runs the entry. | `arm64`, `amd64` |
| `TAG_SUFFIX` | Image tag suffix appended after the branch name. | `arm`, `amd` |
| `DOCKERFILE` *(only when arches need different Dockerfiles)* | Path to the Dockerfile for this entry. | `Dockerfile`, `Dockerfile.jetson` |
Most repos use the same `Dockerfile` for both arches (multi-arch base images handle the rest), so `DOCKERFILE` can be omitted from the matrix and hardcoded in the build command. Repos with split per-arch Dockerfiles (e.g., `detections` uses `Dockerfile.jetson` on Jetson with TensorRT/CUDA-on-L4T) declare `DOCKERFILE` as a matrix var.
When only one architecture is currently in use, keep the matrix block with a single entry and the second entry commented out — adding a new arch is then a one-line uncomment, not a structural change.
### `.woodpecker/01-test.yml`
```yaml
when:
event: [push, pull_request, manual]
branch: [dev, stage, main]
matrix:
include:
- PLATFORM: arm64
TAG_SUFFIX: arm
# - PLATFORM: amd64
# TAG_SUFFIX: amd
labels:
platform: ${PLATFORM}
steps:
- name: e2e
image: docker
commands:
- cd e2e
- docker compose -f docker-compose.test.yml up --abort-on-container-exit --exit-code-from e2e-runner --build
- docker compose -f docker-compose.test.yml down -v
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- name: report
image: docker
when:
status: [success, failure]
commands:
- test -f e2e/results/report.csv && cat e2e/results/report.csv || echo "no report"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
```
Notes:
- `--abort-on-container-exit` shuts the whole compose down as soon as ANY service exits, so a crashed dependency surfaces immediately instead of hanging the runner.
- `--exit-code-from e2e-runner` ensures the pipeline's exit code reflects the test runner's, not the SUT's.
- The `report` step runs on `[success, failure]` so the report is always published; without this the CSV is lost on red builds.
- `down -v` between runs drops mock state and DB volumes — every test run starts clean.
### `.woodpecker/02-build-push.yml`
```yaml
when:
event: [push, manual]
branch: [dev, stage, main]
depends_on:
- 01-test
matrix:
include:
- PLATFORM: arm64
TAG_SUFFIX: arm
# - PLATFORM: amd64
# TAG_SUFFIX: amd
labels:
platform: ${PLATFORM}
steps:
- name: build-push
image: docker
environment:
REGISTRY_HOST:
from_secret: registry_host
REGISTRY_USER:
from_secret: registry_user
REGISTRY_TOKEN:
from_secret: registry_token
commands:
- echo "$REGISTRY_TOKEN" | docker login "$REGISTRY_HOST" -u "$REGISTRY_USER" --password-stdin
- export TAG=${CI_COMMIT_BRANCH}-${TAG_SUFFIX}
- export BUILD_DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ)
- |
docker build -f Dockerfile \
--build-arg CI_COMMIT_SHA=$CI_COMMIT_SHA \
--label org.opencontainers.image.revision=$CI_COMMIT_SHA \
--label org.opencontainers.image.created=$BUILD_DATE \
--label org.opencontainers.image.source=$CI_REPO_URL \
-t $REGISTRY_HOST/azaion/<service>:$TAG .
- docker push $REGISTRY_HOST/azaion/<service>:$TAG
volumes:
- /var/run/docker.sock:/var/run/docker.sock
```
Notes:
- `depends_on: [01-test]` is enforced by Woodpecker — a failed `01-test` (any matrix entry) skips this workflow.
- The build workflow does NOT trigger on `pull_request` events: PRs get test signal only; pushes to `dev`/`stage`/`main` produce images. Avoids polluting the registry with PR images.
- Replace `<service>` with the actual service name (matches the registry namespace pattern `azaion/<service>`).
- For repos with split per-arch Dockerfiles, add `DOCKERFILE: Dockerfile.jetson` (or similar) to the matrix entry and substitute `${DOCKERFILE}` for `Dockerfile` in the `docker build -f` line.
### Variations by stack
The contract is language-agnostic because the runner is `docker compose`. The Dockerfile inside `e2e/` selects the test framework:
| Stack | `e2e/Dockerfile` runs |
|-------|----------------------|
| Python | `pytest --csv=/results/report.csv -v` |
| .NET | `dotnet test --logger:"trx;LogFileName=/results/report.trx"` (convert to CSV in a final step if needed) |
| Node/UI | `npm test -- --reporters=default --reporters=jest-junit --outputDirectory=/results` |
| Rust | `cargo test --no-fail-fast -- --format json > /results/report.json` |
When the repo has **only unit tests** (no `e2e/docker-compose.test.yml`), drop the compose orchestration and run the native test command directly inside a stack-appropriate image. Keep the same two-workflow split — `01-test.yml` runs unit tests, `02-build-push.yml` is unchanged.
### Manual-trigger override (test infrastructure not yet validated)
If a repo ships a complete `e2e/` layout but the test fixtures are not yet validated end-to-end (e.g., expected-results data is still being authored), gate `01-test.yml` on `event: [manual]` only and add a TODO comment pointing to the unblocking task. The `02-build-push.yml` workflow drops its `depends_on` clause for the manual-only window — an explicit and reversible exception, not a permanent split.
@@ -31,6 +31,7 @@ _docs/
│ ├── components.md
│ └── flows/
├── 04_verification_log.md # Step 4
├── glossary.md # Step 4.5 (confirmed-by-user)
├── FINAL_report.md # Step 7
└── state.json # Resumability
```
@@ -49,6 +50,7 @@ Maintained in `DOCUMENT_DIR/state.json` for resumability:
"modules_remaining": ["services/auth", "api/endpoints"],
"module_batch": 1,
"components_written": [],
"step_4_5_glossary_vision": "not_started",
"last_updated": "2026-03-21T14:00:00Z"
}
```
+135 -2
View File
@@ -15,7 +15,7 @@ Covers three related modes that share the same 8-step pipeline:
## Progress Tracking
Create a TodoWrite with all steps (0 through 7). Update status as each step completes.
Create a TodoWrite with all steps (0 through 7, including the inline Step 2.5 Module Layout Derivation and Step 4.5 Glossary & Architecture Vision). Update status as each step completes.
## Steps
@@ -142,6 +142,37 @@ Re-entry is seamless: `state.json` tracks exactly which modules are done.
---
### Step 2.5: Module Layout Derivation
**Role**: Software architect
**Goal**: Produce `_docs/02_document/module-layout.md` — the authoritative file-ownership map read by `/implement` Step 4, `/code-review` Phase 7, and `/refactor` discovery. Required for any downstream skill that assigns file ownership or checks architectural layering.
This step derives the layout from the **existing** codebase rather than from a plan. Decompose Step 1.5 is the greenfield counterpart and uses the same template; this step uses the same output shape so downstream consumers don't branch on origin.
1. For each component identified in Step 2, resolve its owning directory from module docs (Step 1) and from directory groupings used in Step 2.
2. For each component, compute:
- **Public API**: exported symbols. Language-specific: Python — `__init__.py` re-exports + non-underscore root-level symbols; TypeScript — `index.ts` / barrel exports; C# — `public` types in the namespace root; Rust — `pub` items in `lib.rs` / `mod.rs`; Go — exported (capitalized) identifiers in the package root.
- **Internal**: everything else under the component's directory.
- **Owns**: the component's directory glob.
- **Imports from**: other components whose Public API this one references (parse imports; reuse tooling from Step 0's dependency graph).
- **Consumed by**: reverse of Imports from across all components.
3. Identify `shared/*` directories already present in the code (or infer candidates: modules imported by ≥2 components and owning no domain logic). Create a Shared / Cross-Cutting entry per concern.
4. Infer the Allowed Dependencies layering table by topologically sorting the import graph built in step 2. Components that import only from `shared/*` go to Layer 1; each successive layer imports only from lower layers.
5. Write `_docs/02_document/module-layout.md` using `.cursor/skills/decompose/templates/module-layout.md`. At the top of the file add `**Status**: derived-from-code` and a `## Verification Needed` block listing any inference that was not clean (detected cycles, ambiguous ownership, components not cleanly assignable to a layer).
**Self-verification**:
- [ ] Every component from Step 2 has a Per-Component Mapping entry
- [ ] Every Public API list is grounded in an actual exported symbol (no guesses)
- [ ] No component's `Imports from` points at a component in a higher layer
- [ ] Shared directories detected in code are listed under Shared / Cross-Cutting
- [ ] Cycles from Step 0 that span components are surfaced in `## Verification Needed`
**Save**: `_docs/02_document/module-layout.md`
**BLOCKING**: Present the layering table and the `## Verification Needed` block to the user. Do NOT proceed until the user confirms (or patches) the derived layout. Downstream skills assume this file is accurate.
---
### Step 3: System-Level Synthesis
**Role**: Software architect
@@ -220,7 +251,107 @@ Apply corrections inline to the documents that need them.
**BLOCKING**: Present verification summary to user. Do NOT proceed until user confirms corrections are acceptable or requests additional fixes.
**Session boundary**: After verification is confirmed, suggest a session break before proceeding to the synthesis steps (57). These steps produce different artifact types and benefit from fresh context:
---
### Step 4.5: Glossary & Architecture Vision (BLOCKING)
**Role**: Software architect + business analyst
**Goal**: Reconcile the AI's verified understanding of the codebase with the user's intended terminology and architecture vision. Existing-code projects often carry domain language and structural intent that is invisible from code alone (synonyms, deprecated names, modules that are "supposed to" be split, components the user thinks of as one logical unit even though they live in two folders). This step makes that intent explicit before any downstream skill (refactor, decompose, new-task) acts on the docs.
**When this step runs**:
- Always, after Step 4 (Verification Pass) — for Full and Resume modes.
- **Skipped** in Focus Area mode (the glossary/vision is system-wide; running it on a partial scan would produce a partial glossary). Resume the user once a full pass exists.
**Inputs** (already on disk after Step 4):
- `DOCUMENT_DIR/architecture.md`, `system-flows.md`, `data_model.md`, `deployment/*`
- `DOCUMENT_DIR/components/*/description.md`
- `DOCUMENT_DIR/modules/*.md`
- `DOCUMENT_DIR/04_verification_log.md` (so the AI knows which doc parts are confirmed vs. flagged)
**Outputs**:
- `DOCUMENT_DIR/glossary.md` (NEW)
- `DOCUMENT_DIR/architecture.md` updated in place: a new `## Architecture Vision` section is prepended (or merged into an existing "Overview" / "Vision" heading if already present); existing technical sections are preserved verbatim
**Procedure**:
1. **Draft glossary** from verified docs:
- Domain entities, processes, roles named in module/component docs
- Acronyms / abbreviations
- Internal codenames (project, service, model names) that recur in the codebase
- Synonym pairs the AI noticed (e.g., the codebase uses "flight" but module comments say "mission")
- Stakeholder personas if any docs reference them
Each entry: one-line definition + source reference (`source: components/03_flights/description.md`). Skip generic CS/industry terms.
2. **Draft architecture vision** as the AI currently understands the codebase:
- **One paragraph**: what the system is, who runs it, the runtime topology shape (monolith / services / pipeline / library / hybrid), and the dominant pattern (e.g., "submodule-based meta-repo with REST + SSE between UI and backend").
- **Components & responsibilities** (one-line each), pulled from `components/*/description.md`.
- **Major data flows** (one or two sentences each), pulled from `system-flows.md`.
- **Architectural principles / non-negotiables** the AI inferred from the code (e.g., "DB-driven config", "all UI traffic via REST + SSE only", "no per-component shared state"). Mark each with `inferred-from: <source>`.
- **Open questions / drift signals**: places where the code disagrees with itself, or where the AI cannot tell intent from implementation (e.g., two components doing similar work — is that legacy duplication or deliberate?).
3. **Present condensed view** to the user (NOT the full draft files — a synopsis only):
```
══════════════════════════════════════
REVIEW: Glossary + Architecture Vision (existing code)
══════════════════════════════════════
Glossary (N terms drafted from verified docs):
- <Term>: <one-line definition>
- ...
Architecture Vision — as inferred from the codebase:
<one-paragraph synopsis>
Components / responsibilities:
- <component>: <one-line>
- ...
Principles / non-negotiables (inferred):
- <principle> [inferred-from: <source>]
- ...
Open questions / drift signals:
- <q1>
- <q2>
══════════════════════════════════════
A) Inferred vision matches my intent — write the files
B) Add / correct entries (provide diffs — terms, components,
principles, or rename pairs)
C) Resolve the open questions / drift signals first
══════════════════════════════════════
Recommendation: pick C if any drift signals exist;
otherwise B if the vision misses
project-specific intent; A only when
the inferred vision is exactly right.
══════════════════════════════════════
```
4. **Iterate**:
- On B → integrate the user's diffs/additions, re-present, loop until A.
- On C → ask the listed open questions in one batch (M4-style), integrate answers, re-present.
- **Do NOT proceed to step 5 until the user picks A.**
5. **Save**:
- Write `DOCUMENT_DIR/glossary.md`, alphabetical, with a top-line `**Status**: confirmed-by-user` and the date.
- Update `DOCUMENT_DIR/architecture.md`:
- If a `## Architecture Vision` (or `## Vision` / `## Overview`) section already exists at the top, replace its body with the confirmed paragraph + components + principles.
- Otherwise, insert `## Architecture Vision` as the first H2 after the title; preserve every existing H2 below.
- Do NOT delete or re-order existing technical sections (Tech Stack, Deployment Model, Data Model, NFRs, ADRs).
6. **Update `state.json`**: mark `step_4_5_glossary_vision: confirmed`. Resume on rerun must skip this step unless the user explicitly invokes `/document --refresh-vision`.
**Self-verification**:
- [ ] Every glossary entry traces to at least one file under `DOCUMENT_DIR/`
- [ ] Every component listed in the vision matches a folder under `DOCUMENT_DIR/components/`
- [ ] All open questions are answered or explicitly deferred (with the user's acknowledgement)
- [ ] `architecture.md` still contains all H2 sections it had before this step
- [ ] User picked option A on the latest condensed view
**BLOCKING**: Do NOT proceed to the session boundary / Step 5 until both files are saved and the user has picked A.
---
**Session boundary**: After Step 4.5 is confirmed, suggest a session break before proceeding to the synthesis steps (57). These steps produce different artifact types and benefit from fresh context:
```
══════════════════════════════════════
@@ -358,6 +489,8 @@ Using `.cursor/skills/plan/templates/final-report.md` as structure:
│ (batched ~5 modules; session break between batches) │
│ 2. Component Assembly → group modules, write component specs │
│ [BLOCKING: user confirms components] │
│ 2.5 Module Layout → derive module-layout.md from code │
│ [BLOCKING: user confirms layout] │
│ 3. System Synthesis → architecture, flows, data model, deploy │
│ 4. Verification → compare all docs vs code, fix errors │
│ [BLOCKING: user reviews corrections] │
+22
View File
@@ -26,6 +26,27 @@ One or more task spec files from `_docs/02_tasks/todo/` or `_docs/02_tasks/done/
- System-level docs (only if the task changed API endpoints, data models, or external integrations)
- Problem-level docs (only if the task changed input parameters, acceptance criteria, or restrictions)
### Task Step 0.5: Import-Graph Ripple
A module that changed may be imported by other modules whose docs are now stale even though those other modules themselves were not directly edited. Compute the reverse-dependency set and fold it into the update list.
1. For each source file in the set of changed files from Step 0, build its module-level identifier (Python module path, C# namespace, Rust module path, TS import-specifier, Go package path — depending on the project language).
2. Search the codebase for files that import from any of those identifiers. Preferred tooling per language:
- **Python**: `rg -e "^(from|import) <module>"` then parse with `ast` to confirm actual symbol use.
- **TypeScript / JavaScript**: `rg "from ['\"].*<path>"` then resolve via `tsconfig.json` paths / `jsconfig.json` if present.
- **C#**: `rg "^using <namespace>"` plus `.csproj` `ProjectReference` graph.
- **Rust**: `rg "use <crate>::"` plus `Cargo.toml` workspace members.
- **Go**: `rg "\"<module-path>\""` plus `go.mod` requires.
If a static analyzer is available for the project (e.g., `pydeps`, `madge`, `depcruise`, `NDepend`, `cargo modules`, `go list -deps`), prefer its output — it is more reliable than regex.
3. For each importing file found, look up the component it belongs to via `_docs/02_document/module-layout.md` (if present) or by directory match against `DOCUMENT_DIR/components/`.
4. Add every such component and module to the update list, even if it was not in the current cycle's task spec.
5. Produce `_docs/02_document/ripple_log_cycle<N>.md` (where `<N>` is `state.cycle` from `_docs/_autodev_state.md`, default `1`) listing each downstream doc that was added to the refresh set and the reason (which changed file triggered it). Example line:
```
- docs/components/02_ingestor.md — refreshed because src/ingestor/queue.py imports src/shared/serializer.py (changed by AZ-173)
```
6. When parsing imports fails (missing tooling, unsupported language), log the parse failure in the ripple log and fall back to a directory-proximity heuristic: any component whose source directory contains files matching the changed-file basenames. Note: heuristic mode is explicitly marked in the log so the user can request a manual pass.
### Task Step 1: Module Doc Updates
For each affected module:
@@ -78,6 +99,7 @@ Present a summary of all docs updated:
Component docs updated: [count]
System-level docs updated: [list or "none"]
Problem-level docs updated: [list or "none"]
Ripple-refreshed docs (imports changed indirectly): [count, see ripple_log_cycle<N>.md]
══════════════════════════════════════
```
+227 -70
View File
@@ -1,41 +1,59 @@
---
name: implement
description: |
Orchestrate task implementation with dependency-aware batching, parallel subagents, and integrated code review.
Implement tasks sequentially with dependency-aware batching and integrated code review.
Reads flat task files and _dependencies_table.md from TASKS_DIR, computes execution batches via topological sort,
launches up to 4 implementer subagents in parallel, runs code-review skill after each batch, and loops until done.
implements tasks one at a time in dependency order, runs code-review skill after each batch, and loops until done.
Use after /decompose has produced task files.
Trigger phrases:
- "implement", "start implementation", "implement tasks"
- "run implementers", "execute tasks"
- "execute tasks"
category: build
tags: [implementation, orchestration, batching, parallel, code-review]
tags: [implementation, batching, code-review]
disable-model-invocation: true
---
# Implementation Orchestrator
# Implementation Runner
Orchestrate the implementation of all tasks produced by the `/decompose` skill. This skill is a **pure orchestrator** — it does NOT write implementation code itself. It reads task specs, computes execution order, delegates to `implementer` subagents, validates results via the `/code-review` skill, and escalates issues.
Implement all tasks produced by the `/decompose` skill. This skill reads task specs, computes execution order, writes the code and tests for each task **sequentially** (no subagents, no parallel execution), validates results via the `/code-review` skill, and escalates issues.
The `implementer` agent is the specialist that writes all the code — it receives a task spec, analyzes the codebase, implements the feature, writes tests, and verifies acceptance criteria.
For each task the main agent receives a task spec, analyzes the codebase, implements the feature, writes tests, and verifies acceptance criteria — then moves on to the next task.
## Core Principles
- **Orchestrate, don't implement**: this skill delegates all coding to `implementer` subagents
- **Dependency-aware batching**: tasks run only when all their dependencies are satisfied
- **Max 4 parallel agents**: never launch more than 4 implementer subagents simultaneously
- **File isolation**: no two parallel agents may write to the same file
- **Sequential execution**: implement one task at a time. Do NOT spawn subagents and do NOT run tasks in parallel. (See `.cursor/rules/no-subagents.mdc`.)
- **Dependency-aware ordering**: tasks run only when all their dependencies are satisfied
- **Batching for review, not parallelism**: tasks are grouped into batches so `/code-review` and commits operate on a coherent unit of work — all tasks inside a batch are still implemented one after the other
- **Integrated review**: `/code-review` skill runs automatically after each batch
- **Auto-start**: batches launch immediately — no user confirmation before a batch
- **Completeness before testing**: product implementation is not done until code is checked against task outcomes, included scope, architecture/component promises, named runtime dependencies, and unresolved scaffold/native placeholders — not just task AC tests
- **Runtime dependency reality**: production code cannot satisfy a task by exposing only a protocol, fake runner, deterministic fallback, or "native bridge" placeholder when the task/architecture promises a concrete internal capability such as BASALT VIO, FAISS retrieval, LightGlue matching, or a full A-Z localization pipeline. Stubs are allowed only for external systems and tests.
- **Auto-start**: batches start immediately — no user confirmation before a batch
- **Gate on failure**: user confirmation is required only when code review returns FAIL
- **Commit and push per batch**: after each batch is confirmed, commit and push to remote
- **Commit per batch**: after each batch is confirmed, commit. Ask the user whether to push to remote unless the user previously opted into auto-push for this session.
## Context Resolution
- TASKS_DIR: `_docs/02_tasks/`
- Task files: all `*.md` files in `TASKS_DIR/todo/` (excluding files starting with `_`)
- Task files: selected `*.md` files in `TASKS_DIR/todo/` (excluding files starting with `_`)
- Dependency table: `TASKS_DIR/_dependencies_table.md`
### Task Selection Context
The invoking flow decides which task category this run should execute. The implement skill must honor that selected context instead of consuming every file in `todo/`.
| Context | Selected task files |
|---------|---------------------|
| Product implementation | Task specs that are not test-only and not refactoring specs |
| Test implementation | `*_test_infrastructure.md` plus task specs whose `Component` or `Epic` identifies `Blackbox Tests` |
| Refactoring | Task specs whose filename or task ID includes `_refactor_` |
If no explicit context is provided, infer it from the active autodev step:
- greenfield Step 7 or existing-code Step 10 → Product implementation
- greenfield Step 10 or existing-code Step 6 → Test implementation
- refactor Phase 4 → Refactoring
Unselected task files remain in `TASKS_DIR/todo/` for their later flow step.
### Task Lifecycle Folders
```
@@ -46,19 +64,48 @@ TASKS_DIR/
└── done/ ← completed tasks (moved here after implementation)
```
### Suite-level invocation context (meta-repo flow)
When invoked from `.cursor/skills/autodev/flows/meta-repo.md` Step 3.5 (or any caller that supplies the same context envelope), the skill receives:
```
suite_level: true
TASKS_DIR: <override> # e.g., _docs/tasks/ (vs. default _docs/02_tasks/)
module_layout_path: <override> # e.g., _docs/tasks/_suite_module_layout.md
```
When `suite_level: true` is present, the following gate adjustments apply — and ONLY these. All other steps (114, 16) execute unchanged:
1. **TASKS_DIR override** is honored throughout the skill (Step 1 Parse, Step 13 Archive, Step 15 input paths if it ran). Default `_docs/02_tasks/` is replaced by the supplied path.
2. **module_layout_path override** is read instead of the hardcoded `_docs/02_document/module-layout.md` in Step 4 (Assign File Ownership). The supplied file uses the same `Per-Component Mapping` schema. If both the override and the hardcoded path are missing, behavior is unchanged from default mode (STOP and instruct).
3. **Step 14.5 (Cumulative Code Review) — SKIPPED**. The meta-repo has no `_docs/02_document/architecture_compliance_baseline.md`; cross-task drift is captured by the next `monorepo-status` cycle instead.
4. **Step 15 (Product Implementation Completeness Gate) — SKIPPED**. The gate's hard inputs (`_docs/02_document/architecture.md`, `system-flows.md`, `components/*/description.md`) do not exist in the meta-repo artifact layout. Suite-level tasks are infrastructure / coordination work (renames, cross-repo edits, suite-root infra additions), not feature implementation; the equivalent completeness signal is the next `monorepo-status` drift report (which the meta-repo flow re-runs immediately after Step 3.5 returns).
5. **Final report filename**: `_docs/03_implementation/suite_implementation_report_{run_name}.md` (in addition to the existing feature/test/refactor variants). Batch reports follow `_docs/03_implementation/suite_batch_{NN}_report.md`.
6. **Tracker integration** (Step 5: In Progress, Step 12: In Testing) runs unchanged — suite-level tickets follow the same tracker rules as any other.
Without `suite_level: true`, none of these adjustments apply and the skill runs exactly as documented in default mode.
## Prerequisite Checks (BLOCKING)
1. `TASKS_DIR/todo/` exists and contains at least one task file — **STOP if missing**
1. `TASKS_DIR/todo/` exists and contains at least one task file for the selected context **STOP if missing**
- Exception for Product implementation re-entry: if no selected product tasks remain in `todo/`, but the active autodev state is Step 7 or the latest product completeness report is missing/invalid/contains `FAIL`, skip directly to Step 15 (Product Implementation Completeness Gate). This gate may create remediation tasks and return to Step 1. Do not write a final implementation report from this state.
2. `_dependencies_table.md` exists — **STOP if missing**
3. At least one task is not yet completed — **STOP if all done**
4. **Working tree is clean** — run `git status --porcelain`; the output must be empty.
- If dirty, STOP and present the list of changed files to the user via the Choose format:
- A) Commit or stash stray changes manually, then re-invoke `/implement`
- B) Agent commits stray changes as a single `chore: WIP pre-implement` commit and proceeds
- C) Abort
- Rationale: each batch ends with a commit. Unrelated uncommitted changes would get silently folded into batch commits otherwise.
- This check is repeated at the start of each batch iteration (see step 6 / step 14 Loop).
## Algorithm
### 1. Parse
- Read all task `*.md` files from `TASKS_DIR/todo/` (excluding files starting with `_`)
- Read selected task `*.md` files from `TASKS_DIR/todo/` (excluding files starting with `_`)
- Read `_dependencies_table.md` — parse into a dependency graph (DAG)
- Validate: no circular dependencies, all referenced dependencies exist
- Validate: no circular dependencies in the selected task graph, all referenced selected-task dependencies exist or are already completed in `TASKS_DIR/done/`
### 2. Detect Progress
@@ -71,43 +118,55 @@ TASKS_DIR/
- Topological sort remaining tasks
- Select tasks whose dependencies are ALL satisfied (completed)
- If a ready task depends on any task currently being worked on in this batch, it must wait for the next batch
- Cap the batch at 4 parallel agents
- A batch is simply a coherent group of tasks for review + commit. Within the batch, tasks are implemented sequentially in topological order.
- Cap the batch size at a reasonable review scope (default: 4 tasks)
- If the batch would exceed 20 total complexity points, suggest splitting and let the user decide
### 4. Assign File Ownership
The authoritative file-ownership map is `_docs/02_document/module-layout.md` (produced by the decompose skill's Step 1.5), unless `suite_level: true` was supplied in the invocation context — in which case the `module_layout_path` override is read instead (see "Suite-level invocation context" above). Task specs are purely behavioral — they do NOT carry file paths. Derive ownership from the layout, not from the task spec's prose.
For each task in the batch:
- Parse the task spec's Component field and Scope section
- Map the component to directories/files in the project
- Determine: files OWNED (exclusive write), files READ-ONLY (shared interfaces, types), files FORBIDDEN (other agents' owned files)
- If two tasks in the same batch would modify the same file, schedule them sequentially instead of in parallel
- Read the task spec's **Component** field.
- Look up the component in `_docs/02_document/module-layout.md` → Per-Component Mapping.
- Set **OWNED** = the component's `Owns` glob (the files this task is allowed to write).
- Set **READ-ONLY** = Public API files of every component in the component's `Imports from` list, plus all `shared/*` Public API files.
- Set **FORBIDDEN** = every other component's `Owns` glob, and every other component's internal (non-Public API) files.
- If the task is a shared / cross-cutting task (lives under `shared/*`), OWNED = that shared directory; READ-ONLY = nothing; FORBIDDEN = every component directory.
Since execution is sequential, there is no parallel-write conflict to resolve; ownership here is a **scope discipline** check — it stops a task from drifting into unrelated components even when alone.
If `_docs/02_document/module-layout.md` is missing or the component is not found:
- STOP the batch.
- Instruct the user to run `/decompose` Step 1.5 or to manually add the component entry to `module-layout.md`.
- Do NOT guess file paths from the task spec — that is exactly the drift this file exists to prevent.
### 5. Update Tracker Status → In Progress
For each task in the batch, transition its ticket status to **In Progress** via the configured work item tracker (see `protocols.md` for tracker detection) before launching the implementer. If `tracker: local`, skip this step.
For each task in the batch, transition its ticket status to **In Progress** via the configured work item tracker (see `protocols.md` for tracker detection) before starting work. If `tracker: local`, skip this step. If a tracker operation fails unexpectedly, follow `.cursor/rules/tracker.mdc`.
### 6. Launch Implementer Subagents
### 6. Implement Tasks Sequentially
For each task in the batch, launch an `implementer` subagent with:
- Path to the task spec file
- List of files OWNED (exclusive write access)
- List of files READ-ONLY
- List of files FORBIDDEN
- **Explicit instruction**: the implementer must write or update tests that validate each acceptance criterion in the task spec. If a test cannot run in the current environment (e.g., TensorRT requires GPU), the test must still be written and skip with a clear reason.
**Per-batch dirty-tree re-check**: before starting the batch, run `git status --porcelain`. On the first batch this is guaranteed clean by the prerequisite check. On subsequent batches, the previous batch ended with a commit so the tree should still be clean. If the tree is dirty at this point, STOP and surface the dirty files to the user using the same A/B/C choice as the prerequisite check. The most likely causes are a failed commit in the previous batch, a user who edited files mid-loop, or a pre-commit hook that re-wrote files and was not captured.
Launch all subagents immediately — no user confirmation.
For each task in the batch **in topological order, one at a time**:
1. Read the task spec file.
2. Respect the file-ownership envelope computed in Step 4 (OWNED / READ-ONLY / FORBIDDEN).
3. Implement the feature and write/update tests for every acceptance criterion in the spec. Tests for internal product behavior must exercise the production implementation path. If a test cannot run in the current environment (e.g., TensorRT requires GPU), the test must still exist and skip/block with a clear prerequisite reason, but that skip does not make missing production code complete.
4. Run the relevant tests locally before moving on to the next task in the batch. If tests fail, fix in-place — do not defer.
5. Capture a short per-task status line (files changed, tests pass/fail, any blockers) for the batch report.
### 7. Monitor
Do NOT spawn subagents and do NOT attempt to implement two tasks simultaneously, even if they touch disjoint files. See `.cursor/rules/no-subagents.mdc`.
- Wait for all subagents to complete
- Collect structured status reports from each implementer
- If any implementer reports "Blocked", log the blocker and continue with others
### 7. Collect Status
**Stuck detection** — while monitoring, watch for these signals per subagent:
- Same file modified 3+ times without test pass rate improving → flag as stuck, stop the subagent, report as Blocked
- Subagent has not produced new output for an extended period → flag as potentially hung
- If a subagent is flagged as stuck, do NOT let it continue looping — stop it and record the blocker in the batch report
- After all tasks in the batch are finished, aggregate the per-task status lines into a structured batch status.
- If any task reported "Blocked", log the blocker with the failing task's ID and continue — the batch report will surface it.
**Stuck detection** — while implementing a task, watch for these signals in your own progress:
- The same file has been rewritten 3+ times without tests going green → stop, mark the task Blocked, and move to the next task in the batch (the user will be asked at the end of the batch).
- You have tried 3+ distinct approaches without evidence-driven progress → stop, mark Blocked, move on.
- Do NOT loop indefinitely on a single task. Record the blocker and proceed.
### 8. AC Test Coverage Verification
@@ -120,8 +179,8 @@ Before code review, verify that every acceptance criterion in each task spec has
- **Not covered**: no test exists for this AC
If any AC is **Not covered**:
- This is a **BLOCKING** failure — the implementer must write the missing test before proceeding
- Re-launch the implementer with the specific ACs that need tests
- This is a **BLOCKING** failure — the missing test must be written before proceeding
- Go back to the offending task, add tests for the specific ACs that lack coverage, then re-run this check
- If the test cannot run in the current environment (GPU required, platform-specific, external service), the test must still exist and skip with `pytest.mark.skipif` or `pytest.skip()` explaining the prerequisite
- A skipped test counts as **Covered** — the test exists and will run when the environment allows
@@ -134,54 +193,150 @@ Only proceed to Step 9 when every AC has a corresponding test.
### 10. Auto-Fix Gate
Auto-fix loop with bounded retries (max 2 attempts) before escalating to user:
Bounded auto-fix loop — only applies to **mechanical** findings. Critical and Security findings are never auto-fixed.
1. If verdict is **PASS** or **PASS_WITH_WARNINGS**: show findings as info, continue automatically to step 11
2. If verdict is **FAIL** (attempt 1 or 2):
- Parse the code review findings (Critical and High severity items)
- For each finding, attempt an automated fix using the finding's location, description, and suggestion
- Re-run `/code-review` on the modified files
- If now PASS or PASS_WITH_WARNINGS → continue to step 11
- If still FAIL → increment retry counter, repeat from (2) up to max 2 attempts
3. If still **FAIL** after 2 auto-fix attempts: present all findings to user (**BLOCKING**). User must confirm fixes or accept before proceeding.
**Auto-fix eligibility matrix:**
Track `auto_fix_attempts` count in the batch report for retrospective analysis.
| Severity | Category | Auto-fix? |
|----------|----------|-----------|
| Low | any | yes |
| Medium | Style, Maintainability, Performance | yes |
| Medium | Bug, Spec-Gap, Security, Architecture | escalate |
| High | Style, Scope | yes |
| High | Bug, Spec-Gap, Performance, Maintainability, Architecture | escalate |
| Critical | any | escalate |
| any | Security | escalate |
| any | Architecture (cyclic deps) | escalate |
### 11. Commit and Push
Flow:
1. If verdict is **PASS** or **PASS_WITH_WARNINGS**: show findings as info, continue to step 11
2. If verdict is **FAIL**:
- Partition findings into auto-fix-eligible and escalate (using the matrix above)
- For eligible findings, attempt fixes using location/description/suggestion, then re-run `/code-review` on modified files (max 2 rounds)
- If all remaining findings are auto-fix-eligible and re-review now passes → continue to step 11
- If any non-eligible finding exists at any point → stop auto-fixing, present the full list to the user (**BLOCKING**)
3. User must explicitly approve each non-auto-fix finding (accept, request manual fix, mark as out-of-scope) before proceeding.
Track `auto_fix_attempts` and `escalated_findings` in the batch report for retrospective analysis.
### 11. Commit (and optionally Push)
- After user confirms the batch (explicitly for FAIL, implicitly for PASS/PASS_WITH_WARNINGS):
- `git add` all changed files from the batch
- `git commit` with a message that includes ALL task IDs (tracker IDs or numeric prefixes) of tasks implemented in the batch, followed by a summary of what was implemented. Format: `[TASK-ID-1] [TASK-ID-2] ... Summary of changes`
- `git push` to the remote branch
- Ask the user whether to push to remote, unless the user previously opted into auto-push for this session
### 12. Update Tracker Status → In Testing
After the batch is committed and pushed, transition the ticket status of each task in the batch to **In Testing** via the configured work item tracker. If `tracker: local`, skip this step.
After the batch is committed (and pushed if the user approved pushing), transition the ticket status of each task in the batch to **In Testing** via the configured work item tracker. If `tracker: local`, skip this step. If a tracker operation fails unexpectedly, follow `.cursor/rules/tracker.mdc`.
### 13. Archive Completed Tasks
Move each completed task file from `TASKS_DIR/todo/` to `TASKS_DIR/done/`.
For product implementation, this archive means "batch implementation accepted." The Product Implementation Completeness Gate can still require follow-up remediation tasks before the feature is complete; it does not move original task files back to `todo/`.
### 14. Loop
- Go back to step 2 until all tasks in `todo/` are done
### 15. Final Test Run
### 14.5. Cumulative Code Review (every K batches)
- After all batches are complete, run the full test suite once
- Read and execute `.cursor/skills/test-run/SKILL.md` (detect runner, run suite, diagnose failures, present blocking choices)
- Test failures are a **blocking gate** — do not proceed until the test-run skill completes with a user decision
- When tests pass, report final summary
**Skipped entirely when `suite_level: true`** (see "Suite-level invocation context" above) — the meta-repo has no `architecture_compliance_baseline.md` to evaluate against; cross-task drift is captured by the next `monorepo-status` cycle.
- **Trigger**: every K completed batches (default `K = 3`; configurable per run via a `cumulative_review_interval` knob in the invocation context)
- **Purpose**: per-batch review (Step 9) catches batch-local issues; cumulative review catches issues that only appear when tasks are combined — architecture drift, cross-task inconsistency, duplicate symbols introduced across different batches, contracts that drifted across producer/consumer batches
- **Scope**: the union of files changed since the **last** cumulative review (or since the start of the run if this is the first)
- **Action**: invoke `.cursor/skills/code-review/SKILL.md` in **cumulative mode**. All 7 phases run, with emphasis on Phase 6 (Cross-Task Consistency), Phase 7 (Architecture Compliance), and duplicate-symbol detection across the accumulated code
- **Output**: write the report to `_docs/03_implementation/cumulative_review_batches_[NN-MM]_cycle[N]_report.md` where `[NN-MM]` is the batch range covered and `[N]` is the current `state.cycle`. When `_docs/02_document/architecture_compliance_baseline.md` exists, the report includes the `## Baseline Delta` section (carried over / resolved / newly introduced) per `code-review/SKILL.md` "Baseline delta".
- **Gate**:
- `PASS` or `PASS_WITH_WARNINGS` → continue to next batch (step 14 loop)
- `FAIL` → STOP. Present the report to the user via the Choose format:
- A) Auto-fix findings using the Auto-Fix Gate matrix in step 10, then re-run cumulative review
- B) Open a targeted refactor run (invoke refactor skill in guided mode with the findings as `list-of-changes.md`)
- C) Manually fix, then re-invoke `/implement`
- Do NOT loop to the next batch on `FAIL` — the whole point is to stop drift before it compounds
- **Interaction with Auto-Fix Gate**: Architecture findings (new category from code-review Phase 7) always escalate per the implement auto-fix matrix; they cannot silently auto-fix
- **Resumability**: if interrupted, the next invocation checks for the latest `cumulative_review_batches_*.md` and computes the changed-file set from batch reports produced after that review
### 15. Product Implementation Completeness Gate
Run this gate after all **product implementation** tasks are complete and before writing any final product implementation report or allowing autodev to proceed to testability/test decomposition. Skip this gate when (a) the remaining context is explicitly test implementation or refactoring (as determined by the task files and report filename rules), OR (b) `suite_level: true` was supplied in the invocation context (the gate's inputs do not exist in the meta-repo artifact layout — see "Suite-level invocation context" above).
**Goal**: catch the failure mode where narrow tests validate scaffold behavior while the task's actual outcome, included scope, architecture promise, or named integration remains unimplemented.
Inputs:
- Completed product task specs from `_docs/02_tasks/done/` for the current cycle
- `_docs/02_document/architecture.md`
- `_docs/02_document/system-flows.md`
- Relevant `_docs/02_document/components/*/description.md` files
- Current source code under each completed task's ownership envelope
- Batch reports and code-review reports for the current cycle
For each completed product task:
1. Read these sections from the task spec: `Description`, `Outcome`, `Scope / Included`, `Acceptance Criteria`, `Non-Functional Requirements`, `Constraints`, and explicit named technologies or integrations.
2. Compare those promises against actual source code, not only tests or report prose.
3. Search the task's owned component files for unresolved implementation markers: `placeholder`, `stub`, `reserved`, `TODO`, `NotImplemented`, `pass`, `deterministic`, `fake`, `mock`, `scaffold`, `native bridge`, and empty native/readme-only integration directories. Ignore test fixtures/mocks only when they are under test-owned paths and not used as production behavior.
4. Verify that each named runtime dependency in the task promise is integrated as production behavior, not merely represented by an interface. Examples: if a task promises FAISS, DINOv2, BASALT, LightGlue, OpenCV, RANSAC, a database, cloud service, or hardware SDK, the production code must either call that dependency or contain an adapter that loads and executes the real dependency package. A deterministic fallback, fake runner, empty `native/` package, or "bridge to be supplied later" is **FAIL** unless the task itself explicitly scoped the dependency out before implementation started.
5. Distinguish internal implementation from external prerequisites:
- Internal product capabilities (VIO, anchor verification, cache retrieval, safety wrapper, FDR, MAVLink emission) must be implemented in production code before the task can pass.
- External systems/hardware/data (Jetson device, physical camera, ArduPilot process, QGC, third-party service credentials, unavailable licensed dataset) may be `BLOCKED` only when production code exists and the missing prerequisite is outside the product boundary.
6. Verify tests exercise the real implementation path where local prerequisites exist. Environment-gated tests may skip only with an explicit prerequisite reason; they do not make missing production code complete.
7. For any architecture promise that describes an end-to-end user outcome, verify there is an executable production pipeline connecting the relevant components. Isolated component contracts and test-only harness orchestration are not enough.
8. Classify each task:
- **PASS**: task promises are implemented or explicitly out of scope in the task itself.
- **BLOCKED**: production code exists but cannot be fully verified due to external hardware/data/license/runtime prerequisites; the blocker is explicit and tests report blocked/skipped with reason.
- **FAIL**: promised production behavior is missing, only scaffolded, or only represented in tests/reports.
Save the audit to `_docs/03_implementation/implementation_completeness_cycle[N]_report.md` with:
- Per-task classification
- Evidence files/symbols checked
- Any unresolved scaffold/native placeholders
- Any named promised technologies not integrated
- Required remediation task suggestions, each sized to 5 points or less
Gate:
- If every product task is `PASS` or `BLOCKED` with explicit prerequisite evidence, continue to Final Test Run.
- If any product task is `FAIL`, STOP. Do not write the final product implementation report and do not proceed to any downstream autodev step. Completed original task files remain in `done/`; the missing work is represented by remediation tasks. Present a Choose block:
- A) Create remediation tasks now and return to implementation
- B) Mark the missing behavior explicitly out of scope in task/docs, then re-run this gate
- C) Abort for manual correction
- Recommendation must normally be A unless the user deliberately accepts reduced scope.
Remediation task creation:
1. For each `FAIL`, create one or more task specs using `.cursor/skills/decompose/templates/task.md`; each remediation task must be sized at 5 points or less.
2. Save each task to `_docs/02_tasks/todo/` with a short name prefixed by `remediate_`.
3. Set **Component** to the failed task's component and set **Dependencies** to the failed task ID plus any remediation prerequisites.
4. Create or defer tracker tickets using the same tracker rules as decompose/new-task: if tracker is available, create tickets immediately; if the user explicitly chose `tracker: local`, keep numeric prefixes with `Tracker: pending` / `Epic: pending`.
5. Append the remediation tasks to `_docs/02_tasks/_dependencies_table.md`.
6. Return to Step 1 (Parse) in **Product implementation** context. The final product implementation report can be written only after remediation tasks complete and this gate reruns without `FAIL`.
### 16. Final Test Run
- After all batches are complete, run the full test suite once unless the invoking flow's immediate next step is `Run Tests`.
- If the next flow step is `Run Tests`, record a handoff in the final implementation report and let `.cursor/skills/test-run/SKILL.md` own the full-suite gate to avoid duplicate full runs.
- When this step does run, read and execute `.cursor/skills/test-run/SKILL.md` (detect runner, run suite, diagnose failures, present blocking choices).
- Test failures are a **blocking gate** — do not proceed until the test-run skill completes with a user decision.
- When tests pass, report final summary.
## Batch Report Persistence
After each batch completes, save the batch report to `_docs/03_implementation/batch_[NN]_report.md`. Create the directory if it doesn't exist. When all tasks are complete, produce a FINAL implementation report with a summary of all batches. The filename depends on context:
After each batch completes, save the batch report to `_docs/03_implementation/batch_[NN]_cycle[N]_report.md` for feature implementation (or `batch_[NN]_report.md` for test/refactor runs). Create the directory if it doesn't exist. For product implementation, produce the FINAL implementation report only after the Product Implementation Completeness Gate passes. For test and refactor implementation, produce the FINAL report after all selected tasks complete and the full-suite gate is either run or handed off per Step 16. The filename depends on context:
- **Test implementation** (tasks from test decomposition): `_docs/03_implementation/implementation_report_tests.md`
- **Feature implementation**: `_docs/03_implementation/implementation_report_{feature_slug}.md` where `{feature_slug}` is derived from the batch task names (e.g., `implementation_report_core_api.md`)
- **Feature implementation**: `_docs/03_implementation/implementation_report_{feature_slug}_cycle{N}.md` where `{feature_slug}` is derived from the batch task names (e.g., `implementation_report_core_api_cycle2.md`) and `{N}` is the current `state.cycle` from `_docs/_autodev_state.md`. If `state.cycle` is absent (pre-migration), default to `cycle1`.
- **Refactoring**: `_docs/03_implementation/implementation_report_refactor_{run_name}.md`
- **Suite-level** (when `suite_level: true` was supplied — see "Suite-level invocation context" above): `_docs/03_implementation/suite_implementation_report_{run_name}.md`. Batch reports use `_docs/03_implementation/suite_batch_{NN}_report.md`. `{run_name}` is derived from the batch task IDs (e.g., `suite_implementation_report_az543_az549_az550.md`).
Determine the context from the task files being implemented: if all tasks have test-related names or belong to a test epic, use the tests filename; otherwise derive the feature slug from the component names.
Determine the context from the task files being implemented: if all tasks have test-related names or belong to a test epic, use the tests filename; if `suite_level: true` was supplied, use the suite filename; otherwise derive the feature slug from the component names and append the cycle suffix.
Batch report filenames must also include the cycle counter when running feature implementation: `_docs/03_implementation/batch_{NN}_cycle{N}_report.md` (test and refactor runs may use the plain `batch_{NN}_report.md` form since they are not cycle-scoped).
## Batch Report
@@ -212,9 +367,10 @@ After each batch, produce a structured report:
| Situation | Action |
|-----------|--------|
| Implementer fails same approach 3+ times | Stop it, escalate to user |
| Same task rewritten 3+ times without green tests | Mark Blocked, continue batch, escalate at batch end |
| Task blocked on external dependency (not in task list) | Report and skip |
| File ownership conflict unresolvable | ASK user |
| File ownership violated (task wrote outside OWNED) | ASK user |
| Product completeness gate finds missing promised implementation | STOP — create remediation tasks or get explicit user scope reduction |
| Test failure after final test run | Delegate to test-run skill — blocking gate |
| All tasks complete | Report final summary, suggest final commit |
| `_dependencies_table.md` missing | STOP — run `/decompose` first |
@@ -224,12 +380,13 @@ After each batch, produce a structured report:
Each batch commit serves as a rollback checkpoint. If recovery is needed:
- **Tests fail after final test run**: `git revert <batch-commit-hash>` using hashes from the batch reports in `_docs/03_implementation/`
- **Resuming after interruption**: Read `_docs/03_implementation/batch_*_report.md` files to determine which batches completed, then continue from the next batch
- **Resuming after interruption**: Read `_docs/03_implementation/batch_*_report.md` files (filtered by current `state.cycle` for feature implementation) to determine which batches completed, then continue from the next batch
- **Multiple consecutive batches fail**: Stop and escalate to user with links to batch reports and commit hashes
## Safety Rules
- Never launch tasks whose dependencies are not yet completed
- Never allow two parallel agents to write to the same file
- If a subagent fails or is flagged as stuck, stop it and report — do not let it loop indefinitely
- Always run the full test suite after all batches complete (step 15)
- Never start a task whose dependencies are not yet completed
- Never run tasks in parallel and never spawn subagents — see `.cursor/rules/no-subagents.mdc`
- If a task is flagged as stuck, stop working on it and report — do not let it loop indefinitely
- Always run the Product Implementation Completeness Gate before final product reports
- Always run or hand off the full test suite after all batches complete (step 16)
@@ -3,29 +3,31 @@
## Topological Sort with Batch Grouping
The `/implement` skill uses a topological sort to determine execution order,
then groups tasks into batches for parallel execution.
then groups tasks into batches for code review and commit. Execution within a
batch is **sequential** — see `.cursor/rules/no-subagents.mdc`.
## Algorithm
1. Build adjacency list from `_dependencies_table.md`
2. Compute in-degree for each task node
3. Initialize batch 0 with all nodes that have in-degree 0
3. Initialize the ready set with all nodes that have in-degree 0
4. For each batch:
a. Select up to 4 tasks from the ready set
b. Check file ownership — if two tasks would write the same file, defer one to the next batch
c. Launch selected tasks as parallel implementer subagents
d. When all complete, remove them from the graph and decrement in-degrees of dependents
e. Add newly zero-in-degree nodes to the next batch's ready set
a. Select up to 4 tasks from the ready set (default batch size cap)
b. Implement the selected tasks one at a time in topological order
c. When all tasks in the batch complete, remove them from the graph and
decrement in-degrees of dependents
d. Add newly zero-in-degree nodes to the ready set
5. Repeat until the graph is empty
## File Ownership Conflict Resolution
## Ordering Inside a Batch
When two tasks in the same batch map to overlapping files:
- Prefer to run the lower-numbered task first (it's more foundational)
- Defer the higher-numbered task to the next batch
- If both have equal priority, ask the user
Tasks inside a batch are executed in topological order — a task is only
started after every task it depends on (inside the batch or in a previous
batch) is done. When two tasks have the same topological rank, prefer the
lower-numbered (more foundational) task first.
## Complexity Budget
Each batch should not exceed 20 total complexity points.
If it does, split the batch and let the user choose which tasks to include.
The budget exists to keep the per-batch code review scope reviewable.
+164
View File
@@ -0,0 +1,164 @@
---
name: monorepo-cicd
description: Syncs CI/CD and infrastructure configuration at the monorepo root (compose files, install scripts, env templates, CI service tables) after one or more components changed. Reads `_docs/_repo-config.yaml` (produced by monorepo-discover) to know which CI artifacts are in play and how they're structured. Touches ONLY CI/infra files — never documentation, component directories, or per-component CI configs. Use when a component added/changed a Dockerfile path, port, env var, image tag format, or runtime dependency.
---
# Monorepo CI/CD
Propagates component changes into the repo-level CI/CD and infrastructure artifacts. Strictly scoped — never edits docs, component internals, or per-component CI configs.
## Scope — explicit
| In scope | Out of scope |
| -------- | ------------ |
| `docker-compose.*.yml` at repo root | Unified docs in `_docs/*.md` → use `monorepo-document` |
| `.env.example` / `.env.template` | Root `README.md` documentation → `monorepo-document` |
| Install scripts (`ci-*.sh`, `setup.sh`, etc.) | Per-component CI configs (`<component>/.woodpecker/*`, `<component>/.github/*`) |
| CI service-registry docs (`ci_steps.md` or similar — the human-readable index of pipelines; in scope only if the config says so under `ci.service_registry_doc`) | Component source code, Dockerfiles, or internal docs |
| Kustomization / Helm manifests at repo root | `_docs/_repo-config.yaml` itself (only `monorepo-discover` and `monorepo-onboard` write it) |
If a component change needs doc updates too, tell the user to also run `monorepo-document`.
**Special case**: `ci.service_registry_doc` (e.g., `ci_steps.md`) is a **CI artifact that happens to be markdown**. It's in this skill's scope, not `monorepo-document`'s, because it describes the pipeline/service topology — not user-facing feature docs.
## Preconditions (hard gates)
1. `_docs/_repo-config.yaml` exists.
2. Top-level `confirmed_by_user: true`.
3. `ci.*` section is populated in config (not empty).
4. Components-in-scope have confirmed CI mappings, OR user explicitly approves inferred ones.
If any gate fails, redirect to `monorepo-discover` or ask for confirmation.
## Mitigations (M1M7)
- **M1** Separation: this skill only touches CI/infra files; no docs, no component internals.
- **M3** Factual vs. interpretive: image tag format, port numbers, env var names — FACTUAL, read from code. Doc cross-references — out of scope entirely (belongs to `monorepo-document`).
- **M4** Batch questions at checkpoints.
- **M5** Skip over guess: component with no CI mapping → skip and report.
- **M6** Assumptions footer + append to `_repo-config.yaml` `assumptions_log`.
- **M7** Drift detection: verify every file in `ci.orchestration_files`, `ci.install_scripts`, `ci.env_template` exists; stop if not.
## Workflow
### Phase 1: Drift check (M7)
Verify every CI file listed in config exists on disk. Missing file → stop, ask user:
- Run `monorepo-discover` to refresh, OR
- Skip the missing file (recorded in report)
Do NOT recreate missing infra files automatically.
### Phase 2: Determine scope
Ask the user (unless specified):
> Which components changed? (a) list them, (b) auto-detect, (c) skip detection (I'll apply specific changes).
For **auto-detect**, for each component:
```bash
git -C <path> log --oneline -20 # submodule
# or
git log --oneline -20 -- <path> # monorepo subfolder
```
Flag commits that touch CI-relevant concerns:
- Dockerfile additions, renames, or path changes
- CI pipeline files (`<component>/.woodpecker/*`, `<component>/.github/workflows/*`, etc.)
- New exposed ports
- New environment variables consumed by the component
- Changes to image name / tag format
- New dependency on another service (e.g., new DB, new broker)
Present the flagged list; confirm.
### Phase 3: Classify changes per component
| Change type | Target CI files |
| ----------- | --------------- |
| Dockerfile path moved/renamed | `ci.service_registry_doc` service table; per-component CI is OUT OF SCOPE (tell user to update it) |
| New port exposed | `ci.service_registry_doc` ports section (if infra port); component's service block in orchestration file |
| Registry URL changed | `ci.install_scripts` (all of them); `ci.env_template`; `ci.service_registry_doc` |
| Branch naming convention changed | All `ci.install_scripts`; all `ci.orchestration_files` referencing the branch; `ci.service_registry_doc` |
| New runtime env var | `ci.env_template`; component's service block in orchestration file |
| New infrastructure component (DB, cache, broker) | Relevant `ci.orchestration_files`; `ci.service_registry_doc` architecture section |
| New image tag format | All `ci.orchestration_files`; `ci.install_scripts`; `ci.service_registry_doc` |
| Watchtower/polling config change | Specific `ci.orchestration_files`; `ci.service_registry_doc` |
If a change type isn't covered here or in the config, add to an unresolved list and skip (M5).
### Phase 4: Apply edits
For each (change → target file) pair:
1. Read the target file.
2. Locate the service block / table row / section.
3. Edit carefully:
- **Orchestration files (compose/kustomize/helm)**: YAML; preserve indentation, anchors, and references exactly. Match existing service-block structure. Never reformat unchanged lines.
- **Install scripts (`*.sh`)**: shell; any edit must remain **idempotent**. Re-running the script on an already-configured host must not break it. If an edit cannot be made idempotent, flag for the user and skip.
- **`.env.example`**: append new vars at the appropriate section; never remove user's local customizations (file is in git, so comments may be significant).
- **`ci.service_registry_doc`** (markdown): preserve column widths, ordering (alphabetical or compose-order — whichever existed), ASCII diagrams.
### Phase 5: Skip-and-report (M5)
Skip a component if:
- No `ci_config` in its config entry AND no entry in config's CI mappings
- `confirmed: false` on its mapping and user didn't approve
- Component's Dockerfile path declared in config doesn't exist on disk — surface contradiction
- Change type unrecognized — skip, report for manual handling
### Phase 6: Idempotency / lint check
- Shell: if `shellcheck` available, run on any edited `*.sh`.
- YAML: if `yamllint` or `prettier` available, run on edited `*.yml` / `*.yaml`.
- For edited install scripts, **mentally re-run** the logic: would a second invocation crash, duplicate, or corrupt? Flag anything that might.
Skip linters silently if none configured — don't install tools.
### Phase 7: Report + assumptions footer (M6)
```
monorepo-cicd run complete.
CI files updated (N):
- docker-compose.run.yml — added `loader` service block
- .env.example — added LOADER_BUCKET_NAME placeholder
- ci_steps.md — added `loader` row in service table
Skipped (K):
- satellite-provider: no ci_config in repo-config.yaml
- detections: Dockerfile path in config (admin/src/Dockerfile) does not exist on disk
Manual actions needed (M):
- Update `<submodule>/.woodpecker/*.yml` inside the submodule's own workspace
(per-component CI is not maintained by this skill)
Assumptions used this run:
- image tag format: ${REGISTRY}/${NAME}:${BRANCH}-${ARCH_TAG} (confirmed in config)
- target branch for triggers: [stage, main] (confirmed in config)
Next step: review the diff, then commit with
`<commit_prefix> Sync CI after <components>` (or your own message).
```
Append run entry to `_docs/_repo-config.yaml` `assumptions_log:`.
## What this skill will NEVER do
- Modify files inside component directories
- Edit unified docs under `docs.root`
- Edit per-component CI configs (`.woodpecker/*`, `.github/*`, etc.)
- Auto-generate CI pipeline YAML for components (only provide template guidance)
- Set `confirmed_by_user` or `confirmed:` flags
- Auto-commit
- Install tools (shellcheck, yamllint, etc.) — use if present, skip if absent
## Edge cases
- **Compose file has service blocks for components NOT in config**: note in report; ask user whether to rediscover (`monorepo-discover`) or leave them alone.
- **`.env.example` has entries for removed components**: don't auto-remove; flag to user.
- **Install script edit cannot be made idempotent**: don't save; ask user to handle manually.
- **Branch trigger vs. runtime branch mismatch**: if config says triggers are `[stage, main]` but a compose file references a branch tag `develop`, stop and ask.
+183
View File
@@ -0,0 +1,183 @@
---
name: monorepo-discover
description: Scans a monorepo or meta-repo (git-submodule aggregators, npm/cargo workspaces, etc.) and generates a human-reviewable `_docs/_repo-config.yaml` that other `monorepo-*` skills (document, cicd, onboard, status) read. Produces inferred mappings tagged with evidence; never writes to the config's `confirmed_by_user` flag — the human does that. Use on first setup in a new monorepo, or to refresh the config after structural changes.
---
# Monorepo Discover
Writes or refreshes `_docs/_repo-config.yaml` — the shared config file that every other `monorepo-*` skill depends on. Does NOT modify any other files.
## Core principle
**Discovery is a suggestion, not a commitment.** The skill infers repo structure, but every inferred entry is tagged with `confirmed: false` + evidence. Action skills (`monorepo-document`, `monorepo-cicd`, `monorepo-onboard`) refuse to run until the human reviews the config and sets `confirmed_by_user: true`.
## Mitigations against LLM inference errors (applies throughout)
| Rule | What it means |
| ---- | ------------- |
| **M1** Separation | This skill never triggers other skills. It stops after writing config. |
| **M2** Evidence thresholds | No mapping gets recorded without at least one signal (name match, textual reference, directory convention, explicit statement). Zero-signal candidates go under `unresolved:` with a question. |
| **M3** Factual vs. interpretive | Resolve factual questions alone (file exists? line says what?). Ask for interpretive ones (does A feed into B?) unless M2 evidence is present. Ask for conventional ones always (commit prefix? target branch?). |
| **M4** Batch questions | Accumulate all `unresolved:` questions. Present at end of discovery, not drip-wise. |
| **M5** Skip over guess | Never record a zero-evidence mapping under `components:` or `docs:` — always put it in `unresolved:` with a question. |
| **M6** Assumptions footer | Every run ends with an explicit list of assumptions used. Also append to `assumptions_log:` in the config. |
| **M7** Structural drift | If the config already exists, produce a diff of what would change and ask for approval before overwriting. Never silently regenerate. |
## Guardrail
**This skill writes ONLY `_docs/_repo-config.yaml`.** It never edits unified docs, CI files, or component directories. If the workflow ever pushes you to modify anything else, stop.
## Workflow
### Phase 1: Detect repo type
Check which of these exists (first match wins):
1. `.gitmodules`**git-submodules meta-repo**
2. `package.json` with `workspaces` field → **npm/yarn/pnpm workspace**
3. `pnpm-workspace.yaml`**pnpm workspace**
4. `Cargo.toml` with `[workspace]` section → **cargo workspace**
5. `go.work`**go workspace**
6. Multiple top-level subfolders each with their own `package.json` / `Cargo.toml` / `pyproject.toml` / `*.csproj`**ad-hoc monorepo**
If none match → **ask the user** what kind of monorepo this is. Don't guess.
Record in `repo.type` and `repo.component_registry`.
### Phase 2: Enumerate components
Based on repo type, parse the registry and list components. For each collect:
- `name`, `path`
- `stack` — infer from files present (`.csproj` → .NET, `pyproject.toml` → Python, `Cargo.toml` → Rust, `package.json` → Node/TS, `go.mod` → Go). Multiple signals → pick dominant one. No signals → `stack: unknown` and add to `unresolved:`.
- `evidence` — list of signals used (e.g., `[gitmodules_entry, csproj_present]`)
Do NOT yet populate `primary_doc`, `secondary_docs`, `ci_config`, or `deployment_tier` — those come in Phases 4 and 5.
### Phase 3: Locate docs root
Probe in order: `_docs/`, `docs/`, `documentation/`, or a root-level README with links to sub-docs.
- Multiple candidates → ask user which is canonical
- None → `docs.root: null` + flag under `unresolved:`
Once located, classify each `*.md`:
- **Primary doc** — filename or H1 names a component/feature
- **Cross-cutting doc** — describes repo-wide concerns (architecture, schema, auth, index)
- **Index** — `README.md`, `index.md`, or `_index.md`
Detect filename convention (e.g., `NN_<name>.md`) and next unused prefix.
### Phase 4: Map components to docs (inference, M2-gated)
For each component, attempt to find its **primary doc** using the evidence rules. A mapping qualifies for `components:` (with `confirmed: false`) if at least ONE of these holds:
- **Name match** — component name appears in the doc filename OR H1
- **Textual reference** — doc body explicitly names the component path or git URL
- **Directory convention** — doc lives inside the component's folder
- **Explicit statement** — README, index, or comment asserts the mapping
No signal → entry goes under `unresolved:` with an A/B/C question, NOT under `components:` as a guess.
Cross-cutting docs go in `docs.cross_cutting:` with an `owns:` list describing what triggers updates to them. If you can't classify a doc, add an `unresolved:` entry asking the user.
### Phase 5: Detect CI tooling
Probe at repo root AND per-component for CI configs:
- `.github/workflows/*.yml` → GitHub Actions
- `.gitlab-ci.yml` → GitLab CI
- `.woodpecker/` or `.woodpecker.yml` → Woodpecker
- `.drone.yml` → Drone
- `Jenkinsfile` → Jenkins
- `bitbucket-pipelines.yml` → Bitbucket
- `azure-pipelines.yml` → Azure Pipelines
- `.circleci/config.yml` → CircleCI
Probe for orchestration/infra at root:
- `docker-compose*.yml`
- `kustomization.yaml`, `helm/`
- `Makefile` with build/deploy targets
- `*-install.sh`, `*-setup.sh`
- `.env.example`, `.env.template`
Record under `ci:`. For image tag formats, grep compose files for `image:` lines and record the pattern (e.g., `${REGISTRY}/${NAME}:${BRANCH}-${ARCH}`).
Anything ambiguous → `unresolved:` entry.
### Phase 6: Detect conventions
- **Commit prefix**: `git log --format=%s -50` → look for `[PREFIX]` consistency
- **Target/work branch**: check CI config trigger branches; fall back to `git remote show origin`
- **Ticket ID pattern**: grep commits and docs for regex like `[A-Z]+-\d+`
- **Image tag format**: see Phase 5
- **Deployment tiers**: scan root README and architecture docs for named tiers/environments
Record inferred conventions with `confirmed: false`.
### Phase 7: Read existing config (if any) and produce diff
If `_docs/_repo-config.yaml` already exists:
1. Parse it.
2. Compare against what Phases 16 discovered.
3. Produce a **diff report**:
- Entries added (new components, new docs)
- Entries changed (e.g., `primary_doc` changed due to doc renaming)
- Entries removed (component removed from registry)
4. **Ask the user** whether to apply the diff.
5. If applied, **preserve `confirmed: true` flags** for entries that still match — don't reset human-approved mappings.
6. **Preserve user-owned top-level keys verbatim**: `glossary_doc:` (written by autodev meta-repo Step 2.5) and any `assumptions_log:` entries are NEVER edited or removed by this skill. Carry them through unchanged. If the file referenced by `glossary_doc:` no longer exists on disk, surface as an `unresolved:` question — do not auto-clear the field.
7. If user declines, stop — leave config untouched.
### Phase 8: Batch question checkpoint (M4)
Present ALL accumulated `unresolved:` questions in one round. For each offer options when possible (A/B/C), open-ended only when no options exist.
After answers, update the draft config with the resolutions.
### Phase 9: Write config file
Write `_docs/_repo-config.yaml` using the schema in [templates/repo-config.example.yaml](templates/repo-config.example.yaml).
- Top-level `confirmed_by_user: false` ALWAYS — only the human flips this
- Every entry has `confirmed: <bool>` and (when `false`) `evidence: [...]`
- Append to `assumptions_log:` a new entry for this run
### Phase 10: Review handoff + assumptions footer (M6)
Output:
```
Generated/refreshed _docs/_repo-config.yaml:
- N components discovered (X confirmed, Y inferred, Z unresolved)
- M docs located (K primary, L cross-cutting)
- CI tooling: <detected>
- P unresolved questions resolved this run; Q still open — see config
- Assumptions made during discovery:
- Treated <path> as unified-docs root (only candidate found)
- Inferred `<component>` primary doc = `<doc>` (name match)
- Commit prefix `<prefix>` seen in N of last 20 commits
Next step: please review _docs/_repo-config.yaml, correct any wrong inferences,
and set `confirmed_by_user: true` at the top. After that, monorepo-document,
monorepo-cicd, monorepo-status, and monorepo-onboard will run.
```
Then stop.
## What this skill will NEVER do
- Modify any file other than `_docs/_repo-config.yaml`
- Set `confirmed_by_user: true`
- Record a mapping with zero evidence
- Chain to another skill automatically
- Commit the generated config
## Failure / ambiguity handling
- Internal contradictions in a component (README references files not in code) → surface to user, stop, do NOT silently reconcile
- Docs root cannot be located → record `docs.root: null` and list unresolved question; do not create a new `_docs/` folder
- Parsing fails on `_docs/_repo-config.yaml` (existing file is corrupt) → surface to user, stop; never overwrite silently
@@ -0,0 +1,172 @@
# _docs/_repo-config.yaml — schema and example
#
# Generated by monorepo-discover. Reviewed by a human. Consumed by:
# - monorepo-document (reads docs.* and components.*.primary_doc/secondary_docs)
# - monorepo-cicd (reads ci.* and components.*.ci_config)
# - monorepo-onboard (reads all sections; writes new component entries)
# - monorepo-status (reads all sections; writes nothing)
#
# Every entry has a `confirmed:` flag:
# true = human reviewed and approved
# false = inferred by monorepo-discover; needs review
# And an `evidence:` list documenting why discovery made the inference.
# ---------------------------------------------------------------------------
# Metadata
# ---------------------------------------------------------------------------
version: 1
last_updated: 2026-04-17
confirmed_by_user: false # HUMAN ONLY: flip to true after reviewing
# ---------------------------------------------------------------------------
# Repo identity
# ---------------------------------------------------------------------------
repo:
name: example-monorepo
type: git-submodules # git-submodules | npm-workspaces | cargo-workspace | pnpm-workspace | go-workspace | adhoc
component_registry: .gitmodules
root_readme: README.md
work_branch: dev
# ---------------------------------------------------------------------------
# Components
# ---------------------------------------------------------------------------
components:
- name: annotations
path: annotations/
stack: .NET 10
confirmed: true
evidence: [gitmodules_entry, csproj_present]
primary_doc: _docs/01_annotations.md
secondary_docs:
- _docs/00_database_schema.md
- _docs/00_roles_permissions.md
ci_config: annotations/.woodpecker/
deployment_tier: api-layer
ports:
- "5001/http"
depends_on: []
env_vars:
- ANNOTATIONS_DB_URL
- name: loader
path: loader/
stack: Python 3.12
confirmed: false # inferred, needs review
evidence: [gitmodules_entry, pyproject_present]
primary_doc: _docs/07_admin.md
primary_doc_section: "Model delivery"
secondary_docs:
- _docs/00_top_level_architecture.md
ci_config: loader/.woodpecker/
deployment_tier: edge
ports: []
depends_on: [admin]
env_vars: []
# ---------------------------------------------------------------------------
# Documentation
# ---------------------------------------------------------------------------
docs:
root: _docs/
index: _docs/README.md
file_convention: "NN_<name>.md"
next_unused_prefix: "13"
cross_cutting:
- path: _docs/00_top_level_architecture.md
owns:
- deployment topology
- component communication
- infrastructure inventory
confirmed: true
- path: _docs/00_database_schema.md
owns:
- database schema changes
- ER diagram
confirmed: true
- path: _docs/00_roles_permissions.md
owns:
- permission codes
- role-to-feature mapping
confirmed: true
# ---------------------------------------------------------------------------
# CI/CD
# ---------------------------------------------------------------------------
ci:
tooling: Woodpecker # GitHub Actions | GitLab CI | Woodpecker | Drone | Jenkins | ...
service_registry_doc: ci_steps.md
orchestration_files:
- docker-compose.ci.yml
- docker-compose.run.yml
- docker-compose.ci-agent-amd64.yml
install_scripts:
- ci-server-install.sh
- ci-client-install.sh
- ci-agent-amd64-install.sh
env_template: .env.example
image_tag_format: "${REGISTRY}/${NAME}:${BRANCH}-${ARCH_TAG}"
branch_triggers: [stage, main]
expected_files_per_component:
- path_glob: "<component>/.woodpecker/build-*.yml"
required: at-least-one
pipeline_template: |
when:
branch: [stage, main]
labels:
platform: arm64
steps:
- name: build-push
image: docker
commands:
- docker build -f Dockerfile -t localhost:5000/<service>:${CI_COMMIT_BRANCH}-arm .
- docker push localhost:5000/<service>:${CI_COMMIT_BRANCH}-arm
volumes:
- /var/run/docker.sock:/var/run/docker.sock
confirmed: false
# ---------------------------------------------------------------------------
# Conventions
# ---------------------------------------------------------------------------
conventions:
commit_prefix: "[suite]"
meta_commit_fallback: "[meta]"
ticket_id_pattern: "AZ-\\d+"
component_naming: lowercase-hyphen
deployment_tiers:
- edge
- remote
- operator-station
- api-layer
confirmed: false
# ---------------------------------------------------------------------------
# Unresolved questions (populated by monorepo-discover)
# ---------------------------------------------------------------------------
# Every question discovery couldn't resolve goes here. Action skills refuse
# to touch entries that map to `unresolved:` items until the human resolves them.
unresolved:
- id: satellite-provider-doc-slot
question: "Component `satellite-provider` has no matching doc. Create new file or extend an existing doc?"
options:
- "new _docs/13_satellite_provider.md"
- "extend _docs/11_gps_denied.md with a Satellite section"
- "no doc needed (internal utility)"
# ---------------------------------------------------------------------------
# Assumptions log (append-only, audit trail)
# ---------------------------------------------------------------------------
# monorepo-discover appends a new entry each run.
# monorepo-document, monorepo-cicd, monorepo-onboard also append their
# per-run assumptions here so the user can audit what was taken on faith.
assumptions_log:
- date: 2026-04-17
skill: monorepo-discover
run_notes: "Initial discovery"
assumptions:
- "Treated _docs/ as unified-docs root (only candidate found)"
- "Inferred component→doc mappings via name matching for 9/11 components"
- "Commit prefix [suite] observed in 14 of last 20 commits"
+179
View File
@@ -0,0 +1,179 @@
---
name: monorepo-document
description: Syncs unified documentation (`_docs/*.md` and equivalent) in a monorepo after one or more components changed. Reads `_docs/_repo-config.yaml` (produced by monorepo-discover) to know which doc files each component feeds into and which cross-cutting docs own which concerns. Touches ONLY documentation files — never CI, compose, env templates, or component directories. Use when a submodule/package added/changed an API, schema, permission, event, or dependency and the unified docs need to catch up.
---
# Monorepo Document
Propagates component changes into the unified documentation set. Strictly scoped to `*.md` files under `docs.root` (and `repo.root_readme` if referenced as cross-cutting).
## Scope — explicit
| In scope | Out of scope |
| -------- | ------------ |
| `_docs/*.md` (primary and cross-cutting) | `.env.example`, `docker-compose.*.yml` → use `monorepo-cicd` |
| Root `README.md` **only** if `_repo-config.yaml` lists it as a doc target (e.g., services table) | Install scripts (`ci-*.sh`) → use `monorepo-cicd` |
| Docs index (`_docs/README.md` or similar) cross-reference tables | Component-internal docs (`<component>/README.md`, `<component>/docs/*`) |
| Cross-cutting docs listed in `docs.cross_cutting` | `_docs/_repo-config.yaml` itself (only `monorepo-discover` and `monorepo-onboard` write it) |
| Body of cross-cutting docs **except** the `## Architecture Vision` section (preserved verbatim — owned by autodev meta-repo Step 2.5) | The file at `glossary_doc:` (user-confirmed; only autodev meta-repo Step 2.5 rewrites it). New project terms surfaced during sync are reported back to the user, not silently appended |
| `## Architecture Vision` body — read-only, may be referenced for terminology consistency but never edited | — |
If a component change requires CI/env updates too, tell the user to also run `monorepo-cicd`. This skill does NOT cross domains.
## Preconditions (hard gates)
1. `_docs/_repo-config.yaml` exists.
2. Top-level `confirmed_by_user: true` in the config.
3. `docs.root` is set (non-null) in the config.
4. Components-in-scope have `confirmed: true` mappings, OR the user explicitly approves an inferred mapping for this run.
If any gate fails:
- Config missing → redirect: "Run `monorepo-discover` first."
- `confirmed_by_user: false` → "Please review the config and set `confirmed_by_user: true`."
- `docs.root: null` → "Config has no docs root. Run `monorepo-discover` to re-detect, or edit the config."
- Component inferred but not confirmed → ask user: "Mapping `<component>``<doc>` is inferred. Use it this run? (y/n/edit config first)"
## Mitigations (same M1M7 spirit)
- **M1** Separation: this skill only syncs docs; never touches CI or config.
- **M3** Factual vs. interpretive: don't guess mappings. Use config. If config has an `unresolved:` entry for a component in scope, SKIP it (M5) and report.
- **M4** Batch questions at checkpoints: end of scope determination, end of drift check.
- **M5** Skip over guess: missing/ambiguous mapping → skip and report, never pick a default.
- **M6** Assumptions footer every run; append to config's `assumptions_log:`.
- **M7** Drift detection before action: re-scan `docs.root` to verify config-listed docs still exist; if not, stop and ask.
## Workflow
### Phase 1: Drift check (M7)
Before editing anything:
1. For each component in scope, verify its `primary_doc` and each `secondary_docs` file exists on disk.
2. For each entry in `docs.cross_cutting`, verify the file exists.
3. If any expected file is missing → **stop**, ask user whether to:
- Run `monorepo-discover` to refresh the config, OR
- Skip the missing file for this run (recorded as skipped in report)
Do NOT silently create missing docs. That's onboarding territory.
### Phase 2: Determine scope
If the user hasn't specified which components changed, ask:
> Which components changed? (a) list them, (b) auto-detect from recent commits, (c) skip to review changes you've already made.
For **auto-detect**, for each component in config:
```bash
git -C <path> log --oneline -20 # submodule
# or
git log --oneline -20 -- <path> # monorepo subfolder
```
Flag components whose recent commits touch doc-relevant concerns:
- API/route files (controllers, handlers, OpenAPI specs, route definitions)
- Schema/migration files
- Auth/permission files (attributes, middleware, policies)
- Streaming/SSE/websocket event definitions
- Public exports (`index.ts`, `mod.rs`, `__init__.py`)
- Component's own README if it documents API
- Environment variable additions (only impact docs if a Configuration section exists)
Present the flagged list; ask for confirmation before proceeding.
### Phase 3: Classify changes per component
For each in-scope component, read recent diffs and classify changes:
| Change type | Target doc concern |
| ----------- | ------------------ |
| New/changed REST endpoint | Primary doc API section; cross-cutting arch doc if pattern changes |
| Schema/migration | Cross-cutting schema doc; primary doc if entity documented there |
| New permission/role | Cross-cutting roles/permissions doc; index permission-matrix table |
| New streaming/SSE event | Primary doc events section; cross-cutting arch doc |
| New inter-component dependency | Cross-cutting arch doc; primary doc dependencies section |
| New env variable (affects docs) | Primary doc Configuration section only — `.env.example` is out of scope |
Match concerns to docs via `docs.cross_cutting[].owns`. If a concern has no owner, add to an in-memory unresolved list and skip it (M5) — tell the user at the end.
### Phase 4: Apply edits
For each mapping (component change → target doc):
1. Read the target doc.
2. Locate the relevant section (heading match, anchor, or `primary_doc_section` from config).
3. Edit only that section. Preserve:
- Heading structure and anchors (inbound links depend on them)
- Table column widths / alignment style
- ASCII diagrams (characters, indentation, widths)
- Cross-reference wording style
4. Update cross-references when needed: if a renamed doc is linked elsewhere, fix links too.
### Phase 5: Skip-and-report (M5)
Skip a component, don't guess, if:
- No mapping in config (the component itself isn't listed)
- Mapping tagged `confirmed: false` and user didn't approve it in Phase 2
- Component internally inconsistent (README asserts endpoints not in code) — surface contradiction
Each skip gets a line in the report with the reason.
### Phase 6: Lint / format
Run markdown linter or formatter if the project has one (check for `.markdownlintrc`, `prettier`, or similar at repo root). Skip if none.
### Phase 7: Report + assumptions footer (M6)
Output:
```
monorepo-document run complete.
Docs updated (N):
- _docs/01_flights.md — added endpoint POST /flights/gps-denied-start
- _docs/00_roles_permissions.md — added permission `FLIGHTS.GPS_DENIED.OPERATE`
- _docs/README.md — permission-matrix row updated
Skipped (K):
- satellite-provider: no confirmed mapping (config has unresolved entry)
- detections-semantic: internal README references endpoints not in code — needs reconciliation
Assumptions used this run:
- component `flights` → `_docs/02_flights.md` (user-confirmed in config)
- roles doc = `_docs/00_roles_permissions.md` (user-confirmed cross-cutting)
- target branch: `dev` (from conventions.work_branch)
Next step: review the diff in your editor, then commit with
`<commit_prefix> Sync docs after <components>` (or your own message).
```
Append to `_docs/_repo-config.yaml` under `assumptions_log:`:
```yaml
- date: 2026-04-17
skill: monorepo-document
run_notes: "Synced <components>"
assumptions:
- "<list>"
```
## What this skill will NEVER do
- Modify files inside component directories
- Edit CI files, compose files, install scripts, or env templates
- Create new doc files (that's `monorepo-onboard`)
- Change `confirmed_by_user` or any `confirmed: <bool>` flag
- Auto-commit or push
- Guess a mapping not in the config
- Edit `glossary_doc:` (the file recorded under the config's `glossary_doc:` key)
- Edit the `## Architecture Vision` section of any cross-cutting doc; if a sync would conflict with that section, surface the conflict to the user and skip — do not silently rewrite user-confirmed content
## Edge cases
- **Component has no primary doc** (UI component that spans all feature docs): if config has `primary_doc: null` or similar marker, iterate through `docs.cross_cutting` where the component is referenced. Don't invent a doc.
- **Multiple components touch the same cross-cutting doc in one run**: apply sequentially; after each edit re-read to get updated line numbers.
- **Cosmetic-only changes** (whitespace renames, internal refactors without API changes): inform user, ask whether to sync or skip.
- **Large gap** (doc untouched for months, component has dozens of commits): ask user which commits matter — don't reconstruct full history.
+152
View File
@@ -0,0 +1,152 @@
---
name: monorepo-e2e
description: Syncs the suite-level integration e2e harness (`e2e/docker-compose.suite-e2e.yml`, fixtures, Playwright runner) when component contracts drift in ways that affect the cross-service scenario. Reads `_docs/_repo-config.yaml` to know which suite-e2e artifacts are in play. Touches ONLY suite-e2e files — never per-component CI, docs, or component internals. Use when a component changes a port, env var, public API endpoint, DB schema column, or detection model that the suite e2e exercises.
---
# Monorepo Suite-E2E
Propagates component changes into the suite-level integration e2e harness. Strictly scoped — never edits docs, component internals, per-component CI configs, or the production deploy compose.
## Scope — explicit
| In scope | Out of scope |
| -------- | ------------ |
| `e2e/docker-compose.suite-e2e.yml` (overlay, healthchecks, seed services) | Production `_infra/deploy/<target>/docker-compose.yml``monorepo-cicd` owns it |
| `e2e/fixtures/init.sql` (seeded rows that the spec depends on) | Component DB migrations — owned by each component |
| `e2e/fixtures/expected_detections.json` (detection baseline) | Detection model itself — owned by `detections/` |
| `e2e/runner/tests/*.spec.ts` selector / contract-driven edits | New scenarios (user-driven, not drift-driven) |
| `e2e/runner/Dockerfile` / `package.json` Playwright version bumps | Net-new e2e infrastructure (use `monorepo-onboard` or initial scaffolding) |
| `.woodpecker/suite-e2e.yml` (suite-level pipeline) | Per-component `.woodpecker/01-test.yml` / `02-build-push.yml``monorepo-cicd` owns those |
| Suite-e2e leftover entries under `_docs/_process_leftovers/` | Per-component leftovers — owned by each component |
If a component change needs doc updates too, tell the user to also run `monorepo-document`. If it needs production-deploy or per-component CI updates, run `monorepo-cicd`. This skill **only** updates the suite-e2e surface.
## Preconditions (hard gates)
1. `_docs/_repo-config.yaml` exists.
2. Top-level `confirmed_by_user: true`.
3. `suite_e2e.*` section is populated in config (see "Required config block" below). If absent, abort and ask the user to extend the config via `monorepo-discover`.
4. Components-in-scope have confirmed contract mappings (port, public API path, DB tables touched), OR user explicitly approves inferred ones.
## Required config block
This skill expects `_docs/_repo-config.yaml` to carry:
```yaml
suite_e2e:
overlay: e2e/docker-compose.suite-e2e.yml
fixtures:
init_sql: e2e/fixtures/init.sql
baseline_json: e2e/fixtures/expected_detections.json
binary_fixtures:
- e2e/fixtures/sample.mp4
- e2e/fixtures/model.tar.gz
runner:
dockerfile: e2e/runner/Dockerfile
package_json: e2e/runner/package.json
spec_dir: e2e/runner/tests
pipeline: .woodpecker/suite-e2e.yml
scenario:
description: "Upload video → detect → overlays → dataset → DB persistence"
components_exercised:
- ui
- annotations
- detections
- postgres-local
api_contracts:
- component: ui
path: /api/admin/auth/login
- component: annotations
path: /api/annotations/media/batch
- component: annotations
path: /api/annotations/media/{id}/annotations
db_tables:
- media
- annotations
- detection
- detection_classes
model_pin:
detections_repo_path: <path-to-model-config-or-classes-source>
classes_source: annotations/src/Database/DatabaseMigrator.cs
```
If `suite_e2e:` is missing the skill **stops** — it does not invent a default mapping.
## Mitigations (M1M7)
- **M1** Separation: this skill only touches suite-e2e files; no production deploy compose, no per-component CI, no docs, no component internals.
- **M3** Factual vs. interpretive: port, env var, API path, DB column — FACTUAL, read from the components' code. Whether a baseline still matches the model — DEFERRED to the user (the skill flags drift, never silently re-records).
- **M4** Batch questions at checkpoints.
- **M5** Skip over guess: a component change that doesn't map cleanly to one of the in-scope artifacts → skip and report.
- **M6** Assumptions footer + append to `_repo-config.yaml` `assumptions_log`.
- **M7** Drift detection: verify every path under `suite_e2e.*` exists on disk; stop if not.
## Workflow
### Phase 1: Drift check (M7)
Verify every file listed under `suite_e2e.*` (excluding `binary_fixtures`, which are gitignored) exists on disk. Missing file → stop and ask:
- Run `monorepo-discover` to refresh, OR
- Skip the missing artifact (recorded in report)
For `binary_fixtures` paths that are absent (expected — they live in S3/LFS), check whether `expected_detections.json._meta.video_sha256` is still a `TBD-...` placeholder. If yes, surface this as a known leftover (`_docs/_process_leftovers/2026-04-22_suite-e2e-binary-fixtures.md`) and continue.
### Phase 2: Determine scope
Same as `monorepo-cicd` Phase 2 — ask the user, or auto-detect. For **auto-detect**, flag commits that touch suite-e2e-relevant concerns:
| Commit pattern | Suite-e2e impact |
| -------------- | ---------------- |
| New port exposed by `<component>` | Healthcheck override may change in `e2e/docker-compose.suite-e2e.yml` |
| New required env var on `<component>` | `e2e/docker-compose.suite-e2e.yml` `e2e-runner` env block + `init.sql` seed |
| Public API path renamed / removed | Spec selector / API call path in `e2e/runner/tests/*.spec.ts` |
| DB schema column renamed in a `db_tables` entry | `init.sql` column reference + spec `pg.query` text |
| New required DB table referenced by spec | `init.sql` insert block (skip if owned by component migration) |
| Detection model rev change in `detections/` | `expected_detections.json` `_meta.model.revision` + flag baseline as stale |
| New canonical detection class added | `expected_detections.json._meta` annotation |
Present the flagged list; confirm.
### Phase 3: Classify changes per component
| Change type | Target suite-e2e files |
| ----------- | ---------------------- |
| Port / env var change | `e2e/docker-compose.suite-e2e.yml` |
| API path / contract change | `e2e/runner/tests/*.spec.ts` |
| DB schema reference change | `e2e/fixtures/init.sql` and spec SQL queries |
| Model / class catalog change | `e2e/fixtures/expected_detections.json` (mark `_meta.fixture_version` bump + leftover entry for binary refresh) |
| Playwright dependency drift | `e2e/runner/package.json` + `e2e/runner/Dockerfile` |
| Suite scenario steps gone stale | **Stop and ask** — scenario edits are user-driven, not drift-driven |
### Phase 4: Apply edits
Edit each in-scope file. After each batch, run `ReadLints` on touched files. Do NOT run the suite e2e itself — that's a downstream pipeline operation, not a sync-skill responsibility.
For `expected_detections.json`: when the model revision changes, the skill **does not** re-record the baseline — the binary fixture cannot be regenerated from the dev environment. Instead:
1. Set `_meta.model.revision` to the new revision.
2. Set `_meta.fixture_version` to a new bumped version with a `-stale` suffix (e.g., `0.2.0-stale`).
3. Append a new entry to `_docs/_process_leftovers/` describing the required re-record.
4. Leave `expected.by_class` untouched — the spec's tolerance check will fail loudly until the binary refresh lands.
### Phase 5: Update assumptions log
Append a new `assumptions_log:` entry to `_docs/_repo-config.yaml` recording:
- Date, components in scope, which suite-e2e files were touched
- Any inferred contract mappings still tagged `confirmed: false`
- Any leftover entries created
### Phase 6: Report
Render a Choose-format summary of the synced files, surface any `_process_leftovers/` entries created, and end. Do NOT auto-commit.
## Self-verification
- [ ] No file outside `e2e/`, `.woodpecker/suite-e2e.yml`, or `_docs/_process_leftovers/` was edited
- [ ] `_docs/_repo-config.yaml` `suite_e2e:` block was not silently mutated except for `assumptions_log` append
- [ ] `expected_detections.json` was not re-recorded (only metadata bumped + leftover added)
- [ ] Every spec edit traces to a flagged commit pattern in Phase 2
- [ ] `ReadLints` clean on every touched file
## Failure handling
Same retry / escalation protocol as `monorepo-cicd` — see `protocols.md`. The most common failure mode is the binary-fixture leftover (sample.mp4 missing or SHA-mismatched); this skill does not attempt to resolve it, only surfaces it.
+248
View File
@@ -0,0 +1,248 @@
---
name: monorepo-onboard
description: Adds a new component (submodule / package / workspace member) to a monorepo as a single atomic operation. Updates the component registry (`.gitmodules` / `package.json` workspaces / `Cargo.toml` / etc.), places or extends unified docs, updates CI/compose/env artifacts, and appends an entry to `_docs/_repo-config.yaml`. Intentionally monolithic — onboarding is one user intent that spans multiple artifact domains. Use when the user says "onboard X", "add service Y to the monorepo", "register new repo".
---
# Monorepo Onboard
Onboards a new component atomically. Spans registry + docs + CI + env + config in one coordinated run — because onboarding is a single user intent, and splitting it across multiple skills would fragment the user experience, cause duplicate input collection, and create inconsistent intermediate states in the config file.
## Why this skill is monolithic
Onboarding ONE component requires updating ~8 artifacts. If the user had to invoke `monorepo-document`, `monorepo-cicd`, and a registry skill separately, they would answer overlapping questions 23 times, and the config file would pass through invalid states between runs. Monolithic preserves atomicity and consistency.
Sync operations (after onboarding is done) ARE split by artifact — see `monorepo-document` and `monorepo-cicd`.
## Preconditions (hard gates)
1. `_docs/_repo-config.yaml` exists.
2. Top-level `confirmed_by_user: true`.
3. The component is NOT already in `components:` — if it is, redirect to `monorepo-document` or `monorepo-cicd` (it's an update, not an onboarding).
## Mitigations (M1M7)
- **M1** Separation: this skill does not invoke `monorepo-discover` automatically. If `_repo-config.yaml` needs regeneration first, tell the user.
- **M3** Factual vs. interpretive vs. conventional: all user inputs below are CONVENTIONAL (project choices) — always ASK, never infer.
- **M4** Batch inputs in one question round.
- **M5** Skip over guess: if the user's answer doesn't match enumerable options in config (e.g., unknown deployment tier), stop and ask whether to extend config or adjust answer.
- **M6** Assumptions footer + config `assumptions_log` append.
- **M7** Drift detection: before writing anything, verify every artifact path that will be touched exists (or will be created) — stop on unexpected conditions.
## Required inputs (batch-ask, M4)
Collect ALL of these upfront. If any missing, stop and ask. Offer choices from config when the input has a constrained domain (e.g., `conventions.deployment_tiers`).
| Input | Example | Enumerable? |
| ----- | ------- | ----------- |
| `name` | `satellite-provider` | No — open-ended, follow `conventions.component_naming` |
| `location` | git URL / path | No |
| `stack` | `.NET 10`, `Python 3.12` | No — open-ended |
| `purpose` (one line) | "Fetches satellite imagery" | No |
| `doc_placement` | "extend `_docs/07_admin.md`" OR "new `_docs/NN_satellite.md`" | Yes — offer options based on `docs.*` |
| `ci_required` | Which pipelines (or "none") | Yes — infer from `ci.tooling` |
| `deployment_tier` | `edge` | Yes — `conventions.deployment_tiers` |
| `ports` | "5010/http" or "none" | No |
| `depends_on` | Other components called | Yes — list from `components:` names |
| `env_vars` | Name + placeholder value | No (never real secrets) |
If the user provides an answer outside the enumerable set (e.g., deployment tier not in config), **stop** and ask whether to extend the config or pick from the existing set (M5).
## Workflow
### Phase 1: Drift check (M7)
Before writing:
1. Verify `repo.component_registry` exists on disk.
2. Verify `docs.root` exists.
3. If `doc_placement` = extend existing doc, verify that doc exists.
4. Verify every file in `ci.orchestration_files` and `ci.env_template` exists.
5. Verify `ci.service_registry_doc` exists (if set).
Any missing → stop, ask whether to run `monorepo-discover` first or proceed skipping that artifact.
### Phase 2: Register in component registry
Based on `repo.type`:
| Registry | Action |
| -------- | ------ |
| `git-submodules` | Append `[submodule "<name>"]` stanza to `.gitmodules`. Preserve existing indentation style exactly. |
| `npm-workspaces` | Add path to `workspaces` array in `package.json`. Preserve JSON formatting. |
| `pnpm-workspace` | Add to `packages:` in `pnpm-workspace.yaml`. |
| `cargo-workspace` | Add to `members:` in `Cargo.toml`. |
| `go-workspace` | Add to `use (...)` block in `go.work`. |
| `adhoc` | Update the registry file that config points to. |
**Do NOT run** `git submodule add`, `npm install`, or equivalent commands. Produce the text diff; the user runs the actual registration command after review.
### Phase 3: Root README update
If the root README contains a component/services table (check `repo.root_readme`):
1. Insert a new row following existing ordering (alphabetical or deployment-order — match what's there).
2. Match column widths and punctuation exactly.
If there's an ASCII architecture diagram and `deployment_tier` implies new runtime presence, **ask** the user where to place the new box — don't invent a position.
### Phase 4: Unified docs placement
**If extending an existing doc**:
1. Read the target file.
2. Add a new H2 section at the appropriate position. If ambiguous (the file has multiple possible sections), ask.
3. Update file's internal TOC if present.
4. Update `docs.index` ONLY if that index has a cross-reference table that includes sub-sections (check the file).
**If creating a new doc file**:
1. Determine the filename via `docs.file_convention` and `docs.next_unused_prefix` (e.g., `13_satellite_provider.md`).
2. Create using this template:
```markdown
# <Component Name>
## Overview
<expanded purpose from user input>
## API
<endpoints or "None">
## Data model
<if applicable, else "None">
## Configuration
<env vars from user input>
```
3. Update `docs.index` (`_docs/README.md` or equivalent):
- Add row to docs table, matching existing format
- If the component introduces a permission AND the index has a permission → feature matrix, update that too
4. After creating, update `docs.next_unused_prefix` in `_docs/_repo-config.yaml`.
### Phase 5: Cross-cutting docs
For each `docs.cross_cutting` entry whose `owns:` matches a fact provided by the user, update that doc:
- `depends_on` non-empty → architecture/communication doc
- New schema/tables → schema doc (ask user for schema details if not provided)
- New permission/role → permissions doc
If a cross-cutting concern is implied by inputs but has no owner in config → add to `unresolved:` in config and ask.
### Phase 6: CI/CD integration
Update:
- **`ci.service_registry_doc`**: add new row to the service table in that file (if set). Match existing format.
- **Orchestration files** (`ci.orchestration_files`): add service block if component is a runtime service. Use `ci.image_tag_format` for the image string. Include `depends_on`, `ports`, `environment`, `volumes` based on user inputs and existing service-block structure.
- **`ci.env_template`**: append new env vars with placeholder values. NEVER real secrets.
### Phase 7: Per-component CI — guidance ONLY
For `<component>/.woodpecker/*.yml`, `<component>/.github/workflows/*`, etc.:
**Do NOT create these files.** They live inside the component's own repo/workspace.
Instead, output the `ci.pipeline_template` (from config) customized for this component, so the user can copy it into the component's workspace themselves.
### Phase 8: Update `_docs/_repo-config.yaml`
Append new entry to `components:`:
```yaml
- name: <name>
path: <path>/
stack: <stack>
confirmed: true # user explicitly onboarded = confirmed
evidence: [user_onboarded]
primary_doc: <new doc path>
secondary_docs: [...]
ci_config: <component>/.<ci_tool>/ # expected location
deployment_tier: <tier>
ports: [...]
depends_on: [...]
env_vars: [...]
```
If `docs.next_unused_prefix` was consumed, increment it.
Append to `assumptions_log:`:
```yaml
- date: <date>
skill: monorepo-onboard
run_notes: "Onboarded <name>"
assumptions:
- "<list>"
```
Do NOT change `confirmed_by_user` — only human sets that.
### Phase 9: Verification report (M6 footer)
```
monorepo-onboard run complete — onboarded `<name>`.
Files modified (N):
- .gitmodules — added submodule entry
- README.md — added row in Services table
- _docs/NN_<name>.md — created
- _docs/README.md — added index row + permission-matrix row
- _docs/00_top_level_architecture.md — added to Communication section
- docker-compose.run.yml — added service block
- .env.example — added <NAME>_API_KEY placeholder
- ci_steps.md — added service-table row
- _docs/_repo-config.yaml — recorded component + updated next_unused_prefix
Files NOT modified but the user must handle:
- <component>/.woodpecker/build-*.yml — create inside the component's own workspace
(template below)
- CI system UI — activate the new repo
Next manual actions:
1. Actually add the component: `git submodule add <url> <path>` (or equivalent)
2. Create per-component CI config using the template
3. Activate the repo in your CI system
4. Review the full diff, then commit with `<commit_prefix> Onboard <name>`
Pipeline template for <name>:
<rendered ci.pipeline_template with <service> replaced>
Assumptions used this run:
- Doc filename convention: <from config>
- Image tag format: <from config>
- Alphabetical ordering in Services table (observed)
```
## What this skill will NEVER do
- Run `git submodule add`, `npm install`, or any network/install-touching command
- Create per-component CI configs inside component directories
- Invent env vars, ports, permissions, or ticket IDs — all from user
- Auto-commit
- Reorder existing table rows beyond inserting the new one
- Set `confirmed_by_user: true` in config
- Touch a file outside the explicit scope
## Rollback (pre-commit)
Before the user commits, revert is straightforward:
```bash
git checkout -- <every file listed in the report>
```
For the new doc file, remove it explicitly:
```bash
rm _docs/NN_<name>.md
```
The component itself (if already registered via `git submodule add` or workspace install) requires manual cleanup — outside this skill's scope.
## Edge cases
- **Component already in config** (not registry) or vice versa → state mismatch. Redirect to `monorepo-discover` to reconcile.
- **User input contradicts config convention** (e.g., new deployment tier not in `conventions.deployment_tiers`): stop, ask — extend config, or choose from existing.
- **`docs.next_unused_prefix` collides with an existing file** (race condition): bump and retry once; if still colliding, stop.
- **No `docs.root` in config**: cannot place a doc. Ask user to run `monorepo-discover` or manually set it in the config first.
+160
View File
@@ -0,0 +1,160 @@
---
name: monorepo-status
description: Read-only drift/coverage report for a monorepo. Reads `_docs/_repo-config.yaml` and compares live repo state (component commits, doc files, CI artifacts) against it. Surfaces which components have unsynced docs, missing CI coverage, unresolved questions, or structural drift. Writes nothing. Use before releases, during audits, or whenever the user asks "what's out of sync?".
---
# Monorepo Status
Read-only. Reports drift between the live repo and `_docs/_repo-config.yaml`. Writes **nothing** — not even `assumptions_log`. Its only deliverable is a text report.
## Preconditions (soft gates)
1. `_docs/_repo-config.yaml` exists — if not, redirect: "Run `monorepo-discover` first."
2. `confirmed_by_user: true` is NOT required — this skill can run on an unconfirmed config, but will flag it prominently.
## Mitigations (M1M7)
- **M1/M7** This skill IS M7 — it is the drift-detection mechanism other skills invoke conceptually. It surfaces drift, never "fixes" it.
- **M3** All checks are FACTUAL (file exists? commit date? referenced in config?). No interpretive work.
- **M6** Assumptions footer included; but this skill does NOT append to `assumptions_log` in config (writes nothing).
## What the report covers
### Section 1: Config health
- Is `confirmed_by_user: true`? (If false, flag prominently — other skills won't run)
- How many entries have `confirmed: false` (inferred)?
- Count of `unresolved:` entries + their IDs
- Age of config (`last_updated`) — flag if > 60 days old
### Section 2: Component drift
For each component in `components:`:
1. Last commit date of component:
```bash
git -C <path> log -1 --format=%cI # submodule
# or
git log -1 --format=%cI -- <path> # subfolder
```
2. Last commit date of `primary_doc` (and each `secondary_docs` entry):
```bash
git log -1 --format=%cI -- <doc_path>
```
3. Flag as drift if ANY doc's last commit is older than the component's last commit by more than a threshold (default: 0 days — any ordering difference is drift, but annotate magnitude).
### Section 3: CI coverage
For each component:
- Does it have files matching `ci.expected_files_per_component[*].path_glob`?
- Is it present in each `ci.orchestration_files` that's expected to include it (heuristic: check if the compose file mentions the component name or image)?
- Is it listed in `ci.service_registry_doc` if that file has a service table?
Mark each as `complete` / `partial` / `missing` and explain.
### Section 4: Registry vs. config consistency
- Every component in the registry (`.gitmodules`, workspaces, etc.) appears in `components:` — flag mismatches
- Every component in `components:` appears in the registry — flag mismatches
- Every `docs.root` file cross-referenced in config exists on disk — flag missing
- Every `ci.orchestration_files` and `ci.install_scripts` exists — flag missing
- `glossary_doc:` (if recorded in config) points to a file that exists on disk — flag missing
- The cross-cutting architecture doc identified by `docs.cross_cutting` contains a `## Architecture Vision` section — flag missing (signals the meta-repo flow's Step 2.5 was skipped or the section was removed)
### Section 5: Unresolved questions
List every `unresolved:` entry in config with its ID and question — so the user knows what's blocking full confirmation.
## Workflow
1. Read `_docs/_repo-config.yaml`. If missing or unparseable, STOP with a redirect to `monorepo-discover`.
2. Run all checks above (purely read-only).
3. Render the single summary table and supporting sections.
4. Include the assumptions footer.
5. STOP. Do not edit any file.
## Report template
```
═══════════════════════════════════════════════════
MONOREPO STATUS
═══════════════════════════════════════════════════
Config: _docs/_repo-config.yaml
confirmed_by_user: <true|false> [FLAG if false]
last_updated: <date> [FLAG if > 60 days]
inferred entries: <count> of <total>
unresolved: <count> open
═══════════════════════════════════════════════════
Component drift
═══════════════════════════════════════════════════
Component | Last commit | Primary doc age | Secondary docs | Status
-------------------- | ----------- | --------------- | -------------- | ------
annotations | 2d ago | 2d ago | OK | in-sync
flights | 1d ago | 12d ago | 1 stale (schema)| drift
satellite-provider | 3d ago | N/A | N/A | no mapping
═══════════════════════════════════════════════════
CI coverage
═══════════════════════════════════════════════════
Component | CI configs | Orchestration | Service registry
-------------------- | ---------- | ------------- | ----------------
annotations | complete | yes | yes
flights | complete | yes | yes
satellite-provider | missing | no | no
═══════════════════════════════════════════════════
Registry vs. config
═══════════════════════════════════════════════════
In registry, not in config: [list or "(none)"]
In config, not in registry: [list or "(none)"]
Config-referenced docs missing: [list or "(none)"]
Config-referenced CI files missing: [list or "(none)"]
glossary_doc: [path or "not recorded — run /autodev to capture"]
Architecture Vision section: [present | missing in <doc>]
═══════════════════════════════════════════════════
Unresolved questions
═══════════════════════════════════════════════════
- <id>: <question>
- <id>: <question>
═══════════════════════════════════════════════════
Recommendations
═══════════════════════════════════════════════════
- Run monorepo-document for: flights (docs drift)
- Run monorepo-cicd for: satellite-provider (no CI coverage)
- Run monorepo-onboard for: satellite-provider (no mapping)
- Run monorepo-discover to refresh config (if drift is widespread or config is stale)
═══════════════════════════════════════════════════
Assumptions used this run
═══════════════════════════════════════════════════
- Drift threshold: any ordering difference counts as drift
- CI coverage heuristic: component name or image appears in compose file
- Component last-commit measured via `git log` against the component path
Report only. No files modified.
```
## What this skill will NEVER do
- Modify any file (including the config `assumptions_log`)
- Run `monorepo-discover`, `monorepo-document`, `monorepo-cicd`, or `monorepo-onboard` automatically — only recommend them
- Block on unresolved entries (it just lists them)
- Install tools
## Edge cases
- **Git not available / shallow clone**: commit dates may be inaccurate — note in the assumptions footer.
- **Config has `confirmed: false` but no unresolved entries**: this is a sign discovery ran but the human never reviewed. Flag in Section 1.
- **Component in registry but no entry in config** (or vice versa): flag in Section 4 — don't guess what the mapping should be; just report the mismatch.
- **Very large monorepos (100+ components)**: don't truncate tables; tell the user if the report will be long, offer to scope to a subset.
+39 -5
View File
@@ -75,7 +75,9 @@ Record the description verbatim for use in subsequent steps.
**Role**: Technical analyst
**Goal**: Determine whether deep research is needed.
Read the user's description and the existing codebase documentation from DOCUMENT_DIR (architecture.md, components/, system-flows.md).
Read the user's description and the existing codebase documentation from DOCUMENT_DIR (architecture.md including its `## Architecture Vision` section, glossary.md, components/, system-flows.md). Use `glossary.md` to keep the new task's name, acceptance-criteria wording, and component references aligned with the user's confirmed vocabulary; flag the task to the user if the request appears to violate an Architecture Vision principle, do not silently allow it.
**Consult LESSONS.md**: if `_docs/LESSONS.md` exists, read it and look for entries in categories `estimation`, `architecture`, `dependencies` that might apply to the task under consideration. If a relevant lesson exists (e.g., "estimation: auth-related changes historically take 2x estimate"), bias the classification and recommendation accordingly. Note in the output which lessons (if any) were applied.
Assess the change along these dimensions:
- **Scope**: how many components/files are affected?
@@ -132,7 +134,8 @@ The `<task_slug>` is a short kebab-case name derived from the feature descriptio
**Goal**: Determine where and how to insert the new functionality, and whether existing tests cover the new requirements.
1. Read the codebase documentation from DOCUMENT_DIR:
- `architecture.md` — overall structure
- `architecture.md` — overall structure (the `## Architecture Vision` H2 is user-confirmed intent and must not be violated by the new task without explicit approval)
- `glossary.md` — project terminology; reuse the user's vocabulary in task names, AC, and component references
- `components/` — component specs
- `system-flows.md` — data flows (if exists)
- `data_model.md` — data model (if exists)
@@ -178,6 +181,34 @@ When gaps are found, the task spec (Step 6) MUST include the missing tests in th
---
### Step 4.5: Contract & Layout Check
**Role**: Architect
**Goal**: Prevent silent public-API drift and keep `module-layout.md` consistent before implementation locks file ownership.
Apply the four shared-task triggers from `.cursor/skills/decompose/SKILL.md` Step 2 rule #10 (shared/*, Scope mentions interface/DTO/schema/event/contract/API/shared-model, parent epic is cross-cutting, ≥2 consumers) and classify the task:
- **Producer** — any trigger fires, OR the task changes a public signature / invariant / serialization / error variant of an existing symbol:
1. Check for an existing contract at `_docs/02_document/contracts/<component>/<name>.md`.
2. If present → decide version bump (patch / minor / major per the contract's Versioning Rules) and add the Change Log entry to the task's deliverables.
3. If absent → add creation of the contract file (using `.cursor/skills/decompose/templates/api-contract.md`) to the task's Scope.Included; add a `## Contract` section to the task spec.
4. List every currently-known consumer (from Codebase Analysis Step 4) and add them to the contract's Consumer tasks field.
- **Consumer** — the task imports or calls a public API belonging to another component:
1. Resolve the component's contract file; add it to the task's `### Document Dependencies` section.
2. If the cross-component interface has no contract file, Choose: **A)** create a retroactive contract now as a prerequisite task, **B)** proceed without (logs an explicit coupling risk in the task's Risks & Mitigation).
- **Layout delta** — the task introduces a new component OR changes an existing component's Public API surface:
1. Draft the Per-Component Mapping entry (or the Public API diff) against `_docs/02_document/module-layout.md` using `.cursor/skills/decompose/templates/module-layout.md` format.
2. Add the layout edit to the task's deliverables; the implementer writes it alongside the code change.
3. If `module-layout.md` does not exist, STOP and instruct the user to run `/document` first (existing-code flow) or `/decompose` default mode (greenfield). Do not guess.
Record the classification and any contract/layout deliverables in the working notes; they feed Step 5 (Validate Assumptions) and Step 6 (Create Task).
**BLOCKING**: none — this step surfaces findings; the user confirms them in Step 5.
---
### Step 5: Validate Assumptions
**Role**: Quality gate
@@ -229,6 +260,9 @@ Present using the Choose format for each decision that has meaningful alternativ
- [ ] Complexity points match the assessment
- [ ] Dependencies reference existing task tracker IDs where applicable
- [ ] No implementation details leaked into the spec
- [ ] If Step 4.5 classified the task as producer, the `## Contract` section exists and points at a contract file
- [ ] If Step 4.5 classified the task as consumer, `### Document Dependencies` lists the relevant contract file
- [ ] If Step 4.5 flagged a layout delta, the task's Scope.Included names the `module-layout.md` edit
---
@@ -237,7 +271,7 @@ Present using the Choose format for each decision that has meaningful alternativ
**Role**: Project coordinator
**Goal**: Create a work item ticket and link it to the task file.
1. Create a ticket via the configured work item tracker (see `autopilot/protocols.md` for tracker detection):
1. Create a ticket via the configured work item tracker (see `autodev/protocols.md` for tracker detection):
- Summary: the task's **Name** field
- Description: the task's **Problem** and **Acceptance Criteria** sections
- Story points: the task's **Complexity** value
@@ -248,7 +282,7 @@ Present using the Choose format for each decision that has meaningful alternativ
- Update **Epic** field: `[EPIC-ID]`
3. Rename the file from `[##]_[short_name].md` to `[TICKET-ID]_[short_name].md`
If the work item tracker is not authenticated or unavailable (`tracker: local`):
If the work item tracker is not authenticated or unavailable, follow `.cursor/rules/tracker.mdc` before continuing. Only if the user explicitly chooses `tracker: local`:
- Keep the numeric prefix
- Set **Tracker** to `pending`
- Set **Epic** to `pending`
@@ -303,7 +337,7 @@ After the user chooses **Done**:
| Research skill hits a blocker | Follow research skill's own escalation rules |
| Codebase analysis reveals conflicting architectures | **ASK** user which pattern to follow |
| Complexity exceeds 5 points | **WARN** user and suggest splitting into multiple tasks |
| Work item tracker MCP unavailable | **WARN**, continue with local-only task files |
| Work item tracker MCP unavailable | Follow `.cursor/rules/tracker.mdc`; do not continue in local mode unless the user explicitly chooses it |
## Trigger Conditions
+7 -4
View File
@@ -69,7 +69,7 @@ Capture any new questions, findings, or insights that arise during test specific
### Step 2: Solution Analysis
Read and follow `steps/02_solution-analysis.md`.
Read and follow `steps/02_solution-analysis.md`. The step opens with **Phase 2a.0: Glossary & Architecture Vision** (BLOCKING) — drafts `_docs/02_document/glossary.md` and a one-paragraph architecture vision, presents the condensed view to the user, iterates until confirmed, then proceeds into the architecture, data-model, and deployment phases. The confirmed vision becomes the first `## Architecture Vision` H2 of `architecture.md`.
---
@@ -107,6 +107,7 @@ Read and follow `steps/07_quality-checklist.md`.
- **Coding during planning**: this workflow produces documents, never code
- **Multi-responsibility components**: if a component does two things, split it
- **Skipping BLOCKING gates**: never proceed past a BLOCKING marker without user confirmation
- **Skipping the glossary/vision gate (Phase 2a.0)**: drafting `architecture.md` from raw `solution.md` without confirming terminology and vision means the AI's mental model is not aligned with the user's; every downstream artifact will inherit that drift
- **Diagrams without data**: generate diagrams only after the underlying structure is documented
- **Copy-pasting problem.md**: the architecture doc should analyze and transform, not repeat the input
- **Vague interfaces**: "component A talks to component B" is not enough; define the method, input, output
@@ -119,7 +120,7 @@ Read and follow `steps/07_quality-checklist.md`.
|-----------|--------|
| Missing acceptance_criteria.md, restrictions.md, or input_data/ | **STOP** — planning cannot proceed |
| Ambiguous requirements | ASK user |
| Input data coverage below 70% | Search internet for supplementary data, ASK user to validate |
| Input data coverage below 75% | Search internet for supplementary data, ASK user to validate |
| Technology choice with multiple valid options | ASK user |
| Component naming | PROCEED, confirm at next BLOCKING gate |
| File structure within templates | PROCEED |
@@ -137,8 +138,10 @@ Read and follow `steps/07_quality-checklist.md`.
│ │
│ 1. Blackbox Tests → test-spec/SKILL.md │
│ [BLOCKING: user confirms test coverage] │
│ 2. Solution Analysis → architecture, data model, deployment
[BLOCKING: user confirms architecture]
│ 2. Solution Analysis → glossary + vision, architecture,
data model, deployment
│ [BLOCKING 2a.0: user confirms glossary + vision] │
│ [BLOCKING 2a: user confirms architecture] │
│ 3. Component Decomp → component specs + interfaces │
│ [BLOCKING: user confirms components] │
│ 4. Review & Risk → risk register, iterations │
@@ -4,20 +4,105 @@
**Goal**: Produce `architecture.md`, `system-flows.md`, `data_model.md`, and `deployment/` from the solution draft
**Constraints**: No code, no component-level detail yet; focus on system-level view
### Phase 2a.0: Glossary & Architecture Vision (BLOCKING)
**Role**: Software architect + business analyst
**Goal**: Align the AI's mental model of the project with the user's intent BEFORE drafting `architecture.md`. Capture domain terminology and the user's high-level architecture vision so every downstream artifact (architecture, components, flows, tests, epics) is grounded in confirmed user intent — not in AI inference.
**Inputs**:
- `_docs/00_problem/problem.md`, `acceptance_criteria.md`, `restrictions.md`
- `_docs/00_problem/input_data/*`
- `_docs/01_solution/solution.md` (and any earlier `solution_draft*.md` siblings)
- Any blackbox-test findings produced in Step 1
**Outputs**:
- `_docs/02_document/glossary.md` (NEW)
- A confirmed "Architecture Vision" paragraph + bullet list held in working memory and used as the spine of Phase 2a's `architecture.md`
**Procedure**:
1. **Draft glossary** — extract project-specific terminology from inputs (NOT generic software terms). Include:
- Domain entities, processes, and roles
- Acronyms / abbreviations
- Internal codenames or product names
- Synonym pairs in active use (e.g., "flight" vs. "mission")
- Stakeholder personas referenced in problem.md
Each entry: one-line definition, plus a parenthetical source (`source: problem.md`, `source: solution.md §3`).
Skip terms that have a single well-known industry meaning (REST, JSON, etc.).
2. **Draft architecture vision** — synthesize from inputs:
- **One paragraph**: what the system is, who uses it, the shape of the runtime topology (monolith / services / pipeline / library / hybrid).
- **Components & responsibilities** (one-line each). At this stage these are *intent-level*, not the formal decomposition that Step 3 produces.
- **Major data flows** (one or two sentences each).
- **Architectural principles / non-negotiables** the user has implied (e.g., "DB-driven config", "no per-component state outside Redis", "all UI traffic via REST + SSE only").
- **Open architectural questions** the AI cannot resolve from inputs alone.
3. **Present condensed view** to the user (NOT the full draft files — a synopsis only):
```
══════════════════════════════════════
REVIEW: Glossary + Architecture Vision
══════════════════════════════════════
Glossary (N terms drafted):
- <Term>: <one-line definition>
- ...
Architecture Vision:
<one-paragraph synopsis>
Components / responsibilities:
- <component>: <one-line>
- ...
Principles / non-negotiables:
- <principle>
- ...
Open questions (AI could not resolve):
- <q1>
- <q2>
══════════════════════════════════════
A) Looks correct — write glossary.md, use vision for Phase 2a
B) I want to add / correct entries (provide diffs)
C) Answer the open questions first, then re-present
══════════════════════════════════════
Recommendation: pick C if open questions exist, otherwise A
══════════════════════════════════════
```
4. **Iterate**:
- On B → integrate the user's diffs/additions, re-present the condensed view, loop until A.
- On C → ask the listed open questions one round (M4-style batch), integrate answers, re-present.
- **Do NOT proceed to step 5 until the user picks A.**
5. **Save**:
- Write `_docs/02_document/glossary.md` with terms in alphabetical order. Include a top-line `**Status**: confirmed-by-user` and the date.
- Hold the confirmed vision (paragraph + components + principles) in working memory; Phase 2a will materialize it into `architecture.md` and **must** preserve every confirmed principle and component intent verbatim.
**Self-verification**:
- [ ] Every glossary entry traces to at least one input file (no invented terms)
- [ ] Every component listed in the vision is one the inputs reference
- [ ] All open questions are either answered or explicitly deferred (with the user's acknowledgement)
- [ ] User picked option A on the latest condensed view
**BLOCKING**: Do NOT proceed to Phase 2a until `glossary.md` is saved and the user has confirmed the architecture vision.
### Phase 2a: Architecture & Flows
1. Read all input files thoroughly
2. Incorporate findings, questions, and insights discovered during Step 1 (blackbox tests)
3. Research unknown or questionable topics via internet; ask user about ambiguities
4. Document architecture using `templates/architecture.md` as structure
5. Document system flows using `templates/system-flows.md` as structure
3. **Apply confirmed vision from Phase 2a.0**: the architecture document must include a top-level `## Architecture Vision` section that contains the user-confirmed paragraph, components, and principles verbatim. The rest of `architecture.md` (tech stack, deployment model, NFRs, ADRs) builds on top of that section, never contradicts it
4. Research unknown or questionable topics via internet; ask user about ambiguities
5. Document architecture using `templates/architecture.md` as structure
6. Document system flows using `templates/system-flows.md` as structure
**Self-verification**:
- [ ] `architecture.md` opens with a `## Architecture Vision` section matching Phase 2a.0
- [ ] Architecture covers all capabilities mentioned in solution.md
- [ ] System flows cover all main user/system interactions
- [ ] No contradictions with problem.md or restrictions.md
- [ ] No contradictions with problem.md, restrictions.md, or the confirmed vision
- [ ] Technology choices are justified
- [ ] Blackbox test findings are reflected in architecture decisions
- [ ] Every term used in `architecture.md` that is project-specific appears in `glossary.md`
**Save action**: Write `architecture.md` and `system-flows.md`
@@ -6,12 +6,22 @@
**Constraints**: Epic descriptions must be **comprehensive and self-contained** — a developer reading only the epic should understand the full context without needing to open separate files.
0. **Consult LESSONS.md** — if `_docs/LESSONS.md` exists, read it and factor any `estimation` / `architecture` / `dependencies` entries into epic sizing, scope, and dependency ordering. This closes the retrospective feedback loop; lessons from prior cycles directly inform current epic shape. Note in the Step 6 output which lessons were applied (or that none were relevant).
1. **Create "Bootstrap & Initial Structure" epic first** — this epic will parent the `01_initial_structure` task created by the decompose skill. It covers project scaffolding: folder structure, shared models, interfaces, stubs, CI/CD config, DB migrations setup, test structure.
2. Generate epics for each component using the configured work item tracker (see `autopilot/protocols.md` for tracker detection), structured per `templates/epic-spec.md`
3. Order epics by dependency (Bootstrap epic is always first, then components based on their dependency graph)
4. Include effort estimation per epic (T-shirt size or story points range)
5. Ensure each epic has clear acceptance criteria cross-referenced with component specs
6. Generate Mermaid diagrams showing component-to-epic mapping and component relationships
2. **Identify cross-cutting concerns from architecture.md and restrictions.md**. Default candidates to consider (include only if architecture/restrictions reference them):
- Logging / observability (structured logging, correlation IDs, metrics)
- Error handling / envelope / result types
- Configuration loading (env vars, config files, secrets)
- Authentication / authorization middleware
- Feature flags / toggles
- Telemetry / tracing
- i18n / localization
For each identified concern, create ONE epic named `Cross-Cutting: <name>` with `epic_type: cross-cutting`. Each cross-cutting epic will parent exactly ONE shared implementation task (placed under `src/shared/<concern>/` by decompose skill). All component-level tasks that consume the concern declare the shared task as a dependency — they do NOT re-implement the concern locally. This rule is enforced by code-review Phase 6 (Cross-Task Consistency) and Phase 7 (Architecture Compliance).
3. Generate epics for each component using the configured work item tracker (see `autodev/protocols.md` for tracker detection), structured per `templates/epic-spec.md`
4. Order epics by dependency: Bootstrap epic first, then Cross-Cutting epics (they underlie everything), then component epics in dependency order
5. Include effort estimation per epic (T-shirt size or story points range). Use LESSONS.md estimation entries as a calibration hint — if a lesson says "component X was underestimated by 2x last time" and the current plan has a comparable component, widen that epic's estimate.
6. Ensure each epic has clear acceptance criteria cross-referenced with component specs
7. Generate Mermaid diagrams showing component-to-epic mapping and component relationships; include cross-cutting epics as horizontal dependencies of every consuming component epic
**CRITICAL — Epic description richness requirements**:
@@ -35,14 +45,17 @@ Do NOT create minimal epics with just a summary and short description. The epic
**Self-verification**:
- [ ] "Bootstrap & Initial Structure" epic exists and is first in order
- [ ] Every identified cross-cutting concern has exactly one `Cross-Cutting: <name>` epic
- [ ] No two epics own the same cross-cutting concern
- [ ] "Blackbox Tests" epic exists
- [ ] Every component maps to exactly one epic
- [ ] Every component maps to exactly one component epic
- [ ] Dependency order is respected (no epic depends on a later one)
- [ ] Cross-Cutting epics precede every consuming component epic
- [ ] Acceptance criteria are measurable
- [ ] Effort estimates are realistic
- [ ] Effort estimates are realistic and reflect LESSONS.md calibration hints (if any applied)
- [ ] Every epic description includes architecture diagram, interface spec, data flow, risks, and NFRs
- [ ] Epic descriptions are self-contained — readable without opening other files
7. **Create "Blackbox Tests" epic** — this epic will parent the blackbox test tasks created by the `/decompose` skill. It covers implementing the test scenarios defined in `tests/`.
8. **Create "Blackbox Tests" epic** — this epic will parent the blackbox test tasks created by the `/decompose` skill. It covers implementing the test scenarios defined in `tests/`.
**Save action**: Epics created via the configured tracker MCP. Also saved locally in `epics.md` with ticket IDs. If `tracker: local`, save locally only.
**Save action**: Epics created via the configured tracker MCP. Also saved locally in `epics.md` with ticket IDs. If tracker availability fails, follow `.cursor/rules/tracker.mdc`; only if the user explicitly chooses `tracker: local`, save locally only with pending tracker markers.
+12 -3
View File
@@ -1,6 +1,6 @@
# Epic Template
Use this template for each epic. Create epics via the configured work item tracker (see `autopilot/protocols.md` for tracker detection).
Use this template for each epic. Create epics via the configured work item tracker (see `autodev/protocols.md` for tracker detection).
---
@@ -9,6 +9,9 @@ Use this template for each epic. Create epics via the configured work item track
**Example**: Data Ingestion — Near-real-time pipeline
**epic_type**: [component | bootstrap | cross-cutting | tests]
**concern** (cross-cutting only): [logging | error-handling | config | authn | authz | feature-flags | telemetry | i18n | other-named-concern]
### Epic Summary
[1-2 sentences: what we are building + why it matters]
@@ -123,5 +126,11 @@ Link to architecture.md and relevant component spec.]
- Be concise. Fewer words with the same meaning = better epic.
- Capabilities in scope are "what", not "how" — avoid describing implementation details.
- Dependency order matters: epics that must be done first should be listed earlier in the backlog.
- Every epic maps to exactly one component. If a component is too large for one epic, split the component first.
- Complexity points for child issues follow the project standard: 1, 2, 3, 5, 8. Do not create issues above 5 points — split them.
- Every `component` epic maps to exactly one component. If a component is too large for one epic, split the component first.
- A `cross-cutting` epic maps to exactly one shared concern and parents exactly one shared implementation task. Component epics that consume the concern declare the cross-cutting epic as a dependency.
- Valid `epic_type` values:
- `bootstrap` — the initial-structure epic (always exactly one per project)
- `component` — a normal per-component epic
- `cross-cutting` — a shared concern that spans ≥2 components
- `tests` — the blackbox-tests epic (always exactly one)
- Complexity points for child issues follow the project standard: 1, 2, 3, 5. Do not create issues above 5 points — split them.
+2
View File
@@ -181,6 +181,8 @@ Categorized measurable criteria with markdown headers and bullet points:
Every criterion must have a measurable value. Vague criteria like "should be fast" are not acceptable — push for "less than 400ms end-to-end".
**AC must be design-independent**: describe testable outcomes only — no libraries, algorithms, params, or design choices. Implementation follows AC, never reverse. (IEEE 830 / Atlassian / GitScrum)
### input_data/
At least one file. Options:
+19 -1
View File
@@ -24,6 +24,8 @@ Phase details live in `phases/` — read the relevant file before executing each
- **Save immediately**: write artifacts to disk after each phase
- **Delegate execution**: all code changes go through the implement skill via task files
- **Ask, don't assume**: when scope or priorities are unclear, STOP and ask the user
- **Exact-fit recommendations**: do not recommend a replacement pattern, library, service, architecture, algorithm, or "modern approach" merely because it improves structure or solves a similar class of problem. It must fit confirmed product constraints, acceptance criteria, operating context, integration boundaries, and current code realities. Otherwise reject it, mark it experimental, or ask the user before adding it to the roadmap.
- **Per-mode API capability verification on replacements**: when a refactor proposes replacing or adding a library/SDK/framework/service that exposes multiple modes or configurations, pin the exact mode the refactored code will use (inputs, outputs, runtime) and verify *that mode* via mandatory `context7` lookup plus a saved Minimum Viable Example before promoting the recommendation to `Selected`. Capability claims at the category level ("supports A, B, C modes") must be cross-checked against the literal mode enumeration — `A, B → A+B` style conflations are the recurring silent-failure path.
## Context Resolution
@@ -57,7 +59,7 @@ Create REFACTOR_DIR and RUN_DIR if missing. If a RUN_DIR with the same name alre
Both modes produce `RUN_DIR/list-of-changes.md` (template: `templates/list-of-changes.md`). Both modes then convert that file into task files in TASKS_DIR during Phase 2.
**Guided mode cleanup**: after `RUN_DIR/list-of-changes.md` is created from the input file, delete the original input file to avoid duplication.
**Guided mode cleanup**: after `RUN_DIR/list-of-changes.md` is created from the input file, delete the original input file only if it lives outside `RUN_DIR`. If the provided file is already the canonical `RUN_DIR/list-of-changes.md`, keep it as the audit record.
## Workflow
@@ -69,6 +71,7 @@ Both modes produce `RUN_DIR/list-of-changes.md` (template: `templates/list-of-ch
| | | *Quick Assessment stops here* | |
| 3 | `phases/03-safety-net.md` | Check existing tests or implement pre-refactoring tests (skip for testability runs) | GATE: all tests pass |
| 4 | `phases/04-execution.md` | Delegate task execution to implement skill | GATE: implement completes |
| 4.5 | (inline, testability runs only) | Produce `testability_changes_summary.md` listing every applied change in plain language, surface to user | GATE: user acknowledges summary |
| 5 | `phases/05-test-sync.md` | Remove obsolete, update broken, add new tests | GATE: all tests pass |
| 6 | `phases/06-verification.md` | Run full suite, compare metrics vs baseline | GATE: all pass, no regressions |
| 7 | `phases/07-documentation.md` | Update `_docs/` to reflect refactored state | Skip if `_docs/02_document/` absent |
@@ -78,6 +81,20 @@ Both modes produce `RUN_DIR/list-of-changes.md` (template: `templates/list-of-ch
- "refactor [specific target]" → skip phase 1 if docs exist
- Default → all phases
**Testability-run specifics** (guided mode invoked by autodev existing-code Step 4 or greenfield Step 8):
- Run name is `01-testability-refactoring`.
- Phase 3 (Safety Net) is skipped by design — no tests exist yet. Compensating control: the `list-of-changes.md` gate in Phase 1 must be reviewed and approved by the user before Phase 4 runs.
- Scope is MINIMAL and surgical; reject change entries that drift into full refactor territory (see the invoking flow's testability step for allowed/disallowed lists). Flagged entries go to `RUN_DIR/deferred_to_refactor.md` for the next optional full-refactor step or backlog consideration.
- After Phase 4 (Execution) completes, write `RUN_DIR/testability_changes_summary.md` as Phase 4.5. Format: one bullet per applied change.
```markdown
# Testability Changes Summary ({{run_name}})
Applied {{N}} change(s):
- **{{change_id}}** — changed {{symbol}} in `{{file}}`: {{plain-language reason}}. Risk: {{low|medium|high}}.
```
Group bullets by category (config extraction, DI insertion, singleton wrapping, interface extraction, function split). Present the summary to the user via the Choose format before proceeding to Phase 5.
At the start of execution, create a TodoWrite with all applicable phases.
## Artifact Structure
@@ -94,6 +111,7 @@ analysis/research_findings.md Phase 2
analysis/refactoring_roadmap.md Phase 2
test_specs/[##]_[test_name].md Phase 3
execution_log.md Phase 4
testability_changes_summary.md Phase 4.5 (testability runs only)
test_sync/{obsolete_tests,updated_tests,new_tests}.md Phase 5
verification_report.md Phase 6
doc_update_log.md Phase 7
@@ -19,7 +19,7 @@ Determine the input mode set during Context Resolution (see SKILL.md):
### 1g. Read and Validate Input File
1. Read the provided input file (e.g., `list-of-changes.md` from the autopilot testability revision step or user-provided file)
1. Read the provided input file (e.g., `list-of-changes.md` from the autodev testability revision step or user-provided file)
2. Extract file paths, problem descriptions, and proposed changes from each entry
3. For each entry, verify against actual codebase:
- Referenced files exist
@@ -95,7 +95,7 @@ Also copy to project standard locations:
**Critical step — do not skip.** Before producing the change list, cross-reference documented business flows against actual implementation. This catches issues that static code inspection alone misses.
1. **Read documented flows**: Load `DOCUMENT_DIR/system-flows.md`, `DOCUMENT_DIR/architecture.md`, and `SOLUTION_DIR/solution.md` (if they exist). Extract every documented business flow, data path, and architectural decision.
1. **Read documented flows**: Load `DOCUMENT_DIR/system-flows.md`, `DOCUMENT_DIR/architecture.md` (paying special attention to its `## Architecture Vision` section — that's the user-confirmed structural intent), `DOCUMENT_DIR/glossary.md`, `DOCUMENT_DIR/module-layout.md`, every file under `DOCUMENT_DIR/contracts/`, and `SOLUTION_DIR/solution.md` (whichever exist). Extract every documented business flow, data path, architectural decision, module ownership boundary, and contract shape. Any refactor change that contradicts a confirmed Architecture Vision principle must either be rejected or surfaced to the user before being added to `list-of-changes.md` — those principles are not refactor targets without explicit user approval.
2. **Trace each flow through code**: For every documented flow (e.g., "video batch processing", "image tiling", "engine initialization"), walk the actual code path line by line. At each decision point ask:
- Does the code match the documented/intended behavior?
@@ -133,6 +133,8 @@ From the component analysis, solution synthesis, and **logical flow analysis**,
9. Performance bottlenecks
10. **Logical flow contradictions** (from step 1c)
11. **Silent data loss or wasted computation** (from step 1c)
12. **Module ownership violations** — code that lives under one component's directory but implements another component's concern, or imports another component's internal (non-Public API) file. Cross-check against `DOCUMENT_DIR/module-layout.md` if present.
13. **Contract drift** — shared-models / shared-API implementations whose public shape has drifted from the contract file in `DOCUMENT_DIR/contracts/`. Include both producer drift and consumer drift.
Write `RUN_DIR/list-of-changes.md` using `templates/list-of-changes.md` format:
- Set **Mode**: `automatic`
+29 -4
View File
@@ -7,14 +7,29 @@
## 2a. Deep Research
1. Analyze current implementation patterns
2. Research modern approaches for similar systems
3. Identify what could be done differently
4. Suggest improvements based on state-of-the-art practices
2. Extract the **Project Constraint Matrix** from `problem.md`, `restrictions.md`, `acceptance_criteria.md`, current architecture/docs, and actual code constraints. Include required inputs/outputs, operating context, lifecycle assumptions, integration boundaries, non-functional targets, and hard disqualifiers.
3. Research modern approaches for similar systems
4. For each alternative pattern/library/service/architecture/algorithm, research intrinsic implementation constraints: required inputs/outputs, runtime assumptions, supported deployment modes, resource needs, operational limits, licensing/security constraints, and known failure reports.
**API Capability Verification — Per-Mode (MANDATORY, BLOCKING for proposed replacements)**
When a refactor recommendation replaces (or adds) a library/SDK/framework/service, the same per-mode verification used by `/research` Step 2 applies — selecting a replacement on category fit alone is the same silent-failure path. For every replacement candidate that has multiple modes or configurations:
1. **Pin the exact mode/configuration** the refactored code will use, in one explicit sentence. Inputs (data shapes, sensor counts, payloads, rates), outputs (per `acceptance_criteria.md` and contract files), runtime (matching the project's deployment).
2. **Run `context7` (or equivalent docs lookup)** for the candidate. **Mandatory for every replacement library/SDK/framework candidate**, not optional. Minimum three queries per candidate: mode enumeration, project's exact mode (with input/output shapes), disqualifier probe ("does this mode produce the required output? are there published limitations on this runtime?"). Append URLs to `RUN_DIR/analysis/research_findings.md` references section.
3. **Save a Minimum Viable Example (MVE)** for the pinned mode under `RUN_DIR/analysis/mve_evidence.md` with: source, inputs in example, outputs in example, project inputs, project outputs required, match assessment ✅/⚠️/❌. If no official example covers the project's exact configuration, the recommendation cannot be `Selected` based on category fit alone — it must be `Experimental only` (with required-evidence note) or `Rejected`.
4. **Treat "the same library in a different mode" as a different recommendation.** If the project's pinned mode is `<X>` but the only documented evidence covers `<Y>`, do not silently soften the description. Open a separate recommendation row, with its own MVE, fit assessment, and disqualifiers.
5. **Common silent-failure pattern**: a fact summary paraphrases docs as "supports A, B, C, D modes" when the docs actually mean "supports A; B; C and D as separate orthogonal modes" — no `A+B` combination exists. Cross-check paraphrased capability claims against the literal mode enumeration.
5. Identify what could be done differently
6. Suggest improvements only when they fit the Project Constraint Matrix. A cleaner or more modern approach that violates product constraints must be marked `Rejected` or `Experimental only`, not added as a roadmap recommendation.
Write `RUN_DIR/analysis/research_findings.md`:
- Current state analysis: patterns used, strengths, weaknesses
- Alternative approaches per component: current vs alternative, pros/cons, migration effort
- Prioritized recommendations: quick wins + strategic improvements
- Constraint-fit table: recommendation, **pinned mode/config**, constraints checked, **API capability evidence (MVE link)**, evidence, mismatches/disqualifiers, status (`Selected` / `Rejected` / `Experimental only` / `Needs user decision`)
- For every recommendation that replaces or adds a library/SDK/framework, append a **Restrictions × Candidate-Mode sub-matrix** that walks every numbered line of `restrictions.md` and `acceptance_criteria.md` against the candidate's pinned mode, marking each cell ✅ Pass / ❌ Fail / ❓ Verify / N/A with cited evidence. A recommendation cannot be `Selected` while any cell is ❌ or ❓.
## 2b. Solution Assessment & Hardening Tracks
@@ -22,6 +37,7 @@ Write `RUN_DIR/analysis/research_findings.md`:
2. Identify weak points in codebase, map to specific code areas
3. Perform gap analysis: acceptance criteria vs current state
4. Prioritize changes by impact and effort
5. Reject or escalate any proposed refactor that improves code structure while weakening required behavior, integration contracts, runtime constraints, safety/security posture, or acceptance criteria
Present optional hardening tracks for user to include in the roadmap:
@@ -47,6 +63,9 @@ Write `RUN_DIR/analysis/refactoring_roadmap.md`:
- Gap analysis: what's missing, what needs improvement
- Phased roadmap: Phase 1 (critical fixes), Phase 2 (major improvements), Phase 3 (enhancements)
- Selected hardening tracks and their items
- Applicability gate: each roadmap item must state constraint fit, mismatches, required evidence, and status (`Selected` / `Rejected` / `Experimental only` / `Needs user decision`)
**BLOCKING applicability gate**: Before 2c and 2d, every recommendation in the roadmap must be `Selected`. Items marked `Rejected` are excluded. Items marked `Experimental only` or `Needs user decision` require a user decision before task creation.
## 2c. Create Epic
@@ -55,7 +74,7 @@ Create a work item tracker epic for this refactoring run:
1. Epic name: the RUN_DIR name (e.g., `01-testability-refactoring`)
2. Create the epic via configured tracker MCP
3. Record the Epic ID — all tasks in 2d will be linked under this epic
4. If tracker unavailable, use `PENDING` placeholder and note for later
4. If tracker is unavailable, follow `.cursor/rules/tracker.mdc`; only use `PENDING` placeholders if the user explicitly chooses `tracker: local`
## 2d. Task Decomposition
@@ -79,6 +98,12 @@ Convert the finalized `RUN_DIR/list-of-changes.md` into implementable task files
**Self-verification**:
- [ ] All acceptance criteria are addressed in gap analysis
- [ ] Recommendations are grounded in actual code, not abstract
- [ ] Every recommendation has been checked against the Project Constraint Matrix
- [ ] No recommendation violates product restrictions, acceptance criteria, documented architecture decisions, or actual code integration boundaries
- [ ] Every replacement library/SDK/framework recommendation has a pinned mode/config, a saved MVE in `mve_evidence.md`, and a Restrictions × Candidate-Mode sub-matrix with no ❌ or ❓ cells
- [ ] `context7` (or equivalent) was consulted for every replacement library/SDK/framework recommendation
- [ ] Paraphrased capability claims have been cross-checked against the literal mode-enumeration evidence (no `A, B → A+B` style conflation)
- [ ] Rejected and experimental approaches are documented but not converted into implementation tasks without user approval
- [ ] Roadmap phases are prioritized by impact
- [ ] Epic created and all tasks linked to it
- [ ] Every entry in list-of-changes.md has a corresponding task file in TASKS_DIR
@@ -10,7 +10,7 @@
- All `[TRACKER-ID]_refactor_*.md` files are present
- Each task file has valid header fields (Task, Name, Description, Complexity, Dependencies)
2. Verify `TASKS_DIR/_dependencies_table.md` includes the refactoring tasks
3. Verify all tests pass (safety net from Phase 3 is green)
3. Verify all tests pass (safety net from Phase 3 is green), unless this is a testability run where Phase 3 was intentionally skipped
4. If any check fails, go back to the relevant phase to fix
## 4b. Delegate to Implement Skill
@@ -21,9 +21,9 @@ The implement skill will:
1. Parse task files and dependency graph from TASKS_DIR
2. Detect already-completed tasks (skip non-refactoring tasks from prior workflow steps)
3. Compute execution batches for the refactoring tasks
4. Launch implementer subagents (up to 4 in parallel)
4. Implement tasks sequentially in topological order (no subagents, no parallelism)
5. Run code review after each batch
6. Commit and push per batch
6. Commit per batch and push only when the user approved pushing
7. Update work item ticket status
Do NOT modify, skip, or abbreviate any part of the implement skill's workflow. The refactor skill is delegating execution, not optimizing it.
@@ -47,7 +47,7 @@ After the implement skill completes:
For each successfully completed refactoring task:
1. Transition the work item ticket status to **Done** via the configured tracker MCP
2. If tracker unavailable, note the pending status transitions in `RUN_DIR/execution_log.md`
2. If tracker is unavailable, follow `.cursor/rules/tracker.mdc`; if the user explicitly chose `tracker: local`, note the pending status transitions in `RUN_DIR/execution_log.md`
For any failed or blocked tasks, leave their status as-is (the implement skill already set them to In Testing or blocked).
@@ -32,7 +32,7 @@ For each component doc affected:
## 7d. Update System-Level Documentation
If structural changes were made (new modules, removed modules, changed interfaces):
1. Update `_docs/02_document/architecture.md` if architecture changed
1. Update `_docs/02_document/architecture.md` if architecture changed — but **never edit the `## Architecture Vision` section**. That section is user-confirmed (plan Phase 2a.0 / document Step 4.5); if a refactor invalidates a vision principle, surface it to the user and let them update the vision themselves before continuing. Update only the technical sections below the Vision H2.
2. Update `_docs/02_document/system-flows.md` if flow sequences changed
3. Update `_docs/02_document/diagrams/components.md` if component relationships changed
@@ -23,6 +23,7 @@ Save as `RUN_DIR/list-of-changes.md`. Produced during Phase 1 (Discovery).
- **Problem**: [what makes this problematic / untestable / coupled]
- **Change**: [what to do — behavioral description, not implementation steps]
- **Rationale**: [why this change is needed]
- **Constraint Fit**: [which product constraints / acceptance criteria / integration boundaries this preserves; or "Rejected — violates ..."]
- **Risk**: [low | medium | high]
- **Dependencies**: [other change IDs this depends on, or "None"]
@@ -31,6 +32,7 @@ Save as `RUN_DIR/list-of-changes.md`. Produced during Phase 1 (Discovery).
- **Problem**: [description]
- **Change**: [description]
- **Rationale**: [description]
- **Constraint Fit**: [description]
- **Risk**: [low | medium | high]
- **Dependencies**: [C01, or "None"]
```
@@ -44,6 +46,8 @@ Save as `RUN_DIR/list-of-changes.md`. Produced during Phase 1 (Discovery).
- **File(s)** must reference actual files verified to exist in the codebase
- **Problem** describes the current state, not the desired state
- **Change** describes what the system should do differently — behavioral, not prescriptive
- **Constraint Fit** proves the change preserves confirmed product requirements, restrictions, acceptance criteria, architecture decisions, and integration contracts
- Do not include changes whose only benefit is structural cleanliness if they weaken required behavior or violate constraints; record those as rejected in analysis instead
- **Dependencies** reference other change IDs within this list; cross-run dependencies use tracker IDs
- In guided mode, the input file entries are validated against actual code and enriched with file paths, risk, and dependencies before writing
- In automatic mode, entries are derived from Phase 1 component analysis and Phase 2 research findings
+21
View File
@@ -30,6 +30,27 @@ Transform vague topics raised by users into high-quality, deliverable research r
- **Internet-first investigation** — do not rely on training data for factual claims; search the web extensively for every sub-question, rephrase queries when results are thin, and keep searching until you have converging evidence from multiple independent sources
- **Multi-perspective analysis** — examine every problem from at least 3 different viewpoints (e.g., end-user, implementer, business decision-maker, contrarian, domain expert, field practitioner); each perspective should generate its own search queries
- **Question multiplication** — for each sub-question, generate multiple reformulated search queries (synonyms, related terms, negations, "what can go wrong" variants, practitioner-focused variants) to maximize coverage and uncover blind spots
- **Component option breadth** — for every component area, build a broad option landscape before selecting. Search direct candidates, adjacent-domain alternatives, commercial/open-source variants, classical/simple baselines, current SOTA, and "do not use" failure cases. A component may not be narrowed to one candidate until alternatives have been searched and rejected with evidence.
- **Component research depth** — for every serious component candidate, go beyond discovery pages. Read official docs, repository/license files, issue discussions, benchmarks, deployment guides, version/platform requirements, security notes, maintenance signals, and real-world failure reports. Extract evidence for inputs/outputs, lifecycle assumptions, runtime/storage/latency fit, integration boundaries, licensing, operational risks, and unsupported scenarios before assigning any selection status.
- **Exact-fit component selection** — never select a component, tool, library, service, architecture pattern, or algorithm merely because it solves a similar class of problem. It must be proven compatible with the project's explicit operating context, constraints, required inputs/outputs, non-functional requirements, lifecycle assumptions, and acceptance criteria. If fit is unproven or mismatched, mark it `Rejected`, `Experimental only`, or escalate for user decision before it can shape the solution.
- **Per-mode API capability verification** *(applies only to technical-component selection — see Research Output Class below)* — when a candidate library/SDK/framework/service exposes multiple modes or configurations, *the candidate is not a single thing*. Pin the exact mode the project will use (one explicit sentence: inputs, outputs, runtime), and verify *that mode* against the project's required inputs/outputs via official docs (mandatory `context7` lookup) plus a saved Minimum Viable Example. Capability claims at the category level ("supports X, Y, Z modes") must be cross-checked against the literal mode enumeration before being treated as project-applicable. Two modes of one library are two distinct candidates for the purposes of the Component Applicability Gate. Does not apply to non-technical research (concept comparison, market/policy investigation, knowledge organization, etc.).
## Research Output Class (BLOCKING — set in Step 1)
Before applying any of the technical-component gates (per-mode API capability verification, Component Applicability Gate, Restrictions × Candidate-Mode sub-matrix, MVE evidence, mandatory `context7` lookup), classify the research output into one of two classes. Record the decision in `00_question_decomposition.md` once, near the top, so every downstream step honors it.
| Class | What the output recommends or selects | Examples | Technical-component gates apply? |
|-------|---------------------------------------|----------|----------------------------------|
| **Technical-component selection** | One or more libraries, SDKs, frameworks, services, protocols, data formats, infrastructure patterns, algorithms, or APIs that will be implemented or operated against | "Pick a vector database", "Compare auth-token strategies for our API", "Should we use Kafka or RabbitMQ?", architecture / tech-stack / migration drafts (Mode A, Mode B) | **Yes — all gates active** |
| **Non-technical investigation** | Concept comparisons, knowledge organization, root-cause investigation of an event, market/policy/regulatory/social analysis, literature review, decision support without committing to specific tooling | "Why did adoption stall in Q3?", "Compare phenomenology vs constructivism", "Map regulatory landscape for X", "What do practitioners say about onboarding under remote-first orgs?" | **No — skip API/MVE/sub-matrix gates; the rest of the 8-step engine still applies** |
How to decide:
1. Inspect the question and the input files (`problem.md`, `restrictions.md`, `acceptance_criteria.md`, or the standalone input file).
2. If the deliverable will name specific software/services/protocols that someone will then build with or operate, it is **Technical-component selection**.
3. If the deliverable is a report, comparison, or recommendation that does not commit to specific tooling, it is **Non-technical investigation**.
4. **Mixed runs are valid.** Some research questions have a non-technical core but include one technical sub-question (or vice versa). In that case classify per component area within the run, not the run as a whole, and note in `00_question_decomposition.md` which component areas trigger the technical-component gates.
When the run is purely **Non-technical investigation**, the rest of the research engine — question decomposition, perspective rotation, exhaustive web search, fact extraction, comparison framework, reasoning chain, validation, deliverable formatting — still applies in full. The sections that get skipped are explicitly the technical gates listed in the table above.
## Context Resolution
@@ -32,3 +32,17 @@
6. Applicable scenarios
7. Team capability requirements
8. Migration difficulty
## Decomposition Completeness Probes (Completeness Audit Reference)
Used during Step 1's Decomposition Completeness Audit. After generating sub-questions, ask each probe against the current decomposition. If a probe reveals an uncovered area, add a sub-question for it.
| Probe | What it catches |
|-------|-----------------|
| **What does this cost — in money, time, resources, or trade-offs?** | Budget, pricing, licensing, tax, opportunity cost, maintenance burden |
| **What are the hard constraints — physical, legal, regulatory, environmental?** | Regulations, certifications, spectrum/frequency rules, export controls, physics limits, IP restrictions |
| **What are the dependencies and assumptions that could break?** | Supply chain, vendor lock-in, API stability, single points of failure, standards evolution |
| **What does the operating environment actually look like?** | Terrain, weather, connectivity, infrastructure, power, latency, user skill level |
| **What failure modes exist and what happens when they trigger?** | Degraded operation, fallback, safety margins, blast radius, recovery time |
| **What do practitioners who solved similar problems say matters most?** | Field-tested priorities that don't appear in specs or papers |
| **What changes over time — and what looks stable now but isn't?** | Technology roadmaps, regulatory shifts, deprecation risk, scaling effects |
@@ -10,6 +10,12 @@
- [ ] Every citation can be directly verified by the user (source verifiability)
- [ ] Structure hierarchy is clear; executives can quickly locate information
## Decomposition Completeness
- [ ] Domain discovery search executed: searched "key factors when [problem domain]" before starting research
- [ ] Completeness probes applied: every probe from `references/comparison-frameworks.md` checked against sub-questions
- [ ] No uncovered areas remain: all gaps filled with sub-questions or justified as not applicable
## Internet Search Depth
- [ ] Every sub-question was searched with at least 3-5 different query variants
@@ -21,13 +27,26 @@
- [ ] Iterative deepening completed: follow-up questions from initial findings were searched
- [ ] No sub-question relies solely on training data without web verification
## Component Option Breadth
- [ ] `00_question_decomposition.md` contains a Component Option Search Plan
- [ ] Every component area was searched across simple baseline, established production, open-source, commercial/vendor, current SOTA, adjacent-domain, no-build/defer, and known-bad options where applicable
- [ ] Every component area has at least 3 realistic candidates, or a documented explanation of why broad searches found fewer
- [ ] Each lead candidate has official/source-of-truth evidence plus independent validation when available
- [ ] Each component area includes at least one baseline/fallback option and at least one rejected or experimental option when possible
- [ ] Alternative names, synonyms, and neighboring-domain terms were searched before declaring the option landscape complete
- [ ] Licensing, runtime, platform, maintenance, and unsupported-scenario searches were performed for every lead, fallback, and rejected candidate
## Mode A Specific
- [ ] Phase 1 completed: AC assessment was presented to and confirmed by user
- [ ] AC assessment consistent: Solution draft respects the (possibly adjusted) acceptance criteria and restrictions
- [ ] Competitor analysis included: Existing solutions were researched
- [ ] All components have comparison tables: Each component lists alternatives with tools, advantages, limitations, security, cost
- [ ] Component options are broad: component tables include baseline, production, open-source, commercial/vendor, SOTA/research, adjacent-domain, defer/no-build, and disqualified options where applicable
- [ ] Tools/libraries verified: Suggested tools actually exist and work as described
- [ ] Component fit matrix completed: `06_component_fit_matrix.md` (or `06_component_fit_matrix/` if split) exists and every selected component/tool/pattern is marked `Selected`
- [ ] No field-adjacent substitution: no selected candidate is chosen only because it solves a similar class of problem while failing the project's explicit constraints
- [ ] Testing strategy covers AC: Tests map to acceptance criteria
- [ ] Tech stack documented (if Phase 3 ran): `tech_stack.md` has evaluation tables, risk assessment, and learning requirements
- [ ] Security analysis documented (if Phase 4 ran): `security_analysis.md` has threat model and per-component controls
@@ -39,6 +58,9 @@
- [ ] New draft is self-contained: Written as if from scratch, no "updated" markers
- [ ] Performance column included: Mode B comparison tables include performance characteristics
- [ ] Previous draft issues addressed: Every finding in the table is resolved in the new draft
- [ ] Existing selected components were challenged against a broad alternative landscape before being kept
- [ ] Existing component fit audited: every old and new component/tool/pattern was checked against `restrictions.md`, `acceptance_criteria.md`, and the Project Constraint Matrix
- [ ] Rejected/experimental candidates are not lead recommendations unless the user explicitly accepted the risk
## Timeliness Check (High-Sensitivity Domain BLOCKING)
@@ -58,7 +80,7 @@ When the research topic has Critical or High sensitivity level:
## Target Audience Consistency Check (BLOCKING)
- [ ] Research boundary clearly defined: `00_question_decomposition.md` has clear population/geography/timeframe/level boundaries
- [ ] Every source has target audience annotated in `01_source_registry.md`
- [ ] Every source has target audience annotated in `01_source_registry.md` (or category files under `01_source_registry/` if split)
- [ ] Mismatched sources properly handled (excluded, annotated, or marked reference-only)
- [ ] No audience confusion in fact cards: Every fact has target audience consistent with research boundary
- [ ] No audience confusion in the report: Policies/research/data cited have consistent target audiences
@@ -70,3 +92,33 @@ When the research topic has Critical or High sensitivity level:
- [ ] Cited facts have corresponding statements in the original text (no over-interpretation)
- [ ] Source publication/update dates annotated; technical docs include version numbers
- [ ] Unverifiable information annotated `[limited source]` and not sole support for core conclusions
## Exact-Fit Validation (BLOCKING)
- [ ] Project Constraint Matrix extracted from problem context before component selection
- [ ] Component fit matrix includes `Component Area`, `Option Family`, and `Pinned Mode/Config` columns
- [ ] Every selected component/tool/library/service/pattern/algorithm has evidence for required inputs/outputs and integration boundaries
- [ ] Every selected candidate has evidence for the operating context and lifecycle assumptions it must support
- [ ] Every selected candidate has evidence for non-functional targets that are binding for the project
- [ ] Known unsupported scenarios and failure reports were searched for every selected candidate
- [ ] Mismatches are recorded as disqualifiers, not softened into generic limitations
- [ ] Any candidate with unproven fit is marked `Experimental only` or escalated for user decision
- [ ] Any candidate with documented constraint conflict is marked `Rejected`
## API Capability Verification (BLOCKING)
**Applicability**: this checklist applies only when the run is classified as **Technical-component selection** (see SKILL.md → Research Output Class). For non-technical research (concept comparison, market/policy investigation, root-cause analysis, knowledge organization), skip this checklist entirely and note the skip in `05_validation_log.md`. For mixed runs, apply only to technical component areas.
For every lead candidate that is a library/SDK/framework/service:
- [ ] The exact mode/configuration the project will use is pinned in one explicit sentence (inputs, outputs, runtime); no vague "supports X" language
- [ ] `context7` (or equivalent docs lookup) was run for the candidate, with at least 3 queries: mode enumeration, project's exact mode, disqualifier probe
- [ ] All consulted URLs from context7 / official docs are appended to `01_source_registry.md` (or files under `01_source_registry/` if split)
- [ ] A Minimum Viable Example (MVE) was saved for the pinned mode in `02_fact_cards.md` / `02_fact_cards/` (or `02_mve_evidence.md`) with: source, inputs in example, outputs in example, project inputs, project outputs required, match assessment ✅/⚠️/❌
- [ ] When the MVE inputs or outputs do not exactly match the project's, the mismatch is cited from the official docs (not inferred), and the candidate is `Experimental only` or `Rejected`
- [ ] When a library has multiple modes, each project-relevant mode appears as its own candidate row (not a single library row that softens across modes)
- [ ] Restrictions × Candidate-Modes sub-matrix in `06_component_fit_matrix.md` (or files under `06_component_fit_matrix/` if split) is filled for every lead candidate, with one row per numbered restriction and per numbered acceptance criterion
- [ ] Sub-matrix uses ✅ / ❌ / ❓ / N/A only — no free-form prose substitutes
- [ ] No `Selected` candidate has any ❌ or ❓ cell in its sub-matrix
- [ ] "Validation gate required" footnotes are explicitly classified as either *API capability* (must be resolved here) or *runtime quality* (may be carried forward)
- [ ] Paraphrased capability claims in fact cards have been cross-checked against the literal mode-enumeration evidence (no `mono, inertial → mono-inertial` style conflation)
@@ -89,7 +89,7 @@ Value Translation:
## Source Registry Entry Template
For each source consulted, immediately append to `01_source_registry.md`:
For each source consulted, immediately append to `01_source_registry.md` (or the appropriate category file under `01_source_registry/` if the artifact has been split — see splittable-artifacts convention in `steps/00_project-integration.md`):
```markdown
## Source #[number]
- **Title**: [source title]
@@ -57,22 +57,49 @@ RESEARCH_DIR/
├── 03_comparison_framework.md # Step 4 output: selected framework and populated data
├── 04_reasoning_chain.md # Step 6 output: fact → conclusion reasoning
├── 05_validation_log.md # Step 7 output: use-case validation results
├── 06_component_fit_matrix.md # Step 7.5 output: component exact-fit gate
└── raw/ # Raw source archive (optional)
├── source_1.md
└── source_2.md
```
#### Splittable artifacts — Layout convention
The following three artifacts MAY equivalently be a **folder** of the same base name when the single-file form has grown unwieldy (typically ≳ 1000 lines or ≳ 200 KB):
- `01_source_registry.md``01_source_registry/`
- `02_fact_cards.md``02_fact_cards/`
- `06_component_fit_matrix.md``06_component_fit_matrix/`
When using the folder form:
- Place a `00_summary.md` index file at the folder root with a short common summary table and the cross-cutting status the single-file form would have carried in its preamble.
- Split per-entry content into category files (e.g. one file per sub-question or per component): `SQ1_*.md`, `C1_*.md`, etc. Keep entry numbering global across the folder so cross-references like "Source #42" still resolve to exactly one place.
- Cross-references from outside the folder may point at either `01_source_registry/00_summary.md` (for the index) or directly at the relevant category file.
```
RESEARCH_DIR/01_source_registry/ # split form (when single-file is too large)
├── 00_summary.md # index + investigation status + compact source table
├── SQ1_existing_systems.md # category file
├── SQ2_canonical_pipeline.md # category file
├── C1_vio.md # per-component file
└── ...
```
Throughout the rest of this skill (other steps, references, templates), the singular `XX.md` form is used as a logical name; treat each occurrence as applying equally to the folder form when the artifact has been split.
### Save Timing & Content
| Step | Save immediately after completion | Filename |
|------|-----------------------------------|----------|
| Mode A Phase 1 | AC & restrictions assessment tables | `00_ac_assessment.md` |
| Step 0-1 | Question type classification + sub-question list | `00_question_decomposition.md` |
| Step 2 | Each consulted source link, tier, summary | `01_source_registry.md` |
| Step 3 | Each fact card (statement + source + confidence) | `02_fact_cards.md` |
| Step 2 | Each consulted source link, tier, summary | `01_source_registry.md` *(splittable, see convention)* |
| Step 3 | Each fact card (statement + source + confidence) | `02_fact_cards.md` *(splittable, see convention)* |
| Step 4 | Selected comparison framework + initial population | `03_comparison_framework.md` |
| Step 6 | Reasoning process for each dimension | `04_reasoning_chain.md` |
| Step 7 | Validation scenarios + results + review checklist | `05_validation_log.md` |
| Step 7.5 | Component exact-fit gate and selection status | `06_component_fit_matrix.md` *(splittable, see convention)* |
| Step 8 | Complete solution draft | `OUTPUT_DIR/solution_draft##.md` |
### Save Principles
@@ -90,11 +117,12 @@ RESEARCH_DIR/
|------|---------|----------------|
| `00_ac_assessment.md` | AC & restrictions assessment (Mode A only) | After Phase 1 completion |
| `00_question_decomposition.md` | Question type, sub-question list | After Step 0-1 completion |
| `01_source_registry.md` | All source links and summaries | Continuously updated during Step 2 |
| `02_fact_cards.md` | Extracted facts and sources | Continuously updated during Step 3 |
| `01_source_registry.md` *(splittable)* | All source links and summaries | Continuously updated during Step 2 |
| `02_fact_cards.md` *(splittable)* | Extracted facts and sources | Continuously updated during Step 3 |
| `03_comparison_framework.md` | Selected framework and populated data | After Step 4 completion |
| `04_reasoning_chain.md` | Fact → conclusion reasoning | After Step 6 completion |
| `05_validation_log.md` | Use-case validation and review | After Step 7 completion |
| `06_component_fit_matrix.md` *(splittable)* | Exact-fit matrix for every proposed component/tool/pattern with status `Selected` / `Rejected` / `Experimental only` / `Needs user decision` | Before Step 8 deliverable formatting |
| `OUTPUT_DIR/solution_draft##.md` | Complete solution draft | After Step 8 completion |
| `OUTPUT_DIR/tech_stack.md` | Tech stack evaluation and decisions | After Phase 3 (optional) |
| `OUTPUT_DIR/security_analysis.md` | Threat model and security controls | After Phase 4 (optional) |
@@ -6,7 +6,9 @@ Triggered when no `solution_draft*.md` files exist in OUTPUT_DIR, or when the us
**Role**: Professional software architect
A focused preliminary research pass **before** the main solution research. The goal is to validate that the acceptance criteria and restrictions are realistic before designing a solution around them.
> **AC must be design-independent**: describe testable outcomes only — no libraries, algorithms, params, or design choices. Implementation follows AC, never reverse. (IEEE 830 / Atlassian / GitScrum)
A focused preliminary research pass **before** the main solution research. The goal is to validate that the acceptance criteria and restrictions are realistic before designing a solution around them. Any revision proposed in this phase must respect the design-independence rule above — propose AC changes as outcome/budget edits, not as implementation prescriptions.
**Input**: All files from INPUT_DIR (or INPUT_FILE in standalone mode)
@@ -73,16 +75,18 @@ Full 8-step research methodology. Produces the first solution draft.
**Task** (drives the 8-step engine):
1. Research existing/competitor solutions for similar problems — search broadly across industries and adjacent domains, not just the obvious competitors
2. Research the problem thoroughly — all possible ways to solve it, split into components; search for how different fields approach analogous problems
3. For each component, research all possible solutions and find the most efficient state-of-the-art approaches — use multiple query variants and perspectives from Step 1
4. For each promising approach, search for real-world deployment experience: success stories, failure reports, lessons learned, and practitioner opinions
5. Search for contrarian viewpoints — who argues against the common approaches and why? What failure modes exist?
6. Verify that suggested tools/libraries actually exist and work as described — check official repos, latest releases, and community health (stars, recent commits, open issues)
7. Include security considerations in each component analysis
8. Provide rough cost estimates for proposed solutions
3. Derive a **Project Constraint Matrix** before evaluating component options. Extract exact constraints from `problem.md`, `restrictions.md`, `acceptance_criteria.md`, input data notes, and the Phase 1 AC assessment. Include required inputs/outputs, operating context, runtime envelope, data availability, lifecycle boundaries, non-functional targets, integration boundaries, security constraints, and explicit out-of-scope decisions.
4. For each component, research all possible solutions and find the most efficient state-of-the-art approaches — use multiple query variants and perspectives from Step 1
5. For each promising approach, search for real-world deployment experience: success stories, failure reports, lessons learned, and practitioner opinions
6. Search for contrarian viewpoints — who argues against the common approaches and why? What failure modes exist?
7. Verify that suggested tools/libraries actually exist and work as described — check official repos, latest releases, and community health (stars, recent commits, open issues)
8. For every candidate component/tool/library/service/pattern/algorithm, prove exact fit against the Project Constraint Matrix. A field-adjacent solution is not selectable unless its documented implementation assumptions match the project's constraints. Mismatches must be recorded as disqualifiers and the candidate marked `Rejected`, `Experimental only`, or `Needs user decision`.
9. Include security considerations in each component analysis
10. Provide rough cost estimates for proposed solutions
Be concise in formulating. The fewer words, the better, but do not miss any important details.
**Save action**: Write `OUTPUT_DIR/solution_draft##.md` using template: `templates/solution_draft_mode_a.md`
**Save action**: Write `RESEARCH_DIR/06_component_fit_matrix.md` (or its split-folder equivalent under `RESEARCH_DIR/06_component_fit_matrix/`, per the splittable-artifacts convention in `00_project-integration.md`) before the final draft, then write `OUTPUT_DIR/solution_draft##.md` using template: `templates/solution_draft_mode_a.md`
---
@@ -10,18 +10,25 @@ Full 8-step research methodology applied to assessing and improving an existing
**Task** (drives the 8-step engine):
1. Read the existing solution draft thoroughly
2. Research in internet extensively — for each component/decision in the draft, search for:
2. Derive or refresh the **Project Constraint Matrix** from all files in INPUT_DIR. Include required inputs/outputs, operating context, runtime envelope, data availability, lifecycle boundaries, non-functional targets, integration boundaries, security constraints, and explicit out-of-scope decisions.
3. Audit every component/decision in the existing draft against the Project Constraint Matrix before researching alternatives:
- If a component's documented implementation assumptions match the project constraints, keep it eligible and record evidence.
- If fit is unproven, mark it `Experimental only` until evidence is found.
- If constraints conflict, mark it `Rejected` and search for alternatives.
- If rejecting it changes product behavior or risk materially, escalate for user decision.
4. Research in internet extensively — for each component/decision in the draft, search for:
- Known problems and limitations of the chosen approach
- What practitioners say about using it in production
- Better alternatives that may have emerged recently
- Common failure modes and edge cases
- How competitors/similar projects solve the same problem differently
3. Search specifically for contrarian views: "why not [chosen approach]", "[chosen approach] criticism", "[chosen approach] failure"
4. Identify security weak points and vulnerabilities — search for CVEs, security advisories, and known attack vectors for each technology in the draft
5. Identify performance bottlenecks — search for benchmarks, load test results, and scalability reports
6. For each identified weak point, search for multiple solution approaches and compare them
7. Based on findings, form a new solution draft in the same format
5. Search specifically for contrarian views: "why not [chosen approach]", "[chosen approach] criticism", "[chosen approach] failure"
6. Identify security weak points and vulnerabilities — search for CVEs, security advisories, and known attack vectors for each technology in the draft
7. Identify performance bottlenecks — search for benchmarks, load test results, and scalability reports
8. For each identified weak point, search for multiple solution approaches and compare them
9. For every revised candidate, prove exact fit against the Project Constraint Matrix. Do not select field-adjacent or "similar problem" options unless their intrinsic implementation constraints match the project.
10. Based on findings, form a new solution draft in the same format
**Save action**: Write `OUTPUT_DIR/solution_draft##.md` (incremented) using template: `templates/solution_draft_mode_b.md`
**Save action**: Write `RESEARCH_DIR/06_component_fit_matrix.md` (or its split-folder equivalent under `RESEARCH_DIR/06_component_fit_matrix/`, per the splittable-artifacts convention in `00_project-integration.md`) before the final draft, then write `OUTPUT_DIR/solution_draft##.md` (incremented) using template: `templates/solution_draft_mode_b.md`
**Optional follow-up**: After Mode B completes, the user can request Phase 3 (Tech Stack Consolidation) or Phase 4 (Security Deep Dive) using the revised draft. These phases work identically to their Mode A descriptions in `steps/01_mode-a-initial-research.md`.
@@ -40,6 +40,7 @@ Key principle: Critical-sensitivity topics (AI/LLMs, blockchain) require sources
- "What existing/competitor solutions address this problem?"
- "What are the component parts of this problem?"
- "For each component, what are the state-of-the-art solutions?"
- "For each component, what are the practical alternatives across simple baseline, established production option, open-source option, commercial option, current SOTA, adjacent-domain option, and no-build/defer option?"
- "What are the security considerations per component?"
- "What are the cost implications of each approach?"
@@ -48,6 +49,7 @@ Key principle: Critical-sensitivity topics (AI/LLMs, blockchain) require sources
- "What are the security vulnerabilities in the proposed architecture?"
- "Where are the performance bottlenecks?"
- "What solutions exist for each identified issue?"
- "For each component already selected in the draft, what alternatives should be considered before keeping, replacing, or rejecting it?"
**General sub-question patterns** (use when applicable):
- **Sub-question A**: "What is X and how does it work?" (Definition & mechanism)
@@ -84,6 +86,27 @@ For **each sub-question**, generate **at least 3-5 search query variants** befor
Record all planned queries in `00_question_decomposition.md` alongside each sub-question.
#### Component Option Breadth (MANDATORY)
Before Step 2, identify the component areas implied by the problem and create a search plan for options in each area. A component area is any replaceable tool, library, model, service, algorithm, data format, protocol, infrastructure pattern, or validation approach that could materially affect the solution.
For every component area, generate search queries for these option families unless clearly not applicable:
- **Simple baseline**: low-complexity classical or manual approach that can serve as a fallback or regression baseline.
- **Established production option**: mature library/service/pattern with field usage.
- **Open-source candidate**: permissive-license option with inspectable implementation and community history.
- **Commercial/vendor option**: paid or vendor-supported option, including SDK/platform constraints.
- **Current SOTA / research option**: recent model, paper, or benchmark leader that may be promising but immature.
- **Adjacent-domain option**: solution from a neighboring domain with similar constraints.
- **No-build / defer option**: whether the component can be avoided, simplified, or moved out of scope.
- **Known bad option**: candidate or family that appears attractive but has documented failure modes or disqualifiers.
For each component area, record:
- Candidate names and option families to search.
- At least 5 query variants covering alternatives, comparisons, limitations, licensing, runtime/scale, and exact project constraints.
- The minimum evidence needed to mark a candidate `Selected`, `Rejected`, `Experimental only`, or `Needs user decision`.
Add this as a "Component Option Search Plan" section in `00_question_decomposition.md`.
**Research Subject Boundary Definition (BLOCKING - must be explicit)**:
When decomposing questions, you must explicitly define the **boundaries of the research subject**:
@@ -94,9 +117,22 @@ When decomposing questions, you must explicitly define the **boundaries of the r
| **Geography** | Which region is being studied? | Chinese universities vs US universities vs global |
| **Timeframe** | Which period is being studied? | Post-2020 vs full historical picture |
| **Level** | Which level is being studied? | Undergraduate vs graduate vs vocational |
| **Operating context** | What exact environment, lifecycle phase, and runtime conditions must the solution support? | In-flight embedded runtime vs offline post-processing; production web traffic vs admin batch job |
| **Required interfaces** | What inputs, outputs, protocols, data shapes, and ownership boundaries are fixed? | One camera vs stereo rig; REST API vs message queue; local file boundary vs service API |
| **Non-functional envelope** | What latency, throughput, storage, memory, availability, safety, security, cost, and maintainability targets are binding? | <400 ms p95, 8 GB RAM, 99.9% availability, reversible migrations |
**Common mistake**: User asks about "university classroom issues" but sources include policies targeting "K-12 students" — mismatched target populations will invalidate the entire research.
#### Decomposition Completeness Audit (MANDATORY)
After generating sub-questions, verify the decomposition covers all major dimensions of the problem — not just the ones that came to mind first.
1. **Domain discovery search**: Search the web for "key factors when [problem domain]" / "what to consider when [problem domain]" (e.g., "key factors GPS-denied navigation", "what to consider when choosing an edge deployment strategy"). Extract dimensions that practitioners and domain experts consider important but are absent from the current sub-questions.
2. **Run completeness probes**: Walk through each probe in `references/comparison-frameworks.md` → "Decomposition Completeness Probes" against the current sub-question list. For each probe, note whether it is covered, not applicable (state why), or missing.
3. **Fill gaps**: Add sub-questions (with search query variants) for any uncovered area. Do this before proceeding to Step 2.
Record the audit result in `00_question_decomposition.md` as a "Completeness Audit" section.
**Save action**:
1. Read all files from INPUT_DIR to ground the research in the project context
2. Create working directory `RESEARCH_DIR/`
@@ -106,9 +142,12 @@ When decomposing questions, you must explicitly define the **boundaries of the r
- Summary of relevant problem context from INPUT_DIR
- Classified question type and rationale
- **Research subject boundary definition** (population, geography, timeframe, level)
- **Project Constraint Matrix summary** (operating context, required interfaces, non-functional envelope, lifecycle assumptions, and hard disqualifiers extracted from input files)
- List of decomposed sub-questions
- **Chosen perspectives** (at least 3 from the Perspective Rotation table) with rationale
- **Search query variants** for each sub-question (at least 3-5 per sub-question)
- **Component Option Search Plan** (component areas, option families, candidate names, query variants, required evidence)
- **Completeness audit** (taxonomy cross-reference + domain discovery results)
4. Write TodoWrite to track progress
---
@@ -121,7 +160,7 @@ Tier sources by authority, **prioritize primary sources** (L1 > L2 > L3 > L4). C
**Tool Usage**:
- Use `WebSearch` for broad searches; `WebFetch` to read specific pages
- Use the `context7` MCP server (`resolve-library-id` then `get-library-docs`) for up-to-date library/framework documentation
- Use the `context7` MCP server (`resolve-library-id` then `query-docs` / `get-library-docs`) for up-to-date library/framework documentation. **Mandatory per lead candidate** — see "API Capability Verification" below.
- Always cross-verify training data claims against live sources for facts that may have changed (versions, APIs, deprecations, security advisories)
- When citing web sources, include the URL and date accessed
@@ -134,17 +173,77 @@ Do not stop at the first few results. The goal is to build a comprehensive evide
- Consult at least **2 different source tiers** per sub-question (e.g., L1 official docs + L4 community discussion)
- If initial searches yield fewer than 3 relevant sources for a sub-question, **broaden the search** with alternative terms, related domains, or analogous problems
**Minimum search effort per component area**:
- Search every option family from the "Component Option Search Plan" before choosing a lead candidate.
- For each lead, fallback, or rejected candidate, search at least one official/source-of-truth page and at least one independent validation source when available.
- Search `"[component] alternatives"`, `"[candidate] vs [alternative]"`, `"[candidate] limitations"`, `"[candidate] license"`, `"[candidate] production"`, and `"[candidate] [binding project constraint]"`.
- If fewer than 3 realistic candidates are found for a component area, explicitly document why the landscape is narrow and search adjacent domains before accepting that result.
- Include at least one simple baseline and one "do not use" or disqualified candidate per component area when possible; these prevent false confidence in the selected option.
**Candidate implementation-limit searches (MANDATORY)**:
For every component/tool/library/service/pattern/algorithm that may be selected or recommended, search for its intrinsic implementation constraints. Do not rely on product category labels, marketing summaries, or examples from a different operating context. Include query variants for:
- Official supported inputs/outputs, protocols, data formats, and deployment modes
- Required hardware/runtime/platform/version constraints
- Timing, throughput, memory, storage, synchronization, and scaling assumptions
- Lifecycle assumptions: offline vs online, batch vs real time, development vs production, single tenant vs multi tenant, local vs networked
- Known unsupported scenarios, limitations, issue reports, production failures, and workarounds
- Licensing, security, maintenance, and community-health constraints
- Exact phrases from the project's restrictions and acceptance criteria combined with the candidate name
**API Capability Verification — Per-Mode (MANDATORY, BLOCKING for lead candidates)**:
**Applicability**: this section applies only when the run is classified as **Technical-component selection** in the SKILL's Research Output Class section, and only to lead candidates that are libraries/SDKs/frameworks/services/protocols/data formats with multiple modes or configurations. For non-technical research (concept comparison, market/policy investigation, knowledge organization, root-cause analysis without tooling commitments), skip this entire sub-section and continue with the rest of Step 2 — the broader candidate implementation-limit search above is sufficient. State the skip explicitly once in `02_fact_cards.md` (or in `02_fact_cards/00_summary.md` if split): `API Capability Verification: not applicable — this run is a Non-technical investigation, no library/SDK/service candidates`.
Most libraries/SDKs/services expose **multiple modes or configurations** (e.g., monocular vs stereo VO, sync vs async API, batch vs streaming inference, write-through vs write-behind cache). Selecting a candidate "because it supports X" without pinning *which mode* the project will use, and *whether that exact mode produces the required outputs from the required inputs*, is the most common silent-failure path in research. A library can support a class of problem in mode A while being unusable for the project's specific configuration in mode B.
For every lead candidate that is a library/SDK/framework/service with multiple modes or configurations, do the following — in this order, before marking the candidate `Selected`:
1. **Pin the exact mode/configuration the project will use.**
Derived from the Project Constraint Matrix: which inputs are available (sensor count, sensor types, data shapes, rates), which outputs are required (per `acceptance_criteria.md` and contract files), which hardware/runtime is fixed (per `restrictions.md`). Write this as a single sentence: "We will use `<library>` in `<mode/config>` with inputs `<list>` and expect outputs `<list>` on `<runtime>`." Do not progress past this step on a vague mode description.
2. **Run `context7` (or equivalent docs lookup) for the candidate** — this is **mandatory for every lead library/SDK/framework candidate**, not optional. Minimum three queries per candidate:
1. *Mode enumeration*: "What modes/configurations does `<library>` support? List every value of the mode/config enum and what each requires as input."
2. *Project's exact mode*: "Show a minimum runnable example of `<library>` in `<the pinned mode>` with `<the project's input shape>`. What does it produce?"
3. *Disqualifier probe*: "Does `<library>` `<the pinned mode>` produce `<the required output>`? Are there published limitations of `<the pinned mode>` for `<the project's runtime/hardware>`?"
For services without context7 coverage, use official docs site + WebFetch on the API reference page + the project's example/tutorial directory in the source repo. Append every consulted URL to `01_source_registry.md` (or the appropriate category file under `01_source_registry/` if split — see splittable-artifacts convention in `00_project-integration.md`).
3. **Save a Minimum Viable Example (MVE) for the pinned mode.**
Append to `02_fact_cards.md` / `02_fact_cards/` (or a sibling `02_mve_evidence.md`) at least one block per lead library candidate with:
```markdown
## MVE — <library> in <pinned mode>
- **Source**: <official URL or context7 reference, with date>
- **Inputs in the example**: <e.g., 2 calibrated cameras + IMU at 200 Hz>
- **Outputs in the example**: <e.g., 6-DoF pose with covariance>
- **Project inputs**: <e.g., 1 camera + IMU at 200 Hz>
- **Project outputs required**: <e.g., 6-DoF pose with metric translation>
- **Match assessment**: ✅ exact match / ⚠️ partial (specify dimension) / ❌ mismatch (specify dimension)
- **If ⚠️ or ❌**: cite the official-docs sentence that establishes the mismatch.
```
If no official example covers the project's exact configuration → the candidate cannot be marked `Selected` based on category fit alone. Status must be `Experimental only` (with required-evidence note) or `Rejected` (when the docs explicitly disqualify the configuration).
4. **Bind every numbered Restriction and Acceptance Criterion to the candidate's pinned mode.**
For each numbered line in `restrictions.md` and `acceptance_criteria.md`, decide one of: `Pass` (the pinned mode satisfies it with cited evidence), `Fail` (the pinned mode contradicts it with cited evidence), `Verify` (no evidence either way; deeper investigation required), `N/A` (the line is irrelevant to this component area). Record this in `02_fact_cards.md` (or the candidate's per-component file under `02_fact_cards/` if split) under the candidate's MVE block. The structural matrix in Step 7.5 reads from these bindings.
5. **Treat "the same library in a different mode" as a different candidate.**
If the project's pinned mode is `Monocular` but the only documented evidence covers `Stereo`, do not silently soften "rotation only" into "rotation + translation". Open a separate candidate row for the Monocular mode, with its own MVE, fit assessment, and disqualifiers. Two modes of one library are two distinct candidates for the purposes of this gate.
**Common silent-failure pattern this guards against**: a fact card paraphrases the docs as "supports A, B, C, D modes" when the docs actually mean "supports A; B; C and D as separate orthogonal modes". A category-level "Selected" decision then carries through every downstream artifact, masking that the project's required A+B combination does not exist as a single mode.
**Search broadening strategies** (use when results are thin):
- Try adjacent fields: if researching "drone indoor navigation", also search "robot indoor navigation", "warehouse AGV navigation"
- Try different communities: academic papers, industry whitepapers, military/defense publications, hobbyist forums
- Try different geographies: search in English + search for European/Asian approaches if relevant
- Try historical evolution: "history of X", "evolution of X approaches", "X state of the art 2024 2025"
- Try failure analysis: "X project failure", "X post-mortem", "X recall", "X incident report"
- Try disqualifier probes: "X unsupported", "X limitations", "X requirements", "X with [project constraint]", "X without [required input]", "X real-time [target]", "X production failure"
**Search saturation rule**: Continue searching until new queries stop producing substantially new information. If the last 3 searches only repeat previously found facts, the sub-question is saturated.
**Save action**:
For each source consulted, **immediately** append to `01_source_registry.md` using the entry template from `references/source-tiering.md`.
For each source consulted, **immediately** append to `01_source_registry.md` (or the appropriate category file under `01_source_registry/` if split) using the entry template from `references/source-tiering.md`.
---
@@ -174,7 +273,7 @@ Transform sources into **verifiable fact cards**:
- ❓ Low: Inference or from unofficial sources
**Save action**:
For each extracted fact, **immediately** append to `02_fact_cards.md`:
For each extracted fact, **immediately** append to `02_fact_cards.md` (or the appropriate category file under `02_fact_cards/` if split):
```markdown
## Fact #[number]
- **Statement**: [specific fact description]
@@ -183,6 +282,7 @@ For each extracted fact, **immediately** append to `02_fact_cards.md`:
- **Target Audience**: [which group this fact applies to, inherited from source or further refined]
- **Confidence**: ✅/⚠️/❓
- **Related Dimension**: [corresponding comparison dimension]
- **Fit Impact**: [supports selection / disqualifies / makes experimental / needs user decision]
```
**Target audience in fact statements**:
@@ -218,7 +318,7 @@ After initial fact extraction, review what you have found and identify **knowled
- Failure cases and edge conditions
- Recent developments that may change the picture
4. **Update artifacts**: Append new sources to `01_source_registry.md`, new facts to `02_fact_cards.md`
4. **Update artifacts**: Append new sources to `01_source_registry.md`, new facts to `02_fact_cards.md` (use the appropriate category files under `01_source_registry/` and `02_fact_cards/` if split)
**Exit criteria**: Proceed to Step 4 when:
- Every sub-question has at least 3 facts with at least one from L1/L2
@@ -24,6 +24,18 @@ Write to `03_comparison_framework.md`:
| ... | | | |
```
**Required exact-fit dimensions for component/tool decisions**:
When the output selects or recommends a component, tool, library, service, architecture pattern, or algorithm, the framework MUST include these dimensions unless explicitly not applicable:
- Option family (`Simple baseline`, `Established production`, `Open-source`, `Commercial/vendor`, `Current SOTA`, `Adjacent-domain`, `No-build/defer`, `Known bad`)
- Required inputs/outputs and ownership boundaries
- Operating context and lifecycle fit
- Non-functional envelope fit
- Implementation assumptions and hard disqualifiers
- Evidence quality and source tier
- Selection status (`Selected`, `Rejected`, `Experimental only`, `Needs user decision`)
For each component area, include multiple candidates in the initial population. Do not present only the preferred option unless the investigation found no realistic alternatives; if so, state the searches that proved the narrow landscape.
---
### Step 5: Reference Point Baseline Alignment
@@ -97,6 +109,8 @@ Validate conclusions against a typical scenario:
- [ ] Are there any important dimensions missed?
- [ ] Is there any over-extrapolation?
- [ ] Are conclusions actionable/verifiable?
- [ ] Does every selected component/tool/pattern match the Project Constraint Matrix?
- [ ] Are mismatches marked as disqualifiers instead of hidden as generic "limitations"?
**Save action**:
Write to `05_validation_log.md`:
@@ -128,6 +142,66 @@ If using Y: [expected behavior]
---
### Step 7.5: Component Applicability Gate (BLOCKING)
**Applicability**: this gate applies only when the run is classified as **Technical-component selection** in the SKILL's Research Output Class section. For non-technical research (concept comparison, market/policy investigation, root-cause analysis without tooling, knowledge organization), skip this entire step and proceed to Step 8 — there are no components to gate. State the skip once in `05_validation_log.md`: `Step 7.5 (Component Applicability Gate): not applicable — Non-technical investigation`. For mixed runs (some component areas technical, some not), apply this gate only to the technical component areas; the non-technical ones do not produce 7.5 rows.
Before finalizing the solution draft, build an exact-fit matrix for every component/tool/library/service/pattern/algorithm that is selected, recommended, rejected, or treated as a fallback. Free-form prose in a "Project Constraints Checked" column is **not sufficient** — mismatches hide inside rationale text. The matrix must be structured per restriction and per acceptance criterion.
#### 7.5.1 Top-level Component Fit Matrix
```markdown
# Component Fit Matrix
| Component Area | Candidate | Pinned Mode/Config | Option Family | Intended Role | API Capability Evidence | Mismatches / Disqualifiers | Status | Decision Rationale |
|----------------|-----------|--------------------|---------------|---------------|-------------------------|----------------------------|--------|--------------------|
| [area] | [name] | [exact mode/config the project will use, copied verbatim from the MVE block in Step 2] | [family] | [role] | MVE: [link to MVE block in `02_fact_cards.md` / `02_fact_cards/` or `02_mve_evidence.md`]; docs: [Source #] | [none / list] | Selected / Rejected / Experimental only / Needs user decision | [why] |
```
The new **Pinned Mode/Config** column is mandatory. A row without a pinned mode is incomplete. The new **API Capability Evidence** column links to the Minimum Viable Example saved during Step 2's API Capability Verification — without an MVE link the candidate cannot be `Selected`.
#### 7.5.2 Restrictions × Candidate-Modes Sub-Matrix (MANDATORY)
For each lead candidate row in the top-level matrix, append a structured cross-check that walks every numbered line of `restrictions.md` and `acceptance_criteria.md` against the candidate's **pinned mode/config**.
```markdown
## Sub-Matrix — <Candidate Name> in <Pinned Mode>
| Restriction / AC | Candidate-mode behavior | Result | Evidence |
|------------------|-------------------------|--------|----------|
| R1: <verbatim line from restrictions.md> | <how the pinned mode behaves under this restriction> | ✅ Pass / ❌ Fail / ❓ Verify / N/A | [Fact # / Source # / MVE link] |
| R2: ... | ... | ... | ... |
| ... | ... | ... | ... |
| AC-1.1: <verbatim line from acceptance_criteria.md> | <how the pinned mode satisfies (or contradicts) this AC's measurable target> | ✅ / ❌ / ❓ / N/A | [Fact # / Source # / MVE link] |
| AC-1.2: ... | ... | ... | ... |
| ... | ... | ... | ... |
```
Cell semantics:
- ✅ **Pass** — the candidate's pinned mode satisfies this line, with cited official-doc or MVE evidence.
- ❌ **Fail** — the candidate's pinned mode contradicts this line, with cited evidence. Even one ❌ disqualifies the candidate from `Selected` status.
- ❓ **Verify** — no evidence yet either way; further investigation required (loops back to Step 2 / Step 3.5). A row left ❓ at the end of analysis blocks the candidate.
- **N/A** — the line is irrelevant to this component area (state why in one phrase).
A candidate row may not be marked `Selected` while any cell is ❌ or ❓.
#### 7.5.3 Decision Rules
- `Selected` is allowed only when (a) the top-level row has an MVE link, (b) the sub-matrix has zero ❌, (c) the sub-matrix has zero ❓, and (d) the candidate's documented implementation assumptions match the project's explicit constraints and acceptance criteria.
- `Experimental only` is required when a candidate might work but lacks proof for the exact operating context (e.g., MVE exists for a similar configuration but not the exact one).
- `Rejected` is required when documented assumptions conflict with project constraints (any sub-matrix row is ❌ with cited evidence).
- `Needs user decision` is required when a mismatch changes scope, cost, safety, product behavior, or acceptance criteria — and the user has not yet been consulted.
- Each component area must include at least one selected or fallback-safe option, plus the most credible rejected/experimental alternatives discovered during web research.
- A component area with only one candidate is incomplete unless `00_question_decomposition.md` documents the broader searches and why they yielded no realistic alternatives.
- A candidate may not appear as the lead solution in Step 8 unless this gate marks it `Selected`.
- "Validation gate required" footnotes are not equivalent to `Selected`. If the validation gate concerns API capability (does the mode produce the required output?), that is a Step-2 / Step-7.5 question and must be resolved here, not deferred to runtime. Only validation gates concerning *runtime quality* (e.g., "does this VO converge on this terrain class?") may be carried forward as `Selected with runtime gate`.
**Save action**: Write `06_component_fit_matrix.md` (or, when split, the equivalent files under `06_component_fit_matrix/` — typically `00_summary.md` for the top-level matrix plus per-component sub-matrix files) containing both 7.5.1 (top-level) and 7.5.2 (per-candidate sub-matrices).
**BLOCKING**: If any lead candidate has ❌, ❓, `Experimental only`, `Rejected`, or `Needs user decision` status, do not silently proceed. Ask the user or choose a different selected candidate.
---
### Step 8: Deliverable Formatting
Make the output **readable, traceable, and actionable**.
@@ -139,8 +213,8 @@ Integrate all intermediate artifacts. Write to `OUTPUT_DIR/solution_draft##.md`
Sources to integrate:
- Extract background from `00_question_decomposition.md`
- Reference key facts from `02_fact_cards.md`
- Reference key facts from `02_fact_cards.md` (or files under `02_fact_cards/` if split)
- Organize conclusions from `04_reasoning_chain.md`
- Generate references from `01_source_registry.md`
- Generate references from `01_source_registry.md` (or files under `01_source_registry/` if split)
- Supplement with use cases from `05_validation_log.md`
- For Mode A: include AC assessment from `00_ac_assessment.md`
@@ -10,12 +10,21 @@
[Architecture solution that meets restrictions and acceptance criteria.]
> **Applicability** — the table columns `Pinned Mode/Config` and `API Capability Evidence` apply only to technical-component runs (per SKILL.md → Research Output Class). For non-technical research outputs (concept comparison, market/policy report, investigation answer), this Architecture section may be replaced with a comparison/analysis section that does not use these columns; or the columns may be marked `N/A` per row when the row describes a non-technical "component" (a process, a policy, an organizational construct). For mixed runs, fill the columns only on rows that describe libraries/SDKs/frameworks/services/protocols/data formats/algorithms.
### Component: [Component Name]
| Solution | Tools | Advantages | Limitations | Requirements | Security | Cost | Fit |
|----------|-------|-----------|-------------|-------------|----------|------|-----|
| [Option 1] | [lib/platform] | [pros] | [cons] | [reqs] | [security] | [cost] | [fit assessment] |
| [Option 2] | [lib/platform] | [pros] | [cons] | [reqs] | [security] | [cost] | [fit assessment] |
| Solution | Tools | Pinned Mode/Config | Advantages | Limitations | Requirements | Security | Cost | API Capability Evidence | Fit |
|----------|-------|--------------------|-----------|-------------|-------------|----------|------|-------------------------|-----|
| [Option 1] | [lib/platform] | [exact mode/config used: inputs, outputs, runtime] | [pros] | [cons] | [intrinsic requirements] | [security] | [cost] | MVE: [link to MVE block]; docs: [Source #] | [Selected / Rejected / Experimental only / Needs user decision — cite exact-fit evidence and disqualifiers] |
| [Option 2] | [lib/platform] | [exact mode/config used] | [pros] | [cons] | [intrinsic requirements] | [security] | [cost] | MVE: [link]; docs: [Source #] | [Selected / Rejected / Experimental only / Needs user decision] |
**Exact-fit evidence**:
- Project constraints checked: [inputs/outputs, operating context, lifecycle, NFRs, acceptance criteria]
- Evidence: [Fact # / Source #]
- Disqualifiers: [none or list]
- Restrictions × Candidate-Modes sub-matrix: see `06_component_fit_matrix.md` (or `06_component_fit_matrix/` if split) § <Candidate Name>
- API capability gates: ✅ MVE saved / ⚠️ partial — see disqualifiers / ❌ no MVE — candidate is Experimental only or Rejected
[Repeat per component]
@@ -13,12 +13,21 @@
[Architecture solution that meets restrictions and acceptance criteria.]
> **Applicability** — the table columns `Pinned Mode/Config` and `API Capability Evidence` apply only to technical-component runs (per SKILL.md → Research Output Class). For non-technical assessment outputs (e.g., reassessing a policy approach, comparing organizational designs), this Architecture section may be replaced with the assessment content that does not use these columns; or the columns may be marked `N/A` per row for non-technical "components". For mixed runs, fill the columns only on rows that describe libraries/SDKs/frameworks/services/protocols/data formats/algorithms.
### Component: [Component Name]
| Solution | Tools | Advantages | Limitations | Requirements | Security | Performance | Fit |
|----------|-------|-----------|-------------|-------------|----------|------------|-----|
| [Option 1] | [lib/platform] | [pros] | [cons] | [reqs] | [security] | [perf] | [fit assessment] |
| [Option 2] | [lib/platform] | [pros] | [cons] | [reqs] | [security] | [perf] | [fit assessment] |
| Solution | Tools | Pinned Mode/Config | Advantages | Limitations | Requirements | Security | Performance | API Capability Evidence | Fit |
|----------|-------|--------------------|-----------|-------------|-------------|----------|------------|-------------------------|-----|
| [Option 1] | [lib/platform] | [exact mode/config used: inputs, outputs, runtime] | [pros] | [cons] | [intrinsic requirements] | [security] | [perf] | MVE: [link to MVE block]; docs: [Source #] | [Selected / Rejected / Experimental only / Needs user decision — cite exact-fit evidence and disqualifiers] |
| [Option 2] | [lib/platform] | [exact mode/config used] | [pros] | [cons] | [intrinsic requirements] | [security] | [perf] | MVE: [link]; docs: [Source #] | [Selected / Rejected / Experimental only / Needs user decision] |
**Exact-fit evidence**:
- Project constraints checked: [inputs/outputs, operating context, lifecycle, NFRs, acceptance criteria]
- Evidence: [Fact # / Source #]
- Disqualifiers: [none or list]
- Restrictions × Candidate-Modes sub-matrix: see `06_component_fit_matrix.md` (or `06_component_fit_matrix/` if split) § <Candidate Name>
- API capability gates: ✅ MVE saved / ⚠️ partial — see disqualifiers / ❌ no MVE — candidate is Experimental only or Rejected
[Repeat per component]
+75 -2
View File
@@ -53,9 +53,15 @@ METRICS_DIR/
└── ...
```
## Invocation Modes
- **cycle-end mode** (default): invoked automatically at end of cycle by the autodev orchestrator — as greenfield Step 11 Retrospective (after Step 10 Deploy) and existing-code Step 17 Retrospective (after Step 16 Deploy). Runs Steps 14. Output: `retro_<YYYY-MM-DD>.md` + LESSONS.md update.
- **incident mode**: invoked automatically after the failure retry protocol reaches `retry_count: 3` and the user has made a recovery choice. Runs Steps 1 (scoped to the failing skill's artifacts only), 2 (focused on the failure), 3 (shorter report), 4 (append 13 lessons in the `process` or `tooling` category). Output: `_docs/06_metrics/incident_<YYYY-MM-DD>_<skill>.md` + LESSONS.md update. Pass the invocation context with `mode: incident`, `failing_skill: <skill-name>`, and `failure_summary: <string>`.
- **on-demand mode**: user-triggered (trigger phrases above). Runs Steps 14 over the entire artifact set.
## Progress Tracking
At the start of execution, create a TodoWrite with all steps (1 through 3). Update status as each step completes.
At the start of execution, create a TodoWrite with all steps (1 through 4). Update status as each step completes.
## Workflow
@@ -74,6 +80,9 @@ At the start of execution, create a TodoWrite with all steps (1 through 3). Upda
| Task spec files in TASKS_DIR | Complexity points per task, dependency count |
| `implementation_report_*.md` | Total tasks, total batches, overall duration |
| Git log (if available) | Commits per batch, files changed per batch |
| `cumulative_review_batches_*.md` `## Baseline Delta` | Architecture findings: carried over / resolved / newly introduced counts |
| `_docs/02_document/module-layout.md` + source import graph | Component count, cross-component edges, cycles, avg imports/module |
| `_docs/02_document/contracts/**/*.md` | Contract count, contracts per public-API symbol |
#### Metrics to Compute
@@ -90,15 +99,35 @@ At the start of execution, create a TodoWrite with all steps (1 through 3). Upda
- Code review findings by category: Bug, Spec-Gap, Security, Performance, Maintainability, Style, Scope
- FAIL count (batches that required user intervention)
**Structural Metrics** (skip only if `module-layout.md` is absent):
- Component count and change vs previous cycle
- Cross-component import edges and change vs previous cycle
- Cycles in the component import graph (should stay 0; any new cycle is a regression)
- Average imports per module
- New Architecture violations this cycle (from `## Baseline Delta` → Newly introduced)
- Resolved Architecture violations this cycle (from `## Baseline Delta` → Resolved)
- Net Architecture delta = new resolved (negative is good)
- Percentage of public-API symbols covered by a contract file (contract count / public-API symbol count)
- `shared/*` entries used by ≥2 components (healthy) vs by ≤1 component (dead cross-cutting)
Persist the structural snapshot to `METRICS_DIR/structure_[YYYY-MM-DD].md` so future retros can compute deltas without re-deriving from source.
**Efficiency Metrics**:
- Blocked task count and reasons
- Tasks completed on first attempt vs requiring fixes
- Batch with most findings (identify problem areas)
**Auto-lesson triggers** (feed Step 4 LESSONS.md generation):
- Net Architecture delta > 0 this cycle → `architecture` lesson
- Any structural metric regressed by >20% vs previous snapshot → `architecture` or `dependencies` lesson depending on the metric
- Contract coverage % decreased → `architecture` lesson
**Self-verification**:
- [ ] All batch reports parsed
- [ ] All metric categories computed
- [ ] No batch reports missed
- [ ] Structural snapshot written (or explicitly skipped with reason "module-layout.md absent")
- [ ] If a previous `structure_*.md` exists, deltas are computed against the most recent one
---
@@ -141,12 +170,55 @@ Write `METRICS_DIR/retro_[YYYY-MM-DD].md` using `templates/retrospective-report.
- [ ] Top 3 improvement actions clearly stated
- [ ] Suggested rule/skill updates are specific
**Save action**: Write `retro_[YYYY-MM-DD].md`
**Save action**: Write `retro_[YYYY-MM-DD].md` (in cycle-end / on-demand mode) or `incident_[YYYY-MM-DD]_[skill].md` (in incident mode).
Present the report summary to the user.
---
### Step 4: Update Lessons Log
**Role**: Process improvement analyst
**Goal**: Keep a short, frequently-consulted log of actionable lessons that downstream skills read before they plan or estimate.
1. Extract the **top 3 concrete lessons** from the current retrospective (or 13 lessons in incident mode, scoped to the failing skill). Each lesson must:
- Be specific enough to change future behavior (not a platitude).
- Be single-sentence.
- Be tied to one of the categories: `estimation`, `architecture`, `testing`, `dependencies`, `tooling`, `process`.
2. Append one bullet per lesson to `_docs/LESSONS.md` using this format:
```
- [YYYY-MM-DD] [category] one-line lesson statement.
Source: _docs/06_metrics/retro_YYYY-MM-DD.md
```
3. After appending, trim `_docs/LESSONS.md` to keep only the last **15 entries** (ring buffer). Oldest entries drop off the top. Preserve the file's header section if present.
4. If `_docs/LESSONS.md` does not exist, create it with this skeleton before appending:
```markdown
# Lessons Log
A ring buffer of the last 15 actionable lessons extracted from retrospectives and incidents.
Downstream skills consume this file:
- `.cursor/skills/new-task/SKILL.md` (Step 2 Complexity Assessment)
- `.cursor/skills/plan/steps/06_work-item-epics.md` (epic sizing)
- `.cursor/skills/decompose/SKILL.md` (Step 2 task complexity)
- `.cursor/skills/autodev/SKILL.md` (Execution Loop step 0 — surface top 3 lessons)
Categories: estimation · architecture · testing · dependencies · tooling · process
```
**Self-verification**:
- [ ] 13 lessons extracted (3 in cycle-end / on-demand mode, 13 in incident mode)
- [ ] Each lesson is single-sentence, specific, and tagged with a valid category
- [ ] Each lesson includes a Source link back to its retro or incident file
- [ ] `_docs/LESSONS.md` trimmed to at most 15 entries
- [ ] Skeleton header preserved if file was just created
**Save action**: Write (or update) `_docs/LESSONS.md`.
---
## Escalation Rules
| Situation | Action |
@@ -167,6 +239,7 @@ Present the report summary to the user.
│ 1. Collect Metrics → parse batch reports, compute metrics │
│ 2. Analyze Trends → patterns, comparison, improvement areas │
│ 3. Produce Report → _docs/06_metrics/retro_[date].md │
│ 4. Update Lessons → append top-3 to _docs/LESSONS.md (≤15) │
├────────────────────────────────────────────────────────────────┤
│ Principles: Data-driven · Actionable · Cumulative │
│ Non-judgmental · Save immediately │
+1 -1
View File
@@ -4,7 +4,7 @@ description: |
OWASP-based security audit skill. Analyzes codebase for vulnerabilities across dependency scanning,
static analysis, OWASP Top 10 review, and secrets detection. Produces a structured security report
with severity-ranked findings and remediation guidance.
Can be invoked standalone or as part of the autopilot flow (optional step before deploy).
Can be invoked standalone or as part of the autodev flow (optional step before deploy).
Trigger phrases:
- "security audit", "security scan", "OWASP review"
- "vulnerability scan", "security check"
+162 -26
View File
@@ -13,9 +13,35 @@ disable-model-invocation: true
# Test Run
Run the project's test suite and report results. This skill is invoked by the autopilot at verification checkpoints — after implementing tests, after implementing features, or at any point where the test suite must pass before proceeding.
Run the project's test suite and report results. This skill is invoked by the autodev at verification checkpoints — after implementing tests, after implementing features, before deploy — or any point where a test suite must pass before proceeding.
## Workflow
## Modes
test-run has two modes. The caller passes the mode explicitly; if missing, default to `functional`.
| Mode | Scope | Typical caller | Input artifacts |
|------|-------|---------------|-----------------|
| `functional` (default) | Unit / integration / blackbox tests — correctness | autodev Steps that verify after Implement Tests or Implement | `scripts/run-tests.sh`, `_docs/02_document/tests/environment.md`, `_docs/02_document/tests/blackbox-tests.md` |
| `perf` | Performance / load / stress / soak tests — latency, throughput, error-rate thresholds | autodev greenfield Step 15, existing-code Step 15 (pre-deploy) | `scripts/run-performance-tests.sh`, `_docs/02_document/tests/performance-tests.md`, AC thresholds in `_docs/00_problem/acceptance_criteria.md` |
Direct user invocation (`/test-run`) defaults to `functional`. If the user says "perf tests", "load test", "performance", or passes a performance scenarios file, run `perf` mode.
After selecting a mode, read its corresponding workflow below; do not mix them.
---
## Functional Mode
### 0. System-Under-Test Reality Gate
Before accepting any functional, blackbox, or e2e result as a pass, verify what the tests actually exercised.
1. If `_docs/00_problem/input_data/expected_results/results_report.md` exists, at least one e2e/blackbox run must compare actual product outputs against that mapping or the machine-readable files it references.
2. Stubs are allowed only for external systems outside the product boundary: flight controller/SITL, QGC observer, satellite-provider/Suite service, physical Jetson hardware, physical camera, unavailable licensed datasets, and network services.
3. Stubs, fakes, deterministic fallbacks, monkeypatches, or direct replacement of internal product modules are not allowed for the behavior under test. Internal examples include VIO, safety/anchor wrapper, satellite retrieval, anchor verification, tile manager, MAVLink output adapter, FDR, and the A-Z localization pipeline.
4. If tests pass only because an internal module is fake/scaffolded, classify the run as **failed** with category `missing product implementation`.
5. If a scenario is blocked because external hardware/data is absent, verify the production code path exists before accepting the block as legitimate. Missing internal production code is not an environment block.
6. If the test runner writes CSV/Markdown reports, inspect them. A zero exit code is not enough; blocked/internal-stubbed scenarios still require classification.
### 1. Detect Test Runner
@@ -79,7 +105,7 @@ Categorize skips as: **explicit skip (dead code)**, **runtime skip (unreachable)
### 5. Handle Outcome
**All tests pass, zero skipped** → return success to the autopilot for auto-chain.
**All tests pass, zero skipped, and the System-Under-Test Reality Gate passes** → return success to the autodev for auto-chain.
**Any test fails or errors** → this is a **blocking gate**. Never silently ignore failures. **Always investigate the root cause before deciding on an action.** Read the failing test code, read the error output, check service logs if applicable, and determine whether the bug is in the test or in the production code.
@@ -100,34 +126,48 @@ After investigating, present:
```
- If user picks A → apply fixes, then re-run (loop back to step 2)
- If user picks B → return failure to the autopilot
- If user picks B → return failure to the autodev
**Any test skipped** → this is also a **blocking gate**. Skipped tests mean something is wrong — either with the test, the environment, or the test design. **Never blindly remove a skipped test.** Always investigate the root cause first.
**Any skipped test** → classify as legitimate or illegitimate before deciding whether to block.
#### Investigation Protocol for Skipped Tests
#### Legitimate skips (accept and proceed)
For each skipped test:
The code path genuinely cannot execute on this runner. Acceptable reasons:
1. **Read the test code** — understand what the test is supposed to verify and why it skips.
2. **Determine the root cause** — why did the skip condition fire?
- Is the test environment misconfigured? (e.g., wrong ports, missing env vars, service not started correctly)
- Is the test ordering wrong? (e.g., a fixture in an earlier test mutates shared state)
- Is a dependency missing? (e.g., package not installed, fixture file absent)
- Is the skip condition outdated? (e.g., code was refactored but the skip guard still checks the old behavior)
- Is the test fundamentally untestable in the current setup? (e.g., requires Docker restart, different OS, special hardware)
3. **Try to fix the root cause first** — the goal is to make the test run, not to delete it:
- Fix the environment or configuration
- Reorder tests or isolate shared state
- Install the missing dependency
- Update the skip condition to match current behavior
4. **Only remove as last resort** — if the test truly cannot run in any realistic test environment (e.g., requires hardware not available, duplicates another test with identical assertions), then removal is justified. Document the reasoning.
- Hardware not physically present (GPU, Apple Neural Engine, sensor, serial device)
- Operating system mismatch (Darwin-only test on Linux CI, Windows-only test on macOS)
- Feature-flag-gated test whose feature is intentionally disabled in this environment
- External service the project deliberately does not control (e.g., a third-party API with no sandbox, and the project has a documented contract test instead)
#### Categorization
For legitimate skips: verify the skip condition is accurate (the test would run if the hardware/OS were present), verify it has a clear reason string, and proceed.
- **explicit skip (dead code)**: Has `@pytest.mark.skip` — investigate whether the reason in the decorator is still valid. Often these are temporary skips that became permanent by accident.
- **runtime skip (unreachable)**: `pytest.skip()` fires inside the test body — investigate why the condition always triggers. Often fixable by adjusting test order, environment, or the condition itself.
- **environment mismatch**: Test assumes a different environment — investigate whether the test environment setup can be fixed.
- **missing fixture/data**: Data or service not available — investigate whether it can be provided.
#### Illegitimate skips (BLOCKING — must resolve)
The skip is a workaround for something we can and should fix. NOT acceptable reasons:
- Required service not running (database, message broker, downstream API we control) → fix: bring the service up, add a docker-compose dependency, or add a mock
- Missing test fixture, seed data, or sample file → fix: provide the data, generate it, or ASK the user for it
- Missing environment variable or credential → fix: add to `.env.example`, document, ASK user for the value
- Flaky-test quarantine with no tracking ticket → fix: create the ticket (or replay via leftovers if tracker is down)
- Inherited skip from a prior refactor that was never cleaned up → fix: clean it up now
- Test ordering mutates shared state → fix: isolate the state
**Rule of thumb**: if the reason for skipping is "we didn't set something up," that's not a valid skip — set it up. If the reason is "this hardware/OS isn't here," that's valid.
#### Resolution steps for illegitimate skips
1. Classify the skip (read the skip reason and test body)
2. If the fix is **mechanical** — start a container, install a dep, add a mock, reorder fixtures — attempt it automatically and re-run
3. If the fix requires **user input** — credentials, sample data, a business decision — BLOCK and ASK
4. Never silently mark the skip as "accepted" — every illegitimate skip must either be fixed or escalated
5. Removal is a last resort and requires explicit user approval with documented reasoning
#### Categorization cheatsheet
- **explicit skip (e.g. `@pytest.mark.skip`)**: check whether the reason in the decorator is still valid
- **conditional skip (e.g. `@pytest.mark.skipif`)**: check whether the condition is accurate and whether we can change the environment to make it false
- **runtime skip (e.g. `pytest.skip()` in body)**: check why the condition fires — often an ordering or environment bug
- **missing fixture/data**: treated as illegitimate unless user confirms the data is unavailable
After investigating, present findings:
@@ -145,6 +185,102 @@ After investigating, present findings:
Only option B allows proceeding with skips, and it requires explicit user approval with documented justification for each skip.
---
## Perf Mode
Performance tests differ from functional tests in what they measure (latency / throughput / error-rate distributions, not pass/fail of a single assertion) and when they run (once before deploy, not per batch). The mode reuses the same orchestration shape (detect → run → report → gate on outcome) but with perf-specific tool detection and threshold comparison.
### 1. Detect Perf Runner
Check in order — first match wins:
1. `scripts/run-performance-tests.sh` exists (generated by `test-spec` Phase 4) → use it; the script already encodes the correct load profile and tool invocation.
2. `_docs/02_document/tests/performance-tests.md` exists → read the scenarios, then auto-detect a load-testing tool:
- `k6` binary available → prefer k6 (scriptable, good default reporting)
- `locust` in project deps or installed → locust
- `artillery` in `package.json` or installed globally → artillery
- `wrk` binary available → wrk (simple HTTP only; use only if scenarios are HTTP GET/POST)
- Language-native benchmark harness (`cargo bench`, `go test -bench`, `pytest-benchmark`) → use when scenarios are CPU-bound or in-process
3. No runner and no scenarios spec → STOP and ask the user to either run `/test-spec` first (to produce `performance-tests.md` + the runner script) or supply a runner script manually. Do not improvise perf tests from scratch.
### 2. Run
Execute the detected runner against the target system. Capture per-scenario metrics:
- Latency percentiles: p50, p95, p99 (and p999 if load volume permits)
- Throughput: requests/sec or operations/sec
- Error rate: failed / total
- Duration: actual run time (for soak/ramp scenarios)
- Resource usage if the scenarios call for it (CPU%, RSS, GPU utilization)
Tear down any environment the runner spun up after metrics are captured.
### 3. Compare Against Thresholds
Load thresholds in this order:
1. Per-scenario expected results from `_docs/02_document/tests/performance-tests.md`
2. Project-wide thresholds from `_docs/00_problem/acceptance_criteria.md` (latency / throughput lines)
3. Fallback: no threshold → record the measurement but classify the scenario as **Unverified** (not pass/fail)
Classify each scenario:
- **Pass** — all thresholds met
- **Warn** — within 10% of any threshold (e.g., p95 = 460ms against a 500ms threshold)
- **Fail** — any threshold violated
- **Unverified** — no threshold to compare against
### 4. Report
```
══════════════════════════════════════
PERF RESULTS
══════════════════════════════════════
Scenarios: [pass N · warn M · fail K · unverified U]
──────────────────────────────────────
1. [scenario_name] — [Pass/Warn/Fail/Unverified]
p50 = [x]ms · p95 = [y]ms · p99 = [z]ms
throughput = [r] rps · errors = [e]%
threshold: [criterion and verdict detail]
2. ...
══════════════════════════════════════
```
Persist the full report to `_docs/06_metrics/perf_<YYYY-MM-DD>_<run_label>.md` for trend tracking across cycles.
### 5. Handle Outcome
**All scenarios Pass (or Pass + Unverified only)** → return success to the caller.
**Any Warn or Fail** → this is a **blocking gate**. Investigate before deciding — read the runner output, check if the warn-band was historically stable, rule out transient infrastructure noise (always worth one re-run before declaring a regression).
After investigating, present:
```
══════════════════════════════════════
PERF GATE: [summary]
══════════════════════════════════════
Failing / warning scenarios:
1. [scenario] — [metric] = [observed] vs threshold [threshold]
likely cause: [1-line diagnosis]
══════════════════════════════════════
A) Fix and re-run (investigate and address the regression)
B) Proceed anyway (accept the regression — requires written justification
recorded in the perf report)
C) Abort — investigate offline
══════════════════════════════════════
Recommendation: A — perf regressions caught pre-deploy
are orders of magnitude cheaper to fix than post-deploy
══════════════════════════════════════
```
- User picks A → apply fixes, re-run (back to step 2).
- User picks B → append the justification to the perf report; return success to the caller.
- User picks C → return failure to the caller.
**Any Unverified scenarios with no Warn/Fail** → not blocking, but surface them in the report so the user knows coverage gaps exist. Suggest running `/test-spec` to add expected results next cycle.
## Trigger Conditions
This skill is invoked by the autopilot at test verification checkpoints. It is not typically invoked directly by the user.
This skill is invoked by the autodev at test verification checkpoints. It is not typically invoked directly by the user. When invoked directly, select the mode from the user's phrasing ("run tests" → functional; "load test" / "perf test" → perf).
+49 -331
View File
@@ -27,19 +27,27 @@ Analyze input data completeness and produce detailed black-box test specificatio
- **Save immediately**: write artifacts to disk after each phase; never accumulate unsaved work
- **Ask, don't assume**: when requirements are ambiguous, ask the user before proceeding
- **Spec, don't code**: this workflow produces test specifications, never test implementation code
- **No test without data**: every test scenario MUST have concrete test data; tests without data are removed
- **No test without expected result**: every test scenario MUST pair input data with a quantifiable expected result; a test that cannot compare actual output against a known-correct answer is not verifiable and must be removed
- **Every test must have a pass/fail criterion**. Two acceptable shapes:
- **Input/output shape**: concrete input data paired with a quantifiable expected result (exact value, tolerance, threshold, pattern, reference file). Typical for functional blackbox tests, performance tests with load data, data-processing pipelines.
- **Behavioral shape**: a trigger condition + observable system behavior + quantifiable pass/fail criterion, with no input data required. Typical for startup/shutdown tests, retry/backoff policies, state transitions, logging/metrics emission, resilience scenarios. Example criteria: "startup logs `service ready` within 5s", "retry emits 3 attempts with exponential backoff (base 100ms ± 20ms)", "on SIGTERM, service drains in-flight requests within 30s grace period", "health endpoint returns 503 while migrations run".
- For behavioral tests the observable (log line, metric value, state transition, emitted event, elapsed time) must still be quantifiable — the test must programmatically decide pass/fail.
- A test that cannot produce a pass/fail verdict through either shape is not verifiable and must be removed.
## Context Resolution
Fixed paths — no mode detection needed:
Fixed paths:
- PROBLEM_DIR: `_docs/00_problem/`
- SOLUTION_DIR: `_docs/01_solution/`
- DOCUMENT_DIR: `_docs/02_document/`
- TESTS_OUTPUT_DIR: `_docs/02_document/tests/`
Announce the resolved paths to the user before proceeding.
Announce the resolved paths and the detected invocation mode (below) to the user before proceeding.
### Invocation Modes
- **full** (default): runs all 4 phases against the whole `PROBLEM_DIR` + `DOCUMENT_DIR`. Used in greenfield Plan Step 1 and existing-code Step 3.
- **cycle-update**: runs only a scoped refresh of the existing test-spec artifacts against the current feature cycle's completed tasks. Used by the existing-code flow's per-cycle sync step. See `modes/cycle-update.md` for the narrowed workflow.
## Input Specification
@@ -59,7 +67,7 @@ Every input data item MUST have a corresponding expected result that defines wha
Expected results live inside `_docs/00_problem/input_data/` in one or both of:
1. **Mapping file** (`input_data/expected_results/results_report.md`): a table pairing each input with its quantifiable expected output, using the format defined in `.cursor/skills/test-spec/templates/expected-results.md`
1. **Mapping file** (`input_data/expected_results/results_report.md`): a table pairing each input with its quantifiable expected output, using the format defined in `templates/expected-results.md`
2. **Reference files folder** (`input_data/expected_results/`): machine-readable files (JSON, CSV, etc.) containing full expected outputs for complex cases, referenced from the mapping file
@@ -74,7 +82,8 @@ input_data/
└── data_parameters.md
```
**Quantifiability requirements** (see template for full format and examples):
**Quantifiability requirements** (see `templates/expected-results.md` for full format and examples):
- Numeric values: exact value or value ± tolerance (e.g., `confidence ≥ 0.85`, `position ± 10px`)
- Structured data: exact JSON/CSV values, or a reference file in `expected_results/`
- Counts: exact counts (e.g., "3 detections", "0 errors")
@@ -95,7 +104,7 @@ input_data/
1. `acceptance_criteria.md` exists and is non-empty — **STOP if missing**
2. `restrictions.md` exists and is non-empty — **STOP if missing**
3. `input_data/` exists and contains at least one file — **STOP if missing**
4. `input_data/expected_results/results_report.md` exists and is non-empty — **STOP if missing**. Prompt the user: *"Expected results mapping is required. Please create `_docs/00_problem/input_data/expected_results/results_report.md` pairing each input with its quantifiable expected output. Use `.cursor/skills/test-spec/templates/expected-results.md` as the format reference."*
4. `input_data/expected_results/results_report.md` exists and is non-empty — **STOP if missing**. Prompt the user: *"Expected results mapping is required. Please create `_docs/00_problem/input_data/expected_results/results_report.md` pairing each input with its quantifiable expected output. Use `templates/expected-results.md` as the format reference."*
5. `problem.md` exists and is non-empty — **STOP if missing**
6. `solution.md` exists and is non-empty — **STOP if missing**
7. Create TESTS_OUTPUT_DIR if it does not exist
@@ -133,6 +142,7 @@ TESTS_OUTPUT_DIR/
| Phase 3 | Updated test data spec (if data added) | `test-data.md` |
| Phase 3 | Updated test files (if tests removed) | respective test file |
| Phase 3 | Updated traceability matrix (if tests removed) | `traceability-matrix.md` |
| Hardware Assessment | Test Execution section | `environment.md` (updated) |
| Phase 4 | Test runner script | `scripts/run-tests.sh` |
| Phase 4 | Performance test runner script | `scripts/run-performance-tests.sh` |
@@ -147,331 +157,44 @@ If TESTS_OUTPUT_DIR already contains files:
## Progress Tracking
At the start of execution, create a TodoWrite with all four phases. Update status as each phase completes.
At the start of execution, create a TodoWrite with all four phases (plus the hardware assessment between Phase 3 and Phase 4). Update status as each phase completes.
## Workflow
### Phase 1: Input Data Completeness Analysis
### Phase 1: Input Data & Expected Results Completeness Analysis
**Role**: Professional Quality Assurance Engineer
**Goal**: Assess whether the available input data is sufficient to build comprehensive test scenarios
**Constraints**: Analysis only — no test specs yet
1. Read `_docs/01_solution/solution.md`
2. Read `acceptance_criteria.md`, `restrictions.md`
3. Read testing strategy from solution.md (if present)
4. If `DOCUMENT_DIR/architecture.md` and `DOCUMENT_DIR/system-flows.md` exist, read them for additional context on system interfaces and flows
5. Read `input_data/expected_results/results_report.md` and any referenced files in `input_data/expected_results/`
6. Analyze `input_data/` contents against:
- Coverage of acceptance criteria scenarios
- Coverage of restriction edge cases
- Coverage of testing strategy requirements
7. Analyze `input_data/expected_results/results_report.md` completeness:
- Every input data item has a corresponding expected result row in the mapping
- Expected results are quantifiable (contain numeric thresholds, exact values, patterns, or file references — not vague descriptions like "works correctly" or "returns result")
- Expected results specify a comparison method (exact match, tolerance range, pattern match, threshold) per the template
- Reference files in `input_data/expected_results/` that are cited in the mapping actually exist and are valid
8. Present input-to-expected-result pairing assessment:
| Input Data | Expected Result Provided? | Quantifiable? | Issue (if any) |
|------------|--------------------------|---------------|----------------|
| [file/data] | Yes/No | Yes/No | [missing, vague, no tolerance, etc.] |
9. Threshold: at least 70% coverage of scenarios AND every covered scenario has a quantifiable expected result (see `.cursor/rules/cursor-meta.mdc` Quality Thresholds table)
10. If coverage is low, search the internet for supplementary data, assess quality with user, and if user agrees, add to `input_data/` and update `input_data/expected_results/results_report.md`
11. If expected results are missing or not quantifiable, ask user to provide them before proceeding
**BLOCKING**: Do NOT proceed until user confirms both input data coverage AND expected results completeness are sufficient.
Read and follow `phases/01-input-data-analysis.md`.
---
### Phase 2: Test Scenario Specification
**Role**: Professional Quality Assurance Engineer
**Goal**: Produce detailed black-box test specifications covering blackbox, performance, resilience, security, and resource limit scenarios
**Constraints**: Spec only — no test code. Tests describe what the system should do given specific inputs, not how the system is built.
Based on all acquired data, acceptance_criteria, and restrictions, form detailed test scenarios:
1. Define test environment using `.cursor/skills/plan/templates/test-environment.md` as structure
2. Define test data management using `.cursor/skills/plan/templates/test-data.md` as structure
3. Write blackbox test scenarios (positive + negative) using `.cursor/skills/plan/templates/blackbox-tests.md` as structure
4. Write performance test scenarios using `.cursor/skills/plan/templates/performance-tests.md` as structure
5. Write resilience test scenarios using `.cursor/skills/plan/templates/resilience-tests.md` as structure
6. Write security test scenarios using `.cursor/skills/plan/templates/security-tests.md` as structure
7. Write resource limit test scenarios using `.cursor/skills/plan/templates/resource-limit-tests.md` as structure
8. Build traceability matrix using `.cursor/skills/plan/templates/traceability-matrix.md` as structure
**Self-verification**:
- [ ] Every acceptance criterion is covered by at least one test scenario
- [ ] Every restriction is verified by at least one test scenario
- [ ] Every test scenario has a quantifiable expected result from `input_data/expected_results/results_report.md`
- [ ] Expected results use comparison methods from `.cursor/skills/test-spec/templates/expected-results.md`
- [ ] Positive and negative scenarios are balanced
- [ ] Consumer app has no direct access to system internals
- [ ] Test environment matches project constraints (see Hardware-Dependency & Execution Environment Assessment below)
- [ ] External dependencies have mock/stub services defined
- [ ] Traceability matrix has no uncovered AC or restrictions
**Save action**: Write all files under TESTS_OUTPUT_DIR:
- `environment.md`
- `test-data.md`
- `blackbox-tests.md`
- `performance-tests.md`
- `resilience-tests.md`
- `security-tests.md`
- `resource-limit-tests.md`
- `traceability-matrix.md`
**BLOCKING**: Present test coverage summary (from traceability-matrix.md) to user. Do NOT proceed until confirmed.
Capture any new questions, findings, or insights that arise during test specification — these feed forward into downstream skills (plan, refactor, etc.).
Read and follow `phases/02-test-scenarios.md`.
---
### Phase 3: Test Data Validation Gate (HARD GATE)
**Role**: Professional Quality Assurance Engineer
**Goal**: Ensure every test scenario produced in Phase 2 has concrete, sufficient test data. Remove tests that lack data. Verify final coverage stays above 70%.
**Constraints**: This phase is MANDATORY and cannot be skipped.
#### Step 1 — Build the test-data and expected-result requirements checklist
Scan `blackbox-tests.md`, `performance-tests.md`, `resilience-tests.md`, `security-tests.md`, and `resource-limit-tests.md`. For every test scenario, extract:
| # | Test Scenario ID | Test Name | Required Input Data | Required Expected Result | Result Quantifiable? | Comparison Method | Input Provided? | Expected Result Provided? |
|---|-----------------|-----------|---------------------|-------------------------|---------------------|-------------------|----------------|--------------------------|
| 1 | [ID] | [name] | [data description] | [what system should output] | [Yes/No] | [exact/tolerance/pattern/threshold] | [Yes/No] | [Yes/No] |
Present this table to the user.
#### Step 2 — Ask user to provide missing test data AND expected results
For each row where **Input Provided?** is **No** OR **Expected Result Provided?** is **No**, ask the user:
> **Option A — Provide the missing items**: Supply what is missing:
> - **Missing input data**: Place test data files in `_docs/00_problem/input_data/` or indicate the location.
> - **Missing expected result**: Provide the quantifiable expected result for this input. Update `_docs/00_problem/input_data/expected_results/results_report.md` with a row mapping the input to its expected output. If the expected result is complex, provide a reference CSV file in `_docs/00_problem/input_data/expected_results/`. Use `.cursor/skills/test-spec/templates/expected-results.md` for format guidance.
>
> Expected results MUST be quantifiable — the test must be able to programmatically compare actual vs expected. Examples:
> - "3 detections with bounding boxes [(x1,y1,x2,y2), ...] ± 10px"
> - "HTTP 200 with JSON body matching `expected_response_01.json`"
> - "Processing time < 500ms"
> - "0 false positives in the output set"
>
> **Option B — Skip this test**: If you cannot provide the data or expected result, this test scenario will be **removed** from the specification.
**BLOCKING**: Wait for the user's response for every missing item.
#### Step 3 — Validate provided data and expected results
For each item where the user chose **Option A**:
**Input data validation**:
1. Verify the data file(s) exist at the indicated location
2. Verify **quality**: data matches the format, schema, and constraints described in the test scenario (e.g., correct image resolution, valid JSON structure, expected value ranges)
3. Verify **quantity**: enough data samples to cover the scenario (e.g., at least N images for a batch test, multiple edge-case variants)
**Expected result validation**:
4. Verify the expected result exists in `input_data/expected_results/results_report.md` or as a referenced file in `input_data/expected_results/`
5. Verify **quantifiability**: the expected result can be evaluated programmatically — it must contain at least one of:
- Exact values (counts, strings, status codes)
- Numeric values with tolerance (e.g., `± 10px`, `≥ 0.85`)
- Pattern matches (regex, substring, JSON schema)
- Thresholds (e.g., `< 500ms`, `≤ 5% error rate`)
- Reference file for structural comparison (JSON diff, CSV diff)
6. Verify **completeness**: the expected result covers all outputs the test checks (not just one field when the test validates multiple)
7. Verify **consistency**: the expected result is consistent with the acceptance criteria it traces to
If any validation fails, report the specific issue and loop back to Step 2 for that item.
#### Step 4 — Remove tests without data or expected results
For each item where the user chose **Option B**:
1. Warn the user: `⚠️ Test scenario [ID] "[Name]" will be REMOVED from the specification due to missing test data or expected result.`
2. Remove the test scenario from the respective test file
3. Remove corresponding rows from `traceability-matrix.md`
4. Update `test-data.md` to reflect the removal
**Save action**: Write updated files under TESTS_OUTPUT_DIR:
- `test-data.md`
- Affected test files (if tests removed)
- `traceability-matrix.md` (if tests removed)
#### Step 5 — Final coverage check
After all removals, recalculate coverage:
1. Count remaining test scenarios that trace to acceptance criteria
2. Count total acceptance criteria + restrictions
3. Calculate coverage percentage: `covered_items / total_items * 100`
| Metric | Value |
|--------|-------|
| Total AC + Restrictions | ? |
| Covered by remaining tests | ? |
| **Coverage %** | **?%** |
**Decision**:
- **Coverage ≥ 70%** → Phase 3 **PASSED**. Present final summary to user.
- **Coverage < 70%** → Phase 3 **FAILED**. Report:
> ❌ Test coverage dropped to **X%** (minimum 70% required). The removed test scenarios left gaps in the following acceptance criteria / restrictions:
>
> | Uncovered Item | Type (AC/Restriction) | Missing Test Data Needed |
> |---|---|---|
>
> **Action required**: Provide the missing test data for the items above, or add alternative test scenarios that cover these items with data you can supply.
**BLOCKING**: Loop back to Step 2 with the uncovered items. Do NOT finalize until coverage ≥ 70%.
#### Phase 3 Completion
When coverage ≥ 70% and all remaining tests have validated data AND quantifiable expected results:
1. Present the final coverage report
2. List all removed tests (if any) with reasons
3. Confirm every remaining test has: input data + quantifiable expected result + comparison method
4. Confirm all artifacts are saved and consistent
Read and follow `phases/03-data-validation-gate.md`.
---
### Hardware-Dependency & Execution Environment Assessment (BLOCKING — runs before Phase 4)
### Hardware-Dependency & Execution Environment Assessment (BLOCKING — runs between Phase 3 and Phase 4)
Docker is the **preferred** test execution environment (reproducibility, isolation, CI parity). However, hardware-dependent projects may require local execution to exercise the real code paths. This assessment determines the right execution strategy by scanning both documentation and source code.
#### Step 1 — Documentation scan
Check the following files for mentions of hardware-specific requirements:
| File | Look for |
|------|----------|
| `_docs/00_problem/restrictions.md` | Platform requirements, hardware constraints, OS-specific features |
| `_docs/01_solution/solution.md` | Engine selection logic, platform-dependent paths, hardware acceleration |
| `_docs/02_document/architecture.md` | Component diagrams showing hardware layers, engine adapters |
| `_docs/02_document/components/*/description.md` | Per-component hardware mentions |
| `TESTS_OUTPUT_DIR/environment.md` | Existing environment decisions |
#### Step 2 — Code scan
Search the project source for indicators of hardware dependence. The project is **hardware-dependent** if ANY of the following are found:
| Category | Code indicators (imports, APIs, config) |
|----------|-----------------------------------------|
| GPU / CUDA | `import pycuda`, `import tensorrt`, `import pynvml`, `torch.cuda`, `nvidia-smi`, `CUDA_VISIBLE_DEVICES`, `runtime: nvidia` |
| Apple Neural Engine / CoreML | `import coremltools`, `CoreML`, `MLModel`, `ComputeUnit`, `MPS`, `sys.platform == "darwin"`, `platform.machine() == "arm64"` |
| OpenCL / Vulkan | `import pyopencl`, `clCreateContext`, vulkan headers |
| TPU / FPGA | `import tensorflow.distribute.TPUStrategy`, FPGA bitstream loaders |
| Sensors / Cameras | `import cv2.VideoCapture(0)` (device index), serial port access, GPIO, V4L2 |
| OS-specific services | Kernel modules (`modprobe`), host-level drivers, platform-gated code (`sys.platform` branches selecting different backends) |
Also check dependency files (`requirements.txt`, `setup.py`, `pyproject.toml`, `Cargo.toml`, `*.csproj`) for hardware-specific packages.
#### Step 3 — Classify the project
Based on Steps 12, classify the project:
- **Not hardware-dependent**: no indicators found → use Docker (preferred default), skip to "Record the decision" below
- **Hardware-dependent**: one or more indicators found → proceed to Step 4
#### Step 4 — Present execution environment choice
Present the findings and ask the user using Choose format:
```
══════════════════════════════════════
DECISION REQUIRED: Test execution environment
══════════════════════════════════════
Hardware dependencies detected:
- [list each indicator found, with file:line]
══════════════════════════════════════
Running in Docker means these hardware code paths
are NOT exercised — Docker uses a Linux VM where
[specific hardware, e.g. CoreML / CUDA] is unavailable.
The system would fall back to [fallback engine/path].
══════════════════════════════════════
A) Local execution only (tests the real hardware path)
B) Docker execution only (tests the fallback path)
C) Both local and Docker (tests both paths, requires
two test runs — recommended for CI with heterogeneous
runners)
══════════════════════════════════════
Recommendation: [A, B, or C] — [reason]
══════════════════════════════════════
```
#### Step 5 — Record the decision
Write or update a **"Test Execution"** section in `TESTS_OUTPUT_DIR/environment.md` with:
1. **Decision**: local / docker / both
2. **Hardware dependencies found**: list with file references
3. **Execution instructions** per chosen mode:
- **Local mode**: prerequisites (OS, SDK, hardware), how to start services, how to run the test runner, environment variables
- **Docker mode**: docker-compose profile/command, required images, how results are collected
- **Both mode**: instructions for each, plus guidance on which CI runner type runs which mode
Read and follow `phases/hardware-assessment.md`.
---
### Phase 4: Test Runner Script Generation
**Skip condition**: If this skill was invoked from the `/plan` skill (planning context, no code exists yet), skip Phase 4 entirely. Script creation should instead be planned as a task during decompose — the decomposer creates a task for creating these scripts. Phase 4 only runs when invoked from the existing-code flow (where source code already exists) or standalone.
**Role**: DevOps engineer
**Goal**: Generate executable shell scripts that run the specified tests, so the autopilot and CI can invoke them consistently.
**Constraints**: Scripts must be idempotent, portable across dev/CI, and exit with non-zero on failure. Respect the Docker Suitability Assessment decision above.
#### Step 1 — Detect test infrastructure
1. Identify the project's test runner from manifests and config files:
- Python: `pytest` (pyproject.toml, setup.cfg, pytest.ini)
- .NET: `dotnet test` (*.csproj, *.sln)
- Rust: `cargo test` (Cargo.toml)
- Node: `npm test` or `vitest` / `jest` (package.json)
2. Check Docker Suitability Assessment result:
- If **local execution** was chosen → do NOT generate docker-compose test files; scripts run directly on host
- If **Docker execution** was chosen → identify/generate docker-compose files for integration/blackbox tests
3. Identify performance/load testing tools from dependencies (k6, locust, artillery, wrk, or built-in benchmarks)
4. Read `TESTS_OUTPUT_DIR/environment.md` for infrastructure requirements
#### Step 2 — Generate test runner
**Docker is the default.** Only generate a local `scripts/run-tests.sh` if the Hardware-Dependency Assessment determined **local** or **both** execution (i.e., the project requires real hardware like GPU/CoreML/TPU/sensors). For all other projects, use `docker-compose.test.yml` — it provides reproducibility, isolation, and CI parity without a custom shell script.
**If local script is needed** — create `scripts/run-tests.sh` at the project root using `.cursor/skills/test-spec/templates/run-tests-script.md` as structural guidance. The script must:
1. Set `set -euo pipefail` and trap cleanup on EXIT
2. **Install all project and test dependencies** (e.g. `pip install -q -r requirements.txt -r e2e/requirements.txt`, `dotnet restore`, `npm ci`). This prevents collection-time import errors on fresh environments.
3. Optionally accept a `--unit-only` flag to skip blackbox tests
4. Run unit/blackbox tests using the detected test runner (activate virtualenv if present, run test runner directly on host)
5. Print a summary of passed/failed/skipped tests
6. Exit 0 on all pass, exit 1 on any failure
**If Docker** — generate or update `docker-compose.test.yml` that builds the test image, installs all dependencies inside the container, runs the test suite, and exits with the test runner's exit code.
#### Step 3 — Generate `scripts/run-performance-tests.sh`
Create `scripts/run-performance-tests.sh` at the project root. The script must:
1. Set `set -euo pipefail` and trap cleanup on EXIT
2. Read thresholds from `_docs/02_document/tests/performance-tests.md` (or accept as CLI args)
3. Start the system under test (local or docker-compose, matching the Docker Suitability Assessment decision)
4. Run load/performance scenarios using the detected tool
5. Compare results against threshold values from the test spec
6. Print a pass/fail summary per scenario
7. Exit 0 if all thresholds met, exit 1 otherwise
#### Step 4 — Verify scripts
1. Verify both scripts are syntactically valid (`bash -n scripts/run-tests.sh`)
2. Mark both scripts as executable (`chmod +x`)
3. Present a summary of what each script does to the user
**Save action**: Write `scripts/run-tests.sh` and `scripts/run-performance-tests.sh` to the project root.
Read and follow `phases/04-runner-scripts.md`.
---
### cycle-update mode
If invoked in `cycle-update` mode (see "Invocation Modes" above), read and follow `modes/cycle-update.md` instead of the full 4-phase workflow.
## Escalation Rules
| Situation | Action |
@@ -479,27 +202,28 @@ Create `scripts/run-performance-tests.sh` at the project root. The script must:
| Missing acceptance_criteria.md, restrictions.md, or input_data/ | **STOP** — specification cannot proceed |
| Missing input_data/expected_results/results_report.md | **STOP** — ask user to provide expected results mapping using the template |
| Ambiguous requirements | ASK user |
| Input data coverage below 70% (Phase 1) | Search internet for supplementary data, ASK user to validate |
| Input data coverage below 75% (Phase 1) | Search internet for supplementary data, ASK user to validate |
| Expected results missing or not quantifiable (Phase 1) | ASK user to provide quantifiable expected results before proceeding |
| Test scenario conflicts with restrictions | ASK user to clarify intent |
| System interfaces unclear (no architecture.md) | ASK user or derive from solution.md |
| Test data or expected result not provided for a test scenario (Phase 3) | WARN user and REMOVE the test |
| Final coverage below 70% after removals (Phase 3) | BLOCK — require user to supply data or accept reduced spec |
| Final coverage below 75% after removals (Phase 3) | BLOCK — require user to supply data or accept reduced spec |
## Common Mistakes
- **Referencing internals**: tests must be black-box — no internal module names, no direct DB queries against the system under test
- **Vague expected outcomes**: "works correctly" is not a test outcome; use specific measurable values
- **Missing expected results**: input data without a paired expected result is useless — the test cannot determine pass/fail without knowing what "correct" looks like
- **Non-quantifiable expected results**: "should return good results" is not verifiable; expected results must have exact values, tolerances, thresholds, or pattern matches that code can evaluate
- **Missing pass/fail criterion**: input/output tests without an expected result, OR behavioral tests without a measurable observable — both are unverifiable and must be removed
- **Non-quantifiable criteria**: "should return good results", "works correctly", "behaves properly" — not verifiable. Use exact values, tolerances, thresholds, pattern matches, or timing bounds that code can evaluate.
- **Forcing the wrong shape**: do not invent fake input data for a behavioral test (e.g., "input: SIGTERM signal") just to fit the input/output shape. Classify the test correctly and use the matching checklist.
- **Missing negative scenarios**: every positive scenario category should have corresponding negative/edge-case tests
- **Untraceable tests**: every test should trace to at least one AC or restriction
- **Writing test code**: this skill produces specifications, never implementation code
- **Tests without data**: every test scenario MUST have concrete test data AND a quantifiable expected result; a test spec without either is not executable and must be removed
## Trigger Conditions
When the user wants to:
- Specify blackbox tests before implementation or refactoring
- Analyze input data completeness for test coverage
- Produce test scenarios from acceptance criteria
@@ -516,36 +240,30 @@ When the user wants to:
│ → verify AC, restrictions, input_data (incl. expected_results.md) │
│ │
│ Phase 1: Input Data & Expected Results Completeness Analysis │
│ → assess input_data/ coverage vs AC scenarios (≥70%)
│ → verify every input has a quantifiable expected result │
│ → present input→expected-result pairing assessment │
│ → phases/01-input-data-analysis.md
│ [BLOCKING: user confirms input data + expected results coverage] │
│ │
│ Phase 2: Test Scenario Specification │
│ → environment.md
│ → test-data.md (with expected results mapping)
│ → blackbox-tests.md (positive + negative)
│ → performance-tests.md
│ → resilience-tests.md │
│ → security-tests.md │
│ → resource-limit-tests.md │
│ → traceability-matrix.md │
│ → phases/02-test-scenarios.md
│ → environment.md · test-data.md · blackbox-tests.md
│ → performance-tests.md · resilience-tests.md · security-tests.md
│ → resource-limit-tests.md · traceability-matrix.md
│ [BLOCKING: user confirms test coverage] │
│ │
│ Phase 3: Test Data & Expected Results Validation Gate (HARD GATE) │
│ → build test-data + expected-result requirements checklist
→ ask user: provide data+result (A) or remove test (B)
→ validate input data (quality + quantity)
→ validate expected results (quantifiable + comparison method)
│ → remove tests without data or expected result, warn user
│ → final coverage check (≥70% or FAIL + loop back) │
│ [BLOCKING: coverage ≥ 70% required to pass] │
│ → phases/03-data-validation-gate.md
[BLOCKING: coverage ≥ 75% required to pass]
Hardware-Dependency Assessment (BLOCKING, pre-Phase-4)
│ → phases/hardware-assessment.md
│ │
│ Phase 4: Test Runner Script Generation │
│ → detect test runner + docker-compose + load tool
│ → phases/04-runner-scripts.md
│ → scripts/run-tests.sh (unit + blackbox) │
│ → scripts/run-performance-tests.sh (load/perf scenarios) │
→ verify scripts are valid and executable
│ cycle-update mode (scoped refresh) │
│ → modes/cycle-update.md │
├──────────────────────────────────────────────────────────────────────┤
│ Principles: Black-box only · Traceability · Save immediately │
│ Ask don't assume · Spec don't code │
@@ -0,0 +1,26 @@
# Mode: cycle-update
A scoped refresh of existing test-spec artifacts against the current feature cycle's completed tasks. Used by `existing-code` flow's per-cycle sync step.
## Inputs
- The list of task spec files in `_docs/02_tasks/done/` implemented in the current cycle
- `_docs/03_implementation/implementation_report_{feature_slug}_cycle{N}.md`
## Phases that run
- Skip Phase 1 (input data analysis)
- Skip Phase 4 (script generation)
- Run a **narrowed** Phase 2 and Phase 3 per the rules below
## Narrowed rules
1. For each new AC in the cycle's task specs, check `traceability-matrix.md`. If not covered, append one row.
2. For each new component surface exposed in the cycle (new endpoint, event, DTO field — detectable from task Scope and from diffs against `module-layout.md`), append scenarios to the relevant `blackbox-tests.md` / `performance-tests.md` / `security-tests.md` / `resilience-tests.md` / `resource-limit-tests.md` category. Reuse the existing test template shapes.
3. For each NFR declared in a cycle task spec, propagate it to the matching spec file. If the NFR conflicts with an existing spec entry, present via the Choose format.
4. Do NOT rewrite unaffected sections. Preserve existing traceability IDs.
5. Save only the files that changed, update `traceability-matrix.md` last.
## Save action
Save only the changed test artifact files under `TESTS_OUTPUT_DIR`. Update `traceability-matrix.md` last, after all per-category files are written.
@@ -0,0 +1,39 @@
# Phase 1: Input Data & Expected Results Completeness Analysis
**Role**: Professional Quality Assurance Engineer
**Goal**: Assess whether the available input data is sufficient to build comprehensive test scenarios, and whether every input is paired with a quantifiable expected result.
**Constraints**: Analysis only — no test specs yet.
## Steps
1. Read `_docs/01_solution/solution.md`
2. Read `acceptance_criteria.md`, `restrictions.md`
3. Read testing strategy from `solution.md` (if present)
4. If `DOCUMENT_DIR/architecture.md` and `DOCUMENT_DIR/system-flows.md` exist, read them for additional context on system interfaces and flows
5. Read `input_data/expected_results/results_report.md` and any referenced files in `input_data/expected_results/`
6. Analyze `input_data/` contents against:
- Coverage of acceptance criteria scenarios
- Coverage of restriction edge cases
- Coverage of testing strategy requirements
7. Analyze `input_data/expected_results/results_report.md` completeness:
- Every input data item has a corresponding expected result row in the mapping
- Expected results are quantifiable (contain numeric thresholds, exact values, patterns, or file references — not vague descriptions like "works correctly" or "returns result")
- Expected results specify a comparison method (exact match, tolerance range, pattern match, threshold) per the template
- Reference files in `input_data/expected_results/` that are cited in the mapping actually exist and are valid
8. Present input-to-expected-result pairing assessment:
| Input Data | Expected Result Provided? | Quantifiable? | Issue (if any) |
|------------|--------------------------|---------------|----------------|
| [file/data] | Yes/No | Yes/No | [missing, vague, no tolerance, etc.] |
9. Threshold: at least 75% coverage of scenarios AND every covered scenario has a quantifiable expected result (see `.cursor/rules/cursor-meta.mdc` Quality Thresholds table)
10. If coverage is low, search the internet for supplementary data, assess quality with user, and if user agrees, add to `input_data/` and update `input_data/expected_results/results_report.md`
11. If expected results are missing or not quantifiable, ask user to provide them before proceeding
## Blocking
**BLOCKING**: Do NOT proceed to Phase 2 until the user confirms both input data coverage AND expected results completeness are sufficient.
## No save action
Phase 1 does not write an artifact. Findings feed Phase 2.
@@ -0,0 +1,49 @@
# Phase 2: Test Scenario Specification
**Role**: Professional Quality Assurance Engineer
**Goal**: Produce detailed black-box test specifications covering blackbox, performance, resilience, security, and resource limit scenarios.
**Constraints**: Spec only — no test code. Tests describe what the system should do given specific inputs, not how the system is built.
## Steps
Based on all acquired data, acceptance_criteria, and restrictions, form detailed test scenarios:
1. Define test environment using `.cursor/skills/plan/templates/test-environment.md` as structure
2. Define test data management using `.cursor/skills/plan/templates/test-data.md` as structure
3. Write blackbox test scenarios (positive + negative) using `.cursor/skills/plan/templates/blackbox-tests.md` as structure
4. Write performance test scenarios using `.cursor/skills/plan/templates/performance-tests.md` as structure
5. Write resilience test scenarios using `.cursor/skills/plan/templates/resilience-tests.md` as structure
6. Write security test scenarios using `.cursor/skills/plan/templates/security-tests.md` as structure
7. Write resource limit test scenarios using `.cursor/skills/plan/templates/resource-limit-tests.md` as structure
8. Build traceability matrix using `.cursor/skills/plan/templates/traceability-matrix.md` as structure
## Self-verification
- [ ] Every acceptance criterion is covered by at least one test scenario
- [ ] Every restriction is verified by at least one test scenario
- [ ] Every test scenario has a quantifiable expected result from `input_data/expected_results/results_report.md`
- [ ] Expected results use comparison methods from `.cursor/skills/test-spec/templates/expected-results.md`
- [ ] Positive and negative scenarios are balanced
- [ ] Consumer app has no direct access to system internals
- [ ] Test environment matches project constraints (see `phases/hardware-assessment.md`, which runs before Phase 4)
- [ ] External dependencies have mock/stub services defined
- [ ] Traceability matrix has no uncovered AC or restrictions
## Save action
Write all files under TESTS_OUTPUT_DIR:
- `environment.md`
- `test-data.md`
- `blackbox-tests.md`
- `performance-tests.md`
- `resilience-tests.md`
- `security-tests.md`
- `resource-limit-tests.md`
- `traceability-matrix.md`
## Blocking
**BLOCKING**: Present test coverage summary (from `traceability-matrix.md`) to user. Do NOT proceed to Phase 3 until confirmed.
Capture any new questions, findings, or insights that arise during test specification — these feed forward into downstream skills (plan, refactor, etc.).
@@ -0,0 +1,118 @@
# Phase 3: Test Data & Expected Results Validation Gate (HARD GATE)
**Role**: Professional Quality Assurance Engineer
**Goal**: Ensure every test scenario produced in Phase 2 has concrete, sufficient test data. Remove tests that lack data. Verify final coverage stays above 75%.
**Constraints**: This phase is MANDATORY and cannot be skipped.
## Step 1 — Build the requirements checklist
Scan `blackbox-tests.md`, `performance-tests.md`, `resilience-tests.md`, `security-tests.md`, and `resource-limit-tests.md`. For every test scenario, classify its shape (input/output or behavioral) and extract:
**Input/output tests:**
| # | Test Scenario ID | Test Name | Required Input Data | Required Expected Result | Result Quantifiable? | Comparison Method | Input Provided? | Expected Result Provided? |
|---|-----------------|-----------|---------------------|-------------------------|---------------------|-------------------|----------------|--------------------------|
| 1 | [ID] | [name] | [data description] | [what system should output] | [Yes/No] | [exact/tolerance/pattern/threshold] | [Yes/No] | [Yes/No] |
**Behavioral tests:**
| # | Test Scenario ID | Test Name | Trigger Condition | Observable Behavior | Pass/Fail Criterion | Quantifiable? |
|---|-----------------|-----------|-------------------|--------------------|--------------------|---------------|
| 1 | [ID] | [name] | [e.g., service receives SIGTERM] | [e.g., drain logs emitted, port closed] | [e.g., drain completes ≤30s] | [Yes/No] |
Present both tables to the user.
## Step 2 — Ask user to provide missing test data AND expected results
For each row where **Input Provided?** is **No** OR **Expected Result Provided?** is **No**, ask the user:
> **Option A — Provide the missing items**: Supply what is missing:
> - **Missing input data**: Place test data files in `_docs/00_problem/input_data/` or indicate the location.
> - **Missing expected result**: Provide the quantifiable expected result for this input. Update `_docs/00_problem/input_data/expected_results/results_report.md` with a row mapping the input to its expected output. If the expected result is complex, provide a reference CSV file in `_docs/00_problem/input_data/expected_results/`. Use `.cursor/skills/test-spec/templates/expected-results.md` for format guidance.
>
> Expected results MUST be quantifiable — the test must be able to programmatically compare actual vs expected. Examples:
> - "3 detections with bounding boxes [(x1,y1,x2,y2), ...] ± 10px"
> - "HTTP 200 with JSON body matching `expected_response_01.json`"
> - "Processing time < 500ms"
> - "0 false positives in the output set"
>
> **Option B — Skip this test**: If you cannot provide the data or expected result, this test scenario will be **removed** from the specification.
**BLOCKING**: Wait for the user's response for every missing item.
## Step 3 — Validate provided data and expected results
For each item where the user chose **Option A**:
**Input data validation**:
1. Verify the data file(s) exist at the indicated location
2. Verify **quality**: data matches the format, schema, and constraints described in the test scenario (e.g., correct image resolution, valid JSON structure, expected value ranges)
3. Verify **quantity**: enough data samples to cover the scenario (e.g., at least N images for a batch test, multiple edge-case variants)
**Expected result validation**:
4. Verify the expected result exists in `input_data/expected_results/results_report.md` or as a referenced file in `input_data/expected_results/`
5. Verify **quantifiability**: the expected result can be evaluated programmatically — it must contain at least one of:
- Exact values (counts, strings, status codes)
- Numeric values with tolerance (e.g., `± 10px`, `≥ 0.85`)
- Pattern matches (regex, substring, JSON schema)
- Thresholds (e.g., `< 500ms`, `≤ 5% error rate`)
- Reference file for structural comparison (JSON diff, CSV diff)
6. Verify **completeness**: the expected result covers all outputs the test checks (not just one field when the test validates multiple)
7. Verify **consistency**: the expected result is consistent with the acceptance criteria it traces to
If any validation fails, report the specific issue and loop back to Step 2 for that item.
## Step 4 — Remove tests without data or expected results
For each item where the user chose **Option B**:
1. Warn the user: `⚠️ Test scenario [ID] "[Name]" will be REMOVED from the specification due to missing test data or expected result.`
2. Remove the test scenario from the respective test file
3. Remove corresponding rows from `traceability-matrix.md`
4. Update `test-data.md` to reflect the removal
**Save action**: Write updated files under TESTS_OUTPUT_DIR:
- `test-data.md`
- Affected test files (if tests removed)
- `traceability-matrix.md` (if tests removed)
## Step 5 — Final coverage check
After all removals, recalculate coverage:
1. Count remaining test scenarios that trace to acceptance criteria
2. Count total acceptance criteria + restrictions
3. Calculate coverage percentage: `covered_items / total_items * 100`
| Metric | Value |
|--------|-------|
| Total AC + Restrictions | ? |
| Covered by remaining tests | ? |
| **Coverage %** | **?%** |
**Decision**:
- **Coverage ≥ 75%** → Phase 3 **PASSED**. Present final summary to user.
- **Coverage < 75%** → Phase 3 **FAILED**. Report:
> ❌ Test coverage dropped to **X%** (minimum 75% required). The removed test scenarios left gaps in the following acceptance criteria / restrictions:
>
> | Uncovered Item | Type (AC/Restriction) | Missing Test Data Needed |
> |---|---|---|
>
> **Action required**: Provide the missing test data for the items above, or add alternative test scenarios that cover these items with data you can supply.
**BLOCKING**: Loop back to Step 2 with the uncovered items. Do NOT finalize until coverage ≥ 75%.
## Phase 3 Completion
When coverage ≥ 75% and all remaining tests have validated data AND quantifiable expected results:
1. Present the final coverage report
2. List all removed tests (if any) with reasons
3. Confirm every remaining test has: input data + quantifiable expected result + comparison method
4. Confirm all artifacts are saved and consistent
After Phase 3 completion, run `phases/hardware-assessment.md` before Phase 4.
@@ -0,0 +1,60 @@
# Phase 4: Test Runner Script Generation
**Skip condition**: If this skill was invoked from the `/plan` skill (planning context, no code exists yet), skip Phase 4 entirely. Script creation should instead be planned as a task during decompose — the decomposer creates a task for creating these scripts. Phase 4 only runs when invoked from the existing-code flow (where source code already exists) or standalone.
**Role**: DevOps engineer
**Goal**: Generate executable shell scripts that run the specified tests, so autodev and CI can invoke them consistently.
**Constraints**: Scripts must be idempotent, portable across dev/CI, and exit with non-zero on failure. Respect the Hardware-Dependency Assessment decision recorded in `environment.md`.
**Prerequisite**: `phases/hardware-assessment.md` must have completed and written the "Test Execution" section to `TESTS_OUTPUT_DIR/environment.md`.
## Step 1 — Detect test infrastructure
1. Identify the project's test runner from manifests and config files:
- Python: `pytest` (`pyproject.toml`, `setup.cfg`, `pytest.ini`)
- .NET: `dotnet test` (`*.csproj`, `*.sln`)
- Rust: `cargo test` (`Cargo.toml`)
- Node: `npm test` or `vitest` / `jest` (`package.json`)
2. Check the Hardware-Dependency Assessment result recorded in `environment.md`:
- If **local execution** was chosen → do NOT generate docker-compose test files; scripts run directly on host
- If **Docker execution** was chosen → identify/generate docker-compose files for integration/blackbox tests
- If **both** was chosen → generate both
3. Identify performance/load testing tools from dependencies (`k6`, `locust`, `artillery`, `wrk`, or built-in benchmarks)
4. Read `TESTS_OUTPUT_DIR/environment.md` for infrastructure requirements
## Step 2 — Generate test runner
**Docker is the default.** Only generate a local `scripts/run-tests.sh` if the Hardware-Dependency Assessment determined **local** or **both** execution (i.e., the project requires real hardware like GPU/CoreML/TPU/sensors). For all other projects, use `docker-compose.test.yml` — it provides reproducibility, isolation, and CI parity without a custom shell script.
**If local script is needed** — create `scripts/run-tests.sh` at the project root using `.cursor/skills/test-spec/templates/run-tests-script.md` as structural guidance. The script must:
1. Set `set -euo pipefail` and trap cleanup on EXIT
2. **Install all project and test dependencies** (e.g. `pip install -q -r requirements.txt -r e2e/requirements.txt`, `dotnet restore`, `npm ci`). This prevents collection-time import errors on fresh environments.
3. Optionally accept a `--unit-only` flag to skip blackbox tests
4. Run unit/blackbox tests using the detected test runner (activate virtualenv if present, run test runner directly on host)
5. Print a summary of passed/failed/skipped tests
6. Exit 0 on all pass, exit 1 on any failure
**If Docker** — generate or update `docker-compose.test.yml` that builds the test image, installs all dependencies inside the container, runs the test suite, and exits with the test runner's exit code.
## Step 3 — Generate `scripts/run-performance-tests.sh`
Create `scripts/run-performance-tests.sh` at the project root. The script must:
1. Set `set -euo pipefail` and trap cleanup on EXIT
2. Read thresholds from `_docs/02_document/tests/performance-tests.md` (or accept as CLI args)
3. Start the system under test (local or docker-compose, matching the Hardware-Dependency Assessment decision)
4. Run load/performance scenarios using the detected tool
5. Compare results against threshold values from the test spec
6. Print a pass/fail summary per scenario
7. Exit 0 if all thresholds met, exit 1 otherwise
## Step 4 — Verify scripts
1. Verify both scripts are syntactically valid (`bash -n scripts/run-tests.sh`)
2. Mark both scripts as executable (`chmod +x`)
3. Present a summary of what each script does to the user
## Save action
Write `scripts/run-tests.sh` and `scripts/run-performance-tests.sh` to the project root.
@@ -0,0 +1,78 @@
# Hardware-Dependency & Execution Environment Assessment (BLOCKING)
Runs between Phase 3 and Phase 4.
Docker is the **preferred** test execution environment (reproducibility, isolation, CI parity). However, hardware-dependent projects may require local execution to exercise the real code paths. This assessment determines the right execution strategy by scanning both documentation and source code.
## Step 1 — Documentation scan
Check the following files for mentions of hardware-specific requirements:
| File | Look for |
|------|----------|
| `_docs/00_problem/restrictions.md` | Platform requirements, hardware constraints, OS-specific features |
| `_docs/01_solution/solution.md` | Engine selection logic, platform-dependent paths, hardware acceleration |
| `_docs/02_document/architecture.md` | Component diagrams showing hardware layers, engine adapters |
| `_docs/02_document/components/*/description.md` | Per-component hardware mentions |
| `TESTS_OUTPUT_DIR/environment.md` | Existing environment decisions |
## Step 2 — Code scan
Search the project source for indicators of hardware dependence. The project is **hardware-dependent** if ANY of the following are found:
| Category | Code indicators (imports, APIs, config) |
|----------|-----------------------------------------|
| GPU / CUDA | `import pycuda`, `import tensorrt`, `import pynvml`, `torch.cuda`, `nvidia-smi`, `CUDA_VISIBLE_DEVICES`, `runtime: nvidia` |
| Apple Neural Engine / CoreML | `import coremltools`, `CoreML`, `MLModel`, `ComputeUnit`, `MPS`, `sys.platform == "darwin"`, `platform.machine() == "arm64"` |
| OpenCL / Vulkan | `import pyopencl`, `clCreateContext`, vulkan headers |
| TPU / FPGA | `import tensorflow.distribute.TPUStrategy`, FPGA bitstream loaders |
| Sensors / Cameras | `import cv2.VideoCapture(0)` (device index), serial port access, GPIO, V4L2 |
| OS-specific services | Kernel modules (`modprobe`), host-level drivers, platform-gated code (`sys.platform` branches selecting different backends) |
Also check dependency files (`requirements.txt`, `setup.py`, `pyproject.toml`, `Cargo.toml`, `*.csproj`) for hardware-specific packages.
## Step 3 — Classify the project
Based on Steps 12, classify the project:
- **Not hardware-dependent**: no indicators found → use Docker (preferred default), skip to Step 5 "Record the decision"
- **Hardware-dependent**: one or more indicators found → proceed to Step 4
## Step 4 — Present execution environment choice
Present the findings and ask the user using Choose format:
```
══════════════════════════════════════
DECISION REQUIRED: Test execution environment
══════════════════════════════════════
Hardware dependencies detected:
- [list each indicator found, with file:line]
══════════════════════════════════════
Running in Docker means these hardware code paths
are NOT exercised — Docker uses a Linux VM where
[specific hardware, e.g. CoreML / CUDA] is unavailable.
The system would fall back to [fallback engine/path].
══════════════════════════════════════
A) Local execution only (tests the real hardware path)
B) Docker execution only (tests the fallback path)
C) Both local and Docker (tests both paths, requires
two test runs — recommended for CI with heterogeneous
runners)
══════════════════════════════════════
Recommendation: [A, B, or C] — [reason]
══════════════════════════════════════
```
## Step 5 — Record the decision
Write or update a **"Test Execution"** section in `TESTS_OUTPUT_DIR/environment.md` with:
1. **Decision**: local / docker / both
2. **Hardware dependencies found**: list with file references
3. **Execution instructions** per chosen mode:
- **Local mode**: prerequisites (OS, SDK, hardware), how to start services, how to run the test runner, environment variables
- **Docker mode**: docker-compose profile/command, required images, how results are collected
- **Both mode**: instructions for each, plus guidance on which CI runner type runs which mode
The decision is consumed by Phase 4 to choose between local `scripts/run-tests.sh` and `docker-compose.test.yml`.
@@ -95,7 +95,7 @@ Examples:
File: `expected_results/image_01_detections.json`
```json
```json
{
"input": "image_01.jpg",
"expected": {
@@ -119,7 +119,7 @@ File: `expected_results/image_01_detections.json`
]
}
}
```
```
```
---
+31
View File
@@ -33,6 +33,37 @@ End-to-end UI design workflow producing production-quality HTML+CSS mockups enti
- **Ask, don't assume**: when design direction is ambiguous, STOP and ask the user
- **One screen at a time**: generate individual screens, not entire applications at once
## Applicability Check
When invoked directly by a user (`/ui-design ...`), proceed — the user explicitly asked.
When invoked by an orchestrator (e.g. the autodev greenfield flow Step 4), first decide whether the project actually has UI work to do. The project IS a UI project if ANY of the following are true:
- `package.json` exists in the workspace root or any subdirectory
- `*.html`, `*.jsx`, or `*.tsx` files exist in the workspace
- `_docs/02_document/components/` contains a component whose `description.md` mentions UI, frontend, page, screen, dashboard, form, or view
- `_docs/02_document/architecture.md` mentions frontend, UI layer, SPA, or client-side rendering
- `_docs/01_solution/solution.md` mentions frontend, web interface, or user-facing UI
If none of the above match → return `outcome: skipped, reason: not-a-ui-project` to the caller and exit without running any phase.
If at least one matches → present using Choose format:
```
══════════════════════════════════════
DECISION REQUIRED: UI project detected — generate mockups?
══════════════════════════════════════
A) Generate UI mockups (recommended before decomposition)
B) Skip — proceed without mockups
══════════════════════════════════════
Recommendation: A — mockups before decomposition
produce better task specs for frontend components
══════════════════════════════════════
```
- If **A** → continue to Context Resolution below and run the workflow.
- If **B** → return `outcome: skipped, reason: user-declined` and exit.
## Context Resolution
Determine the operating mode based on invocation before any other logic runs.
+35
View File
@@ -0,0 +1,35 @@
# Azaion UI — Vite build-time environment variables.
#
# All variables here are read at build time via `import.meta.env.VITE_*` and
# inlined by Vite. Copy this file to `.env.local` (gitignored) for local
# dev; CI / Docker pass the same variables through the build environment.
#
# Every variable is OPTIONAL. When unset, the SPA falls back to production-
# default behavior:
# - VITE_API_BASE_URL : '' (relative paths; SPA and suite share nginx)
# - VITE_OWM_API_KEY : undefined → getWeatherData returns null
# - VITE_OWM_BASE_URL : https://api.openweathermap.org/data/2.5
# - VITE_SATELLITE_TILE_URL : http://localhost:5100/tiles/{z}/{x}/{y}
# (dev default; production builds MUST override
# to the same-origin nginx path so cookie auth
# is honored — AZ-498 / contract @
# _docs/02_document/contracts/satellite-provider/tiles.md)
# Prefix for every API request (production: empty; tests / alt deployments: set).
# A trailing slash is stripped automatically.
# Example: VITE_API_BASE_URL=http://azaion-ui:80
VITE_API_BASE_URL=
# OpenWeatherMap API key. Required for the FlightsPage weather feature.
# Leave unset in CI tests — the e2e profile routes to owm-stub.
VITE_OWM_API_KEY=<your-openweathermap-api-key>
# OpenWeatherMap REST base URL. Default targets the public endpoint; tests
# override to point at the owm-stub service.
# Example for the e2e profile: http://owm-stub:8081/data/2.5
VITE_OWM_BASE_URL=
# Suite satellite-provider tile URL template (Leaflet TileLayer.url).
# Production: same-origin path (`/tiles/{z}/{x}/{y}`) so the auth cookie rides.
# E2E profile: http://tile-stub:8082/tiles/{z}/{x}/{y}
VITE_SATELLITE_TILE_URL=
+8 -8
View File
@@ -3,15 +3,17 @@
.superpowers
# dependencies
/node_modules
/.pnp
.pnp.js
node_modules/
# testing
/coverage
# production
/build
/dist
# TypeScript build cache
*.tsbuildinfo
# misc
.DS_Store
@@ -20,13 +22,11 @@
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
package-lock.json
yarn.lock
# Playwright
node_modules/
# Test runners (Vitest + Playwright)
/test-output/
/test-results/
/playwright-report/
/blob-report/
+18 -3
View File
@@ -8,9 +8,24 @@ labels:
steps:
- name: build-push
image: docker
environment:
REGISTRY_HOST:
from_secret: registry_host
REGISTRY_USER:
from_secret: registry_user
REGISTRY_TOKEN:
from_secret: registry_token
commands:
- if [ "$CI_COMMIT_BRANCH" = "main" ]; then export TAG=arm; else export TAG=${CI_COMMIT_BRANCH}-arm; fi
- docker build -f Dockerfile -t localhost:5000/ui:$TAG .
- docker push localhost:5000/ui:$TAG
- echo "$REGISTRY_TOKEN" | docker login "$REGISTRY_HOST" -u "$REGISTRY_USER" --password-stdin
- export TAG=${CI_COMMIT_BRANCH}-arm
- export BUILD_DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ)
- |
docker build -f Dockerfile \
--build-arg CI_COMMIT_SHA=$CI_COMMIT_SHA \
--label org.opencontainers.image.revision=$CI_COMMIT_SHA \
--label org.opencontainers.image.created=$BUILD_DATE \
--label org.opencontainers.image.source=$CI_REPO_URL \
-t $REGISTRY_HOST/azaion/ui:$TAG .
- docker push $REGISTRY_HOST/azaion/ui:$TAG
volumes:
- /var/run/docker.sock:/var/run/docker.sock
+3 -1
View File
@@ -1,4 +1,4 @@
FROM --platform=$BUILDPLATFORM oven/bun:1-alpine AS build
FROM --platform=$BUILDPLATFORM oven/bun:1.3.11-alpine AS build
WORKDIR /app
COPY package.json bun.lock* ./
RUN bun install --frozen-lockfile
@@ -6,6 +6,8 @@ COPY . .
RUN bun run build
FROM nginx:alpine
ARG CI_COMMIT_SHA=unknown
ENV AZAION_REVISION=$CI_COMMIT_SHA
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
+227
View File
@@ -0,0 +1,227 @@
# azaion-ui
React SPA that serves as the **single front-end for the entire Azaion suite**.
It does not own data or business logic; it is the operator's window onto
every backend service that lives as a sibling submodule in the
[`azaion/suite`](../README.md) monorepo.
```
suite/
├── annotations/ .NET 10 — Annotations / Media / Datasets / Settings
├── flights/ .NET 10 — Flights, waypoints, aircrafts, GPS SSE
├── detections/ Cython — YOLO inference (ONNX / TensorRT)
├── detections-semantic/ Cython — Semantic detection
├── loader/ Cython — Encrypted resource loader
├── gps-denied-onboard/ Python — GPS-denied positioning (UAV side)
├── gps-denied-desktop/ Python — GPS-denied positioning (operator side)
├── autopilot/ Python — UAV control via MAVLink
├── admin/ .NET 10 — Users, roles, detection classes, model versions
├── ai-training/ Python — YOLO training, ONNX export
├── satellite-provider/ .NET 10 — Google Maps tile cache
└── ui/ React 19 — ◄ this repository
```
For the suite-wide architecture, deployment topology, database design, and
the legacy WPF predecessor see:
- [`suite/_docs/`](../_docs/) — system-level architecture and per-service
feature docs (canonical source of truth).
- [`_docs/legacy/wpf-era.md`](_docs/legacy/wpf-era.md) — what the
pre-rewrite Windows desktop application looked like, why the React port
exists, and which behaviours are intentionally being preserved.
- [`_docs/ui_design/`](_docs/ui_design/) — page-level wireframes
(HTML mockups + a design README) inherited from the WPF UI; the
authoritative reference for layout, keyboard shortcuts, color scheme,
affiliation icons, annotation row gradient, etc.
> **Status.** The code currently in `src/` is a **rudimentary first cut**
> mechanically translated from the legacy WPF / XAML UI. It is not yet
> fully wired to the new suite APIs and has no test coverage. Formal
> bottom-up documentation, a test specification, a testability pass, and
> the initial test suite are being produced via the
> [`/autodev` existing-code flow](.cursor/skills/autodev/SKILL.md). When
> the documentation + safety net are in place, feature work resumes
> through the same flow.
---
## What this repo is — and is not
| | this repo (`ui/`) | the suite services |
|--|---|---|
| **Owns** | rendering, routing, client-side state, i18n, drag-and-drop, the Leaflet map, `<video>` playback, optimistic UI, keyboard shortcuts, layout persistence | data, persistence, queues, inference, model delivery, telemetry, RBAC, tile caching, autopilot |
| **Talks to** | every backend submodule via REST + SSE (HTTP) | each other via REST / SSE / RabbitMQ; no shared source code |
| **Builds to** | a static bundle served by nginx (`Dockerfile`) | individual service Docker images |
| **Runs on** | operator station (laptop / tablet / mini-PC); browser of choice | edge device or remote server, per service tier (see [`suite/_docs/00_top_level_architecture.md`](../_docs/00_top_level_architecture.md)) |
| **Reaches the network** | only through the operator's browser, with the user's JWT | service-to-service inside the docker network and to `admin/` over the internet |
The React app must remain stateless beyond what `localStorage` /
`UserSettings` (Annotations API) can hold. **No business rules in the UI.**
## Pages → backend submodules
| Page | Route | Primary submodule(s) consumed |
|------|-------|-------------------------------|
| Login | `/login` | `admin/` (auth + user) |
| Flights | `/flights` | `flights/`, `gps-denied-desktop/`, `gps-denied-onboard/` (live GPS SSE), `satellite-provider/` (orthophoto reference tiles), `autopilot/` (mission status) |
| Annotations | `/annotations` | `annotations/` (media, annotations, settings), `detections/` + `detections-semantic/` (AI detect), `loader/` (model availability status only) |
| Dataset Explorer | `/dataset` | `annotations/` (queries, validation), `ai-training/` (class distribution, dataset health), `admin/` (detection classes seed) |
| Admin | `/admin` | `admin/` (users, detection classes, AI recognition + GPS device + model-version settings) |
| Settings | `/settings` | `annotations/` (tenant / directories / aircrafts), `admin/` (connection check) |
`Header` exposes a global flight selector — the **selected flight is the
application context** and most other pages auto-filter by it. The
selection is persisted server-side via `UserSettings` in the
`annotations/` API.
For the full UX spec (wireframes, interactions, keyboard shortcuts, color
tokens, affiliation icons, combat-readiness indicator, gradient annotation
list, time-window video annotation overlay, drawer behaviour, etc.) see
[`_docs/ui_design/README.md`](_docs/ui_design/README.md).
## Tech stack
- **React 19** + **TypeScript 5.7**
- **Vite 6** (`bun run dev` / `bun run build`)
- **Bun 1.3.11** as package manager and runtime (`packageManager` field)
- **Tailwind CSS 4** via `@tailwindcss/vite`
- **react-router-dom 7** for routing
- **react-i18next** for UA/EN localization (see `src/i18n/`)
- **leaflet** + **react-leaflet** + **leaflet-draw** + **leaflet-polylinedecorator**
for the Flights map
- **chart.js** + **react-chartjs-2** for telemetry / class distribution
- **@hello-pangea/dnd** for waypoint reordering
- **react-icons** for icon set
- **react-dropzone** for orthophoto upload
There is no client-side state library — local component state and
`Context` (`AuthContext`, `FlightContext`) are sufficient at this scale.
Server data is fetched on demand and not cached beyond component
lifetime; introduce TanStack Query when the test suite is in place if
the lack of caching becomes a real problem.
## Repository layout
```
src/
├── main.tsx app entry point (creates the React root)
├── App.tsx routes, AuthProvider, FlightProvider
├── index.css tailwind base + custom CSS variables
├── api/
│ ├── client.ts fetch wrapper, JWT injection, error normalization
│ └── sse.ts EventSource helper used by flights + detections
├── auth/
│ ├── AuthContext.tsx JWT lifecycle, user identity, role
│ └── ProtectedRoute.tsx route guard
├── components/ shared UI (Header, FlightContext, ConfirmDialog,
│ DetectionClasses, HelpModal …)
├── features/
│ ├── login/ LoginPage
│ ├── flights/ FlightsPage + map, sidebar, params panel,
│ │ waypoint list, altitude chart, mini-map,
│ │ wind effect, JSON editor, draw control
│ ├── annotations/ AnnotationsPage + canvas editor, video player,
│ │ media list, annotations sidebar, class colors
│ ├── dataset/ DatasetPage
│ ├── admin/ AdminPage
│ └── settings/ SettingsPage
├── hooks/ useDebounce, useResizablePanel
├── i18n/ i18n.ts + en.json + ua.json
└── types/ shared TS types
_docs/
├── legacy/ history of the WPF predecessor
└── ui_design/ page-level wireframes inherited from the WPF UI
.cursor/ workspace-scoped agents/rules/skills
.woodpecker/ CI pipeline (Woodpecker, ARM build target)
Dockerfile multi-stage: bun build → nginx static
nginx.conf production nginx config (SPA fallback to /index.html)
vite.config.ts vite + react + tailwind plugin
tsconfig.json TS config
```
The skeleton mirrors the **page-per-feature, control-per-domain**
decomposition of the legacy WPF app:
`Azaion.Annotator``features/annotations/`,
`Azaion.Dataset``features/dataset/`,
`Azaion.Suite.MainSuite``components/Header.tsx`, etc. See
`_docs/legacy/wpf-era.md` §10 for the per-feature mapping and §11 for
the parts that are intentionally NOT being ported.
## Local development
Prerequisites:
- [Bun](https://bun.sh/) 1.3.11+
- A reachable suite (or at least the `admin/` and `annotations/`
services). For an all-in-one local stack, see
[`suite/_infra/dev/README.md`](../_infra/dev/README.md).
```bash
# from suite/ui/
bun install --frozen-lockfile
bun run dev # http://localhost:5173 (Vite)
bun run build # tsc -b + vite build → dist/
bun run preview # serve the production build locally
```
API base URL is configured via Vite environment variables. Copy
`.env.example` (when introduced — currently the wiring is hardcoded;
this is one of the testability fixes scheduled for `/autodev` Step 4)
to `.env.local` before `bun run dev`. Until then, see
`src/api/client.ts` for the current base-URL strategy.
## Production build
The production image is a static bundle behind nginx:
```bash
docker build -t azaion-ui:dev .
docker run --rm -p 8080:80 azaion-ui:dev
# open http://localhost:8080/
```
The image expects the suite's reverse-proxy / ingress to terminate TLS
and forward `/api/*` to the appropriate backend service. See
[`suite/_infra/deploy/`](../_infra/deploy/) for per-target compose files.
## CI
CI runs in self-hosted **Woodpecker**, building the multi-arch Docker
image and pushing it to the suite's Harbor registry. Pipeline: see
[`.woodpecker/build-arm.yml`](.woodpecker/build-arm.yml). Suite-wide CI
infra: [`suite/_infra/ci/README.md`](../_infra/ci/README.md).
The build is triggered on push to `dev`, `stage`, and `main`. Image tags
are branch-tagged; no `latest` tag is published.
## How this repo is being matured
1. **Document the existing code** — bottom-up, via the `/document`
skill: `_docs/02_document/` will hold module docs, component specs,
architecture, and a final report. Triggered automatically as Step 1
of the existing-code flow.
2. **Architecture baseline scan** of the produced architecture against
the codebase (`_docs/02_document/architecture_compliance_baseline.md`).
3. **Test specifications** — produced from the documentation, not from
the code, so the tests describe intended behaviour. Output:
`_docs/02_document/tests/`.
4. **Testability revision** — the smallest possible refactor that lets
tests run (replace hardcoded API URLs with env vars, etc.).
Strictly minimal; deeper refactoring is deferred to step 8.
5. **Decompose tests** into individual tasks and **implement** them.
6. **Run tests** — green tests become the safety net.
7. **(Optional) Refactor** the codebase against the safety net.
8. From there, the project enters the existing-code feature cycle:
*new task → implement → run tests → sync test specs → update docs
→ security audit → performance test → deploy → retrospective*, and
loops.
The state machine for this is in [`_docs/_autodev_state.md`](_docs/_autodev_state.md).
The orchestration definition is in
[`.cursor/skills/autodev/SKILL.md`](.cursor/skills/autodev/SKILL.md).
## License
See the parent suite repository.

Some files were not shown because too many files have changed in this diff Show More