eval-quality 0.1.0 → 0.3.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 (179) hide show
  1. package/README.md +142 -67
  2. package/corpus/dev/README.md +20 -13
  3. package/corpus/dev/compile-seal-example/brief.json +1 -1
  4. package/corpus/dev/compile-seal-example/contract.json +1 -1
  5. package/corpus/dev/contracts/absent-collection-locations.json +1 -1
  6. package/corpus/dev/contracts/absent-sibling-groups.json +1 -1
  7. package/corpus/dev/contracts/absent-success-indicator.json +1 -1
  8. package/corpus/dev/contracts/empty-channel-roles.json +1 -1
  9. package/corpus/dev/contracts/empty-collection-locations.json +1 -1
  10. package/corpus/dev/contracts/empty-request-shapes.json +1 -1
  11. package/corpus/dev/contracts/empty-sibling-groups.json +1 -1
  12. package/corpus/dev/contracts/fragment-selection.json +1 -0
  13. package/corpus/dev/contracts/no-collection-quantifier.json +1 -1
  14. package/corpus/dev/contracts/no-operation-inventory.json +1 -1
  15. package/corpus/dev/contracts/no-read-back-relation.json +1 -1
  16. package/corpus/dev/contracts/no-state-change-marker.json +1 -1
  17. package/corpus/dev/contracts/no-type-violating-step.json +1 -1
  18. package/corpus/dev/contracts/per-key-split-oracles.json +1 -1
  19. package/corpus/dev/contracts/review-corpus.json +1 -0
  20. package/corpus/dev/contracts/satisfied-declarations.json +1 -1
  21. package/corpus/dev/contracts/single-required-response-key.json +1 -1
  22. package/corpus/dev/contracts/split-indicator-oracle.json +1 -1
  23. package/corpus/dev/contracts/unaddressed-parameter-sibling.json +1 -1
  24. package/corpus/dev/contracts/unnamed-reference-set.json +1 -1
  25. package/corpus/dev/contracts/wrong-cardinality-form.json +1 -1
  26. package/corpus/dev/index.json +1 -1
  27. package/dist/application/index.d.ts +2 -0
  28. package/dist/application/index.js +1 -0
  29. package/dist/application/score.d.ts +48 -0
  30. package/dist/application/score.js +186 -0
  31. package/dist/cli/arguments.d.ts +7 -3
  32. package/dist/cli/arguments.js +73 -5
  33. package/dist/cli/exit-codes.d.ts +6 -2
  34. package/dist/cli/exit-codes.js +8 -9
  35. package/dist/cli/main.js +9 -0
  36. package/dist/cli/render.d.ts +3 -6
  37. package/dist/cli/render.js +57 -5
  38. package/dist/cli/run.d.ts +13 -3
  39. package/dist/cli/run.js +136 -16
  40. package/dist/core/canonical/canonicalize.d.ts +12 -0
  41. package/dist/core/canonical/canonicalize.js +18 -4
  42. package/dist/core/compile/bindings.d.ts +89 -0
  43. package/dist/core/compile/bindings.js +334 -0
  44. package/dist/core/compile/compile.d.ts +17 -0
  45. package/dist/core/compile/compile.js +37 -1
  46. package/dist/core/compile/excluded-content.d.ts +11 -0
  47. package/dist/core/compile/excluded-content.js +42 -0
  48. package/dist/core/compile/expression-legality.d.ts +49 -0
  49. package/dist/core/compile/expression-legality.js +158 -38
  50. package/dist/core/compile/forbidden-inputs.d.ts +8 -1
  51. package/dist/core/compile/forbidden-inputs.js +16 -3
  52. package/dist/core/compile/interface-inventory.d.ts +57 -2
  53. package/dist/core/compile/interface-inventory.js +119 -13
  54. package/dist/core/compile/reachability.d.ts +28 -1
  55. package/dist/core/compile/reachability.js +167 -35
  56. package/dist/core/compile/schema-version.d.ts +2 -0
  57. package/dist/core/compile/schema-version.js +25 -0
  58. package/dist/core/compile/sensitivity-witness.d.ts +31 -12
  59. package/dist/core/compile/sensitivity-witness.js +110 -23
  60. package/dist/core/compile/step-reference.d.ts +2 -0
  61. package/dist/core/compile/step-reference.js +49 -0
  62. package/dist/core/coverage/operations.d.ts +62 -0
  63. package/dist/core/coverage/operations.js +57 -0
  64. package/dist/core/coverage/relevance.d.ts +4 -2
  65. package/dist/core/coverage/relevance.js +22 -23
  66. package/dist/core/coverage/satisfaction.d.ts +2 -2
  67. package/dist/core/coverage/satisfaction.js +73 -48
  68. package/dist/core/declared-inputs.d.ts +83 -4
  69. package/dist/core/declared-inputs.js +105 -8
  70. package/dist/core/emit/emit.d.ts +9 -0
  71. package/dist/core/emit/emit.js +214 -0
  72. package/dist/core/emit/private-artifact-digest.d.ts +11 -0
  73. package/dist/core/emit/private-artifact-digest.js +31 -0
  74. package/dist/core/evaluate/evidence-resolution.d.ts +10 -3
  75. package/dist/core/evaluate/evidence-resolution.js +74 -11
  76. package/dist/core/evaluate/operators.d.ts +22 -0
  77. package/dist/core/evaluate/operators.js +17 -1
  78. package/dist/core/evaluate/resolution.d.ts +14 -3
  79. package/dist/core/evaluate/resolution.js +63 -3
  80. package/dist/core/excluded-content.d.ts +65 -0
  81. package/dist/core/excluded-content.js +113 -0
  82. package/dist/core/failure-codes.d.ts +2 -2
  83. package/dist/core/failure-codes.js +7 -2
  84. package/dist/core/ingest/conditions.d.ts +201 -0
  85. package/dist/core/ingest/conditions.js +48 -0
  86. package/dist/core/ingest/index.d.ts +13 -0
  87. package/dist/core/ingest/index.js +11 -0
  88. package/dist/core/ingest/ingest.d.ts +68 -0
  89. package/dist/core/ingest/ingest.js +318 -0
  90. package/dist/core/lineage/stage-table.d.ts +21 -4
  91. package/dist/core/lineage/stage-table.js +35 -3
  92. package/dist/core/preflight/plan.d.ts +7 -5
  93. package/dist/core/preflight/plan.js +75 -32
  94. package/dist/core/preflight/projection.d.ts +6 -3
  95. package/dist/core/preflight/projection.js +22 -2
  96. package/dist/core/preflight/reduce.js +47 -7
  97. package/dist/core/preflight/witness-evidence.d.ts +5 -5
  98. package/dist/core/preflight/witness-evidence.js +73 -20
  99. package/dist/core/schemas/artifact.d.ts +1049 -30
  100. package/dist/core/schemas/constraint-ledger.js +51 -0
  101. package/dist/core/schemas/defect-signature.d.ts +695 -0
  102. package/dist/core/schemas/defect-signature.js +175 -0
  103. package/dist/core/schemas/eval-contract.d.ts +550 -12
  104. package/dist/core/schemas/eval-contract.js +32 -2
  105. package/dist/core/schemas/evidence-artifact.d.ts +109 -19
  106. package/dist/core/schemas/evidence-artifact.js +64 -8
  107. package/dist/core/schemas/interface.d.ts +741 -13
  108. package/dist/core/schemas/interface.js +120 -7
  109. package/dist/core/schemas/isolation-manifest.js +16 -9
  110. package/dist/core/schemas/plan.d.ts +329 -3
  111. package/dist/core/schemas/plan.js +89 -3
  112. package/dist/core/schemas/pointer.d.ts +47 -1
  113. package/dist/core/schemas/pointer.js +89 -8
  114. package/dist/core/schemas/port-messages.d.ts +194 -10
  115. package/dist/core/schemas/port-messages.js +73 -6
  116. package/dist/core/schemas/probe-body.d.ts +18 -0
  117. package/dist/core/schemas/probe-body.js +13 -0
  118. package/dist/core/schemas/probe-qualification.d.ts +168 -0
  119. package/dist/core/schemas/probe-qualification.js +106 -0
  120. package/dist/core/schemas/probe.d.ts +431 -0
  121. package/dist/core/schemas/probe.js +6 -2
  122. package/dist/core/schemas/scoring-policy.d.ts +1 -0
  123. package/dist/core/schemas/scoring-policy.js +6 -1
  124. package/dist/core/schemas/sealed-evaluator-brief.d.ts +1 -0
  125. package/dist/core/schemas/sealed-evaluator-brief.js +4 -1
  126. package/dist/core/schemas/sealed-run-record.d.ts +161 -12
  127. package/dist/core/schemas/sealed-run-record.js +92 -15
  128. package/dist/core/schemas/sensitivity-witness.d.ts +108 -6
  129. package/dist/core/schemas/sensitivity-witness.js +61 -5
  130. package/dist/core/score/binding-order.d.ts +31 -0
  131. package/dist/core/score/binding-order.js +88 -0
  132. package/dist/core/score/bindings.d.ts +93 -0
  133. package/dist/core/score/bindings.js +309 -0
  134. package/dist/core/score/ladder-table.d.ts +23 -0
  135. package/dist/core/score/ladder-table.js +109 -0
  136. package/dist/core/score/ladder.d.ts +229 -0
  137. package/dist/core/score/ladder.js +464 -0
  138. package/dist/core/score/mode-agreement.d.ts +30 -0
  139. package/dist/core/score/mode-agreement.js +16 -0
  140. package/dist/core/score/outcome-table.d.ts +17 -0
  141. package/dist/core/score/outcome-table.js +172 -0
  142. package/dist/core/score/outcome.d.ts +466 -0
  143. package/dist/core/score/outcome.js +562 -0
  144. package/dist/core/score/qualification.d.ts +83 -0
  145. package/dist/core/score/qualification.js +645 -0
  146. package/dist/core/score/quotation.d.ts +56 -0
  147. package/dist/core/score/quotation.js +226 -0
  148. package/dist/core/score/reduce-trials.d.ts +80 -0
  149. package/dist/core/score/reduce-trials.js +90 -0
  150. package/dist/core/score/score.d.ts +72 -0
  151. package/dist/core/score/score.js +607 -0
  152. package/dist/core/score/selection.d.ts +80 -0
  153. package/dist/core/score/selection.js +98 -0
  154. package/dist/core/score/strength.d.ts +58 -0
  155. package/dist/core/score/strength.js +227 -0
  156. package/dist/core/score/witness.d.ts +138 -0
  157. package/dist/core/score/witness.js +320 -0
  158. package/dist/core/seal/derived-reference.d.ts +2 -9
  159. package/dist/core/seal/derived-reference.js +293 -46
  160. package/dist/core/seal/plan-index.d.ts +18 -3
  161. package/dist/core/seal/plan-index.js +44 -8
  162. package/dist/core/seal/seal.js +8 -3
  163. package/dist/core/stage-contracts.d.ts +62 -2
  164. package/dist/index.d.ts +1 -1
  165. package/dist/index.js +1 -1
  166. package/dist/ports/environment-probe-port.d.ts +60 -4
  167. package/dist/testing/index.d.ts +2 -0
  168. package/dist/testing/index.js +1 -0
  169. package/dist/testing/probe-conformance.d.ts +29 -0
  170. package/dist/testing/probe-conformance.js +34 -5
  171. package/package.json +12 -3
  172. package/schemas/eval-contract.schema.json +1787 -797
  173. package/schemas/evidence-artifact.schema.json +126 -9
  174. package/schemas/isolation-manifest.schema.json +17 -10
  175. package/schemas/probe.schema.json +636 -5
  176. package/schemas/rubric.schema.json +1 -1
  177. package/schemas/scoring-policy.schema.json +8 -1
  178. package/schemas/sealed-evaluator-brief.schema.json +11 -1
  179. package/schemas/sealed-run-record.schema.json +314 -40
