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,23 +1,23 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: yad-connect-repos
|
|
3
|
-
description: 'Connects code repos to the
|
|
3
|
+
description: 'Connects code repos to the Product so the front/"brain" phases are code-aware. Registers N code repos (GitHub or GitLab, local-user auth, no stored tokens) into the project-wide .sdlc/repos.json, then caches an AI-readable picture of each — a compressed Repomix pack and a lightweight code-map (existing endpoints/events/data-models/modules), secret-scanned. Run at one-time setup or any time a new repo is added. Reusable, idempotent, refreshable; staleness is tracked by HEAD sha. `yad repo refresh --push` publishes the refreshed code-maps + registry to the Product default branch as a chore(hub): sync code-context [skip ci] audit commit. Also drafts each code repo's risk map (.sdlc/risk-map — a level per directory, no names), classified by reading the code and marked guessed for a person to confirm. Use when the user says "connect a repo", "connect the code repos", "refresh the code context", "list connected repos", or "push the code-map refresh".'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# SDLC — Connect Code Repos (make the brain code-aware)
|
|
7
7
|
|
|
8
8
|
**Goal:** Give the front/"brain" phases (`yad-epic` → `-architecture` → `-ui` → `-stories`)
|
|
9
9
|
full context about what **already exists** in the code, so the AI does not author a contract, UI, or
|
|
10
|
-
stories that contradict or duplicate what is built. This skill **connects** code repos to the product
|
|
11
|
-
hub and caches an AI-readable picture of each. It is the product → code half of the 2-way link (the
|
|
10
|
+
stories that contradict or duplicate what is built. This skill **connects** code repos to the Product and caches an AI-readable picture of each. It is the product → code half of the 2-way link (the
|
|
12
11
|
code → product half is the existing `link.md` back-pointer each spec carries).
|
|
13
12
|
|
|
14
13
|
This is **setup/maintenance**, not a gated Shape step — it never touches `.sdlc/state.json` or any
|
|
15
|
-
epic's approvals. It
|
|
14
|
+
epic's approvals. It writes the project-wide registry, the per-repo context cache, and — in the code
|
|
15
|
+
repo itself — a draft of that repo's risk map (Step 3b), which the team commits there through a PR.
|
|
16
16
|
|
|
17
17
|
## Conventions
|
|
18
18
|
|
|
19
|
-
- `{project-root}` resolves from the project working directory (the **
|
|
20
|
-
- The **product repo is the Shape phase toolchain
|
|
19
|
+
- `{project-root}` resolves from the project working directory (the **Product**).
|
|
20
|
+
- The **product repo is where the Shape phase toolchain runs** (`config.yaml` `code_context`): Repomix (and
|
|
21
21
|
Impeccable, later) are installed/run **here** and target the connected code repos **by path**. The
|
|
22
22
|
code repos themselves need no install for this. (The Build CI gates are the exception — they
|
|
23
23
|
live inside each code repo; see `yad-checks`.)
|
|
@@ -28,18 +28,15 @@ epic's approvals. It only writes the project-wide registry and the per-repo cont
|
|
|
28
28
|
|
|
29
29
|
## Inputs
|
|
30
30
|
|
|
31
|
-
- `action` — `connect` | `refresh` | `list` | `disconnect` | `detect-hub`
|
|
31
|
+
- `action` — `connect` | `refresh` | `list` | `disconnect` | `detect-hub` (default `connect`).
|
|
32
32
|
- `repo` — the repo's short name (the key used in stories' `repos:` tag, e.g. `backend`).
|
|
33
|
-
- `login`, `name`, `email`, `roles` — for `roster` (map login → name + commit email + the per-scope
|
|
34
|
-
`roles` map, e.g. `roles: hub=owner,reviewer backend=domain-owner`). Validate the login against the
|
|
35
|
-
hub (`gh api users/<login>` / `glab api users?username=`); a miss is flagged `unverified` (warn-only).
|
|
36
33
|
- `path` — local path to the code repo (relative to `{project-root}` or absolute). For local repos.
|
|
37
34
|
It must resolve inside the **workspace** — the project root's parent — so the standard layout, where
|
|
38
|
-
the code repos sit **beside** the
|
|
35
|
+
the code repos sit **beside** the Product rather than under it, registers as `../backend`:
|
|
39
36
|
|
|
40
37
|
```text
|
|
41
38
|
project/ <- the workspace (containment boundary)
|
|
42
|
-
product/ <- the
|
|
39
|
+
product/ <- the Product repo; `yad setup` runs here
|
|
43
40
|
backend/ <- ../backend
|
|
44
41
|
frontend/ <- ../frontend
|
|
45
42
|
```
|
|
@@ -49,12 +46,13 @@ epic's approvals. It only writes the project-wide registry and the per-repo cont
|
|
|
49
46
|
later used as a working directory (repomix) and written into (`.coderabbit.yaml`, CI wiring).
|
|
50
47
|
It is stored **exactly as typed**; every consumer re-resolves it against the project root.
|
|
51
48
|
|
|
52
|
-
The workspace is the trust boundary, so **put the
|
|
53
|
-
directly in `$HOME` — with the
|
|
49
|
+
The workspace is the trust boundary, so **put the Product one level below it** (`project/product`), not
|
|
50
|
+
directly in `$HOME` — with the Product at `~/product` the workspace becomes `~` and every home-dir
|
|
54
51
|
sibling turns into a registrable repo. The workspace directory itself (`..`) is never registrable.
|
|
55
52
|
- `git_url` — optional remote (SSH or HTTPS; GitHub or GitLab). Used when the repo is not yet on disk.
|
|
56
|
-
|
|
57
|
-
|
|
53
|
+
|
|
54
|
+
yadflow keeps **no list of people** (E62): no roster, no roles, no repo owners, no commit emails. Do not
|
|
55
|
+
ask for them and do not write them.
|
|
58
56
|
|
|
59
57
|
## On Activation
|
|
60
58
|
|
|
@@ -93,6 +91,30 @@ module layout**. Mark anything unclear `<!-- unverified: ... -->`; never fill ga
|
|
|
93
91
|
behaviour. This is the cheap artifact every Shape phase loads by default (the full pack is read only
|
|
94
92
|
when a phase needs depth).
|
|
95
93
|
|
|
94
|
+
### Step 3b — Draft the risk map (a level per directory, from the code)
|
|
95
|
+
Each code repo keeps `.sdlc/risk-map` **in the code repo**: one line per directory saying `high`, `medium`
|
|
96
|
+
or `low`, and **no names** (E65). Format, rubric and edit rules: `references/risk-map.md`.
|
|
97
|
+
|
|
98
|
+
1. Run `yad risk-map draft <path>` with the repo's **path**, not its name: on a first `connect` the repo is
|
|
99
|
+
not in `repos.json` until Step 4, and a name it does not know is refused. It adds an `unset` line for
|
|
100
|
+
every directory no line covers and never changes a line that is already there.
|
|
101
|
+
2. For every `unset` line, **read the code in that directory** — the pack, the code-map, and the files
|
|
102
|
+
themselves when those do not say — and decide the level by the rubric. Judge by what the code does,
|
|
103
|
+
never by the folder's name — with one exception, `.sdlc/`, which is `high` because it holds the risk
|
|
104
|
+
map (see the rubric). Write the level, `guessed`, and a one-line reason from the code
|
|
105
|
+
(`src/payments/ high guessed # charge.js calls the card processor`). When unsure between two levels,
|
|
106
|
+
choose the higher one. When a directory's parts differ, add a deeper line for each part.
|
|
107
|
+
3. A `guessed` line may be re-levelled if the code says otherwise — except `.sdlc/`, which is raised to
|
|
108
|
+
`high` if it is not (the rubric's one exception). **Never edit, re-level or delete a `confirmed` line**:
|
|
109
|
+
when the code now contradicts one, report it as a suggestion for a person. Never mark anything
|
|
110
|
+
`confirmed` — only a person does that. Write no name, secret or customer value.
|
|
111
|
+
4. Run `yad risk-map check <path>` and report what is left.
|
|
112
|
+
5. Tell the person to review every `guessed` line, change the right ones to `confirmed`, and commit
|
|
113
|
+
`.sdlc/risk-map` **in the code repo, on a new branch, through a PR** — never straight to its default branch. Its `risk-map` check warns on that PR that the map
|
|
114
|
+
was edited — expected, and advisory.
|
|
115
|
+
|
|
116
|
+
With no AI agent available, stop after step 1 and tell the person the `unset` lines are theirs to fill.
|
|
117
|
+
|
|
96
118
|
### Step 4 — Record the repo in the registry
|
|
97
119
|
Upsert the repo into `{project-root}/.sdlc/repos.json` (create the file if absent). Record the current
|
|
98
120
|
HEAD sha as `syncedHead` (this drives staleness):
|
|
@@ -104,8 +126,6 @@ HEAD sha as `syncedHead` (this drives staleness):
|
|
|
104
126
|
"path": "<path rel. to project-root>",
|
|
105
127
|
"git_url": "<url or null>",
|
|
106
128
|
"platform": "github|gitlab|null",
|
|
107
|
-
"domain_owners": ["<owner>", "…"],
|
|
108
|
-
"domain_owner": "<domain_owners[0] — legacy mirror>",
|
|
109
129
|
"default_branch": "<branch>",
|
|
110
130
|
"connectedAt": "<YYYY-MM-DD>",
|
|
111
131
|
"lastSyncedAt": "<YYYY-MM-DD>",
|
|
@@ -118,7 +138,9 @@ HEAD sha as `syncedHead` (this drives staleness):
|
|
|
118
138
|
}
|
|
119
139
|
```
|
|
120
140
|
`connect` is **idempotent** — re-running it for an existing repo refreshes its entry in place. Adding a
|
|
121
|
-
new repo later is the same `connect` action.
|
|
141
|
+
new repo later is the same `connect` action. Write no `domain_owner`/`domain_owners`; an entry an older
|
|
142
|
+
release wrote with them is left as it is (nothing reads them, and `yad doctor` warns
|
|
143
|
+
`people:domain-owners-unused`).
|
|
122
144
|
|
|
123
145
|
### Step 5 — Report
|
|
124
146
|
Report the connected repo, its `platform`, the pack + code-map paths, the secret-scan result, and that
|
|
@@ -126,12 +148,12 @@ the Shape phases will now load this repo's code-map. Nothing auto-advances; this
|
|
|
126
148
|
|
|
127
149
|
## Other actions
|
|
128
150
|
|
|
129
|
-
- **`refresh`** — re-run Steps 2–4 for an already-connected repo (after its code moves). Updates
|
|
151
|
+
- **`refresh`** — re-run Steps 2–4 (including Step 3b) for an already-connected repo (after its code moves). A new directory gets an `unset` line and a guess; a `confirmed` line is only ever suggested against. Updates
|
|
130
152
|
`syncedHead` + `lastSyncedAt`. Same machinery as `connect`. Once the AI has regenerated the
|
|
131
|
-
`code-map.md` (Step 3), publish it to the
|
|
153
|
+
`code-map.md` (Step 3), publish it to the Product with **`yad repo refresh <repo> --push`**: it
|
|
132
154
|
commits the tracked code-maps + `.sdlc/repos.json` (never the gitignored `pack.md`) as one
|
|
133
155
|
audit-trail commit `chore(hub): sync code-context — <repos> by @<login> [skip ci]` and pushes it
|
|
134
|
-
straight to the
|
|
156
|
+
straight to the Product's **default branch** (add `--allow-branch` to commit on a non-default branch).
|
|
135
157
|
This is the code-context analogue of `yad checkpoint` — human-owned machine state, no Task trailer,
|
|
136
158
|
no Co-Authored-By.
|
|
137
159
|
- **`list`** — print every registry entry with a **fresh/stale** flag: compare each repo's current HEAD
|
|
@@ -139,14 +161,14 @@ the Shape phases will now load this repo's code-map. Nothing auto-advances; this
|
|
|
139
161
|
- **`disconnect`** — remove the repo from the registry and delete its cache dir. Leaves the **code repo
|
|
140
162
|
itself untouched**.
|
|
141
163
|
|
|
142
|
-
##
|
|
164
|
+
## Product detection (the Shape review bridge)
|
|
143
165
|
|
|
144
|
-
The
|
|
145
|
-
approval cycle can run through a real PR/MR on the
|
|
146
|
-
|
|
166
|
+
The Product is itself a git repo on a platform. This action records that so the Shape review/comment/
|
|
167
|
+
approval cycle can run through a real PR/MR on the Product (`yad-review-gate` + `yad-hub-bridge`). It
|
|
168
|
+
writes only `{project-root}/.sdlc/hub.json` (`config.yaml` `product.config` (older projects: `hub.config`)) — never an epic's state/approvals.
|
|
147
169
|
|
|
148
|
-
- **`detect-hub`** — detect the
|
|
149
|
-
`git remote get-url origin` **on the
|
|
170
|
+
- **`detect-hub`** — detect the Product's own platform and upsert `.sdlc/hub.json`. Run
|
|
171
|
+
`git remote get-url origin` **on the Product** and read the host with the SAME logic Step 1 uses for code
|
|
150
172
|
repos: `github.com` → `github`, GitLab host → `gitlab`, no remote → `platform: null`. Record
|
|
151
173
|
`git_url`, `default_branch`, `detectedAt`, and **all three of** `ledger`, `bridge_enabled` and
|
|
152
174
|
`bridge`:
|
|
@@ -155,7 +177,10 @@ write only `{project-root}/.sdlc/hub.json` (`config.yaml` `hub.config`) — neve
|
|
|
155
177
|
|---|---|
|
|
156
178
|
| `"ledger": "verified"`, `bridge_enabled: true`, `bridge: true` | `"ledger": "local"`, `bridge_enabled: false`, `bridge: false` |
|
|
157
179
|
|
|
158
|
-
|
|
180
|
+
Write no `roster`. Leave any other key already in the file as it is — including a `roster` or
|
|
181
|
+
`verified_authors` an older release wrote. Neither decides anything (the roster's name → login pairs
|
|
182
|
+
only help the first sync recognise older approvals); `yad doctor` warns
|
|
183
|
+
`people:roster-unused` / `people:verified-authors-unused`, and nothing deletes them.
|
|
159
184
|
|
|
160
185
|
**`ledger` is the one that decides.** `isVerifiedLedger` (`cli/manifest.mjs`) reads it first and
|
|
161
186
|
falls back to the booleans only when it is absent — so on a project that has already run
|
|
@@ -168,22 +193,15 @@ write only `{project-root}/.sdlc/hub.json` (`config.yaml` `hub.config`) — neve
|
|
|
168
193
|
|
|
169
194
|
A platform and a verified ledger travel together: verified mode is a platform AND the switch
|
|
170
195
|
(`isVerifiedLedger`, `cli/manifest.mjs`), and `yad setup` derives both from one value, so marking a
|
|
171
|
-
platform-less
|
|
196
|
+
platform-less Product verified creates a state no CLI path can produce and the gates read
|
|
172
197
|
differently (#186).
|
|
173
198
|
Auth is the local user's own `gh`/`glab`/git; **store no tokens**. Idempotent — safe to re-run.
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
degrades to a plain `reviewer`, never auto-promoted to owner/domain-owner.
|
|
181
|
-
**The deterministic half is the `yad roster` CLI command** — runnable any time, not just at setup:
|
|
182
|
-
`yad roster list`; `yad roster add <login>` (upsert, then a repo-driven walk that asks for each
|
|
183
|
-
connected repo's role); `yad roster grant|revoke <name> <repo> <role>`; `yad roster remove <login>`.
|
|
184
|
-
A `domain-owner` grant/revoke keeps `repos.json` `domain_owners` in sync so the gate never drifts.
|
|
185
|
-
|
|
186
|
-
If the hub has no remote (`platform: null`) or the verified ledger is disabled, the Shape gate runs
|
|
199
|
+
|
|
200
|
+
There is **no roster action** (removed in E62). `yad roster` is gone too: typing it prints a notice and
|
|
201
|
+
exits 1. A team gate needs 1 approval from someone other than the author, and each approval records the
|
|
202
|
+
platform login that gave it. The platform, not a stored list, decides who can approve.
|
|
203
|
+
|
|
204
|
+
If the Product has no remote (`platform: null`) or the verified ledger is disabled, the Shape gate runs
|
|
187
205
|
local with no error — the verified ledger is purely additive.
|
|
188
206
|
|
|
189
207
|
## Live on-demand (the third context layer)
|
|
@@ -205,11 +223,14 @@ it does not silently re-pack. Refreshing the cache is a human decision. Document
|
|
|
205
223
|
- **Describe what exists; never invent.** The code-map records built behaviour, not a design.
|
|
206
224
|
- **Setup, not a gate.** Never touch `.sdlc/state.json`, approvals, or the contract lock from here.
|
|
207
225
|
- **Idempotent + refreshable.** `connect`/`refresh` are safe to re-run; staleness is HEAD-sha based.
|
|
226
|
+
- **The risk map holds no names, and the agent never confirms.** It fills `unset`, may re-level `guessed`,
|
|
227
|
+
and only suggests against `confirmed`.
|
|
208
228
|
|
|
209
229
|
## Reference
|
|
210
230
|
- Registry schema + freshness rule: `references/repos-registry.md`.
|
|
211
|
-
-
|
|
231
|
+
- The risk map — format, rubric, what the agent may change: `references/risk-map.md`.
|
|
232
|
+
- Product config (the review bridge): `references/hub-config.md`.
|
|
212
233
|
- Repomix command, secret-scan, degrade path, the code-map prompt, and live on-demand:
|
|
213
234
|
`references/code-context.md`.
|
|
214
235
|
- The repomix discipline this reuses (one-feature-at-a-time variant): `../yad-backfill/references/backfill.md`.
|
|
215
|
-
- Repos convention
|
|
236
|
+
- Repos convention: `../yad-stories/references/story-schema.md`.
|
|
@@ -6,7 +6,7 @@ variant; backfill is the one-feature-at-a-time variant).
|
|
|
6
6
|
|
|
7
7
|
## Layer 1 — the cached pack (full context)
|
|
8
8
|
|
|
9
|
-
Run from the
|
|
9
|
+
Run from the Product, targeting the connected repo (flags from `config.yaml`
|
|
10
10
|
`code_context.pack_flags`):
|
|
11
11
|
|
|
12
12
|
```
|
|
@@ -81,11 +81,11 @@ side-effect:** when a repo is stale (HEAD ≠ `syncedHead`), the phase **flags i
|
|
|
81
81
|
"`<repo>` is stale; run `yad repo refresh <repo>` to re-pack the cache + `syncedHead`" — rather than
|
|
82
82
|
silently re-packing the whole repo. A phase never refreshes the registry on its own; the human runs
|
|
83
83
|
`yad repo refresh` (or `yad check --fix`). After the AI regenerates the code-map, `yad repo refresh
|
|
84
|
-
--push` publishes the refreshed code-maps + registry to the
|
|
84
|
+
--push` publishes the refreshed code-maps + registry to the Product's default branch as a `chore(hub): sync
|
|
85
85
|
code-context … [skip ci]` audit commit (never the pack's content; `--allow-branch` overrides the branch
|
|
86
86
|
guard). The `pack.md` is gitignored — `yad repo refresh`/`yad setup` scaffold
|
|
87
|
-
`.sdlc/code-context/*/pack.md` into the
|
|
88
|
-
and a
|
|
87
|
+
`.sdlc/code-context/*/pack.md` into the Product `.gitignore` (so a regenerated pack never dirties the tree),
|
|
88
|
+
and a Product that tracked the pack *before* that ignore existed is self-healed: `--push` untracks it and
|
|
89
89
|
lands the removal + the managed `.gitignore` line in the same audit commit. The commit is a scoped
|
|
90
90
|
`git commit -- <paths>` — it never sweeps unrelated staged work, and an unrelated hand-edit to
|
|
91
91
|
`.gitignore` is left for the human to commit rather than riding the `[skip ci]` audit commit.
|
|
@@ -1,80 +1,75 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Product config — schema, detection, and who is recorded
|
|
2
2
|
|
|
3
|
-
The
|
|
4
|
-
approval cycle can run through a real PR/MR on the
|
|
5
|
-
|
|
3
|
+
The Product config is the Product's record of **its own** platform (so the Shape review/comment/
|
|
4
|
+
approval cycle can run through a real PR/MR on the Product). It holds **no list of people** — no roster,
|
|
5
|
+
no roles, no commit emails (E62). It is a single object for the Product itself — the sibling of the per-repo
|
|
6
6
|
`repos.json` registry (see `repos-registry.md`), kept separate so it never pollutes that array.
|
|
7
7
|
|
|
8
8
|
## Location
|
|
9
9
|
|
|
10
10
|
`{project-root}/.sdlc/hub.json`
|
|
11
11
|
|
|
12
|
-
(`config.yaml` `hub.config
|
|
12
|
+
(`config.yaml` `product.config` (older projects: `hub.config`).) Created/updated by `yad-connect-repos action: detect-hub`.
|
|
13
13
|
|
|
14
14
|
## Schema
|
|
15
15
|
|
|
16
16
|
```json
|
|
17
17
|
{
|
|
18
|
-
"schemaVersion":
|
|
19
|
-
"platform": "github", // github | gitlab (from the
|
|
18
|
+
"schemaVersion": 10, // the file's shape. Absent means 1 (rule 1). `yad migrate` moves it; see docs/migrations/shape-2.md
|
|
19
|
+
"platform": "github", // github | gitlab (from the Product's own remote host); null when local-only
|
|
20
20
|
"git_url": "https://github.com/abdelrahmannasr/yadflow.git", // REQUIRED when platform is non-null (scopes auth + opens PRs); yad doctor warns YAD-CFG-005 if absent
|
|
21
21
|
"default_branch": "main",
|
|
22
22
|
"ledger": "verified", // WHO WRITES THE LEDGER, and the one that decides: "verified" = CI only, signed; "local" = this machine. Travels WITH platform — verified is both (isVerifiedLedger), so never "verified" beside platform: null (#186)
|
|
23
23
|
"bridge_enabled": true, // the older spelling of the same switch, kept so a check gate that predates `yad update` still reads it. Write it to MATCH `ledger`, never against it
|
|
24
24
|
"bridge": true, // older still. Same rule
|
|
25
|
-
"gate_sync_version": "
|
|
25
|
+
"gate_sync_version": "4.0.0", // OPTIONAL exact pin for the wired gate-sync job; an exact release of the wired fragment's major (4.x.y in this release), prereleases included (4.1.0-rc.1) — anything else, a 3.x pin included, is skipped. Omitted => the .sdlc/cli-version.json stamp if that qualifies, else floating on that major
|
|
26
26
|
"review": { "requireEngagement": false }, // Review Companion: false (soft) counts bare approves but nudges; true counts only verified-engagement approvals
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
{ "login": "carol-gh", "name": "carol", "email": "carol@example.com",
|
|
32
|
-
"roles": { "hub": ["reviewer"], "backend": ["domain-owner", "owner"], "payments": ["reviewer"] } }
|
|
33
|
-
]
|
|
27
|
+
"solo": false, // SOLO MODE, and the one that decides: true waives the approval requirement on every review gate (the merge + resolved threads still gate). Set by `yad setup --solo` / `--team <n>` or `yad mode`
|
|
28
|
+
"mode": "team", // the roadmap's name for the same switch (E10): "solo" | "team", written beside `solo` by `yad mode` and `yad setup`. NOT read by the gates this major — `yad doctor` warns `mode:disagree` when it contradicts `solo`. Not the ledger switch: "verified mode" elsewhere means `ledger`
|
|
29
|
+
"mode_set": { "from": "solo", "to": "team", "by": "al", "date": "2026-09-15", "reason": null }, // the last change of mode (E10): who, when, why. `yad mode solo` requires the reason
|
|
30
|
+
"detectedAt": "2026-06-08" // last detect-hub run (YYYY-MM-DD)
|
|
34
31
|
}
|
|
35
32
|
```
|
|
36
33
|
|
|
37
|
-
##
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
**
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
it stays a plain reviewer until a human adds it to the roster, so a stranger cannot satisfy the
|
|
66
|
-
owner/domain-owner requirement.
|
|
34
|
+
## People — no roster (E62)
|
|
35
|
+
|
|
36
|
+
yadflow keeps **no stored list of people**. A list is a claim that goes stale; the platform already knows
|
|
37
|
+
who is logged in and who has access.
|
|
38
|
+
|
|
39
|
+
- **Who a record names.** A record's `by` is the platform login that `gh api user` / `glab api user`
|
|
40
|
+
reports, else git `user.name` (no platform, CLI missing or logged out, no network).
|
|
41
|
+
`YAD_PLATFORM_LOGIN=0` turns the lookup off.
|
|
42
|
+
- **Approvals.** Each approval records the platform login that gave it as `approver`, with no `role` and
|
|
43
|
+
no `domain`. A team gate needs at least **1 approval from someone other than the author**, plus
|
|
44
|
+
resolved threads and a merged PR. The full count is `base 1 + risk step` (`contract` +2, `auth` /
|
|
45
|
+
`payments` +1, the largest and never the sum); the gate caps it at the active people less one and
|
|
46
|
+
reports that (E72); the risk step is advisory. Solo
|
|
47
|
+
mode still waives the approval.
|
|
48
|
+
- **Reviewers.** Nothing requests reviewers on a PR/MR. Ask them on the PR/MR itself. `yad open-pr`
|
|
49
|
+
prints a suggestion for a code-repo PR (E68) from recent history and CODEOWNERS — a hint only.
|
|
50
|
+
|
|
51
|
+
**Legacy data an older release wrote.** A `roster` array (with `login`/`name`/`email`/`roles`, or the
|
|
52
|
+
older `role`) and a `verified_authors` list may still sit in this file. Nothing adds them, and nothing
|
|
53
|
+
deletes them (`yad migrate`'s shape-3 step still adds a `product` role key beside `hub` in an old roster, so
|
|
54
|
+
an older project upgrades the same way it always did). `verified_authors` decides nothing — only `yad doctor`
|
|
55
|
+
reads it, to warn. The roster is read for one thing only: its `name` →
|
|
56
|
+
`login` pairs let a gate write record the login on older approval and comment records
|
|
57
|
+
(`../../yad-hub-bridge/references/login-roster.md` → "Recording the login on older records"). `yad doctor`
|
|
58
|
+
warns `people:roster-unused` and `people:verified-authors-unused` so nobody edits them believing they decide
|
|
59
|
+
something. Delete `verified_authors` when convenient; delete `roster` when `people:roster-unused` says it
|
|
60
|
+
can go — no older record needs it any more, or only records it cannot place are left and their reviews are
|
|
61
|
+
closed.
|
|
67
62
|
|
|
68
63
|
## Detection
|
|
69
64
|
|
|
70
65
|
`detect-hub` reuses the same host-detection logic this skill already applies to code repos:
|
|
71
|
-
run `git remote get-url origin` **on the
|
|
66
|
+
run `git remote get-url origin` **on the Product itself** and read the host —
|
|
72
67
|
`github.com` → `github`, `gitlab.com`/self-hosted GitLab → `gitlab`, no remote → `platform: null`.
|
|
73
68
|
Auth is the **local user's own** `gh`/`glab`/git credentials; **no tokens are ever stored** (same rule
|
|
74
69
|
as the registry). `detect-hub` upserts `hub.json` in place — it is idempotent and safe to re-run.
|
|
75
70
|
|
|
76
71
|
**`git_url` is required whenever `platform` is non-null.** `yad doctor` uses it to scope the auth
|
|
77
|
-
probe to the
|
|
72
|
+
probe to the Product's own host (an unscoped `glab auth status` fails on any unrelated broken instance),
|
|
78
73
|
and the verified ledger/PR flow uses it to open PRs. Doctor flags its absence with a warn (`YAD-CFG-005`);
|
|
79
74
|
re-running `yad setup` backfills it from the origin remote (idempotent, non-interactive).
|
|
80
75
|
|
|
@@ -92,10 +87,10 @@ So on a migrated project `ledger` wins, and writing a boolean that contradicts i
|
|
|
92
87
|
Keep all three in step.
|
|
93
88
|
|
|
94
89
|
- `ledger: "verified"` **and** a non-null `platform` **and** `gh`/`glab` authenticated → the Shape
|
|
95
|
-
review opens a PR/MR on the
|
|
90
|
+
review opens a PR/MR on the Product and `yad-review-gate action: sync` pulls platform state into the ledger.
|
|
96
91
|
- `ledger: "local"`, `platform: null`, or no/unauthenticated CLI → the gate falls back to the
|
|
97
92
|
existing **local** flow with no error. The file ledger is the source of truth in both modes.
|
|
98
|
-
- The master switch `config.yaml` `
|
|
93
|
+
- The master switch `config.yaml` `product.bridge: false` (older projects: `hub.bridge`) disables the verified ledger globally regardless of `hub.json`.
|
|
99
94
|
|
|
100
95
|
## Review Companion engagement (`review.requireEngagement`)
|
|
101
96
|
|
|
@@ -108,11 +103,12 @@ read the artifact. Applies to both the Shape gate and the Build engineer review.
|
|
|
108
103
|
|
|
109
104
|
## Git tracking
|
|
110
105
|
|
|
111
|
-
Commit `hub.json` — it is small, reviewable, and carries no secrets
|
|
106
|
+
Commit `hub.json` — it is small, reviewable, and carries no secrets or tokens. The only people data in it is the login or git name in `mode_set.by`, plus
|
|
107
|
+
whatever an older `roster` still lists.
|
|
112
108
|
This mirrors how `repos.json` and the per-epic `.sdlc/` state are committed.
|
|
113
109
|
|
|
114
110
|
## Greenfield
|
|
115
111
|
|
|
116
|
-
A brand-new
|
|
112
|
+
A brand-new Product has no `hub.json`. That is valid — the Shape gate runs local until `detect-hub`
|
|
117
113
|
records a platform. The verified ledger is purely additive; nothing about authoring or the gate predicate changes.
|
|
118
114
|
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Repos registry — schema + freshness rule
|
|
2
2
|
|
|
3
|
-
The registry is the
|
|
3
|
+
The registry is the Product's record of which code repos are connected and where their cached
|
|
4
4
|
code-context lives. It is **project-wide** (shared across every epic), so it lives at the product root,
|
|
5
5
|
not under any `epics/EP-<slug>/.sdlc/`.
|
|
6
6
|
|
|
@@ -21,8 +21,6 @@ not under any `epics/EP-<slug>/.sdlc/`.
|
|
|
21
21
|
"path": "demo-repos/backend", // path to the code repo, rel. to {project-root} (or absolute)
|
|
22
22
|
"git_url": "git@github.com:org/backend.git", // optional remote; SSH or HTTPS; GitHub or GitLab; null if local-only
|
|
23
23
|
"platform": "github", // github | gitlab (from the URL host); null when local-only
|
|
24
|
-
"domain_owners": ["carol", "dave"], // engineers who own this repo's domain (review routing); a repo may have several
|
|
25
|
-
"domain_owner": "carol", // legacy single-owner mirror = domain_owners[0] (kept for back-compat readers)
|
|
26
24
|
"default_branch": "main",
|
|
27
25
|
"connectedAt": "2026-06-08", // first connect (YYYY-MM-DD)
|
|
28
26
|
"lastSyncedAt": "2026-06-08", // last connect/refresh
|
|
@@ -37,6 +35,9 @@ not under any `epics/EP-<slug>/.sdlc/`.
|
|
|
37
35
|
|
|
38
36
|
## Rules
|
|
39
37
|
|
|
38
|
+
- **No owners.** An entry names no people (E62). `connect` writes no `domain_owner`/`domain_owners`. An
|
|
39
|
+
entry an older release wrote with them keeps them; nothing reads them, nothing deletes them, and
|
|
40
|
+
`yad doctor` warns `people:domain-owners-unused`.
|
|
40
41
|
- **`name`** is the join key. It MUST match the names used in epic/story `repos:` tags so the Shape
|
|
41
42
|
phases can map `epic.repos` → registry entries → code-maps. Keep it stable.
|
|
42
43
|
- **Auth is never stored.** No tokens, passwords, or PATs in the registry. `git_url` is a plain remote;
|
|
@@ -52,14 +53,14 @@ not under any `epics/EP-<slug>/.sdlc/`.
|
|
|
52
53
|
|
|
53
54
|
Commit the **registry** (`repos.json`) and each repo's **`code-map.md`** — they are small, reviewable,
|
|
54
55
|
and are what the Shape phases actually read (a diff on a code-map shows when a repo's surface moved).
|
|
55
|
-
`yad repo refresh --push` commits and pushes exactly these (never `pack.md`) to the
|
|
56
|
+
`yad repo refresh --push` commits and pushes exactly these (never `pack.md`) to the Product's default
|
|
56
57
|
branch as one `chore(hub): sync code-context … [skip ci]` audit commit.
|
|
57
|
-
**Ignore** the full Repomix `pack.md` — it is large and regenerable (`action: refresh`). The
|
|
58
|
-
|
|
58
|
+
**Ignore** the full Repomix `pack.md` — it is large and regenerable (`action: refresh`). The Product
|
|
59
|
+
's `.gitignore` carries `.sdlc/code-context/*/pack.md` for this. This mirrors how the per-epic
|
|
59
60
|
`.sdlc/` state (state.json, approvals.json, build-log.json) is committed.
|
|
60
61
|
|
|
61
62
|
## Greenfield
|
|
62
63
|
|
|
63
|
-
A brand-new
|
|
64
|
+
A brand-new Product has no `repos.json` (or an empty `{ "repos": [] }`). That is valid — the Shape
|
|
64
65
|
phases treat "no repos connected" as "nothing to consider yet" and proceed unchanged. The registry
|
|
65
66
|
appears the first time `connect` runs.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Risk map — format, the classification rubric, and the rules for the agent
|
|
2
|
+
|
|
3
|
+
A code repo's **risk map** is one file, `.sdlc/risk-map`, **in the code repo** (not the Product). It
|
|
4
|
+
gives each directory a risk level. It holds **no names** — no people, no roles, no teams, no `@login`.
|
|
5
|
+
It is the team's file: `yad update` never installs, owns or overwrites it, and it changes only through
|
|
6
|
+
that repo's PRs (E65).
|
|
7
|
+
|
|
8
|
+
**What the levels do (E66).** A change touching a `high` directory asks for one more approver. The count
|
|
9
|
+
reads the map on the **base branch**, so a PR cannot lower its own count, and a `guessed` level counts
|
|
10
|
+
exactly as a `confirmed` one. That is why a guess matters: a `high` guess adds a reviewer to every change
|
|
11
|
+
under that directory until a person confirms or changes it. `medium` and `low` add nothing. The count is
|
|
12
|
+
reported, not enforced: branch protection holds the merge, and `yad open-pr` shows the count capped by the
|
|
13
|
+
active people (E72). A `high` directory also asks for an approval from someone who has committed there in the last 30 days
|
|
14
|
+
(E67), named live from the base branch's history — so a guess here decides who can review, too.
|
|
15
|
+
|
|
16
|
+
## Format
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
# yad-risk-map v1
|
|
20
|
+
src/payments/ high confirmed # charge.js calls the card processor
|
|
21
|
+
src/catalog/ low guessed # read-only product listing
|
|
22
|
+
docs/ unset
|
|
23
|
+
./ low confirmed # the files at the repo root
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
| Rule | Meaning |
|
|
27
|
+
|---|---|
|
|
28
|
+
| Header | The first line is `# yad-risk-map v1`. |
|
|
29
|
+
| One line per directory | `<dir>/ <level> <guessed\|confirmed>`, fields split on spaces or tabs, so a path holds none. |
|
|
30
|
+
| Directory | Written from the repo root, ending in `/`. No leading `/` or `#`, no `.` or `..` segment, no space, tab, `*`, `?`, `[` or `\`. A directory whose name holds one of those (`app/[slug]/`) cannot have a line of its own: its parent's line covers it. At the top level (`my docs/`) nothing can, and the check says to rename it. |
|
|
31
|
+
| `./` | The files **at** the repo root only — not everything below it. |
|
|
32
|
+
| Which line decides | The deepest listed directory above a file. |
|
|
33
|
+
| Levels | `high`, `medium`, `low`, or `unset` (listed, not classified; its state may be left out). |
|
|
34
|
+
| States | `guessed` (an AI agent filled it in) or `confirmed` (a person checked it). |
|
|
35
|
+
| Comment | Everything from the first `#` that follows a space or tab. |
|
|
36
|
+
| Names | A word starting `@` (`@alice`, `@org/team`) is a name and is warned about. A word ending in `/` (`@types/`) is a directory. |
|
|
37
|
+
| No `contract` | The contract surface keeps its own lock, `contract-check` and `Contract-Change` trailer. |
|
|
38
|
+
|
|
39
|
+
The rules are code: `cli/riskmap.mjs`, with a bash twin in `checks/risk-map-check.sh`.
|
|
40
|
+
|
|
41
|
+
## Rubric — read the CODE, not the folder name (one exception, below)
|
|
42
|
+
|
|
43
|
+
Decide from what the code in the directory **does**: the calls it makes, the data it writes, the
|
|
44
|
+
libraries it imports. A folder called `utils/` can move money; a folder called `payments/` can hold only
|
|
45
|
+
display text. Use the pack and the code-map first, and open the files themselves when they do not say.
|
|
46
|
+
|
|
47
|
+
| Level | The code in the directory… |
|
|
48
|
+
|---|---|
|
|
49
|
+
| `high` | moves money or bills anyone; handles login, sessions, tokens, permissions, secrets or keys; deletes stored data or changes its shape (migrations); reads or writes personal data (identity, contact, health, payment details); builds, deploys or releases (CI workflows, deploy scripts, infrastructure); and `.sdlc/` — see the exception below the table |
|
|
50
|
+
| `medium` | writes to a database, a queue or an outside service in ordinary ways; serves a public API or event others depend on; is a shared library most of the code imports; sets build or dependency configuration |
|
|
51
|
+
| `low` | only reads and shows data; styling and UI text; documentation; tests, fixtures and examples; developer tooling that never ships |
|
|
52
|
+
|
|
53
|
+
- **When unsure between two levels, choose the higher one** and say what you could not tell in the reason.
|
|
54
|
+
- **Split a directory when its parts differ.** If `src/` holds `payments/` (`high`) and `catalog/` (`low`),
|
|
55
|
+
write a line for each part, and keep a line for `src/` itself for the files directly in it.
|
|
56
|
+
- **The one exception: `.sdlc/` is `high`**, judged by what it HOLDS — this map, which decides how much
|
|
57
|
+
review every later change needs — not by what its code does (the user's decision, 2026-09-17). A
|
|
58
|
+
`yad update` PR touches that folder too, so those PRs ask for the extra approver as well; accepted,
|
|
59
|
+
because they rewrite the gate scripts the repo runs.
|
|
60
|
+
- **The reason is one line, taken from the code**: a file and what it does (`charge.js calls the card
|
|
61
|
+
processor`). Never a name, a secret, a customer value or an address.
|
|
62
|
+
|
|
63
|
+
## What the agent may and may not change
|
|
64
|
+
|
|
65
|
+
| Line | The agent may… | The agent may not… |
|
|
66
|
+
|---|---|---|
|
|
67
|
+
| `unset` | give it a level, a reason and `guessed` | mark it `confirmed` |
|
|
68
|
+
| `guessed` | change its level or reason, keeping `guessed` | mark it `confirmed` |
|
|
69
|
+
| `confirmed` | nothing — print a **suggestion** when the code now says otherwise | edit, re-level or delete it |
|
|
70
|
+
| any | add a deeper line when a directory's parts differ | delete a line, or add a name |
|
|
71
|
+
|
|
72
|
+
Only a person turns `guessed` into `confirmed`, in a PR in the code repo. The commit records who.
|
|
73
|
+
|
|
74
|
+
## Staying true
|
|
75
|
+
|
|
76
|
+
| Where | What it says |
|
|
77
|
+
|---|---|
|
|
78
|
+
| `checks/risk-map-check.sh` on every PR (both CI templates) | a file this change adds or edits that no line covers (names the directory to add); a line whose directory holds no file; a touched line still `unset` or `guessed`; a line it cannot read or that names a person; a change that edits the map itself. **Warnings only** — it never fails the build |
|
|
79
|
+
| `yad risk-map check [repo]` | the same, for the whole repo |
|
|
80
|
+
| `yad doctor`, section `risk-map` | one line per connected repo on disk |
|
|
81
|
+
| `yad repo refresh` + this skill | a new directory is drafted `unset` and classified; a `confirmed` line the code now contradicts is printed as a suggestion |
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: yad-connect-testing
|
|
3
|
-
description: 'Connects a testing tool (Playwright, or another tool — pluggable) to the
|
|
3
|
+
description: 'Connects a testing tool (Playwright, or another tool — pluggable) to the Product so the test-cases step can implement the actual automation tests, not just Markdown test cases. Registers the tool into the project-wide .sdlc/testing.json (local-user / MCP-session auth, no stored tokens), detecting whether a testing-tool MCP is available and degrading to artifacts-only when it is not. Run at setup or any time the testing tool changes. Reusable, idempotent, refreshable. Use when the user says "connect Playwright", "connect a testing tool", "refresh the testing connection", or "list the testing connection".'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# SDLC — Connect a Testing Tool (make the test-cases step automation-aware)
|
|
7
7
|
|
|
8
8
|
**Goal:** Let the test-cases step (`yad-test-cases`) produce the **actual automation tests** — the
|
|
9
9
|
runnable specs in a connected code repo — alongside the Markdown artifact (`test-cases.md`). This skill
|
|
10
|
-
**connects** a testing tool such as **Playwright** to the
|
|
10
|
+
**connects** a testing tool such as **Playwright** to the Product and records *how* to reach it (the
|
|
11
11
|
tool, the suite references, which MCP runs it) — never a credential.
|
|
12
12
|
|
|
13
13
|
This is **setup/maintenance**, not a gated Shape step — it never touches `.sdlc/state.json` or any
|
|
@@ -18,7 +18,7 @@ connected, `yad-test-cases` runs artifacts-only exactly as before.
|
|
|
18
18
|
|
|
19
19
|
## Conventions
|
|
20
20
|
|
|
21
|
-
- `{project-root}` resolves from the project working directory (the **
|
|
21
|
+
- `{project-root}` resolves from the project working directory (the **Product**).
|
|
22
22
|
- The integration is **Playwright-first but pluggable** (`config.yaml` `testing.tools`): a testing-tool
|
|
23
23
|
*adapter*, like the GitHub/GitLab platform adapter or the design-tool adapter. Playwright is the
|
|
24
24
|
primary provider; `cypress`, `pytest` and `maestro` are second providers; `none` → artifacts-only.
|
|
@@ -29,7 +29,7 @@ connected, `yad-test-cases` runs artifacts-only exactly as before.
|
|
|
29
29
|
the sibling of `.sdlc/repos.json`, `.sdlc/hub.json`, and `.sdlc/design.json`.
|
|
30
30
|
- Per-epic test→suite links are written later by `yad-test-cases`
|
|
31
31
|
(`epics/EP-<slug>/.sdlc/test-links.json`), not here.
|
|
32
|
-
- Speak in the
|
|
32
|
+
- Speak in the `communication_language` set in `{project-root}/.sdlc/config.yaml`; write documents in `document_output_language`.
|
|
33
33
|
|
|
34
34
|
## Inputs
|
|
35
35
|
|
|
@@ -101,7 +101,7 @@ automation tests here**. Nothing auto-advances; this is setup.
|
|
|
101
101
|
**available/unavailable** flag for the MCP (best-effort, the user's own session). No testing tool
|
|
102
102
|
connected ⇒ "artifacts-only".
|
|
103
103
|
- **`disconnect`** — remove the registry file (or set `tool: "none"`). The testing tool's own
|
|
104
|
-
project/suites are **never touched** — only the
|
|
104
|
+
project/suites are **never touched** — only the Product's record of them.
|
|
105
105
|
|
|
106
106
|
## Hard rules
|
|
107
107
|
|
|
@@ -27,8 +27,7 @@ produce.
|
|
|
27
27
|
|
|
28
28
|
## Generate (write automation tests into the repo)
|
|
29
29
|
|
|
30
|
-
When the connected provider is write-capable, the `test architect` lens (
|
|
31
|
-
`bmad-testarch-automate`) produces the epic's automation tests in the connected code repo(s), covering
|
|
30
|
+
When the connected provider is write-capable, the `test architect` lens produces the epic's automation tests in the connected code repo(s), covering
|
|
32
31
|
the cases `test-cases.md` enumerates and the acceptance criteria the stories define:
|
|
33
32
|
|
|
34
33
|
- **Playwright** — the lens authors `*.spec.ts` E2E/API specs (reusing the repo's existing fixtures and
|
|
@@ -43,7 +42,7 @@ the cases `test-cases.md` enumerates and the acceptance criteria the stories def
|
|
|
43
42
|
|
|
44
43
|
Reuse what already exists: load the connected code repos' code-maps (`yad-test-cases` Step 2b) so
|
|
45
44
|
generated tests target real endpoints/components, not invented ones, and prefer the lowest useful test
|
|
46
|
-
level (unit > integration > E2E)
|
|
45
|
+
level (unit > integration > E2E).
|
|
47
46
|
|
|
48
47
|
## Link (reference an existing suite)
|
|
49
48
|
|
|
@@ -55,7 +54,7 @@ path/name + URL, and map it to the story it covers.
|
|
|
55
54
|
|
|
56
55
|
Either direction ends by writing `epics/EP-<slug>/.sdlc/test-links.json` — the machine-readable
|
|
57
56
|
case→test map — and a `## Automation (<tool>)` section in `test-cases.md` linking each case to its test.
|
|
58
|
-
The tests themselves live in the code repo; the
|
|
57
|
+
The tests themselves live in the code repo; the Product keeps the *links* and the Markdown spec beside the
|
|
59
58
|
other epic artifacts.
|
|
60
59
|
|
|
61
60
|
## Degrade path (no MCP / no tool)
|