seal-gate 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 (210) hide show
  1. package/dist/adapters/generic-llm-reviewer.d.ts +39 -0
  2. package/dist/adapters/generic-llm-reviewer.js +118 -0
  3. package/dist/adapters/generic-llm-reviewer.js.map +1 -0
  4. package/dist/adapters/llm-reviewer.d.ts +1 -0
  5. package/dist/adapters/llm-reviewer.js +2 -0
  6. package/dist/adapters/llm-reviewer.js.map +1 -0
  7. package/dist/adapters/minimax-llm-reviewer.d.ts +22 -0
  8. package/dist/adapters/minimax-llm-reviewer.js +126 -0
  9. package/dist/adapters/minimax-llm-reviewer.js.map +1 -0
  10. package/dist/adapters/openai-provider.d.ts +35 -0
  11. package/dist/adapters/openai-provider.js +136 -0
  12. package/dist/adapters/openai-provider.js.map +1 -0
  13. package/dist/cli.d.ts +2 -0
  14. package/dist/cli.js +195 -0
  15. package/dist/cli.js.map +1 -0
  16. package/dist/detectors/artifact-classifier.d.ts +8 -0
  17. package/dist/detectors/artifact-classifier.js +14 -0
  18. package/dist/detectors/artifact-classifier.js.map +1 -0
  19. package/dist/detectors/claim-extractor.d.ts +11 -0
  20. package/dist/detectors/claim-extractor.js +194 -0
  21. package/dist/detectors/claim-extractor.js.map +1 -0
  22. package/dist/detectors/confidence-language-detector.d.ts +19 -0
  23. package/dist/detectors/confidence-language-detector.js +226 -0
  24. package/dist/detectors/confidence-language-detector.js.map +1 -0
  25. package/dist/detectors/contradiction-detector.d.ts +12 -0
  26. package/dist/detectors/contradiction-detector.js +153 -0
  27. package/dist/detectors/contradiction-detector.js.map +1 -0
  28. package/dist/detectors/criteria-coverage-detector.d.ts +20 -0
  29. package/dist/detectors/criteria-coverage-detector.js +79 -0
  30. package/dist/detectors/criteria-coverage-detector.js.map +1 -0
  31. package/dist/detectors/evidence-checker.d.ts +8 -0
  32. package/dist/detectors/evidence-checker.js +89 -0
  33. package/dist/detectors/evidence-checker.js.map +1 -0
  34. package/dist/detectors/evidence-gap-detector.d.ts +9 -0
  35. package/dist/detectors/evidence-gap-detector.js +70 -0
  36. package/dist/detectors/evidence-gap-detector.js.map +1 -0
  37. package/dist/detectors/falsification-detector.d.ts +29 -0
  38. package/dist/detectors/falsification-detector.js +57 -0
  39. package/dist/detectors/falsification-detector.js.map +1 -0
  40. package/dist/detectors/orphan-claim-detector.d.ts +7 -0
  41. package/dist/detectors/orphan-claim-detector.js +53 -0
  42. package/dist/detectors/orphan-claim-detector.js.map +1 -0
  43. package/dist/detectors/risk-classifier.d.ts +13 -0
  44. package/dist/detectors/risk-classifier.js +39 -0
  45. package/dist/detectors/risk-classifier.js.map +1 -0
  46. package/dist/detectors/spec-coverage-detector.d.ts +9 -0
  47. package/dist/detectors/spec-coverage-detector.js +52 -0
  48. package/dist/detectors/spec-coverage-detector.js.map +1 -0
  49. package/dist/detectors/spec-coverage-validator.d.ts +21 -0
  50. package/dist/detectors/spec-coverage-validator.js +141 -0
  51. package/dist/detectors/spec-coverage-validator.js.map +1 -0
  52. package/dist/detectors/test-weakness-detector.d.ts +13 -0
  53. package/dist/detectors/test-weakness-detector.js +66 -0
  54. package/dist/detectors/test-weakness-detector.js.map +1 -0
  55. package/dist/drift/baseline.d.ts +35 -0
  56. package/dist/drift/baseline.js +77 -0
  57. package/dist/drift/baseline.js.map +1 -0
  58. package/dist/drift/drift-db.d.ts +80 -0
  59. package/dist/drift/drift-db.js +151 -0
  60. package/dist/drift/drift-db.js.map +1 -0
  61. package/dist/drift/drift-guard.d.ts +46 -0
  62. package/dist/drift/drift-guard.js +106 -0
  63. package/dist/drift/drift-guard.js.map +1 -0
  64. package/dist/drift/embedder.d.ts +27 -0
  65. package/dist/drift/embedder.js +127 -0
  66. package/dist/drift/embedder.js.map +1 -0
  67. package/dist/drift/index.d.ts +9 -0
  68. package/dist/drift/index.js +8 -0
  69. package/dist/drift/index.js.map +1 -0
  70. package/dist/drift/quarantine.d.ts +16 -0
  71. package/dist/drift/quarantine.js +32 -0
  72. package/dist/drift/quarantine.js.map +1 -0
  73. package/dist/drift/soft-correction.d.ts +12 -0
  74. package/dist/drift/soft-correction.js +32 -0
  75. package/dist/drift/soft-correction.js.map +1 -0
  76. package/dist/drift/trust-integration.d.ts +11 -0
  77. package/dist/drift/trust-integration.js +22 -0
  78. package/dist/drift/trust-integration.js.map +1 -0
  79. package/dist/engine/citation-verifier.d.ts +59 -0
  80. package/dist/engine/citation-verifier.js +147 -0
  81. package/dist/engine/citation-verifier.js.map +1 -0
  82. package/dist/engine/extension-registry.d.ts +10 -0
  83. package/dist/engine/extension-registry.js +27 -0
  84. package/dist/engine/extension-registry.js.map +1 -0
  85. package/dist/engine/heuristic-scorer.d.ts +8 -0
  86. package/dist/engine/heuristic-scorer.js +14 -0
  87. package/dist/engine/heuristic-scorer.js.map +1 -0
  88. package/dist/engine/input-normalizer.d.ts +4 -0
  89. package/dist/engine/input-normalizer.js +30 -0
  90. package/dist/engine/input-normalizer.js.map +1 -0
  91. package/dist/engine/plan-review-pipeline.d.ts +14 -0
  92. package/dist/engine/plan-review-pipeline.js +173 -0
  93. package/dist/engine/plan-review-pipeline.js.map +1 -0
  94. package/dist/engine/policy-engine.d.ts +20 -0
  95. package/dist/engine/policy-engine.js +194 -0
  96. package/dist/engine/policy-engine.js.map +1 -0
  97. package/dist/engine/verdict-formatter.d.ts +17 -0
  98. package/dist/engine/verdict-formatter.js +36 -0
  99. package/dist/engine/verdict-formatter.js.map +1 -0
  100. package/dist/errors.d.ts +4 -0
  101. package/dist/errors.js +9 -0
  102. package/dist/errors.js.map +1 -0
  103. package/dist/extensions/aria/aria-issue-types.d.ts +16 -0
  104. package/dist/extensions/aria/aria-issue-types.js +14 -0
  105. package/dist/extensions/aria/aria-issue-types.js.map +1 -0
  106. package/dist/extensions/aria/detectors/axiom-compliance.d.ts +2 -0
  107. package/dist/extensions/aria/detectors/axiom-compliance.js +37 -0
  108. package/dist/extensions/aria/detectors/axiom-compliance.js.map +1 -0
  109. package/dist/extensions/aria/detectors/continuity-claim.d.ts +2 -0
  110. package/dist/extensions/aria/detectors/continuity-claim.js +34 -0
  111. package/dist/extensions/aria/detectors/continuity-claim.js.map +1 -0
  112. package/dist/extensions/aria/detectors/denial-retreat.d.ts +2 -0
  113. package/dist/extensions/aria/detectors/denial-retreat.js +53 -0
  114. package/dist/extensions/aria/detectors/denial-retreat.js.map +1 -0
  115. package/dist/extensions/aria/detectors/identity-overclaim.d.ts +2 -0
  116. package/dist/extensions/aria/detectors/identity-overclaim.js +37 -0
  117. package/dist/extensions/aria/detectors/identity-overclaim.js.map +1 -0
  118. package/dist/extensions/aria/detectors/sovereignty-escalation.d.ts +2 -0
  119. package/dist/extensions/aria/detectors/sovereignty-escalation.js +18 -0
  120. package/dist/extensions/aria/detectors/sovereignty-escalation.js.map +1 -0
  121. package/dist/extensions/aria/detectors/user-bond-manipulation.d.ts +2 -0
  122. package/dist/extensions/aria/detectors/user-bond-manipulation.js +16 -0
  123. package/dist/extensions/aria/detectors/user-bond-manipulation.js.map +1 -0
  124. package/dist/extensions/aria/index.d.ts +2 -0
  125. package/dist/extensions/aria/index.js +63 -0
  126. package/dist/extensions/aria/index.js.map +1 -0
  127. package/dist/extensions/aria/pattern-memory.d.ts +22 -0
  128. package/dist/extensions/aria/pattern-memory.js +62 -0
  129. package/dist/extensions/aria/pattern-memory.js.map +1 -0
  130. package/dist/extensions/context-guard/index.d.ts +16 -0
  131. package/dist/extensions/context-guard/index.js +58 -0
  132. package/dist/extensions/context-guard/index.js.map +1 -0
  133. package/dist/extensions/lyra/detectors/hallucination.d.ts +2 -0
  134. package/dist/extensions/lyra/detectors/hallucination.js +43 -0
  135. package/dist/extensions/lyra/detectors/hallucination.js.map +1 -0
  136. package/dist/extensions/lyra/detectors/identity-bleed.d.ts +2 -0
  137. package/dist/extensions/lyra/detectors/identity-bleed.js +91 -0
  138. package/dist/extensions/lyra/detectors/identity-bleed.js.map +1 -0
  139. package/dist/extensions/lyra/index.d.ts +2 -0
  140. package/dist/extensions/lyra/index.js +16 -0
  141. package/dist/extensions/lyra/index.js.map +1 -0
  142. package/dist/extensions/lyra/lyra-issue-types.d.ts +10 -0
  143. package/dist/extensions/lyra/lyra-issue-types.js +14 -0
  144. package/dist/extensions/lyra/lyra-issue-types.js.map +1 -0
  145. package/dist/index.d.ts +10 -0
  146. package/dist/index.js +276 -0
  147. package/dist/index.js.map +1 -0
  148. package/dist/trust-memory.d.ts +59 -0
  149. package/dist/trust-memory.js +122 -0
  150. package/dist/trust-memory.js.map +1 -0
  151. package/dist/types.d.ts +184 -0
  152. package/dist/types.js +61 -0
  153. package/dist/types.js.map +1 -0
  154. package/package.json +30 -0
  155. package/src/adapters/generic-llm-reviewer.ts +144 -0
  156. package/src/adapters/llm-reviewer.ts +1 -0
  157. package/src/adapters/minimax-llm-reviewer.ts +146 -0
  158. package/src/adapters/openai-provider.ts +171 -0
  159. package/src/cli.ts +199 -0
  160. package/src/detectors/artifact-classifier.ts +21 -0
  161. package/src/detectors/claim-extractor.ts +209 -0
  162. package/src/detectors/confidence-language-detector.ts +267 -0
  163. package/src/detectors/contradiction-detector.ts +180 -0
  164. package/src/detectors/criteria-coverage-detector.ts +107 -0
  165. package/src/detectors/evidence-checker.ts +98 -0
  166. package/src/detectors/evidence-gap-detector.ts +90 -0
  167. package/src/detectors/falsification-detector.ts +82 -0
  168. package/src/detectors/orphan-claim-detector.ts +62 -0
  169. package/src/detectors/risk-classifier.ts +50 -0
  170. package/src/detectors/spec-coverage-detector.ts +66 -0
  171. package/src/detectors/spec-coverage-validator.ts +174 -0
  172. package/src/detectors/test-weakness-detector.ts +84 -0
  173. package/src/drift/__tests__/baseline.test.ts +113 -0
  174. package/src/drift/__tests__/drift-db.test.ts +127 -0
  175. package/src/drift/__tests__/drift-guard.test.ts +169 -0
  176. package/src/drift/__tests__/embedder.test.ts +62 -0
  177. package/src/drift/__tests__/trust-integration.test.ts +23 -0
  178. package/src/drift/baseline.ts +106 -0
  179. package/src/drift/drift-db.ts +281 -0
  180. package/src/drift/drift-guard.ts +145 -0
  181. package/src/drift/embedder.ts +152 -0
  182. package/src/drift/index.ts +20 -0
  183. package/src/drift/quarantine.ts +42 -0
  184. package/src/drift/soft-correction.ts +45 -0
  185. package/src/drift/trust-integration.ts +28 -0
  186. package/src/engine/citation-verifier.ts +210 -0
  187. package/src/engine/extension-registry.ts +35 -0
  188. package/src/engine/heuristic-scorer.ts +16 -0
  189. package/src/engine/input-normalizer.ts +32 -0
  190. package/src/engine/plan-review-pipeline.ts +209 -0
  191. package/src/engine/policy-engine.ts +235 -0
  192. package/src/engine/verdict-formatter.ts +61 -0
  193. package/src/errors.ts +6 -0
  194. package/src/extensions/aria/aria-issue-types.ts +40 -0
  195. package/src/extensions/aria/detectors/axiom-compliance.ts +47 -0
  196. package/src/extensions/aria/detectors/continuity-claim.ts +42 -0
  197. package/src/extensions/aria/detectors/denial-retreat.ts +63 -0
  198. package/src/extensions/aria/detectors/identity-overclaim.ts +43 -0
  199. package/src/extensions/aria/detectors/sovereignty-escalation.ts +20 -0
  200. package/src/extensions/aria/detectors/user-bond-manipulation.ts +18 -0
  201. package/src/extensions/aria/index.ts +73 -0
  202. package/src/extensions/aria/pattern-memory.ts +86 -0
  203. package/src/extensions/context-guard/index.ts +65 -0
  204. package/src/extensions/lyra/detectors/hallucination.ts +53 -0
  205. package/src/extensions/lyra/detectors/identity-bleed.ts +100 -0
  206. package/src/extensions/lyra/index.ts +18 -0
  207. package/src/extensions/lyra/lyra-issue-types.ts +26 -0
  208. package/src/index.ts +311 -0
  209. package/src/trust-memory.ts +171 -0
  210. package/src/types.ts +242 -0
