qfai 1.10.0 → 1.10.2

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.
Files changed (103) hide show
  1. package/README.md +95 -25
  2. package/assets/init/.qfai/assistant/README.md +27 -0
  3. package/assets/init/.qfai/assistant/agents/completion-reviewer.md +17 -1
  4. package/assets/init/.qfai/assistant/agents/delivery-planner.md +8 -0
  5. package/assets/init/.qfai/assistant/agents/implementation-reviewer.md +12 -1
  6. package/assets/init/.qfai/assistant/agents/orchestrator.md +2 -2
  7. package/assets/init/.qfai/assistant/agents/product-experience-architect.md +2 -1
  8. package/assets/init/.qfai/assistant/agents/product-surface-reviewer.md +1 -1
  9. package/assets/init/.qfai/assistant/agents/qa-gatekeeper.md +99 -14
  10. package/assets/init/.qfai/assistant/agents/test-design-analyst.md +4 -1
  11. package/assets/init/.qfai/assistant/catalog/cli-ux-guidelines.md +3 -0
  12. package/assets/init/.qfai/assistant/catalog/test-layers-ci-lanes.md +60 -0
  13. package/assets/init/.qfai/assistant/catalog/test-layers.md +169 -87
  14. package/assets/init/.qfai/assistant/catalog/worklog-entry.schema.md +4 -3
  15. package/assets/init/.qfai/assistant/constitution/agent-selection.md +7 -1
  16. package/assets/init/.qfai/assistant/constitution/communication.md +1 -1
  17. package/assets/init/.qfai/assistant/constitution/constitution.md +8 -2
  18. package/assets/init/.qfai/assistant/constitution/drift-protocol.md +177 -14
  19. package/assets/init/.qfai/assistant/constitution/review-convergence.md +121 -0
  20. package/assets/init/.qfai/assistant/constitution/shared-skill-delegation-baseline.md +205 -89
  21. package/assets/init/.qfai/assistant/constitution/shared-skill-operating-baseline.md +59 -5
  22. package/assets/init/.qfai/assistant/manifest/agent-catalog.yml +145 -21
  23. package/assets/init/.qfai/assistant/manifest/agent-routing.yml +69 -3
  24. package/assets/init/.qfai/assistant/skills/qfai-atdd/SKILL.md +131 -74
  25. package/assets/init/.qfai/assistant/skills/qfai-atdd/references/credential-reuse.md +146 -0
  26. package/assets/init/.qfai/assistant/skills/qfai-atdd/references/red-provenance.md +498 -0
  27. package/assets/init/.qfai/assistant/skills/qfai-atdd/references/review-fix-rounds.md +128 -0
  28. package/assets/init/.qfai/assistant/skills/qfai-atdd/references/scaffolding.md +71 -0
  29. package/assets/init/.qfai/assistant/skills/qfai-atdd/references/shared-test-artifacts.md +124 -0
  30. package/assets/init/.qfai/assistant/skills/qfai-atdd/references/stale-manifest.md +34 -0
  31. package/assets/init/.qfai/assistant/skills/qfai-atdd/references/test-case-depth-checklist.md +38 -1
  32. package/assets/init/.qfai/assistant/skills/qfai-configure/SKILL.md +4 -3
  33. package/assets/init/.qfai/assistant/skills/qfai-discussion/SKILL.md +10 -8
  34. package/assets/init/.qfai/assistant/skills/qfai-discussion/references/discussion-completion-matrix.md +23 -2
  35. package/assets/init/.qfai/assistant/skills/qfai-discussion/references/review-cycle-playbook.md +16 -1
  36. package/assets/init/.qfai/assistant/skills/qfai-discussion/references/ui-bearing-playbook.md +47 -11
  37. package/assets/init/.qfai/assistant/skills/qfai-discussion/references/ui_ux/trend_scan_playbook.md +1 -1
  38. package/assets/init/.qfai/assistant/skills/qfai-discussion/references/ui_ux_best_practices.md +6 -4
  39. package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/01_Context.md +2 -2
  40. package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/03_Story-Workshop.md +1 -1
  41. package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/04_Sources.md +40 -6
  42. package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/14_Review-Request.md +7 -7
  43. package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/review/Rxx_reviewer.md +3 -3
  44. package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/review/review_request.md +4 -3
  45. package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/review/summary.json +3 -0
  46. package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/uiux/00_index.md +14 -5
  47. package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/uiux/40_screen_contracts.md +17 -1
  48. package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/uiux/50_review_input_bundle.md +13 -8
  49. package/assets/init/.qfai/assistant/skills/qfai-implement/SKILL.md +83 -84
  50. package/assets/init/.qfai/assistant/skills/qfai-implement/references/checkpoint-verification.md +339 -39
  51. package/assets/init/.qfai/assistant/skills/qfai-implement/references/cross-spec-ownership.md +1 -1
  52. package/assets/init/.qfai/assistant/skills/qfai-implement/references/evidence-revision.md +348 -15
  53. package/assets/init/.qfai/assistant/skills/qfai-implement/references/execution-ledger.md +203 -32
  54. package/assets/init/.qfai/assistant/skills/qfai-implement/references/final-checklist.md +159 -12
  55. package/assets/init/.qfai/assistant/skills/qfai-implement/references/finding-classification.md +70 -5
  56. package/assets/init/.qfai/assistant/skills/qfai-implement/references/ledger-preconditions.md +55 -14
  57. package/assets/init/.qfai/assistant/skills/qfai-implement/references/parallelization-policy.md +92 -3
  58. package/assets/init/.qfai/assistant/skills/qfai-implement/references/red-not-observable.md +48 -6
  59. package/assets/init/.qfai/assistant/skills/qfai-implement/references/relevant-test-suite.md +13 -1
  60. package/assets/init/.qfai/assistant/skills/qfai-implement/references/review-artifact-layout.md +71 -9
  61. package/assets/init/.qfai/assistant/skills/qfai-implement/references/round-evidence.md +31 -7
  62. package/assets/init/.qfai/assistant/skills/qfai-implement/references/upstream-artifact-ordering.md +33 -0
  63. package/assets/init/.qfai/assistant/skills/qfai-implement/references/volume-policy.md +19 -12
  64. package/assets/init/.qfai/assistant/skills/qfai-prototyping/SKILL.md +76 -8
  65. package/assets/init/.qfai/assistant/skills/qfai-prototyping/references/design-md-spec.md +20 -0
  66. package/assets/init/.qfai/assistant/skills/qfai-prototyping/references/evidence-requirements.md +7 -4
  67. package/assets/init/.qfai/assistant/skills/qfai-prototyping/references/generator-prompt.md +83 -22
  68. package/assets/init/.qfai/assistant/skills/qfai-prototyping/references/reviewer-prompt.md +29 -4
  69. package/assets/init/.qfai/assistant/skills/qfai-sdd/SKILL.md +134 -20
  70. package/assets/init/.qfai/assistant/skills/qfai-sdd/references/contract-artifact-rules.md +31 -3
  71. package/assets/init/.qfai/assistant/skills/qfai-sdd/references/review-cycle-playbook.md +22 -1
  72. package/assets/init/.qfai/assistant/skills/qfai-sdd/references/sdd-execution-playbook.md +41 -5
  73. package/assets/init/.qfai/assistant/skills/qfai-sdd/references/sdd-phase-checklists.md +16 -4
  74. package/assets/init/.qfai/assistant/skills/qfai-sdd/references/sdd-triage.md +77 -7
  75. package/assets/init/.qfai/assistant/skills/qfai-sdd/references/spec-traceability-rules.md +60 -11
  76. package/assets/init/.qfai/assistant/skills/qfai-sdd/references/ui-design-contract-normalization.md +9 -3
  77. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/change-request.md +14 -1
  78. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/contracts/ui-contract.sample.yaml +13 -3
  79. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/evidence/sdd-spec.md +5 -1
  80. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/report/preflight_summary.md +3 -2
  81. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/_policies/04_Business-Flow.md +4 -1
  82. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/_policies/05_Contracts.md +12 -5
  83. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/_policies/11_Slice-Policy.md +8 -9
  84. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/spec/02_User-stories.md +9 -0
  85. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/spec/tdd/test-list.md +68 -23
  86. package/assets/init/.qfai/assistant/skills/qfai-verify/SKILL.md +4 -4
  87. package/assets/init/.qfai/assistant/skills/qfai-verify/references/articles.md +1 -1
  88. package/assets/init/.qfai/assistant/skills/qfai-verify/references/validate-json-schema.md +79 -0
  89. package/assets/init/.qfai/assistant/skills/web-research/SKILL.md +3 -2
  90. package/assets/init/root/.github/workflows/qfai-tests.yml +318 -0
  91. package/assets/init/root/.github/workflows/qfai-validate.yml +327 -24
  92. package/assets/init/root/qfai.config.yaml +11 -2
  93. package/dist/cli/index.cjs +25083 -11488
  94. package/dist/cli/index.cjs.map +1 -1
  95. package/dist/cli/index.mjs +25216 -11589
  96. package/dist/cli/index.mjs.map +1 -1
  97. package/dist/index.cjs +16731 -8386
  98. package/dist/index.cjs.map +1 -1
  99. package/dist/index.d.cts +407 -17
  100. package/dist/index.d.ts +407 -17
  101. package/dist/index.mjs +16701 -8370
  102. package/dist/index.mjs.map +1 -1
  103. package/package.json +6 -1
