yadflow 4.0.0-next.3 → 4.0.0
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 +699 -0
- package/README.md +85 -22
- package/bin/commands.mjs +3 -1
- package/bin/yad.mjs +183 -29
- package/cli/capture.mjs +4 -2
- package/cli/checkpoint.mjs +10 -10
- package/cli/claims.mjs +4 -4
- package/cli/commit.mjs +48 -12
- package/cli/docs.mjs +15 -13
- package/cli/doctor.mjs +557 -141
- package/cli/epic-state.mjs +41 -18
- package/cli/errors.mjs +3 -2
- package/cli/find-product.mjs +197 -0
- package/cli/fold.mjs +4 -4
- package/cli/gate-local.mjs +13 -13
- package/cli/gate.mjs +111 -103
- package/cli/history.mjs +13 -13
- package/cli/hook.mjs +201 -30
- package/cli/index-command.mjs +6 -6
- package/cli/lib.mjs +91 -29
- package/cli/manifest.mjs +171 -104
- package/cli/migrate.mjs +208 -17
- package/cli/mode.mjs +22 -22
- package/cli/next.mjs +6 -6
- package/cli/openpr.mjs +32 -24
- package/cli/people.mjs +22 -10
- package/cli/plan.mjs +718 -45
- package/cli/platform.mjs +13 -7
- package/cli/product-index.mjs +4 -4
- package/cli/{hubcommit.mjs → productcommit.mjs} +11 -7
- package/cli/protection.mjs +19 -9
- package/cli/reconcile.mjs +98 -23
- package/cli/repo-publish.mjs +22 -16
- package/cli/repo.mjs +128 -33
- package/cli/report.mjs +4 -2
- package/cli/review.mjs +26 -19
- package/cli/setup.mjs +105 -36
- package/cli/ship.mjs +1 -1
- package/cli/skip.mjs +4 -4
- package/cli/tidy.mjs +7 -7
- package/cli/update-commit.mjs +22 -19
- package/cli/workspace.mjs +495 -0
- package/package.json +7 -4
- package/skills/sdlc/config.yaml +14 -13
- package/skills/sdlc/module-help.csv +8 -8
- package/skills/yad-analysis/SKILL.md +6 -4
- package/skills/yad-architecture/SKILL.md +4 -3
- package/skills/yad-backfill/SKILL.md +11 -5
- package/skills/yad-backfill/references/backfill.md +33 -3
- package/skills/yad-backfill/templates/checks/backfill-check.sh +200 -17
- package/skills/yad-change/SKILL.md +1 -1
- package/skills/yad-checks/SKILL.md +48 -27
- package/skills/yad-checks/references/check-gates.md +213 -53
- package/skills/yad-checks/templates/checks/commit-message.sh +39 -13
- package/skills/yad-checks/templates/checks/contract-check.sh +472 -23
- package/skills/yad-checks/templates/checks/epic-open.sh +398 -8
- package/skills/yad-checks/templates/checks/ledger-guard.sh +75 -25
- package/skills/yad-checks/templates/checks/lineage-check.sh +391 -7
- package/skills/yad-checks/templates/checks/product-checkout.sh +141 -0
- package/skills/yad-checks/templates/checks/reconcile-debt-check.sh +399 -8
- package/skills/yad-checks/templates/checks/risk-map-check.sh +35 -3
- package/skills/yad-checks/templates/checks/spec-link.sh +36 -3
- package/skills/yad-checks/templates/checks/verified-commits.sh +26 -2
- package/skills/yad-checks/templates/github/yad-checks.yml +33 -13
- package/skills/yad-checks/templates/github/{yad-hub-checks.yml → yad-product-checks.yml} +14 -10
- package/skills/yad-checks/templates/github/yad-update-guard.yml +1 -1
- package/skills/yad-checks/templates/github/yad-verified-commits.yml +1 -1
- package/skills/yad-checks/templates/gitlab/yad-checks.gitlab-ci.yml +12 -0
- package/skills/yad-checks/templates/gitlab/{yad-hub-checks.gitlab-ci.yml → yad-product-checks.gitlab-ci.yml} +16 -16
- package/skills/yad-checks/templates/gitlab/yad-verified-commits.gitlab-ci.yml +2 -2
- package/skills/yad-checks/templates/hooks/ledger-guard-cursor.mjs +130 -0
- package/skills/yad-checks/templates/hooks/ledger-guard.mjs +117 -0
- package/skills/yad-checks/templates/hooks/yad-capture.mjs +117 -0
- package/skills/yad-commit/SKILL.md +18 -7
- package/skills/yad-connect-design/SKILL.md +1 -1
- package/skills/yad-connect-design/references/design-registry.md +1 -1
- package/skills/yad-connect-docs/SKILL.md +16 -11
- package/skills/yad-connect-docs/references/docs-registry.md +8 -8
- package/skills/yad-connect-learning/SKILL.md +1 -1
- package/skills/yad-connect-learning/references/learning-registry.md +1 -1
- package/skills/yad-connect-repos/SKILL.md +31 -8
- package/skills/yad-connect-repos/references/code-context.md +1 -1
- package/skills/yad-connect-repos/references/{hub-config.md → product-config.md} +19 -11
- package/skills/yad-connect-repos/references/repos-registry.md +1 -1
- package/skills/yad-connect-testing/SKILL.md +1 -1
- package/skills/yad-connect-testing/references/testing-registry.md +1 -1
- package/skills/yad-discovery/SKILL.md +2 -2
- package/skills/yad-discovery/references/discovery-schema.md +1 -1
- package/skills/yad-docs/SKILL.md +1 -1
- package/skills/yad-docs/references/data-mapping.md +1 -1
- package/skills/yad-docs/templates/app/package-lock.json +8 -8
- package/skills/yad-docs/templates/app/package.json +1 -1
- package/skills/yad-docs/templates/app/src/components/Canvas/FlowCanvas.tsx +2 -2
- package/skills/yad-docs-overview/references/pipeline-model.md +3 -3
- package/skills/yad-engineer-review/SKILL.md +2 -2
- package/skills/yad-engineer-review/references/ship-and-record.md +3 -3
- package/skills/yad-epic/SKILL.md +6 -4
- package/skills/yad-epic/references/state-schema.md +13 -12
- package/skills/yad-open-pr/SKILL.md +1 -1
- package/skills/yad-pair-review/SKILL.md +5 -5
- package/skills/yad-pair-review/references/session-state.md +2 -2
- package/skills/yad-pr-template/SKILL.md +14 -12
- package/skills/yad-pr-template/templates/checks/pr-template.sh +18 -16
- package/skills/yad-pr-template/templates/checks/pr-title.sh +15 -13
- package/skills/yad-pr-template/templates/{hub → product}/github/pull_request_template.md +2 -2
- package/skills/yad-pr-template/templates/{hub → product}/gitlab/merge_request_templates/Default.md +2 -2
- package/skills/{yad-hub-bridge → yad-product-bridge}/SKILL.md +15 -15
- package/skills/{yad-hub-bridge → yad-product-bridge}/references/bridge.md +15 -10
- package/skills/{yad-hub-bridge → yad-product-bridge}/references/login-roster.md +2 -2
- package/skills/{yad-hub-bridge/templates/checks/hub-route.sh → yad-product-bridge/templates/checks/product-route.sh} +2 -2
- package/skills/{yad-hub-bridge → yad-product-bridge}/templates/github/yad-gate-sync.yml +29 -16
- package/skills/{yad-hub-bridge → yad-product-bridge}/templates/gitlab/gitlab-ci.include-root.yml +1 -1
- package/skills/{yad-hub-bridge → yad-product-bridge}/templates/gitlab/yad-gate-sync.gitlab-ci.yml +5 -3
- package/skills/yad-report/SKILL.md +1 -1
- package/skills/yad-review-companion/SKILL.md +3 -3
- package/skills/yad-review-gate/SKILL.md +22 -23
- package/skills/yad-review-gate/references/gating.md +13 -13
- package/skills/yad-run/SKILL.md +2 -2
- package/skills/yad-run/references/run-loop.md +2 -2
- package/skills/yad-spec/SKILL.md +2 -1
- package/skills/yad-spec/references/spec-handoff.md +19 -10
- package/skills/yad-stories/SKILL.md +2 -2
- package/skills/yad-sync-repos/SKILL.md +19 -3
- package/skills/yad-test-cases/SKILL.md +2 -2
- package/skills/yad-ui/SKILL.md +2 -2
- package/skills/yad-checks/templates/hooks/ledger-guard-cursor.sh +0 -91
- package/skills/yad-checks/templates/hooks/ledger-guard.sh +0 -100
- package/skills/yad-checks/templates/hooks/yad-capture.sh +0 -53
|
@@ -7,9 +7,17 @@ no roles, no commit emails (E62). It is a single object for the Product itself
|
|
|
7
7
|
|
|
8
8
|
## Location
|
|
9
9
|
|
|
10
|
-
`{project-root}/.sdlc/hub.json`
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
`{project-root}/.sdlc/product.json`, written together with its older name `{project-root}/.sdlc/hub.json`
|
|
11
|
+
(E122). Read `product.json` first; read `hub.json` only on an older Product that has only that name.
|
|
12
|
+
Every save writes both names with the same bytes, until v5 deletes `hub.json` (check gates an older
|
|
13
|
+
yadflow installed read `hub.json` by path). If both exist and their bytes differ, every yad command but
|
|
14
|
+
`yad doctor`, `yad migrate` and `yad report` refuses with `YAD-STATE-008`, and the CI gates FAIL;
|
|
15
|
+
`yad migrate --apply` (or `--apply --keep product` / `--keep hub`) chooses the copy to keep. To edit a
|
|
16
|
+
setting by hand, edit `product.json`, then run `yad migrate --apply --keep product` (it copies it over
|
|
17
|
+
`hub.json`). A Product that has only `hub.json` has not been migrated: edit `hub.json`, and never create a
|
|
18
|
+
`product.json` beside it by hand — `--keep product` would copy that one file over every other setting.
|
|
19
|
+
|
|
20
|
+
(`config.yaml` `product.config` (older projects: `hub.config`).) Created/updated by `yad-connect-repos action: detect-product` (older name: `detect-hub`).
|
|
13
21
|
|
|
14
22
|
## Schema
|
|
15
23
|
|
|
@@ -27,7 +35,7 @@ no roles, no commit emails (E62). It is a single object for the Product itself
|
|
|
27
35
|
"solo": false, // SOLO MODE, and the one that decides: true waives the approval requirement on every review gate (the merge + resolved threads still gate). Set by `yad setup --solo` / `--team <n>` or `yad mode`
|
|
28
36
|
"mode": "team", // the roadmap's name for the same switch (E10): "solo" | "team", written beside `solo` by `yad mode` and `yad setup`. NOT read by the gates this major — `yad doctor` warns `mode:disagree` when it contradicts `solo`. Not the ledger switch: "verified mode" elsewhere means `ledger`
|
|
29
37
|
"mode_set": { "from": "solo", "to": "team", "by": "al", "date": "2026-09-15", "reason": null }, // the last change of mode (E10): who, when, why. `yad mode solo` requires the reason
|
|
30
|
-
"detectedAt": "2026-06-08" // last detect-
|
|
38
|
+
"detectedAt": "2026-06-08" // last detect-product run (YYYY-MM-DD)
|
|
31
39
|
}
|
|
32
40
|
```
|
|
33
41
|
|
|
@@ -54,19 +62,19 @@ deletes them (`yad migrate`'s shape-3 step still adds a `product` role key besid
|
|
|
54
62
|
an older project upgrades the same way it always did). `verified_authors` decides nothing — only `yad doctor`
|
|
55
63
|
reads it, to warn. The roster is read for one thing only: its `name` →
|
|
56
64
|
`login` pairs let a gate write record the login on older approval and comment records
|
|
57
|
-
(`../../yad-
|
|
65
|
+
(`../../yad-product-bridge/references/login-roster.md` → "Recording the login on older records"). `yad doctor`
|
|
58
66
|
warns `people:roster-unused` and `people:verified-authors-unused` so nobody edits them believing they decide
|
|
59
67
|
something. Delete `verified_authors` when convenient; delete `roster` when `people:roster-unused` says it
|
|
60
|
-
can go — no older record needs it any more, or only records it cannot place are left and their reviews are
|
|
68
|
+
can go (edit the settings as the rule at the top of this page says) — no older record needs it any more, or only records it cannot place are left and their reviews are
|
|
61
69
|
closed.
|
|
62
70
|
|
|
63
71
|
## Detection
|
|
64
72
|
|
|
65
|
-
`detect-
|
|
73
|
+
`detect-product` reuses the same host-detection logic this skill already applies to code repos:
|
|
66
74
|
run `git remote get-url origin` **on the Product itself** and read the host —
|
|
67
75
|
`github.com` → `github`, `gitlab.com`/self-hosted GitLab → `gitlab`, no remote → `platform: null`.
|
|
68
76
|
Auth is the **local user's own** `gh`/`glab`/git credentials; **no tokens are ever stored** (same rule
|
|
69
|
-
as the registry). `detect-
|
|
77
|
+
as the registry). `detect-product` upserts the file in place: it writes `product.json`, then copies it byte for byte to `hub.json` (`cp`) — idempotent and safe to re-run.
|
|
70
78
|
|
|
71
79
|
**`git_url` is required whenever `platform` is non-null.** `yad doctor` uses it to scope the auth
|
|
72
80
|
probe to the Product's own host (an unscoped `glab auth status` fails on any unrelated broken instance),
|
|
@@ -90,7 +98,7 @@ Keep all three in step.
|
|
|
90
98
|
review opens a PR/MR on the Product and `yad-review-gate action: sync` pulls platform state into the ledger.
|
|
91
99
|
- `ledger: "local"`, `platform: null`, or no/unauthenticated CLI → the gate falls back to the
|
|
92
100
|
existing **local** flow with no error. The file ledger is the source of truth in both modes.
|
|
93
|
-
- The master switch `config.yaml` `product.bridge: false` (older projects: `hub.bridge`) disables the verified ledger globally regardless of `
|
|
101
|
+
- The master switch `config.yaml` `product.bridge: false` (older projects: `hub.bridge`) disables the verified ledger globally regardless of `product.json`.
|
|
94
102
|
|
|
95
103
|
## Review Companion engagement (`review.requireEngagement`)
|
|
96
104
|
|
|
@@ -103,12 +111,12 @@ read the artifact. Applies to both the Shape gate and the Build engineer review.
|
|
|
103
111
|
|
|
104
112
|
## Git tracking
|
|
105
113
|
|
|
106
|
-
Commit `hub.json` — it is small, reviewable, and carries no secrets or tokens. The only people data in it is the login or git name in `mode_set.by`, plus
|
|
114
|
+
Commit `product.json` and `hub.json` together — it is small, reviewable, and carries no secrets or tokens. The only people data in it is the login or git name in `mode_set.by`, plus
|
|
107
115
|
whatever an older `roster` still lists.
|
|
108
116
|
This mirrors how `repos.json` and the per-epic `.sdlc/` state are committed.
|
|
109
117
|
|
|
110
118
|
## Greenfield
|
|
111
119
|
|
|
112
|
-
A brand-new Product has no `hub.json
|
|
120
|
+
A brand-new Product has no `product.json` (and no `hub.json`). That is valid — the Shape gate runs local until `detect-product`
|
|
113
121
|
records a platform. The verified ledger is purely additive; nothing about authoring or the gate predicate changes.
|
|
114
122
|
```
|
|
@@ -54,7 +54,7 @@ not under any `epics/EP-<slug>/.sdlc/`.
|
|
|
54
54
|
Commit the **registry** (`repos.json`) and each repo's **`code-map.md`** — they are small, reviewable,
|
|
55
55
|
and are what the Shape phases actually read (a diff on a code-map shows when a repo's surface moved).
|
|
56
56
|
`yad repo refresh --push` commits and pushes exactly these (never `pack.md`) to the Product's default
|
|
57
|
-
branch as one `chore(
|
|
57
|
+
branch as one `chore(product): sync code-context … [skip ci]` audit commit.
|
|
58
58
|
**Ignore** the full Repomix `pack.md` — it is large and regenerable (`action: refresh`). The Product
|
|
59
59
|
's `.gitignore` carries `.sdlc/code-context/*/pack.md` for this. This mirrors how the per-epic
|
|
60
60
|
`.sdlc/` state (state.json, approvals.json, build-log.json) is committed.
|
|
@@ -26,7 +26,7 @@ connected, `yad-test-cases` runs artifacts-only exactly as before.
|
|
|
26
26
|
same shape as the design tool's MCP, not Repomix's `npx`. The skill detects the MCP and degrades when
|
|
27
27
|
it is absent; it never installs an MCP server.
|
|
28
28
|
- Registry: `{project-root}/.sdlc/testing.json` (project-wide, shared across all epics — NOT per-epic),
|
|
29
|
-
the sibling of `.sdlc/repos.json`, `.sdlc/
|
|
29
|
+
the sibling of `.sdlc/repos.json`, `.sdlc/product.json`, and `.sdlc/design.json`.
|
|
30
30
|
- Per-epic test→suite links are written later by `yad-test-cases`
|
|
31
31
|
(`epics/EP-<slug>/.sdlc/test-links.json`), not here.
|
|
32
32
|
- Speak in the `communication_language` set in `{project-root}/.sdlc/config.yaml`; write documents in `document_output_language`.
|
|
@@ -46,7 +46,7 @@ root, not under any `epics/EP-<slug>/.sdlc/`.
|
|
|
46
46
|
## Git tracking
|
|
47
47
|
|
|
48
48
|
Commit the **registry** (`testing.json`) — it is small, reviewable, and holds no secrets (references
|
|
49
|
-
only). This mirrors how `repos.json`, `
|
|
49
|
+
only). This mirrors how `repos.json`, `product.json`, and `design.json` are committed.
|
|
50
50
|
|
|
51
51
|
## Greenfield
|
|
52
52
|
|
|
@@ -45,7 +45,7 @@ reserved `EP-discovery` epic; that older spelling is still read (see Step 1).
|
|
|
45
45
|
- on a **verified** ledger CI owns that ledger and it cannot be moved by hand — keep working in
|
|
46
46
|
`epics/EP-discovery/`, and review it with `yad gate open EP-discovery discovery/`.
|
|
47
47
|
|
|
48
|
-
Detect the project mode from `{project-root}/.sdlc/hub.json` `profile.codebase`
|
|
48
|
+
Detect the project mode from `{project-root}/.sdlc/product.json` (`.sdlc/hub.json` on an older Product that has only that name) `profile.codebase`
|
|
49
49
|
(`greenfield` | `brownfield`, set by `yad setup`). If absent, ask the user; default `greenfield`.
|
|
50
50
|
|
|
51
51
|
### Step 2 — Shape with the field-expert lenses (assist: analyst + pm)
|
|
@@ -159,7 +159,7 @@ yad gate open EP-foundation foundation/
|
|
|
159
159
|
the gate passes, the ledger moves to the `foundation-done` sentinel (not `ready-for-build` — the
|
|
160
160
|
Foundation has no Build). From then on `foundation/roadmap.md` and `foundation/scope.md` are the inputs
|
|
161
161
|
each `yad-epic` reads (its "Step 2c"). When the Product has a platform, the gate opens a review PR on the
|
|
162
|
-
Product (via `yad-
|
|
162
|
+
Product (via `yad-product-bridge`) and `yad-review-gate action: sync` pulls platform approvals and comments
|
|
163
163
|
into the ledger; otherwise the review is recorded locally.
|
|
164
164
|
|
|
165
165
|
## Reference
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
The project discovery phase ("epic zero") lives under `{project-root}/epics/EP-discovery/`. It reuses
|
|
17
17
|
the per-epic ledger files (`.sdlc/state.json`, `approvals.json`, `comments.json`, `reviews/`,
|
|
18
|
-
`hub-prs.json`) unchanged — `EP-discovery` is a valid epic id, so the existing gate, PR/MR bridge, CI
|
|
18
|
+
`product-prs.json` + `hub-prs.json`) unchanged — `EP-discovery` is a valid epic id, so the existing gate, PR/MR bridge, CI
|
|
19
19
|
sync, and `yad next` all operate on it. What is special is the `kind: "discovery"` marker on the state
|
|
20
20
|
object and the 2-step chain.
|
|
21
21
|
|
package/skills/yad-docs/SKILL.md
CHANGED
|
@@ -88,7 +88,7 @@ Copy the shell from `templates/app/` **verbatim**, then:
|
|
|
88
88
|
2. **Derive stakeholder roles** (`roles.ts`) from the yadflow lens set (analyst / pm / architect / ux /
|
|
89
89
|
dev / tester / reviewer / engineer), kept only where the epic's artifacts give that lens something to
|
|
90
90
|
read (which steps have artifacts, and the stories' `repos:` tags). No people or roles are read from
|
|
91
|
-
`.sdlc/
|
|
91
|
+
`.sdlc/product.json` — yadflow keeps no list of people. Each role → its relevant doc `sectionIds` +
|
|
92
92
|
`relevantPathIds` (`references/data-mapping.md`).
|
|
93
93
|
3. **Theme the `:root` block of `src/index.css`** from the design tokens, by the 4-tier priority in
|
|
94
94
|
`references/theme-map.md`: **DESIGN.md → design.json/design-links.json palette → code-map tokens →
|
|
@@ -54,7 +54,7 @@ contract is rendered exactly as locked — the docs are a *view* of the locked s
|
|
|
54
54
|
|
|
55
55
|
A stakeholder role is generated for each lens that is **relevant to this epic** — that is, the epic's
|
|
56
56
|
artifacts give the lens something to read. yadflow keeps no list of people, so no people or roles are
|
|
57
|
-
read from `.sdlc/
|
|
57
|
+
read from `.sdlc/product.json`.
|
|
58
58
|
|
|
59
59
|
1. Start from the **yadflow lens set**: `analyst`, `pm`, `architect`, `ux`, `dev`, `tester`, `reviewer`,
|
|
60
60
|
`engineer`.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yadflow-docs-site",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "yadflow-docs-site",
|
|
9
|
-
"version": "0.0.
|
|
9
|
+
"version": "0.0.2",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"framer-motion": "^12.34.4",
|
|
12
12
|
"react": "^19.2.0",
|
|
@@ -1484,9 +1484,9 @@
|
|
|
1484
1484
|
}
|
|
1485
1485
|
},
|
|
1486
1486
|
"node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
|
|
1487
|
-
"version": "5.0.
|
|
1488
|
-
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.
|
|
1489
|
-
"integrity": "sha512-
|
|
1487
|
+
"version": "5.0.12",
|
|
1488
|
+
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz",
|
|
1489
|
+
"integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==",
|
|
1490
1490
|
"dev": true,
|
|
1491
1491
|
"license": "MIT",
|
|
1492
1492
|
"dependencies": {
|
|
@@ -1685,9 +1685,9 @@
|
|
|
1685
1685
|
}
|
|
1686
1686
|
},
|
|
1687
1687
|
"node_modules/brace-expansion": {
|
|
1688
|
-
"version": "1.1.
|
|
1689
|
-
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.
|
|
1690
|
-
"integrity": "sha512-
|
|
1688
|
+
"version": "1.1.21",
|
|
1689
|
+
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.21.tgz",
|
|
1690
|
+
"integrity": "sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==",
|
|
1691
1691
|
"dev": true,
|
|
1692
1692
|
"license": "MIT",
|
|
1693
1693
|
"dependencies": {
|
|
@@ -77,11 +77,11 @@ export const FlowCanvas: React.FC = () => {
|
|
|
77
77
|
|
|
78
78
|
// Optional loop-back arc, swept below the canvas to read as "the pipeline repeats".
|
|
79
79
|
// Rendered only when both endpoint nodes exist (e.g. the SDLC-overview's
|
|
80
|
-
// trust-log → product
|
|
80
|
+
// trust-log → product cycle); a no-op for diagrams without them.
|
|
81
81
|
const loopBack = useMemo(() => {
|
|
82
82
|
if (dims.width === 0) return null;
|
|
83
83
|
const a = COMPONENTS.find((c) => c.id === 'trust-log');
|
|
84
|
-
const b = COMPONENTS.find((c) => c.id === 'product
|
|
84
|
+
const b = COMPONENTS.find((c) => c.id === 'product');
|
|
85
85
|
if (!a || !b) return null;
|
|
86
86
|
const x1 = (a.position.x / 100) * dims.width;
|
|
87
87
|
const y1 = (a.position.y / 100) * dims.height;
|
|
@@ -26,7 +26,7 @@ and never gates.
|
|
|
26
26
|
|
|
27
27
|
| Step (skill) | Outputs / sideEffects |
|
|
28
28
|
|--------------|------------------------|
|
|
29
|
-
| `yad-connect-repos` | `repos.json`, `code-context/<repo>/pack.md` + `code-map.md` (+ `detect-
|
|
29
|
+
| `yad-connect-repos` | `repos.json`, `code-context/<repo>/pack.md` + `code-map.md` (+ `detect-product` → `product.json` + `hub.json`) |
|
|
30
30
|
| `yad-connect-design` | `design.json` |
|
|
31
31
|
| `yad-connect-testing` | `testing.json` |
|
|
32
32
|
| `yad-connect-learning` | `learning.json` |
|
|
@@ -76,7 +76,7 @@ The gated authoring chain + the reusable review gate (10 steps, or 12 with the o
|
|
|
76
76
|
| `yad-test-cases` | → `test-cases-review` (parallel, non-blocking) | `test-cases.md`, `test-links.json` |
|
|
77
77
|
| `yad-review-gate` | the shared gate | `reviews/*.md`, `approvals.json`, `comments.json` |
|
|
78
78
|
| `yad-review-companion` | the fun/visible review layer (trailer/cards/chat + engagement) | `approvals.json` `engagement`, platform trailer/cards |
|
|
79
|
-
| `yad-
|
|
79
|
+
| `yad-product-bridge` | the platform PR/MR bridge | `product-prs.json` + `hub-prs.json` |
|
|
80
80
|
|
|
81
81
|
### Path: Build (`phase: 3-build`)
|
|
82
82
|
Per-story, per-repo: `spec → tasks → implement → checks → engineer-review`, plus the commit/PR helpers.
|
|
@@ -123,7 +123,7 @@ runs the sweep. The three thread gates ride in the Build `yad-checks` set above.
|
|
|
123
123
|
## System components = the durable state objects
|
|
124
124
|
|
|
125
125
|
`components.ts` renders these on the canvas (deterministic positions): the **Product**; each
|
|
126
|
-
`.sdlc/*.json` (`state.json`, `approvals.json`, `comments.json`, `
|
|
126
|
+
`.sdlc/*.json` (`state.json`, `approvals.json`, `comments.json`, `product.json`, `repos.json`, `design.json`,
|
|
127
127
|
`testing.json`, `learning.json`, `docs.json`, `contract-lock.json`, `build-state/*`, `trust-log.json`,
|
|
128
128
|
and the change-thread ledgers `change.json`, `reconcile-debt.json`, `build-log.json`);
|
|
129
129
|
the **connected code repos**; the **design / testing / learning tools**; and the **platform**
|
|
@@ -118,7 +118,7 @@ as one list: someone who has worked in ANY of them meets the ask. Nothing says w
|
|
|
118
118
|
Record `engagement: verified` when the engineer reviewed through the companion (else `none` for a bare
|
|
119
119
|
approve); `yad review reconcile --epic <id> --repo <r> --pr <n>` stamps it onto the ship record from the
|
|
120
120
|
platform (mutating the ship's shard where it lives, or its folded entry if already tidied). Soft by default (both count; a bare approve draws `yad review nudge`); only gates when
|
|
121
|
-
`
|
|
121
|
+
`review.requireEngagement: true` in the Product settings. The signal is gameable by design and sits **beside** the CI gates,
|
|
122
122
|
never above them.
|
|
123
123
|
Recording an approval does **not** ship — shipping is a separate, explicit step. Shape discipline:
|
|
124
124
|
the gate talks only through files; refuse to treat AI review as a human approval.
|
|
@@ -153,7 +153,7 @@ engineer-review rule is satisfied (Step 2). Then:
|
|
|
153
153
|
(it never weakens the merge gate — the engineer still owns the merge).
|
|
154
154
|
- **Commit the machine-written ledgers.** Run `yad checkpoint --push` from `{project-root}` to commit
|
|
155
155
|
the Build ledgers just written (the `build-log/` shard, and the `trust-log/` shard /
|
|
156
|
-
`build-state/<story>.json` if the story ran through `yad-run`) as one `chore(
|
|
156
|
+
`build-state/<story>.json` if the story ran through `yad-run`) as one `chore(product): …` audit-trail
|
|
157
157
|
commit — default branch only, staging the shard dirs (`yad tidy up` folds finished shards later),
|
|
158
158
|
never a Shape gate file. It is the Build analogue of the Shape `yad gate` sync. The
|
|
159
159
|
same commit also **carries the story `status:` flip** you just wrote (`approved → in-build/shipped`,
|
|
@@ -70,7 +70,7 @@ This is the Build analogue of Shape's `approvals.json` — files only, no hidden
|
|
|
70
70
|
future service can drive ship by writing the same records. Like the trust log and build-state, it is a
|
|
71
71
|
machine-written ledger committed by **`yad checkpoint`** (the Build analogue of `yad gate` sync),
|
|
72
72
|
not by hand: after recording the ship, `yad checkpoint --push` lands the new `build-log/` shard as a
|
|
73
|
-
`chore(
|
|
73
|
+
`chore(product): …` audit-trail commit on the default branch (allowlist-scoped to the Build ledgers,
|
|
74
74
|
never a Shape gate file); `yad tidy up` folds finished shards into `build-log.json` later.
|
|
75
75
|
|
|
76
76
|
### Retroactive ship — a pre-tracking story (#142)
|
|
@@ -134,7 +134,7 @@ reclaimed after 30s, and a live one reports `YAD-STATE-006` rather than writing
|
|
|
134
134
|
(`yad review trailer/context/nudge`, a real trailer/cards/chat session over the diff), `none` for a bare
|
|
135
135
|
approve. The optional `companion` block records which faces ran. It is **soft by default** (both count;
|
|
136
136
|
a bare approve draws a friendly `yad review nudge`); it only gates ship when
|
|
137
|
-
`
|
|
137
|
+
`review.requireEngagement: true` in the Product settings. `yad review reconcile --epic <id> --repo <r> --pr <n>` reads the
|
|
138
138
|
code PR's approvals (with the engagement signal) and stamps them onto the matching ship record — writing
|
|
139
139
|
back into the ship's shard where it lives (or its folded entry if the story was already tidied) — the
|
|
140
140
|
Build **bridge**, the analogue of `yad gate sync`. The signal is gameable by design ("visible, not
|
|
@@ -151,7 +151,7 @@ The story frontmatter `status` reflects build progress:
|
|
|
151
151
|
- `shipped` — **every** task in `tasks.md` has a ship record.
|
|
152
152
|
|
|
153
153
|
You write this flip into `stories/<story>.md`, but **do not hand-commit it** — the next
|
|
154
|
-
`yad checkpoint --push` carries it in the same `chore(
|
|
154
|
+
`yad checkpoint --push` carries it in the same `chore(product)` commit as the ledgers (the story now has a
|
|
155
155
|
build-log ship, so checkpoint stages it; #112). This is what keeps the story artifact from drifting
|
|
156
156
|
from the build ledger, so there is never a reason to fall back to a raw `git push origin main`.
|
|
157
157
|
|
package/skills/yad-epic/SKILL.md
CHANGED
|
@@ -19,7 +19,9 @@ drafted, control passes to `yad-review-gate`.
|
|
|
19
19
|
inline with the analyst, assigns `EP-<slug>`, and seeds the **10-step** chain.
|
|
20
20
|
|
|
21
21
|
This skill enforces the build plan's core rules: all state lives in files; IDs are generated by the
|
|
22
|
-
engine (never typed by hand); Shape
|
|
22
|
+
engine (never typed by hand); every Shape step starts at `advance: human`. A review gate is always
|
|
23
|
+
human; only the team can set a Shape author step to auto (`yad dial`, recorded in
|
|
24
|
+
`.sdlc/automation.json`; nothing acts on it yet).
|
|
23
25
|
|
|
24
26
|
## Conventions
|
|
25
27
|
|
|
@@ -186,7 +188,7 @@ yad epic new EP-<slug> --profile chore # the short upkeep lane — see below
|
|
|
186
188
|
|
|
187
189
|
That writes `{project-root}/epics/EP-<slug>/.sdlc/state.json`, the empty `approvals.json` and
|
|
188
190
|
`comments.json`, and the `reviews/` directory. Without `--profile` the chain is the full **10-step**
|
|
189
|
-
`classic` route (no analysis). Every step
|
|
191
|
+
`classic` route (no analysis). Every step starts at `advance: human`; `epic` is open and the rest
|
|
190
192
|
are blocked. The chain comes from the step catalogue and the lifecycle profile in the engine
|
|
191
193
|
(`references/state-schema.md`), so there is one definition of it and no copy here to drift from it.
|
|
192
194
|
|
|
@@ -236,7 +238,7 @@ Notes:
|
|
|
236
238
|
*(**Always run this**, on both entry modes. The chain is seeded by now either way — by `yad-analysis`,
|
|
237
239
|
by `yad epic new` in Step 5, or by `yad epic new` before this skill was invoked — and `epic.md` is
|
|
238
240
|
written. This is the step that closes the authoring step and opens its gate.)*
|
|
239
|
-
**Check the mode first — the two modes have opposite instructions here.** Read `.sdlc/hub.json
|
|
241
|
+
**Check the mode first — the two modes have opposite instructions here.** Read `.sdlc/product.json` (`.sdlc/hub.json` on an older Product that has only that name):
|
|
240
242
|
**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.
|
|
241
243
|
|
|
242
244
|
**verified mode — do NOT write `state.json`.** The ledger is CI-owned: the `ledger-guard` check rejects
|
|
@@ -281,7 +283,7 @@ reviewers approve, through the gate.
|
|
|
281
283
|
Report: epic ID, the path to `epic.md`, and that the next action is **review** via
|
|
282
284
|
`yad-review-gate`. **Never mark the epic-review step approved here** — only real reviewers do that
|
|
283
285
|
through the gate. Shape steps do not auto-advance. When the Product has a platform, the gate opens a review
|
|
284
|
-
PR on the Product (via `yad-
|
|
286
|
+
PR on the Product (via `yad-product-bridge`) and `yad-review-gate action: sync` pulls platform approvals/
|
|
285
287
|
comments into the ledger; otherwise the review is recorded local.
|
|
286
288
|
|
|
287
289
|
## Reference
|
|
@@ -28,8 +28,8 @@ Three rules go with it, and they are permanent (`docs/roadmap-idea-1.md`, Part 2
|
|
|
28
28
|
1. **A file with no version counts as version 1.** Nothing has to be rewritten to be readable. Files
|
|
29
29
|
written before the stamp existed are read as shape 1, and get the key the next time the engine
|
|
30
30
|
writes them.
|
|
31
|
-
2. **The list files never carry it.** `approvals.json`, `comments.json`, `
|
|
32
|
-
|
|
31
|
+
2. **The list files never carry it.** `approvals.json`, `comments.json`, `product-prs.json` (also written
|
|
32
|
+
under its older name `hub-prs.json`) and `reconcile-debt.json` are JSON arrays at the top level, and an array cannot hold a key. Rule 1
|
|
33
33
|
covers them: no version means version 1.
|
|
34
34
|
3. **`schemaVersion` is not the CLI version.** `.sdlc/cli-version.json` records which release of the
|
|
35
35
|
`yad` CLI set the project up, and changes on every release. `schemaVersion` describes the file's
|
|
@@ -206,7 +206,7 @@ A chain missing steps still matches — dropping `ui-design` is normal. An epic
|
|
|
206
206
|
nothing gets NO `profile` key from the migration: inventing one would silence `step:off-route` by
|
|
207
207
|
making the file agree with itself.
|
|
208
208
|
|
|
209
|
-
> **Two different things are called a profile.** This one is the lifecycle route. `
|
|
209
|
+
> **Two different things are called a profile.** This one is the lifecycle route. `product.json.profile` is
|
|
210
210
|
> the unrelated setup record `yad setup` writes: `{ codebase, repo_layout, team_size }`.
|
|
211
211
|
|
|
212
212
|
### The six phases
|
|
@@ -556,7 +556,7 @@ unchanged.)
|
|
|
556
556
|
Each front **authoring** step opens its own git branch at the start of the step, named
|
|
557
557
|
`<step>/EP-<slug>` where `<step>` ∈ `analysis | epic | architecture | ui-design | stories | test-cases`
|
|
558
558
|
(`config.yaml` `defaults.shape_authoring_branch`). This is **distinct** from the review branch
|
|
559
|
-
`review/EP-<slug>/<artifact-base>` that `yad-
|
|
559
|
+
`review/EP-<slug>/<artifact-base>` that `yad-product-bridge` opens later for the review PR/MR.
|
|
560
560
|
|
|
561
561
|
The shared procedure (run once the `EP-<slug>` is known):
|
|
562
562
|
1. **Git-safe / greenfield-safe:** if `{project-root}` is not a git work tree
|
|
@@ -596,10 +596,10 @@ name. The gate never reads the role. While the roster is on disk, the next sync
|
|
|
596
596
|
`yad gate ci`) records the login on such an entry when the roster places it for certain, removes `role`
|
|
597
597
|
and `domain`, and keeps the old name in `rosterName` (E64). Some entries are left as they are — a name two
|
|
598
598
|
logins share, or several records that do not prove they are one review (most GitLab role records); see
|
|
599
|
-
`yad-
|
|
599
|
+
`yad-product-bridge/references/login-roster.md`. The dated `approved.md` still prints the roles as recorded.
|
|
600
600
|
|
|
601
601
|
`source: "bridge"` marks an approval synced from a Product review PR/MR by `yad-review-gate action: sync`
|
|
602
|
-
(via `yad-
|
|
602
|
+
(via `yad-product-bridge`). Manual approvals omit `source` and are never altered by `sync`, except for the
|
|
603
603
|
login recorded on an older entry (above). A manual approval written by `yad gate approve` (E112, a
|
|
604
604
|
Product with no platform) carries `artifactHash`, so an edit to the artifact revokes it as it revokes a
|
|
605
605
|
bridge approval; one written by hand before E112 has none, so an edit does not revoke it.
|
|
@@ -614,7 +614,7 @@ rather than *who approved*:
|
|
|
614
614
|
| `pr` | the PR/MR number the approval arrived on. The second proof of a genuine re-approval, and the only one available on GitLab: a re-opened review is always a new PR, so an approval on a different number cannot be the old one re-read. Records written before this field existed are stamped once, from the `hub-prs.json` pointer they were recorded against. |
|
|
615
615
|
| `commit`, `url`, `reviewId` | the platform's evidence for the review (E64): the commit it was given on, its link, and its node id. GitHub only, and only when the read gave them — never written `null`. An MR approval on GitLab is not tied to a commit, so none is recorded there. For the record only; the gate never reads them. |
|
|
616
616
|
| `rosterName` | on an older entry whose login was recorded from the roster (E64), the name it had. The gate lets an exact submission time move such an entry to the person who really submitted that review. |
|
|
617
|
-
| `engagement` | `verified` when the approval carried the companion's engagement marker, else `none`. Advisory unless `
|
|
617
|
+
| `engagement` | `verified` when the approval carried the companion's engagement marker, else `none`. Advisory unless `review.requireEngagement` (Product settings) is on. |
|
|
618
618
|
|
|
619
619
|
`date` is when the sync **recorded** the approval, not when it was given — it is preserved across an
|
|
620
620
|
unchanged re-sync so that re-reading a review never churns the ledger.
|
|
@@ -632,7 +632,7 @@ Append-only ledger (an array), the machine-readable counterpart to the `reviews/
|
|
|
632
632
|
written by `yad gate comment` (E112, no platform) also carries `artifactHash`, the fingerprint of the
|
|
633
633
|
artifact its round was opened with (a late record joining the round carries the same one): a round is one version, so `--new-round` opens the next only after an edit. An older entry may still carry `role` and `domain`; the gate never reads them, and while the roster is on disk the next sync write records the login on it, keeping the old name in `rosterName` — unless two records in one round would then name the same login (E64).
|
|
634
634
|
|
|
635
|
-
## `hub-prs.json`
|
|
635
|
+
## `product-prs.json` (and `hub-prs.json`)
|
|
636
636
|
Present only when the Shape review runs through the platform bridge. Per review step, the review
|
|
637
637
|
PR/MR opened on the Product (sibling of `approvals.json`, so the locked `state.json` step shape is untouched):
|
|
638
638
|
|
|
@@ -640,8 +640,9 @@ PR/MR opened on the Product (sibling of `approvals.json`, so the locked `state.j
|
|
|
640
640
|
{ "step": "<review step id>", "artifact": "<artifact>", "platform": "github|gitlab", "number": <n>, "url": "<pr/mr url>", "branch": "review/EP-<slug>/<artifact-base>", "lastSyncedAt": "<YYYY-MM-DD or null>" }
|
|
641
641
|
```
|
|
642
642
|
|
|
643
|
-
The same array is written under two names: `product-prs.json` (the name from shape 3
|
|
644
|
-
(the old name,
|
|
643
|
+
The same array is written under two names, with identical bytes: `product-prs.json` (the name from shape 3,
|
|
644
|
+
read first) and `hub-prs.json` (the old name, written until v5 and read only when `product-prs.json` is
|
|
645
|
+
absent — E122). `yad gate sync` may add `nudged`, the logins it has already asked to
|
|
645
646
|
use the review companion, so it never asks them twice.
|
|
646
647
|
|
|
647
648
|
## `design-links.json`
|
|
@@ -693,10 +694,10 @@ whether to advance on its own. Two new files under `.sdlc/` do this.
|
|
|
693
694
|
> **Who commits these.** `build-state/<story-id>.json`, `trust-log.json`, and `build-log.json` are
|
|
694
695
|
> **machine-written** by Build (`yad-run`, `yad-engineer-review`) and committed by
|
|
695
696
|
> **`yad checkpoint`** — the Build analogue of the Shape `yad gate ci` sync. It lands them as
|
|
696
|
-
> one `chore(
|
|
697
|
+
> one `chore(product): sync Build state — <epic>/<story> by @<login>` audit-trail commit, on the
|
|
697
698
|
> default branch, staging **only** these three ledgers by an explicit allowlist (never a Shape
|
|
698
699
|
> gate file — `state/approvals/comments/product-prs/hub-prs.json`, `reviews/*.md` — so `ledger-guard` never trips).
|
|
699
|
-
> Teammates don't review these machine writes; the commit exists so CI, `yad
|
|
700
|
+
> Teammates don't review these machine writes; the commit exists so CI, the `yad-status` skill, and other
|
|
700
701
|
> machines always see current trust evidence.
|
|
701
702
|
|
|
702
703
|
## `build-state/<story-id>.json`
|
|
@@ -32,7 +32,7 @@ the Product.
|
|
|
32
32
|
`pull_request_template.md`, so the Product `pr-template` gate passes.
|
|
33
33
|
In a code repo nothing changes — it reads the repo's own committed code-task template.
|
|
34
34
|
- **Base branch** — **resolved, never assumed.** In order: `--base` → the repo's `default_branch` in
|
|
35
|
-
`.sdlc/repos.json` → (for a PR against the Product itself) `
|
|
35
|
+
`.sdlc/repos.json` → (for a PR against the Product itself) `product.json`'s `default_branch` (`hub.json` on an older Product) → what the
|
|
36
36
|
platform reports (`gh repo view --json defaultBranchRef` / `glab api projects/:id`) → local
|
|
37
37
|
`origin/HEAD` → `main`. The same **configuration-outranks-the-remote** order `yad repo sync` and the
|
|
38
38
|
contract-check gate already use (they stop at `origin/HEAD`; only this chain also asks the platform).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: yad-pair-review
|
|
3
|
-
description: 'The guided, two-way, teaching pair-review walkthrough for the SDLC review gates — the AI-driven companion face. The human opens a PR/MR with an AI session and the AI walks them through the change ONE STOP AT A TIME (highest-risk first), giving comprehensive context per change, then asking the human a Socratic question about it; the human answers and asks back, and both keep going until BOTH declare satisfied. The session doubles as a learning session: it demonstrates a transferable review method, scores the engineer against it, and records their review-skill growth in the local-only yad-learn ledger (rolled up by yad
|
|
3
|
+
description: 'The guided, two-way, teaching pair-review walkthrough for the SDLC review gates — the AI-driven companion face. The human opens a PR/MR with an AI session and the AI walks them through the change ONE STOP AT A TIME (highest-risk first), giving comprehensive context per change, then asking the human a Socratic question about it; the human answers and asks back, and both keep going until BOTH declare satisfied. The session doubles as a learning session: it demonstrates a transferable review method, scores the engineer against it, and records their review-skill growth in the local-only yad-learn ledger (rolled up by the yad-status skill). Works on the Build code PR/MR (yad review) and the Shape artifact-review PR/MR (yad gate). Soft and additive — it NEVER blocks a merge or gate; it rides the existing engagement signal and surfaces genuine concerns as normal blocking comments. Use when the user says "pair review this", "walk me through the PR/MR", "review with me", "co-review", or "teach me to review".'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# SDLC — Pair Review (the guided, two-way, teaching walkthrough)
|
|
@@ -99,7 +99,7 @@ addresses them) — nothing advances on a half-finished session.
|
|
|
99
99
|
|
|
100
100
|
### Step 5 — Record the session (twice) — see `references/session-state.md`
|
|
101
101
|
1. **Session comment (PR/MR history).** Post one comment built by the CLI helper `pairSessionBody`
|
|
102
|
-
(carries `<!-- yad:pair -->` so `yad
|
|
102
|
+
(carries `<!-- yad:pair -->` so the `yad-status` skill can count paired reviews, and `<!-- yad:noblock -->` so it
|
|
103
103
|
never holds the gate): the transcript summary, the **review-skill scorecard**, your AI verdict, and
|
|
104
104
|
both sign-offs. Post it with the platform CLI (`gh pr comment` / `glab mr note`).
|
|
105
105
|
2. **Learning record (local-only).** Append a `yad-learn` record for the `member`: `concept` =
|
|
@@ -108,14 +108,14 @@ addresses them) — nothing advances on a half-finished session.
|
|
|
108
108
|
comprehension), `comprehension` = the scorecard roll-up, `tutorial` = a rendered
|
|
109
109
|
`learning/<member>--review-<pr>.md` capturing the method as applied to this PR + the engineer's gaps.
|
|
110
110
|
**First ensure the Product `.gitignore` covers the learning paths** (reuse yad-learn's guard), then write —
|
|
111
|
-
these are personal, gitignored, **never committed or pushed**. The growth rolls up under `yad
|
|
112
|
-
"My skills".
|
|
111
|
+
these are personal, gitignored, **never committed or pushed**. The growth rolls up under the `yad-status`
|
|
112
|
+
skill's "My skills".
|
|
113
113
|
|
|
114
114
|
## Hard rules
|
|
115
115
|
|
|
116
116
|
- **Never a gate.** This skill never moves `currentStep`, never records an approval on the human's
|
|
117
117
|
behalf, and never merges. It enriches the input and rides the existing soft `engagement` signal only.
|
|
118
|
-
Strict mode (`
|
|
118
|
+
Strict mode (`review.requireEngagement` (Product settings)) is the gate's switch, not this skill's.
|
|
119
119
|
- **The CLI never calls an LLM.** The sequencer (`stops[]`) and the markers are deterministic; *you*
|
|
120
120
|
generate every briefing, question, and answer. Same split as the companion.
|
|
121
121
|
- **Grounded only in real material.** Briefings/answers come from the diff + artifact + contract +
|
|
@@ -8,7 +8,7 @@ of which ever blocks the gate. The gate's predicate (approvals + resolved thread
|
|
|
8
8
|
Built by the CLI helper `pairSessionBody({ summary, scorecard, verdict, humanSignoff, aiSignoff })` in
|
|
9
9
|
`cli/companion.mjs`. It carries **both** markers:
|
|
10
10
|
|
|
11
|
-
- `<!-- yad:pair -->` — so this is countable as a *paired review* in the `yad
|
|
11
|
+
- `<!-- yad:pair -->` — so this is countable as a *paired review* in the `yad-status` skill's 🏆 roll-up.
|
|
12
12
|
- `<!-- yad:noblock -->` — so the thread is excluded from the gate's blocking check and persists as
|
|
13
13
|
permanent history (a deliberate, unresolved trail), exactly like the companion's card/chat threads.
|
|
14
14
|
|
|
@@ -71,7 +71,7 @@ Field notes:
|
|
|
71
71
|
Also render the tutorial artifact `epics/EP-<slug>/learning/<member>--review-<pr>.md` (front-matter:
|
|
72
72
|
`member`, `concept`, `stage`, `tool`, `requestedAt`) — the review method as applied to *this* PR plus the
|
|
73
73
|
engineer's specific gaps and how to close them. Both files are **local-only, gitignored, never committed
|
|
74
|
-
or pushed, and never written into a code repo** — they are a private personal skills log. `yad
|
|
74
|
+
or pushed, and never written into a code repo** — they are a private personal skills log. The `yad-status` skill
|
|
75
75
|
rolls them up by stage (e.g. "engineer-review: 3").
|
|
76
76
|
|
|
77
77
|
## Optional: stamp the build-log (Build)
|
|
@@ -23,21 +23,21 @@ routing helper.
|
|
|
23
23
|
- `templates/gitlab/merge_request_templates/Default.md` → installs to
|
|
24
24
|
`<repo>/.gitlab/merge_request_templates/Default.md`
|
|
25
25
|
- `templates/checks/risk-route.sh` → installs to `<repo>/checks/risk-route.sh` (advisory routing helper)
|
|
26
|
-
- **Product variants** (`repo:
|
|
27
|
-
`templates/
|
|
28
|
-
`templates/
|
|
26
|
+
- **Product variants** (`repo: product`) — Shape artifact-review PR/MR bodies:
|
|
27
|
+
`templates/product/github/pull_request_template.md` → `{project-root}/.github/pull_request_template.md`;
|
|
28
|
+
`templates/product/gitlab/merge_request_templates/Default.md` →
|
|
29
29
|
`{project-root}/.gitlab/merge_request_templates/Default.md`. The Product body carries no `Task:` trailer
|
|
30
|
-
(Product PRs change artifacts, not code); its routing helper is `yad-
|
|
31
|
-
`templates/checks/
|
|
30
|
+
(Product PRs change artifacts, not code); its routing helper is `yad-product-bridge`'s
|
|
31
|
+
`templates/checks/product-route.sh`, run from the skill (nothing installs it into the Product's `checks/`).
|
|
32
32
|
- **GitLab reads a truncated description.** The `pr-template` gate is fed
|
|
33
33
|
`$CI_MERGE_REQUEST_DESCRIPTION`, which GitLab cuts at **2700 characters** — a required section below
|
|
34
34
|
that cutoff is invisible to the gate even though the MR shows it, and the failure reads "does not use
|
|
35
35
|
the template" (#164). Both GitLab templates say so in a comment and keep `## Summary` /
|
|
36
|
-
`## Impact & Risk` / `## Checklist` (
|
|
36
|
+
`## Impact & Risk` / `## Checklist` (Product: `## Artifact under review` / `## Impact & Risk (front-half)`
|
|
37
37
|
/ `## Checklist`) early, so a truncated body still passes. Long narrative goes **after** them.
|
|
38
38
|
Sections may be reordered freely; deleting one fails the gate. GitHub is unaffected.
|
|
39
39
|
- **Installed code-repo templates are yad-managed.** `yad update` rewrites them on upgrade (the Product
|
|
40
|
-
variants under `templates/
|
|
40
|
+
variants under `templates/product/` are copied by hand in Step 2 and are not managed). An edit yad can
|
|
41
41
|
prove — the file's sha differs from the one it recorded when it wrote the template — is reported as
|
|
42
42
|
`modified` and left alone; a copy it has no record of is replaced after a `.yad-orig` backup (see
|
|
43
43
|
`docs/CLI.md` → *Managed files*). Either way, put knowledge that must survive an upgrade in an ADR
|
|
@@ -54,7 +54,8 @@ routing helper.
|
|
|
54
54
|
|
|
55
55
|
## Inputs
|
|
56
56
|
|
|
57
|
-
- `repo` — the code repo to add the template to (one of an epic's repos), or `
|
|
57
|
+
- `repo` — the code repo to add the template to (one of an epic's repos), or `product` for the Product (`hub`, the old name, still works). A code repo that is itself named
|
|
58
|
+
`product`: give its registered path instead (for example `repos/product`), so it is not taken for the Product.
|
|
58
59
|
- `action` — `wire` (commit the matching template + helper) | `route` (print the approver count from a
|
|
59
60
|
PR body). Default `wire`.
|
|
60
61
|
- `body` — for `route`: a file holding the PR/MR description to evaluate.
|
|
@@ -62,17 +63,18 @@ routing helper.
|
|
|
62
63
|
## On Activation
|
|
63
64
|
|
|
64
65
|
### Step 1 — Resolve the repo and detect the platform
|
|
65
|
-
Map `repo` → `{project-root}/demo-repos/<repo>/` (or the registry `path`).
|
|
66
|
+
Map `repo` → `{project-root}/demo-repos/<repo>/` (or the registry `path`). A `repo` value with a `/` in it is a registry `path`, not a name: match it against each entry's `path`
|
|
67
|
+
(so a code repo named `product` is reached as, for example, `repos/product`). Detect the platform: a GitHub
|
|
66
68
|
remote or `.github/` → GitHub; a GitLab remote or `.gitlab/` → GitLab. If ambiguous, ask. For
|
|
67
|
-
`repo:
|
|
69
|
+
`repo: product`, the target is `{project-root}` itself and the platform comes from `.sdlc/product.json` (`.sdlc/hub.json` on an older Product that has only that name).
|
|
68
70
|
|
|
69
71
|
### Step 2 — `wire` (drop only the matching template)
|
|
70
72
|
Copy from this skill's `templates/`:
|
|
71
73
|
- GitHub → `templates/github/pull_request_template.md` to `<repo>/.github/pull_request_template.md`.
|
|
72
74
|
- GitLab → `templates/gitlab/merge_request_templates/Default.md` to
|
|
73
75
|
`<repo>/.gitlab/merge_request_templates/Default.md`.
|
|
74
|
-
- **`repo:
|
|
75
|
-
`.github/`/`.gitlab/`. The Product's routing helper (`
|
|
76
|
+
- **`repo: product`** → use the `templates/product/<platform>/…` variants, installed into `{project-root}`'s own
|
|
77
|
+
`.github/`/`.gitlab/`. The Product's routing helper (`product-route.sh`) stays in `yad-product-bridge`'s
|
|
76
78
|
`templates/checks/`; neither this skill nor `yad setup` / `yad check --fix` installs it.
|
|
77
79
|
Drop **only the matching** template (drop both only if the repo genuinely uses both). For code repos also
|
|
78
80
|
install `templates/checks/risk-route.sh` to `<repo>/checks/` (`chmod +x`), beside
|