yadflow 2.1.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs/index.html CHANGED
@@ -284,12 +284,16 @@
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 17 skills into your IDE dirs</small></div>
287
+ <div class="node plain"><strong>Install the module</strong><small><code>npx yadflow setup</code> — copies the 20 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>
291
291
  <div class="node plain"><strong>Connect code repos</strong><small><code>yad-connect-repos</code> → <code>repos.json</code> + a cached code-map per repo <em>(skip if greenfield)</em></small></div>
292
292
  <div class="arrow-v">▼</div>
293
+ <div class="node plain"><strong>Connect a design tool</strong><small><code>yad-connect-design</code> → <code>design.json</code> (Figma-first, pluggable) so <code>yad-ui</code> can materialize the screens <em>(optional — degrades to markdown-only)</em></small></div>
294
+ <div class="arrow-v">▼</div>
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
+ <div class="arrow-v">▼</div>
293
297
  <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>
294
298
  </div>
295
299
  </div>
@@ -311,7 +315,7 @@
311
315
  <div class="arrow-v">▼</div>
312
316
  <div class="node gate">gate · architecture review<small><strong>escalated:</strong> base rule + a domain owner for every repo in the epic</small></div>
313
317
  <div class="arrow-v">▼</div>
314
- <div class="node artifact"><strong>yad-ui</strong><small><code>ui-design.md</code> + <code>DESIGN.md</code></small></div>
318
+ <div class="node artifact"><strong>yad-ui</strong><small><code>ui-design.md</code> + <code>DESIGN.md</code> + the screens in the connected design tool (<code>design-links.json</code>)</small></div>
315
319
  <div class="arrow-v">▼</div>
316
320
  <div class="node gate">gate · UI review<small>base rule</small></div>
317
321
  <div class="arrow-v">▼</div>
@@ -319,7 +323,9 @@
319
323
  <div class="arrow-v">▼</div>
320
324
  <div class="node gate">gate · stories review<small><strong>per-repo:</strong> base rule + the engineer of each touched repo</small></div>
321
325
  <div class="arrow-v">▼</div>
322
- <div class="node sentinel"><strong>ready-for-build</strong><small>the front half is done — building can start</small></div>
326
+ <div class="node sentinel"><strong>ready-for-build</strong><small>the gating front half is done — building can start (and <code>yad-test-cases</code> opens in parallel)</small></div>
327
+ <div class="arrow-v">▼</div>
328
+ <div class="node artifact"><strong>yad-test-cases</strong> <em>(parallel · non-blocking)</em><small>opens when the stories gate passes and runs <strong>alongside the build half</strong> — with the test architect → <code>test-cases.md</code> + the automation tests in the connected testing tool (<code>test-links.json</code>) → its own base-rule review. Never blocks <code>ready-for-build</code>.</small></div>
323
329
  </div>
324
330
  </div>
325
331
 
@@ -367,11 +373,12 @@
367
373
  epic.md the feature, agreed
368
374
  architecture.md how it will be built
369
375
  contract.md the LOCKED shared surface (APIs, events, data model)
370
- ui-design.md + DESIGN.md
376
+ ui-design.md + DESIGN.md (+ the screens in the connected design tool)
371
377
  stories/ one file per story (EP-&lt;slug&gt;-S01.md …)
378
+ test-cases.md the test cases (+ the automation tests when a testing tool is connected)
372
379
  reviews/ reviewer comments, per artifact
373
380
  .sdlc/ state.json · approvals.json · contract-lock.json
374
- build-state/ · trust-log.json · build-log.json
381
+ design-links.json · test-links.json · build-state/ · trust-log.json · build-log.json
375
382
 
376
383
  each code repo/
377
384
  specs/&lt;story-id&gt;/ spec, plan, tasks (+ link.md back to the story)
@@ -438,8 +445,8 @@ each code repo/
438
445
  <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>
439
446
  <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>
440
447
  <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>
441
- <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 17 skills live and where you pull updates from. No real product work happens inside it.</div>
442
- <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. Permanently human-approved.</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 20 skills live and where you pull updates from. No real product work happens inside it.</div>
449
+ <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>
443
450
  <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>
444
451
  <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>
445
452
  <div class="term"><strong>Assistance dial</strong><span class="badge b-core">core</span><br>A per-step setting for how much AI helps with the work: <code>none</code>, <code>review</code> (AI checks human work), or <code>heavy</code> (AI does the drafting, human directs).</div>
@@ -518,7 +525,7 @@ each code repo/
518
525
  <div class="term"><strong>Trust threshold</strong><span class="badge b-auto">automation</span><br>The bar a step must clear to earn automation — by default at least 5 runs with ≥80% “approved-unchanged” (configurable in <code>config.yaml</code>).</div>
519
526
  <div class="term"><strong>Run verdicts</strong><span class="badge b-auto">automation</span><br>How each engineer review scores an automated run: <code>approved-unchanged</code> (merged exactly as authored — the strongest signal), <code>approved-with-edits</code> (a human fixed it first), <code>rejected</code> (failed).</div>
520
527
  <div class="term"><strong>Kill switch</strong><span class="badge b-auto">automation</span><br><code>yad-run action: kill</code> — one move that forces <em>every</em> step system-wide back to <code>human_approve</code> instantly, no code change needed. <code>unkill</code> restores earned automation. Automation is always reversible in one move.</div>
521
- <div class="term"><strong>Locked steps</strong><span class="badge b-auto">automation</span><br>The steps that may <em>never</em> be set to <code>machine_advance</code>: all four front authoring steps, their reviews, and the engineer review. A front state advances only on a human act.</div>
528
+ <div class="term"><strong>Locked steps</strong><span class="badge b-auto">automation</span><br>The steps that may <em>never</em> be set to <code>machine_advance</code>: all five front authoring steps, their reviews, and the engineer review. A front state advances only on a human act.</div>
522
529
  <div class="term"><strong>Fleet roll-up</strong><span class="badge b-auto">automation</span><br>The cross-epic summary <code>yad-status</code> prints: where every epic stands, which steps are “earned but still manual” (nudge cost), at a glance.</div>
523
530
 
524
531
  <h3>Tools the workflow builds on</h3>
@@ -529,7 +536,7 @@ each code repo/
529
536
  <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>
530
537
  <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>
531
538
  <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>
532
- <div class="term"><strong>Skill</strong><span class="badge b-tool">tools</span><br>One of the 17 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>
539
+ <div class="term"><strong>Skill</strong><span class="badge b-tool">tools</span><br>One of the 20 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>
533
540
  <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>
534
541
 
