@3f-consulting/spec-controller-core 0.1.0-alpha.5 → 0.1.0-alpha.50

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 (245) hide show
  1. package/README.md +6 -4
  2. package/dist/assemble/evidenceReconciliationFromSources.d.ts +5 -40
  3. package/dist/assemble/evidenceReconciliationFromSources.d.ts.map +1 -1
  4. package/dist/assemble/evidenceReconciliationFromSources.js +31 -319
  5. package/dist/assemble/evidenceReconciliationFromSources.js.map +1 -1
  6. package/dist/assemble/renderInput.d.ts +6 -72
  7. package/dist/assemble/renderInput.d.ts.map +1 -1
  8. package/dist/assemble/renderInput.js +3 -45
  9. package/dist/assemble/renderInput.js.map +1 -1
  10. package/dist/census/evidenceObligations.d.ts +10 -46
  11. package/dist/census/evidenceObligations.d.ts.map +1 -1
  12. package/dist/census/evidenceObligations.js +15 -25
  13. package/dist/census/evidenceObligations.js.map +1 -1
  14. package/dist/domain/evidenceOrder.d.ts +3 -0
  15. package/dist/domain/evidenceOrder.d.ts.map +1 -0
  16. package/dist/domain/evidenceOrder.js +15 -0
  17. package/dist/domain/evidenceOrder.js.map +1 -0
  18. package/dist/domain/evidenceReconciliation.d.ts +16 -386
  19. package/dist/domain/evidenceReconciliation.d.ts.map +1 -1
  20. package/dist/domain/evidenceReconciliation.js +79 -375
  21. package/dist/domain/evidenceReconciliation.js.map +1 -1
  22. package/dist/domain/featureCode.d.ts +4 -0
  23. package/dist/domain/featureCode.d.ts.map +1 -0
  24. package/dist/domain/featureCode.js +12 -0
  25. package/dist/domain/featureCode.js.map +1 -0
  26. package/dist/domain/journal.d.ts +7 -392
  27. package/dist/domain/journal.d.ts.map +1 -1
  28. package/dist/domain/journal.js +6 -118
  29. package/dist/domain/journal.js.map +1 -1
  30. package/dist/domain/ledger.d.ts +4 -328
  31. package/dist/domain/ledger.d.ts.map +1 -1
  32. package/dist/domain/ledger.js +11 -317
  33. package/dist/domain/ledger.js.map +1 -1
  34. package/dist/domain/outcome.d.ts +3 -0
  35. package/dist/domain/outcome.d.ts.map +1 -0
  36. package/dist/domain/outcome.js +2 -0
  37. package/dist/domain/outcome.js.map +1 -0
  38. package/dist/domain/posting.d.ts +5 -102
  39. package/dist/domain/posting.d.ts.map +1 -1
  40. package/dist/domain/posting.js +3 -55
  41. package/dist/domain/posting.js.map +1 -1
  42. package/dist/domain/qualityCheckFault.d.ts +1 -41
  43. package/dist/domain/qualityCheckFault.d.ts.map +1 -1
  44. package/dist/domain/qualityCheckFault.js +0 -24
  45. package/dist/domain/qualityCheckFault.js.map +1 -1
  46. package/dist/domain/qualityCheckFaultMessages.d.ts +0 -35
  47. package/dist/domain/qualityCheckFaultMessages.d.ts.map +1 -1
  48. package/dist/domain/qualityCheckFaultMessages.js +0 -28
  49. package/dist/domain/qualityCheckFaultMessages.js.map +1 -1
  50. package/dist/domain/qualityCheckReconciliation.d.ts +5 -278
  51. package/dist/domain/qualityCheckReconciliation.d.ts.map +1 -1
  52. package/dist/domain/qualityCheckReconciliation.js +53 -453
  53. package/dist/domain/qualityCheckReconciliation.js.map +1 -1
  54. package/dist/domain/qualityCheckReconciliationFault.d.ts +0 -19
  55. package/dist/domain/qualityCheckReconciliationFault.d.ts.map +1 -1
  56. package/dist/domain/qualityCheckReconciliationFault.js +0 -23
  57. package/dist/domain/qualityCheckReconciliationFault.js.map +1 -1
  58. package/dist/domain/scenarioCodeError.d.ts +16 -0
  59. package/dist/domain/scenarioCodeError.d.ts.map +1 -0
  60. package/dist/domain/scenarioCodeError.js +4 -0
  61. package/dist/domain/scenarioCodeError.js.map +1 -0
  62. package/dist/domain/scenarioReconciliation.d.ts +0 -205
  63. package/dist/domain/scenarioReconciliation.d.ts.map +1 -1
  64. package/dist/domain/scenarioReconciliation.js +1 -98
  65. package/dist/domain/scenarioReconciliation.js.map +1 -1
  66. package/dist/domain/scnAllocation.d.ts +27 -0
  67. package/dist/domain/scnAllocation.d.ts.map +1 -0
  68. package/dist/domain/scnAllocation.js +33 -0
  69. package/dist/domain/scnAllocation.js.map +1 -0
  70. package/dist/domain/verdictCode.d.ts +10 -0
  71. package/dist/domain/verdictCode.d.ts.map +1 -0
  72. package/dist/domain/verdictCode.js +16 -0
  73. package/dist/domain/verdictCode.js.map +1 -0
  74. package/dist/index.d.ts +12 -38
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +6 -86
  77. package/dist/index.js.map +1 -1
  78. package/dist/internal.d.ts +3 -25
  79. package/dist/internal.d.ts.map +1 -1
  80. package/dist/internal.js +3 -93
  81. package/dist/internal.js.map +1 -1
  82. package/dist/lib/bareTerm.d.ts +0 -39
  83. package/dist/lib/bareTerm.d.ts.map +1 -1
  84. package/dist/lib/bareTerm.js +0 -39
  85. package/dist/lib/bareTerm.js.map +1 -1
  86. package/dist/lib/portablePath.d.ts.map +1 -1
  87. package/dist/lib/portablePath.js +0 -14
  88. package/dist/lib/portablePath.js.map +1 -1
  89. package/dist/lib/scnCitation.d.ts +0 -32
  90. package/dist/lib/scnCitation.d.ts.map +1 -1
  91. package/dist/lib/scnCitation.js +2 -42
  92. package/dist/lib/scnCitation.js.map +1 -1
  93. package/dist/model.d.ts +0 -23
  94. package/dist/model.d.ts.map +1 -1
  95. package/dist/model.js +0 -23
  96. package/dist/model.js.map +1 -1
  97. package/dist/parse/checkScriptsRunInCI.d.ts +3 -151
  98. package/dist/parse/checkScriptsRunInCI.d.ts.map +1 -1
  99. package/dist/parse/checkScriptsRunInCI.js +5 -143
  100. package/dist/parse/checkScriptsRunInCI.js.map +1 -1
  101. package/dist/parse/ciStepRecord.d.ts +2 -117
  102. package/dist/parse/ciStepRecord.d.ts.map +1 -1
  103. package/dist/parse/ciStepRecord.js +12 -218
  104. package/dist/parse/ciStepRecord.js.map +1 -1
  105. package/dist/parse/commandRuns.d.ts +0 -39
  106. package/dist/parse/commandRuns.d.ts.map +1 -1
  107. package/dist/parse/commandRuns.js +0 -58
  108. package/dist/parse/commandRuns.js.map +1 -1
  109. package/dist/parse/cucumber.d.ts +0 -52
  110. package/dist/parse/cucumber.d.ts.map +1 -1
  111. package/dist/parse/cucumber.js +37 -143
  112. package/dist/parse/cucumber.js.map +1 -1
  113. package/dist/parse/discoveryScope.d.ts +0 -45
  114. package/dist/parse/discoveryScope.d.ts.map +1 -1
  115. package/dist/parse/discoveryScope.js +0 -55
  116. package/dist/parse/discoveryScope.js.map +1 -1
  117. package/dist/parse/fitnessCitations.d.ts +1 -72
  118. package/dist/parse/fitnessCitations.d.ts.map +1 -1
  119. package/dist/parse/fitnessCitations.js +3 -55
  120. package/dist/parse/fitnessCitations.js.map +1 -1
  121. package/dist/parse/reconcilerSteps.d.ts +0 -46
  122. package/dist/parse/reconcilerSteps.d.ts.map +1 -1
  123. package/dist/parse/reconcilerSteps.js +0 -63
  124. package/dist/parse/reconcilerSteps.js.map +1 -1
  125. package/dist/parse/runningStaticChecks.d.ts +2 -118
  126. package/dist/parse/runningStaticChecks.d.ts.map +1 -1
  127. package/dist/parse/runningStaticChecks.js +14 -273
  128. package/dist/parse/runningStaticChecks.js.map +1 -1
  129. package/dist/parse/scenarioCodeErrors.d.ts +12 -0
  130. package/dist/parse/scenarioCodeErrors.d.ts.map +1 -0
  131. package/dist/parse/scenarioCodeErrors.js +88 -0
  132. package/dist/parse/scenarioCodeErrors.js.map +1 -0
  133. package/dist/parse/scenarios.d.ts +3 -228
  134. package/dist/parse/scenarios.d.ts.map +1 -1
  135. package/dist/parse/scenarios.js +11 -447
  136. package/dist/parse/scenarios.js.map +1 -1
  137. package/dist/parse/stepAccounting.d.ts +0 -46
  138. package/dist/parse/stepAccounting.d.ts.map +1 -1
  139. package/dist/parse/stepAccounting.js +0 -54
  140. package/dist/parse/stepAccounting.js.map +1 -1
  141. package/dist/parse/stepExclusions.d.ts +0 -47
  142. package/dist/parse/stepExclusions.d.ts.map +1 -1
  143. package/dist/parse/stepExclusions.js +0 -45
  144. package/dist/parse/stepExclusions.js.map +1 -1
  145. package/dist/parse/stepNames.d.ts +0 -27
  146. package/dist/parse/stepNames.d.ts.map +1 -1
  147. package/dist/parse/stepNames.js +0 -27
  148. package/dist/parse/stepNames.js.map +1 -1
  149. package/dist/parse/targetCorpus.d.ts +1 -78
  150. package/dist/parse/targetCorpus.d.ts.map +1 -1
  151. package/dist/parse/targetCorpus.js +4 -46
  152. package/dist/parse/targetCorpus.js.map +1 -1
  153. package/dist/parse/targetManifest.d.ts +8 -146
  154. package/dist/parse/targetManifest.d.ts.map +1 -1
  155. package/dist/parse/targetManifest.js +47 -198
  156. package/dist/parse/targetManifest.js.map +1 -1
  157. package/dist/parse/vitest.d.ts +0 -60
  158. package/dist/parse/vitest.d.ts.map +1 -1
  159. package/dist/parse/vitest.js +1 -81
  160. package/dist/parse/vitest.js.map +1 -1
  161. package/dist/provenance/provenance.d.ts +2 -110
  162. package/dist/provenance/provenance.d.ts.map +1 -1
  163. package/dist/provenance/provenance.js +2 -58
  164. package/dist/provenance/provenance.js.map +1 -1
  165. package/dist/render/behaviouralRunners.d.ts +0 -29
  166. package/dist/render/behaviouralRunners.d.ts.map +1 -1
  167. package/dist/render/behaviouralRunners.js +0 -64
  168. package/dist/render/behaviouralRunners.js.map +1 -1
  169. package/dist/render/configurationNotRead.d.ts +3 -0
  170. package/dist/render/configurationNotRead.d.ts.map +1 -0
  171. package/dist/render/configurationNotRead.js +17 -0
  172. package/dist/render/configurationNotRead.js.map +1 -0
  173. package/dist/render/discoveryScope.d.ts +0 -37
  174. package/dist/render/discoveryScope.d.ts.map +1 -1
  175. package/dist/render/discoveryScope.js +0 -37
  176. package/dist/render/discoveryScope.js.map +1 -1
  177. package/dist/render/evidenceGrid.d.ts +1 -35
  178. package/dist/render/evidenceGrid.d.ts.map +1 -1
  179. package/dist/render/evidenceGrid.js +18 -100
  180. package/dist/render/evidenceGrid.js.map +1 -1
  181. package/dist/render/excludedSteps.d.ts +0 -26
  182. package/dist/render/excludedSteps.d.ts.map +1 -1
  183. package/dist/render/excludedSteps.js +0 -29
  184. package/dist/render/excludedSteps.js.map +1 -1
  185. package/dist/render/json.d.ts +0 -11
  186. package/dist/render/json.d.ts.map +1 -1
  187. package/dist/render/json.js +0 -11
  188. package/dist/render/json.js.map +1 -1
  189. package/dist/render/markdown.d.ts +0 -54
  190. package/dist/render/markdown.d.ts.map +1 -1
  191. package/dist/render/markdown.js +88 -426
  192. package/dist/render/markdown.js.map +1 -1
  193. package/dist/render/provenanceSection.d.ts +0 -22
  194. package/dist/render/provenanceSection.d.ts.map +1 -1
  195. package/dist/render/provenanceSection.js +0 -44
  196. package/dist/render/provenanceSection.js.map +1 -1
  197. package/dist/render/reconcilerSteps.d.ts +0 -25
  198. package/dist/render/reconcilerSteps.d.ts.map +1 -1
  199. package/dist/render/reconcilerSteps.js +0 -26
  200. package/dist/render/reconcilerSteps.js.map +1 -1
  201. package/dist/render/runVerdict.d.ts +0 -38
  202. package/dist/render/runVerdict.d.ts.map +1 -1
  203. package/dist/render/runVerdict.js +68 -127
  204. package/dist/render/runVerdict.js.map +1 -1
  205. package/dist/render/scenarioCodeErrorsSection.d.ts +3 -0
  206. package/dist/render/scenarioCodeErrorsSection.d.ts.map +1 -0
  207. package/dist/render/scenarioCodeErrorsSection.js +42 -0
  208. package/dist/render/scenarioCodeErrorsSection.js.map +1 -0
  209. package/dist/render/staticChecks.d.ts +0 -20
  210. package/dist/render/staticChecks.d.ts.map +1 -1
  211. package/dist/render/staticChecks.js +1 -59
  212. package/dist/render/staticChecks.js.map +1 -1
  213. package/dist/render/stepAccounting.d.ts +0 -36
  214. package/dist/render/stepAccounting.d.ts.map +1 -1
  215. package/dist/render/stepAccounting.js +0 -44
  216. package/dist/render/stepAccounting.js.map +1 -1
  217. package/dist/render/testVolume.d.ts +0 -25
  218. package/dist/render/testVolume.d.ts.map +1 -1
  219. package/dist/render/testVolume.js +0 -32
  220. package/dist/render/testVolume.js.map +1 -1
  221. package/package.json +4 -1
  222. package/dist/domain/checkCharacteristics.d.ts +0 -88
  223. package/dist/domain/checkCharacteristics.d.ts.map +0 -1
  224. package/dist/domain/checkCharacteristics.js +0 -109
  225. package/dist/domain/checkCharacteristics.js.map +0 -1
  226. package/dist/domain/fitnessChecks.d.ts +0 -79
  227. package/dist/domain/fitnessChecks.d.ts.map +0 -1
  228. package/dist/domain/fitnessChecks.js +0 -81
  229. package/dist/domain/fitnessChecks.js.map +0 -1
  230. package/dist/lib/featureCode.d.ts +0 -21
  231. package/dist/lib/featureCode.d.ts.map +0 -1
  232. package/dist/lib/featureCode.js +0 -24
  233. package/dist/lib/featureCode.js.map +0 -1
  234. package/dist/parse/corpusCodeFaults.d.ts +0 -76
  235. package/dist/parse/corpusCodeFaults.d.ts.map +0 -1
  236. package/dist/parse/corpusCodeFaults.js +0 -121
  237. package/dist/parse/corpusCodeFaults.js.map +0 -1
  238. package/dist/parse/corpusFaults.d.ts +0 -124
  239. package/dist/parse/corpusFaults.d.ts.map +0 -1
  240. package/dist/parse/corpusFaults.js +0 -72
  241. package/dist/parse/corpusFaults.js.map +0 -1
  242. package/dist/parse/corpusGrammarFaults.d.ts +0 -71
  243. package/dist/parse/corpusGrammarFaults.d.ts.map +0 -1
  244. package/dist/parse/corpusGrammarFaults.js +0 -292
  245. package/dist/parse/corpusGrammarFaults.js.map +0 -1
