ferrycat 0.3.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +132 -21
- package/README_zh.md +131 -23
- package/bin/ferrycat.js +19 -1
- package/dist/cli.js +112 -146
- package/dist/cli.js.map +1 -1
- package/dist/daemon.d.ts +54 -0
- package/dist/daemon.js +372 -0
- package/dist/daemon.js.map +1 -0
- package/dist/demo.d.ts +36 -0
- package/dist/demo.js +340 -0
- package/dist/demo.js.map +1 -0
- package/dist/engine.d.ts +29 -1
- package/dist/engine.js +188 -27
- package/dist/engine.js.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/schemas.d.ts +228 -0
- package/dist/schemas.js +41 -0
- package/dist/schemas.js.map +1 -1
- package/dist/supervisor.d.ts +98 -0
- package/dist/supervisor.js +562 -0
- package/dist/supervisor.js.map +1 -0
- package/dist/types.d.ts +41 -0
- package/package.json +2 -1
- package/server.json +2 -2
package/dist/demo.js
ADDED
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FerryCat Zero-Config Sandbox Demo (REQ-EXP-01).
|
|
3
|
+
*
|
|
4
|
+
* Runs a complete contract lifecycle — dispatch -> claim -> supervised execution -> TOCTOU
|
|
5
|
+
* re-verification -> COMPLETED — entirely inside an isolated temporary sandbox, so a brand-new
|
|
6
|
+
* user can see the deterministic handoff loop without configuring a single MCP server.
|
|
7
|
+
*
|
|
8
|
+
* Design constraints:
|
|
9
|
+
* - Zero pollution: every artifact (sample source, handler script, SQLite database) lives under
|
|
10
|
+
* `os.tmpdir()/ferrycat-demo-*`. The user's real workspace and `~/.ferrycat/mesh.db` are never touched.
|
|
11
|
+
* - No simulation shortcuts on the engine path: the demo drives the exact same public APIs a real
|
|
12
|
+
* daemon uses (`dispatchContract` / `pollNextTask` / `executeTaskAndFulfill` / `verifyContract`),
|
|
13
|
+
* so a green demo is genuine evidence rather than a puppet show.
|
|
14
|
+
* - Machine-readable mode: with `json: true` the function writes nothing to stdout and returns a
|
|
15
|
+
* plain object, keeping CI/upstream automation parseable.
|
|
16
|
+
*/
|
|
17
|
+
import fs from 'node:fs';
|
|
18
|
+
import os from 'node:os';
|
|
19
|
+
import path from 'node:path';
|
|
20
|
+
import { FerryCatEngine } from './engine.js';
|
|
21
|
+
import { executeTaskAndFulfill } from './supervisor.js';
|
|
22
|
+
const TOTAL_STEPS = 4;
|
|
23
|
+
const SAMPLE_REL_PATH = 'src/calc.ts';
|
|
24
|
+
/**
|
|
25
|
+
* Sample source under review. Deliberately contains exactly one advisory-level defect
|
|
26
|
+
* (`==` instead of `===`) so the demo handler has something real to find and the verdict
|
|
27
|
+
* is deterministic across runs and platforms.
|
|
28
|
+
*/
|
|
29
|
+
const SAMPLE_SOURCE = `export function add(a: number, b: number): number {
|
|
30
|
+
return a + b;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function divide(a: number, b: number): number {
|
|
34
|
+
if (b == 0) {
|
|
35
|
+
throw new Error('Division by zero');
|
|
36
|
+
}
|
|
37
|
+
return a / b;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const VERSION = '1.0.0';
|
|
41
|
+
`;
|
|
42
|
+
/**
|
|
43
|
+
* Handler script written into the sandbox. It reads the contract from stdin (same protocol as
|
|
44
|
+
* scripts/review-handler.js), inspects the real pointer file on disk, then emits a delivery
|
|
45
|
+
* envelope on stdout. `execDelayMs` keeps the child alive long enough for the supervisor
|
|
46
|
+
* heartbeat ticker to fire at least once, so the demo can prove lease renewal is live.
|
|
47
|
+
*/
|
|
48
|
+
function buildHandlerScript(execDelayMs) {
|
|
49
|
+
return `/**
|
|
50
|
+
* FerryCat demo handler (generated by \`ferrycat-cli demo\`).
|
|
51
|
+
* Reads the contract JSON from stdin, inspects the pointer file, prints a delivery envelope.
|
|
52
|
+
*/
|
|
53
|
+
const fs = require('node:fs');
|
|
54
|
+
const path = require('node:path');
|
|
55
|
+
|
|
56
|
+
const EXEC_DELAY_MS = ${execDelayMs};
|
|
57
|
+
|
|
58
|
+
function inspect(workspaceRoot, pointers) {
|
|
59
|
+
const issues = [];
|
|
60
|
+
for (const pointer of pointers || []) {
|
|
61
|
+
const absPath = path.resolve(workspaceRoot, pointer.path);
|
|
62
|
+
if (!fs.existsSync(absPath)) {
|
|
63
|
+
issues.push(pointer.path + ': file is missing on disk');
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const lines = fs.readFileSync(absPath, 'utf8').split(/\\r?\\n/);
|
|
67
|
+
lines.forEach((line, idx) => {
|
|
68
|
+
// Loose equality on a numeric/string guard is the classic review catch.
|
|
69
|
+
if (/(^|[^=!<>])==([^=]|$)/.test(line)) {
|
|
70
|
+
issues.push(pointer.path + ':' + (idx + 1) + " uses '==' instead of '===' (strict equality)");
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return issues;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function main() {
|
|
78
|
+
const raw = fs.readFileSync(0, 'utf8');
|
|
79
|
+
if (!raw.trim()) {
|
|
80
|
+
console.error('demo handler: no contract payload received on stdin');
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
const contract = JSON.parse(raw);
|
|
84
|
+
const workspaceRoot = process.env.FERRYCAT_WORKSPACE_ROOT || process.cwd();
|
|
85
|
+
const issues = inspect(workspaceRoot, contract.pointers);
|
|
86
|
+
|
|
87
|
+
const finish = () => {
|
|
88
|
+
process.stdout.write(
|
|
89
|
+
JSON.stringify({
|
|
90
|
+
ok: true,
|
|
91
|
+
summary:
|
|
92
|
+
'Reviewed ' + (contract.pointers || []).length + ' file(s) for contract ' +
|
|
93
|
+
contract.contract_id + '; ' + issues.length + ' advisory finding(s).',
|
|
94
|
+
structured_output: {
|
|
95
|
+
passed: true,
|
|
96
|
+
issues,
|
|
97
|
+
},
|
|
98
|
+
}) + '\\n'
|
|
99
|
+
);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
if (EXEC_DELAY_MS > 0) {
|
|
103
|
+
setTimeout(finish, EXEC_DELAY_MS);
|
|
104
|
+
} else {
|
|
105
|
+
finish();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
main();
|
|
110
|
+
`;
|
|
111
|
+
}
|
|
112
|
+
function makePainter(enabled) {
|
|
113
|
+
const wrap = (code) => (text) => enabled ? `\u001b[${code}m${text}\u001b[0m` : text;
|
|
114
|
+
return {
|
|
115
|
+
bold: wrap('1'),
|
|
116
|
+
dim: wrap('2'),
|
|
117
|
+
green: wrap('32'),
|
|
118
|
+
cyan: wrap('36'),
|
|
119
|
+
yellow: wrap('33'),
|
|
120
|
+
magenta: wrap('35'),
|
|
121
|
+
gray: wrap('90'),
|
|
122
|
+
red: wrap('31'),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function shortSha(sha) {
|
|
126
|
+
return sha.length <= 12 ? sha : `${sha.slice(0, 8)}...${sha.slice(-4)}`;
|
|
127
|
+
}
|
|
128
|
+
function removeSandbox(sandbox) {
|
|
129
|
+
// Windows keeps WAL/SHM handles briefly after close(); retries absorb that window.
|
|
130
|
+
fs.rmSync(sandbox, { recursive: true, force: true, maxRetries: 5, retryDelay: 50 });
|
|
131
|
+
}
|
|
132
|
+
export async function runDemo(options = {}) {
|
|
133
|
+
const startedAt = Date.now();
|
|
134
|
+
const execDelayMs = Math.max(0, options.execDelayMs ?? 1900);
|
|
135
|
+
const execTtlSec = Math.max(2, options.execTtlSec ?? 5);
|
|
136
|
+
const human = !options.json;
|
|
137
|
+
const colorOn = options.color ?? (human && Boolean(process.stdout.isTTY) && !process.env.NO_COLOR);
|
|
138
|
+
const paint = makePainter(colorOn);
|
|
139
|
+
const write = options.write ?? ((line) => process.stdout.write(`${line}\n`));
|
|
140
|
+
const say = (line = '') => {
|
|
141
|
+
if (human)
|
|
142
|
+
write(line);
|
|
143
|
+
};
|
|
144
|
+
const sandbox = fs.mkdtempSync(path.join(os.tmpdir(), 'ferrycat-demo-'));
|
|
145
|
+
let engine;
|
|
146
|
+
let succeeded = false;
|
|
147
|
+
const steps = [];
|
|
148
|
+
const warnings = [];
|
|
149
|
+
let heartbeatRenewals = 0;
|
|
150
|
+
let contractId = '';
|
|
151
|
+
let claimToken = '';
|
|
152
|
+
let status = 'UNKNOWN';
|
|
153
|
+
let verdict = 'PASSED';
|
|
154
|
+
let issues = [];
|
|
155
|
+
let dirtyFiles = 0;
|
|
156
|
+
const record = (index, title, fields) => {
|
|
157
|
+
steps.push({ index, total: TOTAL_STEPS, title, fields });
|
|
158
|
+
say('');
|
|
159
|
+
say(` ${paint.green('✔')} ${paint.bold(`[${index}/${TOTAL_STEPS}] ${title}`)}`);
|
|
160
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
161
|
+
say(` ${paint.gray(key.padEnd(10))}${value}`);
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
try {
|
|
165
|
+
// ---------------------------------------------------------------------
|
|
166
|
+
// Sandbox scaffolding (isolated workspace + handler + SQLite database)
|
|
167
|
+
// ---------------------------------------------------------------------
|
|
168
|
+
const srcDir = path.join(sandbox, 'src');
|
|
169
|
+
fs.mkdirSync(srcDir, { recursive: true });
|
|
170
|
+
fs.writeFileSync(path.join(sandbox, SAMPLE_REL_PATH), SAMPLE_SOURCE, 'utf8');
|
|
171
|
+
const handlerPath = path.join(sandbox, 'demo-handler.cjs');
|
|
172
|
+
fs.writeFileSync(handlerPath, buildHandlerScript(execDelayMs), 'utf8');
|
|
173
|
+
engine = new FerryCatEngine({ dbPath: path.join(sandbox, 'demo-mesh.db') });
|
|
174
|
+
say('');
|
|
175
|
+
say(paint.bold('⚡ FerryCat Zero-Config Sandbox Demo ⚡'));
|
|
176
|
+
say(`${paint.gray('Sandbox:')} ${sandbox}`);
|
|
177
|
+
say(paint.gray('No MCP config. No daemon. Your real workspace and mesh.db are untouched.'));
|
|
178
|
+
// ---------------------------------------------------------------------
|
|
179
|
+
// [1/4] Dispatch — Antigravity locks the pointer fingerprint
|
|
180
|
+
// ---------------------------------------------------------------------
|
|
181
|
+
const dispatchRes = engine.dispatchContract({
|
|
182
|
+
requester_agent: 'antigravity',
|
|
183
|
+
target_agent: 'workbuddy',
|
|
184
|
+
task_type: 'code_review',
|
|
185
|
+
title: 'Review calc.ts for correctness and strict-equality hygiene',
|
|
186
|
+
context_summary: 'Sandbox demo contract. Inspect src/calc.ts and report any correctness or ' +
|
|
187
|
+
'strict-equality violations. This contract is generated by `ferrycat-cli demo`.',
|
|
188
|
+
workspace_root: sandbox,
|
|
189
|
+
pointers: [{ path: SAMPLE_REL_PATH }],
|
|
190
|
+
contract_schema: {
|
|
191
|
+
type: 'object',
|
|
192
|
+
properties: {
|
|
193
|
+
passed: { type: 'boolean' },
|
|
194
|
+
issues: { type: 'array', items: { type: 'string' } },
|
|
195
|
+
},
|
|
196
|
+
required: ['passed', 'issues'],
|
|
197
|
+
additionalProperties: false,
|
|
198
|
+
},
|
|
199
|
+
exec_ttl_sec: execTtlSec,
|
|
200
|
+
});
|
|
201
|
+
contractId = dispatchRes.contract_id;
|
|
202
|
+
const lockedFile = dispatchRes.files[0];
|
|
203
|
+
if (dispatchRes.warning) {
|
|
204
|
+
warnings.push(dispatchRes.warning);
|
|
205
|
+
}
|
|
206
|
+
record(1, 'Contract Dispatched', {
|
|
207
|
+
ID: contractId,
|
|
208
|
+
Actor: `antigravity -> workbuddy ${paint.dim('(task: code_review)')}`,
|
|
209
|
+
Locked: `${lockedFile.path} ${paint.dim(`(sha256: ${shortSha(lockedFile.sha256)})`)}`,
|
|
210
|
+
Status: `${paint.cyan('SUBMITTED')} ${paint.dim('-> queue')}`,
|
|
211
|
+
});
|
|
212
|
+
// ---------------------------------------------------------------------
|
|
213
|
+
// [2/4] Claim — WorkBuddy polls, verifies fingerprints, wins the CAS lease
|
|
214
|
+
// ---------------------------------------------------------------------
|
|
215
|
+
const pollRes = await engine.pollNextTask({ agent_id: 'workbuddy' });
|
|
216
|
+
if (!pollRes.has_task || !pollRes.contract || pollRes.status !== 'CLAIMED') {
|
|
217
|
+
throw new Error(`Demo claim failed: expected CLAIMED, got has_task=${pollRes.has_task} status=${pollRes.status ?? 'undefined'}. ` +
|
|
218
|
+
`${pollRes.message ?? ''}`.trim());
|
|
219
|
+
}
|
|
220
|
+
claimToken = pollRes.contract.claim_token ?? '';
|
|
221
|
+
const claimed = pollRes.contract;
|
|
222
|
+
record(2, 'Contract Claimed', {
|
|
223
|
+
Holder: claimed.target_agent,
|
|
224
|
+
Lease: claimToken || paint.yellow('(none)'),
|
|
225
|
+
Status: `${paint.dim('SUBMITTED ->')} ${paint.yellow('CLAIMED')}`,
|
|
226
|
+
Verify: `${paint.green('fingerprints matched')} ${paint.dim('(0 dirty files)')}`,
|
|
227
|
+
});
|
|
228
|
+
// ---------------------------------------------------------------------
|
|
229
|
+
// [3/4] Supervised execution — real child process, heartbeat, schema gate
|
|
230
|
+
// ---------------------------------------------------------------------
|
|
231
|
+
const execResult = await executeTaskAndFulfill(engine, claimed, { execFile: handlerPath }, {
|
|
232
|
+
onEvent: (event) => {
|
|
233
|
+
if (event.event === 'HEARTBEAT_RENEWED') {
|
|
234
|
+
heartbeatRenewals += 1;
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
});
|
|
238
|
+
if (!execResult.ok) {
|
|
239
|
+
throw new Error(`Supervised execution failed: ${execResult.error ?? execResult.status}`);
|
|
240
|
+
}
|
|
241
|
+
// The authoritative delivery lives on the row, not on the fulfill ack.
|
|
242
|
+
const finalState = engine.inspectMeshState({ contract_id: contractId });
|
|
243
|
+
const finalRow = finalState.contracts[0] ?? {};
|
|
244
|
+
status = String(finalRow.status ?? 'UNKNOWN');
|
|
245
|
+
const structured = finalRow.structured_output;
|
|
246
|
+
if (structured && Array.isArray(structured.issues)) {
|
|
247
|
+
issues = structured.issues.map((item) => String(item));
|
|
248
|
+
}
|
|
249
|
+
verdict = issues.length > 0 ? 'CHANGES_REQUESTED' : 'PASSED';
|
|
250
|
+
record(3, 'Execution & Schema Check', {
|
|
251
|
+
Handler: `${path.basename(handlerPath)} ${paint.dim('(sandboxed child process)')}`,
|
|
252
|
+
Schema: `${paint.green('passed Ajv validation')}`,
|
|
253
|
+
Heartbeat: heartbeatRenewals > 0
|
|
254
|
+
? `${paint.green(`${heartbeatRenewals} lease renewal(s)`)}`
|
|
255
|
+
: paint.dim('no renewal needed (short task)'),
|
|
256
|
+
Verdict: verdict === 'PASSED'
|
|
257
|
+
? paint.green('PASSED')
|
|
258
|
+
: paint.yellow(`CHANGES_REQUESTED ${paint.dim(`(${issues.length} advisory)`)}`),
|
|
259
|
+
});
|
|
260
|
+
// ---------------------------------------------------------------------
|
|
261
|
+
// [4/4] Delivery — second TOCTOU pass then terminal COMPLETED
|
|
262
|
+
// ---------------------------------------------------------------------
|
|
263
|
+
const verifyRes = engine.verifyContract({
|
|
264
|
+
contract_id: contractId,
|
|
265
|
+
agent_id: 'workbuddy',
|
|
266
|
+
});
|
|
267
|
+
dirtyFiles = verifyRes.dirty_files.length;
|
|
268
|
+
if (!verifyRes.valid) {
|
|
269
|
+
throw new Error(`Demo TOCTOU re-verification failed: ${verifyRes.dirty_files.length} dirty file(s).`);
|
|
270
|
+
}
|
|
271
|
+
if (status !== 'COMPLETED') {
|
|
272
|
+
throw new Error(`Demo expected terminal status COMPLETED, got ${status}.`);
|
|
273
|
+
}
|
|
274
|
+
record(4, 'Contract Completed', {
|
|
275
|
+
TOCTOU: `${paint.green(`fingerprints matched (${dirtyFiles} dirty files)`)}`,
|
|
276
|
+
Final: `${paint.green(paint.bold('COMPLETED'))} ${paint.dim(`(elapsed: ${Date.now() - startedAt}ms)`)}`,
|
|
277
|
+
Findings: issues.length === 0
|
|
278
|
+
? paint.dim('none')
|
|
279
|
+
: issues.map((item) => paint.dim(item)).join(`\n${' '.repeat(14)}`),
|
|
280
|
+
});
|
|
281
|
+
succeeded = true;
|
|
282
|
+
return {
|
|
283
|
+
ok: true,
|
|
284
|
+
sandbox,
|
|
285
|
+
sandbox_kept: Boolean(options.keep),
|
|
286
|
+
contract_id: contractId,
|
|
287
|
+
claim_token: claimToken,
|
|
288
|
+
status,
|
|
289
|
+
verdict,
|
|
290
|
+
issues,
|
|
291
|
+
dirty_files: dirtyFiles,
|
|
292
|
+
heartbeat_renewals: heartbeatRenewals,
|
|
293
|
+
elapsed_ms: Date.now() - startedAt,
|
|
294
|
+
steps,
|
|
295
|
+
warnings,
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
finally {
|
|
299
|
+
if (engine) {
|
|
300
|
+
try {
|
|
301
|
+
engine.close();
|
|
302
|
+
}
|
|
303
|
+
catch {
|
|
304
|
+
// Closing is best-effort; the sandbox removal below is the real cleanup contract.
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
const retainSandbox = Boolean(options.keep || !succeeded);
|
|
308
|
+
if (retainSandbox) {
|
|
309
|
+
if (options.keep) {
|
|
310
|
+
say('');
|
|
311
|
+
say(`${paint.gray('Sandbox kept at:')} ${sandbox}`);
|
|
312
|
+
say(paint.gray(' Inspect it with: sqlite3 "<sandbox>/demo-mesh.db" ".tables"'));
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
try {
|
|
317
|
+
removeSandbox(sandbox);
|
|
318
|
+
}
|
|
319
|
+
catch (err) {
|
|
320
|
+
warnings.push(`Sandbox cleanup failed (${err instanceof Error ? err.message : String(err)}); remove "${sandbox}" manually.`);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
if (succeeded) {
|
|
324
|
+
say('');
|
|
325
|
+
say(paint.green(paint.bold(' 🎉 End-to-end multi-agent handoff verified successfully!')));
|
|
326
|
+
say('');
|
|
327
|
+
say(paint.bold(' Next steps:'));
|
|
328
|
+
say(` ${paint.gray('•')} Add to your IDE: ${paint.cyan('npx -y ferrycat')} ${paint.dim('(MCP server entry in mcpServers)')}`);
|
|
329
|
+
say(` ${paint.gray('•')} Inspect contracts: ${paint.cyan('npx ferrycat inspect --target workbuddy')}`);
|
|
330
|
+
say(` ${paint.gray('•')} Keep a sandbox: ${paint.cyan('npx ferrycat demo --keep')}`);
|
|
331
|
+
say(` ${paint.gray('•')} Full CLI help: ${paint.cyan('npx ferrycat --help')}`);
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
say('');
|
|
335
|
+
say(paint.red(' ✖ Demo did not reach a terminal COMPLETED state.'));
|
|
336
|
+
say(paint.gray(` Sandbox retained for debugging: ${sandbox}`));
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
//# sourceMappingURL=demo.js.map
|
package/dist/demo.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demo.js","sourceRoot":"","sources":["../src/demo.ts"],"names":[],"mappings":"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"}
|
package/dist/engine.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DispatchContractInput, DispatchContractResult, ExtendTtlInput, ExtendTtlResult, FailContractInput, FailContractResult, FulfillContractInput, FulfillContractResult, InspectMeshStateInput, PollNextTaskInput, PollNextTaskResult, ReleaseContractInput, ReleaseContractResult, TaskType, VerifyContractInput, VerifyContractResult } from './types.js';
|
|
1
|
+
import type { AcquireDaemonLeaseInput, AcquireDaemonLeaseResult, DaemonLockRow, DispatchContractInput, DispatchContractResult, ExtendTtlInput, ExtendTtlResult, FailContractInput, FailContractResult, FulfillContractInput, FulfillContractResult, InspectMeshStateInput, PollNextTaskInput, PollNextTaskResult, ReleaseContractInput, ReleaseContractResult, ReleaseDaemonLeaseInput, ReleaseDaemonLeaseResult, RenewDaemonLeaseInput, RenewDaemonLeaseResult, TaskType, VerifyContractInput, VerifyContractResult } from './types.js';
|
|
2
2
|
/** Default queue window (SUBMITTED) in seconds. */
|
|
3
3
|
export declare const DEFAULT_QUEUE_TTL_SEC = 1800;
|
|
4
4
|
/**
|
|
@@ -85,6 +85,30 @@ export declare class FerryCatEngine {
|
|
|
85
85
|
* (created_at + LIFETIME_QUEUE_TTL_MULTIPLIER * queue_ttl_sec).
|
|
86
86
|
*/
|
|
87
87
|
extendTtl(input: ExtendTtlInput, nowMs?: number): ExtendTtlResult;
|
|
88
|
+
/**
|
|
89
|
+
* Read-only lease snapshot used by the execution supervisor (Phase 3 Step 0, CK-03) to
|
|
90
|
+
* re-read row state after an optimistic-lock conflict instead of crashing the worker.
|
|
91
|
+
* Never mutates state.
|
|
92
|
+
*/
|
|
93
|
+
getLeaseSnapshot(contractId: string): {
|
|
94
|
+
status: string;
|
|
95
|
+
claim_token: string | null;
|
|
96
|
+
claimed_at: number | null;
|
|
97
|
+
exec_ttl_sec: number;
|
|
98
|
+
extend_count: number;
|
|
99
|
+
} | null;
|
|
100
|
+
/**
|
|
101
|
+
* Persist partial worker output into salvaged_result_json WITHOUT any status transition
|
|
102
|
+
* (Phase 3 Step 0, CK-07 / CK-09). Allowed for the lease holder while CLAIMED, and also
|
|
103
|
+
* right after the window closed (TIMED_OUT) so produced output is never silently dropped.
|
|
104
|
+
* Returns false when the caller no longer owns the lease (no write happens).
|
|
105
|
+
*/
|
|
106
|
+
recordSalvage(input: {
|
|
107
|
+
contract_id: string;
|
|
108
|
+
agent_id?: string;
|
|
109
|
+
claim_token?: string;
|
|
110
|
+
salvage: Record<string, unknown>;
|
|
111
|
+
}): boolean;
|
|
88
112
|
/**
|
|
89
113
|
* CLAIMED -> FAILED (terminal). Lets the holder close the loop explicitly instead of
|
|
90
114
|
* leaving the requester waiting for the execution TTL to expire.
|
|
@@ -103,5 +127,9 @@ export declare class FerryCatEngine {
|
|
|
103
127
|
total_returned: number;
|
|
104
128
|
contracts: Array<Record<string, unknown>>;
|
|
105
129
|
};
|
|
130
|
+
acquireDaemonLease(input: AcquireDaemonLeaseInput): AcquireDaemonLeaseResult;
|
|
131
|
+
renewDaemonLease(input: RenewDaemonLeaseInput): RenewDaemonLeaseResult;
|
|
132
|
+
releaseDaemonLease(input: ReleaseDaemonLeaseInput): ReleaseDaemonLeaseResult;
|
|
133
|
+
inspectDaemonLease(lockId?: string): DaemonLockRow | null;
|
|
106
134
|
close(): void;
|
|
107
135
|
}
|