535
542
  <h3>People &amp; AI roles</h3>
@@ -572,7 +579,7 @@ each code repo/
572
579
  <div class="flow-v">
573
580
  <div class="node plain"><strong>Setup</strong><small>install skills · create the hub repo · create empty code repos · wire each repo (CI gates + PR template) · <s>connect-repos</s> <em>skipped — nothing to map yet</em></small></div>
574
581
  <div class="arrow-v">▼</div>
575
- <div class="node artifact"><strong>Front half</strong><small>(analysis) → epic → architecture + contract → UI (<code>craft</code> → <code>extract</code>) → stories — all human-gated</small></div>
582
+ <div class="node artifact"><strong>Front half</strong><small>(analysis) → epic → architecture + contract → UI (<code>craft</code> → <code>extract</code>) → stories — all human-gated; then test cases runs in parallel with the build half</small></div>
576
583
  <div class="arrow-v">▼</div>
577
584
  <div class="node"><strong>Build half</strong><small>spec → implement → checks → PR → ship, per story per repo — specs exist for 100% of the code from day one</small></div>
578
585
  <div class="arrow-v">▼</div>
@@ -672,7 +679,7 @@ each code repo/
672
679
 
673
680
  <!-- ======================================================= -->
674
681
  <section id="skills">
675
- <h2>6. The 17 skills — what each does, how to use it, and when</h2>
682
+ <h2>6. The 20 skills — what each does, how to use it, and when</h2>
676
683
  <p>A <strong>skill</strong> is an agent you invoke <em>by name</em> in your AI IDE — you just ask in
677
684
  plain words, e.g. <em>“run <code>yad-epic</code>”</em>, adding any inputs the skill needs
678
685
  (<code>repo: backend</code>, <code>story: EP-…-S01</code>, <code>action: wire</code>, …).
@@ -682,11 +689,14 @@ each code repo/
682
689
  <table>
683
690
  <tr><th>Skill</th><th>Half</th><th>One line</th></tr>
684
691
  <tr><td><a href="#sk-connect"><code>yad-connect-repos</code></a></td><td>Setup</td><td>Register a code repo with the hub + cache its code-map.</td></tr>
692
+ <tr><td><a href="#sk-connect-design"><code>yad-connect-design</code></a></td><td>Setup</td><td>Connect a design tool (Figma-first) so <code>yad-ui</code> can materialize the screens.</td></tr>
693
+ <tr><td><a href="#sk-connect-testing"><code>yad-connect-testing</code></a></td><td>Setup</td><td>Connect a testing tool (Playwright-first) so <code>yad-test-cases</code> can implement the automation.</td></tr>
685
694
  <tr><td><a href="#sk-analysis"><code>yad-analysis</code></a></td><td>Front</td><td><em>(Optional)</em> pressure-test an idea into <code>analysis.md</code>.</td></tr>
686
695
  <tr><td><a href="#sk-epic"><code>yad-epic</code></a></td><td>Front</td><td>Start a feature: write <code>epic.md</code>, assign the ID.</td></tr>
687
696
  <tr><td><a href="#sk-arch"><code>yad-architecture</code></a></td><td>Front</td><td>Author <code>architecture.md</code> + the locked <code>contract.md</code>.</td></tr>
688
- <tr><td><a href="#sk-ui"><code>yad-ui</code></a></td><td>Front</td><td>Author <code>ui-design.md</code> + <code>DESIGN.md</code>.</td></tr>
697
+ <tr><td><a href="#sk-ui"><code>yad-ui</code></a></td><td>Front</td><td>Author <code>ui-design.md</code> + <code>DESIGN.md</code>; materialize the screens in the connected design tool.</td></tr>
689
698
  <tr><td><a href="#sk-stories"><code>yad-stories</code></a></td><td>Front</td><td>Break the epic into repo-tagged stories.</td></tr>
699
+ <tr><td><a href="#sk-test-cases"><code>yad-test-cases</code></a></td><td>Front</td><td>With the test architect, author the test cases; implement the automation when a testing tool is connected.</td></tr>
690
700
  <tr><td><a href="#sk-gate"><code>yad-review-gate</code></a></td><td>Cross-cutting</td><td>Review / comment / approve / advance <strong>any</strong> gate.</td></tr>
691
701
  <tr><td><a href="#sk-bridge"><code>yad-hub-bridge</code></a></td><td>Cross-cutting</td><td>Run front-half reviews over real PRs/MRs and sync them back.</td></tr>
692
702
  <tr><td><a href="#sk-comments"><code>yad-review-comments</code></a></td><td>Setup</td><td>Install the structured review-comment scaffolds.</td></tr>
@@ -715,6 +725,28 @@ yad-connect-repos action: roster login: alice-gh name: alice role: owner # onc
715
725
  <div class="row"><span class="lbl lbl-when">When</span> During one-time setup, and again any time you add a new code repo. Re-run <code>refresh</code> when a skill warns a repo is stale. <strong>Greenfield with no code yet? Skip it entirely</strong> — the brain proceeds without it.</div>
716
726
  </div>
717
727
 
728
+ <div class="skillcard" id="sk-connect-design">
729
+ <h4><code>yad-connect-design</code></h4>
730
+ <div class="row"><span class="lbl lbl-what">What</span> Connects a <strong>design tool</strong> to the product hub so the UI step can materialize the <em>actual</em> feature design — mobile screens / web pages — inside it, alongside the Markdown. <strong>Figma-first but pluggable</strong> (a design-tool adapter; <code>pencil</code> is a second provider). It records the tool + project/file references in <code>design.json</code> through your own authenticated MCP session — <strong>no tokens are ever stored</strong> — and degrades to markdown-only when no design-tool MCP is available.</div>
731
+ <div class="row"><span class="lbl lbl-how">How</span> Run it in the product hub, once per project:</div>
732
+ <pre><code>yad-connect-design action: connect tool: figma project_url: https://figma.com/files/project/…
733
+ yad-connect-design action: list # show the connection + whether the MCP is available
734
+ yad-connect-design action: refresh # re-detect the MCP (after authenticating a session)
735
+ yad-connect-design action: disconnect</code></pre>
736
+ <div class="row"><span class="lbl lbl-when">When</span> During one-time setup (the wizard records it), and again any time you switch design tools. <strong>No design tool? Skip it</strong> — <code>yad-ui</code> simply authors the Markdown, exactly as before.</div>
737
+ </div>
738
+
739
+ <div class="skillcard" id="sk-connect-testing">
740
+ <h4><code>yad-connect-testing</code></h4>
741
+ <div class="row"><span class="lbl lbl-what">What</span> Connects a <strong>testing tool</strong> to the product hub so the test-cases step can implement the <em>actual</em> automation tests inside it, alongside the Markdown. <strong>Playwright-first but pluggable</strong> (a testing-tool adapter; <code>cypress</code> and <code>pytest</code> are second providers). It records the tool + project/suite references in <code>testing.json</code> through your own authenticated MCP session — <strong>no tokens are ever stored</strong> — and degrades to artifacts-only when no testing-tool MCP is available.</div>
742
+ <div class="row"><span class="lbl lbl-how">How</span> Run it in the product hub, once per project:</div>
743
+ <pre><code>yad-connect-testing action: connect tool: playwright project_url: tests/playwright.config.ts
744
+ yad-connect-testing action: list # show the connection + whether the MCP is available
745
+ yad-connect-testing action: refresh # re-detect the MCP (after authenticating a session)
746
+ yad-connect-testing action: disconnect</code></pre>
747
+ <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
+ </div>
749
+
718
750
  <h3>Front half — author the thinking (in the product hub)</h3>
