@mmnto/totem 1.105.0 → 1.107.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/ast-classifier.d.ts +3 -3
- package/dist/ast-classifier.js +12 -3
- package/dist/ast-classifier.js.map +1 -1
- package/dist/ast-classifier.test.js +33 -2
- package/dist/ast-classifier.test.js.map +1 -1
- package/dist/capability/schema.d.ts +2 -2
- package/dist/errors.d.ts +3 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -2
- package/dist/index.js.map +1 -1
- package/dist/ledger.d.ts +92 -4
- package/dist/ledger.d.ts.map +1 -1
- package/dist/ledger.js +91 -13
- package/dist/ledger.js.map +1 -1
- package/dist/qbd/compliance.d.ts +216 -0
- package/dist/qbd/compliance.d.ts.map +1 -0
- package/dist/qbd/compliance.js +490 -0
- package/dist/qbd/compliance.js.map +1 -0
- package/dist/qbd/compliance.test.d.ts +2 -0
- package/dist/qbd/compliance.test.d.ts.map +1 -0
- package/dist/qbd/compliance.test.js +539 -0
- package/dist/qbd/compliance.test.js.map +1 -0
- package/dist/qbd/correlation-id.d.ts +130 -0
- package/dist/qbd/correlation-id.d.ts.map +1 -0
- package/dist/qbd/correlation-id.js +224 -0
- package/dist/qbd/correlation-id.js.map +1 -0
- package/dist/qbd/correlation-id.test.d.ts +2 -0
- package/dist/qbd/correlation-id.test.d.ts.map +1 -0
- package/dist/qbd/correlation-id.test.js +136 -0
- package/dist/qbd/correlation-id.test.js.map +1 -0
- package/dist/qbd/record.d.ts +140 -0
- package/dist/qbd/record.d.ts.map +1 -0
- package/dist/qbd/record.js +419 -0
- package/dist/qbd/record.js.map +1 -0
- package/dist/qbd/record.test.d.ts +27 -0
- package/dist/qbd/record.test.d.ts.map +1 -0
- package/dist/qbd/record.test.js +607 -0
- package/dist/qbd/record.test.js.map +1 -0
- package/dist/rule-engine.test.js +85 -0
- package/dist/rule-engine.test.js.map +1 -1
- package/dist/session-id.d.ts.map +1 -1
- package/dist/session-id.js +19 -3
- package/dist/session-id.js.map +1 -1
- package/dist/session-id.test.js +35 -0
- package/dist/session-id.test.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,539 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { LEDGER_EVENT_TYPES, QBD_EVENT_TYPES } from '../ledger.js';
|
|
3
|
+
import { computeQbdCompliance, formatQbdRate, groupQbdSessions, QBD_PRE_REGISTERED_THRESHOLD, QBD_PRE_REGISTERED_WINDOW_SESSIONS, QBD_PRE_REGISTRATION_STATEMENT, scanQbdLedger, } from './compliance.js';
|
|
4
|
+
import { mintQbdCorrelationId } from './correlation-id.js';
|
|
5
|
+
const T0 = Date.parse('2026-07-28T12:00:00.000Z');
|
|
6
|
+
/** Deterministic distinct session UUIDs. */
|
|
7
|
+
function sid(n) {
|
|
8
|
+
return `00000000-0000-4000-8000-${String(n).padStart(12, '0')}`;
|
|
9
|
+
}
|
|
10
|
+
function queryLine(ms, sessionId, agentSource) {
|
|
11
|
+
const id = mintQbdCorrelationId(ms);
|
|
12
|
+
return {
|
|
13
|
+
id,
|
|
14
|
+
line: JSON.stringify({
|
|
15
|
+
timestamp: new Date(ms).toISOString(),
|
|
16
|
+
type: 'corpus_query',
|
|
17
|
+
activity_name: 'totem_search',
|
|
18
|
+
source: 'lint',
|
|
19
|
+
justification: '',
|
|
20
|
+
qbd_correlation_id: id,
|
|
21
|
+
...(sessionId !== undefined && { session_id: sessionId }),
|
|
22
|
+
...(agentSource !== undefined && { agent_source: agentSource }),
|
|
23
|
+
}),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function deriveLine(ms, sessionId, correlationId, agentSource) {
|
|
27
|
+
return JSON.stringify({
|
|
28
|
+
timestamp: new Date(ms).toISOString(),
|
|
29
|
+
type: 'derive_action',
|
|
30
|
+
activity_name: 'spec',
|
|
31
|
+
source: 'lint',
|
|
32
|
+
justification: '',
|
|
33
|
+
...(correlationId !== undefined && { qbd_correlation_id: correlationId }),
|
|
34
|
+
...(sessionId !== undefined && { session_id: sessionId }),
|
|
35
|
+
...(agentSource !== undefined && { agent_source: agentSource }),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
describe('scanQbdLedger', () => {
|
|
39
|
+
it('lifts QBD rows and ignores other subsystems’ rows without degrading', () => {
|
|
40
|
+
const q = queryLine(T0, sid(1));
|
|
41
|
+
const content = [
|
|
42
|
+
JSON.stringify({
|
|
43
|
+
timestamp: new Date(T0).toISOString(),
|
|
44
|
+
type: 'suppress',
|
|
45
|
+
ruleId: 'abc',
|
|
46
|
+
file: 'a.ts',
|
|
47
|
+
source: 'lint',
|
|
48
|
+
justification: '',
|
|
49
|
+
}),
|
|
50
|
+
q.line,
|
|
51
|
+
deriveLine(T0 + 1000, sid(1), q.id),
|
|
52
|
+
'',
|
|
53
|
+
].join('\n');
|
|
54
|
+
const scan = scanQbdLedger(content);
|
|
55
|
+
expect(scan.rows).toHaveLength(2);
|
|
56
|
+
expect(scan.degraded).toBe(false);
|
|
57
|
+
expect(scan.linesScanned).toBe(3);
|
|
58
|
+
});
|
|
59
|
+
it('counts a torn JSON line per-item and degrades', () => {
|
|
60
|
+
const q = queryLine(T0, sid(1));
|
|
61
|
+
const content = [q.line, '{ not json', deriveLine(T0 + 1000, sid(1), q.id)].join('\n');
|
|
62
|
+
const scan = scanQbdLedger(content);
|
|
63
|
+
expect(scan.anomalies.malformedJson).toBe(1);
|
|
64
|
+
expect(scan.degraded).toBe(true);
|
|
65
|
+
expect(scan.anomalies.details.some((d) => d.includes('not valid JSON'))).toBe(true);
|
|
66
|
+
});
|
|
67
|
+
it('counts a BACKFILLED correlation row as a contract violation, not as data', () => {
|
|
68
|
+
// A hand-edited ledger row: an ID minted an hour after the derive it is
|
|
69
|
+
// attached to. The schema rejects it; the scan must COUNT that rejection
|
|
70
|
+
// rather than let `readLedgerEvents`-style silent skipping hide it.
|
|
71
|
+
const backfilled = mintQbdCorrelationId(T0 + 3_600_000);
|
|
72
|
+
const content = [deriveLine(T0, sid(1), backfilled)].join('\n');
|
|
73
|
+
const scan = scanQbdLedger(content);
|
|
74
|
+
expect(scan.rows).toHaveLength(0);
|
|
75
|
+
expect(scan.anomalies.correlationContractViolations).toBe(1);
|
|
76
|
+
expect(scan.degraded).toBe(true);
|
|
77
|
+
});
|
|
78
|
+
it('does not CRASH on an out-of-range mint instant — counts it instead', () => {
|
|
79
|
+
// `qbd1-zzzzzzzzzzz-<hex>` decodes to ~1.3e17, past the max Date value.
|
|
80
|
+
// It used to pass the finite/non-negative guards, then reach
|
|
81
|
+
// `new Date(...).toISOString()` while building a violation detail INSIDE
|
|
82
|
+
// `LedgerEventSchema`'s refinement. Zod does not trap refinement throws, so
|
|
83
|
+
// `safeParse` threw and one forged line killed the whole scan.
|
|
84
|
+
const forged = `qbd1-zzzzzzzzzzz-${'a'.repeat(16)}`;
|
|
85
|
+
const content = [
|
|
86
|
+
JSON.stringify({
|
|
87
|
+
timestamp: new Date(T0).toISOString(),
|
|
88
|
+
type: 'derive_action',
|
|
89
|
+
activity_name: 'spec',
|
|
90
|
+
source: 'lint',
|
|
91
|
+
justification: '',
|
|
92
|
+
qbd_correlation_id: forged,
|
|
93
|
+
session_id: sid(1),
|
|
94
|
+
}),
|
|
95
|
+
// A clean row after it: the scan must survive to reach this.
|
|
96
|
+
deriveLine(T0 + 1000, sid(1)),
|
|
97
|
+
].join('\n');
|
|
98
|
+
const scan = scanQbdLedger(content);
|
|
99
|
+
expect(scan.anomalies.correlationContractViolations).toBe(1);
|
|
100
|
+
expect(scan.degraded).toBe(true);
|
|
101
|
+
// The following row was still scanned — the failure was contained.
|
|
102
|
+
expect(scan.rows).toHaveLength(1);
|
|
103
|
+
});
|
|
104
|
+
it('is clean on an empty ledger', () => {
|
|
105
|
+
const scan = scanQbdLedger('');
|
|
106
|
+
expect(scan.rows).toHaveLength(0);
|
|
107
|
+
expect(scan.degraded).toBe(false);
|
|
108
|
+
});
|
|
109
|
+
it('CATCHES a forged correlation ID smuggled onto a non-QBD event type', () => {
|
|
110
|
+
// The scanner used to short-circuit on "this type belongs to another
|
|
111
|
+
// subsystem" BEFORE testing for QBD markers, so a row that claimed
|
|
112
|
+
// type `mcp_call` while carrying a `qbd_correlation_id` was dropped with
|
|
113
|
+
// zero anomalies — a tampered ledger rendering perfectly clean. The QBD
|
|
114
|
+
// marker test must win.
|
|
115
|
+
const content = JSON.stringify({
|
|
116
|
+
timestamp: new Date(T0).toISOString(),
|
|
117
|
+
type: 'mcp_call',
|
|
118
|
+
source: 'bot',
|
|
119
|
+
justification: '',
|
|
120
|
+
qbd_correlation_id: mintQbdCorrelationId(T0),
|
|
121
|
+
session_id: sid(1),
|
|
122
|
+
});
|
|
123
|
+
const scan = scanQbdLedger(content);
|
|
124
|
+
expect(scan.anomalies.correlationContractViolations).toBe(1);
|
|
125
|
+
expect(scan.degraded).toBe(true);
|
|
126
|
+
});
|
|
127
|
+
it('leaves a schema-failed non-QBD row alone when it carries no QBD markers', () => {
|
|
128
|
+
// Control for the test above: another subsystem's row failing its OWN
|
|
129
|
+
// schema is not this metric's integrity problem.
|
|
130
|
+
const content = JSON.stringify({
|
|
131
|
+
timestamp: new Date(T0).toISOString(),
|
|
132
|
+
type: 'suppress',
|
|
133
|
+
source: 'lint',
|
|
134
|
+
justification: '',
|
|
135
|
+
ruleId: '', // invalid: min(1)
|
|
136
|
+
});
|
|
137
|
+
const scan = scanQbdLedger(content);
|
|
138
|
+
expect(scan.anomalies.correlationContractViolations).toBe(0);
|
|
139
|
+
expect(scan.anomalies.unclassifiedInvalid).toBe(0);
|
|
140
|
+
expect(scan.degraded).toBe(false);
|
|
141
|
+
});
|
|
142
|
+
it('treats an unknown event type as ADVISORY version skew, not tampering', () => {
|
|
143
|
+
// Polarity check: benign skew must not flip DEGRADED, or routine skew
|
|
144
|
+
// drowns the signal that real tampering produces.
|
|
145
|
+
const content = JSON.stringify({
|
|
146
|
+
timestamp: new Date(T0).toISOString(),
|
|
147
|
+
type: 'some_future_event_type',
|
|
148
|
+
source: 'lint',
|
|
149
|
+
justification: '',
|
|
150
|
+
});
|
|
151
|
+
const scan = scanQbdLedger(content);
|
|
152
|
+
expect(scan.anomalies.unknownTypeRows).toBe(1);
|
|
153
|
+
expect(scan.degraded).toBe(false);
|
|
154
|
+
expect(scan.anomalies.details.some((d) => d.includes('version skew'))).toBe(true);
|
|
155
|
+
});
|
|
156
|
+
it('DEGRADES on backdated appends into an append-only ledger', () => {
|
|
157
|
+
// The cheap attack on a "first N sessions" window: append rows stamped in
|
|
158
|
+
// the past. Each row is individually contract-valid, so only cross-row
|
|
159
|
+
// monotonicity can see it.
|
|
160
|
+
const recent = queryLine(T0, sid(1));
|
|
161
|
+
const backdatedMs = Date.parse('2019-01-01T00:00:00.000Z');
|
|
162
|
+
const content = [
|
|
163
|
+
recent.line,
|
|
164
|
+
deriveLine(T0 + 1000, sid(1), recent.id),
|
|
165
|
+
deriveLine(backdatedMs, sid(2)),
|
|
166
|
+
].join('\n');
|
|
167
|
+
const scan = scanQbdLedger(content);
|
|
168
|
+
expect(scan.anomalies.backdatedRows).toBe(1);
|
|
169
|
+
expect(scan.degraded).toBe(true);
|
|
170
|
+
// The backdated row is still COUNTED — dropping it would shrink the
|
|
171
|
+
// denominator, which is the other failure mode.
|
|
172
|
+
expect(scan.rows).toHaveLength(3);
|
|
173
|
+
});
|
|
174
|
+
it('DEGRADES on backdated QBD rows appended after NON-QBD-only history', () => {
|
|
175
|
+
// The fresh-adopter state, which is exactly the state the pre-registered
|
|
176
|
+
// first-20 window is filled from. The monotonicity reference used to advance
|
|
177
|
+
// only on QBD rows, so a ledger whose history is all `suppress`/`mcp_call`
|
|
178
|
+
// offered no baseline and 20 backdated pairs read PASS, degraded=false.
|
|
179
|
+
// Existing non-QBD history IS the baseline.
|
|
180
|
+
const suppressRow = JSON.stringify({
|
|
181
|
+
timestamp: new Date(T0).toISOString(),
|
|
182
|
+
type: 'suppress',
|
|
183
|
+
ruleId: 'abc',
|
|
184
|
+
file: 'a.ts',
|
|
185
|
+
source: 'lint',
|
|
186
|
+
justification: '',
|
|
187
|
+
});
|
|
188
|
+
const backdatedMs = Date.parse('2019-01-01T00:00:00.000Z');
|
|
189
|
+
const q = queryLine(backdatedMs, sid(1));
|
|
190
|
+
const content = [suppressRow, q.line, deriveLine(backdatedMs + 1000, sid(1), q.id)].join('\n');
|
|
191
|
+
const scan = scanQbdLedger(content);
|
|
192
|
+
expect(scan.anomalies.backdatedRows).toBeGreaterThan(0);
|
|
193
|
+
expect(scan.degraded).toBe(true);
|
|
194
|
+
});
|
|
195
|
+
it('stays clean when QBD rows follow non-QBD history in order (control)', () => {
|
|
196
|
+
const suppressRow = JSON.stringify({
|
|
197
|
+
timestamp: new Date(T0).toISOString(),
|
|
198
|
+
type: 'suppress',
|
|
199
|
+
ruleId: 'abc',
|
|
200
|
+
file: 'a.ts',
|
|
201
|
+
source: 'lint',
|
|
202
|
+
justification: '',
|
|
203
|
+
});
|
|
204
|
+
const q = queryLine(T0 + 1000, sid(1));
|
|
205
|
+
const content = [suppressRow, q.line, deriveLine(T0 + 2000, sid(1), q.id)].join('\n');
|
|
206
|
+
const scan = scanQbdLedger(content);
|
|
207
|
+
expect(scan.anomalies.backdatedRows).toBe(0);
|
|
208
|
+
expect(scan.degraded).toBe(false);
|
|
209
|
+
});
|
|
210
|
+
it('tolerates small out-of-order jitter from concurrent writers', () => {
|
|
211
|
+
const q = queryLine(T0, sid(1));
|
|
212
|
+
const content = [
|
|
213
|
+
q.line,
|
|
214
|
+
deriveLine(T0 + 1000, sid(1), q.id),
|
|
215
|
+
deriveLine(T0 + 500, sid(1)),
|
|
216
|
+
].join('\n');
|
|
217
|
+
const scan = scanQbdLedger(content);
|
|
218
|
+
expect(scan.anomalies.backdatedRows).toBe(0);
|
|
219
|
+
expect(scan.degraded).toBe(false);
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
describe('ledger type parity', () => {
|
|
223
|
+
it('derives the non-QBD type set from the schema instead of hand-mirroring it', () => {
|
|
224
|
+
// A hand-copied list rots the moment a type is added to ledger.ts, and here
|
|
225
|
+
// that rot changes a DEGRADED verdict. Pin the partition to the schema.
|
|
226
|
+
//
|
|
227
|
+
// The fixtures MUST be schema-INVALID (`ruleId: ''` fails `min(1)`).
|
|
228
|
+
// `NON_QBD_TYPES` is consulted only inside the `!result.success` branch, so
|
|
229
|
+
// rows that parse never reach it — an earlier version of this test used
|
|
230
|
+
// valid rows and would have passed with the set emptied entirely.
|
|
231
|
+
const qbd = new Set(QBD_EVENT_TYPES);
|
|
232
|
+
const expectedNonQbd = LEDGER_EVENT_TYPES.filter((t) => !qbd.has(t));
|
|
233
|
+
for (const type of expectedNonQbd) {
|
|
234
|
+
const row = JSON.stringify({
|
|
235
|
+
timestamp: new Date(T0).toISOString(),
|
|
236
|
+
type,
|
|
237
|
+
source: 'lint',
|
|
238
|
+
justification: '',
|
|
239
|
+
ruleId: '',
|
|
240
|
+
file: 'a.ts',
|
|
241
|
+
});
|
|
242
|
+
const scan = scanQbdLedger(row);
|
|
243
|
+
// Recognised as another subsystem's row: skipped silently, NOT counted as
|
|
244
|
+
// an unknown type and NOT counted as unclassifiable.
|
|
245
|
+
expect(scan.anomalies.unknownTypeRows, `type '${type}' should be known`).toBe(0);
|
|
246
|
+
expect(scan.anomalies.unclassifiedInvalid, `type '${type}' should be skipped`).toBe(0);
|
|
247
|
+
expect(scan.degraded, `type '${type}' must not degrade`).toBe(false);
|
|
248
|
+
}
|
|
249
|
+
// And the two QBD types are exactly the metric's own.
|
|
250
|
+
expect([...QBD_EVENT_TYPES].sort()).toEqual(['corpus_query', 'derive_action']);
|
|
251
|
+
});
|
|
252
|
+
it('flags a schema-invalid row whose type is NOT in the schema list', () => {
|
|
253
|
+
// The discriminating control: if NON_QBD_TYPES were empty, the loop above
|
|
254
|
+
// would still pass only if this also changed — pinning both directions.
|
|
255
|
+
const row = JSON.stringify({
|
|
256
|
+
timestamp: new Date(T0).toISOString(),
|
|
257
|
+
type: 'not_a_real_type',
|
|
258
|
+
source: 'lint',
|
|
259
|
+
justification: '',
|
|
260
|
+
ruleId: '',
|
|
261
|
+
});
|
|
262
|
+
const scan = scanQbdLedger(row);
|
|
263
|
+
expect(scan.anomalies.unknownTypeRows).toBe(1);
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
describe('read-side 1:1 enforcement (consume-on-use)', () => {
|
|
267
|
+
it('refuses to credit several derives citing ONE query', () => {
|
|
268
|
+
// The leg's exact probe. Before this, one query and three derives read as
|
|
269
|
+
// compliance 1.00, degraded=false — because 1:1 was enforced only at write
|
|
270
|
+
// time, where a failed/raced/bypassed pointer consume leaves it unenforced.
|
|
271
|
+
const q = queryLine(T0, sid(1));
|
|
272
|
+
const content = [
|
|
273
|
+
q.line,
|
|
274
|
+
deriveLine(T0 + 1000, sid(1), q.id),
|
|
275
|
+
deriveLine(T0 + 2000, sid(1), q.id),
|
|
276
|
+
deriveLine(T0 + 3000, sid(1), q.id),
|
|
277
|
+
].join('\n');
|
|
278
|
+
const report = computeQbdCompliance(scanQbdLedger(content));
|
|
279
|
+
// First derive earns the credit; the other two are anomalies.
|
|
280
|
+
expect(report.window).toEqual({ derives: 3, correlated: 1 });
|
|
281
|
+
expect(report.compliance).toBeCloseTo(1 / 3);
|
|
282
|
+
expect(report.anomalies.duplicateCorrelations).toBe(2);
|
|
283
|
+
expect(report.degraded).toBe(true);
|
|
284
|
+
});
|
|
285
|
+
it('credits the EARLIEST citation, not an arbitrary one', () => {
|
|
286
|
+
const q = queryLine(T0, sid(1));
|
|
287
|
+
const content = [
|
|
288
|
+
q.line,
|
|
289
|
+
deriveLine(T0 + 5000, sid(1), q.id),
|
|
290
|
+
deriveLine(T0 + 1000, sid(1), q.id),
|
|
291
|
+
].join('\n');
|
|
292
|
+
const report = computeQbdCompliance(scanQbdLedger(content));
|
|
293
|
+
expect(report.window).toEqual({ derives: 2, correlated: 1 });
|
|
294
|
+
expect(report.anomalies.details.some((d) => d.includes(new Date(T0 + 5000).toISOString()))).toBe(true);
|
|
295
|
+
});
|
|
296
|
+
it('leaves a clean 1:1 ledger uncounted as duplicate (control)', () => {
|
|
297
|
+
const q1 = queryLine(T0, sid(1));
|
|
298
|
+
const q2 = queryLine(T0 + 2000, sid(1));
|
|
299
|
+
const content = [
|
|
300
|
+
q1.line,
|
|
301
|
+
deriveLine(T0 + 1000, sid(1), q1.id),
|
|
302
|
+
q2.line,
|
|
303
|
+
deriveLine(T0 + 3000, sid(1), q2.id),
|
|
304
|
+
].join('\n');
|
|
305
|
+
const report = computeQbdCompliance(scanQbdLedger(content));
|
|
306
|
+
expect(report.window).toEqual({ derives: 2, correlated: 2 });
|
|
307
|
+
expect(report.anomalies.duplicateCorrelations).toBe(0);
|
|
308
|
+
expect(report.degraded).toBe(false);
|
|
309
|
+
});
|
|
310
|
+
});
|
|
311
|
+
describe('seat-mismatch diagnostic', () => {
|
|
312
|
+
it('hints when an uncorrelated derive had an in-window query from another seat', () => {
|
|
313
|
+
// One-sided seat plumbing (seated CLI, unseated MCP server) produces a
|
|
314
|
+
// truthful-looking 0.00 with no other tell. Surface it as a config smell.
|
|
315
|
+
const q = queryLine(T0, sid(1), 'seat-a');
|
|
316
|
+
const content = [q.line, deriveLine(T0 + 1000, sid(1), undefined, 'seat-b')].join('\n');
|
|
317
|
+
const report = computeQbdCompliance(scanQbdLedger(content));
|
|
318
|
+
expect(report.compliance).toBe(0);
|
|
319
|
+
expect(report.anomalies.seatMismatchHints).toBe(1);
|
|
320
|
+
// A config smell is NOT tampering — it must not degrade the read.
|
|
321
|
+
expect(report.degraded).toBe(false);
|
|
322
|
+
});
|
|
323
|
+
it('does NOT hint when a same-seat query is also in the window', () => {
|
|
324
|
+
// Mixed-seat window. The derive has a same-seat query available, so its
|
|
325
|
+
// being uncorrelated has an ordinary explanation (spent pointer, different
|
|
326
|
+
// session) and seat plumbing is not implicated. Flagging on the first
|
|
327
|
+
// different-seat query found — which both this walk and the `.some()` it
|
|
328
|
+
// replaced did — reported a config problem that was not there.
|
|
329
|
+
const own = queryLine(T0, sid(1), 'seat-a');
|
|
330
|
+
const other = queryLine(T0 + 500, sid(2), 'seat-b');
|
|
331
|
+
const content = [own.line, other.line, deriveLine(T0 + 1000, sid(1), undefined, 'seat-a')].join('\n');
|
|
332
|
+
const report = computeQbdCompliance(scanQbdLedger(content));
|
|
333
|
+
expect(report.anomalies.seatMismatchHints).toBe(0);
|
|
334
|
+
});
|
|
335
|
+
it('hints when the ONLY in-window queries are from another seat', () => {
|
|
336
|
+
// Same fixture minus the same-seat query — the genuine one-sided signature.
|
|
337
|
+
const other = queryLine(T0 + 500, sid(2), 'seat-b');
|
|
338
|
+
const content = [other.line, deriveLine(T0 + 1000, sid(1), undefined, 'seat-a')].join('\n');
|
|
339
|
+
const report = computeQbdCompliance(scanQbdLedger(content));
|
|
340
|
+
expect(report.anomalies.seatMismatchHints).toBe(1);
|
|
341
|
+
});
|
|
342
|
+
it('does not hint when both sides are unseated (the solo default)', () => {
|
|
343
|
+
const q = queryLine(T0, sid(1));
|
|
344
|
+
const content = [q.line, deriveLine(T0 + 1000, sid(1))].join('\n');
|
|
345
|
+
const report = computeQbdCompliance(scanQbdLedger(content));
|
|
346
|
+
expect(report.anomalies.seatMismatchHints).toBe(0);
|
|
347
|
+
});
|
|
348
|
+
});
|
|
349
|
+
describe('computeQbdCompliance — denominator discipline (#2510 falsifier 1)', () => {
|
|
350
|
+
it('counts derives from ZERO-QUERY sessions in the denominator', () => {
|
|
351
|
+
const q = queryLine(T0, sid(1));
|
|
352
|
+
const content = [
|
|
353
|
+
// Session 1: queried, then derived → compliant.
|
|
354
|
+
q.line,
|
|
355
|
+
deriveLine(T0 + 1000, sid(1), q.id),
|
|
356
|
+
// Session 2: derived twice, never queried → both count, neither compliant.
|
|
357
|
+
deriveLine(T0 + 10_000, sid(2)),
|
|
358
|
+
deriveLine(T0 + 11_000, sid(2)),
|
|
359
|
+
].join('\n');
|
|
360
|
+
const report = computeQbdCompliance(scanQbdLedger(content));
|
|
361
|
+
expect(report.window.derives).toBe(3);
|
|
362
|
+
expect(report.window.correlated).toBe(1);
|
|
363
|
+
expect(report.compliance).toBeCloseTo(1 / 3);
|
|
364
|
+
});
|
|
365
|
+
it('counts a zero-query session as an instrumented session (window level)', () => {
|
|
366
|
+
// The operator-pinned window is "sessions carrying ≥1 derive-class event,
|
|
367
|
+
// REGARDLESS OF QUERY COUNT". A query-less session must enter the window.
|
|
368
|
+
const content = [deriveLine(T0, sid(1)), deriveLine(T0 + 1000, sid(2))].join('\n');
|
|
369
|
+
const report = computeQbdCompliance(scanQbdLedger(content));
|
|
370
|
+
expect(report.instrumentedSessions).toBe(2);
|
|
371
|
+
expect(report.compliance).toBe(0);
|
|
372
|
+
});
|
|
373
|
+
it('does NOT count a session that only queried', () => {
|
|
374
|
+
const q = queryLine(T0, sid(1));
|
|
375
|
+
const report = computeQbdCompliance(scanQbdLedger(q.line));
|
|
376
|
+
expect(report.instrumentedSessions).toBe(0);
|
|
377
|
+
expect(report.compliance).toBeNull();
|
|
378
|
+
expect(formatQbdRate(report.window)).toContain('n/a');
|
|
379
|
+
});
|
|
380
|
+
});
|
|
381
|
+
describe('computeQbdCompliance — numerator integrity (#2510 falsifier 2)', () => {
|
|
382
|
+
it('refuses to credit a derive citing a query row that does not exist', () => {
|
|
383
|
+
const orphan = mintQbdCorrelationId(T0);
|
|
384
|
+
const content = deriveLine(T0 + 1000, sid(1), orphan);
|
|
385
|
+
const report = computeQbdCompliance(scanQbdLedger(content));
|
|
386
|
+
expect(report.window).toEqual({ derives: 1, correlated: 0 });
|
|
387
|
+
expect(report.anomalies.orphanCorrelations).toBe(1);
|
|
388
|
+
expect(report.degraded).toBe(true);
|
|
389
|
+
});
|
|
390
|
+
it('refuses to credit a derive whose query came from another session', () => {
|
|
391
|
+
const q = queryLine(T0, sid(1));
|
|
392
|
+
const content = [q.line, deriveLine(T0 + 1000, sid(2), q.id)].join('\n');
|
|
393
|
+
const report = computeQbdCompliance(scanQbdLedger(content));
|
|
394
|
+
expect(report.window.correlated).toBe(0);
|
|
395
|
+
expect(report.anomalies.crossSessionCorrelations).toBe(1);
|
|
396
|
+
expect(report.degraded).toBe(true);
|
|
397
|
+
});
|
|
398
|
+
it('rejects — and SURFACES — a derive whose cited query came after it', () => {
|
|
399
|
+
// This row is refused by the schema outright (the charter's "a backfilled ID
|
|
400
|
+
// is a schema violation, not a data point"), so it never reaches the join
|
|
401
|
+
// check. That removes it from the denominator too, which is precisely why
|
|
402
|
+
// the rejection must be COUNTED and the scan marked degraded: a tampered
|
|
403
|
+
// ledger may not quietly shrink the denominator and still render clean.
|
|
404
|
+
const q = queryLine(T0 + 5000, sid(1));
|
|
405
|
+
const content = [q.line, deriveLine(T0 + 1000, sid(1), q.id)].join('\n');
|
|
406
|
+
const report = computeQbdCompliance(scanQbdLedger(content));
|
|
407
|
+
expect(report.window.correlated).toBe(0);
|
|
408
|
+
expect(report.anomalies.correlationContractViolations).toBe(1);
|
|
409
|
+
expect(report.degraded).toBe(true);
|
|
410
|
+
expect(report.anomalies.details.some((d) => d.includes('derive-id-minted-after-derive'))).toBe(true);
|
|
411
|
+
});
|
|
412
|
+
});
|
|
413
|
+
describe('computeQbdCompliance — the pre-registered threshold and window', () => {
|
|
414
|
+
function sessionsWith(count, correlated) {
|
|
415
|
+
const lines = [];
|
|
416
|
+
for (let i = 0; i < count; i++) {
|
|
417
|
+
const ms = T0 + i * 86_400_000;
|
|
418
|
+
if (correlated) {
|
|
419
|
+
const q = queryLine(ms, sid(i));
|
|
420
|
+
lines.push(q.line, deriveLine(ms + 1000, sid(i), q.id));
|
|
421
|
+
}
|
|
422
|
+
else {
|
|
423
|
+
lines.push(deriveLine(ms, sid(i)));
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
return lines.join('\n');
|
|
427
|
+
}
|
|
428
|
+
it('exposes the operator-pinned statement verbatim', () => {
|
|
429
|
+
expect(QBD_PRE_REGISTRATION_STATEMENT).toBe('compliance ≥ 0.50, evaluated over the first 20 instrumented sessions carrying ≥1 derive-class event, regardless of query count');
|
|
430
|
+
expect(QBD_PRE_REGISTERED_THRESHOLD).toBe(0.5);
|
|
431
|
+
expect(QBD_PRE_REGISTERED_WINDOW_SESSIONS).toBe(20);
|
|
432
|
+
});
|
|
433
|
+
it('stays PENDING until the window fills', () => {
|
|
434
|
+
const report = computeQbdCompliance(scanQbdLedger(sessionsWith(19, false)));
|
|
435
|
+
expect(report.instrumentedSessions).toBe(19);
|
|
436
|
+
expect(report.verdict).toBe('PENDING');
|
|
437
|
+
});
|
|
438
|
+
it('records FAIL when the filled window is below the floor', () => {
|
|
439
|
+
const report = computeQbdCompliance(scanQbdLedger(sessionsWith(20, false)));
|
|
440
|
+
expect(report.instrumentedSessions).toBe(20);
|
|
441
|
+
expect(report.compliance).toBe(0);
|
|
442
|
+
expect(report.verdict).toBe('FAIL');
|
|
443
|
+
});
|
|
444
|
+
it('records PASS when the filled window is at or above the floor', () => {
|
|
445
|
+
const report = computeQbdCompliance(scanQbdLedger(sessionsWith(20, true)));
|
|
446
|
+
expect(report.compliance).toBe(1);
|
|
447
|
+
expect(report.verdict).toBe('PASS');
|
|
448
|
+
});
|
|
449
|
+
it('evaluates the FIRST 20 sessions, not the most recent 20', () => {
|
|
450
|
+
// 20 uncorrelated sessions, then a 21st that is perfectly compliant. The
|
|
451
|
+
// pre-registration is a fixed window: the late good session must not rescue
|
|
452
|
+
// the verdict.
|
|
453
|
+
const lines = sessionsWith(20, false).split('\n');
|
|
454
|
+
const lateMs = T0 + 100 * 86_400_000;
|
|
455
|
+
const q = queryLine(lateMs, sid(999));
|
|
456
|
+
lines.push(q.line, deriveLine(lateMs + 1000, sid(999), q.id));
|
|
457
|
+
const report = computeQbdCompliance(scanQbdLedger(lines.join('\n')));
|
|
458
|
+
expect(report.instrumentedSessions).toBe(21);
|
|
459
|
+
expect(report.evaluatedSessions).toBe(20);
|
|
460
|
+
expect(report.window.derives).toBe(20);
|
|
461
|
+
expect(report.compliance).toBe(0);
|
|
462
|
+
expect(report.verdict).toBe('FAIL');
|
|
463
|
+
});
|
|
464
|
+
it('pins first-20 ordering from the other direction', () => {
|
|
465
|
+
// Mirror image: 20 GOOD sessions first, then a bad 21st. Under a
|
|
466
|
+
// `slice(-20)` bug this reads 19/20 instead of 20/20, so the two tests
|
|
467
|
+
// together pin the window's direction rather than just its size.
|
|
468
|
+
const lines = sessionsWith(20, true).split('\n');
|
|
469
|
+
const lateMs = T0 + 100 * 86_400_000;
|
|
470
|
+
lines.push(deriveLine(lateMs, sid(999)));
|
|
471
|
+
const report = computeQbdCompliance(scanQbdLedger(lines.join('\n')));
|
|
472
|
+
expect(report.instrumentedSessions).toBe(21);
|
|
473
|
+
expect(report.evaluatedSessions).toBe(20);
|
|
474
|
+
expect(report.window).toEqual({ derives: 20, correlated: 20 });
|
|
475
|
+
expect(report.compliance).toBe(1);
|
|
476
|
+
expect(report.verdict).toBe('PASS');
|
|
477
|
+
});
|
|
478
|
+
it('reports a trend once there are enough sessions on both sides', () => {
|
|
479
|
+
const lines = [];
|
|
480
|
+
// Two bad sessions, then two good ones.
|
|
481
|
+
for (let i = 0; i < 2; i++)
|
|
482
|
+
lines.push(deriveLine(T0 + i * 86_400_000, sid(i)));
|
|
483
|
+
for (let i = 2; i < 4; i++) {
|
|
484
|
+
const ms = T0 + i * 86_400_000;
|
|
485
|
+
const q = queryLine(ms, sid(i));
|
|
486
|
+
lines.push(q.line, deriveLine(ms + 1000, sid(i), q.id));
|
|
487
|
+
}
|
|
488
|
+
const report = computeQbdCompliance(scanQbdLedger(lines.join('\n')));
|
|
489
|
+
expect(report.trend).not.toBeNull();
|
|
490
|
+
expect(report.trend.earlier).toEqual({ derives: 2, correlated: 0 });
|
|
491
|
+
expect(report.trend.recent).toEqual({ derives: 2, correlated: 2 });
|
|
492
|
+
});
|
|
493
|
+
it('withholds a trend below four instrumented sessions', () => {
|
|
494
|
+
const report = computeQbdCompliance(scanQbdLedger(sessionsWith(3, false)));
|
|
495
|
+
expect(report.trend).toBeNull();
|
|
496
|
+
});
|
|
497
|
+
});
|
|
498
|
+
describe('session grouping', () => {
|
|
499
|
+
it('never merges two SEATS into one rolling-window session', () => {
|
|
500
|
+
// Cohort seats share one working tree, so both write to the same ledger
|
|
501
|
+
// inside the same span. Merging them would put seat A's query in the same
|
|
502
|
+
// session as seat B's derive.
|
|
503
|
+
const rows = [
|
|
504
|
+
{ ms: T0, type: 'corpus_query', agentSource: 'seat-a' },
|
|
505
|
+
{ ms: T0 + 1000, type: 'derive_action', agentSource: 'seat-b' },
|
|
506
|
+
];
|
|
507
|
+
const sessions = groupQbdSessions(rows);
|
|
508
|
+
expect(sessions).toHaveLength(2);
|
|
509
|
+
});
|
|
510
|
+
it('refuses to credit a derive correlated to another SEAT’s query', () => {
|
|
511
|
+
const q = queryLine(T0, sid(1), 'seat-a');
|
|
512
|
+
const content = [q.line, deriveLine(T0 + 1000, sid(1), q.id, 'seat-b')].join('\n');
|
|
513
|
+
const report = computeQbdCompliance(scanQbdLedger(content));
|
|
514
|
+
expect(report.window.correlated).toBe(0);
|
|
515
|
+
expect(report.anomalies.crossSessionCorrelations).toBe(1);
|
|
516
|
+
expect(report.degraded).toBe(true);
|
|
517
|
+
});
|
|
518
|
+
it('rolls id-less rows into windows rather than dropping them', () => {
|
|
519
|
+
const q = queryLine(T0);
|
|
520
|
+
const content = [
|
|
521
|
+
q.line,
|
|
522
|
+
deriveLine(T0 + 1000, undefined, q.id),
|
|
523
|
+
// Well outside the rolling window → a separate session.
|
|
524
|
+
deriveLine(T0 + 10 * 60 * 60 * 1000),
|
|
525
|
+
].join('\n');
|
|
526
|
+
const report = computeQbdCompliance(scanQbdLedger(content));
|
|
527
|
+
expect(report.instrumentedSessions).toBe(2);
|
|
528
|
+
expect(report.window).toEqual({ derives: 2, correlated: 1 });
|
|
529
|
+
});
|
|
530
|
+
});
|
|
531
|
+
describe('formatQbdRate', () => {
|
|
532
|
+
it('renders a rate with its raw counts', () => {
|
|
533
|
+
expect(formatQbdRate({ derives: 4, correlated: 3 })).toBe('0.75 (3/4)');
|
|
534
|
+
});
|
|
535
|
+
it('never renders an empty denominator as 0%', () => {
|
|
536
|
+
expect(formatQbdRate({ derives: 0, correlated: 0 })).toBe('n/a (0 derive-class events)');
|
|
537
|
+
});
|
|
538
|
+
});
|
|
539
|
+
//# sourceMappingURL=compliance.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compliance.test.js","sourceRoot":"","sources":["../../src/qbd/compliance.test.ts"],"names":[],"mappings":"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"}
|