@@ -1,212 +1,41 @@
1
- /**
2
- * THE LEDGER — the accounts with their posted entries, co-located with its OWN whole-run
3
- * behaviour: `isBalanced`, `hasPendingItems`, `hasBrokenEvidence` (module, not class). These
4
- * three pure predicates are the whole-run verdict surface the CLI edge maps to exit codes;
5
- * they were the reconcile orchestration's exports and now live WITH the concept they fold over.
6
- */
7
- // The row-level static-check cut (3F-2203) — the Ledger-wide lint list is built ON it, so the
8
- // obligation-side rule is stated once, at the row.
9
1
  import { staticCheckReconciliationsOf, isScenario } from "./scenarioReconciliation.js";
10
- /**
11
- * The WHOLE-RUN verdict — is the ENTIRE reconciliation balanced? A pure domain
12
- * derivation over the WHOLE `Ledger`: balanced IFF NO reconciling
13
- * item exists ANYWHERE, across every Scenario Reconciliation row — scenario,
14
- * phantom, and suspense alike. Out-of-balance iff ANY row carries a reconciling
15
- * item: a scenario's out-of-balance items (failing / missing /
16
- * no-evidence-obligation / both-missing) AND the credit-side suspense/phantom rows (a
17
- * no-evidence-obligation static-check watermelon, an uncited credit, a phantom scenario).
18
- *
19
- * It is deliberately NOT a scan of scenario verdicts alone — that would
20
- * let a watermelon-only run (every scenario balanced, yet a no-evidence-obligation
21
- * static check sitting unreconciled in the suspense row) read as balanced, the
22
- * false pass a CI gate must never give. Every row's `reconcilingItems` is
23
- * consulted, so the suspense/phantom rows (verdict ALWAYS out-of-balance) count.
24
- *
25
- * The CLI edge maps this boolean to the process exit code — balanced → 0,
26
- * out-of-balance → EXACTLY 1 — an ENUMERATED status, never a count (a count would
27
- * 8-bit `& 0xFF` wrap → false pass).
28
- */
29
2
  export function isBalanced(reconciliation) {
30
3
  return reconciliation.scenarioReconciliations.every((row) => row.reconcilingItems.length === 0);
31
4
  }
