loopforge 2.0.0 → 2.6.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/README.md +7 -5
- package/dist/backends/interface.d.ts +4 -3
- package/dist/backends/interface.d.ts.map +1 -1
- package/dist/backends/interface.js +4 -1
- package/dist/backends/interface.js.map +1 -1
- package/dist/canonical-state.d.ts +23 -2
- package/dist/canonical-state.d.ts.map +1 -1
- package/dist/canonical-state.js +90 -6
- package/dist/canonical-state.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +6 -2
- package/dist/cli.js.map +1 -1
- package/dist/enforcement-gate.d.ts +1 -1
- package/dist/enforcement-gate.d.ts.map +1 -1
- package/dist/enforcement-gate.js +86 -7
- package/dist/enforcement-gate.js.map +1 -1
- package/dist/engine.d.ts +3 -33
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +127 -343
- package/dist/engine.js.map +1 -1
- package/dist/evidence-provider.d.ts +38 -5
- package/dist/evidence-provider.d.ts.map +1 -1
- package/dist/evidence-provider.js +132 -46
- package/dist/evidence-provider.js.map +1 -1
- package/dist/index.d.ts +10 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -9
- package/dist/index.js.map +1 -1
- package/dist/interop.d.ts +5 -0
- package/dist/interop.d.ts.map +1 -1
- package/dist/interop.js +5 -0
- package/dist/interop.js.map +1 -1
- package/dist/loop-compiler.d.ts.map +1 -1
- package/dist/loop-compiler.js +515 -50
- package/dist/loop-compiler.js.map +1 -1
- package/dist/loop-extras-parser.d.ts +82 -0
- package/dist/loop-extras-parser.d.ts.map +1 -0
- package/dist/loop-extras-parser.js +217 -0
- package/dist/loop-extras-parser.js.map +1 -0
- package/dist/loop-store.d.ts +26 -4
- package/dist/loop-store.d.ts.map +1 -1
- package/dist/loop-store.js +118 -8
- package/dist/loop-store.js.map +1 -1
- package/dist/mcp/server.js +1 -1
- package/dist/mcp/session.d.ts +29 -6
- package/dist/mcp/session.d.ts.map +1 -1
- package/dist/mcp/session.js +187 -161
- package/dist/mcp/session.js.map +1 -1
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +33 -5
- package/dist/mcp/tools.js.map +1 -1
- package/dist/observability.d.ts +5 -36
- package/dist/observability.d.ts.map +1 -1
- package/dist/observability.js +9 -79
- package/dist/observability.js.map +1 -1
- package/dist/policy-metrics.d.ts +1 -0
- package/dist/policy-metrics.d.ts.map +1 -1
- package/dist/policy-metrics.js +2 -0
- package/dist/policy-metrics.js.map +1 -1
- package/dist/policy.d.ts +58 -8
- package/dist/policy.d.ts.map +1 -1
- package/dist/policy.js +25 -12
- package/dist/policy.js.map +1 -1
- package/dist/prompt-assembler.d.ts.map +1 -1
- package/dist/prompt-assembler.js +129 -4
- package/dist/prompt-assembler.js.map +1 -1
- package/dist/protocol.d.ts +118 -87
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +40 -30
- package/dist/protocol.js.map +1 -1
- package/dist/replay.d.ts +0 -1
- package/dist/replay.d.ts.map +1 -1
- package/dist/replay.js +1 -87
- package/dist/replay.js.map +1 -1
- package/dist/round-coordinator.d.ts +4 -6
- package/dist/round-coordinator.d.ts.map +1 -1
- package/dist/round-coordinator.js +75 -80
- package/dist/round-coordinator.js.map +1 -1
- package/dist/round-driver.d.ts +1 -0
- package/dist/round-driver.d.ts.map +1 -1
- package/dist/round-driver.js +2 -0
- package/dist/round-driver.js.map +1 -1
- package/dist/round-transaction.d.ts.map +1 -1
- package/dist/round-transaction.js +2 -22
- package/dist/round-transaction.js.map +1 -1
- package/dist/run.d.ts +51 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +200 -0
- package/dist/run.js.map +1 -0
- package/dist/self-eval.d.ts +23 -0
- package/dist/self-eval.d.ts.map +1 -0
- package/dist/self-eval.js +151 -0
- package/dist/self-eval.js.map +1 -0
- package/dist/storage.d.ts +3 -2
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +70 -68
- package/dist/storage.js.map +1 -1
- package/dist/token-utils.d.ts +22 -0
- package/dist/token-utils.d.ts.map +1 -0
- package/dist/token-utils.js +46 -0
- package/dist/token-utils.js.map +1 -0
- package/dist/verification-gate.d.ts +17 -23
- package/dist/verification-gate.d.ts.map +1 -1
- package/dist/verification-gate.js +241 -135
- package/dist/verification-gate.js.map +1 -1
- package/loop_policy.json +21 -12
- package/package.json +2 -2
- package/dist/runtime.d.ts +0 -94
- package/dist/runtime.d.ts.map +0 -1
- package/dist/runtime.js +0 -718
- package/dist/runtime.js.map +0 -1
package/dist/storage.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/** Persistence adapters for session state and committed round lookup. */
|
|
2
|
-
|
|
2
|
+
import { LOOP_STORE_SCHEMA_VERSION } from "./loop-store.js";
|
|
3
|
+
function isLeaseOwnerAlive(ownerId, leaseExpiresAt) {
|
|
3
4
|
const match = ownerId.match(/^(\d+):/);
|
|
4
5
|
if (!match)
|
|
5
|
-
return true;
|
|
6
|
+
return true; // No PID in ownerId — assume alive (safety)
|
|
6
7
|
const pid = Number(match[1]);
|
|
7
8
|
if (!Number.isInteger(pid) || pid <= 0)
|
|
8
9
|
return true;
|
|
@@ -11,7 +12,17 @@ function isLeaseOwnerAlive(ownerId) {
|
|
|
11
12
|
return true;
|
|
12
13
|
}
|
|
13
14
|
catch (error) {
|
|
14
|
-
|
|
15
|
+
const code = error.code;
|
|
16
|
+
if (code === "EPERM") {
|
|
17
|
+
// Windows may return EPERM for dead processes. If the lease has
|
|
18
|
+
// expired or is within 5 s of expiry, treat the owner as dead
|
|
19
|
+
// regardless so a new owner can acquire the session.
|
|
20
|
+
if (leaseExpiresAt !== undefined && leaseExpiresAt <= Date.now() + 5000) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
return true; // EPERM with lease remaining — assume alive
|
|
24
|
+
}
|
|
25
|
+
return false; // ESRCH or other — definitely dead
|
|
15
26
|
}
|
|
16
27
|
}
|
|
17
28
|
export class SessionLeaseConflictError extends Error {
|
|
@@ -23,17 +34,22 @@ export class SessionLeaseConflictError extends Error {
|
|
|
23
34
|
}
|
|
24
35
|
}
|
|
25
36
|
export class VaultSessionStateStore {
|
|
26
|
-
|
|
27
|
-
constructor(
|
|
28
|
-
this.
|
|
37
|
+
store;
|
|
38
|
+
constructor(store) {
|
|
39
|
+
this.store = store;
|
|
29
40
|
}
|
|
30
41
|
load(loopId) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
entry.task_id === `loop:${loopId}:session`);
|
|
42
|
+
const session = this.store.readSession(loopId);
|
|
43
|
+
return session?.entry;
|
|
34
44
|
}
|
|
35
45
|
list() {
|
|
36
|
-
|
|
46
|
+
const result = [];
|
|
47
|
+
for (const loopId of this.store.listLoopIds()) {
|
|
48
|
+
const session = this.store.readSession(loopId);
|
|
49
|
+
if (session)
|
|
50
|
+
result.push(session.entry);
|
|
51
|
+
}
|
|
52
|
+
return result;
|
|
37
53
|
}
|
|
38
54
|
save(entry, options = {}) {
|
|
39
55
|
const loopId = entry.loop_id;
|
|
@@ -41,13 +57,9 @@ export class VaultSessionStateStore {
|
|
|
41
57
|
throw new Error("Session state entry requires loop_id");
|
|
42
58
|
}
|
|
43
59
|
const write = () => {
|
|
44
|
-
const
|
|
45
|
-
const entries = Array.isArray(vault.entries)
|
|
46
|
-
? vault.entries
|
|
47
|
-
: [];
|
|
48
|
-
const existing = entries.find((item) => item.task_type === "session_state" && item.loop_id === loopId);
|
|
60
|
+
const existing = this.store.readSession(loopId);
|
|
49
61
|
if (existing && options.expectedLeaseOwner) {
|
|
50
|
-
const lineage = this.lineage(existing);
|
|
62
|
+
const lineage = this.lineage(existing.entry);
|
|
51
63
|
const owner = typeof lineage.lease_owner === "string"
|
|
52
64
|
? lineage.lease_owner
|
|
53
65
|
: "";
|
|
@@ -55,30 +67,23 @@ export class VaultSessionStateStore {
|
|
|
55
67
|
throw new SessionLeaseConflictError(loopId);
|
|
56
68
|
}
|
|
57
69
|
}
|
|
58
|
-
|
|
59
|
-
|
|
70
|
+
const doc = {
|
|
71
|
+
schemaVersion: LOOP_STORE_SCHEMA_VERSION,
|
|
72
|
+
loopId,
|
|
73
|
+
updatedAt: new Date().toISOString(),
|
|
60
74
|
entry,
|
|
61
|
-
|
|
62
|
-
this.
|
|
75
|
+
};
|
|
76
|
+
this.store.writeSession(loopId, doc);
|
|
63
77
|
};
|
|
64
|
-
|
|
65
|
-
this.backend.withLock(write);
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
write();
|
|
69
|
-
}
|
|
78
|
+
this.store.withLock(write);
|
|
70
79
|
}
|
|
71
80
|
acquireLease(loopId, ownerId, leaseMs, now = Date.now()) {
|
|
72
81
|
let claimed;
|
|
73
82
|
const write = () => {
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
? vault.entries
|
|
77
|
-
: [];
|
|
78
|
-
const index = entries.findIndex((entry) => entry.task_type === "session_state" && entry.loop_id === loopId);
|
|
79
|
-
if (index < 0)
|
|
83
|
+
const session = this.store.readSession(loopId);
|
|
84
|
+
if (!session)
|
|
80
85
|
return;
|
|
81
|
-
const entry =
|
|
86
|
+
const entry = session.entry;
|
|
82
87
|
const lineage = this.lineage(entry);
|
|
83
88
|
const owner = typeof lineage.lease_owner === "string"
|
|
84
89
|
? lineage.lease_owner
|
|
@@ -104,63 +109,58 @@ export class VaultSessionStateStore {
|
|
|
104
109
|
lease_epoch: owner === ownerId ? previousEpoch : previousEpoch + 1,
|
|
105
110
|
},
|
|
106
111
|
};
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
112
|
+
const doc = {
|
|
113
|
+
schemaVersion: LOOP_STORE_SCHEMA_VERSION,
|
|
114
|
+
loopId,
|
|
115
|
+
updatedAt: new Date(now).toISOString(),
|
|
116
|
+
entry: updated,
|
|
117
|
+
};
|
|
118
|
+
this.store.writeSession(loopId, doc);
|
|
110
119
|
claimed = updated;
|
|
111
120
|
};
|
|
112
|
-
|
|
113
|
-
this.backend.withLock(write);
|
|
114
|
-
else
|
|
115
|
-
write();
|
|
121
|
+
this.store.withLock(write);
|
|
116
122
|
return claimed;
|
|
117
123
|
}
|
|
118
124
|
renewLease(loopId, ownerId, leaseMs, now = Date.now()) {
|
|
119
125
|
let renewed = false;
|
|
120
126
|
const write = () => {
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
? vault.entries
|
|
124
|
-
: [];
|
|
125
|
-
const index = entries.findIndex((entry) => entry.task_type === "session_state" && entry.loop_id === loopId);
|
|
126
|
-
if (index < 0)
|
|
127
|
+
const session = this.store.readSession(loopId);
|
|
128
|
+
if (!session)
|
|
127
129
|
return;
|
|
128
|
-
const entry =
|
|
130
|
+
const entry = session.entry;
|
|
129
131
|
const lineage = this.lineage(entry);
|
|
130
132
|
if (lineage.lease_owner !== ownerId)
|
|
131
133
|
return;
|
|
132
|
-
|
|
134
|
+
const updated = {
|
|
133
135
|
...entry,
|
|
134
136
|
loop_lineage: {
|
|
135
137
|
...lineage,
|
|
136
138
|
lease_expires_at: now + Math.max(1, leaseMs),
|
|
137
139
|
},
|
|
138
140
|
};
|
|
139
|
-
|
|
140
|
-
|
|
141
|
+
const doc = {
|
|
142
|
+
schemaVersion: LOOP_STORE_SCHEMA_VERSION,
|
|
143
|
+
loopId,
|
|
144
|
+
updatedAt: new Date(now).toISOString(),
|
|
145
|
+
entry: updated,
|
|
146
|
+
};
|
|
147
|
+
this.store.writeSession(loopId, doc);
|
|
141
148
|
renewed = true;
|
|
142
149
|
};
|
|
143
|
-
|
|
144
|
-
this.backend.withLock(write);
|
|
145
|
-
else
|
|
146
|
-
write();
|
|
150
|
+
this.store.withLock(write);
|
|
147
151
|
return renewed;
|
|
148
152
|
}
|
|
149
153
|
releaseLease(loopId, ownerId) {
|
|
150
154
|
let released = false;
|
|
151
155
|
const write = () => {
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
? vault.entries
|
|
155
|
-
: [];
|
|
156
|
-
const index = entries.findIndex((entry) => entry.task_type === "session_state" && entry.loop_id === loopId);
|
|
157
|
-
if (index < 0)
|
|
156
|
+
const session = this.store.readSession(loopId);
|
|
157
|
+
if (!session)
|
|
158
158
|
return;
|
|
159
|
-
const entry =
|
|
159
|
+
const entry = session.entry;
|
|
160
160
|
const lineage = this.lineage(entry);
|
|
161
161
|
if (lineage.lease_owner !== ownerId)
|
|
162
162
|
return;
|
|
163
|
-
|
|
163
|
+
const updated = {
|
|
164
164
|
...entry,
|
|
165
165
|
loop_lineage: {
|
|
166
166
|
...lineage,
|
|
@@ -168,14 +168,16 @@ export class VaultSessionStateStore {
|
|
|
168
168
|
lease_expires_at: 0,
|
|
169
169
|
},
|
|
170
170
|
};
|
|
171
|
-
|
|
172
|
-
|
|
171
|
+
const doc = {
|
|
172
|
+
schemaVersion: LOOP_STORE_SCHEMA_VERSION,
|
|
173
|
+
loopId,
|
|
174
|
+
updatedAt: new Date().toISOString(),
|
|
175
|
+
entry: updated,
|
|
176
|
+
};
|
|
177
|
+
this.store.writeSession(loopId, doc);
|
|
173
178
|
released = true;
|
|
174
179
|
};
|
|
175
|
-
|
|
176
|
-
this.backend.withLock(write);
|
|
177
|
-
else
|
|
178
|
-
write();
|
|
180
|
+
this.store.withLock(write);
|
|
179
181
|
return released;
|
|
180
182
|
}
|
|
181
183
|
lineage(entry) {
|
package/dist/storage.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA,yEAAyE;AAIzE,SAAS,iBAAiB,CAAC,OAAe;
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Shared token utilities — Jaccard similarity, dedup, vault entry helpers.
|
|
2
|
+
*
|
|
3
|
+
* Single source of truth for tokenization and similarity functions used
|
|
4
|
+
* by the compiler, verification gate, and canonical state renderer.
|
|
5
|
+
*
|
|
6
|
+
* The Unicode token regex covers CJK Unified Ideographs (U+4E00–U+9FFF)
|
|
7
|
+
* plus CJK Extension A (U+3400–U+4DBF), ensuring consistent similarity
|
|
8
|
+
* scores across all modules.
|
|
9
|
+
*/
|
|
10
|
+
/** Tokenize text into a set of lowercase words and CJK characters.
|
|
11
|
+
* Regex covers Latin alphanumeric + CJK Unified + CJK Extension A. */
|
|
12
|
+
export declare function tokenize(text: string): Set<string>;
|
|
13
|
+
/** Jaccard similarity in [0, 1]. Returns 1 when either set is empty
|
|
14
|
+
* (empty descriptions never match anything, so they don't false-positive). */
|
|
15
|
+
export declare function jaccardSimilarity(left: string, right: string): number;
|
|
16
|
+
/** Filter null/undefined/empty strings, trim, and deduplicate via Set. */
|
|
17
|
+
export declare function unique(values: Array<string | null | undefined>): string[];
|
|
18
|
+
/** Extract the round number from a vault entry-like object by reading
|
|
19
|
+
* `loop_lineage.round` (with `lineage.round` fallback). Returns 0 if
|
|
20
|
+
* the entry has no recognizable round field. */
|
|
21
|
+
export declare function entryRound(entry: Record<string, unknown>): number;
|
|
22
|
+
//# sourceMappingURL=token-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-utils.d.ts","sourceRoot":"","sources":["../src/token-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;uEACuE;AACvE,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAElD;AAED;+EAC+E;AAC/E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAOrE;AAID,0EAA0E;AAC1E,wBAAgB,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,MAAM,EAAE,CAKzE;AAID;;iDAEiD;AACjD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAIjE"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** Shared token utilities — Jaccard similarity, dedup, vault entry helpers.
|
|
2
|
+
*
|
|
3
|
+
* Single source of truth for tokenization and similarity functions used
|
|
4
|
+
* by the compiler, verification gate, and canonical state renderer.
|
|
5
|
+
*
|
|
6
|
+
* The Unicode token regex covers CJK Unified Ideographs (U+4E00–U+9FFF)
|
|
7
|
+
* plus CJK Extension A (U+3400–U+4DBF), ensuring consistent similarity
|
|
8
|
+
* scores across all modules.
|
|
9
|
+
*/
|
|
10
|
+
// ── Tokenization & similarity ──────────────────────────────────────────────
|
|
11
|
+
/** Tokenize text into a set of lowercase words and CJK characters.
|
|
12
|
+
* Regex covers Latin alphanumeric + CJK Unified + CJK Extension A. */
|
|
13
|
+
export function tokenize(text) {
|
|
14
|
+
return new Set(text.toLowerCase().match(/[a-z0-9㐀-鿿]+/g) ?? []);
|
|
15
|
+
}
|
|
16
|
+
/** Jaccard similarity in [0, 1]. Returns 1 when either set is empty
|
|
17
|
+
* (empty descriptions never match anything, so they don't false-positive). */
|
|
18
|
+
export function jaccardSimilarity(left, right) {
|
|
19
|
+
const a = tokenize(left);
|
|
20
|
+
const b = tokenize(right);
|
|
21
|
+
if (a.size === 0 || b.size === 0)
|
|
22
|
+
return 1;
|
|
23
|
+
let intersection = 0;
|
|
24
|
+
for (const value of a)
|
|
25
|
+
if (b.has(value))
|
|
26
|
+
intersection++;
|
|
27
|
+
return intersection / new Set([...a, ...b]).size;
|
|
28
|
+
}
|
|
29
|
+
// ── Dedup helper ───────────────────────────────────────────────────────────
|
|
30
|
+
/** Filter null/undefined/empty strings, trim, and deduplicate via Set. */
|
|
31
|
+
export function unique(values) {
|
|
32
|
+
return [...new Set(values
|
|
33
|
+
.filter((value) => typeof value === "string")
|
|
34
|
+
.map((value) => value.trim())
|
|
35
|
+
.filter(Boolean))];
|
|
36
|
+
}
|
|
37
|
+
// ── Vault entry helpers ────────────────────────────────────────────────────
|
|
38
|
+
/** Extract the round number from a vault entry-like object by reading
|
|
39
|
+
* `loop_lineage.round` (with `lineage.round` fallback). Returns 0 if
|
|
40
|
+
* the entry has no recognizable round field. */
|
|
41
|
+
export function entryRound(entry) {
|
|
42
|
+
const lin = (entry.loop_lineage ?? entry.lineage ?? {});
|
|
43
|
+
const rnd = lin.round;
|
|
44
|
+
return typeof rnd === "number" && Number.isInteger(rnd) ? rnd : 0;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=token-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-utils.js","sourceRoot":"","sources":["../src/token-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,8EAA8E;AAE9E;uEACuE;AACvE,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC;AAClE,CAAC;AAED;+EAC+E;AAC/E,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,KAAa;IAC3D,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IACzB,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1B,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAC3C,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,KAAK,MAAM,KAAK,IAAI,CAAC;QAAE,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,YAAY,EAAE,CAAC;IACxD,OAAO,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACnD,CAAC;AAED,8EAA8E;AAE9E,0EAA0E;AAC1E,MAAM,UAAU,MAAM,CAAC,MAAwC;IAC7D,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM;aACtB,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC;aAC7D,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;aAC5B,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACvB,CAAC;AAED,8EAA8E;AAE9E;;iDAEiD;AACjD,MAAM,UAAU,UAAU,CAAC,KAA8B;IACvD,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,OAAO,IAAI,EAAE,CAA4B,CAAC;IACnF,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC;IACtB,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC"}
|
|
@@ -15,31 +15,29 @@
|
|
|
15
15
|
import type { VaultEntry } from "./backends/interface.js";
|
|
16
16
|
import type { ProviderSnapshot } from "./evidence-provider.js";
|
|
17
17
|
import type { SelfEvaluation, VerificationResult } from "./protocol.js";
|
|
18
|
+
export { type GitFileState, captureGitFileState, captureGitModifiedFiles, } from "./evidence-provider.js";
|
|
18
19
|
/** Extract the round number from a vault entry's loop_lineage.
|
|
19
20
|
* Returns 0 if the entry has no lineage or no round field.
|
|
20
21
|
* In practice, persistLoopLineage always writes round ≥ 1, so 0
|
|
21
22
|
* unambiguously means "not a valid round entry" in this context.
|
|
22
23
|
* Exported for reuse by enforcement-gate.ts. */
|
|
23
24
|
export declare function entryRound(entry: VaultEntry): number;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
staged: string[];
|
|
30
|
-
/** Untracked files not yet known to git (git ls-files --others --exclude-standard). */
|
|
31
|
-
untracked: string[];
|
|
25
|
+
interface ParsedTestCounts {
|
|
26
|
+
passed: number;
|
|
27
|
+
failed: number;
|
|
28
|
+
skipped: number;
|
|
29
|
+
total: number;
|
|
32
30
|
}
|
|
33
|
-
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
export declare function
|
|
31
|
+
/** Best-effort parse of test counts from common test-runner output formats.
|
|
32
|
+
*
|
|
33
|
+
* Scans the last 2000 characters of stdout (where summary lines typically
|
|
34
|
+
* appear) and tries patterns in descending specificity order. Returns null
|
|
35
|
+
* when the output format is unrecognized, stdout is empty, or a confident
|
|
36
|
+
* parse cannot be made.
|
|
37
|
+
*
|
|
38
|
+
* Recognized formats: Jest verbose/compact, Mocha, pytest/unittest, Go test,
|
|
39
|
+
* and PHPUnit OK summaries. */
|
|
40
|
+
export declare function parseTestOutput(stdout: string): ParsedTestCounts | null;
|
|
43
41
|
/** Verify a SelfEvaluation against the loop's cross-round lineage.
|
|
44
42
|
*
|
|
45
43
|
* @param selfEval The agent's self-evaluation for the current round.
|
|
@@ -47,12 +45,8 @@ export declare function captureGitModifiedFiles(): string[] | null;
|
|
|
47
45
|
* @param vaultEntries Vault entries for this loop (non-feedback only).
|
|
48
46
|
* @param prevSelfEval The agent's self-evaluation from the previous round
|
|
49
47
|
* (null for round 1).
|
|
50
|
-
* @param runtimeFilesChanged v1.16: Files detected as changed by git diff between
|
|
51
|
-
* before/after execute. null if git is unavailable.
|
|
52
|
-
* Used by checkFilesIntegrity to cross-validate
|
|
53
|
-
* agent-reported files_changed against reality.
|
|
54
48
|
* @param evidenceSnapshots v1.18: Evidence snapshots from configured providers.
|
|
55
49
|
* Used by checkEvidenceIntegrity for multi-provider
|
|
56
50
|
* cross-validation. Defaults to empty array. */
|
|
57
|
-
export declare function verifySelfEvaluation(selfEval: SelfEvaluation, currentRound: number, vaultEntries: VaultEntry[], prevSelfEval?: SelfEvaluation | null,
|
|
51
|
+
export declare function verifySelfEvaluation(selfEval: SelfEvaluation, currentRound: number, vaultEntries: VaultEntry[], prevSelfEval?: SelfEvaluation | null, evidenceSnapshots?: ProviderSnapshot[]): VerificationResult;
|
|
58
52
|
//# sourceMappingURL=verification-gate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verification-gate.d.ts","sourceRoot":"","sources":["../src/verification-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;
|
|
1
|
+
{"version":3,"file":"verification-gate.d.ts","sourceRoot":"","sources":["../src/verification-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,OAAO,KAAK,EAAE,cAAc,EAAoB,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAO1F,OAAO,EACL,KAAK,YAAY,EACjB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAMhC;;;;iDAIiD;AACjD,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAEpD;AAkTD,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;gCAQgC;AAChC,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CA4DvE;AA8ID;;;;;;;;;4EAS4E;AAC5E,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,cAAc,EACxB,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,UAAU,EAAE,EAC1B,YAAY,GAAE,cAAc,GAAG,IAAW,EAC1C,iBAAiB,GAAE,gBAAgB,EAAO,GACzC,kBAAkB,CAgDpB"}
|