yadflow 3.18.1 → 4.0.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/CHANGELOG.md +355 -0
  2. package/README.md +79 -26
  3. package/bin/commands.mjs +41 -0
  4. package/bin/yad.mjs +437 -124
  5. package/cli/artifact-status.mjs +34 -15
  6. package/cli/checkpoint.mjs +69 -49
  7. package/cli/codeowners-command.mjs +170 -0
  8. package/cli/codeowners.mjs +397 -0
  9. package/cli/commit.mjs +13 -9
  10. package/cli/companion.mjs +2 -2
  11. package/cli/dial.mjs +183 -0
  12. package/cli/docs.mjs +88 -32
  13. package/cli/doctor.mjs +1472 -97
  14. package/cli/epic-state.mjs +3478 -232
  15. package/cli/epic.mjs +506 -0
  16. package/cli/errors.mjs +4 -1
  17. package/cli/gate.mjs +1002 -209
  18. package/cli/history.mjs +556 -0
  19. package/cli/hook.mjs +266 -55
  20. package/cli/hubcommit.mjs +6 -17
  21. package/cli/index-command.mjs +87 -0
  22. package/cli/ledger.mjs +57 -7
  23. package/cli/lib.mjs +184 -18
  24. package/cli/manifest.mjs +367 -56
  25. package/cli/migrate.mjs +726 -53
  26. package/cli/mode.mjs +170 -0
  27. package/cli/next.mjs +349 -90
  28. package/cli/openpr.mjs +191 -39
  29. package/cli/people.mjs +654 -0
  30. package/cli/plan.mjs +417 -132
  31. package/cli/platform.mjs +110 -129
  32. package/cli/product-index.mjs +287 -0
  33. package/cli/protection.mjs +706 -0
  34. package/cli/reconcile.mjs +38 -12
  35. package/cli/repo-publish.mjs +24 -26
  36. package/cli/repo.mjs +23 -14
  37. package/cli/report.mjs +21 -15
  38. package/cli/review.mjs +24 -27
  39. package/cli/riskmap-command.mjs +289 -0
  40. package/cli/riskmap.mjs +373 -0
  41. package/cli/setup.mjs +139 -287
  42. package/cli/ship.mjs +7 -6
  43. package/cli/skill.mjs +180 -0
  44. package/cli/skip.mjs +211 -30
  45. package/cli/thread.mjs +42 -17
  46. package/cli/tidy.mjs +20 -20
  47. package/cli/update-commit.mjs +22 -22
  48. package/cli/usage.mjs +115 -109
  49. package/package.json +3 -3
  50. package/skills/sdlc/config.yaml +166 -87
  51. package/skills/sdlc/module-help.csv +35 -35
  52. package/skills/yad-analysis/SKILL.md +125 -65
  53. package/skills/yad-architecture/SKILL.md +34 -23
  54. package/skills/yad-architecture/references/contract-format.md +10 -8
  55. package/skills/yad-backfill/SKILL.md +14 -8
  56. package/skills/yad-backfill/references/backfill.md +1 -1
  57. package/skills/yad-change/SKILL.md +127 -52
  58. package/skills/yad-change/references/triage.md +42 -28
  59. package/skills/yad-checks/SKILL.md +89 -45
  60. package/skills/yad-checks/references/check-gates.md +315 -92
  61. package/skills/yad-checks/templates/checks/build-test-lint.sh +25 -7
  62. package/skills/yad-checks/templates/checks/commit-message.sh +17 -3
  63. package/skills/yad-checks/templates/checks/contract-check.sh +58 -2
  64. package/skills/yad-checks/templates/checks/epic-open.sh +3 -3
  65. package/skills/yad-checks/templates/checks/install-deps.sh +46 -0
  66. package/skills/yad-checks/templates/checks/ledger-guard.sh +94 -18
  67. package/skills/yad-checks/templates/checks/lineage-check.sh +23 -9
  68. package/skills/yad-checks/templates/checks/package-manager.sh +140 -0
  69. package/skills/yad-checks/templates/checks/reconcile-debt-check.sh +4 -4
  70. package/skills/yad-checks/templates/checks/risk-map-check.sh +438 -0
  71. package/skills/yad-checks/templates/checks/verified-commits.sh +20 -46
  72. package/skills/yad-checks/templates/github/yad-checks.yml +37 -5
  73. package/skills/yad-checks/templates/github/yad-hub-checks.yml +5 -5
  74. package/skills/yad-checks/templates/github/yad-update-guard.yml +3 -4
  75. package/skills/yad-checks/templates/github/yad-verified-commits.yml +4 -4
  76. package/skills/yad-checks/templates/gitlab/.gitlab-ci.yml +7 -1
  77. package/skills/yad-checks/templates/gitlab/yad-checks.gitlab-ci.yml +22 -4
  78. package/skills/yad-checks/templates/gitlab/yad-hub-checks.gitlab-ci.yml +5 -5
  79. package/skills/yad-checks/templates/gitlab/yad-verified-commits.gitlab-ci.yml +4 -4
  80. package/skills/yad-checks/templates/hooks/ledger-guard-cursor.sh +91 -0
  81. package/skills/yad-checks/templates/hooks/ledger-guard.sh +38 -7
  82. package/skills/yad-commit/SKILL.md +6 -6
  83. package/skills/yad-connect-design/SKILL.md +6 -6
  84. package/skills/yad-connect-design/references/design-context.md +1 -1
  85. package/skills/yad-connect-design/references/design-registry.md +2 -2
  86. package/skills/yad-connect-docs/SKILL.md +12 -12
  87. package/skills/yad-connect-docs/references/docs-registry.md +1 -1
  88. package/skills/yad-connect-learning/SKILL.md +5 -5
  89. package/skills/yad-connect-learning/references/learning-registry.md +2 -2
  90. package/skills/yad-connect-repos/SKILL.md +92 -54
  91. package/skills/yad-connect-repos/references/code-context.md +6 -6
  92. package/skills/yad-connect-repos/references/hub-config.md +68 -58
  93. package/skills/yad-connect-repos/references/repos-registry.md +10 -9
  94. package/skills/yad-connect-repos/references/risk-map.md +81 -0
  95. package/skills/yad-connect-testing/SKILL.md +6 -6
  96. package/skills/yad-connect-testing/references/testing-context.md +3 -4
  97. package/skills/yad-connect-testing/references/testing-registry.md +2 -2
  98. package/skills/yad-defects/SKILL.md +8 -8
  99. package/skills/yad-discovery/SKILL.md +130 -94
  100. package/skills/yad-discovery/references/discovery-schema.md +23 -7
  101. package/skills/yad-discovery/references/foundation-schema.md +374 -0
  102. package/skills/yad-docs/SKILL.md +16 -11
  103. package/skills/yad-docs/references/data-mapping.md +9 -7
  104. package/skills/yad-docs/templates/app/package-lock.json +3 -3
  105. package/skills/yad-docs-overview/SKILL.md +32 -17
  106. package/skills/yad-docs-overview/references/pipeline-model.md +47 -28
  107. package/skills/yad-docs-sync/SKILL.md +10 -5
  108. package/skills/yad-docs-sync/references/staleness.md +8 -7
  109. package/skills/yad-engineer-review/SKILL.md +88 -24
  110. package/skills/yad-engineer-review/references/ship-and-record.md +25 -16
  111. package/skills/yad-epic/SKILL.md +178 -100
  112. package/skills/yad-epic/references/state-schema.md +626 -117
  113. package/skills/yad-hub-bridge/SKILL.md +66 -48
  114. package/skills/yad-hub-bridge/references/bridge.md +110 -83
  115. package/skills/yad-hub-bridge/references/login-roster.md +163 -70
  116. package/skills/yad-hub-bridge/templates/checks/hub-route.sh +22 -19
  117. package/skills/yad-hub-bridge/templates/github/yad-gate-sync.yml +34 -14
  118. package/skills/yad-hub-bridge/templates/gitlab/gitlab-ci.include-root.yml +2 -2
  119. package/skills/yad-hub-bridge/templates/gitlab/yad-gate-sync.gitlab-ci.yml +22 -12
  120. package/skills/yad-implement/SKILL.md +29 -15
  121. package/skills/yad-implement/references/implement-conventions.md +2 -2
  122. package/skills/yad-learn/SKILL.md +9 -9
  123. package/skills/yad-learn/references/learning-state.md +2 -2
  124. package/skills/yad-open-pr/SKILL.md +64 -29
  125. package/skills/yad-pair-review/SKILL.md +18 -16
  126. package/skills/yad-pair-review/references/session-state.md +4 -4
  127. package/skills/yad-pr-template/SKILL.md +48 -27
  128. package/skills/yad-pr-template/references/risk-routing.md +97 -24
  129. package/skills/yad-pr-template/templates/checks/pr-template.sh +37 -15
  130. package/skills/yad-pr-template/templates/checks/pr-title.sh +27 -13
  131. package/skills/yad-pr-template/templates/checks/risk-route.sh +107 -14
  132. package/skills/yad-pr-template/templates/github/pull_request_template.md +7 -5
  133. package/skills/yad-pr-template/templates/gitlab/merge_request_templates/Default.md +7 -5
  134. package/skills/yad-pr-template/templates/hub/github/pull_request_template.md +15 -14
  135. package/skills/yad-pr-template/templates/hub/gitlab/merge_request_templates/Default.md +15 -13
  136. package/skills/yad-reconcile/SKILL.md +3 -3
  137. package/skills/yad-report/SKILL.md +5 -5
  138. package/skills/yad-review-companion/SKILL.md +12 -9
  139. package/skills/yad-review-gate/SKILL.md +198 -79
  140. package/skills/yad-review-gate/references/gating.md +230 -54
  141. package/skills/yad-run/SKILL.md +86 -56
  142. package/skills/yad-run/references/run-loop.md +67 -45
  143. package/skills/yad-ship/SKILL.md +18 -14
  144. package/skills/yad-spec/SKILL.md +31 -17
  145. package/skills/yad-spec/references/spec-handoff.md +17 -5
  146. package/skills/yad-status/SKILL.md +114 -56
  147. package/skills/yad-stories/SKILL.md +42 -27
  148. package/skills/yad-stories/references/story-schema.md +10 -9
  149. package/skills/yad-stub/SKILL.md +59 -48
  150. package/skills/yad-sync-repos/SKILL.md +3 -3
  151. package/skills/yad-test-cases/SKILL.md +37 -30
  152. package/skills/yad-test-cases/references/test-cases-schema.md +8 -5
  153. package/skills/yad-timeline/SKILL.md +8 -7
  154. package/skills/yad-ui/SKILL.md +46 -25
  155. package/cli/roster.mjs +0 -164
  156. package/skills/sdlc/install.sh +0 -68
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  name: yad-analysis
3
- description: 'Optional front state 1 of the gated SDLC. With the analyst, pressure-test a feature idea and write the discovery brief into analysis.md. Assigns the EP-<slug> ID and seeds .sdlc/ state (the 12-step chain that puts analysis before epic). Never auto-advances — hands off to the team review gate. Optional: if skipped, the epic step does this shaping inline. Use when the user says "analyse the idea", "start with analysis", or "author the analysis".'
3
+ description: 'Optional Shape step 1 of the gated SDLC. With the analyst, pressure-test a feature idea and write the discovery brief into analysis.md. Assigns the EP-<slug> ID and seeds .sdlc/ state (the 12-step chain that puts analysis before epic). Never auto-advances — hands off to the team review gate. Optional: if skipped, the epic step does this shaping inline. Use when the user says "analyse the idea", "start with analysis", or "author the analysis".'
4
4
  ---
