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.
- package/CHANGELOG.md +355 -0
- package/README.md +79 -26
- package/bin/commands.mjs +41 -0
- package/bin/yad.mjs +437 -124
- package/cli/artifact-status.mjs +34 -15
- package/cli/checkpoint.mjs +69 -49
- package/cli/codeowners-command.mjs +170 -0
- package/cli/codeowners.mjs +397 -0
- package/cli/commit.mjs +13 -9
- package/cli/companion.mjs +2 -2
- package/cli/dial.mjs +183 -0
- package/cli/docs.mjs +88 -32
- package/cli/doctor.mjs +1472 -97
- package/cli/epic-state.mjs +3478 -232
- package/cli/epic.mjs +506 -0
- package/cli/errors.mjs +4 -1
- package/cli/gate.mjs +1002 -209
- package/cli/history.mjs +556 -0
- package/cli/hook.mjs +266 -55
- package/cli/hubcommit.mjs +6 -17
- package/cli/index-command.mjs +87 -0
- package/cli/ledger.mjs +57 -7
- package/cli/lib.mjs +184 -18
- package/cli/manifest.mjs +367 -56
- package/cli/migrate.mjs +726 -53
- package/cli/mode.mjs +170 -0
- package/cli/next.mjs +349 -90
- package/cli/openpr.mjs +191 -39
- package/cli/people.mjs +654 -0
- package/cli/plan.mjs +417 -132
- package/cli/platform.mjs +110 -129
- package/cli/product-index.mjs +287 -0
- package/cli/protection.mjs +706 -0
- package/cli/reconcile.mjs +38 -12
- package/cli/repo-publish.mjs +24 -26
- package/cli/repo.mjs +23 -14
- package/cli/report.mjs +21 -15
- package/cli/review.mjs +24 -27
- package/cli/riskmap-command.mjs +289 -0
- package/cli/riskmap.mjs +373 -0
- package/cli/setup.mjs +139 -287
- package/cli/ship.mjs +7 -6
- package/cli/skill.mjs +180 -0
- package/cli/skip.mjs +211 -30
- package/cli/thread.mjs +42 -17
- package/cli/tidy.mjs +20 -20
- package/cli/update-commit.mjs +22 -22
- package/cli/usage.mjs +115 -109
- package/package.json +3 -3
- package/skills/sdlc/config.yaml +166 -87
- package/skills/sdlc/module-help.csv +35 -35
- package/skills/yad-analysis/SKILL.md +125 -65
- package/skills/yad-architecture/SKILL.md +34 -23
- package/skills/yad-architecture/references/contract-format.md +10 -8
- package/skills/yad-backfill/SKILL.md +14 -8
- package/skills/yad-backfill/references/backfill.md +1 -1
- package/skills/yad-change/SKILL.md +127 -52
- package/skills/yad-change/references/triage.md +42 -28
- package/skills/yad-checks/SKILL.md +89 -45
- package/skills/yad-checks/references/check-gates.md +315 -92
- package/skills/yad-checks/templates/checks/build-test-lint.sh +25 -7
- package/skills/yad-checks/templates/checks/commit-message.sh +17 -3
- package/skills/yad-checks/templates/checks/contract-check.sh +58 -2
- package/skills/yad-checks/templates/checks/epic-open.sh +3 -3
- package/skills/yad-checks/templates/checks/install-deps.sh +46 -0
- package/skills/yad-checks/templates/checks/ledger-guard.sh +94 -18
- package/skills/yad-checks/templates/checks/lineage-check.sh +23 -9
- package/skills/yad-checks/templates/checks/package-manager.sh +140 -0
- package/skills/yad-checks/templates/checks/reconcile-debt-check.sh +4 -4
- package/skills/yad-checks/templates/checks/risk-map-check.sh +438 -0
- package/skills/yad-checks/templates/checks/verified-commits.sh +20 -46
- package/skills/yad-checks/templates/github/yad-checks.yml +37 -5
- package/skills/yad-checks/templates/github/yad-hub-checks.yml +5 -5
- package/skills/yad-checks/templates/github/yad-update-guard.yml +3 -4
- package/skills/yad-checks/templates/github/yad-verified-commits.yml +4 -4
- package/skills/yad-checks/templates/gitlab/.gitlab-ci.yml +7 -1
- package/skills/yad-checks/templates/gitlab/yad-checks.gitlab-ci.yml +22 -4
- package/skills/yad-checks/templates/gitlab/yad-hub-checks.gitlab-ci.yml +5 -5
- package/skills/yad-checks/templates/gitlab/yad-verified-commits.gitlab-ci.yml +4 -4
- package/skills/yad-checks/templates/hooks/ledger-guard-cursor.sh +91 -0
- package/skills/yad-checks/templates/hooks/ledger-guard.sh +38 -7
- package/skills/yad-commit/SKILL.md +6 -6
- package/skills/yad-connect-design/SKILL.md +6 -6
- package/skills/yad-connect-design/references/design-context.md +1 -1
- package/skills/yad-connect-design/references/design-registry.md +2 -2
- package/skills/yad-connect-docs/SKILL.md +12 -12
- package/skills/yad-connect-docs/references/docs-registry.md +1 -1
- package/skills/yad-connect-learning/SKILL.md +5 -5
- package/skills/yad-connect-learning/references/learning-registry.md +2 -2
- package/skills/yad-connect-repos/SKILL.md +92 -54
- package/skills/yad-connect-repos/references/code-context.md +6 -6
- package/skills/yad-connect-repos/references/hub-config.md +68 -58
- package/skills/yad-connect-repos/references/repos-registry.md +10 -9
- package/skills/yad-connect-repos/references/risk-map.md +81 -0
- package/skills/yad-connect-testing/SKILL.md +6 -6
- package/skills/yad-connect-testing/references/testing-context.md +3 -4
- package/skills/yad-connect-testing/references/testing-registry.md +2 -2
- package/skills/yad-defects/SKILL.md +8 -8
- package/skills/yad-discovery/SKILL.md +130 -94
- package/skills/yad-discovery/references/discovery-schema.md +23 -7
- package/skills/yad-discovery/references/foundation-schema.md +374 -0
- package/skills/yad-docs/SKILL.md +16 -11
- package/skills/yad-docs/references/data-mapping.md +9 -7
- package/skills/yad-docs/templates/app/package-lock.json +3 -3
- package/skills/yad-docs-overview/SKILL.md +32 -17
- package/skills/yad-docs-overview/references/pipeline-model.md +47 -28
- package/skills/yad-docs-sync/SKILL.md +10 -5
- package/skills/yad-docs-sync/references/staleness.md +8 -7
- package/skills/yad-engineer-review/SKILL.md +88 -24
- package/skills/yad-engineer-review/references/ship-and-record.md +25 -16
- package/skills/yad-epic/SKILL.md +178 -100
- package/skills/yad-epic/references/state-schema.md +626 -117
- package/skills/yad-hub-bridge/SKILL.md +66 -48
- package/skills/yad-hub-bridge/references/bridge.md +110 -83
- package/skills/yad-hub-bridge/references/login-roster.md +163 -70
- package/skills/yad-hub-bridge/templates/checks/hub-route.sh +22 -19
- package/skills/yad-hub-bridge/templates/github/yad-gate-sync.yml +34 -14
- package/skills/yad-hub-bridge/templates/gitlab/gitlab-ci.include-root.yml +2 -2
- package/skills/yad-hub-bridge/templates/gitlab/yad-gate-sync.gitlab-ci.yml +22 -12
- package/skills/yad-implement/SKILL.md +29 -15
- package/skills/yad-implement/references/implement-conventions.md +2 -2
- package/skills/yad-learn/SKILL.md +9 -9
- package/skills/yad-learn/references/learning-state.md +2 -2
- package/skills/yad-open-pr/SKILL.md +64 -29
- package/skills/yad-pair-review/SKILL.md +18 -16
- package/skills/yad-pair-review/references/session-state.md +4 -4
- package/skills/yad-pr-template/SKILL.md +48 -27
- package/skills/yad-pr-template/references/risk-routing.md +97 -24
- package/skills/yad-pr-template/templates/checks/pr-template.sh +37 -15
- package/skills/yad-pr-template/templates/checks/pr-title.sh +27 -13
- package/skills/yad-pr-template/templates/checks/risk-route.sh +107 -14
- package/skills/yad-pr-template/templates/github/pull_request_template.md +7 -5
- package/skills/yad-pr-template/templates/gitlab/merge_request_templates/Default.md +7 -5
- package/skills/yad-pr-template/templates/hub/github/pull_request_template.md +15 -14
- package/skills/yad-pr-template/templates/hub/gitlab/merge_request_templates/Default.md +15 -13
- package/skills/yad-reconcile/SKILL.md +3 -3
- package/skills/yad-report/SKILL.md +5 -5
- package/skills/yad-review-companion/SKILL.md +12 -9
- package/skills/yad-review-gate/SKILL.md +198 -79
- package/skills/yad-review-gate/references/gating.md +230 -54
- package/skills/yad-run/SKILL.md +86 -56
- package/skills/yad-run/references/run-loop.md +67 -45
- package/skills/yad-ship/SKILL.md +18 -14
- package/skills/yad-spec/SKILL.md +31 -17
- package/skills/yad-spec/references/spec-handoff.md +17 -5
- package/skills/yad-status/SKILL.md +114 -56
- package/skills/yad-stories/SKILL.md +42 -27
- package/skills/yad-stories/references/story-schema.md +10 -9
- package/skills/yad-stub/SKILL.md +59 -48
- package/skills/yad-sync-repos/SKILL.md +3 -3
- package/skills/yad-test-cases/SKILL.md +37 -30
- package/skills/yad-test-cases/references/test-cases-schema.md +8 -5
- package/skills/yad-timeline/SKILL.md +8 -7
- package/skills/yad-ui/SKILL.md +46 -25
- package/cli/roster.mjs +0 -164
- package/skills/sdlc/install.sh +0 -68
package/skills/yad-epic/SKILL.md
CHANGED
|
@@ -1,29 +1,31 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: yad-epic
|
|
3
|
-
description: '
|
|
3
|
+
description: 'Shape step for the epic in the gated SDLC. Shape a feature idea with the analyst (or read analysis.md when the optional analysis step already ran), then write the epic with the pm, into epic.md. The entry point when analysis is skipped: assigns the EP-<slug> ID and seeds .sdlc/ state. Never auto-advances — hands off to the team review gate. Use when the user says "start a new feature/epic" or "author an epic".'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# SDLC — Author Epic (
|
|
6
|
+
# SDLC — Author Epic (Shape step)
|
|
7
7
|
|
|
8
8
|
**Goal:** Produce a human-authored, AI-assisted `epic.md` for a new feature, and — when the epic is the
|
|
9
9
|
entry point — assign its stable `EP-<slug>` ID and initialise the per-epic state machine in `.sdlc/`.
|
|
10
|
-
This is a **
|
|
10
|
+
This is a **Shape step**: human-authored with AI assist and **never auto-advances**. When the epic is
|
|
11
11
|
drafted, control passes to `yad-review-gate`.
|
|
12
12
|
|
|
13
|
-
**Two entry modes
|
|
14
|
-
- **
|
|
15
|
-
`analysis
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
**Two entry modes**, decided by one question: does `.sdlc/state.json` already exist?
|
|
14
|
+
- **Chain already seeded** — `state.json` exists with `currentStep == "epic"`. Two things put it there:
|
|
15
|
+
the optional `yad-analysis` step (which also wrote `analysis.md`, and the epic **reads** it as its
|
|
16
|
+
shaped input), or `yad epic new <slug>`, which seeds the same chain and writes no artifact. Either
|
|
17
|
+
way this skill does **not** re-seed state.
|
|
18
|
+
- **Nothing seeded** (the default) — no `state.json`. The epic is the entry point: it shapes the idea
|
|
19
|
+
inline with the analyst, assigns `EP-<slug>`, and seeds the **10-step** chain.
|
|
18
20
|
|
|
19
21
|
This skill enforces the build plan's core rules: all state lives in files; IDs are generated by the
|
|
20
|
-
engine (never typed by hand);
|
|
22
|
+
engine (never typed by hand); Shape steps are locked to `advance: human`.
|
|
21
23
|
|
|
22
24
|
## Conventions
|
|
23
25
|
|
|
24
26
|
- `{project-root}` resolves from the project working directory.
|
|
25
27
|
- Epic artifacts live under `{project-root}/epics/EP-<slug>/` (build plan §6).
|
|
26
|
-
- Speak in the
|
|
28
|
+
- Speak in the `communication_language` set in `{project-root}/.sdlc/config.yaml`; write documents in `document_output_language`.
|
|
27
29
|
|
|
28
30
|
## On Activation
|
|
29
31
|
|
|
@@ -31,23 +33,27 @@ engine (never typed by hand); front steps are locked to `human_approve`.
|
|
|
31
33
|
Read `{project-root}/epics/EP-<slug>/.sdlc/state.json` if an epic is named, otherwise check whether one
|
|
32
34
|
exists for the idea.
|
|
33
35
|
|
|
34
|
-
- **
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
`
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
- **Chain already seeded** — `state.json` exists with `currentStep == "epic"`. Skip **Step 3** (the ID
|
|
37
|
+
is already assigned) and **Step 5** (the chain is already there — re-seeding is refused anyway). For
|
|
38
|
+
Step 2, read `analysis.md` when it is there (the analysis ran); when it is not, the chain came from
|
|
39
|
+
`yad epic new` and no analysis exists, so shape the idea inline with the analyst exactly as the
|
|
40
|
+
greenfield branch does.
|
|
41
|
+
- **Nothing seeded** (the default) — no `state.json`. The epic is the entry point: run Steps 2–5
|
|
42
|
+
(inline analyst shaping + ID assignment + seed).
|
|
43
|
+
|
|
44
|
+
**Step 5b runs on both paths.** It is what closes the authoring step and opens its gate, and nothing
|
|
45
|
+
else does it.
|
|
40
46
|
|
|
41
47
|
Either mode runs Step 3b (branch), Step 4 (write the epic), and Step 6 (stop at the gate).
|
|
42
48
|
|
|
43
|
-
**Precondition gate (rail):** if `state.json` already exists (
|
|
49
|
+
**Precondition gate (rail):** if `state.json` already exists (seeded, or a re-entry), run
|
|
44
50
|
`yad next EP-<slug> --check epic` — if it exits non-zero, **STOP** and surface the blocker, pointing the
|
|
45
51
|
user at `yad next EP-<slug>`. When no `state.json` exists yet, this is the greenfield entry point — the
|
|
46
52
|
check is not applicable, so proceed and seed state.
|
|
47
53
|
|
|
48
54
|
### Step 2 — Shape the idea (assist: analyst) — or read the analysis
|
|
49
55
|
- **Analysis skipped:** ask the user for a one-line feature idea if not provided, then adopt the
|
|
50
|
-
**analyst** lens
|
|
56
|
+
**analyst** lens to pressure-test it: who is the user, what problem, what
|
|
51
57
|
signals success, what is out of scope. Keep it brief — this is shaping, not a PRD.
|
|
52
58
|
- **Analysis ran:** read `{project-root}/epics/EP-<slug>/analysis.md` (the analyst's discovery brief)
|
|
53
59
|
and carry its Recommendation / Scope framing forward — do not re-shape from scratch.
|
|
@@ -68,40 +74,86 @@ and let it inform which `repos` the epic should touch.
|
|
|
68
74
|
- For depth on a specific area not in the map, do a live on-demand read (see `yad-connect-repos`
|
|
69
75
|
`references/code-context.md`) — do not block on it.
|
|
70
76
|
|
|
71
|
-
### Step 2c — Read the
|
|
72
|
-
Consume the
|
|
73
|
-
draft or in-review
|
|
74
|
-
|
|
75
|
-
`currentStep == "
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
77
|
+
### Step 2c — Read the Foundation (product context, only once it is APPROVED)
|
|
78
|
+
Consume the Product level (written by `yad-discovery`) **only after its review gate has passed** — never
|
|
79
|
+
a draft or in-review one (that would bypass its gate). Gate on the **state**, not file existence:
|
|
80
|
+
- **The Foundation:** read `{project-root}/foundation/.sdlc/state.json` and proceed **only when
|
|
81
|
+
`currentStep == "foundation-done"`**. Then read `foundation/purpose.md`, `scope.md`, `mvp.md` and
|
|
82
|
+
`roadmap.md` (and `stack.md` / `repos.md` for the technical frame).
|
|
83
|
+
- **The old spelling**, only when there is no Foundation: read
|
|
84
|
+
`{project-root}/epics/EP-discovery/.sdlc/state.json` and proceed **only when
|
|
85
|
+
`currentStep == "discovery-done"`**. Then read its `roadmap.md` and sibling `requirements.md`.
|
|
86
|
+
|
|
87
|
+
Use it for: which phase (MVP / later) this feature belongs to, what the product explicitly is **not**,
|
|
88
|
+
the requirements it carries, and how it fits the wider plan — so the epic's **Goal / Scope / Acceptance
|
|
89
|
+
signals** stay consistent with the approved product. **Optional & non-blocking:** if there is no product
|
|
90
|
+
level, or it has not passed its gate yet (absent / still draft / in-review), proceed unchanged — do not
|
|
91
|
+
consume an unapproved one. (`yad next` reports feature work that goes ahead of an unapproved Foundation;
|
|
92
|
+
it never blocks it.) Prefer the roadmap row's **proposed epic id** when you assign the id (Step 3), so
|
|
93
|
+
the feature and its epic stay linked. **Do not edit the roadmap row's `Status` after seeding** (the
|
|
94
|
+
Foundation never auto-seeds epics, and nothing needs the row changed): the roadmap table is part of what
|
|
95
|
+
the Foundation's reviewers approved, so the edit makes `yad doctor` report their approvals as stale.
|
|
96
|
+
`yad foundation status` reads how far each feature has got from the epic ledgers instead.
|
|
82
97
|
|
|
83
98
|
### Step 3 — Generate the Epic ID (engine-assigned, never by hand) — analysis-skipped only
|
|
84
|
-
*(Skip when
|
|
99
|
+
*(Skip when `state.json` already exists — the ID was assigned by whatever seeded the chain.)*
|
|
85
100
|
Derive `EP-<slug>` where `slug` is **2–4 lowercase words joined by hyphens**, drawn from the idea
|
|
86
|
-
(e.g. `EP-checkout`). Lowercase except the fixed `EP` prefix. `EP-discovery`
|
|
87
|
-
for the
|
|
101
|
+
(e.g. `EP-checkout`). Lowercase except the fixed `EP` prefix. `EP-foundation` and `EP-discovery` are
|
|
102
|
+
**reserved** for the Product level — never use either for a feature. **The ID is assigned once and
|
|
88
103
|
never renamed** — renaming breaks every downstream link (build plan §6b).
|
|
89
104
|
Check `{project-root}/epics/` for collisions; if the slug exists, append a distinguishing word.
|
|
90
105
|
|
|
91
106
|
### Step 3b — Open the authoring branch
|
|
92
107
|
Open the epic authoring branch `epic/EP-<slug>` per the shared procedure
|
|
93
108
|
(`references/state-schema.md` → "Authoring branches"): git-safe (skip with a note if `{project-root}`
|
|
94
|
-
is not a git work tree), check out the branch if it exists, else create it from the
|
|
95
|
-
branch. Author and commit `epic.md` on it. This is **distinct** from the
|
|
109
|
+
is not a git work tree), check out the branch if it exists, else create it from the Product's default
|
|
110
|
+
branch. Author and commit `epic.md` on it. This is **distinct** from the verified ledger's `review/…` branch.
|
|
96
111
|
|
|
97
112
|
### Step 4 — Write the epic (assist: pm)
|
|
98
|
-
Adopt the **pm** lens
|
|
99
|
-
using EXACTLY this template (build plan §6b)
|
|
113
|
+
Adopt the **pm** lens and write `{project-root}/epics/EP-<slug>/epic.md`
|
|
114
|
+
using EXACTLY this template (build plan §6b).
|
|
115
|
+
|
|
116
|
+
**Five of these keys are read by machines, so write them BARE — no trailing `#` comment.** The
|
|
117
|
+
frontmatter readers (`readFrontmatter` in the CLI, `fm_val` in the check gates) keep the whole rest of
|
|
118
|
+
the line, so a comment becomes part of the value and the gates stop recognising it:
|
|
119
|
+
|
|
120
|
+
- `title` is the epic's **one-line name** — the name a list of work items shows for it (E111; it is carried in `.sdlc/index.json`). Plain words,
|
|
121
|
+
such as `Checkout from the mobile app`, on ONE line. Quotes are optional: a title quoted the YAML way
|
|
122
|
+
(`"…"` or `'…'`) is read without them. If the title begins with `[` and ends with `]` (such as
|
|
123
|
+
`[Mobile] Checkout [v2]`), wrap it in double quotes, writing an inner `"` as `\"` — otherwise it is
|
|
124
|
+
read as a list, which is not a title. The full rules are the `title` row of the frontmatter table in
|
|
125
|
+
`references/state-schema.md`. Never end it with a `#` comment (the comment becomes part of the title), and never use a YAML
|
|
126
|
+
block (`>` or `|`): only one line is read. Set it NOW, for the same reason as the theme below: the epic review gate is bound to a hash of
|
|
127
|
+
the file, so a title added or reworded after that gate is approved drops the approval as stale. An
|
|
128
|
+
epic with no title is shown by its id.
|
|
129
|
+
- `kind` and `type` are the **work-item type**, and both carry the same value. `kind:` is the name
|
|
130
|
+
every reader still uses; `type:` is the name from shape 5 on. Write both. Use `feature` for new
|
|
131
|
+
value, or `chore` for upkeep with no user-visible change — those are the two types allowed to stand
|
|
132
|
+
alone with no `parent:`. Everything else (`change`, `defect`, `hotfix`) is authored by `yad-change`.
|
|
133
|
+
- `thread` is the thread id. A genesis epic is the root of its own thread, so `thread == id` and there
|
|
134
|
+
is no `parent:`.
|
|
135
|
+
- `theme` is an optional **grouping tag**: one word or short phrase shared by every epic that belongs
|
|
136
|
+
together, such as `checkout-revamp`. It is what this method has instead of a rung above the Epic —
|
|
137
|
+
the ladder stays Product → Epic → Story → Task, and grouping is a label. Nothing has to be
|
|
138
|
+
registered first and no list of allowed themes exists. Ask the user whether this epic belongs to a
|
|
139
|
+
group; if one already exists, **copy its spelling exactly** (`yad doctor` reports a theme spelled
|
|
140
|
+
two ways, because two spellings group as two themes). Leave the key empty when there is no group.
|
|
141
|
+
Write ONE tag, never a list — `theme: [a, b]` is read as no theme at all — and never write a `#`:
|
|
142
|
+
`yad next` and `yad thread` PRINT the tag as `#checkout-revamp`, but the `#` is decoration on the
|
|
143
|
+
screen, and anything from a `#` onward is kept as part of the value, so the epic then groups only
|
|
144
|
+
with epics carrying that exact text. Any language is fine. Set it NOW, while the epic
|
|
145
|
+
is being written: the epic review gate is bound to a hash of the file (all of it except the `status:` line), so adding a theme after
|
|
146
|
+
that gate is approved drops the approval as stale and the step has to be approved again.
|
|
100
147
|
|
|
101
148
|
```markdown
|
|
102
149
|
---
|
|
103
150
|
id: EP-<slug>
|
|
151
|
+
title: <one line: what this epic delivers>
|
|
104
152
|
status: draft
|
|
153
|
+
kind: feature
|
|
154
|
+
type: feature
|
|
155
|
+
thread: EP-<slug>
|
|
156
|
+
theme:
|
|
105
157
|
owner:
|
|
106
158
|
technical_product_owner:
|
|
107
159
|
repos: [backend, mobile, dashboard]
|
|
@@ -118,90 +170,116 @@ code-context: { repos: [], loaded: <YYYY-MM-DD or none> } # which code-maps in
|
|
|
118
170
|
```
|
|
119
171
|
|
|
120
172
|
Fill the body with the user; leave `owner` / `technical_product_owner` for the user to set. Set
|
|
121
|
-
`repos` to the repos this epic will touch.
|
|
122
|
-
|
|
123
|
-
### Step 5 — Seed the state machine —
|
|
124
|
-
*(Skip when
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
"createdAt": "<YYYY-MM-DD>",
|
|
134
|
-
"currentStep": "epic-review",
|
|
135
|
-
"steps": [
|
|
136
|
-
{ "id": "epic", "type": "author", "artifact": "epic.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "done", "risk_tags": [] },
|
|
137
|
-
{ "id": "epic-review", "type": "review+approve", "artifact": "epic.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "in_review", "risk_tags": [] },
|
|
138
|
-
{ "id": "architecture", "type": "author", "artifact": "architecture.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
|
|
139
|
-
{ "id": "architecture-review","type": "review+approve", "artifact": "architecture.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": ["contract"] },
|
|
140
|
-
{ "id": "ui-design", "type": "author", "artifact": "ui-design.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
|
|
141
|
-
{ "id": "ui-design-review", "type": "review+approve", "artifact": "ui-design.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
|
|
142
|
-
{ "id": "stories", "type": "author", "artifact": "stories/", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
|
|
143
|
-
{ "id": "stories-review", "type": "review+approve", "artifact": "stories/", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
|
|
144
|
-
{ "id": "test-cases", "type": "author", "artifact": "test-cases.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
|
|
145
|
-
{ "id": "test-cases-review", "type": "review+approve", "artifact": "test-cases.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] }
|
|
146
|
-
]
|
|
147
|
-
}
|
|
173
|
+
`repos` to the repos this epic will touch, and `theme` only if the user names a group.
|
|
174
|
+
|
|
175
|
+
### Step 5 — Seed the state machine — only when nothing is seeded
|
|
176
|
+
*(Skip when `state.json` already exists — `yad-analysis` seeded the 12-step chain, or `yad epic new`
|
|
177
|
+
seeded the 10-step one. Go to Step 5b.)*
|
|
178
|
+
|
|
179
|
+
**Run the engine. Do not hand-write the chain.**
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
yad epic new EP-<slug> # after Step 4: the type comes from epic.md
|
|
183
|
+
yad epic new EP-<slug> --type chore # only when there is no epic.md yet
|
|
184
|
+
yad epic new EP-<slug> --profile chore # the short upkeep lane — see below
|
|
148
185
|
```
|
|
149
186
|
|
|
187
|
+
That writes `{project-root}/epics/EP-<slug>/.sdlc/state.json`, the empty `approvals.json` and
|
|
188
|
+
`comments.json`, and the `reviews/` directory. Without `--profile` the chain is the full **10-step**
|
|
189
|
+
`classic` route (no analysis). Every step is `advance: human` and locked; `epic` is open and the rest
|
|
190
|
+
are blocked. The chain comes from the step catalogue and the lifecycle profile in the engine
|
|
191
|
+
(`references/state-schema.md`), so there is one definition of it and no copy here to drift from it.
|
|
192
|
+
|
|
193
|
+
**Ask which lane this work belongs on before you run it.** `classic` is the default and the right
|
|
194
|
+
answer for a feature. For upkeep somebody has already decided on — a dependency bump, a CI move —
|
|
195
|
+
`--profile chore` seeds a **4-step** lane instead: `epic → epic-review → stories → stories-review`,
|
|
196
|
+
with no architecture, UI-design or test-case steps. `--profile spike` is the same lane with the
|
|
197
|
+
analyst's brief in front, for a timeboxed question (start that one from `yad-analysis`, which owns the
|
|
198
|
+
first step). Both are described in `references/state-schema.md`.
|
|
199
|
+
|
|
200
|
+
A short lane has **no architecture gate, so no `contract.md` and no lock**, and no step on it is
|
|
201
|
+
optional — `yad skip` is refused. **Choose the route before you seed, because the choice is final:**
|
|
202
|
+
`yad epic new` refuses an epic that already has a `state.json` and there is no re-seed flag. If the
|
|
203
|
+
work turns out to move the shared cross-repo surface, the short-lane epic records the finding and the
|
|
204
|
+
surface change belongs to a NEW epic on `classic` — say that rather than trying to widen this one. The
|
|
205
|
+
work-item type is a separate choice: `--type chore --profile classic` is right for large upkeep that
|
|
206
|
+
does touch the contract.
|
|
207
|
+
|
|
208
|
+
It writes no `epic.md`, no branch and no commit, and it refuses an epic that already has a
|
|
209
|
+
`state.json`. Run it **after** Step 4 when `epic.md` exists, and it reads the type from that header —
|
|
210
|
+
then `--type` is unnecessary and a contradicting one is refused.
|
|
211
|
+
|
|
150
212
|
Notes:
|
|
151
|
-
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
213
|
+
- **Then advance the authoring step.** The seed leaves `epic` open, which is truthful: the command runs
|
|
214
|
+
before the artifact exists. Closing it is Step 5b's job, and on the local path `yad gate open` does it
|
|
215
|
+
— so after writing `epic.md`, take Step 5b.
|
|
216
|
+
- `architecture-review` carries `risk_tags: ["contract"]` by default (build plan §4): the tag raises
|
|
217
|
+
the step's full approver count to 3 (base 1 + contract risk 2). Only the base holds the
|
|
218
|
+
gate; the risk step is advisory, reported as a shortfall against the count capped at the
|
|
219
|
+
active people less one (E72). The catalogue sets it;
|
|
220
|
+
there is nothing to type.
|
|
221
|
+
- `test-cases` / `test-cases-review` are a **parallel, non-blocking track**: they seed `todo` and open
|
|
222
|
+
when `stories-review` passes — at which point the epic is already `ready-for-build`, so Build
|
|
155
223
|
runs alongside the tester. They never gate `ready-for-build` (see `references/state-schema.md`).
|
|
156
|
-
- Commit the seed on this step's authoring branch. It reaches the
|
|
224
|
+
- Commit the seed on this step's authoring branch. It reaches the Product's default branch through the
|
|
157
225
|
epic's **first** review PR/MR — cut `review/EP-<slug>/epic` from the authoring branch so it carries
|
|
158
|
-
the seed. In
|
|
226
|
+
the seed. In verified mode `ledger-guard` exempts a new epic's ledger (creation, not mutation, #162);
|
|
159
227
|
every later change to it is CI's. See `references/state-schema.md`, "Authoring branches".
|
|
160
|
-
-
|
|
161
|
-
and an empty comments ledger `{project-root}/epics/EP-<slug>/.sdlc/comments.json`, each containing
|
|
162
|
-
`[]`, and the `reviews/` directory. (`comments.json` is the machine-readable counterpart to the
|
|
163
|
-
`reviews/*--comments.md` markdown — `yad-review-gate` appends to it on every `comment`.)
|
|
164
|
-
- **No UI?** Seed the chain **as-is** (always include the two `ui-design` steps). If this epic has no
|
|
228
|
+
- **No UI?** Seed the chain **as-is** (the two `ui-design` steps are always in it). If this epic has no
|
|
165
229
|
user-facing surface (a backend/API service, data pipeline, infra), the `ui-design` step is optional
|
|
166
230
|
and can be marked N/A now with `yad skip EP-<slug> ui-design --reason "<why>"` — it stays visible,
|
|
167
231
|
short-circuits its gate, and advances straight to `stories` when architecture is approved. It is
|
|
168
|
-
reversible with
|
|
232
|
+
reversible with `yad unskip EP-<slug> ui-design` until the stories review opens. **On a verified Product, now is the only time:** once this epic's first review PR merges, CI owns `state.json` and `yad skip` refuses. Don't hand-edit the chain to drop the steps;
|
|
169
233
|
the skip is the single, auditable mechanism (see `references/state-schema.md` → "ui-design is optional").
|
|
170
234
|
|
|
171
|
-
### Step 5b —
|
|
172
|
-
*(
|
|
235
|
+
### Step 5b — Open the epic's review gate
|
|
236
|
+
*(**Always run this**, on both entry modes. The chain is seeded by now either way — by `yad-analysis`,
|
|
237
|
+
by `yad epic new` in Step 5, or by `yad epic new` before this skill was invoked — and `epic.md` is
|
|
238
|
+
written. This is the step that closes the authoring step and opens its gate.)*
|
|
173
239
|
**Check the mode first — the two modes have opposite instructions here.** Read `.sdlc/hub.json`:
|
|
174
|
-
**
|
|
240
|
+
**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.
|
|
175
241
|
|
|
176
|
-
**
|
|
177
|
-
any non-bot commit touching `epics/*/.sdlc/{state,approvals,comments,hub-prs}.json` or
|
|
242
|
+
**verified mode — do NOT write `state.json`.** The ledger is CI-owned: the `ledger-guard` check rejects
|
|
243
|
+
any non-bot commit touching `epics/*/.sdlc/{state,approvals,comments,product-prs,hub-prs}.json` or
|
|
178
244
|
`epics/*/reviews/*.md`, `yad gate open` deliberately skips this write for the same reason, and
|
|
179
245
|
`yad gate ci --merged` performs the whole transition when the review PR merges. Making the edit here
|
|
180
246
|
fails the gate if it rides the review PR, and desynchronises the ledger CI is about to rewrite if it
|
|
181
|
-
is pushed around the gate.
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
>
|
|
194
|
-
>
|
|
195
|
-
>
|
|
196
|
-
>
|
|
197
|
-
|
|
247
|
+
is pushed around the gate.
|
|
248
|
+
|
|
249
|
+
**Do not EDIT the ledger — but do COMMIT it when it is untracked.** Those are two different acts and
|
|
250
|
+
the guard treats them differently. Commit `epic.md`, and also `.sdlc/state.json`, `.sdlc/approvals.json`
|
|
251
|
+
and `.sdlc/comments.json` when `git status` shows them **untracked** — that is the case after
|
|
252
|
+
`yad epic new`, whose seed has never been reviewed and so rides this epic's first review PR exactly as
|
|
253
|
+
a Step 5 seed does. Leave their contents exactly as they are. When `git status` shows them tracked and
|
|
254
|
+
unmodified (the `yad-analysis` path), commit `epic.md` alone. Then hand off to `yad-review-gate`.
|
|
255
|
+
|
|
256
|
+
> **The Step 5 seed exemption may or may not still apply — read the base ref, not the calendar.**
|
|
257
|
+
> `ledger-guard` exempts an epic whose ledger is absent from the BASE ref: that is creation, not
|
|
258
|
+
> mutation (#162). After `yad-analysis` the ledger reached the base ref through the analysis review,
|
|
259
|
+
> so the exemption is spent and the guard is absolute. After `yad epic new` the ledger has never been
|
|
260
|
+
> reviewed, so it is still off the base ref and the seed rides this epic's first review PR exactly as
|
|
261
|
+
> in Step 5. Either way the instruction above is the safe one: in verified mode, do not write
|
|
262
|
+
> `state.json` here. Advancing a step is a mutation on any path, and CI performs it at merge.
|
|
263
|
+
|
|
264
|
+
**Otherwise — local, or a platform with no gate-sync CI — the engine makes this edit, not you.**
|
|
265
|
+
`yad gate open <epic> epic.md` marks `epic-review` `in_review`, closes `epic` as `done`, and moves
|
|
266
|
+
`currentStep` to the gate — the same transition, from the one function that owns it (`markInReview`, `cli/epic-state.mjs`).
|
|
267
|
+
`yad-review-gate action: open` runs that command; hand off to it rather than editing the ledger here.
|
|
268
|
+
|
|
269
|
+
**With no platform configured** it writes the ledger and simply opens no PR, so this works offline.
|
|
270
|
+
**With a platform** the `review/EP-<slug>/epic` branch must already be **on origin** — the command refuses
|
|
271
|
+
and writes nothing otherwise. Cut it from the authoring branch and push it before handing off
|
|
272
|
+
(`yad open-pr` does both, then delegates).
|
|
273
|
+
|
|
274
|
+
Do **not** hand-edit `state.json`, do **not** re-seed, and do **not** touch `approvals.json` — only real
|
|
275
|
+
reviewers approve, through the gate.
|
|
198
276
|
|
|
199
277
|
### Step 6 — Stop at the gate (do NOT advance)
|
|
200
278
|
Report: epic ID, the path to `epic.md`, and that the next action is **review** via
|
|
201
279
|
`yad-review-gate`. **Never mark the epic-review step approved here** — only real reviewers do that
|
|
202
|
-
through the gate.
|
|
203
|
-
PR on the
|
|
204
|
-
comments into the ledger; otherwise the review is recorded
|
|
280
|
+
through the gate. Shape steps do not auto-advance. When the Product has a platform, the gate opens a review
|
|
281
|
+
PR on the Product (via `yad-hub-bridge`) and `yad-review-gate action: sync` pulls platform approvals/
|
|
282
|
+
comments into the ledger; otherwise the review is recorded local.
|
|
205
283
|
|
|
206
284
|
## Reference
|
|
207
285
|
- State schema and field meanings: `references/state-schema.md`.
|