qfai 1.10.0 → 1.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +95 -25
- package/assets/init/.qfai/assistant/README.md +27 -0
- package/assets/init/.qfai/assistant/agents/completion-reviewer.md +17 -1
- package/assets/init/.qfai/assistant/agents/delivery-planner.md +8 -0
- package/assets/init/.qfai/assistant/agents/implementation-reviewer.md +12 -1
- package/assets/init/.qfai/assistant/agents/orchestrator.md +2 -2
- package/assets/init/.qfai/assistant/agents/product-experience-architect.md +2 -1
- package/assets/init/.qfai/assistant/agents/product-surface-reviewer.md +1 -1
- package/assets/init/.qfai/assistant/agents/qa-gatekeeper.md +99 -14
- package/assets/init/.qfai/assistant/agents/test-design-analyst.md +4 -1
- package/assets/init/.qfai/assistant/catalog/cli-ux-guidelines.md +3 -0
- package/assets/init/.qfai/assistant/catalog/test-layers-ci-lanes.md +60 -0
- package/assets/init/.qfai/assistant/catalog/test-layers.md +169 -87
- package/assets/init/.qfai/assistant/catalog/worklog-entry.schema.md +4 -3
- package/assets/init/.qfai/assistant/constitution/agent-selection.md +7 -1
- package/assets/init/.qfai/assistant/constitution/communication.md +1 -1
- package/assets/init/.qfai/assistant/constitution/constitution.md +8 -2
- package/assets/init/.qfai/assistant/constitution/drift-protocol.md +177 -14
- package/assets/init/.qfai/assistant/constitution/review-convergence.md +121 -0
- package/assets/init/.qfai/assistant/constitution/shared-skill-delegation-baseline.md +205 -89
- package/assets/init/.qfai/assistant/constitution/shared-skill-operating-baseline.md +59 -5
- package/assets/init/.qfai/assistant/manifest/agent-catalog.yml +145 -21
- package/assets/init/.qfai/assistant/manifest/agent-routing.yml +69 -3
- package/assets/init/.qfai/assistant/skills/qfai-atdd/SKILL.md +131 -74
- package/assets/init/.qfai/assistant/skills/qfai-atdd/references/credential-reuse.md +146 -0
- package/assets/init/.qfai/assistant/skills/qfai-atdd/references/red-provenance.md +498 -0
- package/assets/init/.qfai/assistant/skills/qfai-atdd/references/review-fix-rounds.md +128 -0
- package/assets/init/.qfai/assistant/skills/qfai-atdd/references/scaffolding.md +71 -0
- package/assets/init/.qfai/assistant/skills/qfai-atdd/references/shared-test-artifacts.md +124 -0
- package/assets/init/.qfai/assistant/skills/qfai-atdd/references/stale-manifest.md +34 -0
- package/assets/init/.qfai/assistant/skills/qfai-atdd/references/test-case-depth-checklist.md +38 -1
- package/assets/init/.qfai/assistant/skills/qfai-configure/SKILL.md +4 -3
- package/assets/init/.qfai/assistant/skills/qfai-discussion/SKILL.md +10 -8
- package/assets/init/.qfai/assistant/skills/qfai-discussion/references/discussion-completion-matrix.md +23 -2
- package/assets/init/.qfai/assistant/skills/qfai-discussion/references/review-cycle-playbook.md +16 -1
- package/assets/init/.qfai/assistant/skills/qfai-discussion/references/ui-bearing-playbook.md +47 -11
- package/assets/init/.qfai/assistant/skills/qfai-discussion/references/ui_ux/trend_scan_playbook.md +1 -1
- package/assets/init/.qfai/assistant/skills/qfai-discussion/references/ui_ux_best_practices.md +6 -4
- package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/01_Context.md +2 -2
- package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/03_Story-Workshop.md +1 -1
- package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/04_Sources.md +40 -6
- package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/14_Review-Request.md +7 -7
- package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/review/Rxx_reviewer.md +3 -3
- package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/review/review_request.md +4 -3
- package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/review/summary.json +3 -0
- package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/uiux/00_index.md +14 -5
- package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/uiux/40_screen_contracts.md +17 -1
- package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/uiux/50_review_input_bundle.md +13 -8
- package/assets/init/.qfai/assistant/skills/qfai-implement/SKILL.md +83 -84
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/checkpoint-verification.md +339 -39
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/cross-spec-ownership.md +1 -1
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/evidence-revision.md +348 -15
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/execution-ledger.md +203 -32
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/final-checklist.md +159 -12
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/finding-classification.md +70 -5
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/ledger-preconditions.md +55 -14
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/parallelization-policy.md +92 -3
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/red-not-observable.md +48 -6
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/relevant-test-suite.md +13 -1
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/review-artifact-layout.md +71 -9
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/round-evidence.md +31 -7
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/upstream-artifact-ordering.md +33 -0
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/volume-policy.md +19 -12
- package/assets/init/.qfai/assistant/skills/qfai-prototyping/SKILL.md +76 -8
- package/assets/init/.qfai/assistant/skills/qfai-prototyping/references/design-md-spec.md +20 -0
- package/assets/init/.qfai/assistant/skills/qfai-prototyping/references/evidence-requirements.md +7 -4
- package/assets/init/.qfai/assistant/skills/qfai-prototyping/references/generator-prompt.md +83 -22
- package/assets/init/.qfai/assistant/skills/qfai-prototyping/references/reviewer-prompt.md +29 -4
- package/assets/init/.qfai/assistant/skills/qfai-sdd/SKILL.md +134 -20
- package/assets/init/.qfai/assistant/skills/qfai-sdd/references/contract-artifact-rules.md +31 -3
- package/assets/init/.qfai/assistant/skills/qfai-sdd/references/review-cycle-playbook.md +22 -1
- package/assets/init/.qfai/assistant/skills/qfai-sdd/references/sdd-execution-playbook.md +41 -5
- package/assets/init/.qfai/assistant/skills/qfai-sdd/references/sdd-phase-checklists.md +16 -4
- package/assets/init/.qfai/assistant/skills/qfai-sdd/references/sdd-triage.md +77 -7
- package/assets/init/.qfai/assistant/skills/qfai-sdd/references/spec-traceability-rules.md +60 -11
- package/assets/init/.qfai/assistant/skills/qfai-sdd/references/ui-design-contract-normalization.md +9 -3
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/change-request.md +14 -1
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/contracts/ui-contract.sample.yaml +13 -3
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/evidence/sdd-spec.md +5 -1
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/report/preflight_summary.md +3 -2
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/_policies/04_Business-Flow.md +4 -1
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/_policies/05_Contracts.md +12 -5
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/_policies/11_Slice-Policy.md +8 -9
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/spec/02_User-stories.md +9 -0
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/spec/tdd/test-list.md +68 -23
- package/assets/init/.qfai/assistant/skills/qfai-verify/SKILL.md +4 -4
- package/assets/init/.qfai/assistant/skills/qfai-verify/references/articles.md +1 -1
- package/assets/init/.qfai/assistant/skills/qfai-verify/references/validate-json-schema.md +79 -0
- package/assets/init/.qfai/assistant/skills/web-research/SKILL.md +3 -2
- package/assets/init/root/.github/workflows/qfai-tests.yml +318 -0
- package/assets/init/root/.github/workflows/qfai-validate.yml +327 -24
- package/assets/init/root/qfai.config.yaml +11 -2
- package/dist/cli/index.cjs +25083 -11488
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.mjs +25216 -11589
- package/dist/cli/index.mjs.map +1 -1
- package/dist/index.cjs +16731 -8386
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +407 -17
- package/dist/index.d.ts +407 -17
- package/dist/index.mjs +16701 -8370
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -1
|
@@ -13,7 +13,12 @@ Upstream artifacts include, at minimum:
|
|
|
13
13
|
- `10_Plan.md` and other owner-phase planning outputs
|
|
14
14
|
- Legacy spec-pack SSOT files when present: `spec.md`, `delta.md`, `plan.md`, `traceability-matrix.md`, `scenario.feature`, `case-catalogue.md`, and numbered pack files (for example `01_Spec.md`..`18_delta.md`)
|
|
15
15
|
- contracts and schema decisions owned by earlier phases
|
|
16
|
-
- outputs of
|
|
16
|
+
- outputs of the sdd and review stages. A **discussion pack is NOT upstream
|
|
17
|
+
SSOT** — it is non-normative discovery material, and `.qfai/specs/**` is the
|
|
18
|
+
behaviour and design SSOT it feeds. A defect found in one downstream is fixed
|
|
19
|
+
in the SDD-owned artifact, the discrepancy recorded in delta/evidence. This
|
|
20
|
+
reclassifies ONLY the pack: genuine upstream is still repaired upstream-first.
|
|
21
|
+
|
|
17
22
|
- **test or production artifacts another spec's completed implement run
|
|
18
23
|
certifies** — a file named in another `tdd/test-list.md`'s `Test file` column
|
|
19
24
|
on a `done` row. Changing one is not forbidden (the codebase is not
|
|
@@ -25,8 +30,9 @@ Upstream artifacts include, at minimum:
|
|
|
25
30
|
|
|
26
31
|
One file inside `.qfai/specs/**` is carved out of that last line:
|
|
27
32
|
`<spec-id>/tdd/test-list.md`, and only its `Status` / `DR-ID` / `Evidence`
|
|
28
|
-
cells
|
|
29
|
-
|
|
33
|
+
cells unconditionally, plus its `Test file` and `Selector` cells under the two
|
|
34
|
+
machine-checkable conditions in `#allowed-exceptions-minimal-whitelist`. Its
|
|
35
|
+
**rows** — which obligations exist and what each covers — remain upstream.
|
|
30
36
|
|
|
31
37
|
**Every artifact in this list requires an owner rerun by definition.** There is
|
|
32
38
|
no downstream test for "is an owner rerun required here?" — being on this list
|
|
@@ -40,10 +46,24 @@ case required reading the agent roster and reasoning backwards from it.
|
|
|
40
46
|
|
|
41
47
|
- `.qfai/evidence/**` append/update
|
|
42
48
|
- `.qfai/specs/<spec-id>/tdd/test-list.md` — the `Status`, `DR-ID` and
|
|
43
|
-
`Evidence` cells
|
|
44
|
-
|
|
45
|
-
|
|
49
|
+
`Evidence` cells unconditionally, append/update by `/qfai-implement`, plus two
|
|
50
|
+
cells that are writable **only** while a stated condition holds:
|
|
51
|
+
- the `Test file` cell, only while the seeded value is empty or a dash
|
|
52
|
+
placeholder;
|
|
53
|
+
- the `Selector` cell, only while the seeded value does not resolve against
|
|
54
|
+
the row's named test file — the validator's own `selectorResolves`
|
|
55
|
+
predicate is false.
|
|
56
|
+
|
|
57
|
+
Both conditions are machine-checkable, so a reviewer verifies the precondition
|
|
58
|
+
instead of taking the writing stage's word for it, and both are one-way: once
|
|
59
|
+
the condition that authorised the write has ceased to hold — a `Test file` that
|
|
60
|
+
names a path, a `Selector` that resolves — rewriting it is no longer covered.
|
|
61
|
+
Every other
|
|
62
|
+
column of that file — `TC-Refs`, `Layer`, `US-Refs`, `CON-API-Refs` — and
|
|
63
|
+
every other file under `.qfai/specs/**`, stays upstream SSOT: adding, removing
|
|
64
|
+
or re-scoping a row is an upstream change and takes the
|
|
46
65
|
`#when-drift-is-detected` path.
|
|
66
|
+
|
|
47
67
|
- **creating** a governance record under `.qfai/decisions/` — a Change Request
|
|
48
68
|
(`CR-YYYYMMDD-NNNN-<slug>.md`, per `#when-drift-is-detected` step 2) or an
|
|
49
69
|
anomaly Decision Record (`DR-<id>-<slug>.md`, where `<id>` follows the
|
|
@@ -56,7 +76,7 @@ Any exception beyond this list requires explicit user approval.
|
|
|
56
76
|
`/qfai-implement` must write `tdd/test-list.md` after every phase transition,
|
|
57
77
|
and the file lives inside `.qfai/specs/**`. The protocol never classified it in
|
|
58
78
|
either direction, but `#core-rule`'s list is explicitly open-ended ("at minimum")
|
|
59
|
-
and sweeps in "outputs of
|
|
79
|
+
and sweeps in "outputs of the sdd and review stages" — and the ledger's schema
|
|
60
80
|
is documented in `skills/qfai-sdd/references/spec-traceability-rules.md`, an
|
|
61
81
|
SDD-stage reference. On the natural reading the ledger _is_ an sdd-stage output,
|
|
62
82
|
so "Downstream skills must not patch upstream SSOT directly" applied to it.
|
|
@@ -81,6 +101,46 @@ So an agent obeying the protocol could not satisfy gate item 10, and an agent
|
|
|
81
101
|
satisfying it was in drift. The entry above names the file and the three cells
|
|
82
102
|
unconditionally, which is what removes the choice.
|
|
83
103
|
|
|
104
|
+
### Why `Test file` and `Selector` are conditional
|
|
105
|
+
|
|
106
|
+
The deadlock that put the ledger on this list recurs one and two columns over,
|
|
107
|
+
and two shipped validator rules are what create it:
|
|
108
|
+
|
|
109
|
+
- `TDDLIST_TEST_FILE_MISSING` fires at **error** severity for a row whose
|
|
110
|
+
`Test file` cell is empty or a dash placeholder, once its `Status` is `green`,
|
|
111
|
+
`refactor`, `review-fix` or `done`.
|
|
112
|
+
- `TDDLIST_SELECTOR_UNRESOLVED` fires when the `Selector` cell's text is not
|
|
113
|
+
found in the named test file, and its own remediation text says to update the
|
|
114
|
+
selector. The per-row checkpoint command is `<runner> <Test file> -t
|
|
115
|
+
'<Selector>'`, so an unresolved selector also produces a run that selects
|
|
116
|
+
nothing while exiting 0.
|
|
117
|
+
|
|
118
|
+
A row is seeded with a descriptive selector and, commonly, no test file: the
|
|
119
|
+
path is a downstream decision, and the test's title does not exist until the
|
|
120
|
+
micro-cycle authors it. So the writing stage cannot hold the status the first
|
|
121
|
+
three cells **do** authorise without also writing a cell they do **not** — and
|
|
122
|
+
the earlier status it would otherwise have to keep is false, because the row has
|
|
123
|
+
already passed that phase. Seeding both cells upstream does not resolve it
|
|
124
|
+
either: it would require inventing titles that implementers then match exactly,
|
|
125
|
+
inverting the direction of authority between the spec and the test.
|
|
126
|
+
|
|
127
|
+
The conditions are what keep this narrow. They authorise **filling a placeholder
|
|
128
|
+
and repairing an unresolvable selector**, never rewriting a cell that already
|
|
129
|
+
resolves, and never touching the columns that carry the row's obligation
|
|
130
|
+
identity. Decomposing an existing obligation across rows stays in remit for the
|
|
131
|
+
executing stage; minting a new obligation id does not, and that line is
|
|
132
|
+
unchanged.
|
|
133
|
+
|
|
134
|
+
One limit is worth stating, because the `Selector` condition is narrower than it
|
|
135
|
+
reads. `selectorResolves` is deliberately lenient: it accepts verbatim
|
|
136
|
+
containment, then containment of the selector's last identifier-shaped token. So
|
|
137
|
+
a `Selector` that is materially wrong — one that misdescribes which obligations
|
|
138
|
+
its row covers — but happens to share a trailing token with its test file still
|
|
139
|
+
**resolves**, the condition is false, and this carve-out does **not** authorise
|
|
140
|
+
repairing it. That is the conservative direction and it is intended: only a
|
|
141
|
+
selector the runner's own file could not match is repairable here, and a merely
|
|
142
|
+
misdescribing one stays an upstream change.
|
|
143
|
+
|
|
84
144
|
### Why the Decision Record is on this list
|
|
85
145
|
|
|
86
146
|
A downstream stage cannot always avoid needing one. `qfai-implement` Phase Red
|
|
@@ -277,17 +337,36 @@ is a defect.
|
|
|
277
337
|
- Every reviewer finding declares a `Traces to:` value. See
|
|
278
338
|
`shared-skill-delegation-baseline.md#finding-provenance-must` for the response schema. Legal
|
|
279
339
|
values:
|
|
280
|
-
- an upstream obligation (`AC-*`, `BR-*`, `TC-*`, `CON-*`) or a named constitution/catalog rule
|
|
340
|
+
- an upstream obligation (`AC-*`, `BR-*`, `TC-*`, `CON-*`) or a named constitution/catalog rule
|
|
341
|
+
**that governs the product's behaviour**;
|
|
281
342
|
- `defect:correctness`, `defect:security`, or `defect:code-quality` — the deliverable-defect
|
|
282
343
|
classes above, each of which MUST carry the concrete evidence in the changed artifacts that
|
|
283
344
|
demonstrates it;
|
|
345
|
+
- `record:<CODE>` — a defect in the run's own record rather than in the product;
|
|
284
346
|
- `none` — reviewer-originated scope.
|
|
285
|
-
- The first two are **blocking** and gate `done`.
|
|
347
|
+
- The first two are **blocking** and gate `done`. `record:*` and `none` are not.
|
|
348
|
+
- `Traces to: record:<CODE>` is a record defect: the ledger, a round block, an evidence anchor or
|
|
349
|
+
the provenance prose is wrong while the product is not. It MUST be recorded as `advisory`, MUST
|
|
350
|
+
NOT be `blocking`, and settles in the spec's record-defect queue (`#the-record-defect-queue`)
|
|
351
|
+
rather than by re-running the row. `record:unchecked` is a bug report against `validateTddList`,
|
|
352
|
+
not against the item — a record rule worth a round is worth a validator code.
|
|
353
|
+
- **A record that misrepresents the run is not a record defect.** Evidence copied from a previous
|
|
354
|
+
round or a sibling row, an evidence anchor resolving to a run other than the one it names, and a
|
|
355
|
+
false `Authored/edited under review` attestation do not merely mis-state the work — they claim
|
|
356
|
+
work that was not done, or independence the reviewer did not have. `agents/qa-gatekeeper.md`
|
|
357
|
+
rejects the first two outright and
|
|
358
|
+
`shared-skill-delegation-baseline.md#reviewer-response-template` forbids a `PASS` on the third,
|
|
359
|
+
so classifying them `record:*` would let an advisory-only review return `PASS` and release
|
|
360
|
+
`done` over the very evidence the gate exists to reject. They stay **blocking** as
|
|
361
|
+
`defect:code-quality` and MUST NOT be filed as `record:*`. `record:*` covers a record that is
|
|
362
|
+
honestly produced and merely wrong — a tier missing from an Evidence cell, a `Satisfied-by`
|
|
363
|
+
naming the wrong sibling row, an unlabelled round block.
|
|
286
364
|
- `Traces to: none` is reviewer-originated scope. It is **drift**, and it is **not satisfiable
|
|
287
365
|
downstream**: encoding it as production code plus a hard test assertion is the same violation as
|
|
288
366
|
patching upstream SSOT, inverted. It MUST be recorded as `advisory`, MUST NOT be `blocking`, and
|
|
289
367
|
is routed to the Change Request / Open Question path — never to the implementer.
|
|
290
|
-
- Routing
|
|
368
|
+
- Routing a `none` advisory (a `record:*` advisory takes `#the-record-defect-queue` instead — the
|
|
369
|
+
Change Request path adjudicates product obligations and cannot repair a record):
|
|
291
370
|
1. The reviewer records it in its response under `Advisory / Change Request proposals`, with
|
|
292
371
|
enough context for the owner phase to adjudicate. The reviewer does **not** write it into
|
|
293
372
|
`08_Open-questions.md`: that file is upstream SSOT (see `#core-rule`) and is owned by
|
|
@@ -308,10 +387,94 @@ is a defect.
|
|
|
308
387
|
Completing against an obligation that is known to be under revision would ship a knowingly
|
|
309
388
|
inconsistent SSOT.
|
|
310
389
|
|
|
390
|
+
### The record-defect queue
|
|
391
|
+
|
|
392
|
+
Making `record:*` advisory removes the round it used to force. It does not remove the defect, so
|
|
393
|
+
the class is only honest if the defect lands somewhere with an owner and is consumed. That place is
|
|
394
|
+
one queue per spec, and it is defined by a destination, an owner, an entry shape and a drain.
|
|
395
|
+
|
|
396
|
+
- **Where.** A `## Record defects` section in the evidence file the reviewing stage's **own
|
|
397
|
+
completion contract** names. For a `/qfai-implement` review that is
|
|
398
|
+
`.qfai/evidence/implement-<spec-id>.md` when that file exists, otherwise
|
|
399
|
+
`.qfai/evidence/atdd-<spec-id>.md` — the same file rule the spec-level checkpoint boundary uses,
|
|
400
|
+
so a spec never has this queue in two places. **Do not derive the path from a
|
|
401
|
+
`<stage>-<spec-id>.md` pattern.** Each stage names its own evidence file and not every one of
|
|
402
|
+
them is spec-scoped — `/qfai-configure` writes `.qfai/evidence/configure-<run-id>.md`, one per
|
|
403
|
+
run, and has no `configure-<spec-id>.md` at all — so the pattern named files no stage creates.
|
|
404
|
+
Never `08_Open-questions.md`: that file is upstream SSOT owned by `/qfai-sdd` (see
|
|
405
|
+
`#core-rule`), and a record defect is not a product obligation.
|
|
406
|
+
- **The class needs a drain, so a stage whose completion contract has none does not use it.** Every
|
|
407
|
+
stage sharing `shared-skill-delegation-baseline.md` reads the provenance rules, but an entry is
|
|
408
|
+
only worth filing where something consumes it, and the queue above is defined as much by the
|
|
409
|
+
drain as by the destination. The test is textual and local: **that stage's own completion
|
|
410
|
+
conditions must require this queue drained before it declares completion.** `/qfai-implement`
|
|
411
|
+
states it (`skills/qfai-implement/SKILL.md#spec-completion-conditions`), and no other stage's
|
|
412
|
+
completion conditions mention the queue at all — so `/qfai-sdd`, `/qfai-atdd`, `/qfai-configure`,
|
|
413
|
+
`/qfai-verify`, `/qfai-discussion` and `/web-research` reviewers MUST NOT classify a finding
|
|
414
|
+
`record:*`; it keeps the class it would have had, blocking under the rule it names. A stage gains
|
|
415
|
+
the class by adding the drain to its completion conditions, never by being named here. A class
|
|
416
|
+
whose entries are written where nothing drains them is the round-dropped-and-defect-dropped
|
|
417
|
+
outcome this queue exists to prevent, and it is worse in the stages that never gained the queue
|
|
418
|
+
than the round ever was.
|
|
419
|
+
- **Who.** The reviewer records the finding in its response as an advisory, as for any advisory.
|
|
420
|
+
The **orchestrator** that dispatched the review appends it to the queue when the round closes —
|
|
421
|
+
the same role that owns the ledger. A finding that stays in the reviewer response and never
|
|
422
|
+
reaches the queue is an unrouted advisory, which the review gate already forbids.
|
|
423
|
+
- **Entry.** One line per defect: the `<CODE>`, the row or artifact it is against, what the record
|
|
424
|
+
says against what the run actually did, and the round it came from. That is what makes it
|
|
425
|
+
repairable later by someone who did not watch the round.
|
|
426
|
+
- **Drain, at the spec boundary.** Before spec-level completion is declared, every open entry is
|
|
427
|
+
**repaired in place**: the record is corrected to what the run did, with no row re-run and no
|
|
428
|
+
status change. Repair is the only close. When the rule the entry names is one no validator
|
|
429
|
+
checks, the entry **also** produces a validator bug report per the `record:unchecked` ratchet
|
|
430
|
+
above — that report tracks the missing check and does not stand in for the repair. Closing an
|
|
431
|
+
entry on the report alone leaves the wrong record exactly as wrong as it was, with the round
|
|
432
|
+
that found it already spent: a missing tier stays missing, and the item stays complete. The two
|
|
433
|
+
are different obligations against different backlogs. Completion is not declared while an entry
|
|
434
|
+
is open. This gates the **spec** boundary only: a `record:*` finding still never holds an
|
|
435
|
+
individual row out of `done`, which is the whole point of the class.
|
|
436
|
+
- **When the record cannot be repaired honestly.** Repair means writing what the run actually did,
|
|
437
|
+
which needs the round's artifacts to still say what that was. Where they do not — nothing
|
|
438
|
+
reconciles the entry with any run — the finding was never a record defect: what is missing is
|
|
439
|
+
not a correct record of the work but any evidence the work happened, which is the integrity case
|
|
440
|
+
above. Reclassify it as `defect:code-quality`, blocking, and take the ordinary REVISE path.
|
|
441
|
+
There is no third exit: an entry closes on a corrected record or on a blocking finding.
|
|
442
|
+
- **Re-attest a repair in a pack of its own; never re-run it, and never edit a sealed one.** A
|
|
443
|
+
defect inside a `Satisfied-by`, a round block or any other phase-authored field sits inside the
|
|
444
|
+
exact bytes a reviewer's `Audited evidence hash` covers, and the completion gate recomputes that
|
|
445
|
+
hash — so repairing in place makes a correct PASS read as stale, and skipping the recomputation
|
|
446
|
+
would accept evidence nobody read. Repair the record, then have a reviewer **of the role that
|
|
447
|
+
issued the verdict** re-read the repaired entry and emit a **record re-attestation**: the
|
|
448
|
+
`TDD-ID`, the same `Reviewed revision`, the same `Result`, a recomputed `Audited evidence hash`,
|
|
449
|
+
and the queue entry's `<CODE>`.
|
|
450
|
+
- **The re-attestation is a new review pack, and the pack it supersedes is left untouched.** A
|
|
451
|
+
verdict lives in a `review-<timestamp>/` pack fixed by a `Review pack seal` the completion gate
|
|
452
|
+
recomputes, so replacing that verdict's `Audited evidence hash` line where it is stored breaks
|
|
453
|
+
the seal by construction, and replacing only the evidence file's copy leaves the sealed reviewer
|
|
454
|
+
response carrying a hash nothing agrees with. Write the re-attestation as its own
|
|
455
|
+
`review-<timestamp>/` pack, sealed by the same procedure. The superseded verdict keeps the hash
|
|
456
|
+
it recorded — it was correct over the bytes it read — and its pack keeps recomputing. The
|
|
457
|
+
evidence entry records `Record re-attestation` beside the verdict it supersedes, with its own
|
|
458
|
+
`Record re-attestation pack` and `Record re-attestation pack seal`; the completion gate
|
|
459
|
+
recomputes the superseding hash and both seals, which is what makes the re-attestation an
|
|
460
|
+
artifact a validator can see rather than an untraceable edit. No code runs, no row changes
|
|
461
|
+
status, and it spends no round — it opens none, so it is not a `Round N:` pack. The revision a
|
|
462
|
+
verdict names excludes `.qfai/evidence/**`, so by construction nothing outside the record moved.
|
|
463
|
+
**A repair that would move the revision is not a record repair**: it is a change to the
|
|
464
|
+
deliverable and takes the ordinary path. A repaired entry whose verdict carries no
|
|
465
|
+
re-attestation is still an open entry.
|
|
466
|
+
|
|
467
|
+
An unconsumed queue would make the class worse than what it replaced: the round is gone and the
|
|
468
|
+
defect is gone with it. The drain is what pays for dropping the round.
|
|
469
|
+
|
|
311
470
|
### Which evidence is committed
|
|
312
471
|
|
|
313
|
-
- **
|
|
314
|
-
|
|
472
|
+
- **Durable per-item TDD evidence** — `.qfai/evidence/implement-<spec-id>.md`
|
|
473
|
+
and `.qfai/evidence/atdd-<spec-id>.md`. Ledger `Evidence` cells point to
|
|
474
|
+
anchors in these files, and validation resolves those anchors on a fresh
|
|
475
|
+
clone, so the managed `.gitignore` block re-includes and commits them.
|
|
476
|
+
- **Regenerable** — other stage logs, run logs, and reports. Reproducible by
|
|
477
|
+
rerunning the owner skill; not committed.
|
|
315
478
|
- **Governance record** — Change Requests (`.qfai/decisions/CR-*.md`) and
|
|
316
479
|
durable decision records (`.qfai/evidence/decisions/*.json`). They carry
|
|
317
480
|
user approval and cannot be regenerated, so they are committed. The managed
|
|
@@ -325,8 +488,8 @@ is a defect.
|
|
|
325
488
|
— diffs the branch against `baseBranch` and emits `QFAI-DRIFT-001` (`error`)
|
|
326
489
|
for every changed file under `paths.contractsDir`, under `_policies/`, or
|
|
327
490
|
matching a protected spec-pack filename. A Change Request at `Status:
|
|
328
|
-
approved`
|
|
329
|
-
|
|
491
|
+
approved` whose **`## Impact scope` names the changed path** silences it — not
|
|
492
|
+
a path named elsewhere in it, not a contract ID, and never an `open` CR. The check does not run in the `sdd`
|
|
330
493
|
profile: `/qfai-sdd` owns these files.
|
|
331
494
|
- Downstream reviewers must not originate binding obligations that upstream SSOT does not contain.
|
|
332
495
|
- If approval is not available, stay in STOP state **for that CR's blocked set**
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Review Convergence
|
|
2
|
+
|
|
3
|
+
How a review round ends, and what may follow it. Referenced from
|
|
4
|
+
`shared-skill-delegation-baseline.md#round-budget-and-convergence-must`,
|
|
5
|
+
which owns the delegation rules these sit beside.
|
|
6
|
+
|
|
7
|
+
### Round budget (MUST)
|
|
8
|
+
|
|
9
|
+
- **Two rounds per reviewer per artifact.** Round 1 is the initial review;
|
|
10
|
+
round 2 reviews the fixes. **The budget is spent the moment round 2 returns
|
|
11
|
+
`REVISE`**: the orchestrator MUST NOT start a third review, and MUST stop and
|
|
12
|
+
escalate to the user with the open findings, the fixes already applied, and a
|
|
13
|
+
recommendation. The decision point is round 2's verdict, never a prediction
|
|
14
|
+
about a review that must not run.
|
|
15
|
+
- Escalation is not failure. The artifact stays at its current status and the
|
|
16
|
+
user decides: accept with the finding recorded as an Open Question, apply a
|
|
17
|
+
named fix, or drop the item from scope.
|
|
18
|
+
- **Completion after escalation.** The user's decision is the exception to
|
|
19
|
+
"no DONE until all blocking reviewers `PASS`", so the escalation has an exit:
|
|
20
|
+
- _Accept as Open Question_ or _drop from scope_ — the artifact may reach
|
|
21
|
+
DONE with the finding recorded; the reviewer's outstanding `REVISE` is
|
|
22
|
+
superseded by the recorded user decision. Cite the decision where the
|
|
23
|
+
stage records decisions (`*_delta.md` / `07_Decisions.md` / a Change
|
|
24
|
+
Request).
|
|
25
|
+
- _Apply a named fix_ — one **verification review** of exactly that fix is
|
|
26
|
+
permitted and does not consume budget (it is round 2b, not round 3). Its
|
|
27
|
+
remit is the named fix only. It may not raise findings unrelated to that
|
|
28
|
+
fix, but a defect the fix **introduced or exposed** is in remit and MUST be
|
|
29
|
+
reported rather than passed over: verifying only the named lines and
|
|
30
|
+
returning `PASS` while a regression sits next to them is a false `PASS`.
|
|
31
|
+
Such a finding escalates immediately (see the severity floor below) and
|
|
32
|
+
still does not start a round 3. The review returns `PASS` or escalates
|
|
33
|
+
again.
|
|
34
|
+
- **One 2b per artifact, total.** The verification review is free of budget,
|
|
35
|
+
not unbounded: a second escalation on the same artifact MUST NOT be
|
|
36
|
+
answered with another _apply a named fix_ + 2b cycle. Without this cap the
|
|
37
|
+
two rules compose into a loop — 2b costs nothing, and escalating again is
|
|
38
|
+
always allowed — so the gate has no guaranteed end. At the second
|
|
39
|
+
escalation the user is offered only _accept as Open Question_ or _drop the
|
|
40
|
+
item from scope_. The severity floor below then withholds _accept as Open
|
|
41
|
+
Question_ for its classes, so for those findings the intersection of the
|
|
42
|
+
two rules leaves _drop the item from scope_ alone — which is the state
|
|
43
|
+
**Corrective review** below exists to give an exit.
|
|
44
|
+
- **Severity floor on the exit.** _Accept as Open Question_ is NOT available
|
|
45
|
+
for a finding that names a concrete security defect, data loss or
|
|
46
|
+
corruption, or a correctness defect that would break a released contract.
|
|
47
|
+
Present the user only _apply a named fix_ or _drop the item from scope_ for
|
|
48
|
+
those, and say why the third option is withheld. Without this the general
|
|
49
|
+
exit is a route around "deferring such a finding to an Open Question so a
|
|
50
|
+
`PASS` can be returned is prohibited" — one that needs no lateness and no
|
|
51
|
+
reviewer consent, only a user click.
|
|
52
|
+
- **Corrective review (the one exit the floor leaves open).** The two rules
|
|
53
|
+
above compose into a dead end, and it is reachable: a Round 2b that
|
|
54
|
+
correctly reports a defect the named fix INTRODUCED or EXPOSED escalates a
|
|
55
|
+
second time, at which point the 2b cap withholds _apply a named fix_ and
|
|
56
|
+
the severity floor withholds _accept as Open Question_ — so for a security,
|
|
57
|
+
data-loss or released-contract-correctness finding the only remaining
|
|
58
|
+
option is _drop the item from scope_. Fixing the defect and keeping the
|
|
59
|
+
requirement has no path: the fix cannot be verified, and the artifact
|
|
60
|
+
stays at `REVISE` forever. Round 2b doing its job is what puts the stage
|
|
61
|
+
there.
|
|
62
|
+
|
|
63
|
+
When that state is reached AND the user chooses to fix rather than drop,
|
|
64
|
+
the stage MAY open **one corrective review artifact**. It is not a third
|
|
65
|
+
round and not a budget reset; it is a separate artifact with a remit
|
|
66
|
+
narrower than any round, and it is bounded so that the two rules above
|
|
67
|
+
cannot compose through it either.
|
|
68
|
+
|
|
69
|
+
Required before the review runs — all of it, in the stage's evidence:
|
|
70
|
+
1. the originating artifact, and the Round 2b finding verbatim;
|
|
71
|
+
2. the user's decision, recorded where the stage records decisions
|
|
72
|
+
(`*_delta.md` / `07_Decisions.md` / a Change Request);
|
|
73
|
+
3. what was changed to fix it;
|
|
74
|
+
4. the before and after revision of every artifact the fix touched, as
|
|
75
|
+
digests a reader can re-derive rather than as a round name.
|
|
76
|
+
|
|
77
|
+
Constraints on the review itself:
|
|
78
|
+
- **Remit is the finding and the named fix, nothing else.** Narrower than a
|
|
79
|
+
round: a corrective reviewer may not re-open the artifact generally. An
|
|
80
|
+
unrelated finding goes to the owning stage's delta or a Change Request
|
|
81
|
+
under the convergence rules, and does NOT extend this review.
|
|
82
|
+
- **One independent review, once.** Recorded as `Round: corrective` — not
|
|
83
|
+
`2c`, and not a numbered round, because a number invites a successor.
|
|
84
|
+
- **`PASS` supersedes the Round 2b finding** on the originating artifact
|
|
85
|
+
and returns the stage to the review gates it had not yet reached. It does
|
|
86
|
+
not retro-`PASS` anything else.
|
|
87
|
+
- **`REVISE` is terminal.** The stage stops with the finding recorded. No
|
|
88
|
+
second corrective artifact, no further review, and no route back to
|
|
89
|
+
_apply a named fix_. This is the guaranteed end the 2b cap exists to
|
|
90
|
+
provide, moved one step later rather than removed.
|
|
91
|
+
- **The floor and the Open Question prohibition are unchanged.** A
|
|
92
|
+
corrective review cannot return `PASS` over a live security, data-loss or
|
|
93
|
+
released-contract defect, and the finding cannot be deferred to an Open
|
|
94
|
+
Question at any point in this path.
|
|
95
|
+
- **A discussion pack is not an input to this.** It is non-normative
|
|
96
|
+
reference material, so a corrective review neither repairs one nor treats
|
|
97
|
+
one as the upstream to fix.
|
|
98
|
+
|
|
99
|
+
- The round number MUST be recorded on each reviewer response
|
|
100
|
+
(`Round:` in the shared response template).
|
|
101
|
+
|
|
102
|
+
### Convergence (MUST)
|
|
103
|
+
|
|
104
|
+
- A finding first raised in round N > 1 MUST state why it was not raisable in
|
|
105
|
+
round N-1 — the fix introduced it, or the fix exposed it. A finding that was
|
|
106
|
+
raisable in round 1 and was not raised is **out of budget**: record it as an
|
|
107
|
+
Open Question or a `*_delta.md` Decision Record for the owning stage, do not
|
|
108
|
+
block on it.
|
|
109
|
+
- A reviewer MUST NOT open a new blocking _class_ of finding after the artifact
|
|
110
|
+
under review has been declared stable. New classes go to the owning stage.
|
|
111
|
+
- **Severity overrides lateness.** The out-of-budget rule is about review
|
|
112
|
+
discipline, not about shipping known harm. A late finding that names a
|
|
113
|
+
concrete security defect, data loss or corruption, or a correctness defect
|
|
114
|
+
that would break a released contract is **not** deferrable: the orchestrator
|
|
115
|
+
stops and escalates to the user immediately, exactly as it does when the
|
|
116
|
+
round budget is spent. It is still not a third round — no further review is
|
|
117
|
+
started, the finding goes straight to the user with its evidence. Deferring
|
|
118
|
+
such a finding to an Open Question so a `PASS` can be returned is prohibited.
|
|
119
|
+
That prohibition does not depend on lateness or on who proposes the deferral:
|
|
120
|
+
the escalation exit in the round budget withholds _Accept as Open Question_
|
|
121
|
+
for this same class, so a user choice cannot supersede it either.
|