harnery 0.34.0 → 0.35.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/commander.d.ts.map +1 -1
- package/dist/commander.js +2 -0
- package/dist/commands/agents.d.ts +15 -4
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +91 -162
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +26 -2
- package/dist/commands/decision.d.ts.map +1 -1
- package/dist/commands/decision.js +2 -2
- package/dist/commands/events.d.ts.map +1 -1
- package/dist/commands/events.js +18 -1
- package/dist/commands/presence.d.ts.map +1 -1
- package/dist/commands/presence.js +2 -2
- package/dist/commands/semantic.d.ts +4 -0
- package/dist/commands/semantic.d.ts.map +1 -0
- package/dist/commands/semantic.js +147 -0
- package/dist/commands/web.d.ts.map +1 -1
- package/dist/commands/web.js +17 -0
- package/dist/core/agents/canonical-emit.d.ts +3 -0
- package/dist/core/agents/canonical-emit.d.ts.map +1 -1
- package/dist/core/agents/canonical-emit.js +12 -0
- package/dist/core/agents/claim-path.d.ts +11 -0
- package/dist/core/agents/claim-path.d.ts.map +1 -0
- package/dist/core/agents/claim-path.js +22 -0
- package/dist/core/agents/coord-client.d.ts +29 -3
- package/dist/core/agents/coord-client.d.ts.map +1 -1
- package/dist/core/agents/coord-client.js +88 -9
- package/dist/core/agents/live-authority-v3.d.ts.map +1 -1
- package/dist/core/agents/live-authority-v3.js +1 -3
- package/dist/core/agents/live-lifecycle-v3.js +3 -3
- package/dist/core/agents/live-observation-v3.d.ts.map +1 -1
- package/dist/core/agents/live-observation-v3.js +2 -2
- package/dist/core/agents/render/prompt-context.js +12 -10
- package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
- package/dist/core/agents/rules/stop-hook.js +23 -11
- package/dist/core/agents/session-name-display.d.ts +2 -1
- package/dist/core/agents/session-name-display.d.ts.map +1 -1
- package/dist/core/agents/session-name-display.js +10 -3
- package/dist/core/agents/state/heartbeat-reader.d.ts +46 -0
- package/dist/core/agents/state/heartbeat-reader.d.ts.map +1 -0
- package/dist/core/agents/state/heartbeat-reader.js +25 -0
- package/dist/core/agents/state/heartbeat-writer.d.ts +3 -48
- package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.js +16 -34
- package/dist/core/agents/state/live-coordination-view.d.ts +1 -1
- package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-view.js +25 -1
- package/dist/core/agents/state/names.d.ts +9 -1
- package/dist/core/agents/state/names.d.ts.map +1 -1
- package/dist/core/agents/state/names.js +190 -182
- package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
- package/dist/core/agents/state/stale-sweep.js +23 -5
- package/dist/core/artifacts/constants.d.ts +5 -0
- package/dist/core/artifacts/constants.d.ts.map +1 -0
- package/dist/core/artifacts/constants.js +4 -0
- package/dist/core/artifacts/index.d.ts +3 -3
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +50 -7
- package/dist/core/events/v3/base-contract.d.ts +795 -0
- package/dist/core/events/v3/base-contract.d.ts.map +1 -1
- package/dist/core/events/v3/base-contract.js +33 -0
- package/dist/core/events/v3/capabilities.d.ts +11 -0
- package/dist/core/events/v3/capabilities.d.ts.map +1 -1
- package/dist/core/events/v3/capabilities.js +23 -0
- package/dist/core/events/v3/generated.d.ts +1 -1
- package/dist/core/events/v3/generated.js +1 -1
- package/dist/core/events/v3/index.d.ts +4 -3
- package/dist/core/events/v3/index.d.ts.map +1 -1
- package/dist/core/events/v3/index.js +4 -3
- package/dist/core/events/v3/latency.d.ts +31 -1
- package/dist/core/events/v3/latency.d.ts.map +1 -1
- package/dist/core/events/v3/latency.js +127 -3
- package/dist/core/events/v3/live-routing.d.ts +30 -0
- package/dist/core/events/v3/live-routing.d.ts.map +1 -1
- package/dist/core/events/v3/live-routing.js +109 -1
- package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/command-recorder.js +10 -1
- package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/coordination-recorder.js +14 -3
- package/dist/core/events/v3/producers/hook-base.d.ts +17 -1
- package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
- package/dist/core/events/v3/producers/hook-base.js +82 -1
- package/dist/core/events/v3/producers/intake.d.ts +6 -0
- package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
- package/dist/core/events/v3/producers/intake.js +11 -0
- package/dist/core/events/v3/producers/recorder.d.ts +62 -0
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +654 -18
- package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts +51 -0
- package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts.map +1 -0
- package/dist/core/events/v3/runtime-telemetry-capabilities.js +54 -0
- package/dist/core/events/v3/turn-telemetry.d.ts +9 -0
- package/dist/core/events/v3/turn-telemetry.d.ts.map +1 -1
- package/dist/core/hooks/adapter/parse.d.ts +3 -0
- package/dist/core/hooks/adapter/parse.d.ts.map +1 -1
- package/dist/core/hooks/adapter/parse.js +14 -0
- package/dist/core/hooks/adapter/runtime-telemetry.d.ts +119 -0
- package/dist/core/hooks/adapter/runtime-telemetry.d.ts.map +1 -0
- package/dist/core/hooks/adapter/runtime-telemetry.js +568 -0
- package/dist/core/hooks/cli.js +114 -38
- package/dist/core/hooks/remediation-cap.d.ts +34 -0
- package/dist/core/hooks/remediation-cap.d.ts.map +1 -0
- package/dist/core/hooks/remediation-cap.js +71 -0
- package/dist/core/hooks/resolve/transcript.d.ts +25 -9
- package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
- package/dist/core/hooks/resolve/transcript.js +35 -17
- package/dist/core/semantic/adapters.d.ts +34 -0
- package/dist/core/semantic/adapters.d.ts.map +1 -0
- package/dist/core/semantic/adapters.js +222 -0
- package/dist/core/semantic/contract.d.ts +588 -0
- package/dist/core/semantic/contract.d.ts.map +1 -0
- package/dist/core/semantic/contract.js +230 -0
- package/dist/core/semantic/evidence.d.ts +11 -0
- package/dist/core/semantic/evidence.d.ts.map +1 -0
- package/dist/core/semantic/evidence.js +262 -0
- package/dist/core/semantic/index.d.ts +10 -0
- package/dist/core/semantic/index.d.ts.map +1 -0
- package/dist/core/semantic/index.js +9 -0
- package/dist/core/semantic/once.d.ts +33 -0
- package/dist/core/semantic/once.d.ts.map +1 -0
- package/dist/core/semantic/once.js +293 -0
- package/dist/core/semantic/prompt.d.ts +12 -0
- package/dist/core/semantic/prompt.d.ts.map +1 -0
- package/dist/core/semantic/prompt.js +70 -0
- package/dist/core/semantic/scheduler.d.ts +16 -0
- package/dist/core/semantic/scheduler.d.ts.map +1 -0
- package/dist/core/semantic/scheduler.js +67 -0
- package/dist/core/semantic/service-status.d.ts +31 -0
- package/dist/core/semantic/service-status.d.ts.map +1 -0
- package/dist/core/semantic/service-status.js +84 -0
- package/dist/core/semantic/service.d.ts +51 -0
- package/dist/core/semantic/service.d.ts.map +1 -0
- package/dist/core/semantic/service.js +470 -0
- package/dist/core/semantic/storage.d.ts +71 -0
- package/dist/core/semantic/storage.d.ts.map +1 -0
- package/dist/core/semantic/storage.js +179 -0
- package/dist/core/semantic/validate.d.ts +16 -0
- package/dist/core/semantic/validate.d.ts.map +1 -0
- package/dist/core/semantic/validate.js +174 -0
- package/dist/lib/browser/client.d.ts +11 -0
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +13 -0
- package/dist/lib/browser/index.d.ts +1 -0
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/standalone-html.d.ts +25 -0
- package/dist/lib/browser/standalone-html.d.ts.map +1 -0
- package/dist/lib/browser/standalone-html.js +284 -0
- package/dist/lib/instructions/apply.d.ts.map +1 -1
- package/dist/lib/instructions/apply.js +1 -0
- package/dist/lib/instructions/templates.d.ts +2 -0
- package/dist/lib/instructions/templates.d.ts.map +1 -1
- package/dist/lib/instructions/templates.js +144 -4
- package/package.json +6 -1
- package/schemas/event-v3.schema.json +2758 -478
- package/src/commander.ts +2 -0
- package/src/commands/agents.ts +104 -152
- package/src/commands/browse.ts +25 -2
- package/src/commands/decision.ts +8 -2
- package/src/commands/events.ts +21 -1
- package/src/commands/presence.ts +7 -2
- package/src/commands/semantic.ts +179 -0
- package/src/commands/web.ts +15 -0
- package/src/core/agents/canonical-emit.ts +15 -0
- package/src/core/agents/claim-path.ts +23 -0
- package/src/core/agents/coord-client.ts +92 -8
- package/src/core/agents/live-authority-v3.ts +1 -4
- package/src/core/agents/live-lifecycle-v3.ts +8 -3
- package/src/core/agents/live-observation-v3.ts +7 -2
- package/src/core/agents/render/prompt-context.ts +13 -10
- package/src/core/agents/rules/stop-hook.ts +24 -11
- package/src/core/agents/session-name-display.ts +11 -3
- package/src/core/agents/state/heartbeat-reader.ts +69 -0
- package/src/core/agents/state/heartbeat-writer.ts +20 -84
- package/src/core/agents/state/live-coordination-view.ts +26 -1
- package/src/core/agents/state/names.ts +190 -182
- package/src/core/agents/state/stale-sweep.ts +25 -5
- package/src/core/artifacts/constants.ts +4 -0
- package/src/core/artifacts/index.ts +49 -7
- package/src/core/events/v3/base-contract.ts +39 -0
- package/src/core/events/v3/capabilities.ts +34 -0
- package/src/core/events/v3/generated.ts +1 -1
- package/src/core/events/v3/index.ts +21 -0
- package/src/core/events/v3/latency.ts +213 -2
- package/src/core/events/v3/live-routing.ts +120 -1
- package/src/core/events/v3/producers/command-recorder.ts +10 -1
- package/src/core/events/v3/producers/coordination-recorder.ts +17 -5
- package/src/core/events/v3/producers/hook-base.ts +115 -1
- package/src/core/events/v3/producers/intake.ts +18 -0
- package/src/core/events/v3/producers/recorder.ts +856 -21
- package/src/core/events/v3/runtime-telemetry-capabilities.ts +137 -0
- package/src/core/events/v3/turn-telemetry.ts +10 -0
- package/src/core/hooks/adapter/parse.ts +16 -0
- package/src/core/hooks/adapter/runtime-telemetry.ts +805 -0
- package/src/core/hooks/cli.ts +126 -41
- package/src/core/hooks/remediation-cap.ts +77 -0
- package/src/core/hooks/resolve/transcript.ts +49 -17
- package/src/core/semantic/adapters.ts +293 -0
- package/src/core/semantic/contract.ts +298 -0
- package/src/core/semantic/evidence.ts +336 -0
- package/src/core/semantic/index.ts +127 -0
- package/src/core/semantic/once.ts +410 -0
- package/src/core/semantic/prompt.ts +84 -0
- package/src/core/semantic/scheduler.ts +107 -0
- package/src/core/semantic/service-status.ts +118 -0
- package/src/core/semantic/service.ts +580 -0
- package/src/core/semantic/storage.ts +286 -0
- package/src/core/semantic/validate.ts +212 -0
- package/src/lib/browser/client.ts +21 -0
- package/src/lib/browser/index.ts +4 -0
- package/src/lib/browser/standalone-html.ts +312 -0
- package/src/lib/instructions/apply.ts +1 -0
- package/src/lib/instructions/templates.ts +149 -4
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { randomBytes, randomUUID } from "node:crypto";
|
|
3
|
+
import { appendFileSync, chmodSync, closeSync, existsSync, mkdirSync, openSync, readFileSync, renameSync, rmSync, statSync, unlinkSync, watch, writeFileSync, } from "node:fs";
|
|
4
|
+
import { hostname } from "node:os";
|
|
5
|
+
import { dirname, resolve } from "node:path";
|
|
6
|
+
import { readEventV3ControlState, readLedgerV3Since, } from "../events/v3/index.js";
|
|
7
|
+
import { eventV3ActiveWatchPath } from "../events/v3/reader.js";
|
|
8
|
+
import { runSemanticOnce } from "./once.js";
|
|
9
|
+
import { readSemanticServiceStatus, SEMANTIC_SERVICE_STATUS_SCHEMA_VERSION, } from "./service-status.js";
|
|
10
|
+
import { listSemanticAgentDocuments, readSemanticManifest, semanticPaths, writeSemanticManifest, } from "./storage.js";
|
|
11
|
+
export { readSemanticServiceStatus, SEMANTIC_SERVICE_STATUS_SCHEMA_VERSION, } from "./service-status.js";
|
|
12
|
+
export const SEMANTIC_SERVICE_DEFAULT_DEBOUNCE_MS = 5_000;
|
|
13
|
+
export const SEMANTIC_SERVICE_DEFAULT_WAKE_MS = 1_000;
|
|
14
|
+
export const SEMANTIC_SERVICE_DEFAULT_HEARTBEAT_MS = 5_000;
|
|
15
|
+
const FOREIGN_STATUS_STALE_MS = 2 * 60_000;
|
|
16
|
+
const MAX_FILE_BYTES = 512 * 1024;
|
|
17
|
+
const MAX_LOG_BYTES = 512 * 1024;
|
|
18
|
+
const REPEATED_ERROR_LOG_INTERVAL_MS = 60_000;
|
|
19
|
+
export async function spawnSemanticService(coordRootRaw, options = {}) {
|
|
20
|
+
const coordRoot = resolve(coordRootRaw);
|
|
21
|
+
const current = readSemanticServiceStatus(coordRoot);
|
|
22
|
+
if (current.running) {
|
|
23
|
+
throw new Error(`semantic service is already running under pid ${current.record?.pid}`);
|
|
24
|
+
}
|
|
25
|
+
const paths = semanticPaths(coordRoot);
|
|
26
|
+
mkdirSync(paths.root, { recursive: true, mode: 0o700 });
|
|
27
|
+
const logFd = openSync(paths.log, "a", 0o600);
|
|
28
|
+
chmodSync(paths.log, 0o600);
|
|
29
|
+
const harnBin = new URL("../../../bin/harn", import.meta.url).pathname;
|
|
30
|
+
if (!existsSync(harnBin)) {
|
|
31
|
+
closeSync(logFd);
|
|
32
|
+
throw new Error(`cannot find harn executable at ${harnBin}`);
|
|
33
|
+
}
|
|
34
|
+
const args = ["semantic", "service", "daemon", "--root", coordRoot];
|
|
35
|
+
if (options.callsPerHour !== undefined) {
|
|
36
|
+
args.push("--calls-per-hour", String(options.callsPerHour));
|
|
37
|
+
}
|
|
38
|
+
let spawnError;
|
|
39
|
+
const child = spawn(harnBin, args, {
|
|
40
|
+
cwd: coordRoot,
|
|
41
|
+
detached: true,
|
|
42
|
+
stdio: ["ignore", logFd, logFd],
|
|
43
|
+
env: {
|
|
44
|
+
...process.env,
|
|
45
|
+
HARNERY_COORD_ROOT_OVERRIDE: coordRoot,
|
|
46
|
+
HARNERY_OUTPUT_SESSION_TEE: "0",
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
child.once("error", (error) => {
|
|
50
|
+
spawnError = error;
|
|
51
|
+
});
|
|
52
|
+
closeSync(logFd);
|
|
53
|
+
child.unref();
|
|
54
|
+
const deadline = Date.now() + 5_000;
|
|
55
|
+
while (Date.now() < deadline) {
|
|
56
|
+
await delay(50);
|
|
57
|
+
if (spawnError)
|
|
58
|
+
throw spawnError;
|
|
59
|
+
const status = readSemanticServiceStatus(coordRoot);
|
|
60
|
+
if (status.running && status.record?.pid === child.pid)
|
|
61
|
+
return status;
|
|
62
|
+
if (child.exitCode !== null)
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
throw new Error(`semantic service failed to start; inspect ${paths.log}`);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Start semantic reading when V3 is active, unless an operator paused it.
|
|
69
|
+
*
|
|
70
|
+
* Dashboard hosts call this before launching their web process. A failed
|
|
71
|
+
* semantic launch is reported as data instead of throwing so the read-only
|
|
72
|
+
* dashboard remains available.
|
|
73
|
+
*/
|
|
74
|
+
export async function ensureSemanticServiceRunning(coordRootRaw, overrides = {}) {
|
|
75
|
+
const coordRoot = resolve(coordRootRaw);
|
|
76
|
+
const dependencies = {
|
|
77
|
+
readStatus: readSemanticServiceStatus,
|
|
78
|
+
start: spawnSemanticService,
|
|
79
|
+
isPaused: (root) => existsSync(semanticPaths(root).stop),
|
|
80
|
+
isActive: (root) => readEventV3ControlState(root).state === "active",
|
|
81
|
+
...overrides,
|
|
82
|
+
};
|
|
83
|
+
const status = dependencies.readStatus(coordRoot);
|
|
84
|
+
if (status.running)
|
|
85
|
+
return { state: "running", status };
|
|
86
|
+
if (dependencies.isPaused(coordRoot))
|
|
87
|
+
return { state: "paused", status };
|
|
88
|
+
if (!dependencies.isActive(coordRoot))
|
|
89
|
+
return { state: "inactive", status };
|
|
90
|
+
try {
|
|
91
|
+
return { state: "started", status: await dependencies.start(coordRoot) };
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
return {
|
|
95
|
+
state: "unavailable",
|
|
96
|
+
status: dependencies.readStatus(coordRoot),
|
|
97
|
+
error: error instanceof Error ? error.message : String(error),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
export function requestSemanticServiceStop(coordRootRaw) {
|
|
102
|
+
const coordRoot = resolve(coordRootRaw);
|
|
103
|
+
const status = readSemanticServiceStatus(coordRoot);
|
|
104
|
+
mkdirSync(semanticPaths(coordRoot).root, { recursive: true, mode: 0o700 });
|
|
105
|
+
writePrivateJsonAtomic(semanticPaths(coordRoot).stop, {
|
|
106
|
+
requested_at: new Date().toISOString(),
|
|
107
|
+
requested_by_pid: process.pid,
|
|
108
|
+
});
|
|
109
|
+
if (status.running && status.record?.host === hostname()) {
|
|
110
|
+
try {
|
|
111
|
+
process.kill(status.record.pid, "SIGTERM");
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
// The durable stop request remains for a racing or restarted daemon.
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return readSemanticServiceStatus(coordRoot);
|
|
118
|
+
}
|
|
119
|
+
export async function runSemanticServiceDaemon(input) {
|
|
120
|
+
const coordRoot = resolve(input.coordRoot);
|
|
121
|
+
const paths = semanticPaths(coordRoot);
|
|
122
|
+
const release = acquireSemanticServiceLease(coordRoot);
|
|
123
|
+
rmSync(paths.stop, { force: true });
|
|
124
|
+
const now = input.now ?? (() => new Date());
|
|
125
|
+
const debounceMs = Math.max(0, input.debounceMs ?? SEMANTIC_SERVICE_DEFAULT_DEBOUNCE_MS);
|
|
126
|
+
const wakeIntervalMs = positiveInterval(input.wakeIntervalMs ?? SEMANTIC_SERVICE_DEFAULT_WAKE_MS, "wake interval");
|
|
127
|
+
const heartbeatIntervalMs = positiveInterval(input.heartbeatIntervalMs ?? SEMANTIC_SERVICE_DEFAULT_HEARTBEAT_MS, "heartbeat interval");
|
|
128
|
+
const readSince = input.readSince ?? readLedgerV3Since;
|
|
129
|
+
const runOnce = input.runOnce ??
|
|
130
|
+
(async (options) => await runSemanticOnce({
|
|
131
|
+
coordRoot: options.coordRoot,
|
|
132
|
+
callsPerHour: options.callsPerHour,
|
|
133
|
+
debounceMs: options.debounceMs,
|
|
134
|
+
shouldStop: options.shouldStop,
|
|
135
|
+
}));
|
|
136
|
+
const startedAt = now().toISOString();
|
|
137
|
+
const status = {
|
|
138
|
+
schema_version: SEMANTIC_SERVICE_STATUS_SCHEMA_VERSION,
|
|
139
|
+
pid: process.pid,
|
|
140
|
+
host: hostname(),
|
|
141
|
+
nonce: randomUUID(),
|
|
142
|
+
state: "starting",
|
|
143
|
+
started_at: startedAt,
|
|
144
|
+
heartbeat_at: startedAt,
|
|
145
|
+
...(input.callsPerHour !== undefined ? { calls_per_hour: input.callsPerHour } : {}),
|
|
146
|
+
sweep_count: 0,
|
|
147
|
+
pass_count: 0,
|
|
148
|
+
model_calls: 0,
|
|
149
|
+
cache_hits: 0,
|
|
150
|
+
};
|
|
151
|
+
let stopRequested = false;
|
|
152
|
+
let dirtySince;
|
|
153
|
+
let lastLoggedErrorCode;
|
|
154
|
+
let lastLoggedErrorAt = Number.NEGATIVE_INFINITY;
|
|
155
|
+
const writeStatus = () => {
|
|
156
|
+
status.heartbeat_at = now().toISOString();
|
|
157
|
+
writePrivateJsonAtomic(paths.service, status);
|
|
158
|
+
};
|
|
159
|
+
const requestStop = () => {
|
|
160
|
+
stopRequested = true;
|
|
161
|
+
status.state = "stopping";
|
|
162
|
+
writeStatus();
|
|
163
|
+
};
|
|
164
|
+
process.on("SIGINT", requestStop);
|
|
165
|
+
process.on("SIGTERM", requestStop);
|
|
166
|
+
status.state = "running";
|
|
167
|
+
writeStatus();
|
|
168
|
+
appendSemanticServiceLog(coordRoot, { event: "service_started" });
|
|
169
|
+
const heartbeat = setInterval(() => {
|
|
170
|
+
try {
|
|
171
|
+
writeStatus();
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
// A later sweep or status read will expose the stopped or stale process.
|
|
175
|
+
}
|
|
176
|
+
}, heartbeatIntervalMs);
|
|
177
|
+
try {
|
|
178
|
+
while (!stopRequested && !existsSync(paths.stop)) {
|
|
179
|
+
const sweepAt = now();
|
|
180
|
+
status.sweep_count += 1;
|
|
181
|
+
try {
|
|
182
|
+
const before = safeManifest(coordRoot);
|
|
183
|
+
let read = readSince(coordRoot, before?.cursor, { authority: "active" });
|
|
184
|
+
if (read.reset_required) {
|
|
185
|
+
read = readSince(coordRoot, undefined, { authority: "active" });
|
|
186
|
+
}
|
|
187
|
+
requireCompleteLedger(read);
|
|
188
|
+
if (read.events.length > 0 || !before?.cursor) {
|
|
189
|
+
dirtySince ??= sweepAt.getTime();
|
|
190
|
+
}
|
|
191
|
+
const hasPending = (before?.pending.length ?? 0) > 0;
|
|
192
|
+
const hasEligibleDeferred = listSemanticAgentDocuments(coordRoot).some((document) => document.reader_outcome === "deferred" &&
|
|
193
|
+
Date.parse(document.receipt.eligible_after) <= sweepAt.getTime());
|
|
194
|
+
if (hasPending ||
|
|
195
|
+
hasEligibleDeferred ||
|
|
196
|
+
(dirtySince !== undefined && sweepAt.getTime() - dirtySince >= debounceMs)) {
|
|
197
|
+
const report = await runOnce({
|
|
198
|
+
coordRoot,
|
|
199
|
+
...(input.callsPerHour !== undefined ? { callsPerHour: input.callsPerHour } : {}),
|
|
200
|
+
debounceMs,
|
|
201
|
+
shouldStop: () => stopRequested || existsSync(paths.stop),
|
|
202
|
+
});
|
|
203
|
+
status.pass_count += 1;
|
|
204
|
+
status.model_calls += report.model_calls;
|
|
205
|
+
status.cache_hits += report.cache_hits;
|
|
206
|
+
status.last_pass_at = report.completed_at;
|
|
207
|
+
status.last_error_code = undefined;
|
|
208
|
+
lastLoggedErrorCode = undefined;
|
|
209
|
+
const after = safeManifest(coordRoot);
|
|
210
|
+
if (after && read.cursor) {
|
|
211
|
+
after.cursor = read.cursor;
|
|
212
|
+
writeSemanticManifest(coordRoot, after);
|
|
213
|
+
}
|
|
214
|
+
dirtySince = undefined;
|
|
215
|
+
const logEntry = {
|
|
216
|
+
event: "pass",
|
|
217
|
+
evidence_count: report.evidence_count,
|
|
218
|
+
evidence_by_harness: report.evidence_by_harness,
|
|
219
|
+
model_calls: report.model_calls,
|
|
220
|
+
cache_hits: report.cache_hits,
|
|
221
|
+
accepted: report.outcomes.filter((outcome) => outcome.action === "accepted").length,
|
|
222
|
+
unavailable: report.outcomes.filter((outcome) => outcome.action === "unavailable")
|
|
223
|
+
.length,
|
|
224
|
+
invalid: report.outcomes.filter((outcome) => outcome.action === "invalid").length,
|
|
225
|
+
deferred: report.outcomes.filter((outcome) => outcome.action === "deferred").length,
|
|
226
|
+
harness_metrics: semanticHarnessMetrics(report),
|
|
227
|
+
};
|
|
228
|
+
if (report.model_calls > 0 || report.cache_hits > 0 || logEntry.unavailable > 0) {
|
|
229
|
+
appendSemanticServiceLog(coordRoot, logEntry);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
catch (error) {
|
|
234
|
+
status.last_error_code = serviceErrorCode(error);
|
|
235
|
+
if (status.last_error_code !== lastLoggedErrorCode ||
|
|
236
|
+
sweepAt.getTime() - lastLoggedErrorAt >= REPEATED_ERROR_LOG_INTERVAL_MS) {
|
|
237
|
+
appendSemanticServiceLog(coordRoot, {
|
|
238
|
+
event: "sweep_error",
|
|
239
|
+
reason_code: status.last_error_code,
|
|
240
|
+
});
|
|
241
|
+
lastLoggedErrorCode = status.last_error_code;
|
|
242
|
+
lastLoggedErrorAt = sweepAt.getTime();
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
status.last_sweep_at = now().toISOString();
|
|
246
|
+
writeStatus();
|
|
247
|
+
if (input.maxSweeps !== undefined && status.sweep_count >= input.maxSweeps)
|
|
248
|
+
break;
|
|
249
|
+
if (!stopRequested && !existsSync(paths.stop)) {
|
|
250
|
+
if (input.waitForWake)
|
|
251
|
+
await input.waitForWake(wakeIntervalMs);
|
|
252
|
+
else
|
|
253
|
+
await waitForLedgerWake(eventV3ActiveWatchPath(coordRoot), wakeIntervalMs);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
finally {
|
|
258
|
+
clearInterval(heartbeat);
|
|
259
|
+
process.off("SIGINT", requestStop);
|
|
260
|
+
process.off("SIGTERM", requestStop);
|
|
261
|
+
status.state = "stopped";
|
|
262
|
+
status.stopped_at = now().toISOString();
|
|
263
|
+
writeStatus();
|
|
264
|
+
appendSemanticServiceLog(coordRoot, {
|
|
265
|
+
event: "service_stopped",
|
|
266
|
+
sweeps: status.sweep_count,
|
|
267
|
+
passes: status.pass_count,
|
|
268
|
+
model_calls: status.model_calls,
|
|
269
|
+
});
|
|
270
|
+
release();
|
|
271
|
+
}
|
|
272
|
+
return status;
|
|
273
|
+
}
|
|
274
|
+
export function acquireSemanticServiceLease(coordRootRaw) {
|
|
275
|
+
const path = semanticPaths(coordRootRaw).lease;
|
|
276
|
+
mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
|
|
277
|
+
const owner = {
|
|
278
|
+
pid: process.pid,
|
|
279
|
+
host: hostname(),
|
|
280
|
+
nonce: randomUUID(),
|
|
281
|
+
created_at: new Date().toISOString(),
|
|
282
|
+
};
|
|
283
|
+
const acquire = () => {
|
|
284
|
+
try {
|
|
285
|
+
const fd = openSync(path, "wx", 0o600);
|
|
286
|
+
try {
|
|
287
|
+
writeFileSync(fd, `${JSON.stringify(owner)}\n`, "utf8");
|
|
288
|
+
}
|
|
289
|
+
finally {
|
|
290
|
+
closeSync(fd);
|
|
291
|
+
}
|
|
292
|
+
return true;
|
|
293
|
+
}
|
|
294
|
+
catch (error) {
|
|
295
|
+
if (error.code !== "EEXIST")
|
|
296
|
+
throw error;
|
|
297
|
+
return false;
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
if (!acquire()) {
|
|
301
|
+
const existing = readLease(path);
|
|
302
|
+
if (existing && leaseOwnerIsLive(existing)) {
|
|
303
|
+
throw new Error(`semantic service is already running under pid ${existing.pid}`);
|
|
304
|
+
}
|
|
305
|
+
unlinkSync(path);
|
|
306
|
+
if (!acquire())
|
|
307
|
+
throw new Error("semantic service lease raced with another process");
|
|
308
|
+
}
|
|
309
|
+
return () => {
|
|
310
|
+
try {
|
|
311
|
+
const existing = readLease(path);
|
|
312
|
+
if (existing?.nonce === owner.nonce)
|
|
313
|
+
unlinkSync(path);
|
|
314
|
+
}
|
|
315
|
+
catch {
|
|
316
|
+
// A later explicit start can recover a stale private lease.
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
function semanticHarnessMetrics(report) {
|
|
321
|
+
const metrics = {
|
|
322
|
+
"claude-code": emptyHarnessMetrics(report.evidence_by_harness["claude-code"]),
|
|
323
|
+
codex: emptyHarnessMetrics(report.evidence_by_harness.codex),
|
|
324
|
+
cursor: emptyHarnessMetrics(report.evidence_by_harness.cursor),
|
|
325
|
+
};
|
|
326
|
+
for (const outcome of report.outcomes) {
|
|
327
|
+
const harness = metrics[outcome.source_harness];
|
|
328
|
+
if (outcome.model_call)
|
|
329
|
+
harness.model_calls += 1;
|
|
330
|
+
if (outcome.action === "cached")
|
|
331
|
+
harness.cache_hits += 1;
|
|
332
|
+
if (outcome.action === "accepted")
|
|
333
|
+
harness.accepted += 1;
|
|
334
|
+
if (outcome.action === "unavailable")
|
|
335
|
+
harness.unavailable += 1;
|
|
336
|
+
if (outcome.action === "invalid")
|
|
337
|
+
harness.invalid += 1;
|
|
338
|
+
if (outcome.action === "deferred")
|
|
339
|
+
harness.deferred += 1;
|
|
340
|
+
if (outcome.duration_ms !== undefined)
|
|
341
|
+
harness.duration_ms.push(outcome.duration_ms);
|
|
342
|
+
if (outcome.input_bytes !== undefined)
|
|
343
|
+
harness.input_bytes.push(outcome.input_bytes);
|
|
344
|
+
if (outcome.output_bytes !== undefined)
|
|
345
|
+
harness.output_bytes.push(outcome.output_bytes);
|
|
346
|
+
}
|
|
347
|
+
return metrics;
|
|
348
|
+
}
|
|
349
|
+
function emptyHarnessMetrics(evidenceCount) {
|
|
350
|
+
return {
|
|
351
|
+
evidence_count: evidenceCount,
|
|
352
|
+
model_calls: 0,
|
|
353
|
+
cache_hits: 0,
|
|
354
|
+
accepted: 0,
|
|
355
|
+
unavailable: 0,
|
|
356
|
+
invalid: 0,
|
|
357
|
+
deferred: 0,
|
|
358
|
+
duration_ms: [],
|
|
359
|
+
input_bytes: [],
|
|
360
|
+
output_bytes: [],
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
function requireCompleteLedger(read) {
|
|
364
|
+
if (!read.complete || read.diagnostics.length > 0)
|
|
365
|
+
throw new Error("ledger_unavailable");
|
|
366
|
+
}
|
|
367
|
+
function serviceErrorCode(error) {
|
|
368
|
+
return error instanceof Error && error.message === "ledger_unavailable"
|
|
369
|
+
? "ledger_unavailable"
|
|
370
|
+
: "semantic_pass_failed";
|
|
371
|
+
}
|
|
372
|
+
function safeManifest(coordRoot) {
|
|
373
|
+
try {
|
|
374
|
+
return readSemanticManifest(coordRoot);
|
|
375
|
+
}
|
|
376
|
+
catch {
|
|
377
|
+
return undefined;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
function readLease(path) {
|
|
381
|
+
try {
|
|
382
|
+
const value = JSON.parse(readFileSync(path, "utf8"));
|
|
383
|
+
if (!Number.isSafeInteger(value.pid) ||
|
|
384
|
+
(value.pid ?? 0) < 1 ||
|
|
385
|
+
typeof value.host !== "string" ||
|
|
386
|
+
typeof value.nonce !== "string" ||
|
|
387
|
+
!validTimestamp(value.created_at)) {
|
|
388
|
+
return undefined;
|
|
389
|
+
}
|
|
390
|
+
return value;
|
|
391
|
+
}
|
|
392
|
+
catch {
|
|
393
|
+
return undefined;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
function leaseOwnerIsLive(lease) {
|
|
397
|
+
if (lease.host !== hostname()) {
|
|
398
|
+
const age = Date.now() - Date.parse(lease.created_at);
|
|
399
|
+
return Number.isFinite(age) && age < FOREIGN_STATUS_STALE_MS;
|
|
400
|
+
}
|
|
401
|
+
return pidAlive(lease.pid);
|
|
402
|
+
}
|
|
403
|
+
function pidAlive(pid) {
|
|
404
|
+
try {
|
|
405
|
+
process.kill(pid, 0);
|
|
406
|
+
return true;
|
|
407
|
+
}
|
|
408
|
+
catch (error) {
|
|
409
|
+
return error.code === "EPERM";
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
async function waitForLedgerWake(path, milliseconds) {
|
|
413
|
+
await new Promise((done) => {
|
|
414
|
+
let settled = false;
|
|
415
|
+
let watcher;
|
|
416
|
+
const finish = () => {
|
|
417
|
+
if (settled)
|
|
418
|
+
return;
|
|
419
|
+
settled = true;
|
|
420
|
+
clearTimeout(timer);
|
|
421
|
+
watcher?.close();
|
|
422
|
+
done();
|
|
423
|
+
};
|
|
424
|
+
const timer = setTimeout(finish, milliseconds);
|
|
425
|
+
try {
|
|
426
|
+
watcher = watch(path, { persistent: false }, finish);
|
|
427
|
+
}
|
|
428
|
+
catch {
|
|
429
|
+
// The timer is the polling fallback when the active file does not exist yet.
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
function appendSemanticServiceLog(coordRoot, entry) {
|
|
434
|
+
const path = semanticPaths(coordRoot).log;
|
|
435
|
+
mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
|
|
436
|
+
appendFileSync(path, `${JSON.stringify({ schema_version: 1, ts: new Date().toISOString(), ...entry })}\n`, { encoding: "utf8", mode: 0o600 });
|
|
437
|
+
chmodSync(path, 0o600);
|
|
438
|
+
if (statSync(path).size <= MAX_LOG_BYTES)
|
|
439
|
+
return;
|
|
440
|
+
const buffer = readFileSync(path);
|
|
441
|
+
const tail = buffer.subarray(Math.max(0, buffer.length - Math.floor(MAX_LOG_BYTES / 2)));
|
|
442
|
+
const newline = tail.indexOf(10);
|
|
443
|
+
const body = newline >= 0 ? tail.subarray(newline + 1) : tail;
|
|
444
|
+
const temporary = `${path}.tmp-${process.pid}-${randomBytes(4).toString("hex")}`;
|
|
445
|
+
writeFileSync(temporary, body, { flag: "wx", mode: 0o600 });
|
|
446
|
+
renameSync(temporary, path);
|
|
447
|
+
}
|
|
448
|
+
function writePrivateJsonAtomic(path, value) {
|
|
449
|
+
const body = `${JSON.stringify(value, null, 2)}\n`;
|
|
450
|
+
if (Buffer.byteLength(body) > MAX_FILE_BYTES) {
|
|
451
|
+
throw new Error(`semantic service file exceeds ${MAX_FILE_BYTES} bytes`);
|
|
452
|
+
}
|
|
453
|
+
mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
|
|
454
|
+
chmodSync(dirname(path), 0o700);
|
|
455
|
+
const temporary = `${path}.tmp-${process.pid}-${randomBytes(4).toString("hex")}`;
|
|
456
|
+
writeFileSync(temporary, body, { encoding: "utf8", flag: "wx", mode: 0o600 });
|
|
457
|
+
renameSync(temporary, path);
|
|
458
|
+
chmodSync(path, 0o600);
|
|
459
|
+
}
|
|
460
|
+
function validTimestamp(value) {
|
|
461
|
+
return typeof value === "string" && Number.isFinite(Date.parse(value));
|
|
462
|
+
}
|
|
463
|
+
function positiveInterval(value, label) {
|
|
464
|
+
if (!Number.isFinite(value) || value < 1)
|
|
465
|
+
throw new Error(`${label} must be positive`);
|
|
466
|
+
return Math.floor(value);
|
|
467
|
+
}
|
|
468
|
+
function delay(milliseconds) {
|
|
469
|
+
return new Promise((done) => setTimeout(done, milliseconds));
|
|
470
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { LedgerCursorV3 } from "../events/v3/reader.js";
|
|
2
|
+
import { SEMANTIC_EVIDENCE_CONTRACT_VERSION, SEMANTIC_PROMPT_CONTRACT_VERSION, type SemanticAgentReadModelV2, type SemanticConfiguredModel, type SemanticHarness } from "./contract.js";
|
|
3
|
+
export declare const SEMANTIC_MANIFEST_SCHEMA_VERSION: 2;
|
|
4
|
+
export interface SemanticReaderResolution {
|
|
5
|
+
harness: SemanticHarness;
|
|
6
|
+
configured_model: SemanticConfiguredModel;
|
|
7
|
+
resolved_model_id?: string;
|
|
8
|
+
model_attestation?: "verified" | "requested-only";
|
|
9
|
+
available: boolean;
|
|
10
|
+
reason_code?: "harness_unavailable" | "authentication_unavailable" | "model_unavailable" | "model_mismatch";
|
|
11
|
+
discovered_at: string;
|
|
12
|
+
}
|
|
13
|
+
export interface SemanticPendingItem {
|
|
14
|
+
generation_id: string;
|
|
15
|
+
evidence_digest: `sha256:${string}`;
|
|
16
|
+
band: 1 | 2;
|
|
17
|
+
pending_since: string;
|
|
18
|
+
}
|
|
19
|
+
export interface SemanticCallReceipt {
|
|
20
|
+
generation_id: string;
|
|
21
|
+
started_at: string;
|
|
22
|
+
}
|
|
23
|
+
export interface SemanticManifestV2 {
|
|
24
|
+
schema_version: typeof SEMANTIC_MANIFEST_SCHEMA_VERSION;
|
|
25
|
+
ledger_genesis_id: string;
|
|
26
|
+
cursor?: LedgerCursorV3;
|
|
27
|
+
configuration_digest: `sha256:${string}`;
|
|
28
|
+
evidence_contract_version: typeof SEMANTIC_EVIDENCE_CONTRACT_VERSION;
|
|
29
|
+
prompt_contract_version: typeof SEMANTIC_PROMPT_CONTRACT_VERSION;
|
|
30
|
+
adapter_resolutions: Partial<Record<SemanticHarness, SemanticReaderResolution>>;
|
|
31
|
+
pending: SemanticPendingItem[];
|
|
32
|
+
call_history: SemanticCallReceipt[];
|
|
33
|
+
last_first_band_generation_id?: string;
|
|
34
|
+
newest_successful_pass?: string;
|
|
35
|
+
updated_at: string;
|
|
36
|
+
}
|
|
37
|
+
export interface SemanticCacheIdentity {
|
|
38
|
+
evidence_digest: `sha256:${string}`;
|
|
39
|
+
source_harness: SemanticHarness;
|
|
40
|
+
configured_model: SemanticConfiguredModel;
|
|
41
|
+
resolved_model_id: string;
|
|
42
|
+
evidence_contract_version: number;
|
|
43
|
+
prompt_contract_version: number;
|
|
44
|
+
}
|
|
45
|
+
export declare function semanticPaths(coordRootRaw: string): {
|
|
46
|
+
root: string;
|
|
47
|
+
manifest: string;
|
|
48
|
+
agents: string;
|
|
49
|
+
cache: string;
|
|
50
|
+
service: string;
|
|
51
|
+
stop: string;
|
|
52
|
+
lease: string;
|
|
53
|
+
log: string;
|
|
54
|
+
};
|
|
55
|
+
export declare function semanticConfigurationDigest(resolutions: Partial<Record<SemanticHarness, SemanticReaderResolution>>): `sha256:${string}`;
|
|
56
|
+
export declare function semanticCacheKey(identity: SemanticCacheIdentity): `sha256:${string}`;
|
|
57
|
+
export declare function readSemanticManifest(coordRootRaw: string): SemanticManifestV2 | undefined;
|
|
58
|
+
export declare function writeSemanticManifest(coordRootRaw: string, manifest: SemanticManifestV2): void;
|
|
59
|
+
export declare function readSemanticAgentDocument(coordRootRaw: string, generationId: string): SemanticAgentReadModelV2 | undefined;
|
|
60
|
+
export declare function listSemanticAgentDocuments(coordRootRaw: string): SemanticAgentReadModelV2[];
|
|
61
|
+
export declare function inspectSemanticDocument(coordRootRaw: string, instanceOrGeneration: string): SemanticAgentReadModelV2 | undefined;
|
|
62
|
+
export declare function writeSemanticAgentDocument(coordRootRaw: string, document: SemanticAgentReadModelV2): void;
|
|
63
|
+
export declare function readSemanticCache(coordRootRaw: string, cacheKey: string): SemanticAgentReadModelV2 | undefined;
|
|
64
|
+
export declare function writeSemanticCache(coordRootRaw: string, cacheKey: string, document: SemanticAgentReadModelV2): void;
|
|
65
|
+
export declare function invalidateSemanticDerivedState(coordRootRaw: string): void;
|
|
66
|
+
export declare function pruneSemanticStorage(coordRootRaw: string, options: {
|
|
67
|
+
keepGenerations: ReadonlySet<string>;
|
|
68
|
+
now?: number;
|
|
69
|
+
maxCacheFiles?: number;
|
|
70
|
+
}): void;
|
|
71
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/core/semantic/storage.ts"],"names":[],"mappings":"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"}
|