719
751
 
720
752
  <div class="skillcard" id="sk-analysis">
@@ -743,7 +775,7 @@ yad-connect-repos action: roster login: alice-gh name: alice role: owner # onc
743
775
 
744
776
  <div class="skillcard" id="sk-ui">
745
777
  <h4><code>yad-ui</code></h4>
746
- <div class="row"><span class="lbl lbl-what">What</span> With the ux-designer AI, authors the UI design for the epic: <code>ui-design.md</code> (this feature’s screens and flows) + <code>DESIGN.md</code> (the reusable design language). Drives Impeccable’s <code>document / extract / craft</code> commands when installed; writes the files directly when not (and records that).</div>
778
+ <div class="row"><span class="lbl lbl-what">What</span> With the ux-designer AI, authors the UI design for the epic: <code>ui-design.md</code> (this feature’s screens and flows) + <code>DESIGN.md</code> (the reusable design language). Drives Impeccable’s <code>document / extract / craft</code> commands when installed; writes the files directly when not (and records that). When a design tool is connected (<code>yad-connect-design</code>), it also <strong>materializes the screens in that tool</strong> — generating them from the spec or linking an existing design — and records the screen→frame map in <code>design-links.json</code>; otherwise it stays markdown-only.</div>
747
779
  <div class="row"><span class="lbl lbl-how">How</span> In the product hub, after the architecture gate passes:</div>
748
780
  <pre><code>run yad-ui — epic: EP-istifta-inquiries</code></pre>
749
781
  <div class="row"><span class="lbl lbl-when">When</span> After architecture, before stories. Skip-able only if the epic genuinely has no UI. Stops at the <strong>UI review gate</strong> (base rule).</div>
@@ -754,7 +786,15 @@ yad-connect-repos action: roster login: alice-gh name: alice role: owner # onc
754
786
  <div class="row"><span class="lbl lbl-what">What</span> With the pm AI, slices the approved epic into user stories small enough to build — one file each under <code>stories/</code>, with stable IDs (<code>EP-&lt;slug&gt;-S01</code>…) and a <code>repos:</code> tag naming which code repos must implement each one. Reads epic + architecture + contract + UI as input.</div>
755
787
  <div class="row"><span class="lbl lbl-how">How</span> In the product hub, after the UI gate passes:</div>
756
788
  <pre><code>run yad-stories — epic: EP-istifta-inquiries</code></pre>
757
- <div class="row"><span class="lbl lbl-when">When</span> The last front-half author step. Stops at the <strong>stories review gate</strong> (per-repo rule). When that gate passes, the epic is <code>ready-for-build</code>.</div>
789
+ <div class="row"><span class="lbl lbl-when">When</span> After the UI gate passes. Stops at the <strong>stories review gate</strong> (per-repo rule). When it passes the epic is <code>ready-for-build</code> — the build half can start, and <code>yad-test-cases</code> opens in parallel.</div>
790
+ </div>
791
+
792
+ <div class="skillcard" id="sk-test-cases">
793
+ <h4><code>yad-test-cases</code></h4>
794
+ <div class="row"><span class="lbl lbl-what">What</span> With the <strong>test architect</strong> AI (Murat), authors the risk-based test cases that cover the approved stories → <code>test-cases.md</code> (cases prioritised P0–P3, with story→case traceability). When a testing tool is connected (<code>yad-connect-testing</code>), it also <strong>implements the automation tests in that tool</strong> — generating them into the connected code repo(s) or linking an existing suite — and records the case→test map in <code>test-links.json</code>; otherwise it stays artifacts-only. Reads epic + architecture + contract + UI + stories as input.</div>
795
+ <div class="row"><span class="lbl lbl-how">How</span> In the product hub, after the stories gate passes:</div>
796
+ <pre><code>run yad-test-cases — epic: EP-istifta-inquiries</code></pre>
797
+ <div class="row"><span class="lbl lbl-when">When</span> A <strong>parallel, non-blocking</strong> track: it opens the moment the stories gate passes — the epic is already <code>ready-for-build</code>, so this runs <strong>alongside the build half</strong>, not before it. Stops at its own <strong>test-cases review gate</strong> (base rule); that review never blocks building.</div>
758
798
  </div>
759
799
 
760
800
  <h3>The review gate &amp; its plumbing (cross-cutting)</h3>
@@ -883,7 +923,7 @@ yad-status EP-istifta-inquiries # one epic in detail</code></pre>
883
923
 
884
924
  <div class="skillcard">
885
925
  <h4><code>npx yadflow setup</code></h4>
886
- <div class="row"><span class="lbl lbl-what">What</span> The guided first-run wizard. Seven steps: preflight (git/node check), install all 17 skills into the IDE dirs you pick, detect the hub’s platform + record the reviewer roster, 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>
926
+ <div class="row"><span class="lbl lbl-what">What</span> The guided first-run wizard. Nine steps: preflight (git/node check), install all 20 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 your code repos, wire each one (CI gates, PR template, comment scaffold), optionally write the AI-review config, and stamp the installed version.</div>
887
927
  <div class="row"><span class="lbl lbl-how">How</span></div>
888
928
  <pre><code>cd &lt;product-hub-repo&gt;
889
929
  npx yadflow setup</code></pre>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yadflow",
3
- "version": "2.1.0",
3
+ "version": "2.3.0",
4
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 + 17 yad-* skills.",
5
5
  "type": "module",
6
6
  "author": "AbdelRahman Nasr",