32
- /**
33
- * Does the WHOLE reconciliation carry any Pending Item? A pure domain predicate over the
34
- * WHOLE `Ledger`, SYMMETRIC with `isBalanced` — together they are the
35
- * whole-run verdict surface. True iff ANY Scenario Reconciliation row carries a Pending
36
- * Item (a deferred `<quality-check>pending` obligation partitioned off before reconciliation,
37
- * @SCN-PND-004). Pending Items are run-neutral by default (@SCN-PND-008); the CLI edge
38
- * consults this ALONGSIDE `isBalanced` to escalate an otherwise-balanced run to the distinct
39
- * exit code 3 under `--strict` (@SCN-CLI-011) — an OPT-IN gate on deferred obligations,
40
- * checked only when `isBalanced` is true (out-of-balance dominates, exit 1).
41
- */
42
5
  export function hasPendingItems(reconciliation) {
43
6
  return reconciliation.scenarioReconciliations.some((row) => row.pendingItems.length > 0);
44
7
  }
45
- /**
46
- * Does the WHOLE reconciliation carry BROKEN evidence — i.e. is the run UNSOUND? The THIRD
47
- * whole-run predicate (@SCN-LDG-018), beside `isBalanced` and `hasPendingItems`, and the
48
- * EXISTENTIAL TWIN of the latter: the same `some(row => some(item => item.outcome === X))` scan.
49
- *
50
- * Soundness is a property of the RUN, not of a scenario. If any PROOF NEVER RAN — a vitest suite
51
- * that failed to collect (@SCN-LDG-017), or a cucumber step matched by two or more definitions
52
- * (@SCN-LDG-019) — the evidence never fully materialised, so every `missing` in that run is
53
- * SUSPECT: it may be a broken proof rather than an absent one, and the remedies differ (fix the
54
- * harness vs write a test). The scenario's own row stays honest at its own resolution (`missing`);
55
- * the RUN is what is stamped unsound.
56
- *
57
- * DERIVED, NEVER STORED — no soundness flag is written onto `Ledger`, the same
58
- * no-drift reason `isBalanced` and `hasPendingItems` derive. Machine consumers read soundness off
59
- * `summary.byOutcome.broken > 0` (type-forced into the JSON the moment `broken` joined the
60
- * `Outcome` union); the markdown renderer prints the HEADLINE word — "unsound" is the render word,
61
- * never the predicate's name, exactly as "out-of-balance" is for `isBalanced`.
62
- *
63
- * Keyed on the `broken` OUTCOME specifically, never on `!isBalanced`: an ordinary out-of-balance
64
- * run (an honest `missing`, no broken evidence) is perfectly SOUND. The three whole-run
65
- * predicates are INDEPENDENT — a run may carry Pending Items and be sound; a run may carry broken
66
- * evidence and no Pending Items. (A broken run is ALWAYS out-of-balance, since the `broken` item
67
- * sits on the suspense row — which is why the CLI edge must consult THIS predicate BEFORE the
68
- * balance verdict, @SCN-CLI-012, or its exit code would be unreachable.)
69
- */
70
8
  export function hasBrokenEvidence(reconciliation) {
71
9
  return brokenItemsOf(reconciliation).length > 0;
72
10
  }