5
5
 
6
- # SDLC — Author Analysis (optional front state 1)
6
+ # SDLC — Author Analysis (optional Shape step 1)
7
7
 
8
8
  **Goal:** Produce a human-authored, AI-assisted `analysis.md` — the analyst's discovery brief that
9
9
  shapes the feature **before** the epic — assign its stable `EP-<slug>` ID, and initialise the per-epic
10
- state machine in `.sdlc/`. This is a **front state**: human-authored with AI assist and **never
10
+ state machine in `.sdlc/`. This is a **Shape step**: human-authored with AI assist and **never
11
11
  auto-advances**. When the analysis is drafted, control passes to `yad-review-gate`.
12
12
 
13
13
  This step is **optional**. When it runs, it is the entry point: it assigns the ID and seeds the
@@ -15,26 +15,33 @@ This step is **optional**. When it runs, it is the entry point: it assigns the I
15
15
  analyst shaping inline and seeds the **10-step** chain — no behaviour change for teams that skip it.
16
16
 
17
17
  This skill enforces the build plan's core rules: all state lives in files; IDs are generated by the
18
- engine (never typed by hand); front steps are locked to `human_approve`.
18
+ engine (never typed by hand); Shape steps are locked to `advance: human`.
19
19
 
20
20
  ## Conventions