@@ -20,12 +20,12 @@ output_folder: "{project-root}/_bmad-output"
20
20
  defaults:
21
21
  assistance: review # none | review | heavy
22
22
  automation: human_approve # human_approve | machine_advance
23
- # Front steps (analysis [optional], epic, architecture, ui-design, stories) are locked to
23
+ # Front steps (analysis [optional], epic, architecture, ui-design, stories, test-cases) are locked to
24
24
  # human_approve and may NOT be set to machine_advance in this version (build plan §1, §8.7).
25
25
  front_steps_locked: true
26
26
  # Each front authoring step opens its own branch at the start of the step (the <step> is the step id:
27
- # analysis | epic | architecture | ui-design | stories). Git/greenfield-safe; distinct from the
28
- # bridge's review branch (hub.artifact_branch). See yad-epic/references/state-schema.md.
27
+ # analysis | epic | architecture | ui-design | stories | test-cases). Git/greenfield-safe; distinct
28
+ # from the bridge's review branch (hub.artifact_branch). See yad-epic/references/state-schema.md.
29
29
  front_authoring_branch: "<step>/EP-<slug>"
30
30
 
31
31
  # Team review gate defaults (build plan §3 piece 2, §4).
@@ -118,6 +118,38 @@ code_context:
118
118
  # works for both github and gitlab (and self-hosted), and stores NO tokens in the registry.
119
119
  platforms: [github, gitlab]
120
120
 
121
+ # Design tool (yad-connect-design) — the UI design step (yad-ui) materializes the actual feature design
122
+ # (mobile screens / web pages) inside a connected design tool, alongside ui-design.md + DESIGN.md. The
123
+ # tool is reached through its MCP (a harness MCP server, like Impeccable's slash-commands — NOT a CLI),
124
+ # detected per provider and DEGRADING to markdown-only when absent. Figma-first but PLUGGABLE: a
125
+ # design-tool adapter, like the github/gitlab platform adapter. Connection is one-per-project, recorded
126
+ # at setup; the per-epic screen->frame map (design-links.json) is written by yad-ui per epic.
127
+ design:
128
+ registry: "{project-root}/.sdlc/design.json" # project-wide design connection (NOT per-epic)
129
+ tools: [figma, pencil] # supported adapters; an unknown tool falls back to `primary`
130
+ primary: figma # the default/named provider
131
+ degrade: markdown-only # no tool / no MCP => yad-ui authors ui-design.md + DESIGN.md only
132
+ links: "{project-root}/epics/EP-<slug>/.sdlc/design-links.json" # per-epic screen->frame map (yad-ui)
133
+ # Auth: `yad-connect-design` connects through the LOCAL user's own authenticated MCP session and stores
134
+ # NO tokens in the registry (project_url/files are plain references, never credentials).
135
+ auth: user
136
+
137
+ # Testing tool (yad-connect-testing) — the test-cases step (yad-test-cases) materializes the actual
138
+ # automation tests inside a connected testing tool, alongside test-cases.md. The tool is reached through
139
+ # its MCP (a harness MCP server, like the design tool — NOT a CLI), detected per provider and DEGRADING
140
+ # to artifacts-only when absent. Playwright-first but PLUGGABLE: a testing-tool adapter, like the
141
+ # design-tool adapter. Connection is one-per-project, recorded at setup; the per-epic case->test map
142
+ # (test-links.json) is written by yad-test-cases per epic.
143
+ testing:
144
+ registry: "{project-root}/.sdlc/testing.json" # project-wide testing connection (NOT per-epic)
145
+ tools: [playwright, cypress, pytest] # supported adapters; an unknown tool falls back to `primary`
146
+ primary: playwright # the default/named provider
147
+ degrade: artifacts-only # no tool / no MCP => yad-test-cases authors test-cases.md only
148
+ links: "{project-root}/epics/EP-<slug>/.sdlc/test-links.json" # per-epic case->test map (yad-test-cases)
149
+ # Auth: `yad-connect-testing` connects through the LOCAL user's own authenticated MCP session and stores
150
+ # NO tokens in the registry (project_url/suites are plain references, never credentials).
151
+ auth: user
152
+
121
153
  # Hub platform + front-half review bridge (yad-connect-repos `detect-hub`; yad-review-gate + yad-hub-bridge).
122
154
  # The product hub is itself a git repo on a platform. With the bridge enabled, the front-half review/
123
155
  # comment/approval cycle runs through a real PR/MR on the hub: a review PR is opened per artifact, reviewers
@@ -150,7 +182,7 @@ automation:
150
182
  # Hard lock — the dial-setter REFUSES machine_advance for these, regardless of trust evidence.
151
183
  # The front authoring steps (already locked:true in state.json; analysis is optional) + the human
152
184
  # merge gate.
153
- locked_steps: [analysis, epic, architecture, ui-design, stories, engineer-review]
185
+ locked_steps: [analysis, epic, architecture, ui-design, stories, test-cases, engineer-review]
154
186
  # Kill switch (phase-4-build-plan.md §Safety): true => every step forced to human_approve
155
187
  # system-wide, no per-step edits. One line, instantly reversible. Toggle via `yad-run action: kill`.
156
188
  kill_switch: false
@@ -11,7 +11,7 @@ set -euo pipefail
11
11
  ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
12
12
  cd "$ROOT"
13
13
 
14
- SKILLS=(yad-analysis yad-epic yad-architecture yad-ui yad-stories yad-connect-repos yad-spec yad-implement yad-checks yad-pr-template yad-review-comments yad-hub-bridge yad-ship yad-backfill yad-run yad-review-gate yad-status)
14
+ SKILLS=(yad-analysis yad-epic yad-architecture yad-ui yad-stories yad-test-cases yad-connect-repos yad-connect-design yad-connect-testing yad-spec yad-implement yad-checks yad-pr-template yad-review-comments yad-hub-bridge yad-ship yad-backfill yad-run yad-review-gate yad-status)
15
15
 
16
16
  echo "Installing sdlc module from $ROOT/skills ..."
17
17
 
@@ -1,10 +1,13 @@
1
1
  module,skill,display-name,menu-code,description,action,args,phase,preceded-by,followed-by,required,output-location,outputs
2
2
  SDLC Workflow,yad-epic,Author Epic,AE,"Front state 1: shape an idea with analyst then pm into epic.md; assign EP-<slug> ID and seed .sdlc state. Never auto-advances.",,{idea: one-line feature idea},1-front,,yad-review-gate,true,epics/EP-<slug>/,epic.md state.json
