yadflow 2.3.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 +19 -1
- package/README.md +46 -14
- package/cli/doctor.mjs +23 -1
- package/cli/errors.mjs +1 -0
- package/cli/manifest.mjs +13 -1
- package/cli/setup.mjs +59 -10
- package/docs/index.html +30 -5
- package/package.json +5 -3
- package/skills/sdlc/config.yaml +21 -0
- package/skills/sdlc/install.sh +1 -1
- package/skills/sdlc/module-help.csv +3 -0
- 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-learn/SKILL.md +146 -0
- package/skills/yad-learn/references/learning-state.md +75 -0
- package/skills/yad-status/SKILL.md +27 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,28 @@
|
|
|
1
|
-
# [2.
|
|
1
|
+
# [2.4.0](https://github.com/abdelrahmannasr/yadflow/compare/v2.3.0...v2.4.0) (2026-06-13)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* address CodeRabbit review on PR [#48](https://github.com/abdelrahmannasr/yadflow/issues/48) ([2f182f7](https://github.com/abdelrahmannasr/yadflow/commit/2f182f72b68e226196b6190802771b0e12b585f9))
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* add DeepTutor learning layer across all SDLC stages ([bd8d4ea](https://github.com/abdelrahmannasr/yadflow/commit/bd8d4eaaa0258242a62ed1b131f7e3f74506af64))
|
|
12
|
+
* make learning-layer output local-only (never committed or pushed) ([aa8f74e](https://github.com/abdelrahmannasr/yadflow/commit/aa8f74eb61855d3a663810a0c68cf8e37fbedd66))
|
|
13
|
+
|
|
14
|
+
# [2.2.0](https://github.com/abdelrahmannasr/yadflow/compare/v2.1.0...v2.2.0) (2026-06-14)
|
|
2
15
|
|
|
3
16
|
|
|
4
17
|
### Features
|
|
5
18
|
|
|
6
19
|
* add parallel test-cases step with pluggable testing-tool connection ([#45](https://github.com/abdelrahmannasr/yadflow/issues/45)) ([19c282f](https://github.com/abdelrahmannasr/yadflow/commit/19c282f6bd737364bca122179b05de8ea94493a9))
|
|
7
20
|
|
|
21
|
+
|
|
22
|
+
### Continuous Integration
|
|
23
|
+
|
|
24
|
+
* wire the hub's gate-sync + verified-commits CI and stamp the CLI version ([#46](https://github.com/abdelrahmannasr/yadflow/issues/46)) ([c856398](https://github.com/abdelrahmannasr/yadflow/commit/c856398a213b17aebea9c46204dbf955b92ea9cf))
|
|
25
|
+
|
|
8
26
|
# [1.1.0](https://github.com/abdelrahmannasr/sdlc-workflow/compare/v1.0.3...v1.1.0) (2026-06-09)
|
|
9
27
|
|
|
10
28
|
|
package/README.md
CHANGED
|
@@ -51,6 +51,8 @@ human**. Detailed walkthroughs for each phase follow below.
|
|
|
51
51
|
| `skills/yad-stories/` | Front state 7: break the epic into repo-tagged stories with stable `EP-<slug>-S0N` IDs. |
|
|
52
52
|
| `skills/yad-test-cases/` | Front state 9: with the test architect author `test-cases.md`; implement the automation in the connected testing tool, or produce artifacts only. |
|
|
53
53
|
| `skills/yad-connect-repos/` | Connect code repos to the hub (GitHub/GitLab, local-user auth); cache a Repomix pack + **code-map** per repo so the front phases are code-aware. |
|
|
54
|
+
| `skills/yad-connect-learning/` | Connect a learning tool (DeepTutor-first, pluggable) — a CLI subprocess like Repomix; record `.sdlc/learning.json` + an optional grounded knowledge base. |
|
|
55
|
+
| `skills/yad-learn/` | The cross-cutting **learning layer**: tutor any member, at any stage, in the context of what's being built; records a personal, local-only skills log (gitignored, never committed/pushed). Opt-in, never gates. |
|
|
54
56
|
| `skills/yad-review-gate/` | The reusable **team review + approve gate** (used for all five reviews). |
|
|
55
57
|
| `skills/yad-spec/` | Build Step A: run the Spec Kit ceremony once per story per repo → `specs/<story-id>/`. |
|
|
56
58
|
| `skills/yad-implement/` | Build Step B: implement ONE atomic task as a small diff on its own branch. |
|
|
@@ -123,10 +125,10 @@ a manual `yad gate sync` racing CI, or GitLab pipelines — two simultaneous syn
|
|
|
123
125
|
*commits* via the rebase retry but each works from the state it read at start, so the rarer of two
|
|
124
126
|
simultaneous advancements can be lost; the next event or scheduled sweep re-syncs and converges.
|
|
125
127
|
|
|
126
|
-
### What `setup` walks you through (
|
|
128
|
+
### What `setup` walks you through (10 steps)
|
|
127
129
|
|
|
128
130
|
1. **Preflight** — confirm the hub is a git repo (offers `git init`); check `git`/`node`/`npx`.
|
|
129
|
-
2. **Install the module** — copy all
|
|
131
|
+
2. **Install the module** — copy all 22 `yad-*` skills into the IDE skill dirs you pick
|
|
130
132
|
(`.claude/`, `.agents/`, `.zencoder/`, `.opencode/`) and register `_bmad/sdlc/`.
|
|
131
133
|
3. **Hub platform & roster** — detect GitHub/GitLab from the remote; record reviewers → `.sdlc/hub.json`.
|
|
132
134
|
4. **Connect a design tool** — record the design tool (Figma / pencil / none) → `.sdlc/design.json` so
|
|
@@ -134,10 +136,13 @@ simultaneous advancements can be lost; the next event or scheduled sweep re-sync
|
|
|
134
136
|
5. **Connect a testing tool** — record the testing tool (Playwright / cypress / pytest / none) →
|
|
135
137
|
`.sdlc/testing.json` so the test-cases step can implement the automation; the MCP itself is confirmed
|
|
136
138
|
later by `yad-connect-testing`.
|
|
137
|
-
6. **Connect
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
139
|
+
6. **Connect a learning tool** — record the learning tool (DeepTutor / none) → `.sdlc/learning.json` so
|
|
140
|
+
the learning layer can tutor the team; the CLI + knowledge base are confirmed later by
|
|
141
|
+
`yad-connect-learning`.
|
|
142
|
+
7. **Connect code repos** — register each repo into `.sdlc/repos.json` and cache a Repomix pack.
|
|
143
|
+
8. **Wire each repo** — CI gates, PR/MR template, and review-comment scaffold.
|
|
144
|
+
9. **AI review** — optionally write `.coderabbit.yaml`.
|
|
145
|
+
10. **Done** — stamp `.sdlc/cli-version.json` and hand off the AI-only steps (code-maps; first epic).
|
|
141
146
|
|
|
142
147
|
The deterministic file work runs automatically; the AI-only steps are handed to the Claude Code skills
|
|
143
148
|
with a printed next-action. Re-run `… check --fix` any time the workflow updates — it never re-asks for
|
|
@@ -175,10 +180,11 @@ with a fix-it hint per finding. Failures carry stable, greppable codes, also pri
|
|
|
175
180
|
| `YAD-CFG-001` | `hub.json` names an unknown platform | expected `github`, `gitlab`, or `null` — fix it or re-run `yad setup` |
|
|
176
181
|
| `YAD-CFG-002` | `design.json` names an unknown design tool | expected one of `config.yaml` `design.tools` (e.g. `figma`, `pencil`), or `none` — fix it or re-run `yad setup` |
|
|
177
182
|
| `YAD-CFG-003` | `testing.json` names an unknown testing tool | expected one of `config.yaml` `testing.tools` (e.g. `playwright`, `cypress`, `pytest`), or `none` — fix it or re-run `yad setup` |
|
|
183
|
+
| `YAD-CFG-004` | `learning.json` names an unknown learning tool | expected one of `config.yaml` `learning.tools` (e.g. `deeptutor`), or `none` — fix it or re-run `yad setup` |
|
|
178
184
|
|
|
179
185
|
Filing a bug? Attach `yad doctor --json` — it contains no secrets (names, paths, and check results only).
|
|
180
186
|
|
|
181
|
-
## Agent skills (all
|
|
187
|
+
## Agent skills (all 22)
|
|
182
188
|
|
|
183
189
|
The CLI **installs and wires** the module; the skills below are the **agents you invoke by name** in your
|
|
184
190
|
AI IDE (e.g. *“run `yad-epic`”*) to actually do the work. State lives in files you can also edit
|
|
@@ -201,6 +207,25 @@ directly. Each skill stops at a gate and never auto-advances unless a step has *
|
|
|
201
207
|
project/suite references in `.sdlc/testing.json` (local-user / MCP-session auth, no stored tokens),
|
|
202
208
|
detecting the testing-tool MCP and degrading to artifacts-only when absent. Idempotent and
|
|
203
209
|
refreshable; one connection per project.
|
|
210
|
+
- **`yad-connect-learning`** — Connects a learning/tutoring tool (DeepTutor-first, pluggable) so the
|
|
211
|
+
cross-cutting learning layer can tutor any team member in the context of what's being built. Records
|
|
212
|
+
the tool + an optional grounded knowledge base in `.sdlc/learning.json` (local-user auth, no stored
|
|
213
|
+
tokens), detecting the **DeepTutor CLI on PATH** (a subprocess like Repomix — DeepTutor ships no MCP)
|
|
214
|
+
and degrading to **harness-native** tutoring when absent. Idempotent and refreshable; one connection
|
|
215
|
+
per project.
|
|
216
|
+
|
|
217
|
+
### The learning layer (cross-cutting — any member, any stage)
|
|
218
|
+
|
|
219
|
+
- **`yad-learn`** — At **any** SDLC stage, a team member can ask to learn a concept and be tutored *in
|
|
220
|
+
the context of what the team is building* — e.g. *"teach me why the architecture hash-locks the
|
|
221
|
+
contract surface"*. Routes the request to the connected learning tool (`.sdlc/learning.json`,
|
|
222
|
+
DeepTutor-first) grounded in the project knowledge base, or degrades to **harness-native** tutoring
|
|
223
|
+
(the harness model reading the artifacts) when nothing is connected — so it always works. Renders a
|
|
224
|
+
tutorial artifact and appends to a per-member **learning ledger** kept **local-only** (gitignored,
|
|
225
|
+
never committed or pushed — to the hub or any code repo) so it stays a private, personal **skills log**
|
|
226
|
+
(`yad-status` rolls up the local records). **Purely opt-in — it never blocks a gate** and
|
|
227
|
+
never touches epic state, approvals, or the contract lock. *AI builds, the hand decides* — and now the
|
|
228
|
+
hand can also learn, on demand, what it is deciding about.
|
|
204
229
|
|
|
205
230
|
### Front half — author the "thinking" (once per epic, human-gated)
|
|
206
231
|
|
|
@@ -297,17 +322,19 @@ detailed sections below expand every phase. Invoke a skill by name in your agent
|
|
|
297
322
|
|
|
298
323
|
### 0 — One-time setup
|
|
299
324
|
|
|
300
|
-
> **Shortcut:** `npx yadflow setup`
|
|
301
|
-
>
|
|
302
|
-
> `… check --fix` any time afterwards to reconcile. The manual steps below are the
|
|
303
|
-
> equivalent and still work.
|
|
325
|
+
> **Shortcut:** `npx yadflow setup` runs the guided wizard interactively — module install, hub
|
|
326
|
+
> detect + roster, connect a design/testing/learning tool (each optional), connect repos, wire each
|
|
327
|
+
> repo. Run `… check --fix` any time afterwards to reconcile. The manual steps below are the
|
|
328
|
+
> long-hand equivalent and still work.
|
|
304
329
|
|
|
305
330
|
1. **Install the module:** `bash skills/sdlc/install.sh` (re-run after any BMAD update).
|
|
306
331
|
2. **Have your code repo(s).** They are **separate git repos** (one `.git` each). For the demo they
|
|
307
332
|
live under `demo-repos/<repo>/` — regenerate from `demo-repos/README.md`.
|
|
308
333
|
3. **Optional tools** (the workflow degrades gracefully and records it if any are absent): **Spec Kit**
|
|
309
334
|
(`/speckit.*`), **Impeccable** (`/impeccable …`), **Repomix** (`npx repomix`, used by
|
|
310
|
-
`yad-connect-repos` and `yad-backfill`), **CodeRabbit** (advisory AI review)
|
|
335
|
+
`yad-connect-repos` and `yad-backfill`), **CodeRabbit** (advisory AI review), **DeepTutor**
|
|
336
|
+
(`deeptutor`, the learning layer's tutor — degrades to harness-native, used by `yad-connect-learning`
|
|
337
|
+
and `yad-learn`).
|
|
311
338
|
4. **Wire each code repo once:** `yad-checks repo:<repo> action: wire` (installs the CI gates —
|
|
312
339
|
*merges* with any existing CI, never clobbers), `yad-pr-template repo:<repo> action: wire` (PR/MR
|
|
313
340
|
template + risk routing), `yad-review-comments repo:<repo> action: wire` (review-comment scaffold).
|
|
@@ -318,11 +345,16 @@ detailed sections below expand every phase. Invoke a skill by name in your agent
|
|
|
318
345
|
(SSH or credential helper; GitHub or GitLab; no stored tokens). Re-run for any new repo. Freshness is a
|
|
319
346
|
**human decision**: `yad repo list` shows fresh/stale, `yad repo refresh [name]` re-packs a moved repo
|
|
320
347
|
(skills flag staleness and point here — they never silently re-pack). Greenfield → skip it.
|
|
321
|
-
6. **(Optional)
|
|
348
|
+
6. **(Optional) Connect tools** so the matching steps do real work (each degrades gracefully and is
|
|
349
|
+
recorded if absent): `yad-connect-design action: connect` (Figma-first → `design.json`, lets
|
|
350
|
+
`yad-ui` materialize screens), `yad-connect-testing action: connect` (Playwright-first →
|
|
351
|
+
`testing.json`, lets `yad-test-cases` implement automation), `yad-connect-learning action: connect`
|
|
352
|
+
(DeepTutor-first → `learning.json`, powers the cross-cutting learning layer).
|
|
353
|
+
7. **(Optional) Put the hub on a platform** so the front-half review runs through real PRs:
|
|
322
354
|
`yad-connect-repos action: detect-hub`, then `action: roster` once per reviewer (login → SDLC
|
|
323
355
|
name + role), and `yad-pr-template repo:hub action: wire` / `yad-review-comments repo:hub action:
|
|
324
356
|
wire` / `yad-checks repo:hub action: wire`. With no hub platform the front gate just runs file-only.
|
|
325
|
-
|
|
357
|
+
8. **Conventions:** commits and PR/MR titles follow Conventional Commits (lowercase after the type), the
|
|
326
358
|
human author owns each commit with an optional per-commit `Co-Authored-By` AI trailer — see
|
|
327
359
|
[`CONTRIBUTING.md`](CONTRIBUTING.md).
|
|
328
360
|
|
package/cli/doctor.mjs
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import fs from 'node:fs';
|
|
7
7
|
import { c, log, ok, info, warn, fail, hand, run, has, exists, readJSON, readJSONStrict } from './lib.mjs';
|
|
8
|
-
import { VERSION, PROJECT_FILES, DESIGN_TOOLS, TESTING_TOOLS } from './manifest.mjs';
|
|
8
|
+
import { VERSION, PROJECT_FILES, DESIGN_TOOLS, TESTING_TOOLS, LEARNING_TOOLS } from './manifest.mjs';
|
|
9
9
|
import { loadLedger, epicRoot } from './epic-state.mjs';
|
|
10
10
|
import { gitHead } from './setup.mjs';
|
|
11
11
|
import { cliFor } from './platform.mjs';
|
|
@@ -115,6 +115,28 @@ export function projectChecks(checks, root) {
|
|
|
115
115
|
else check(checks, 'testing', 'project', 'warn', `testing: ${testing.tool} recorded but the MCP is not confirmed`, 'run `yad-connect-testing` in Claude Code to detect the MCP');
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
// learning.json: parse + shape + tool + CLI confirmation (absent is the normal harness-native default —
|
|
119
|
+
// pre-feature projects have none, so silence rather than warn when the file does not exist). DeepTutor
|
|
120
|
+
// has no MCP, so `source` is deeptutor-cli (found on PATH) or harness-native (degraded).
|
|
121
|
+
const learningPath = path.join(root, PROJECT_FILES.learningConfig);
|
|
122
|
+
if (exists(learningPath)) {
|
|
123
|
+
let learning = null, learningBroken = false;
|
|
124
|
+
try {
|
|
125
|
+
learning = readJSONStrict(learningPath, null);
|
|
126
|
+
} catch (e) {
|
|
127
|
+
learningBroken = true;
|
|
128
|
+
check(checks, 'learning', 'project', 'fail', `${PROJECT_FILES.learningConfig} does not parse [${e.code || 'YAD-STATE-001'}]`, e.hint || 'fix the JSON or restore it from git');
|
|
129
|
+
}
|
|
130
|
+
if (learningBroken) { /* reported above */ }
|
|
131
|
+
else if (typeof learning !== 'object' || Array.isArray(learning) || learning === null) check(checks, 'learning', 'project', 'fail', `${PROJECT_FILES.learningConfig} has the wrong shape [YAD-STATE-002]`, 'expected a JSON object');
|
|
132
|
+
else if (learning.tool === 'none') check(checks, 'learning', 'project', 'ok', 'learning: harness-native');
|
|
133
|
+
else if (!LEARNING_TOOLS.includes(learning.tool)) check(checks, 'learning', 'project', 'fail', `${PROJECT_FILES.learningConfig}: unknown or missing learning tool '${learning.tool}' [YAD-CFG-004]`, `expected one of ${LEARNING_TOOLS.join(', ')}, or none`);
|
|
134
|
+
else if (learning.source === 'deeptutor-cli') check(checks, 'learning', 'project', 'ok', `learning: ${learning.tool} (${learning.source})`);
|
|
135
|
+
else if (learning.source === 'harness-native') check(checks, 'learning', 'project', 'warn', `learning: ${learning.tool} CLI unavailable — yad-learn tutors harness-native`, 'install the deeptutor CLI, then run `yad-connect-learning` (action: refresh)');
|
|
136
|
+
else if (learning.source == null) check(checks, 'learning', 'project', 'warn', `learning: ${learning.tool} recorded but the CLI is not confirmed`, 'run `yad-connect-learning` in Claude Code to detect the CLI');
|
|
137
|
+
else check(checks, 'learning', 'project', 'fail', `${PROJECT_FILES.learningConfig}: unknown source '${learning.source}' [YAD-STATE-002]`, 'expected deeptutor-cli, harness-native, or null');
|
|
138
|
+
}
|
|
139
|
+
|
|
118
140
|
// repos.json: parse + every entry is a live git repo; staleness vs syncedHead
|
|
119
141
|
let registry = { repos: [] };
|
|
120
142
|
let regBroken = false;
|
package/cli/errors.mjs
CHANGED
|
@@ -22,6 +22,7 @@ export const CODES = {
|
|
|
22
22
|
'YAD-CFG-001': 'hub.json names an unknown platform (expected github, gitlab, or null)',
|
|
23
23
|
'YAD-CFG-002': 'design.json names an unknown design tool (expected one of config.yaml design.tools, or none)',
|
|
24
24
|
'YAD-CFG-003': 'testing.json names an unknown testing tool (expected one of config.yaml testing.tools, or none)',
|
|
25
|
+
'YAD-CFG-004': 'learning.json names an unknown learning tool (expected one of config.yaml learning.tools, or none)',
|
|
25
26
|
};
|
|
26
27
|
|
|
27
28
|
export const err = (code, message, hint) => new YadError(code, message, hint);
|
package/cli/manifest.mjs
CHANGED
|
@@ -10,7 +10,7 @@ import { readFileSync } from 'node:fs';
|
|
|
10
10
|
const { version } = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
|
|
11
11
|
export const VERSION = version;
|
|
12
12
|
|
|
13
|
-
// The
|
|
13
|
+
// The 22 hand-authored yad-* skills (mirrors skills/sdlc/install.sh).
|
|
14
14
|
export const SKILLS = [
|
|
15
15
|
'yad-analysis',
|
|
16
16
|
'yad-epic',
|
|
@@ -21,6 +21,8 @@ export const SKILLS = [
|
|
|
21
21
|
'yad-connect-repos',
|
|
22
22
|
'yad-connect-design',
|
|
23
23
|
'yad-connect-testing',
|
|
24
|
+
'yad-connect-learning',
|
|
25
|
+
'yad-learn',
|
|
24
26
|
'yad-spec',
|
|
25
27
|
'yad-implement',
|
|
26
28
|
'yad-checks',
|
|
@@ -96,12 +98,22 @@ export const DESIGN_PRIMARY = 'figma';
|
|
|
96
98
|
export const TESTING_TOOLS = ['playwright', 'cypress', 'pytest'];
|
|
97
99
|
export const TESTING_PRIMARY = 'playwright';
|
|
98
100
|
|
|
101
|
+
// Supported learning-tool adapters (mirrors skills/sdlc/config.yaml `learning.tools`); `LEARNING_PRIMARY`
|
|
102
|
+
// is the fallback `registerLearning`/setup use when an unknown tool is named, and `none` is the explicit
|
|
103
|
+
// harness-native choice (yad-learn tutors via the harness model when no tool is connected). DeepTutor is
|
|
104
|
+
// a CLI subprocess (no MCP), so the connect skill detects the binary — not an MCP — but the registry +
|
|
105
|
+
// degrade shape mirrors design/testing. (doctor does NOT fall back — an unknown tool there is a hard
|
|
106
|
+
// YAD-CFG-004 fail, mirroring the design-tool YAD-CFG-002.)
|
|
107
|
+
export const LEARNING_TOOLS = ['deeptutor'];
|
|
108
|
+
export const LEARNING_PRIMARY = 'deeptutor';
|
|
109
|
+
|
|
99
110
|
// Project-level files setup produces (used by `check` to spot missing setup).
|
|
100
111
|
export const PROJECT_FILES = {
|
|
101
112
|
reposRegistry: '.sdlc/repos.json',
|
|
102
113
|
hubConfig: '.sdlc/hub.json',
|
|
103
114
|
designConfig: '.sdlc/design.json',
|
|
104
115
|
testingConfig: '.sdlc/testing.json',
|
|
116
|
+
learningConfig: '.sdlc/learning.json',
|
|
105
117
|
version: '.sdlc/cli-version.json',
|
|
106
118
|
};
|
|
107
119
|
|
package/cli/setup.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
c, log, step, ok, info, warn, hand, fail, ask, askYesNo, run, has,
|
|
6
6
|
exists, readJSON, writeJSON,
|
|
7
7
|
} from './lib.mjs';
|
|
8
|
-
import { VERSION, IDE_FOLDER_TARGETS, PROJECT_FILES, DESIGN_TOOLS, DESIGN_PRIMARY, TESTING_TOOLS, TESTING_PRIMARY } from './manifest.mjs';
|
|
8
|
+
import { VERSION, IDE_FOLDER_TARGETS, PROJECT_FILES, DESIGN_TOOLS, DESIGN_PRIMARY, TESTING_TOOLS, TESTING_PRIMARY, LEARNING_TOOLS, LEARNING_PRIMARY } from './manifest.mjs';
|
|
9
9
|
import { moduleActions, repoActions, hubActions, authorsActions } from './plan.mjs';
|
|
10
10
|
|
|
11
11
|
const ALL_IDES = [...IDE_FOLDER_TARGETS, '.opencode'];
|
|
@@ -115,6 +115,34 @@ export function registerTesting(root, { tool, project_url = null, suites = null,
|
|
|
115
115
|
return testing;
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
// Record the project's learning-tool connection into .sdlc/learning.json (the deterministic half of the
|
|
119
|
+
// connect loop; CLI detection + the kb build are AI steps, handed off to `yad-connect-learning`). An
|
|
120
|
+
// unknown tool falls back to the primary adapter rather than being rejected — mirrors registerDesign/
|
|
121
|
+
// registerTesting. `none` is the explicit harness-native choice (yad-learn tutors via the harness model).
|
|
122
|
+
// DeepTutor has no MCP, so `source` stays null at setup until the connect skill detects the CLI on PATH.
|
|
123
|
+
export function registerLearning(root, { tool, kb = null, today = null } = {}) {
|
|
124
|
+
// Idempotent re-connect: carry the original first-connect date forward; only lastSyncedAt moves.
|
|
125
|
+
const learningPath = path.join(root, PROJECT_FILES.learningConfig);
|
|
126
|
+
const prev = readJSON(learningPath, null);
|
|
127
|
+
const connectedAt = prev && prev.connectedAt ? prev.connectedAt : today;
|
|
128
|
+
let t = (tool || '').toLowerCase();
|
|
129
|
+
if (t === 'none' || t === '') {
|
|
130
|
+
const off = { tool: 'none', provider: null, version: null, kb: null, kb_sources: [], auth: 'user',
|
|
131
|
+
connectedAt, lastSyncedAt: today, source: 'harness-native' };
|
|
132
|
+
writeJSON(learningPath, off);
|
|
133
|
+
return off;
|
|
134
|
+
}
|
|
135
|
+
if (!LEARNING_TOOLS.includes(t)) { warn(`unknown learning tool '${tool}' — using ${LEARNING_PRIMARY}`); t = LEARNING_PRIMARY; }
|
|
136
|
+
// source stays null until `yad-connect-learning` detects the CLI on PATH (AI step). doctor reports a
|
|
137
|
+
// recorded-but-unconfirmed connection as a warning pointing at that skill.
|
|
138
|
+
const learning = {
|
|
139
|
+
tool: t, provider: null, version: null, kb: kb || null, kb_sources: [], auth: 'user',
|
|
140
|
+
connectedAt, lastSyncedAt: today, source: null,
|
|
141
|
+
};
|
|
142
|
+
writeJSON(learningPath, learning);
|
|
143
|
+
return learning;
|
|
144
|
+
}
|
|
145
|
+
|
|
118
146
|
function applyActions(actions, { force = false } = {}) {
|
|
119
147
|
let changed = 0;
|
|
120
148
|
for (const a of actions) {
|
|
@@ -128,7 +156,7 @@ function applyActions(actions, { force = false } = {}) {
|
|
|
128
156
|
}
|
|
129
157
|
|
|
130
158
|
export async function runSetup(root, opts = {}) {
|
|
131
|
-
const total =
|
|
159
|
+
const total = 10;
|
|
132
160
|
log(c.bold(`\nSDLC Workflow setup ${c.dim('v' + VERSION)}`));
|
|
133
161
|
log(c.dim(`target: ${root}`));
|
|
134
162
|
|
|
@@ -224,8 +252,25 @@ export async function runSetup(root, opts = {}) {
|
|
|
224
252
|
: `wrote ${PROJECT_FILES.testingConfig} (${tool})`);
|
|
225
253
|
}
|
|
226
254
|
|
|
227
|
-
// 6. Connect
|
|
228
|
-
step(6, total, 'Connect
|
|
255
|
+
// 6. Connect a learning tool (DeepTutor-first, pluggable; the learning layer tutors team members here)
|
|
256
|
+
step(6, total, 'Connect a learning tool (deeptutor / none)');
|
|
257
|
+
const learningPath = path.join(root, PROJECT_FILES.learningConfig);
|
|
258
|
+
if (exists(learningPath) && !(await askYesNo('learning.json exists — reconfigure?', false))) {
|
|
259
|
+
info('keeping existing .sdlc/learning.json');
|
|
260
|
+
} else {
|
|
261
|
+
let tool = (await ask(`Learning tool (${LEARNING_TOOLS.join('/')}/none)`, LEARNING_PRIMARY)).toLowerCase();
|
|
262
|
+
if (![...LEARNING_TOOLS, 'none'].includes(tool)) {
|
|
263
|
+
warn(`unknown learning tool '${tool}' — using ${LEARNING_PRIMARY}`);
|
|
264
|
+
tool = LEARNING_PRIMARY;
|
|
265
|
+
}
|
|
266
|
+
registerLearning(root, { tool, today: opts.today ?? null });
|
|
267
|
+
ok(tool === 'none'
|
|
268
|
+
? `wrote ${PROJECT_FILES.learningConfig} (harness-native)`
|
|
269
|
+
: `wrote ${PROJECT_FILES.learningConfig} (${tool})`);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// 7. Connect code repos
|
|
273
|
+
step(7, total, 'Connect code repos');
|
|
229
274
|
const regPath = path.join(root, PROJECT_FILES.reposRegistry);
|
|
230
275
|
const registry = readJSON(regPath, { repos: [] });
|
|
231
276
|
const known = new Set(registry.repos.map((r) => r.name));
|
|
@@ -248,8 +293,8 @@ export async function runSetup(root, opts = {}) {
|
|
|
248
293
|
}
|
|
249
294
|
}
|
|
250
295
|
|
|
251
|
-
//
|
|
252
|
-
step(
|
|
296
|
+
// 8. Wire each connected repo + the hub itself
|
|
297
|
+
step(8, total, 'Wire connected repos + the hub (CI gates, PR template, comment scaffold, gate-sync)');
|
|
253
298
|
if (registry.repos.length === 0) info('no repos to wire');
|
|
254
299
|
for (const repo of registry.repos) {
|
|
255
300
|
log(` ${c.bold(repo.name)} ${c.dim(`(${repo.platform})`)}`);
|
|
@@ -264,8 +309,8 @@ export async function runSetup(root, opts = {}) {
|
|
|
264
309
|
// author allowlists for the verified-commits gate (hub + every repo), from the roster emails
|
|
265
310
|
applyActions(authorsActions(root, registry.repos), { force: true });
|
|
266
311
|
|
|
267
|
-
//
|
|
268
|
-
step(
|
|
312
|
+
// 9. Optional CodeRabbit
|
|
313
|
+
step(9, total, 'AI review (CodeRabbit)');
|
|
269
314
|
for (const repo of registry.repos) {
|
|
270
315
|
const cr = path.join(path.resolve(root, repo.path), '.coderabbit.yaml');
|
|
271
316
|
if (exists(cr)) { info(`${repo.name}: .coderabbit.yaml present`); continue; }
|
|
@@ -275,8 +320,8 @@ export async function runSetup(root, opts = {}) {
|
|
|
275
320
|
}
|
|
276
321
|
}
|
|
277
322
|
|
|
278
|
-
//
|
|
279
|
-
step(
|
|
323
|
+
// 10. Summary + version stamp
|
|
324
|
+
step(10, total, 'Done');
|
|
280
325
|
writeJSON(path.join(root, PROJECT_FILES.version), { version: VERSION, ideTargets, updatedAt: opts.today ?? null });
|
|
281
326
|
ok(`stamped ${PROJECT_FILES.version} (v${VERSION})`);
|
|
282
327
|
log('');
|
|
@@ -290,6 +335,10 @@ export async function runSetup(root, opts = {}) {
|
|
|
290
335
|
if (testing && testing.tool && testing.tool !== 'none') {
|
|
291
336
|
hand(`confirm the testing tool: run \`yad-connect-testing\` to detect the ${testing.tool} MCP (or it degrades to artifacts-only)`);
|
|
292
337
|
}
|
|
338
|
+
const learning = readJSON(learningPath, null);
|
|
339
|
+
if (learning && learning.tool && learning.tool !== 'none') {
|
|
340
|
+
hand(`confirm the learning tool: run \`yad-connect-learning\` to detect the ${learning.tool} CLI (or it degrades to harness-native)`);
|
|
341
|
+
}
|
|
293
342
|
hand('author your first epic: run `yad-epic`');
|
|
294
343
|
log('');
|
|
295
344
|
log(c.dim('Re-run anytime: `yad check` (report) / `yad check --fix` (reconcile).'));
|
package/docs/index.html
CHANGED
|
@@ -284,7 +284,7 @@
|
|
|
284
284
|
<div class="lane">
|
|
285
285
|
<div class="lane-title">0 · One-time setup (team lead, per project)</div>
|
|
286
286
|
<div class="flow-v">
|
|
287
|
-
<div class="node plain"><strong>Install the module</strong><small><code>npx yadflow setup</code> — copies the
|
|
287
|
+
<div class="node plain"><strong>Install the module</strong><small><code>npx yadflow setup</code> — copies the 22 skills into your IDE dirs</small></div>
|
|
288
288
|
<div class="arrow-v">▼</div>
|
|
289
289
|
<div class="node plain"><strong>Wire each repo</strong><small><code>yad-checks</code> · <code>yad-pr-template</code> · <code>yad-review-comments</code> (CI gates, PR template, comment scaffold)</small></div>
|
|
290
290
|
<div class="arrow-v">▼</div>
|
|
@@ -294,6 +294,8 @@
|
|
|
294
294
|
<div class="arrow-v">▼</div>
|
|
295
295
|
<div class="node plain"><strong>Connect a testing tool</strong><small><code>yad-connect-testing</code> → <code>testing.json</code> (Playwright-first, pluggable) so <code>yad-test-cases</code> can implement the automation <em>(optional — degrades to artifacts-only)</em></small></div>
|
|
296
296
|
<div class="arrow-v">▼</div>
|
|
297
|
+
<div class="node plain"><strong>Connect a learning tool</strong><small><code>yad-connect-learning</code> → <code>learning.json</code> (DeepTutor-first, pluggable) so the learning layer can tutor in context <em>(optional — degrades to harness-native)</em></small></div>
|
|
298
|
+
<div class="arrow-v">▼</div>
|
|
297
299
|
<div class="node plain"><strong>Optional: hub on a platform</strong><small>detect GitHub/GitLab + reviewer roster, so reviews run on real PRs/MRs</small></div>
|
|
298
300
|
</div>
|
|
299
301
|
</div>
|
|
@@ -445,7 +447,7 @@ each code repo/
|
|
|
445
447
|
<div class="term"><strong>State machine</strong><span class="badge b-core">core</span><br>The core design: the workflow is a fixed set of <em>states</em> (steps). Each state does its work and waits at a gate. The states never change — only the <em>trigger</em> (who moves work forward) changes. That is what lets the team start fully manual and automate gradually without rebuilding anything.</div>
|
|
446
448
|
<div class="term"><strong>Product hub (product repo)</strong><span class="badge b-core">core</span><br>The git repo that holds the shared “thinking”: epics, architecture, the contract, UI design, stories, reviews and all state. The brain of the project. Code never lives here.</div>
|
|
447
449
|
<div class="term"><strong>Code repo</strong><span class="badge b-core">core</span><br>A separate git repo holding real application code (e.g. backend, mobile, dashboard). Each story’s spec lives inside the code repo it belongs to, with a link back to the story in the hub.</div>
|
|
448
|
-
<div class="term"><strong>Skills source (this repo)</strong><span class="badge b-core">core</span><br>The <code>yadflow</code> repo itself — where the
|
|
450
|
+
<div class="term"><strong>Skills source (this repo)</strong><span class="badge b-core">core</span><br>The <code>yadflow</code> repo itself — where the 22 skills live and where you pull updates from. No real product work happens inside it.</div>
|
|
449
451
|
<div class="term"><strong>Front half (“decide” / the brain)</strong><span class="badge b-core">core</span><br>The first half of the workflow, run once per epic in the product hub: analysis (optional) → epic → architecture + contract → UI design → stories — each followed by a human review gate, ending at <code>ready-for-build</code>. <strong>Test cases</strong> is a parallel, non-blocking track that opens at the stories gate and runs alongside the build half. Permanently human-approved.</div>
|
|
450
452
|
<div class="term"><strong>Back half / build half (“build”)</strong><span class="badge b-core">core</span><br>The second half, run once per story per code repo, inside that repo: spec → implement → checks → PR → ship. These mechanical steps may earn automation over time.</div>
|
|
451
453
|
<div class="term"><strong>Gate</strong><span class="badge b-core">core</span><br>A stopping point after a step. The step writes its output and <em>waits</em>; a human must approve before the workflow moves on. “Every step stops at a gate” is the heart of the whole system.</div>
|
|
@@ -536,7 +538,7 @@ each code repo/
|
|
|
536
538
|
<div class="term"><strong>CodeRabbit</strong><span class="badge b-tool">tools</span><br>An AI code-review service used as the advisory first pass on PRs. Optional; never the merge authority.</div>
|
|
537
539
|
<div class="term"><strong>Graceful degradation</strong><span class="badge b-tool">tools</span><br>The rule that every optional tool (Spec Kit, Impeccable, Repomix, CodeRabbit) can be absent: the workflow falls back to doing the work directly and <em>records</em> that the tool was missing. You can start with none of them.</div>
|
|
538
540
|
<div class="term"><strong>Tool-agnostic rule</strong><span class="badge b-tool">tools</span><br>Talk to every tool through its commands and files, never through its internal code — so each tool stays swappable.</div>
|
|
539
|
-
<div class="term"><strong>Skill</strong><span class="badge b-tool">tools</span><br>One of the
|
|
541
|
+
<div class="term"><strong>Skill</strong><span class="badge b-tool">tools</span><br>One of the 22 named agents (e.g. <code>yad-epic</code>) you invoke by name in your AI IDE. Each skill does one step’s work, writes files, and stops at its gate.</div>
|
|
540
542
|
<div class="term"><strong>The <code>yad</code> CLI</strong><span class="badge b-tool">tools</span><br>A zero-dependency command-line tool (npm: <code>yadflow</code>) that installs, wires and reconciles the workflow (<code>setup</code>, <code>check --fix</code>, <code>update</code>) and runs the deterministic pieces (<code>gate</code>, <code>commit</code>, <code>open-pr</code>, <code>repo</code>).</div>
|
|
541
543
|
|
|
542
544
|
<h3>People & AI roles</h3>
|
|
@@ -679,7 +681,7 @@ each code repo/
|
|
|
679
681
|
|
|
680
682
|
<!-- ======================================================= -->
|
|
681
683
|
<section id="skills">
|
|
682
|
-
<h2>6. The
|
|
684
|
+
<h2>6. The 22 skills — what each does, how to use it, and when</h2>
|
|
683
685
|
<p>A <strong>skill</strong> is an agent you invoke <em>by name</em> in your AI IDE — you just ask in
|
|
684
686
|
plain words, e.g. <em>“run <code>yad-epic</code>”</em>, adding any inputs the skill needs
|
|
685
687
|
(<code>repo: backend</code>, <code>story: EP-…-S01</code>, <code>action: wire</code>, …).
|
|
@@ -747,6 +749,29 @@ yad-connect-testing action: disconnect</code></pre>
|
|
|
747
749
|
<div class="row"><span class="lbl lbl-when">When</span> During one-time setup (the wizard records it), and again any time you switch testing tools. <strong>No testing tool? Skip it</strong> — <code>yad-test-cases</code> simply authors the test cases, exactly as before.</div>
|
|
748
750
|
</div>
|
|
749
751
|
|
|
752
|
+
<div class="skillcard" id="sk-connect-learning">
|
|
753
|
+
<h4><code>yad-connect-learning</code></h4>
|
|
754
|
+
<div class="row"><span class="lbl lbl-what">What</span> Connects a <strong>learning/tutoring tool</strong> to the product hub so the cross-cutting <strong>learning layer</strong> can tutor any team member, at any stage, in the context of what's being built. <strong>DeepTutor-first but pluggable.</strong> Unlike the design/testing tools, DeepTutor is a <strong>CLI subprocess</strong> (like Repomix's <code>npx</code>) — it ships no MCP — so this skill detects the <code>deeptutor</code> binary on PATH and optionally builds a project knowledge base from the SDLC artifacts + secret-scanned code-maps. It records the connection in <code>learning.json</code> — <strong>no tokens are ever stored</strong> — and degrades to <strong>harness-native</strong> tutoring when DeepTutor isn't installed.</div>
|
|
755
|
+
<div class="row"><span class="lbl lbl-how">How</span> Run it in the product hub, once per project:</div>
|
|
756
|
+
<pre><code>yad-connect-learning action: connect tool: deeptutor
|
|
757
|
+
yad-connect-learning action: list # show the connection + whether the CLI is available
|
|
758
|
+
yad-connect-learning action: refresh # re-detect the CLI + rebuild the knowledge base
|
|
759
|
+
yad-connect-learning action: disconnect</code></pre>
|
|
760
|
+
<div class="row"><span class="lbl lbl-when">When</span> During one-time setup (the wizard records it), and again any time you switch learning tools. <strong>No DeepTutor? Skip it</strong> — <code>yad-learn</code> still tutors using the harness model reading your artifacts.</div>
|
|
761
|
+
</div>
|
|
762
|
+
|
|
763
|
+
<h3>The learning layer — tutor any member, any stage (cross-cutting)</h3>
|
|
764
|
+
|
|
765
|
+
<div class="skillcard" id="sk-learn">
|
|
766
|
+
<h4><code>yad-learn</code></h4>
|
|
767
|
+
<div class="row"><span class="lbl lbl-what">What</span> The <strong>learning layer</strong>. At <em>any</em> SDLC stage a team member can ask to learn a concept and be tutored <em>in the context of what the team is building</em> — e.g. "teach me why the architecture hash-locks the contract surface." It routes to the connected learning tool (DeepTutor, grounded in the project knowledge base) or degrades to <strong>harness-native</strong> tutoring, renders a tutorial artifact, and appends to a per-member <strong>learning ledger</strong> kept <strong>local-only</strong> (gitignored — never committed or pushed, to the hub or any code repo) so it stays a private, personal skills log (<code>yad-status</code> rolls up the local records). <strong>Purely opt-in — it never blocks a gate</strong> and never touches epic state, approvals, or the contract lock.</div>
|
|
768
|
+
<div class="row"><span class="lbl lbl-how">How</span> Any time, from any stage:</div>
|
|
769
|
+
<pre><code>run yad-learn — concept: "contract versioning" epic: EP-istifta-inquiries stage: architecture-review
|
|
770
|
+
yad-learn action: list # your local skills-log records for this epic
|
|
771
|
+
yad-learn action: complete concept: "contract versioning" # mark it learned</code></pre>
|
|
772
|
+
<div class="row"><span class="lbl lbl-when">When</span> Whenever a member wants to understand what is being built — to review a gate with confidence, onboard onto a domain, or grow a skill. It is additive and reversible: learning never gates the work.</div>
|
|
773
|
+
</div>
|
|
774
|
+
|
|
750
775
|
<h3>Front half — author the thinking (in the product hub)</h3>
|
|
751
776
|
|
|
752
777
|
<div class="skillcard" id="sk-analysis">
|
|
@@ -923,7 +948,7 @@ yad-status EP-istifta-inquiries # one epic in detail</code></pre>
|
|
|
923
948
|
|
|
924
949
|
<div class="skillcard">
|
|
925
950
|
<h4><code>npx yadflow setup</code></h4>
|
|
926
|
-
<div class="row"><span class="lbl lbl-what">What</span> The guided first-run wizard.
|
|
951
|
+
<div class="row"><span class="lbl lbl-what">What</span> The guided first-run wizard. Ten steps: preflight (git/node check), install all 22 skills into the IDE dirs you pick, detect the hub’s platform + record the reviewer roster, connect a design tool (Figma-first; optional), connect a testing tool (Playwright-first; optional), connect a learning tool (DeepTutor-first; optional), connect your code repos, wire each one (CI gates, PR template, comment scaffold), optionally write the AI-review config, and stamp the installed version.</div>
|
|
927
952
|
<div class="row"><span class="lbl lbl-how">How</span></div>
|
|
928
953
|
<pre><code>cd <product-hub-repo>
|
|
929
954
|
npx yadflow setup</code></pre>
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yadflow",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "Yadflow — the gated, team, multi-repo SDLC: author → review → build with a PR-driven review gate and a zero-dependency `yad` CLI (setup, gate, commit, open-pr, repo). A BMAD module +
|
|
3
|
+
"version": "2.4.0",
|
|
4
|
+
"description": "Yadflow — the gated, team, multi-repo SDLC: author → review → build with a PR-driven review gate and a zero-dependency `yad` CLI (setup, gate, commit, open-pr, repo). A BMAD module + 22 yad-* skills.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "AbdelRahman Nasr",
|
|
7
7
|
"license": "MIT",
|
|
@@ -50,7 +50,9 @@
|
|
|
50
50
|
"bmad",
|
|
51
51
|
"workflow",
|
|
52
52
|
"cli",
|
|
53
|
-
"spec-driven-development"
|
|
53
|
+
"spec-driven-development",
|
|
54
|
+
"learning",
|
|
55
|
+
"deeptutor"
|
|
54
56
|
],
|
|
55
57
|
"devDependencies": {
|
|
56
58
|
"@eslint/js": "^9.39.4",
|
package/skills/sdlc/config.yaml
CHANGED
|
@@ -150,6 +150,27 @@ testing:
|
|
|
150
150
|
# NO tokens in the registry (project_url/suites are plain references, never credentials).
|
|
151
151
|
auth: user
|
|
152
152
|
|
|
153
|
+
# Learning tool (yad-connect-learning) — the cross-cutting LEARNING LAYER. At any SDLC stage a team member
|
|
154
|
+
# can invoke `yad-learn` to be tutored on a concept IN THE CONTEXT of what is being built, and the request
|
|
155
|
+
# is recorded in a personal, LOCAL-ONLY skills log (gitignored, never committed/pushed; surfaced read-only
|
|
156
|
+
# by yad-status for the local learner). The tool is
|
|
157
|
+
# DeepTutor (https://github.com/HKUDS/DeepTutor) — an Apache-2.0 Python CLI, reached as a SUBPROCESS like
|
|
158
|
+
# Repomix's `npx` (it has NO MCP), NOT the MCP shape of the design/testing tools. DeepTutor-first but
|
|
159
|
+
# PLUGGABLE: a learning-tool adapter. Connection is one-per-project, recorded at setup; the per-epic,
|
|
160
|
+
# per-member learning ledger (learning-records.json) + rendered tutorials are written by yad-learn.
|
|
161
|
+
learning:
|
|
162
|
+
registry: "{project-root}/.sdlc/learning.json" # project-wide learning connection (NOT per-epic) — the ONLY committed learning file (no secrets/personal data)
|
|
163
|
+
tools: [deeptutor] # supported adapters; an unknown tool falls back to `primary`
|
|
164
|
+
primary: deeptutor # the default/named provider
|
|
165
|
+
degrade: harness-native # no deeptutor CLI => yad-learn tutors via the harness model
|
|
166
|
+
# reading the project artifacts directly (always works, never blocks)
|
|
167
|
+
records: "{project-root}/epics/EP-<slug>/.sdlc/learning-records.json" # per-epic learning ledger (yad-learn) — LOCAL-ONLY, gitignored, never committed/pushed
|
|
168
|
+
artifacts: "{project-root}/epics/EP-<slug>/learning/" # rendered tutorial markdown (yad-learn) — LOCAL-ONLY, gitignored, never committed/pushed
|
|
169
|
+
capabilities: { explain: chat, deep: deep_research, quiz: deep_question } # yad-learn mode -> deeptutor capability
|
|
170
|
+
# Auth: `yad-connect-learning` uses the LOCAL user's own deeptutor CLI config/session and stores NO
|
|
171
|
+
# tokens in the registry (kb name + sources are plain references, never credentials). Opt-in, never a gate.
|
|
172
|
+
auth: user
|
|
173
|
+
|
|
153
174
|
# Hub platform + front-half review bridge (yad-connect-repos `detect-hub`; yad-review-gate + yad-hub-bridge).
|
|
154
175
|
# The product hub is itself a git repo on a platform. With the bridge enabled, the front-half review/
|
|
155
176
|
# comment/approval cycle runs through a real PR/MR on the hub: a review PR is opened per artifact, reviewers
|
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-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)
|
|
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-connect-learning yad-learn 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,4 +1,5 @@
|
|
|
1
1
|
module,skill,display-name,menu-code,description,action,args,phase,preceded-by,followed-by,required,output-location,outputs
|
|
2
|
+
SDLC Workflow,yad-analysis,Author Analysis,AN,"Optional front state: 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 chain that puts analysis before epic). If skipped, the epic step does this shaping inline. Never auto-advances.",,{idea: one-line feature idea},1-front,,yad-review-gate,false,epics/EP-<slug>/,analysis.md state.json
|
|
2
3
|
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
4
|
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
5
|
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
|
|
@@ -8,6 +9,8 @@ SDLC Workflow,yad-test-cases,Author Test Cases,TC,"Front state 9 (PARALLEL, non-
|
|
|
8
9
|
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
|
|
9
10
|
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
11
|
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
|
|
12
|
+
SDLC Workflow,yad-connect-learning,Connect Learning Tool,CL,"Setup/maintenance: connect a learning/tutoring tool (DeepTutor-first, pluggable) so the cross-cutting learning layer can tutor any team member, at any SDLC stage, in the context of what is being built. Records the tool + an optional grounded knowledge base in .sdlc/learning.json (local-user auth, no stored tokens), detecting whether the DeepTutor CLI is on PATH (a subprocess like Repomix, not an MCP) and degrading to harness-native tutoring 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: deeptutor|none} {kb: <name>} {ground: true|false},0-setup,,yad-learn,false,.sdlc/,learning.json
|
|
13
|
+
SDLC Workflow,yad-learn,Learn (Tutor),LN,"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 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). Renders a tutorial artifact and appends to a per-member learning ledger kept LOCAL-ONLY (gitignored, never committed/pushed to the hub or any code repo) so it stays a private, personal skills log (yad-status rolls up the local records). Purely opt-in — never blocks a gate, never touches epic state, approvals, or the contract lock.",,{concept: <idea>} {context: <focus>} {epic: EP-<slug>} {stage: <sdlc stage>} {member: <who>} {mode: explain|deep|quiz} {action: learn|list|complete},,,,,false,epics/EP-<slug>/,learning-records.json learning/<member>--<concept>.md
|
|
11
14
|
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
|
|
12
15
|
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
|
|
13
16
|
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
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: yad-connect-learning
|
|
3
|
+
description: 'Connects a learning/tutoring tool (DeepTutor, or another tool — pluggable) to the product hub so the cross-cutting learning layer can tutor any team member, at any SDLC stage, in the context of what is being built. Registers the tool into the project-wide .sdlc/learning.json (local-user auth, no stored tokens), detecting whether the DeepTutor CLI is on PATH and degrading to harness-native tutoring (the harness model reading project artifacts) when it is not. Optionally builds a project knowledge base from the SDLC artifacts + secret-scanned code-maps so tutoring is grounded. Run at setup or any time the learning tool changes. Reusable, idempotent, refreshable. Use when the user says "connect DeepTutor", "connect a learning tool", "refresh the learning connection", or "list the learning connection".'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SDLC — Connect a Learning Tool (the cross-cutting learning layer)
|
|
7
|
+
|
|
8
|
+
**Goal:** Let any team member pause at **any** SDLC stage and ask to learn a concept — and get tutored
|
|
9
|
+
*in the context of what the team is actually building*. This skill **connects** a learning tool such as
|
|
10
|
+
**DeepTutor** to the product hub and records *how* to reach it (the tool, the CLI, an optional grounded
|
|
11
|
+
knowledge base) — never a credential. The consumer skill **`yad-learn`** does the tutoring per request
|
|
12
|
+
and records the team's skills.
|
|
13
|
+
|
|
14
|
+
This is **setup/maintenance**, not a gated state — it never touches `.sdlc/state.json` or any epic's
|
|
15
|
+
approvals. It only writes the project-wide learning registry. `yad-learn` consumes it: when DeepTutor is
|
|
16
|
+
available it drives the CLI (grounded in the knowledge base); when nothing is connected, `yad-learn`
|
|
17
|
+
degrades to **harness-native** tutoring — the harness model reads the project artifacts directly and
|
|
18
|
+
explains the concept. The learning layer is **purely opt-in and never blocks a gate**.
|
|
19
|
+
|
|
20
|
+
## Conventions
|
|
21
|
+
|
|
22
|
+
- `{project-root}` resolves from the project working directory (the **product hub**).
|
|
23
|
+
- The integration is **DeepTutor-first but pluggable** (`config.yaml` `learning.tools`): a learning-tool
|
|
24
|
+
*adapter*, like the design/testing adapters. `none` → harness-native (yad-learn still tutors via the
|
|
25
|
+
harness model).
|
|
26
|
+
- **DeepTutor is reached as a CLI SUBPROCESS** (`deeptutor …`), the same shape as Repomix's `npx` — NOT
|
|
27
|
+
an MCP like the design/testing tools (DeepTutor ships no MCP server). The skill detects the **binary on
|
|
28
|
+
PATH** and degrades when it is absent; it never installs DeepTutor.
|
|
29
|
+
- Registry: `{project-root}/.sdlc/learning.json` (project-wide, shared across all epics — NOT per-epic),
|
|
30
|
+
the sibling of `.sdlc/repos.json`, `.sdlc/hub.json`, `.sdlc/design.json`, and `.sdlc/testing.json`.
|
|
31
|
+
- Per-epic, per-member learning records + rendered tutorials are written later by `yad-learn`
|
|
32
|
+
(`epics/EP-<slug>/.sdlc/learning-records.json` and `epics/EP-<slug>/learning/`), not here.
|
|
33
|
+
- Speak in the configured `communication_language`; write documents in `document_output_language`.
|
|
34
|
+
|
|
35
|
+
## Inputs
|
|
36
|
+
|
|
37
|
+
- `action` — `connect` (default) | `refresh` | `list` | `disconnect`.
|
|
38
|
+
- `tool` — `deeptutor` | another adapter id (`config.yaml` `learning.tools`). `none` records a deliberate
|
|
39
|
+
harness-native project.
|
|
40
|
+
- `kb` — optional knowledge-base name (default `yadflow-<project-slug>`). The DeepTutor kb that grounds
|
|
41
|
+
tutoring in this project.
|
|
42
|
+
- `ground` — `true` (default) | `false`. When `true` and DeepTutor is available, build/refresh the
|
|
43
|
+
knowledge base from the SDLC artifacts + code-maps (the "grounded in the project" piece).
|
|
44
|
+
|
|
45
|
+
## On Activation
|
|
46
|
+
|
|
47
|
+
### Step 1 — Resolve the tool and detect the CLI (the learning-tool adapter)
|
|
48
|
+
Determine which tool is being connected from `tool` (default `deeptutor`); reject a `tool` not in
|
|
49
|
+
`config.yaml` `learning.tools` (fall back to the configured `learning.primary` with a warning, the same
|
|
50
|
+
way `registerRepo`/`registerDesign` fall back). Then **detect the tool's CLI on PATH**:
|
|
51
|
+
|
|
52
|
+
- **deeptutor** → run a best-effort `deeptutor --version` (or `deeptutor config show`). If it succeeds,
|
|
53
|
+
record `provider: "deeptutor-cli"` and the reported `version`.
|
|
54
|
+
- another adapter → its named CLI.
|
|
55
|
+
|
|
56
|
+
**Auth is the local user's own** — DeepTutor's own config (`deeptutor init`, `data/user/settings/`) and
|
|
57
|
+
the user's LLM provider keys. The skill **stores no tokens**; `kb`/`kb_sources` are plain references.
|
|
58
|
+
|
|
59
|
+
**Graceful degradation:** if the `deeptutor` binary is not on PATH, record `source: "harness-native"`
|
|
60
|
+
and report that `yad-learn` will still tutor **using the harness model reading the project artifacts**
|
|
61
|
+
(no error — the learning layer is additive and always works; DeepTutor only adds knowledge-base
|
|
62
|
+
grounding, quizzes, and deep research). Do **not** install DeepTutor as part of this step.
|
|
63
|
+
|
|
64
|
+
### Step 2 — Ground it in the project (optional, when DeepTutor is available)
|
|
65
|
+
When `ground: true` and DeepTutor is available, build or refresh a project **knowledge base** so tutoring
|
|
66
|
+
quotes what is actually being built:
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
deeptutor kb create <kb> # idempotent: reuse if it exists
|
|
70
|
+
deeptutor kb add <kb> --doc <path> # per source below
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Add only **already-committed** artifacts + the **secret-scanned code-maps** (never raw repos): each
|
|
74
|
+
epic's `epic.md`, `architecture.md`, `contract.md`, `ui-design.md`, the `stories/` files, and every
|
|
75
|
+
`.sdlc/code-context/<repo>/code-map.md`. Record the kb name and the source globs in the registry. Skip
|
|
76
|
+
silently (record `kb: null`) when there are no artifacts yet (greenfield-safe).
|
|
77
|
+
|
|
78
|
+
### Step 3 — Record the connection in the registry
|
|
79
|
+
Upsert into `{project-root}/.sdlc/learning.json` (create the file + parent `.sdlc/` if absent):
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"tool": "deeptutor",
|
|
84
|
+
"provider": "deeptutor-cli",
|
|
85
|
+
"version": "1.4.5",
|
|
86
|
+
"kb": "yadflow-<project-slug>",
|
|
87
|
+
"kb_sources": ["epic.md", "architecture.md", "contract.md", "ui-design.md", "stories/", "code-context/*/code-map.md"],
|
|
88
|
+
"auth": "user",
|
|
89
|
+
"connectedAt": "<YYYY-MM-DD>",
|
|
90
|
+
"lastSyncedAt": "<YYYY-MM-DD>",
|
|
91
|
+
"source": "deeptutor-cli"
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
- `tool: "none"` records a deliberate harness-native project: `{ "tool": "none", "provider": null,
|
|
96
|
+
"kb": null, "source": "harness-native", ... }`.
|
|
97
|
+
- A DeepTutor connection whose CLI is absent records `{ "tool": "deeptutor", "provider": null,
|
|
98
|
+
"kb": null, "source": "harness-native", ... }` until a `refresh` finds the binary.
|
|
99
|
+
- `connect` is **idempotent** — re-running it overwrites the single connection in place; the original
|
|
100
|
+
`connectedAt` is preserved and only `lastSyncedAt` moves.
|
|
101
|
+
|
|
102
|
+
### Step 4 — Report (never auto-advance)
|
|
103
|
+
Report the connected `tool`, its `provider`, whether the CLI is available (or that `yad-learn` will run
|
|
104
|
+
harness-native), the `kb`, and that **`yad-learn` will now tutor team members on request**. Nothing
|
|
105
|
+
auto-advances; this is setup.
|
|
106
|
+
|
|
107
|
+
## Other actions
|
|
108
|
+
|
|
109
|
+
- **`refresh`** — re-detect the CLI, rebuild the knowledge base from the latest artifacts, and update
|
|
110
|
+
`lastSyncedAt`. Same machinery as `connect`. Re-detection may flip `source` between `deeptutor-cli` and
|
|
111
|
+
`harness-native` — report the change.
|
|
112
|
+
- **`list`** — print the current connection: `tool`, `provider`, `version`, the `kb`, and an
|
|
113
|
+
**available/harness-native** flag for the CLI (best-effort). No learning tool connected ⇒
|
|
114
|
+
"harness-native".
|
|
115
|
+
- **`disconnect`** — remove the registry file (or set `tool: "none"`). DeepTutor's own config and
|
|
116
|
+
knowledge bases are **never touched** — only the hub's record of them.
|
|
117
|
+
|
|
118
|
+
## Hard rules
|
|
119
|
+
|
|
120
|
+
- **Local-user auth only; store no tokens.** Connect through the user's own DeepTutor config / LLM keys;
|
|
121
|
+
never embed a key or any credential in the registry. `kb`/`kb_sources` are plain references.
|
|
122
|
+
- **Degrade gracefully.** No DeepTutor CLI → `yad-learn` tutors harness-native with no error. The
|
|
123
|
+
learning layer is additive and always works — never a blocker.
|
|
124
|
+
- **Setup, not a gate.** Never touch `.sdlc/state.json`, approvals, or the contract lock from here.
|
|
125
|
+
- **Idempotent + refreshable.** `connect`/`refresh` are safe to re-run; a project carries one learning
|
|
126
|
+
connection at a time.
|
|
127
|
+
- **Ground only committed, secret-scanned sources.** Feed the knowledge base from committed SDLC
|
|
128
|
+
artifacts + the already-scanned code-maps — never raw repository contents.
|
|
129
|
+
- **Describe the connection; do not tutor here.** This skill records *how to reach* the tool. The actual
|
|
130
|
+
tutoring + the personal, local-only learning records are produced by `yad-learn`, per request.
|
|
131
|
+
- **The registry is the only committed learning file.** `.sdlc/learning.json` is shared, reviewable
|
|
132
|
+
config (no secrets, no personal data). The records ledger and tutorials `yad-learn` writes are
|
|
133
|
+
local-only — gitignored, never committed or pushed.
|
|
134
|
+
|
|
135
|
+
## Reference
|
|
136
|
+
- Registry schema + freshness rule: `references/learning-registry.md`.
|
|
137
|
+
- CLI detection, the knowledge-base build recipe, the mode→capability map, and the harness-native degrade
|
|
138
|
+
path: `references/learning-context.md`.
|
|
139
|
+
- The connect pattern this mirrors (testing tool): `../yad-connect-testing/SKILL.md`.
|
|
140
|
+
- The consumer — how `yad-learn` tutors and writes `learning-records.json`: `../yad-learn/SKILL.md`.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Learning context — CLI detection, knowledge-base build, capability map, degrade path
|
|
2
|
+
|
|
3
|
+
How `yad-connect-learning` reaches DeepTutor, grounds it in the project, and how `yad-learn` consumes the
|
|
4
|
+
connection. DeepTutor is a **CLI subprocess** (Apache-2.0, `pip install -U deeptutor`) — it ships **no
|
|
5
|
+
MCP server**, so this adapter detects a **binary on PATH**, the same shape as Repomix's `npx` in
|
|
6
|
+
`yad-connect-repos`/`yad-backfill`, not the MCP shape of the design/testing tools.
|
|
7
|
+
|
|
8
|
+
## CLI detection
|
|
9
|
+
|
|
10
|
+
Best-effort, never fatal:
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
deeptutor --version # success => provider: "deeptutor-cli", capture the version
|
|
14
|
+
deeptutor config show # fallback probe if --version is unavailable
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
- Binary found → `source: "deeptutor-cli"`.
|
|
18
|
+
- Binary absent → `source: "harness-native"` (no error). Report that `yad-learn` will tutor via the
|
|
19
|
+
harness model reading the project artifacts.
|
|
20
|
+
|
|
21
|
+
DeepTutor's own setup (`deeptutor init`, LLM provider keys under `data/user/settings/`) is the **user's**
|
|
22
|
+
responsibility and lives outside this repo. The skill never runs `deeptutor init` and never writes keys.
|
|
23
|
+
|
|
24
|
+
## Knowledge-base build (grounding)
|
|
25
|
+
|
|
26
|
+
When `ground: true` and the CLI is present, build/refresh a project knowledge base so tutoring quotes
|
|
27
|
+
what is actually being built:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
deeptutor kb create <kb> # idempotent — reuse if it already exists
|
|
31
|
+
deeptutor kb add <kb> --doc <path> # once per source path below
|
|
32
|
+
deeptutor kb list # verify
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Ingest only **committed, secret-scanned** sources (never raw repos):
|
|
36
|
+
|
|
37
|
+
- Per epic under `epics/EP-<slug>/`: `epic.md`, `architecture.md`, `contract.md`, `ui-design.md`, and the
|
|
38
|
+
`stories/*.md` files.
|
|
39
|
+
- Per connected repo: `.sdlc/code-context/<repo>/code-map.md` (already secret-scanned by
|
|
40
|
+
`yad-connect-repos`). Do **not** add `pack.md` or the raw repo.
|
|
41
|
+
|
|
42
|
+
Record `kb` and `kb_sources` in the registry. If there are no artifacts yet (greenfield), skip and record
|
|
43
|
+
`kb: null` — `yad-learn` falls back to passing context inline.
|
|
44
|
+
|
|
45
|
+
## Mode → capability map (consumed by `yad-learn`)
|
|
46
|
+
|
|
47
|
+
`config.yaml` `learning.capabilities` maps a `yad-learn` mode to a DeepTutor capability:
|
|
48
|
+
|
|
49
|
+
| `yad-learn` mode | DeepTutor capability | use |
|
|
50
|
+
|------------------|----------------------|-----|
|
|
51
|
+
| `explain` (default) | `chat` | a focused, grounded explanation of the concept |
|
|
52
|
+
| `deep` | `deep_research` | a deeper, multi-source dive |
|
|
53
|
+
| `quiz` | `deep_question` | generate questions to confirm comprehension (records a signal) |
|
|
54
|
+
|
|
55
|
+
`yad-learn` invokes:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
deeptutor run <capability> "<concept> — in the context of <scoped artifact/stage>" \
|
|
59
|
+
--kb <kb> --format json
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`--format json` streams **NDJSON** — one event per line with a `type` (`content` | `tool_call` |
|
|
63
|
+
`tool_result` | `done`) and a `session_id`. `yad-learn` concatenates `content` events into the tutorial
|
|
64
|
+
and captures `session_id` from the `done` event for the learning record.
|
|
65
|
+
|
|
66
|
+
## Degrade path (harness-native)
|
|
67
|
+
|
|
68
|
+
When `source: "harness-native"` (no CLI, or `tool: "none"`), `yad-learn` does **not** fail. It tutors
|
|
69
|
+
using the **harness model itself**: it reads the scoped epic's `epic.md` / `architecture.md` /
|
|
70
|
+
`contract.md` / code-maps and explains the concept grounded in them. The local-only learning record is
|
|
71
|
+
written identically (with `"tool": "harness-native"`), so the learning layer always works and always
|
|
72
|
+
records — DeepTutor only adds knowledge-base grounding, deep research, and quizzes.
|
|
73
|
+
|
|
74
|
+
## Freshness
|
|
75
|
+
|
|
76
|
+
Like the code-context cache, the knowledge base can drift from the artifacts. `refresh` rebuilds it from
|
|
77
|
+
the current committed artifacts and moves `lastSyncedAt`. Rebuilding is a human decision (run `connect`/
|
|
78
|
+
`refresh`); `yad-learn` never silently rebuilds the kb mid-tutorial — at most it notes the kb may be
|
|
79
|
+
stale and proceeds.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Learning registry — schema + freshness rule
|
|
2
|
+
|
|
3
|
+
The registry is the product hub's record of which learning tool is connected and how to reach it. It is
|
|
4
|
+
**project-wide** (one learning 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/learning.json`
|
|
10
|
+
|
|
11
|
+
(`config.yaml` `learning.registry`.) Create the file and its parent `.sdlc/` on the first `connect`.
|
|
12
|
+
|
|
13
|
+
## Schema
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"tool": "deeptutor", // deeptutor | <adapter id> | none (harness-native)
|
|
18
|
+
"provider": "deeptutor-cli", // the concrete CLI: deeptutor-cli | null
|
|
19
|
+
"version": "1.4.5", // CLI version reported at detect time; null if absent
|
|
20
|
+
"kb": "yadflow-istifta", // grounded knowledge-base name; null if not built
|
|
21
|
+
"kb_sources": ["epic.md", "architecture.md", "contract.md", "ui-design.md", "stories/", "code-context/*/code-map.md"],
|
|
22
|
+
"auth": "user", // ALWAYS the user's own DeepTutor config / LLM keys — never a token
|
|
23
|
+
"connectedAt": "2026-06-14", // first connect (YYYY-MM-DD)
|
|
24
|
+
"lastSyncedAt": "2026-06-14", // last connect/refresh
|
|
25
|
+
"source": "deeptutor-cli" // deeptutor-cli (CLI on PATH) | harness-native (degraded)
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Rules
|
|
30
|
+
|
|
31
|
+
- **`tool`** selects the adapter; it MUST be one of `config.yaml` `learning.tools` (or `none`). At
|
|
32
|
+
**connect** time an unknown tool is normalized to `learning.primary` with a warning (so the registry
|
|
33
|
+
never persists an unknown value); a registry hand-edited to an unknown or missing tool **fails
|
|
34
|
+
`doctor`** with `YAD-CFG-004` and must be fixed.
|
|
35
|
+
- **Auth is never stored.** No LLM key, token, or any credential in the registry. `kb`/`kb_sources` are
|
|
36
|
+
plain references; DeepTutor is reached through the user's own `deeptutor` config.
|
|
37
|
+
- **`connect` overwrites in place** — a project carries exactly one learning connection at a time;
|
|
38
|
+
switching tools is just another `connect`. There is no array (unlike `repos.json`). The original
|
|
39
|
+
`connectedAt` is preserved across re-connects; only `lastSyncedAt` moves.
|
|
40
|
+
- **`source`** is the authority for availability: `deeptutor-cli` means `yad-learn` can drive the CLI
|
|
41
|
+
(grounded in `kb`); `harness-native` means `yad-learn` tutors via the harness model reading the
|
|
42
|
+
artifacts directly. `refresh` re-detects and may flip it.
|
|
43
|
+
- **`ground` is not persisted.** The `ground: true|false` input only governs whether the AI connect
|
|
44
|
+
step builds/refreshes the knowledge base at connect time; the registry records the *result* (`kb` +
|
|
45
|
+
`kb_sources`), never the flag itself.
|
|
46
|
+
- **`tool: "none"`** is a valid, deliberate state: a project that has chosen harness-native tutoring.
|
|
47
|
+
`yad-learn` treats it exactly like an absent registry — it still tutors, just without DeepTutor.
|
|
48
|
+
- **`disconnect`** removes the file (or sets `tool: "none"`). DeepTutor's own config and knowledge bases
|
|
49
|
+
are never touched.
|
|
50
|
+
|
|
51
|
+
## Git tracking
|
|
52
|
+
|
|
53
|
+
Commit the **registry** (`learning.json`) — it is small, reviewable, and holds no secrets (references
|
|
54
|
+
only). This mirrors how `repos.json`, `hub.json`, `design.json`, and `testing.json` are committed.
|
|
55
|
+
|
|
56
|
+
## Greenfield
|
|
57
|
+
|
|
58
|
+
A brand-new product hub has no `learning.json`. That is valid — `yad-learn` treats "no learning tool
|
|
59
|
+
connected" the same as `tool: "none"` and tutors harness-native. The registry appears the first time
|
|
60
|
+
`connect` runs.
|
|
@@ -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,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,8 +22,10 @@ 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:
|
|
@@ -82,13 +84,28 @@ Print, in this order:
|
|
|
82
84
|
recommendation to flip — earning the evidence and flipping the dial stay deliberate human acts
|
|
83
85
|
(`yad-run action: set-dial`). See `docs/phase-5-build-plan.md` §"What to instrument now".
|
|
84
86
|
|
|
85
|
-
9. **
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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.
|
|
92
109
|
|
|
93
110
|
### Hard rule
|
|
94
111
|
This skill is strictly read-only. If the user wants to comment, approve, or advance, point them to
|