@@ -0,0 +1,71 @@
1
+ # Scaffolding
2
+
3
+ `npx qfai atdd scaffold --spec <spec-id>` bulk-emits one placeholder test per
4
+ `TC-*` **this skill owns**, each carrying its `QFAI:SPEC-XXXX:TC-YYYY`
5
+ annotation. Skeletons land in `tests/integration/<spec-id>/` — the directory
6
+ `QFAI-ATDD-112` scans — so a filled-in skeleton counts as coverage. It is
7
+ idempotent: existing files are left untouched.
8
+
9
+ ## Which language the skeleton is written in
10
+
11
+ The skeleton's language is derived from
12
+ `qfai.config.yaml#validation.traceability.testFileGlobs` — the same key
13
+ `QFAI-ATDD-112` derives its scan extensions from, so the file the command
14
+ writes is always a file the gate reads. A JS/TS glob set (and the unconfigured
15
+ default) gets a `vitest` body; a Python one gets a `unittest.TestCase`
16
+ subclass, which pytest **and** `python -m unittest discover` both collect —
17
+ the globs name an extension, never a runner, and a module-level `def test_...`
18
+ that unittest never collects would let you clear the gate with zero tests run.
19
+ A stack with neither is refused with a non-zero exit naming the derived
20
+ pattern: author those TCs by hand in `tests/integration/<spec-id>/`, keeping
21
+ the `QFAI:SPEC-XXXX:TC-YYYY` annotation.
22
+
23
+ The file **path** follows the same key one level finer. The extension is one
24
+ the globs actually admit (`tests/**/*.test.js` gets `.test.js`, not `.test.ts`),
25
+ and the basename follows the configured convention — `test_<tc_id>.py` or
26
+ `<tc_id>_test.py`, `<TC-ID>.test.ts` or `<TC-ID>.spec.ts`; extglob patterns
27
+ (`*.@(test|spec).ts`) are read the way fast-glob reads them. `QFAI-ATDD-112`
28
+ widens to the bare extension, so a file your runner does not collect would
29
+ clear the coverage gate with a test that never runs. The check is made against
30
+ the **whole** destination path, directories included, and it is case-sensitive
31
+ the way fast-glob is: globs that only cover `src/**` do not reach
32
+ `tests/integration/<spec-id>/`, and `TEST_*.py` does not admit the lowercase
33
+ name the command emits, so it refuses in both cases rather than writing a file
34
+ nothing runs. `testFileExcludeGlobs` is applied as well — a destination you
35
+ have excluded is one your own test scan skips. When several languages are
36
+ configured, every one of them is tried and the first whose path your globs
37
+ admit wins, so a repository with `src/**/*.test.ts` and `tests/**/*.py` gets
38
+ the Python skeleton. Add a glob that covers the scaffold directory, or author
39
+ those TCs by hand.
40
+
41
+ A skeleton an earlier run wrote under a different convention is removed only
42
+ while it is still the untouched skeleton the command emitted. Any file you have
43
+ edited is kept and named on stderr so you can port it — including one where you
44
+ implemented the assertion inside `it.skip(...)` but left the `TODO` comment
45
+ above it, which still looks like a placeholder to the marker heuristic.
46
+
47
+ The refusal is evaluated only when the spec actually has L3 skeletons to emit,
48
+ so sweeping many specs on an unsupported stack still succeeds for the ones with
49
+ nothing in scope.
50
+
51
+ ## Which TCs are skipped, and why
52
+
53
+ Skeletons are integration-only, so two groups of TC are skipped, both named on
54
+ stderr.
55
+
56
+ `L1` / `Unit` and `L2` / `Component`: their skeleton would land in
57
+ `tests/integration/**`, the duplication the Coverage obligations section
58
+ forbids, and `QFAI-ATDD-112` would not count it — filling one in discharges
59
+ nothing. Their ledger row under `/qfai-implement` is where they are owed.
60
+
61
+ `L4` / `API` and `L5` / `E2E`: their home is `tests/api/**` / `tests/e2e/**`, so
62
+ an integration skeleton is both uncounted and a forbidden reference
63
+ (`QFAI-ATDD-123`). Author those by hand in their own directory — or re-file the
64
+ obligation as `CON-API-*` / `US-*`, which is what a `TC-*` at L4/L5 usually
65
+ means (`.qfai/assistant/catalog/test-layers.md#annotation-routing`).
66
+
67
+ ## A skeleton is not a discharge
68
+
69
+ A skeleton left in placeholder shape across repeated validate runs escalates
70
+ (`qfai.config.yaml#atdd.scaffoldEscalateCycles`), so scaffolding is a start, not
71
+ a discharge of the obligation.
@@ -0,0 +1,124 @@
1
+ # A shared test artifact outlives the row that recorded it
2
+
3
+ P1c closes one row before the next test is written, so the `RED test manifest`
4
+ of a `done` row addresses a fixture, snapshot or helper that a **later** row may
5
+ still edit. The hash then disagrees with the tree, and a `done` row has no
6
+ re-entry edge of its own — so the spec either accepts stale evidence or cannot
7
+ be closed.
8
+
9
+ **Stabilise first where the row can see it coming.** The artifacts an
10
+ acceptance test owns — fixtures, snapshots, helpers under the test tree — are
11
+ written in P2-P4 with every row's obligation in view, not grown one row at a
12
+ time. Where that holds, no later row edits them and the manifests stay true.
13
+
14
+ **Where a later row does have to edit one, it re-verifies the rows that read
15
+ it — and records that on itself.** The editing row already runs its own
16
+ selector; run the earlier rows' selectors in the same pass and record them in
17
+ **the editing row's** entry, under `Shared-artifact re-verify`: one line per
18
+ earlier row naming **its spec and `TDD-ID` together** (`spec-0002/TDD-0001`) and
19
+ the evidence file that row's anchor points at, then the selector re-run, its
20
+ result, and the artifact's new manifest and hash. A `TDD-ID` is unique within a
21
+ ledger, not across them, and one fixture is read by acceptance tests from
22
+ several specs — named by id alone, a re-verify could clear a hash mismatch on a
23
+ row in the wrong spec, or fail to clear the right one.
24
+
25
+ **The machine-readable form is fixed.** Write a `Shared-artifact re-verify`
26
+ heading with one `spec-NNNN/TDD-NNNN` subsection per consumer one level below
27
+ it, carrying these fields: `Evidence file`, `Revision`, `Selector`,
28
+ `Re-verify command`, `Re-verify result`, `Proof command`, `Proof result`,
29
+ `Restored GREEN command`, `Restored GREEN result`, `RED test manifest`, and
30
+ `RED test hash`. Both GREEN results are PASS outcomes, the proof result is the
31
+ observed failure, `Revision` names a tree in one of the two forms
32
+ `../../qfai-implement/references/evidence-revision.md` defines, and every
33
+ command is the exact command executed. Gate item 10 accepts a moved current
34
+ manifest only when this complete subsection targets the same spec/item,
35
+ evidence file and selector, and its manifest/hash recompute from the current
36
+ artifacts. Prose mentioning a re-run, or a subsection for another item, clears
37
+ nothing.
38
+
39
+ **And it is fixed where it is written, not only in what it says.** The record
40
+ goes **inside the editing row's own entry** — `#### Shared-artifact re-verify`
41
+ under that `### TDD-NNNN`, ahead of its review and checkpoint fields, so the
42
+ `audited evidence hash` its reviewers recorded covers these bytes. That
43
+ placement is the whole claim: a block written anywhere else is a paragraph
44
+ nobody audited, and one appended to the consumer's own `done` entry would be
45
+ the row clearing its own mismatch. Gate item 10 reads a record only from an
46
+ entry whose recorded `Spec` and `Code quality audited evidence hash` still
47
+ recompute over it, and never from the consumer's own item.
48
+
49
+ **When this stage has no row of its own, the record is stage-level.** A fresh
50
+ spec is the ordinary case here and can own no ATDD row at all, while still
51
+ creating and editing the fixtures a completed spec's handed-over rows read. With
52
+ the record tied to an "editing row" there was nowhere to put it: the re-run was
53
+ made and had no home, so the earlier row's `RED test hash` stayed mismatched
54
+ with nothing able to clear it, or the change was accepted unverified. Write the
55
+ same lines under `## Shared-artifact re-verify` in the stage evidence file
56
+ (`.qfai/evidence/coverage-depth-<spec-id>.md`, beside `## Final status`), with
57
+ the same identity — spec and `TDD-ID` together — and the same "a passing re-run
58
+ is not enough on a row that has a proof" rule below. A consumer clearing a
59
+ mismatch reads **both** places: the editing row's entry when one exists, and the
60
+ stage block of any stage that touched the artifact. `/qfai-implement`'s gate
61
+ item 10 does not run on a spec with no rows, so this block is checked where the
62
+ stage's own pack seal is: it is inside the sealed stage evidence, so a record
63
+ added after the fact moves the seal. A stage block is read only from
64
+ `.qfai/evidence/coverage-depth-<spec-id>.md` and only when that file's
65
+ `## Final status` names its `Review pack` and a `Review pack seal` that still
66
+ recomputes from it — the stage has no item entry to hold an audit hash, so the
67
+ seal is what stands in its place.
68
+
69
+ **A passing re-run is not enough on a row that has a proof.** Weakening an
70
+ assertion helper, a snapshot or an expected-value fixture leaves the earlier
71
+ row's selector passing while making it tautological — and its recorded
72
+ `Oracle proof` was taken against the artifact as it was, so it no longer shows
73
+ what `qa-gatekeeper` requires: that the **current** test fails when the
74
+ predicate the row owns is broken. For each affected row that carries one,
75
+ re-run its original mutation — the one its `Oracle proof` plan or
76
+ `Satisfied-by` names — under the changed artifact, capture the failure, revert,
77
+ and record the restored GREEN, in the same `Shared-artifact re-verify` block.
78
+ A row whose mutation no longer fails the test is the tautology this exists to
79
+ catch, and the editing row does not reach `done` until it is repaired.
80
+
81
+ **This stage owns no production agent, so on a zero-row stage the mutation is
82
+ handed over.** Every phase here authors tests; none edits production code, and
83
+ the rows being re-verified are already `done`, so `/qfai-implement`'s named-row,
84
+ `todo` and `review-fix` entry paths do not reach them either. Left as written,
85
+ the stage had two ways out and both were wrong: edit production in breach of its
86
+ own Non-goals, or leave the shared fixture's mismatch permanently unclearable.
87
+ So define the handoff explicitly, and keep it transient: hand
88
+ `/qfai-implement` a **mutation-only request** naming, per affected row, its
89
+ `spec/TDD-ID`, the mutation its `Oracle proof` plan or `Satisfied-by` names, and
90
+ the selector to run under the changed artifact. That skill applies the mutation,
91
+ captures the failure, **reverts it in the same step** and returns the pair. It
92
+ does **not** reopen the row: the status stays `done`, no round block is opened,
93
+ and nothing is written to that row's evidence — the returned proof is recorded
94
+ here, in this stage's `Shared-artifact re-verify` block, like every other line
95
+ in it. A `done` row has no legal transition that would let it re-observe
96
+ anything, which is exactly why the proof belongs to the stage that moved the
97
+ artifact rather than to the row that owns the test. **A row whose re-run fails is not
98
+ re-verified** — it is a regression the editing row introduced, and the editing
99
+ row does not reach `done` until it is fixed, exactly as any other failure in
100
+ its own checkpoint.
101
+
102
+ **The earlier rows' entries are not touched**, and that is deliberate on two
103
+ counts. There is no legal reopen for them: `done` has one exit, the upstream
104
+ reset, and it requires an approved upstream change — a sibling editing a fixture
105
+ is not one. And their evidence is a record of an observation, not a claim about
106
+ the present: a `RED test hash` addresses the manifest **as it was when that RED
107
+ was taken**, which is the only thing it can honestly say. Appending to them
108
+ would also break the very verdicts that closed them, since the audit hash covers
109
+ the entry.
110
+
111
+ **And the consumer has to accept that pairing.** The completion gate
112
+ recomputes `RED test hash` for every handed-over row from the current manifest,
113
+ so an earlier row whose shared artifact was edited mismatches **by
114
+ construction** — and the mismatch route sends it back here for a fresh RED,
115
+ which a `done` row cannot take. A mismatch is cleared instead by a
116
+ `Shared-artifact re-verify` entry on the editing row that names this `TDD-ID`,
117
+ records the re-run and the re-taken proof, and carries the artifact's new
118
+ manifest and hash: that is the evidence the recomputation was looking for, made
119
+ where a row is still open. Without such an entry the mismatch stands.
120
+
121
+ So the pairing is: the earlier row keeps the observation it made, and the row
122
+ that moved the ground under it carries the proof that the observation still
123
+ holds. The editing row's own reviewers and checkpoint audit that proof, which is
124
+ what makes it evidence rather than an assertion.
@@ -0,0 +1,34 @@
1
+ # A project whose manifest predates this contract
2
+
3
+ `npx qfai init --force` regenerates `assistant/skills/**` and `assistant/agents/**`
4
+ but leaves `assistant/manifest/**` alone: those are the declarative files
5
+ `qfai-configure` owns, and overwriting a project's adjusted agent taxonomy is
6
+ the worse failure. So an existing project can take this skill's update without
7
+ taking the `red` phase the update relies on.
8
+
9
+ **Two files are stale, not one.** `agent-routing.yml` is the obvious one, and
10
+ `agent-catalog.yml` carries each role's `developer_instructions` — the reviewer's
11
+ own contract — which `constitution/agent-selection.md` treats as SSOT alongside
12
+ routing. An old catalog's `qa-gatekeeper` does not know that `Satisfied-by` takes
13
+ a path and symbol, that an ATDD row's evidence lives in `atdd-<spec-id>.md`, that
14
+ a RED-time Oracle proof is a plan, or that an item cycle is exempt from the
15
+ completion inputs — so it REVISEs correct handoffs, and routing it by hand does
16
+ not help.
17
+
18
+ The gate still applies, and the remedy is to bring both files forward:
19
+
20
+ 1. **Diff the two files against the installed package** —
21
+ `node_modules/qfai/assets/init/.qfai/assistant/manifest/agent-catalog.yml` and
22
+ `agent-routing.yml` — and merge the shipped roles' contracts in, keeping the
23
+ project's own routing choices and any roles it added. This is the step that
24
+ actually moves the files. `/qfai-configure` owns these manifests as
25
+ artifacts, which is why `init --force` leaves them alone, but it edits what
26
+ the project has rather than reconciling it against the package: there is no
27
+ migration to invoke, so do not wait for one.
28
+ 2. **Until that merge has run**, route `qa-gatekeeper` for the branch-1 rows by
29
+ hand at P1b **and state in the evidence file that the catalog predates this
30
+ contract**, so a REVISE that cites a rule the current contract does not have
31
+ is read as the stale input it is rather than as a finding about the row.
32
+
33
+ A missing phase is a stale manifest, never the gate not applying — and the same
34
+ is true of the production owners `qfai-implement`'s red phase needs for step 3c.
@@ -3,6 +3,20 @@
3
3
  This checklist ensures test cases cover not only happy paths but also boundary values, error paths, edge cases, and combinatorial scenarios.
