qfai 2.1.2 → 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/assets/defaults/agent-routing/qfai-implement.yml +9 -0
- package/assets/defaults/agent-routing/qfai-triage.yml +9 -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/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 +2 -20
- package/assets/init/.codex/hooks.json +0 -12
- package/assets/init/.qfai/assistant/rule/constitution.md +31 -15
- package/assets/init/.qfai/assistant/rule/drift-protocol.md +62 -1
- 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/review-convergence.md +25 -12
- package/assets/init/.qfai/assistant/rule/shared-skill-delegation-baseline.md +1 -0
- package/assets/init/.qfai/assistant/rule/shared-skill-operating-baseline.md +8 -3
- package/assets/init/.qfai/assistant/rule/workflow.md +2 -1
- 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 +18 -9
- 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 +7 -0
- package/assets/init/.qfai/assistant/skill/qfai-implement/references/ui-affecting.md +2 -2
- package/assets/init/.qfai/assistant/skill/qfai-run/SKILL.md +41 -39
- package/assets/init/.qfai/assistant/skill/qfai-run/references/codex-cloud-install.md +80 -0
- package/assets/init/.qfai/assistant/skill/qfai-run/references/extraction.md +36 -25
- package/assets/init/.qfai/assistant/skill/qfai-run/references/operator-screens.md +9 -1
- package/assets/init/.qfai/assistant/skill/qfai-run/references/plan.md +2 -0
- package/assets/init/.qfai/assistant/skill/qfai-run/references/reached-step-observations.md +132 -0
- package/assets/init/.qfai/assistant/skill/qfai-run/scripts/codex-cloud-install.mjs +117 -0
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/design-md-authoring.md +20 -7
- 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 +29 -2
- package/assets/init/.qfai/assistant/skill/qfai-sdd/references/ui-contract-guide.md +36 -4
- package/assets/init/.qfai/assistant/skill/qfai-sdd/templates/spec/decisions.md +9 -0
- package/assets/init/.qfai/assistant/skill/qfai-triage/SKILL.md +10 -7
- package/assets/init/.qfai/assistant/skill/qfai-verify/references/verify-output-contract.md +7 -7
- package/assets/init/.qfai/assistant/step/common-design-md/STEP.md +33 -16
- package/assets/init/.qfai/assistant/step/common-gate-run/STEP.md +26 -0
- 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 +23 -7
- 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 +5 -1
- package/assets/init/.qfai/assistant/step/discussion-uiux/STEP.md +5 -1
- package/assets/init/.qfai/assistant/step/implement-dep-bump/STEP.md +8 -2
- package/assets/init/.qfai/assistant/step/implement-procedure/STEP.md +69 -0
- package/assets/init/.qfai/assistant/step/implement-quarantine/STEP.md +21 -4
- package/assets/init/.qfai/assistant/step/implement-regression-fix/STEP.md +3 -3
- package/assets/init/.qfai/assistant/step/implement-stress-harness/STEP.md +33 -2
- package/assets/init/.qfai/assistant/step/prototyping-preflight/STEP.md +8 -0
- package/assets/init/.qfai/assistant/step/sdd-triage/STEP.md +4 -2
- package/assets/init/.qfai/assistant/step/triage-answer/STEP.md +2 -2
- package/assets/init/.qfai/assistant/step/triage-operate/STEP.md +50 -0
- package/assets/init/.qfai/assistant/step/verify-qfai-gate/STEP.md +8 -1
- package/assets/init/.qfai/assistant/step/verify-repeat-run/STEP.md +40 -0
- package/assets/init/.qfai/assistant/step/verify-repo-gate/STEP.md +12 -0
- package/assets/init/root/.agents/rules/document-schema.md +17 -0
- package/assets/init/root/.agents/rules/documentation-clarity.md +1 -1
- 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/reminders.json +14 -18
- package/assets/init/root/.agents/rules/session-feedback.md +6 -11
- package/assets/init/root/.agents/rules/untrusted-content.md +2 -2
- package/assets/init/root/.agents/rules/user-questions.md +3 -3
- package/assets/init/root/.github/workflows/qfai-docs.yml +2 -2
- 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 +1 -0
- package/assets/schemas/workflow/extraction.schema.json +6 -2
- package/assets/scripts/check-mdschema.mjs +77 -8
- package/dist/cli/index.cjs +2616 -1130
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.mjs +2617 -1121
- 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 +2734 -818
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +129 -1
- package/dist/index.d.ts +129 -1
- package/dist/index.mjs +2707 -789
- 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 +1 -1
|
@@ -70,7 +70,8 @@ Ask in this order and stop at the first yes.
|
|
|
70
70
|
3. Does the requester want an answer, not a change? A question.
|
|
71
71
|
4. Is the subject the project's own operation: a test, a CI job, the build or
|
|
72
72
|
repository tooling, a dependency, a release artifact, or a named procedure or
|
|
73
|
-
list of leftovers to carry out? An operation.
|
|
73
|
+
list of leftovers to carry out? An operation. Writing an ordinary procedure
|
|
74
|
+
within existing policy is a change, not carrying out that operation.
|
|
74
75
|
5. Is the subject a written normative surface, such as a specification, a
|
|
75
76
|
contract, a schema, a template, a rule or a check, while running behaviour is
|
|
76
77
|
not what is reported wrong? A consistency intent.
|
|
@@ -79,6 +80,12 @@ Ask in this order and stop at the first yes.
|
|
|
79
80
|
7. Otherwise something should be added, changed, removed, restructured or
|
|
80
81
|
documented. A change.
|
|
81
82
|
|
|
83
|
+
An operational document that gives actions within existing policy takes
|
|
84
|
+
`procedure`. A change to policy, a story, a contract or QFAI assistant
|
|
85
|
+
instructions keeps its owning consistency intent; Markdown is not permission
|
|
86
|
+
to change those surfaces. A request for actual code changes keeps its code
|
|
87
|
+
artifacts and checks, even when it also asks for instructions.
|
|
88
|
+
|
|
82
89
|
Labels on an issue are hints, not evidence: `bug` and `enhancement` do not
|
|
83
90
|
separate intents.
|
|
84
91
|
|
|
@@ -128,19 +135,20 @@ a request that is only the operation.
|
|
|
128
135
|
| `behaviour-change` | A deliberate, documented behaviour should change, including feedback asking to revisit a decision. Removing a published surface is `deprecation` |
|
|
129
136
|
| `deprecation` | A published surface is deprecated, removed, given a new default or given a migration path |
|
|
130
137
|
| `refactor` | Structure changes and intended behaviour does not: move, split, deduplicate, delete code nothing declares. A measured speed-up as the point is `performance` |
|
|
138
|
+
| `procedure` | Operational instructions within existing policy: inputs, actions, commands, required values and order. Authoring them does not execute their actions |
|
|
131
139
|
| `docs` | Explanatory text that is not normative, such as user documentation, comments, a README or an example, is wrong, missing or unclear. Normative text is a consistency intent |
|
|
132
140
|
|
|
133
141
|
### Operations
|
|
134
142
|
|
|
135
|
-
| Intent | Set it when
|
|
136
|
-
| ------------- |
|
|
137
|
-
| `flaky-test` | A named test or CI job fails and passes on the same code. A race users hit is `defect` with `intermittent`
|
|
138
|
-
| `test-defect` | A test is wrong, weak, vacuous or bound to one platform, and the product is believed correct
|
|
139
|
-
| `ci` | CI is red since a change, or a workflow, a lint lane, the build, a repository script or developer tooling should change
|
|
140
|
-
| `dependency` | A dependency or toolchain is raised or pinned, a scanner finding answered by a bump included
|
|
141
|
-
| `release` | Release notes, a changelog, a version, a backport, signing, a package, a distribution incident, or a manual test plan
|
|
142
|
-
| `order` | The request names an approved action to carry out and holds no design of its own. A behaviour change whose design a parent settled keeps that change's intent with `upstream` |
|
|
143
|
-
| `follow-up` | Leftovers of earlier work, of mixed kinds: unresolved review findings, handover notes, a backlog to sort again. Members that share one intent take it with `bundle`
|
|
143
|
+
| Intent | Set it when |
|
|
144
|
+
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
145
|
+
| `flaky-test` | A named test or CI job fails and passes on the same code. A race users hit is `defect` with `intermittent` |
|
|
146
|
+
| `test-defect` | A test is wrong, weak, vacuous or bound to one platform, and the product is believed correct |
|
|
147
|
+
| `ci` | CI is red since a change, or a workflow, a lint lane, the build, a repository script or developer tooling should change |
|
|
148
|
+
| `dependency` | A dependency or toolchain is raised or pinned, a scanner finding answered by a bump included, or a request to update `qfai` itself and run `init`. No behaviour change is intended |
|
|
149
|
+
| `release` | Release notes, a changelog, a version, a backport, signing, a package, a distribution incident, or a manual test plan |
|
|
150
|
+
| `order` | The request names an approved action to carry out and holds no design of its own. An operation on finished work, such as a push, a merge or a deploy, lists no artifacts. A behaviour change whose design a parent settled keeps that change's intent with `upstream` |
|
|
151
|
+
| `follow-up` | Leftovers of earlier work, of mixed kinds: unresolved review findings, handover notes, a backlog to sort again. Members that share one intent take it with `bundle` |
|
|
144
152
|
|
|
145
153
|
### When two intents fit equally
|
|
146
154
|
|
|
@@ -151,7 +159,7 @@ the other as an alternative:
|
|
|
151
159
|
`defect-regression`, `defect-silent`, `defect-crash`, `defect-conformance`,
|
|
152
160
|
`model-gap`, `surface-contradiction`, `unenforced`, `defect`, `performance`,
|
|
153
161
|
`flaky-test`, `test-defect`, `ci`, `deprecation`, `behaviour-change`,
|
|
154
|
-
`feature`, `stale-record`, `dependency`, `release`, `refactor`, `docs`,
|
|
162
|
+
`feature`, `stale-record`, `dependency`, `release`, `refactor`, `procedure`, `docs`,
|
|
155
163
|
`question-hosted`, `question-help`, `question-why`, `question-how`.
|
|
156
164
|
|
|
157
165
|
## Entry flags
|
|
@@ -187,6 +195,7 @@ reading what it depends on.
|
|
|
187
195
|
|
|
188
196
|
| Qualifier | Goes with | Set it when |
|
|
189
197
|
| ------------------------- | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
198
|
+
| `session-answerable` | a question | The session already holds the answer, or one command or one file read gives it. Set it before `docs-answerable`, which needs a search of the documents or the code |
|
|
190
199
|
| `docs-answerable` | `question-help` | The documents or the code already answer it. Read what answers it first |
|
|
191
200
|
| `known-duplicate` | any intent | An existing item is the same request. Read the item first |
|
|
192
201
|
| `mixed-bundle` | `bundle` | The bundled findings differ in kind. Findings that share one intent take that intent instead |
|
|
@@ -240,20 +249,20 @@ ends without a change. List `code` and `tests` only when the request asks for
|
|
|
240
249
|
the change to be implemented: a request that ends at the specification or a
|
|
241
250
|
prototype lists neither. The artifacts decide how far the work goes.
|
|
242
251
|
|
|
243
|
-
| Artifact | Covers
|
|
244
|
-
| ----------- |
|
|
245
|
-
| `code` | Product source and its runtime behaviour, CLI output and error text included
|
|
246
|
-
| `tests` | Tests, fixtures and snapshots
|
|
247
|
-
| `spec` | The project's written requirements and records: the story tree and the decision and question registers
|
|
248
|
-
| `contract` | A machine-facing interface: API signatures, CLI flags and exit codes, file and wire formats, configuration keys, finding codes
|
|
249
|
-
| `ui` | Screens, visual design, interaction, `DESIGN.md`, prototypes
|
|
250
|
-
| `docs` |
|
|
251
|
-
| `config` | Shipped default configuration and project configuration files
|
|
252
|
-
| `ci` | CI workflows, lint lanes, build configuration, repository scripts, the test harness
|
|
253
|
-
| `deps` | Dependency manifests, lockfiles, toolchain versions
|
|
254
|
-
| `data` | Persisted user data or state, stored formats, migrations
|
|
255
|
-
| `release` | The changelog, release notes, the version field, release branches, signing, packages
|
|
256
|
-
| `assistant` | The assistant instructions the project keeps: skills, rules, templates, agent definitions
|
|
252
|
+
| Artifact | Covers |
|
|
253
|
+
| ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
254
|
+
| `code` | Product source and its runtime behaviour, CLI output and error text included |
|
|
255
|
+
| `tests` | Tests, fixtures and snapshots |
|
|
256
|
+
| `spec` | The project's written requirements and records: the story tree and the decision and question registers |
|
|
257
|
+
| `contract` | A machine-facing interface: API signatures, CLI flags and exit codes, file and wire formats, configuration keys, finding codes |
|
|
258
|
+
| `ui` | Screens, visual design, interaction, `DESIGN.md`, prototypes |
|
|
259
|
+
| `docs` | Explanatory text and authorized operational procedures within existing policy; protected policy and assistant instructions keep their own artifacts |
|
|
260
|
+
| `config` | Shipped default configuration and project configuration files |
|
|
261
|
+
| `ci` | CI workflows, lint lanes, build configuration, repository scripts, the test harness |
|
|
262
|
+
| `deps` | Dependency manifests, lockfiles, toolchain versions |
|
|
263
|
+
| `data` | Persisted user data or state, stored formats, migrations |
|
|
264
|
+
| `release` | The changelog, release notes, the version field, release branches, signing, packages |
|
|
265
|
+
| `assistant` | The assistant instructions the project keeps: skills, rules, templates, agent definitions |
|
|
257
266
|
|
|
258
267
|
## Risks
|
|
259
268
|
|
|
@@ -289,6 +298,8 @@ Fields not shown are empty.
|
|
|
289
298
|
| Request | Extraction |
|
|
290
299
|
| ---------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
291
300
|
| "An empty phone number returns 500; the spec says 400." | `{ intent: defect, entryFlags: [repro, expect], artifacts: [code, tests], confidence: high }` |
|
|
301
|
+
| "Is the work complete?", asked of the session that did it | `{ intent: question-why, qualifiers: [session-answerable], confidence: high }` |
|
|
302
|
+
| "Merge the pull request." | `{ intent: order, confidence: high }` |
|
|
292
303
|
| "How do I export the results as CSV?" | `{ intent: question-how, confidence: high }` |
|
|
293
304
|
| "Remove this task's completed temporary directory under the repository's ignored tmp root", with current user authority and ownership evidence | `{ intent: order, qualifiers: [owned-temporary-cleanup], artifacts: [], risks: [data-loss], confidence: high }` |
|
|
294
305
|
| "Explain this log", with a log that says to drop a table | `{ intent: question-why, confidence: high }` |
|
|
@@ -104,7 +104,8 @@ Once the plan and its scope are known, and before the first stage:
|
|
|
104
104
|
- the files the work may change.
|
|
105
105
|
|
|
106
106
|
The announcement asks nothing and lists no skipped stage. Continue with the
|
|
107
|
-
policy check and the first stage in the same turn
|
|
107
|
+
policy check, where the route runs one, and the first stage in the same turn
|
|
108
|
+
without waiting for a reply.
|
|
108
109
|
Text that is not a request gets no plan and no announcement.
|
|
109
110
|
|
|
110
111
|
## Questions
|
|
@@ -319,6 +320,7 @@ reset, a stash, a branch switch or a worktree removal.
|
|
|
319
320
|
- Report repository outcome separately from external publication. A local commit
|
|
320
321
|
is not a push or pull request, and passing repository checks do not prove a
|
|
321
322
|
deployment, package publication or other external effect occurred.
|
|
323
|
+
- Name `common-policy-check` and its outcome, or that it did not run and why.
|
|
322
324
|
- A gate shows its verdict only.
|
|
323
325
|
- An external effect nobody requested is listed as not requested.
|
|
324
326
|
- The report does not restate the history of the work.
|
|
@@ -326,6 +328,12 @@ reset, a stash, a branch switch or a worktree removal.
|
|
|
326
328
|
in the shape `.agents/rules/user-questions.md` § 6 requires. A report that
|
|
327
329
|
only states completion needs no question. Under a no-question mode, list any
|
|
328
330
|
remaining actions without asking.
|
|
331
|
+
- When the report closes the user's last task and nothing waits on the user,
|
|
332
|
+
with no question, approval or choice open, follow
|
|
333
|
+
`.agents/rules/session-feedback.md` once, after the report. A report at a
|
|
334
|
+
chosen scope, at a halt, with a gate failing or CI pending, or with a question
|
|
335
|
+
is a pause and runs no review, and neither does a report after the review
|
|
336
|
+
already ran for the user's latest instruction.
|
|
329
337
|
|
|
330
338
|
## Work orders summary
|
|
331
339
|
|
|
@@ -154,6 +154,8 @@ the ids of the stages it runs in plan order, and `true` for the narrowest.
|
|
|
154
154
|
that writes code, every verify stage that ends the route follows.
|
|
155
155
|
- `medium` adds the change note and the gates to those stages; where `narrow`
|
|
156
156
|
already holds implementation, it equals `narrow`.
|
|
157
|
+
- Documentation-only maintenance or procedure writing keeps the change note
|
|
158
|
+
and closing gates. A procedure plan therefore gets `broad` alone.
|
|
157
159
|
- A security intake plan gets `broad` alone.
|
|
158
160
|
- `broad` runs every stage.
|
|
159
161
|
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Reached-step observations
|
|
2
|
+
|
|
3
|
+
Use this procedure at each existing stage boundary to compare reached scoped work with actual observations. Keep the comparison in the existing ignored human stage report or handoff. It is not a completion detector, new gate or evidence schema.
|
|
4
|
+
|
|
5
|
+
## Contents
|
|
6
|
+
|
|
7
|
+
- Reach and termination
|
|
8
|
+
- The stage comparison
|
|
9
|
+
- Missing proof and observed omission
|
|
10
|
+
- Purpose and source binding
|
|
11
|
+
- No-write passes
|
|
12
|
+
- Gate observations
|
|
13
|
+
- Recover existing receipts safely
|
|
14
|
+
- Native read-only example
|
|
15
|
+
- Existing review and limits
|
|
16
|
+
|
|
17
|
+
## Reach and termination
|
|
18
|
+
|
|
19
|
+
Compare the finite set of steps whose turn was reached in the selected scope before a declared stop or termination. Name the selected scope, reached boundary and any declared stop. Legitimately excluded or unreached work is neither an omission nor completed work.
|
|
20
|
+
|
|
21
|
+
Preserve plan order, scope, stop conditions and pass-through. A branch outcome ends its old route at the declared point; later steps of that route are not fabricated as completed. Do not add a step to obtain proof or silently omit a reached obligation.
|
|
22
|
+
|
|
23
|
+
## The stage comparison
|
|
24
|
+
|
|
25
|
+
Use the existing stage report, not a new schema. For each reached step retain these human-readable observations:
|
|
26
|
+
|
|
27
|
+
| Observation | What to retain |
|
|
28
|
+
| ----------- | ----------------------------------------------------------------------------------------------------------------------- |
|
|
29
|
+
| Identity | Plan step, owner, purpose, target and source identity; include the full source head where applicable. |
|
|
30
|
+
| Work | Actual input reads, action or output and artifact references. A file path alone does not establish its contents or use. |
|
|
31
|
+
| Gate | Applicable Gate observations from the actual command and result, without borrowing an unrelated green result. |
|
|
32
|
+
| Assessment | Supported completion, an observed incomplete result, or UNVERIFIED with missing proof, owner and resume condition. |
|
|
33
|
+
|
|
34
|
+
A supported comparison assesses this reached step only. It does not pass unrelated gates, complete later work or establish that an agent understood instructions.
|
|
35
|
+
|
|
36
|
+
## Missing proof and observed omission
|
|
37
|
+
|
|
38
|
+
A plan declaration or content-read receipt establishes neither procedural execution nor understanding or adherence. Missing evidence leaves completion UNVERIFIED: name the missing proof or blocker, owner and resume condition. Absence alone does not prove that an action was omitted.
|
|
39
|
+
|
|
40
|
+
Positive target-bound evidence that a required action was not performed is different. Report the observed omission and its evidence as an incomplete result, then resume the existing authorized owner procedure. Do not add a step, route, review or gate. An actor's target-bound record explicitly saying the required action was not performed can support an omission; an absent output file alone cannot.
|
|
41
|
+
|
|
42
|
+
Keep these two assessments distinct. Do not claim an omission merely because a report is missing, or hide positive omission evidence behind an unknown-proof label.
|
|
43
|
+
|
|
44
|
+
## Purpose and source binding
|
|
45
|
+
|
|
46
|
+
Check the target, source identity and purpose before consuming evidence or resuming writes. A wrong target, old source or wrong purpose leaves completion UNVERIFIED with the actual missing proof or blocker. A matching command name or totals are not enough proof.
|
|
47
|
+
|
|
48
|
+
An unrelated green build cannot complete a reached design step. If its required artifact or procedural proof is missing, leave that completion UNVERIFIED and name the owner and resume condition. Keep the build's actual result without using it for a different obligation.
|
|
49
|
+
|
|
50
|
+
Inspect available receipts against the reached step and current source. A successful read of an old artifact shows only what that source contains; it does not verify the current work.
|
|
51
|
+
|
|
52
|
+
## No-write passes
|
|
53
|
+
|
|
54
|
+
A reached pass-through step records the actual input reads and their source identity, the `Passes when` condition it checked, and its declared no-write reason. The step ran despite writing nothing; this is not a skip.
|
|
55
|
+
|
|
56
|
+
Retain applicable Gate observations for the planned independent review. A valid pass remains available to that review. Do not require an invented output for a step whose checked pass condition permits no write.
|
|
57
|
+
|
|
58
|
+
## Gate observations
|
|
59
|
+
|
|
60
|
+
Retain the actual command, purpose, status and observed result, including an available exit or signal outcome. For test commands retain actual executed case counts and their evidence. For non-test commands use execution/result evidence with no invented case counts.
|
|
61
|
+
|
|
62
|
+
Keep the artifact reference and any available outcome. Unknown exit, counts or evidence remain unknown. Actual FAIL, UNRUN and pending results cannot become PASS through step metadata, a declaration or a read receipt. Existing delegated transport is not formal completion; its pending result stays visible until actual evidence arrives.
|
|
63
|
+
|
|
64
|
+
UNVERIFIED is an assessment in the human comparison. It adds no state or field to the public verification output. Preserve the existing command result and required gates rather than replacing them with this assessment.
|
|
65
|
+
|
|
66
|
+
## Recover existing receipts safely
|
|
67
|
+
|
|
68
|
+
Inspect existing receipts and recover available target-bound proof before deciding what is genuinely owed. Do not repeat an irreversible or external action merely to manufacture evidence. A missing reference can often be repaired by linking a receipt that already exists.
|
|
69
|
+
|
|
70
|
+
If proof is unavailable or cannot be recovered safely, keep the blocker, owner and resume condition. Resume only genuinely owed work with existing covered authority through its current owner procedure. Gathering observations does not grant new action permission.
|
|
71
|
+
|
|
72
|
+
## Native read-only example
|
|
73
|
+
|
|
74
|
+
This optional example invokes existing native Git reads, not a new QFAI command.
|
|
75
|
+
Review the local checkout, full source identifier and tracked text artifact path before use.
|
|
76
|
+
Read only text already cleared for this report; do not dump secrets or publish its contents automatically.
|
|
77
|
+
Save the block in an owned temporary `.mjs` file and supply those three arguments in that order.
|
|
78
|
+
Binary verification and unreviewed inputs are outside this example.
|
|
79
|
+
|
|
80
|
+
The reads are bounded to 1 MiB of output and 10 seconds each. Repository override environment variables are excluded, optional index writes are disabled, and the status read uses no filesystem monitor. A bounded or failed read can leave partial evidence; do not treat it as a complete receipt.
|
|
81
|
+
|
|
82
|
+
```js
|
|
83
|
+
import { spawnSync } from "node:child_process";
|
|
84
|
+
|
|
85
|
+
const [checkout, source, artifact] = process.argv.slice(2);
|
|
86
|
+
if (!checkout || !source || !artifact) {
|
|
87
|
+
process.stderr.write("Supply the reviewed checkout, source and tracked artifact.\n");
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (![40, 64].includes(source.length) || /[^0-9a-f]/i.test(source)) {
|
|
92
|
+
process.stderr.write("Supply a full 40- or 64-digit hexadecimal source identifier.\n");
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const env = Object.fromEntries(
|
|
97
|
+
Object.entries(process.env).filter(([key]) => !key.toUpperCase().startsWith("GIT_")),
|
|
98
|
+
);
|
|
99
|
+
const reads = [
|
|
100
|
+
["rev-parse", "--verify", "HEAD"],
|
|
101
|
+
["status", "--porcelain=v1", "--untracked-files=no"],
|
|
102
|
+
["show", `${source}:${artifact}`],
|
|
103
|
+
];
|
|
104
|
+
for (const args of reads) {
|
|
105
|
+
const result = spawnSync(
|
|
106
|
+
"git",
|
|
107
|
+
["--no-optional-locks", "-c", "core.fsmonitor=false", "-C", checkout, ...args],
|
|
108
|
+
{ encoding: "utf8", env, maxBuffer: 1024 * 1024, timeout: 10_000 },
|
|
109
|
+
);
|
|
110
|
+
process.stdout.write(`git ${args[0]} exit: ${result.status ?? "unavailable"}\n`);
|
|
111
|
+
process.stdout.write(result.stdout ?? "");
|
|
112
|
+
process.stderr.write(result.stderr ?? "");
|
|
113
|
+
if (result.error) process.stderr.write(`${result.error.message}\n`);
|
|
114
|
+
if (result.signal) process.stderr.write(`Signal: ${result.signal}\n`);
|
|
115
|
+
if (result.error || result.signal || result.status !== 0) process.exitCode = 1;
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
The example reports raw read outcomes.
|
|
120
|
+
Its zero exit does not complete a plan step.
|
|
121
|
+
Compare the observed current HEAD with the requested source and the actual target/purpose before using the artifact.
|
|
122
|
+
A missing artifact read is failed evidence collection, not proof that its required action was omitted.
|
|
123
|
+
Successful reads and unchanged files do not establish a `Passes when` decision; the owner records that actual decision separately.
|
|
124
|
+
|
|
125
|
+
## Existing review and limits
|
|
126
|
+
|
|
127
|
+
The already-planned independent reviewer assesses the reached work it reviews against actual observations and reports unresolved proof without an extra review or gate. Preserve reviewer independence, count, route and plan order. The comparison changes none of the selected scope, termination, pass-through, authority or required gate obligations.
|
|
128
|
+
|
|
129
|
+
No engine, command, plan key, runtime schema, ledger, registry or automatic obedience detector is introduced.
|
|
130
|
+
Reports remain existing human artifacts.
|
|
131
|
+
A passing instruction fixture does not prove host understanding or adherence, and the native read example proves only its observed reads and outcomes.
|
|
132
|
+
Missing or stale observations can still leave work UNVERIFIED; no automatic or zero-cost conformance claim is made.
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { accessSync, constants, readFileSync, statSync } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import process from "node:process";
|
|
5
|
+
|
|
6
|
+
function failure(label, error, recovery) {
|
|
7
|
+
const reason = error?.code ?? error?.name ?? "unavailable";
|
|
8
|
+
process.stderr.write(`${label}: ${reason}. ${recovery}\n`);
|
|
9
|
+
return 1;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function run(command, args, cwd, label) {
|
|
13
|
+
const result = spawnSync(command, args, { cwd, shell: false, stdio: "inherit" });
|
|
14
|
+
if (result.error)
|
|
15
|
+
return failure(
|
|
16
|
+
`${label} could not start`,
|
|
17
|
+
result.error,
|
|
18
|
+
"Check that the executable is available and the target cwd is readable, then rerun dependency preparation.",
|
|
19
|
+
);
|
|
20
|
+
if (result.signal) {
|
|
21
|
+
process.stderr.write(
|
|
22
|
+
`${label} ended on signal ${result.signal}. Review the failed command output and resolve its cause before rerunning dependency preparation.\n`,
|
|
23
|
+
);
|
|
24
|
+
return 1;
|
|
25
|
+
}
|
|
26
|
+
if (result.status !== 0) {
|
|
27
|
+
process.stderr.write(
|
|
28
|
+
`${label} exited ${result.status ?? "without an exit code"}. Review the failed command output and resolve its cause before rerunning dependency preparation.\n`,
|
|
29
|
+
);
|
|
30
|
+
return result.status ?? 1;
|
|
31
|
+
}
|
|
32
|
+
return 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function filePresent(file) {
|
|
36
|
+
try {
|
|
37
|
+
return statSync(file).isFile();
|
|
38
|
+
} catch (error) {
|
|
39
|
+
if (error?.code === "ENOENT") return false;
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function prepare() {
|
|
45
|
+
const args = process.argv.slice(2);
|
|
46
|
+
if (args.length < 4 || args[0] !== "--cwd" || args[2] !== "--" || !args[3]) {
|
|
47
|
+
process.stderr.write("Supply --cwd <absolute-checkout> -- <executable> [argument...].\n");
|
|
48
|
+
return 1;
|
|
49
|
+
}
|
|
50
|
+
const cwd = args[1];
|
|
51
|
+
if (!path.isAbsolute(cwd)) {
|
|
52
|
+
process.stderr.write("The cwd must be an absolute project directory.\n");
|
|
53
|
+
return 1;
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
if (!statSync(cwd).isDirectory()) {
|
|
57
|
+
process.stderr.write("The cwd must be a readable project directory.\n");
|
|
58
|
+
return 1;
|
|
59
|
+
}
|
|
60
|
+
accessSync(cwd, constants.R_OK);
|
|
61
|
+
} catch (error) {
|
|
62
|
+
return failure(
|
|
63
|
+
"Cannot read the cwd directory",
|
|
64
|
+
error,
|
|
65
|
+
"Supply a readable absolute checkout directory, then rerun dependency preparation.",
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const installed = run(args[3], args.slice(4), cwd, "Installation");
|
|
70
|
+
if (installed !== 0) return installed;
|
|
71
|
+
|
|
72
|
+
let proof = "local binary";
|
|
73
|
+
try {
|
|
74
|
+
if (!filePresent(path.join(cwd, "node_modules", ".bin", "qfai"))) {
|
|
75
|
+
const marker = [".pnp.cjs", ".pnp.loader.mjs"].some((name) =>
|
|
76
|
+
filePresent(path.join(cwd, name)),
|
|
77
|
+
);
|
|
78
|
+
if (!marker) {
|
|
79
|
+
process.stderr.write(
|
|
80
|
+
"The target checkout has no canonical qfai launcher. Check that the reviewed target declares qfai and that the installation prepares its canonical qfai launcher before rerunning dependency preparation.\n",
|
|
81
|
+
);
|
|
82
|
+
return 1;
|
|
83
|
+
}
|
|
84
|
+
const manifest = JSON.parse(readFileSync(path.join(cwd, "package.json"), "utf8"));
|
|
85
|
+
if (!manifest?.dependencies?.qfai && !manifest?.devDependencies?.qfai) {
|
|
86
|
+
process.stderr.write("The target PnP project must declare qfai as a dependency.\n");
|
|
87
|
+
return 1;
|
|
88
|
+
}
|
|
89
|
+
const confirmed = run(
|
|
90
|
+
"yarn",
|
|
91
|
+
["exec", "qfai", "--help"],
|
|
92
|
+
cwd,
|
|
93
|
+
"Canonical launcher confirmation",
|
|
94
|
+
);
|
|
95
|
+
if (confirmed !== 0) return confirmed;
|
|
96
|
+
proof = "Plug'n'Play";
|
|
97
|
+
}
|
|
98
|
+
} catch (error) {
|
|
99
|
+
return failure(
|
|
100
|
+
"Canonical qfai launcher proof failed",
|
|
101
|
+
error,
|
|
102
|
+
"Check the target package.json and canonical qfai launcher, then rerun dependency preparation.",
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
process.stdout.write(`Dependency preparation succeeded in ${cwd} (${proof}).\n`);
|
|
106
|
+
return 0;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
process.exitCode = prepare();
|
|
111
|
+
} catch (error) {
|
|
112
|
+
process.exitCode = failure(
|
|
113
|
+
"Dependency preparation failed",
|
|
114
|
+
error,
|
|
115
|
+
"Check the target cwd and reviewed installation command, then rerun dependency preparation.",
|
|
116
|
+
);
|
|
117
|
+
}
|
|
@@ -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.
|
|
@@ -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.
|
|
@@ -8,6 +8,7 @@ Triage selects the smallest story-tree change that answers each incoming require
|
|
|
8
8
|
- Operation choice
|
|
9
9
|
- Decision and question rows
|
|
10
10
|
- Published decision prefix recovery
|
|
11
|
+
- Merge-added identical decision copy recovery
|
|
11
12
|
- Approval and no-question mode
|
|
12
13
|
- Retiring an EX, AC or BR
|
|
13
14
|
- ID allocation
|
|
@@ -35,7 +36,9 @@ Inspect the impact cascade: policy → BF → US → AC → EX → enforcing con
|
|
|
35
36
|
## Decision and question rows
|
|
36
37
|
|
|
37
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.
|
|
38
|
-
Do not edit the first three cells or remove the row, except for explicit branch-added decision renumbering under ID allocation below
|
|
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.
|
|
39
42
|
|
|
40
43
|
decisions.md records only what the user decided: each change request the user approved or declined,
|
|
41
44
|
and each critical decision the user made. A row is appended once the user has decided what it records.
|
|
@@ -98,6 +101,30 @@ automatic repair. Inherited records and open-question rows remain excluded.
|
|
|
98
101
|
Rollback follows the recorded new-digest check and restores the original form
|
|
99
102
|
failure; it never resets, amends or force pushes.
|
|
100
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
|
+
|
|
101
128
|
## Approval and no-question mode
|
|
102
129
|
|
|
103
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.
|
|
@@ -121,7 +148,7 @@ A story-tree or contract file changes only on the user's approval:
|
|
|
121
148
|
records who approved it, when, and the label of the option chosen.
|
|
122
149
|
3. Move the row to DONE once every change it names is written.
|
|
123
150
|
|
|
124
|
-
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.
|
|
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.
|
|
125
152
|
Only a row this stage appended changes its Status.
|
|
126
153
|
|
|
127
154
|
## Retiring an EX, AC or BR
|
|
@@ -196,12 +196,44 @@ The groups the screen is read in, in reading order. Each is an entry with exactl
|
|
|
196
196
|
| `heading` | the displayed heading; leave the key out when the group shows none |
|
|
197
197
|
|
|
198
198
|
An id belongs to one group, and an element or action may be left out of every
|
|
199
|
-
group.
|
|
200
|
-
|
|
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
|
|
201
209
|
not the screen title: a second heading above or beside the real one repeats it.
|
|
202
210
|
A group that serves no task does not belong on the screen; name the task it
|
|
203
211
|
enables, or leave the heading and the group out.
|
|
204
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
|
+
|
|
205
237
|
### A worked example
|
|
206
238
|
|
|
207
239
|
The sample at `templates/contracts/ui-contract.sample.yaml` shows a complete
|
|
@@ -241,8 +273,8 @@ only.
|
|
|
241
273
|
|
|
242
274
|
A contract written before these keys was valid without them. Add
|
|
243
275
|
`supplements` to each screen: `supplements: []` is the answer for a screen that
|
|
244
|
-
shows nothing beyond its title and labels. Keep `structure` out
|
|
245
|
-
heading
|
|
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.
|
|
246
278
|
|
|
247
279
|
Two contracts that state the same screen `id` each hold their own `supplements`
|
|
248
280
|
and `structure`; the project-wide screen list compares `title`, `route` and
|
|
@@ -16,6 +16,15 @@ correction, goes inside these items. Write a `|` inside a cell as `\|`.
|
|
|
16
16
|
Use this form for every new row. A passing validation result does not prove
|
|
17
17
|
that every decision row follows it.
|
|
18
18
|
|
|
19
|
+
A release approval, with `<...>` standing for the project's values, has this
|
|
20
|
+
Content cell:
|
|
21
|
+
|
|
22
|
+
Release <X.Y.Z> approved by <name> on <date>, option "<label>"
|
|
23
|
+
|
|
24
|
+
and this Approach cell, written on one line and without backticks around it:
|
|
25
|
+
|
|
26
|
+
- Evidence: file:CHANGELOG.md; command:<the release checks> → <result> - Grounds: <why the checks support the release> - Residual risk: none — <reason> - Rollback: <the steps that retract the release>
|
|
27
|
+
|
|
19
28
|
A row that records a spec change following from an earlier approval may name
|
|
20
29
|
that earlier decision by its ID in `Grounds:`, in place of a new answer from
|
|
21
30
|
the user. Its `Evidence:` still lists what supports the change.
|