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.
Files changed (123) hide show
  1. package/README.md +48 -2
  2. package/assets/init/.qfai/assistant/agents/acceptance-test-engineer.md +1 -0
  3. package/assets/init/.qfai/assistant/agents/backend-engineer.md +1 -0
  4. package/assets/init/.qfai/assistant/agents/completion-reviewer.md +13 -2
  5. package/assets/init/.qfai/assistant/agents/delivery-planner.md +9 -0
  6. package/assets/init/.qfai/assistant/agents/frontend-engineer.md +1 -0
  7. package/assets/init/.qfai/assistant/agents/implementation-reviewer.md +6 -0
  8. package/assets/init/.qfai/assistant/agents/orchestrator.md +2 -2
  9. package/assets/init/.qfai/assistant/agents/qa-gatekeeper.md +96 -3
  10. package/assets/init/.qfai/assistant/agents/test-design-analyst.md +20 -3
  11. package/assets/init/.qfai/assistant/catalog/cli-ux-guidelines.md +2 -2
  12. package/assets/init/.qfai/assistant/catalog/spec_required_files.json +2 -1
  13. package/assets/init/.qfai/assistant/catalog/test-layers.md +355 -14
  14. package/assets/init/.qfai/assistant/catalog/worklog-entry.schema.md +165 -0
  15. package/assets/init/.qfai/assistant/constitution/communication.md +1 -1
  16. package/assets/init/.qfai/assistant/constitution/drift-protocol.md +304 -10
  17. package/assets/init/.qfai/assistant/constitution/quality.md +35 -5
  18. package/assets/init/.qfai/assistant/constitution/requirements-decomposition.md +37 -0
  19. package/assets/init/.qfai/assistant/constitution/shared-skill-delegation-baseline.md +244 -8
  20. package/assets/init/.qfai/assistant/constitution/shared-skill-operating-baseline.md +122 -5
  21. package/assets/init/.qfai/assistant/constitution/workflow.md +53 -7
  22. package/assets/init/.qfai/assistant/manifest/agent-catalog.yml +316 -945
  23. package/assets/init/.qfai/assistant/manifest/agent-routing.yml +50 -4
  24. package/assets/init/.qfai/assistant/manifest/review-profiles.yml +9 -0
  25. package/assets/init/.qfai/assistant/process/migrations/v1.4.27-atdd-alignment.md +1 -1
  26. package/assets/init/.qfai/assistant/skills/qfai-atdd/SKILL.md +61 -21
  27. package/assets/init/.qfai/assistant/skills/qfai-atdd/references/test-case-depth-checklist.md +23 -4
  28. package/assets/init/.qfai/assistant/skills/qfai-configure/SKILL.md +15 -7
  29. package/assets/init/.qfai/assistant/skills/qfai-discussion/SKILL.md +8 -4
  30. package/assets/init/.qfai/assistant/skills/qfai-discussion/references/design-md-brand-catalog.md +2 -2
  31. package/assets/init/.qfai/assistant/skills/qfai-discussion/references/discussion-completion-matrix.md +17 -7
  32. package/assets/init/.qfai/assistant/skills/qfai-discussion/references/rcp_footer.md +10 -4
  33. package/assets/init/.qfai/assistant/skills/qfai-discussion/references/review-cycle-playbook.md +1 -1
  34. package/assets/init/.qfai/assistant/skills/qfai-discussion/references/ui-bearing-playbook.md +4 -4
  35. package/assets/init/.qfai/assistant/skills/qfai-discussion/references/ui_ux/review_audit_playbook.md +1 -1
  36. package/assets/init/.qfai/assistant/skills/qfai-discussion/references/ui_ux/trend_scan_playbook.md +1 -1
  37. package/assets/init/.qfai/assistant/skills/qfai-discussion/references/ui_ux_best_practices.md +17 -7
  38. package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/01_Context.md +1 -1
  39. package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/02_Inception-Deck.md +1 -1
  40. package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/03_Story-Workshop.md +11 -3
  41. package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/05_Scope.md +5 -2
  42. package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/07_NFR.md +1 -1
  43. package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/09_Constraints.md +7 -4
  44. package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/10_Policy.md +1 -1
  45. package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/11_OQ-Register.md +1 -1
  46. package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/12_OQ-Resolution-Log.md +1 -1
  47. package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/14_Review-Request.md +14 -7
  48. package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/99_delta.md +1 -1
  49. package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/review/Rxx_reviewer.md +16 -7
  50. package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/review/review_request.md +9 -6
  51. package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/uiux/40_screen_contracts.md +3 -2
  52. package/assets/init/.qfai/assistant/skills/qfai-discussion/templates/uiux/50_review_input_bundle.md +4 -2
  53. package/assets/init/.qfai/assistant/skills/qfai-implement/SKILL.md +250 -128
  54. package/assets/init/.qfai/assistant/skills/qfai-implement/references/change-request-reset.md +93 -0
  55. package/assets/init/.qfai/assistant/skills/qfai-implement/references/checkpoint-verification.md +106 -0
  56. package/assets/init/.qfai/assistant/skills/qfai-implement/references/cross-spec-ownership.md +73 -0
  57. package/assets/init/.qfai/assistant/skills/qfai-implement/references/evidence-revision.md +77 -0
  58. package/assets/init/.qfai/assistant/skills/qfai-implement/references/execution-ledger.md +303 -0
  59. package/assets/init/.qfai/assistant/skills/qfai-implement/references/final-checklist.md +19 -0
  60. package/assets/init/.qfai/assistant/skills/qfai-implement/references/finding-classification.md +49 -0
  61. package/assets/init/.qfai/assistant/skills/qfai-implement/references/ledger-preconditions.md +55 -0
  62. package/assets/init/.qfai/assistant/skills/qfai-implement/references/oracle-strength.md +81 -0
  63. package/assets/init/.qfai/assistant/skills/qfai-implement/references/parallelization-policy.md +235 -0
  64. package/assets/init/.qfai/assistant/skills/qfai-implement/references/red-admissibility.md +91 -0
  65. package/assets/init/.qfai/assistant/skills/qfai-implement/references/red-not-observable.md +70 -0
  66. package/assets/init/.qfai/assistant/skills/qfai-implement/references/relevant-test-suite.md +87 -0
  67. package/assets/init/.qfai/assistant/skills/qfai-implement/references/review-artifact-layout.md +31 -0
  68. package/assets/init/.qfai/assistant/skills/qfai-implement/references/round-evidence.md +102 -0
  69. package/assets/init/.qfai/assistant/skills/qfai-implement/references/selector-granularity.md +24 -0
  70. package/assets/init/.qfai/assistant/skills/qfai-implement/references/volume-policy.md +149 -0
  71. package/assets/init/.qfai/assistant/skills/qfai-prototyping/SKILL.md +35 -18
  72. package/assets/init/.qfai/assistant/skills/qfai-prototyping/references/evidence-requirements.md +1 -1
  73. package/assets/init/.qfai/assistant/skills/qfai-prototyping/references/generator-prompt.md +106 -7
  74. package/assets/init/.qfai/assistant/skills/qfai-prototyping/references/handoff.md +40 -11
  75. package/assets/init/.qfai/assistant/skills/qfai-prototyping/references/iteration-loop.md +48 -1
  76. package/assets/init/.qfai/assistant/skills/qfai-prototyping/templates/DESIGN.md.sample +6 -0
  77. package/assets/init/.qfai/assistant/skills/qfai-sdd/SKILL.md +82 -22
  78. package/assets/init/.qfai/assistant/skills/qfai-sdd/references/contract-artifact-rules.md +148 -0
  79. package/assets/init/.qfai/assistant/skills/qfai-sdd/references/rcp_footer.md +10 -4
  80. package/assets/init/.qfai/assistant/skills/qfai-sdd/references/review-cycle-playbook.md +1 -1
  81. package/assets/init/.qfai/assistant/skills/qfai-sdd/references/sdd-execution-playbook.md +4 -2
  82. package/assets/init/.qfai/assistant/skills/qfai-sdd/references/sdd-phase-checklists.md +18 -0
  83. package/assets/init/.qfai/assistant/skills/qfai-sdd/references/sdd-quality-gate.md +44 -3
  84. package/assets/init/.qfai/assistant/skills/qfai-sdd/references/sdd-triage.md +60 -7
  85. package/assets/init/.qfai/assistant/skills/qfai-sdd/references/spec-traceability-rules.md +157 -5
  86. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/change-request.md +125 -0
  87. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/contracts/db-contract.sample.sql +6 -0
  88. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/evidence/sdd-spec.md +92 -0
  89. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/_policies/01_Objective.md +27 -0
  90. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/_policies/02_Initiative.md +30 -0
  91. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/_policies/05_Contracts.md +16 -6
  92. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/_policies/06_Glossary.md +19 -0
  93. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/_policies/07_Constraints.md +25 -0
  94. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/_policies/08_Decisions.md +22 -2
  95. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/_policies/11_Slice-Policy.md +37 -10
  96. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/spec/02_User-stories.md +20 -0
  97. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/spec/03_Acceptance-Criteria.md +19 -0
  98. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/spec/04_Business-Rules.md +32 -3
  99. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/spec/06_Test-Cases.md +56 -0
  100. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/spec/07_Decisions.md +29 -2
  101. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/spec/10_Plan.md +41 -0
  102. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/spec/16_Traceability-ledger.md +58 -0
  103. package/assets/init/.qfai/assistant/skills/qfai-sdd/templates/specs/spec/tdd/test-list.md +56 -0
  104. package/assets/init/.qfai/assistant/skills/qfai-verify/SKILL.md +57 -102
  105. package/assets/init/.qfai/assistant/skills/qfai-verify/references/articles.md +24 -0
  106. package/assets/init/.qfai/assistant/skills/qfai-verify/references/context-load.md +22 -0
  107. package/assets/init/.qfai/assistant/skills/qfai-verify/references/verify-output-contract.md +48 -0
  108. package/assets/init/.qfai/assistant/skills/qfai-verify/templates/verify-evidence.md +48 -0
  109. package/assets/init/.qfai/assistant/skills/web-research/SKILL.md +25 -7
  110. package/assets/init/.qfai/waivers.yml +11 -5
  111. package/assets/init/root/DESIGN.md +6 -0
  112. package/assets/init/root/qfai.config.yaml +15 -12
  113. package/dist/cli/index.cjs +11023 -7139
  114. package/dist/cli/index.cjs.map +1 -1
  115. package/dist/cli/index.mjs +10963 -7080
  116. package/dist/cli/index.mjs.map +1 -1
  117. package/dist/index.cjs +8782 -5257
  118. package/dist/index.cjs.map +1 -1
  119. package/dist/index.d.cts +280 -8
  120. package/dist/index.d.ts +280 -8
  121. package/dist/index.mjs +11776 -8264
  122. package/dist/index.mjs.map +1 -1
  123. 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
- - progress status updates only when the project workflow explicitly allows downstream updates
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 immediately.
28
- 2. Create a Change Request that includes:
29
- - context (what conflicts)
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
- 4. Rerun the owner skill for the upstream artifact.
37
- 5. Resume downstream work only after upstream artifacts are updated.
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
- - If approval is not available, stay in STOP state and report blockers.
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
- - `pnpm format:check`
14
- - `pnpm lint`
15
- - `pnpm check-types`
16
- - `pnpm test`
17
- - `pnpm verify:pack` (when publishing/distribution matters)
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.