73
- /**
74
- * Does the WHOLE run have NOTHING TO RECONCILE — no accounts at all? The FOURTH whole-run
75
- * predicate (@SCN-CLI-019), beside `isBalanced` / `hasPendingItems` / `hasBrokenEvidence`, and the
76
- * one shape the other three cannot speak about.
77
- *
78
- * THE FAULT IT EXISTS TO NAME. `isBalanced` is `.every()` over the rows, so on an EMPTY ledger it
79
- * is VACUOUSLY TRUE; `hasPendingItems` and `hasBrokenEvidence` are `.some()`, so they are
80
- * vacuously FALSE. A target that declared nothing and produced nothing therefore satisfied every
81
- * existing predicate in the direction that reads as a pass, and was told "BALANCED … (exit 0)" — a
82
- * green over silence, from the tool whose whole claim is that silence is not the same as nothing
83
- * wrong. No combination of the three separates an empty run from a clean one, which is why this is
84
- * a predicate and not a derivation of one.
85
- *
86
- * ITS OWN ENUMERATED STATE, exit 5 (taxonomy: 0 balanced / 1 out-of-balance / 2 usage / 3
87
- * pending-under-strict / 4 unsound / 5 nothing to reconcile). Not balanced — there are no accounts
88
- * to agree. Not out-of-balance — nothing disagrees. Not a usage fault — the invocation was valid
89
- * and `new-client` is a supported adoption state, not a degraded one. Not unsound — no proof
90
- * failed; none was owed.
91
- *
92
- * KEYED ON THE EMPTY LEDGER, NEVER ON THE EMPTY CORPUS, and that is load-bearing rather than
93
- * pedantic: a target with no corpus but uncited credits HAS a row — its suspense row — and is an
94
- * ordinary out-of-balance report at exit 1 (@SCN-CLI-020). Keyed on "no corpus" instead, the modal
95
- * first run's whole report would disappear behind exit 5.
96
- *
97
- * DERIVED, NEVER STORED — no emptiness flag is written onto `Ledger`, the same no-drift reason its
98
- * three siblings derive, and the reason no JSON-schema change is owed: a machine consumer reads
99
- * the row count off the ledger it already has. The markdown renderer prints the HEADLINE word —
100
- * "NOTHING TO RECONCILE" is the render word, never the predicate's name, exactly as "unsound" is
101
- * for `hasBrokenEvidence`.
102
- *
103
- * WHERE IT MUST BE ASKED, MEASURED RATHER THAN ARGUED (3F-3344). The ticket predicted this would
104
- * be @SCN-CLI-012's pre-emption one code further on — ask it after `isBalanced` and the branch
105
- * goes unreachable. IT IS NOT, and the plant that was supposed to prove it stayed GREEN. An empty
106
- * ledger is MUTUALLY EXCLUSIVE with all three siblings: with no rows there is no row to carry a
107
- * broken item, a reconciling item or a Pending Item, so it fires NONE of them and its position
108
- * AMONG them is unobservable. Moving it below `!isBalanced` in the CLI ladder still exits 5
109
- * (measured).
110
- *
111
- * WHAT IS LOAD-BEARING is its position against the chain's DEFAULT. "Balanced" is not a predicate
112
- * branch — it is the fall-through — so there is no "after the balanced case" to append a fifth
113
- * code to, and a chain that reaches its default has already called the run balanced. Appended
114
- * after the default the branch is dead code and the run exits 0 (measured: the plant that DID red).
115
- * That is also why the fault survived: a fifth code cannot be ADDED to this chain, it has to
116
- * DISPLACE the default, and nothing about the other three predicates says so.
117
- */
118
11
  export function hasNothingToReconcile(reconciliation) {
119
12
  return reconciliation.scenarioReconciliations.length === 0;
120
13
  }
121
- /**
122
- * The BROKEN reconciling items across the WHOLE run (3F-2203) — every proof that never ran, in row
123
- * order, each carrying its WHERE-to-fix (locator) and WHAT-broke (the runner's message).
124
- *
125
- * The QUANTITATIVE twin of `hasBrokenEvidence`, which is now derived FROM it: "is this run
126
- * unsound?" and "which proofs never ran?" are one question at two resolutions, so they are one
127
- * scan. The markdown's Run-integrity section listed these by re-deriving the scan itself — a model
128
- * query living in the renderer, and a second statement of which outcome means broken.
129
- *
130
- * The renderer READS this list and takes its length for the count-phrase; asking a list you were
131
- * given how long it is is projection, not derivation.
132
- */
133
14
  export function brokenItemsOf(reconciliation) {
134
15
  return reconciliation.scenarioReconciliations.flatMap((row) => row.reconcilingItems.filter((item) => item.outcome === "broken"));
135
16
  }
