yadflow 3.18.1 → 4.0.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +355 -0
- package/README.md +79 -26
- package/bin/commands.mjs +41 -0
- package/bin/yad.mjs +437 -124
- package/cli/artifact-status.mjs +34 -15
- package/cli/checkpoint.mjs +69 -49
- package/cli/codeowners-command.mjs +170 -0
- package/cli/codeowners.mjs +397 -0
- package/cli/commit.mjs +13 -9
- package/cli/companion.mjs +2 -2
- package/cli/dial.mjs +183 -0
- package/cli/docs.mjs +88 -32
- package/cli/doctor.mjs +1472 -97
- package/cli/epic-state.mjs +3478 -232
- package/cli/epic.mjs +506 -0
- package/cli/errors.mjs +4 -1
- package/cli/gate.mjs +1002 -209
- package/cli/history.mjs +556 -0
- package/cli/hook.mjs +266 -55
- package/cli/hubcommit.mjs +6 -17
- package/cli/index-command.mjs +87 -0
- package/cli/ledger.mjs +57 -7
- package/cli/lib.mjs +184 -18
- package/cli/manifest.mjs +367 -56
- package/cli/migrate.mjs +726 -53
- package/cli/mode.mjs +170 -0
- package/cli/next.mjs +349 -90
- package/cli/openpr.mjs +191 -39
- package/cli/people.mjs +654 -0
- package/cli/plan.mjs +417 -132
- package/cli/platform.mjs +110 -129
- package/cli/product-index.mjs +287 -0
- package/cli/protection.mjs +706 -0
- package/cli/reconcile.mjs +38 -12
- package/cli/repo-publish.mjs +24 -26
- package/cli/repo.mjs +23 -14
- package/cli/report.mjs +21 -15
- package/cli/review.mjs +24 -27
- package/cli/riskmap-command.mjs +289 -0
- package/cli/riskmap.mjs +373 -0
- package/cli/setup.mjs +139 -287
- package/cli/ship.mjs +7 -6
- package/cli/skill.mjs +180 -0
- package/cli/skip.mjs +211 -30
- package/cli/thread.mjs +42 -17
- package/cli/tidy.mjs +20 -20
- package/cli/update-commit.mjs +22 -22
- package/cli/usage.mjs +115 -109
- package/package.json +3 -3
- package/skills/sdlc/config.yaml +166 -87
- package/skills/sdlc/module-help.csv +35 -35
- package/skills/yad-analysis/SKILL.md +125 -65
- package/skills/yad-architecture/SKILL.md +34 -23
- package/skills/yad-architecture/references/contract-format.md +10 -8
- package/skills/yad-backfill/SKILL.md +14 -8
- package/skills/yad-backfill/references/backfill.md +1 -1
- package/skills/yad-change/SKILL.md +127 -52
- package/skills/yad-change/references/triage.md +42 -28
- package/skills/yad-checks/SKILL.md +89 -45
- package/skills/yad-checks/references/check-gates.md +315 -92
- package/skills/yad-checks/templates/checks/build-test-lint.sh +25 -7
- package/skills/yad-checks/templates/checks/commit-message.sh +17 -3
- package/skills/yad-checks/templates/checks/contract-check.sh +58 -2
- package/skills/yad-checks/templates/checks/epic-open.sh +3 -3
- package/skills/yad-checks/templates/checks/install-deps.sh +46 -0
- package/skills/yad-checks/templates/checks/ledger-guard.sh +94 -18
- package/skills/yad-checks/templates/checks/lineage-check.sh +23 -9
- package/skills/yad-checks/templates/checks/package-manager.sh +140 -0
- package/skills/yad-checks/templates/checks/reconcile-debt-check.sh +4 -4
- package/skills/yad-checks/templates/checks/risk-map-check.sh +438 -0
- package/skills/yad-checks/templates/checks/verified-commits.sh +20 -46
- package/skills/yad-checks/templates/github/yad-checks.yml +37 -5
- package/skills/yad-checks/templates/github/yad-hub-checks.yml +5 -5
- package/skills/yad-checks/templates/github/yad-update-guard.yml +3 -4
- package/skills/yad-checks/templates/github/yad-verified-commits.yml +4 -4
- package/skills/yad-checks/templates/gitlab/.gitlab-ci.yml +7 -1
- package/skills/yad-checks/templates/gitlab/yad-checks.gitlab-ci.yml +22 -4
- package/skills/yad-checks/templates/gitlab/yad-hub-checks.gitlab-ci.yml +5 -5
- package/skills/yad-checks/templates/gitlab/yad-verified-commits.gitlab-ci.yml +4 -4
- package/skills/yad-checks/templates/hooks/ledger-guard-cursor.sh +91 -0
- package/skills/yad-checks/templates/hooks/ledger-guard.sh +38 -7
- package/skills/yad-commit/SKILL.md +6 -6
- package/skills/yad-connect-design/SKILL.md +6 -6
- package/skills/yad-connect-design/references/design-context.md +1 -1
- package/skills/yad-connect-design/references/design-registry.md +2 -2
- package/skills/yad-connect-docs/SKILL.md +12 -12
- package/skills/yad-connect-docs/references/docs-registry.md +1 -1
- package/skills/yad-connect-learning/SKILL.md +5 -5
- package/skills/yad-connect-learning/references/learning-registry.md +2 -2
- package/skills/yad-connect-repos/SKILL.md +92 -54
- package/skills/yad-connect-repos/references/code-context.md +6 -6
- package/skills/yad-connect-repos/references/hub-config.md +68 -58
- package/skills/yad-connect-repos/references/repos-registry.md +10 -9
- package/skills/yad-connect-repos/references/risk-map.md +81 -0
- package/skills/yad-connect-testing/SKILL.md +6 -6
- package/skills/yad-connect-testing/references/testing-context.md +3 -4
- package/skills/yad-connect-testing/references/testing-registry.md +2 -2
- package/skills/yad-defects/SKILL.md +8 -8
- package/skills/yad-discovery/SKILL.md +130 -94
- package/skills/yad-discovery/references/discovery-schema.md +23 -7
- package/skills/yad-discovery/references/foundation-schema.md +374 -0
- package/skills/yad-docs/SKILL.md +16 -11
- package/skills/yad-docs/references/data-mapping.md +9 -7
- package/skills/yad-docs/templates/app/package-lock.json +3 -3
- package/skills/yad-docs-overview/SKILL.md +32 -17
- package/skills/yad-docs-overview/references/pipeline-model.md +47 -28
- package/skills/yad-docs-sync/SKILL.md +10 -5
- package/skills/yad-docs-sync/references/staleness.md +8 -7
- package/skills/yad-engineer-review/SKILL.md +88 -24
- package/skills/yad-engineer-review/references/ship-and-record.md +25 -16
- package/skills/yad-epic/SKILL.md +178 -100
- package/skills/yad-epic/references/state-schema.md +626 -117
- package/skills/yad-hub-bridge/SKILL.md +66 -48
- package/skills/yad-hub-bridge/references/bridge.md +110 -83
- package/skills/yad-hub-bridge/references/login-roster.md +163 -70
- package/skills/yad-hub-bridge/templates/checks/hub-route.sh +22 -19
- package/skills/yad-hub-bridge/templates/github/yad-gate-sync.yml +34 -14
- package/skills/yad-hub-bridge/templates/gitlab/gitlab-ci.include-root.yml +2 -2
- package/skills/yad-hub-bridge/templates/gitlab/yad-gate-sync.gitlab-ci.yml +22 -12
- package/skills/yad-implement/SKILL.md +29 -15
- package/skills/yad-implement/references/implement-conventions.md +2 -2
- package/skills/yad-learn/SKILL.md +9 -9
- package/skills/yad-learn/references/learning-state.md +2 -2
- package/skills/yad-open-pr/SKILL.md +64 -29
- package/skills/yad-pair-review/SKILL.md +18 -16
- package/skills/yad-pair-review/references/session-state.md +4 -4
- package/skills/yad-pr-template/SKILL.md +48 -27
- package/skills/yad-pr-template/references/risk-routing.md +97 -24
- package/skills/yad-pr-template/templates/checks/pr-template.sh +37 -15
- package/skills/yad-pr-template/templates/checks/pr-title.sh +27 -13
- package/skills/yad-pr-template/templates/checks/risk-route.sh +107 -14
- package/skills/yad-pr-template/templates/github/pull_request_template.md +7 -5
- package/skills/yad-pr-template/templates/gitlab/merge_request_templates/Default.md +7 -5
- package/skills/yad-pr-template/templates/hub/github/pull_request_template.md +15 -14
- package/skills/yad-pr-template/templates/hub/gitlab/merge_request_templates/Default.md +15 -13
- package/skills/yad-reconcile/SKILL.md +3 -3
- package/skills/yad-report/SKILL.md +5 -5
- package/skills/yad-review-companion/SKILL.md +12 -9
- package/skills/yad-review-gate/SKILL.md +198 -79
- package/skills/yad-review-gate/references/gating.md +230 -54
- package/skills/yad-run/SKILL.md +86 -56
- package/skills/yad-run/references/run-loop.md +67 -45
- package/skills/yad-ship/SKILL.md +18 -14
- package/skills/yad-spec/SKILL.md +31 -17
- package/skills/yad-spec/references/spec-handoff.md +17 -5
- package/skills/yad-status/SKILL.md +114 -56
- package/skills/yad-stories/SKILL.md +42 -27
- package/skills/yad-stories/references/story-schema.md +10 -9
- package/skills/yad-stub/SKILL.md +59 -48
- package/skills/yad-sync-repos/SKILL.md +3 -3
- package/skills/yad-test-cases/SKILL.md +37 -30
- package/skills/yad-test-cases/references/test-cases-schema.md +8 -5
- package/skills/yad-timeline/SKILL.md +8 -7
- package/skills/yad-ui/SKILL.md +46 -25
- package/cli/roster.mjs +0 -164
- package/skills/sdlc/install.sh +0 -68
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: yad-checks
|
|
3
|
-
description: 'Build
|
|
3
|
+
description: 'Build Step C of the gated SDLC — the production-safety check gates. Wire and run the CI gates on a code repo: spec-link (every change links a real story/spec via its Task trailer), contract-check (a diff that changes the contract surface without a Contract-Change + an updated, re-locked contract FAILS and routes back to the architecture gate), build/test/lint, verified-commits (no unsigned commits — every commit carries a platform-Verified signature; write access to the repo decides who can author, on the Product and every repo), and the Phase 6 feature-thread gates lineage-check / epic-open / reconcile-debt (a change links a real threaded epic; a sealed epic refuses new behaviour; a thread with open hotfix debt is frozen until paid), plus an advisory risk-map check (warns when .sdlc/risk-map is stale). The gates are CI-agnostic bash, invoked by GitHub Actions and GitLab CI. Use when the user says "wire the check gates", "run the gates", "require signed commits", or "set up CI checks" for a repo.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# SDLC — Check Gates (
|
|
6
|
+
# SDLC — Check Gates (Build Step C)
|
|
7
7
|
|
|
8
8
|
**Goal:** Install and run the **check gates** that protect production for a code repo. They run
|
|
9
9
|
in CI on every PR/MR and must pass before merge (build plan §C). Each is a small, separate check:
|
|
@@ -16,31 +16,53 @@ in CI on every PR/MR and must pass before merge (build plan §C). Each is a smal
|
|
|
16
16
|
contract upstream, it **FAILS and routes back to the architecture gate**. The shared surface is
|
|
17
17
|
never widened from inside a code repo (Phase 2 contract representation: delimited block + SHA-256 lock).
|
|
18
18
|
Every story whose slice the diff touches is checked, not just the first — see `references/check-gates.md`.
|
|
19
|
+
A claimed `Contract-Change` against an epic that has **no lock at all** fails too: an epic on a short
|
|
20
|
+
lane (`chore`/`spike`) has no architecture step and never locks a surface, so it may consume the
|
|
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.
|
|
19
23
|
3. **build/test/lint** — standard quality stage; tests must actually exercise new behavior, not just pass.
|
|
24
|
+
CI installs and runs through the package manager declared by the repo's standard
|
|
25
|
+
`package.json#packageManager` field (`npm` and `pnpm` are supported; any other manager stays on
|
|
26
|
+
npm with a warning when an npm lockfile is present, and fails closed otherwise); an npm repo
|
|
27
|
+
without that field retains the historical npm behavior. A declared manager requires a full, exact semantic
|
|
28
|
+
version (with Corepack's optional integrity suffix supported), and CI activates that exact version.
|
|
29
|
+
The code-repo `yad-checks` workflow uses Node 22 by default (the build/test/lint job on GitHub; every
|
|
30
|
+
`yad-*` gate job's image in the GitLab fragment) and reads `YAD_NODE_VERSION` (a GitHub repository
|
|
31
|
+
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, hub-checks, update-guard,
|
|
33
|
+
gate-sync) only run the `yad` CLI and keep their own pinned Node; the variable does not reach them.
|
|
20
34
|
The CI job sets `YAD_TEST_MAX_WORKERS` (default `2`); the gate caps jest/vitest test concurrency at
|
|
21
35
|
that and is a no-op for other runners (see `references/check-gates.md`).
|
|
22
|
-
4. **verified-commits** — no
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
**
|
|
26
|
-
ledger pushes are unaffected (never replace it with a default-branch push rule — see
|
|
36
|
+
4. **verified-commits** — no unsigned commits: every commit in the range must carry a signature the
|
|
37
|
+
platform marks **Verified**. There is no author allowlist (E62): write access to the repo decides who
|
|
38
|
+
can author. An old `.sdlc/verified-authors` file is no longer read, and the gate prints a note when it
|
|
39
|
+
finds one. Enforced on the **Product and every connected repo**; runs on PRs/MRs only, so the
|
|
40
|
+
gate-sync bot's direct ledger pushes are unaffected (never replace it with a default-branch push rule — see
|
|
27
41
|
`references/check-gates.md` §4).
|
|
28
42
|
5. **lineage-check** (Phase 6) — the change's owning epic is a valid node in a **feature thread**: a
|
|
29
43
|
`change`/`defect`/`hotfix` epic must thread to a real `parent`. Builds on spec-link's story→epic
|
|
30
44
|
resolution; the every-code-change-has-a-threaded-epic enforcement.
|
|
31
45
|
6. **epic-open** (Phase 6, the staleness preventer) — an epic is **sealed** once every story is
|
|
32
46
|
`shipped`; a commit targeting a sealed epic **FAILS**, forcing new behaviour into a new threaded
|
|
33
|
-
change-epic (so the
|
|
47
|
+
change-epic (so the Shape artifacts can never go stale).
|
|
34
48
|
7. **reconcile-debt** (Phase 6) — a hotfix that shipped first opens debt; the **next** change on its
|
|
35
49
|
thread **FAILS** until the debt is paid (artifacts updated + a regression test added).
|
|
50
|
+
8. **risk-map** (E65, **advisory — never fails**) — reads the code repo's `.sdlc/risk-map` (one line per
|
|
51
|
+
directory: `high` / `medium` / `low`, no names) and **warns** when this change adds a directory no line
|
|
52
|
+
covers, leaves a line whose directory is gone, touches a line still `unset` or `guessed`, or edits the
|
|
53
|
+
map itself. A repo with no map gets one note. It also prints the **approver count** (E66): a change
|
|
54
|
+
touching a directory the **base branch's** map marks `high` asks for one more approver — reported,
|
|
55
|
+
never enforced: branch protection holds the merge — and names who has **committed there in the last 30 days**
|
|
56
|
+
(E67), so the team knows who can meet that ask. The map is the team's file, never wired; the
|
|
57
|
+
`yad-connect-repos` skill drafts it. See `references/check-gates.md` §10.
|
|
36
58
|
|
|
37
|
-
The Phase 6 gates read the owning epic in the **
|
|
38
|
-
`product-repo` path (like contract-check), and degrade to a PASS-with-note when the
|
|
59
|
+
The Phase 6 gates read the owning epic in the **Product** via `specs/<story>/link.md`'s
|
|
60
|
+
`product-repo` path (like contract-check), and degrade to a PASS-with-note when the Product is not reachable
|
|
39
61
|
from CI. See `references/check-gates.md` and `skills/yad-change`.
|
|
40
62
|
|
|
41
63
|
The gates are **CI-agnostic bash** in `checks/`; thin pipeline configs invoke them on GitHub Actions
|
|
42
64
|
and GitLab CI. This step is **by hand** in Phase 3 — run the gates with the skill or let CI run them;
|
|
43
|
-
**nothing auto-advances**. The gates are blocking in CI, but the human still owns the merge (Step E).
|
|
65
|
+
**nothing auto-advances**. The gates are blocking in CI (all but the advisory risk-map check), but the human still owns the merge (Step E).
|
|
44
66
|
|
|
45
67
|
## Conventions
|
|
46
68
|
|
|
@@ -50,10 +72,11 @@ and GitLab CI. This step is **by hand** in Phase 3 — run the gates with the sk
|
|
|
50
72
|
(`config.yaml` `build.code_repos_root`).
|
|
51
73
|
- Canonical gate sources live in this skill's `templates/` (the source of truth that gets installed
|
|
52
74
|
into each code repo):
|
|
53
|
-
- `templates/checks/{spec-link,contract-check,build-test-lint,verified-commits}.sh`
|
|
54
|
-
- `templates/checks/ledger-guard.sh` → **
|
|
55
|
-
carries BOTH a `platform` and `
|
|
56
|
-
|
|
75
|
+
- `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** — hub.json
|
|
77
|
+
carries BOTH a `platform` and `ledger: "verified"` — or, before `yad migrate`, `bridge_enabled`
|
|
78
|
+
(or the legacy `bridge`) true. The same predicate
|
|
79
|
+
`isVerifiedLedger` (`cli/manifest.mjs`) applies, so the gate and the CLI can never disagree about who owns the
|
|
57
80
|
ledger (#186). A no-op otherwise, when humans legitimately own it. On review PRs it FAILs any
|
|
58
81
|
commit that touches the
|
|
59
82
|
CI-owned gate ledger (`.sdlc/{state,approvals,comments,hub-prs}.json`, `reviews/*.md`) unless it
|
|
@@ -62,27 +85,36 @@ and GitLab CI. This step is **by hand** in Phase 3 — run the gates with the sk
|
|
|
62
85
|
no CI path can create a ledger (`gate ci` only *advances* an existing chain, at merge, on the
|
|
63
86
|
default branch), so an epic whose `.sdlc/state.json` is absent from the base ref may be created by
|
|
64
87
|
a human on its first review PR/MR — **creation, not mutation** (#162). Once the ledger is on the
|
|
65
|
-
default branch the guard is absolute again. Runs in `yad-hub-checks`
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
- `templates/hooks/ledger-guard.sh` → **
|
|
69
|
-
(the same `
|
|
88
|
+
default branch the guard is absolute again. Runs in `yad-hub-checks`; `verified-commits` runs beside
|
|
89
|
+
it in its own `yad-verified-commits` workflow (and requires the bot's signature like any other
|
|
90
|
+
commit's). See `yad-hub-bridge`.
|
|
91
|
+
- `templates/hooks/ledger-guard.sh` → **Product-only** agent guardrail, active **only in verified mode**
|
|
92
|
+
(the same `isVerifiedLedger` predicate). Not a CI gate: it is a **harness hook** that refuses an agent's
|
|
70
93
|
edit to the CI-owned ledger at the moment it is attempted and names `yad gate open` instead — the
|
|
71
|
-
local half of `checks/ledger-guard.sh` (#171). Installed to `<
|
|
72
|
-
`PreToolUse` entry in `.claude/settings.json
|
|
94
|
+
local half of `checks/ledger-guard.sh` (#171). Installed to `<product>/hooks/ledger-guard.sh` with the
|
|
95
|
+
`PreToolUse` entry in `.claude/settings.json`; a `.cursor` project also gets
|
|
96
|
+
`templates/hooks/ledger-guard-cursor.sh` and a `preToolUse` entry in `.cursor/hooks.json`.
|
|
97
|
+
Fails OPEN; see "Step 2b" below.
|
|
73
98
|
- `templates/github/yad-verified-commits.yml` + `templates/gitlab/yad-verified-commits.gitlab-ci.yml`
|
|
74
|
-
→ the standalone
|
|
75
|
-
- `templates/github/yad-checks.yml` → installs to `.github/workflows/yad-checks.yml` (marked `# yad-managed: yad-checks`)
|
|
76
|
-
|
|
99
|
+
→ the standalone Product-side verified-commits CI (installed by `yad check --fix` with the Product wiring)
|
|
100
|
+
- `templates/github/yad-checks.yml` → installs to `.github/workflows/yad-checks.yml` (marked `# yad-managed: yad-checks`);
|
|
101
|
+
its quality job uses `install-deps.sh`, reads the optional `YAD_NODE_VERSION` repository variable,
|
|
102
|
+
exports the PR's exact `NX_BASE`/`NX_HEAD`, and filters unrelated history blobs while preserving
|
|
103
|
+
the full commit graph.
|
|
104
|
+
- `templates/gitlab/yad-checks.gitlab-ci.yml` → includable fragment, installs to `.gitlab/ci/yad-checks.yml`;
|
|
105
|
+
it uses the same installer, honors a project/group `YAD_NODE_VERSION` CI/CD variable, and exports
|
|
106
|
+
the MR's exact `NX_BASE`/`NX_HEAD`.
|
|
77
107
|
- `templates/gitlab/gitlab-ci.include-root.yml` → minimal root written only when no root `.gitlab-ci.yml` exists
|
|
78
|
-
- `templates/gitlab/.gitlab-ci.yml` → legacy standalone root (greenfield single-file option)
|
|
108
|
+
- `templates/gitlab/.gitlab-ci.yml` → legacy standalone root (greenfield single-file option), kept
|
|
109
|
+
semantically aligned with the includable fragment's Node version, Nx range, dependency install,
|
|
110
|
+
and test-worker cap
|
|
79
111
|
- The gates depend on the conventions from earlier steps: the `Task:`/`Contract-Change:` commit
|
|
80
112
|
trailers (`yad-implement`), the `specs/<story>/link.md` + `contracts/` slice (`yad-spec`), and the
|
|
81
113
|
locked `contract.md` (`yad-architecture`).
|
|
82
114
|
|
|
83
115
|
## Inputs
|
|
84
116
|
|
|
85
|
-
- `repo` — the code repo to wire/run gates for (one of an epic's repos), or `hub` to wire the
|
|
117
|
+
- `repo` — the code repo to wire/run gates for (one of an epic's repos), or `hub` to wire the Product itself.
|
|
86
118
|
- `action` — `wire` (install the gates into the repo) | `run` (run the three gates now). Default `run`.
|
|
87
119
|
- `base` — for `run`: the base ref to diff against (the PR/MR target; default the repo's default branch).
|
|
88
120
|
|
|
@@ -91,7 +123,7 @@ and GitLab CI. This step is **by hand** in Phase 3 — run the gates with the sk
|
|
|
91
123
|
### Step 1 — Resolve the code repo
|
|
92
124
|
Map `repo` → `{project-root}/demo-repos/<repo>/` (or the registry `path` in `.sdlc/repos.json`); confirm
|
|
93
125
|
it is its own git repo. Operate inside it with absolute paths. For `repo: hub`, the target is
|
|
94
|
-
`{project-root}` itself and the platform comes from `.sdlc/hub.json` — see "Wiring the
|
|
126
|
+
`{project-root}` itself and the platform comes from `.sdlc/hub.json` — see "Wiring the Product" in
|
|
95
127
|
`references/check-gates.md`.
|
|
96
128
|
|
|
97
129
|
### Step 2 — `wire` (install the gates, syncing with any existing CI)
|
|
@@ -144,16 +176,17 @@ Re-running `wire` is **idempotent** — markers (`# yad-managed: yad-checks`,
|
|
|
144
176
|
`# yad-managed-include: yad-checks`) and the include-entry check make a second run a no-op.
|
|
145
177
|
Commit the wiring on the repo's default branch (it is shared infrastructure, not a task diff).
|
|
146
178
|
|
|
147
|
-
**The
|
|
148
|
-
with a
|
|
179
|
+
**The Product is wired the same way.** `repo: hub` wires the Product repo itself (platform from `.sdlc/hub.json`)
|
|
180
|
+
with a Product-flavored gate set — see "Wiring the Product" in `references/check-gates.md`.
|
|
149
181
|
|
|
150
|
-
**The
|
|
151
|
-
`<
|
|
152
|
-
|
|
182
|
+
**The Product also gets the agent guardrail** (see below): `templates/hooks/ledger-guard.sh` →
|
|
183
|
+
`<product>/hooks/ledger-guard.sh`, plus the `PreToolUse` entry in `.claude/settings.json`. A project
|
|
184
|
+
whose targets include `.cursor` also gets `templates/hooks/ledger-guard-cursor.sh` and a `preToolUse`
|
|
185
|
+
entry in `.cursor/hooks.json`. `yad setup` and `yad check --fix` install them; nothing by hand.
|
|
153
186
|
|
|
154
|
-
### Step 2b — the agent guardrail (harness hooks,
|
|
187
|
+
### Step 2b — the agent guardrail (harness hooks, verified mode only)
|
|
155
188
|
The CI gates speak at CI time. That is too late for one failure the field kept hitting (#171): in
|
|
156
|
-
|
|
189
|
+
verified mode the gate ledger is **CI-owned**, so an agent that hand-edits
|
|
157
190
|
`epics/*/.sdlc/state.json` only finds out twenty minutes later, from a `ledger-guard` FAIL with
|
|
158
191
|
nothing connecting cause to effect — and by then the write has to be reverted before the review
|
|
159
192
|
PR/MR can go green.
|
|
@@ -164,24 +197,35 @@ file-editing tool call and refuses the write up front, naming the command that o
|
|
|
164
197
|
|
|
165
198
|
- **Harness-agnostic by contract.** The script only locates `yad` and hands the tool payload to
|
|
166
199
|
`yad hook ledger-guard`: **stdin** is a JSON tool-call payload, **exit 0** allows, **exit 2**
|
|
167
|
-
denies with the reason on stderr. Claude Code's `PreToolUse`
|
|
168
|
-
|
|
200
|
+
denies with the reason on stderr. Claude Code's `PreToolUse` reads exactly that, so its entry points
|
|
201
|
+
straight at the script. Cursor does NOT: its `preToolUse` is a **permission hook**, which wants a
|
|
202
|
+
JSON verdict on stdout and treats an empty or off-schema answer as a refusal — and this script
|
|
203
|
+
prints nothing when it allows, so wiring it there directly would block every file write in the
|
|
204
|
+
project. Cursor's entry points at `hooks/ledger-guard-cursor.sh` instead, which runs
|
|
205
|
+
`yad hook ledger-guard --format cursor` and always answers `{"permission":"allow"}` or
|
|
206
|
+
`{"permission":"deny","user_message":…,"agent_message":…}`. **Check which kind a harness is
|
|
207
|
+
before wiring it by hand.** A hook that fires only AFTER the write, such as Cursor's
|
|
208
|
+
`afterFileEdit`, is not used: it could report the edit but never refuse it, and reporting is what
|
|
209
|
+
the CI gate already does.
|
|
210
|
+
- **Targets with no such hook are named, not skipped.** `.agents`, `.gemini`, `.zencoder` and
|
|
211
|
+
`.opencode` get the script and no wiring, and `yad doctor` says which of a project's targets are
|
|
212
|
+
guarded by CI alone. Silence about an unguarded target reads as a guarded one.
|
|
169
213
|
- **Same scope as the CI gate**, deliberately: guarded are `epics/*/.sdlc/{state,approvals,comments,hub-prs}.json`
|
|
170
214
|
and `epics/*/reviews/*.md` (at the gate's own glob depth, which spans `/`); exempt are
|
|
171
215
|
`contract-lock.json`, `change.json`, and every artifact. A **new** epic's ledger is exempt too —
|
|
172
216
|
creation, not mutation (#162), decided by listing the epics the **base ref** carries (an
|
|
173
217
|
`origin/` ref, case-folded slugs), never by looking at the working tree.
|
|
174
|
-
- **A no-op
|
|
218
|
+
- **A no-op with a local ledger.** There the ledger is locally owned and the hand-edit the authoring
|
|
175
219
|
skills describe is *correct*, so nothing is wired and nothing is blocked.
|
|
176
|
-
- **It fails OPEN** — no `yad`, no
|
|
220
|
+
- **It fails OPEN** — no `yad`, no Product, an unreadable config, an unparseable payload all ALLOW, with
|
|
177
221
|
a note on stderr. `ledger-guard` in CI fails *closed* and remains the authority. `YAD_HOOK_DISABLE=1`
|
|
178
222
|
skips one command.
|
|
179
223
|
- **Known gaps** (both caught by the CI gate instead): a `Bash` tool call (`sed -i epics/…`) is not
|
|
180
224
|
intercepted — matching it would mean parsing shell; and the hook arms sessions **rooted at the
|
|
181
|
-
|
|
182
|
-
above the
|
|
225
|
+
Product**, since a harness reads hooks from its own project root — a session opened at the workspace
|
|
226
|
+
above the Product never loads the Product's `.claude/settings.json`.
|
|
183
227
|
|
|
184
|
-
`yad doctor` reports the guardrail as `agent ledger guard wired` / `not wired` on a
|
|
228
|
+
`yad doctor` reports the guardrail as `agent ledger guard wired` / `not wired` on a verified Product.
|
|
185
229
|
See `references/check-gates.md` §"The agent guardrail".
|
|
186
230
|
|
|
187
231
|
### Step 3 — `run` (run the gates now)
|
|
@@ -206,8 +250,8 @@ human engineer review (Step E) still own the merge. This skill never edits the e
|
|
|
206
250
|
- **Run standalone** (the Phase 3 default): **stop** here. A clean pass does not advance anything; a
|
|
207
251
|
human takes the next step.
|
|
208
252
|
- **Run by the orchestrator** (`yad-run`, Phase 4): this skill still just reports PASS/FAIL — the
|
|
209
|
-
*advance decision* is the orchestrator's, read from the `checks` step's
|
|
210
|
-
pass with `checks`
|
|
253
|
+
*advance decision* is the orchestrator's, read from the `checks` step's advance dial. On a clean
|
|
254
|
+
pass with `checks` set to `advance: auto`, `yad-run` advances to `engineer-review` on its own;
|
|
211
255
|
on any FAIL it halts and pulls in a human (build plan §B). **What the gates check is unchanged** —
|
|
212
256
|
only who decides to proceed after a clean pass.
|
|
213
257
|
|
|
@@ -218,7 +262,7 @@ human engineer review (Step E) still own the merge. This skill never edits the e
|
|
|
218
262
|
to the architecture gate; only an updated, re-locked contract + `Contract-Change: yes` may pass.
|
|
219
263
|
- **Tests must exercise behavior.** build/test/lint is not satisfied by empty or trivial tests.
|
|
220
264
|
- **The gate never advances itself.** A FAIL always halts. A clean PASS advances only when the
|
|
221
|
-
orchestrator's `checks` dial is `
|
|
265
|
+
orchestrator's `checks` dial is `advance: auto` (`yad dial`) — and only as far as the engineer review,
|
|
222
266
|
which is always human. Standalone, the gate still stops and the human owns the merge.
|
|
223
267
|
|
|
224
268
|
## Reference
|