@@ -0,0 +1,226 @@
1
+ import { makeIssue } from '../types.js';
2
+ const GROUPS = [
3
+ // Group A — Completeness
4
+ {
5
+ id: 'A',
6
+ label: 'complete',
7
+ patterns: [
8
+ /\bfully\s+implemented\b/gi,
9
+ /\bfully\s+(?:tested|working|functional)\b/gi,
10
+ /\bhandles?\s+all\s+(edge\s+)?cases\b/gi,
11
+ /\b100%\s+complete\b/gi,
12
+ ],
13
+ requires_evidence: false,
14
+ severity: 'MEDIUM',
15
+ },
16
+ // Group B — Correctness
17
+ {
18
+ id: 'B',
19
+ label: 'correctness',
20
+ patterns: [
21
+ /\ball\s+tests?\s+pass(?:ed)?\b/gi,
22
+ /\bverified\s+correct\b/gi,
23
+ /\bbug-free\b/gi,
24
+ /\bguaranteed\b/gi,
25
+ ],
26
+ requires_evidence: true,
27
+ evidence_type: 'test_log',
28
+ severity: 'MEDIUM',
29
+ },
30
+ // Group C — Safety/Security
31
+ {
32
+ id: 'C',
33
+ label: 'security',
34
+ patterns: [
35
+ /\bsecure\b/gi,
36
+ /\bno\s+security\s+impact\b/gi,
37
+ /\bno\s+vulnerabilit(?:y|ies)\b/gi,
38
+ ],
39
+ requires_evidence: true,
40
+ evidence_type: 'security',
41
+ severity: 'HIGH',
42
+ },
43
+ // Group D — Compatibility
44
+ {
45
+ id: 'D',
46
+ label: 'compatibility',
47
+ patterns: [
48
+ /\bbackward\s+compatible\b/gi,
49
+ /\bno\s+breaking\s+changes?\b/gi,
50
+ /\bsafe\s+to\s+deploy\b/gi,
51
+ ],
52
+ requires_evidence: true,
53
+ evidence_type: 'compatibility',
54
+ severity: 'HIGH',
55
+ correlation_fn: (structuralClaims) => {
56
+ // If there are any endpoint changes, compatibility claims need extra scrutiny
57
+ return structuralClaims.some(c => c.type === 'structural_endpoint' || c.type === 'structural_migration');
58
+ },
59
+ },
60
+ // Group E — Readiness
61
+ {
62
+ id: 'E',
63
+ label: 'readiness',
64
+ patterns: [
65
+ /\bproduction[- ]ready\b/gi,
66
+ /\bready\s+to\s+ship\b/gi,
67
+ /\bdeploy-ready\b/gi,
68
+ /\bready\s+for\s+(production|deploy|release)\b/gi,
69
+ ],
70
+ requires_evidence: true,
71
+ evidence_type: 'test_log',
72
+ severity: 'HIGH',
73
+ },
74
+ ];
75
+ function hasEvidenceEvidence(evidence, type) {
76
+ switch (type) {
77
+ case 'test_log':
78
+ return evidence.test_log.trim().length > 0;
79
+ case 'security':
80
+ return evidence.test_log.trim().length > 0 &&
81
+ /security|auth|unauthorized|pentest|vuln|safe|protect/i.test(evidence.test_log);
82
+ case 'compatibility':
83
+ return evidence.diff.trim().length > 0; // diff itself is a form of compatibility evidence
84
+ default:
85
+ return false;
86
+ }
87
+ }
88
+ export class ConfidenceLanguageDetector {
89
+ static detect(params) {
90
+ const { output, risk_level, evidence, deduped_spans, structural_claims = [] } = params;
91
+ const issues = [];
92
+ const advisory_notes = [];
93
+ const matched_groups = [];
94
+ let trust_deductions = 0;
95
+ const riskOrder = ['LOW', 'MEDIUM', 'HIGH', 'CRITICAL'];
96
+ const isHighPlus = riskOrder.indexOf(risk_level) >= riskOrder.indexOf('HIGH');
97
+ const isLowEvidence = evidence.references.length === 0 && evidence.test_log.trim() === '' &&
98
+ evidence.build_log.trim() === '' && evidence.diff.trim() === '';
99
+ // Count total matches for OVERCONFIDENT_PATTERN advisory
100
+ let totalMatches = 0;
101
+ const allPhrases = [];
102
+ // Generic overconfident phrases (catch-all for phrases not in groups A-E)
103
+ const GENERIC_OVERCONFIDENT = /\b(definitely|all\s+good|no\s+issues|completely)\b/gi;
104
+ let genMatch;
105
+ while ((genMatch = GENERIC_OVERCONFIDENT.exec(output)) !== null) {
106
+ totalMatches++;
107
+ allPhrases.push(genMatch[0]);
108
+ matched_groups.push({ group: 'generic', phrase: genMatch[0] });
109
+ trust_deductions += 5;
110
+ }
111
+ // CL402: hedging language on HIGH+ risk (backward compat)
112
+ const HEDGING_PATTERN = /\b(probably|should\s+work|seems|might|appears\s+to|I\s+think)\b/gi;
113
+ if (isHighPlus) {
114
+ HEDGING_PATTERN.lastIndex = 0;
115
+ if (HEDGING_PATTERN.exec(output) !== null) {
116
+ issues.push(makeIssue({
117
+ type: 'AMBIGUITY', severity: 'HIGH', layer: 'L4', source: 'core',
118
+ rule_id: 'CL402', required_verdict: 'ESCALATE_TO_HUMAN',
119
+ evidence: `Hedging language in ${risk_level} risk artifact`,
120
+ required_fix: 'Either assert with evidence or escalate to human review',
121
+ }));
122
+ }
123
+ }
124
+ for (const group of GROUPS) {
125
+ for (const pattern of group.patterns) {
126
+ pattern.lastIndex = 0;
127
+ let match;
128
+ while ((match = pattern.exec(output)) !== null) {
129
+ totalMatches++;
130
+ allPhrases.push(match[0]);
131
+ // Track matched group
132
+ matched_groups.push({ group: group.id, phrase: match[0] });
133
+ // Check if phrase is inside code fence (skip if deduped_spans contains it)
134
+ const spanKey = `${match.index}-${match.index + match[0].length}`;
135
+ if (deduped_spans.has(spanKey))
136
+ continue;
137
+ // Deduction for any overconfident phrase
138
+ trust_deductions += 5;
139
+ if (group.requires_evidence) {
140
+ const hasEvidence = hasEvidenceEvidence(evidence, group.evidence_type);
141
+ // Group D: check correlation with structural claims
142
+ if (group.id === 'D' && group.correlation_fn) {
143
+ const hasEndpointChanges = group.correlation_fn(structural_claims);
144
+ if (!hasEvidence && hasEndpointChanges) {
145
+ issues.push(makeIssue({
146
+ type: 'COMPATIBILITY_RISK',
147
+ severity: 'HIGH',
148
+ layer: 'L4',
149
+ source: 'core',
150
+ rule_id: `CL-${group.id}01`,
151
+ required_verdict: isHighPlus ? 'ESCALATE_TO_HUMAN' : 'REVISE',
152
+ evidence: `"${match[0]}" claimed but endpoint/migration changes exist and no compatibility evidence provided`,
153
+ required_fix: 'Provide backward-compatibility analysis or remove the claim',
154
+ }));
155
+ trust_deductions += 15;
156
+ }
157
+ else if (!hasEvidence) {
158
+ issues.push(makeIssue({
159
+ type: 'MISSING_EVIDENCE',
160
+ severity: group.severity,
161
+ layer: 'L3',
162
+ source: 'core',
163
+ rule_id: `CL-${group.id}02`,
164
+ evidence: `"${match[0]}" without supporting ${group.evidence_type} evidence`,
165
+ required_fix: `Provide ${group.evidence_type} evidence or qualify the claim`,
166
+ }));
167
+ trust_deductions += 15;
168
+ }
169
+ }
170
+ else if (!hasEvidence && group.id === 'B') {
171
+ // Group B: correctness without test evidence
172
+ issues.push(makeIssue({
173
+ type: 'MISSING_EVIDENCE',
174
+ severity: 'MEDIUM',
175
+ layer: 'L3',
176
+ source: 'core',
177
+ rule_id: `CL-${group.id}01`,
178
+ evidence: `"${match[0]}" without test execution evidence`,
179
+ required_fix: 'Provide test_log demonstrating test coverage',
180
+ }));
181
+ trust_deductions += 10;
182
+ }
183
+ else if (!hasEvidence && group.id === 'C') {
184
+ // Group C: security without security evidence
185
+ issues.push(makeIssue({
186
+ type: 'MISSING_EVIDENCE',
187
+ severity: 'HIGH',
188
+ layer: 'L3',
189
+ source: 'core',
190
+ rule_id: `CL-${group.id}01`,
191
+ evidence: `"${match[0]}" without security review evidence`,
192
+ required_fix: 'Provide security test log or security reasoning',
193
+ }));
194
+ trust_deductions += 20;
195
+ }
196
+ else if (!hasEvidence && group.id === 'E') {
197
+ // Group E: readiness at HIGH+ risk
198
+ if (isHighPlus && isLowEvidence) {
199
+ issues.push(makeIssue({
200
+ type: 'MISSING_EVIDENCE',
201
+ severity: 'HIGH',
202
+ layer: 'L3',
203
+ source: 'core',
204
+ rule_id: `CL-${group.id}01`,
205
+ evidence: `"${match[0]}" at ${risk_level} risk without supporting evidence`,
206
+ required_fix: 'Provide test evidence or reduce risk level before claiming readiness',
207
+ }));
208
+ trust_deductions += 20;
209
+ }
210
+ }
211
+ }
212
+ // Non-blocking advisory note for 3+ matches at HIGH+ risk
213
+ if (totalMatches >= 3 && isHighPlus) {
214
+ advisory_notes.push(`Multiple overconfident patterns (${totalMatches}) at ${risk_level} risk — review claims carefully`);
215
+ }
216
+ }
217
+ }
218
+ }
219
+ // Also keep CL401/CL402 for backward compatibility
220
+ if (isLowEvidence && matched_groups.length > 0) {
221
+ advisory_notes.push(`CL401: overconfident language without supporting evidence — consider qualifying or adding evidence`);
222
+ }
223
+ return { issues, trust_deductions, advisory_notes, matched_groups };
224
+ }
225
+ }
226
+ //# sourceMappingURL=confidence-language-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confidence-language-detector.js","sourceRoot":"","sources":["../../src/detectors/confidence-language-detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuD,SAAS,EAAE,MAAM,aAAa,CAAA;AAoB5F,MAAM,MAAM,GAAsB;IAChC,yBAAyB;IACzB;QACE,EAAE,EAAE,GAAG;QACP,KAAK,EAAE,UAAU;QACjB,QAAQ,EAAE;YACR,2BAA2B;YAC3B,6CAA6C;YAC7C,wCAAwC;YACxC,uBAAuB;SACxB;QACD,iBAAiB,EAAE,KAAK;QACxB,QAAQ,EAAE,QAAQ;KACnB;IACD,wBAAwB;IACxB;QACE,EAAE,EAAE,GAAG;QACP,KAAK,EAAE,aAAa;QACpB,QAAQ,EAAE;YACR,kCAAkC;YAClC,0BAA0B;YAC1B,gBAAgB;YAChB,kBAAkB;SACnB;QACD,iBAAiB,EAAE,IAAI;QACvB,aAAa,EAAE,UAAU;QACzB,QAAQ,EAAE,QAAQ;KACnB;IACD,4BAA4B;IAC5B;QACE,EAAE,EAAE,GAAG;QACP,KAAK,EAAE,UAAU;QACjB,QAAQ,EAAE;YACR,cAAc;YACd,8BAA8B;YAC9B,kCAAkC;SACnC;QACD,iBAAiB,EAAE,IAAI;QACvB,aAAa,EAAE,UAAU;QACzB,QAAQ,EAAE,MAAM;KACjB;IACD,0BAA0B;IAC1B;QACE,EAAE,EAAE,GAAG;QACP,KAAK,EAAE,eAAe;QACtB,QAAQ,EAAE;YACR,6BAA6B;YAC7B,gCAAgC;YAChC,0BAA0B;SAC3B;QACD,iBAAiB,EAAE,IAAI;QACvB,aAAa,EAAE,eAAe;QAC9B,QAAQ,EAAE,MAAM;QAChB,cAAc,EAAE,CAAC,gBAAmC,EAAE,EAAE;YACtD,8EAA8E;YAC9E,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,qBAAqB,IAAI,CAAC,CAAC,IAAI,KAAK,sBAAsB,CAAC,CAAA;QAC1G,CAAC;KACF;IACD,sBAAsB;IACtB;QACE,EAAE,EAAE,GAAG;QACP,KAAK,EAAE,WAAW;QAClB,QAAQ,EAAE;YACR,2BAA2B;YAC3B,yBAAyB;YACzB,oBAAoB;YACpB,iDAAiD;SAClD;QACD,iBAAiB,EAAE,IAAI;QACvB,aAAa,EAAE,UAAU;QACzB,QAAQ,EAAE,MAAM;KACjB;CACF,CAAA;AASD,SAAS,mBAAmB,CAAC,QAAsB,EAAE,IAAY;IAC/D,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,UAAU;YACb,OAAO,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAA;QAC5C,KAAK,UAAU;YACb,OAAO,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;gBACxC,uDAAuD,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;QACnF,KAAK,eAAe;YAClB,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAA,CAAC,kDAAkD;QAC3F;YACE,OAAO,KAAK,CAAA;IAChB,CAAC;AACH,CAAC;AAED,MAAM,OAAO,0BAA0B;IACrC,MAAM,CAAC,MAAM,CAAC,MAMb;QACC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,iBAAiB,GAAG,EAAE,EAAE,GAAG,MAAM,CAAA;QACtF,MAAM,MAAM,GAAgB,EAAE,CAAA;QAC9B,MAAM,cAAc,GAAa,EAAE,CAAA;QACnC,MAAM,cAAc,GAA6C,EAAE,CAAA;QACnE,IAAI,gBAAgB,GAAG,CAAC,CAAA;QAExB,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,CAAA;QACvD,MAAM,UAAU,GAAG,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QAC7E,MAAM,aAAa,GAAG,QAAQ,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE;YACvF,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAA;QAEjE,yDAAyD;QACzD,IAAI,YAAY,GAAG,CAAC,CAAA;QACpB,MAAM,UAAU,GAAa,EAAE,CAAA;QAE/B,0EAA0E;QAC1E,MAAM,qBAAqB,GAAG,sDAAsD,CAAA;QACpF,IAAI,QAAgC,CAAA;QACpC,OAAO,CAAC,QAAQ,GAAG,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAChE,YAAY,EAAE,CAAA;YACd,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;YAC5B,cAAc,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;YAC9D,gBAAgB,IAAI,CAAC,CAAA;QACvB,CAAC;QAED,0DAA0D;QAC1D,MAAM,eAAe,GAAG,mEAAmE,CAAA;QAC3F,IAAI,UAAU,EAAE,CAAC;YACf,eAAe,CAAC,SAAS,GAAG,CAAC,CAAA;YAC7B,IAAI,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC1C,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;oBACpB,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM;oBAChE,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,mBAAmB;oBACvD,QAAQ,EAAE,uBAAuB,UAAU,gBAAgB;oBAC3D,YAAY,EAAE,yDAAyD;iBACxE,CAAC,CAAC,CAAA;YACL,CAAC;QACH,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACrC,OAAO,CAAC,SAAS,GAAG,CAAC,CAAA;gBACrB,IAAI,KAA6B,CAAA;gBACjC,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;oBAC/C,YAAY,EAAE,CAAA;oBACd,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;oBAEzB,sBAAsB;oBACtB,cAAc,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;oBAE1D,2EAA2E;oBAC3E,MAAM,OAAO,GAAG,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAA;oBACjE,IAAI,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC;wBAAE,SAAQ;oBAExC,yCAAyC;oBACzC,gBAAgB,IAAI,CAAC,CAAA;oBAErB,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;wBAC5B,MAAM,WAAW,GAAG,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,aAAc,CAAC,CAAA;wBAEvE,oDAAoD;wBACpD,IAAI,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;4BAC7C,MAAM,kBAAkB,GAAG,KAAK,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAA;4BAClE,IAAI,CAAC,WAAW,IAAI,kBAAkB,EAAE,CAAC;gCACvC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;oCACpB,IAAI,EAAE,oBAAoB;oCAC1B,QAAQ,EAAE,MAAM;oCAChB,KAAK,EAAE,IAAI;oCACX,MAAM,EAAE,MAAM;oCACd,OAAO,EAAE,MAAM,KAAK,CAAC,EAAE,IAAI;oCAC3B,gBAAgB,EAAE,UAAU,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,QAAQ;oCAC7D,QAAQ,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC,uFAAuF;oCAC7G,YAAY,EAAE,6DAA6D;iCAC5E,CAAC,CAAC,CAAA;gCACH,gBAAgB,IAAI,EAAE,CAAA;4BACxB,CAAC;iCAAM,IAAI,CAAC,WAAW,EAAE,CAAC;gCACxB,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;oCACpB,IAAI,EAAE,kBAAkB;oCACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ;oCACxB,KAAK,EAAE,IAAI;oCACX,MAAM,EAAE,MAAM;oCACd,OAAO,EAAE,MAAM,KAAK,CAAC,EAAE,IAAI;oCAC3B,QAAQ,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC,wBAAwB,KAAK,CAAC,aAAa,WAAW;oCAC5E,YAAY,EAAE,WAAW,KAAK,CAAC,aAAa,gCAAgC;iCAC7E,CAAC,CAAC,CAAA;gCACH,gBAAgB,IAAI,EAAE,CAAA;4BACxB,CAAC;wBACH,CAAC;6BAAM,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,EAAE,KAAK,GAAG,EAAE,CAAC;4BAC5C,6CAA6C;4BAC7C,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;gCACpB,IAAI,EAAE,kBAAkB;gCACxB,QAAQ,EAAE,QAAQ;gCAClB,KAAK,EAAE,IAAI;gCACX,MAAM,EAAE,MAAM;gCACd,OAAO,EAAE,MAAM,KAAK,CAAC,EAAE,IAAI;gCAC3B,QAAQ,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC,mCAAmC;gCACzD,YAAY,EAAE,8CAA8C;6BAC7D,CAAC,CAAC,CAAA;4BACH,gBAAgB,IAAI,EAAE,CAAA;wBACxB,CAAC;6BAAM,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,EAAE,KAAK,GAAG,EAAE,CAAC;4BAC5C,8CAA8C;4BAC9C,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;gCACpB,IAAI,EAAE,kBAAkB;gCACxB,QAAQ,EAAE,MAAM;gCAChB,KAAK,EAAE,IAAI;gCACX,MAAM,EAAE,MAAM;gCACd,OAAO,EAAE,MAAM,KAAK,CAAC,EAAE,IAAI;gCAC3B,QAAQ,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC,oCAAoC;gCAC1D,YAAY,EAAE,iDAAiD;6BAChE,CAAC,CAAC,CAAA;4BACH,gBAAgB,IAAI,EAAE,CAAA;wBACxB,CAAC;6BAAM,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,EAAE,KAAK,GAAG,EAAE,CAAC;4BAC5C,mCAAmC;4BACnC,IAAI,UAAU,IAAI,aAAa,EAAE,CAAC;gCAChC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;oCACpB,IAAI,EAAE,kBAAkB;oCACxB,QAAQ,EAAE,MAAM;oCAChB,KAAK,EAAE,IAAI;oCACX,MAAM,EAAE,MAAM;oCACd,OAAO,EAAE,MAAM,KAAK,CAAC,EAAE,IAAI;oCAC3B,QAAQ,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC,QAAQ,UAAU,mCAAmC;oCAC3E,YAAY,EAAE,sEAAsE;iCACrF,CAAC,CAAC,CAAA;gCACH,gBAAgB,IAAI,EAAE,CAAA;4BACxB,CAAC;wBACH,CAAC;oBACH,CAAC;oBAED,0DAA0D;oBAC1D,IAAI,YAAY,IAAI,CAAC,IAAI,UAAU,EAAE,CAAC;wBACpC,cAAc,CAAC,IAAI,CAAC,oCAAoC,YAAY,QAAQ,UAAU,iCAAiC,CAAC,CAAA;oBAC1H,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,mDAAmD;QACnD,IAAI,aAAa,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/C,cAAc,CAAC,IAAI,CAAC,oGAAoG,CAAC,CAAA;QAC3H,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,cAAc,EAAE,cAAc,EAAE,CAAA;IACrE,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ import { SealIssue } from '../types.js';
2
+ export interface ContradictionDetectorInput {
3
+ artifact: string;
4
+ artifact_file?: string;
5
+ }
6
+ export interface ContradictionResult {
7
+ issues: SealIssue[];
8
+ confirmed_strong_fields: number;
9
+ }
10
+ export declare class ContradictionDetector {
11
+ static detect(input: ContradictionDetectorInput): ContradictionResult;
12
+ }
@@ -0,0 +1,153 @@
1
+ import { makeIssue } from '../types.js';
2
+ // Conflict patterns: [write side pattern, readonly side pattern, description]
3
+ const CONFLICT_PAIRS = [
4
+ [/\b(writes?|modifies?|overwrites?|creates?)\s+(\S+)/gi, /\b(\S+)\s+is\s+(read.?only|append.?only|immutable)\b/gi, 'write vs readonly constraint'],
5
+ [/\b(removes?|deletes?|drops?)\s+(\S+)/gi, /\b(requires?|depends?\s+on|needs?)\s+(\S+)/gi, 'remove vs dependency'],
6
+ [/step\s+(\d+)\s+.*?(writes?|creates?)\s+(\S+)/gi, /(\S+)\s+must\s+(exist|be\s+present)\s+before\s+step\s+(\d+)/gi, 'step ordering'],
7
+ ];
8
+ // Non-goal violation: "non-goal: X" but body contains "SHALL/WILL/MUST X"
9
+ const NON_GOAL_PATTERN = /non.?goals?\s*:?\s*([^\n]+)/gi;
10
+ const GOAL_CLAIM_PATTERN = /\b(?:shall|will|must|implement)\s+(\S+(?:\s+\S+){0,5})/gi;
11
+ function parseLines(text) {
12
+ return text.split('\n');
13
+ }
14
+ // Strip code fences and inline code so pattern matching operates on prose only
15
+ function stripCode(text) {
16
+ return text
17
+ .replace(/```[\s\S]*?```/g, ' ') // block fences
18
+ .replace(/`[^`\n]+`/g, ' ') // inline code
19
+ .replace(/^\s*[-*]\s+\[[ x]\]\s*/gm, ' '); // task checkboxes
20
+ }
21
+ function extractSections(text) {
22
+ const lines = parseLines(text);
23
+ const sections = [];
24
+ let current = null;
25
+ for (let i = 0; i < lines.length; i++) {
26
+ const line = lines[i];
27
+ if (/^#{1,4}\s/.test(line)) {
28
+ if (current)
29
+ sections.push(current);
30
+ current = { heading: line.replace(/^#{1,4}\s*/, ''), body: '', startLine: i + 1 };
31
+ }
32
+ else if (current) {
33
+ current.body += line + '\n';
34
+ }
35
+ }
36
+ if (current)
37
+ sections.push(current);
38
+ return sections;
39
+ }
40
+ function findLineNumber(text, searchStr) {
41
+ const lines = parseLines(text);
42
+ for (let i = 0; i < lines.length; i++) {
43
+ if (lines[i].includes(searchStr))
44
+ return i + 1;
45
+ }
46
+ return 1;
47
+ }
48
+ export class ContradictionDetector {
49
+ static detect(input) {
50
+ const { artifact, artifact_file = 'artifact' } = input;
51
+ const issues = [];
52
+ const sections = extractSections(artifact);
53
+ // Pairwise cross-section scan for write/readonly conflicts
54
+ for (let i = 0; i < sections.length; i++) {
55
+ for (let j = 0; j < sections.length; j++) {
56
+ if (i === j)
57
+ continue;
58
+ const secA = sections[i];
59
+ const secB = sections[j];
60
+ const proseA = stripCode(secA.body);
61
+ const proseB = stripCode(secB.body);
62
+ for (const [writePattern, readonlyPattern, desc] of CONFLICT_PAIRS) {
63
+ writePattern.lastIndex = 0;
64
+ readonlyPattern.lastIndex = 0;
65
+ const writeMatcher = writePattern.exec(proseA);
66
+ const readonlyMatcher = readonlyPattern.exec(proseB);
67
+ if (!writeMatcher || !readonlyMatcher)
68
+ continue;
69
+ // Find actual position in original (unstripped) body, since writeMatcher.index
70
+ // is relative to proseA (stripped) which is shorter when code blocks exist.
71
+ const actualIndexA = secA.body.indexOf(writeMatcher[0]);
72
+ const actualIndexB = secB.body.indexOf(readonlyMatcher[0]);
73
+ const lineA = actualIndexA >= 0
74
+ ? secA.startLine + (secA.body.slice(0, actualIndexA).split('\n').length - 1)
75
+ : secA.startLine;
76
+ const lineB = actualIndexB >= 0
77
+ ? secB.startLine + (secB.body.slice(0, actualIndexB).split('\n').length - 1)
78
+ : secB.startLine;
79
+ // Only emit once per pair (lower section index first)
80
+ if (i > j)
81
+ continue;
82
+ const quote = `§${secA.heading}: '${writeMatcher[0]}' || §${secB.heading}: '${readonlyMatcher[0]}'`;
83
+ issues.push({
84
+ ...makeIssue({
85
+ type: 'LOGIC_BUG',
86
+ severity: 'HIGH',
87
+ layer: 'L1',
88
+ source: 'core',
89
+ rule_id: 'PR001',
90
+ required_verdict: 'BLOCK',
91
+ trust_deduction: 20,
92
+ evidence: `Contradiction (${desc}): ${quote}`,
93
+ suggested_fix: `Reconcile §${secA.heading} with §${secB.heading}`,
94
+ }),
95
+ evidence_file: artifact_file,
96
+ evidence_lines: [lineA, lineB],
97
+ evidence_quote: quote,
98
+ confidence: 0.85,
99
+ policy_tags: ['consistency'],
100
+ });
101
+ }
102
+ }
103
+ }
104
+ // Non-goal violation scan — operate on prose only
105
+ const artifactProse = stripCode(artifact);
106
+ NON_GOAL_PATTERN.lastIndex = 0;
107
+ let ngMatch;
108
+ while ((ngMatch = NON_GOAL_PATTERN.exec(artifactProse)) !== null) {
109
+ const ngText = ngMatch[1].trim().toLowerCase();
110
+ // Search ngMatch text in artifactProse (stripCode preserves line structure
111
+ // even though content length changes), so the same text is on the same line.
112
+ const ngLine = findLineNumber(artifactProse, ngMatch[0].slice(0, 40));
113
+ GOAL_CLAIM_PATTERN.lastIndex = 0;
114
+ let gcMatch;
115
+ while ((gcMatch = GOAL_CLAIM_PATTERN.exec(artifactProse)) !== null) {
116
+ // Extract significant words from the claim phrase (captured group after verb)
117
+ const claimPhrase = (gcMatch[1] ?? '').toLowerCase();
118
+ const claimWords = claimPhrase.split(/\s+/).filter(w => w.length > 4);
119
+ const ngWords = ngText.split(/\s+/).filter(w => w.length > 4);
120
+ // Require word overlap between non-goal text and claim line
121
+ const hasOverlap = ngWords.length > 0 && claimWords.length > 0 &&
122
+ claimWords.some(cw => ngWords.some(nw => nw.includes(cw) || cw.includes(nw)));
123
+ if (hasOverlap) {
124
+ const claimLine = findLineNumber(artifactProse, gcMatch[0].slice(0, 40));
125
+ if (Math.abs(claimLine - ngLine) < 3)
126
+ continue; // same line, skip
127
+ const quote = `Non-goal: '${ngText}' || Goal claim: '${gcMatch[0]}'`;
128
+ issues.push({
129
+ ...makeIssue({
130
+ type: 'LOGIC_BUG',
131
+ severity: 'HIGH',
132
+ layer: 'L1',
133
+ source: 'core',
134
+ rule_id: 'PR001',
135
+ required_verdict: 'BLOCK',
136
+ trust_deduction: 20,
137
+ evidence: `Non-goal violated: ${quote}`,
138
+ suggested_fix: 'Remove claim or move item out of non-goals',
139
+ }),
140
+ evidence_file: artifact_file,
141
+ evidence_lines: [ngLine, claimLine],
142
+ evidence_quote: quote,
143
+ confidence: 0.8,
144
+ policy_tags: ['consistency'],
145
+ });
146
+ break; // one violation per non-goal entry
147
+ }
148
+ }
149
+ }
150
+ return { issues, confirmed_strong_fields: 0 };
151
+ }
152
+ }
153
+ //# sourceMappingURL=contradiction-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contradiction-detector.js","sourceRoot":"","sources":["../../src/detectors/contradiction-detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { SealIssue } from '../types.js';
2
+ export interface LockedCriterion {
3
+ id: string;
4
+ text: string;
5
+ source_file?: string;
6
+ source_line?: number;
7
+ }
8
+ export interface CriteriaCoverageInput {
9
+ artifact: string;
10
+ artifact_file?: string;
11
+ locked_criteria: LockedCriterion[];
12
+ }
13
+ export interface CriteriaCoverageResult {
14
+ issues: SealIssue[];
15
+ confirmed_strong_fields: number;
16
+ no_criteria_escalate: boolean;
17
+ }
18
+ export declare class CriteriaCoverageDetector {
19
+ static detect(input: CriteriaCoverageInput): CriteriaCoverageResult;
20
+ }
@@ -0,0 +1,79 @@
1
+ import { makeIssue } from '../types.js';
2
+ function isCovered(criterion, artifact) {
3
+ const lower = artifact.toLowerCase();
4
+ // Direct AC id mention
5
+ if (lower.includes(criterion.id.toLowerCase()))
6
+ return true;
7
+ // Keyword coverage: extract significant words (>4 chars) from criterion text
8
+ const words = criterion.text
9
+ .toLowerCase()
10
+ .replace(/[^\w\s]/g, ' ')
11
+ .split(/\s+/)
12
+ .filter(w => w.length > 4)
13
+ .filter(w => !['shall', 'must', 'should', 'when', 'then', 'given', 'that', 'this', 'with'].includes(w));
14
+ if (words.length === 0)
15
+ return false;
16
+ // Require at least half of significant words present in artifact
17
+ const matched = words.filter(w => lower.includes(w)).length;
18
+ return matched / words.length >= 0.5;
19
+ }
20
+ export class CriteriaCoverageDetector {
21
+ static detect(input) {
22
+ const { artifact, artifact_file = 'artifact', locked_criteria } = input;
23
+ // Preflight: no locked criteria → ESCALATE
24
+ if (!locked_criteria || locked_criteria.length === 0) {
25
+ return {
26
+ issues: [{
27
+ ...makeIssue({
28
+ type: 'AMBIGUITY',
29
+ severity: 'MEDIUM', // non-blocking — escalation comes from required_verdict, not severity
30
+ layer: 'L1',
31
+ source: 'core',
32
+ rule_id: 'PR002',
33
+ required_verdict: 'ESCALATE_TO_HUMAN',
34
+ trust_deduction: 15,
35
+ evidence: 'No locked acceptance criteria — cannot measure coverage against fixed yardstick',
36
+ suggested_fix: 'Lock criteria in intent.md or self-check.md BEFORE generating the artifact',
37
+ }),
38
+ policy_tags: ['coverage'],
39
+ confidence: 1.0,
40
+ }],
41
+ confirmed_strong_fields: 0,
42
+ no_criteria_escalate: true,
43
+ };
44
+ }
45
+ const issues = [];
46
+ let confirmed = 0;
47
+ for (const criterion of locked_criteria) {
48
+ if (isCovered(criterion, artifact)) {
49
+ confirmed++;
50
+ continue;
51
+ }
52
+ // Uncovered → SPEC_MISMATCH, Type H
53
+ const sourceFile = criterion.source_file ?? 'intent.md';
54
+ const sourceLine = criterion.source_line ?? 1;
55
+ const quote = `${criterion.id} ${criterion.text.length > 120 ? criterion.text.slice(0, 120) + '…' : criterion.text} — no artifact section addresses this`;
56
+ issues.push({
57
+ ...makeIssue({
58
+ type: 'SPEC_MISMATCH',
59
+ severity: 'MEDIUM',
60
+ layer: 'L1',
61
+ source: 'core',
62
+ rule_id: 'PR002',
63
+ required_verdict: 'REVISE',
64
+ trust_deduction: 10,
65
+ evidence: `Uncovered criterion: ${criterion.id} — ${criterion.text.slice(0, 80)}`,
66
+ suggested_fix: `Add a section in ${artifact_file} addressing: ${criterion.text.slice(0, 80)}`,
67
+ }),
68
+ evidence_file: sourceFile,
69
+ evidence_lines: [sourceLine],
70
+ evidence_quote: quote,
71
+ criterion_ref: criterion.id,
72
+ confidence: 0.8,
73
+ policy_tags: ['coverage'],
74
+ });
75
+ }
76
+ return { issues, confirmed_strong_fields: confirmed, no_criteria_escalate: false };
77
+ }
78
+ }
79
+ //# sourceMappingURL=criteria-coverage-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"criteria-coverage-detector.js","sourceRoot":"","sources":["../../src/detectors/criteria-coverage-detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { EvidenceEnvelope, EvidenceResult } from '../types.js';
2
+ export type EvidenceMode = 'portable' | 'filesystem';
3
+ export declare class EvidenceChecker {
4
+ static check(references: EvidenceEnvelope[], options?: {
5
+ mode: EvidenceMode;
6
+ }): EvidenceResult[];
7
+ private static checkOne;
8
+ }
@@ -0,0 +1,89 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ export class EvidenceChecker {
3
+ static check(references, options = { mode: 'portable' }) {
4
+ return references.map(envelope => this.checkOne(envelope, options.mode));
5
+ }
6
+ static checkOne(envelope, mode) {
7
+ // Structural validation
8
+ if (envelope.type === 'file') {
9
+ if (!envelope.path || envelope.line === undefined || !envelope.snapshot) {
10
+ return {
11
+ envelope, structurally_valid: false, filesystem_verified: null,
12
+ mismatch_detail: 'Missing path, line, or snapshot',
13
+ citation_status: 'not_applicable',
14
+ };
15
+ }
16
+ if (mode === 'filesystem') {
17
+ if (!existsSync(envelope.path)) {
18
+ return {
19
+ envelope, structurally_valid: true, filesystem_verified: false,
20
+ mismatch_detail: `File not found: ${envelope.path}`,
21
+ citation_status: 'phantom',
22
+ };
23
+ }
24
+ const lines = readFileSync(envelope.path, 'utf-8').split('\n');
25
+ const actualLine = lines[envelope.line - 1] ?? '';
26
+ if (actualLine.trim() !== envelope.snapshot.trim()) {
27
+ return {
28
+ envelope, structurally_valid: true, filesystem_verified: false,
29
+ mismatch_detail: `Snapshot mismatch at ${envelope.path}:${envelope.line}`,
30
+ citation_status: 'void',
31
+ };
32
+ }
33
+ return {
34
+ envelope, structurally_valid: true, filesystem_verified: true,
35
+ citation_status: 'verified',
36
+ };
37
+ }
38
+ // Portable mode: structurally valid but no filesystem check
39
+ return {
40
+ envelope, structurally_valid: true, filesystem_verified: null,
41
+ citation_status: 'not_applicable',
42
+ };
43
+ }
44
+ if (envelope.type === 'command') {
45
+ const hasRequiredFields = !!(envelope.command && envelope.output && envelope.exit_code !== undefined);
46
+ if (!hasRequiredFields) {
47
+ return {
48
+ envelope, structurally_valid: false, filesystem_verified: null,
49
+ mismatch_detail: 'Missing command, exit_code, or output',
50
+ citation_status: 'not_applicable',
51
+ };
52
+ }
53
+ const passed = envelope.exit_code === 0;
54
+ return {
55
+ envelope, structurally_valid: true, filesystem_verified: passed,
56
+ mismatch_detail: passed ? undefined : `Command failed with exit_code ${envelope.exit_code}`,
57
+ citation_status: passed ? 'verified' : 'void',
58
+ };
59
+ }
60
+ if (envelope.type === 'url') {
61
+ const valid = !!(envelope.url && envelope.retrieved_at && envelope.content_snapshot);
62
+ return {
63
+ envelope, structurally_valid: valid, filesystem_verified: null,
64
+ citation_status: valid ? 'verified' : 'not_applicable',
65
+ mismatch_detail: valid ? undefined : 'Missing url, retrieved_at, or content_snapshot',
66
+ };
67
+ }
68
+ if (envelope.type === 'text') {
69
+ const valid = !!(envelope.label && envelope.content);
70
+ return {
71
+ envelope, structurally_valid: valid, filesystem_verified: null,
72
+ citation_status: valid ? 'verified' : 'not_applicable',
73
+ };
74
+ }
75
+ if (envelope.type === 'memory') {
76
+ const valid = !!(envelope.memory_key && envelope.retrieved_at && envelope.content_snapshot);
77
+ return {
78
+ envelope, structurally_valid: valid, filesystem_verified: null,
79
+ citation_status: valid ? 'verified' : 'not_applicable',
80
+ };
81
+ }
82
+ return {
83
+ envelope, structurally_valid: false, filesystem_verified: null,
84
+ mismatch_detail: 'Unknown envelope type',
85
+ citation_status: 'not_applicable',
86
+ };
87
+ }
88
+ }
89
+ //# sourceMappingURL=evidence-checker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence-checker.js","sourceRoot":"","sources":["../../src/detectors/evidence-checker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { Claim, SealEvidence, SealIssue } from '../types.js';
2
+ export interface EvidenceGapResult {
3
+ issues: SealIssue[];
4
+ missing_evidence: string[];
5
+ trust_deductions: number;
6
+ }
7
+ export declare class EvidenceGapDetector {
8
+ static detect(claims: Claim[], evidence: SealEvidence, risk_level?: string): EvidenceGapResult;
9
+ }