yadflow 3.19.0-next.2 → 4.0.0-next.3
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 +371 -0
- package/README.md +160 -22
- package/bin/commands.mjs +46 -0
- package/bin/yad.mjs +506 -117
- package/cli/artifact-status.mjs +30 -11
- package/cli/capture.mjs +417 -0
- package/cli/checkpoint.mjs +47 -27
- package/cli/claims.mjs +165 -0
- package/cli/codeowners-command.mjs +170 -0
- package/cli/codeowners.mjs +397 -0
- package/cli/commit.mjs +13 -9
- package/cli/dial.mjs +183 -0
- package/cli/docs.mjs +88 -32
- package/cli/doctor.mjs +1682 -90
- package/cli/epic-state.mjs +3460 -211
- package/cli/epic.mjs +506 -0
- package/cli/errors.mjs +3 -0
- package/cli/fold.mjs +247 -0
- package/cli/gate-local.mjs +296 -0
- package/cli/gate.mjs +977 -183
- package/cli/history.mjs +556 -0
- package/cli/hook.mjs +264 -53
- package/cli/hubcommit.mjs +9 -19
- package/cli/index-command.mjs +87 -0
- package/cli/ledger.mjs +54 -4
- package/cli/lib.mjs +161 -9
- package/cli/manifest.mjs +376 -38
- package/cli/migrate.mjs +683 -52
- package/cli/mode.mjs +170 -0
- package/cli/next.mjs +365 -86
- package/cli/openpr.mjs +193 -34
- package/cli/owners.mjs +266 -0
- package/cli/people.mjs +657 -0
- package/cli/plan.mjs +466 -125
- package/cli/platform.mjs +109 -128
- package/cli/product-index.mjs +287 -0
- package/cli/protection.mjs +706 -0
- package/cli/reconcile.mjs +40 -12
- package/cli/repo-publish.mjs +24 -26
- package/cli/repo.mjs +23 -14
- package/cli/report.mjs +24 -14
- package/cli/review.mjs +19 -22
- package/cli/riskmap-command.mjs +289 -0
- package/cli/riskmap.mjs +373 -0
- package/cli/setup.mjs +127 -279
- package/cli/ship.mjs +6 -5
- package/cli/skill.mjs +180 -0
- package/cli/skip.mjs +211 -30
- package/cli/thread.mjs +41 -16
- package/cli/tidy.mjs +18 -18
- package/cli/update-commit.mjs +21 -21
- package/cli/usage.mjs +115 -109
- package/package.json +3 -3
- package/skills/sdlc/config.yaml +149 -70
- package/skills/sdlc/module-help.csv +24 -24
- package/skills/yad-analysis/SKILL.md +121 -59
- package/skills/yad-architecture/SKILL.md +30 -18
- package/skills/yad-architecture/references/contract-format.md +8 -5
- package/skills/yad-backfill/SKILL.md +10 -4
- package/skills/yad-backfill/references/backfill.md +8 -1
- package/skills/yad-backfill/templates/checks/backfill-check.sh +10 -2
- package/skills/yad-change/SKILL.md +119 -42
- package/skills/yad-change/references/triage.md +42 -27
- package/skills/yad-checks/SKILL.md +68 -35
- package/skills/yad-checks/references/check-gates.md +310 -85
- package/skills/yad-checks/templates/checks/commit-message.sh +17 -3
- package/skills/yad-checks/templates/checks/contract-check.sh +130 -9
- package/skills/yad-checks/templates/checks/epic-open.sh +2 -2
- package/skills/yad-checks/templates/checks/ledger-guard.sh +55 -8
- package/skills/yad-checks/templates/checks/lineage-check.sh +23 -9
- package/skills/yad-checks/templates/checks/reconcile-debt-check.sh +1 -1
- 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 +13 -2
- package/skills/yad-checks/templates/github/yad-hub-checks.yml +5 -5
- package/skills/yad-checks/templates/github/yad-update-guard.yml +7 -5
- package/skills/yad-checks/templates/github/yad-verified-commits.yml +4 -4
- package/skills/yad-checks/templates/gitlab/yad-checks.gitlab-ci.yml +10 -1
- 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 +3 -3
- package/skills/yad-checks/templates/hooks/ledger-guard-cursor.sh +91 -0
- package/skills/yad-checks/templates/hooks/ledger-guard.sh +37 -6
- package/skills/yad-checks/templates/hooks/yad-capture.sh +53 -0
- package/skills/yad-commit/SKILL.md +4 -4
- package/skills/yad-connect-design/SKILL.md +5 -5
- 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 +11 -11
- 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 +66 -45
- package/skills/yad-connect-repos/references/code-context.md +4 -4
- package/skills/yad-connect-repos/references/hub-config.md +47 -51
- package/skills/yad-connect-repos/references/repos-registry.md +8 -7
- package/skills/yad-connect-repos/references/risk-map.md +81 -0
- package/skills/yad-connect-testing/SKILL.md +5 -5
- 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 +7 -7
- package/skills/yad-discovery/SKILL.md +131 -94
- package/skills/yad-discovery/references/discovery-schema.md +22 -6
- package/skills/yad-discovery/references/foundation-schema.md +374 -0
- package/skills/yad-docs/SKILL.md +13 -8
- 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 +30 -15
- package/skills/yad-docs-overview/references/pipeline-model.md +33 -20
- 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 +81 -17
- package/skills/yad-engineer-review/references/ship-and-record.md +17 -8
- package/skills/yad-epic/SKILL.md +173 -92
- package/skills/yad-epic/references/state-schema.md +610 -94
- package/skills/yad-hub-bridge/SKILL.md +57 -38
- package/skills/yad-hub-bridge/references/bridge.md +94 -67
- 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 +21 -11
- package/skills/yad-implement/SKILL.md +27 -13
- 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 +61 -26
- package/skills/yad-pair-review/SKILL.md +7 -5
- package/skills/yad-pair-review/references/session-state.md +1 -1
- package/skills/yad-pr-template/SKILL.md +47 -26
- package/skills/yad-pr-template/references/risk-routing.md +97 -24
- package/skills/yad-pr-template/templates/checks/pr-template.sh +34 -11
- package/skills/yad-pr-template/templates/checks/pr-title.sh +32 -9
- 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 +14 -13
- package/skills/yad-pr-template/templates/hub/gitlab/merge_request_templates/Default.md +14 -12
- package/skills/yad-reconcile/SKILL.md +3 -3
- package/skills/yad-report/SKILL.md +5 -5
- package/skills/yad-review-companion/SKILL.md +6 -3
- package/skills/yad-review-gate/SKILL.md +203 -93
- package/skills/yad-review-gate/references/gating.md +232 -54
- package/skills/yad-run/SKILL.md +81 -51
- package/skills/yad-run/references/run-loop.md +61 -39
- package/skills/yad-ship/SKILL.md +15 -11
- package/skills/yad-spec/SKILL.md +21 -6
- package/skills/yad-spec/references/spec-handoff.md +17 -5
- package/skills/yad-status/SKILL.md +115 -50
- package/skills/yad-stories/SKILL.md +37 -21
- package/skills/yad-stories/references/story-schema.md +7 -6
- package/skills/yad-stub/SKILL.md +58 -47
- package/skills/yad-sync-repos/SKILL.md +2 -2
- package/skills/yad-test-cases/SKILL.md +32 -23
- package/skills/yad-test-cases/references/test-cases-schema.md +7 -4
- package/skills/yad-timeline/SKILL.md +8 -7
- package/skills/yad-ui/SKILL.md +41 -18
- package/cli/roster.mjs +0 -164
- package/skills/sdlc/install.sh +0 -68
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: yad-implement
|
|
3
|
-
description: 'Build Step B of the gated SDLC. With the dev lens, implement ONE atomic task from a story''s Spec Kit tasks.md as a small diff (≤3 files) on its own branch in the code repo. The diff stays inside the files the task declared — flag and STOP if it would grow beyond them. Commit per convention, ending with the task ID; add Contract-Change: yes only if the diff touches the locked contract surface (which routes back to the architecture gate). The step never advances itself; it produces a committed branch and hands off to the check gates, which the orchestrator (yad-run) may auto-run once `implement`
|
|
3
|
+
description: 'Build Step B of the gated SDLC. With the dev lens, implement ONE atomic task from a story''s Spec Kit tasks.md as a small diff (≤3 files) on its own branch in the code repo. The diff stays inside the files the task declared — flag and STOP if it would grow beyond them. Commit per convention, ending with the task ID; add Contract-Change: yes only if the diff touches the locked contract surface (which routes back to the architecture gate). The step never advances itself; it produces a committed branch and hands off to the check gates, which the orchestrator (yad-run) may auto-run once the team sets `implement` to `advance: auto` (`yad dial`) — the merge still needs the gates and the engineer review. Use when the user says "implement task <id>" or after a story is spec''d.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# SDLC — Implement Task (Build Step B)
|
|
@@ -14,7 +14,7 @@ This step **never auto-advances**. When the task is implemented and committed, c
|
|
|
14
14
|
**check gates** (Step C — `yad-checks`: spec-link, contract-check, build/test/lint) and then human/AI
|
|
15
15
|
review (Steps D–E, not built yet). Implementation here produces a branch + commit and stops.
|
|
16
16
|
|
|
17
|
-
The implementing lens is **`dev
|
|
17
|
+
The implementing lens is **`dev`**. The dev writes only what the task
|
|
18
18
|
declares; it does not redesign, does not widen the contract, and does not pick up sibling tasks.
|
|
19
19
|
|
|
20
20
|
## Conventions
|
|
@@ -30,7 +30,7 @@ declares; it does not redesign, does not widen the contract, and does not pick u
|
|
|
30
30
|
`Co-Authored-By:` for any AI tool that helped author the diff (the human author owns the commit;
|
|
31
31
|
trailer order `Task:` → `Contract-Change:` → `Co-Authored-By:`). The skill installs a `.gitmessage`
|
|
32
32
|
template that scaffolds these (Step 2).
|
|
33
|
-
- Speak in the
|
|
33
|
+
- Speak in the `communication_language` set in `{project-root}/.sdlc/config.yaml`; write code/comments in `document_output_language`.
|
|
34
34
|
|
|
35
35
|
## Inputs
|
|
36
36
|
|
|
@@ -55,7 +55,7 @@ rather than forking a second one (one task = one branch).
|
|
|
55
55
|
**On the first implement in a repo, install the commit template** (idempotent): copy this skill's
|
|
56
56
|
`templates/.gitmessage` to `<repo>/.gitmessage` and run `git -C <repo> config commit.template .gitmessage`
|
|
57
57
|
so every commit is pre-scaffolded with the `Task:` trailer and the commented per-commit `Co-Authored-By:`
|
|
58
|
-
choices (`config.yaml` `build.ai_coauthor.allowed`). Do the same at the
|
|
58
|
+
choices (`config.yaml` `build.ai_coauthor.allowed`). Do the same at the Product root for Product commit. Skip if
|
|
59
59
|
already configured.
|
|
60
60
|
|
|
61
61
|
### Step 3 — Read the spec inputs (do NOT re-derive the contract)
|
|
@@ -77,9 +77,14 @@ declared files are wrong is a spec bug, not an implementation decision.
|
|
|
77
77
|
|
|
78
78
|
This stop is a **scope overrun** — a halt condition that pulls in a human regardless of any automation
|
|
79
79
|
dial. When this step is driven by the orchestrator (`yad-run`, Phase 4), the stop must be legible to
|
|
80
|
-
it: mark the `implement` step `status: blocked` in `build-state/<story>.json`
|
|
81
|
-
`
|
|
82
|
-
|
|
80
|
+
it: mark the `implement` step `status: blocked` in `build-state/<story>.json` — **with a `record`**,
|
|
81
|
+
`{ "reason": "scope overrun: <which file>", "by": "<login or null>", "date": "<YYYY-MM-DD>" }` — and
|
|
82
|
+
surface `scope_overrun: true` so the run records a `rejected` trust entry and halts (it never advances
|
|
83
|
+
past a boundary breach). The same applies to the Step 5 contract-surface stop (`contract_touch: true`).
|
|
84
|
+
|
|
85
|
+
The record is what makes the halt legible. Since shape 7 (E38) a `blocked` step carrying nothing
|
|
86
|
+
reads as `todo` — "not started" — because that is what the word meant in every file written before
|
|
87
|
+
shape 7. The record is the only thing that separates a lane that stopped from a lane nobody began.
|
|
83
88
|
|
|
84
89
|
### Step 5 — Contract-surface check (local pre-flight for Step C)
|
|
85
90
|
Determine whether the diff touches the **locked contract surface** (the API/event/data-model shapes in
|
|
@@ -89,9 +94,18 @@ A contract change means the diff alters the agreed cross-repo shape itself.
|
|
|
89
94
|
|
|
90
95
|
- If the diff does **not** change the surface: proceed; no `Contract-Change` trailer.
|
|
91
96
|
- If the task **requires** changing the surface: **flag and STOP**. The contract is owned upstream;
|
|
92
|
-
route back to the **architecture gate** to amend and re-lock `contract.md` first
|
|
97
|
+
route back to the **architecture gate** to amend and re-lock `contract.md` first — on a route that
|
|
98
|
+
has one; the short lanes do not, see the bullet below. Only then return
|
|
93
99
|
here, and record `Contract-Change: yes` in the commit body (the Step C contract-check will require a
|
|
94
100
|
matching, already-updated contract).
|
|
101
|
+
- **Short-lane epics have no contract and no architecture gate.** Read
|
|
102
|
+
`epics/<epic>/.sdlc/state.json`'s `profile` (or, on an epic seeded before file shape 6, what its
|
|
103
|
+
`steps[]` contains): on `chore` and `spike` there is no `contract.md`, so
|
|
104
|
+
there is no surface block to compare against and **no gate to route back to**. Never write
|
|
105
|
+
`Contract-Change: yes` on a short-lane task: there is no lock for the check to verify it against, so
|
|
106
|
+
the claim cannot be true of anything. Where the Product repo is reachable the gate now FAILS it
|
|
107
|
+
outright; where it is not, the check defers and nothing catches it. If the task needs the shared cross-repo surface to change, **STOP and escalate
|
|
108
|
+
to a human**: the work belongs to a new epic on `classic`.
|
|
95
109
|
|
|
96
110
|
### Step 6 — Commit on the task branch
|
|
97
111
|
Stage only the declared files. Commit with the convention: a conventional subject, a short body, and a
|
|
@@ -109,13 +123,13 @@ then the PR and review (Steps D–E). Do **not** open a PR, merge, or hand-edit
|
|
|
109
123
|
- **Run standalone:** stop here; a human triggers the gates.
|
|
110
124
|
- **Run by the orchestrator** (`yad-run`): this skill still just produces the committed branch and
|
|
111
125
|
signals success (or a scope/contract halt). The orchestrator records the `implement` step's status
|
|
112
|
-
and trust entry and, when `implement` is
|
|
126
|
+
and trust entry and, when `implement` is set to `advance: auto` (`yad dial`), **auto-runs
|
|
113
127
|
the check gates** instead of waiting for a manual nudge. The diff still cannot merge without the
|
|
114
128
|
gates passing and the engineer review — Step D removes only the "now run the gates" hand-off.
|
|
115
129
|
|
|
116
130
|
### Step 8 — Record the `tasks` trust signal on first consume (Phase 4b)
|
|
117
131
|
Resolving a task from `tasks.md` (Step 1) is the moment the generated task list "survives contact" —
|
|
118
|
-
the
|
|
132
|
+
part of the run record `yad dial` shows beside the `tasks` dial. When driven by `yad-run`,
|
|
119
133
|
finalize a `tasks` trust entry, anchored to what the human/dev actually did with the list:
|
|
120
134
|
- the task is implemented with its declared `Files:`/scope **as generated** → `approved-unchanged`;
|
|
121
135
|
- the task is **re-scoped** first (its `Files:`/boundary edited) → `approved-with-edits`
|
|
@@ -124,8 +138,8 @@ finalize a `tasks` trust entry, anchored to what the human/dev actually did with
|
|
|
124
138
|
Write the entry to its own shard `epics/<epic>/.sdlc/trust-log/<story>-<repo>-tasks-<uid>.json` (a fresh
|
|
125
139
|
`uid` per run, so concurrent writers never conflict; readers union the folded `trust-log.json` + the
|
|
126
140
|
loose shards, skipping any shard whose full `(story, repo, step, uid)` already appears folded — a
|
|
127
|
-
half-applied `yad tidy up` — so entries are never double-counted). Schema: `../yad-epic/references/state-schema.md`.
|
|
128
|
-
the
|
|
141
|
+
half-applied `yad tidy up` — so entries are never double-counted). Schema: `../yad-epic/references/state-schema.md`. The record is advice: the `tasks` dial
|
|
142
|
+
is whatever the team sets with `yad dial`. (The `implement` step's own verdict is finalized later,
|
|
129
143
|
at the engineer review in `yad-engineer-review`: merged as authored → `approved-unchanged`; edited first →
|
|
130
144
|
`approved-with-edits`; scope/contract/checks halt → `rejected`.)
|
|
131
145
|
|
|
@@ -136,7 +150,7 @@ at the engineer review in `yad-engineer-review`: merged as authored → `approve
|
|
|
136
150
|
- **Never widen the contract here.** Surface changes go back to the architecture gate (Step 5).
|
|
137
151
|
- **The step never advances itself.** A scope overrun or contract touch always halts. The
|
|
138
152
|
`implement → checks` hand-off advances only when the orchestrator's `implement` dial is
|
|
139
|
-
`
|
|
153
|
+
`advance: auto` (`yad dial`) — and never past the engineer review, which is always human.
|
|
140
154
|
Standalone, the step stops at a committed branch.
|
|
141
155
|
|
|
142
156
|
## Reference
|
|
@@ -89,8 +89,8 @@ The **locked contract surface** is the cross-repo agreement in `epics/<epic>/con
|
|
|
89
89
|
change; no trailer.
|
|
90
90
|
- **Changing the contract** (exceptional) — altering the agreed shape itself (new field crossing repos,
|
|
91
91
|
changed status enum, new shared endpoint). This is **not** an implementation decision. Stop, go back
|
|
92
|
-
to the **architecture gate**, amend and re-lock `contract.md` (which
|
|
93
|
-
|
|
92
|
+
to the **architecture gate**, amend and re-lock `contract.md` (which sends that review round again; its contract `risk_tags`
|
|
93
|
+
raise the full approver count, which is advisory — E72 reports it capped at the active people less one), and only then implement — recording `Contract-Change: yes` so the §C
|
|
94
94
|
contract-check finds the matching, already-updated contract.
|
|
95
95
|
|
|
96
96
|
This keeps the contract singular and owned upstream: a code repo can never widen the shared surface
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: yad-learn
|
|
3
|
-
description: 'The cross-cutting learning layer: at ANY SDLC stage, a team member can ask to learn a concept and be tutored in the context of what the team is building. Routes the request to the connected learning tool (.sdlc/learning.json, DeepTutor-first) grounded in the project knowledge base, or degrades to harness-native tutoring (the harness model reading the artifacts) when no tool is connected. Renders a tutorial artifact and appends to a per-member learning ledger that is kept LOCAL-ONLY — gitignored, never committed or pushed to the
|
|
3
|
+
description: 'The cross-cutting learning layer: at ANY SDLC stage, a team member can ask to learn a concept and be tutored in the context of what the team is building. Routes the request to the connected learning tool (.sdlc/learning.json, DeepTutor-first) grounded in the project knowledge base, or degrades to harness-native tutoring (the harness model reading the artifacts) when no tool is connected. Renders a tutorial artifact and appends to a per-member learning ledger that is kept LOCAL-ONLY — gitignored, never committed or pushed to the Product or any code repo — so it stays a private, personal skills log (yad-status rolls up the local records). Purely opt-in — it NEVER blocks a gate and never touches epic state, approvals, or the contract lock. Use when the user says "teach me <concept>", "learn about <concept>", or "yad-learn".'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# SDLC — Learn (the cross-cutting tutor)
|
|
@@ -13,8 +13,8 @@ therefore their **control over what is being built** — explicit, without ever
|
|
|
13
13
|
to the team.
|
|
14
14
|
|
|
15
15
|
**Learning output is LOCAL-ONLY.** The records ledger and the rendered tutorials are personal artifacts:
|
|
16
|
-
they are **gitignored and must never be committed or pushed** — not to the
|
|
17
|
-
code repo. The skill ensures the
|
|
16
|
+
they are **gitignored and must never be committed or pushed** — not to the Product and not to any
|
|
17
|
+
code repo. The skill ensures the Product's `.gitignore` lists these paths before it writes them. The
|
|
18
18
|
only committed, shared learning file is the connection registry `.sdlc/learning.json` (no secrets, no
|
|
19
19
|
personal data) — written by `yad-connect-learning`, not here.
|
|
20
20
|
|
|
@@ -24,7 +24,7 @@ approvals ledger, or the contract lock. It writes only the local learning ledger
|
|
|
24
24
|
|
|
25
25
|
## Conventions
|
|
26
26
|
|
|
27
|
-
- `{project-root}` resolves from the project working directory (the **
|
|
27
|
+
- `{project-root}` resolves from the project working directory (the **Product**).
|
|
28
28
|
- The tutor is reached via the project's learning connection (`.sdlc/learning.json`, written by
|
|
29
29
|
`yad-connect-learning`). **DeepTutor-first** (a CLI subprocess); when no tool is connected (or the
|
|
30
30
|
`deeptutor` binary is absent) it degrades to **harness-native** tutoring — the harness model reads the
|
|
@@ -35,7 +35,7 @@ approvals ledger, or the contract lock. It writes only the local learning ledger
|
|
|
35
35
|
- When no epic is scoped, records go to `.sdlc/learning-records.json` and tutorials to `.sdlc/learning/`
|
|
36
36
|
(cross-project learning).
|
|
37
37
|
- **Local-only, never committed.** All of the above paths are personal output. Before writing any of
|
|
38
|
-
them, ensure the **
|
|
38
|
+
them, ensure the **Product's** `.gitignore` ignores learning output (idempotent — append only if
|
|
39
39
|
the lines are absent):
|
|
40
40
|
```
|
|
41
41
|
# yadflow learning layer — personal, local-only (never commit or push)
|
|
@@ -44,10 +44,10 @@ approvals ledger, or the contract lock. It writes only the local learning ledger
|
|
|
44
44
|
epics/*/.sdlc/learning-records.json
|
|
45
45
|
epics/*/learning/
|
|
46
46
|
```
|
|
47
|
-
Never write learning output into a connected **code repo** — it lives only in the
|
|
47
|
+
Never write learning output into a connected **code repo** — it lives only in the Product, and only
|
|
48
48
|
on the local machine. `.sdlc/learning.json` (the connection registry) is the sole committed learning
|
|
49
49
|
file and is NOT ignored.
|
|
50
|
-
- Speak in the
|
|
50
|
+
- Speak in the `communication_language` set in `{project-root}/.sdlc/config.yaml`; write tutorials in `document_output_language`.
|
|
51
51
|
|
|
52
52
|
## Inputs
|
|
53
53
|
|
|
@@ -84,7 +84,7 @@ Keep the tutorial focused (usually < 600 words): explain the concept, then tie i
|
|
|
84
84
|
example from this project** (an artifact line, a contract field, a story).
|
|
85
85
|
|
|
86
86
|
### Step 2 — Render the tutorial artifact (local-only)
|
|
87
|
-
First ensure the
|
|
87
|
+
First ensure the Product's `.gitignore` lists the learning-output paths (see Conventions — append the
|
|
88
88
|
block only if absent, so the artifacts can never be committed or pushed). Then write the tutorial to
|
|
89
89
|
`epics/EP-<slug>/learning/<member>--<concept-slug>.md` (or `.sdlc/learning/` when no epic is scoped).
|
|
90
90
|
Front-matter the file with `member`, `concept`, `stage`, `tool`, and `requestedAt`.
|
|
@@ -130,7 +130,7 @@ there is no approval and no gate. The learner runs `action: complete` (below) wh
|
|
|
130
130
|
- **Read-only except the learning ledger.** It writes only `learning-records.json` + tutorial artifacts;
|
|
131
131
|
it never touches `state.json`, `approvals.json`, `comments.json`, or the contract lock.
|
|
132
132
|
- **Local-only output.** The records ledger and tutorials are gitignored personal artifacts — never
|
|
133
|
-
commit or push them, and never write them into a code repo. Ensure the
|
|
133
|
+
commit or push them, and never write them into a code repo. Ensure the Product `.gitignore` covers them
|
|
134
134
|
before writing (see Conventions).
|
|
135
135
|
- **Always works.** No DeepTutor / no connection → tutor harness-native. Never fail because a tool is
|
|
136
136
|
absent.
|
|
@@ -12,7 +12,7 @@ evidence base for the **local skills-log roll-up** in `yad-status`.
|
|
|
12
12
|
(`config.yaml` `learning.records` and `learning.artifacts`.)
|
|
13
13
|
|
|
14
14
|
**Local-only.** Every path above is personal output and is **gitignored — never committed or pushed**, to
|
|
15
|
-
the
|
|
15
|
+
the Product or any code repo. `yad-learn` ensures the Product `.gitignore` lists them before writing. The
|
|
16
16
|
only committed learning file is the connection registry `.sdlc/learning.json`.
|
|
17
17
|
|
|
18
18
|
## Record schema
|
|
@@ -42,7 +42,7 @@ only committed learning file is the connection registry `.sdlc/learning.json`.
|
|
|
42
42
|
- **No secrets.** Records hold concept text + references only — never keys or raw tool output beyond the
|
|
43
43
|
rendered tutorial.
|
|
44
44
|
- **Never commit the ledger or tutorials.** They are personal, local-only artifacts: gitignored, never
|
|
45
|
-
committed or pushed (to the
|
|
45
|
+
committed or pushed (to the Product or a code repo). Only `.sdlc/learning.json` is committed.
|
|
46
46
|
|
|
47
47
|
## Mode → DeepTutor capability
|
|
48
48
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: yad-open-pr
|
|
3
|
-
description: 'Build helper of the gated SDLC. Open a code-repo task PR/MR from the committed platform template — detect GitHub/GitLab, push the current task branch, and create the PR/MR with the template body prefilled (Summary / Story-task / Impact & Risk) and the title defaulting to the commit subject.
|
|
3
|
+
description: 'Build helper of the gated SDLC. Open a code-repo task PR/MR from the committed platform template — detect GitHub/GitLab, push the current task branch, and create the PR/MR with the template body prefilled (Summary / Story-task / Impact & Risk) and the title defaulting to the commit subject. Assigns the PR/MR to the logged-in gh/glab login and requests no reviewers (ask them on the PR itself); prints a reviewer suggestion from recent history and CODEOWNERS, a hint and never a request. High risk / contract surface raises the approver count (risk-route.sh prints it). Drives the `yad open-pr` CLI; never merges. Use when the user says "open the PR", "open the MR", or "raise the merge request".'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# SDLC — Open Task PR/MR (Build helper)
|
|
7
7
|
|
|
8
8
|
**Goal:** Open the PR/MR for the current task branch from the repo's committed PR/MR template
|
|
9
|
-
(installed by `yad-pr-template`, Step D), with the body prefilled and the
|
|
9
|
+
(installed by `yad-pr-template`, Step D), with the body prefilled and the assignee set.
|
|
10
10
|
This is the standalone open-PR step; it **never merges** — the engineer review (`yad-engineer-review`,
|
|
11
11
|
Step E) owns the merge. Distinct from `yad gate open`, which opens a Shape artifact-review PR on
|
|
12
|
-
the
|
|
12
|
+
the Product.
|
|
13
13
|
|
|
14
14
|
## Conventions
|
|
15
15
|
|
|
@@ -19,19 +19,20 @@ the product hub.
|
|
|
19
19
|
- **Title** — defaults to the last commit subject (one atomic task = one branch = one PR/MR), so it
|
|
20
20
|
follows the same Conventional-Commits style and passes the `pr-title` gate. Override with `--title`.
|
|
21
21
|
- **Body** — the committed template (`.github/pull_request_template.md` /
|
|
22
|
-
`.gitlab/merge_request_templates/Default.md`) with
|
|
23
|
-
|
|
22
|
+
`.gitlab/merge_request_templates/Default.md`) with the Summary (from the commit), the story/task id and
|
|
23
|
+
its `specs/` path, `Risk level:`, `Contract surface touched:`, and `Domains` (the repo name when
|
|
24
|
+
`--repo` is passed) prefilled; the rest is left for the author. This satisfies the `pr-template`
|
|
24
25
|
gate.
|
|
25
|
-
- **Stage-aware on the
|
|
26
|
+
- **Stage-aware on the Product** — `open-pr` mirrors the `--head` split the Product gates apply:
|
|
26
27
|
- a **`review/EP-*/<artifact>`** branch is a Shape artifact-review PR → it **delegates to
|
|
27
|
-
`yad gate open`** (artifact-review title `review: <artifact> (EP-<slug>)`, the
|
|
28
|
+
`yad gate open`** (artifact-review title `review: <artifact> (EP-<slug>)`, the Product artifact-review
|
|
28
29
|
body, and the gate ledger bookkeeping all in one place). Any `--title`/`-m` is ignored here.
|
|
29
|
-
- any **other
|
|
30
|
-
(`## Summary` / `Risk level:` / `## Checklist`) instead of the
|
|
31
|
-
`pull_request_template.md`, so the
|
|
30
|
+
- any **other Product branch** is a tooling/CI change → it uses the bundled **code-task** template
|
|
31
|
+
(`## Summary` / `Risk level:` / `## Checklist`) instead of the Product's artifact-review
|
|
32
|
+
`pull_request_template.md`, so the Product `pr-template` gate passes.
|
|
32
33
|
In a code repo nothing changes — it reads the repo's own committed code-task template.
|
|
33
34
|
- **Base branch** — **resolved, never assumed.** In order: `--base` → the repo's `default_branch` in
|
|
34
|
-
`.sdlc/repos.json` → (for a PR against the
|
|
35
|
+
`.sdlc/repos.json` → (for a PR against the Product itself) `hub.json`'s `default_branch` → what the
|
|
35
36
|
platform reports (`gh repo view --json defaultBranchRef` / `glab api projects/:id`) → local
|
|
36
37
|
`origin/HEAD` → `main`. The same **configuration-outranks-the-remote** order `yad repo sync` and the
|
|
37
38
|
contract-check gate already use (they stop at `origin/HEAD`; only this chain also asks the platform).
|
|
@@ -41,18 +42,28 @@ the product hub.
|
|
|
41
42
|
auto-review eligibility from the base at PR-**open** time, and retargeting afterwards does not undo
|
|
42
43
|
the skip. Hardcoding `main` here is the same bug the check gates already refuse to make (see
|
|
43
44
|
`../yad-checks/references/check-gates.md`).
|
|
44
|
-
- **
|
|
45
|
-
the
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
- **Assignee** — the person opening it: `@me` on GitHub (`gh` resolves it on the repo's own host), and
|
|
46
|
+
on GitLab the login `glab` reports (no assignee is passed when that lookup fails). **No reviewers are
|
|
47
|
+
requested** (E62): yadflow keeps no list of people. The CLI prints `no
|
|
48
|
+
reviewers were requested — ask them on the PR itself`. For a `high` directory the CLI names the people
|
|
49
|
+
who have worked there lately (E67, Step 3). For every code-repo change it also prints a reviewer **suggestion**
|
|
50
|
+
(E68, Step 3a): who has committed in the touched folders lately, and what CODEOWNERS lists — a hint
|
|
51
|
+
only, never a request.
|
|
52
|
+
- **Routing** — the merge needs 1 approval from someone other than the author (the base). `high` risk
|
|
53
|
+
adds 1, a touched contract surface adds 2, and a change touching a `high` directory on the base
|
|
54
|
+
branch's risk map adds 1 (E66) — the larger, never the sum. That risk step is advisory: branch
|
|
55
|
+
protection holds the merge, never this count. The CLI prints the count once the PR is open — capped by
|
|
56
|
+
the active people (E72) when run from the Product — for example `this PR asks for 3 approvers = base 1
|
|
57
|
+
+ contract risk 2, capped to 1 for 2 active people — base enforced, risk step advisory; …` — and prints the count of people on its
|
|
58
|
+
own line (`active people: not counted — no cap applies; …` when it cannot count them).
|
|
59
|
+
`bash checks/risk-route.sh <body>` prints the same count from the PR body, without the cap: a code
|
|
60
|
+
repo's CI has no Product to count people from.
|
|
50
61
|
|
|
51
62
|
## Inputs
|
|
52
63
|
|
|
53
64
|
- `repo` — target a registered repo by name (optional; else the current dir).
|
|
54
65
|
- `risk` — `low|medium|high` (default `low`); prefilled into the body.
|
|
55
|
-
- `contractChange` — flag; marks the contract surface touched and
|
|
66
|
+
- `contractChange` — flag; marks the contract surface touched and raises the approver count.
|
|
56
67
|
- `base` — override the PR/MR base (optional; defaults to the repo's own default branch —
|
|
57
68
|
see **Base branch** above). Only pass it deliberately: a non-default base loses the AI first pass.
|
|
58
69
|
- `platform` / `title` — optional overrides.
|
|
@@ -69,8 +80,8 @@ Run from the repo root:
|
|
|
69
80
|
yad open-pr [--repo <name>] [--risk <level>] [--contract-change] [--title "<subject>"]
|
|
70
81
|
```
|
|
71
82
|
The CLI pushes the branch (sets upstream, the user's own auth), fills the template, and creates the
|
|
72
|
-
PR/MR with the
|
|
73
|
-
from.
|
|
83
|
+
PR/MR with the assignee set and no reviewers requested. It prints the base it resolved and where that
|
|
84
|
+
came from.
|
|
74
85
|
|
|
75
86
|
The non-default-base warning is **advisory — it does not block, and the PR/MR is already open by the
|
|
76
87
|
time you read it.** If the base was intended (a stacked PR, a release branch), carry on. If it was
|
|
@@ -78,9 +89,33 @@ not, do **not** just retarget the open PR — that leaves the AI first pass skip
|
|
|
78
89
|
cause (the repo's `default_branch`, or drop the wrong `--base`), and re-run `yad open-pr` so the PR
|
|
79
90
|
is *created* against the right base.
|
|
80
91
|
|
|
81
|
-
### Step 3 — Route the review (if
|
|
82
|
-
|
|
83
|
-
|
|
92
|
+
### Step 3 — Route the review (if the count is raised)
|
|
93
|
+
Once the PR is open, the CLI prints how many approvers it asks for — the same count the engineer review
|
|
94
|
+
(`yad-engineer-review`) uses. It joins the body's level (`--risk`, `--contract-change`) with the code
|
|
95
|
+
repo's risk map on `origin/<base>`: a change touching a `high` directory adds 1 even when the body says
|
|
96
|
+
`low`, and the CLI warns that the two disagree. It also names who has **committed in those directories
|
|
97
|
+
in the last 30 days** (E67) — the people who can meet that ask — or says plainly that nobody has, or
|
|
98
|
+
that the history could not be read. It only prints; the body keeps the author's level. If
|
|
99
|
+
the level in the body is wrong, fix the body on the PR. When the map cannot be read (no `origin/<base>`
|
|
100
|
+
fetched, a newer map), it says so and counts the body alone. `bash checks/risk-route.sh "<pr body>"`
|
|
101
|
+
also lists the touched domains as a hint for whom to ask; request those reviewers on the PR/MR yourself.
|
|
102
|
+
|
|
103
|
+
### Step 3a — Relay the reviewer suggestion (E68)
|
|
104
|
+
The CLI then prints two hints about whom to ask, on separate lines: the people who have **committed in
|
|
105
|
+
the folders this change touches in the last 30 days** (base branch; the change's own authors and robots
|
|
106
|
+
left out; ranked by commits, five shown), and what **CODEOWNERS on the base branch** lists for the changed
|
|
107
|
+
files. Relay both as they are. It is a **suggestion only**:
|
|
108
|
+
|
|
109
|
+
- Never request those people as reviewers on the PR/MR yourself, and never call them owners or required
|
|
110
|
+
approvers. A name is a hint about who **may** know the code. The author decides whom to ask.
|
|
111
|
+
- CODEOWNERS is a hint: these files go stale. A `CODEOWNERS line N not read — …` line is a line yadflow
|
|
112
|
+
could not match safely (the first three get a reason, the rest a count, and the list then says it
|
|
113
|
+
`may be wrong`); mention it, do not guess what it meant.
|
|
114
|
+
If the author asks whether CODEOWNERS is out of date, run `yad codeowners check <repo>` (E69) and relay
|
|
115
|
+
it. Never edit CODEOWNERS for them: a name written there becomes an owner the platform can enforce.
|
|
116
|
+
- The same person can appear in both lists under two names (a git name, a platform login). Do not join
|
|
117
|
+
them unless the output says `also in the 30-day history` (only a `noreply` login of the same platform counts, and only on github.com or gitlab.com).
|
|
118
|
+
- `not read` (a shallow clone, a missing base) is never "nobody". Say it as the CLI says it.
|
|
84
119
|
|
|
85
120
|
### Step 3b — Post the review trailer (optional, recommended)
|
|
86
121
|
Make the reviewer's job easy: generate the 60-sec briefing and post it to the new PR/MR so it greets
|
|
@@ -93,8 +128,8 @@ The full fun-review flow (cards + grounded chat + engagement) is driven by the
|
|
|
93
128
|
design — companion comments carry `<!-- yad:noblock -->`.
|
|
94
129
|
|
|
95
130
|
### Step 4 — Stop (no merge)
|
|
96
|
-
Report the PR/MR URL and
|
|
97
|
-
engineer review and merge happen in `yad-engineer-review` (Step E).
|
|
131
|
+
Report the PR/MR URL and that no reviewers were requested. The PR now runs the check gates (Step C);
|
|
132
|
+
the human engineer review and merge happen in `yad-engineer-review` (Step E).
|
|
98
133
|
|
|
99
134
|
## Hard rules
|
|
100
135
|
|
|
@@ -102,7 +137,7 @@ engineer review and merge happen in `yad-engineer-review` (Step E).
|
|
|
102
137
|
- **The base is the repo's default branch** unless you deliberately chose otherwise with `--base`.
|
|
103
138
|
Never hardcode `main`, and never ignore the non-default-base warning silently.
|
|
104
139
|
- **Title follows the commit subject** — Conventional-Commits style, so the `pr-title` gate passes.
|
|
105
|
-
- **High risk
|
|
140
|
+
- **High risk raises the approver count** — the same count as the gate; never a separate rule.
|
|
106
141
|
- **Opening a PR never merges.** The human owns the merge in Step E.
|
|
107
142
|
|
|
108
143
|
## Reference
|
|
@@ -26,14 +26,14 @@ platform.**
|
|
|
26
26
|
|
|
27
27
|
## Conventions
|
|
28
28
|
|
|
29
|
-
- `{project-root}` resolves from the project working directory — the **
|
|
29
|
+
- `{project-root}` resolves from the project working directory — the **Product**.
|
|
30
30
|
- Build (code PR/MR): grounded by `yad review walkthrough --repo <r> --pr <n>`.
|
|
31
31
|
- Shape (artifact-review PR/MR): grounded by `yad gate walkthrough <epic> [artifact]`.
|
|
32
32
|
- The transferable review method + scorecard live in `references/review-rubric.md`.
|
|
33
33
|
- The session-record comment shape, the dual sign-off, and the learning record this writes live in
|
|
34
34
|
`references/session-state.md` (it reuses [`yad-learn`](../yad-learn/SKILL.md)'s ledger + gitignore
|
|
35
35
|
discipline **verbatim** — the learning output is **local-only, never committed or pushed**).
|
|
36
|
-
- Speak in the
|
|
36
|
+
- Speak in the `communication_language` set in `{project-root}/.sdlc/config.yaml`; write any rendered tutorial in
|
|
37
37
|
`document_output_language`.
|
|
38
38
|
|
|
39
39
|
## Inputs
|
|
@@ -49,7 +49,9 @@ platform.**
|
|
|
49
49
|
Run the walkthrough grounding for the half you're on:
|
|
50
50
|
- Build: `yad review walkthrough --repo <r> --pr <n>` → prints the grounding bundle **plus an ordered
|
|
51
51
|
`stops[]`** (the code diff parsed into hunk-anchored, risk-tagged review stops, highest-risk first).
|
|
52
|
-
- Shape: `yad gate walkthrough <epic> [artifact]` → the same, over the artifact's review diff.
|
|
52
|
+
- Shape: `yad gate walkthrough <epic> [artifact]` → the same, over the artifact's review diff. Its
|
|
53
|
+
`step.gateRule` carries the step's full approver count (`needed` distinct people, and the `risk`
|
|
54
|
+
tier that set it), and `step.cap` — an object `{ active, limit, to, capped }`: `to` is the count capped by the active people (E72), `capped` is true when the cap lowered it, and the whole field is `null` when the people were not counted — useful context for how hard a step is being reviewed, never a pass/fail input.
|
|
53
55
|
|
|
54
56
|
**Read the real material yourself** — run the bundle's `diffCmd`, and read the named `codeMap` / `pack` /
|
|
55
57
|
`contract` / `artifactPath` / `specs/<story>/` files. Never invent content. If a stop's material isn't
|
|
@@ -105,7 +107,7 @@ addresses them) — nothing advances on a half-finished session.
|
|
|
105
107
|
`engineer-review` (back) / `<artifact>-review` (front), `mode` = `deep` (or `quiz` when you scored
|
|
106
108
|
comprehension), `comprehension` = the scorecard roll-up, `tutorial` = a rendered
|
|
107
109
|
`learning/<member>--review-<pr>.md` capturing the method as applied to this PR + the engineer's gaps.
|
|
108
|
-
**First ensure the
|
|
110
|
+
**First ensure the Product `.gitignore` covers the learning paths** (reuse yad-learn's guard), then write —
|
|
109
111
|
these are personal, gitignored, **never committed or pushed**. The growth rolls up under `yad status`
|
|
110
112
|
"My skills".
|
|
111
113
|
|
|
@@ -127,7 +129,7 @@ addresses them) — nothing advances on a half-finished session.
|
|
|
127
129
|
|
|
128
130
|
## local mode (no platform)
|
|
129
131
|
|
|
130
|
-
With no
|
|
132
|
+
With no Product platform there is no PR to post to: write the session record to
|
|
131
133
|
`reviews/<base>--<date>--pair-session.md` alongside the existing `reviews/*.md`, and the human records
|
|
132
134
|
approval the manual way via [`yad-review-gate`](../yad-review-gate/SKILL.md). The learning record is
|
|
133
135
|
written exactly the same (it is local-only regardless of platform). The session logic is unchanged; only
|
|
@@ -30,7 +30,7 @@ This is the "review **is** the lesson" half. It reuses [`yad-learn`](../../yad-l
|
|
|
30
30
|
schema and gitignore discipline **verbatim** — see `yad-learn/references/learning-state.md`. Do not
|
|
31
31
|
invent a new store.
|
|
32
32
|
|
|
33
|
-
**Before writing anything**, ensure the **
|
|
33
|
+
**Before writing anything**, ensure the **Product's** `.gitignore` covers the learning paths
|
|
34
34
|
(idempotent — append only if absent), the same block yad-learn uses:
|
|
35
35
|
|
|
36
36
|
```
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: yad-pr-template
|
|
3
|
-
description: 'Build Step D of the gated SDLC. Detect a code repo''s platform and commit the matching PR/MR template — .github/pull_request_template.md (GitHub) or .gitlab/merge_request_templates/Default.md (GitLab). The template carries an Impact & Risk block; a high risk level (or a touched contract
|
|
3
|
+
description: 'Build Step D of the gated SDLC. Detect a code repo''s platform and commit the matching PR/MR template — .github/pull_request_template.md (GitHub) or .gitlab/merge_request_templates/Default.md (GitLab). The template carries an Impact & Risk block; a high risk level (or a touched contract surface) raises the approver count, the same count yad-review-gate prints. Includes risk-route.sh to print that count from a PR body. Never auto-advances. Use when the user says "add the PR template" or "set up the MR template" for a repo.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# SDLC — PR/MR Template (Build Step D)
|
|
7
7
|
|
|
8
8
|
**Goal:** Commit the platform-correct PR/MR template into a code repo so every PR/MR carries an
|
|
9
9
|
**Impact & Risk** block and a checklist tied to the check gates. A **high** risk level (or a touched
|
|
10
|
-
contract
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
contract surface) **raises the approver count** — the same count `yad-review-gate` prints on
|
|
11
|
+
the Shape gates: base 1 (someone other than the author, enforced) plus a risk step (`high` +1, contract
|
|
12
|
+
+2, advisory — branch protection holds the merge; `yad open-pr` shows the count capped by the active
|
|
13
|
+
people). This step **never auto-advances**; it sets up the template and the
|
|
14
|
+
routing helper.
|
|
13
15
|
|
|
14
16
|
## Conventions
|
|
15
17
|
|
|
@@ -21,11 +23,12 @@ touched domain). This step **never auto-advances**; it sets up the template and
|
|
|
21
23
|
- `templates/gitlab/merge_request_templates/Default.md` → installs to
|
|
22
24
|
`<repo>/.gitlab/merge_request_templates/Default.md`
|
|
23
25
|
- `templates/checks/risk-route.sh` → installs to `<repo>/checks/risk-route.sh` (advisory routing helper)
|
|
24
|
-
- **
|
|
26
|
+
- **Product variants** (`repo: hub`) — Shape artifact-review PR/MR bodies:
|
|
25
27
|
`templates/hub/github/pull_request_template.md` → `{project-root}/.github/pull_request_template.md`;
|
|
26
28
|
`templates/hub/gitlab/merge_request_templates/Default.md` →
|
|
27
|
-
`{project-root}/.gitlab/merge_request_templates/Default.md`. The
|
|
28
|
-
(
|
|
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-hub-bridge`'s
|
|
31
|
+
`templates/checks/hub-route.sh`, run from the skill (nothing installs it into the Product's `checks/`).
|
|
29
32
|
- **GitLab reads a truncated description.** The `pr-template` gate is fed
|
|
30
33
|
`$CI_MERGE_REQUEST_DESCRIPTION`, which GitLab cuts at **2700 characters** — a required section below
|
|
31
34
|
that cutoff is invisible to the gate even though the MR shows it, and the failure reads "does not use
|
|
@@ -33,14 +36,15 @@ touched domain). This step **never auto-advances**; it sets up the template and
|
|
|
33
36
|
`## Impact & Risk` / `## Checklist` (hub: `## Artifact under review` / `## Impact & Risk (front-half)`
|
|
34
37
|
/ `## Checklist`) early, so a truncated body still passes. Long narrative goes **after** them.
|
|
35
38
|
Sections may be reordered freely; deleting one fails the gate. GitHub is unaffected.
|
|
36
|
-
- **Installed templates are yad-managed.** `yad update` rewrites them on upgrade
|
|
39
|
+
- **Installed code-repo templates are yad-managed.** `yad update` rewrites them on upgrade (the Product
|
|
40
|
+
variants under `templates/hub/` are copied by hand in Step 2 and are not managed). An edit yad can
|
|
37
41
|
prove — the file's sha differs from the one it recorded when it wrote the template — is reported as
|
|
38
42
|
`modified` and left alone; a copy it has no record of is replaced after a `.yad-orig` backup (see
|
|
39
43
|
`docs/CLI.md` → *Managed files*). Either way, put knowledge that must survive an upgrade in an ADR
|
|
40
44
|
under `docs/`, not in the template.
|
|
41
45
|
- The Impact & Risk block reuses the conventions of earlier steps: the `Task: <story>-<task>` trailer
|
|
42
46
|
(`yad-implement`), the contract surface (`yad-architecture` / contract-check), and the
|
|
43
|
-
|
|
47
|
+
approver count (`yad-review-gate`).
|
|
44
48
|
- **PR/MR title.** One atomic task = one branch = one PR/MR, so the title **defaults to that task's
|
|
45
49
|
commit subject** and follows the same Conventional Commits style — `<type>: <lowercase imperative
|
|
46
50
|
description, no trailing period>`, proper nouns/acronyms keep their case (`config.yaml`
|
|
@@ -50,8 +54,8 @@ touched domain). This step **never auto-advances**; it sets up the template and
|
|
|
50
54
|
|
|
51
55
|
## Inputs
|
|
52
56
|
|
|
53
|
-
- `repo` — the code repo to add the template to (one of an epic's repos), or `hub` for the
|
|
54
|
-
- `action` — `wire` (commit the matching template + helper) | `route` (print
|
|
57
|
+
- `repo` — the code repo to add the template to (one of an epic's repos), or `hub` for the Product.
|
|
58
|
+
- `action` — `wire` (commit the matching template + helper) | `route` (print the approver count from a
|
|
55
59
|
PR body). Default `wire`.
|
|
56
60
|
- `body` — for `route`: a file holding the PR/MR description to evaluate.
|
|
57
61
|
|
|
@@ -68,24 +72,41 @@ Copy from this skill's `templates/`:
|
|
|
68
72
|
- GitLab → `templates/gitlab/merge_request_templates/Default.md` to
|
|
69
73
|
`<repo>/.gitlab/merge_request_templates/Default.md`.
|
|
70
74
|
- **`repo: hub`** → use the `templates/hub/<platform>/…` variants, installed into `{project-root}`'s own
|
|
71
|
-
`.github/`/`.gitlab/`. The
|
|
75
|
+
`.github/`/`.gitlab/`. The Product's routing helper (`hub-route.sh`) stays in `yad-hub-bridge`'s
|
|
76
|
+
`templates/checks/`; neither this skill nor `yad setup` / `yad check --fix` installs it.
|
|
72
77
|
Drop **only the matching** template (drop both only if the repo genuinely uses both). For code repos also
|
|
73
|
-
install `templates/checks/risk-route.sh` to `<repo>/checks/` (`chmod +x`)
|
|
78
|
+
install `templates/checks/risk-route.sh` to `<repo>/checks/` (`chmod +x`), beside
|
|
79
|
+
`../yad-checks/templates/checks/risk-map-check.sh` — risk-route reads the risk map through it, and
|
|
80
|
+
without it every count says "not counted". `yad update` installs both. If the target already has a
|
|
74
81
|
non-SDLC PR/MR template, do not clobber it — back it up / ask. Commit the template on the repo's default
|
|
75
82
|
branch (shared infrastructure, not a task diff).
|
|
76
83
|
|
|
77
|
-
### Step 3 — `route` (show
|
|
78
|
-
Run `bash checks/risk-route.sh <body
|
|
79
|
-
|
|
80
|
-
- **low | medium** risk →
|
|
81
|
-
- **high** risk
|
|
82
|
-
|
|
83
|
-
|
|
84
|
+
### Step 3 — `route` (show how many approvers)
|
|
85
|
+
Run `bash checks/risk-route.sh <body> [<base>]` **inside the code repo, on the PR's branch** to parse the
|
|
86
|
+
PR description's Impact & Risk block, read the base branch's risk map, and print the approver count:
|
|
87
|
+
- **low | medium** risk → `ROUTE: 1 approver = base 1 (no risk step).`
|
|
88
|
+
- **high** risk → `ROUTE: 2 approvers = base 1 + high risk 1 (risk: high)`.
|
|
89
|
+
- a **contract surface** touched → `ROUTE: 3 approvers = base 1 + contract risk 2 (contract surface
|
|
90
|
+
touched)`. With `high` too, the larger step (contract) wins, never the sum.
|
|
91
|
+
- a change touching a directory the **base branch's** `.sdlc/risk-map` marks `high` → +1 as well (E66),
|
|
92
|
+
even when the body says `low`: the larger step wins, and the script says the two disagree. A `guessed`
|
|
93
|
+
level counts. When the map cannot be read, it says so and counts the body alone.
|
|
94
|
+
- that same `high` directory asks for an approval from someone who **committed there in the last 30
|
|
95
|
+
days** (E67). The script names them from the base branch's history, without this change's own authors,
|
|
96
|
+
as one list across every `high` directory touched; "nobody" and "not read" are said apart.
|
|
84
97
|
|
|
85
|
-
When the
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
98
|
+
When the count is raised, the script adds that branch protection holds the merge, not this count (at
|
|
99
|
+
least 1 approval from someone other than the author), that the risk step is advisory and not capped
|
|
100
|
+
there (`yad open-pr` shows the count capped by the active people), and lists the touched
|
|
101
|
+
domains as a hint for whom to ask. The actual approvals are recorded by the engineer review (Step E),
|
|
102
|
+
via `yad-review-gate`.
|
|
103
|
+
|
|
104
|
+
When the PR/MR is actually opened with `yad open-pr`, **no reviewers are requested** — it prints `no
|
|
105
|
+
reviewers were requested — ask them on the PR itself`. The **assignee** is the person opening it: `@me`
|
|
106
|
+
on GitHub (resolved by `gh`), and on GitLab the login `glab` reports (no assignee is passed when that
|
|
107
|
+
lookup fails). yadflow keeps no list of people. After opening, it prints a reviewer suggestion (E68):
|
|
108
|
+
who has committed in the touched folders in the last 30 days, and what CODEOWNERS lists — a hint only,
|
|
109
|
+
never a request.
|
|
89
110
|
|
|
90
111
|
### Step 4 — Stop (no auto-advance)
|
|
91
112
|
Report what was committed (or the routing result). The template and routing are advisory inputs to the
|
|
@@ -94,10 +115,10 @@ human review (Step E); they do not approve or merge. Do not touch the epic's `.s
|
|
|
94
115
|
## Hard rules (build plan §D, Cross-cutting)
|
|
95
116
|
|
|
96
117
|
- **Drop only the matching template** for the detected platform.
|
|
97
|
-
- **High risk
|
|
118
|
+
- **High risk raises the approver count** — the same count as the gate; never a separate rule.
|
|
98
119
|
- **Nothing auto-advances.** The template sets up review; the human owns the merge.
|
|
99
120
|
|
|
100
121
|
## Reference
|
|
101
122
|
- The Impact & Risk block, the risk levels, and the routing rule: `references/risk-routing.md`.
|
|
102
|
-
- The
|
|
123
|
+
- The approver count this reuses: `../yad-review-gate/SKILL.md` and its `references/gating.md`.
|
|
103
124
|
- The check gates the checklist references: `../yad-checks/references/check-gates.md`.
|