qfai 2.1.1 → 2.2.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/README.md +56 -36
- package/assets/defaults/agent-routing/qfai-implement.yml +9 -0
- package/assets/defaults/agent-routing/qfai-triage.yml +18 -0
- package/assets/defaults/workflows/answer-in-session.yml +8 -0
- package/assets/defaults/workflows/quarantine-flaky.yml +3 -0
- package/assets/defaults/workflows/repair-consistency.yml +1 -0
- package/assets/defaults/workflows/run-operation.yml +11 -0
- package/assets/defaults/workflows/run-owned-cleanup.yml +12 -0
- package/assets/defaults/workflows/write-procedure.yml +18 -0
- package/assets/graph/codegraph-native.mjs +174 -0
- package/assets/graph/graphify-native.py +72 -0
- package/assets/init/.claude/settings.json +9 -9
- package/assets/init/.codex/hooks.json +8 -8
- package/assets/init/.qfai/assistant/agent/frontend-engineer.md +5 -0
- package/assets/init/.qfai/assistant/agent/product-experience-architect.md +4 -0
- package/assets/init/.qfai/assistant/agent/product-surface-reviewer.md +7 -0
- package/assets/init/.qfai/assistant/agent/requirements-analyst.md +8 -0
- package/assets/init/.qfai/assistant/rule/communication.md +18 -8
- package/assets/init/.qfai/assistant/rule/constitution.md +31 -15
- package/assets/init/.qfai/assistant/rule/drift-protocol.md +119 -2
- package/assets/init/.qfai/assistant/rule/references/asset-authoring.md +6 -4
- package/assets/init/.qfai/assistant/rule/references/codex-delegation.md +27 -0
- package/assets/init/.qfai/assistant/rule/references/griller-recommendations.md +21 -9
- package/assets/init/.qfai/assistant/rule/references/worker-edit-boundary.md +48 -0
- package/assets/init/.qfai/assistant/rule/review-convergence.md +25 -12
- package/assets/init/.qfai/assistant/rule/shared-skill-delegation-baseline.md +16 -25
- package/assets/init/.qfai/assistant/rule/shared-skill-operating-baseline.md +16 -11
- package/assets/init/.qfai/assistant/rule/ui-definition-protocol.md +6 -1
- package/assets/init/.qfai/assistant/rule/workflow.md +2 -1
- package/assets/init/.qfai/assistant/skill/qfai-configure/SKILL.md +3 -3
- package/assets/init/.qfai/assistant/skill/qfai-discussion/SKILL.md +6 -0
- package/assets/init/.qfai/assistant/skill/qfai-discussion/references/discussion-completion-matrix.md +20 -15
- package/assets/init/.qfai/assistant/skill/qfai-discussion/references/ui-bearing-playbook.md +2 -4
- package/assets/init/.qfai/assistant/skill/qfai-discussion/references/ui_ux_best_practices.md +1 -6
- package/assets/init/.qfai/assistant/skill/qfai-discussion/templates/uiux/00_index.md +0 -16
- package/assets/init/.qfai/assistant/skill/qfai-grilling/SKILL.md +30 -20
- package/assets/init/.qfai/assistant/skill/qfai-grilling/references/delegated-session.md +4 -3
- package/assets/init/.qfai/assistant/skill/qfai-grilling/references/session-record.md +8 -2
- package/assets/init/.qfai/assistant/skill/qfai-implement/SKILL.md +16 -3
- package/assets/init/.qfai/assistant/skill/qfai-implement/references/parallelization-policy.md +9 -1
- package/assets/init/.qfai/assistant/skill/qfai-implement/references/red-admissibility.md +46 -0
- package/assets/init/.qfai/assistant/skill/qfai-implement/references/ui-affecting.md +5 -2
- package/assets/init/.qfai/assistant/skill/qfai-maintain/SKILL.md +3 -3
- package/assets/init/.qfai/assistant/skill/qfai-migration-v1-to-v2/SKILL.md +12 -6
- package/assets/init/.qfai/assistant/skill/qfai-migration-v1-to-v2/references/migration-guide.md +1 -265
- package/assets/init/.qfai/assistant/skill/qfai-migration-v1-to-v2/references/migration-placement.md +273 -0
- package/assets/init/.qfai/assistant/skill/qfai-prototyping/SKILL.md +4 -3
- package/assets/init/.qfai/assistant/skill/qfai-prototyping/references/review-payload-schema.md +2 -3
- package/assets/init/.qfai/assistant/skill/qfai-prototyping/references/reviewer-prompt.md +17 -1
- package/assets/init/.qfai/assistant/skill/qfai-run/SKILL.md +52 -37
- package/assets/init/.qfai/assistant/skill/qfai-run/references/codex-cloud-install.md +80 -0
- package/assets/init/.qfai/assistant/skill/qfai-run/references/evidence-delivery.md +322 -0
- package/assets/init/.qfai/assistant/skill/qfai-run/references/extraction.md +83 -49
- package/assets/init/.qfai/assistant/skill/qfai-run/references/operator-screens.md +226 -11
- package/assets/init/.qfai/assistant/skill/qfai-run/references/plan.md +6 -3
- package/assets/init/.qfai/assistant/skill/qfai-run/references/reached-step-observations.md +132 -0
- package/assets/init/.qfai/assistant/skill/qfai-run/references/stage-points.md +14 -0
- package/assets/init/.qfai/assistant/skill/qfai-run/scripts/codex-cloud-install.mjs +117 -0
- package/assets/init/.qfai/assistant/skill/qfai-sdd/SKILL.md +4 -3
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/contract-artifact-rules.md +1 -0
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/design-anti-patterns.md +23 -5
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/design-md-authoring.md +20 -7
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/requirements-decomposition.md +8 -0
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/sdd-execution-playbook.md +29 -4
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/sdd-phase-checklists.md +1 -1
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/sdd-pre-draft-grilling.md +4 -1
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/sdd-quality-gate.md +1 -1
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/sdd-triage.md +159 -4
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/spec-traceability-rules.md +14 -2
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/ui-contract-guide.md +146 -0
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/ui-design-contract-normalization.md +4 -29
- package/assets/init/.qfai/assistant/skill/qfai-sdd/templates/change-request.md +38 -1
- package/assets/init/.qfai/assistant/skill/qfai-sdd/templates/contracts/ui-contract.sample.yaml +52 -5
- package/assets/init/.qfai/assistant/skill/qfai-sdd/templates/spec/decisions.md +12 -0
- package/assets/init/.qfai/assistant/skill/qfai-triage/SKILL.md +34 -21
- package/assets/init/.qfai/assistant/skill/qfai-verify/SKILL.md +5 -4
- package/assets/init/.qfai/assistant/skill/qfai-verify/references/context-load.md +9 -6
- package/assets/init/.qfai/assistant/skill/qfai-verify/references/verify-output-contract.md +80 -15
- package/assets/init/.qfai/assistant/skill/web-research/SKILL.md +35 -21
- package/assets/init/.qfai/assistant/skill/web-research/mcp-templates/brave-search/config.toml +2 -4
- package/assets/init/.qfai/assistant/skill/web-research/mcp-templates/brave-search/mcp-config.json +9 -5
- package/assets/init/.qfai/assistant/skill/web-research/mcp-templates/firecrawl/.mcp.json +1 -2
- package/assets/init/.qfai/assistant/skill/web-research/mcp-templates/firecrawl/config.toml +3 -3
- package/assets/init/.qfai/assistant/skill/web-research/mcp-templates/firecrawl/mcp-config.json +11 -8
- package/assets/init/.qfai/assistant/skill/web-research/mcp-templates/playwright/config.toml +1 -1
- package/assets/init/.qfai/assistant/skill/web-research/mcp-templates/playwright/mcp-config.json +7 -3
- package/assets/init/.qfai/assistant/step/common-design-md/STEP.md +33 -20
- package/assets/init/.qfai/assistant/step/common-gate-run/STEP.md +124 -8
- package/assets/init/.qfai/assistant/step/common-grilling-record/STEP.md +10 -2
- package/assets/init/.qfai/assistant/step/common-policy-check/STEP.md +1 -0
- package/assets/init/.qfai/assistant/step/common-review-cycle/STEP.md +26 -9
- package/assets/init/.qfai/assistant/step/discussion-interview/STEP.md +15 -8
- package/assets/init/.qfai/assistant/step/discussion-oq/STEP.md +5 -1
- package/assets/init/.qfai/assistant/step/discussion-pack/STEP.md +6 -1
- package/assets/init/.qfai/assistant/step/discussion-research/STEP.md +2 -0
- package/assets/init/.qfai/assistant/step/discussion-uiux/STEP.md +6 -4
- package/assets/init/.qfai/assistant/step/implement-backport/STEP.md +1 -1
- package/assets/init/.qfai/assistant/step/implement-benchmark/STEP.md +7 -4
- package/assets/init/.qfai/assistant/step/implement-dep-bump/STEP.md +11 -2
- package/assets/init/.qfai/assistant/step/implement-diagnose/STEP.md +2 -0
- package/assets/init/.qfai/assistant/step/implement-oracle-parity/STEP.md +2 -2
- package/assets/init/.qfai/assistant/step/implement-procedure/STEP.md +69 -0
- package/assets/init/.qfai/assistant/step/implement-quarantine/STEP.md +24 -7
- package/assets/init/.qfai/assistant/step/implement-refactor/STEP.md +2 -2
- package/assets/init/.qfai/assistant/step/implement-regression-fix/STEP.md +7 -6
- package/assets/init/.qfai/assistant/step/implement-retire/STEP.md +6 -3
- package/assets/init/.qfai/assistant/step/implement-revert/STEP.md +4 -3
- package/assets/init/.qfai/assistant/step/implement-seam/STEP.md +6 -5
- package/assets/init/.qfai/assistant/step/implement-stress-harness/STEP.md +34 -3
- package/assets/init/.qfai/assistant/step/implement-sweep/STEP.md +4 -3
- package/assets/init/.qfai/assistant/step/implement-tdd/STEP.md +39 -5
- package/assets/init/.qfai/assistant/step/implement-tooling/STEP.md +22 -2
- package/assets/init/.qfai/assistant/step/maintain-edit/STEP.md +18 -14
- package/assets/init/.qfai/assistant/step/prototyping-grill/STEP.md +4 -3
- package/assets/init/.qfai/assistant/step/prototyping-loop/STEP.md +4 -0
- package/assets/init/.qfai/assistant/step/prototyping-preflight/STEP.md +9 -3
- package/assets/init/.qfai/assistant/step/sdd-contract/STEP.md +11 -0
- package/assets/init/.qfai/assistant/step/sdd-flow/STEP.md +2 -0
- package/assets/init/.qfai/assistant/step/sdd-story/STEP.md +10 -0
- package/assets/init/.qfai/assistant/step/sdd-triage/STEP.md +34 -10
- package/assets/init/.qfai/assistant/step/triage-answer/STEP.md +7 -6
- package/assets/init/.qfai/assistant/step/triage-close/STEP.md +33 -23
- package/assets/init/.qfai/assistant/step/triage-cluster/STEP.md +5 -3
- package/assets/init/.qfai/assistant/step/triage-decompose/STEP.md +2 -0
- package/assets/init/.qfai/assistant/step/triage-dedupe/STEP.md +4 -0
- package/assets/init/.qfai/assistant/step/triage-handoff/STEP.md +13 -4
- package/assets/init/.qfai/assistant/step/triage-investigate/STEP.md +8 -5
- package/assets/init/.qfai/assistant/step/triage-operate/STEP.md +50 -0
- package/assets/init/.qfai/assistant/step/triage-owned-cleanup/STEP.md +86 -0
- package/assets/init/.qfai/assistant/step/triage-request-info/STEP.md +2 -0
- package/assets/init/.qfai/assistant/step/triage-security-intake/STEP.md +6 -3
- package/assets/init/.qfai/assistant/step/verify-change-note/STEP.md +1 -0
- package/assets/init/.qfai/assistant/step/verify-commit/STEP.md +37 -9
- package/assets/init/.qfai/assistant/step/verify-external/STEP.md +5 -2
- package/assets/init/.qfai/assistant/step/verify-qfai-gate/STEP.md +14 -16
- package/assets/init/.qfai/assistant/step/verify-release-notes/STEP.md +1 -0
- package/assets/init/.qfai/assistant/step/verify-repeat-run/STEP.md +46 -4
- package/assets/init/.qfai/assistant/step/verify-repo-gate/STEP.md +133 -30
- package/assets/init/root/.agents/rules/ai-readable-markdown.md +2 -2
- package/assets/init/root/.agents/rules/api-budget.md +187 -8
- package/assets/init/root/.agents/rules/document-schema.md +17 -0
- package/assets/init/root/.agents/rules/documentation-clarity.md +163 -34
- package/assets/init/root/.agents/rules/graph-exploration.md +150 -0
- package/assets/init/root/.agents/rules/grilling.md +100 -43
- package/assets/init/root/.agents/rules/minimal-implementation.md +3 -3
- package/assets/init/root/.agents/rules/reminders.json +27 -18
- package/assets/init/root/.agents/rules/session-feedback.md +131 -0
- package/assets/init/root/.agents/rules/temporary-files.md +33 -0
- package/assets/init/root/.agents/rules/untrusted-content.md +2 -2
- package/assets/init/root/.agents/rules/user-questions.md +51 -40
- package/assets/init/root/.github/workflows/qfai-docs.yml +3 -3
- package/assets/init/root/.github/workflows/qfai-tests.yml +88 -35
- package/assets/init/root/.github/workflows/qfai-validate.yml +2 -2
- package/assets/init/root/AGENTS.md +24 -22
- package/assets/sandbox-templates/default-deny.yaml +9 -3
- package/assets/schemas/workflow/extraction.schema.json +89 -5
- package/assets/scripts/check-mdschema.mjs +77 -8
- package/assets/uix-rev/comparison-review.md +1 -1
- package/assets/uix-rev/contracts-review.md +1 -2
- package/dist/cli/index.cjs +9444 -10071
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.mjs +9421 -10041
- package/dist/cli/index.mjs.map +1 -1
- package/dist/graph/cli.cjs +1568 -0
- package/dist/graph/cli.cjs.map +1 -0
- package/dist/graph/cli.d.cts +9 -0
- package/dist/graph/cli.d.ts +9 -0
- package/dist/graph/cli.mjs +1541 -0
- package/dist/graph/cli.mjs.map +1 -0
- package/dist/graph/hook.cjs +817 -0
- package/dist/graph/hook.cjs.map +1 -0
- package/dist/graph/hook.d.cts +9 -0
- package/dist/graph/hook.d.ts +9 -0
- package/dist/graph/hook.mjs +792 -0
- package/dist/graph/hook.mjs.map +1 -0
- package/dist/index.cjs +7634 -8517
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +146 -658
- package/dist/index.d.ts +146 -658
- package/dist/index.mjs +7462 -8318
- package/dist/index.mjs.map +1 -1
- package/dist/process-C21nTvkT.d.cts +12 -0
- package/dist/process-C21nTvkT.d.ts +12 -0
- package/package.json +4 -6
- package/assets/init/root/CLAUDE.md +0 -46
|
@@ -22,6 +22,7 @@ naming the pattern is what works.
|
|
|
22
22
|
- Placement
|
|
23
23
|
- Motion and transitions
|
|
24
24
|
- Copy in the UI
|
|
25
|
+
- Copy that adds no meaning
|
|
25
26
|
- Information architecture and flow
|
|
26
27
|
- States and accessibility
|
|
27
28
|
- Implementation defaults
|
|
@@ -51,11 +52,13 @@ naming the pattern is what works.
|
|
|
51
52
|
flow_ and _States and accessibility_ do, `interface-clarity.md` and the spec
|
|
52
53
|
are the rules. The entry is the form a breach of them takes on a generated
|
|
53
54
|
screen.
|
|
54
|
-
- The reviewer inside the prototyping loop does not apply
|
|
55
|
-
`DESIGN.md` locks the brand values that reviewer sees, so
|
|
56
|
-
|
|
57
|
-
`DESIGN.md` is written.
|
|
58
|
-
the
|
|
55
|
+
- The reviewer inside the prototyping loop does not apply the sections about
|
|
56
|
+
identity. Root `DESIGN.md` locks the brand values that reviewer sees, so a
|
|
57
|
+
pattern there is caught where the design direction is reviewed and where
|
|
58
|
+
`DESIGN.md` is written. That reviewer does apply _Copy that adds no meaning_,
|
|
59
|
+
through the criterion on explanatory text, because those patterns are about
|
|
60
|
+
what the text tells the user, not about a brand. No entry here is a `lap-*`
|
|
61
|
+
detection.
|
|
59
62
|
|
|
60
63
|
## Color and background
|
|
61
64
|
|
|
@@ -269,6 +272,21 @@ naming the pattern is what works.
|
|
|
269
272
|
- The screen shows technical detail nobody asked for, such as GPU status or
|
|
270
273
|
average generation time.
|
|
271
274
|
|
|
275
|
+
## Copy that adds no meaning
|
|
276
|
+
|
|
277
|
+
These patterns are judged against the screen's tasks and the `supplements` its UI
|
|
278
|
+
contract declares, in SDD, in implementation and in every surface review. A chosen
|
|
279
|
+
visual direction does not exempt them. A disclosure about demo data, cost, storage
|
|
280
|
+
or transmission that is true and shown where the user decides is not one of them:
|
|
281
|
+
judge where it sits and what it lets the user do, not the word.
|
|
282
|
+
|
|
283
|
+
- A second heading or a sentence repeats the main heading, an action label, a
|
|
284
|
+
state, or the content beside it.
|
|
285
|
+
- A condition the user already knows is explained again where it adds nothing to
|
|
286
|
+
the decision being made.
|
|
287
|
+
- Production copy carries a development instruction, implementation commentary,
|
|
288
|
+
or a demo note repeated on screen after screen.
|
|
289
|
+
|
|
272
290
|
## Information architecture and flow
|
|
273
291
|
|
|
274
292
|
- Sections follow the stock order: hero, logos, three features, stats or
|
|
@@ -25,9 +25,10 @@ this flow's provenance names:
|
|
|
25
25
|
| `uiux/00_index.md`, `uiux/40_screen_contracts.md` | the screen-level sidecars |
|
|
26
26
|
|
|
27
27
|
`01_Context.md#Design Direction` is the decision the user made: the adopted
|
|
28
|
-
theme, what departs from it, and what stays ordinary.
|
|
29
|
-
|
|
30
|
-
which is the same rule an
|
|
28
|
+
theme, what departs from it, and what stays ordinary. For initial authoring of
|
|
29
|
+
a missing file, a UI-bearing pack that records no design direction leaves the
|
|
30
|
+
brand unchosen — stop and ask rather than pick one, which is the same rule an
|
|
31
|
+
imported specification gets.
|
|
31
32
|
|
|
32
33
|
Each registry entry carries what was adopted, what was rejected, and how it
|
|
33
34
|
was translated. The competitor registry feeds brand and tokens; the component
|
|
@@ -116,7 +117,19 @@ to touch a colour has nothing to be consistent with.
|
|
|
116
117
|
|
|
117
118
|
## When the file already exists
|
|
118
119
|
|
|
119
|
-
`npx qfai init`
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
`npx qfai init` writes no root `DESIGN.md`; the sample is shipped only as a
|
|
121
|
+
skill template. A root file that exists was authored by `common-design-md` or
|
|
122
|
+
copied from that template on purpose, and a project may have authored its own.
|
|
123
|
+
Write a missing file from the recorded direction. Repair an existing file only when SDD triage names its exact path
|
|
124
|
+
and the requested change, and a new WIP change request authorizes both. Apply
|
|
125
|
+
only the authorized change; preserve existing brand and tokens unless their
|
|
126
|
+
change is authorized and supported by recorded direction or named theme
|
|
127
|
+
values. Record the source of each changed value and leave unrelated content
|
|
128
|
+
unchanged. Stop without writing a value neither source supplies. Without that
|
|
129
|
+
authorization, validate the existing file without an overwrite; an inherited
|
|
130
|
+
DONE row authorizes no new change. An unreplaced sample is refused.
|
|
131
|
+
|
|
132
|
+
For an existing valid file, validation and authorized repairs that preserve
|
|
133
|
+
its brand and tokens require no new brand selection. An authorized brand or
|
|
134
|
+
token change still needs recorded direction or named theme values for each
|
|
135
|
+
changed value; without either source, stop without writing the change.
|
|
@@ -25,6 +25,14 @@ Use source-backed discussion requirements to write one connected, testable story
|
|
|
25
25
|
- An EX is one concrete input and expected result for exactly one AC. Split examples whose paths can pass or fail independently.
|
|
26
26
|
- A BR is one independently falsifiable constraint. If removing a clause leaves another complete rule, split it.
|
|
27
27
|
|
|
28
|
+
A capacity-only sibling may represent the same actual actor goal within the
|
|
29
|
+
same BF when requested AC or EX additions exceed the source story's remaining
|
|
30
|
+
capacity. Prefer preserving published cases and IDs, and place only new,
|
|
31
|
+
cohesive incoming cases under their own covering change request. Confirm
|
|
32
|
+
retired-inclusive capacity and the owning approval before writing; this
|
|
33
|
+
exception invents no new product outcome and grants no future creation or move
|
|
34
|
+
permission.
|
|
35
|
+
|
|
28
36
|
Allocate each ID as the highest ID of its kind in its defined scope plus one, counting retired IDs. Never reuse an ID. The scopes and widths are in the `ID allocation` section of the triage reference.
|
|
29
37
|
|
|
30
38
|
## Ambiguity
|
|
@@ -4,10 +4,35 @@ Use this sequence for /qfai-sdd. The shipped templates under ../templates/spec/
|
|
|
4
4
|
|
|
5
5
|
## Stage 0: source inventory
|
|
6
6
|
|
|
7
|
-
1.
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
1. Use the launcher established by
|
|
8
|
+
`.qfai/assistant/rule/shared-skill-operating-baseline.md#canonical-qfai-launcher-mandatory`.
|
|
9
|
+
Record its resolved package path and version in the SDD report. Check that
|
|
10
|
+
the installed Stage 0 instructions support the procedure being used.
|
|
11
|
+
2. Run `npx qfai sdd preflight` and read its `selectedInputPath` and `source`.
|
|
12
|
+
Respect an explicitly selected discussion pack, including one older than the
|
|
13
|
+
newest pack.
|
|
14
|
+
3. Read the selected pack, completed reviews that target it, explicit user
|
|
15
|
+
requirements, and the existing story tree. A pack is reference and provenance
|
|
16
|
+
material. Disposition its applicable review advice in the SDD report, a decision
|
|
17
|
+
row, or an open question. A pack discrepancy does not itself block SDD. For
|
|
18
|
+
the current request, read the existing purpose in
|
|
19
|
+
`<paths.specsDir>/01_policy/objective.md` and inspect related flows and stories.
|
|
20
|
+
4. A missing discussion pack does not mean that specifications are missing. If
|
|
21
|
+
an existing readable specification is authoritative for this request, run
|
|
22
|
+
`npx qfai sdd preflight --import <path>` with that file. The fallback does
|
|
23
|
+
not replace a selected pack or bypass unsafe pack names, unreadable files,
|
|
24
|
+
invalid active pointers, config errors, or a mismatched tool.
|
|
25
|
+
5. Use an explicit user requirement as supplied and name it in the SDD report.
|
|
26
|
+
Do not invent an import file from conversation. Without a file, CLI preflight
|
|
27
|
+
can remain blocked while SDD assesses that explicit requirement.
|
|
28
|
+
6. Use `/qfai-discussion` only when no usable source exists; stop SDD until one
|
|
29
|
+
is available. Stop on an unresolved product decision that cannot safely be
|
|
30
|
+
inferred; record the question in `open-questions.md`. Do not manufacture or
|
|
31
|
+
regenerate a past discussion pack, or regenerate the existing purpose,
|
|
32
|
+
merely to clear preflight.
|
|
33
|
+
7. Import-lite readiness identifies the input source. It does not establish
|
|
34
|
+
complete requirements or a validation PASS. Keep the existing purpose and
|
|
35
|
+
current request while updating only affected flow and story content.
|
|
11
36
|
|
|
12
37
|
## Stage 1: triage and decisions
|
|
13
38
|
|
|
@@ -56,7 +56,7 @@ Follow the cycle the `sdd-cycle` step sets out.
|
|
|
56
56
|
- Every affected BF passed npx qfai validate --profile sdd --fail-on error --flow BF-NNNN with error=0.
|
|
57
57
|
- Every document written passes its document schema. A failure was fixed by reshaping the document, not by adding to it.
|
|
58
58
|
- The log path and result for each BF are in the SDD report.
|
|
59
|
-
- Each entered design-writing stage has a pre-draft grilling checkpoint before its first mutation. The final report lists each decision a checkpoint adopted; unanswered critical decisions remain open and block completion.
|
|
59
|
+
- Each entered design-writing stage has a pre-draft grilling checkpoint before its first mutation. A checkpoint that finds no open decision holds no session. The final report lists each decision a checkpoint adopted; unanswered critical decisions remain open and block completion.
|
|
60
60
|
- Reviewers are independent of the authors, and every finding of the one review is fixed or answered.
|
|
61
61
|
- Rejected options remain excluded, or a documented reopening decision exists.
|
|
62
62
|
- Remaining risks and next actions are explicit in the SDD report.
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# Pre-draft Grilling
|
|
2
2
|
|
|
3
|
-
Before an SDD stage makes a design decision, the session agent gathers the stage's open decisions into one frontier
|
|
3
|
+
Before an SDD stage makes a design decision, the session agent gathers the stage's open decisions into one frontier.
|
|
4
|
+
When the frontier holds a design decision the repository cannot settle, the agent settles the frontier in a delegated grilling session under `.qfai/assistant/rule/review-convergence.md#agent-to-agent-grilling-must`, using the `qfai-grilling` method. It asks the user each critical decision the frontier holds.
|
|
5
|
+
|
|
6
|
+
When the request, the story tree, the contracts and the recorded decisions already settle every decision of the stage, the frontier is empty. Then no session is held and no griller starts. The stage writes what is settled, and its final report lists no adopted decision for the checkpoint.
|
|
4
7
|
|
|
5
8
|
## Checkpoints
|
|
6
9
|
|
|
@@ -38,7 +38,7 @@ Do not use a sibling's in-flight findings to hold or clear the current flow. Rec
|
|
|
38
38
|
|
|
39
39
|
## Review and evidence
|
|
40
40
|
|
|
41
|
-
- A pre-draft grilling checkpoint ran before the first write of every design-writing stage entered, and each critical decision it held was put to the user.
|
|
41
|
+
- A pre-draft grilling checkpoint ran before the first write of every design-writing stage entered. It held a grilling session only where it found a decision the repository cannot settle, and each critical decision it held was put to the user.
|
|
42
42
|
- The final report lists each decision a checkpoint adopted, with its reason.
|
|
43
43
|
- Reviewers are independent of authors, and every finding of the one review is fixed or answered under `.qfai/assistant/rule/review-convergence.md`, with no re-review.
|
|
44
44
|
- Evidence records the source, changed IDs and files, contract executability, commands, reviewer verdicts, rejected options excluded, and remaining risks.
|
|
@@ -7,6 +7,8 @@ Triage selects the smallest story-tree change that answers each incoming require
|
|
|
7
7
|
- Inputs
|
|
8
8
|
- Operation choice
|
|
9
9
|
- Decision and question rows
|
|
10
|
+
- Published decision prefix recovery
|
|
11
|
+
- Merge-added identical decision copy recovery
|
|
10
12
|
- Approval and no-question mode
|
|
11
13
|
- Retiring an EX, AC or BR
|
|
12
14
|
- ID allocation
|
|
@@ -34,7 +36,9 @@ Inspect the impact cascade: policy → BF → US → AC → EX → enforcing con
|
|
|
34
36
|
## Decision and question rows
|
|
35
37
|
|
|
36
38
|
Use <paths.specsDir>/decisions.md and <paths.specsDir>/open-questions.md, each with exactly ID, Content, Approach, Status. Append a row; later only Status may change, including to `PARTLY SUPERSEDED (by DEC-NNNN)` when a later row narrows a decision without replacing it.
|
|
37
|
-
Do not edit the first three cells or remove the row
|
|
39
|
+
Do not edit the first three cells or remove the row, except for explicit branch-added decision renumbering under ID allocation below
|
|
40
|
+
or the bounded published decision prefix recovery below, and remove a row only as a proven surplus copy under the merge-added
|
|
41
|
+
identical decision copy recovery below. Inherited rows retain those cells. Use the next highest ID in the table plus one. A retired item still reserves its BF or US ID.
|
|
38
42
|
|
|
39
43
|
decisions.md records only what the user decided: each change request the user approved or declined,
|
|
40
44
|
and each critical decision the user made. A row is appended once the user has decided what it records.
|
|
@@ -58,6 +62,69 @@ whose Content opens Unadjudicated:, at TODO until decided. A justified test exce
|
|
|
58
62
|
decision Content with Test exception:, names the exact BF, AC, or EX it exempts, and puts the reason
|
|
59
63
|
in Approach. It takes effect only at DONE; it never exempts descendant items.
|
|
60
64
|
|
|
65
|
+
A test annotation may remain pending only when authority to change the
|
|
66
|
+
specification covers that state and the test deferral is approved. Record the
|
|
67
|
+
specification change in its own `Change request:` row. Record the deferral as a
|
|
68
|
+
`Test exception:` decision naming the exact AC at DONE. Its Approach states
|
|
69
|
+
the reason, untested scope, owner, next decision date and condition for restoring
|
|
70
|
+
the annotation.
|
|
71
|
+
|
|
72
|
+
DONE establishes the exception decision; it does not mean test completion.
|
|
73
|
+
The existing info finding names the exempted AC and its decision without
|
|
74
|
+
claiming test execution or coverage. The exception never exempts descendant EX
|
|
75
|
+
obligations or authorizes changes to EX or BR scope. Do not silently substitute
|
|
76
|
+
an EX or prose rewrite for an approved specification change. Use the next
|
|
77
|
+
decision date for manual review; there is no automatic expiry and no automatic
|
|
78
|
+
warning.
|
|
79
|
+
|
|
80
|
+
When specification changes are forbidden or either authority is missing, first
|
|
81
|
+
append an `Unadjudicated:` OQ at TODO. Name the affected IDs, expected versus
|
|
82
|
+
actual behavior, implementation-change evidence, owner and required permission.
|
|
83
|
+
Stop dependent AC, EX and BR edits; independent authorized work may continue.
|
|
84
|
+
|
|
85
|
+
## Published decision prefix recovery
|
|
86
|
+
|
|
87
|
+
When an approved request names a published malformed decision added by the
|
|
88
|
+
branch, read `.qfai/assistant/rule/drift-protocol.md#published-decision-prefix-recovery`.
|
|
89
|
+
That rule defines the source, byte boundaries, exact prefix and stop conditions.
|
|
90
|
+
Approval of the generic protocol alone authorizes no target; append a separate
|
|
91
|
+
new target-specific recovery change request using `templates/change-request.md`.
|
|
92
|
+
|
|
93
|
+
Record the fixed base and unique common ancestor, absence of the target in both,
|
|
94
|
+
the published source commit's ancestry, raw Approach digests and the exact
|
|
95
|
+
approved prefix. Immediately before writing, recheck the unique current row,
|
|
96
|
+
its original ID, Content and Status, and its old digest. Preserve every original
|
|
97
|
+
Approach byte as the suffix and leave every other row unchanged. Recheck the
|
|
98
|
+
existing form and validation; status or supersession clears no malformed form.
|
|
99
|
+
Record actual results, including any stopped recovery, without claiming an
|
|
100
|
+
automatic repair. Inherited records and open-question rows remain excluded.
|
|
101
|
+
Rollback follows the recorded new-digest check and restores the original form
|
|
102
|
+
failure; it never resets, amends or force pushes.
|
|
103
|
+
|
|
104
|
+
## Merge-added identical decision copy recovery
|
|
105
|
+
|
|
106
|
+
When a merge left a second byte-identical copy of an inherited decision and the
|
|
107
|
+
duplicate-ID check rejects it, read
|
|
108
|
+
`.qfai/assistant/rule/drift-protocol.md#merge-added-identical-decision-copy-recovery`.
|
|
109
|
+
That rule defines the lineage, the raw-row proof and the stop conditions.
|
|
110
|
+
Approval of the generic protocol alone authorizes no target; append a separate
|
|
111
|
+
new target-specific change request using `templates/change-request.md`.
|
|
112
|
+
|
|
113
|
+
The request names the exact path, the ID, the bad merge, both parents, the
|
|
114
|
+
common ancestor, the base and its comparison ancestor, each occurrence's
|
|
115
|
+
location, the raw SHA-256 including the line ending and the retain/remove
|
|
116
|
+
mapping. Fresh evidence, reviewed independently after the request is appended,
|
|
117
|
+
fixes the actual write HEAD, the complete preimage and replacement hashes and
|
|
118
|
+
the current authority. Immediately before writing, recheck refs, path,
|
|
119
|
+
authority, counts, mapping and bytes; stale or changed proof stops the
|
|
120
|
+
recovery. Remove only the mapped surplus copies. Keep one original and every
|
|
121
|
+
other row, reference and byte. Open-question rows, rows that differ in any cell,
|
|
122
|
+
padding or line ending, and surplus the base already holds stay excluded.
|
|
123
|
+
Duplicate, drift and Status rules apply as before. The result is no whole-target
|
|
124
|
+
PASS, and the request stays WIP while any named action or required check is
|
|
125
|
+
unfinished. Rollback restores the recorded preimage only while the file still
|
|
126
|
+
equals the replacement; it never resets, amends or force pushes.
|
|
127
|
+
|
|
61
128
|
## Approval and no-question mode
|
|
62
129
|
|
|
63
130
|
Use the shared user-question protocol for CREATE, DELETE, SPLIT, MERGE, SUPERSEDE, and UPDATE:REMOVE. Present the target and rationale. Do not self-approve. A request from the user in the session that names the operation and its effect is the approval, and no second question is asked.
|
|
@@ -81,7 +148,7 @@ A story-tree or contract file changes only on the user's approval:
|
|
|
81
148
|
records who approved it, when, and the label of the option chosen.
|
|
82
149
|
3. Move the row to DONE once every change it names is written.
|
|
83
150
|
|
|
84
|
-
A row present before the stage started keeps its ID, Content and Approach.
|
|
151
|
+
A row present before the stage started keeps its ID, Content and Approach, except for explicit branch-added decision renumbering under ID allocation below or published decision prefix recovery above. Inherited rows keep those cells without exception; the merge-added identical decision copy recovery above removes only surplus copies and keeps the original.
|
|
85
152
|
Only a row this stage appended changes its Status.
|
|
86
153
|
|
|
87
154
|
## Retiring an EX, AC or BR
|
|
@@ -104,12 +171,74 @@ Read all IDs of the kind in the relevant scope, including IDs named by retiremen
|
|
|
104
171
|
A contract number spans every contract kind, and a BR is numbered inside its contract. DEC and OQ each span their table.
|
|
105
172
|
Empty numeric scopes begin at 0001, and AC/EX tails begin at 01. Do not reuse an ID because its file was removed or a row was rejected.
|
|
106
173
|
|
|
174
|
+
### Capacity before writing
|
|
175
|
+
|
|
176
|
+
AC and EX tails stay two digits, from 01 through 99. Before writing a planned
|
|
177
|
+
batch, report each affected kind and story, its high-water number H (0 when
|
|
178
|
+
empty), remaining capacity 99-H and the number of requested additions. Count
|
|
179
|
+
valid IDs in the tree and decisions, including retired IDs, plus observed
|
|
180
|
+
published parallel heads and known reservations under the project's existing
|
|
181
|
+
method. Name the fixed observation and what it did not cover. A snapshot
|
|
182
|
+
reserves nothing and cannot cover unpublished concurrent work.
|
|
183
|
+
|
|
184
|
+
If requested additions exceed 99-H, stop before any partial allocation or
|
|
185
|
+
invalid declaration. Never fill gaps, reuse retired IDs or emit tail 100.
|
|
186
|
+
An empty scope has capacity 99. H = 98 allows one addition at tail 99, not two;
|
|
187
|
+
a retired 99 still exhausts the scope. Recheck newly published claims or
|
|
188
|
+
collisions before publication.
|
|
189
|
+
|
|
190
|
+
### Capacity partition
|
|
191
|
+
|
|
192
|
+
Only additions exceeding an actual AC or EX scope's remaining 99-H qualify for
|
|
193
|
+
a capacity-only story partition. Record the source story, affected kind, H,
|
|
194
|
+
remainder and requested count first. Prefer leaving every published case and ID
|
|
195
|
+
in place and putting a cohesive incoming group in a capacity-checked sibling
|
|
196
|
+
under the same BF and actual actor goal. An in-force owning change request must
|
|
197
|
+
explicitly approve this partition and its affected paths before writing.
|
|
198
|
+
|
|
199
|
+
State the sibling's truthful cohesive scope and settle each criterion's owner;
|
|
200
|
+
do not invent a new product outcome, duplicate an obligation or weaken it.
|
|
201
|
+
A different actor, goal, flow or intended behavior needs its existing owning
|
|
202
|
+
approval path. Additions that fit the original scope do not qualify. Missing
|
|
203
|
+
authority, insufficient destination capacity or no truthful partition stops
|
|
204
|
+
the dependent write. This prospective split places new overflow cases; moving
|
|
205
|
+
an existing case also needs the complete map below. These instructions approve
|
|
206
|
+
no future specific creation, move or split.
|
|
207
|
+
|
|
208
|
+
### Actual moves and incoming collisions
|
|
209
|
+
|
|
210
|
+
Before an approved actual AC/EX move or incoming collision repair, make a
|
|
211
|
+
complete one-to-one map of:
|
|
212
|
+
|
|
213
|
+
- the fixed source commit and declaration path;
|
|
214
|
+
- each original BF/US/AC/EX identity and its case meaning;
|
|
215
|
+
- destination story, AC/EX IDs and paths;
|
|
216
|
+
- every affected active BR citation and counted adjacent test declaration;
|
|
217
|
+
- unaffected cases and the input, expected outcome and executable assertion
|
|
218
|
+
each mapped case preserves.
|
|
219
|
+
|
|
220
|
+
Check both scopes' retired-inclusive capacity. Each destination EX needs one
|
|
221
|
+
existing destination AC; each AC needs an EX. Preserve every moved EX's
|
|
222
|
+
owning BR link and counted test obligation. An ID change alone proves no
|
|
223
|
+
coverage. Retire old moved IDs in a new approved record and never refill them.
|
|
224
|
+
Inherited published DEC ID, Content and Approach cells and their old-ID
|
|
225
|
+
references remain historical and unchanged; update only approved active
|
|
226
|
+
references.
|
|
227
|
+
|
|
228
|
+
Keep unaffected published cases and IDs. Identify same-number branch cases by
|
|
229
|
+
fixed provenance and meaning, and change only the provably incoming item,
|
|
230
|
+
without blanket replacement. Unknown ownership, ambiguous collisions,
|
|
231
|
+
uncovered declarations, missing counted test links, changed assertions or an
|
|
232
|
+
incomplete map stops the move without a completion claim. This is a manual
|
|
233
|
+
approval and mapping procedure, not a relocation executor or mapping schema.
|
|
234
|
+
|
|
107
235
|
Two branches can take the same next ID. When a merge leaves one ID on two items:
|
|
108
236
|
|
|
109
237
|
1. The merge target's item keeps the ID. Renumber the incoming item, the one the merge brings in.
|
|
110
238
|
2. Give it the next ID of its scope.
|
|
111
239
|
A renumbered BF or US takes its child IDs and its directory names with it, as a move to another BF does below.
|
|
112
|
-
3. Change every citation
|
|
240
|
+
3. Change every citation belonging to the incoming item in the same commit.
|
|
241
|
+
For a decision, leave inherited references unchanged.
|
|
113
242
|
4. State the old ID, the new ID and the renamed record's subject or path in the commit message.
|
|
114
243
|
A citation of the old ID elsewhere is then told apart from the item that kept it.
|
|
115
244
|
|
|
@@ -118,7 +247,33 @@ A row the incoming branch added takes the next ID of its table.
|
|
|
118
247
|
An ID that two merged records already share is not renumbered:
|
|
119
248
|
ask the user for a change request row that states which record each citation meant.
|
|
120
249
|
|
|
121
|
-
|
|
250
|
+
For a unique decision added by the incoming branch, repair its ID before merging:
|
|
251
|
+
|
|
252
|
+
```text
|
|
253
|
+
qfai sdd renumber-decision --from <old-DEC-ID> --to <new-DEC-ID> --base <local-ref>
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
The explicit base and HEAD must resolve locally and have one common ancestor
|
|
257
|
+
that declares no source row. The base may already use that ID; the current
|
|
258
|
+
tree must declare it only once. Choose an unused destination above both story trees'
|
|
259
|
+
highest decision number, retired IDs included, within the four-digit grammar.
|
|
260
|
+
The command reserves no number and chooses no final number automatically.
|
|
261
|
+
|
|
262
|
+
Read the preview's fixed SHAs, IDs, relative paths and replacement lines or
|
|
263
|
+
counts. It writes nothing and dumps no original lines or full files. Each
|
|
264
|
+
invocation builds its own plan. Run with `--apply` to recheck that invocation's
|
|
265
|
+
fixed refs and original bytes before writing; changed refs after a preview can
|
|
266
|
+
produce a different plan. Preflight-only
|
|
267
|
+
`--format`, `--fail-on`, `--import` and `--assume` are not accepted here.
|
|
268
|
+
Only provably branch-added exact references change. Inherited references stay
|
|
269
|
+
fixed; ambiguous ownership, dirty or linked candidates, unsupported text or
|
|
270
|
+
failed reads stop the whole plan before writing. Unrelated links and dirty
|
|
271
|
+
files are not candidates. Apply rechecks original bytes before each write.
|
|
272
|
+
Rollback restores a changed file only if its bytes still match this invocation's
|
|
273
|
+
replacement, preserving concurrent changes and naming any unrestored path.
|
|
274
|
+
These checks guarantee neither atomic concurrency nor power-loss safety.
|
|
275
|
+
|
|
276
|
+
A move to another BF changes the story's US ID and all child AC and EX IDs. It follows the existing approval path, not the same-BF capacity exception. Apply the complete map above to approved active citations and retire old IDs in a new approved record; inherited DEC cells and their historical references stay unchanged.
|
|
122
277
|
|
|
123
278
|
## Completion of triage
|
|
124
279
|
|
|
@@ -89,14 +89,26 @@ The table holds no rule. A behaviour a layer must show is a BR in the contract t
|
|
|
89
89
|
|
|
90
90
|
Use highest existing number plus one in the scope. Count IDs named in retired-item decisions, so deletion never frees an ID. Empty scopes begin at 0001 or, for AC and EX tails, 01. Directory names match their BF and US IDs. Do not add a CLI allocator.
|
|
91
91
|
|
|
92
|
+
AC/EX tails remain two digits with upper bound 99. Before planned additions,
|
|
93
|
+
compare requested additions with the retired-inclusive remaining 99-H. Stop an
|
|
94
|
+
over-capacity batch before partial declarations. For an approved capacity-only
|
|
95
|
+
sibling or actual move, apply the owning stage's capacity preflight and complete
|
|
96
|
+
map before writing; no larger ID or new product outcome is a substitute for the
|
|
97
|
+
required scope.
|
|
98
|
+
|
|
92
99
|
Constraint IDs are the exception. `TC-NN`, `OC-NN` and `BC-NN` in constraint.md are positional: each section numbers its rows from 01 in table order. No other document cites one, so a removed row closes the gap and the rows after it are renumbered. `npx qfai validate` reports a constraint ID that is not its row's place.
|
|
93
100
|
|
|
94
|
-
Moving a story to another flow changes its US ID and every child AC and EX ID
|
|
101
|
+
Moving a story to another flow changes its US ID and every child AC and EX ID
|
|
102
|
+
under its existing approval path. Preserve case meanings and assertions through
|
|
103
|
+
the complete fixed-source map, update approved active indexes, contract citations
|
|
104
|
+
and counted test references. Record the old IDs as retired in a new approved
|
|
105
|
+
record so they cannot be issued again. Inherited DEC ID, Content and Approach
|
|
106
|
+
cells and their old-ID references stay historical and unchanged.
|
|
95
107
|
|
|
96
108
|
## Edge rules
|
|
97
109
|
|
|
98
110
|
1. business-flows.md cites each actual BF. Each business-flow.md states its BF in its H1, gives its purpose, and draws its main path as exactly one Mermaid flowchart or sequenceDiagram under `## Flow`.
|
|
99
|
-
2. user-stories.md cites each US under that flow. A user story declares its US in its H1. Its parent BF is the directory it sits in, and no line of the file restates it. Keep each observable outcome in its own story.
|
|
111
|
+
2. user-stories.md cites each US under that flow. A user story declares its US in its H1. Its parent BF is the directory it sits in, and no line of the file restates it. Keep each observable outcome in its own story, except the explicitly approved same-BF, same-actor-goal capacity-only partition above.
|
|
100
112
|
3. 02_Acceptance-Criteria.md states each AC under that US as an `# AC-NNNN-NNNN-NN` comment followed by exactly one Gherkin `Scenario:`.
|
|
101
113
|
4. Each EX row in 03_Example.md has exactly one AC-Ref. It names an AC in that story. Every AC has at least one EX.
|
|
102
114
|
5. Each BR lives in an enforcing contract and cites one or more full EX IDs that already exist. Every EX is cited by at least one BR. Several BRs may cite an EX, and one BR may cite several EXs.
|
|
@@ -11,6 +11,7 @@ The flows a UI contract serves are the flows whose examples its rules cite; the
|
|
|
11
11
|
- `elements[].label` is inspection-target text
|
|
12
12
|
- `data-qfai` marker convention
|
|
13
13
|
- Prototype metadata
|
|
14
|
+
- Purposeful copy: `supplements` and `structure`
|
|
14
15
|
- Screen contract rules
|
|
15
16
|
- Template
|
|
16
17
|
- Typical failures
|
|
@@ -143,6 +144,142 @@ evidence records nothing against it — an entry is a note between the contract'
|
|
|
143
144
|
author and whoever reviews the prototype. Follow the shape
|
|
144
145
|
`templates/contracts/ui-contract.sample.yaml` shows.
|
|
145
146
|
|
|
147
|
+
## Purposeful copy: `supplements` and `structure`
|
|
148
|
+
|
|
149
|
+
A screen states the words it shows, so that implementation adds none the contract
|
|
150
|
+
did not ask for and review can compare the rendered screen with what was agreed.
|
|
151
|
+
The words are the screen `title` (its one heading), the labels of `elements` and
|
|
152
|
+
`actions`, the group headings, and the supplements below. Two keys carry them,
|
|
153
|
+
beside `primary_tasks`, `elements` and `actions`, which stay as they are.
|
|
154
|
+
|
|
155
|
+
### `supplements` (required)
|
|
156
|
+
|
|
157
|
+
Every text the screen shows beyond its `title`, group headings and labels: a
|
|
158
|
+
sentence under a field, a notice, an empty-state message, a disclosure, the result
|
|
159
|
+
of a save or a send, the instruction after a failure, the consequence of an action
|
|
160
|
+
that cannot be undone. Each is an entry with exactly these keys, all non-empty:
|
|
161
|
+
|
|
162
|
+
| Key | Holds |
|
|
163
|
+
| ------ | ----------------------------------------------------------------------------------------- |
|
|
164
|
+
| `id` | stable key, unique in the screen |
|
|
165
|
+
| `near` | the `id` of the element, action or structure group the text sits with |
|
|
166
|
+
| `when` | the state it shows in: `default`, `empty`, `loading`, `error` or `success` |
|
|
167
|
+
| `text` | the words as displayed |
|
|
168
|
+
| `why` | what the user could not know or do without it, and why a label or structure is not enough |
|
|
169
|
+
|
|
170
|
+
`supplements: []` says the screen shows none. Most screens need few, and a screen
|
|
171
|
+
need not have any. Two kinds of text are not supplements: the message of a field
|
|
172
|
+
rule is owned by the `validations` of its element, and data the product shows or
|
|
173
|
+
the user types is not copy the contract authors. A field message that says more
|
|
174
|
+
than its rule does is a supplement with `when: error`.
|
|
175
|
+
|
|
176
|
+
The list is the whole inventory in both directions. Text the screen shows that is
|
|
177
|
+
not listed is excess. A listed text the screen does not show is an unmet need, so
|
|
178
|
+
a necessary condition, cost, destination, result, recovery step or consequence
|
|
179
|
+
that is written here cannot be dropped by a later tidy-up; removing it is a
|
|
180
|
+
change to the contract, which goes back to `/qfai-sdd`.
|
|
181
|
+
|
|
182
|
+
Write `why` for the point of decision. "Explains the Save button" is a reason to
|
|
183
|
+
delete the text. "After the click the user cannot see where the draft went" is a
|
|
184
|
+
reason to keep it.
|
|
185
|
+
|
|
186
|
+
### `structure` (optional)
|
|
187
|
+
|
|
188
|
+
The groups the screen is read in, in reading order. Each is an entry with exactly
|
|
189
|
+
`id`, `tasks`, `members` and, when the group shows a heading, `heading`:
|
|
190
|
+
|
|
191
|
+
| Key | Holds |
|
|
192
|
+
| --------- | ------------------------------------------------------------------ |
|
|
193
|
+
| `id` | stable key, unique in the screen |
|
|
194
|
+
| `tasks` | the `primary_tasks[].id` values the group serves, at least one |
|
|
195
|
+
| `members` | the `elements[].id` and `actions[].id` values it holds, in order |
|
|
196
|
+
| `heading` | the displayed heading; leave the key out when the group shows none |
|
|
197
|
+
|
|
198
|
+
An id belongs to one group, and an element or action may be left out of every
|
|
199
|
+
group. `structure` is optional only for a screen that shows no heading beyond its
|
|
200
|
+
`title`. A screen that shows any other heading, at any level, has one group with a
|
|
201
|
+
`heading` for each, so a screen with several `h2` headings writes `structure`.
|
|
202
|
+
Leaving the key out says the screen shows no such heading; it never says the
|
|
203
|
+
screen may show one without a group. A group needs a task and a member, so the
|
|
204
|
+
heading must head something the user reads or acts on: declare the table or list
|
|
205
|
+
that shows data as an element, and the group holds it. A heading over prose or
|
|
206
|
+
supplements alone has neither a task nor a member, and does not belong on the
|
|
207
|
+
screen. `npx qfai validate` does not check this, so the
|
|
208
|
+
reviewer compares the rendered headings with the groups. A group heading is
|
|
209
|
+
not the screen title: a second heading above or beside the real one repeats it.
|
|
210
|
+
A group that serves no task does not belong on the screen; name the task it
|
|
211
|
+
enables, or leave the heading and the group out.
|
|
212
|
+
|
|
213
|
+
### Which key holds which text
|
|
214
|
+
|
|
215
|
+
Every text the screen shows has one home. The table applies the definitions above
|
|
216
|
+
to the text authors and reviewers most often disagree about:
|
|
217
|
+
|
|
218
|
+
| Rendered text | Home |
|
|
219
|
+
| ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
|
|
220
|
+
| The one page heading (`h1`) | `title` |
|
|
221
|
+
| A heading over a group of elements or actions (`h2`, `h3`) | `structure[].heading` of that group |
|
|
222
|
+
| A small line above or beside a heading (eyebrow, kicker) | a supplement with `near` set to the group; it is not a heading and not a label |
|
|
223
|
+
| The text of a field, button or other control | `label` of that element or action |
|
|
224
|
+
| Link text | `label` of a `navigate` action |
|
|
225
|
+
| A table column header | recommended: `label` of an element declared for that column, as elements are the display fields |
|
|
226
|
+
| A figure caption | a supplement with `near` set to the element it describes |
|
|
227
|
+
| An item of a list the product writes (a fixed checklist) | a supplement |
|
|
228
|
+
| An item of a list made of data the product shows | outside the contract: data is not copy the contract authors |
|
|
229
|
+
| Product or site-identity text (a name, a tagline) | `label` when it is a link or control, otherwise a supplement |
|
|
230
|
+
| The message of a field rule | `validations` of that element |
|
|
231
|
+
|
|
232
|
+
Nothing is outside the contract merely because it repeats across screens. Text that
|
|
233
|
+
repeats on every screen is listed on each, and when no `why` that names a decision
|
|
234
|
+
can be written for it, the text is a candidate for removal from the screen rather
|
|
235
|
+
than a reason to leave it unlisted.
|
|
236
|
+
|
|
237
|
+
### A worked example
|
|
238
|
+
|
|
239
|
+
The sample at `templates/contracts/ui-contract.sample.yaml` shows a complete
|
|
240
|
+
screen. Its draft action reads "Save draft", and no paragraph says what Save draft
|
|
241
|
+
does. What the label cannot say is declared instead: `Saved to Drafts` after the
|
|
242
|
+
click, and `Not saved. Your entries are still here. Try again.` after a failure.
|
|
243
|
+
The user learns where the draft went and what a failure means, and nothing is
|
|
244
|
+
written twice.
|
|
245
|
+
|
|
246
|
+
### What a necessary text looks like
|
|
247
|
+
|
|
248
|
+
Subtraction removes text that adds no meaning. It never removes:
|
|
249
|
+
|
|
250
|
+
- a condition, cost, storage or transmission destination, or the result of an
|
|
251
|
+
action that is not visible otherwise (a demo-data notice that is true and
|
|
252
|
+
shown where the user decides is one of these);
|
|
253
|
+
- error recovery, and the consequence of an action that cannot be undone;
|
|
254
|
+
- labels, accessible names, roles and states.
|
|
255
|
+
|
|
256
|
+
Moving such text into a tooltip or a placeholder does not keep it. A word or
|
|
257
|
+
character count never approves or rejects a screen; a count is an observation
|
|
258
|
+
a finding may cite.
|
|
259
|
+
|
|
260
|
+
### What validate checks
|
|
261
|
+
|
|
262
|
+
`QFAI-CONTRACT-043` reports `supplements` absent, a key that is not a list, an
|
|
263
|
+
entry that is not a mapping, a missing, empty or extra key, a `when` outside the
|
|
264
|
+
five states, and a repeated `id`; the same for `structure` when it is written.
|
|
265
|
+
`QFAI-CONTRACT-044` reports a `members`, `tasks` or `near` that names an id
|
|
266
|
+
the screen does not declare, and an element or action in two groups.
|
|
267
|
+
`QFAI-CONTRACT-045` warns when a group heading is the screen title, or a
|
|
268
|
+
supplement's text is the title, a group heading, the label of what it sits near, or
|
|
269
|
+
another supplement's text near the same target in the same state; case, spacing and
|
|
270
|
+
closing punctuation do not make a text different. Whether a sentence is needed is
|
|
271
|
+
judged against the task by the reviewer; validate compares ids and exact wording
|
|
272
|
+
only.
|
|
273
|
+
|
|
274
|
+
A contract written before these keys was valid without them. Add
|
|
275
|
+
`supplements` to each screen: `supplements: []` is the answer for a screen that
|
|
276
|
+
shows nothing beyond its title and labels. Keep `structure` out while the screen
|
|
277
|
+
shows no heading beyond its title; the first such heading needs its group.
|
|
278
|
+
|
|
279
|
+
Two contracts that state the same screen `id` each hold their own `supplements`
|
|
280
|
+
and `structure`; the project-wide screen list compares `title`, `route` and
|
|
281
|
+
`primary_tasks` only.
|
|
282
|
+
|
|
146
283
|
## Screen contract rules
|
|
147
284
|
|
|
148
285
|
`screens[].elements[]` are the display fields:
|
|
@@ -185,6 +322,13 @@ Render the element with that marker, or remove the marker from the contract.
|
|
|
185
322
|
**A label does not match.** Update the contract label, then the rendered text or
|
|
186
323
|
marker mapping. Updating one side leaves the two out of step.
|
|
187
324
|
|
|
325
|
+
**`QFAI-CONTRACT-043` names a screen with no `supplements`.** Add `supplements: []`
|
|
326
|
+
if the screen shows no text beyond its title, group headings and labels, or list each
|
|
327
|
+
text with its `near`, `when`, `text` and `why`.
|
|
328
|
+
|
|
329
|
+
**`QFAI-CONTRACT-045` warns that a supplement repeats a label.** Delete the supplement,
|
|
330
|
+
or word it so it tells the user something the label does not.
|
|
331
|
+
|
|
188
332
|
**The discussion pack already has screen contracts, so this looks redundant.**
|
|
189
333
|
It is not. A discussion pack is discovery output and is non-normative; the
|
|
190
334
|
downstream skills and every validate lane read `<paths.contractsDir>/ui/*.yaml`.
|
|
@@ -207,4 +351,6 @@ For a UI-bearing visual flow, the root `DESIGN.md` is authored and validated by
|
|
|
207
351
|
- [ ] Every UI-bearing contract has one full declared ID, at least one screen, and a matching `contracts.md` row.
|
|
208
352
|
- [ ] Screen IDs, routes, primary tasks, labels, markers, and actions are stable and testable.
|
|
209
353
|
- [ ] Every declared action has an observable effect, including relevant failure states.
|
|
354
|
+
- [ ] Every screen declares `supplements` (`[]` when none), each with the reason the text is needed, and its `structure` names every heading beyond the title.
|
|
355
|
+
- [ ] No supplement restates a label, heading or action the screen already shows, and none is development commentary.
|
|
210
356
|
- [ ] Prototyping coverage uses full contract IDs and the current cycle-0 fields.
|