4
4
  Reviewers MUST use this checklist when evaluating test case completeness during ATDD and SDD review gates.
5
5
 
6
+ ## Where the matrix lives
7
+
8
+ Re-running `/qfai-atdd` recomputes which cells are `❌`. It does not recompute
9
+ _why_ an uncoverable obligation was accepted, and that judgement is what
10
+ discharges the "no unjustified `❌`" gate — so the matrix is a **governance
11
+ record**, not a regenerable log.
12
+
13
+ The per-item ATDD evidence is committed because ledger anchors resolve into it,
14
+ but the matrix remains a separate governance artifact with its own validation
15
+ contract and lifecycle. Embedding it in a ledger-evidence entry would not
16
+ satisfy that contract. Write the matrix and one justification per `❌` to
17
+ `.qfai/evidence/coverage-depth-<spec-id>.md`; the stage evidence file links to
18
+ it rather than restating it.
19
+
6
20
  ## 1. Equivalence Partitioning (同値分割)
7
21
 
8
22
  For each input parameter or condition:
@@ -79,6 +93,13 @@ case's assertion can fail. A test that cannot fail satisfies every category.
79
93
  Reviewers and test-design-analysts MUST produce this matrix for each spec under review.
80
94
  Mark each cell: ✅ covered, ⚠️ partial, ❌ missing.