21
21
 
22
22
  - `{project-root}` resolves from the project working directory.
23
23
  - Analysis artifacts live under `{project-root}/epics/EP-<slug>/` (build plan §6).
24
- - Speak in the configured `communication_language`; write documents in `document_output_language`.
24
+ - Speak in the `communication_language` set in `{project-root}/.sdlc/config.yaml`; write documents in `document_output_language`.
25
25
 
26
26
  ## On Activation
27
27
 
28
28
  ### Step 1 — Get the idea
29
29
  Ask the user for a one-line feature idea if not provided.
30
30
 
31
- **Precondition gate (rail):** analysis is the optional first entry point and seeds state exactly once.
32
- If `.sdlc/state.json` already exists for the target epic, run `yad next EP-<slug> --check analysis`; if it
33
- exits non-zero, **STOP** and point the user at `yad next EP-<slug>` (the epic is past analysis). If it
34
- exits zero, resume analysis for that epic. When no `state.json` exists yet, proceed and seed state.
31
+ **Precondition gate (rail):** the chain is seeded exactly once, and this skill is no longer the only
32
+ thing that can have done it — `yad epic new <slug> --profile analysis-first` seeds the same 12-step
33
+ chain from the CLI. So the question is whether `.sdlc/state.json` exists, not who wrote it:
34
+
35
+ - **A chain already exists** — run `yad next EP-<slug> --check analysis`. If it exits non-zero, **STOP**
36
+ and point the user at `yad next EP-<slug>` (the epic is past analysis). If it exits zero, resume
37
+ analysis for that epic and **skip Step 6** (the chain is already there — re-seeding is refused anyway).
38
+ - **No `state.json`** — this is the entry point. Run Step 6 to seed the chain.
39
+
40
+ **Step 6b runs on both paths.** It is what closes the authoring step and opens its gate, and nothing
41
+ else does it.
35
42
 
36
43
  ### Step 2 — Shape the idea (assist: analyst)
37
- Adopt the **analyst** lens (`bmad-agent-analyst`, Mary) to pressure-test the idea in depth: who is the
44
+ Adopt the **analyst** lens to pressure-test the idea in depth: who is the
38
45
  user, what problem, what already exists, what options are on the table, what signals success, what is
39
46
  out of scope, and what the recommendation to the epic is. This is the discovery the epic will build on.
40
47
 
