@llm-dev-ops/agentics-cli 2.1.5 → 2.4.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.
- package/dist/pipeline/auto-chain.d.ts +190 -0
- package/dist/pipeline/auto-chain.d.ts.map +1 -1
- package/dist/pipeline/auto-chain.js +1571 -72
- package/dist/pipeline/auto-chain.js.map +1 -1
- package/dist/pipeline/phase2/phases/prompt-generator.d.ts.map +1 -1
- package/dist/pipeline/phase2/phases/prompt-generator.js +205 -12
- package/dist/pipeline/phase2/phases/prompt-generator.js.map +1 -1
- package/dist/pipeline/phase2/schemas.d.ts +10 -10
- package/dist/pipeline/phase4/phases/http-server-generator.d.ts +12 -0
- package/dist/pipeline/phase4/phases/http-server-generator.d.ts.map +1 -1
- package/dist/pipeline/phase4/phases/http-server-generator.js +92 -25
- package/dist/pipeline/phase4/phases/http-server-generator.js.map +1 -1
- package/dist/pipeline/phase4-5-pre-render/financial-model.d.ts +51 -0
- package/dist/pipeline/phase4-5-pre-render/financial-model.d.ts.map +1 -0
- package/dist/pipeline/phase4-5-pre-render/financial-model.js +118 -0
- package/dist/pipeline/phase4-5-pre-render/financial-model.js.map +1 -0
- package/dist/pipeline/phase4-5-pre-render/post-render-reconciler.d.ts +53 -0
- package/dist/pipeline/phase4-5-pre-render/post-render-reconciler.d.ts.map +1 -0
- package/dist/pipeline/phase4-5-pre-render/post-render-reconciler.js +130 -0
- package/dist/pipeline/phase4-5-pre-render/post-render-reconciler.js.map +1 -0
- package/dist/pipeline/phase4-5-pre-render/pre-render-coordinator.d.ts +47 -0
- package/dist/pipeline/phase4-5-pre-render/pre-render-coordinator.d.ts.map +1 -0
- package/dist/pipeline/phase4-5-pre-render/pre-render-coordinator.js +105 -0
- package/dist/pipeline/phase4-5-pre-render/pre-render-coordinator.js.map +1 -0
- package/dist/pipeline/phase4-5-pre-render/sector-baselines.d.ts +42 -0
- package/dist/pipeline/phase4-5-pre-render/sector-baselines.d.ts.map +1 -0
- package/dist/pipeline/phase4-5-pre-render/sector-baselines.js +117 -0
- package/dist/pipeline/phase4-5-pre-render/sector-baselines.js.map +1 -0
- package/dist/pipeline/phase5-build/phase5-build-coordinator.d.ts.map +1 -1
- package/dist/pipeline/phase5-build/phase5-build-coordinator.js +44 -0
- package/dist/pipeline/phase5-build/phase5-build-coordinator.js.map +1 -1
- package/dist/pipeline/phase5-build/phases/post-generation-validator.d.ts +75 -0
- package/dist/pipeline/phase5-build/phases/post-generation-validator.d.ts.map +1 -0
- package/dist/pipeline/phase5-build/phases/post-generation-validator.js +1068 -0
- package/dist/pipeline/phase5-build/phases/post-generation-validator.js.map +1 -0
- package/dist/pipeline/phase5-build/types.d.ts +1 -1
- package/dist/pipeline/phase5-build/types.d.ts.map +1 -1
- package/dist/pipeline/types.d.ts +87 -0
- package/dist/pipeline/types.d.ts.map +1 -1
- package/dist/pipeline/types.js +51 -1
- package/dist/pipeline/types.js.map +1 -1
- package/dist/synthesis/consensus-svg.d.ts +19 -0
- package/dist/synthesis/consensus-svg.d.ts.map +1 -0
- package/dist/synthesis/consensus-svg.js +95 -0
- package/dist/synthesis/consensus-svg.js.map +1 -0
- package/dist/synthesis/consensus-tiers.d.ts +99 -0
- package/dist/synthesis/consensus-tiers.d.ts.map +1 -0
- package/dist/synthesis/consensus-tiers.js +285 -0
- package/dist/synthesis/consensus-tiers.js.map +1 -0
- package/dist/synthesis/domain-labor-classifier.d.ts +101 -0
- package/dist/synthesis/domain-labor-classifier.d.ts.map +1 -0
- package/dist/synthesis/domain-labor-classifier.js +312 -0
- package/dist/synthesis/domain-labor-classifier.js.map +1 -0
- package/dist/synthesis/domain-unit-registry.d.ts +59 -0
- package/dist/synthesis/domain-unit-registry.d.ts.map +1 -0
- package/dist/synthesis/domain-unit-registry.js +320 -0
- package/dist/synthesis/domain-unit-registry.js.map +1 -0
- package/dist/synthesis/financial-claim-extractor.d.ts +72 -0
- package/dist/synthesis/financial-claim-extractor.d.ts.map +1 -0
- package/dist/synthesis/financial-claim-extractor.js +382 -0
- package/dist/synthesis/financial-claim-extractor.js.map +1 -0
- package/dist/synthesis/financial-consistency-rules.d.ts +70 -0
- package/dist/synthesis/financial-consistency-rules.d.ts.map +1 -0
- package/dist/synthesis/financial-consistency-rules.js +483 -0
- package/dist/synthesis/financial-consistency-rules.js.map +1 -0
- package/dist/synthesis/financial-consistency-runner.d.ts +73 -0
- package/dist/synthesis/financial-consistency-runner.d.ts.map +1 -0
- package/dist/synthesis/financial-consistency-runner.js +131 -0
- package/dist/synthesis/financial-consistency-runner.js.map +1 -0
- package/dist/synthesis/forbidden-spin-phrases.d.ts +32 -0
- package/dist/synthesis/forbidden-spin-phrases.d.ts.map +1 -0
- package/dist/synthesis/forbidden-spin-phrases.js +84 -0
- package/dist/synthesis/forbidden-spin-phrases.js.map +1 -0
- package/dist/synthesis/phase-gate-thresholds.d.ts +30 -0
- package/dist/synthesis/phase-gate-thresholds.d.ts.map +1 -0
- package/dist/synthesis/phase-gate-thresholds.js +34 -0
- package/dist/synthesis/phase-gate-thresholds.js.map +1 -0
- package/dist/synthesis/prompts/index.d.ts.map +1 -1
- package/dist/synthesis/prompts/index.js +22 -0
- package/dist/synthesis/prompts/index.js.map +1 -1
- package/dist/synthesis/roadmap-dates.d.ts +72 -0
- package/dist/synthesis/roadmap-dates.d.ts.map +1 -0
- package/dist/synthesis/roadmap-dates.js +203 -0
- package/dist/synthesis/roadmap-dates.js.map +1 -0
- package/dist/synthesis/simulation-artifact-generator.d.ts.map +1 -1
- package/dist/synthesis/simulation-artifact-generator.js +135 -1
- package/dist/synthesis/simulation-artifact-generator.js.map +1 -1
- package/dist/synthesis/simulation-renderers.d.ts +105 -2
- package/dist/synthesis/simulation-renderers.d.ts.map +1 -1
- package/dist/synthesis/simulation-renderers.js +1192 -123
- package/dist/synthesis/simulation-renderers.js.map +1 -1
- package/dist/synthesis/unit-economics-loader.d.ts +71 -0
- package/dist/synthesis/unit-economics-loader.d.ts.map +1 -0
- package/dist/synthesis/unit-economics-loader.js +200 -0
- package/dist/synthesis/unit-economics-loader.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,483 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ADR-PIPELINE-067: Financial Consistency Rules (FCR-001..009)
|
|
3
|
+
*
|
|
4
|
+
* Pure functions over the output of financial-claim-extractor + an optional
|
|
5
|
+
* unit-economics manifest. Each rule returns zero or more Violation objects.
|
|
6
|
+
*
|
|
7
|
+
* Rule IDs:
|
|
8
|
+
* FCR-001 Same scope + same kind across documents ⇒ numeric ranges must overlap
|
|
9
|
+
* FCR-002 Pilot investment MUST be ≤ full-program investment
|
|
10
|
+
* FCR-003 Phase-1 range MUST be a subset of full-program range
|
|
11
|
+
* FCR-004 Every currency claim MUST have a non-unscoped scope
|
|
12
|
+
* FCR-005 Timeline claims for the same scope MUST match within ±1 week
|
|
13
|
+
* FCR-006 Savings + investment for the same scope MUST yield the ROI stated
|
|
14
|
+
* FCR-007 When unit-economics manifest exists, top-line figures match ±1%
|
|
15
|
+
* FCR-008 Pilot savings × (enterprise/pilot units) MUST equal enterprise savings ±5%
|
|
16
|
+
* FCR-009 At most one "headline" figure per document
|
|
17
|
+
*/
|
|
18
|
+
import { EXPECTS_TAGS } from './financial-claim-extractor.js';
|
|
19
|
+
import { findForbiddenSpinPhrases } from './forbidden-spin-phrases.js';
|
|
20
|
+
// ============================================================================
|
|
21
|
+
// Helpers
|
|
22
|
+
// ============================================================================
|
|
23
|
+
function anchorValue(claim) {
|
|
24
|
+
if (claim.pointValue !== undefined)
|
|
25
|
+
return claim.pointValue;
|
|
26
|
+
if (claim.rangeLow !== undefined)
|
|
27
|
+
return claim.rangeLow;
|
|
28
|
+
return 0;
|
|
29
|
+
}
|
|
30
|
+
function rangeOf(claim) {
|
|
31
|
+
if (claim.rangeLow !== undefined && claim.rangeHigh !== undefined) {
|
|
32
|
+
return [claim.rangeLow, claim.rangeHigh];
|
|
33
|
+
}
|
|
34
|
+
const v = claim.pointValue ?? 0;
|
|
35
|
+
return [v, v];
|
|
36
|
+
}
|
|
37
|
+
function rangesOverlap(a, b) {
|
|
38
|
+
return a[0] <= b[1] && b[0] <= a[1];
|
|
39
|
+
}
|
|
40
|
+
function isCurrencyClaim(c) {
|
|
41
|
+
return c.unit === 'USD';
|
|
42
|
+
}
|
|
43
|
+
function byKey(items, key) {
|
|
44
|
+
const out = new Map();
|
|
45
|
+
for (const item of items) {
|
|
46
|
+
const k = key(item);
|
|
47
|
+
const list = out.get(k) ?? [];
|
|
48
|
+
list.push(item);
|
|
49
|
+
out.set(k, list);
|
|
50
|
+
}
|
|
51
|
+
return out;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Two scopes are considered "same" for FCR-001 when they match exactly,
|
|
55
|
+
* or when both map to the pilot/phase-1 concept.
|
|
56
|
+
*/
|
|
57
|
+
function canonicalScope(scope) {
|
|
58
|
+
if (scope === 'phase-1')
|
|
59
|
+
return 'pilot';
|
|
60
|
+
return scope;
|
|
61
|
+
}
|
|
62
|
+
// ============================================================================
|
|
63
|
+
// FCR-001 — Same scope + same kind across documents ⇒ ranges must overlap
|
|
64
|
+
// ============================================================================
|
|
65
|
+
function ruleFcr001(claims) {
|
|
66
|
+
const violations = [];
|
|
67
|
+
const currency = claims.filter(isCurrencyClaim);
|
|
68
|
+
const grouped = byKey(currency, c => `${canonicalScope(c.scope)}|${c.kind}`);
|
|
69
|
+
for (const [key, group] of grouped) {
|
|
70
|
+
if (group.length < 2)
|
|
71
|
+
continue;
|
|
72
|
+
const byDoc = byKey(group, c => c.document);
|
|
73
|
+
if (byDoc.size < 2)
|
|
74
|
+
continue;
|
|
75
|
+
// Compare each pair of documents' widest range.
|
|
76
|
+
const docEntries = Array.from(byDoc.entries()).map(([doc, list]) => {
|
|
77
|
+
const lows = [];
|
|
78
|
+
const highs = [];
|
|
79
|
+
for (const c of list) {
|
|
80
|
+
const [lo, hi] = rangeOf(c);
|
|
81
|
+
lows.push(lo);
|
|
82
|
+
highs.push(hi);
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
document: doc,
|
|
86
|
+
low: Math.min(...lows),
|
|
87
|
+
high: Math.max(...highs),
|
|
88
|
+
claims: list,
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
for (let i = 0; i < docEntries.length; i++) {
|
|
92
|
+
for (let j = i + 1; j < docEntries.length; j++) {
|
|
93
|
+
const a = docEntries[i];
|
|
94
|
+
const b = docEntries[j];
|
|
95
|
+
if (!rangesOverlap([a.low, a.high], [b.low, b.high])) {
|
|
96
|
+
violations.push({
|
|
97
|
+
ruleId: 'FCR-001',
|
|
98
|
+
severity: 'error',
|
|
99
|
+
message: `[${key}] ${a.document} [$${a.low.toLocaleString()}–$${a.high.toLocaleString()}] does not overlap with ${b.document} [$${b.low.toLocaleString()}–$${b.high.toLocaleString()}]`,
|
|
100
|
+
claims: [...a.claims, ...b.claims],
|
|
101
|
+
suggestedFix: 'Reconcile figures — either widen the scope label on one side or relabel the divergent figure with the correct scope.',
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return violations;
|
|
108
|
+
}
|
|
109
|
+
// ============================================================================
|
|
110
|
+
// FCR-002 — Pilot investment ≤ full-program investment
|
|
111
|
+
// FCR-003 — Phase-1 range MUST be a subset of full-program range
|
|
112
|
+
// ============================================================================
|
|
113
|
+
function ruleFcr002and003(claims) {
|
|
114
|
+
const violations = [];
|
|
115
|
+
const investments = claims.filter(c => isCurrencyClaim(c) && c.kind === 'investment');
|
|
116
|
+
const pilots = investments.filter(c => c.scope === 'pilot' || c.scope === 'phase-1');
|
|
117
|
+
const fulls = investments.filter(c => c.scope === 'full-program');
|
|
118
|
+
if (pilots.length === 0 || fulls.length === 0)
|
|
119
|
+
return violations;
|
|
120
|
+
const fullHigh = Math.max(...fulls.map(c => rangeOf(c)[1]));
|
|
121
|
+
// FCR-002 — pilot must not exceed the full-program ceiling.
|
|
122
|
+
for (const pilot of pilots) {
|
|
123
|
+
const [pLow] = rangeOf(pilot);
|
|
124
|
+
if (pLow > fullHigh) {
|
|
125
|
+
violations.push({
|
|
126
|
+
ruleId: 'FCR-002',
|
|
127
|
+
severity: 'error',
|
|
128
|
+
message: `pilot investment ${pilot.rawText} exceeds full-program ceiling $${fullHigh.toLocaleString()}`,
|
|
129
|
+
claims: [pilot, ...fulls],
|
|
130
|
+
suggestedFix: 'Lower the pilot figure or correct the full-program range.',
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// FCR-003 — the same numeric range must not appear with different scope
|
|
135
|
+
// labels across documents. This catches the OPERA regression where the
|
|
136
|
+
// executive summary labels $2.7M–$4.1M as (pilot) while the decision memo
|
|
137
|
+
// labels the identical range as (full-program).
|
|
138
|
+
const rangesApproxEqual = (a, b) => {
|
|
139
|
+
const [alo, ahi] = rangeOf(a);
|
|
140
|
+
const [blo, bhi] = rangeOf(b);
|
|
141
|
+
const loDelta = Math.abs(alo - blo) / Math.max(1, Math.max(alo, blo));
|
|
142
|
+
const hiDelta = Math.abs(ahi - bhi) / Math.max(1, Math.max(ahi, bhi));
|
|
143
|
+
return loDelta <= 0.1 && hiDelta <= 0.1;
|
|
144
|
+
};
|
|
145
|
+
for (const pilot of pilots) {
|
|
146
|
+
for (const full of fulls) {
|
|
147
|
+
if (pilot.document === full.document)
|
|
148
|
+
continue;
|
|
149
|
+
if (!rangesApproxEqual(pilot, full))
|
|
150
|
+
continue;
|
|
151
|
+
violations.push({
|
|
152
|
+
ruleId: 'FCR-003',
|
|
153
|
+
severity: 'error',
|
|
154
|
+
message: `${pilot.document} declares ${pilot.rawText} (${pilot.scope}) but ${full.document} labels the same range as (full-program)`,
|
|
155
|
+
claims: [pilot, full],
|
|
156
|
+
suggestedFix: "Relabel the pilot figure to '(full program)' if it covers the whole program, or split into distinct pilot + full-program lines.",
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return violations;
|
|
161
|
+
}
|
|
162
|
+
// ============================================================================
|
|
163
|
+
// FCR-004 — Every currency claim MUST have a non-unscoped scope
|
|
164
|
+
// ============================================================================
|
|
165
|
+
function ruleFcr004(claims) {
|
|
166
|
+
const unscoped = claims.filter(c => isCurrencyClaim(c) && c.scope === 'unscoped' && !c.tagged);
|
|
167
|
+
if (unscoped.length === 0)
|
|
168
|
+
return [];
|
|
169
|
+
// One violation per claim so callers can map it to a file:line
|
|
170
|
+
return unscoped.map(claim => ({
|
|
171
|
+
ruleId: 'FCR-004',
|
|
172
|
+
severity: 'error',
|
|
173
|
+
message: `${claim.document} line ${claim.line}: ${claim.rawText} has no scope label`,
|
|
174
|
+
claims: [claim],
|
|
175
|
+
suggestedFix: "Append a scope label in parens — e.g. '(pilot)' or '(full program)' — or add an HTML fcv:scope= tag.",
|
|
176
|
+
}));
|
|
177
|
+
}
|
|
178
|
+
// ============================================================================
|
|
179
|
+
// FCR-005 — Timeline claims for the same scope match within ±1 week
|
|
180
|
+
// ============================================================================
|
|
181
|
+
const WEEK_IN_WEEKS = 1;
|
|
182
|
+
function timelineToWeeks(c) {
|
|
183
|
+
const v = c.pointValue ?? 0;
|
|
184
|
+
if (c.unit === 'weeks')
|
|
185
|
+
return v;
|
|
186
|
+
if (c.unit === 'months')
|
|
187
|
+
return v * 4.34524;
|
|
188
|
+
if (c.unit === 'years')
|
|
189
|
+
return v * 52;
|
|
190
|
+
return v;
|
|
191
|
+
}
|
|
192
|
+
function ruleFcr005(claims) {
|
|
193
|
+
const violations = [];
|
|
194
|
+
const timelines = claims.filter(c => c.kind === 'timeline' && c.scope !== 'unscoped');
|
|
195
|
+
const grouped = byKey(timelines, c => canonicalScope(c.scope));
|
|
196
|
+
for (const [scope, group] of grouped) {
|
|
197
|
+
if (group.length < 2)
|
|
198
|
+
continue;
|
|
199
|
+
const byDoc = byKey(group, c => c.document);
|
|
200
|
+
if (byDoc.size < 2)
|
|
201
|
+
continue;
|
|
202
|
+
const weeksByDoc = Array.from(byDoc.entries()).map(([doc, list]) => ({
|
|
203
|
+
document: doc,
|
|
204
|
+
weeks: Math.max(...list.map(timelineToWeeks)),
|
|
205
|
+
claims: list,
|
|
206
|
+
}));
|
|
207
|
+
for (let i = 0; i < weeksByDoc.length; i++) {
|
|
208
|
+
for (let j = i + 1; j < weeksByDoc.length; j++) {
|
|
209
|
+
const a = weeksByDoc[i];
|
|
210
|
+
const b = weeksByDoc[j];
|
|
211
|
+
if (Math.abs(a.weeks - b.weeks) > WEEK_IN_WEEKS) {
|
|
212
|
+
violations.push({
|
|
213
|
+
ruleId: 'FCR-005',
|
|
214
|
+
severity: 'error',
|
|
215
|
+
message: `[${scope}] timeline mismatch: ${a.document} says ${Math.round(a.weeks)} weeks, ${b.document} says ${Math.round(b.weeks)} weeks`,
|
|
216
|
+
claims: [...a.claims, ...b.claims],
|
|
217
|
+
suggestedFix: 'Align timelines or split into distinct scopes (pilot vs. full program).',
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return violations;
|
|
224
|
+
}
|
|
225
|
+
// ============================================================================
|
|
226
|
+
// FCR-006 — Savings ÷ investment ≈ ROI for the same scope (WARN)
|
|
227
|
+
// ============================================================================
|
|
228
|
+
function ruleFcr006(claims) {
|
|
229
|
+
const violations = [];
|
|
230
|
+
const byDoc = byKey(claims, c => c.document);
|
|
231
|
+
for (const [doc, docClaims] of byDoc) {
|
|
232
|
+
const investments = docClaims.filter(c => isCurrencyClaim(c) && c.kind === 'investment');
|
|
233
|
+
const savings = docClaims.filter(c => isCurrencyClaim(c) && c.kind === 'savings');
|
|
234
|
+
const rois = docClaims.filter(c => c.kind === 'roi' && c.unit === 'percent');
|
|
235
|
+
if (investments.length === 0 || savings.length === 0 || rois.length === 0)
|
|
236
|
+
continue;
|
|
237
|
+
// Use the largest investment and savings in this document.
|
|
238
|
+
const topInvest = investments.reduce((a, b) => (anchorValue(a) >= anchorValue(b) ? a : b));
|
|
239
|
+
const topSavings = savings.reduce((a, b) => (anchorValue(a) >= anchorValue(b) ? a : b));
|
|
240
|
+
const topRoi = rois.reduce((a, b) => ((a.pointValue ?? 0) >= (b.pointValue ?? 0) ? a : b));
|
|
241
|
+
const investVal = anchorValue(topInvest);
|
|
242
|
+
const savingsVal = anchorValue(topSavings);
|
|
243
|
+
if (investVal <= 0)
|
|
244
|
+
continue;
|
|
245
|
+
const computed = (savingsVal / investVal) * 100;
|
|
246
|
+
const stated = topRoi.pointValue ?? 0;
|
|
247
|
+
if (Math.abs(computed - stated) / Math.max(1, stated) > 0.5) {
|
|
248
|
+
violations.push({
|
|
249
|
+
ruleId: 'FCR-006',
|
|
250
|
+
severity: 'warn',
|
|
251
|
+
message: `${doc}: savings $${savingsVal.toLocaleString()} ÷ investment $${investVal.toLocaleString()} ≈ ${Math.round(computed)}% but document states ROI of ${stated}%`,
|
|
252
|
+
claims: [topInvest, topSavings, topRoi],
|
|
253
|
+
suggestedFix: 'Restate the ROI line or the underlying savings/investment figures so they reconcile.',
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return violations;
|
|
258
|
+
}
|
|
259
|
+
// ============================================================================
|
|
260
|
+
// FCR-007 — Match unit-economics manifest within ±1%
|
|
261
|
+
// ============================================================================
|
|
262
|
+
function ruleFcr007(claims, manifest) {
|
|
263
|
+
if (!manifest)
|
|
264
|
+
return [];
|
|
265
|
+
const tol = 0.01;
|
|
266
|
+
const violations = [];
|
|
267
|
+
const savings = claims.filter(c => isCurrencyClaim(c) && c.kind === 'savings');
|
|
268
|
+
const enterpriseSavings = savings.filter(c => c.scope === 'full-program');
|
|
269
|
+
const pilotSavings = savings.filter(c => c.scope === 'pilot' || c.scope === 'phase-1');
|
|
270
|
+
const checkAgainst = (printed, target, label) => {
|
|
271
|
+
for (const claim of printed) {
|
|
272
|
+
const [lo, hi] = rangeOf(claim);
|
|
273
|
+
const value = (lo + hi) / 2;
|
|
274
|
+
const delta = Math.abs(value - target) / Math.max(1, target);
|
|
275
|
+
if (delta > tol) {
|
|
276
|
+
violations.push({
|
|
277
|
+
ruleId: 'FCR-007',
|
|
278
|
+
severity: 'error',
|
|
279
|
+
message: `${claim.document} ${label} ${claim.rawText} deviates from unit-economics.json ($${target.toLocaleString()}) by ${(delta * 100).toFixed(1)}% (tolerance ±1%)`,
|
|
280
|
+
claims: [claim],
|
|
281
|
+
suggestedFix: 'Regenerate the executive document or correct the unit-economics manifest so the two agree.',
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
checkAgainst(enterpriseSavings, manifest.annual_extrapolated_savings_usd, 'enterprise savings');
|
|
287
|
+
checkAgainst(pilotSavings, manifest.annual_measured_savings_usd, 'pilot savings');
|
|
288
|
+
return violations;
|
|
289
|
+
}
|
|
290
|
+
// ============================================================================
|
|
291
|
+
// FCR-008 — Pilot × scope-ratio ≈ enterprise savings within ±5%
|
|
292
|
+
// ============================================================================
|
|
293
|
+
function ruleFcr008(claims, manifest) {
|
|
294
|
+
if (!manifest)
|
|
295
|
+
return [];
|
|
296
|
+
if (manifest.annual_measured_savings_usd <= 0)
|
|
297
|
+
return [];
|
|
298
|
+
const tol = 0.05;
|
|
299
|
+
const violations = [];
|
|
300
|
+
const manifestRatio = manifest.annual_extrapolated_savings_usd / manifest.annual_measured_savings_usd;
|
|
301
|
+
const savings = claims.filter(c => isCurrencyClaim(c) && c.kind === 'savings');
|
|
302
|
+
const byDoc = byKey(savings, c => c.document);
|
|
303
|
+
for (const [doc, docSavings] of byDoc) {
|
|
304
|
+
const pilot = docSavings.find(c => c.scope === 'pilot' || c.scope === 'phase-1');
|
|
305
|
+
const full = docSavings.find(c => c.scope === 'full-program');
|
|
306
|
+
if (!pilot || !full)
|
|
307
|
+
continue;
|
|
308
|
+
const pilotVal = anchorValue(pilot);
|
|
309
|
+
const fullVal = anchorValue(full);
|
|
310
|
+
if (pilotVal <= 0)
|
|
311
|
+
continue;
|
|
312
|
+
const ratio = fullVal / pilotVal;
|
|
313
|
+
const delta = Math.abs(ratio - manifestRatio) / Math.max(0.01, manifestRatio);
|
|
314
|
+
if (delta > tol) {
|
|
315
|
+
violations.push({
|
|
316
|
+
ruleId: 'FCR-008',
|
|
317
|
+
severity: 'error',
|
|
318
|
+
message: `${doc}: pilot→enterprise ratio ${ratio.toFixed(1)}× deviates from manifest scope ratio ${manifestRatio.toFixed(1)}× by ${(delta * 100).toFixed(1)}% (tolerance ±5%)`,
|
|
319
|
+
claims: [pilot, full],
|
|
320
|
+
suggestedFix: 'Align the printed figures with the manifest scope ratio or widen the extrapolation method explanation.',
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return violations;
|
|
325
|
+
}
|
|
326
|
+
// ============================================================================
|
|
327
|
+
// FCR-009 — At most one headline figure per document (WARN)
|
|
328
|
+
// ============================================================================
|
|
329
|
+
function ruleFcr009(claims) {
|
|
330
|
+
const violations = [];
|
|
331
|
+
const byDoc = byKey(claims, c => c.document);
|
|
332
|
+
for (const [doc, docClaims] of byDoc) {
|
|
333
|
+
const headlines = docClaims.filter(c => isCurrencyClaim(c) && c.kind === 'savings' && c.scope === 'full-program');
|
|
334
|
+
if (headlines.length <= 1)
|
|
335
|
+
continue;
|
|
336
|
+
// Collapse identical numbers (same anchor) before flagging — a doc that
|
|
337
|
+
// states "$30M/yr" twice isn't a problem, two *different* $30M and $4.1M
|
|
338
|
+
// headline figures is.
|
|
339
|
+
const distinct = new Set(headlines.map(c => Math.round(anchorValue(c))));
|
|
340
|
+
if (distinct.size <= 1)
|
|
341
|
+
continue;
|
|
342
|
+
violations.push({
|
|
343
|
+
ruleId: 'FCR-009',
|
|
344
|
+
severity: 'warn',
|
|
345
|
+
message: `${doc} has ${distinct.size} distinct full-program headline savings figures: ${[...distinct].map(v => '$' + v.toLocaleString()).join(' and ')}`,
|
|
346
|
+
claims: headlines,
|
|
347
|
+
suggestedFix: 'Pick one headline savings figure and demote the others to a pilot/phase-1 scope or a sensitivity range.',
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
return violations;
|
|
351
|
+
}
|
|
352
|
+
// ============================================================================
|
|
353
|
+
// FCR-011 — Every money figure in EXPECTS_TAGS docs must be tagged (ADR-PIPELINE-073)
|
|
354
|
+
// ============================================================================
|
|
355
|
+
function ruleFcr011(claims) {
|
|
356
|
+
const violations = [];
|
|
357
|
+
for (const c of claims) {
|
|
358
|
+
if (!isCurrencyClaim(c))
|
|
359
|
+
continue;
|
|
360
|
+
if (!EXPECTS_TAGS.has(c.document))
|
|
361
|
+
continue;
|
|
362
|
+
if (c.tagged)
|
|
363
|
+
continue;
|
|
364
|
+
violations.push({
|
|
365
|
+
ruleId: 'FCR-011',
|
|
366
|
+
severity: 'error',
|
|
367
|
+
message: `${c.document} line ${c.line}: ${c.rawText} has no preceding fcv tag. ` +
|
|
368
|
+
'LLM synthesis may have stripped the authoritative scope label.',
|
|
369
|
+
claims: [c],
|
|
370
|
+
suggestedFix: 'Re-emit the document from the skeleton and ensure the LLM synthesis prompt preserves <!-- fcv:... --> comments verbatim (ADR-PIPELINE-073).',
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
return violations;
|
|
374
|
+
}
|
|
375
|
+
// ============================================================================
|
|
376
|
+
// FCR-012 — fcv tag `doc=` field must match the enclosing document (ADR-PIPELINE-073)
|
|
377
|
+
// ============================================================================
|
|
378
|
+
function ruleFcr012(claims) {
|
|
379
|
+
const violations = [];
|
|
380
|
+
for (const c of claims) {
|
|
381
|
+
if (!c.tagged)
|
|
382
|
+
continue;
|
|
383
|
+
if (!c.docTag)
|
|
384
|
+
continue;
|
|
385
|
+
if (c.docTag === c.document)
|
|
386
|
+
continue;
|
|
387
|
+
violations.push({
|
|
388
|
+
ruleId: 'FCR-012',
|
|
389
|
+
severity: 'error',
|
|
390
|
+
message: `${c.document} line ${c.line}: fcv tag carries doc="${c.docTag}" but the figure lives in ${c.document}. ` +
|
|
391
|
+
'Cross-document tag contamination — LLM synthesis copy-pasted content with its tag attached.',
|
|
392
|
+
claims: [c],
|
|
393
|
+
suggestedFix: 'Relabel the tag\'s doc= field to match the enclosing document, or remove the figure entirely if it was copy-pasted from another doc.',
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
return violations;
|
|
397
|
+
}
|
|
398
|
+
function ruleFcr010(documents, consensus) {
|
|
399
|
+
if (!consensus || consensus.tier !== 'contested')
|
|
400
|
+
return [];
|
|
401
|
+
const violations = [];
|
|
402
|
+
for (const doc of documents) {
|
|
403
|
+
const findings = findForbiddenSpinPhrases(doc.content);
|
|
404
|
+
if (findings.length === 0)
|
|
405
|
+
continue;
|
|
406
|
+
for (const f of findings) {
|
|
407
|
+
const claim = {
|
|
408
|
+
document: doc.document,
|
|
409
|
+
section: '(spin scan)',
|
|
410
|
+
kind: 'investment',
|
|
411
|
+
scope: 'unscoped',
|
|
412
|
+
unit: 'USD',
|
|
413
|
+
rawText: f.rawText,
|
|
414
|
+
line: f.line,
|
|
415
|
+
tagged: false,
|
|
416
|
+
};
|
|
417
|
+
violations.push({
|
|
418
|
+
ruleId: 'FCR-010',
|
|
419
|
+
severity: 'error',
|
|
420
|
+
message: `${doc.document} line ${f.line}: forbidden spin phrase "${f.rawText}" — ${f.note} (consensus is contested at agreement ${consensus.agreementLevelPct}%, precision ${consensus.precisionConfidencePct}%)`,
|
|
421
|
+
claims: [claim],
|
|
422
|
+
suggestedFix: 'Remove the phrase or relabel the document — under contested consensus the executive narrative must NOT minimize dissent.',
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
return violations;
|
|
427
|
+
}
|
|
428
|
+
export function runConsistencyRules(input) {
|
|
429
|
+
const { claims, manifest = null, documents = [], consensus = null } = input;
|
|
430
|
+
return [
|
|
431
|
+
...ruleFcr001(claims),
|
|
432
|
+
...ruleFcr002and003(claims),
|
|
433
|
+
...ruleFcr004(claims),
|
|
434
|
+
...ruleFcr005(claims),
|
|
435
|
+
...ruleFcr006(claims),
|
|
436
|
+
...ruleFcr007(claims, manifest),
|
|
437
|
+
...ruleFcr008(claims, manifest),
|
|
438
|
+
...ruleFcr009(claims),
|
|
439
|
+
...ruleFcr010(documents, consensus),
|
|
440
|
+
...ruleFcr011(claims),
|
|
441
|
+
...ruleFcr012(claims),
|
|
442
|
+
];
|
|
443
|
+
}
|
|
444
|
+
// Exported for unit tests so individual rules can be exercised in isolation.
|
|
445
|
+
export const __internal = {
|
|
446
|
+
ruleFcr001,
|
|
447
|
+
ruleFcr002and003,
|
|
448
|
+
ruleFcr004,
|
|
449
|
+
ruleFcr005,
|
|
450
|
+
ruleFcr006,
|
|
451
|
+
ruleFcr007,
|
|
452
|
+
ruleFcr008,
|
|
453
|
+
ruleFcr009,
|
|
454
|
+
ruleFcr010,
|
|
455
|
+
ruleFcr011,
|
|
456
|
+
ruleFcr012,
|
|
457
|
+
};
|
|
458
|
+
// Back-compat alias for callers that only need the counts.
|
|
459
|
+
export function countViolations(vs) {
|
|
460
|
+
let errors = 0;
|
|
461
|
+
let warnings = 0;
|
|
462
|
+
for (const v of vs) {
|
|
463
|
+
if (v.severity === 'error')
|
|
464
|
+
errors++;
|
|
465
|
+
else
|
|
466
|
+
warnings++;
|
|
467
|
+
}
|
|
468
|
+
return { errors, warnings };
|
|
469
|
+
}
|
|
470
|
+
// Keep a helper so the runner can prefix per-document warnings easily.
|
|
471
|
+
export function violationsByDocument(vs) {
|
|
472
|
+
const out = new Map();
|
|
473
|
+
for (const v of vs) {
|
|
474
|
+
for (const c of v.claims) {
|
|
475
|
+
const list = out.get(c.document) ?? [];
|
|
476
|
+
if (!list.includes(v))
|
|
477
|
+
list.push(v);
|
|
478
|
+
out.set(c.document, list);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
return out;
|
|
482
|
+
}
|
|
483
|
+
//# sourceMappingURL=financial-consistency-rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"financial-consistency-rules.js","sourceRoot":"","sources":["../../src/synthesis/financial-consistency-rules.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ADR-PIPELINE-067: Financial Consistency Runner
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates the extract → rules → report pipeline. Writes a structured
|
|
5
|
+
* violations report to the run directory, prepends a warning header to any
|
|
6
|
+
* affected markdown document, and escalates to a hard failure under
|
|
7
|
+
* AGENTICS_STRICT_FCV=true.
|
|
8
|
+
*/
|
|
9
|
+
import { type FinancialClaim, type FinancialClaimDocument } from './financial-claim-extractor.js';
|
|
10
|
+
import { type Violation } from './financial-consistency-rules.js';
|
|
11
|
+
import type { UnitEconomics } from '../pipeline/types.js';
|
|
12
|
+
import type { ConsensusSnapshot } from './consensus-tiers.js';
|
|
13
|
+
export interface InputDocument {
|
|
14
|
+
readonly kind: FinancialClaimDocument;
|
|
15
|
+
readonly path: string;
|
|
16
|
+
readonly content: string;
|
|
17
|
+
}
|
|
18
|
+
export interface ConsistencyReport {
|
|
19
|
+
readonly run_id: string;
|
|
20
|
+
readonly generated_at: string;
|
|
21
|
+
readonly passed: boolean;
|
|
22
|
+
readonly strict: boolean;
|
|
23
|
+
readonly totals: {
|
|
24
|
+
errors: number;
|
|
25
|
+
warnings: number;
|
|
26
|
+
};
|
|
27
|
+
readonly violations: readonly ReportViolation[];
|
|
28
|
+
readonly documents_scanned: number;
|
|
29
|
+
readonly claims_extracted: number;
|
|
30
|
+
}
|
|
31
|
+
export interface ReportViolation {
|
|
32
|
+
readonly rule_id: string;
|
|
33
|
+
readonly severity: 'error' | 'warn';
|
|
34
|
+
readonly message: string;
|
|
35
|
+
readonly suggested_fix?: string;
|
|
36
|
+
readonly claims: readonly ReportClaim[];
|
|
37
|
+
}
|
|
38
|
+
export interface ReportClaim {
|
|
39
|
+
readonly document: FinancialClaimDocument;
|
|
40
|
+
readonly section: string;
|
|
41
|
+
readonly kind: string;
|
|
42
|
+
readonly scope: string;
|
|
43
|
+
readonly line: number;
|
|
44
|
+
readonly rawText: string;
|
|
45
|
+
}
|
|
46
|
+
export declare class FinancialConsistencyError extends Error {
|
|
47
|
+
readonly code: string;
|
|
48
|
+
constructor(message: string, code?: string);
|
|
49
|
+
}
|
|
50
|
+
export interface RunOptions {
|
|
51
|
+
readonly documents: readonly InputDocument[];
|
|
52
|
+
readonly runDir: string;
|
|
53
|
+
readonly runId?: string;
|
|
54
|
+
readonly manifest?: UnitEconomics | null;
|
|
55
|
+
/** Optional consensus snapshot — required for FCR-010 (ADR-PIPELINE-071). */
|
|
56
|
+
readonly consensus?: ConsensusSnapshot | null;
|
|
57
|
+
/** Override for testing. Defaults to AGENTICS_STRICT_FCV env check. */
|
|
58
|
+
readonly strict?: boolean;
|
|
59
|
+
/** When true, write affected documents back with a warning header. */
|
|
60
|
+
readonly annotateDocuments?: boolean;
|
|
61
|
+
}
|
|
62
|
+
export interface RunResult {
|
|
63
|
+
readonly report: ConsistencyReport;
|
|
64
|
+
readonly reportPath: string;
|
|
65
|
+
readonly violations: readonly Violation[];
|
|
66
|
+
readonly claims: readonly FinancialClaim[];
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Run the extractor + rules against a set of documents and write the report.
|
|
70
|
+
* Returns the structured result so callers can log, annotate, or branch.
|
|
71
|
+
*/
|
|
72
|
+
export declare function runConsistencyCheck(options: RunOptions): RunResult;
|
|
73
|
+
//# sourceMappingURL=financial-consistency-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"financial-consistency-runner.d.ts","sourceRoot":"","sources":["../../src/synthesis/financial-consistency-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC5B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAGL,KAAK,SAAS,EACf,MAAM,kCAAkC,CAAC;AAE1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,sBAAsB,CAAC;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACtD,QAAQ,CAAC,UAAU,EAAE,SAAS,eAAe,EAAE,CAAC;IAChD,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;CACzC;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,yBAA0B,SAAQ,KAAK;aACL,IAAI;gBAArC,OAAO,EAAE,MAAM,EAAkB,IAAI,SAAiB;CAInE;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,SAAS,EAAE,SAAS,aAAa,EAAE,CAAC;IAC7C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACzC,6EAA6E;IAC7E,QAAQ,CAAC,SAAS,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC9C,uEAAuE;IACvE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,sEAAsE;IACtE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;CACtC;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,SAAS,SAAS,EAAE,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;CAC5C;AAmCD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,UAAU,GAAG,SAAS,CAqFlE"}
|