qfai 1.9.2 → 1.10.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 +48 -2
- package/assets/init/.qfai/assistant/agents/acceptance-test-engineer.md +1 -0
- package/assets/init/.qfai/assistant/agents/backend-engineer.md +1 -0
- package/assets/init/.qfai/assistant/agents/completion-reviewer.md +13 -2
- package/assets/init/.qfai/assistant/agents/delivery-planner.md +9 -0
- package/assets/init/.qfai/assistant/agents/frontend-engineer.md +1 -0
- package/assets/init/.qfai/assistant/agents/implementation-reviewer.md +6 -0
- package/assets/init/.qfai/assistant/agents/orchestrator.md +2 -2
- package/assets/init/.qfai/assistant/agents/qa-gatekeeper.md +96 -3
- package/assets/init/.qfai/assistant/agents/test-design-analyst.md +20 -3
- package/assets/init/.qfai/assistant/catalog/cli-ux-guidelines.md +2 -2
- package/assets/init/.qfai/assistant/catalog/spec_required_files.json +2 -1
- package/assets/init/.qfai/assistant/catalog/test-layers.md +355 -14
- package/assets/init/.qfai/assistant/catalog/worklog-entry.schema.md +165 -0
- package/assets/init/.qfai/assistant/constitution/communication.md +1 -1
- package/assets/init/.qfai/assistant/constitution/drift-protocol.md +304 -10
- package/assets/init/.qfai/assistant/constitution/quality.md +35 -5
- package/assets/init/.qfai/assistant/constitution/requirements-decomposition.md +37 -0
- package/assets/init/.qfai/assistant/constitution/shared-skill-delegation-baseline.md +244 -8
- package/assets/init/.qfai/assistant/constitution/shared-skill-operating-baseline.md +122 -5
- package/assets/init/.qfai/assistant/constitution/workflow.md +53 -7
- package/assets/init/.qfai/assistant/manifest/agent-catalog.yml +316 -945
- package/assets/init/.qfai/assistant/manifest/agent-routing.yml +50 -4
- package/assets/init/.qfai/assistant/manifest/review-profiles.yml +9 -0
- package/assets/init/.qfai/assistant/process/migrations/v1.4.27-atdd-alignment.md +1 -1
- package/assets/init/.qfai/assistant/skills/qfai-atdd/SKILL.md +61 -21
- package/assets/init/.qfai/assistant/skills/qfai-atdd/references/test-case-depth-checklist.md +23 -4
- package/assets/init/.qfai/assistant/skills/qfai-configure/SKILL.md +15 -7
- package/assets/init/.qfai/assistant/skills/qfai-discussion/SKILL.md +8 -4
- package/assets/init/.qfai/assistant/skills/qfai-discussion/references/design-md-brand-catalog.md +2 -2
- package/assets/init/.qfai/assistant/skills/qfai-discussion/references/discussion-completion-matrix.md +17 -7
- package/assets/init/.qfai/assistant/skills/qfai-discussion/references/rcp_footer.md +10 -4
- package/assets/init/.qfai/assistant/skills/qfai-discussion/references/review-cycle-playbook.md +1 -1
- package/assets/init/.qfai/assistant/skills/qfai-discussion/references/ui-bearing-playbook.md +4 -4
- package/assets/init/.qfai/assistant/skills/qfai-discussion/references/ui_ux/review_audit_playbook.md +1 -1
- 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 +17 -7
- package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/01_Context.md +1 -1
- package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/02_Inception-Deck.md +1 -1
- package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/03_Story-Workshop.md +11 -3
- package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/05_Scope.md +5 -2
- package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/07_NFR.md +1 -1
- package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/09_Constraints.md +7 -4
- package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/10_Policy.md +1 -1
- package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/11_OQ-Register.md +1 -1
- package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/12_OQ-Resolution-Log.md +1 -1
- package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/14_Review-Request.md +14 -7
- package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/99_delta.md +1 -1
- package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/review/Rxx_reviewer.md +16 -7
- package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/review/review_request.md +9 -6
- package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/uiux/40_screen_contracts.md +3 -2
- package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/uiux/50_review_input_bundle.md +4 -2
- package/assets/init/.qfai/assistant/skills/qfai-implement/SKILL.md +250 -128
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/change-request-reset.md +93 -0
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/checkpoint-verification.md +106 -0
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/cross-spec-ownership.md +73 -0
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/evidence-revision.md +77 -0
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/execution-ledger.md +303 -0
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/final-checklist.md +19 -0
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/finding-classification.md +49 -0
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/ledger-preconditions.md +55 -0
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/oracle-strength.md +81 -0
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/parallelization-policy.md +235 -0
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/red-admissibility.md +91 -0
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/red-not-observable.md +70 -0
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/relevant-test-suite.md +87 -0
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/review-artifact-layout.md +31 -0
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/round-evidence.md +102 -0
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/selector-granularity.md +24 -0
- package/assets/init/.qfai/assistant/skills/qfai-implement/references/volume-policy.md +149 -0
- package/assets/init/.qfai/assistant/skills/qfai-prototyping/SKILL.md +35 -18
- package/assets/init/.qfai/assistant/skills/qfai-prototyping/references/evidence-requirements.md +1 -1
- package/assets/init/.qfai/assistant/skills/qfai-prototyping/references/generator-prompt.md +106 -7
- package/assets/init/.qfai/assistant/skills/qfai-prototyping/references/handoff.md +40 -11
- package/assets/init/.qfai/assistant/skills/qfai-prototyping/references/iteration-loop.md +48 -1
- package/assets/init/.qfai/assistant/skills/qfai-prototyping/templates/DESIGN.md.sample +6 -0
- package/assets/init/.qfai/assistant/skills/qfai-sdd/SKILL.md +82 -22
- package/assets/init/.qfai/assistant/skills/qfai-sdd/references/contract-artifact-rules.md +148 -0
- package/assets/init/.qfai/assistant/skills/qfai-sdd/references/rcp_footer.md +10 -4
- package/assets/init/.qfai/assistant/skills/qfai-sdd/references/review-cycle-playbook.md +1 -1
- package/assets/init/.qfai/assistant/skills/qfai-sdd/references/sdd-execution-playbook.md +4 -2
- package/assets/init/.qfai/assistant/skills/qfai-sdd/references/sdd-phase-checklists.md +18 -0
- package/assets/init/.qfai/assistant/skills/qfai-sdd/references/sdd-quality-gate.md +44 -3
- package/assets/init/.qfai/assistant/skills/qfai-sdd/references/sdd-triage.md +60 -7
- package/assets/init/.qfai/assistant/skills/qfai-sdd/references/spec-traceability-rules.md +157 -5
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/change-request.md +125 -0
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/contracts/db-contract.sample.sql +6 -0
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/evidence/sdd-spec.md +92 -0
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/_policies/01_Objective.md +27 -0
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/_policies/02_Initiative.md +30 -0
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/_policies/05_Contracts.md +16 -6
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/_policies/06_Glossary.md +19 -0
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/_policies/07_Constraints.md +25 -0
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/_policies/08_Decisions.md +22 -2
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/_policies/11_Slice-Policy.md +37 -10
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/spec/02_User-stories.md +20 -0
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/spec/03_Acceptance-Criteria.md +19 -0
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/spec/04_Business-Rules.md +32 -3
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/spec/06_Test-Cases.md +56 -0
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/spec/07_Decisions.md +29 -2
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/spec/10_Plan.md +41 -0
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/spec/16_Traceability-ledger.md +58 -0
- package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/spec/tdd/test-list.md +56 -0
- package/assets/init/.qfai/assistant/skills/qfai-verify/SKILL.md +57 -102
- package/assets/init/.qfai/assistant/skills/qfai-verify/references/articles.md +24 -0
- package/assets/init/.qfai/assistant/skills/qfai-verify/references/context-load.md +22 -0
- package/assets/init/.qfai/assistant/skills/qfai-verify/references/verify-output-contract.md +48 -0
- package/assets/init/.qfai/assistant/skills/qfai-verify/templates/verify-evidence.md +48 -0
- package/assets/init/.qfai/assistant/skills/web-research/SKILL.md +25 -7
- package/assets/init/.qfai/waivers.yml +11 -5
- package/assets/init/root/DESIGN.md +6 -0
- package/assets/init/root/qfai.config.yaml +15 -12
- package/dist/cli/index.cjs +11023 -7139
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.mjs +10963 -7080
- package/dist/cli/index.mjs.map +1 -1
- package/dist/index.cjs +8782 -5257
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +280 -8
- package/dist/index.d.ts +280 -8
- package/dist/index.mjs +11776 -8264
- package/dist/index.mjs.map +1 -1
- package/package.json +18 -19
|
@@ -14,29 +14,323 @@ Upstream artifacts include, at minimum:
|
|
|
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
16
|
- outputs of discussion/sdd/review stages
|
|
17
|
+
- **test or production artifacts another spec's completed implement run
|
|
18
|
+
certifies** — a file named in another `tdd/test-list.md`'s `Test file` column
|
|
19
|
+
on a `done` row. Changing one is not forbidden (the codebase is not
|
|
20
|
+
partitioned and duplication removal is mandated), but it must be recorded and
|
|
21
|
+
re-reviewed per
|
|
22
|
+
`skills/qfai-implement/references/cross-spec-ownership.md`. It becomes drift
|
|
23
|
+
in the full sense — STOP, Change Request, owner rerun — when the other spec's
|
|
24
|
+
obligation no longer holds rather than merely moving.
|
|
25
|
+
|
|
26
|
+
One file inside `.qfai/specs/**` is carved out of that last line:
|
|
27
|
+
`<spec-id>/tdd/test-list.md`, and only its `Status` / `DR-ID` / `Evidence`
|
|
28
|
+
cells. See `#allowed-exceptions-minimal-whitelist`. Its **rows** — which obligations exist and
|
|
29
|
+
what each covers — remain upstream.
|
|
30
|
+
|
|
31
|
+
**Every artifact in this list requires an owner rerun by definition.** There is
|
|
32
|
+
no downstream test for "is an owner rerun required here?" — being on this list
|
|
33
|
+
is the answer, and the rerun is a _consequence_ of the artifact being upstream
|
|
34
|
+
SSOT, never a precondition for the prohibition. A downstream phase that finds
|
|
35
|
+
itself weighing whether the owner needs to be involved has already left its
|
|
36
|
+
lane: it cannot see who owns the artifact, and working that out in the observed
|
|
37
|
+
case required reading the agent roster and reasoning backwards from it.
|
|
17
38
|
|
|
18
39
|
## Allowed exceptions (minimal whitelist)
|
|
19
40
|
|
|
20
41
|
- `.qfai/evidence/**` append/update
|
|
21
|
-
-
|
|
42
|
+
- `.qfai/specs/<spec-id>/tdd/test-list.md` — the `Status`, `DR-ID` and
|
|
43
|
+
`Evidence` cells only, append/update by `/qfai-implement`. Every other column
|
|
44
|
+
of that file, and every other file under `.qfai/specs/**`, stays upstream
|
|
45
|
+
SSOT: adding, removing or re-scoping a row is an upstream change and takes the
|
|
46
|
+
`#when-drift-is-detected` path.
|
|
47
|
+
- **creating** a governance record under `.qfai/decisions/` — a Change Request
|
|
48
|
+
(`CR-YYYYMMDD-NNNN-<slug>.md`, per `#when-drift-is-detected` step 2) or an
|
|
49
|
+
anomaly Decision Record (`DR-<id>-<slug>.md`, where `<id>` follows the
|
|
50
|
+
Decision Record ID scheme in the spec's `07_Decisions.md`)
|
|
22
51
|
|
|
23
52
|
Any exception beyond this list requires explicit user approval.
|
|
24
53
|
|
|
54
|
+
### Why the execution ledger is named here
|
|
55
|
+
|
|
56
|
+
`/qfai-implement` must write `tdd/test-list.md` after every phase transition,
|
|
57
|
+
and the file lives inside `.qfai/specs/**`. The protocol never classified it in
|
|
58
|
+
either direction, but `#core-rule`'s list is explicitly open-ended ("at minimum")
|
|
59
|
+
and sweeps in "outputs of discussion/sdd/review stages" — and the ledger's schema
|
|
60
|
+
is documented in `skills/qfai-sdd/references/spec-traceability-rules.md`, an
|
|
61
|
+
SDD-stage reference. On the natural reading the ledger _is_ an sdd-stage output,
|
|
62
|
+
so "Downstream skills must not patch upstream SSOT directly" applied to it.
|
|
63
|
+
|
|
64
|
+
The bullet that used to sit here — "progress status updates only when the project
|
|
65
|
+
workflow explicitly allows downstream updates" — could not rescue that, for two
|
|
66
|
+
reasons:
|
|
67
|
+
|
|
68
|
+
- **The condition had no referent.** `progress status`, `project workflow` and
|
|
69
|
+
`downstream update` each occurred exactly once in the whole shipped tree: that
|
|
70
|
+
line itself. Nothing defined what the project workflow is, where such a
|
|
71
|
+
permission is recorded, or what the default is, so in a freshly initialized project the
|
|
72
|
+
condition could never be satisfied.
|
|
73
|
+
- **It was too narrow even if it had.** It covered "progress status", while
|
|
74
|
+
`qfai-implement`'s completion gate item 10 additionally requires the `Evidence`
|
|
75
|
+
column, and the skill's own hard rules forbid the substitute
|
|
76
|
+
("status-only evidence … MUST be rejected"). The content declared mandatory and
|
|
77
|
+
non-substitutable was precisely the content no rule authorised anyone to
|
|
78
|
+
persist.
|
|
79
|
+
|
|
80
|
+
So an agent obeying the protocol could not satisfy gate item 10, and an agent
|
|
81
|
+
satisfying it was in drift. The entry above names the file and the three cells
|
|
82
|
+
unconditionally, which is what removes the choice.
|
|
83
|
+
|
|
84
|
+
### Why the Decision Record is on this list
|
|
85
|
+
|
|
86
|
+
A downstream stage cannot always avoid needing one. `qfai-implement` Phase Red
|
|
87
|
+
orders an anomalous row to `exception` as an inline step, and that status is
|
|
88
|
+
invalid without a `DR-*` in the `DR-ID` column — enforced at `error` by
|
|
89
|
+
`TDDLIST_EXCEPTION_MISSING_DR`. Every upstream home for a Decision Record
|
|
90
|
+
(`07_Decisions.md`, `09_delta.md`) is on the `#core-rule` list above, and neither
|
|
91
|
+
of the first two whitelist entries covers minting one: a Decision Record is not
|
|
92
|
+
an `.qfai/evidence/**` write and not a ledger-cell update.
|
|
93
|
+
|
|
94
|
+
Without this entry the only compliant route to executing an inline Phase Red
|
|
95
|
+
step was STOP -> Change Request -> user approval -> owner-skill rerun. That made
|
|
96
|
+
the framework's single escape hatch for a blocked item reachable only through
|
|
97
|
+
the approval loop the block is waiting on, so the first anomaly in any project
|
|
98
|
+
either halted the stage or produced a rule-violating ledger row.
|
|
99
|
+
|
|
100
|
+
The carve-out is exactly as narrow as that need:
|
|
101
|
+
|
|
102
|
+
- **create only.** `.qfai/decisions/` is not upstream SSOT and no owner phase
|
|
103
|
+
writes it, so creating a file there patches nothing. Editing an already-
|
|
104
|
+
approved record is not covered.
|
|
105
|
+
- **the record only, never the reference.** The `07_Decisions.md` /
|
|
106
|
+
`09_delta.md` entry that cites the DR stays an owner-skill write, exactly as
|
|
107
|
+
step 2 already says for a Change Request. A compliant `exception` row needs
|
|
108
|
+
the record and the `DR-ID` cell, not the upstream cross-reference.
|
|
109
|
+
- **not an approval.** Creating the record does not decide the anomaly. A parked
|
|
110
|
+
row still carries `TDDLIST_EXCEPTION_PARKED` until the risk is accepted
|
|
111
|
+
through the `TDDLIST-001` waiver, which is a separate, user-owned artifact.
|
|
112
|
+
|
|
113
|
+
## Drift classes
|
|
114
|
+
|
|
115
|
+
Drift is one of two things, and the class decides what the Change Request must
|
|
116
|
+
carry. It does **not** decide whether a Change Request is needed: both classes
|
|
117
|
+
STOP, both raise a CR, both wait for approval, both are applied by the owner
|
|
118
|
+
skill. The ownership boundary in `#core-rule` is identical for both.
|
|
119
|
+
|
|
120
|
+
- **Intent drift** — the upstream artifact states something downstream
|
|
121
|
+
disagrees with. There is a real decision to make, the upstream artifact is
|
|
122
|
+
internally consistent, and reasonable alternatives exist.
|
|
123
|
+
- **Defect drift** — the upstream artifact is internally inconsistent,
|
|
124
|
+
unreachable, or contradicts its own declared behaviour, **demonstrated by a
|
|
125
|
+
reproduction**. A `.sql` contract that raises `AmbiguousColumnError` on its
|
|
126
|
+
own declared code path conflicts with nothing: it contradicts only itself.
|
|
127
|
+
|
|
128
|
+
Defect drift is claimed by evidence, not by assertion. A CR that declares
|
|
129
|
+
`Class: defect` without a reproduction — a command plus its verbatim output, or
|
|
130
|
+
the two artifact excerpts that contradict each other — is an intent-drift CR
|
|
131
|
+
that skipped its options, and must be treated as incomplete. "This is obviously
|
|
132
|
+
wrong" is not a reproduction; neither is "the fix is trivial". Cost is not a
|
|
133
|
+
classifier: a large intent change stays intent drift, and a one-token defect
|
|
134
|
+
stays defect drift.
|
|
135
|
+
|
|
136
|
+
Where exactly one correct fix exists, inventing a second and a third option to
|
|
137
|
+
satisfy a template produces a worse record, not a safer one — the operator then
|
|
138
|
+
ratifies a comparison the author knew was fabricated.
|
|
139
|
+
|
|
25
140
|
## When drift is detected
|
|
26
141
|
|
|
27
|
-
1. STOP downstream editing
|
|
28
|
-
|
|
29
|
-
-
|
|
142
|
+
1. STOP downstream editing **of the affected upstream artifact and of every
|
|
143
|
+
downstream item that depends on it**. Unaffected items continue. A dependent
|
|
144
|
+
item is one whose `TC-Refs` / `US-Refs` / `CON-API-Refs` names an obligation
|
|
145
|
+
the CR would change, or whose implementation reads the artifact under
|
|
146
|
+
dispute; when the dependency is arguable, it is dependent. The halt is not
|
|
147
|
+
repository-wide: one defective contract does not stop specs that never
|
|
148
|
+
reference it. What it does stop is `done` — a dependent item may not be
|
|
149
|
+
completed against an obligation known to be under revision.
|
|
150
|
+
2. Create a Change Request as a file at
|
|
151
|
+
`.qfai/decisions/CR-YYYYMMDD-NNNN-<slug>.md`, from
|
|
152
|
+
`.qfai/assistant/skills/qfai-sdd/templates/change-request.md`. The ID
|
|
153
|
+
pattern is `CR-\d{8}-\d{4}` and the file carries `ID`, `Status`
|
|
154
|
+
(`open` / `approved` / `rejected` / `superseded`), `Approved by`,
|
|
155
|
+
`Approved at` and `Approved option` so the approval is a record, not a
|
|
156
|
+
memory. Creating this file is the only write this step makes: `09_delta.md`
|
|
157
|
+
and `07_Decisions.md` are upstream SSOT, so the reference to this CR is
|
|
158
|
+
written there by the owner skill in step 4, never before approval.
|
|
159
|
+
Contents:
|
|
160
|
+
- class (`intent` / `defect`) — see `#drift-classes`
|
|
161
|
+
- context — for intent drift, what conflicts; for defect drift, what the
|
|
162
|
+
artifact declares and how it breaks that declaration
|
|
163
|
+
- reproduction (command + verbatim output, or the two contradicting
|
|
164
|
+
excerpts) — **required for defect drift**, omit for intent drift
|
|
30
165
|
- proposed change
|
|
31
|
-
- options (at least 3) and recommendation
|
|
166
|
+
- options (at least 3) and recommendation — **intent drift only**; for
|
|
167
|
+
defect drift record the single correct fix instead. Do not manufacture
|
|
168
|
+
alternatives for a change that has one correct answer
|
|
169
|
+
- blocked downstream items — the enumerated set the halt in step 1 covers
|
|
170
|
+
(spec IDs, `TDD-ID` ledger rows, contract paths). This is what makes the
|
|
171
|
+
halt checkable: a reviewer can ask whether an item that kept moving is on
|
|
172
|
+
the list, and an item not on the list is not blocked by this CR
|
|
32
173
|
- impact scope (spec/plan/tests/contracts/schema)
|
|
33
174
|
- decision needed from user
|
|
34
175
|
- approved actions (owner skill rerun plan)
|
|
35
|
-
3. Wait for explicit user approval.
|
|
36
|
-
|
|
37
|
-
|
|
176
|
+
3. Wait for explicit user approval, then set `Status` and the approval fields.
|
|
177
|
+
A defect-drift CR has no option set, so `Approved option` stays `-`; what is
|
|
178
|
+
approved is the single correct fix under `## Proposed change`. The wait
|
|
179
|
+
itself is not waived — the operator is ratifying the classification as much
|
|
180
|
+
as the fix.
|
|
181
|
+
4. Rerun the owner skill for the upstream artifact, **naming the invocation and
|
|
182
|
+
the mode** the CR approved. That rerun is what records the CR reference in
|
|
183
|
+
`09_delta.md` / `07_Decisions.md`.
|
|
184
|
+
|
|
185
|
+
Invocation by artifact class:
|
|
186
|
+
|
|
187
|
+
| Upstream artifact | Invocation |
|
|
188
|
+
| -------------------- | ------------------------------- |
|
|
189
|
+
| `spec-*/**` files | `/qfai-sdd <spec-id>` |
|
|
190
|
+
| `_policies/**` | `/qfai-sdd` (no argument) |
|
|
191
|
+
| `.qfai/contracts/**` | `/qfai-sdd --contract <CON-ID>` |
|
|
192
|
+
|
|
193
|
+
Mode — the CR's "approved actions" field MUST name one:
|
|
194
|
+
- **`confirm-only`** — re-read the artifact and confirm it already satisfies
|
|
195
|
+
the approved change. Writes nothing but the CR reference. Use when the
|
|
196
|
+
change was already applied by hand under approval, or when the CR only
|
|
197
|
+
re-scopes something the artifact already says.
|
|
198
|
+
- **`re-derive`** — regenerate the artifact from its inputs. May rewrite any
|
|
199
|
+
part of it, and sweeps the downstream ledgers in step 5.
|
|
200
|
+
|
|
201
|
+
Without a named mode neither the author nor the approver can state what the
|
|
202
|
+
rerun executes or what it costs, and "rerun the owner skill" is the whole
|
|
203
|
+
plan.
|
|
204
|
+
|
|
205
|
+
5. **Sweep the downstream ledgers.** Identify every `tdd/test-list.md` row the
|
|
206
|
+
rerun invalidated — its `TC-Refs` / `US-Refs` / `CON-API-Refs` obligation
|
|
207
|
+
changed or disappeared — and apply the upstream reset transition
|
|
208
|
+
(any status -> `todo`), recording the approved CR/DR ID in `DR-ID` — that
|
|
209
|
+
column carries both `DR-*` and `CR-*` references. The
|
|
210
|
+
sweep covers in-flight rows too: a `red` row whose obligation changed, and
|
|
211
|
+
an `exception` row whose anomaly the rerun resolved or superseded, reset the
|
|
212
|
+
same way. A row whose obligation was deleted outright is removed, not reset.
|
|
213
|
+
6. Resume the **blocked set of this CR** only after upstream artifacts are
|
|
214
|
+
updated **and** the sweep has run. Resuming with a stale `done` row is
|
|
215
|
+
resuming on a ledger that asserts something known to be false. Resume is
|
|
216
|
+
per-CR: an item on two blocked sets resumes when both release, and an item
|
|
217
|
+
on neither never stopped.
|
|
218
|
+
7. Record the outcome in the CR: fill `Resolution` and set `Applied at`.
|
|
219
|
+
Approval alone does not release the downstream gate — `qfai-implement`
|
|
220
|
+
treats an `approved` CR without `Applied at` as unresolved.
|
|
221
|
+
|
|
222
|
+
### Multiple open Change Requests
|
|
223
|
+
|
|
224
|
+
More than one Change Request may be open at once. They are **independent**
|
|
225
|
+
unless they name the same upstream artifact.
|
|
226
|
+
|
|
227
|
+
- A defect found while a CR is open is raised as **its own CR**, not folded
|
|
228
|
+
into the open one. Folding it in would silently widen an approval the
|
|
229
|
+
operator already gave, and the blocked set the operator approved would no
|
|
230
|
+
longer be the blocked set in force.
|
|
231
|
+
- Two CRs naming the same upstream artifact are **ordered**: the second states
|
|
232
|
+
which one it assumes has landed, because the owner-skill rerun for the first
|
|
233
|
+
changes the text the second is written against. If the first is rejected, the
|
|
234
|
+
second is restated or superseded, never applied as written.
|
|
235
|
+
- The effective halt is the **union** of the open CRs' blocked sets. Nothing
|
|
236
|
+
else is halted, however many CRs are open.
|
|
237
|
+
- Open CRs accumulating is itself a project risk: report the count and their
|
|
238
|
+
ages alongside the blockers, rather than letting a queue of unanswered
|
|
239
|
+
decisions read as normal.
|
|
240
|
+
|
|
241
|
+
## Reviewer-originated obligations
|
|
242
|
+
|
|
243
|
+
The rules above govern a downstream phase **editing** upstream SSOT. This section governs the
|
|
244
|
+
mirror case: a downstream reviewer **originating** a requirement that upstream SSOT does not
|
|
245
|
+
contain. Both are drift.
|
|
246
|
+
|
|
247
|
+
### Defect or new scope: decide this first
|
|
248
|
+
|
|
249
|
+
Reviewer-originated scope means a **new obligation on the product** — behaviour, policy, or a
|
|
250
|
+
quality bar that upstream never asked for. It does **not** mean "a problem with no `AC-*` beside
|
|
251
|
+
it".
|
|
252
|
+
|
|
253
|
+
A finding is a **defect in the deliverable under review** — not new scope — when it is
|
|
254
|
+
demonstrable from the changed artifacts themselves: the reviewer can point at the code or evidence
|
|
255
|
+
and show it is wrong on its own terms. Typical shapes:
|
|
256
|
+
|
|
257
|
+
- **correctness** — the code does not do what the artifact it implements says it does: an
|
|
258
|
+
unhandled rejection, an unreachable or inverted branch, a contract the code itself declares and
|
|
259
|
+
then breaks;
|
|
260
|
+
- **security / data integrity** — missing validation on an input the code already treats as
|
|
261
|
+
trusted, credential or personal-data exposure, an injection or traversal path opened by the
|
|
262
|
+
change;
|
|
263
|
+
- **code quality** — a regression against a gate the repository already runs (lint, types, tests)
|
|
264
|
+
or against a named constitution / catalog rule.
|
|
265
|
+
|
|
266
|
+
These findings are **blocking**. Their provenance is the deliverable plus the defect class, never
|
|
267
|
+
an `AC-*`: requiring an acceptance criterion for them would oblige a reviewer who has just
|
|
268
|
+
demonstrated a bug to pass it.
|
|
269
|
+
|
|
270
|
+
A finding is **reviewer-originated scope** only when satisfying it would add product behaviour or
|
|
271
|
+
a quality bar that upstream SSOT does not contain and the changed artifacts do not already imply.
|
|
272
|
+
"It would be better if the feature also did X" is scope. "The feature does not do what it says"
|
|
273
|
+
is a defect.
|
|
274
|
+
|
|
275
|
+
### Provenance and routing
|
|
276
|
+
|
|
277
|
+
- Every reviewer finding declares a `Traces to:` value. See
|
|
278
|
+
`shared-skill-delegation-baseline.md#finding-provenance-must` for the response schema. Legal
|
|
279
|
+
values:
|
|
280
|
+
- an upstream obligation (`AC-*`, `BR-*`, `TC-*`, `CON-*`) or a named constitution/catalog rule;
|
|
281
|
+
- `defect:correctness`, `defect:security`, or `defect:code-quality` — the deliverable-defect
|
|
282
|
+
classes above, each of which MUST carry the concrete evidence in the changed artifacts that
|
|
283
|
+
demonstrates it;
|
|
284
|
+
- `none` — reviewer-originated scope.
|
|
285
|
+
- The first two are **blocking** and gate `done`.
|
|
286
|
+
- `Traces to: none` is reviewer-originated scope. It is **drift**, and it is **not satisfiable
|
|
287
|
+
downstream**: encoding it as production code plus a hard test assertion is the same violation as
|
|
288
|
+
patching upstream SSOT, inverted. It MUST be recorded as `advisory`, MUST NOT be `blocking`, and
|
|
289
|
+
is routed to the Change Request / Open Question path — never to the implementer.
|
|
290
|
+
- Routing an advisory finding:
|
|
291
|
+
1. The reviewer records it in its response under `Advisory / Change Request proposals`, with
|
|
292
|
+
enough context for the owner phase to adjudicate. The reviewer does **not** write it into
|
|
293
|
+
`08_Open-questions.md`: that file is upstream SSOT (see `#core-rule`) and is owned by
|
|
294
|
+
`/qfai-sdd`.
|
|
295
|
+
2. If it changes an already-approved obligation, raise a Change Request per
|
|
296
|
+
`#when-drift-is-detected`.
|
|
297
|
+
3. The owner phase (`/qfai-sdd`) adjudicates and is the phase that records the question in
|
|
298
|
+
`08_Open-questions.md`: **promoted** into `AC-*`/`BR-*`/`TC-*`, **deferred**, or
|
|
299
|
+
**rejected-with-rationale**.
|
|
300
|
+
4. Only after promotion and an owner rerun may the obligation become a blocking gate — at which
|
|
301
|
+
point it has an upstream ID and is no longer reviewer-originated.
|
|
302
|
+
- A **new** advisory — one that adds a question without changing an already-approved obligation —
|
|
303
|
+
does not block downstream work: the item may reach `done` against its existing upstream
|
|
304
|
+
obligations, with the advisory recorded.
|
|
305
|
+
- An advisory that **changes an already-approved obligation** takes the Change Request path
|
|
306
|
+
instead, and `#when-drift-is-detected` governs from step 1: STOP, no `done` for items that
|
|
307
|
+
depend on the obligation under dispute, resume only after approval and the owner rerun.
|
|
308
|
+
Completing against an obligation that is known to be under revision would ship a knowingly
|
|
309
|
+
inconsistent SSOT.
|
|
310
|
+
|
|
311
|
+
### Which evidence is committed
|
|
312
|
+
|
|
313
|
+
- **Regenerable** — stage evidence (`.qfai/evidence/<stage>-<spec-id>.md`),
|
|
314
|
+
run logs, reports. Reproducible by rerunning the owner skill; not committed.
|
|
315
|
+
- **Governance record** — Change Requests (`.qfai/decisions/CR-*.md`) and
|
|
316
|
+
durable decision records (`.qfai/evidence/decisions/*.json`). They carry
|
|
317
|
+
user approval and cannot be regenerated, so they are committed. The managed
|
|
318
|
+
`.gitignore` block written by `npx qfai init` negates them after the ignore
|
|
319
|
+
lines for exactly this reason.
|
|
38
320
|
|
|
39
321
|
## Non-negotiable constraints
|
|
40
322
|
|
|
41
|
-
- Downstream skills must not patch upstream SSOT directly.
|
|
42
|
-
|
|
323
|
+
- Downstream skills must not patch upstream SSOT directly. **This is detected.**
|
|
324
|
+
`npx qfai validate --profile tdd` — the completion gate `qfai-implement` names
|
|
325
|
+
— diffs the branch against `baseBranch` and emits `QFAI-DRIFT-001` (`error`)
|
|
326
|
+
for every changed file under `paths.contractsDir`, under `_policies/`, or
|
|
327
|
+
matching a protected spec-pack filename. A Change Request at `Status:
|
|
328
|
+
approved` that **names the changed path** silences it; an `open` CR does not,
|
|
329
|
+
because an open CR authorises nothing. The check does not run in the `sdd`
|
|
330
|
+
profile: `/qfai-sdd` owns these files.
|
|
331
|
+
- Downstream reviewers must not originate binding obligations that upstream SSOT does not contain.
|
|
332
|
+
- If approval is not available, stay in STOP state **for that CR's blocked set**
|
|
333
|
+
and report blockers. Work outside every open CR's blocked set proceeds; an
|
|
334
|
+
unanswered decision is not a reason to stop what it does not touch. Report
|
|
335
|
+
each open CR with its age and its blocked set, so an unanswered CR surfaces as
|
|
336
|
+
a standing blocker rather than aging out of view.
|
|
@@ -8,13 +8,43 @@ update_frequency: occasional
|
|
|
8
8
|
|
|
9
9
|
## Quality gates (baseline)
|
|
10
10
|
|
|
11
|
+
**Gate commands are project-defined. Always discover them from the repo.** This
|
|
12
|
+
file names the capabilities a gate set must cover; it never names the commands,
|
|
13
|
+
because the commands belong to the stack. `constitution.md` Article VIII and
|
|
14
|
+
`workflow.md` say the same thing — this file used to disagree with both by
|
|
15
|
+
stating five `pnpm` commands as fact, which on a non-Node repository is five
|
|
16
|
+
commands that do not exist.
|
|
17
|
+
|
|
11
18
|
When code changes are requested, the expected minimum gates are:
|
|
12
19
|
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
20
|
+
- format check
|
|
21
|
+
- lint
|
|
22
|
+
- typecheck
|
|
23
|
+
- tests
|
|
24
|
+
- pack / distribution verification (when publishing or distribution matters)
|
|
25
|
+
|
|
26
|
+
Discover the actual commands from the repository, in this order: the project's
|
|
27
|
+
task-runner manifest (`package.json` `scripts`, `Makefile`, `justfile`,
|
|
28
|
+
`pyproject.toml`, `Cargo.toml`, …), then the CI workflow, then the project's own
|
|
29
|
+
contributing docs. `/qfai-configure` records what it detected in
|
|
30
|
+
`.qfai/assistant/catalog/tech.md`; read that before guessing.
|
|
31
|
+
|
|
32
|
+
A capability with no discoverable command is **UNRUN**, not passed. Report it as
|
|
33
|
+
a blocker rather than substituting a command from another stack — a gate that
|
|
34
|
+
cannot run is a gate that silently passes.
|
|
35
|
+
|
|
36
|
+
<!--
|
|
37
|
+
Worked examples, for reading only. Neither list is a default; the capability
|
|
38
|
+
list above is the rule.
|
|
39
|
+
Node (this toolkit's own): `pnpm format:check` / `pnpm lint` /
|
|
40
|
+
`pnpm check-types` / `pnpm test` / `pnpm verify:pack`.
|
|
41
|
+
Python: `uv run ruff format --check` / `uv run ruff check` / `uv run mypy` /
|
|
42
|
+
`uv run pytest` / `uv build`.
|
|
43
|
+
-->
|
|
44
|
+
|
|
45
|
+
This file stays stack-neutral, which is what `category: universal` in its front
|
|
46
|
+
matter claims. `/qfai-configure` reads it and reconciles it with the detected
|
|
47
|
+
toolchain; it does not rewrite the capability list.
|
|
18
48
|
|
|
19
49
|
## Do not weaken safety nets
|
|
20
50
|
|
|
@@ -64,3 +64,40 @@ This document is the decision rule SSOT for AI and humans when answering:
|
|
|
64
64
|
- Managing release status flags in specs.
|
|
65
65
|
- Keeping full requirement prose in `.qfai/discussion/`.
|
|
66
66
|
- Treating diagrams as mandatory at require stage.
|
|
67
|
+
|
|
68
|
+
## Item granularity (AC/BR/EX/TC)
|
|
69
|
+
|
|
70
|
+
Directory-level slicing answers "which spec does this belong to". It does not
|
|
71
|
+
answer "how big is one item". Referential integrity is trivially satisfied by a
|
|
72
|
+
single oversized node — one BR can carry nine independent rule families and
|
|
73
|
+
still pass every hop of `US -> AC -> BR -> EX -> TC` — so item granularity
|
|
74
|
+
needs its own rule.
|
|
75
|
+
|
|
76
|
+
- **AC** — one acceptance criterion is one observable outcome a reviewer can
|
|
77
|
+
agree or disagree with in isolation.
|
|
78
|
+
- **BR** — one business rule is one independently falsifiable rule. Deletion
|
|
79
|
+
test: if removing half the `Rule` text leaves a complete rule behind, split.
|
|
80
|
+
- **EX** — one example is one concrete input/expected pair for one BR.
|
|
81
|
+
- **TC** — one test case is one verification of one AC or EX. `06_Test-Cases.md`
|
|
82
|
+
already requires at least two TCs per AC; the reciprocal signal is a BR whose
|
|
83
|
+
fan-out is 1 while its `Rule` cell is a size outlier against its siblings.
|
|
84
|
+
|
|
85
|
+
### Worked split
|
|
86
|
+
|
|
87
|
+
Too coarse:
|
|
88
|
+
|
|
89
|
+
| BR-ID | Rule |
|
|
90
|
+
| ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
91
|
+
| BR-0001 | An order is accepted when the customer is verified, the stock is reserved, the payment authorisation succeeds, and the delivery address is inside the service area; otherwise it is rejected with the first failing reason. |
|
|
92
|
+
|
|
93
|
+
Each clause is independently falsifiable, so it is four rules:
|
|
94
|
+
|
|
95
|
+
| BR-ID | Rule |
|
|
96
|
+
| ------- | -------------------------------------------------------- |
|
|
97
|
+
| BR-0001 | An unverified customer's order is rejected. |
|
|
98
|
+
| BR-0002 | An order whose stock cannot be reserved is rejected. |
|
|
99
|
+
| BR-0003 | An order whose payment authorisation fails is rejected. |
|
|
100
|
+
| BR-0004 | An order addressed outside the service area is rejected. |
|
|
101
|
+
|
|
102
|
+
Rejection _ordering_ is a fifth rule if the order is observable, and belongs in
|
|
103
|
+
its own BR rather than as a trailing clause on the others.
|