@@ -50,28 +57,37 @@ connected repo** (the epic's `repos` are not chosen yet), load the lightweight c
50
57
  stamp `code-context: stale` in the frontmatter.
51
58
  - **Traceability:** record which maps you loaded in the analysis frontmatter `code-context:` field.
52
59
 
53
- ### Step 2c — Read the project roadmap (project context, only once discovery is APPROVED)
54
- Consume the project front-zero (`yad-discovery`) **only after its review gate has passed** — never a
55
- draft or in-review roadmap (that would bypass `discovery-review`). Gate on the **state**, not file
56
- existence: read `{project-root}/epics/EP-discovery/.sdlc/state.json` and proceed **only when
57
- `currentStep == "discovery-done"`**. When it is, read its `roadmap.md` and sibling `requirements.md`
58
- for the project framing: which phase (MVP / later) this feature belongs to and the requirements it
59
- carries — so the analysis's **Problem / Options / Recommendation** stay consistent with the approved
60
- roadmap. **Optional & non-blocking:** if there is no discovery, or it has not yet reached
61
- `discovery-done`, proceed unchanged — do not consume an unapproved roadmap.
60
+ ### Step 2c — Read the Foundation (product context, only once it is APPROVED)
61
+ Consume the Product level (written by `yad-discovery`) **only after its review gate has passed** — never
62
+ a draft or in-review one (that would bypass its gate). Gate on the **state**, not file existence:
63
+ - **The Foundation:** read `{project-root}/foundation/.sdlc/state.json` and proceed **only when
64
+ `currentStep == "foundation-done"`**. Then read `foundation/purpose.md`, `scope.md`, `mvp.md` and
65
+ `roadmap.md` for the product framing.
66
+ - **The old spelling**, only when there is no Foundation: read
67
+ `{project-root}/epics/EP-discovery/.sdlc/state.json` and proceed **only when
68
+ `currentStep == "discovery-done"`**. Then read its `roadmap.md` and sibling `requirements.md`.
69
+
70
+ Use it for: which phase (MVP / later) this feature belongs to, what the product explicitly is **not**,
71
+ and the requirements it carries — so the analysis's **Problem / Options / Recommendation** stay
72
+ consistent with the approved product. **Optional & non-blocking:** if there is no product level, or it
73
+ has not passed its gate yet, proceed unchanged — do not consume an unapproved one. (`yad next` reports
74
+ feature work that goes ahead of an unapproved Foundation; it never blocks it.)
62
75
 
63
76
  ### Step 3 — Generate the Epic ID (engine-assigned, never by hand)
77
+ *(Skip when `state.json` already exists — the id was assigned by whatever seeded the chain.)*
64
78
  Derive `EP-<slug>` where `slug` is **2–4 lowercase words joined by hyphens**, drawn from the idea
65
- (e.g. `EP-checkout`). Lowercase except the fixed `EP` prefix. `EP-discovery` is **reserved**
66
- for the project front-zero — never use it for a feature. **The ID is assigned once and
79
+ (e.g. `EP-checkout`). Lowercase except the fixed `EP` prefix. `EP-foundation` and `EP-discovery` are
80
+ **reserved** for the Product level — never use either for a feature. **The ID is assigned once and
67
81
  never renamed** — renaming breaks every downstream link (build plan §6b). Check
68
- `{project-root}/epics/` for collisions; if the slug exists, append a distinguishing word.
82
+ `{project-root}/epics/` for collisions; if the slug exists, append a distinguishing word. When the
83
+ Foundation's `roadmap.md` has a row for this feature, prefer that row's **proposed epic id**, so
84
+ `yad foundation status` can match the feature to its epic.
69
85
 
70
86
  ### Step 4 — Open the authoring branch
71
87
  Open the analysis authoring branch `analysis/EP-<slug>` per the shared procedure
72
- (`references/state-schema.md` → "Authoring branches"): git-safe (skip with a note if `{project-root}`
73
- is not a git work tree), check out the branch if it exists, else create it from the hub's default
74
- branch. Author and commit `analysis.md` on it. This is **distinct** from the bridge's `review/…` branch.
88
+ (`../yad-epic/references/state-schema.md` → "Authoring branches"): git-safe (skip with a note if `{project-root}`
89
+ is not a git work tree), check out the branch if it exists, else create it from the Product's default
90
+ branch. Author and commit `analysis.md` on it. This is **distinct** from the verified ledger's `review/…` branch.
75
91
 
76
92
  ### Step 5 — Write the analysis (assist: analyst)
77
93
  Write `{project-root}/epics/EP-<slug>/analysis.md` using EXACTLY this template:
@@ -101,57 +117,101 @@ code-context: { repos: [], loaded: <YYYY-MM-DD or none> } # which code-maps in
101
117
 
102
118
  Fill the body with the user; leave `owner` for the user to set.
103
119
 
104
- ### Step 6 — Seed the state machine
105
- Create `{project-root}/epics/EP-<slug>/.sdlc/state.json` describing the full **12-step** front-state
106
- sequence (analysis before epic), all steps defaulting to `automation: human_approve`, with every
107
- authoring step **locked**. Use this exact shape (see `references/state-schema.md`):
108
-
109
- ```json
110
- {
111
- "schemaVersion": 1,
112
- "epicId": "EP-<slug>",
113
- "createdAt": "<YYYY-MM-DD>",
114
- "currentStep": "analysis-review",
115
- "steps": [
116
- { "id": "analysis", "type": "author", "artifact": "analysis.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "done", "risk_tags": [] },
117
- { "id": "analysis-review", "type": "review+approve", "artifact": "analysis.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "in_review", "risk_tags": [] },
118
- { "id": "epic", "type": "author", "artifact": "epic.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
119
- { "id": "epic-review", "type": "review+approve", "artifact": "epic.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
120
- { "id": "architecture", "type": "author", "artifact": "architecture.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
121
- { "id": "architecture-review","type": "review+approve", "artifact": "architecture.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": ["contract"] },
122
- { "id": "ui-design", "type": "author", "artifact": "ui-design.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
123
- { "id": "ui-design-review", "type": "review+approve", "artifact": "ui-design.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
124
- { "id": "stories", "type": "author", "artifact": "stories/", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
125
- { "id": "stories-review", "type": "review+approve", "artifact": "stories/", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
126
- { "id": "test-cases", "type": "author", "artifact": "test-cases.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
127
- { "id": "test-cases-review", "type": "review+approve", "artifact": "test-cases.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] }
128
- ]
129
- }
120
+ ### Step 6 — Seed the state machine — only when nothing is seeded
121
+ *(Skip when `state.json` already exists — `yad epic new --profile analysis-first` seeded it. Go to
122
+ Step 6b. Re-seeding would overwrite a ledger, and in verified mode that is the mutation
123
+ `ledger-guard` rejects.)*
124
+
125
+ **Run the engine. Do not hand-write the chain.**
126
+
127
+ ```bash
128
+ yad epic new EP-<slug> --profile analysis-first --type <feature|chore>
129
+ yad epic new EP-<slug> --profile spike --type <feature|chore> # a timeboxed investigation
130
130
  ```
131
131
 
132
+ That writes `{project-root}/epics/EP-<slug>/.sdlc/state.json`, the empty `approvals.json` and
133
+ `comments.json`, and the `reviews/` directory. With `--profile analysis-first` the chain is the full
134
+ **12-step** route (`analysis` before `epic`). Every step is `advance: human` and locked; `analysis` is
135
+ open and the rest are `todo`. The chain comes from the step catalogue and the lifecycle profile in
136
+ the engine (`../yad-epic/references/state-schema.md`), so there is one definition of it and no copy
137
+ here to drift from it.
138
+
139
+ **Ask whether this is a spike before you seed.** `analysis-first` is the right answer when the
140
+ analysis is the front of a real feature. When the work IS the investigation — a timeboxed question
141
+ whose output is a finding and a throwaway prototype — `--profile spike` seeds a **6-step** lane
142
+ instead: `analysis → analysis-review → epic → epic-review → stories → stories-review`, with no
143
+ architecture, UI-design or test-case steps. `analysis` is still the open first step either way, so
144
+ every step below this one is unchanged.
145
+
146
+ A spike has **no architecture gate, so no `contract.md` and no lock**, and no step on it is optional —
147
+ `yad skip` is refused. **Choose the route before you seed, because the choice is final:** there is no
148
+ re-seed. If the investigation concludes that the shared cross-repo surface has to move, the follow-up
149
+ belongs on `classic` — the spike records the finding, and a NEW epic builds it.
150
+
151
+ It writes no `analysis.md`, no branch and no commit, and it refuses an epic that already has a
152
+ `state.json`. There is no `epic.md` at this point, so pass `--type` (it defaults to `feature`).
153
+
132
154
  Notes:
133
- - `analysis-review` carries no `risk_tags` — it is the **base** rule (owner + 1 reviewer).
134
- - `architecture-review` carries `risk_tags: ["contract"]` so the gate escalates it by default
135
- (build plan §4): the contract review needs domain owners, not just owner + 1.
136
- - `test-cases` / `test-cases-review` are a **parallel, non-blocking track**: they seed `blocked` and open
137
- when `stories-review` passes — the epic is already `ready-for-build` by then, so the build half runs
138
- alongside the tester (see `../yad-epic/references/state-schema.md`).
139
- - Also create an empty approvals ledger `{project-root}/epics/EP-<slug>/.sdlc/approvals.json`
140
- and an empty comments ledger `{project-root}/epics/EP-<slug>/.sdlc/comments.json`, each containing
141
- `[]`, and the `reviews/` directory.
155
+ - **Then advance the authoring step.** The seed leaves `analysis` open, which is truthful: the command
156
+ runs before the artifact exists. Closing it is Step 6b's job, and on the local path `yad gate open`
157
+ does it — so after writing `analysis.md`, take Step 6b.
158
+ - `analysis-review` carries no `risk_tags` — it is the **base** rule (1 distinct approver, who
159
+ should not be the author). The catalogue sets that; there is nothing to type.
160
+ - `architecture-review` carries `risk_tags: ["contract"]` by default (build plan §4): the tag raises
161
+ the step's full approver count to 3 (base 1 + contract risk 2). Only the base holds the
162
+ gate; the risk step is advisory, reported as a shortfall against the count capped at the
163
+ active people less one (E72).
164
+ - `test-cases` / `test-cases-review` are a **parallel, non-blocking track**: they seed `todo` and open
165
+ when `stories-review` passes — the epic is already `ready-for-build` by then, so Build
166
+ runs alongside the tester (see `../yad-epic/references/state-schema.md`).
142
167
  - Commit the seed on the `analysis/EP-<slug>` branch, and cut `review/EP-<slug>/analysis` from it so the
143
- epic's **first** review PR/MR carries the ledger to the default branch. In bridge mode `ledger-guard`
168
+ epic's **first** review PR/MR carries the ledger to the default branch. In verified mode `ledger-guard`
144
169
  exempts a new epic's ledger (creation, not mutation, #162); every later change to it is CI's. See
145
170
  `../yad-epic/references/state-schema.md`, "Authoring branches".
171
+ - **No UI, on a verified Product?** The analysis review PR is this epic's first, so until it merges is the
172
+ only time `yad skip` can write the ledger. If the idea clearly has no user-facing surface, offer
173
+ `yad skip EP-<slug> ui-design --reason "<why>"` now; after that PR merges, CI owns `state.json` and the
174
+ skip is refused. On a local ledger there is no hurry: `yad-ui` offers the same skip later.
175
+
176
+ ### Step 6b — Open the analysis review gate
177
+ *(**Always run this**, on both entry modes. The chain is seeded by now either way — by `yad epic new`
178
+ in Step 6, or by `yad epic new` before this skill was invoked — and `analysis.md` is written. This is
179
+ the step that closes the authoring step and opens its gate.)*
180
+ **Check the mode first — the two modes have opposite instructions here.** Read `.sdlc/hub.json`:
181
+ **verified mode** is `platform` set AND `ledger: "verified"` — or, on a project that has not run
182
+ `yad migrate` yet, `bridge_enabled` (or legacy `bridge`) `true`. `ledger` wins whenever it is present.
183
+
184
+ **verified mode — do NOT write `state.json`.** The ledger is CI-owned and advancing a step is a
185
+ mutation: `ledger-guard` rejects any non-bot commit that changes one, and `yad gate ci --merged`
186
+ performs the whole transition when the review PR merges.
187
+
188
+ **Do not EDIT the ledger — but do COMMIT it when it is untracked.** Those are two different acts.
189
+ Commit `analysis.md`, and also `.sdlc/state.json`, `.sdlc/approvals.json` and `.sdlc/comments.json`
190
+ when `git status` shows them **untracked** — an engine-seeded ledger has never been reviewed, so it is
191
+ still off the base ref and `ledger-guard` exempts it (creation, not mutation, #162). It rides this
192
+ epic's first review PR exactly as a Step 6 seed does. Leave their contents alone.
193
+
194
+ **Otherwise — local, or a platform with no gate-sync CI — the engine makes this edit, not you.**
195
+ `yad gate open <epic> analysis.md` marks `analysis-review` `in_review`, closes `analysis` as `done`,
196
+ and moves `currentStep` to the gate — the same transition, from the one function that owns it (`markInReview`, `cli/epic-state.mjs`).
197
+ `yad-review-gate action: open` runs that command; hand off to it rather than editing the ledger here.
198
+
199
+ **With no platform configured** it writes the ledger and simply opens no PR, so this works offline.
200
+ **With a platform** the `review/EP-<slug>/analysis` branch must already be **on origin** — the command refuses
201
+ and writes nothing otherwise. Cut it from the authoring branch and push it before handing off
202
+ (`yad open-pr` does both, then delegates).
203
+
204
+ Do **not** hand-edit `state.json`, do **not** re-seed, and do **not** touch `approvals.json` — only real
205
+ reviewers approve, through the gate.
146
206
 
147
207
  ### Step 7 — Stop at the gate (do NOT advance)
148
208
  Report: epic ID, the path to `analysis.md`, and that the next action is **review** via
149
- `yad-review-gate` (base rule: owner + 1 reviewer). **Never mark the analysis-review step approved
150
- here** — only real reviewers do that through the gate. Front states do not auto-advance. When the
209
+ `yad-review-gate` (base rule: 1 distinct approver, who should not be the author). **Never mark the analysis-review step approved
210
+ here** — only real reviewers do that through the gate. Shape steps do not auto-advance. When the
151
211
  analysis gate passes, control moves to `yad-epic`, which reads `analysis.md` as input. When the
152
- hub has a platform, the gate opens a review PR on the hub (via `yad-hub-bridge`) and
212
+ Product has a platform, the gate opens a review PR on the Product (via `yad-hub-bridge`) and
153
213
  `yad-review-gate action: sync` pulls platform approvals/comments into the ledger; otherwise the review
154
- is recorded file-only.
214
+ is recorded local.
155
215
 
156
216
  ## Reference
157
217
  - State schema, the two chain shapes, and the authoring-branch procedure:
@@ -1,24 +1,24 @@
1
1
  ---
2
2
  name: yad-architecture
3
- description: 'Front state 3 of the gated SDLC. With the architect, author architecture.md and the locked contract.md (the shared cross-repo surface), then hash-lock the contract surface into .sdlc/contract-lock.json. Reads epic.md as input. Never auto-advances — hands off to the team review gate (which escalates on the contract risk tag). Use when the user says "author the architecture" or after the epic gate passes.'
3
+ description: 'Shape step 3 of the gated SDLC. With the architect, author architecture.md and the locked contract.md (the shared cross-repo surface), then hash-lock the contract surface into .sdlc/contract-lock.json. Reads epic.md as input. Never auto-advances — hands off to the team review gate (the contract risk tag raises its approver count). Use when the user says "author the architecture" or after the epic gate passes.'
4
4
  ---
5
5
 
6
- # SDLC — Author Architecture + Contract (front state 3)
6
+ # SDLC — Author Architecture + Contract (Shape step 3)
7
7
 
8
8
  **Goal:** Produce a human-authored, AI-assisted `architecture.md` and the **locked** `contract.md`
9
9
  for an approved epic, then record a hash-lock of the contract surface so a later contract-check can
10
- detect drift. This is a **front state**: human-authored with AI assist, **never auto-advances**.
11
- When both artifacts are drafted, control passes to `yad-review-gate`, which **escalates** this review
12
- by default (the architecture step carries `risk_tags: ["contract"]`).
10
+ detect drift. This is a **Shape step**: human-authored with AI assist, **never auto-advances**.
11
+ When both artifacts are drafted, control passes to `yad-review-gate`. The architecture step carries
12
+ `risk_tags: ["contract"]` by default, which raises the review's (advisory) approver count.
13
13
 
14
14
  This skill enforces the build plan's core rules: all state lives in files; the contract holds only the
15
- shared cross-repo surface at charter altitude; front steps stay locked to `human_approve`.
15
+ shared cross-repo surface at charter altitude; Shape steps stay locked to `advance: human`.
16
16
 
17
17
  ## Conventions
18
18
 
19
19
  - `{project-root}` resolves from the project working directory.
20
20
  - Artifacts live under `{project-root}/epics/EP-<slug>/` (build plan §6).
21
- - Speak in the configured `communication_language`; write documents in `document_output_language`.
21
+ - Speak in the `communication_language` set in `{project-root}/.sdlc/config.yaml`; write documents in `document_output_language`.
22
22
 
23
23
  ## On Activation
24
24
 
@@ -36,8 +36,8 @@ This passes when `architecture` is the next runnable step per the state sequence
36
36
  Open the architecture authoring branch `architecture/EP-<slug>` per the shared procedure
37
37
  (`../yad-epic/references/state-schema.md` → "Authoring branches"): git-safe (skip with a note
38
38
  if `{project-root}` is not a git work tree), check out the branch if it exists, else create it from the
39
- hub's default branch. Author and commit `architecture.md` / `contract.md` / `contract-lock.json` on it.
40
- This is **distinct** from the bridge's `review/…` branch.
39
+ Product's default branch. Author and commit `architecture.md` / `contract.md` / `contract-lock.json` on it.
40
+ This is **distinct** from the verified ledger's `review/…` branch.
41
41
 
42
42
  ### Step 2 — Read the epic as input context
43
43
  Read `epic.md`. Note `repos` (the touched domains), the goal, scope, and acceptance signals. The
@@ -63,7 +63,7 @@ is always present.)
63
63
  `references/code-context.md`).
64
64
 
65
65
  ### Step 3 — Author the architecture (assist: architect)
66
- Adopt the **architect** lens (`bmad-agent-architect`, Winston) and write
66
+ Adopt the **architect** lens and write
67
67
  `{project-root}/epics/EP-<slug>/architecture.md` using EXACTLY this template:
68
68
 
69
69
  ```markdown
@@ -179,30 +179,41 @@ awk '/CONTRACT-SURFACE:BEGIN/{f=1;next} /CONTRACT-SURFACE:END/{f=0} f' \
179
179
 
180
180
  ### Step 6 — Advance the authoring step (NOT the gate)
181
181
  **Check the mode first — the two modes have opposite instructions here.** Read `.sdlc/hub.json`:
182
- **bridge mode** is `platform` set AND `bridge_enabled` (or legacy `bridge`) `true`.
182
+ **verified mode** is `platform` set AND `ledger: "verified"` — or, on a project that has not run `yad migrate` yet, `bridge_enabled` (or legacy `bridge`) `true`. `ledger` wins whenever it is present.
183
183
 
184
- **Bridge mode — do NOT write `state.json`.** The ledger is CI-owned: the `ledger-guard` check rejects
185
- any non-bot commit touching `epics/*/.sdlc/{state,approvals,comments,hub-prs}.json` or
184
+ **verified mode — do NOT write `state.json`.** The ledger is CI-owned: the `ledger-guard` check rejects
185
+ any non-bot commit touching `epics/*/.sdlc/{state,approvals,comments,product-prs,hub-prs}.json` or
186
186
  `epics/*/reviews/*.md`, `yad gate open` deliberately skips this write for the same reason, and
187
187
  `yad gate ci --merged` performs the whole transition when the review PR merges. Making the edit here
188
188
  fails the gate if it rides the review PR, and desynchronises the ledger CI is about to rewrite if it
189
189
  is pushed around the gate. Commit the artifact set — **`architecture.md`, `contract.md`, and
190
190
  `.sdlc/contract-lock.json`** (artifact-side, not ledger) — then hand off to `yad-review-gate`.
191
191
 
192
- **Otherwise — file-only, or a platform with no gate-sync CI — write it.** In `state.json`: set
193
- `architecture.status: "done"`, set `architecture-review.status: "in_review"`, and set
194
- `currentStep: "architecture-review"`. Write `state.json`. Do **not** touch `approvals.json` — only
195
- real reviewers approve, through the gate. On this branch `yad gate open` makes the same edit, so it
196
- is a no-op once the gate has run.
192
+ **Otherwise — local, or a platform with no gate-sync CI — the engine makes this edit, not you.**
193
+ `yad gate open <epic> architecture.md` marks `architecture-review` `in_review`, closes `architecture` as `done`, and moves `currentStep` to the gate
194
+ — the same transition, from the one function that owns it (`markInReview`, `cli/epic-state.mjs`).
195
+ `yad-review-gate action: open` runs that command; hand off to it rather than editing the ledger here.
196
+
197
+ **With no platform configured** it writes the ledger and simply opens no PR, so this works offline.
198
+ **With a platform** the `review/EP-<slug>/architecture` branch must already be **on origin** — the command
199
+ refuses and writes nothing otherwise. Cut it from the authoring branch and push it before handing off
200
+ (or run `yad open-pr` from that branch: it pushes the branch, then delegates).
201
+
202
+ Do **not** hand-edit `state.json`, and do **not** touch `approvals.json` — only real reviewers approve,
203
+ through the gate.
197
204
 
198
205
  ### Step 7 — Stop at the gate (do NOT advance)
199
206
  Report: the paths to `architecture.md`, `contract.md`, and `contract-lock.json`; the contract hash;
200
- and that the next action is **review** via `yad-review-gate`. Note that this review **escalates**
201
- (risk tag `contract`): it needs owner + 1 reviewer **plus a domain owner for each touched repo**.
202
- **Never record approval here.** Front states do not auto-advance. When the hub has a platform, the gate
203
- opens a review PR on the hub (via `yad-hub-bridge`, labelled per touched repo) and
207
+ and that the next action is **review** via `yad-review-gate`. Because of the risk tag `contract`, the
208
+ step's full approver count is 3 distinct people (base 1 + contract risk 2), none of whom should be the
209
+ author. Only the base (1 distinct approver) holds the gate; the risk step is advisory. The engine caps
210
+ the count at the active people less one, floor 1, and prints it (E72) — with 2 active people the capped
211
+ ask is 1, with 3 it is 2, with 4 or more all 3 — and a shortfall never holds the gate. When the people
212
+ cannot be counted (as in Product CI with connected repos), no cap is shown. The review PR requests no reviewers; the team asks them on the PR itself.
213
+ **Never record approval here.** Shape steps do not auto-advance. When the Product has a platform, the gate
214
+ opens a review PR on the Product (via `yad-hub-bridge`, labelled per touched repo) and
204
215
  `yad-review-gate action: sync` pulls platform approvals/comments into the ledger; a contract re-lock
205
- invalidates prior platform approvals too. Otherwise the review is recorded file-only.
216
+ invalidates prior platform approvals too. Otherwise the review is recorded local.
206
217
 
207
218
  ## Reference
208
219
  - Contract surface, altitude rule, and hashing recipe: `references/contract-format.md`.
@@ -1,8 +1,8 @@
1
1
  # Contract surface — format, altitude, and hash-lock
2
2
 
3
- The `contract.md` produced at front state 3 is the **single source of truth for the shared cross-repo
4
- surface** of an epic. Phase 3's contract-check (not built yet) fails a PR when a repo drifts from this
5
- surface. To make that check possible, the surface is delimited and hash-locked now.
3
+ The `contract.md` produced at Shape step 3 is the **single source of truth for the shared cross-repo
4
+ surface** of an epic. The contract-check gate (`yad-checks`) fails a code-repo PR that changes its copy of
5
+ this surface without a `Contract-Change: yes` trailer and a re-locked contract. To make that check possible, the surface is delimited and hash-locked now.
6
6
 
7
7
  ## What goes in the surface (altitude rule)
8
8
 
@@ -62,14 +62,16 @@ awk '/CONTRACT-SURFACE:BEGIN/{f=1;next} /CONTRACT-SURFACE:END/{f=0} f' \
62
62
 
63
63
  ## Interaction with the review gate
64
64
 
65
- - The `architecture-review` step carries `risk_tags: ["contract"]`, so `yad-review-gate` **escalates**
66
- it: owner + 1 reviewer **plus** one `domain-owner` approval per repo in the epic's `repos`.
65
+ - The `architecture-review` step carries `risk_tags: ["contract"]`. The tag sets the step's approver
66
+ count — 3 distinct people (base 1 + contract risk 2). `yad-review-gate` enforces only the base (1
67
+ distinct approver, who should not be the author); the risk step is reported as a shortfall
68
+ against the count capped at the active people less one (E72), and does not hold the gate. No per-repo or role approval is required. The review PR names
69
+ and labels the epic's `repos`.
67
70
  - **Staleness:** if the surface block is edited after approvals are recorded, the recomputed hash will
68
71
  not match the lock — approvals are stale and the gate drops back to `comment`. Re-lock (Step 5 of the
69
72
  skill) and re-approve.
70
73
 
71
74
  ## Why a hash (vs structured diff)
72
75
 
73
- A hash is the smallest representation that proves "did the agreed surface change?" — which is all the
74
- front half needs. A field-by-field structured diff is a Phase 3 concern (it tells you *what* drifted in
75
- a failing PR); the lock established here is what that future check compares against.
76
+ A hash is the smallest representation that proves "did the agreed surface change?" — which is all Shape needs. A field-by-field structured diff is a Phase 3 concern (it tells you *what* drifted in
77
+ a failing PR); the lock established here is what the contract-check compares against.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: yad-backfill
3
- description: 'Build-half Step G of the gated SDLC — backfill: generate specs for already-built features in an existing repo so new work does not break them. Confirm Repomix (the one true CLI subprocess: npx repomix), pack ONE feature at a time (compress + git logs, secret-scan), feed it to AI with a "describe what exists, do not invent" prompt, and write a DRAFT spec marked unverified. Require human approval (reuse yad-review-gate) before the spec counts as real. Boundary is auto-proposed from the project convention and human-confirmed. A change is blocked only until the features IT touches have approved specs. The `promote` action flips a brownfield stub epic (minted by yad-stub, so defects could thread off it) to a real, verified feature epic once its backfill spec is approved. Use when the user says "backfill specs", "document an existing feature", "spec the legacy code", or "promote the stub epic".'
3
+ description: 'Build Step G of the gated SDLC — backfill: generate specs for already-built features in an existing repo so new work does not break them. Confirm Repomix (the one true CLI subprocess: npx repomix), pack ONE feature at a time (compress + git logs, secret-scan), feed it to AI with a "describe what exists, do not invent" prompt, and write a DRAFT spec marked unverified. Require human approval (reuse yad-review-gate) before the spec counts as real. Boundary is auto-proposed from the project convention and human-confirmed. A change is blocked only until the features IT touches have approved specs. The `promote` action flips a brownfield stub epic (minted by yad-stub, so defects could thread off it) to a real, verified feature epic once its backfill spec is approved. Use when the user says "backfill specs", "document an existing feature", "spec the legacy code", or "promote the stub epic".'
4
4
  ---
5
5
 
6
6
  # SDLC — Backfill (existing-code specs)
@@ -66,8 +66,8 @@ Mark every uncertain item explicitly (`<!-- unverified: ... -->`); do not fill g
66
66
  behaviour.
67
67
 
68
68
  ### Step 4 — `approve` (human approval — reuse the gate)
69
- A human reads the draft against the real code and approves it with the same `human_approve` discipline
70
- as `yad-review-gate` (owner + 1 reviewer). On approval set the frontmatter `verified: true` and record
69
+ A human reads the draft against the real code and approves it with the same `advance: human` discipline
70
+ as `yad-review-gate` (at least 1 approver who is not the author). On approval set the frontmatter `verified: true` and record
71
71
  the approver(s) + date. Only a `verified: true` backfill spec counts as real.
72
72
 
73
73
  ### Step 5 — `gate` (block changes per touched feature)
@@ -89,20 +89,26 @@ thread off it, `promote` is what makes that anchor real — run it once the feat
89
89
  and `yad thread` / `yad-status` (read `epic.md`) will disagree about whether the epic is still a stub.
90
90
  - **`epic.md`:** set `verified: true`, **remove** the `stub:` marker, and add a `backfill:` block linking
91
91
  the approved spec, e.g. `backfill: { spec: specs/backfill/<feature>/spec.md, promoted: <YYYY-MM-DD> }`.
92
+ Keep the stub's `title:`; set one now if it has none (the one-line name of the feature), by the
93
+ rules in the `title` row of the `epic.md` frontmatter table in `../yad-epic/references/state-schema.md`.
92
94
  - **`state.json`:** **remove** the top-level `kind: "stub"`, and move `currentStep` off the
93
- `backfill-pending` sentinel (per the promote flavour below).
95
+ `backfill-pending` sentinel (per the promote flavour below). **Leave the top-level `type` exactly
96
+ as it is.** `kind` and `type` are two different things in this file: `kind: "stub"` is the
97
+ lifecycle marker you are clearing, and `type: "feature"` is the work-item type, which a promoted
98
+ stub still has. Nothing would report its loss — `yad doctor` only compares a `type` that is
99
+ there — so the ledger would quietly stop saying what kind of work it holds.
94
100
  - **Light promote (default):** the feature's documentation lives in the approved backfill spec — do NOT
95
- wake the front chain. Set `state.json` `currentStep: "backfill-done"` (a terminal sentinel, like
101
+ wake the Shape chain. Set `state.json` `currentStep: "backfill-done"` (a terminal sentinel, like
96
102
  `discovery-done`): the epic is now a real, verified anchor and its later evolution threads normally with
97
103
  `yad-change`. `yad next` then reports it as a documented anchor, not a pending stub.
98
- - **Full promote (opt-in):** to bring the feature fully under the front half and lock a real contract,
104
+ - **Full promote (opt-in):** to bring the feature fully under Shape and lock a real contract,
99
105
  "wake" the state chain — set `currentStep: "epic"`, `epic` step `status: "in_progress"` — then run
100
106
  `yad-epic` → `yad-architecture` → … the normal way. This re-locks a contract that subsequent thread
101
107
  changes will inherit.
102
- - **Bridge mode — promote is not wired.** The `state.json` edits above mutate an epic whose ledger is
108
+ - **verified mode — promote is not wired.** The `state.json` edits above mutate an epic whose ledger is
103
109
  already on the base ref, so the `#162` seed exemption does not apply and `ledger-guard` rejects the
104
110
  commit; unlike the authoring steps there is no `yad backfill` CLI and no `gate ci` path that performs
105
- the promotion instead. On a bridge hub, STOP and report this — the promotion needs the gate bot (or a
111
+ the promotion instead. On a verified Product, STOP and report this — the promotion needs the gate bot (or a
106
112
  maintainer landing it out of band). Only the `epic.md` half is safe to commit. Tracked as a gap; do
107
113
  **not** push the ledger edit around the guard.
108
114
  - Never auto-advances; a human confirms the promotion.
@@ -45,7 +45,7 @@ generated: <YYYY-MM-DD>
45
45
  ---
46
46
  ```
47
47
 
48
- `verified: false` until a human approves (the `yad-review-gate` discipline: owner + 1 reviewer). On
48
+ `verified: false` until a human approves (the `yad-review-gate` discipline: at least 1 approver who is not the author). On
49
49
  approval, set `verified: true` and record the approver(s) + date. Only a `verified: true` backfill spec
50
50
  counts as real.
51
51