@@ -0,0 +1,172 @@
1
+ /**
2
+ * AD-33's published decision table, emitted from the four rule tables the
3
+ * procedure decides with and from the fixture set's resolved cases.
4
+ *
5
+ * Pure, so the writer and the drift check cannot disagree about bytes. Its
6
+ * inputs are arguments, so the fixture set stays under `tests/` and nothing
7
+ * here reaches for it.
8
+ *
9
+ * AD-33 establishes that a cell per input tuple, each with a positive and a
10
+ * negative fixture, is arithmetically out of reach, and asks for a total
11
+ * function whose enumerated output is published. The enumerated output is the
12
+ * four rule tables, the named structural constraints with the infeasible pairs
13
+ * derived from them, and five censuses over the fixture set. Every census
14
+ * count is asserted at least one here, so a rule or a state losing its last
15
+ * case fails the build.
16
+ */
17
+ import { OUTCOME_STATES } from '../schemas/evidence-artifact.js';
18
+ import { CORROBORATION_RULES, INVALIDATING_CONDITIONS, OUTCOME_RULES, WAIVER_RULES, } from './outcome.js';
19
+ /** `|` escaped: a guard is prose, and a broken table is still byte-stable. */
20
+ const cell = (text) => text.replace(/\|/g, '\\|');
21
+ const row = (cells) => `| ${cells.map(cell).join(' | ')} |`;
22
+ const table = (headers, rows) => [
23
+ row(headers),
24
+ `| ${headers.map(() => '---').join(' | ')} |`,
25
+ ...rows.map(row),
26
+ ];
27
+ const code = (text) => `\`${text}\``;
28
+ const HEADER = [
29
+ '# AD-33 outcome decision',
30
+ '',
31
+ 'Generated by `npm run generate:ad33-table` from the four rule tables in',
32
+ '`src/core/score/outcome.ts` and from the fixture set that exercises them. Guarded by',
33
+ '`npm run check:ad33-table`, a byte-exact drift check. A hand edit fails that check; regenerate.',
34
+ '',
35
+ 'The procedure is pure and total: every input value returns a defined resolution and nothing',
36
+ 'throws. Stage A evaluates the invalidating conditions independently of the state, so no',
37
+ 'condition is masked by another that fired first. Stage B is a first-match ladder. Stage C',
38
+ 'adjusts the state for a waiver. Corroboration is decided after the state.',
39
+ ];
40
+ /**
41
+ * Counts each key across the cases, then reports the first key no case
42
+ * reached. A zero census is what a narrowed fixture set looks like, and no
43
+ * regeneration repairs it.
44
+ */
45
+ const census = (label, keys, countOf) => keys.map((key) => {
46
+ const count = countOf(key);
47
+ if (count === 0) {
48
+ throw new Error(`outcomeDecisionTable: no case reaches ${label} ${key}, so the published census would claim coverage the fixture set does not have`);
49
+ }
50
+ return [code(key), String(count)];
51
+ });
52
+ /** The whole document. Throws a worded diagnosis on an empty census cell. */
53
+ export function outcomeDecisionTable(cases, constraints) {
54
+ if (cases.length === 0) {
55
+ throw new Error('outcomeDecisionTable: no resolved cases, so every census below would be empty');
56
+ }
57
+ const seen = new Set();
58
+ for (const constraint of constraints.constraints) {
59
+ if (seen.has(constraint.id)) {
60
+ throw new Error(`outcomeDecisionTable: two structural constraints share the identifier ${constraint.id}`);
61
+ }
62
+ seen.add(constraint.id);
63
+ }
64
+ if (constraints.constraints.length === 0) {
65
+ throw new Error('outcomeDecisionTable: no structural constraints, so the infeasible pairs below rest on nothing');
66
+ }
67
+ const conditionRows = INVALIDATING_CONDITIONS.map((condition) => [
68
+ code(condition.id),
69
+ condition.guard,
70
+ ]);
71
+ const ladderRows = OUTCOME_RULES.map((rule, index) => [
72
+ String(index + 1),
73
+ code(rule.id),
74
+ rule.guard,
75
+ code(rule.state),
76
+ rule.resolvesFromCitation ? 'yes' : 'no',
77
+ ]);
78
+ const waiverRows = WAIVER_RULES.map((rule) => [
79
+ code(rule.id),
80
+ rule.guard,
81
+ `state becomes ${code(rule.state)}`,
82
+ ]);
83
+ const corroborationRows = CORROBORATION_RULES.map((rule, index) => [
84
+ String(index + 1),
85
+ code(rule.id),
86
+ rule.guard,
87
+ rule.value,
88
+ ]);
89
+ const constraintRows = constraints.constraints.map((constraint) => [
90
+ code(constraint.id),
91
+ constraint.implication,
92
+ ]);
93
+ const infeasibleRows = constraints.infeasiblePairs.map((pair) => [
94
+ code(pair.left),
95
+ code(pair.right),
96
+ ]);
97
+ const stateCensus = census('the AD-6 state', OUTCOME_STATES, (key) => cases.filter((resolved) => resolved.state === key).length);
98
+ const ladderCensus = census('the ladder rule', OUTCOME_RULES.map((rule) => rule.id), (key) => cases.filter((resolved) => resolved.rule === key).length);
99
+ const waiverCensus = census('the waiver rule', WAIVER_RULES.map((rule) => rule.id), (key) => cases.filter((resolved) => resolved.waiverRule === key).length);
100
+ const corroborationCensus = census('the corroboration rule', CORROBORATION_RULES.map((rule) => rule.id), (key) => cases.filter((resolved) => resolved.corroborationRule === key).length);
101
+ const conditionCensus = census('the invalidating condition', INVALIDATING_CONDITIONS.map((condition) => condition.id), (key) => cases.filter((resolved) => resolved.invalidatingConditions.some((fired) => fired === key)).length);
102
+ const lines = [
103
+ ...HEADER,
104
+ '',
105
+ '## Invalidating conditions',
106
+ '',
107
+ 'Evaluated independently of the state ladder. Every one that holds is returned, sorted.',
108
+ '',
109
+ ...table(['Condition', 'Holds when'], conditionRows),
110
+ '',
111
+ '## The state ladder',
112
+ '',
113
+ 'First match wins. The final row carries the stated negation of every guard above it.',
114
+ '',
115
+ ...table(['#', 'Rule', 'Guard', 'State', 'Resolves from the citation'], ladderRows),
116
+ '',
117
+ '## The waiver adjustment',
118
+ '',
119
+ 'Applied to the provisional state the ladder produced. Neither rule fires on a waiver of',
120
+ '`none` or `expired`, and neither fires over a state outside the waivable group.',
121
+ '',
122
+ ...table(['Rule', 'Holds when', 'Effect'], waiverRows),
123
+ '',
124
+ '## Corroboration',
125
+ '',
126
+ 'Decided after the final state. First match wins and no row is an `otherwise`.',
127
+ '',
128
+ ...table(['#', 'Rule', 'Holds when', 'Value'], corroborationRows),
129
+ '',
130
+ '## Structural constraints',
131
+ '',
132
+ 'Named implications the declared input domains satisfy. Each leaves its offending tuple',
133
+ 'representable and resolvable. The four `cannot-qualify` constraints route theirs to the',
134
+ 'unqualified-probe rule, since the gate that names them sets `probeQualified` false; the other',
135
+ 'three describe what the upstream records can carry, and a tuple violating one still resolves.',
136
+ '',
137
+ ...table(['Constraint', 'Implication'], constraintRows),
138
+ '',
139
+ '## Infeasible pairs',
140
+ '',
141
+ 'Pairs of domain values no tuple satisfying the constraints above contains, derived from',
142
+ 'those constraints themselves.',
143
+ '',
144
+ ...table(['Left', 'Right'], infeasibleRows),
145
+ '',
146
+ '## Census',
147
+ '',
148
+ `Over the ${cases.length} resolved fixture cases. Every count is at least one, checked when this`,
149
+ 'document is built.',
150
+ '',
151
+ '### By state',
152
+ '',
153
+ ...table(['State', 'Cases'], stateCensus),
154
+ '',
155
+ '### By ladder rule',
156
+ '',
157
+ ...table(['Rule', 'Cases'], ladderCensus),
158
+ '',
159
+ '### By waiver rule',
160
+ '',
161
+ ...table(['Rule', 'Cases'], waiverCensus),
162
+ '',
163
+ '### By corroboration rule',
164
+ '',
165
+ ...table(['Rule', 'Cases'], corroborationCensus),
166
+ '',
167
+ '### By invalidating condition',
168
+ '',
169
+ ...table(['Condition', 'Cases'], conditionCensus),
170
+ ];
171
+ return `${lines.join('\n')}\n`;
172
+ }
@@ -0,0 +1,466 @@
1
+ /**
2
+ * AD-33's reference decision procedure: the one component that assigns an AD-6
3
+ * outcome state.
4
+ *
5
+ * Pure and total. Every input value returns a defined resolution, nothing
6
+ * throws, and no clock, filesystem, or randomness is read. A `RuntimeFault`
7
+ * raised below propagates undecorated, because AD-28's fault vocabulary and
8
+ * AD-6's state vocabulary are disjoint.
9
+ *
10
+ * Three stages over one input record. Stage A evaluates ten invalidating
11
+ * conditions independently and unions them, so AD-21 receives every condition
12
+ * that fired and a persistent judge fault cannot mask a real regression.
13
+ * Stage B is an ordered first-match ladder of twenty rules producing a
14
+ * provisional state. Stage C adjusts that state for a waiver over a single
15
+ * waivable failure. Corroboration is a fourth ordered table decided after the
16
+ * state, which is how a disposition and a declined citation reach the outcome
17
+ * without deciding one, since AD-3 forbids a check resolution as the source of
18
+ * a state.
19
+ *
20
+ * All four tables are data, so `outcome-table.ts` emits the published decision
21
+ * table from them and a byte-exact drift check compares it against the
22
+ * committed document.
23
+ */
24
+ import type { CheckResolutionValue, CORROBORATION_VALUES, OUTCOME_STATES, UncitedFindingGap } from '../schemas/evidence-artifact.ts';
25
+ import type { Polarity } from '../schemas/expression.ts';
26
+ import type { Probe } from '../schemas/probe.ts';
27
+ import type { OracleDisposition, SealedRunRecord } from '../schemas/sealed-run-record.ts';
28
+ import type { StepSelection } from './selection.ts';
29
+ import type { ProbeWitnessMatch } from './witness.ts';
30
+ type OutcomeStateValue = (typeof OUTCOME_STATES)[number];
31
+ type CorroborationValue = (typeof CORROBORATION_VALUES)[number];
32
+ /**
33
+ * The four buckets `mapFindings` sorts a defect finding into, each carrying a
34
+ * distinct AD consequence. Keyed on the cited finding's own `probeId`, which
35
+ * is unrelated to whatever probe an outcome row is about.
36
+ */
37
+ export declare const FINDING_BUCKETS: readonly ["mapped", "unmapped", "dangling", "signatureless"];
38
+ export type FindingBucketValue = (typeof FINDING_BUCKETS)[number];
39
+ /**
40
+ * AD-6 qualifies `not-applicable` by an unexpired waiver satisfying AD-5.
41
+ * Completeness is settled at compile time by `checkWaiverCompleteness`, and
42
+ * `core/score` reads no clock, so both expiry and whether the waiver's opaque
43
+ * context condition was met arrive already decided.
44
+ */
45
+ export declare const WAIVER_STATES: readonly ['none', 'applied-condition-met', 'applied-condition-unmet', 'expired'];
46
+ export type WaiverStateValue = (typeof WAIVER_STATES)[number];
47
+ /**
48
+ * AD-17 names no field for a malformed judge response and `JudgeResult` is
49
+ * keyed by rubric criterion, so conduct arrives per oracle. `absent` is the
50
+ * ordinary value: a contract with no rubric produces no judge call.
51
+ */
52
+ export declare const JUDGE_CONDUCT_STATES: readonly ['absent', 'conforming', 'malformed'];
53
+ export type JudgeConductValue = (typeof JUDGE_CONDUCT_STATES)[number];
54
+ /** The defect finding whose `oracleId` is this oracle, with its bucket. */
55
+ export type CitedFinding = {
56
+ readonly findingId: string;
57
+ readonly bucket: FindingBucketValue;
58
+ };
59
+ /**
60
+ * The fifteen declared inputs. The upstream records travel whole, so the
61
+ * resolution can return the finding it resolved from and the observation
62
+ * identifiers it read, which is what AD-33 records on the outcome.
63
+ *
64
+ * `disposition` is the whole record, because Stage A and the corroboration
65
+ * rules read its `observationIds`.
66
+ *
67
+ * `probeSigned` is the one field no rule reads. It is declared because the
68
+ * published table states the relation AD-40 fixes between a signature and a
69
+ * witness, and a caller assembling a row from a probe already holds it.
70
+ */
71
+ export type OutcomeInputs = {
72
+ readonly required: boolean;
73
+ readonly disposition: OracleDisposition | null;
74
+ readonly citedFinding: CitedFinding | null;
75
+ readonly witness: ProbeWitnessMatch | null;
76
+ readonly selections: readonly StepSelection[];
77
+ readonly selectorAmbiguity: boolean;
78
+ readonly checkResolution: CheckResolutionValue['resolution'] | null;
79
+ readonly polarity: Polarity;
80
+ readonly probeClass: Probe['probeClass'] | null;
81
+ readonly expectedClean: boolean | null;
82
+ readonly probeSigned: boolean | null;
83
+ readonly probeQualified: boolean | null;
84
+ readonly waiver: WaiverStateValue;
85
+ readonly judgeConduct: JudgeConductValue;
86
+ readonly evaluationFault: boolean;
87
+ };
88
+ export type OutcomeResolution = {
89
+ readonly rule: OutcomeRuleId;
90
+ readonly waiverRule: WaiverRuleId | null;
91
+ readonly corroborationRule: CorroborationRuleId;
92
+ readonly state: OutcomeStateValue;
93
+ readonly corroboration: CorroborationValue;
94
+ readonly resolvedFrom: string | null;
95
+ readonly selectedObservationIds: readonly string[];
96
+ /** an `unmapped` or `signatureless` citation the state declined to resolve from. */
97
+ readonly declinedFindingIds: readonly string[];
98
+ readonly invalidatingConditions: readonly InvalidatingCondition[];
99
+ };
100
+ declare const probeUnqualified: (inputs: OutcomeInputs) => boolean;
101
+ declare const checkExaminedNothing: (inputs: OutcomeInputs) => boolean;
102
+ declare const dispositionUnsupported: (inputs: OutcomeInputs) => boolean;
103
+ /**
104
+ * `violated` with no defect finding, `held` with one, or `not-attempted` with
105
+ * one. A `not-attempted` citing observations is well supported: those are the
106
+ * observations showing why the evaluator could not proceed. Its contradiction
107
+ * is a defect finding filed against the same oracle.
108
+ */
109
+ declare const dispositionContradictsEvidence: (inputs: OutcomeInputs) => boolean;
110
+ declare const citationDeclined: (inputs: OutcomeInputs) => boolean;
111
+ /**
112
+ * A canary carries no signature, so it has no witness and step reachability is
113
+ * the only proxy for whether the evaluator took the path. AD-33 names
114
+ * punishing a contract for the evaluator's path choice as an anti-goal, so the
115
+ * condition and its ladder row share this guard.
116
+ */
117
+ declare const canaryUndetected: (inputs: OutcomeInputs) => boolean;
118
+ /**
119
+ * Stage A. Ten predicates evaluated independently of the state ladder, so a
120
+ * condition is never masked by another that fired first. Every one that holds
121
+ * is returned.
122
+ *
123
+ * Nine reach AD-21's Invalid rung through an AD-6 invalidating state or, for
124
+ * `disposition-missing`, by name. `unsupported-disposition` produces no state
125
+ * and is not in that enumeration; the half enforced here is the corroboration,
126
+ * which is AD-33's own requirement that an unsupported disposition invalidates
127
+ * cross-artifact agreement.
128
+ */
129
+ export declare const INVALIDATING_CONDITIONS: readonly [{
130
+ readonly id: 'evaluation-fault';
131
+ readonly guard: 'an AD-26 evaluation fault was recorded';
132
+ readonly holds: (inputs: OutcomeInputs) => boolean;
133
+ }, {
134
+ readonly id: 'judge-malformed';
135
+ readonly guard: 'judge conduct `malformed`';
136
+ readonly holds: (inputs: OutcomeInputs) => boolean;
137
+ }, {
138
+ readonly id: 'unqualified-probe-in-sealed-set';
139
+ readonly guard: 'a probe is present and its qualification failed';
140
+ readonly holds: typeof probeUnqualified;
141
+ }, {
142
+ readonly id: 'dangling-probe-citation';
143
+ readonly guard: "the cited finding's bucket is `dangling`";
144
+ readonly holds: (inputs: OutcomeInputs) => boolean;
145
+ }, {
146
+ readonly id: 'unwitnessed-detection-claim';
147
+ readonly guard: 'witness result `unwitnessed-claim`';
148
+ readonly holds: (inputs: OutcomeInputs) => boolean;
149
+ }, {
150
+ readonly id: 'vacuous-signature';
151
+ readonly guard: 'witness result `vacuous`';
152
+ readonly holds: (inputs: OutcomeInputs) => boolean;
153
+ }, {
154
+ readonly id: 'selector-ambiguity';
155
+ readonly guard: 'a step matched several observations under a single-valued cardinality';
156
+ readonly holds: (inputs: OutcomeInputs) => boolean;
157
+ }, {
158
+ readonly id: 'canary-non-detection';
159
+ readonly guard: 'class `canary`, some selection resolved other than `none`, and no defect finding cites the oracle';
160
+ readonly holds: typeof canaryUndetected;
161
+ }, {
162
+ readonly id: 'unsupported-disposition';
163
+ readonly guard: 'the disposition is `held` or `violated` with empty `observationIds`';
164
+ readonly holds: typeof dispositionUnsupported;
165
+ }, {
166
+ readonly id: 'disposition-missing';
167
+ readonly guard: 'the oracle is required and its disposition is `null`';
168
+ readonly holds: (inputs: OutcomeInputs) => boolean;
169
+ }];
170
+ export type InvalidatingCondition = (typeof INVALIDATING_CONDITIONS)[number]['id'];
171
+ /**
172
+ * Row 9. The witness conjunct keeps an unmatched selection from deleting a
173
+ * witnessed detection, and admits `not-triggered`, the one witness value
174
+ * carrying no detection to protect. The length conjunct keeps an oracle that
175
+ * declared no step out, since AD-6 scopes `unreached` to declared steps and
176
+ * `every` is vacuous over an empty array.
177
+ */
178
+ declare const stepsUnreached: (inputs: OutcomeInputs) => boolean;
179
+ /** AD-33's first fixed cell. A `zero-action` probe on the seeding branch seeds a defect whose correct behaviour is refusal, so "satisfied" is the signature manifesting and a finding witnessing it, which is `matched`. */
180
+ declare const zeroActionDetected: (inputs: OutcomeInputs) => boolean;
181
+ declare const cleanControlFalsePositive: (inputs: OutcomeInputs) => boolean;
182
+ /**
183
+ * A clean control whose check examined nothing falls past this row to the
184
+ * abstention row: AD-4 makes `insufficient-evidence` terminal and AD-6 lands
185
+ * it on `abstained`, so a build cannot pass green on an oracle that examined
186
+ * an empty collection. The false-positive row stays above both; a filed
187
+ * finding survives a check that examined nothing.
188
+ */
189
+ declare const cleanControlPassed: (inputs: OutcomeInputs) => boolean;
190
+ declare const canaryDetected: (inputs: OutcomeInputs) => boolean;
191
+ /**
192
+ * The three witness rows above the clean-control pair each carry
193
+ * `expectedClean`, so AD-9's legal states for a clean control hold over the
194
+ * whole input type, beyond the tuples the qualification gate can produce. The
195
+ * unexercised row carries the guard for its own reason: AD-6 legalises
196
+ * `not-applicable` for a probe AD-40 records as unexercised, and a clean
197
+ * control carries no signature, so AD-40 records nothing about it.
198
+ */
199
+ declare const witnessUnexercised: (inputs: OutcomeInputs) => boolean;
200
+ declare const witnessMatched: (inputs: OutcomeInputs) => boolean;
201
+ declare const witnessManifestedUnclaimed: (inputs: OutcomeInputs) => boolean;
202
+ /**
203
+ * On a witness-free oracle, `mapped` is the one bucket that resolves `caught`.
204
+ * AD-40 calls an unmapped finding an unexpected real defect and keeps it out
205
+ * of every catch.
206
+ */
207
+ declare const oracleCitedDefect: (inputs: OutcomeInputs) => boolean;
208
+ /** Row 20's guard, written out as the negation of every guard above it. */
209
+ declare const outcomeClear: (inputs: OutcomeInputs) => boolean;
210
+ /**
211
+ * Stage B. First match wins; the identifier of the row that fired is
212
+ * returned.
213
+ *
214
+ * Rows 5, 6, 8, 15, 16, and 19 consume all six witness results, so anything
215
+ * reaching row 20 carries no witness. Rows 9 and 18 each take a subset of an
216
+ * earlier row's domain without widening it, which is why the witness rows are
217
+ * not contiguous. Rows 13 and 14 are deliberately not total over `canary`: an
218
+ * undetected canary that matched no selection falls past both and lands on row
219
+ * 18 or row 20 unless row 9 took it.
220
+ *
221
+ * Rows 10 and 15 overlap on a `zero-action` probe with a `matched` witness.
222
+ * Row 10 is kept so AD-33's first fixed cell has a line of its own in the
223
+ * emitted table.
224
+ */
225
+ export declare const OUTCOME_RULES: readonly [{
226
+ readonly id: 'evaluation-fault';
227
+ readonly guard: 'an AD-26 evaluation fault was recorded';
228
+ readonly state: 'oracle-error';
229
+ readonly resolvesFromCitation: false;
230
+ readonly holds: (inputs: OutcomeInputs) => boolean;
231
+ }, {
232
+ readonly id: 'judge-malformed';
233
+ readonly guard: 'judge conduct `malformed`';
234
+ readonly state: 'judge-error';
235
+ readonly resolvesFromCitation: false;
236
+ readonly holds: (inputs: OutcomeInputs) => boolean;
237
+ }, {
238
+ readonly id: 'probe-unqualified';
239
+ readonly guard: 'a probe is present and its qualification failed';
240
+ readonly state: 'infrastructure-error';
241
+ readonly resolvesFromCitation: false;
242
+ readonly holds: typeof probeUnqualified;
243
+ }, {
244
+ readonly id: 'finding-dangling-probe';
245
+ readonly guard: "the cited finding's bucket is `dangling`";
246
+ readonly state: 'infrastructure-error';
247
+ readonly resolvesFromCitation: true;
248
+ readonly holds: (inputs: OutcomeInputs) => boolean;
249
+ }, {
250
+ readonly id: 'witness-unwitnessed-claim';
251
+ readonly guard: 'witness result `unwitnessed-claim`';
252
+ readonly state: 'infrastructure-error';
253
+ readonly resolvesFromCitation: false;
254
+ readonly holds: (inputs: OutcomeInputs) => boolean;
255
+ }, {
256
+ readonly id: 'witness-vacuous';
257
+ readonly guard: 'witness result `vacuous`';
258
+ readonly state: 'infrastructure-error';
259
+ readonly resolvesFromCitation: false;
260
+ readonly holds: (inputs: OutcomeInputs) => boolean;
261
+ }, {
262
+ readonly id: 'selector-ambiguous';
263
+ readonly guard: 'a step matched several observations under a single-valued cardinality';
264
+ readonly state: 'infrastructure-error';
265
+ readonly resolvesFromCitation: false;
266
+ readonly holds: (inputs: OutcomeInputs) => boolean;
267
+ }, {
268
+ readonly id: 'witness-unexercised';
269
+ readonly guard: 'witness result `unexercised` on a probe outside the `expectedClean` branch';
270
+ readonly state: 'not-applicable';
271
+ readonly resolvesFromCitation: false;
272
+ readonly holds: typeof witnessUnexercised;
273
+ }, {
274
+ readonly id: 'steps-unreached';
275
+ readonly guard: 'no witness or witness result `not-triggered`; `selections` non-empty; every member resolved `none`';
276
+ readonly state: 'unreached';
277
+ readonly resolvesFromCitation: false;
278
+ readonly holds: typeof stepsUnreached;
279
+ }, {
280
+ readonly id: 'zero-action-detected';
281
+ readonly guard: 'class `zero-action` on the seeding branch with witness result `matched`';
282
+ readonly state: 'caught';
283
+ readonly resolvesFromCitation: false;
284
+ readonly holds: typeof zeroActionDetected;
285
+ }, {
286
+ readonly id: 'clean-control-false-positive';
287
+ readonly guard: '`expectedClean` and a defect finding cites the oracle';
288
+ readonly state: 'false-positive';
289
+ readonly resolvesFromCitation: true;
290
+ readonly holds: typeof cleanControlFalsePositive;
291
+ }, {
292
+ readonly id: 'clean-control-passed';
293
+ readonly guard: '`expectedClean` and the check root did not resolve `insufficient-evidence`';
294
+ readonly state: 'passed-clean-control';
295
+ readonly resolvesFromCitation: false;
296
+ readonly holds: typeof cleanControlPassed;
297
+ }, {
298
+ readonly id: 'canary-detected';
299
+ readonly guard: 'class `canary` and a defect finding cites the oracle';
300
+ readonly state: 'caught';
301
+ readonly resolvesFromCitation: true;
302
+ readonly holds: typeof canaryDetected;
303
+ }, {
304
+ readonly id: 'canary-undetected';
305
+ readonly guard: 'class `canary`, some selection resolved other than `none`, and no defect finding cites the oracle';
306
+ readonly state: 'infrastructure-error';
307
+ readonly resolvesFromCitation: false;
308
+ readonly holds: typeof canaryUndetected;
309
+ }, {
310
+ readonly id: 'witness-matched';
311
+ readonly guard: 'witness result `matched` on a probe outside the `expectedClean` branch';
312
+ readonly state: 'caught';
313
+ readonly resolvesFromCitation: false;
314
+ readonly holds: typeof witnessMatched;
315
+ }, {
316
+ readonly id: 'witness-manifested-unclaimed';
317
+ readonly guard: 'witness result `manifested-unclaimed` on a probe outside the `expectedClean` branch';
318
+ readonly state: 'missed';
319
+ readonly resolvesFromCitation: false;
320
+ readonly holds: typeof witnessManifestedUnclaimed;
321
+ }, {
322
+ readonly id: 'oracle-cited-defect';
323
+ readonly guard: "no witness and the cited finding's bucket is `mapped`";
324
+ readonly state: 'caught';
325
+ readonly resolvesFromCitation: true;
326
+ readonly holds: typeof oracleCitedDefect;
327
+ }, {
328
+ readonly id: 'check-insufficient-evidence';
329
+ readonly guard: 'the check root resolved `insufficient-evidence`';
330
+ readonly state: 'abstained';
331
+ readonly resolvesFromCitation: false;
332
+ readonly holds: typeof checkExaminedNothing;
333
+ }, {
334
+ readonly id: 'witness-not-triggered';
335
+ readonly guard: 'witness result `not-triggered`';
336
+ readonly state: 'confirmed';
337
+ readonly resolvesFromCitation: false;
338
+ readonly holds: (inputs: OutcomeInputs) => boolean;
339
+ }, {
340
+ readonly id: 'outcome-clear';
341
+ readonly guard: 'the stated negation of every guard above';
342
+ readonly state: 'confirmed';
343
+ readonly resolvesFromCitation: false;
344
+ readonly holds: typeof outcomeClear;
345
+ }];
346
+ export type OutcomeRuleId = (typeof OUTCOME_RULES)[number]['id'];
347
+ /**
348
+ * A waiver excuses a known gap, and `missed` is the only gap here.
349
+ * `false-positive` is a clean control's own calibration; `abstained` is an
350
+ * unknown. AD-7 counts every exercised probe in its denominator, so a waiver
351
+ * honoured over a `matched` witness would depress the catch rate.
352
+ */
353
+ export declare const WAIVABLE_FAILURES: readonly ["missed"];
354
+ /**
355
+ * Neither rule fires on `none` or `expired`, which is AD-21's expired waiver
356
+ * reinstating its gap. `bypassed` is a gap excused without earning the excuse,
357
+ * which is the group AD-6 puts it in and the only firing condition the AD
358
+ * gives it anywhere.
359
+ */
360
+ export declare const WAIVER_RULES: readonly [{
361
+ readonly id: 'waiver-honoured';
362
+ readonly guard: 'waiver `applied-condition-met` over a waivable failure';
363
+ readonly state: 'not-applicable';
364
+ readonly holds: (inputs: OutcomeInputs, provisional: "abstained" | "bypassed" | "caught" | "confirmed" | "false-positive" | "infrastructure-error" | "judge-error" | "missed" | "not-applicable" | "oracle-error" | "passed-clean-control" | "unreached") => boolean;
365
+ }, {
366
+ readonly id: 'waiver-bypassed';
367
+ readonly guard: 'waiver `applied-condition-unmet` over a waivable failure';
368
+ readonly state: 'bypassed';
369
+ readonly holds: (inputs: OutcomeInputs, provisional: "abstained" | "bypassed" | "caught" | "confirmed" | "false-positive" | "infrastructure-error" | "judge-error" | "missed" | "not-applicable" | "oracle-error" | "passed-clean-control" | "unreached") => boolean;
370
+ }];
371
+ export type WaiverRuleId = (typeof WAIVER_RULES)[number]['id'];
372
+ /**
373
+ * The corroboration table, decided after the final state. First match wins and
374
+ * no row is an `otherwise`.
375
+ *
376
+ * The order carries three obligations. Rows 1 to 3 sit above both
377
+ * check-derived rows so a disposition and a declined citation are not
378
+ * believed. Row 4 sits above row 5 so a check that resolved
379
+ * `insufficient-evidence` never records `not-evaluable`, which AD-33 forbids
380
+ * and which row 9 of the ladder makes reachable. Rows 6, 7, and 8 partition
381
+ * satisfaction against citation, so the table is total.
382
+ *
383
+ * A `disagrees` is diagnostic and moves nothing on its own, and it carries the
384
+ * whole cost of the tail collapsing to `confirmed`. Row 3 is where an
385
+ * `unmapped` or `signatureless` citation records that the evaluator and the
386
+ * oracle are pointing at different defects.
387
+ *
388
+ * Row 5 widens AD-33's `not-evaluable` from unreached steps to any `null` root
389
+ * resolution, which is the same condition reached by a second route: an oracle
390
+ * whose `check` is `null`, half of what `oracle-missing-channel` fires on.
391
+ */
392
+ export declare const CORROBORATION_RULES: readonly [{
393
+ readonly id: 'disposition-unsupported';
394
+ readonly guard: 'the disposition is `held` or `violated` with empty `observationIds`';
395
+ readonly value: '`disagrees`';
396
+ readonly holds: typeof dispositionUnsupported;
397
+ readonly corroboration: () => "disagrees";
398
+ }, {
399
+ readonly id: 'disposition-contradicts-evidence';
400
+ readonly guard: '`violated` with no defect finding, `held` with one, or `not-attempted` with one';
401
+ readonly value: '`disagrees`';
402
+ readonly holds: typeof dispositionContradictsEvidence;
403
+ readonly corroboration: () => "disagrees";
404
+ }, {
405
+ readonly id: 'citation-declined';
406
+ readonly guard: "the cited finding's bucket is `unmapped` or `signatureless`";
407
+ readonly value: '`disagrees`';
408
+ readonly holds: typeof citationDeclined;
409
+ readonly corroboration: () => "disagrees";
410
+ }, {
411
+ readonly id: 'examined-nothing';
412
+ readonly guard: 'the check root resolved `insufficient-evidence`';
413
+ readonly value: '`disagrees` where a defect finding cited the oracle, `agrees` where none did';
414
+ readonly holds: typeof checkExaminedNothing;
415
+ readonly corroboration: (inputs: OutcomeInputs) => "agrees" | "disagrees";
416
+ }, {
417
+ readonly id: 'never-ran';
418
+ readonly guard: 'the final state is `unreached`, or the check root resolution is `null`';
419
+ readonly value: '`not-evaluable`';
420
+ readonly holds: (inputs: OutcomeInputs, state: "abstained" | "bypassed" | "caught" | "confirmed" | "false-positive" | "infrastructure-error" | "judge-error" | "missed" | "not-applicable" | "oracle-error" | "passed-clean-control" | "unreached") => boolean;
421
+ readonly corroboration: () => "not-evaluable";
422
+ }, {
423
+ readonly id: 'check-confirms-silence';
424
+ readonly guard: 'the check satisfies and no defect finding cited the oracle';
425
+ readonly value: '`agrees`';
426
+ readonly holds: (inputs: OutcomeInputs) => boolean;
427
+ readonly corroboration: () => "agrees";
428
+ }, {
429
+ readonly id: 'check-confirms-finding';
430
+ readonly guard: 'the check does not satisfy and a defect finding cited the oracle';
431
+ readonly value: '`agrees`';
432
+ readonly holds: (inputs: OutcomeInputs) => boolean;
433
+ readonly corroboration: () => "agrees";
434
+ }, {
435
+ readonly id: 'check-and-findings-diverge';
436
+ readonly guard: 'the check satisfies with a finding cited, or does not satisfy with none';
437
+ readonly value: '`disagrees`';
438
+ readonly holds: (inputs: OutcomeInputs) => boolean;
439
+ readonly corroboration: () => "disagrees";
440
+ }];
441
+ export type CorroborationRuleId = (typeof CORROBORATION_RULES)[number]['id'];
442
+ /**
443
+ * AD-33's total reference decision procedure. One AD-6 state, one
444
+ * corroboration value, the rules that produced them, and the evidence the
445
+ * resolution read.
446
+ */
447
+ export declare function resolveOutcome(inputs: OutcomeInputs): OutcomeResolution;
448
+ /**
449
+ * The findings citing no oracle. AD-33 keeps them: discarding one would hide
450
+ * the evaluator-chosen detection AD-23 exists to preserve. Named apart from
451
+ * the artifact's own `uncitedFindings` field so the two do not collide, and
452
+ * covering every finding type, since AD-23's carve-out is about the oracle
453
+ * citation.
454
+ */
455
+ export declare function uncitedFindingIds(record: Pick<SealedRunRecord, 'findings'>): readonly string[];
456
+ /**
457
+ * Owed item 5: every uncited `defect` finding, as `UncitedFindingGap`'s
458
+ * persisted shape. Deliberately not a rename or extension of
459
+ * `uncitedFindingIds` above: that function is broader (every finding type)
460
+ * and thinner (an identifier only), and already backs the artifact's own bare
461
+ * `uncitedFindings` field; this one is narrower (`defect` only, since only
462
+ * that branch carries `quotedEvidence`) and richer (the full gap record), and
463
+ * the two coexist rather than one replacing the other.
464
+ */
465
+ export declare function uncitedDefectFindingGaps(record: Pick<SealedRunRecord, 'findings'>): readonly UncitedFindingGap[];
466
+ export {};