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
@@ -0,0 +1,19 @@
1
+ # Final Checklist
2
+
3
+ Check this list last, immediately before the completion message. Every box must be ticked; a box that
4
+ cannot be ticked is a reason not to declare completion, not a note to carry forward.
5
+
6
+ - [ ] CRITICAL CONSTRAINTS were followed.
7
+ - [ ] Each item was processed one test at a time, or inside an item-level parallel dispatch authorized by `SKILL.md#parallelization-policy`.
8
+ - [ ] Red phase: test was written and confirmed to fail — or, on the _RED not observable_ path,
9
+ the correct test was written first and the falsifiability trio replaces the natural RED
10
+ (`red-not-observable.md`).
11
+ - [ ] Green phase: minimal code was written and test confirmed to pass — waived on the _RED not
12
+ observable_ path, where the `Satisfied-by` row already implements the predicate.
13
+ - [ ] Refactor phase: code improved with tests still passing.
14
+ - [ ] `test-list.md` statuses are accurate.
15
+ - [ ] No backward transitions occurred.
16
+ - [ ] Exception items have DR-IDs recorded.
17
+ - [ ] All tests pass.
18
+ - [ ] `npx qfai validate --profile tdd --fail-on error` passes with zero `QFAI-TEST-001` findings (no
19
+ `it.todo` / `test.todo` / `describe.todo` stubs remain).
@@ -0,0 +1,49 @@
1
+ # Blocking vs advisory findings
2
+
3
+ Provenance rules: `shared-skill-delegation-baseline.md#finding-provenance-must`.
4
+
5
+ ## Blocking
6
+
7
+ A **blocking** finding cites either an upstream obligation (`AC-*`, `BR-*`,
8
+ `TC-*`, `CON-*`, or a named constitution/catalog rule) or a defect class
9
+ (`defect:correctness`, `defect:security`, `defect:code-quality`) in its
10
+ `Traces to:` field.
11
+
12
+ A defect demonstrable from the changed code — an unhandled rejection, a missing
13
+ validation on trusted input, a leak, a broken contract the code itself declares
14
+ — is blocking without needing an `AC-*`.
15
+
16
+ Only blocking findings force `REVISE`, and only blocking findings hold the item
17
+ out of `done`.
18
+
19
+ ## Advisory
20
+
21
+ An **advisory** finding is one whose `Traces to:` is `none` — a new product
22
+ obligation upstream never asked for. It MUST NOT be implemented as production
23
+ code or pinned as a test assertion.
24
+
25
+ Route it per `drift-protocol.md#reviewer-originated-obligations`: record it in
26
+ the reviewer response under `Advisory / Change Request proposals`.
27
+
28
+ Do **not** edit `08_Open-questions.md` here. It is upstream SSOT under the Drift
29
+ Protocol, and creating spec artifacts is a non-goal of this skill; the owner
30
+ phase (`/qfai-sdd`) records and adjudicates it.
31
+
32
+ ## What an advisory does to `done`
33
+
34
+ - A new advisory that does **not** change an already-approved obligation leaves
35
+ the item free to reach `done`.
36
+ - One that **does** change an approved obligation takes the Change Request path,
37
+ and `drift-protocol.md#when-drift-is-detected` applies: STOP, and no `done`
38
+ for items depending on the obligation under dispute until approval and the
39
+ owner rerun.
40
+
41
+ ## The reviewer verdict is still required
42
+
43
+ `Do not declare DONE until Reviewer returns PASS` is never waived: the Reviewer
44
+ verdict is required on every item, including one whose review produced only
45
+ advisories.
46
+
47
+ What **blocking** findings change is the verdict itself — only they force
48
+ `REVISE` and hold `done`. An advisory-only review returns `PASS`, and that
49
+ `PASS` is still what releases `done`.
@@ -0,0 +1,55 @@
1
+ # Ledger preconditions
2
+
3
+ `.qfai/specs/<spec-id>/tdd/test-list.md` is the execution ledger every step of
4
+ `/qfai-implement` reads. This file states where it comes from, how to recover it
5
+ when it is absent, and how to tell a truthfully empty ledger from an incomplete
6
+ one.
7
+
8
+ ## Producer
9
+
10
+ `/qfai-sdd` Phase 2b seeds one row per coverage-target TC from
11
+ `06_Test-Cases.md`. `US-*` / `CON-API-*` are ATDD obligations traced by `QFAI:`
12
+ annotations, not ledger rows — they never appear as rows here.
13
+
14
+ ## Recovery when it is missing
15
+
16
+ Rerun `/qfai-sdd <spec-id>` for the target spec, or copy
17
+ `.qfai/assistant/skills/qfai-sdd/templates/specs/spec/tdd/test-list.md` into the
18
+ spec directory and derive the rows from `06_Test-Cases.md`.
19
+
20
+ Do **not** proceed with an absent ledger, and do **not** invent rows that no TC
21
+ backs.
22
+
23
+ ## An empty ledger is a fault only when `06_Test-Cases.md` disagrees
24
+
25
+ A header-only table has two very different causes and they need opposite
26
+ responses, so never treat "no rows" as "nothing to do" on its own.
27
+
28
+ Before exiting, read `06_Test-Cases.md` and confirm it declares **no**
29
+ coverage-target TC, judged exactly as the validator judges it
30
+ (`qfai-sdd/references/spec-traceability-rules.md#tdd-execution-ledger`).
31
+
32
+ ### What counts as a coverage target
33
+
34
+ A TC is a target **unless** its `Level` names a non-coverage layer. Both
35
+ spellings the shipped artifacts use count: the words `integration` / `e2e` /
36
+ `system` / `acceptance` / `api`, and the codes `L3` / `L4` / `L5` that
37
+ `06_Test-Cases.md` writes. Matching is case-insensitive.
38
+
39
+ That is an exclusion list, not an allowlist:
40
+
41
+ - an empty or unrecognised `Level` makes the TC a target;
42
+ - a `06_Test-Cases.md` with no `Level` column at all makes **every** TC a target.
43
+
44
+ Never narrow this to a chosen pair of level names. Guidance that names a
45
+ narrower allowlist makes a header-only ledger look truthful and skips the whole
46
+ implementation.
47
+
48
+ ### The two outcomes
49
+
50
+ - **No coverage-target TC is declared** — the ledger is truthfully empty. Report
51
+ "nothing to do" and exit. Rerunning `/qfai-sdd` derives the same empty table
52
+ and loops.
53
+ - **At least one is declared** — the ledger is incomplete (a partial copy or an
54
+ interrupted Phase 2b) and `npx qfai validate` reports `TDDLIST_TC_NOT_COVERED`.
55
+ Run the recovery above instead of exiting.
@@ -0,0 +1,81 @@
1
+ # Oracle Strength
2
+
3
+ Whether a passing test's pass **depends on the behaviour the item owns**.
4
+
5
+ Nothing in qfai asked this. The completion gate and the per-item evidence contract
6
+ record a command that failed and a command that passed; GREEN is measured as
7
+ `exit code == 0`. Downstream, ATDD coverage is annotation presence, the strongest
8
+ content check on a `done` row is that the test file exists, and the Coverage
9
+ Depth Matrix counts **case categories**, never oracle strength. A test that
10
+ cannot fail therefore cleared RED, GREEN, refactor, all completion points,
11
+ `QFAI-ATDD-111/112/113` and `npx qfai validate`.
12
+
13
+ ## `Oracle proof` — the evidence field
14
+
15
+ Per item, alongside the RED/GREEN pair:
16
+
17
+ 1. Name the **smallest production change** that makes this item's test fail
18
+ again — one line, in the code the item owns.
19
+ 2. Apply it, run the row's `Selector`, and record the command and its **failing**
20
+ output.
21
+ 3. **Revert immediately.** The mutation is evidence, not a deliverable; it must
22
+ never appear in the commit.
23
+
24
+ One mutation per item. It is the only evidence that separates a discriminating
25
+ test from a vacuous one, and it costs one run.
26
+
27
+ A row on the _RED not observable_ path already carries
28
+ `Falsifiability command` / `Falsifiability result`, which is the same proof by
29
+ the same method. That satisfies `Oracle proof`; do not do it twice.
30
+
31
+ ## Reject an `Oracle proof` when
32
+
33
+ - the mutation is outside the code the item owns — breaking a shared helper
34
+ proves the helper is used, not that this test discriminates;
35
+ - the mutation is a syntax error, a thrown "not implemented", or a deleted
36
+ export — that is a load failure, the same non-observation
37
+ `red-admissibility.md` rejects for RED;
38
+ - the failing output names a different selector than the row's;
39
+ - the recorded command differs from the `GREEN command`. Proving a different
40
+ test discriminates says nothing about this one.
41
+
42
+ ## Weak-oracle shapes to look for
43
+
44
+ These are the failure modes seen in the wild. Each passes today's gates.
45
+
46
+ - **Truthiness where the value is available.** `expect(result).toBeTruthy()` when
47
+ the boundary's own value is in hand. Assert the value.
48
+ - **Round-tripping the fixture's own helper.** Comparing a stored value against
49
+ the same function that wrote it: the assertion holds for every implementation
50
+ of the function, including a wrong one.
51
+ - **Loops over a collection that is empty by construction.** A `for` over a
52
+ filtered set that no fixture can populate asserts nothing, and reports as a
53
+ pass.
54
+ - **Observations the transport discards.** Asserting on a field the client
55
+ strips, or a log the harness swallows, is an assertion against nothing.
56
+ - **Assertions on the mock.** Verifying that a stub was called with what the
57
+ test just passed it re-states the test's own input.
58
+
59
+ ## The equivalent-mutant case
60
+
61
+ Sometimes no mutation can be found because the **upstream contract is weaker
62
+ than the obligation** — every implementation the contract permits passes the
63
+ test, so the test cannot discriminate without asserting something upstream never
64
+ promised.
65
+
66
+ That is not an implementer defect and must not be worked around by strengthening
67
+ the assertion past the contract: doing so encodes a reviewer-originated
68
+ obligation in a hard assertion, which
69
+ `constitution/drift-protocol.md#reviewer-originated-obligations` forbids in
70
+ exactly those terms.
71
+
72
+ The route:
73
+
74
+ 1. Record `Oracle proof: equivalent-mutant`, naming the contract clause that is
75
+ weaker than the obligation.
76
+ 2. Raise it as an advisory / Change Request per
77
+ `drift-protocol.md#when-drift-is-detected`. `/qfai-sdd` owns closing it, by
78
+ tightening the contract.
79
+ 3. The row may reach `done` against its existing obligation with the advisory
80
+ recorded — the gap is upstream, and blocking the implementer on a finding
81
+ they are forbidden to act on would be a deadlock, not a gate.
@@ -0,0 +1,235 @@
1
+ # Parallelization Policy
2
+
3
+ Full rules for item-level parallelism inside one spec. `qfai-implement/SKILL.md`
4
+ carries the summary and the precedence statement.
5
+
6
+ ## Scope of this policy
7
+
8
+ - **Cross-spec parallelism is barred.** One spec per invocation, always. This
9
+ is the Non-goal above and it is not approvable.
10
+ - **Item-level parallelism inside one spec** is what the rest of this section
11
+ governs. `parallel_groups: []` in `agent-routing.yml` describes **role
12
+ fan-out within a phase**, not item dispatch; it neither permits nor forbids
13
+ what this section decides.
14
+
15
+ ## Gates and precedence
16
+
17
+ Two gates apply, and **both must hold**:
18
+
19
+ 1. **Technical gate** — the conditions below. Adjudicated by
20
+ `delivery-planner`, which is the sole authority for authorizing parallel
21
+ dispatch.
22
+ 2. **Consent gate** — explicit user approval.
23
+
24
+ **Precedence: user approval cannot override a technical DENY.** A DENY from
25
+ `delivery-planner` ends the question; approval is only sought after the
26
+ technical gate passes.
27
+
28
+ - **Default**: Serial execution. Items are processed one test at a time in `test-list.md` order.
29
+ - Serial execution ensures that each test is written and verified in isolation before moving to the next.
30
+
31
+ ## Allow conditions (all must be true)
32
+
33
+ Stated as **concurrent write conflicts**, not as the existence of shared
34
+ things. A read-only fixture module or a DI container that every item constructs
35
+ independently does not veto the policy; a shared database is resolved by
36
+ per-worker schema isolation, not by a blanket deny.
37
+
38
+ - **Every concurrently dispatched row declares an `Owning module`**, and no two
39
+ of them declare the same one. This is the operational form of the next
40
+ bullet: under RED-first the source module does not exist yet, so the only
41
+ thing that can be compared before dispatch is what each row _declares_ it
42
+ will write (`execution-ledger.md#declared-seam-column-optional-required-for-parallel-dispatch`).
43
+ A row carrying `-` in that column is not eligible for parallel dispatch.
44
+ - No two concurrently dispatched items **write** the same source module.
45
+ - No two concurrently dispatched items **write** the same test module.
46
+ - No item **writes** a module that another concurrently dispatched item's test
47
+ or implementation **reads**. A write/read overlap is a conflict even when no
48
+ two items write the same file: the reader's RED/GREEN would observe a
49
+ half-applied module and become timing-dependent.
50
+ - No two concurrently dispatched items **mutate** the same fixture instance,
51
+ singleton instance, or DI container instance. (Constructing a fresh instance
52
+ per item is fine.)
53
+ - No two concurrently dispatched items **write** the same schema or the same
54
+ database rows. Per-worker schema or database isolation satisfies this.
55
+ - No two concurrently dispatched items contend for the same **external runtime
56
+ resource**. Worktree separation isolates the checkout and the index and
57
+ nothing else, so these live outside it and must be checked explicitly:
58
+ - fixed TCP/UDP ports the items' tests bind;
59
+ - absolute or `os.tmpdir()`-rooted paths written outside the worktree;
60
+ - external caches, queues, brokers, containers and other daemons;
61
+ - environment variables and OS-global state the tests set.
62
+
63
+ Satisfy it either by a **disjoint write set** (each item owns different
64
+ ports/paths/keys) or by **per-worker isolation** (ephemeral port 0, a
65
+ `mkdtemp` directory per worker, a namespaced cache/queue prefix). A resource
66
+ neither disjoint nor isolated is a DENY: `constitution/workflow.md#concurrency-stage-independent-mandatory`
67
+ requires no shared state, and the collision would appear at run time as a
68
+ flaky RED/GREEN rather than at adjudication.
69
+
70
+ - No sequential dependency: item B does not consume item A's output.
71
+ - A post-merge integration verify plan exists.
72
+
73
+ Read dependencies are enumerated from the declared write sets: for every write
74
+ target, `delivery-planner` resolves the importers reachable from the other
75
+ items' test and implementation files. An import graph that cannot be resolved
76
+ is a DENY, because the independence claim then has no concrete evidence.
77
+
78
+ ## Isolation requirement (worktree separation)
79
+
80
+ Adjudicated separately from the "all must be true" list above, and **not
81
+ waivable**. Per `constitution/workflow.md#concurrency-stage-independent-mandatory`,
82
+ worktree separation is required for parallel execution, so
83
+ `delivery-planner` has two outcomes, not three:
84
+
85
+ - **Separate worktrees in force** (one worker per `git worktree`, one index
86
+ each) -> requirement met.
87
+ - **Anything else -> DENY.** Record the reason in the dispatch decision and run
88
+ the items serially.
89
+
90
+ A branch is **not** a substitute. Branch separation still shares one working
91
+ tree and one index: workers observe each other's half-written files and
92
+ generated artifacts, which is exactly the hidden coupling the requirement
93
+ exists to prevent, and a sweeping stage command would commit a sibling's
94
+ in-flight files.
95
+
96
+ Worktree separation is also **not sufficient on its own**. It separates the
97
+ checkout and the index; ports, out-of-worktree paths and external services stay
98
+ shared across workers. The external-runtime-resource condition in the allow
99
+ list covers those, and it is evaluated whether or not worktrees are in force.
100
+
101
+ qfai does not provision worktrees itself, so in practice this exception stays
102
+ unreachable until the operator (or the orchestrator, explicitly) creates one
103
+ worktree per worker. That is the intended outcome: serial execution is the
104
+ correct behavior when isolation cannot be guaranteed, and an unreachable
105
+ exception is preferable to a documented way around an upstream SSOT rule.
106
+
107
+ ## Deny conditions (any one blocks parallel dispatch)
108
+
109
+ - Two concurrently dispatched items share the same behavior's Red/Green/Refactor cycle.
110
+ - Two concurrently dispatched items declare the same `Owning module`, or either
111
+ of them declares none.
112
+ - Two concurrently dispatched items modify the same public API surface. Before
113
+ RED this is evaluated over the declared seams; the surface itself does not
114
+ exist yet.
115
+ - Two concurrently dispatched items write the same shared fixture, shared mock,
116
+ or shared global setup **file**. (A shared fixture module that neither item
117
+ writes and each consumes read-only is not a deny — see the allow conditions.)
118
+ - Two concurrently dispatched items bind the same fixed port, write the same
119
+ out-of-worktree path, or share an un-namespaced external cache/queue.
120
+ - Sequential dependency: "A must finish before B has meaning".
121
+ - The independence claim cannot be explained with concrete file/module
122
+ evidence. Before RED that evidence is the rows' declared `Owning module`
123
+ values — not the source tree, which does not yet contain the modules under
124
+ discussion. **If the ledger carries no `Owning module` column, the allow
125
+ conditions cannot be evaluated at all**, and parallel dispatch is permitted
126
+ only for slices whose seams already exist in the repository. "The test files
127
+ differ" is not an independence claim.
128
+
129
+ ## Seam reconciliation (after a parallel run)
130
+
131
+ The post-merge integration verify detects a broken build. It does not detect
132
+ two slices deciding the same thing twice under two names in one module, which
133
+ is the outcome the deny conditions exist to prevent — and that outcome can
134
+ leave the suite green.
135
+
136
+ So after the slices merge, and **independently of whether the merged suite
137
+ passes**:
138
+
139
+ 1. For each slice, list the `src/` paths it actually touched
140
+ (`git diff --name-only <base>..<slice-head> -- <source root>`).
141
+ 2. Compare that list against the slice's declared `Owning module`.
142
+ 3. Report every touched path that no slice declared, and every path touched by
143
+ more than one slice, as a **deny-condition breach**. It is a breach whether
144
+ or not anything broke: the gate was passed on a claim that turned out to be
145
+ false, so the next authorization is being made on the same basis.
146
+ 4. A breach does not automatically roll back a green merge. It does require the
147
+ overlapping modules to be re-read for duplicated behaviour, and the finding
148
+ to be recorded before `delivery-planner` authorizes another parallel run.
149
+
150
+ ## Coordinated parallel mode (ledger ownership)
151
+
152
+ When parallel dispatch is authorized, the ledger has one writer:
153
+
154
+ - The **orchestrator** owns every `test-list.md` write. Workers never edit it.
155
+ - Workers return a per-item evidence block carrying **every** field of the
156
+ `SKILL.md` "Per-item evidence contract": `TDD-ID`, `TC-ref`, RED command and
157
+ result, GREEN command and result, Refactor verify command and result,
158
+ `Spec review`, `Code quality review`, and `Prototype parity` for UI-affecting
159
+ items — plus the resulting status and `DR-ID`.
160
+ - Item 10 of the 11-point gate is satisfied by the orchestrator applying a
161
+ **complete** evidence block to the row, not by the worker writing it. A block
162
+ missing any contract field does not satisfy item 10: the orchestrator obtains
163
+ the missing fields first, and the row stays out of `done` until it has them.
164
+
165
+ ## Ledger ownership
166
+
167
+ `.qfai/specs/<spec-id>/tdd/test-list.md` has exactly one writer: the
168
+ **orchestrator**, in the **trunk**.
169
+
170
+ This is not a style preference. Delegation is mandatory and the orchestrator may
171
+ not write code, so the only role that ever observes RED/GREEN is the
172
+ implementation agent — and the ledger it would have to write lives _inside_ the
173
+ tree that worktree separation copies. N workers would each hold a private copy of
174
+ the one table that is the completion gate, and merging them is a text merge of
175
+ the artifact the gate reads.
176
+
177
+ So:
178
+
179
+ - Parallel workers **MUST NOT** edit `.qfai/specs/<spec-id>/tdd/**`. Their
180
+ worktree copy is read-only for the duration of the slice.
181
+ - Each worker returns, per item it processed: `TDD-ID`, final `Status`, and the
182
+ `Evidence` payload in the per-item evidence contract's form.
183
+ - The orchestrator writes those rows into the trunk ledger during
184
+ `#post-parallel-integration-verify`, before the verify runs.
185
+ - A merged item whose row is still `todo` fails that verify. Silence there is
186
+ indistinguishable from work that was never done.
187
+
188
+ In serial mode the same rule holds with no merge step: the implementation agent
189
+ returns Status + Evidence, the orchestrator writes them.
190
+
191
+ ## Failed integration verify
192
+
193
+ The old rule was one unconditional destructive branch — "flag all slices for
194
+ re-examination and roll back the merge" — with no step attributing the failure to
195
+ anything. That contradicts the Gate Failure Autorepair Protocol the skill
196
+ imports twenty lines later, which classifies this class as a local,
197
+ non-destructive code/test defect to fix and re-run, and reserves stopping for
198
+ _destructive_ changes. It also contradicts the forward-only lifecycle, and never
199
+ said what happened to the rolled-back items' statuses.
200
+
201
+ Classify first, then apply the matching remedy.
202
+
203
+ ### 1. Defect outside every merged slice
204
+
205
+ A stale fixture, a stale composition helper, a shared factory none of the slices
206
+ declared. **Fix locally and re-run integration verify. Do not roll back.**
207
+
208
+ The fix lands outside every slice's declared write boundary, so it is the
209
+ **orchestrator's** to make — no slice owns it, and returning it to a worker would
210
+ route it to an agent whose boundary excludes the file. Record it in the stage
211
+ evidence as an integration fix, not as a slice's work.
212
+
213
+ ### 2. Defect inside one slice
214
+
215
+ Return **that slice's items only**. The other slices keep their state and their
216
+ merged code; re-examining them would discard work the verify did not fault.
217
+ Rows go to `review-fix`, which is the status that exists for rework and has an
218
+ outbound edge back to `refactor`.
219
+
220
+ ### 3. The union itself is inadmissible
221
+
222
+ Only when the slices are individually correct and jointly wrong — a genuine
223
+ interaction the merge exposed — flag all slices and roll back the merge.
224
+
225
+ This is the **one sanctioned backward move** in this skill besides an approved
226
+ Change Request reset. It is a _merge_ rollback, not a status rollback: the rows
227
+ return to `review-fix`, not to `todo`, so the forward-only lifecycle is
228
+ unbroken and the RED/GREEN evidence each row already earned is retained. A row
229
+ that must genuinely restart needs the upstream-reset rule and its recorded
230
+ approval, exactly as elsewhere.
231
+
232
+ ### Round budget
233
+
234
+ Repeating any of the three without progress escalates to the user on the third
235
+ round, per the autorepair protocol. "Roll back and retry" is not a loop.
@@ -0,0 +1,91 @@
1
+ # RED Admissibility
2
+
3
+ What makes a failure count as the RED observation for a ledger row.
4
+
5
+ `Phase: Red` step 4 says "confirm the test actually fails for the expected
6
+ reason". That phrase used to be the whole standard qfai shipped — it appeared
7
+ three times across the assistant tree, always as an obligation and never as a
8
+ definition, and no validator adjudicated it. This file is the definition.
9
+
10
+ ## The criterion
11
+
12
+ A failure is an **admissible RED** when all four hold:
13
+
14
+ 1. The test module **imports and loads successfully**. Nothing under test is
15
+ missing at the module level.
16
+ 2. The failure is raised by an **assertion** — or an expected-exception check —
17
+ **executing inside the row's own `Selector`**. Not in a fixture, not in a
18
+ sibling test, not at collection time.
19
+ 3. The failure message **names the predicate the row owns**: the value, state or
20
+ error the obligation is about. "expected 3, received undefined" names it;
21
+ "cannot find module" does not.
22
+ 4. Deleting every assertion in the test would make the run **pass**. If the run
23
+ would fail identically with no assertions at all, the observation carries no
24
+ information about the assertions.
25
+
26
+ ## What is not a RED
27
+
28
+ A **missing seam**, not a RED:
29
+
30
+ - collection / import / module-resolution error
31
+ - syntax error
32
+ - missing symbol or missing export
33
+ - fixture, factory or test-harness setup error
34
+ - a failure raised outside the row's `Selector`
35
+
36
+ Each of these proves the seam is absent. None of them says anything about
37
+ whether the assertions discriminate — which is the property RED exists to
38
+ establish.
39
+
40
+ This matters most exactly where discriminating power matters most. Under the
41
+ skill's own ordering, Phase Red writes the test and Phase Green writes the
42
+ production code, so for any row that introduces a new module or symbol the first
43
+ failure is a load error **by construction**. Without step 3a below, the gate
44
+ would be met vacuously for every such row.
45
+
46
+ ## Step 3a: create the seam first
47
+
48
+ Before running the test, create the **minimal seam** the test imports: the
49
+ module, export, class or function signature, with **no behaviour** — a no-op
50
+ body, or one returning a placeholder value.
51
+
52
+ Do **not** make the seam throw. An unasserted exception fails the run before any
53
+ assertion executes, which is the same non-observation as a load error: it shows
54
+ the seam is unfinished, not that the assertions discriminate. The one exception
55
+ is a test whose oracle _is_ an expected-exception check — there the throw is what
56
+ the assertion inspects, and the row records `expected-error`.
57
+
58
+ This is not production code and does not satisfy Phase Green's step 1: it
59
+ implements no predicate. Its only job is to make the module load, so that the
60
+ failure the row records is an assertion failure rather than a resolution
61
+ failure.
62
+
63
+ ## Recording it
64
+
65
+ The per-item evidence contract carries `RED failure mode`, whose value is one
66
+ of:
67
+
68
+ | Value | Meaning |
69
+ | ---------------- | ------------------------------------------------------------ |
70
+ | `assertion` | admissible — an assertion inside the row's `Selector` failed |
71
+ | `expected-error` | admissible — an expected-exception check failed |
72
+ | `falsifiability` | the _RED not observable_ path; see `red-not-observable.md` |
73
+
74
+ There is no admissible value for a load error, and that is deliberate: a row
75
+ whose only failure was a load error has not observed RED yet. Create the seam
76
+ and re-run.
77
+
78
+ `RED result` truncation: the general "truncated output is acceptable" allowance
79
+ does **not** extend to the part of the output that demonstrates admissibility.
80
+ The recorded result must retain the assertion message and its location. Truncate
81
+ the stack tail, never the assertion line.
82
+
83
+ ## When an assertion-level RED is genuinely unobservable
84
+
85
+ One case is legitimate: the obligation is already satisfied by a sibling row, so
86
+ the correct test passes on first run. That is **not** a licence to accept a load
87
+ error instead — it is a different path with its own evidence, and it is
88
+ specified in `red-not-observable.md`. Record `RED failure mode: falsifiability`
89
+ and follow that procedure.
90
+
91
+ Never weaken a correct test until it fails in order to manufacture a RED.
@@ -0,0 +1,70 @@
1
+ # RED Not Observable (obligation already satisfied)
2
+
3
+ Handling for `Phase: Red` step 5 when a newly written test passes on its first
4
+ run.
5
+
6
+ ## Classify first
7
+
8
+ - **Obligation already satisfied by a sibling row** — the new test exercises a
9
+ predicate an earlier `done` row already made pass. This is the usual case
10
+ when a BR binds several ACs to one common validator. It is **not an anomaly**
11
+ and does **not** go to `exception`. Follow the procedure below.
12
+ - **Anything else** — the test is wrong, the SUT is wrong, or the cause is
13
+ unknown. Transition to `exception` and record the anomaly.
14
+
15
+ Never weaken a correct test until it fails in order to manufacture a RED.
16
+
17
+ ## Falsifiability evidence
18
+
19
+ An honest GREEN from a sibling item is evidence the system works, not a defect.
20
+ The row still needs to be falsifiable, so substitute falsifiability evidence
21
+ for the natural RED and let the row proceed to `green` and `done`:
22
+
23
+ 1. Record `Satisfied-by: TDD-NNNN` — the row whose implementation already
24
+ satisfies this obligation.
25
+ 2. Break the shared predicate deliberately (inject a mutation), run this row's
26
+ test, and confirm it **fails**. Record the command and its output as
27
+ `Falsifiability command` / `Falsifiability result`.
28
+ 3. Revert the mutation and confirm the test passes again. That run is the row's
29
+ GREEN evidence.
30
+ 4. A mutation-testing result covering the same predicate is an acceptable
31
+ substitute for the **falsifiability demonstration** — step 2 and the revert
32
+ half of step 3 — with the report standing in for `Falsifiability command` /
33
+ `Falsifiability result`. It does **not** substitute for GREEN: the row still
34
+ records a `GREEN command` / `GREEN result` from a run with the predicate
35
+ intact, either the original passing run or an explicit re-run.
36
+
37
+ ## Effect on the gates
38
+
39
+ The `Evidence` cell carries `Satisfied-by`, `Falsifiability command`,
40
+ `Falsifiability result` and the GREEN pair in place of a RED pair. The
41
+ 11-point gate is all-conditions-required, so every item this path touches is
42
+ listed here — a substitute that only covered item 3 would still leave the row
43
+ unable to reach `done`.
44
+
45
+ - **Item 2 ("A failing test was added first")** is satisfied by adding the
46
+ correct test first and proving it falsifiable by mutation. A test that
47
+ passes on its first run because the predicate is already implemented is
48
+ still test-first; the alternative — weakening it until it fails — is what
49
+ the classification step forbids.
50
+ - **Item 3 ("RED was observed")** is satisfied by the falsifiability evidence.
51
+ - **Item 4 ("Minimal production code was written")** is **waived**: the
52
+ `Satisfied-by` row already wrote it. Inventing an unrelated change to tick
53
+ this box is worse than the gap it fills. `Phase: Green` step 1 likewise has
54
+ nothing to write on this path and proceeds straight to running the test.
55
+ - **The per-item evidence contract** treats the RED pair and the
56
+ falsifiability trio as **exclusive alternatives**: exactly one form is
57
+ present, never both and never neither. `qa-gatekeeper` accepts the
58
+ falsifiability form as the minimum evidence for this row.
59
+ - **The completion prohibition** "No RED fresh evidence exists for the item"
60
+ does not apply to a row carrying falsifiability evidence.
61
+ - **The `FINAL CHECKLIST` Red and Green boxes** are ticked by this path's
62
+ substitutes: the falsifiability trio for Red, and the observed pass with no
63
+ new production code for Green.
64
+ - **`project_memory` and `constitution/workflow.md`** restate "fresh RED +
65
+ GREEN evidence is mandatory per item"; both now carry this path's exception,
66
+ so a run that reloads only its memory context does not re-impose the RED pair
67
+ and force a fabricated failure.
68
+
69
+ Every other gate item is unchanged: GREEN must still be observed, refactor
70
+ must still be verified, and both blocking reviewers must still return PASS.