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
|
@@ -19,7 +19,12 @@ in CI on every PR/MR and must pass before merge (build plan §C). Each is a smal
|
|
|
19
19
|
A claimed `Contract-Change` against an epic that has **no lock at all** fails too: an epic on a short
|
|
20
20
|
lane (`chore`/`spike`) has no architecture step and never locks a surface, so it may consume the
|
|
21
21
|
contract but not change it, and the change belongs to a new epic on `classic`. That failure needs the
|
|
22
|
-
epic's ledger directory to resolve — a Product that is simply not checked out still defers, as before
|
|
22
|
+
epic's ledger directory to resolve — a Product that is simply not checked out still defers, as before,
|
|
23
|
+
except on a repo's **first spec** (no `link.md` on the base names a Product): there a slice change whose
|
|
24
|
+
`product-repo` reaches nothing **fails** (E119), because the PR chose that value itself. Where the
|
|
25
|
+
Product lives is a repo fact once `yad check --fix --push` has merged `.sdlc/product-link.json` into
|
|
26
|
+
the code repo (E120): the gates read it from the base first, and `checks/product-checkout.sh` clones
|
|
27
|
+
the Product there in CI when the `YAD_PRODUCT_TOKEN` secret is set (see `references/check-gates.md`).
|
|
23
28
|
3. **build/test/lint** — standard quality stage; tests must actually exercise new behavior, not just pass.
|
|
24
29
|
CI installs and runs through the package manager declared by the repo's standard
|
|
25
30
|
`package.json#packageManager` field (`npm` and `pnpm` are supported; any other manager stays on
|
|
@@ -29,7 +34,7 @@ in CI on every PR/MR and must pass before merge (build plan §C). Each is a smal
|
|
|
29
34
|
The code-repo `yad-checks` workflow uses Node 22 by default (the build/test/lint job on GitHub; every
|
|
30
35
|
`yad-*` gate job's image in the GitLab fragment) and reads `YAD_NODE_VERSION` (a GitHub repository
|
|
31
36
|
variable or GitLab CI/CD variable) for repos whose declared runtime differs (a declared `packageManager` needs Corepack, so the override must be a line that
|
|
32
|
-
bundles a current one: 20.19+, 22.14+ or 24; Node 25+ dropped it). The Product-side workflows (verified-commits,
|
|
37
|
+
bundles a current one: 20.19+, 22.14+ or 24; Node 25+ dropped it). The Product-side workflows (verified-commits, product-checks, update-guard,
|
|
33
38
|
gate-sync) only run the `yad` CLI and keep their own pinned Node; the variable does not reach them.
|
|
34
39
|
The CI job sets `YAD_TEST_MAX_WORKERS` (default `2`); the gate caps jest/vitest test concurrency at
|
|
35
40
|
that and is a no-op for other runners (see `references/check-gates.md`).
|
|
@@ -58,7 +63,8 @@ in CI on every PR/MR and must pass before merge (build plan §C). Each is a smal
|
|
|
58
63
|
|
|
59
64
|
The Phase 6 gates read the owning epic in the **Product** via `specs/<story>/link.md`'s
|
|
60
65
|
`product-repo` path (like contract-check), and degrade to a PASS-with-note when the Product is not reachable
|
|
61
|
-
from CI.
|
|
66
|
+
from CI. `product-repo` is read from the base, a Product this repo tracks is read from the base commit, and
|
|
67
|
+
`epic:` must be the story ID's prefix — the PR cannot choose what is gated (E117, E118). See `references/check-gates.md` and `skills/yad-change`.
|
|
62
68
|
|
|
63
69
|
The gates are **CI-agnostic bash** in `checks/`; thin pipeline configs invoke them on GitHub Actions
|
|
64
70
|
and GitLab CI. This step is **by hand** in Phase 3 — run the gates with the skill or let CI run them;
|
|
@@ -73,29 +79,31 @@ and GitLab CI. This step is **by hand** in Phase 3 — run the gates with the sk
|
|
|
73
79
|
- Canonical gate sources live in this skill's `templates/` (the source of truth that gets installed
|
|
74
80
|
into each code repo):
|
|
75
81
|
- `templates/checks/{spec-link,contract-check,package-manager,install-deps,build-test-lint,verified-commits,risk-map-check}.sh`
|
|
76
|
-
- `templates/checks/ledger-guard.sh` → **Product-only** gate, active **only in verified mode** —
|
|
77
|
-
carries BOTH a `platform` and `ledger: "verified"` — or, before `yad migrate`, `bridge_enabled`
|
|
82
|
+
- `templates/checks/ledger-guard.sh` → **Product-only** gate, active **only in verified mode** — `product.json`
|
|
83
|
+
(`hub.json` on an older Product) carries BOTH a `platform` and `ledger: "verified"` — or, before `yad migrate`, `bridge_enabled`
|
|
78
84
|
(or the legacy `bridge`) true. The same predicate
|
|
79
85
|
`isVerifiedLedger` (`cli/manifest.mjs`) applies, so the gate and the CLI can never disagree about who owns the
|
|
80
86
|
ledger (#186). A no-op otherwise, when humans legitimately own it. On review PRs it FAILs any
|
|
81
87
|
commit that touches the
|
|
82
|
-
CI-owned gate ledger (`.sdlc/{state,approvals,comments,hub-prs}.json`, `reviews/*.md`) unless it
|
|
83
|
-
is a **verified gate-bot commit** — bot-authored AND platform-Verified
|
|
84
|
-
|
|
88
|
+
CI-owned gate ledger (`.sdlc/{state,approvals,comments,product-prs,hub-prs}.json`, `reviews/*.md`) unless it
|
|
89
|
+
is a **verified gate-bot commit** — bot-authored AND platform-Verified. (Known gap: the Verified
|
|
90
|
+
badge proves only that the committer signed, not that the bot did, so the GitHub job is given no
|
|
91
|
+
token and refuses every such commit; on GitLab the gap is still open. See `references/check-gates.md`.) `.sdlc/contract-lock.json` is artifact-side and exempt. So is a **new epic's seed**:
|
|
85
92
|
no CI path can create a ledger (`gate ci` only *advances* an existing chain, at merge, on the
|
|
86
93
|
default branch), so an epic whose `.sdlc/state.json` is absent from the base ref may be created by
|
|
87
94
|
a human on its first review PR/MR — **creation, not mutation** (#162). Once the ledger is on the
|
|
88
|
-
default branch the guard is absolute again. Runs in `yad-
|
|
95
|
+
default branch the guard is absolute again. Runs in `yad-product-checks`; `verified-commits` runs beside
|
|
89
96
|
it in its own `yad-verified-commits` workflow (and requires the bot's signature like any other
|
|
90
|
-
commit's). See `yad-
|
|
91
|
-
- `templates/hooks/ledger-guard.
|
|
97
|
+
commit's). See `yad-product-bridge`.
|
|
98
|
+
- `templates/hooks/ledger-guard.mjs` → **Product-only** agent guardrail, active **only in verified mode**
|
|
92
99
|
(the same `isVerifiedLedger` predicate). Not a CI gate: it is a **harness hook** that refuses an agent's
|
|
93
100
|
edit to the CI-owned ledger at the moment it is attempted and names `yad gate open` instead — the
|
|
94
|
-
local half of `checks/ledger-guard.sh` (#171). Installed to `<product>/hooks/ledger-guard.
|
|
101
|
+
local half of `checks/ledger-guard.sh` (#171). Installed to `<product>/hooks/ledger-guard.mjs` with the
|
|
95
102
|
`PreToolUse` entry in `.claude/settings.json`; a `.cursor` project also gets
|
|
96
|
-
`templates/hooks/ledger-guard-cursor.
|
|
97
|
-
Fails OPEN; see "Step 2b" below.
|
|
98
|
-
|
|
103
|
+
`templates/hooks/ledger-guard-cursor.mjs` and a `preToolUse` entry in `.cursor/hooks.json`.
|
|
104
|
+
Fails OPEN; see "Step 2b" below. Every hook is a Node script the entry runs as `node <script>`, so
|
|
105
|
+
it needs no bash and no execute bit and runs on Windows too (E113).
|
|
106
|
+
- `templates/hooks/yad-capture.mjs` → **Product-only**, in **both** ledger modes (E43): the post-edit
|
|
99
107
|
harness hook that runs `yad capture --hook`, which snapshots every changed Shape artifact onto the
|
|
100
108
|
person's private `yad/wip/<name>/<epic>` branches without touching the checkout. Wired as a
|
|
101
109
|
`PostToolUse` entry in `.claude/settings.json` and an `afterFileEdit` entry in `.cursor/hooks.json`;
|
|
@@ -121,16 +129,18 @@ and GitLab CI. This step is **by hand** in Phase 3 — run the gates with the sk
|
|
|
121
129
|
|
|
122
130
|
## Inputs
|
|
123
131
|
|
|
124
|
-
- `repo` — the code repo to wire/run gates for (one of an epic's repos), or `
|
|
132
|
+
- `repo` — the code repo to wire/run gates for (one of an epic's repos), or `product` to wire the Product itself (`hub`, the old name, still works). A code repo that is itself named
|
|
133
|
+
`product`: give its registered path instead (for example `repos/product`), so it is not taken for the Product.
|
|
125
134
|
- `action` — `wire` (install the gates into the repo) | `run` (run the three gates now). Default `run`.
|
|
126
135
|
- `base` — for `run`: the base ref to diff against (the PR/MR target; default the repo's default branch).
|
|
127
136
|
|
|
128
137
|
## On Activation
|
|
129
138
|
|
|
130
139
|
### Step 1 — Resolve the code repo
|
|
131
|
-
Map `repo` → `{project-root}/demo-repos/<repo>/` (or the registry `path` in `.sdlc/repos.json`)
|
|
132
|
-
|
|
133
|
-
|
|
140
|
+
Map `repo` → `{project-root}/demo-repos/<repo>/` (or the registry `path` in `.sdlc/repos.json`). A `repo` value with a `/` in it is a registry `path`, not a name: match it against each entry's `path`
|
|
141
|
+
(so a code repo named `product` is reached as, for example, `repos/product`). Confirm
|
|
142
|
+
it is its own git repo. Operate inside it with absolute paths. For `repo: product`, the target is
|
|
143
|
+
`{project-root}` itself and the platform comes from `.sdlc/product.json` (`.sdlc/hub.json` on an older Product) — see "Wiring the Product" in
|
|
134
144
|
`references/check-gates.md`.
|
|
135
145
|
|
|
136
146
|
### Step 2 — `wire` (install the gates, syncing with any existing CI)
|
|
@@ -183,12 +193,12 @@ Re-running `wire` is **idempotent** — markers (`# yad-managed: yad-checks`,
|
|
|
183
193
|
`# yad-managed-include: yad-checks`) and the include-entry check make a second run a no-op.
|
|
184
194
|
Commit the wiring on the repo's default branch (it is shared infrastructure, not a task diff).
|
|
185
195
|
|
|
186
|
-
**The Product is wired the same way.** `repo:
|
|
196
|
+
**The Product is wired the same way.** `repo: product` wires the Product repo itself (platform from `.sdlc/product.json`)
|
|
187
197
|
with a Product-flavored gate set — see "Wiring the Product" in `references/check-gates.md`.
|
|
188
198
|
|
|
189
|
-
**The Product also gets the agent guardrail** (see below): `templates/hooks/ledger-guard.
|
|
190
|
-
`<product>/hooks/ledger-guard.
|
|
191
|
-
whose targets include `.cursor` also gets `templates/hooks/ledger-guard-cursor.
|
|
199
|
+
**The Product also gets the agent guardrail** (see below): `templates/hooks/ledger-guard.mjs` →
|
|
200
|
+
`<product>/hooks/ledger-guard.mjs`, plus the `PreToolUse` entry in `.claude/settings.json`. A project
|
|
201
|
+
whose targets include `.cursor` also gets `templates/hooks/ledger-guard-cursor.mjs` and a `preToolUse`
|
|
192
202
|
entry in `.cursor/hooks.json`. `yad setup` and `yad check --fix` install them; nothing by hand.
|
|
193
203
|
|
|
194
204
|
### Step 2b — the agent guardrail (harness hooks, verified mode only)
|
|
@@ -198,7 +208,7 @@ verified mode the gate ledger is **CI-owned**, so an agent that hand-edits
|
|
|
198
208
|
nothing connecting cause to effect — and by then the write has to be reverted before the review
|
|
199
209
|
PR/MR can go green.
|
|
200
210
|
|
|
201
|
-
`hooks/ledger-guard.
|
|
211
|
+
`hooks/ledger-guard.mjs` is the local half of that same rule. It runs as a **harness hook** before a
|
|
202
212
|
file-editing tool call and refuses the write up front, naming the command that owns the transition
|
|
203
213
|
(`yad gate open`), so the agent corrects itself instead of failing a pipeline.
|
|
204
214
|
|
|
@@ -208,7 +218,7 @@ file-editing tool call and refuses the write up front, naming the command that o
|
|
|
208
218
|
straight at the script. Cursor does NOT: its `preToolUse` is a **permission hook**, which wants a
|
|
209
219
|
JSON verdict on stdout and treats an empty or off-schema answer as a refusal — and this script
|
|
210
220
|
prints nothing when it allows, so wiring it there directly would block every file write in the
|
|
211
|
-
project. Cursor's entry
|
|
221
|
+
project. Cursor's entry runs `node hooks/ledger-guard-cursor.mjs` instead, which runs
|
|
212
222
|
`yad hook ledger-guard --format cursor` and always answers `{"permission":"allow"}` or
|
|
213
223
|
`{"permission":"deny","user_message":…,"agent_message":…}`. **Check which kind a harness is
|
|
214
224
|
before wiring it by hand.** A hook that fires only AFTER the write, such as Cursor's
|
|
@@ -217,7 +227,7 @@ file-editing tool call and refuses the write up front, naming the command that o
|
|
|
217
227
|
- **Targets with no such hook are named, not skipped.** `.agents`, `.gemini`, `.zencoder` and
|
|
218
228
|
`.opencode` get the script and no wiring, and `yad doctor` says which of a project's targets are
|
|
219
229
|
guarded by CI alone. Silence about an unguarded target reads as a guarded one.
|
|
220
|
-
- **Same scope as the CI gate**, deliberately: guarded are `epics/*/.sdlc/{state,approvals,comments,hub-prs}.json`
|
|
230
|
+
- **Same scope as the CI gate**, deliberately: guarded are `epics/*/.sdlc/{state,approvals,comments,product-prs,hub-prs}.json`
|
|
221
231
|
and `epics/*/reviews/*.md` (at the gate's own glob depth, which spans `/`); exempt are
|
|
222
232
|
`contract-lock.json`, `change.json`, and every artifact. A **new** epic's ledger is exempt too —
|
|
223
233
|
creation, not mutation (#162), decided by listing the epics the **base ref** carries (an
|
|
@@ -226,7 +236,8 @@ file-editing tool call and refuses the write up front, naming the command that o
|
|
|
226
236
|
skills describe is *correct*, so nothing is wired and nothing is blocked.
|
|
227
237
|
- **It fails OPEN** — no `yad`, no Product, an unreadable config, an unparseable payload all ALLOW, with
|
|
228
238
|
a note on stderr. `ledger-guard` in CI fails *closed* and remains the authority. `YAD_HOOK_DISABLE=1`
|
|
229
|
-
skips one command.
|
|
239
|
+
skips one command. A PERSON who must commit a ledger change anyway uses `yad commit --manual --reason
|
|
240
|
+
"<why>"` (E49) — never the agent on its own initiative.
|
|
230
241
|
- **Known gaps** (both caught by the CI gate instead): a `Bash` tool call (`sed -i epics/…`) is not
|
|
231
242
|
intercepted — matching it would mean parsing shell; and the hook arms sessions **rooted at the
|
|
232
243
|
Product**, since a harness reads hooks from its own project root — a session opened at the workspace
|
|
@@ -235,6 +246,16 @@ file-editing tool call and refuses the write up front, naming the command that o
|
|
|
235
246
|
`yad doctor` reports the guardrail as `agent ledger guard wired` / `not wired` on a verified Product.
|
|
236
247
|
See `references/check-gates.md` §"The agent guardrail".
|
|
237
248
|
|
|
249
|
+
**The same rule for a person's `git commit` (E48).** On a verified Product, `yad check --fix` also
|
|
250
|
+
installs `.git/hooks/pre-commit` in the clone it runs in. It runs `node hooks/ledger-guard.mjs
|
|
251
|
+
--staged`, which judges the files the commit is about to record by the same rules as the CI gate (a
|
|
252
|
+
merge commit and a `yad-gate-sync` commit pass, as they do in CI) and refuses the commit with the files,
|
|
253
|
+
the `git restore --staged` line and the owning command. It is per clone — git never copies hooks — so
|
|
254
|
+
`yad doctor` warns `git-hook` in a clone that has none. A `pre-commit` that is not yad's, or a
|
|
255
|
+
`core.hooksPath` folder, is never written: print the one line `yad doctor` gives and let the person add
|
|
256
|
+
it. Branch protection is what makes the CI gates hold a merge at all: point the team at yadflow's
|
|
257
|
+
`docs/branch-protection.md`.
|
|
258
|
+
|
|
238
259
|
### Step 3 — `run` (run the gates now)
|
|
239
260
|
From inside the repo, run each gate against `base` and report PASS/FAIL per gate:
|
|
240
261
|
```
|