81
95
 
96
+ **Home: `.qfai/evidence/coverage-depth-<spec-id>.md`.** That path is negated in
97
+ the managed `.gitignore` block, so the matrix and the justifications below it
98
+ are committed. The per-item `atdd-<spec-id>.md` is committed too, but it is the
99
+ ledger's evidence payload, not the matrix artifact that the PASS/REVISE criteria
100
+ below read. Write the matrix once, in its own file, and link it from the stage
101
+ evidence.
102
+
82
103
  | US/TC ID | Normal path | Error path | Boundary values | Special values | State transitions | Combinatorial | Oracle strength | Status |
83
104
  | -------- | ----------- | ---------- | --------------- | -------------- | ----------------- | ------------- | --------------- | ------ |
84
105
  | US-0001 | ✅/⚠️/❌ | ✅/⚠️/❌ | ✅/⚠️/❌ | ✅/⚠️/❌ | ✅/⚠️/❌ | ✅/⚠️/❌ | ✅/⚠️/❌ | — |
@@ -91,9 +112,25 @@ Mark each cell: ✅ covered, ⚠️ partial, ❌ missing.
91
112
  category cells are ✅ and whose Oracle strength cell is ❌ is a REVISE: it has
92
113
  cases in every category and no evidence that any of them can fail.
