qfai 1.8.9 → 1.8.10

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/README.md CHANGED
@@ -18,11 +18,19 @@ The agent reads the repository, produces the required artifacts, and iterates un
18
18
  ## Release status
19
19
 
20
20
  - Release posture: runtime truthfulness is enforced.
21
- - Prototyping is UI-only and runs a single-thread evolution loop driven by
22
- `qfai prototyping iterate --cycle <n>`, with deterministic stop conditions
23
- (exit codes 0 continue / 64 convergence / 65 max-iterations / 2 input error).
21
+ - Prototyping is UI-only and runs a multi-spec evolution loop driven by
22
+ `qfai prototyping iterate --cycle <n>`. The skill resolves every
23
+ UI-bearing spec in one invocation, freezes that set at cycle 0, and
24
+ iterates `cycle 0..9` (max 10 cycles) with deterministic stop conditions
25
+ (exit codes 0 continue / 64 convergence / 65 max-iterations /
26
+ 66 license-verify failure / 2 input or lock drift).
24
27
  - Runtime observation is observed-only (no synthetic 200 / API / DB prototyping coverage).
25
- - Per-iter evidence is `screenshot.png` + `index.html` per declared screen plus a single `review.json` (4-axis ordinal, prose critique, anti-slop detection, pivot directive).
28
+ - Per-iter evidence is a single `<screen>.review.json` per declared spec ×
29
+ screen pair (4-axis ordinal verdicts, 6 `*Feel` short-prose impressions
30
+ bounded to 200 words each, `layoutAntiPatternsDetected[]`,
31
+ `designMdViolations[]`, and `pivotDirective`). Reviewer-emitted
32
+ `<screen>.review.json` is the only per-cycle artifact — no `screenshot.png`,
33
+ `index.html`, or `interaction.json`.
26
34
  - Calibration SSOT is the calibration pack referenced by `calibrationRef.packPath`.
27
35
 
28
36
  ## Quick start
@@ -66,8 +74,8 @@ npx qfai report
66
74
  Use `npx qfai prototyping preflight --target-url <url>` for a focused
67
75
  prototyping preflight before the skill starts; it surfaces blocking
68
76
  `QFAI-DCON-*` design-contract issues alongside runtime assumptions and resolves a runnable Playwright CLI launcher.
69
- Use `npx qfai prototyping iterate --cycle <n> --target-url <url>` to drive each cycle of the single-thread
70
- evolution loop. Exit codes: 0 (continue), 64 (convergence), 65 (max-iterations), 2 (input error).
77
+ Use `npx qfai prototyping iterate --cycle <n> --target-url <url>` to drive each cycle of the multi-spec
78
+ evolution loop. Exit codes: 0 (continue), 64 (convergence), 65 (max-iterations), 66 (license-verify failure), 2 (input or lock drift).
71
79
  Traceability refs inside prototyping evidence must use repo-root-relative concrete artifact refs
72
80
  (for example `.qfai/specs/spec-0001/01_Spec.md#L3` or `.qfai/evidence/prototyping/iter-03/home.png`).
73
81
  Absolute paths are invalid. The same strict ref grammar is enforced for top-level and leaf evidence-bearing fields, including