3
- SDLC Workflow,yad-review-gate,Team Review Gate,RG,"Reusable review+approve gate for all four 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
3
+ SDLC Workflow,yad-review-gate,Team Review Gate,RG,"Reusable review+approve gate for all five reviews. Shares an artifact for review, records comments and approvals as files, enforces owner + 1 reviewer (escalates on contract/auth/payments; per-repo routing for stories), advances state only when approved.",,{artifact: file under the epic} {action: open|comment|approve|advance},1-front,,,true,epics/EP-<slug>/reviews/,reviews/*.md approvals.json state.json
4
4
  SDLC Workflow,yad-architecture,Author Architecture,AA,"Front state 3: with the architect author architecture.md and the locked contract.md; hash-lock the contract surface. Never auto-advances.",,{epic: EP-<slug>},1-front,yad-review-gate,yad-review-gate,true,epics/EP-<slug>/,architecture.md contract.md contract-lock.json state.json
5
5
  SDLC Workflow,yad-ui,Author UI Design,AU,"Front state 5: with the ux-designer author ui-design.md and DESIGN.md, driving Impeccable slash-commands when installed. Never auto-advances.",,{epic: EP-<slug>},1-front,yad-review-gate,yad-review-gate,true,epics/EP-<slug>/,ui-design.md DESIGN.md state.json
6
6
  SDLC Workflow,yad-stories,Author Stories,AS,"Front state 7: with the pm break the epic into repo-tagged stories with stable EP-<slug>-S0N IDs, one file each under stories/. Never auto-advances.",,{epic: EP-<slug>},1-front,yad-review-gate,yad-review-gate,true,epics/EP-<slug>/stories/,stories/EP-<slug>-S0N.md state.json
7
+ SDLC Workflow,yad-test-cases,Author Test Cases,TC,"Front state 9 (PARALLEL, non-blocking): opens when the stories gate passes — the epic is already ready-for-build, so the build half can start at the same time the tester works here. With the test architect (Murat) author test-cases.md covering the approved stories, and — when a testing tool is connected (.sdlc/testing.json) — generate/link the actual automation tests in it, recording test-links.json; otherwise produce the test-case artifact only. Its review never moves currentStep off ready-for-build. Never auto-advances.",,{epic: EP-<slug>},1-front,yad-review-gate,yad-review-gate,true,epics/EP-<slug>/,test-cases.md test-links.json state.json
7
8
  SDLC Workflow,yad-connect-repos,Connect Code Repos,CR,"Setup/maintenance: connect code repos to the product hub so the front/brain phases are code-aware. Registers each repo (GitHub or GitLab, local-user auth, no stored tokens) in .sdlc/repos.json and caches a Repomix pack + a lightweight code-map (existing endpoints/events/data-models/modules, secret-scanned). Idempotent and refreshable; staleness tracked by HEAD sha. Run at setup or any time a new repo is added. Not a gated state — never touches epic state or approvals.",,{action: connect|refresh|list|disconnect} {repo: <name>} {path: <path-or-absolute>} {git_url: <ssh-or-https>} {domain_owner: <who>},0-setup,,yad-epic,false,.sdlc/,repos.json code-context/<repo>/pack.md code-context/<repo>/code-map.md
9
+ SDLC Workflow,yad-connect-design,Connect Design Tool,CD,"Setup/maintenance: connect a design tool (Figma-first, pluggable) to the product hub so the UI design step can materialize the actual feature design (mobile screens / web pages) inside it, alongside ui-design.md + DESIGN.md. Records the tool + project/file references in .sdlc/design.json (local-user / MCP-session auth, no stored tokens), detecting whether a design-tool MCP is available and degrading to markdown-only when absent. Idempotent and refreshable; one connection per project. Not a gated state — never touches epic state or approvals.",,{action: connect|refresh|list|disconnect} {tool: figma|pencil|none} {project_url: <team/project/file url>} {files: {web,mobile}},0-setup,,yad-ui,false,.sdlc/,design.json
10
+ SDLC Workflow,yad-connect-testing,Connect Testing Tool,CT,"Setup/maintenance: connect a testing tool (Playwright-first, pluggable) to the product hub so the test-cases step can implement the actual automation tests in it, alongside test-cases.md. Records the tool + project/suite references in .sdlc/testing.json (local-user / MCP-session auth, no stored tokens), detecting whether a testing-tool MCP is available and degrading to artifacts-only when absent. Idempotent and refreshable; one connection per project. Not a gated state — never touches epic state or approvals.",,{action: connect|refresh|list|disconnect} {tool: playwright|cypress|pytest|none} {project_url: <project/config reference>} {suites: {<repo>}},0-setup,,yad-test-cases,false,.sdlc/,testing.json
8
11
  SDLC Workflow,yad-spec,Author Spec,SP,"Build-half Step A: for one ready-for-build story and one of its repos, run the heavy Spec Kit ceremony once (specify→clarify→plan→analyze→checklist→tasks) inside that code repo, writing specs/<story-id>/ in Spec Kit's layout (drives /speckit.* when installed, else hand-authors and records speckit: not-installed). References the locked contract; never re-invents the surface. Writes link.md back to the story. Never auto-advances.",,{epic: EP-<slug>} {story: EP-<slug>-S0N} {repo: <one of story.repos>},3-build,yad-review-gate,,false,demo-repos/<repo>/specs/<story-id>/,spec.md research.md data-model.md contracts/ plan.md tasks.md link.md
9
12
  SDLC Workflow,yad-implement,Implement Task,IM,"Build-half Step B: with the dev lens, implement ONE atomic task from a story's tasks.md as a small diff (<=3 files) on its own branch feat/<story>-<task>-<slug> in the code repo. Diff stays inside the task's declared files (flag and STOP if it grows beyond them). Commit ends with a Task: <story>-<task> trailer; add Contract-Change: yes only when the locked contract surface is touched (routes back to the architecture gate). Never auto-advances.",,{epic: EP-<slug>} {story: EP-<slug>-S0N} {repo: <one of story.repos>} {task: T0N},3-build,yad-spec,,false,demo-repos/<repo>/,branch+commit per atomic task
10
13
  SDLC Workflow,yad-checks,Check Gates,CK,"Build-half Step C: wire and run the three production-safety CI gates on a code repo — spec-link (every change links a real story/spec via its Task trailer), contract-check (a contract-surface change without Contract-Change + an updated re-locked contract FAILS and routes back to the architecture gate), and build/test/lint. CI-agnostic bash invoked by GitHub Actions and GitLab CI. Blocking in CI; the human still owns the merge. Never auto-advances.",,{repo: <one of an epic's repos>} {action: wire|run} {base: target branch},3-build,yad-implement,,false,demo-repos/<repo>/,checks/*.sh .github/workflows/yad-checks.yml .gitlab-ci.yml
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: yad-analysis
3
- description: 'Optional front state 1 of the gated SDLC. With the analyst, pressure-test a feature idea and write the discovery brief into analysis.md. Assigns the EP-<slug> ID and seeds .sdlc/ state (the 10-step chain that puts analysis before epic). Never auto-advances — hands off to the team review gate. Optional: if skipped, the epic step does this shaping inline. Use when the user says "analyse the idea", "start with analysis", or "author the analysis".'
3
+ description: 'Optional front state 1 of the gated SDLC. With the analyst, pressure-test a feature idea and write the discovery brief into analysis.md. Assigns the EP-<slug> ID and seeds .sdlc/ state (the 12-step chain that puts analysis before epic). Never auto-advances — hands off to the team review gate. Optional: if skipped, the epic step does this shaping inline. Use when the user says "analyse the idea", "start with analysis", or "author the analysis".'
4
4
  ---
5
5
 
6
6
  # SDLC — Author Analysis (optional front state 1)
@@ -11,8 +11,8 @@ state machine in `.sdlc/`. This is a **front state**: human-authored with AI ass
11
11
  auto-advances**. When the analysis is drafted, control passes to `yad-review-gate`.
12
12
 
13
13
  This step is **optional**. When it runs, it is the entry point: it assigns the ID and seeds the
14
- **10-step** chain (`analysis` before `epic`). When it is **skipped**, `yad-epic` does the same
15
- analyst shaping inline and seeds the **8-step** chain — no behaviour change for teams that skip it.
14
+ **12-step** chain (`analysis` before `epic`). When it is **skipped**, `yad-epic` does the same
15
+ analyst shaping inline and seeds the **10-step** chain — no behaviour change for teams that skip it.
16
16
 
17
17
  This skill enforces the build plan's core rules: all state lives in files; IDs are generated by the
18
18
  engine (never typed by hand); front steps are locked to `human_approve`.
@@ -88,7 +88,7 @@ code-context: { repos: [], loaded: <YYYY-MM-DD or none> } # which code-maps in
88
88
  Fill the body with the user; leave `owner` for the user to set.
89
89
 
90
90
  ### Step 6 — Seed the state machine
91
- Create `{project-root}/epics/EP-<slug>/.sdlc/state.json` describing the full **10-step** front-state
91
+ Create `{project-root}/epics/EP-<slug>/.sdlc/state.json` describing the full **12-step** front-state
92
92
  sequence (analysis before epic), all steps defaulting to `automation: human_approve`, with every
93
93
  authoring step **locked**. Use this exact shape (see `references/state-schema.md`):
94
94
 
@@ -107,7 +107,9 @@ authoring step **locked**. Use this exact shape (see `references/state-schema.md
107
107
  { "id": "ui-design", "type": "author", "artifact": "ui-design.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
108
108
  { "id": "ui-design-review", "type": "review+approve", "artifact": "ui-design.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
109
109
  { "id": "stories", "type": "author", "artifact": "stories/", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
110
- { "id": "stories-review", "type": "review+approve", "artifact": "stories/", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] }
110
+ { "id": "stories-review", "type": "review+approve", "artifact": "stories/", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
111
+ { "id": "test-cases", "type": "author", "artifact": "test-cases.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] },
112
+ { "id": "test-cases-review", "type": "review+approve", "artifact": "test-cases.md", "assistance": "review", "automation": "human_approve", "locked": true, "status": "blocked", "risk_tags": [] }
111
113
  ]
112
114
  }
113
115
  ```
@@ -116,6 +118,9 @@ Notes:
116
118
  - `analysis-review` carries no `risk_tags` — it is the **base** rule (owner + 1 reviewer).
117
119
  - `architecture-review` carries `risk_tags: ["contract"]` so the gate escalates it by default
118
120
  (build plan §4): the contract review needs domain owners, not just owner + 1.
121
+ - `test-cases` / `test-cases-review` are a **parallel, non-blocking track**: they seed `blocked` and open
122
+ when `stories-review` passes — the epic is already `ready-for-build` by then, so the build half runs
123
+ alongside the tester (see `../yad-epic/references/state-schema.md`).
119
124
  - Also create an empty approvals ledger `{project-root}/epics/EP-<slug>/.sdlc/approvals.json`
120
125
  and an empty comments ledger `{project-root}/epics/EP-<slug>/.sdlc/comments.json`, each containing
121
126
  `[]`, and the `reviews/` directory.
@@ -0,0 +1,117 @@
1
+ ---
2
+ name: yad-connect-design
3
+ description: 'Connects a design tool (Figma, or another tool — pluggable) to the product hub so the UI design step can materialize the full feature design (mobile screens / web pages) inside it, not just Markdown. Registers the tool into the project-wide .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 it is not. Run at setup or any time the design tool changes. Reusable, idempotent, refreshable. Use when the user says "connect Figma", "connect a design tool", "refresh the design connection", or "list the design connection".'
4
+ ---
5
+
6
+ # SDLC — Connect a Design Tool (make the UI step design-tool aware)
7
+
8
+ **Goal:** Let the UI design step (`yad-ui`) produce the **actual feature design** — the mobile screens
9
+ and/or web pages — inside a design tool such as **Figma**, alongside the Markdown artifacts
10
+ (`ui-design.md` / `DESIGN.md`). This skill **connects** a design tool to the product hub and records
11
+ *how* to reach it (the tool, the project/file references, which MCP renders it) — never a credential.
12
+
13
+ This is **setup/maintenance**, not a gated front state — it never touches `.sdlc/state.json` or any
14
+ epic's approvals. It only writes the project-wide design registry. `yad-ui` consumes it: when a tool is
15
+ connected and its MCP is available, the `ux-designer` lens **generates** screens into the tool (or
16
+ **links** an existing human-made design and reads it back); when nothing is connected, `yad-ui` runs
17
+ markdown-only exactly as before.
18
+
19
+ ## Conventions
20
+
21
+ - `{project-root}` resolves from the project working directory (the **product hub**).
22
+ - The integration is **Figma-first but pluggable** (`config.yaml` `design.tools`): a design-tool
23
+ *adapter*, like the GitHub/GitLab platform adapter. Figma is the primary provider; `pencil`
24
+ (the `.pen` web/mobile editor) is a second, write-capable provider; `none` → markdown-only.
25
+ - **The design tool is reached through its MCP** (a harness MCP server), NOT a subprocess CLI — the same
26
+ shape as Impeccable's slash-commands, not Repomix's `npx`. The skill detects the MCP and degrades when
27
+ it is absent; it never installs an MCP server.
28
+ - Registry: `{project-root}/.sdlc/design.json` (project-wide, shared across all epics — NOT per-epic),
29
+ the sibling of `.sdlc/repos.json` and `.sdlc/hub.json`.
30
+ - Per-epic screen→frame links are written later by `yad-ui` (`epics/EP-<slug>/.sdlc/design-links.json`),
31
+ not here.
32
+ - Speak in the configured `communication_language`; write documents in `document_output_language`.
33
+
34
+ ## Inputs
35
+
36
+ - `action` — `connect` (default) | `refresh` | `list` | `disconnect`.
37
+ - `tool` — `figma` | `pencil` | another adapter id (`config.yaml` `design.tools`). `none` records a
38
+ deliberate markdown-only project.
39
+ - `project_url` — the design tool's team/project/file reference (e.g. a Figma project or file URL).
40
+ Optional — a connection with no file yet is valid; `yad-ui` can create one on first generate.
41
+ - `files` — optional default file mapping per platform (`{ web: <ref>, mobile: <ref> }`).
42
+
43
+ ## On Activation
44
+
45
+ ### Step 1 — Resolve the tool and its MCP (the design-tool adapter)
46
+ Determine which tool is being connected from `tool` (default `figma`); reject a `tool` not in
47
+ `config.yaml` `design.tools` (fall back to the configured `design.primary` with a warning, the same way
48
+ `registerRepo` falls back on an unknown platform). Then **detect the tool's MCP** in this harness:
49
+
50
+ - **figma** → a Figma MCP server (Dev Mode MCP for read/link; html.to.design for HTML→Figma *generate*).
51
+ - **pencil** → the `pencil` MCP (`batch_design` writes `.pen` web/mobile screens — generate-capable).
52
+ - another adapter → its named MCP.
53
+
54
+ Record `provider` (the concrete MCP, e.g. `figma-mcp` | `html-to-design` | `pencil-mcp`) and whether it
55
+ is available. **Auth is the local user's own** — the user's authenticated MCP session. The skill
56
+ **stores no tokens**; `project_url`/`files` are plain references, never credentials.
57
+
58
+ **Graceful degradation:** if no design-tool MCP is available, record `source: "unavailable"` and report
59
+ that `yad-ui` will run **markdown-only** until an MCP is connected (no error — the design tool is purely
60
+ additive, exactly like Impeccable being absent). Do **not** install an MCP server as part of this step.
61
+
62
+ ### Step 2 — Record the connection in the registry
63
+ Upsert into `{project-root}/.sdlc/design.json` (create the file + parent `.sdlc/` if absent):
64
+
65
+ ```json
66
+ {
67
+ "tool": "figma",
68
+ "provider": "figma-mcp",
69
+ "project_url": "https://www.figma.com/files/project/<id>/<name>",
70
+ "auth": "user",
71
+ "files": { "web": null, "mobile": null },
72
+ "connectedAt": "<YYYY-MM-DD>",
73
+ "lastSyncedAt": "<YYYY-MM-DD>",
74
+ "source": "figma-mcp"
75
+ }
76
+ ```
77
+
78
+ - `tool: "none"` records a deliberate markdown-only project: `{ "tool": "none", "provider": null,
79
+ "source": "unavailable", ... }`.
80
+ - `connect` is **idempotent** — re-running it overwrites the single connection in place (a project has
81
+ one design tool at a time; switching tools is just another `connect`).
82
+
83
+ ### Step 3 — Report (never auto-advance)
84
+ Report the connected `tool`, its `provider`, whether the MCP is available (or that `yad-ui` will degrade
85
+ to markdown-only), the `project_url`, and that **`yad-ui` will now generate/link the design here**.
86
+ Nothing auto-advances; this is setup.
87
+
88
+ ## Other actions
89
+
90
+ - **`refresh`** — re-detect the MCP and update `lastSyncedAt` (after the user authenticates a session or
91
+ changes tools). Same machinery as `connect`. Re-detection may flip `source` between an MCP id and
92
+ `unavailable` — report the change.
93
+ - **`list`** — print the current connection: `tool`, `provider`, `project_url`, the file mapping, and a
94
+ **available/unavailable** flag for the MCP (best-effort, the user's own session). No design tool
95
+ connected ⇒ "markdown-only".
96
+ - **`disconnect`** — remove the registry file (or set `tool: "none"`). The design tool's own
97
+ project/files are **never touched** — only the hub's record of them.
98
+
99
+ ## Hard rules
100
+
101
+ - **Local-user / MCP-session auth only; store no tokens.** Connect through the user's authenticated MCP
102
+ session; never embed a Figma PAT or any credential in the registry. `project_url`/`files` are plain
103
+ references.
104
+ - **Degrade gracefully.** No design tool / no MCP → `yad-ui` runs markdown-only with no error. The design
105
+ tool is additive, never a blocker — the same discipline as Impeccable and the `gh`/`glab` bridge.
106
+ - **Setup, not a gate.** Never touch `.sdlc/state.json`, approvals, or the contract lock from here.
107
+ - **Idempotent + refreshable.** `connect`/`refresh` are safe to re-run; a project carries one design
108
+ connection at a time.
109
+ - **Describe the connection; do not design here.** This skill records *how to reach* the tool. The actual
110
+ screens are generated/linked by `yad-ui`, per epic.
111
+
112
+ ## Reference
113
+ - Registry schema + freshness rule: `references/design-registry.md`.
114
+ - MCP detection per provider, the generate-vs-link recipes, the degrade path, and the honest
115
+ write-vs-read-only MCP capability note: `references/design-context.md`.
116
+ - The connect pattern this mirrors (code repos): `../yad-connect-repos/SKILL.md`.
117
+ - The consumer — how `yad-ui` generates/links and writes `design-links.json`: `../yad-ui/SKILL.md`.
@@ -0,0 +1,64 @@
1
+ # Design context — MCP detection, generate vs link, and the degrade path
2
+
3
+ How a connected design tool turns into the actual feature design the UI step materializes. The design
4
+ tool is reached through its **MCP** (a harness MCP server), the same shape as Impeccable's
5
+ slash-commands — detect it, use it when present, degrade cleanly when absent. This is the design-side
6
+ analogue of `yad-connect-repos`'s code-context.
7
+
8
+ ## Provider detection
9
+
10
+ `connect`/`refresh` records `provider` (the concrete MCP) and `source` (the MCP id, or `unavailable`).
11
+ Detection is best-effort against the user's own authenticated MCP session:
12
+
13
+ | `tool` | MCP / provider | Capability |
14
+ |--------|----------------|------------|
15
+ | `figma` | a Figma Dev Mode MCP | **read/link** — reference a file, read frames back into `ui-design.md` |
16
+ | `figma` | html.to.design MCP (`import-html`) | **generate** — render HTML/CSS screens into a Figma file |
17
+ | `pencil` | the `pencil` MCP (`batch_design`) | **generate** — author `.pen` web/mobile screens directly |
18
+ | other | the adapter's named MCP | per that adapter |
19
+
20
+ **Honest capability note:** not every design-tool MCP can *write*. A read-only Figma Dev Mode MCP
21
+ supports **link + read-back** only; *generate* needs a write-capable provider (html.to.design for Figma,
22
+ or `pencil`). `yad-ui` picks the direction the connected provider actually supports and records which one
23
+ it used (`direction: generated | linked`). It never claims to have generated screens a read-only MCP
24
+ cannot produce.
25
+
26
+ ## Generate (push screens into the tool)
27
+
28
+ When the connected provider is write-capable, the `ux-designer` lens produces the epic's screens in the
29
+ tool, covering the screens/states `ui-design.md` enumerates and the user flows the architecture defines:
30
+
31
+ - **Figma via html.to.design** — the lens drafts each screen as HTML/CSS (reusing `DESIGN.md` tokens),
32
+ then imports it into the Figma file via the MCP's `import-html`, one frame per screen.
33
+ - **pencil** — the lens calls `batch_design` to author the screens as `.pen` frames directly (mobile
34
+ and/or web per the epic).
35
+
36
+ Reuse what already exists: load the connected code repos' code-maps (`yad-ui` Step 2b) and any
37
+ Impeccable `DESIGN.md` tokens so generated screens match built components, not invented ones.
38
+
39
+ ## Link (reference a human-made design)
40
+
41
+ When a designer has already built the screens (or the provider is read-only), point `yad-ui` at the
42
+ existing file and **read the frames back** so `ui-design.md` reflects the real design: list each frame as
43
+ a screen, capture its node id + URL, and map components/tokens into `DESIGN.md`.
44
+
45
+ ## Write back the linkage (done by `yad-ui`, per epic)
46
+
47
+ Either direction ends by writing `epics/EP-<slug>/.sdlc/design-links.json` — the machine-readable
48
+ screen→frame map — and a `## Design (<tool>)` section in `ui-design.md` linking each screen to its frame
49
+ URL. The design itself lives in the tool; the hub keeps the *links* and the Markdown spec beside the
50
+ other epic artifacts.
51
+
52
+ ## Degrade path (no MCP / no tool)
53
+
54
+ If `design.json` is absent, `tool: "none"`, or `source: "unavailable"`, `yad-ui` runs **markdown-only**:
55
+ it authors `ui-design.md` / `DESIGN.md` exactly as before and records `design: none` in the frontmatter
56
+ with a one-line note (mirroring the `impeccable: not-installed` degrade). No error — the design tool is
57
+ purely additive.
58
+
59
+ ## Staleness / refresh
60
+
61
+ A re-generated or designer-edited file is like a moved code repo: `yad-ui` **flags** a divergence and
62
+ lets a human decide (re-run the step, or `yad-connect-design` action: refresh). It never silently
63
+ overwrites a designer's frames — refreshing the design is a human decision, the same discipline as
64
+ `code_context.refresh: human`.
@@ -0,0 +1,56 @@
1
+ # Design registry — schema + freshness rule
2
+
3
+ The registry is the product hub's record of which design tool is connected and how to reach it. It is
4
+ **project-wide** (one design 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/design.json`
10
+
11
+ (`config.yaml` `design.registry`.) Create the file and its parent `.sdlc/` on the first `connect`.
12
+
13
+ ## Schema
14
+
15
+ ```json
16
+ {
17
+ "tool": "figma", // figma | pencil | <adapter id> | none (markdown-only)
18
+ "provider": "figma-mcp", // the concrete MCP: figma-mcp | html-to-design | pencil-mcp | null
19
+ "project_url": "https://www.figma.com/files/project/123/feature", // team/project/file reference; null if none yet
20
+ "auth": "user", // ALWAYS the user's own MCP session — never a token
21
+ "files": { "web": null, "mobile": null }, // optional default file refs per platform
22
+ "connectedAt": "2026-06-13", // first connect (YYYY-MM-DD)
23
+ "lastSyncedAt": "2026-06-13", // last connect/refresh
24
+ "source": "figma-mcp" // the MCP detected at connect | unavailable (degraded)
25
+ }
26
+ ```
27
+
28
+ ## Rules
29
+
30
+ - **`tool`** selects the adapter; it MUST be one of `config.yaml` `design.tools` (or `none`). At
31
+ **connect** time an unknown tool is normalized to `design.primary` with a warning (so the registry
32
+ never persists an unknown value); a registry hand-edited to an unknown or missing tool **fails
33
+ `doctor`** with `YAD-CFG-002` and must be fixed.
34
+ - **Auth is never stored.** No Figma PAT, OAuth token, or any credential in the registry. `project_url`
35
+ and `files` are plain references; `connect` reaches the tool through the user's authenticated MCP
36
+ session.
37
+ - **`connect` overwrites in place** — a project carries exactly one design connection at a time;
38
+ switching tools is just another `connect`. There is no array (unlike `repos.json`).
39
+ - **`source`** is the authority for availability: an MCP id (`figma-mcp` / `pencil-mcp` / …) means
40
+ `yad-ui` can generate/link; `unavailable` means `yad-ui` degrades to markdown-only. `refresh`
41
+ re-detects and may flip it.
42
+ - **`tool: "none"`** is a valid, deliberate state: a project that has chosen markdown-only. `yad-ui`
43
+ treats it exactly like an absent registry.
44
+ - **`disconnect`** removes the file (or sets `tool: "none"`). The design tool's own project/files are
45
+ never touched.
46
+
47
+ ## Git tracking
48
+
49
+ Commit the **registry** (`design.json`) — it is small, reviewable, and holds no secrets (references
50
+ only). This mirrors how `repos.json` and `hub.json` are committed.
51
+
52
+ ## Greenfield
53
+
54
+ A brand-new product hub has no `design.json`. That is valid — `yad-ui` treats "no design tool connected"
55
+ the same as `tool: "none"` and produces the Markdown artifacts only. The registry appears the first time
56
+ `connect` runs.