93
114
  - **REVISE**: Any cell is ❌ without an explicit justification (e.g., Decision Record).
115
+ - **A justification counts only where it survives.** It goes under the matrix in
116
+ `.qfai/evidence/coverage-depth-<spec-id>.md`, naming the cell, why the
117
+ obligation is not coverable at this layer, and the `DR-*` or `CR-*` that
118
+ carries the decision when one exists. A justification recorded anywhere else
119
+ under `.qfai/evidence/**` does not satisfy the matrix's dedicated artifact
120
+ contract and cannot discharge this gate.
94
121
 
95
122
  ### Usage
96
123
 
97
124
  - `test-design-analyst`: Produce this matrix when defining coverage obligations. Flag ❌ cells as gaps.
98
- - `qa-gatekeeper`: Verify the matrix exists and no unjustified ❌ cells remain.
125
+ - `qa-gatekeeper`: Verify the matrix exists and no unjustified ❌ cells remain. Read
126
+ `.qfai/evidence/coverage-depth-<spec-id>.md`; a matrix that exists only in an
127
+ ATDD per-item evidence file is a missing matrix.
99
128
  - `completion-reviewer`: Confirm the matrix was reviewed and any ⚠️ cells have rationale.
129
+ - `npx qfai validate --profile atdd` reports the three file-level facts the readings
130
+ above assume: `QFAI-ATDD-131` when a spec with ATDD-owned tests has no matrix,
131
+ `QFAI-ATDD-132` when the matrix is excluded by a `.gitignore` — any of them,
132
+ from the git worktree root down — without already being tracked, and
133
+ `QFAI-ATDD-133` when the stage evidence has no `## Coverage Depth Matrix`
134
+ section at all, inlines the table, points at no matrix file, or points at one
135
+ without the counted `✅ N / ⚠️ N / ❌ N` totals beside it. None of them reads
136
+ the cells — that judgement stays with the reviewer.
@@ -122,8 +122,8 @@ Follow `.qfai/assistant/constitution/shared-skill-operating-baseline.md#delta-re
122
122
 
123
123
  - Only update `qfai.config.yaml`, `.qfai/assistant/manifest/*` + `.qfai/assistant/catalog/*`, `.qfai/assistant/constitution/quality.md` (gate capabilities only — never the surrounding rules), and `.qfai/evidence/configure-<run-id>.md` unless explicitly asked.
124
124
  - You MUST produce the required evidence file: `.qfai/evidence/configure-<run-id>.md`.
125
- - `.qfai/evidence/` is intentionally NOT tracked by Git. The mechanism is the QFAI-managed block `npx qfai init` writes into the **project root** `.gitignore` (marker `# ── QFAI managed (generated by qfai init) ──`), which carries `.qfai/evidence/*`. A project generated by `npx qfai init` has no per-directory `.qfai/evidence/.gitignore`: nothing under the init asset set ships one, so an operator who needs to change what is tracked edits the root file, not a directory-local one. (qfai's own repository does carry that file, as a working-tree file outside the init assets — which is why the claim above used to read the other way.)
126
- - Do NOT commit evidence files; summarize key outcomes in the PR description instead.
125
+ - The run-scoped `.qfai/evidence/configure-<run-id>.md` remains local and ignored. The mechanism is the QFAI-managed block `npx qfai init` writes into the **project root** `.gitignore` (marker `# ── QFAI managed (generated by qfai init) ──`), which carries `.qfai/evidence/*`. A project generated by `npx qfai init` has no per-directory `.qfai/evidence/.gitignore`: nothing under the init asset set ships one, so an operator who needs to change what is tracked edits the root file, not a directory-local one. (qfai's own repository does carry that file, as a working-tree file outside the init assets — which is why the claim above used to read the other way.)
126
+ - Durable per-item `implement-*.md` and `atdd-*.md` governance records are committed through the managed negations. Do not commit the configure run file; summarize its key outcomes in the PR description instead.
127
127
  - You MUST run the mandatory checks listed below and record outcomes.
128
128
  - You MUST stop and escalate if tooling choices or runnable path remain ambiguous.
129
129
  - Completion must be approved by a reviewer who did not modify the config.
@@ -223,7 +223,7 @@ Evidence must include:
223
223
 
224
224
  ## Non-Negotiable Principles (QFAI Articles)
225
225
 
226
- These principles are inspired by "constitution / articles" patterns used by other agent frameworks, but tailored to QFAI.
226
+ These principles are inspired by "constitution / articles" patterns used by other agent frameworks, but adapted to QFAI.
227
227
 
228
228
  1. **SDD First (Specification is the source of truth)**
229
229
  If there is a conflict between code and spec, treat the spec as authoritative and either (a) fix code or (b) raise an explicit Open Question to change the spec.
@@ -476,4 +476,5 @@ A skill MAY narrow the auto-decide bucket (drop entries) but MUST NOT widen it.
476
476
  project_memory:
477
477
 
478
478
  - qfai-configure is the user-facing entrypoint for editing `qfai.config.yaml` and the `.qfai/assistant/manifest/` declarative manifests; edits to those files MUST go through this skill so the agent-catalog / agent-routing / review-profiles SSOTs stay consistent.
479
+ - Exception: `agent-catalog.yml#agents[].developer_instructions` is a derived copy of `.qfai/assistant/agents/<id>.md`. Edit the markdown file — the source — then bring the block back into agreement by copying that file from its `## Mission` heading onward, verbatim; never author new content in the block. `QFAI-AGENT-014` warns when the two diverge and when the block is missing.
479
480
  - Run after every major workflow change to refresh the consuming project to the current QFAI baseline. Do NOT edit `qfai.config.yaml` directly when the skill is available.
@@ -42,9 +42,11 @@ Produce a unified 15-file discussion pack plus exploration-first UI sidecars so
42
42
 
43
43
  ## UI-bearing Canonical Sidecar Family
44
44
 
45
- UI-bearing packs must produce, as primary truth: `uiux/40_screen_contracts.md`, `uiux/50_review_input_bundle.md`. They MUST also emit a draft brand SSOT at the **consuming-project root**:
45
+ Every UI-bearing pack must produce, as primary truth: `uiux/00_index.md`, `uiux/40_screen_contracts.md`, `uiux/50_review_input_bundle.md`. Only a pack on a **visual-prototyping surface** (`web`, `mobile`, `desktop` or `mixed`, as `primary_surface` or in `secondary_surfaces`) MUST additionally emit a draft brand SSOT at the **consuming-project root**; a cli-only pack MUST NOT author it:
46
46
 
47
- - `<consuming-project-root>/DESIGN.md` — brand SSOT consumed by `/qfai-sdd` (freezes its sha256 in `.qfai/contracts/design/DESIGN.md.lock.yaml`) and by `/qfai-prototyping` (iterates against locked tokens). Brand intent (product intent, brand signals, anti-goals, reference pool framed as deviate-from inputs) lives in front-matter + `# Brand Philosophy` body — no separate per-aspect sidecar.
47
+ - `<consuming-project-root>/DESIGN.md` — **visual-prototyping surfaces only.** Brand SSOT consumed by `/qfai-sdd` (freezes its sha256 in `.qfai/contracts/design/DESIGN.md.lock.yaml`) and by `/qfai-prototyping` (iterates against locked tokens). Brand intent (product intent, brand signals, anti-goals, reference pool framed as deviate-from inputs) lives in front-matter + `# Brand Philosophy` body — no separate per-aspect sidecar.
48
+
49
+ Root `DESIGN.md` is required only on the visual-prototyping surfaces (`web`, `mobile`, `desktop`, `mixed`), and the test is the whole classified surface set — `primary_surface` **and** every `secondary_surfaces` entry. Only a **cli-only** pack (`primary_surface: cli`, no visual secondary surface) skips it: it stays `ui_bearing: true` and keeps all three screen-level sidecars, but does NOT author root `DESIGN.md`, because `/qfai-prototyping` rejects `cli` and no downstream reader consumes its `visual.*` tokens. `/qfai-sdd` Phase 0 skips the freeze for the same packs. See `references/ui-bearing-playbook.md#visual-prototyping-surfaces-vs-cli`.
48
50
 
49
51
  ## Required Process
50
52
 
@@ -56,15 +58,15 @@ UI-bearing packs must produce, as primary truth: `uiux/40_screen_contracts.md`,
56
58
  6. Run Example Mapping and capture `Example Seeds`.
57
59
  7. Update `11_OQ-Register.md`, resolve OQs until open count is zero, and move deferred items to `13_Deferred.md`.
58
60
  8. Generate the exploration-first sidecar family for UI-bearing targets.
59
- 9. **Emit root `DESIGN.md` draft** for UI-bearing targets per `references/design-dna-intake.md`. Required when UI-bearing; skip otherwise.
60
- 10. Generate `prototyping.yaml` only when the latest discussion pack is UI-bearing and an explicit prototyping recommendation is useful.
61
+ 9. **Emit root `DESIGN.md` draft** per `references/design-dna-intake.md`. Required when any classified surface — primary or secondary — is `web`, `mobile`, `desktop` or `mixed`; skip for cli-only and non-ui targets.
62
+ 10. Generate `prototyping.yaml` only when the latest discussion pack targets a prototyping execution surface (`web`, `mobile`, `desktop`, `mixed`) and an explicit prototyping recommendation is useful. A cli-only pack emits none — `/qfai-prototyping` rejects `cli`.
61
63
  11. Request review and record the Reviewer result.
62
64
 
63
65
  For UI-bearing targets, follow `references/design-dna-intake.md` while authoring the UI/UX sidecars. Keep this `SKILL.md` compact; put detailed interview prompts and examples in the reference file.
64
66
 
65
67
  ## UI-bearing Authoring Requirements
66
68
 
67
- - Root `DESIGN.md` front-matter must define `brand` (name, archetype, voice), `audience` (emotion, do_not_look_like), and the full `visual.*` token tree (colors, typography, spacing, radius, shadow).
69
+ - Root `DESIGN.md` front-matter must define `brand` (name, archetype, voice), `audience` (emotion, do_not_look_like), and the full `visual.*` token tree (colors, typography, spacing, radius, shadow). Visual-prototyping surfaces only — a cli-only pack omits root `DESIGN.md` entirely.
68
70
  - `# Brand Philosophy` body documents do/don't, brand signals, and exploration references framed as **deviate-from** inputs (not imitate-this) for the downstream `/qfai-prototyping` reviewer.
69
71
  - `40_screen_contracts.md` defines each screen contract per the template schema; `50_review_input_bundle.md` documents review inputs for downstream skills.
70
72
  - Evaluation axes are global constants (4-step ordinal: weak / acceptable / strong / exceptional) and are not authored as discussion sidecars.
@@ -83,7 +85,7 @@ Before declaring completion, you MUST:
83
85
  - ensure `Disposition: open` count is zero in `11_OQ-Register.md`;
84
86
  - ensure every deferred item has full metadata in `13_Deferred.md`;
85
87
  - ensure `02_Inception-Deck.md` and `03_Story-Workshop.md` include Mermaid diagrams;
86
- - ensure the UI-bearing sidecar family is complete and the root `DESIGN.md` draft exists at the consuming-project root and parses as valid front-matter;
88
+ - ensure the UI-bearing sidecar family is complete, and — when any classified surface (primary or secondary) is `web`, `mobile`, `desktop` or `mixed` — that the root `DESIGN.md` draft exists at the consuming-project root and parses as valid front-matter;
87
89
  - run `npx qfai validate --profile discussion --fail-on error` and fix discussion-owned findings;
88
90
  - avoid selecting a single visual winner in discussion artifacts.
89
91
 
@@ -117,7 +119,7 @@ Follow `.qfai/assistant/constitution/shared-skill-delegation-baseline.md`.
117
119
 
118
120
  ## Work Orders Summary
119
121
 
120
- Use the shared schema (per-row `Status (PASS/REVISE/PENDING)` column, reviewer response `Result: PASS | REVISE`).
122
+ Use the shared schema (per-row `Status (PASS/REVISE/PENDING)` column, reviewer response `Reviewer role:` + `Reviewed artifact:` + `Result: PASS | REVISE`). A response missing the role or artifact line is not a verdict; re-request it.
121
123
 
122
124
  ## Completion Message & Next Actions (MUST)
123
125
 
@@ -149,6 +151,6 @@ A skill MAY narrow the auto-decide bucket (drop entries) but MUST NOT widen it.
149
151
 
150
152
  project_memory:
151
153
 
152
- - 15-file mandatory output set is fixed; the UI-bearing sidecar family (40_screen_contracts.md + 50_review_input_bundle.md + root DESIGN.md) is required only when the target is UI-bearing.
154
+ - 15-file mandatory output set is fixed; the UI-bearing sidecar family (00_index.md + 40_screen_contracts.md + 50_review_input_bundle.md) is required whenever the target is UI-bearing, cli included, and root DESIGN.md only when a visual-prototyping surface (web/mobile/desktop/mixed) appears as primary or secondary — never for a cli-only pack.
153
155
  - Discussion is planner-first: never pick a single visual winner; carry exploration references as deviate-from inputs, not imitate-this.
154
156
  - Completion requires Disposition: open count = 0 in 11_OQ-Register.md; deferred items must move to 13_Deferred.md with full metadata.
@@ -7,9 +7,11 @@ Use this file for the full completion logic behind `/qfai-discussion`.
7
7
  Completion is blocked until all are true:
8
8
 
9
9
  1. Root `DESIGN.md` exists at the consuming-project root and parses as valid front-matter
10
- (`brand`, `audience`, and the full `visual.*` token tree).
10
+ (`brand`, `audience`, and the full `visual.*` token tree). Required whenever any
11
+ classified surface — `primary_surface` **or** an entry in `secondary_surfaces` — is
12
+ `web`, `mobile`, `desktop` or `mixed`. See `## CLI Packs` below.
11
13
  2. `# Brand Philosophy` body documents do/don't, brand signals, and exploration references
12
- framed as **deviate-from** inputs.
14
+ framed as **deviate-from** inputs. Visual-prototyping surfaces only.
13
15
  3. The canonical `uiux/` family is complete: `00_index.md`, `40_screen_contracts.md`,
14
16
  `50_review_input_bundle.md`.
15
17
  4. Every screen contract in `40_screen_contracts.md` carries the full template schema.
@@ -23,6 +25,25 @@ Evaluation axes are global constants (4-step ordinal: weak / acceptable / strong
23
25
  exceptional) and are NOT authored as discussion sidecars, so no scoring, override, strategy,
24
26
  taste-interview, option-comparison or selected-anchor sidecar is required or permitted.
25
27
 
28
+ ## CLI Packs
29
+
30
+ A **cli-only** pack — `primary_surface: cli` with no `web`/`mobile`/`desktop`/`mixed`
31
+ entry in `secondary_surfaces` — is UI-bearing but is not a visual-prototyping surface,
32
+ so conditions 1 and 2 above do not apply to it:
33
+
34
+ - No root `DESIGN.md` required, and no `visual.*` token tree to author. `/qfai-prototyping`
35
+ rejects `cli`, so nothing downstream ever reads the token values. `/qfai-sdd` Phase 0
36
+ skips the DESIGN.md freeze for a cli-only project, and
37
+ `validators/designContractReadiness.ts` skips `QFAI-DCON-030`/`-031` for it.
38
+ - Conditions 3-7 apply unchanged: all three canonical `uiux/` sidecars, the full
39
+ screen-contract schema, unranked exploration directions, no forbidden legacy sidecar,
40
+ and zero open OQs.
41
+ - `route:` on a `cli` screen contract names the command invocation, not a web path (see
42
+ `ui-bearing-playbook.md#visual-prototyping-surfaces-vs-cli`).
43
+ - No `prototyping.yaml`: `cli` is not a valid prototyping execution surface.
44
+ - `primary_surface: cli` with a visual `secondary_surfaces` entry is NOT a cli-only pack —
45
+ conditions 1 and 2 stay blocking for it.
46
+
26
47
  ## Non-UI Packs
27
48
 
28
49
  - No uiux sidecars required
@@ -18,5 +18,20 @@ Use this file for detailed review-pack handling in `/qfai-discussion`.
18
18
 
19
19
  ## summary.json
20
20
 
21
- - `target.kind` must be `"discussion"`.
21
+ - `target.kind` must be `"discussion"` and `target.path` must be the discussion pack it names — a
22
+ `kind` the path contradicts raises `QFAI-REVIEW-007` and is ignored when deciding which gate the
23
+ pack faces.
24
+ - `producer` must be `"discussion"`, and `review_request.md` carries a matching
25
+ `Producer: discussion` line so the pack is placed before `summary.json` exists. That is what
26
+ makes this stage's gate yours: it judges `producer: "discussion"` packs only, so neither an SDD
27
+ worker's in-flight spec pack nor an implementation one ever fails a discussion cycle. A pack that
28
+ declares no owner at all is judged by both stages, since no other gate would see it.
29
+ - A discussion pack belongs to no spec, so a `--spec` run keeps it: it is a repo-level finding, and
30
+ those stay in every slice.
31
+ - `revision_form: "content-hash"` and `revision` are written here too — the state these verdicts
32
+ describe, as a git rev or `working-tree+<content hash>`
33
+ (`../../qfai-implement/references/evidence-revision.md`). A pack without them raises
34
+ `QFAI-REVIEW-007` in this stage's own hard gate
35
+ (`npx qfai validate --profile discussion --fail-on error`, `rcp_footer.md`) as well as in the
36
+ repo-wide `/qfai-verify --fail-on error`.
22
37
  - Keep rerun history append-only.
@@ -8,14 +8,14 @@ Use this file when `/qfai-discussion` needs the full UI-bearing decision logic.
8
8
 
9
9
  ## Surface Mapping
10
10
 
11
- | Surface | UI-bearing | Result |
12
- | ------- | ---------- | --------------------------------- |
13
- | web | Yes | Generate full uiux sidecar family |
14
- | mobile | Yes | Generate full uiux sidecar family |
15
- | desktop | Yes | Generate full uiux sidecar family |
16
- | cli | Yes | Generate full uiux sidecar family |
17
- | mixed | Yes | Generate full uiux sidecar family |
18
- | non-ui | No | Skip uiux sidecars |
11
+ | Surface | UI-bearing | Result |
12
+ | ------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
13
+ | web | Yes | Generate full uiux sidecar family |
14
+ | mobile | Yes | Generate full uiux sidecar family |
15
+ | desktop | Yes | Generate full uiux sidecar family |
16
+ | cli | Yes | Generate the canonical uiux sidecars (`00_index.md`, `40_screen_contracts.md`, `50_review_input_bundle.md`); no root `DESIGN.md` visual token tree |
17
+ | mixed | Yes | Generate full uiux sidecar family |
18
+ | non-ui | No | Skip uiux sidecars |
19
19
 
20
20
  ## Detection Signals
21
21
 
@@ -26,15 +26,51 @@ Use this file when `/qfai-discussion` needs the full UI-bearing decision logic.
26
26
 
27
27
  ## Sidecar Family SSOT
28
28
 
29
- For UI-bearing packs the brand SSOT is root `DESIGN.md` (drafted by
30
- `/qfai-discussion` and frozen by `/qfai-sdd` Phase 0 into
31
- `.qfai/contracts/design/DESIGN.md.lock.yaml`). The remaining sidecars are
29
+ For UI-bearing packs on a visual-prototyping surface the brand SSOT is root
30
+ `DESIGN.md` (drafted by `/qfai-discussion` and frozen by `/qfai-sdd` Phase 0
31
+ into `.qfai/contracts/design/DESIGN.md.lock.yaml`). The remaining sidecars are
32
32
  the screen-level UX inputs:
33
33
 
34
34
  - `uiux/00_index.md`
35
35
  - `uiux/40_screen_contracts.md`
36
36
  - `uiux/50_review_input_bundle.md`
37
37
 
38
+ ### Visual-prototyping Surfaces vs `cli`
39
+
40
+ Visual-prototyping surfaces are `web`, `mobile`, `desktop` and `mixed` — the
41
+ surfaces `/qfai-prototyping` actually executes. Root `DESIGN.md` and its
42
+ `visual.*` token tree are required **only** when the pack targets one of
43
+ them: the sole consumer of the token values is the prototyping loop's
44
+ DESIGN.md drift scanner, and that loop rejects `cli`.
45
+
46
+ **Judge the whole classified surface set, not `primary_surface` alone.**
47
+ `secondary_surfaces` accepts every UI-bearing surface, so
48
+ `primary_surface: cli` with `secondary_surfaces: [web]` still ships a visual
49
+ surface and still needs the token SSOT. The carve-out applies only to a
50
+ **cli-only** pack: `primary_surface: cli` with no visual surface anywhere in
51
+ `secondary_surfaces`.
52
+
53
+ A cli-only pack stays `ui_bearing: true` and keeps all three screen-level UX
54
+ inputs above — those have downstream readers. It must NOT be blocked on
55
+ inventing brand colors, font stacks, a type scale, spacing tokens, radii or
56
+ shadows:
57
+
58
+ - Do not author root `DESIGN.md` for a cli-only pack. `/qfai-sdd` Phase 0
59
+ skips the DESIGN.md freeze for it, and nothing on the `cli` path reads a
60
+ token value.
61
+ - Screen contracts stay mandatory, including their `route:` field, which on
62
+ `cli` names the command invocation (e.g. `route: myapp deploy --dry-run`)
63
+ instead of a web path. `templates/uiux/40_screen_contracts.md` carries the
64
+ per-surface `route:` meanings.
65
+ - No `prototyping.yaml`: `cli` is not a valid prototyping execution surface,
66
+ so a recommendation naming it cannot be executed downstream.
67
+ - `templates/uiux/00_index.md` carries the same carve-out: the three sidecars
68
+ are the whole family for a cli-only pack, with no root `DESIGN.md` beside them.
69
+ - Downstream, `/qfai-implement`'s Visual Review Guard drops the four
70
+ design-contract inputs (root `DESIGN.md`, its lock, `design-system.yaml`,
71
+ `prototype-handoff.yaml`) and both prototype-evidence inputs for a cli-only
72
+ target, leaving `.qfai/contracts/ui/*.yaml` as its UI contract input.
73
+
38
74
  ### Trend Scan SSOT
39
75
 
40
76
  Trend Scan is **not** a sidecar file. Trend Scan lives at
@@ -44,7 +44,7 @@ Always translate a reference into:
44
44
  - whether it fits the product's users and task frequency;
45
45
  - whether it improves or harms clarity;
46
46
  - whether it changes the brand direction recorded in root `DESIGN.md`;
47
- - whether it affects the selected anchor or contracts;
47
+ - whether it affects the screen contracts in `uiux/40_screen_contracts.md`;
48
48
  - whether it should be adopted, adapted, or rejected.
49
49
 
50
50
  ## Rejection Rules
@@ -105,10 +105,12 @@ packs it resolves through:
105
105
  - review handoff: `uiux/50_review_input_bundle.md`
106
106
 
107
107
  Those three are the entire canonical sidecar family. Evaluation axes are global constants
108
- (4-step ordinal: weak / acceptable / strong / exceptional, in
109
- `core/prototyping/evaluatorReview.ts#ORDINAL_AXES`) and are not authored as discussion
110
- sidecars. Discussion is planner-first: it carries exploration directions unranked and does
111
- not select a single visual winner, so there is no strategy, taste-interview, scoring,
108
+ (4-step ordinal: weak / acceptable / strong / exceptional) fixed by the review validation the
109
+ QFAI CLI applies — not by any file in this tree. The shipped
110
+ `.qfai/assistant/skills/qfai-prototyping/references/reviewer-prompt.md` restates that axis set
111
+ for the reviewer prompt; editing it does not change the set the CLI accepts. Axes are not
112
+ authored as discussion sidecars. Discussion is planner-first: it carries exploration directions
113
+ unranked and does not select a single visual winner, so there is no strategy, taste-interview, scoring,
112
114
  override, option-comparison or selected-anchor sidecar. Do NOT create
113
115
  `10_implementation_strategy.md`, `11_design_taste_interview.md`, the `20-24`
114
116
  design-evaluation family, `30_option_comparison.md`, or `31_selected_anchor_screen.md` —
@@ -16,8 +16,8 @@ Notes:
16
16
 
17
17
  - `primary_surface` is a classification field. Valid values: `web|mobile|desktop|cli|mixed|non-ui`.
18
18
  - `non-ui` is only valid when `ui_bearing: false`. It is a classification value, not a prototyping surface.
19
- - `cli` is a UI-bearing surface. When classified as `cli`, set `ui_bearing: true`.
20
- - Prototyping surfaces (used in `prototyping.yaml`) are a subset: `web|mobile|desktop|cli|mixed`.
19
+ - `cli` is a UI-bearing surface. When classified as `cli`, set `ui_bearing: true`. `cli` is not a visual-prototyping surface, so a **cli-only** pack — `primary_surface: cli` with no `web`/`mobile`/`desktop`/`mixed` entry in `secondary_surfaces` — does not author root `DESIGN.md` (see `references/ui-bearing-playbook.md#visual-prototyping-surfaces-vs-cli`). A visual `secondary_surfaces` entry still requires it.
20
+ - Prototyping execution surfaces (used in `prototyping.yaml`) are a narrower subset: `web|mobile|desktop|mixed`. `cli` and `non-ui` are classification values only — `/qfai-prototyping` rejects them, so a cli-only pack emits no `prototyping.yaml`.
21
21
 
22
22
  ## Metadata
23
23
 
@@ -81,7 +81,7 @@ Screen-level contract details are finalized in `uiux/40_screen_contracts.md`. Pr
81
81
  ## Appendix: Screen Mock — Optional Fallback (HTML+CSS)
82
82
 
83
83
  <!-- Optional fallback only — do not use as the primary UI definition artifact.
84
- Include only when it materially clarifies the selected anchor.
84
+ Include only when it materially clarifies a behavior obligation that prose cannot.
85
85
  Behavior Obligations and sidecar artifacts (uiux/) are the primary UI definitions.
86
86
  The required state SSOT is uiux/40_screen_contracts.md (`default/loading/empty/error`).
87
87
  Links MUST be anchor-form (`<a href="#name">`) — never same-origin absolute