yadflow 2.2.0 → 2.4.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 +16 -5
- package/README.md +75 -22
- package/cli/doctor.mjs +45 -3
- package/cli/epic-state.mjs +19 -2
- package/cli/errors.mjs +2 -0
- package/cli/manifest.mjs +23 -1
- package/cli/setup.mjs +109 -10
- package/docs/index.html +62 -11
- package/package.json +5 -3
- package/skills/sdlc/config.yaml +41 -4
- package/skills/sdlc/install.sh +1 -1
- package/skills/sdlc/module-help.csv +6 -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-learning/SKILL.md +140 -0
- package/skills/yad-connect-learning/references/learning-context.md +79 -0
- package/skills/yad-connect-learning/references/learning-registry.md +60 -0
- 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-learn/SKILL.md +146 -0
- package/skills/yad-learn/references/learning-state.md +75 -0
- 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 +35 -15
- 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
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: yad-learn
|
|
3
|
+
description: 'The cross-cutting learning layer: at ANY SDLC stage, a team member can ask to learn a concept and be tutored in the context of what the team is building. Routes the request to the connected learning tool (.sdlc/learning.json, DeepTutor-first) grounded in the project knowledge base, or degrades to harness-native tutoring (the harness model reading the artifacts) when no tool is connected. Renders a tutorial artifact and appends to a per-member learning ledger that is kept LOCAL-ONLY — gitignored, never committed or pushed to the product hub or any code repo — so it stays a private, personal skills log (yad-status rolls up the local records). Purely opt-in — it NEVER blocks a gate and never touches epic state, approvals, or the contract lock. Use when the user says "teach me <concept>", "learn about <concept>", or "yad-learn".'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SDLC — Learn (the cross-cutting tutor)
|
|
7
|
+
|
|
8
|
+
**Goal:** At any SDLC stage, a team member can pause and ask to learn a concept — e.g. *"teach me why the
|
|
9
|
+
architecture hash-locks the contract surface"* — and get tutored **in the context of this project**. The
|
|
10
|
+
tutorial is rendered as an artifact and the request is recorded in a **personal, local skills log**
|
|
11
|
+
(`yad-status` shows the roll-up of your local records). This makes a learner's own understanding — and
|
|
12
|
+
therefore their **control over what is being built** — explicit, without ever exposing who-learned-what
|
|
13
|
+
to the team.
|
|
14
|
+
|
|
15
|
+
**Learning output is LOCAL-ONLY.** The records ledger and the rendered tutorials are personal artifacts:
|
|
16
|
+
they are **gitignored and must never be committed or pushed** — not to the product hub and not to any
|
|
17
|
+
code repo. The skill ensures the product hub's `.gitignore` lists these paths before it writes them. The
|
|
18
|
+
only committed, shared learning file is the connection registry `.sdlc/learning.json` (no secrets, no
|
|
19
|
+
personal data) — written by `yad-connect-learning`, not here.
|
|
20
|
+
|
|
21
|
+
This is a **cross-cutting, opt-in** skill (like `yad-status`, it runs any time). It is **never a gate**:
|
|
22
|
+
it does not move `currentStep`, never records an approval, and never touches `.sdlc/state.json`, the
|
|
23
|
+
approvals ledger, or the contract lock. It writes only the local learning ledger + tutorial artifacts.
|
|
24
|
+
|
|
25
|
+
## Conventions
|
|
26
|
+
|
|
27
|
+
- `{project-root}` resolves from the project working directory (the **product hub**).
|
|
28
|
+
- The tutor is reached via the project's learning connection (`.sdlc/learning.json`, written by
|
|
29
|
+
`yad-connect-learning`). **DeepTutor-first** (a CLI subprocess); when no tool is connected (or the
|
|
30
|
+
`deeptutor` binary is absent) it degrades to **harness-native** tutoring — the harness model reads the
|
|
31
|
+
scoped artifacts and explains the concept itself. Either way `yad-learn` always works and always
|
|
32
|
+
records.
|
|
33
|
+
- Per-epic learning records: `epics/EP-<slug>/.sdlc/learning-records.json` (append-only personal log).
|
|
34
|
+
Rendered tutorials: `epics/EP-<slug>/learning/`.
|
|
35
|
+
- When no epic is scoped, records go to `.sdlc/learning-records.json` and tutorials to `.sdlc/learning/`
|
|
36
|
+
(cross-project learning).
|
|
37
|
+
- **Local-only, never committed.** All of the above paths are personal output. Before writing any of
|
|
38
|
+
them, ensure the **product hub's** `.gitignore` ignores learning output (idempotent — append only if
|
|
39
|
+
the lines are absent):
|
|
40
|
+
```
|
|
41
|
+
# yadflow learning layer — personal, local-only (never commit or push)
|
|
42
|
+
.sdlc/learning-records.json
|
|
43
|
+
.sdlc/learning/
|
|
44
|
+
epics/*/.sdlc/learning-records.json
|
|
45
|
+
epics/*/learning/
|
|
46
|
+
```
|
|
47
|
+
Never write learning output into a connected **code repo** — it lives only in the product hub, and only
|
|
48
|
+
on the local machine. `.sdlc/learning.json` (the connection registry) is the sole committed learning
|
|
49
|
+
file and is NOT ignored.
|
|
50
|
+
- Speak in the configured `communication_language`; write tutorials in `document_output_language`.
|
|
51
|
+
|
|
52
|
+
## Inputs
|
|
53
|
+
|
|
54
|
+
- `concept` — **required.** The idea to learn (e.g. "contract versioning", "async/await", "the per-repo
|
|
55
|
+
stories gate").
|
|
56
|
+
- `context` — optional free text narrowing the focus (e.g. "why the surface is hash-locked", "in the
|
|
57
|
+
backend event loop").
|
|
58
|
+
- `epic` — optional `EP-<slug>` to scope the tutorial + record to one epic (default: cross-project).
|
|
59
|
+
- `stage` — optional SDLC stage the learner is at (e.g. `architecture-review`, `implement`), recorded for
|
|
60
|
+
the skills roll-up.
|
|
61
|
+
- `member` — the learner (default: the invoking user).
|
|
62
|
+
- `mode` — `explain` (default) | `deep` | `quiz` (`config.yaml` `learning.capabilities`).
|
|
63
|
+
- `action` — `learn` (default) | `list` | `complete`.
|
|
64
|
+
|
|
65
|
+
## On Activation (`action: learn`)
|
|
66
|
+
|
|
67
|
+
### Step 1 — Resolve the connection and route
|
|
68
|
+
Read `.sdlc/learning.json`:
|
|
69
|
+
|
|
70
|
+
- **DeepTutor available** (`source: "deeptutor-cli"`): run the CLI with the mapped capability
|
|
71
|
+
(`explain→chat`, `deep→deep_research`, `quiz→deep_question`), grounded in the kb:
|
|
72
|
+
```
|
|
73
|
+
deeptutor run <capability> "<concept> — in the context of <epic/stage + scoped artifact>" \
|
|
74
|
+
--kb <kb> --format json
|
|
75
|
+
```
|
|
76
|
+
Parse the NDJSON: concatenate `content` events into the tutorial body; capture `session_id` from the
|
|
77
|
+
`done` event. `mode: quiz` issues a `deep_question` follow-up and records the comprehension signal.
|
|
78
|
+
- **Harness-native** (`tool: "none"`, absent registry, or `source: "harness-native"`): tutor with the
|
|
79
|
+
harness model. Read the scoped epic's `epic.md` / `architecture.md` / `contract.md` and any connected
|
|
80
|
+
`code-context/<repo>/code-map.md`, and write a focused explanation grounded in them. No error — this is
|
|
81
|
+
the normal degraded path.
|
|
82
|
+
|
|
83
|
+
Keep the tutorial focused (usually < 600 words): explain the concept, then tie it to **one concrete
|
|
84
|
+
example from this project** (an artifact line, a contract field, a story).
|
|
85
|
+
|
|
86
|
+
### Step 2 — Render the tutorial artifact (local-only)
|
|
87
|
+
First ensure the product hub's `.gitignore` lists the learning-output paths (see Conventions — append the
|
|
88
|
+
block only if absent, so the artifacts can never be committed or pushed). Then write the tutorial to
|
|
89
|
+
`epics/EP-<slug>/learning/<member>--<concept-slug>.md` (or `.sdlc/learning/` when no epic is scoped).
|
|
90
|
+
Front-matter the file with `member`, `concept`, `stage`, `tool`, and `requestedAt`.
|
|
91
|
+
|
|
92
|
+
### Step 3 — Record in the learning ledger (append-only)
|
|
93
|
+
Append to `epics/EP-<slug>/.sdlc/learning-records.json` (create the array if absent):
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"member": "alice",
|
|
98
|
+
"concept": "contract versioning",
|
|
99
|
+
"context": "why the architecture hash-locks the surface",
|
|
100
|
+
"stage": "architecture-review",
|
|
101
|
+
"mode": "explain",
|
|
102
|
+
"tool": "deeptutor",
|
|
103
|
+
"sessionId": "…",
|
|
104
|
+
"tutorial": "learning/alice--contract-versioning.md",
|
|
105
|
+
"comprehension": null,
|
|
106
|
+
"status": "in-progress",
|
|
107
|
+
"requestedAt": "<YYYY-MM-DD>",
|
|
108
|
+
"completedAt": null
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
`tool` is `deeptutor` or `harness-native`. `comprehension` holds the quiz signal when `mode: quiz`,
|
|
113
|
+
else `null`.
|
|
114
|
+
|
|
115
|
+
### Step 4 — Present + confirm (record-only, NO gate)
|
|
116
|
+
Show the tutorial and ask the member to confirm they've reviewed it. This is **record-keeping only** —
|
|
117
|
+
there is no approval and no gate. The learner runs `action: complete` (below) when done.
|
|
118
|
+
|
|
119
|
+
## Other actions
|
|
120
|
+
|
|
121
|
+
- **`list`** — print the learning records for the scoped epic (or cross-project): who learned what, by
|
|
122
|
+
stage, with status. Read-only.
|
|
123
|
+
- **`complete`** — mark a record `status: "learned"` and set `completedAt` (match on `member` + `concept`,
|
|
124
|
+
newest in-progress record). Record-only; advances nothing.
|
|
125
|
+
|
|
126
|
+
## Hard rules
|
|
127
|
+
|
|
128
|
+
- **Opt-in, never a gate.** `yad-learn` never moves `currentStep`, never records an approval, and never
|
|
129
|
+
blocks any step. Learning is additive.
|
|
130
|
+
- **Read-only except the learning ledger.** It writes only `learning-records.json` + tutorial artifacts;
|
|
131
|
+
it never touches `state.json`, `approvals.json`, `comments.json`, or the contract lock.
|
|
132
|
+
- **Local-only output.** The records ledger and tutorials are gitignored personal artifacts — never
|
|
133
|
+
commit or push them, and never write them into a code repo. Ensure the hub `.gitignore` covers them
|
|
134
|
+
before writing (see Conventions).
|
|
135
|
+
- **Always works.** No DeepTutor / no connection → tutor harness-native. Never fail because a tool is
|
|
136
|
+
absent.
|
|
137
|
+
- **Grounded.** Prefer the project's own artifacts/kb; a generic answer with no project tie-in is a last
|
|
138
|
+
resort, and say so when that happens.
|
|
139
|
+
- **Attributable.** Every record names the `member` and `stage`, so the `yad-status` roll-up is a true
|
|
140
|
+
picture of the local learner's own skills log.
|
|
141
|
+
|
|
142
|
+
## Reference
|
|
143
|
+
- Record schema, the mode→capability map, and the harness-native degrade path:
|
|
144
|
+
`references/learning-state.md`.
|
|
145
|
+
- The connection this consumes: `../yad-connect-learning/SKILL.md`.
|
|
146
|
+
- The read-only roll-up: `../yad-status/SKILL.md` (the local skills-log section).
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Learning state — record schema, capability map, degrade path
|
|
2
|
+
|
|
3
|
+
How `yad-learn` records a learner's own learning, drives DeepTutor, and degrades. The records are the
|
|
4
|
+
evidence base for the **local skills-log roll-up** in `yad-status`.
|
|
5
|
+
|
|
6
|
+
## Location
|
|
7
|
+
|
|
8
|
+
- Per-epic ledger: `epics/EP-<slug>/.sdlc/learning-records.json` (append-only JSON array).
|
|
9
|
+
- Cross-project ledger (no epic scoped): `.sdlc/learning-records.json`.
|
|
10
|
+
- Rendered tutorials: `epics/EP-<slug>/learning/<member>--<concept-slug>.md` (or `.sdlc/learning/`).
|
|
11
|
+
|
|
12
|
+
(`config.yaml` `learning.records` and `learning.artifacts`.)
|
|
13
|
+
|
|
14
|
+
**Local-only.** Every path above is personal output and is **gitignored — never committed or pushed**, to
|
|
15
|
+
the product hub or any code repo. `yad-learn` ensures the hub `.gitignore` lists them before writing. The
|
|
16
|
+
only committed learning file is the connection registry `.sdlc/learning.json`.
|
|
17
|
+
|
|
18
|
+
## Record schema
|
|
19
|
+
|
|
20
|
+
```json
|
|
21
|
+
{
|
|
22
|
+
"member": "alice", // the learner (default: invoking user)
|
|
23
|
+
"concept": "contract versioning", // what was learned
|
|
24
|
+
"context": "why the surface is hash-locked", // optional focus
|
|
25
|
+
"stage": "architecture-review", // SDLC stage the learner was at; null if unscoped
|
|
26
|
+
"mode": "explain", // explain | deep | quiz
|
|
27
|
+
"tool": "deeptutor", // deeptutor | harness-native
|
|
28
|
+
"sessionId": "…", // DeepTutor session id; null when harness-native
|
|
29
|
+
"tutorial": "learning/alice--contract-versioning.md",
|
|
30
|
+
"comprehension": null, // quiz signal (e.g. "4/5") when mode: quiz, else null
|
|
31
|
+
"status": "in-progress", // in-progress | learned
|
|
32
|
+
"requestedAt": "2026-06-14",
|
|
33
|
+
"completedAt": null // set by `action: complete`
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Rules
|
|
38
|
+
|
|
39
|
+
- **Append-only.** `learn` pushes a new record. `complete` mutates the newest in-progress record matching
|
|
40
|
+
`member` + `concept` (status → `learned`, set `completedAt`). Never rewrite history.
|
|
41
|
+
- **Attributable.** `member` + `stage` are always set so the local roll-up is accurate.
|
|
42
|
+
- **No secrets.** Records hold concept text + references only — never keys or raw tool output beyond the
|
|
43
|
+
rendered tutorial.
|
|
44
|
+
- **Never commit the ledger or tutorials.** They are personal, local-only artifacts: gitignored, never
|
|
45
|
+
committed or pushed (to the hub or a code repo). Only `.sdlc/learning.json` is committed.
|
|
46
|
+
|
|
47
|
+
## Mode → DeepTutor capability
|
|
48
|
+
|
|
49
|
+
| mode | capability | invocation |
|
|
50
|
+
|------|------------|------------|
|
|
51
|
+
| `explain` | `chat` | `deeptutor run chat "<concept> — in context of <…>" --kb <kb> --format json` |
|
|
52
|
+
| `deep` | `deep_research` | `deeptutor run deep_research "<…>" --kb <kb> --format json` |
|
|
53
|
+
| `quiz` | `deep_question` | `deeptutor run deep_question "<…>" --kb <kb> --format json` → record `comprehension` |
|
|
54
|
+
|
|
55
|
+
`--format json` is **NDJSON**: one event per line, each with `type` (`content` | `tool_call` |
|
|
56
|
+
`tool_result` | `done`) and `session_id`. Concatenate `content` into the tutorial; read `session_id` from
|
|
57
|
+
`done`.
|
|
58
|
+
|
|
59
|
+
## Harness-native degrade
|
|
60
|
+
|
|
61
|
+
When `.sdlc/learning.json` is absent, `tool: "none"`, or `source: "harness-native"`:
|
|
62
|
+
|
|
63
|
+
1. Read the scoped epic's `epic.md` / `architecture.md` / `contract.md` and any
|
|
64
|
+
`code-context/<repo>/code-map.md`.
|
|
65
|
+
2. Explain `concept` (+ `context`) grounded in what those say, with one concrete example from the project.
|
|
66
|
+
3. Write the tutorial + record exactly as the DeepTutor path does, with `"tool": "harness-native"` and
|
|
67
|
+
`"sessionId": null`.
|
|
68
|
+
|
|
69
|
+
The learning layer therefore **always works and always records** — DeepTutor only adds kb grounding,
|
|
70
|
+
deep research, and quizzes.
|
|
71
|
+
|
|
72
|
+
## Greenfield / no epic
|
|
73
|
+
|
|
74
|
+
With no epic scoped, write to the cross-project ledger `.sdlc/learning-records.json` and tutorials to
|
|
75
|
+
`.sdlc/learning/`. `yad-status` reads both the per-epic and cross-project ledgers for the local roll-up.
|
|
@@ -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
|
|
@@ -18,7 +18,7 @@ touched `domain`, `|domainOwners[domain]| >= 1`.
|
|
|
18
18
|
- Stories review: the touched domains are the **union of every story's `repos`** under `stories/`.
|
|
19
19
|
|
|
20
20
|
So one gate, two option-shapes:
|
|
21
|
-
- Epic / UI reviews: base rule (no risk tags, no per-repo routing).
|
|
21
|
+
- Epic / UI / test-cases reviews: base rule (no risk tags, no per-repo routing).
|
|
22
22
|
- Architecture+contract review: escalated (`risk_tags: ["contract"]`) — owner + 1 reviewer + a
|
|
23
23
|
`domain-owner` for **each** repo in `epic.repos`. (A small team may have one engineer own several
|
|
24
24
|
repos — one person can supply several `domain-owner` records with different `domain` values.)
|
|
@@ -57,7 +57,7 @@ if step in cfg.locked_steps: eff = "human_approve"
|
|
|
57
57
|
```
|
|
58
58
|
|
|
59
59
|
So a kill switch, a `locked` flag, or membership in `locked_steps` forces a stop no matter what the
|
|
60
|
-
per-step dial says. `engineer-review` and the
|
|
60
|
+
per-step dial says. `engineer-review` and the five front states are covered by `locked` / `locked_steps`.
|
|
61
61
|
|
|
62
62
|
## Deriving signals & the provisional verdict
|
|
63
63
|
|
|
@@ -115,7 +115,7 @@ Reverting (`to: human_approve`) is never gated — automation must be reversible
|
|
|
115
115
|
## What stays human, always
|
|
116
116
|
|
|
117
117
|
- `engineer-review` — the merge gate. `yad-run` always stops here and hands to `yad-ship`.
|
|
118
|
-
- The
|
|
119
|
-
`locked_steps`; the dial-setter refuses them.
|
|
118
|
+
- The five front states (`epic`, `architecture`, `ui-design`, `stories`, `test-cases`) — not in
|
|
119
|
+
`back_steps`, in `locked_steps`; the dial-setter refuses them.
|
|
120
120
|
- Any contract-surface change — halts the loop and routes back to the architecture gate, regardless of
|
|
121
121
|
the dial.
|
package/skills/yad-spec/SKILL.md
CHANGED
|
@@ -43,7 +43,9 @@ is the same graceful-degradation pattern `yad-ui` uses for Impeccable.
|
|
|
43
43
|
|
|
44
44
|
### Step 1 — Resolve the story and check readiness
|
|
45
45
|
Read `{project-root}/epics/<epic>/.sdlc/state.json`. Proceed only when
|
|
46
|
-
`currentStep == "ready-for-build"` (the
|
|
46
|
+
`currentStep == "ready-for-build"` (the gating front half — through the **stories** gate — is `done`).
|
|
47
|
+
The **`test-cases` track may still be `in_progress`**: it is parallel and non-blocking, so the build
|
|
48
|
+
half runs alongside it — its status does not affect readiness here. Read the story file
|
|
47
49
|
`epics/<epic>/stories/<story>.md`; confirm `repo` is in its `repos`. If the epic is not ready, STOP
|
|
48
50
|
and point the user at `yad-status`. **Do not mutate front-half state** — `ready-for-build` semantics
|
|
49
51
|
stay intact.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: yad-status
|
|
3
|
-
description: 'Read-only view of an SDLC epic: prints the current step, each step''s dials (assistance/automation) and status, and which approvals are still required at the active gate. For stories in the build half it also prints each back-half step''s automation dial, status, and trust record (runs / % approved-unchanged / whether it clears the threshold to be earned), plus the system-wide kill-switch state — so the team can see WHY a step is automated and reverse it with evidence. Surfaces the Phase 5 instrumentation signals: per-step "earned but manual" (nudge cost) and, across multiple epics, a fleet roll-up (scale of read). Use when the user says "yad status", "where is epic EP-...", "what is blocking the gate", "show the trust record", or "fleet status".'
|
|
3
|
+
description: 'Read-only view of an SDLC epic: prints the current step, each step''s dials (assistance/automation) and status, and which approvals are still required at the active gate. For stories in the build half it also prints each back-half step''s automation dial, status, and trust record (runs / % approved-unchanged / whether it clears the threshold to be earned), plus the system-wide kill-switch state — so the team can see WHY a step is automated and reverse it with evidence. Also prints the cross-cutting personal skills-log roll-up from the LOCAL-ONLY learning ledger (gitignored, never committed/pushed — the local learner''s own learning, by stage). Surfaces the Phase 5 instrumentation signals: per-step "earned but manual" (nudge cost) and, across multiple epics, a fleet roll-up (scale of read). Use when the user says "yad status", "where is epic EP-...", "what is blocking the gate", "show the trust record", "team skills", or "fleet status".'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# SDLC — Status (read-only)
|
|
@@ -22,20 +22,25 @@ report all if the user asked for an overview).
|
|
|
22
22
|
Read `.sdlc/state.json`, `.sdlc/approvals.json`, `epic.md` frontmatter (for `repos`), and — if present
|
|
23
23
|
— `.sdlc/contract-lock.json`. For the build half (Phase 4), also read — if present — every
|
|
24
24
|
`.sdlc/build-state/<story-id>.json`, `.sdlc/trust-log.json`, and the `automation` block of
|
|
25
|
-
`skills/sdlc/config.yaml` (`back_steps`, `trust_threshold`, `locked_steps`, `kill_switch`).
|
|
26
|
-
|
|
25
|
+
`skills/sdlc/config.yaml` (`back_steps`, `trust_threshold`, `locked_steps`, `kill_switch`). For the
|
|
26
|
+
cross-cutting learning layer, also read — if present — the **local-only** `.sdlc/learning-records.json`
|
|
27
|
+
(the per-epic learning ledger, gitignored) and the project-wide `{project-root}/.sdlc/learning-records.json`.
|
|
28
|
+
Do not modify any of them.
|
|
27
29
|
|
|
28
30
|
### Step 3 — Report
|
|
29
31
|
Print, in this order:
|
|
30
32
|
|
|
31
33
|
1. **Epic:** `epicId`, `status` from `epic.md` frontmatter, `currentStep`, and `repos` (the touched
|
|
32
34
|
domains).
|
|
33
|
-
2. **Steps table** — for every front step in `steps[]` order (
|
|
35
|
+
2. **Steps table** — for every front step in `steps[]` order (10, or 12 when the optional analysis step
|
|
34
36
|
was run): `id`, `type`, `status`, `assistance`, `automation`, `locked`, and `risk_tags`. Mark the
|
|
35
|
-
`currentStep` with `→`. The
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
`
|
|
37
|
+
`currentStep` with `→`. The gating chain is `[analysis → analysis-review →] epic → epic-review →
|
|
38
|
+
architecture → architecture-review → ui-design → ui-design-review → stories → stories-review` →
|
|
39
|
+
**`ready-for-build`** (the bracketed `analysis` prefix is present only when `yad-analysis` seeded it).
|
|
40
|
+
`test-cases → test-cases-review` is a **parallel, non-blocking track**: it opens when `stories-review`
|
|
41
|
+
passes and runs alongside the build half, so when `currentStep` is `ready-for-build` the `test-cases`
|
|
42
|
+
step may still be `in_progress`/`in_review` — show its status, and note "parallel" so it is clear it
|
|
43
|
+
does not gate the build. Always render exactly the steps present in `steps[]`.
|
|
39
44
|
3. **Active gate** — for the `currentStep` (if it is a `review+approve` step), compute and show:
|
|
40
45
|
- the reviewer rule in force — **base** (`owner + 1 reviewer`), **escalated** (list the required
|
|
41
46
|
domains), or **per-repo** for `stories-review` (list each repo needing sign-off),
|
|
@@ -79,13 +84,28 @@ Print, in this order:
|
|
|
79
84
|
recommendation to flip — earning the evidence and flipping the dial stay deliberate human acts
|
|
80
85
|
(`yad-run action: set-dial`). See `docs/phase-5-build-plan.md` §"What to instrument now".
|
|
81
86
|
|
|
82
|
-
9. **
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
9. **My skills (the learning layer — local-only).** If `.sdlc/learning-records.json` exists for the epic
|
|
88
|
+
(or the project-wide ledger does), print the **personal skills-log** roll-up from it — read-only. These
|
|
89
|
+
records are **local-only (gitignored, never committed or pushed)**, so this reflects only the local
|
|
90
|
+
learner's own learning, not the team's. Show:
|
|
91
|
+
- **By member:** each `member` present in the local ledger with the concepts they have `learned` and
|
|
92
|
+
those `in-progress` (count + names).
|
|
93
|
+
- **By stage:** how many learning requests landed at each SDLC `stage` (e.g. `architecture-review: 3`),
|
|
94
|
+
so heavy-learning stages stand out.
|
|
95
|
+
- **Tool:** whether tutoring ran on `deeptutor` (grounded in the kb) or `harness-native`, per the
|
|
96
|
+
records' `tool` field.
|
|
97
|
+
This section is purely informational — learning is opt-in and never gates a step (it is produced by
|
|
98
|
+
`yad-learn`). If no learning ledger exists, omit the section silently (greenfield/learning not used).
|
|
99
|
+
|
|
100
|
+
10. **Fleet roll-up (overview only).** When the user asked for an overview, or more than one epic exists
|
|
101
|
+
under `{project-root}/epics/`, print a one-line-per-epic roll-up across the fleet: each epic's
|
|
102
|
+
`currentStep` (front gate) and, for stories in the build half, a count of back-half steps **waiting
|
|
103
|
+
at a human gate** and of steps flagged **earned-but-manual**, plus a **local skills-log** count (records
|
|
104
|
+
in the local-only `learning-records.json`: learned / in-progress). Close with fleet totals (epics at
|
|
105
|
+
each front gate; total earned-but-manual back steps; total concepts learned locally across the fleet).
|
|
106
|
+
This is the
|
|
107
|
+
*scale-of-read* signal the Phase 5 trigger watches — when this roll-up stops fitting in one glance,
|
|
108
|
+
that is the measured bottleneck. Still strictly read-only; it only scans the per-epic files.
|
|
89
109
|
|
|
90
110
|
### Hard rule
|
|
91
111
|
This skill is strictly read-only. If the user wants to comment, approve, or advance, point them to
|
|
@@ -97,7 +97,9 @@ In `state.json`: set `stories.status: "done"`, set `stories-review.status: "in_r
|
|
|
97
97
|
### Step 7 — Stop at the gate (do NOT advance)
|
|
98
98
|
Report: the story IDs created, the repos each touches, and that the next action is **review** via
|
|
99
99
|
`yad-review-gate`. Note that this review routes **per-repo reviewers**: owner + 1 reviewer **plus**, for
|
|
100
|
-
each repo appearing in any story's `repos`, a `domain-owner` approval for that repo.
|
|
100
|
+
each repo appearing in any story's `repos`, a `domain-owner` approval for that repo. When this gate
|
|
101
|
+
passes the epic becomes **`ready-for-build`** — the build half can start **and** the parallel
|
|
102
|
+
**`test-cases`** track opens for the tester (`yad-test-cases`); the two run at the same time. **Never record
|
|
101
103
|
approval here.** Front states do not auto-advance. When the hub has a platform, the gate opens a review
|
|
102
104
|
PR on the hub (via `yad-hub-bridge`, with a `domain:<repo>` label per touched repo) and
|
|
103
105
|
`yad-review-gate action: sync` pulls platform approvals/comments into the ledger; otherwise the review
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: yad-test-cases
|
|
3
|
+
description: 'Front state 9 of the gated SDLC — a PARALLEL, non-blocking track. Opens when the stories gate passes (the epic is already ready-for-build, so the build half can start at the same time) and runs alongside implementation. With the test architect (Murat), author test-cases.md for the approved stories, and — when a testing tool is connected — generate/link the actual automation tests in it; otherwise produce the test-case artifact only. Reads epic + architecture + contract + UI + stories as input. Never auto-advances — hands off to the team review gate. Use when the user says "author the test cases" or after the stories gate passes.'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SDLC — Author Test Cases (front state 9 — parallel, non-blocking)
|
|
7
|
+
|
|
8
|
+
**Goal:** Produce a human-authored, AI-assisted `test-cases.md` for an approved epic — the risk-based
|
|
9
|
+
test cases that cover the stories' acceptance criteria — **and**, when a testing tool is connected, the
|
|
10
|
+
**actual automation tests** inside the connected code repo(s), linked back from the artifact. This is a
|
|
11
|
+
**front state**: human-authored with AI assist, **never auto-advances**. When the test cases are
|
|
12
|
+
drafted, control passes to `yad-review-gate` (base rule: owner + 1 reviewer).
|
|
13
|
+
|
|
14
|
+
**This step does NOT block the build half.** It opens when the **stories** gate passes — at which point
|
|
15
|
+
the epic is already `ready-for-build`, so implementation (`yad-spec` → `yad-implement` → …) can start
|
|
16
|
+
**at the same time** the tester works here. The test-cases track is driven by its own step `status`
|
|
17
|
+
(it opens to `in_progress` when `stories-review` passes) and its review **never moves `currentStep`
|
|
18
|
+
away from `ready-for-build`**, so the two run in parallel.
|
|
19
|
+
|
|
20
|
+
Test work is shaped by the **test architect** lens — **Murat** (`bmad-tea`), driving
|
|
21
|
+
`bmad-testarch-test-design` for the cases and `bmad-testarch-automate` for the automation. The
|
|
22
|
+
automation is materialized in the **testing tool connected via `yad-connect-testing`**
|
|
23
|
+
(`.sdlc/testing.json`), reached through its MCP. When a tool is connected the lens **generates** tests
|
|
24
|
+
into it (or **links** an existing suite and reads it back); when none is connected, the step degrades to
|
|
25
|
+
the Markdown artifact only — the testing tool is additive, exactly like the design tool.
|
|
26
|
+
|
|
27
|
+
## Conventions
|
|
28
|
+
|
|
29
|
+
- `{project-root}` resolves from the project working directory.
|
|
30
|
+
- Artifacts live under `{project-root}/epics/EP-<slug>/` (build plan §6).
|
|
31
|
+
- The connected testing tool is recorded in `{project-root}/.sdlc/testing.json` (`config.yaml`
|
|
32
|
+
`testing`), written by `yad-connect-testing`. The per-epic case→test map is `test-links.json`
|
|
33
|
+
(Step 4b).
|
|
34
|
+
- Speak in the configured `communication_language`; write documents in `document_output_language`.
|
|
35
|
+
|
|
36
|
+
## On Activation
|
|
37
|
+
|
|
38
|
+
### Step 1 — Resolve the epic and check the track
|
|
39
|
+
Resolve the `EP-<slug>` (ask if not provided). Read `.sdlc/state.json`. Only proceed when the
|
|
40
|
+
**`test-cases` step's `status == "in_progress"`** — it opens when `stories-review` passes (the epic is
|
|
41
|
+
already `ready-for-build` by then; `currentStep` stays there because this is a parallel track, so do
|
|
42
|
+
**not** gate on `currentStep`). If `test-cases` is still `blocked`, the stories review has not passed —
|
|
43
|
+
stop and point the user at `yad-status` / the gate.
|
|
44
|
+
|
|
45
|
+
### Step 1b — Open the authoring branch
|
|
46
|
+
Open the test-cases authoring branch `test-cases/EP-<slug>` per the shared procedure
|
|
47
|
+
(`../yad-epic/references/state-schema.md` → "Authoring branches"): git-safe (skip with a note if
|
|
48
|
+
`{project-root}` is not a git work tree), check out the branch if it exists, else create it from the
|
|
49
|
+
hub's default branch. Author and commit `test-cases.md` on it. This is **distinct** from the bridge's
|
|
50
|
+
`review/…` branch.
|
|
51
|
+
|
|
52
|
+
### Step 2 — Read inputs
|
|
53
|
+
Read `epic.md` (user-level acceptance signals, scope), `architecture.md` (flows, components by repo),
|
|
54
|
+
`contract.md` (the shared surface under test), `ui-design.md` (screens/states the tests exercise), and
|
|
55
|
+
**all** approved `stories/EP-<slug>-S0N.md`. Each story's **acceptance criteria are the source of truth**
|
|
56
|
+
for the cases — the test cases must collectively verify every story's criteria.
|
|
57
|
+
|
|
58
|
+
### Step 2b — Load existing-code context (make the brain code-aware)
|
|
59
|
+
Read the registry `{project-root}/.sdlc/repos.json` (`config.yaml` `code_context`). For **each repo in
|
|
60
|
+
`epic.repos`**, load the code-map `{project-root}/.sdlc/code-context/<repo>/code-map.md` so the
|
|
61
|
+
automation **targets real existing endpoints/components and reuses existing fixtures** rather than
|
|
62
|
+
inventing parallel ones.
|
|
63
|
+
|
|
64
|
+
- **Greenfield-safe:** if `repos.json` is absent/empty, note "no repos connected" and proceed.
|
|
65
|
+
- **Staleness:** if a repo's current HEAD ≠ its registry `syncedHead`, warn and suggest
|
|
66
|
+
`yad repo refresh <repo>` (a human decision — flag and stop, never auto-refresh); stamp
|
|
67
|
+
`code-context: stale` in the frontmatter.
|
|
68
|
+
- **Traceability:** record the loaded maps in the `test-cases.md` `code-context:` frontmatter field.
|
|
69
|
+
|
|
70
|
+
### Step 3 — Author the test cases (assist: test architect)
|
|
71
|
+
Adopt the **test architect** lens (`bmad-tea`, Murat), driving `bmad-testarch-test-design`. For each
|
|
72
|
+
story / user flow shape risk-based test cases:
|
|
73
|
+
|
|
74
|
+
- **Risk assessment** — categorize and score what can fail (probability × impact); depth scales with
|
|
75
|
+
impact (Murat's "risk-based testing" principle).
|
|
76
|
+
- **Coverage plan** — assign each case a priority **P0 (critical) / P1 (high) / P2 (medium) / P3 (low)**
|
|
77
|
+
and a level, preferring the lowest useful level (unit > integration > E2E).
|
|
78
|
+
- **Entry/exit criteria** and any **NFR** thresholds (security, performance, reliability) in scope.
|
|
79
|
+
- Each case: a stable label, the story it covers, preconditions, steps, and expected result.
|
|
80
|
+
|
|
81
|
+
### Step 3b — Materialize the automation in the connected tool (generate or link)
|
|
82
|
+
Read `{project-root}/.sdlc/testing.json` (`config.yaml` `testing.registry`). Decide the path:
|
|
83
|
+
|
|
84
|
+
- **No tool / `tool: "none"` / `source: "unavailable"`** (or the file is absent): **degrade** — author
|
|
85
|
+
the Markdown artifact only and record `testing: none` in the frontmatter with a one-line note
|
|
86
|
+
(mirrors the `design: none` degrade). Skip to Step 4.
|
|
87
|
+
- **A tool is connected and its MCP is available:** adopt the `test architect` lens and, using the
|
|
88
|
+
provider recorded in `testing.json` (Playwright via a Playwright MCP, Cypress/pytest via theirs) drive
|
|
89
|
+
`bmad-testarch-automate`:
|
|
90
|
+
- **Generate** — when the provider is write-capable, author one automation test per high-priority
|
|
91
|
+
(P0/P1) case into the connected code repo(s) for the repos in `epic.repos`, reusing the code-maps
|
|
92
|
+
(Step 2b) and existing fixtures so tests target built endpoints/components, then run them via the MCP
|
|
93
|
+
to confirm they execute.
|
|
94
|
+
- **Link** — when the user points at an existing suite (or the provider is read-only), reference it and
|
|
95
|
+
**read the tests back** so `test-cases.md` reflects the real suite.
|
|
96
|
+
|
|
97
|
+
Capture each test's `name`, `repo`, `level`, `path`, and `url`. Record which direction was used
|
|
98
|
+
(`generated | linked`). Honest-capability rule: a read-only MCP supports **link** only — never claim a
|
|
99
|
+
test was generated that the provider cannot produce. See
|
|
100
|
+
`../yad-connect-testing/references/testing-context.md`.
|
|
101
|
+
|
|
102
|
+
### Step 4 — Write the test-cases artifact
|
|
103
|
+
Write `{project-root}/epics/EP-<slug>/test-cases.md` using EXACTLY this template:
|
|
104
|
+
|
|
105
|
+
```markdown
|
|
106
|
+
---
|
|
107
|
+
id: EP-<slug>
|
|
108
|
+
epic: EP-<slug>
|
|
109
|
+
artifact: test-cases
|
|
110
|
+
status: draft
|
|
111
|
+
owner: <inherit from epic.md owner> # the epic owner carries through; not retyped
|
|
112
|
+
repos: [<inherit from epic>]
|
|
113
|
+
code-context: { repos: [], loaded: <YYYY-MM-DD or none> } # code-maps that informed the tests (Step 2b)
|
|
114
|
+
testing: <none | { tool: <playwright|cypress|pytest|…>, direction: <generated|linked>, suite: <url/path>, tests: <N> }> # the connected testing tool (Step 3b)
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Test strategy & risk
|
|
118
|
+
<!-- risk assessment (category, probability, impact, score), entry/exit criteria, NFR thresholds in scope -->
|
|
119
|
+
|
|
120
|
+
## Test cases
|
|
121
|
+
<!-- one row/subsection per case: id, story covered, priority (P0–P3), level, preconditions, steps, expected -->
|
|
122
|
+
|
|
123
|
+
## Coverage & traceability
|
|
124
|
+
<!-- story -> case map; confirm every story's acceptance criteria are covered -->
|
|
125
|
+
|
|
126
|
+
## Automation (<tool>)
|
|
127
|
+
<!-- omit this section when testing: none. one row per automation test, linking to it in the repo.
|
|
128
|
+
mirrors test-links.json (Step 4b). -->
|
|
129
|
+
<!-- - <Case id> -> <repo>:<test path> (<level>) — <url> -->
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Step 4b — Write the test-links map (when a tool was used)
|
|
133
|
+
When Step 3b generated or linked automation, write the machine-readable case→test map to
|
|
134
|
+
`{project-root}/epics/EP-<slug>/.sdlc/test-links.json` (sibling of `contract-lock.json` /
|
|
135
|
+
`design-links.json`):
|
|
136
|
+
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"tool": "playwright",
|
|
140
|
+
"suite": "tests/playwright.config.ts",
|
|
141
|
+
"generatedAt": "<YYYY-MM-DD>",
|
|
142
|
+
"direction": "generated | linked",
|
|
143
|
+
"tests": [
|
|
144
|
+
{ "case": "TC-01", "story": "EP-<slug>-S01", "repo": "backend", "level": "e2e",
|
|
145
|
+
"path": "tests/inquiry.spec.ts", "url": "<repo url to the test>" }
|
|
146
|
+
],
|
|
147
|
+
"source": "playwright-mcp"
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Keep the `## Automation (<tool>)` section of `test-cases.md` in step with this file. When Step 3b
|
|
152
|
+
degraded (`testing: none`), do **not** write `test-links.json`.
|
|
153
|
+
|
|
154
|
+
### Step 5 — Advance the authoring step (NOT the gate)
|
|
155
|
+
In `state.json`: set `test-cases.status: "done"` and set `test-cases-review.status: "in_review"`. **Leave
|
|
156
|
+
`currentStep` at `ready-for-build`** — this is the parallel track; moving `currentStep` would pull it
|
|
157
|
+
back from the build half. Write `state.json`. Do **not** touch `approvals.json`.
|
|
158
|
+
|
|
159
|
+
### Step 6 — Stop at the gate (do NOT advance)
|
|
160
|
+
Report: the path to `test-cases.md`, the connected testing tool and what it produced (e.g. "Playwright —
|
|
161
|
+
6 tests generated", the suite path + `test-links.json` path, or "no testing tool — artifacts-only"), that
|
|
162
|
+
the build half may already be underway in parallel, and that the next action is **review** via
|
|
163
|
+
`yad-review-gate` (base rule: owner + 1 reviewer). **Never record approval here.** Front states do not
|
|
164
|
+
auto-advance. When the hub has a platform, the gate opens a review
|
|
165
|
+
PR on the hub (via `yad-hub-bridge`) and `yad-review-gate action: sync` pulls platform approvals/comments
|
|
166
|
+
into the ledger; otherwise the review is recorded file-only.
|
|
167
|
+
|
|
168
|
+
## Reference
|
|
169
|
+
- Test-cases frontmatter, body template, and the `test-links.json` schema: `references/test-cases-schema.md`.
|
|
170
|
+
- State schema and field meanings: `../yad-epic/references/state-schema.md`.
|
|
171
|
+
- Connecting a testing tool (Playwright, pluggable) + generate-vs-link recipes and the degrade path:
|
|
172
|
+
`../yad-connect-testing/SKILL.md` (+ `references/testing-context.md`).
|
|
173
|
+
- Connecting code repos + the code-context the brain reads: `../yad-connect-repos/SKILL.md`.
|