yadflow 2.2.0 → 2.3.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 +2 -9
- package/README.md +36 -15
- package/cli/doctor.mjs +23 -3
- package/cli/epic-state.mjs +19 -2
- package/cli/errors.mjs +1 -0
- package/cli/manifest.mjs +11 -1
- package/cli/setup.mjs +60 -10
- package/docs/index.html +37 -11
- package/package.json +1 -1
- package/skills/sdlc/config.yaml +20 -4
- package/skills/sdlc/install.sh +1 -1
- package/skills/sdlc/module-help.csv +3 -1
- package/skills/yad-analysis/SKILL.md +10 -5
- package/skills/yad-connect-design/SKILL.md +1 -1
- package/skills/yad-connect-design/references/design-registry.md +4 -2
- package/skills/yad-connect-testing/SKILL.md +121 -0
- package/skills/yad-connect-testing/references/testing-context.md +67 -0
- package/skills/yad-connect-testing/references/testing-registry.md +55 -0
- package/skills/yad-epic/SKILL.md +10 -5
- package/skills/yad-epic/references/state-schema.md +42 -11
- package/skills/yad-hub-bridge/SKILL.md +2 -2
- package/skills/yad-review-gate/SKILL.md +14 -11
- package/skills/yad-review-gate/references/gating.md +1 -1
- package/skills/yad-run/references/run-loop.md +3 -3
- package/skills/yad-spec/SKILL.md +3 -1
- package/skills/yad-status/SKILL.md +8 -5
- package/skills/yad-stories/SKILL.md +3 -1
- package/skills/yad-test-cases/SKILL.md +173 -0
- package/skills/yad-test-cases/references/test-cases-schema.md +70 -0
package/skills/sdlc/config.yaml
CHANGED
|
@@ -20,12 +20,12 @@ output_folder: "{project-root}/_bmad-output"
|
|
|
20
20
|
defaults:
|
|
21
21
|
assistance: review # none | review | heavy
|
|
22
22
|
automation: human_approve # human_approve | machine_advance
|
|
23
|
-
# Front steps (analysis [optional], epic, architecture, ui-design, stories) are locked to
|
|
23
|
+
# Front steps (analysis [optional], epic, architecture, ui-design, stories, test-cases) are locked to
|
|
24
24
|
# human_approve and may NOT be set to machine_advance in this version (build plan §1, §8.7).
|
|
25
25
|
front_steps_locked: true
|
|
26
26
|
# Each front authoring step opens its own branch at the start of the step (the <step> is the step id:
|
|
27
|
-
# analysis | epic | architecture | ui-design | stories). Git/greenfield-safe; distinct
|
|
28
|
-
# bridge's review branch (hub.artifact_branch). See yad-epic/references/state-schema.md.
|
|
27
|
+
# analysis | epic | architecture | ui-design | stories | test-cases). Git/greenfield-safe; distinct
|
|
28
|
+
# from the bridge's review branch (hub.artifact_branch). See yad-epic/references/state-schema.md.
|
|
29
29
|
front_authoring_branch: "<step>/EP-<slug>"
|
|
30
30
|
|
|
31
31
|
# Team review gate defaults (build plan §3 piece 2, §4).
|
|
@@ -134,6 +134,22 @@ design:
|
|
|
134
134
|
# NO tokens in the registry (project_url/files are plain references, never credentials).
|
|
135
135
|
auth: user
|
|
136
136
|
|
|
137
|
+
# Testing tool (yad-connect-testing) — the test-cases step (yad-test-cases) materializes the actual
|
|
138
|
+
# automation tests inside a connected testing tool, alongside test-cases.md. The tool is reached through
|
|
139
|
+
# its MCP (a harness MCP server, like the design tool — NOT a CLI), detected per provider and DEGRADING
|
|
140
|
+
# to artifacts-only when absent. Playwright-first but PLUGGABLE: a testing-tool adapter, like the
|
|
141
|
+
# design-tool adapter. Connection is one-per-project, recorded at setup; the per-epic case->test map
|
|
142
|
+
# (test-links.json) is written by yad-test-cases per epic.
|
|
143
|
+
testing:
|
|
144
|
+
registry: "{project-root}/.sdlc/testing.json" # project-wide testing connection (NOT per-epic)
|
|
145
|
+
tools: [playwright, cypress, pytest] # supported adapters; an unknown tool falls back to `primary`
|
|
146
|
+
primary: playwright # the default/named provider
|
|
147
|
+
degrade: artifacts-only # no tool / no MCP => yad-test-cases authors test-cases.md only
|
|
148
|
+
links: "{project-root}/epics/EP-<slug>/.sdlc/test-links.json" # per-epic case->test map (yad-test-cases)
|
|
149
|
+
# Auth: `yad-connect-testing` connects through the LOCAL user's own authenticated MCP session and stores
|
|
150
|
+
# NO tokens in the registry (project_url/suites are plain references, never credentials).
|
|
151
|
+
auth: user
|
|
152
|
+
|
|
137
153
|
# Hub platform + front-half review bridge (yad-connect-repos `detect-hub`; yad-review-gate + yad-hub-bridge).
|
|
138
154
|
# The product hub is itself a git repo on a platform. With the bridge enabled, the front-half review/
|
|
139
155
|
# comment/approval cycle runs through a real PR/MR on the hub: a review PR is opened per artifact, reviewers
|
|
@@ -166,7 +182,7 @@ automation:
|
|
|
166
182
|
# Hard lock — the dial-setter REFUSES machine_advance for these, regardless of trust evidence.
|
|
167
183
|
# The front authoring steps (already locked:true in state.json; analysis is optional) + the human
|
|
168
184
|
# merge gate.
|
|
169
|
-
locked_steps: [analysis, epic, architecture, ui-design, stories, engineer-review]
|
|
185
|
+
locked_steps: [analysis, epic, architecture, ui-design, stories, test-cases, engineer-review]
|
|
170
186
|
# Kill switch (phase-4-build-plan.md §Safety): true => every step forced to human_approve
|
|
171
187
|
# system-wide, no per-step edits. One line, instantly reversible. Toggle via `yad-run action: kill`.
|
|
172
188
|
kill_switch: false
|
package/skills/sdlc/install.sh
CHANGED
|
@@ -11,7 +11,7 @@ set -euo pipefail
|
|
|
11
11
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
12
12
|
cd "$ROOT"
|
|
13
13
|
|
|
14
|
-
SKILLS=(yad-analysis yad-epic yad-architecture yad-ui yad-stories yad-connect-repos yad-connect-design yad-spec yad-implement yad-checks yad-pr-template yad-review-comments yad-hub-bridge yad-ship yad-backfill yad-run yad-review-gate yad-status)
|
|
14
|
+
SKILLS=(yad-analysis yad-epic yad-architecture yad-ui yad-stories yad-test-cases yad-connect-repos yad-connect-design yad-connect-testing yad-spec yad-implement yad-checks yad-pr-template yad-review-comments yad-hub-bridge yad-ship yad-backfill yad-run yad-review-gate yad-status)
|
|
15
15
|
|
|
16
16
|
echo "Installing sdlc module from $ROOT/skills ..."
|
|
17
17
|
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
module,skill,display-name,menu-code,description,action,args,phase,preceded-by,followed-by,required,output-location,outputs
|
|
2
2
|
SDLC Workflow,yad-epic,Author Epic,AE,"Front state 1: shape an idea with analyst then pm into epic.md; assign EP-<slug> ID and seed .sdlc state. Never auto-advances.",,{idea: one-line feature idea},1-front,,yad-review-gate,true,epics/EP-<slug>/,epic.md state.json
|
|
3
|
-
SDLC Workflow,yad-review-gate,Team Review Gate,RG,"Reusable review+approve gate for all
|
|
3
|
+
SDLC Workflow,yad-review-gate,Team Review Gate,RG,"Reusable review+approve gate for all five reviews. Shares an artifact for review, records comments and approvals as files, enforces owner + 1 reviewer (escalates on contract/auth/payments; per-repo routing for stories), advances state only when approved.",,{artifact: file under the epic} {action: open|comment|approve|advance},1-front,,,true,epics/EP-<slug>/reviews/,reviews/*.md approvals.json state.json
|
|
4
4
|
SDLC Workflow,yad-architecture,Author Architecture,AA,"Front state 3: with the architect author architecture.md and the locked contract.md; hash-lock the contract surface. Never auto-advances.",,{epic: EP-<slug>},1-front,yad-review-gate,yad-review-gate,true,epics/EP-<slug>/,architecture.md contract.md contract-lock.json state.json
|
|
5
5
|
SDLC Workflow,yad-ui,Author UI Design,AU,"Front state 5: with the ux-designer author ui-design.md and DESIGN.md, driving Impeccable slash-commands when installed. Never auto-advances.",,{epic: EP-<slug>},1-front,yad-review-gate,yad-review-gate,true,epics/EP-<slug>/,ui-design.md DESIGN.md state.json
|
|
6
6
|
SDLC Workflow,yad-stories,Author Stories,AS,"Front state 7: with the pm break the epic into repo-tagged stories with stable EP-<slug>-S0N IDs, one file each under stories/. Never auto-advances.",,{epic: EP-<slug>},1-front,yad-review-gate,yad-review-gate,true,epics/EP-<slug>/stories/,stories/EP-<slug>-S0N.md state.json
|
|
7
|
+
SDLC Workflow,yad-test-cases,Author Test Cases,TC,"Front state 9 (PARALLEL, non-blocking): opens when the stories gate passes — the epic is already ready-for-build, so the build half can start at the same time the tester works here. With the test architect (Murat) author test-cases.md covering the approved stories, and — when a testing tool is connected (.sdlc/testing.json) — generate/link the actual automation tests in it, recording test-links.json; otherwise produce the test-case artifact only. Its review never moves currentStep off ready-for-build. Never auto-advances.",,{epic: EP-<slug>},1-front,yad-review-gate,yad-review-gate,true,epics/EP-<slug>/,test-cases.md test-links.json state.json
|
|
7
8
|
SDLC Workflow,yad-connect-repos,Connect Code Repos,CR,"Setup/maintenance: connect code repos to the product hub so the front/brain phases are code-aware. Registers each repo (GitHub or GitLab, local-user auth, no stored tokens) in .sdlc/repos.json and caches a Repomix pack + a lightweight code-map (existing endpoints/events/data-models/modules, secret-scanned). Idempotent and refreshable; staleness tracked by HEAD sha. Run at setup or any time a new repo is added. Not a gated state — never touches epic state or approvals.",,{action: connect|refresh|list|disconnect} {repo: <name>} {path: <path-or-absolute>} {git_url: <ssh-or-https>} {domain_owner: <who>},0-setup,,yad-epic,false,.sdlc/,repos.json code-context/<repo>/pack.md code-context/<repo>/code-map.md
|
|
8
9
|
SDLC Workflow,yad-connect-design,Connect Design Tool,CD,"Setup/maintenance: connect a design tool (Figma-first, pluggable) to the product hub so the UI design step can materialize the actual feature design (mobile screens / web pages) inside it, alongside ui-design.md + DESIGN.md. Records the tool + project/file references in .sdlc/design.json (local-user / MCP-session auth, no stored tokens), detecting whether a design-tool MCP is available and degrading to markdown-only when absent. Idempotent and refreshable; one connection per project. Not a gated state — never touches epic state or approvals.",,{action: connect|refresh|list|disconnect} {tool: figma|pencil|none} {project_url: <team/project/file url>} {files: {web,mobile}},0-setup,,yad-ui,false,.sdlc/,design.json
|
|
10
|
+
SDLC Workflow,yad-connect-testing,Connect Testing Tool,CT,"Setup/maintenance: connect a testing tool (Playwright-first, pluggable) to the product hub so the test-cases step can implement the actual automation tests in it, alongside test-cases.md. Records the tool + project/suite references in .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 absent. Idempotent and refreshable; one connection per project. Not a gated state — never touches epic state or approvals.",,{action: connect|refresh|list|disconnect} {tool: playwright|cypress|pytest|none} {project_url: <project/config reference>} {suites: {<repo>}},0-setup,,yad-test-cases,false,.sdlc/,testing.json
|
|
9
11
|
SDLC Workflow,yad-spec,Author Spec,SP,"Build-half Step A: for one ready-for-build story and one of its repos, run the heavy Spec Kit ceremony once (specify→clarify→plan→analyze→checklist→tasks) inside that code repo, writing specs/<story-id>/ in Spec Kit's layout (drives /speckit.* when installed, else hand-authors and records speckit: not-installed). References the locked contract; never re-invents the surface. Writes link.md back to the story. Never auto-advances.",,{epic: EP-<slug>} {story: EP-<slug>-S0N} {repo: <one of story.repos>},3-build,yad-review-gate,,false,demo-repos/<repo>/specs/<story-id>/,spec.md research.md data-model.md contracts/ plan.md tasks.md link.md
|
|
10
12
|
SDLC Workflow,yad-implement,Implement Task,IM,"Build-half Step B: with the dev lens, implement ONE atomic task from a story's tasks.md as a small diff (<=3 files) on its own branch feat/<story>-<task>-<slug> in the code repo. Diff stays inside the task's declared files (flag and STOP if it grows beyond them). Commit ends with a Task: <story>-<task> trailer; add Contract-Change: yes only when the locked contract surface is touched (routes back to the architecture gate). Never auto-advances.",,{epic: EP-<slug>} {story: EP-<slug>-S0N} {repo: <one of story.repos>} {task: T0N},3-build,yad-spec,,false,demo-repos/<repo>/,branch+commit per atomic task
|
|
11
13
|
SDLC Workflow,yad-checks,Check Gates,CK,"Build-half Step C: wire and run the three production-safety CI gates on a code repo — spec-link (every change links a real story/spec via its Task trailer), contract-check (a contract-surface change without Contract-Change + an updated re-locked contract FAILS and routes back to the architecture gate), and build/test/lint. CI-agnostic bash invoked by GitHub Actions and GitLab CI. Blocking in CI; the human still owns the merge. Never auto-advances.",,{repo: <one of an epic's repos>} {action: wire|run} {base: target branch},3-build,yad-implement,,false,demo-repos/<repo>/,checks/*.sh .github/workflows/yad-checks.yml .gitlab-ci.yml
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: yad-analysis
|
|
3
|
-
description: 'Optional front state 1 of the gated SDLC. With the analyst, pressure-test a feature idea and write the discovery brief into analysis.md. Assigns the EP-<slug> ID and seeds .sdlc/ state (the
|
|
3
|
+
description: 'Optional front state 1 of the gated SDLC. With the analyst, pressure-test a feature idea and write the discovery brief into analysis.md. Assigns the EP-<slug> ID and seeds .sdlc/ state (the 12-step chain that puts analysis before epic). Never auto-advances — hands off to the team review gate. Optional: if skipped, the epic step does this shaping inline. Use when the user says "analyse the idea", "start with analysis", or "author the analysis".'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# SDLC — Author Analysis (optional front state 1)
|
|
@@ -11,8 +11,8 @@ state machine in `.sdlc/`. This is a **front state**: human-authored with AI ass
|
|
|
11
11
|
auto-advances**. When the analysis is drafted, control passes to `yad-review-gate`.
|
|
12
12
|
|
|
13
13
|
This step is **optional**. When it runs, it is the entry point: it assigns the ID and seeds the
|
|
14
|
-
**
|
|
15
|
-
analyst shaping inline and seeds the **
|
|
14
|
+
**12-step** chain (`analysis` before `epic`). When it is **skipped**, `yad-epic` does the same
|
|
15
|
+
analyst shaping inline and seeds the **10-step** chain — no behaviour change for teams that skip it.
|
|
16
16
|
|
|
17
17
|
This skill enforces the build plan's core rules: all state lives in files; IDs are generated by the
|
|
18
18
|
engine (never typed by hand); front steps are locked to `human_approve`.
|
|
@@ -88,7 +88,7 @@ code-context: { repos: [], loaded: <YYYY-MM-DD or none> } # which code-maps in
|
|
|
88
88
|
Fill the body with the user; leave `owner` for the user to set.
|
|
89
89
|
|
|
90
90
|
### Step 6 — Seed the state machine
|
|
91
|
-
Create `{project-root}/epics/EP-<slug>/.sdlc/state.json` describing the full **
|
|
91
|
+
Create `{project-root}/epics/EP-<slug>/.sdlc/state.json` describing the full **12-step** front-state
|
|
92
92
|
sequence (analysis before epic), all steps defaulting to `automation: human_approve`, with every
|
|
93
93
|
authoring step **locked**. Use this exact shape (see `references/state-schema.md`):
|
|
94
94
|
|
|
@@ -107,7 +107,9 @@ authoring step **locked**. Use this exact shape (see `references/state-schema.md
|
|
|
107
107
|
{ "id": "ui-design", "type": "author", "artifact": "ui-design.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
|
|
108
108
|
{ "id": "ui-design-review", "type": "review+approve", "artifact": "ui-design.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
|
|
109
109
|
{ "id": "stories", "type": "author", "artifact": "stories/", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
|
|
110
|
-
{ "id": "stories-review", "type": "review+approve", "artifact": "stories/", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] }
|
|
110
|
+
{ "id": "stories-review", "type": "review+approve", "artifact": "stories/", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
|
|
111
|
+
{ "id": "test-cases", "type": "author", "artifact": "test-cases.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
|
|
112
|
+
{ "id": "test-cases-review", "type": "review+approve", "artifact": "test-cases.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] }
|
|
111
113
|
]
|
|
112
114
|
}
|
|
113
115
|
```
|
|
@@ -116,6 +118,9 @@ Notes:
|
|
|
116
118
|
- `analysis-review` carries no `risk_tags` — it is the **base** rule (owner + 1 reviewer).
|
|
117
119
|
- `architecture-review` carries `risk_tags: ["contract"]` so the gate escalates it by default
|
|
118
120
|
(build plan §4): the contract review needs domain owners, not just owner + 1.
|
|
121
|
+
- `test-cases` / `test-cases-review` are a **parallel, non-blocking track**: they seed `blocked` and open
|
|
122
|
+
when `stories-review` passes — the epic is already `ready-for-build` by then, so the build half runs
|
|
123
|
+
alongside the tester (see `../yad-epic/references/state-schema.md`).
|
|
119
124
|
- Also create an empty approvals ledger `{project-root}/epics/EP-<slug>/.sdlc/approvals.json`
|
|
120
125
|
and an empty comments ledger `{project-root}/epics/EP-<slug>/.sdlc/comments.json`, each containing
|
|
121
126
|
`[]`, and the `reviews/` directory.
|
|
@@ -20,7 +20,7 @@ markdown-only exactly as before.
|
|
|
20
20
|
|
|
21
21
|
- `{project-root}` resolves from the project working directory (the **product hub**).
|
|
22
22
|
- The integration is **Figma-first but pluggable** (`config.yaml` `design.tools`): a design-tool
|
|
23
|
-
*adapter*, like the
|
|
23
|
+
*adapter*, like the GitHub/GitLab platform adapter. Figma is the primary provider; `pencil`
|
|
24
24
|
(the `.pen` web/mobile editor) is a second, write-capable provider; `none` → markdown-only.
|
|
25
25
|
- **The design tool is reached through its MCP** (a harness MCP server), NOT a subprocess CLI — the same
|
|
26
26
|
shape as Impeccable's slash-commands, not Repomix's `npx`. The skill detects the MCP and degrades when
|
|
@@ -27,8 +27,10 @@ root, not under any `epics/EP-<slug>/.sdlc/`.
|
|
|
27
27
|
|
|
28
28
|
## Rules
|
|
29
29
|
|
|
30
|
-
- **`tool`** selects the adapter; it MUST be one of `config.yaml` `design.tools` (or `none`).
|
|
31
|
-
tool
|
|
30
|
+
- **`tool`** selects the adapter; it MUST be one of `config.yaml` `design.tools` (or `none`). At
|
|
31
|
+
**connect** time an unknown tool is normalized to `design.primary` with a warning (so the registry
|
|
32
|
+
never persists an unknown value); a registry hand-edited to an unknown or missing tool **fails
|
|
33
|
+
`doctor`** with `YAD-CFG-002` and must be fixed.
|
|
32
34
|
- **Auth is never stored.** No Figma PAT, OAuth token, or any credential in the registry. `project_url`
|
|
33
35
|
and `files` are plain references; `connect` reaches the tool through the user's authenticated MCP
|
|
34
36
|
session.
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: yad-connect-testing
|
|
3
|
+
description: 'Connects a testing tool (Playwright, or another tool — pluggable) to the product hub 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
|
+
---
|
|
5
|
+
|
|
6
|
+
# SDLC — Connect a Testing Tool (make the test-cases step automation-aware)
|
|
7
|
+
|
|
8
|
+
**Goal:** Let the test-cases step (`yad-test-cases`) produce the **actual automation tests** — the
|
|
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 product hub and records *how* to reach it (the
|
|
11
|
+
tool, the suite references, which MCP runs it) — never a credential.
|
|
12
|
+
|
|
13
|
+
This is **setup/maintenance**, not a gated front state — it never touches `.sdlc/state.json` or any
|
|
14
|
+
epic's approvals. It only writes the project-wide testing registry. `yad-test-cases` consumes it: when a
|
|
15
|
+
tool is connected and its MCP is available, the `test architect` lens **generates** automation tests
|
|
16
|
+
into the connected repo(s) (or **links** an existing suite and reads it back); when nothing is
|
|
17
|
+
connected, `yad-test-cases` runs artifacts-only exactly as before.
|
|
18
|
+
|
|
19
|
+
## Conventions
|
|
20
|
+
|
|
21
|
+
- `{project-root}` resolves from the project working directory (the **product hub**).
|
|
22
|
+
- The integration is **Playwright-first but pluggable** (`config.yaml` `testing.tools`): a testing-tool
|
|
23
|
+
*adapter*, like the GitHub/GitLab platform adapter or the design-tool adapter. Playwright is the
|
|
24
|
+
primary provider; `cypress` and `pytest` are second providers; `none` → artifacts-only.
|
|
25
|
+
- **The testing tool is reached through its MCP** (a harness MCP server), NOT a subprocess CLI — the
|
|
26
|
+
same shape as the design tool's MCP, not Repomix's `npx`. The skill detects the MCP and degrades when
|
|
27
|
+
it is absent; it never installs an MCP server.
|
|
28
|
+
- Registry: `{project-root}/.sdlc/testing.json` (project-wide, shared across all epics — NOT per-epic),
|
|
29
|
+
the sibling of `.sdlc/repos.json`, `.sdlc/hub.json`, and `.sdlc/design.json`.
|
|
30
|
+
- Per-epic test→suite links are written later by `yad-test-cases`
|
|
31
|
+
(`epics/EP-<slug>/.sdlc/test-links.json`), not here.
|
|
32
|
+
- Speak in the configured `communication_language`; write documents in `document_output_language`.
|
|
33
|
+
|
|
34
|
+
## Inputs
|
|
35
|
+
|
|
36
|
+
- `action` — `connect` (default) | `refresh` | `list` | `disconnect`.
|
|
37
|
+
- `tool` — `playwright` | `cypress` | `pytest` | another adapter id (`config.yaml` `testing.tools`).
|
|
38
|
+
`none` records a deliberate artifacts-only project.
|
|
39
|
+
- `project_url` — the testing tool's project/config reference (e.g. a `playwright.config.ts` path or a
|
|
40
|
+
test-runner project URL). Optional — a connection with no suite yet is valid; `yad-test-cases` can
|
|
41
|
+
create one on first generate.
|
|
42
|
+
- `suites` — optional default suite mapping per repo (`{ <repo>: <ref> }`).
|
|
43
|
+
|
|
44
|
+
## On Activation
|
|
45
|
+
|
|
46
|
+
### Step 1 — Resolve the tool and its MCP (the testing-tool adapter)
|
|
47
|
+
Determine which tool is being connected from `tool` (default `playwright`); reject a `tool` not in
|
|
48
|
+
`config.yaml` `testing.tools` (fall back to the configured `testing.primary` with a warning, the same
|
|
49
|
+
way `registerRepo` falls back on an unknown platform). Then **detect the tool's MCP** in this harness:
|
|
50
|
+
|
|
51
|
+
- **playwright** → a Playwright MCP server (drives a browser, generates/runs E2E + API specs).
|
|
52
|
+
- **cypress** → the Cypress MCP (generate/run Cypress specs).
|
|
53
|
+
- **pytest** → a pytest MCP (generate/run service-layer tests).
|
|
54
|
+
- another adapter → its named MCP.
|
|
55
|
+
|
|
56
|
+
Record `provider` (the concrete MCP, e.g. `playwright-mcp` | `cypress-mcp` | `pytest-mcp`) and whether
|
|
57
|
+
it is available. **Auth is the local user's own** — the user's authenticated MCP session. The skill
|
|
58
|
+
**stores no tokens**; `project_url`/`suites` are plain references, never credentials.
|
|
59
|
+
|
|
60
|
+
**Graceful degradation:** if no testing-tool MCP is available, record `source: "unavailable"` and report
|
|
61
|
+
that `yad-test-cases` will run **artifacts-only** until an MCP is connected (no error — the testing tool
|
|
62
|
+
is purely additive, exactly like the design tool being absent). Do **not** install an MCP server as part
|
|
63
|
+
of this step.
|
|
64
|
+
|
|
65
|
+
### Step 2 — Record the connection in the registry
|
|
66
|
+
Upsert into `{project-root}/.sdlc/testing.json` (create the file + parent `.sdlc/` if absent):
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"tool": "playwright",
|
|
71
|
+
"provider": "playwright-mcp",
|
|
72
|
+
"project_url": "tests/playwright.config.ts",
|
|
73
|
+
"auth": "user",
|
|
74
|
+
"suites": { "backend": null, "mobile": null },
|
|
75
|
+
"connectedAt": "<YYYY-MM-DD>",
|
|
76
|
+
"lastSyncedAt": "<YYYY-MM-DD>",
|
|
77
|
+
"source": "playwright-mcp"
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
- `tool: "none"` records a deliberate artifacts-only project: `{ "tool": "none", "provider": null,
|
|
82
|
+
"source": "unavailable", ... }`.
|
|
83
|
+
- `connect` is **idempotent** — re-running it overwrites the single connection in place (a project has
|
|
84
|
+
one testing tool at a time; switching tools is just another `connect`).
|
|
85
|
+
|
|
86
|
+
### Step 3 — Report (never auto-advance)
|
|
87
|
+
Report the connected `tool`, its `provider`, whether the MCP is available (or that `yad-test-cases` will
|
|
88
|
+
degrade to artifacts-only), the `project_url`, and that **`yad-test-cases` will now generate/link the
|
|
89
|
+
automation tests here**. Nothing auto-advances; this is setup.
|
|
90
|
+
|
|
91
|
+
## Other actions
|
|
92
|
+
|
|
93
|
+
- **`refresh`** — re-detect the MCP and update `lastSyncedAt` (after the user authenticates a session or
|
|
94
|
+
changes tools). Same machinery as `connect`. Re-detection may flip `source` between an MCP id and
|
|
95
|
+
`unavailable` — report the change.
|
|
96
|
+
- **`list`** — print the current connection: `tool`, `provider`, `project_url`, the suite mapping, and a
|
|
97
|
+
**available/unavailable** flag for the MCP (best-effort, the user's own session). No testing tool
|
|
98
|
+
connected ⇒ "artifacts-only".
|
|
99
|
+
- **`disconnect`** — remove the registry file (or set `tool: "none"`). The testing tool's own
|
|
100
|
+
project/suites are **never touched** — only the hub's record of them.
|
|
101
|
+
|
|
102
|
+
## Hard rules
|
|
103
|
+
|
|
104
|
+
- **Local-user / MCP-session auth only; store no tokens.** Connect through the user's authenticated MCP
|
|
105
|
+
session; never embed a token or any credential in the registry. `project_url`/`suites` are plain
|
|
106
|
+
references.
|
|
107
|
+
- **Degrade gracefully.** No testing tool / no MCP → `yad-test-cases` runs artifacts-only with no error.
|
|
108
|
+
The testing tool is additive, never a blocker — the same discipline as the design tool and Impeccable.
|
|
109
|
+
- **Setup, not a gate.** Never touch `.sdlc/state.json`, approvals, or the contract lock from here.
|
|
110
|
+
- **Idempotent + refreshable.** `connect`/`refresh` are safe to re-run; a project carries one testing
|
|
111
|
+
connection at a time.
|
|
112
|
+
- **Describe the connection; do not author tests here.** This skill records *how to reach* the tool. The
|
|
113
|
+
actual automation tests are generated/linked by `yad-test-cases`, per epic.
|
|
114
|
+
|
|
115
|
+
## Reference
|
|
116
|
+
- Registry schema + freshness rule: `references/testing-registry.md`.
|
|
117
|
+
- MCP detection per provider, the generate-vs-link recipes, the degrade path, and the honest
|
|
118
|
+
write-vs-read-only MCP capability note: `references/testing-context.md`.
|
|
119
|
+
- The connect pattern this mirrors (design tool): `../yad-connect-design/SKILL.md`.
|
|
120
|
+
- The consumer — how `yad-test-cases` generates/links and writes `test-links.json`:
|
|
121
|
+
`../yad-test-cases/SKILL.md`.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Testing context — MCP detection, generate vs link, and the degrade path
|
|
2
|
+
|
|
3
|
+
How a connected testing tool turns into the actual automation tests the test-cases step materializes.
|
|
4
|
+
The testing tool is reached through its **MCP** (a harness MCP server), the same shape as the design
|
|
5
|
+
tool — detect it, use it when present, degrade cleanly when absent. This is the testing-side analogue of
|
|
6
|
+
`yad-connect-design`'s design-context.
|
|
7
|
+
|
|
8
|
+
## Provider detection
|
|
9
|
+
|
|
10
|
+
`connect`/`refresh` records `provider` (the concrete MCP) and `source` (the MCP id, or `unavailable`).
|
|
11
|
+
Detection is best-effort against the user's own authenticated MCP session:
|
|
12
|
+
|
|
13
|
+
| `tool` | MCP / provider | Capability |
|
|
14
|
+
|--------|----------------|------------|
|
|
15
|
+
| `playwright` | a Playwright MCP | **generate** — author + run E2E/API specs against the app |
|
|
16
|
+
| `cypress` | the Cypress MCP | **generate** — author + run Cypress specs |
|
|
17
|
+
| `pytest` | a pytest MCP | **generate** — author + run service-layer tests |
|
|
18
|
+
| any | a read-only runner MCP | **link** — reference an existing suite and read results back |
|
|
19
|
+
| other | the adapter's named MCP | per that adapter |
|
|
20
|
+
|
|
21
|
+
**Honest capability note:** not every testing-tool MCP can *write* tests. A read-only runner MCP
|
|
22
|
+
supports **link + read-back** only; *generate* needs a write-capable provider. `yad-test-cases` picks
|
|
23
|
+
the direction the connected provider actually supports and records which one it used
|
|
24
|
+
(`direction: generated | linked`). It never claims to have generated tests a read-only MCP cannot
|
|
25
|
+
produce.
|
|
26
|
+
|
|
27
|
+
## Generate (write automation tests into the repo)
|
|
28
|
+
|
|
29
|
+
When the connected provider is write-capable, the `test architect` lens (Murat, `bmad-tea` +
|
|
30
|
+
`bmad-testarch-automate`) produces the epic's automation tests in the connected code repo(s), covering
|
|
31
|
+
the cases `test-cases.md` enumerates and the acceptance criteria the stories define:
|
|
32
|
+
|
|
33
|
+
- **Playwright** — the lens authors `*.spec.ts` E2E/API specs (reusing the repo's existing fixtures and
|
|
34
|
+
the code-maps from `yad-test-cases` Step 2b), one spec per high-priority (P0/P1) case, and runs them
|
|
35
|
+
via the MCP to confirm they execute.
|
|
36
|
+
- **Cypress / pytest** — the lens authors the equivalent specs in that framework's layout.
|
|
37
|
+
|
|
38
|
+
Reuse what already exists: load the connected code repos' code-maps (`yad-test-cases` Step 2b) so
|
|
39
|
+
generated tests target real endpoints/components, not invented ones, and prefer the lowest useful test
|
|
40
|
+
level (unit > integration > E2E) per Murat's principles.
|
|
41
|
+
|
|
42
|
+
## Link (reference an existing suite)
|
|
43
|
+
|
|
44
|
+
When a suite already exists (or the provider is read-only), point `yad-test-cases` at it and **read the
|
|
45
|
+
suite back** so `test-cases.md` reflects the real tests: list each test as a case, capture its
|
|
46
|
+
path/name + URL, and map it to the story it covers.
|
|
47
|
+
|
|
48
|
+
## Write back the linkage (done by `yad-test-cases`, per epic)
|
|
49
|
+
|
|
50
|
+
Either direction ends by writing `epics/EP-<slug>/.sdlc/test-links.json` — the machine-readable
|
|
51
|
+
case→test map — and a `## Automation (<tool>)` section in `test-cases.md` linking each case to its test.
|
|
52
|
+
The tests themselves live in the code repo; the hub keeps the *links* and the Markdown spec beside the
|
|
53
|
+
other epic artifacts.
|
|
54
|
+
|
|
55
|
+
## Degrade path (no MCP / no tool)
|
|
56
|
+
|
|
57
|
+
If `testing.json` is absent, `tool: "none"`, or `source: "unavailable"`, `yad-test-cases` runs
|
|
58
|
+
**artifacts-only**: it authors `test-cases.md` exactly as before and records `testing: none` in the
|
|
59
|
+
frontmatter with a one-line note (mirroring the `design: none` degrade). No error — the testing tool is
|
|
60
|
+
purely additive.
|
|
61
|
+
|
|
62
|
+
## Staleness / refresh
|
|
63
|
+
|
|
64
|
+
A re-generated or hand-edited suite is like a moved code repo: `yad-test-cases` **flags** a divergence
|
|
65
|
+
and lets a human decide (re-run the step, or `yad-connect-testing` action: refresh). It never silently
|
|
66
|
+
overwrites a hand-written suite — refreshing the automation is a human decision, the same discipline as
|
|
67
|
+
`code_context.refresh: human`.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Testing registry — schema + freshness rule
|
|
2
|
+
|
|
3
|
+
The registry is the product hub's record of which testing tool is connected and how to reach it. It is
|
|
4
|
+
**project-wide** (one testing tool per project, shared across every epic), so it lives at the product
|
|
5
|
+
root, not under any `epics/EP-<slug>/.sdlc/`.
|
|
6
|
+
|
|
7
|
+
## Location
|
|
8
|
+
|
|
9
|
+
`{project-root}/.sdlc/testing.json`
|
|
10
|
+
|
|
11
|
+
(`config.yaml` `testing.registry`.) Create the file and its parent `.sdlc/` on the first `connect`.
|
|
12
|
+
|
|
13
|
+
## Schema
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"tool": "playwright", // playwright | cypress | pytest | <adapter id> | none (artifacts-only)
|
|
18
|
+
"provider": "playwright-mcp", // the concrete MCP: playwright-mcp | cypress-mcp | pytest-mcp | null
|
|
19
|
+
"project_url": "tests/playwright.config.ts", // project/config reference; null if none yet
|
|
20
|
+
"auth": "user", // ALWAYS the user's own MCP session — never a token
|
|
21
|
+
"suites": { "backend": null, "mobile": null }, // optional default suite refs per repo
|
|
22
|
+
"connectedAt": "2026-06-13", // first connect (YYYY-MM-DD)
|
|
23
|
+
"lastSyncedAt": "2026-06-13", // last connect/refresh
|
|
24
|
+
"source": "playwright-mcp" // the MCP detected at connect | unavailable (degraded)
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Rules
|
|
29
|
+
|
|
30
|
+
- **`tool`** selects the adapter; it MUST be one of `config.yaml` `testing.tools` (or `none`). At
|
|
31
|
+
**connect** time an unknown tool is normalized to `testing.primary` with a warning (so the registry
|
|
32
|
+
never persists an unknown value); a registry hand-edited to an unknown or missing tool **fails
|
|
33
|
+
`doctor`** with `YAD-CFG-003` and must be fixed.
|
|
34
|
+
- **Auth is never stored.** No token, API key, or any credential in the registry. `project_url` and
|
|
35
|
+
`suites` are plain references; `connect` reaches the tool through the user's authenticated MCP session.
|
|
36
|
+
- **`connect` overwrites in place** — a project carries exactly one testing connection at a time;
|
|
37
|
+
switching tools is just another `connect`. There is no array (unlike `repos.json`).
|
|
38
|
+
- **`source`** is the authority for availability: an MCP id (`playwright-mcp` / `cypress-mcp` / …) means
|
|
39
|
+
`yad-test-cases` can generate/link; `unavailable` means `yad-test-cases` degrades to artifacts-only.
|
|
40
|
+
`refresh` re-detects and may flip it.
|
|
41
|
+
- **`tool: "none"`** is a valid, deliberate state: a project that has chosen artifacts-only.
|
|
42
|
+
`yad-test-cases` treats it exactly like an absent registry.
|
|
43
|
+
- **`disconnect`** removes the file (or sets `tool: "none"`). The testing tool's own project/suites are
|
|
44
|
+
never touched.
|
|
45
|
+
|
|
46
|
+
## Git tracking
|
|
47
|
+
|
|
48
|
+
Commit the **registry** (`testing.json`) — it is small, reviewable, and holds no secrets (references
|
|
49
|
+
only). This mirrors how `repos.json`, `hub.json`, and `design.json` are committed.
|
|
50
|
+
|
|
51
|
+
## Greenfield
|
|
52
|
+
|
|
53
|
+
A brand-new product hub has no `testing.json`. That is valid — `yad-test-cases` treats "no testing tool
|
|
54
|
+
connected" the same as `tool: "none"` and produces the Markdown test-case artifact only. The registry
|
|
55
|
+
appears the first time `connect` runs.
|
package/skills/yad-epic/SKILL.md
CHANGED
|
@@ -14,7 +14,7 @@ drafted, control passes to `yad-review-gate`.
|
|
|
14
14
|
- **Analysis ran** — `.sdlc/state.json` already exists with `currentStep == "epic"`. The epic **reads
|
|
15
15
|
`analysis.md`** as its shaped input and does not re-seed state.
|
|
16
16
|
- **Analysis skipped** (the default) — no `state.json` yet. The epic is the entry point: it shapes the
|
|
17
|
-
idea inline with the analyst, assigns `EP-<slug>`, and seeds the **
|
|
17
|
+
idea inline with the analyst, assigns `EP-<slug>`, and seeds the **10-step** chain.
|
|
18
18
|
|
|
19
19
|
This skill enforces the build plan's core rules: all state lives in files; IDs are generated by the
|
|
20
20
|
engine (never typed by hand); front steps are locked to `human_approve`.
|
|
@@ -105,9 +105,9 @@ Fill the body with the user; leave `owner` / `technical_product_owner` for the u
|
|
|
105
105
|
`repos` to the repos this epic will touch.
|
|
106
106
|
|
|
107
107
|
### Step 5 — Seed the state machine — analysis-skipped only
|
|
108
|
-
*(Skip when analysis ran — `yad-analysis` already seeded the
|
|
109
|
-
Create `{project-root}/epics/EP-<slug>/.sdlc/state.json` describing the full **
|
|
110
|
-
sequence (no analysis), all steps defaulting to `automation: human_approve`, with the
|
|
108
|
+
*(Skip when analysis ran — `yad-analysis` already seeded the 12-step chain. Go to Step 5b.)*
|
|
109
|
+
Create `{project-root}/epics/EP-<slug>/.sdlc/state.json` describing the full **10-step** front-state
|
|
110
|
+
sequence (no analysis), all steps defaulting to `automation: human_approve`, with the five authoring
|
|
111
111
|
steps **locked**. Use this exact shape (see `references/state-schema.md`):
|
|
112
112
|
|
|
113
113
|
```json
|
|
@@ -123,7 +123,9 @@ steps **locked**. Use this exact shape (see `references/state-schema.md`):
|
|
|
123
123
|
{ "id": "ui-design", "type": "author", "artifact": "ui-design.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
|
|
124
124
|
{ "id": "ui-design-review", "type": "review+approve", "artifact": "ui-design.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
|
|
125
125
|
{ "id": "stories", "type": "author", "artifact": "stories/", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
|
|
126
|
-
{ "id": "stories-review", "type": "review+approve", "artifact": "stories/", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] }
|
|
126
|
+
{ "id": "stories-review", "type": "review+approve", "artifact": "stories/", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
|
|
127
|
+
{ "id": "test-cases", "type": "author", "artifact": "test-cases.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
|
|
128
|
+
{ "id": "test-cases-review", "type": "review+approve", "artifact": "test-cases.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] }
|
|
127
129
|
]
|
|
128
130
|
}
|
|
129
131
|
```
|
|
@@ -131,6 +133,9 @@ steps **locked**. Use this exact shape (see `references/state-schema.md`):
|
|
|
131
133
|
Notes:
|
|
132
134
|
- `architecture-review` carries `risk_tags: ["contract"]` so the gate escalates it by default
|
|
133
135
|
(build plan §4): the contract review needs domain owners, not just owner + 1.
|
|
136
|
+
- `test-cases` / `test-cases-review` are a **parallel, non-blocking track**: they seed `blocked` and open
|
|
137
|
+
when `stories-review` passes — at which point the epic is already `ready-for-build`, so the build half
|
|
138
|
+
runs alongside the tester. They never gate `ready-for-build` (see `references/state-schema.md`).
|
|
134
139
|
- Also create an empty approvals ledger `{project-root}/epics/EP-<slug>/.sdlc/approvals.json`
|
|
135
140
|
and an empty comments ledger `{project-root}/epics/EP-<slug>/.sdlc/comments.json`, each containing
|
|
136
141
|
`[]`, and the `reviews/` directory. (`comments.json` is the machine-readable counterpart to the
|
|
@@ -17,7 +17,7 @@ Each `steps[]` entry:
|
|
|
17
17
|
|
|
18
18
|
| Field | Values | Meaning |
|
|
19
19
|
|-------|--------|---------|
|
|
20
|
-
| `id` | `analysis`, `analysis-review`, `epic`, `epic-review`, `architecture`, `architecture-review`, `ui-design`, `ui-design-review`, `stories`, `stories-review` | Step identity. |
|
|
20
|
+
| `id` | `analysis`, `analysis-review`, `epic`, `epic-review`, `architecture`, `architecture-review`, `ui-design`, `ui-design-review`, `stories`, `stories-review`, `test-cases`, `test-cases-review` | Step identity. |
|
|
21
21
|
|
|
22
22
|
### Two valid chain shapes (analysis is optional)
|
|
23
23
|
|
|
@@ -26,20 +26,37 @@ ran `yad-analysis` before the epic. The entry-point skill (whichever runs first)
|
|
|
26
26
|
that assigns `EP-<slug>` and seeds `state.json` + the empty ledgers; the other skill detects an
|
|
27
27
|
existing `state.json` and does **not** re-seed.
|
|
28
28
|
|
|
29
|
-
- **With analysis** (
|
|
29
|
+
- **With analysis** (12 steps — `yad-analysis` seeded the chain):
|
|
30
30
|
`analysis → analysis-review → epic → epic-review → architecture → architecture-review → ui-design →
|
|
31
|
-
ui-design-review → stories → stories-review
|
|
32
|
-
starts `blocked`.
|
|
33
|
-
- **Without analysis** (
|
|
34
|
-
`epic → epic-review → … → stories-review`. Seeded `currentStep` is
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
`analysis-review`
|
|
31
|
+
ui-design-review → stories → stories-review → test-cases → test-cases-review`. Seeded `currentStep`
|
|
32
|
+
is `analysis-review`; `epic` starts `blocked`.
|
|
33
|
+
- **Without analysis** (10 steps — `yad-epic` is the entry point, the default):
|
|
34
|
+
`epic → epic-review → … → stories-review → test-cases → test-cases-review`. Seeded `currentStep` is
|
|
35
|
+
`epic-review`.
|
|
36
|
+
|
|
37
|
+
`analysis-review`, `ui-design-review`, and `test-cases-review` carry no `risk_tags` (base rule:
|
|
38
|
+
owner + 1 reviewer).
|
|
39
|
+
|
|
40
|
+
### `test-cases` is a parallel, non-blocking track
|
|
41
|
+
|
|
42
|
+
`test-cases` (and its `test-cases-review` gate) sit in `steps[]` after `stories-review`, but they are a
|
|
43
|
+
**parallel track that does not gate the build half**. When `stories-review` passes, `advanceState`:
|
|
44
|
+
- sets `currentStep` to the **`ready-for-build`** sentinel — so the build half (`yad-spec` → … keyed off
|
|
45
|
+
`currentStep == "ready-for-build"`) can start **immediately**, and
|
|
46
|
+
- opens `test-cases` (`blocked` → `in_progress`) so the tester can work **in parallel**.
|
|
47
|
+
|
|
48
|
+
The `test-cases` track is therefore driven by its own step `status`, **not** by `currentStep`:
|
|
49
|
+
`yad-test-cases` proceeds when `test-cases.status == "in_progress"`, and neither it nor the
|
|
50
|
+
`test-cases-review` gate (`advanceState` / `markInReview`) ever moves `currentStep` away from
|
|
51
|
+
`ready-for-build`. So implementation and test-case authoring run at the same time; the epic is
|
|
52
|
+
`ready-for-build` the moment the **stories** gate passes, whether or not test cases are done. (For an old
|
|
53
|
+
epic seeded before this step existed, `stories-review` → `ready-for-build` with no test-cases track —
|
|
54
|
+
unchanged.)
|
|
38
55
|
|
|
39
56
|
### Authoring branches
|
|
40
57
|
|
|
41
58
|
Each front **authoring** step opens its own git branch at the start of the step, named
|
|
42
|
-
`<step>/EP-<slug>` where `<step>` ∈ `analysis | epic | architecture | ui-design | stories`
|
|
59
|
+
`<step>/EP-<slug>` where `<step>` ∈ `analysis | epic | architecture | ui-design | stories | test-cases`
|
|
43
60
|
(`config.yaml` `defaults.front_authoring_branch`). This is **distinct** from the review branch
|
|
44
61
|
`review/EP-<slug>/<artifact-base>` that `yad-hub-bridge` opens later for the review PR/MR.
|
|
45
62
|
|
|
@@ -99,6 +116,20 @@ chain is unchanged — this is an *output enrichment*, mirrored by the `design:`
|
|
|
99
116
|
"source": "<mcp id>" }
|
|
100
117
|
```
|
|
101
118
|
|
|
119
|
+
## `test-links.json`
|
|
120
|
+
Present only when the `test-cases` step materialized automation in a connected testing tool
|
|
121
|
+
(`yad-connect-testing` → `.sdlc/testing.json`). Written by `yad-test-cases`, the machine-readable
|
|
122
|
+
case→test map (sibling of `contract-lock.json` / `design-links.json`; the locked `state.json` step shape
|
|
123
|
+
is untouched). The `test-cases` step chain is unchanged — this is an *output enrichment*, mirrored by the
|
|
124
|
+
`testing:` frontmatter block and the `## Automation (<tool>)` section in `test-cases.md`. Absent when the
|
|
125
|
+
step ran artifacts-only (`testing: none`).
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{ "tool": "playwright", "suite": "<url/path>", "generatedAt": "<YYYY-MM-DD>", "direction": "generated|linked",
|
|
129
|
+
"tests": [ { "case": "<id>", "story": "EP-<slug>-S0N", "repo": "<name>", "level": "unit|integration|e2e", "path": "<test path>", "url": "<url>" } ],
|
|
130
|
+
"source": "<mcp id>" }
|
|
131
|
+
```
|
|
132
|
+
|
|
102
133
|
## `reviews/`
|
|
103
134
|
Human-readable review records, one file per round:
|
|
104
135
|
`reviews/<artifact-base>--<YYYY-MM-DD>--<status>.md` where `status` ∈ `comments` | `approved`
|
|
@@ -106,7 +137,7 @@ and `<artifact-base>` is the artifact without extension (e.g. `epic`, `architect
|
|
|
106
137
|
|
|
107
138
|
## Dial defaults & locks
|
|
108
139
|
- Every step defaults to `automation: human_approve` (build plan §2).
|
|
109
|
-
- The
|
|
140
|
+
- The five authoring front steps and their reviews are `locked: true` — the engine refuses to set
|
|
110
141
|
them to `machine_advance` in this version (build plan §1, §8.7). Only back states (build pipeline,
|
|
111
142
|
steps 9–14) may move toward machine-advance in a later iteration.
|
|
112
143
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: yad-hub-bridge
|
|
3
|
-
description: 'The templated PR/MR bridge for the front-half review gate. When the product hub has a platform (.sdlc/hub.json), it opens a review PR/MR on the hub for an authored artifact (the optional analysis / epic / architecture+contract / ui-design / stories), sets the required reviewers/labels from the routing rule, and provides the read-only gh/glab recipes that yad-review-gate uses to pull platform comments + approvals back into the file ledger. Can also wire event-driven sync on the hub: a CI workflow that runs `yad gate ci` whenever a reviewer approves / requests changes / a human merges, committing the ledger to the default branch. Local-user auth only — no stored tokens. The file ledger stays the source of truth; degrades to the file-only gate when there is no platform / no CLI. Use when the user says "open the review PR", "route the review", "wire the gate sync", or it is invoked by yad-review-gate open/sync.'
|
|
3
|
+
description: 'The templated PR/MR bridge for the front-half review gate. When the product hub has a platform (.sdlc/hub.json), it opens a review PR/MR on the hub for an authored artifact (the optional analysis / epic / architecture+contract / ui-design / stories / test-cases), sets the required reviewers/labels from the routing rule, and provides the read-only gh/glab recipes that yad-review-gate uses to pull platform comments + approvals back into the file ledger. Can also wire event-driven sync on the hub: a CI workflow that runs `yad gate ci` whenever a reviewer approves / requests changes / a human merges, committing the ledger to the default branch. Local-user auth only — no stored tokens. The file ledger stays the source of truth; degrades to the file-only gate when there is no platform / no CLI. Use when the user says "open the review PR", "route the review", "wire the gate sync", or it is invoked by yad-review-gate open/sync.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# SDLC — Hub Review Bridge (the templated PR/MR bridge)
|
|
@@ -29,7 +29,7 @@ keeps platform mechanics out of the gate). `yad-review-gate` *calls* it; it neve
|
|
|
29
29
|
## Inputs
|
|
30
30
|
|
|
31
31
|
- `epic` — the `EP-<slug>` under review.
|
|
32
|
-
- `artifact` — the artifact file (`analysis.md` | `epic.md` | `architecture.md` | `ui-design.md` | `stories/`).
|
|
32
|
+
- `artifact` — the artifact file (`analysis.md` | `epic.md` | `architecture.md` | `ui-design.md` | `stories/` | `test-cases.md`).
|
|
33
33
|
- `action` — `open` | `route` | `wire` (default `route`). (`sync`'s ledger writes live in
|
|
34
34
|
`yad-review-gate`; this skill provides the read recipes `sync` calls — see `references/bridge.md`.)
|
|
35
35
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: yad-review-gate
|
|
3
|
-
description: 'The reusable team review + approve gate for the SDLC. Shares an authored artifact for review, records reviewer comments and approvals as files, enforces the owner + 1 reviewer rule (escalating to domain owners on contract/auth/payments), and advances the epic state ONLY when approval is recorded. Use when the user says "review the analysis/epic/architecture/UI/stories", "comment", "approve", or "advance the gate".'
|
|
3
|
+
description: 'The reusable team review + approve gate for the SDLC. Shares an authored artifact for review, records reviewer comments and approvals as files, enforces the owner + 1 reviewer rule (escalating to domain owners on contract/auth/payments), and advances the epic state ONLY when approval is recorded. Use when the user says "review the analysis/epic/architecture/UI/stories/test-cases", "comment", "approve", or "advance the gate".'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# SDLC — Team Review Gate (build plan §3 piece 2, §4, §5)
|
|
7
7
|
|
|
8
8
|
**Goal:** One reusable step type that turns any authored artifact into a gated, human-approved
|
|
9
9
|
review. Every `review+approve` step in the workflow (the optional analysis, epic, architecture+contract,
|
|
10
|
-
UI, stories) uses this exact gate. **No step advances until its review is approved** and
|
|
11
|
-
file. The `analysis-review
|
|
12
|
-
escalation applies only where `risk_tags` or per-repo routing call for it.
|
|
10
|
+
UI, stories, test-cases) uses this exact gate. **No step advances until its review is approved** and
|
|
11
|
+
recorded as a file. The `analysis-review`, `epic`/`ui-design`, and `test-cases` reviews use the **base**
|
|
12
|
+
rule (owner + 1 reviewer); escalation applies only where `risk_tags` or per-repo routing call for it.
|
|
13
13
|
|
|
14
14
|
This gate is **swappable and file-driven**: it talks only through files. A front step advances only on a
|
|
15
15
|
human act — recording an approval and `advance`, or (with the bridge) **merging the approved,
|
|
@@ -87,7 +87,7 @@ counterpart to `approvals.json`):
|
|
|
87
87
|
Then help the **owner address the comments** using the agent lens listed for this step
|
|
88
88
|
(analysis → `analyst`; epic → `pm`; architecture → `architect`; ui-design → `ux-designer`;
|
|
89
89
|
stories → `pm`, with `architect` for technical detail — there is **no `sm` agent**, Phase 0
|
|
90
|
-
Deviation 1). Update the authored artifact in place.
|
|
90
|
+
Deviation 1; test-cases → `test architect` / Murat, `bmad-tea`). Update the authored artifact in place.
|
|
91
91
|
Repeat comment→address rounds until reviewers are satisfied. **Commenting never advances the gate.**
|
|
92
92
|
|
|
93
93
|
**`approve`** — Record an approval. Append to `.sdlc/approvals.json`:
|
|
@@ -153,13 +153,16 @@ If the predicate **fails**: report exactly which approvals are still missing and
|
|
|
153
153
|
|
|
154
154
|
If the predicate **passes**:
|
|
155
155
|
- Mark this review step `status: "done"`.
|
|
156
|
-
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
156
|
+
- **`stories-review`** is the end of the gating chain: set `currentStep: "ready-for-build"` (the Phase 3
|
|
157
|
+
handoff sentinel; intentionally not a `steps[]` entry) **and** open the parallel **`test-cases`** track
|
|
158
|
+
(set its step `blocked` → `in_progress`). The build half can now start **and** the tester can work
|
|
159
|
+
`test-cases` at the same time.
|
|
160
|
+
- **`test-cases-review`** is the parallel track's gate: mark it `done` but **leave `currentStep` at
|
|
161
|
+
`ready-for-build`** — completing test cases must never pull the epic back from the build half.
|
|
162
|
+
- Any **other** review step: set the next step in `steps[]` from `blocked` to `in_progress` (authoring)
|
|
163
|
+
or `in_review`, and set `currentStep` to that next step.
|
|
161
164
|
- Write `state.json`. Report the advance and what the next authored artifact is (or that the epic is
|
|
162
|
-
now `ready-for-build`).
|
|
165
|
+
now `ready-for-build`, with `test-cases` running in parallel).
|
|
163
166
|
|
|
164
167
|
### PR-driven automation (the `yad gate` CLI)
|
|
165
168
|
When the hub has a platform, the mechanical `open`/`sync`/`advance` is performed deterministically by the
|