@@ -132,10 +140,19 @@ QFAI includes a small set of custom skills (stored under `.qfai/assistant/skills
132
140
  in `.qfai/specs/_policies/03_Capabilities.md` before the row is accepted
133
141
  (`QFAI-TRIAGE-006`). Every `01_Spec.md` declares a lifecycle
134
142
  `Status: active | superseded | deprecated | removed` (`QFAI-STATUS-001..006`).
135
- - **qfai-prototyping**: Single-thread design evolution loop. One prototype iterated through up to
136
- 15 cycles of generate -> capture -> review with a 4-axis ordinal rubric, anti-slop detection,
137
- prose critique, and explicit pivot permission. Stops deterministically when all four axes hit
138
- `exceptional` (exit 64) or the iteration budget is exhausted (exit 65).
143
+ - **qfai-prototyping**: Multi-spec parallel design evolution loop. Resolves
144
+ every UI-bearing spec in one invocation, freezes that set at cycle 0,
145
+ and iterates each `spec × screen` pair through up to 10 cycles
146
+ (`cycle 0..9`) of generate capture review with a 4-axis ordinal
147
+ rubric, 6 `*Feel` short-prose impressions (200-word bounded), explicit
148
+ layout anti-pattern detection (`lap-001..lap-008`), DESIGN.md token
149
+ violation detection, and explicit pivot permission. Stops
150
+ deterministically when every `spec × screen` pair satisfies the AND
151
+ convergence condition (all four ordinal axes `exceptional` AND
152
+ `layoutAntiPatternsDetected` empty AND `designMdViolations` empty)
153
+ (exit 64), when the 10-cycle budget is exhausted (exit 65), or when a
154
+ stock-photo source violates the cycle-0 frozen license catalog
155
+ (exit 66). Lock drift / input errors exit 2.
139
156
  - **qfai-atdd**: Implement acceptance tests driven by specs/scenarios.
140
157
  - **qfai-implement**: Unified TDD micro-cycle (Red/Green/Refactor) one test at a time using `test-list.md` as the execution ledger, including ledger status updates and exception closure.
141
158
  - **qfai-verify**: Run full-scan local quality gates (`validate --fail-on error`, `report`, repo gates) and produce reviewer-approved evidence under `.qfai/evidence/`.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: qfai-prototyping
3
3
  title: QFAI Prototyping (DESIGN.md-driven UX Loop)
4
- description: "Iterate one prototype through up to 15 cycles of generate-capture-review against a frozen DESIGN.md, focusing on information architecture, navigation flow, usability, and functionality."
4
+ description: "Iterate one prototype through up to 10 cycles of generate-capture-review against a frozen DESIGN.md, focusing on information architecture, navigation flow, usability, and functionality."
5
5
  argument-hint: ""
6
6
  allowed-tools: [Read, Glob, Write, TodoWrite, Task, Bash]
7
7
  roles: [orchestrator, product-experience-architect, product-surface-reviewer, devops-ci-engineer]
@@ -13,14 +13,16 @@ mode: execution-focused
13
13
 
14
14
  [DRIFT-PROTOCOL:MANDATORY]
15
15
 
16
- This skill is static-first and file-based by default: it runs one prototype
17
- through up to 15 iterations against a frozen brand SSOT (`DESIGN.md`), with
18
- no parallel candidates, no mode, and a fixed 15-cycle budget. Visual identity
19
- is fixed for the whole run; every cycle improves information architecture,
20
- navigation flow, usability, and functionality. Supported UI prototyping
21
- surfaces are: web, mobile, desktop, mixed. cli is not a prototyping
22
- execution target and is rejected. ui_bearing: false specs are not prototyping
23
- execution targets and are excluded.
16
+ This skill is static-first and file-based by default: it runs every
17
+ UI-bearing spec resolved at cycle 0 through up to 10 iterations against
18
+ a frozen brand SSOT (`DESIGN.md`) and a frozen spec set, with one
19
+ prototype lineage per `spec × screen` pair, no parallel candidates
20
+ within a pair, no mode, and a fixed 10-cycle budget. Visual identity
21
+ is fixed for the whole run; every cycle improves information
22
+ architecture, navigation flow, usability, and functionality. Supported
23
+ UI prototyping surfaces are: web, mobile, desktop, mixed. cli is not a
24
+ prototyping execution target and is rejected. ui_bearing: false specs
25
+ are not prototyping execution targets and are excluded.
24
26
 
25
27
  ## Goal
26
28
 
@@ -56,7 +58,24 @@ current `DESIGN.md` hash does not match the lock.
56
58
 
57
59
  ### Step 2-A — Verify Contract Preconditions
58
60
 
59
- - Confirm the selected spec is UI-bearing and has a supported `surface`.
61
+ - The skill resolves **every UI-bearing spec in the consumer project in
62
+ one invocation** via `resolveSurfaceUnion()`
63
+ (`core/prototyping/specResolution.ts`) — the same resolver the
64
+ cycle ≥ 1 drift gate and `show-spec`'s live scope consume, so the
65
+ scope you read here is apples-to-apples with what iterate enforces
66
+ downstream. `resolveSurfaceUnion()` internally composes
67
+ `resolveAllUiBearingSpecs()` (the strict `surface_type: ui-bearing`
68
+ frontmatter signal + the matching `.qfai/contracts/ui/<spec-id>*.yaml`
69
+ contract fallback) and folds in the legacy `# … prototyping …`
70
+ title-marker fallback and the operator-pinned spec id from the
71
+ `qfai.config.yaml` `prototyping` section (run
72
+ `qfai doctor --profile prototyping` to surface the resolved value).
73
+ Operators authoring CHG-002-shaped projects can rely on the strict
74
+ frontmatter alone; the broader composition covers legacy /
75
+ config-pinned consumers.
76
+ The operator is never prompted to pick a single spec; zero
77
+ UI-bearing specs at cycle 0 is a deterministic no-op exit `0`.
78
+ Confirm each resolved spec has a supported `surface`.
60
79
  - Confirm root `DESIGN.md` and `.qfai/contracts/design/DESIGN.md.lock.yaml`
61
80
  both exist; confirm `.qfai/contracts/ui/*.yaml` exists.
62
81
  - Run `qfai prototyping preflight --target-url <url>` (alias for
@@ -71,17 +90,64 @@ current `DESIGN.md` hash does not match the lock.
71
90
 
72
91
  ### Step 2-C — Run the Loop
73
92
 
74
- | Step | Actor | Action | Output |
75
- | ------ | --------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- |
76
- | C0 | product-experience-architect | `qfai prototyping iterate --cycle 0 --target-url <url>`. CLI computes `sha256(DESIGN.md)`; lock match enforced. Generator reads contracts + `references/generator-prompt.md` + DESIGN.md tokens and writes `.qfai/prototypes/iter-00/index.html`. Capture + review → `iter-00/review.json`. Append entry; commit `prototyping: iter-00`. | iter-00, prototyping.json#designMdSha256 |
77
- | C1..14 | (a) devops, (b) reviewer, (c) orchestrator, (d) generator | (a) playwright-cli writes `iter-NN/<screen>.{png,html}`; (b) reviewer writes `iter-NN/review.json` per `references/reviewer-prompt.md` (4 UX axes ordinal, 200..500 word critique, `layoutAntiPatternsDetected[]`, `designMdViolations[]`, `pivotDirective`); (c) update `prototyping.json#iterations[]` + `progress.md`, commit `prototyping: iter-NN`; (d) `qfai prototyping iterate --cycle <n+1>` decides exit. | iter-NN, exit ∈ {0, 64, 65, 2} |
78
- | H | orchestrator | Mirror latest to `.qfai/prototypes/final/index.html`. Per `references/handoff.md`: write `design-system.yaml` (deterministic DESIGN.md token mirror, no HTML extraction) + `prototype-handoff.yaml`. Run `qfai validate --profile prototyping --fail-on error` (produces `validate.json` with `counts.error === 0`), then `/qfai-verify` (produces `verify.json` with `status === "PASS"`), then `qfai prototyping certify` — certify requires both gate files to be present and passing before it will seal the certificate. | DONE |
93
+ | Step | Actor | Action | Output |
94
+ | ----- | --------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- |
95
+ | C0 | product-experience-architect | `qfai prototyping iterate --cycle 0 --target-url <url>`. CLI computes `sha256(DESIGN.md)`; lock match enforced. Generator reads contracts + `references/generator-prompt.md` + DESIGN.md tokens and writes `.qfai/prototypes/iter-00/index.html`. Capture + review → `iter-00/review.json`. Append entry; commit `prototyping: iter-00`. | iter-00, prototyping.json#designMdSha256 |
96
+ | C1..9 | (a) devops, (b) reviewer, (c) orchestrator, (d) generator | (a) playwright-cli writes `iter-NN/<screen>.{png,html}`; (b) reviewer writes `iter-NN/review.json` per `references/reviewer-prompt.md` (4 UX axes ordinal, 200..500 word critique, `layoutAntiPatternsDetected[]`, `designMdViolations[]`, `pivotDirective`); (c) update `prototyping.json#iterations[]` + `progress.md`, commit `prototyping: iter-NN`; (d) `qfai prototyping iterate --cycle <n+1>` decides exit. After C9 do NOT call `--cycle 10` — the CLI rejects out-of-range cycles. See the "Cycle 9 budget exhaustion" subsection below for recovery. | iter-NN, exit ∈ {0, 64, 65, 66, 2} |
97
+ | H | orchestrator | Mirror latest to `.qfai/prototypes/final/index.html`. Per `references/handoff.md`: write `design-system.yaml` (deterministic DESIGN.md token mirror, no HTML extraction) + `prototype-handoff.yaml`. Run `qfai validate --profile prototyping --fail-on error` (produces `validate.json` with `counts.error === 0`), then `/qfai-verify` (produces `verify.json` with `status === "PASS"`), then `qfai prototyping certify` — certify requires both gate files to be present and passing before it will seal the certificate. | DONE |
79
98
 
80
99
  **Exit codes**: `0` continue (read `pivotDirective`); `64` convergence (4
81
100
  axes `exceptional` AND `layoutAntiPatternsDetected` empty AND
82
- `designMdViolations` empty); `65` 15 cycles reached; `2` input error
101
+ `designMdViolations` empty); `65` 10 cycles reached; `66` license-verify
102
+ failure (`imageSources[]` resolved to a non-allowlisted source, unknown
103
+ license tier, non-HTTPS URL, host mismatch vs the cycle-0 frozen
104
+ `sourceHosts`, or missing / empty `attribution` — see "License-verify
105
+ hard-stop (exit 66)" below for recovery); `2` input error or lock drift
83
106
  (incl. DESIGN.md hash mismatch — re-run prototyping from cycle 0 after
84
- editing `DESIGN.md` and refreezing the lock via `/qfai-sdd` Phase 0).
107
+ editing `DESIGN.md` and refreezing the lock via `/qfai-sdd` Phase 0; also
108
+ covers `frozenSurfaceUnion` / `frozenLicenseCatalog` drift on cycle ≥ 1).
109
+
110
+ ### License-verify hard-stop (exit 66)
111
+
112
+ `qfai prototyping iterate` exits `66` when an `imageSources[]` entry on
113
+ `prototyping.json` violates the cycle-0 frozen license catalog. The
114
+ verifier rejects five distinct error codes:
115
+
116
+ - `license-not-allowlisted` — `source` is not in
117
+ `frozenLicenseCatalog.allowedSources`
118
+ - `license-tier-unknown` — `license` is not in
119
+ `frozenLicenseCatalog.licenseTiers[source]`
120
+ - `license-non-https-url` — `url` is not HTTPS
121
+ - `license-host-mismatch` — the URL host is not in
122
+ `frozenLicenseCatalog.sourceHosts[source]`
123
+ - `license-missing-attribution` — `attribution` is undefined / empty /
124
+ whitespace-only
125
+
126
+ Recovery path (no in-loop retry — the verifier is fail-closed):
127
+
128
+ 1. Inspect `prototyping.json#frozenLicenseCatalog` to see the frozen
129
+ `allowedSources` / `licenseTiers` / `sourceHosts`.
130
+ 2. Edit the offending `imageSources[]` entry to use an allowlisted
131
+ source / known license tier / HTTPS URL / matching host / non-empty
132
+ attribution. **Do not** edit `frozenLicenseCatalog` mid-loop — that
133
+ triggers a separate exit-2 lock-drift class.
134
+ 3. If the legitimate fix requires a different allowlist (e.g. adding a
135
+ new source), the only path is to refreeze the catalog by restarting
136
+ from cycle 0 (`qfai prototyping iterate --cycle 0 --target-url <url>`)
137
+ with the updated stock-photo configuration.
138
+
139
+ ### Cycle 9 budget exhaustion
140
+
141
+ If convergence is not reached at iter-09, the certify gate will reject
142
+ the run — H handoff artifacts (final mirror, `design-system.yaml`,
143
+ `prototype-handoff.yaml`) and the `validate` / `/qfai-verify` gates can
144
+ still be written / executed for inspection, but
145
+ `qfai prototyping certify --check` will exit non-zero and prevent DONE.
146
+ The recovery path is to restart from cycle 0: review `DESIGN.md`, the
147
+ pivot strategy in `references/reviewer-prompt.md`, and the latest
148
+ `review.json` findings, then re-run `qfai prototyping iterate
149
+ --cycle 0 --target-url <url>` to refreeze the loop. Do not seal a
150
+ completion certificate against an unconverged iter-09.
85
151
 
86
152
  ## Evaluator Inputs (Mandatory)
87
153
 
@@ -106,9 +106,11 @@ routing:
106
106
  review_profile: runtime-heavy
107
107
 
108
108
  - skill: qfai-prototyping
109
- # Single-thread evolution loop: one prototype, 15 iter, 4 ordinal axes,
110
- # prose critique, pivot directive. Routing is the 3 active roles plus
111
- # completion-reviewer at handoff.
109
+ # Multi-spec evolution loop: every UI-bearing spec resolved at cycle 0,
110
+ # one prototype lineage per spec × screen pair, 10 iter (cycle 0..9),
111
+ # 4 ordinal axes + 6 *Feel impressions + layout anti-pattern detection
112
+ # + DESIGN.md token violation gates, prose critique, pivot directive.
113
+ # Routing is the 3 active roles plus completion-reviewer at handoff.
112
114
  phases:
113
115
  - id: seed
114
116
  mandatory_agents: [product-experience-architect]