136
- /**
137
- * The OBLIGATION-SIDE static-check sub-rows across the whole Ledger (3F-2203) — each `lint` Quality
138
- * Check Reconciliation with the scnId of the row that names it, in row-then-document order.
139
- *
140
- * SCENARIO ROWS ONLY. A `lint` obligation is obligation-side, so a phantom or suspense row can carry
141
- * none; the suspense row's lint CREDIT (a no-evidence-obligation static check, `cites-no-scenario`) is an
142
- * observation, not an obligation, and must never inflate the obligation-side lint total.
143
- *
144
- * ONE COPY, BY CONSTRUCTION. That scenario-rows-only filter plus the lint cut existed TWICE,
145
- * character-identical — here in `lintTally` and in the markdown's `### Lint evidence obligations`
146
- * table. They agreed by copy-paste, not construction: either could have grown a clause alone and
147
- * nothing would have redded. Same anaemia, same cure as `evidenceObligationPairsOf` and
148
- * the corpus's own fitness obligations; the tally and the table are now two readings of ONE list.
149
- */
150
- export function lintReconciliationsOf(reconciliation) {
17
+ export function fitnessReconciliationsOf(reconciliation) {
151
18
  return reconciliation.scenarioReconciliations
152
19
  .filter(isScenario)
153
20
  .flatMap((row) => staticCheckReconciliationsOf(row).map((r) => ({ scnId: row.scnId, reconciliation: r })));
154
21
  }
155
- /** The canonical quality-check subject order (lint first, then the runtime quality-checks). */
156
- const QUALITY_CHECK_ORDER = ["lint", "unit", "integration", "e2e", "performance"];
157
- /**
158
- * Tally the LEDGER-PURE summary totals from the balance — the aggregate the markdown's
159
- * trial-balance table derives, carried AS DATA so a later render-from-saved-JSON rebuilds it with
160
- * zero computation (the MATERIALISE ruling). The census pass-throughs (`testVolume`,
161
- * `staticChecks`) are not Ledger-pure and are merged in by the assembler.
162
- */
22
+ const QUALITY_CHECK_ORDER = ["fitness", "unit", "integration", "e2e", "performance"];
163
23
  export function ledgerTally(balance) {
164
24
  const { scenarioReconciliations, pending } = scenarioReconciliationTally(balance);
165
25
  return {
166
26
  scenarioReconciliations,
167
27
  evidenceObligations: evidenceObligationTotals(balance),
168
- // The Pending Items tally (@SCN-PND-011) — its OWN summary count, SEPARATE from the
169
- // scenario verdict counts and the evidence-obligation counts. A Pending Item is deferred,
170
- // not out-of-balance, so it is never one of the `OUT_OF_BALANCE_OUTCOMES` (never a `byOutcome`
171
- // leaf of its own, at any leaf count). Always present (a pure balance derive, like `lint`);
172
- // reads 0 when no scenario raises a pending obligation.
173
28
  pending,
174
- // The static-only lint tally (RMD-005) — replicates markdown's `countStaticEvidenceObligations`
175
- // (static evidenceObligations balanced / total). Always present (a pure balance derive); `byOutcome`
176
- // is kind-agnostic and cannot evidenceObservations this static-only cut.
177
- lint: lintTally(balance),
29
+ fitness: fitnessTally(balance),
178
30
  };
179
31
  }
180
- /**
181
- * The row-level half of `ledgerTally` — the Scenario Reconciliation verdict totals and the
182
- * Pending Items count, both read off one pass over the rows.
183
- */
184
32
  function scenarioReconciliationTally(balance) {
185
- // The headline verdict tally counts EVERY Scenario Reconciliation (@SCN-RMD-001, 3F-1724):
186
- // the summary is the totals over ALL rows (double-entry-manifesto), and phantom / suspense
187
- // reconciliations are ALWAYS out-of-balance, so they count into the tally like any other row.
188
- // `phantom` / `suspense` are kept as SUB-COUNTS — a breakdown OF the total, not a bucket
189
- // outside it. (The retracted "ruling Q3" tallied scenario rows only, which is what let the
190
- // tally read 0 out-of-balance on a run `isBalanced` correctly failed → exit 1: 3F-1703.)
191
33
  const verdict = { balanced: 0, "out-of-balance": 0 };
192
34
  let phantom = 0;
193
35
  let suspense = 0;
194
- // The Pending Items tally (@SCN-PND-011) — the count of Pending Items across the
195
- // reconciliation, one per deferred `<quality-check>pending` obligation. Counts ITEMS, not
196
- // scenarios-carrying-pending (a scenario may raise several), mirroring the out-of-balance
197
- // decomposition, which counts obligations, not scenarios. A Pending Item is a structurally
198
- // distinct category (never a reconciling item / evidence obligation), so it is tallied
199
- // SEPARATELY here — never folded into `byOutcome` (the out-of-balance leaves).
200
36
  let pending = 0;
201
37
  for (const s of balance.scenarioReconciliations) {
202
- // Pending Items ride every row's `pendingItems` (only scenario rows carry them; a
203
- // phantom / suspense row has none — as an EMPTY array, never an absent one), so the tally is
204
- // a plain sum across all rows. `pendingItems` is required on `ScenarioReconciliation`, so
205
- // there is no absent case to fall back from; `hasPendingItems` above already reads it bare.
206
38
  pending += s.pendingItems.length;
207
- // The kind sub-counts, tallied ALONGSIDE the verdict (never instead of it) — the row still
208
- // falls through to the verdict tally below, so a phantom / suspense reconciliation counts
209
- // into `total` and (being always out-of-balance) into `outOfBalance`.
210
39
  if (s.kind === "phantom-scenario")
211
40
  phantom++;
212
41
  if (s.kind === "suspense-scenario")
@@ -215,25 +44,16 @@ function scenarioReconciliationTally(balance) {
215
44
  }
216
45
  return {
217
46
  scenarioReconciliations: {
218
- // Every row's verdict is tallied, so this IS the count of all Scenario Reconciliations
219
- // (scenario + phantom + suspense) — the manifesto's "the summary is the totals".
220
47
  total: verdict.balanced + verdict["out-of-balance"],
221
48
  balanced: verdict.balanced,
222
49
  outOfBalance: verdict["out-of-balance"],
223
- // Sub-counts: a breakdown OF the totals above (scenario = total − phantom − suspense).
224
50
  phantom,
225
51
  suspense,
226
52
  },
227
53
  pending,
228
54
  };
229
55
  }
230
- /**
231
- * The obligation-level half of `ledgerTally` — every Quality Check Reconciliation tallied by
232
- * outcome, with the `missing` ones split by quality-check.
233
- */
234
56
  function evidenceObligationTotals(balance) {
235
- // byOutcome tallies EVERY Quality Check Reconciliation across ALL rows (scenario AND
236
- // phantom), so `cites-unknown-scenario` reflects the real phantom count.
237
57
  const byOutcome = {
238
58
  satisfied: 0,
239
59
  "missing": 0,
@@ -241,28 +61,16 @@ function evidenceObligationTotals(balance) {
241
61
  "watermelon": 0,
242
62
  "cites-unknown-scenario": 0,
243
63
  "cites-no-scenario": 0,
244
- // The debit twin of cites-no-scenario (@SCN-LDG-021) — a scenario with no @SCN code to link.
245
64
  "no-scn-code": 0,
246
- // The broken reconciling item — a proof that NEVER RAN: a vitest suite that failed to collect
247
- // (@SCN-LDG-017), or a cucumber step matched by two or more definitions (@SCN-LDG-019). A
248
- // machine consumer reads run-soundness off this count: `byOutcome.broken > 0` ⇒ any `missing`
249
- // in the run may be a BROKEN proof rather than an absent one.
65
+ "duplicate-scn-code": 0,
250
66
  "broken": 0,
251
- // The no-evidence-obligation reconciling item (@SCN-LDG-008) — a credit citing a real
252
- // scenario at a quality-check it never named. Shown here so a reader sees it break out of
253
- // the reconciliation-matched-attributed count (ruling Q1).
254
67
  "no-evidence-obligation": 0,
255
- // The both-missing reconciling item (@SCN-LDG-009) — the NEITHER-side outcome:
256
- // a scenario reconciling to zero rows on both sides. `byOutcome` is now 8-valued.
257
68
  "both-missing": 0,
258
69
  };
259
70
  const missing = new Map();
260
71
  for (const s of balance.scenarioReconciliations) {
261
72
  for (const o of s.qualityCheckReconciliations) {
262
73
  byOutcome[o.outcome]++;
263
- // The subject IS the flat quality-check — `lint` or a runtime quality-check. The
264
- // both-missing item carries no quality-check (it is not a `missing` evidence obligation), so the
265
- // guard both narrows the type and keeps it out of the missing split.
266
74
  if (o.outcome === "missing" && o.qualityCheck) {
267
75
  missing.set(o.qualityCheck, (missing.get(o.qualityCheck) ?? 0) + 1);
268
76
  }
@@ -276,60 +84,14 @@ function evidenceObligationTotals(balance) {
276
84
  missingByQualityCheck: QUALITY_CHECK_ORDER.filter((s) => (missing.get(s) ?? 0) > 0).map((subject) => ({ subject, count: missing.get(subject) })),
277
85
  };
278
86
  }
279
- /**
280
- * The static-only lint tally (RMD-005) — how many `@lint` (static) evidence obligations reconcile
281
- * satisfied (`balanced`), out of the total raised. Byte-for-byte the markdown's
282
- * `countStaticEvidenceObligations` (`src/render/markdown.ts`), so slice 2 can read `satisfied` / `total`
283
- * with zero byte change. `summary.byOutcome` counts ALL kinds, so the static-only total is derived
284
- * here explicitly.
285
- */
286
- export function lintTally(balance) {
287
- // TWO READINGS OF ONE LIST (3F-2203) — the obligation-side lint sub-rows come from
288
- // `lintReconciliationsOf`, the same list the markdown's lint table renders. The
289
- // scenario-rows-only cut lives there, once, so the tally and the table cannot disagree.
290
- const lint = lintReconciliationsOf(balance);
87
+ export function fitnessTally(balance) {
88
+ const fitness = fitnessReconciliationsOf(balance);
291
89
  return {
292
- satisfied: lint.filter(({ reconciliation }) => reconciliation.outcome === "satisfied").length,
293
- total: lint.length,
90
+ satisfied: fitness.filter(({ reconciliation }) => reconciliation.outcome === "satisfied").length,
91
+ total: fitness.length,
294
92
  };
295
93
  }
296
- // ---------------------------------------------------------------------------
297
- // THE RUNTIME-OBSERVATION TALLY (3F-2102, Read @SCN-RMD-003) — the credit-side
298
- // headline the report's `### Test volume` cut derives, a FOLD OVER THE LEDGER co-located here
299
- // beside `ledgerTally` for the same reason: "the summary is the totals" — the Ledger counts its
300
- // OWN posted credits because it IS the balance. This RETIRES the runtime evidence-observation
301
- // census (`census/evidenceObservations.ts`): "census" and "collection of evidence observations"
302
- // are not manifesto concepts, so the counting folds onto the Ledger rather than living in a
303
- // parallel store. Only the AGGREGATE headlines survive (the raw per-quality-check totals and the
304
- // per-scenario-kind counts) — the per-`(scnId, quality-check)` `attributed[]` list did not, being
305
- // a re-representation of the Ledger's own posted credits (retire, don't relocate).
306
- // ---------------------------------------------------------------------------
307
- /** The canonical runtime quality-check order, in reading order. */
308
94
  export const RUNTIME_QUALITY_CHECKS = ["unit", "integration", "e2e", "performance"];
309
- /**
310
- * Tally the runtime evidence observations from the Ledger — a FOLD OVER THE POSTED CREDITS
311
- * (@SCN-RMD-003), the credit-side twin of `ledgerTally`'s debit-side fold. It walks the POSTED
312
- * CREDITS on each Scenario Reconciliation row (@SCN-LDG-022) and reads each credit's account off
313
- * THE ROW IT POSTED TO — a scenario row ⇒ `onScenario`, a phantom row ⇒ `onPhantomScenario`,
314
- * the suspense row ⇒ `onSuspenseScenario` — summing the raw per-quality-check total in lockstep.
315
- *
316
- * It RE-DERIVES NOTHING and it does NOT classify: the reconciler already decided which account
317
- * every credit posts to (the account IS the citation, @SCN-LDG-022), so asking the row is asking
318
- * that decision. There is ONE place that decides what a credit is, so this tally can never disagree
319
- * with the verdict — the views (Test volume, the per-quality-check table) are projections of the
320
- * same rows, not a parallel opinion kept in step.
321
- *
322
- * Static check (`lint`) credits are SKIPPED, ON THE CHECK and never on the absence of a citation
323
- * (@SCN-RPT-023). A fitness credit now CITES its own scenario and posts to an ordinary
324
- * scenario row, so to a naive walk it is indistinguishable from a runtime credit by the account it
325
- * landed on; the `qualityCheck` is the only thing that tells them apart. Counting one would fold
326
- * the static axis into the Test volume, which must not see it at all.
327
- *
328
- * The per-scenario-kind counts feed `summary.testVolume` directly (`onScenario` counts credits
329
- * citing a scenario, INCLUDING no-evidence-obligation — so the 3-termed identity
330
- * `total = onScenario + onPhantomScenario + onSuspenseScenario` holds); `rawByRuntimeQualityCheck`
331
- * is the re-homed per-quality-check headline the by-level table renders.
332
- */
333
95
  export function runtimeObservationTally(ledger) {
334
96
  const rawByRuntimeQualityCheck = {
335
97
  unit: 0,
@@ -340,13 +102,9 @@ export function runtimeObservationTally(ledger) {
340
102
  let onScenario = 0;
341
103
  let onPhantomScenario = 0;
342
104
  let onSuspenseScenario = 0;
343
- // THE FOLD (@SCN-RMD-003). Walk the POSTED CREDITS and read each credit's ACCOUNT off the row it
344
- // posted to — the reconciler's own ruling, never re-classified here.
345
105
  for (const row of ledger.scenarioReconciliations) {
346
106
  for (const obs of row.evidenceObservations) {
347
- // THE RUNTIME SCOPING — a static check credit rides the `lint` quality-check and is not a
348
- // runtime observation, so it is not counted (see the docstring).
349
- if (obs.qualityCheck === "lint")
107
+ if (obs.qualityCheck === "fitness")
350
108
  continue;
351
109
  rawByRuntimeQualityCheck[obs.qualityCheck]++;
352
110
  if (row.kind === "phantom-scenario")
@@ -357,83 +115,19 @@ export function runtimeObservationTally(ledger) {
357
115
  onScenario++;
358
116
  }
359
117
  }
360
- // THE COMPLETENESS IDENTITY — `Σ raw = onScenario + onPhantomScenario + onSuspenseScenario` —
361
- // holds BY CONSTRUCTION: the single walk above increments a per-quality-check counter and exactly
362
- // one per-scenario-kind counter in the SAME iteration, so the two sides cannot diverge. It is
363
- // COMPLETENESS ONLY: invariant under a misfile BETWEEN its own terms, so it catches a credit
364
- // VANISHING, never a credit in the wrong account (the `@SCN`s and the rows are that).
365
- //
366
- // THE RUNTIME `throw` THAT STOOD HERE IS GONE (3F-2231). It could not fire — both sides move
367
- // together in one loop — so it was dead code asserting an invariant the structure already
368
- // guarantees, which is precisely the scar-tissue shape `why-ddd-for-spec-controller.md` names as
369
- // the anemic tell ("kept honest by hand-written identity assertions"); the goal is that summing
370
- // the wrong rows "stops being POSSIBLE, not merely asserted-against". The invariant is not
371
- // unguarded by its removal: `runtimeObservationTally.test.ts` pins it over a spanning corpus,
372
- // which is where an invariant belongs. If this fold is ever split into two walks the identity
373
- // becomes a real risk again — and that test, not a throw in a pure function, is what will red.
374
118
  const total = RUNTIME_QUALITY_CHECKS.reduce((n, qc) => n + rawByRuntimeQualityCheck[qc], 0);
375
119
  return { rawByRuntimeQualityCheck, total, onScenario, onPhantomScenario, onSuspenseScenario };
376
120
  }
377
- /**
378
- * Tally the static-check observations from the Ledger — a FOLD OVER THE POSTED static-check CREDITS
379
- * (3F-2118), the static-axis twin of `runtimeObservationTally`. It walks the POSTED CREDITS on each
380
- * Scenario Reconciliation row (@SCN-LDG-022), reads each credit off THE ROW IT POSTED TO, and — like
381
- * its runtime sibling — RE-DERIVES NOTHING: the reconciler already decided which account every credit
382
- * posts to, so this can never disagree with the verdict.
383
- *
384
- * `uncitedStaticCheckCount` is the count of RUNNING lint credits on the SUSPENSE row — the
385
- * no-evidence-obligation static checks the reconciler folded there (a static check running with no
386
- * scenario citing it, `cites-no-scenario` on the credit side). THE RUNNING QUALIFIER IS ENFORCED
387
- * HERE AND IS NO LONGER FREE (@SCN-LNT-033). It used to be a plain count, and the sentence in this
388
- * place said that by construction the app pushes only RUNNING checks into that stream
389
- * (`runningStaticChecks`), so every suspense lint credit was running. `@SCN-LNT-032` falsified
390
- * that: the same stream now carries a check whose red its job swallows, which is pushed into it and
391
- * is not running. So the filter below applies to BOTH counts, and the invariant the old sentence
392
- * asserted is the one this fold now MAKES TRUE. A BROKEN credit reaches the same row by a different
393
- * route (@SCN-LNT-026) and is excluded: it is a check a scenario DID name, which did not run.
394
- *
395
- * `runningStaticCheckCount` is the count of RUNNING lint credits across ALL rows. One care-move the
396
- * runtime axis does not need (see the block comment above):
397
- * - FILTER TO RUNNING (`exists && enforcedOverRealSource`): a watermelon (exists, unwired), a
398
- * severed (wired, and the job's verdict does not depend on it) or a missing (absent) check
399
- * STILL posts (posting is not classifying), but it does not RUN over the real source as a gate,
400
- * so it is not a running static check — excluded here exactly as the retired census's
401
- * running-only `continue` excluded it.
402
- *
403
- * The named (implicit) count is `runningStaticCheckCount − uncitedStaticCheckCount`, and it cannot
404
- * go below nil: the uncited count is drawn from inside the running one.
405
- */
406
121
  export function staticObservationTally(ledger) {
407
- // The RUNNING static-check credits across ALL rows. Only running checks
408
- // (`exists && enforcedOverRealSource`) are counted — a watermelon/missing check, which posts but
409
- // does not run, is filtered out (the census's running-only `continue`).
410
122
  let runningStaticCheckCount = 0;
411
- // The uncited static checks — the RUNNING lint credits the reconciler folded onto the SUSPENSE
412
- // row (a no-evidence-obligation running check, `cites-no-scenario`). Not a plain count of that
413
- // row's lint credits: the no-evidence-obligation stream also carries a check the job's verdict
414
- // does not depend on, which is pushed into it and is not running (@SCN-LNT-033).
415
123
  let uncitedStaticCheckCount = 0;
416
124
  for (const row of ledger.scenarioReconciliations) {
417
125
  for (const obs of row.evidenceObservations) {
418
- // THE STATIC SCOPING — only static-check credits ride the `lint` quality-check; a runtime
419
- // credit (the uncited/broken ones the suspense row also holds) is not a static observation.
420
- if (obs.qualityCheck !== "lint")
126
+ if (obs.qualityCheck !== "fitness")
421
127
  continue;
422
- // A BROKEN CREDIT IS NEITHER COUNT (@SCN-LNT-026). It reaches the suspense row for a reason
423
- // the uncited count does not name: the check DID have a scenario naming it, and it did not
424
- // run. Counting it as uncited would report a check nobody named, sending the reader to write
425
- // an obligation that is already written — the misdirection the `broken` outcome exists to
426
- // avoid. It is not a running static check either, and `exists` reads false so the clause
427
- // below already says so; this one is what keeps the sentence true rather than incidental.
428
128
  if (obs.broken === true)
429
129
  continue;
430
- // ONE MEMBERSHIP RULE, NESTED RATHER THAN REPEATED (@SCN-LNT-033). The uncited count is the
431
- // running count's suspense-row SUBSET, so the two cannot be given different rules by a later
432
- // edit to one of them, and the figure a reader takes from the pair — `running − uncited`,
433
- // the named count neither of them prints — cannot go below nil. Two sibling `if`s reading
434
- // the same credit under different conditions is exactly the arrangement that let a severed
435
- // uncited check leave one count and stay in the other.
436
- if (!obs.exists || !obs.enforcedOverRealSource)
130
+ if (!obs.exists)
437
131
  continue;
438
132
  runningStaticCheckCount++;
439
133
  if (row.kind === "suspense-scenario")
@@ -1 +1 @@
1
- {"version":3,"file":"ledger.js","sourceRoot":"","sources":["../../src/domain/ledger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ledger.js","sourceRoot":"","sources":["../../src/domain/ledger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export type Outcome = "satisfied" | "failing" | "watermelon" | "missing" | "cites-unknown-scenario" | "cites-no-scenario" | "broken" | "no-evidence-obligation" | "no-scn-code" | "duplicate-scn-code" | "both-missing";
2
+ export type SidePresence = "Exists" | "None";
3
+ //# sourceMappingURL=outcome.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outcome.d.ts","sourceRoot":"","sources":["../../src/domain/outcome.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,GACf,WAAW,GACX,SAAS,GACT,YAAY,GACZ,SAAS,GACT,wBAAwB,GACxB,mBAAmB,GACnB,QAAQ,GACR,wBAAwB,GACxB,aAAa,GACb,oBAAoB,GACpB,cAAc,CAAC;AACnB,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,MAAM,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=outcome.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outcome.js","sourceRoot":"","sources":["../../src/domain/outcome.ts"],"names":[],"mappings":""}
@@ -1,70 +1,14 @@
1
- /**
2
- * POSTING — the rule for WHERE an entry lands. Canon gives Posting its own glossary group
3
- * (`strategy/double-entry-manifesto.md`, "### Posting") beside Journal, Ledger and Reconciling,
4
- * and this module is that group's home (module, not class), co-locating the destination type with
5
- * the pure rule that decides it.
6
- *
7
- * It sits BETWEEN the journal and the Ledger, which is why it is neither's: `domain/ledger` folds
8
- * over an ASSEMBLED Ledger, and the posting rule runs BEFORE a Ledger exists; `domain/journal`
9
- * owns the entry types and what a scenario NAMES. Posting reads both sides and yields the row an
10
- * entry lands on. (3F-2202 — extracted from the `reconcile` fold, which decided this inline.)
11
- *
12
- * ONE CLAUSE, OVER BOTH AXES (3F-2590). THE CREDIT CITES. A test carries `@SCN-XXX`; a fitness
13
- * check's run carries the `@SCN` of the fitness scenario that raises its obligation. So
14
- * one credit names one scenario and posts to EXACTLY ONE row, and a credit posting to no real
15
- * scenario is PHANTOM (its `@SCN` matches no scenario) or SUSPENSE (it cites nothing).
16
- *
17
- * THE BY-NAME ROUTE IS GONE, and with it the exception it forced. `lint` used to be the axis where
18
- * the DEBIT cited: a scenario carried `@lint=<static-check>`, the run cited nothing, and it was
19
- * matched BY NAME to EVERY row whose obligation named it. That is why the invariant had to be
20
- * written "every evidence observation posts to AT LEAST ONE account, never to none" — not *exactly*
21
- * one, which was the runtime property over-generalised. With both axes citing, EXACTLY ONE is true
22
- * universally, and it is the stronger claim: "at least one" is silent about a double-post, and a
23
- * double-post is a second copy of the same fact. `Posting` is total over the `EvidenceObservation`
24
- * union by construction: every variant yields a destination.
25
- *
26
- * POSTING IS NOT CLASSIFYING. This rule decides WHERE an entry lands, never what it reconciles TO.
27
- * A credit posts to its row whatever outcome it later earns — or none at all. The outcome rules
28
- * are the sibling concepts' (`qualityCheckReconciliation`, `scenarioReconciliation`).
29
- */
30
- import type { EvidenceObservation, RuntimeEvidenceObservation, GuardEvidenceObservation } from "./journal.js";
31
- /**
32
- * WHERE an entry lands — the posting destination, one variant per route canon names.
33
- *
34
- * EVERY `kind` NAMES A ROW, and matches `ScenarioKind` exactly, because each IS the row kind the
35
- * entry posts to. A fourth member used to sit here — a SET of rows resolved by name — and it was
36
- * the one destination that was not a row at all. It went with the by-name route (3F-2590), so the
37
- * type is now exactly the row kinds, on both axes.
38
- *
39
- * Named for the ROW, never `Account`: `account` is RETIRED vocabulary (the container re-term —
40
- * Evidence / Scenario / Quality-Check Reconciliation replaced trial-balance / account /
41
- * sub-account), kept only as the bookkeeping ROOT of the metaphor in canon's glossary.
42
- */
43
- export type Posting =
44
- /** BY CITATION → the row of the one real scenario this credit's `@SCN` names. */
45
- {
1
+ import type { EvidenceObservation, RuntimeEvidenceObservation, FitnessEvidenceObservation } from "./journal.js";
2
+ export type Posting = {
46
3
  kind: "scenario";
47
4
  scnId: string;
48
- }
49
- /** BY CITATION → an INVENTED row: the credit's `@SCN` is one no scenario carries. */
50
- | {
5
+ } | {
51
6
  kind: "phantom-scenario";
52
7
  scnId: string;
53
- }
54
- /**
55
- * → the SUSPENSE row: the entry names no row at all. `posted` carries WHICH of the three
56
- * routes brought it here — they are genuinely different facts with different remedies, and the
57
- * suspense row's items distinguish them (`broken` vs `cites-no-scenario`):
58
- * - `broken` — a proof that NEVER RAN, so it names no test and cites
59
- * nothing, WHATEVER `scnId` / `status` it structurally carries.
60
- * - `cites-nothing` — a runtime credit that RAN and carried no `@SCN`.
61
- * - `no-evidence-obligation-static-check` — a static check that ran with no `@lint` naming it.
62
- */
63
- | {
8
+ } | {
64
9
  kind: "suspense-scenario";
65
10
  posted: "broken" | "cites-nothing" | "no-evidence-obligation-static-check";
66
11
  };
67
- /** The destinations a RUNTIME credit can reach — it is citation-routed, so never by name. */
68
12
  export type RuntimePosting = {
69
13
  kind: "scenario";
70
14
  scnId: string;
@@ -75,22 +19,6 @@ export type RuntimePosting = {
75
19
  kind: "suspense-scenario";
76
20
  posted: "broken" | "cites-nothing";
77
21
  };
78
- /**
79
- * The destinations a STATIC-CHECK credit can reach — the citation-routed ones when the observer
80
- * stamped an `@SCN` on it (@SCN-LNT-001), and suspense when the check named nobody or never ran.
81
- * Structurally `RuntimePosting`'s shape now that the by-name member is gone (3F-2590): one posting
82
- * rule over both axes. The two types stay APART because their SUSPENSE reasons still differ — a
83
- * runtime credit reaches suspense `broken` or `cites-nothing`, a fitness credit `broken` or
84
- * because no obligation names its check — and collapsing them would let a caller be handed a
85
- * reason its axis cannot produce. `cites-nothing` is the one this axis has never had: a converted
86
- * credit that cites nothing is a check nobody named, which is a different fault with a different
87
- * remedy.
88
- *
89
- * `broken` ARRIVES HERE AT @SCN-LNT-026 AND IS NOT A NEW CONCEPT, only a newly reachable one. The
90
- * outcome has meant a proof that never ran since @SCN-LDG-017; what changed is that the static
91
- * axis can now say it, because the CI run's own step record says whether the check ran and the
92
- * reader had been declining to look.
93
- */
94
22
  export type StaticCheckPosting = {
95
23
  kind: "scenario";
96
24
  scnId: string;
@@ -101,32 +29,7 @@ export type StaticCheckPosting = {
101
29
  kind: "suspense-scenario";
102
30
  posted: "broken" | "no-evidence-obligation-static-check";
103
31
  };
104
- /**
105
- * WHERE does this evidence observation post? THE posting rule, in one place.
106
- *
107
- * `scenarioIds` is the OBLIGATION side — which scenarios exist — already the model's own rule,
108
- * built once by the caller and passed rather than re-derived here, so the rule stays a pure
109
- * decision over prepared inputs and cannot disagree with the census that shares it. A second set
110
- * (the named static-check handles) stood beside it for the by-name route and went with it.
111
- *
112
- * ORDER IS LOAD-BEARING — the arms are checked exactly as canon fail-safes them, and ON BOTH
113
- * BRANCHES since @SCN-LNT-026, which is the point of saying it once here:
114
- * 1. `broken` FIRST, on the FLAG, never on `scnId` / `status` (@SCN-LDG-017). A proof that never
115
- * ran cannot discharge or fail an obligation, so it must never be citation-routed — not to a
116
- * real row, not to a phantom one. It structurally MAY carry an `scnId` and a `status`; both
117
- * are ignored here. Checking `broken` after either would misfile it.
118
- * 2. an uncited credit (`scnId === null`, or absent on the static axis) → suspense, never phantom.
119
- * 3. a cited credit whose `@SCN` no scenario carries → phantom.
120
- * 4. otherwise → that scenario's row.
121
- *
122
- * The two branches differ only in what step 2's suspense reason is CALLED, because the two axes
123
- * reach it for different reasons: a runtime credit that ran and cited nothing, a static check no
124
- * obligation names. Steps 1, 3 and 4 are the same rule read twice.
125
- *
126
- * The overloads keep the two axes' destinations apart at the type level, so a caller that has
127
- * already narrowed the union cannot be handed a destination its axis can never reach.
128
- */
129
32
  export declare function postingOf(observation: RuntimeEvidenceObservation, scenarioIds: ReadonlySet<string>): RuntimePosting;
130
- export declare function postingOf(observation: GuardEvidenceObservation, scenarioIds: ReadonlySet<string>): StaticCheckPosting;
33
+ export declare function postingOf(observation: FitnessEvidenceObservation, scenarioIds: ReadonlySet<string>): StaticCheckPosting;
131
34
  export declare function postingOf(observation: EvidenceObservation, scenarioIds: ReadonlySet<string>): Posting;
132
35
  //# sourceMappingURL=posting.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"posting.d.ts","sourceRoot":"","sources":["../../src/domain/posting.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAEV,mBAAmB,EACnB,0BAA0B,EAC1B,wBAAwB,EACzB,MAAM,cAAc,CAAC;AAMtB;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,OAAO;AACjB,iFAAiF;AAC/E;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AACrC,qFAAqF;GACnF;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AAC7C;;;;;;;;GAQG;GACD;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,MAAM,EAAE,QAAQ,GAAG,eAAe,GAAG,qCAAqC,CAAA;CAAE,CAAC;AAE9G,6FAA6F;AAC7F,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,MAAM,EAAE,QAAQ,GAAG,eAAe,CAAA;CAAE,CAAC;AAEtE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,MAAM,EAAE,QAAQ,GAAG,qCAAqC,CAAA;CAAE,CAAC;AAE5F;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,SAAS,CACvB,WAAW,EAAE,0BAA0B,EACvC,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,GAC/B,cAAc,CAAC;AAClB,wBAAgB,SAAS,CACvB,WAAW,EAAE,wBAAwB,EACrC,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,GAC/B,kBAAkB,CAAC;AACtB,wBAAgB,SAAS,CACvB,WAAW,EAAE,mBAAmB,EAChC,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,GAC/B,OAAO,CAAC"}
1
+ {"version":3,"file":"posting.d.ts","sourceRoot":"","sources":["../../src/domain/posting.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,mBAAmB,EACnB,0BAA0B,EAC1B,0BAA0B,EAC3B,MAAM,cAAc,CAAC;AAGtB,MAAM,MAAM,OAAO,GACf;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,MAAM,EAAE,QAAQ,GAAG,eAAe,GAAG,qCAAqC,CAAA;CAAE,CAAC;AAE9G,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,MAAM,EAAE,QAAQ,GAAG,eAAe,CAAA;CAAE,CAAC;AAEtE,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,MAAM,EAAE,QAAQ,GAAG,qCAAqC,CAAA;CAAE,CAAC;AAE5F,wBAAgB,SAAS,CACvB,WAAW,EAAE,0BAA0B,EACvC,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,GAC/B,cAAc,CAAC;AAClB,wBAAgB,SAAS,CACvB,WAAW,EAAE,0BAA0B,EACvC,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,GAC/B,kBAAkB,CAAC;AACtB,wBAAgB,SAAS,CACvB,WAAW,EAAE,mBAAmB,EAChC,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,GAC/B,OAAO,CAAC"}