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
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: yad-analysis
|
|
3
|
-
description: 'Optional
|
|
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
|
|
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 **
|
|
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);
|
|
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
|
|
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):**
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
|
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
|
|
54
|
-
Consume the
|
|
55
|
-
draft or in-review
|
|
56
|
-
|
|
57
|
-
`currentStep == "
|
|
58
|
-
for the
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
`discovery-done
|
|
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`
|
|
66
|
-
for the
|
|
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
|
-
(
|
|
73
|
-
is not a git work tree), check out the branch if it exists, else create it from the
|
|
74
|
-
branch. Author and commit `analysis.md` on it. This is **distinct** from the
|
|
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
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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
|
-
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
- `
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
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
|
|
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:
|
|
150
|
-
here** — only real reviewers do that through the gate.
|
|
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
|
-
|
|
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
|
|
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: '
|
|
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 (
|
|
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 **
|
|
11
|
-
When both artifacts are drafted, control passes to `yad-review-gate
|
|
12
|
-
|
|
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;
|
|
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
|
|
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
|
-
|
|
40
|
-
This is **distinct** from the
|
|
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
|
|
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
|
-
**
|
|
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
|
-
**
|
|
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 —
|
|
193
|
-
`architecture.
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
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`.
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
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
|
|
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
|
|
4
|
-
surface** of an epic.
|
|
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"]
|
|
66
|
-
|
|
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
|
|
74
|
-
|
|
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
|
|
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 `
|
|
70
|
-
as `yad-review-gate` (
|
|
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
|
|
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
|
|
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
|
-
- **
|
|
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
|
|
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:
|
|
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
|
|