@mmnto/totem 1.67.0 → 1.68.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/capability/falsification.d.ts +18 -0
- package/dist/capability/falsification.d.ts.map +1 -0
- package/dist/capability/falsification.js +56 -0
- package/dist/capability/falsification.js.map +1 -0
- package/dist/capability/falsification.test.d.ts +2 -0
- package/dist/capability/falsification.test.d.ts.map +1 -0
- package/dist/capability/falsification.test.js +112 -0
- package/dist/capability/falsification.test.js.map +1 -0
- package/dist/capability/regenerate.d.ts +20 -0
- package/dist/capability/regenerate.d.ts.map +1 -0
- package/dist/capability/regenerate.js +0 -0
- package/dist/capability/regenerate.js.map +1 -0
- package/dist/capability/regenerate.test.d.ts +2 -0
- package/dist/capability/regenerate.test.d.ts.map +1 -0
- package/dist/capability/regenerate.test.js +136 -0
- package/dist/capability/regenerate.test.js.map +1 -0
- package/dist/capability/review-catch.d.ts +53 -0
- package/dist/capability/review-catch.d.ts.map +1 -0
- package/dist/capability/review-catch.js +92 -0
- package/dist/capability/review-catch.js.map +1 -0
- package/dist/capability/review-catch.test.d.ts +2 -0
- package/dist/capability/review-catch.test.d.ts.map +1 -0
- package/dist/capability/review-catch.test.js +90 -0
- package/dist/capability/review-catch.test.js.map +1 -0
- package/dist/capability/schema.d.ts +244 -0
- package/dist/capability/schema.d.ts.map +1 -0
- package/dist/capability/schema.js +141 -0
- package/dist/capability/schema.js.map +1 -0
- package/dist/capability/schema.test.d.ts +2 -0
- package/dist/capability/schema.test.d.ts.map +1 -0
- package/dist/capability/schema.test.js +93 -0
- package/dist/capability/schema.test.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/spine/candidate-rule.d.ts +84 -0
- package/dist/spine/candidate-rule.d.ts.map +1 -0
- package/dist/spine/candidate-rule.js +68 -0
- package/dist/spine/candidate-rule.js.map +1 -0
- package/dist/spine/candidate-rule.test.d.ts +2 -0
- package/dist/spine/candidate-rule.test.d.ts.map +1 -0
- package/dist/spine/candidate-rule.test.js +40 -0
- package/dist/spine/candidate-rule.test.js.map +1 -0
- package/dist/spine/classify.d.ts +93 -0
- package/dist/spine/classify.d.ts.map +1 -0
- package/dist/spine/classify.js +190 -0
- package/dist/spine/classify.js.map +1 -0
- package/dist/spine/classify.test.d.ts +2 -0
- package/dist/spine/classify.test.d.ts.map +1 -0
- package/dist/spine/classify.test.js +302 -0
- package/dist/spine/classify.test.js.map +1 -0
- package/dist/spine/compile.d.ts +62 -0
- package/dist/spine/compile.d.ts.map +1 -0
- package/dist/spine/compile.js +204 -0
- package/dist/spine/compile.js.map +1 -0
- package/dist/spine/compile.test.d.ts +2 -0
- package/dist/spine/compile.test.d.ts.map +1 -0
- package/dist/spine/compile.test.js +327 -0
- package/dist/spine/compile.test.js.map +1 -0
- package/dist/spine/extract.d.ts +146 -0
- package/dist/spine/extract.d.ts.map +1 -0
- package/dist/spine/extract.js +227 -0
- package/dist/spine/extract.js.map +1 -0
- package/dist/spine/extract.test.d.ts +2 -0
- package/dist/spine/extract.test.d.ts.map +1 -0
- package/dist/spine/extract.test.js +382 -0
- package/dist/spine/extract.test.js.map +1 -0
- package/dist/spine/ledgers.d.ts +1102 -0
- package/dist/spine/ledgers.d.ts.map +1 -0
- package/dist/spine/ledgers.js +209 -0
- package/dist/spine/ledgers.js.map +1 -0
- package/dist/spine/miner-harness.d.ts +30 -0
- package/dist/spine/miner-harness.d.ts.map +1 -0
- package/dist/spine/miner-harness.js +214 -0
- package/dist/spine/miner-harness.js.map +1 -0
- package/dist/spine/miner-harness.test.d.ts +2 -0
- package/dist/spine/miner-harness.test.d.ts.map +1 -0
- package/dist/spine/miner-harness.test.js +231 -0
- package/dist/spine/miner-harness.test.js.map +1 -0
- package/dist/spine/selection-rule.d.ts +4 -1
- package/dist/spine/selection-rule.d.ts.map +1 -1
- package/dist/spine/selection-rule.js +3 -2
- package/dist/spine/selection-rule.js.map +1 -1
- package/dist/spine/split.d.ts +149 -0
- package/dist/spine/split.d.ts.map +1 -0
- package/dist/spine/split.js +235 -0
- package/dist/spine/split.js.map +1 -0
- package/dist/spine/split.test.d.ts +2 -0
- package/dist/spine/split.test.d.ts.map +1 -0
- package/dist/spine/split.test.js +142 -0
- package/dist/spine/split.test.js.map +1 -0
- package/dist/spine/windtunnel-lock.d.ts +8 -8
- package/package.json +1 -1
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type RegenerateOptions } from './regenerate.js';
|
|
2
|
+
import type { CapabilityClaim, CapabilityResolution } from './schema.js';
|
|
3
|
+
export type CapabilityFmClause = 'a' | 'c' | 'd';
|
|
4
|
+
export interface CapabilityFmViolation {
|
|
5
|
+
clause: CapabilityFmClause;
|
|
6
|
+
detail: string;
|
|
7
|
+
}
|
|
8
|
+
export interface CapabilityFalsificationResult {
|
|
9
|
+
ok: boolean;
|
|
10
|
+
violations: CapabilityFmViolation[];
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Run FM a/c/d over an append-only claim/resolution log. (FM-b is structural — the
|
|
14
|
+
* `ResolutionSource` enum cannot express an LLM-judge — so there is nothing to check at
|
|
15
|
+
* runtime; it is locked at the schema/type level + asserted in the schema tests.)
|
|
16
|
+
*/
|
|
17
|
+
export declare function runCapabilityFalsification(claims: readonly CapabilityClaim[], resolutions: readonly CapabilityResolution[], opts: RegenerateOptions): CapabilityFalsificationResult;
|
|
18
|
+
//# sourceMappingURL=falsification.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"falsification.d.ts","sourceRoot":"","sources":["../../src/capability/falsification.ts"],"names":[],"mappings":"AAaA,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEzE,MAAM,MAAM,kBAAkB,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAEjD,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,6BAA6B;IAC5C,EAAE,EAAE,OAAO,CAAC;IACZ,UAAU,EAAE,qBAAqB,EAAE,CAAC;CACrC;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,SAAS,eAAe,EAAE,EAClC,WAAW,EAAE,SAAS,oBAAoB,EAAE,EAC5C,IAAI,EAAE,iBAAiB,GACtB,6BAA6B,CAwC/B"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// ─── #697 Layer-B — falsification harness (FM a–d) ───────────────────────────
|
|
2
|
+
//
|
|
3
|
+
// The done-criterion guard over the capability log. FM a–d (#697 fold 4):
|
|
4
|
+
// (a) byte-reproducible — the ledger regenerates identically from the log;
|
|
5
|
+
// (b) no-LLM-judge — STRUCTURAL via the `ResolutionSource` enum (no `llm-judge`
|
|
6
|
+
// member exists), so it is unconstructible, not runtime-checked here;
|
|
7
|
+
// (c) join integrity — every resolution → an existing claim; ≤1 effective terminal
|
|
8
|
+
// per claim per horizon (enforced by `regenerateCapabilityLedger`'s fail-loud
|
|
9
|
+
// throws, surfaced here as clause `c`);
|
|
10
|
+
// (d) arithmetic integrity — every row's `decisiveN`/`hitRate` exactly equals the
|
|
11
|
+
// pinned formula over its counts (catches partial-inflation / wrong-denominator).
|
|
12
|
+
import { canonicalStringify } from '../compile-manifest.js';
|
|
13
|
+
import { collectJoinIntegrityErrors, regenerateCapabilityLedger, } from './regenerate.js';
|
|
14
|
+
/**
|
|
15
|
+
* Run FM a/c/d over an append-only claim/resolution log. (FM-b is structural — the
|
|
16
|
+
* `ResolutionSource` enum cannot express an LLM-judge — so there is nothing to check at
|
|
17
|
+
* runtime; it is locked at the schema/type level + asserted in the schema tests.)
|
|
18
|
+
*/
|
|
19
|
+
export function runCapabilityFalsification(claims, resolutions, opts) {
|
|
20
|
+
const violations = [];
|
|
21
|
+
// FM-c: join integrity — collect the breaches (the SAME shared check `regenerate`
|
|
22
|
+
// throws on) and surface each as a clause-`c` violation. No swallowing catch: the
|
|
23
|
+
// regenerate call below runs only on a log already proven clean, so it cannot throw
|
|
24
|
+
// here — the harness reports integrity breaches as data, never drops them (Tenet 4).
|
|
25
|
+
for (const detail of collectJoinIntegrityErrors(claims, resolutions, opts)) {
|
|
26
|
+
violations.push({ clause: 'c', detail });
|
|
27
|
+
}
|
|
28
|
+
if (violations.length > 0)
|
|
29
|
+
return { ok: false, violations };
|
|
30
|
+
const ledger = regenerateCapabilityLedger(claims, resolutions, opts);
|
|
31
|
+
// FM-a: regenerating again must produce a byte-identical ledger.
|
|
32
|
+
const again = regenerateCapabilityLedger(claims, resolutions, opts);
|
|
33
|
+
if (canonicalStringify(ledger) !== canonicalStringify(again)) {
|
|
34
|
+
violations.push({ clause: 'a', detail: 'ledger is not byte-reproducible from the log' });
|
|
35
|
+
}
|
|
36
|
+
// FM-d: each row's arithmetic is honest — `decisiveN` excludes partial+unresolved and
|
|
37
|
+
// `hitRate` is exactly `correctN / decisiveN` (or null when no decisive evidence).
|
|
38
|
+
for (const row of ledger.rows) {
|
|
39
|
+
const id = `${row.agentSource}/${row.taskType}`;
|
|
40
|
+
if (row.decisiveN !== row.correctN + row.wrongN) {
|
|
41
|
+
violations.push({
|
|
42
|
+
clause: 'd',
|
|
43
|
+
detail: `row ${id}: decisiveN ${row.decisiveN} != correctN+wrongN ${row.correctN + row.wrongN}`,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
const expected = row.decisiveN === 0 ? null : row.correctN / row.decisiveN;
|
|
47
|
+
if (row.hitRate !== expected) {
|
|
48
|
+
violations.push({
|
|
49
|
+
clause: 'd',
|
|
50
|
+
detail: `row ${id}: hitRate ${row.hitRate} != correctN/decisiveN ${expected}`,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return { ok: violations.length === 0, violations };
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=falsification.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"falsification.js","sourceRoot":"","sources":["../../src/capability/falsification.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,EAAE;AACF,0EAA0E;AAC1E,6EAA6E;AAC7E,kFAAkF;AAClF,4EAA4E;AAC5E,qFAAqF;AACrF,oFAAoF;AACpF,8CAA8C;AAC9C,oFAAoF;AACpF,wFAAwF;AAExF,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,GAE3B,MAAM,iBAAiB,CAAC;AAezB;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CACxC,MAAkC,EAClC,WAA4C,EAC5C,IAAuB;IAEvB,MAAM,UAAU,GAA4B,EAAE,CAAC;IAE/C,kFAAkF;IAClF,kFAAkF;IAClF,oFAAoF;IACpF,qFAAqF;IACrF,KAAK,MAAM,MAAM,IAAI,0BAA0B,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC;QAC3E,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;IAC3C,CAAC;IACD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;IAE5D,MAAM,MAAM,GAAG,0BAA0B,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;IAErE,iEAAiE;IACjE,MAAM,KAAK,GAAG,0BAA0B,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;IACpE,IAAI,kBAAkB,CAAC,MAAM,CAAC,KAAK,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7D,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,8CAA8C,EAAE,CAAC,CAAC;IAC3F,CAAC;IAED,sFAAsF;IACtF,mFAAmF;IACnF,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAC9B,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QAChD,IAAI,GAAG,CAAC,SAAS,KAAK,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC;YAChD,UAAU,CAAC,IAAI,CAAC;gBACd,MAAM,EAAE,GAAG;gBACX,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,CAAC,SAAS,uBAAuB,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM,EAAE;aAChG,CAAC,CAAC;QACL,CAAC;QACD,MAAM,QAAQ,GAAG,GAAG,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,SAAS,CAAC;QAC3E,IAAI,GAAG,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YAC7B,UAAU,CAAC,IAAI,CAAC;gBACd,MAAM,EAAE,GAAG;gBACX,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,CAAC,OAAO,0BAA0B,QAAQ,EAAE;aAC9E,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"falsification.test.d.ts","sourceRoot":"","sources":["../../src/capability/falsification.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { runCapabilityFalsification } from './falsification.js';
|
|
3
|
+
import { mineReviewCatch } from './review-catch.js';
|
|
4
|
+
const sha = (n) => String(n).padStart(40, '0');
|
|
5
|
+
const HORIZON = '2026-06-21T00:00:00.000Z';
|
|
6
|
+
const minedLog = () => mineReviewCatch([
|
|
7
|
+
{
|
|
8
|
+
commentId: 1,
|
|
9
|
+
author: 'coderabbitai[bot]',
|
|
10
|
+
prRef: 'x#1',
|
|
11
|
+
commitSha: sha(1),
|
|
12
|
+
assertedAt: '2026-06-20T00:00:00.000Z',
|
|
13
|
+
disposition: 'accepted',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
commentId: 2,
|
|
17
|
+
author: 'gemini-code-assist[bot]',
|
|
18
|
+
prRef: 'x#1',
|
|
19
|
+
commitSha: sha(1),
|
|
20
|
+
assertedAt: '2026-06-20T00:00:00.000Z',
|
|
21
|
+
disposition: 'declined',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
commentId: 3,
|
|
25
|
+
author: 'totem-claude',
|
|
26
|
+
prRef: 'x#1',
|
|
27
|
+
commitSha: sha(1),
|
|
28
|
+
assertedAt: '2026-06-20T00:00:00.000Z',
|
|
29
|
+
},
|
|
30
|
+
]);
|
|
31
|
+
describe('runCapabilityFalsification', () => {
|
|
32
|
+
it('passes a clean mined log (FM a/c/d all hold)', () => {
|
|
33
|
+
const { claims, resolutions } = minedLog();
|
|
34
|
+
const result = runCapabilityFalsification(claims, resolutions, { resolutionHorizon: HORIZON });
|
|
35
|
+
expect(result.ok).toBe(true);
|
|
36
|
+
expect(result.violations).toEqual([]);
|
|
37
|
+
});
|
|
38
|
+
it('flags FM-c when a resolution references an absent claim', () => {
|
|
39
|
+
const { claims } = minedLog();
|
|
40
|
+
const orphan = {
|
|
41
|
+
resolutionId: 'r-orphan',
|
|
42
|
+
claimId: 'does-not-exist',
|
|
43
|
+
outcome: 'correct',
|
|
44
|
+
resolutionSource: 'disposition-thread',
|
|
45
|
+
evidenceRef: 'ev',
|
|
46
|
+
resolvedAt: '2026-06-20T00:00:00.000Z',
|
|
47
|
+
};
|
|
48
|
+
const result = runCapabilityFalsification(claims, [orphan], { resolutionHorizon: HORIZON });
|
|
49
|
+
expect(result.ok).toBe(false);
|
|
50
|
+
expect(result.violations.map((v) => v.clause)).toContain('c');
|
|
51
|
+
});
|
|
52
|
+
it('flags FM-c on a duplicate resolutionId', () => {
|
|
53
|
+
const claims = [
|
|
54
|
+
{
|
|
55
|
+
claimId: 'c1',
|
|
56
|
+
agentSource: 'cr',
|
|
57
|
+
taskType: 'review-catch',
|
|
58
|
+
claimKind: 'review-finding',
|
|
59
|
+
provenance: { ref: 'x#1', commitSha: sha(1) },
|
|
60
|
+
nativeKey: 'gh-review-comment:1',
|
|
61
|
+
assertedAt: '2026-06-20T00:00:00.000Z',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
claimId: 'c2',
|
|
65
|
+
agentSource: 'cr',
|
|
66
|
+
taskType: 'review-catch',
|
|
67
|
+
claimKind: 'review-finding',
|
|
68
|
+
provenance: { ref: 'x#1', commitSha: sha(1) },
|
|
69
|
+
nativeKey: 'gh-review-comment:2',
|
|
70
|
+
assertedAt: '2026-06-20T00:00:00.000Z',
|
|
71
|
+
},
|
|
72
|
+
];
|
|
73
|
+
const dup = [
|
|
74
|
+
{
|
|
75
|
+
resolutionId: 'same',
|
|
76
|
+
claimId: 'c1',
|
|
77
|
+
outcome: 'correct',
|
|
78
|
+
resolutionSource: 'deterministic-event',
|
|
79
|
+
evidenceRef: 'e1',
|
|
80
|
+
resolvedAt: '2026-06-20T00:00:00.000Z',
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
resolutionId: 'same',
|
|
84
|
+
claimId: 'c2',
|
|
85
|
+
outcome: 'wrong',
|
|
86
|
+
resolutionSource: 'deterministic-event',
|
|
87
|
+
evidenceRef: 'e2',
|
|
88
|
+
resolvedAt: '2026-06-20T00:00:00.000Z',
|
|
89
|
+
},
|
|
90
|
+
];
|
|
91
|
+
const result = runCapabilityFalsification(claims, dup, { resolutionHorizon: HORIZON });
|
|
92
|
+
expect(result.ok).toBe(false);
|
|
93
|
+
expect(result.violations.map((v) => v.clause)).toContain('c');
|
|
94
|
+
});
|
|
95
|
+
it('flags FM-c on a duplicate claimId (greptile P1)', () => {
|
|
96
|
+
const dupClaim = {
|
|
97
|
+
claimId: 'same-claim',
|
|
98
|
+
agentSource: 'cr',
|
|
99
|
+
taskType: 'review-catch',
|
|
100
|
+
claimKind: 'review-finding',
|
|
101
|
+
provenance: { ref: 'x#1', commitSha: sha(1) },
|
|
102
|
+
nativeKey: 'gh-review-comment:1',
|
|
103
|
+
assertedAt: '2026-06-20T00:00:00.000Z',
|
|
104
|
+
};
|
|
105
|
+
const result = runCapabilityFalsification([dupClaim, { ...dupClaim }], [], {
|
|
106
|
+
resolutionHorizon: HORIZON,
|
|
107
|
+
});
|
|
108
|
+
expect(result.ok).toBe(false);
|
|
109
|
+
expect(result.violations.map((v) => v.clause)).toContain('c');
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
//# sourceMappingURL=falsification.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"falsification.test.js","sourceRoot":"","sources":["../../src/capability/falsification.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type CapabilityClaim, type CapabilityLedger, type CapabilityResolution } from './schema.js';
|
|
2
|
+
export interface RegenerateOptions {
|
|
3
|
+
/** ISO bound: resolutions with `resolvedAt > resolutionHorizon` are immature and ignored. */
|
|
4
|
+
resolutionHorizon: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Collect FM-c join-integrity errors (empty array = clean): a duplicate `resolutionId`,
|
|
8
|
+
* a resolution referencing an absent `claimId`, or an ambiguous supersession terminal.
|
|
9
|
+
* Pure. SHARED by the fail-loud `regenerateCapabilityLedger` (which throws on the first)
|
|
10
|
+
* and the falsification harness (which surfaces each as a clause-`c` violation) — so the
|
|
11
|
+
* harness reports integrity breaches WITHOUT a swallowing catch (Tenet 4).
|
|
12
|
+
*/
|
|
13
|
+
export declare function collectJoinIntegrityErrors(claims: readonly CapabilityClaim[], resolutions: readonly CapabilityResolution[], opts: RegenerateOptions): string[];
|
|
14
|
+
/**
|
|
15
|
+
* Recompute the `CapabilityLedger` cache from the append-only claim/resolution log.
|
|
16
|
+
* Throws (FM-c join integrity) on a duplicate `resolutionId`, a resolution referencing
|
|
17
|
+
* an absent `claimId`, or an ambiguous supersession terminal.
|
|
18
|
+
*/
|
|
19
|
+
export declare function regenerateCapabilityLedger(claims: readonly CapabilityClaim[], resolutions: readonly CapabilityResolution[], opts: RegenerateOptions): CapabilityLedger;
|
|
20
|
+
//# sourceMappingURL=regenerate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regenerate.d.ts","sourceRoot":"","sources":["../../src/capability/regenerate.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,gBAAgB,EAGrB,KAAK,oBAAoB,EAE1B,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,iBAAiB;IAChC,6FAA6F;IAC7F,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AA0DD;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,SAAS,eAAe,EAAE,EAClC,WAAW,EAAE,SAAS,oBAAoB,EAAE,EAC5C,IAAI,EAAE,iBAAiB,GACtB,MAAM,EAAE,CA6DV;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,SAAS,eAAe,EAAE,EAClC,WAAW,EAAE,SAAS,oBAAoB,EAAE,EAC5C,IAAI,EAAE,iBAAiB,GACtB,gBAAgB,CA4FlB"}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regenerate.js","sourceRoot":"","sources":["../../src/capability/regenerate.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,EAAE;AACF,sFAAsF;AACtF,uFAAuF;AACvF,wFAAwF;AACxF,qFAAqF;AACrF,iFAAiF;AAEjF,OAAO,EAIL,sBAAsB,GAGvB,MAAM,aAAa,CAAC;AAOrB;;;;;GAKG;AACH,SAAS,OAAO,CAAC,GAAW;IAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,yBAAyB,CAChC,OAAe,EACf,WAA4C,EAC5C,OAAe;IAEf,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtC,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,YAAY,CAAC,CAAC;IACnF,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAE7C,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,sBAAsB,KAAK,SAAS,CAAC,CAAC;IAC/E,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,UAAU,GAAG,IAAI,GAAG,CACxB,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAC3F,CAAC;QACF,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;QACvE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CACb,oDAAoD,OAAO,SAAS,KAAK,CAAC,MAAM,6FAA6F,CAC9K,CAAC;QACJ,CAAC;QACD,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAClC,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QACjC,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QACjC,IAAI,EAAE,KAAK,EAAE;YAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe;QACvD,OAAO,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,2CAA2C;IAC9F,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACR,CAAC;AAMD;;;;;;GAMG;AACH,MAAM,UAAU,0BAA0B,CACxC,MAAkC,EAClC,WAA4C,EAC5C,IAAuB;IAEvB,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,sFAAsF;IACtF,wFAAwF;IACxF,uFAAuF;IACvF,8CAA8C;IAC9C,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC;QAClD,CAAC;QACD,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC5C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkC,CAAC;IAE1D,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,IAAI,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC;YAC1C,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC;QAC5D,CAAC;QACD,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;QACtC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7B,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,YAAY,8BAA8B,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC;QACvF,CAAC;QACD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACzC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC9B,CAAC;IAED,sFAAsF;IACtF,qFAAqF;IACrF,qFAAqF;IACrF,0EAA0E;IAC1E,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,IACE,CAAC,CAAC,sBAAsB,KAAK,SAAS;YACtC,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,sBAAsB,CAAC,EAChD,CAAC;YACD,MAAM,CAAC,IAAI,CACT,eAAe,CAAC,CAAC,YAAY,6BAA6B,CAAC,CAAC,sBAAsB,qCAAqC,CACxH,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACrD,KAAK,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC;QACpC,MAAM,SAAS,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,YAAY,CAAC,CAAC;QAC1E,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,sBAAsB,KAAK,SAAS,CAAC;YAAE,SAAS;QAC7E,MAAM,UAAU,GAAG,IAAI,GAAG,CACxB,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAC3F,CAAC;QACF,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;QACvE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,CAAC,IAAI,CACT,UAAU,OAAO,SAAS,KAAK,CAAC,MAAM,wEAAwE,CAC/G,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CACxC,MAAkC,EAClC,WAA4C,EAC5C,IAAuB;IAEvB,+EAA+E;IAC/E,gEAAgE;IAChE,MAAM,eAAe,GAAG,0BAA0B,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;IAC9E,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CACb,6CAA6C,eAAe,CAAC,CAAC,CAAC,wBAAwB,CACxF,CAAC;IACJ,CAAC;IAED,yEAAyE;IACzE,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkC,CAAC;IAC1D,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACzC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,GAAG,EAA0B,CAAC;IAC9C,yDAAyD;IACzD,MAAM,YAAY,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAC7C,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAC3D,CAAC;IAEF,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;QACjC,MAAM,SAAS,GAAG,yBAAyB,CACzC,KAAK,CAAC,OAAO,EACb,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,EAChC,IAAI,CAAC,iBAAiB,CACvB,CAAC;QACF,MAAM,OAAO,GAAY,SAAS,EAAE,OAAO,IAAI,YAAY,CAAC;QAE5D,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACrD,MAAM,GAAG,GACP,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;YACX;gBACC,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,QAAQ,EAAE,CAAC;gBACX,MAAM,EAAE,CAAC;gBACT,QAAQ,EAAE,CAAC;gBACX,WAAW,EAAE,CAAC;gBACd,SAAS,EAAE,CAAC;gBACZ,OAAO,EAAE,IAAI;gBACb,YAAY,EAAE,IAAI;gBAClB,aAAa,EAAE,IAAI;aACM,CAAC;QAE9B,IAAI,OAAO,KAAK,SAAS;YAAE,GAAG,CAAC,QAAQ,IAAI,CAAC,CAAC;aACxC,IAAI,OAAO,KAAK,OAAO;YAAE,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC;aACzC,IAAI,OAAO,KAAK,SAAS;YAAE,GAAG,CAAC,QAAQ,IAAI,CAAC,CAAC;;YAC7C,GAAG,CAAC,WAAW,IAAI,CAAC,CAAC;QAE1B,IACE,SAAS;YACT,CAAC,GAAG,CAAC,aAAa,KAAK,IAAI,IAAI,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,EAC1F,CAAC;YACD,iFAAiF;YACjF,+EAA+E;YAC/E,GAAG,CAAC,aAAa,GAAG,SAAS,CAAC,UAAU,CAAC;QAC3C,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,IAAI,GAA0B,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC;SAClD,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACX,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC;QAC5C,OAAO;YACL,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,SAAS;YACT,OAAO,EAAE,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,GAAG,SAAS;YAC1D,YAAY,EAAE,GAAG,CAAC,aAAa;SACF,CAAC;IAClC,CAAC,CAAC;SACD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACb,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,WAAW;QAC7B,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW;YAC7B,CAAC,CAAC,CAAC,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ;YACvB,CAAC,CAAC,CAAC,CAAC;YACJ,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ;gBACvB,CAAC,CAAC,CAAC;gBACH,CAAC,CAAC,CAAC,CACV,CAAC;IAEJ,OAAO,sBAAsB,CAAC,KAAK,CAAC,EAAE,iBAAiB,EAAE,IAAI,CAAC,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC;AAC3F,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regenerate.test.d.ts","sourceRoot":"","sources":["../../src/capability/regenerate.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { canonicalStringify } from '../compile-manifest.js';
|
|
3
|
+
import { regenerateCapabilityLedger } from './regenerate.js';
|
|
4
|
+
const sha = (n) => String(n).padStart(40, '0');
|
|
5
|
+
const HORIZON = '2026-06-20T12:00:00.000Z';
|
|
6
|
+
function claim(id, agentSource = 'cr', overrides = {}) {
|
|
7
|
+
return {
|
|
8
|
+
claimId: id,
|
|
9
|
+
agentSource,
|
|
10
|
+
taskType: 'review-catch',
|
|
11
|
+
claimKind: 'review-finding',
|
|
12
|
+
provenance: { ref: `mmnto-ai/totem#${id}`, commitSha: sha(1) },
|
|
13
|
+
nativeKey: `gh-review-comment:${id}`,
|
|
14
|
+
assertedAt: '2026-06-19T00:00:00.000Z',
|
|
15
|
+
...overrides,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function resolution(id, claimId, outcome, overrides = {}) {
|
|
19
|
+
return {
|
|
20
|
+
resolutionId: id,
|
|
21
|
+
claimId,
|
|
22
|
+
outcome,
|
|
23
|
+
resolutionSource: 'disposition-thread',
|
|
24
|
+
evidenceRef: `ev:${id}`,
|
|
25
|
+
resolvedAt: '2026-06-19T06:00:00.000Z',
|
|
26
|
+
...overrides,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
const row = (ledger, agent) => ledger.rows.find((r) => r.agentSource === agent);
|
|
30
|
+
describe('regenerateCapabilityLedger — fold + hit-rate', () => {
|
|
31
|
+
it('counts held/wrong/partial/silence and computes hitRate = correct/(correct+wrong)', () => {
|
|
32
|
+
const claims = [claim('1'), claim('2'), claim('3'), claim('4')];
|
|
33
|
+
const resolutions = [
|
|
34
|
+
resolution('r1', '1', 'correct'),
|
|
35
|
+
resolution('r2', '2', 'wrong'),
|
|
36
|
+
resolution('r3', '3', 'partial'),
|
|
37
|
+
// claim 4 has no resolution → unresolved by absence
|
|
38
|
+
];
|
|
39
|
+
const ledger = regenerateCapabilityLedger(claims, resolutions, { resolutionHorizon: HORIZON });
|
|
40
|
+
const cr = row(ledger, 'cr');
|
|
41
|
+
expect(cr.correctN).toBe(1);
|
|
42
|
+
expect(cr.wrongN).toBe(1);
|
|
43
|
+
expect(cr.partialN).toBe(1);
|
|
44
|
+
expect(cr.unresolvedN).toBe(1);
|
|
45
|
+
expect(cr.decisiveN).toBe(2); // partial + unresolved excluded
|
|
46
|
+
expect(cr.hitRate).toBe(0.5); // 1/(1+1)
|
|
47
|
+
});
|
|
48
|
+
it('hitRate is null when there is no decisive evidence (never 0/0)', () => {
|
|
49
|
+
const ledger = regenerateCapabilityLedger([claim('1'), claim('2')], [resolution('r1', '1', 'partial')], // claim 2 unresolved
|
|
50
|
+
{ resolutionHorizon: HORIZON });
|
|
51
|
+
expect(row(ledger, 'cr').hitRate).toBeNull();
|
|
52
|
+
expect(row(ledger, 'cr').decisiveN).toBe(0);
|
|
53
|
+
});
|
|
54
|
+
it('divides the cohort by actor-id (the acceptance shape)', () => {
|
|
55
|
+
const claims = [claim('1', 'cr'), claim('2', 'cr'), claim('3', 'gca'), claim('4', 'gca')];
|
|
56
|
+
const resolutions = [
|
|
57
|
+
resolution('r1', '1', 'correct'),
|
|
58
|
+
resolution('r2', '2', 'correct'),
|
|
59
|
+
resolution('r3', '3', 'correct'),
|
|
60
|
+
resolution('r4', '4', 'wrong'),
|
|
61
|
+
];
|
|
62
|
+
const ledger = regenerateCapabilityLedger(claims, resolutions, { resolutionHorizon: HORIZON });
|
|
63
|
+
expect(row(ledger, 'cr').hitRate).toBe(1); // 2/2
|
|
64
|
+
expect(row(ledger, 'gca').hitRate).toBe(0.5); // 1/2
|
|
65
|
+
});
|
|
66
|
+
it('excludes immature resolutions past the horizon (near-HEAD skew fix)', () => {
|
|
67
|
+
const ledger = regenerateCapabilityLedger([claim('1')], [resolution('r1', '1', 'wrong', { resolvedAt: '2026-06-21T00:00:00.000Z' })], // > horizon
|
|
68
|
+
{ resolutionHorizon: HORIZON });
|
|
69
|
+
expect(row(ledger, 'cr').unresolvedN).toBe(1);
|
|
70
|
+
expect(row(ledger, 'cr').decisiveN).toBe(0);
|
|
71
|
+
});
|
|
72
|
+
it('compares the horizon chronologically across precision — equal instant is within-horizon (greptile P2)', () => {
|
|
73
|
+
// resolvedAt has no ms; horizon has ms — the SAME instant. A raw lexicographic compare
|
|
74
|
+
// would EXCLUDE it ('.' < 'Z'); the chronological compare correctly includes it (<=).
|
|
75
|
+
const ledger = regenerateCapabilityLedger([claim('1')], [resolution('r1', '1', 'correct', { resolvedAt: '2026-06-20T12:00:00Z' })], { resolutionHorizon: '2026-06-20T12:00:00.000Z' });
|
|
76
|
+
expect(row(ledger, 'cr').correctN).toBe(1);
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
describe('regenerateCapabilityLedger — supersession', () => {
|
|
80
|
+
it('selects the terminal of a supersedesResolutionId chain', () => {
|
|
81
|
+
const ledger = regenerateCapabilityLedger([claim('1')], [
|
|
82
|
+
resolution('r1', '1', 'correct', { resolvedAt: '2026-06-19T01:00:00.000Z' }),
|
|
83
|
+
resolution('r2', '1', 'wrong', {
|
|
84
|
+
resolvedAt: '2026-06-19T02:00:00.000Z',
|
|
85
|
+
supersedesResolutionId: 'r1',
|
|
86
|
+
}),
|
|
87
|
+
], { resolutionHorizon: HORIZON });
|
|
88
|
+
expect(row(ledger, 'cr').wrongN).toBe(1); // r2 (terminal) wins
|
|
89
|
+
expect(row(ledger, 'cr').correctN).toBe(0);
|
|
90
|
+
});
|
|
91
|
+
it('falls back to latest resolvedAt when there is no chain', () => {
|
|
92
|
+
const ledger = regenerateCapabilityLedger([claim('1')], [
|
|
93
|
+
resolution('r1', '1', 'wrong', { resolvedAt: '2026-06-19T01:00:00.000Z' }),
|
|
94
|
+
resolution('r2', '1', 'correct', { resolvedAt: '2026-06-19T05:00:00.000Z' }),
|
|
95
|
+
], { resolutionHorizon: HORIZON });
|
|
96
|
+
expect(row(ledger, 'cr').correctN).toBe(1); // latest (r2) wins
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
describe('regenerateCapabilityLedger — FM-c join integrity (fail loud)', () => {
|
|
100
|
+
it('throws on a resolution referencing an absent claim', () => {
|
|
101
|
+
expect(() => regenerateCapabilityLedger([claim('1')], [resolution('r9', 'NOPE', 'correct')], {
|
|
102
|
+
resolutionHorizon: HORIZON,
|
|
103
|
+
})).toThrow(/references absent claim/);
|
|
104
|
+
});
|
|
105
|
+
it('throws on a duplicate resolutionId', () => {
|
|
106
|
+
expect(() => regenerateCapabilityLedger([claim('1'), claim('2')], [resolution('dup', '1', 'correct'), resolution('dup', '2', 'wrong')], { resolutionHorizon: HORIZON })).toThrow(/duplicate resolutionId/);
|
|
107
|
+
});
|
|
108
|
+
it('throws on a duplicate claimId — would otherwise double-count unresolvedN (greptile P1)', () => {
|
|
109
|
+
expect(() => regenerateCapabilityLedger([claim('1'), claim('1')], [], { resolutionHorizon: HORIZON })).toThrow(/duplicate claimId/);
|
|
110
|
+
});
|
|
111
|
+
it('throws on a dangling supersedesResolutionId — references an absent resolutionId (CR)', () => {
|
|
112
|
+
expect(() => regenerateCapabilityLedger([claim('1')], [resolution('r1', '1', 'correct', { supersedesResolutionId: 'r-ghost' })], { resolutionHorizon: HORIZON })).toThrow(/references an absent resolutionId/);
|
|
113
|
+
});
|
|
114
|
+
it('throws on an ambiguous supersession terminal (two unsuperseded heads)', () => {
|
|
115
|
+
// r3 supersedes r1 (a real pointer — no dangling ref); r2 and r3 are both unsuperseded
|
|
116
|
+
// heads → ambiguous. (Pointers are real so the dangling-ref guard does not fire first.)
|
|
117
|
+
expect(() => regenerateCapabilityLedger([claim('1')], [
|
|
118
|
+
resolution('r1', '1', 'correct'),
|
|
119
|
+
resolution('r2', '1', 'wrong'),
|
|
120
|
+
resolution('r3', '1', 'partial', { supersedesResolutionId: 'r1' }),
|
|
121
|
+
], { resolutionHorizon: HORIZON })).toThrow(/ambiguous terminal/);
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
describe('regenerateCapabilityLedger — FM-a byte reproducibility + ordering', () => {
|
|
125
|
+
it('regenerates byte-identically and sorts rows by (agentSource, taskType)', () => {
|
|
126
|
+
const claims = [claim('2', 'gca'), claim('1', 'cr')];
|
|
127
|
+
const resolutions = [resolution('r1', '1', 'correct'), resolution('r2', '2', 'wrong')];
|
|
128
|
+
const a = regenerateCapabilityLedger(claims, resolutions, { resolutionHorizon: HORIZON });
|
|
129
|
+
const b = regenerateCapabilityLedger([...claims].reverse(), [...resolutions].reverse(), {
|
|
130
|
+
resolutionHorizon: HORIZON,
|
|
131
|
+
});
|
|
132
|
+
expect(canonicalStringify(a)).toBe(canonicalStringify(b));
|
|
133
|
+
expect(a.rows.map((r) => r.agentSource)).toEqual(['cr', 'gca']); // sorted
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
//# sourceMappingURL=regenerate.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"regenerate.test.js","sourceRoot":"","sources":["../../src/capability/regenerate.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type CapabilityClaim, type CapabilityResolution } from './schema.js';
|
|
2
|
+
/** The injected port's output — one mined review finding per review comment. */
|
|
3
|
+
export interface MinedReviewFinding {
|
|
4
|
+
/** GitHub review-comment numeric id (REST exposes no GraphQL node_id) — the nativeKey source. */
|
|
5
|
+
commentId: number;
|
|
6
|
+
/** GitHub author login (a review-bot or a cohort seat). */
|
|
7
|
+
author: string;
|
|
8
|
+
/** Provenance ref of the thread/PR, e.g. `mmnto-ai/totem#2205`. */
|
|
9
|
+
prRef: string;
|
|
10
|
+
/** The commit the finding was asserted against (lowercase 40-hex). */
|
|
11
|
+
commitSha: string;
|
|
12
|
+
/** When the finding was posted (ISO). */
|
|
13
|
+
assertedAt: string;
|
|
14
|
+
/**
|
|
15
|
+
* The deterministic disposition read (reusing `bot-review-parser`'s taxonomy):
|
|
16
|
+
* `accepted` → held → `correct`; `declined` → wrong → `wrong`; `undefined` = silence
|
|
17
|
+
* (no disposition, no fix) → NO resolution row → the regenerator derives `unresolved`
|
|
18
|
+
* (strategy pin: never count silence as a miss).
|
|
19
|
+
*/
|
|
20
|
+
disposition?: 'accepted' | 'declined';
|
|
21
|
+
/** The disposition comment id / fix-commit ref the read was grounded in. */
|
|
22
|
+
dispositionEvidenceRef?: string;
|
|
23
|
+
/** When the disposition was made (ISO); falls back to `assertedAt`. */
|
|
24
|
+
resolvedAt?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface ReviewCatchMineResult {
|
|
27
|
+
claims: CapabilityClaim[];
|
|
28
|
+
resolutions: CapabilityResolution[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Resolve a GitHub author login to a stable Layer-B actor-id, COUPLING to existing
|
|
32
|
+
* actors rather than minting a parallel scheme (#697 fold 5, corrected c.4755848293).
|
|
33
|
+
* The namespace is `{ cohort agent-seats } ∪ { coderabbit, gemini-code-assist, greptile }`:
|
|
34
|
+
* the three ACTIVE paid review bots (de-facto home: `doctrine/bot-protocols.md` + the
|
|
35
|
+
* parity-manifest `bot-review-configs` dimension) + the cohort seats (a cohort dispatch
|
|
36
|
+
* login already IS its `cohort-roles.md` id). `pr-agent`/`qodo` are research-only/dropped
|
|
37
|
+
* (no shipped #670 backend registry to couple to — forward-couple only IF #670 ships), so
|
|
38
|
+
* they are NOT specially mapped. Model/backend identity is intentionally NOT folded into
|
|
39
|
+
* the id (so the hit-rate aggregates across model swaps).
|
|
40
|
+
*
|
|
41
|
+
* @param author - the GitHub login of the finding's author (bot or cohort seat).
|
|
42
|
+
* @returns the stable actor-id — a known bot's canonical id, else the trimmed login.
|
|
43
|
+
* @throws if `author` is empty or whitespace-only (no silent empty actor-id).
|
|
44
|
+
*/
|
|
45
|
+
export declare function resolveActorId(author: string): string;
|
|
46
|
+
/**
|
|
47
|
+
* Mine the review-catch column from a list of findings. One claim per finding; a
|
|
48
|
+
* resolution only when the finding carries a disposition (silence → unresolved by
|
|
49
|
+
* absence). Deterministic: `claimId`/`resolutionId` derive from the finding's stable
|
|
50
|
+
* `commentId`, so re-mining identical history yields identical rows.
|
|
51
|
+
*/
|
|
52
|
+
export declare function mineReviewCatch(findings: readonly MinedReviewFinding[]): ReviewCatchMineResult;
|
|
53
|
+
//# sourceMappingURL=review-catch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-catch.d.ts","sourceRoot":"","sources":["../../src/capability/review-catch.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,KAAK,eAAe,EAEpB,KAAK,oBAAoB,EAG1B,MAAM,aAAa,CAAC;AAErB,gFAAgF;AAChF,MAAM,WAAW,kBAAkB;IACjC,iGAAiG;IACjG,SAAS,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,SAAS,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IACtC,4EAA4E;IAC5E,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAID,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,WAAW,EAAE,oBAAoB,EAAE,CAAC;CACrC;AASD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAWrD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,SAAS,kBAAkB,EAAE,GAAG,qBAAqB,CA+C9F"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// ─── #697 Layer-B — review-catch back-miner (the first column) ───────────────
|
|
2
|
+
//
|
|
3
|
+
// Back-mines the review-catch capability column from PR review primitives: each posted
|
|
4
|
+
// review finding is a CLAIM by its author; its disposition (held = accepted+fixed →
|
|
5
|
+
// correct, declined-as-FP → wrong, silence → unresolved-by-absence) is the RESOLUTION.
|
|
6
|
+
// Author-adjudicated correctness, identical scope to #670. Pure + deterministic: it
|
|
7
|
+
// consumes already-mined findings through an injected port (the live GitHub fetch +
|
|
8
|
+
// `bot-review-parser` disposition read is the CLI-side adapter, a follow-on); core stays
|
|
9
|
+
// network/LLM-free. No LLM-judge — the resolution is a deterministic disposition read
|
|
10
|
+
// (resolutionSource `disposition-thread`), so FM-b holds.
|
|
11
|
+
import { CapabilityClaimSchema, CapabilityResolutionSchema, deriveClaimId, } from './schema.js';
|
|
12
|
+
const REVIEW_CATCH_CLAIM_KIND = 'review-finding';
|
|
13
|
+
/** The three active paid review bots → their stable actor-id, keyed by EXACT login. */
|
|
14
|
+
const REVIEW_BOT_ACTOR_IDS = {
|
|
15
|
+
'coderabbitai[bot]': 'coderabbit',
|
|
16
|
+
'gemini-code-assist[bot]': 'gemini-code-assist',
|
|
17
|
+
'greptile-apps[bot]': 'greptile',
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Resolve a GitHub author login to a stable Layer-B actor-id, COUPLING to existing
|
|
21
|
+
* actors rather than minting a parallel scheme (#697 fold 5, corrected c.4755848293).
|
|
22
|
+
* The namespace is `{ cohort agent-seats } ∪ { coderabbit, gemini-code-assist, greptile }`:
|
|
23
|
+
* the three ACTIVE paid review bots (de-facto home: `doctrine/bot-protocols.md` + the
|
|
24
|
+
* parity-manifest `bot-review-configs` dimension) + the cohort seats (a cohort dispatch
|
|
25
|
+
* login already IS its `cohort-roles.md` id). `pr-agent`/`qodo` are research-only/dropped
|
|
26
|
+
* (no shipped #670 backend registry to couple to — forward-couple only IF #670 ships), so
|
|
27
|
+
* they are NOT specially mapped. Model/backend identity is intentionally NOT folded into
|
|
28
|
+
* the id (so the hit-rate aggregates across model swaps).
|
|
29
|
+
*
|
|
30
|
+
* @param author - the GitHub login of the finding's author (bot or cohort seat).
|
|
31
|
+
* @returns the stable actor-id — a known bot's canonical id, else the trimmed login.
|
|
32
|
+
* @throws if `author` is empty or whitespace-only (no silent empty actor-id).
|
|
33
|
+
*/
|
|
34
|
+
export function resolveActorId(author) {
|
|
35
|
+
const trimmed = author.trim();
|
|
36
|
+
if (trimmed.length === 0) {
|
|
37
|
+
// Fail loud: an empty/whitespace login (e.g. a deleted GH user → null author) must
|
|
38
|
+
// never silently mint an empty actor-id (Tenet 4).
|
|
39
|
+
throw new Error('[Totem Error] resolveActorId: author login must be a non-empty string');
|
|
40
|
+
}
|
|
41
|
+
// EXACT login match, NOT a prefix — so a future variant like `greptile-enterprise[bot]`
|
|
42
|
+
// is not silently collapsed into `greptile` and mixed into its hit-rate (greptile P2).
|
|
43
|
+
// A cohort seat login (e.g. `totem-claude`) is unknown here → returned as its own id.
|
|
44
|
+
return REVIEW_BOT_ACTOR_IDS[trimmed.toLowerCase()] ?? trimmed;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Mine the review-catch column from a list of findings. One claim per finding; a
|
|
48
|
+
* resolution only when the finding carries a disposition (silence → unresolved by
|
|
49
|
+
* absence). Deterministic: `claimId`/`resolutionId` derive from the finding's stable
|
|
50
|
+
* `commentId`, so re-mining identical history yields identical rows.
|
|
51
|
+
*/
|
|
52
|
+
export function mineReviewCatch(findings) {
|
|
53
|
+
const claims = [];
|
|
54
|
+
const resolutions = [];
|
|
55
|
+
for (const f of findings) {
|
|
56
|
+
const nativeKey = `gh-review-comment:${f.commentId}`;
|
|
57
|
+
const agentSource = resolveActorId(f.author);
|
|
58
|
+
const claimId = deriveClaimId({
|
|
59
|
+
agentSource,
|
|
60
|
+
taskType: 'review-catch',
|
|
61
|
+
claimKind: REVIEW_CATCH_CLAIM_KIND,
|
|
62
|
+
provenanceRef: f.prRef,
|
|
63
|
+
commitSha: f.commitSha,
|
|
64
|
+
nativeKey,
|
|
65
|
+
});
|
|
66
|
+
claims.push(CapabilityClaimSchema.parse({
|
|
67
|
+
claimId,
|
|
68
|
+
agentSource,
|
|
69
|
+
taskType: 'review-catch',
|
|
70
|
+
claimKind: REVIEW_CATCH_CLAIM_KIND,
|
|
71
|
+
provenance: { ref: f.prRef, commitSha: f.commitSha },
|
|
72
|
+
nativeKey,
|
|
73
|
+
assertedAt: f.assertedAt,
|
|
74
|
+
}));
|
|
75
|
+
if (f.disposition === 'accepted' || f.disposition === 'declined') {
|
|
76
|
+
resolutions.push(CapabilityResolutionSchema.parse({
|
|
77
|
+
resolutionId: `rc-res:${f.commentId}`,
|
|
78
|
+
claimId,
|
|
79
|
+
outcome: f.disposition === 'accepted' ? 'correct' : 'wrong',
|
|
80
|
+
// Deterministic read of the disposition primitive — never an LLM-judge (FM-b).
|
|
81
|
+
resolutionSource: 'disposition-thread',
|
|
82
|
+
// `?.trim() ||` (not `??`) so an empty/whitespace evidenceRef/resolvedAt falls
|
|
83
|
+
// back instead of tripping the schema's non-empty/datetime guards (GCA).
|
|
84
|
+
evidenceRef: f.dispositionEvidenceRef?.trim() || nativeKey,
|
|
85
|
+
resolvedAt: f.resolvedAt?.trim() || f.assertedAt,
|
|
86
|
+
}));
|
|
87
|
+
}
|
|
88
|
+
// silence (no disposition) → no resolution row → regenerator buckets it `unresolved`.
|
|
89
|
+
}
|
|
90
|
+
return { claims, resolutions };
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=review-catch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-catch.js","sourceRoot":"","sources":["../../src/capability/review-catch.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,EAAE;AACF,uFAAuF;AACvF,oFAAoF;AACpF,uFAAuF;AACvF,oFAAoF;AACpF,oFAAoF;AACpF,yFAAyF;AACzF,sFAAsF;AACtF,0DAA0D;AAE1D,OAAO,EAEL,qBAAqB,EAErB,0BAA0B,EAC1B,aAAa,GACd,MAAM,aAAa,CAAC;AA2BrB,MAAM,uBAAuB,GAAG,gBAAgB,CAAC;AAOjD,uFAAuF;AACvF,MAAM,oBAAoB,GAAqC;IAC7D,mBAAmB,EAAE,YAAY;IACjC,yBAAyB,EAAE,oBAAoB;IAC/C,oBAAoB,EAAE,UAAU;CACjC,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,mFAAmF;QACnF,mDAAmD;QACnD,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAC;IAC3F,CAAC;IACD,wFAAwF;IACxF,uFAAuF;IACvF,sFAAsF;IACtF,OAAO,oBAAoB,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,IAAI,OAAO,CAAC;AAChE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,QAAuC;IACrE,MAAM,MAAM,GAAsB,EAAE,CAAC;IACrC,MAAM,WAAW,GAA2B,EAAE,CAAC;IAE/C,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,qBAAqB,CAAC,CAAC,SAAS,EAAE,CAAC;QACrD,MAAM,WAAW,GAAG,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC7C,MAAM,OAAO,GAAG,aAAa,CAAC;YAC5B,WAAW;YACX,QAAQ,EAAE,cAAc;YACxB,SAAS,EAAE,uBAAuB;YAClC,aAAa,EAAE,CAAC,CAAC,KAAK;YACtB,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,SAAS;SACV,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CACT,qBAAqB,CAAC,KAAK,CAAC;YAC1B,OAAO;YACP,WAAW;YACX,QAAQ,EAAE,cAAc;YACxB,SAAS,EAAE,uBAAuB;YAClC,UAAU,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE;YACpD,SAAS;YACT,UAAU,EAAE,CAAC,CAAC,UAAU;SACzB,CAAC,CACH,CAAC;QAEF,IAAI,CAAC,CAAC,WAAW,KAAK,UAAU,IAAI,CAAC,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;YACjE,WAAW,CAAC,IAAI,CACd,0BAA0B,CAAC,KAAK,CAAC;gBAC/B,YAAY,EAAE,UAAU,CAAC,CAAC,SAAS,EAAE;gBACrC,OAAO;gBACP,OAAO,EAAE,CAAC,CAAC,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO;gBAC3D,+EAA+E;gBAC/E,gBAAgB,EAAE,oBAAoB;gBACtC,+EAA+E;gBAC/E,yEAAyE;gBACzE,WAAW,EAAE,CAAC,CAAC,sBAAsB,EAAE,IAAI,EAAE,IAAI,SAAS;gBAC1D,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,UAAU;aACjD,CAAC,CACH,CAAC;QACJ,CAAC;QACD,sFAAsF;IACxF,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-catch.test.d.ts","sourceRoot":"","sources":["../../src/capability/review-catch.test.ts"],"names":[],"mappings":""}
|