zelari-code 2.40.0 → 2.41.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/cli/headless/runOneTurn.js +28 -4
- package/dist/cli/headless/runOneTurn.js.map +1 -1
- package/dist/cli/hooks/useChatTurn.js +12 -1
- package/dist/cli/hooks/useChatTurn.js.map +1 -1
- package/dist/cli/main.bundled.js +919 -516
- package/dist/cli/main.bundled.js.map +4 -4
- package/dist/cli/memory/howWeTest.js +196 -0
- package/dist/cli/memory/howWeTest.js.map +1 -0
- package/dist/cli/memory/opsKnowledge.js +18 -1
- package/dist/cli/memory/opsKnowledge.js.map +1 -1
- package/dist/cli/memory/promotion.js +57 -0
- package/dist/cli/memory/promotion.js.map +1 -1
- package/dist/cli/memory/repeatCheck.js +129 -0
- package/dist/cli/memory/repeatCheck.js.map +1 -0
- package/dist/cli/slashHandlers/memory.js +47 -3
- package/dist/cli/slashHandlers/memory.js.map +1 -1
- package/dist/cli/workspace/worldModel.js +61 -0
- package/dist/cli/workspace/worldModel.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `.zelari/how-we-test.md` — the shared testing playbook (slice C of the
|
|
3
|
+
* "steal Cursor Projects" plan).
|
|
4
|
+
*
|
|
5
|
+
* `opsKnowledge.ts` already remembers a verified `procedure` in Memory V2
|
|
6
|
+
* every time a strict gate PASSes on deterministic, event-backed evidence.
|
|
7
|
+
* That knowledge is only useful to agents that can *read* it, so this module
|
|
8
|
+
* projects it into a human- and agent-readable markdown file.
|
|
9
|
+
*
|
|
10
|
+
* The projection is a pure function of the rows; the writer is atomic
|
|
11
|
+
* (tmp → rename) and byte-idempotent, so regenerating on every promotion does
|
|
12
|
+
* not churn the file when nothing changed.
|
|
13
|
+
*
|
|
14
|
+
* Never throws to the parent run — a projection failure must not affect a gate.
|
|
15
|
+
*/
|
|
16
|
+
import { promises as fs } from 'node:fs';
|
|
17
|
+
import * as path from 'node:path';
|
|
18
|
+
export const HOW_WE_TEST_RELATIVE = path.join('.zelari', 'how-we-test.md');
|
|
19
|
+
/** Header marker: humans must not hand-edit a generated file. */
|
|
20
|
+
export const HOW_WE_TEST_HEADER = '<!-- generato — non editare (rigenera con /memory how-we-test) -->';
|
|
21
|
+
function metaString(node, key) {
|
|
22
|
+
const value = node.metadata?.[key];
|
|
23
|
+
return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;
|
|
24
|
+
}
|
|
25
|
+
function metaNumber(node, key) {
|
|
26
|
+
const value = node.metadata?.[key];
|
|
27
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
28
|
+
}
|
|
29
|
+
/** One row per verified, active `procedure` node. Null when not projectable. */
|
|
30
|
+
export function rowFromNode(node) {
|
|
31
|
+
if (node.kind !== 'procedure' || node.status !== 'active')
|
|
32
|
+
return null;
|
|
33
|
+
if (node.metadata?.verified !== true)
|
|
34
|
+
return null;
|
|
35
|
+
const key = metaString(node, 'opsKnowledgeKey');
|
|
36
|
+
const command = metaString(node, 'command');
|
|
37
|
+
const digest = metaString(node, 'digest');
|
|
38
|
+
if (!key || !command || !digest)
|
|
39
|
+
return null;
|
|
40
|
+
const seq = metaNumber(node, 'seq');
|
|
41
|
+
return {
|
|
42
|
+
key,
|
|
43
|
+
criterionId: metaString(node, 'criterionId') ?? 'unknown',
|
|
44
|
+
command,
|
|
45
|
+
digest,
|
|
46
|
+
...(seq === undefined ? {} : { seq }),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Rows for the projection, deduped by `opsKnowledgeKey` (the same procedure
|
|
51
|
+
* re-verified keeps the newest observation). Order-independent: the input is
|
|
52
|
+
* sorted before deduping so any permutation projects to the same bytes.
|
|
53
|
+
*/
|
|
54
|
+
export function collectHowWeTestRows(nodes) {
|
|
55
|
+
const rows = nodes.map(rowFromNode).filter((row) => row !== null);
|
|
56
|
+
rows.sort((a, b) => a.key.localeCompare(b.key) || (a.seq ?? -1) - (b.seq ?? -1));
|
|
57
|
+
const byKey = new Map();
|
|
58
|
+
for (const row of rows)
|
|
59
|
+
byKey.set(row.key, row);
|
|
60
|
+
return [...byKey.values()].sort((a, b) => a.criterionId.localeCompare(b.criterionId) || a.command.localeCompare(b.command));
|
|
61
|
+
}
|
|
62
|
+
/** Short digest for display: enough to disambiguate, short enough to read. */
|
|
63
|
+
export function shortDigest(digest) {
|
|
64
|
+
return digest.length <= 8 ? digest : digest.slice(0, 8);
|
|
65
|
+
}
|
|
66
|
+
function escapeCell(value) {
|
|
67
|
+
return value.replace(/\r?\n/g, ' ').replace(/`/g, "'").trim();
|
|
68
|
+
}
|
|
69
|
+
/** Pure: rows → markdown. Deterministic and idempotent. */
|
|
70
|
+
export function projectHowWeTest(rows) {
|
|
71
|
+
const lines = [
|
|
72
|
+
'# How we test',
|
|
73
|
+
'',
|
|
74
|
+
HOW_WE_TEST_HEADER,
|
|
75
|
+
'',
|
|
76
|
+
'Procedure verificate (deterministiche, evidence-backed): quello che una run',
|
|
77
|
+
'ha dimostrato resta qui per gli agenti e per gli umani che vengono dopo.',
|
|
78
|
+
'Generato da zelari — rigenera con `/memory how-we-test`.',
|
|
79
|
+
'',
|
|
80
|
+
];
|
|
81
|
+
if (rows.length === 0) {
|
|
82
|
+
lines.push('_Nessuna procedura verificata ancora: niente da proiettare._', '');
|
|
83
|
+
return lines.join('\n');
|
|
84
|
+
}
|
|
85
|
+
let current = null;
|
|
86
|
+
for (const row of rows) {
|
|
87
|
+
if (row.criterionId !== current) {
|
|
88
|
+
current = row.criterionId;
|
|
89
|
+
lines.push(`## ${current}`, '');
|
|
90
|
+
}
|
|
91
|
+
const seq = row.seq === undefined ? '—' : `seq ${row.seq}`;
|
|
92
|
+
lines.push(`- \`${escapeCell(row.command)}\` — exit 0 — digest \`${shortDigest(row.digest)}\` — ultima osservazione ${seq}`);
|
|
93
|
+
}
|
|
94
|
+
lines.push('');
|
|
95
|
+
return lines.join('\n');
|
|
96
|
+
}
|
|
97
|
+
function isMissing(error) {
|
|
98
|
+
return error?.code === 'ENOENT';
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Atomic write to `<projectRoot>/.zelari/how-we-test.md` (tmp + rename), the
|
|
102
|
+
* same pattern `promotion.ts` uses for AGENTS.md. Refuses symlink targets and
|
|
103
|
+
* removes its temporary file on failure.
|
|
104
|
+
*/
|
|
105
|
+
export async function writeHowWeTest(projectRoot, rows) {
|
|
106
|
+
const target = path.join(projectRoot, HOW_WE_TEST_RELATIVE);
|
|
107
|
+
try {
|
|
108
|
+
if ((await fs.lstat(target)).isSymbolicLink()) {
|
|
109
|
+
return { written: false, path: target, rows: rows.length, reason: 'target is a symbolic link' };
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
if (!isMissing(error)) {
|
|
114
|
+
return {
|
|
115
|
+
written: false,
|
|
116
|
+
path: target,
|
|
117
|
+
rows: rows.length,
|
|
118
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
await fs.mkdir(path.dirname(target), { recursive: true });
|
|
123
|
+
const temporary = `${target}.tmp-${process.pid}-${Date.now()}`;
|
|
124
|
+
await fs.writeFile(temporary, projectHowWeTest(rows), { encoding: 'utf8', flag: 'wx' });
|
|
125
|
+
try {
|
|
126
|
+
await fs.rename(temporary, target);
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
await fs.unlink(temporary).catch(() => undefined);
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
132
|
+
return { written: true, path: target, rows: rows.length };
|
|
133
|
+
}
|
|
134
|
+
function nodesFromDump(dump) {
|
|
135
|
+
if (Array.isArray(dump))
|
|
136
|
+
return dump;
|
|
137
|
+
const nodes = dump?.nodes;
|
|
138
|
+
return Array.isArray(nodes) ? nodes : [];
|
|
139
|
+
}
|
|
140
|
+
/** All nodes, or null when the source cannot enumerate (no `export`). */
|
|
141
|
+
export async function listNodes(source) {
|
|
142
|
+
if (typeof source.export !== 'function')
|
|
143
|
+
return null;
|
|
144
|
+
try {
|
|
145
|
+
return nodesFromDump(await source.export());
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/** Verified procedures only, or null when the source cannot enumerate. */
|
|
152
|
+
export async function listVerifiedProcedureNodes(source) {
|
|
153
|
+
const nodes = await listNodes(source);
|
|
154
|
+
if (!nodes)
|
|
155
|
+
return null;
|
|
156
|
+
return nodes.filter((node) => node.kind === 'procedure' && node.metadata?.verified === true);
|
|
157
|
+
}
|
|
158
|
+
/** Explicit regeneration (`/memory how-we-test`). Returns the outcome, never throws. */
|
|
159
|
+
export async function regenerateHowWeTest(source, projectRoot) {
|
|
160
|
+
const nodes = await listVerifiedProcedureNodes(source);
|
|
161
|
+
if (!nodes) {
|
|
162
|
+
return {
|
|
163
|
+
written: false,
|
|
164
|
+
path: path.join(projectRoot, HOW_WE_TEST_RELATIVE),
|
|
165
|
+
rows: 0,
|
|
166
|
+
reason: 'memory backend cannot enumerate procedures',
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
try {
|
|
170
|
+
return await writeHowWeTest(projectRoot, collectHowWeTestRows(nodes));
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
return {
|
|
174
|
+
written: false,
|
|
175
|
+
path: path.join(projectRoot, HOW_WE_TEST_RELATIVE),
|
|
176
|
+
rows: 0,
|
|
177
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Slice C trigger: auto-regenerate after a promotion that created something.
|
|
183
|
+
* Best-effort by contract; the caller is already behind the opt-in flag.
|
|
184
|
+
*/
|
|
185
|
+
export async function regenerateHowWeTestSafe(source, projectRoot) {
|
|
186
|
+
const nodes = await listVerifiedProcedureNodes(source);
|
|
187
|
+
if (!nodes)
|
|
188
|
+
return null;
|
|
189
|
+
try {
|
|
190
|
+
return await writeHowWeTest(projectRoot, collectHowWeTestRows(nodes));
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=howWeTest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"howWeTest.js","sourceRoot":"","sources":["../../../src/cli/memory/howWeTest.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
* Never throws to the parent run.
|
|
16
16
|
*/
|
|
17
17
|
import { createHash } from 'node:crypto';
|
|
18
|
+
import { regenerateHowWeTestSafe, listVerifiedProcedureNodes } from './howWeTest.js';
|
|
18
19
|
import { formatPromoteNotice, meetsPromoteThreshold } from './promotion.js';
|
|
20
|
+
import { constraintFromNode, proposalFromConstraint } from './repeatCheck.js';
|
|
19
21
|
import { CONSTRAINT_CONFIDENCE, CONSTRAINT_IMPORTANCE, constraintNodeId, failureFingerprint, failureNodeId, guessExitCode, repeatConstraintText, } from './repeatFailure.js';
|
|
20
22
|
export { constraintNodeId, failureFingerprint, failureNodeId, repeatConstraintText, } from './repeatFailure.js';
|
|
21
23
|
const ALLOWED_TIERS = new Set(['command-output', 'fs-observation']);
|
|
@@ -220,6 +222,11 @@ export async function promoteOpsKnowledge(gate, deps) {
|
|
|
220
222
|
let skippedDuplicate = 0;
|
|
221
223
|
let constraintsCreated = 0;
|
|
222
224
|
const proposals = [];
|
|
225
|
+
const checkProposals = [];
|
|
226
|
+
// Slice A: a verified procedure for the SAME digest is the only source of a
|
|
227
|
+
// *suggested* regression command. Read once, before the fail loop; the
|
|
228
|
+
// failing command itself is never proposed as a check (repeatCheck.ts).
|
|
229
|
+
const procedureNodes = fails.length > 0 ? ((await listVerifiedProcedureNodes(memory)) ?? []) : [];
|
|
223
230
|
for (const candidate of pass) {
|
|
224
231
|
const outcome = await rememberProcedure(memory, candidate, { sessionId: deps.sessionId });
|
|
225
232
|
if (outcome === 'created') {
|
|
@@ -244,12 +251,21 @@ export async function promoteOpsKnowledge(gate, deps) {
|
|
|
244
251
|
const node = await memory.get(outcome.constraintId);
|
|
245
252
|
if (node && meetsPromoteThreshold(node))
|
|
246
253
|
proposals.push(formatPromoteNotice(node));
|
|
254
|
+
// Second reading of the SAME node: a constraint already carries
|
|
255
|
+
// everything a human needs to confirm a WorldCheck.
|
|
256
|
+
const constraint = constraintFromNode(node);
|
|
257
|
+
if (constraint)
|
|
258
|
+
checkProposals.push(proposalFromConstraint(constraint, procedureNodes));
|
|
247
259
|
}
|
|
248
260
|
else if (outcome.constraint === 'duplicate') {
|
|
249
261
|
skippedDuplicate += 1;
|
|
250
262
|
}
|
|
251
263
|
}
|
|
252
|
-
|
|
264
|
+
// Slice C trigger (b): a promotion that created something changes the
|
|
265
|
+
// playbook. Skipped entirely when the backend cannot enumerate.
|
|
266
|
+
if (created > 0)
|
|
267
|
+
await regenerateHowWeTestSafe(memory, deps.projectRoot);
|
|
268
|
+
return { enabled: true, created, skippedDuplicate, constraintsCreated, proposals, checkProposals };
|
|
253
269
|
}
|
|
254
270
|
/** Best-effort wrapper: never rejects. */
|
|
255
271
|
export async function promoteOpsKnowledgeSafe(gate, deps) {
|
|
@@ -268,6 +284,7 @@ function emptyResult(enabled, skippedReason) {
|
|
|
268
284
|
skippedDuplicate: 0,
|
|
269
285
|
constraintsCreated: 0,
|
|
270
286
|
proposals: [],
|
|
287
|
+
checkProposals: [],
|
|
271
288
|
};
|
|
272
289
|
}
|
|
273
290
|
async function openMemory(projectRoot, env) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opsKnowledge.js","sourceRoot":"","sources":["../../../src/cli/memory/opsKnowledge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAIzC,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,EACb,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,aAAa,GAAG,IAAI,GAAG,CAAsB,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAEzF,MAAM,UAAU,8BAA8B,CAAC,MAAyB,OAAO,CAAC,GAAG;IACjF,MAAM,CAAC,GAAG,GAAG,CAAC,4BAA4B,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACjE,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC;AAChE,CAAC;
|
|
1
|
+
{"version":3,"file":"opsKnowledge.js","sourceRoot":"","sources":["../../../src/cli/memory/opsKnowledge.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,6 +17,63 @@ export function formatPromoteNotice(node) {
|
|
|
17
17
|
const preview = node.content.replace(/\s+/g, ' ').trim().slice(0, 120);
|
|
18
18
|
return `[memory] candidato AGENTS.MD: ${node.kind} “${preview}” — /memory promote ${node.id}`;
|
|
19
19
|
}
|
|
20
|
+
export const PROMOTE_USAGE = 'Usage: /memory promote <id> [--as-check --command "<comando>" [--expect-exit N]]';
|
|
21
|
+
const COMMAND_FLAGS = new Set(['--command', '-c']);
|
|
22
|
+
const EXIT_FLAGS = new Set(['--expect-exit', '-e', '--expectExit']);
|
|
23
|
+
/**
|
|
24
|
+
* Pure parser for `/memory promote` (the slash layer only splits on spaces, so
|
|
25
|
+
* `--command` swallows every token up to the next flag and re-joins them).
|
|
26
|
+
* Applying a check to `checks.json` is always explicit: the command must be
|
|
27
|
+
* typed by a human, nothing is inferred from the failing run.
|
|
28
|
+
*/
|
|
29
|
+
export function parsePromoteArgs(args = []) {
|
|
30
|
+
const result = { asCheck: false };
|
|
31
|
+
const tokens = [...args];
|
|
32
|
+
for (let i = 0; i < tokens.length; i += 1) {
|
|
33
|
+
const token = tokens[i] ?? '';
|
|
34
|
+
const inline = token.startsWith('--') && token.includes('=') ? token.split('=') : null;
|
|
35
|
+
const flag = inline ? (inline[0] ?? '') : token;
|
|
36
|
+
const inlineValue = inline ? inline.slice(1).join('=') : undefined;
|
|
37
|
+
if (flag === '--as-check') {
|
|
38
|
+
result.asCheck = true;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (COMMAND_FLAGS.has(flag) || EXIT_FLAGS.has(flag)) {
|
|
42
|
+
const parts = [];
|
|
43
|
+
if (inlineValue !== undefined && inlineValue !== '')
|
|
44
|
+
parts.push(inlineValue);
|
|
45
|
+
else {
|
|
46
|
+
while (i + 1 < tokens.length && !(tokens[i + 1] ?? '').startsWith('-')) {
|
|
47
|
+
parts.push(tokens[i + 1] ?? '');
|
|
48
|
+
i += 1;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const value = parts
|
|
52
|
+
.join(' ')
|
|
53
|
+
.replace(/^\s*["']|["']\s*$/g, '')
|
|
54
|
+
.trim();
|
|
55
|
+
if (EXIT_FLAGS.has(flag)) {
|
|
56
|
+
const exit = Number(value);
|
|
57
|
+
if (!value || !Number.isInteger(exit)) {
|
|
58
|
+
return { ...result, error: `expect-exit must be an integer, got “${value}”.` };
|
|
59
|
+
}
|
|
60
|
+
result.expectExit = exit;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (!value)
|
|
64
|
+
return { ...result, error: 'missing value for --command.' };
|
|
65
|
+
result.command = value;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (token.startsWith('-'))
|
|
69
|
+
return { ...result, error: `unknown flag “${token}”.` };
|
|
70
|
+
if (!result.id)
|
|
71
|
+
result.id = token;
|
|
72
|
+
else if (!result.command)
|
|
73
|
+
return { ...result, error: `unexpected argument “${token}”.` };
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
20
77
|
function lineFor(node) {
|
|
21
78
|
const content = node.content
|
|
22
79
|
.replace(/\s+/g, ' ')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"promotion.js","sourceRoot":"","sources":["../../../src/cli/memory/promotion.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"promotion.js","sourceRoot":"","sources":["../../../src/cli/memory/promotion.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { failureCommandLabel, guessExitCode } from './repeatFailure.js';
|
|
2
|
+
/**
|
|
3
|
+
* Placeholder command. Deliberately not a shell no-op: an unedited template
|
|
4
|
+
* must fail loudly if it ever reaches `checks.json` (which it cannot — see
|
|
5
|
+
* `confirmCheck`), instead of producing a fake green check.
|
|
6
|
+
*/
|
|
7
|
+
export const PLACEHOLDER_COMMAND = '<confirm-command>';
|
|
8
|
+
function metaString(node, key) {
|
|
9
|
+
const value = node.metadata?.[key];
|
|
10
|
+
return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;
|
|
11
|
+
}
|
|
12
|
+
function metaNumber(node, key) {
|
|
13
|
+
const value = node.metadata?.[key];
|
|
14
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
15
|
+
}
|
|
16
|
+
/** Memory id of the constraint a repeated fingerprint promotes to. */
|
|
17
|
+
export function checkIdForFingerprint(fingerprint) {
|
|
18
|
+
return `con-${fingerprint}`;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Read the check-relevant fields out of a memory node. Returns null when the
|
|
22
|
+
* node is not a repeat-failure constraint (no fingerprint / command / digest):
|
|
23
|
+
* only nodes the slice-3.2 writer produced are proposable.
|
|
24
|
+
*/
|
|
25
|
+
export function constraintFromNode(node) {
|
|
26
|
+
if (!node)
|
|
27
|
+
return null;
|
|
28
|
+
const fingerprint = metaString(node, 'fingerprint');
|
|
29
|
+
const command = metaString(node, 'command');
|
|
30
|
+
const digest = metaString(node, 'digest');
|
|
31
|
+
if (!fingerprint || !command || !digest)
|
|
32
|
+
return null;
|
|
33
|
+
const criterionId = metaString(node, 'criterionId');
|
|
34
|
+
return {
|
|
35
|
+
fingerprint,
|
|
36
|
+
command,
|
|
37
|
+
digest,
|
|
38
|
+
exitCode: metaNumber(node, 'exitCode') ?? guessExitCode(command),
|
|
39
|
+
...(criterionId ? { criterionId } : {}),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/** Two commands are "the same" when their evidence label is the same. */
|
|
43
|
+
function sameCommand(a, b) {
|
|
44
|
+
return failureCommandLabel(a).toLowerCase() === failureCommandLabel(b).toLowerCase();
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* A verified `procedure` for the SAME output digest is the strongest hint we
|
|
48
|
+
* have that a fix exists. A procedure that merely repeats the failed command is
|
|
49
|
+
* not a fix, so it is skipped (never auto-rerun the failing command).
|
|
50
|
+
*/
|
|
51
|
+
export function pickFixProcedure(constraint, procedures = []) {
|
|
52
|
+
return procedures.find((node) => {
|
|
53
|
+
if (node.kind !== 'procedure' || node.status !== 'active')
|
|
54
|
+
return false;
|
|
55
|
+
if (node.metadata?.verified !== true)
|
|
56
|
+
return false;
|
|
57
|
+
const digest = metaString(node, 'digest');
|
|
58
|
+
const command = metaString(node, 'command');
|
|
59
|
+
if (!digest || digest !== constraint.digest || !command)
|
|
60
|
+
return false;
|
|
61
|
+
return !sameCommand(command, constraint.command);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
function commandFromProcedure(procedure) {
|
|
65
|
+
return metaString(procedure, 'command') ?? PLACEHOLDER_COMMAND;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Pure: constraint → check template.
|
|
69
|
+
*
|
|
70
|
+
* `expectExit` is always 0: a check asserts "the fix holds". The exit code of
|
|
71
|
+
* the failing run is reported in `exit`, never used as an expectation.
|
|
72
|
+
*/
|
|
73
|
+
export function proposalFromConstraint(constraint, procedures = []) {
|
|
74
|
+
const fix = pickFixProcedure(constraint, procedures);
|
|
75
|
+
const command = fix ? commandFromProcedure(fix) : PLACEHOLDER_COMMAND;
|
|
76
|
+
return {
|
|
77
|
+
fp: constraint.fingerprint,
|
|
78
|
+
command: constraint.command,
|
|
79
|
+
exit: constraint.exitCode,
|
|
80
|
+
digest: constraint.digest,
|
|
81
|
+
checkId: checkIdForFingerprint(constraint.fingerprint),
|
|
82
|
+
derivedFromProcedure: fix !== undefined,
|
|
83
|
+
suggestedCheck: {
|
|
84
|
+
id: checkIdForFingerprint(constraint.fingerprint),
|
|
85
|
+
command,
|
|
86
|
+
expectExit: 0,
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Human confirmation gate. Returns the `WorldCheck` to append, or null while
|
|
92
|
+
* no human-typed command is available — the placeholder is never applied.
|
|
93
|
+
*/
|
|
94
|
+
export function confirmCheck(proposal, confirmed = {}) {
|
|
95
|
+
const command = (confirmed.command ?? '').replace(/^\s*["']|["']\s*$/g, '').trim();
|
|
96
|
+
if (!command || command === PLACEHOLDER_COMMAND)
|
|
97
|
+
return null;
|
|
98
|
+
const expectExit = typeof confirmed.expectExit === 'number' && Number.isInteger(confirmed.expectExit)
|
|
99
|
+
? confirmed.expectExit
|
|
100
|
+
: (proposal.suggestedCheck.expectExit ?? 0);
|
|
101
|
+
return { id: proposal.checkId, command, expectExit };
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Notice shown in the turn summary — same shape as `formatPromoteNotice`
|
|
105
|
+
* (promotion.ts), so the two candidate channels read identically.
|
|
106
|
+
*/
|
|
107
|
+
export function formatCheckProposalNotice(proposal) {
|
|
108
|
+
const preview = failureCommandLabel(proposal.command).replace(/\s+/g, ' ').slice(0, 120);
|
|
109
|
+
const suffix = proposal.derivedFromProcedure
|
|
110
|
+
? `--as-check --command "${proposal.suggestedCheck.command}"`
|
|
111
|
+
: '--as-check --command "<comando>"';
|
|
112
|
+
return `[memory] candidato WorldCheck: “${preview}” (exit ${proposal.exit}) — /memory promote ${proposal.checkId} ${suffix}`;
|
|
113
|
+
}
|
|
114
|
+
/** How to confirm, or why nothing can be applied yet. */
|
|
115
|
+
export function checkConfirmationHint(proposal) {
|
|
116
|
+
return proposal.derivedFromProcedure
|
|
117
|
+
? `[memory] proposta di check (applicazione sempre manuale):\n` +
|
|
118
|
+
` id: ${proposal.checkId}\n` +
|
|
119
|
+
` comando suggerito (da procedura verificata): ${proposal.suggestedCheck.command}\n` +
|
|
120
|
+
` exit atteso: ${proposal.suggestedCheck.expectExit}\n` +
|
|
121
|
+
` conferma con: /memory promote ${proposal.checkId} --as-check --command "${proposal.suggestedCheck.command}"`
|
|
122
|
+
: `[memory] proposta di check (applicazione sempre manuale):\n` +
|
|
123
|
+
` id: ${proposal.checkId}\n` +
|
|
124
|
+
` comando fallito (NON ri-eseguito automaticamente): ${failureCommandLabel(proposal.command)}\n` +
|
|
125
|
+
` digest: ${proposal.digest} · exit ${proposal.exit}\n` +
|
|
126
|
+
` nessuna procedura verificata per lo stesso digest: scrivi il comando di regressione,\n` +
|
|
127
|
+
` conferma con: /memory promote ${proposal.checkId} --as-check --command "<comando>"`;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=repeatCheck.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repeatCheck.js","sourceRoot":"","sources":["../../../src/cli/memory/repeatCheck.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,10 @@ import { promises as fs } from 'node:fs';
|
|
|
2
2
|
import * as path from 'node:path';
|
|
3
3
|
import { appendSystem } from '../hooks/messageHelpers.js';
|
|
4
4
|
import { getMemoryService } from '../memory/serviceFactory.js';
|
|
5
|
-
import {
|
|
5
|
+
import { listVerifiedProcedureNodes, regenerateHowWeTest } from '../memory/howWeTest.js';
|
|
6
|
+
import { PROMOTE_USAGE, parsePromoteArgs, promoteMemoryToAgentsMd } from '../memory/promotion.js';
|
|
7
|
+
import { checkConfirmationHint, confirmCheck, constraintFromNode, proposalFromConstraint } from '../memory/repeatCheck.js';
|
|
8
|
+
import { appendWorldCheck } from '../workspace/worldModel.js';
|
|
6
9
|
const USAGE = [
|
|
7
10
|
'/memory — backend summary',
|
|
8
11
|
'/memory search <query>',
|
|
@@ -14,6 +17,8 @@ const USAGE = [
|
|
|
14
17
|
'/memory consolidate [query]',
|
|
15
18
|
'/memory index [--force]',
|
|
16
19
|
'/memory promote <id> — append durable knowledge to managed AGENTS.md section',
|
|
20
|
+
'/memory promote con-<fp> --as-check --command "<cmd>" [--expect-exit N] — append a WorldCheck',
|
|
21
|
+
'/memory how-we-test — regenerate .zelari/how-we-test.md from verified procedures',
|
|
17
22
|
'/memory stats | doctor | export [project-relative-path]',
|
|
18
23
|
'/memory audit — read-only decay + contradiction report (nothing is mutated)',
|
|
19
24
|
].join('\n ');
|
|
@@ -190,10 +195,24 @@ export async function handleMemoryCommand(ctx, subcommand = 'stats', args = [])
|
|
|
190
195
|
(result.error ? `\n ${result.error}` : ''));
|
|
191
196
|
return;
|
|
192
197
|
}
|
|
198
|
+
case 'how-we-test': {
|
|
199
|
+
// Slice C, trigger (a): explicit regeneration. The manual path is NOT
|
|
200
|
+
// flag-gated — the opt-in flag only gates the automatic write.
|
|
201
|
+
const result = await regenerateHowWeTest(memory, ctx.cwd);
|
|
202
|
+
emit(result.written
|
|
203
|
+
? `[memory] how-we-test written to ${result.path} (${result.rows} procedure(s))`
|
|
204
|
+
: `[memory] how-we-test not written: ${result.reason ?? 'nothing to project'}.`);
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
193
207
|
case 'promote': {
|
|
194
|
-
const
|
|
208
|
+
const parsed = parsePromoteArgs(args);
|
|
209
|
+
if (parsed.error) {
|
|
210
|
+
emit(`[memory] ${parsed.error}\n ${PROMOTE_USAGE}`);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
const memoryId = parsed.id;
|
|
195
214
|
if (!memoryId) {
|
|
196
|
-
emit(
|
|
215
|
+
emit(PROMOTE_USAGE);
|
|
197
216
|
return;
|
|
198
217
|
}
|
|
199
218
|
const node = await memory.get(memoryId);
|
|
@@ -201,6 +220,31 @@ export async function handleMemoryCommand(ctx, subcommand = 'stats', args = [])
|
|
|
201
220
|
emit(`[memory] ${memoryId} not found in this project.`);
|
|
202
221
|
return;
|
|
203
222
|
}
|
|
223
|
+
if (parsed.asCheck) {
|
|
224
|
+
// Slice A: turn a repeat-failure constraint into a WorldCheck. Reading
|
|
225
|
+
// the proposal is free; APPLYING it requires a human-typed command, so
|
|
226
|
+
// checks.json only ever changes on an explicit instruction.
|
|
227
|
+
const constraint = constraintFromNode(node);
|
|
228
|
+
if (!constraint) {
|
|
229
|
+
emit(`[memory] ${memoryId} is not a repeat-failure constraint (no fingerprint/command/digest) — nothing to turn into a check.`);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
const nodes = await listVerifiedProcedureNodes(memory);
|
|
233
|
+
const proposal = proposalFromConstraint(constraint, nodes ?? []);
|
|
234
|
+
const check = confirmCheck(proposal, {
|
|
235
|
+
command: parsed.command,
|
|
236
|
+
...(parsed.expectExit === undefined ? {} : { expectExit: parsed.expectExit }),
|
|
237
|
+
});
|
|
238
|
+
if (!check) {
|
|
239
|
+
emit(checkConfirmationHint(proposal));
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
const appended = await appendWorldCheck(ctx.cwd, check);
|
|
243
|
+
emit(appended.added
|
|
244
|
+
? `[memory] check “${check.id}” appended to ${appended.path} (${appended.count} check(s))`
|
|
245
|
+
: `[memory] check “${check.id}” already present in ${appended.path} — file untouched.`);
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
204
248
|
const promoted = await promoteMemoryToAgentsMd(ctx.cwd, node);
|
|
205
249
|
emit(promoted.added
|
|
206
250
|
? `[memory] promoted ${memoryId} to ${promoted.path}`
|