@noopolis/daimon 0.2.0 → 0.2.1
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 +6 -0
- package/dist/contracts/attentionContract.d.ts +25 -0
- package/dist/contracts/attentionContract.d.ts.map +1 -1
- package/dist/contracts/attentionContract.js +8 -1
- package/dist/contracts/grokBrokerTaskClock.d.ts +18 -0
- package/dist/contracts/grokBrokerTaskClock.d.ts.map +1 -0
- package/dist/contracts/grokBrokerTaskClock.js +16 -0
- package/dist/contracts/organizationRuntimeContract.d.ts +76 -0
- package/dist/contracts/organizationRuntimeContract.d.ts.map +1 -1
- package/dist/contracts/organizationRuntimeContract.js +2 -0
- package/dist/contracts/runtimeContractManifest.d.ts +222 -15
- package/dist/contracts/runtimeContractManifest.d.ts.map +1 -1
- package/dist/contracts/runtimeContractManifest.js +35 -10
- package/dist/contracts/shellEnvironmentPolicy.d.ts +3 -0
- package/dist/contracts/shellEnvironmentPolicy.d.ts.map +1 -0
- package/dist/contracts/shellEnvironmentPolicy.js +5 -0
- package/dist/contracts/wakeMomentContract.d.ts +61 -0
- package/dist/contracts/wakeMomentContract.d.ts.map +1 -0
- package/dist/contracts/wakeMomentContract.js +27 -0
- package/dist/core/types.d.ts +2 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/examples/jungianPlayAgent.d.ts +1 -0
- package/dist/examples/jungianPlayAgent.d.ts.map +1 -1
- package/dist/examples/jungianPlayAgent.js +6 -2
- package/dist/observability/causalEvents.d.ts +3 -3
- package/dist/observability/causalEvents.d.ts.map +1 -1
- package/dist/observability/causalEvents.js +4 -4
- package/dist/pi/cliEngineSpawn.d.ts +2 -2
- package/dist/pi/cliEngineSpawn.d.ts.map +1 -1
- package/dist/pi/cliEngineSpawn.js +7 -2
- package/dist/pi/cliEnvironment.d.ts.map +1 -1
- package/dist/pi/cliEnvironment.js +2 -0
- package/dist/pi/cliMcpRegistration.d.ts +1 -1
- package/dist/pi/cliMcpRegistration.d.ts.map +1 -1
- package/dist/pi/cliMcpRegistration.js +1 -1
- package/dist/pi/cliSession.d.ts +2 -0
- package/dist/pi/cliSession.d.ts.map +1 -1
- package/dist/pi/cliSession.js +3 -80
- package/dist/pi/cliSessionMcp.d.ts +9 -0
- package/dist/pi/cliSessionMcp.d.ts.map +1 -0
- package/dist/pi/cliSessionMcp.js +80 -0
- package/dist/pi/engineTaskClock.d.ts +9 -0
- package/dist/pi/engineTaskClock.d.ts.map +1 -0
- package/dist/pi/engineTaskClock.js +28 -0
- package/dist/pi/grokHomeMcpRegistration.d.ts.map +1 -1
- package/dist/pi/grokHomeMcpRegistration.js +2 -1
- package/dist/pi/grokSandbox.js +1 -1
- package/dist/pi/memoryClock.d.ts +25 -0
- package/dist/pi/memoryClock.d.ts.map +1 -0
- package/dist/pi/memoryClock.js +18 -0
- package/dist/pi/piAgentHandle.d.ts +3 -1
- package/dist/pi/piAgentHandle.d.ts.map +1 -1
- package/dist/pi/piAgentHandle.js +5 -2
- package/dist/pi/piHarness.d.ts +8 -2
- package/dist/pi/piHarness.d.ts.map +1 -1
- package/dist/pi/piHarness.js +28 -12
- package/dist/pi/taskClockProcess.d.ts +6 -0
- package/dist/pi/taskClockProcess.d.ts.map +1 -0
- package/dist/pi/taskClockProcess.js +8 -0
- package/dist/pi/turnCausal.d.ts +4 -2
- package/dist/pi/turnCausal.d.ts.map +1 -1
- package/dist/pi/turnCausal.js +4 -4
- package/dist/pi/wakeAcceptance.d.ts +1 -1
- package/dist/pi/wakeAcceptance.d.ts.map +1 -1
- package/dist/pi/wakeAcceptance.js +2 -2
- package/dist/runtime/agySubscriptionBootstrap.js +1 -1
- package/dist/runtime/agySubscriptionRealm.js +1 -1
- package/dist/runtime/attention.d.ts +5 -0
- package/dist/runtime/attention.d.ts.map +1 -1
- package/dist/runtime/attention.js +14 -1
- package/dist/runtime/attentionDispatcher.d.ts +14 -2
- package/dist/runtime/attentionDispatcher.d.ts.map +1 -1
- package/dist/runtime/attentionDispatcher.js +127 -33
- package/dist/runtime/cli.js +5 -0
- package/dist/runtime/contract-manifest.json +1 -1
- package/dist/runtime/contract-manifest.sha256 +1 -1
- package/dist/runtime/engineBrokerCapabilities.d.ts +10 -0
- package/dist/runtime/engineBrokerCapabilities.d.ts.map +1 -1
- package/dist/runtime/engineBrokerCapabilities.js +10 -0
- package/dist/runtime/engineBrokerControlClient.d.ts +12 -1
- package/dist/runtime/engineBrokerControlClient.d.ts.map +1 -1
- package/dist/runtime/engineBrokerControlClient.js +139 -43
- package/dist/runtime/engineBrokerCredentialJournal.d.ts +2 -0
- package/dist/runtime/engineBrokerCredentialJournal.d.ts.map +1 -1
- package/dist/runtime/engineBrokerCredentialJournal.js +9 -0
- package/dist/runtime/engineBrokerInferenceProtocol.d.ts +3 -2
- package/dist/runtime/engineBrokerInferenceProtocol.d.ts.map +1 -1
- package/dist/runtime/engineBrokerInferenceProtocol.js +4 -4
- package/dist/runtime/engineBrokerMcpCallLog.d.ts +11 -0
- package/dist/runtime/engineBrokerMcpCallLog.d.ts.map +1 -1
- package/dist/runtime/engineBrokerMcpCallLog.js +13 -1
- package/dist/runtime/engineBrokerMcpFacade.d.ts +5 -2
- package/dist/runtime/engineBrokerMcpFacade.d.ts.map +1 -1
- package/dist/runtime/engineBrokerMcpFacade.js +5 -2
- package/dist/runtime/engineBrokerNativeClient.js +2 -2
- package/dist/runtime/engineBrokerProtocol.d.ts +42 -10
- package/dist/runtime/engineBrokerProtocol.d.ts.map +1 -1
- package/dist/runtime/engineBrokerProtocol.js +97 -14
- package/dist/runtime/engineBrokerSealLedger.d.ts.map +1 -1
- package/dist/runtime/engineBrokerSealLedger.js +9 -0
- package/dist/runtime/engineBrokerService.d.ts +8 -2
- package/dist/runtime/engineBrokerService.d.ts.map +1 -1
- package/dist/runtime/engineBrokerService.js +95 -37
- package/dist/runtime/engineBrokerServiceCli.js +1 -1
- package/dist/runtime/engineBrokerServiceConfig.d.ts +5 -0
- package/dist/runtime/engineBrokerServiceConfig.d.ts.map +1 -1
- package/dist/runtime/engineBrokerServiceConfig.js +47 -9
- package/dist/runtime/engineBrokerTurnRegistry.d.ts +1 -1
- package/dist/runtime/engineBrokerTurnRegistry.d.ts.map +1 -1
- package/dist/runtime/engineBrokerTurnRegistry.js +7 -6
- package/dist/runtime/engineDispatcher.d.ts +2 -0
- package/dist/runtime/engineDispatcher.d.ts.map +1 -1
- package/dist/runtime/engineDispatcher.js +14 -2
- package/dist/runtime/engineReadiness.js +1 -1
- package/dist/runtime/grokBrokerCredentialAuthority.d.ts +1 -0
- package/dist/runtime/grokBrokerCredentialAuthority.d.ts.map +1 -1
- package/dist/runtime/grokBrokerCredentialAuthority.js +48 -22
- package/dist/runtime/grokBrokerCredentialReader.d.ts +1 -0
- package/dist/runtime/grokBrokerCredentialReader.d.ts.map +1 -1
- package/dist/runtime/grokBrokerCredentialReader.js +2 -1
- package/dist/runtime/grokBrokerProjection.d.ts +9 -1
- package/dist/runtime/grokBrokerProjection.d.ts.map +1 -1
- package/dist/runtime/grokBrokerProjection.js +11 -4
- package/dist/runtime/grokBrokerProviderClock.d.ts +26 -0
- package/dist/runtime/grokBrokerProviderClock.d.ts.map +1 -0
- package/dist/runtime/grokBrokerProviderClock.js +133 -0
- package/dist/runtime/grokBrokerProxy.d.ts +17 -3
- package/dist/runtime/grokBrokerProxy.d.ts.map +1 -1
- package/dist/runtime/grokBrokerProxy.js +73 -9
- package/dist/runtime/grokBrokerProxyJson.d.ts +10 -0
- package/dist/runtime/grokBrokerProxyJson.d.ts.map +1 -0
- package/dist/runtime/grokBrokerProxyJson.js +31 -0
- package/dist/runtime/grokBrokerProxyRequest.d.ts.map +1 -1
- package/dist/runtime/grokBrokerProxyRequest.js +17 -6
- package/dist/runtime/grokBrokerRealmLease.js +1 -1
- package/dist/runtime/grokBrokerRefresh.js +1 -1
- package/dist/runtime/grokBrokerRunBudget.d.ts +20 -0
- package/dist/runtime/grokBrokerRunBudget.d.ts.map +1 -0
- package/dist/runtime/grokBrokerRunBudget.js +85 -0
- package/dist/runtime/grokBrokerSlot.d.ts +6 -0
- package/dist/runtime/grokBrokerSlot.d.ts.map +1 -0
- package/dist/runtime/grokBrokerSlot.js +21 -0
- package/dist/runtime/grokBrokerTaskClock.d.ts +32 -0
- package/dist/runtime/grokBrokerTaskClock.d.ts.map +1 -0
- package/dist/runtime/grokBrokerTaskClock.js +120 -0
- package/dist/runtime/grokBrokerTurnMeter.d.ts +55 -3
- package/dist/runtime/grokBrokerTurnMeter.d.ts.map +1 -1
- package/dist/runtime/grokBrokerTurnMeter.js +90 -4
- package/dist/runtime/grokBrokerWorkerConfig.d.ts +5 -2
- package/dist/runtime/grokBrokerWorkerConfig.d.ts.map +1 -1
- package/dist/runtime/grokBrokerWorkerConfig.js +22 -3
- package/dist/runtime/grokEngineBroker.d.ts +43 -3
- package/dist/runtime/grokEngineBroker.d.ts.map +1 -1
- package/dist/runtime/grokEngineBroker.js +159 -71
- package/dist/runtime/grokEngineBrokerTurn.d.ts +32 -8
- package/dist/runtime/grokEngineBrokerTurn.d.ts.map +1 -1
- package/dist/runtime/grokEngineBrokerTurn.js +204 -21
- package/dist/runtime/grokEngineBrokerTurnEnd.d.ts +88 -0
- package/dist/runtime/grokEngineBrokerTurnEnd.d.ts.map +1 -0
- package/dist/runtime/grokEngineBrokerTurnEnd.js +148 -0
- package/dist/runtime/grokInferenceProxy.d.ts.map +1 -1
- package/dist/runtime/grokInferenceProxy.js +3 -0
- package/dist/runtime/grokSubscriptionRealm.js +1 -1
- package/dist/runtime/grokWorkerAttestation.d.ts +9 -4
- package/dist/runtime/grokWorkerAttestation.d.ts.map +1 -1
- package/dist/runtime/grokWorkerAttestation.js +2 -2
- package/dist/runtime/grokWorkerHomeAttestation.d.ts +4 -2
- package/dist/runtime/grokWorkerHomeAttestation.d.ts.map +1 -1
- package/dist/runtime/grokWorkerHomeAttestation.js +10 -4
- package/dist/runtime/index.d.ts +7 -2
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +5 -1
- package/dist/runtime/native/daimon-engine-broker +0 -0
- package/dist/runtime/organizationRuntime.d.ts +3 -0
- package/dist/runtime/organizationRuntime.d.ts.map +1 -1
- package/dist/runtime/organizationRuntimeAdmission.d.ts +6 -0
- package/dist/runtime/organizationRuntimeAdmission.d.ts.map +1 -0
- package/dist/runtime/organizationRuntimeAdmission.js +22 -0
- package/dist/runtime/organizationRuntimeControl.d.ts +9 -0
- package/dist/runtime/organizationRuntimeControl.d.ts.map +1 -1
- package/dist/runtime/organizationRuntimeControl.js +72 -24
- package/dist/runtime/organizationRuntimeHost.d.ts.map +1 -1
- package/dist/runtime/organizationRuntimeHost.js +13 -4
- package/dist/runtime/organizationRuntimeParsing.d.ts.map +1 -1
- package/dist/runtime/organizationRuntimeParsing.js +4 -1
- package/dist/runtime/organizationRuntimeReadiness.d.ts.map +1 -1
- package/dist/runtime/organizationRuntimeReadiness.js +8 -0
- package/dist/runtime/organizationRuntimeRecording.d.ts +7 -0
- package/dist/runtime/organizationRuntimeRecording.d.ts.map +1 -0
- package/dist/runtime/organizationRuntimeRecording.js +58 -0
- package/dist/runtime/physicalReadiness.d.ts +12 -0
- package/dist/runtime/physicalReadiness.d.ts.map +1 -1
- package/dist/runtime/physicalReadiness.js +43 -9
- package/dist/runtime/productionAgentTools.d.ts.map +1 -1
- package/dist/runtime/productionAgentTools.js +13 -5
- package/dist/runtime/relocateRuntimeConfig.d.ts +14 -0
- package/dist/runtime/relocateRuntimeConfig.d.ts.map +1 -0
- package/dist/runtime/relocateRuntimeConfig.js +38 -0
- package/dist/runtime/schedule.d.ts.map +1 -1
- package/dist/runtime/schedule.js +12 -7
- package/dist/runtime/storeCoordination.d.ts +10 -0
- package/dist/runtime/storeCoordination.d.ts.map +1 -1
- package/dist/runtime/storeCoordination.js +23 -0
- package/dist/runtime/taskClock.d.ts +42 -0
- package/dist/runtime/taskClock.d.ts.map +1 -0
- package/dist/runtime/taskClock.js +102 -0
- package/dist/runtime/taskClockProcess.d.ts +17 -0
- package/dist/runtime/taskClockProcess.d.ts.map +1 -0
- package/dist/runtime/taskClockProcess.js +58 -0
- package/dist/runtime/turnRequestLedger.d.ts +0 -5
- package/dist/runtime/turnRequestLedger.d.ts.map +1 -1
- package/dist/runtime/turnRequestLedger.js +23 -21
- package/dist/runtime/wakeAcceptanceClaimDiagnostics.d.ts +34 -0
- package/dist/runtime/wakeAcceptanceClaimDiagnostics.d.ts.map +1 -0
- package/dist/runtime/wakeAcceptanceClaimDiagnostics.js +79 -0
- package/dist/runtime/wakeAcceptanceIndex.d.ts +55 -0
- package/dist/runtime/wakeAcceptanceIndex.d.ts.map +1 -0
- package/dist/runtime/wakeAcceptanceIndex.js +158 -0
- package/dist/runtime/wakeAcceptanceProcessIdentity.d.ts +9 -1
- package/dist/runtime/wakeAcceptanceProcessIdentity.d.ts.map +1 -1
- package/dist/runtime/wakeAcceptanceProcessIdentity.js +5 -1
- package/dist/runtime/wakeAcceptanceRecord.d.ts +2 -0
- package/dist/runtime/wakeAcceptanceRecord.d.ts.map +1 -1
- package/dist/runtime/wakeAcceptanceRecord.js +4 -2
- package/dist/runtime/wakeAcceptanceRetention.d.ts +25 -1
- package/dist/runtime/wakeAcceptanceRetention.d.ts.map +1 -1
- package/dist/runtime/wakeAcceptanceRetention.js +28 -2
- package/dist/runtime/wakeAcceptanceStore.d.ts +8 -8
- package/dist/runtime/wakeAcceptanceStore.d.ts.map +1 -1
- package/dist/runtime/wakeAcceptanceStore.js +66 -63
- package/dist/runtime/wakeFuse.d.ts +58 -3
- package/dist/runtime/wakeFuse.d.ts.map +1 -1
- package/dist/runtime/wakeFuse.js +106 -7
- package/dist/runtime/wakeMomentFs.d.ts +27 -0
- package/dist/runtime/wakeMomentFs.d.ts.map +1 -0
- package/dist/runtime/wakeMomentFs.js +223 -0
- package/dist/runtime/wakeMomentHistory.d.ts +26 -0
- package/dist/runtime/wakeMomentHistory.d.ts.map +1 -0
- package/dist/runtime/wakeMomentHistory.js +109 -0
- package/dist/runtime/wakeMomentIo.d.ts +22 -0
- package/dist/runtime/wakeMomentIo.d.ts.map +1 -0
- package/dist/runtime/wakeMomentIo.js +114 -0
- package/dist/runtime/wakeMomentRecorder.d.ts +33 -0
- package/dist/runtime/wakeMomentRecorder.d.ts.map +1 -0
- package/dist/runtime/wakeMomentRecorder.js +81 -0
- package/dist/runtime/wakeMomentRetention.d.ts +7 -0
- package/dist/runtime/wakeMomentRetention.d.ts.map +1 -0
- package/dist/runtime/wakeMomentRetention.js +143 -0
- package/dist/runtime/wakeMomentRows.d.ts +8 -0
- package/dist/runtime/wakeMomentRows.d.ts.map +1 -0
- package/dist/runtime/wakeMomentRows.js +66 -0
- package/dist/runtime/wakeMomentSnapshot.d.ts +56 -0
- package/dist/runtime/wakeMomentSnapshot.d.ts.map +1 -0
- package/dist/runtime/wakeMomentSnapshot.js +248 -0
- package/package.json +4 -4
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { constants } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { WAKE_MOMENTS } from "../contracts/wakeMomentContract.js";
|
|
5
|
+
import { assertNoSymlinkComponents } from "./physicalReadiness.js";
|
|
6
|
+
import { cleanMomentPaths, ensureMomentDirectory, manifestBytes, momentPathExists, openMomentFile, pinMomentStore, readMomentJson, syncMomentDirectory, WakeMomentFault, writeMomentJson } from "./wakeMomentFs.js";
|
|
7
|
+
import { WakeMomentIo } from "./wakeMomentIo.js";
|
|
8
|
+
import { indexWithSnapshot, latestSnapshotIndex, snapshotName, snapshotRootName, snapshotTime, writeSnapshotIndex } from "./wakeMomentHistory.js";
|
|
9
|
+
export { completeSnapshotNames, snapshotName, snapshotRootName, snapshotTime } from "./wakeMomentHistory.js";
|
|
10
|
+
export async function readSnapshotManifest(directory, name, id, io = new WakeMomentIo(), maxManifestBytes = WAKE_MOMENTS.maxManifestBytes) {
|
|
11
|
+
try {
|
|
12
|
+
const value = await readMomentJson(path.join(directory, `${name}.manifest.json`), io, maxManifestBytes);
|
|
13
|
+
if (!value || value.version !== WAKE_MOMENTS.version || value.id !== id || value.snapshot !== name || Date.parse(value.started_at) !== snapshotTime(name)
|
|
14
|
+
|| typeof value.sourcePath !== "string" || !value.entries || typeof value.entries !== "object" || Array.isArray(value.entries)
|
|
15
|
+
|| Object.keys(value.entries).length > WAKE_MOMENTS.maxSnapshotEntries)
|
|
16
|
+
return undefined;
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
io.check();
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/** SOURCE identity, never the copied inode's metadata: ordinary writers cannot restore ctime. */
|
|
25
|
+
export function sameSnapshotSource(left, right) {
|
|
26
|
+
return left.dev === right.dev && left.ino === right.ino && left.size === right.size
|
|
27
|
+
&& left.mtimeNs === right.mtimeNs && left.ctimeNs === right.ctimeNs && left.mode === right.mode;
|
|
28
|
+
}
|
|
29
|
+
function identity(stat) {
|
|
30
|
+
return { dev: String(stat.dev), ino: String(stat.ino), size: String(stat.size), mtimeNs: String(stat.mtimeNs), ctimeNs: String(stat.ctimeNs), mode: Number(stat.mode) };
|
|
31
|
+
}
|
|
32
|
+
export async function captureWakeSnapshot(input) {
|
|
33
|
+
if (input.io && input.cleanup)
|
|
34
|
+
return capture(input, input.io, input.cleanup);
|
|
35
|
+
const io = new WakeMomentIo(), cleanup = new Set();
|
|
36
|
+
let store;
|
|
37
|
+
try {
|
|
38
|
+
return await io.bounded(WAKE_MOMENTS.captureDeadlineMs, async () => {
|
|
39
|
+
store = await pinMomentStore(input.directory, io);
|
|
40
|
+
io.verifyWrite = (target) => store.verify(io, target);
|
|
41
|
+
return capture(input, io, cleanup);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
if (store) {
|
|
46
|
+
const finalizer = new WakeMomentIo();
|
|
47
|
+
finalizer.verifyWrite = (target) => store.verify(finalizer, target);
|
|
48
|
+
try {
|
|
49
|
+
await finalizer.bounded(WAKE_MOMENTS.finalizationDeadlineMs, () => cleanMomentPaths(cleanup, store, finalizer));
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
void store.close().catch(() => undefined);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async function capture(input, io, cleanup) {
|
|
58
|
+
const namespace = path.join(input.directory, WAKE_MOMENTS.snapshotsDirectory);
|
|
59
|
+
await ensureMomentDirectory(namespace, io);
|
|
60
|
+
const base = path.join(namespace, snapshotRootName(input.root.id));
|
|
61
|
+
await ensureMomentDirectory(base, io);
|
|
62
|
+
const requestedName = snapshotName(input.startedAt, input.executionId);
|
|
63
|
+
let name = requestedName;
|
|
64
|
+
while (await collides(name))
|
|
65
|
+
name = `${requestedName}-${randomUUID()}`;
|
|
66
|
+
const partial = path.join(base, `${name}.partial`), destination = path.join(base, name);
|
|
67
|
+
const { index } = await latestSnapshotIndex(base, io, cleanup), previousName = index?.snapshot;
|
|
68
|
+
let previous = previousName ? await readSnapshotManifest(base, previousName, input.root.id, io, input.maxManifestBytes) : undefined;
|
|
69
|
+
if (previous?.sourcePath !== input.root.path)
|
|
70
|
+
previous = undefined;
|
|
71
|
+
const manifest = { version: WAKE_MOMENTS.version, id: input.root.id, snapshot: name, started_at: input.startedAt, sourcePath: input.root.path, entries: Object.create(null) };
|
|
72
|
+
const snapshot = { id: input.root.id, snapshot: name, files: 0, copied: 0, linked: 0, skipped: 0 };
|
|
73
|
+
const max = Math.min(input.maxEntries ?? WAKE_MOMENTS.maxSnapshotEntries, WAKE_MOMENTS.maxSnapshotEntries);
|
|
74
|
+
let entries = 0, note;
|
|
75
|
+
await io.fs.mkdir(partial, { mode: 0o700 });
|
|
76
|
+
cleanup.add(partial);
|
|
77
|
+
{
|
|
78
|
+
let root;
|
|
79
|
+
try {
|
|
80
|
+
await assertNoSymlinkComponents(input.root.path, io.fs.lstat);
|
|
81
|
+
root = await openSourceDirectory(input.root.path, io);
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
if (error.code === "ENOENT")
|
|
85
|
+
note = "root_missing";
|
|
86
|
+
else
|
|
87
|
+
throw error;
|
|
88
|
+
}
|
|
89
|
+
if (root) {
|
|
90
|
+
try {
|
|
91
|
+
await walk(root, input.root.path, "");
|
|
92
|
+
}
|
|
93
|
+
finally {
|
|
94
|
+
await root.close();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// The writer enforces exactly the reader's byte bound BEFORE either publication rename.
|
|
98
|
+
const bytes = manifestBytes(manifest, input.maxManifestBytes);
|
|
99
|
+
await syncMomentDirectory(partial, io);
|
|
100
|
+
// Reserve the final name exclusively before rename can replace anything at it.
|
|
101
|
+
await io.fs.mkdir(destination, { mode: 0o700 });
|
|
102
|
+
cleanup.add(destination);
|
|
103
|
+
await io.fs.rename(partial, destination);
|
|
104
|
+
cleanup.delete(partial);
|
|
105
|
+
await syncMomentDirectory(base, io);
|
|
106
|
+
const manifestPath = path.join(base, `${name}.manifest.json`);
|
|
107
|
+
await writeMomentJson(manifestPath, bytes, io, cleanup);
|
|
108
|
+
try {
|
|
109
|
+
await writeSnapshotIndex(base, indexWithSnapshot(index, name), io, cleanup);
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
if (!(error instanceof WakeMomentFault) || error.reason !== "invalid_latest_index")
|
|
113
|
+
throw error;
|
|
114
|
+
note = [note, error.reason].filter(Boolean).join("; ");
|
|
115
|
+
}
|
|
116
|
+
const markerPath = path.join(base, `${name}${WAKE_MOMENTS.completionSuffix}`);
|
|
117
|
+
const marker = await openMomentFile(markerPath, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL, io);
|
|
118
|
+
cleanup.add(markerPath);
|
|
119
|
+
try {
|
|
120
|
+
await marker.sync();
|
|
121
|
+
}
|
|
122
|
+
finally {
|
|
123
|
+
await marker.close();
|
|
124
|
+
}
|
|
125
|
+
await syncMomentDirectory(base, io);
|
|
126
|
+
cleanup.delete(markerPath);
|
|
127
|
+
cleanup.delete(manifestPath);
|
|
128
|
+
cleanup.delete(destination);
|
|
129
|
+
return { snapshot, ...(note ? { note } : {}) };
|
|
130
|
+
}
|
|
131
|
+
async function collides(candidate) {
|
|
132
|
+
for (const suffix of ["", ".partial", ".manifest.json", WAKE_MOMENTS.completionSuffix]) {
|
|
133
|
+
if (await momentPathExists(path.join(base, `${candidate}${suffix}`), io))
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
return false; // Temporary metadata names are separately checked and exclusively created.
|
|
137
|
+
}
|
|
138
|
+
async function walk(directory, source, relative) {
|
|
139
|
+
// Linux's descriptor-relative paths pin ancestors against a concurrent rename/symlink swap.
|
|
140
|
+
const anchored = process.platform === "linux" ? `/proc/self/fd/${directory.fd}` : source;
|
|
141
|
+
const expected = await directory.stat({ bigint: true });
|
|
142
|
+
await checkSourceDirectory(directory, source, expected, io);
|
|
143
|
+
for await (const entry of await io.fs.opendir(anchored)) {
|
|
144
|
+
await checkSourceDirectory(directory, source, expected, io);
|
|
145
|
+
if (++entries > max)
|
|
146
|
+
throw new WakeMomentFault("snapshot_entry_limit");
|
|
147
|
+
const rel = relative ? `${relative}/${entry.name}` : entry.name;
|
|
148
|
+
const from = path.join(anchored, entry.name), to = path.join(partial, rel);
|
|
149
|
+
const stat = await io.fs.lstat(from, { bigint: true }), sourceIdentity = identity(stat);
|
|
150
|
+
await checkSourceDirectory(directory, source, expected, io);
|
|
151
|
+
if (stat.isDirectory()) {
|
|
152
|
+
const child = await openSourceDirectory(from, io, stat);
|
|
153
|
+
try {
|
|
154
|
+
await io.fs.mkdir(to, { mode: 0o700 });
|
|
155
|
+
manifest.entries[rel] = { type: "directory", mode: Number(stat.mode), size: String(stat.size), source: sourceIdentity };
|
|
156
|
+
await walk(child, from, rel);
|
|
157
|
+
await syncMomentDirectory(to, io);
|
|
158
|
+
}
|
|
159
|
+
finally {
|
|
160
|
+
await child.close();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
else if (stat.isSymbolicLink()) {
|
|
164
|
+
const target = await io.fs.readlink(from);
|
|
165
|
+
await io.fs.symlink(target, to);
|
|
166
|
+
manifest.entries[rel] = { type: "symlink", mode: Number(stat.mode), size: String(stat.size), source: sourceIdentity, target };
|
|
167
|
+
}
|
|
168
|
+
else if (stat.isFile()) {
|
|
169
|
+
const sourceFile = await io.fs.open(from, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
|
|
170
|
+
try {
|
|
171
|
+
if (!sameSnapshotSource(sourceIdentity, identity(await sourceFile.stat({ bigint: true }))))
|
|
172
|
+
throw new WakeMomentFault("source_changed");
|
|
173
|
+
await checkSourceDirectory(directory, source, expected, io);
|
|
174
|
+
const prior = previous && Object.hasOwn(previous.entries, rel) ? previous.entries[rel] : undefined;
|
|
175
|
+
if (prior?.type === "file" && prior.source && sameSnapshotSource(prior.source, sourceIdentity)) {
|
|
176
|
+
const old = path.join(base, previous.snapshot, rel);
|
|
177
|
+
await assertNoSymlinkComponents(path.dirname(old), io.fs.lstat);
|
|
178
|
+
if (!(await io.fs.lstat(old)).isFile())
|
|
179
|
+
throw new WakeMomentFault("invalid_link_base");
|
|
180
|
+
await io.fs.link(old, to);
|
|
181
|
+
snapshot.linked++;
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
await copyFile(sourceFile, to, stat, io);
|
|
185
|
+
snapshot.copied++;
|
|
186
|
+
}
|
|
187
|
+
if (!sameSnapshotSource(sourceIdentity, identity(await sourceFile.stat({ bigint: true }))))
|
|
188
|
+
throw new WakeMomentFault("source_changed");
|
|
189
|
+
manifest.entries[rel] = { type: "file", mode: Number(stat.mode), size: String(stat.size), source: sourceIdentity };
|
|
190
|
+
snapshot.files++;
|
|
191
|
+
}
|
|
192
|
+
finally {
|
|
193
|
+
await sourceFile.close();
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
else
|
|
197
|
+
snapshot.skipped++;
|
|
198
|
+
}
|
|
199
|
+
await checkSourceDirectory(directory, source, expected, io);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
async function openSourceDirectory(source, io, before) {
|
|
203
|
+
if (process.platform !== "linux" || !source.startsWith("/proc/self/fd/"))
|
|
204
|
+
await assertNoSymlinkComponents(source, io.fs.lstat);
|
|
205
|
+
before ??= await io.fs.lstat(source, { bigint: true });
|
|
206
|
+
const fd = await io.fs.open(source, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
|
|
207
|
+
try {
|
|
208
|
+
await checkSourceDirectory(fd, source, before, io);
|
|
209
|
+
return fd;
|
|
210
|
+
}
|
|
211
|
+
catch (error) {
|
|
212
|
+
await fd.close();
|
|
213
|
+
throw error;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
async function checkSourceDirectory(directory, source, before, io) {
|
|
217
|
+
const opened = await directory.stat({ bigint: true }), current = await io.fs.lstat(source, { bigint: true });
|
|
218
|
+
if (![before, opened, current].every((stat) => stat.isDirectory() && stat.dev === before.dev && stat.ino === before.ino)) {
|
|
219
|
+
throw new WakeMomentFault("source_changed");
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
async function copyFile(source, target, stat, io) {
|
|
223
|
+
if (stat.size > BigInt(Number.MAX_SAFE_INTEGER))
|
|
224
|
+
throw new WakeMomentFault("source_size_limit");
|
|
225
|
+
const output = await io.fs.open(target, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600);
|
|
226
|
+
try {
|
|
227
|
+
const buffer = Buffer.alloc(1024 * 1024);
|
|
228
|
+
let position = 0;
|
|
229
|
+
while (position < Number(stat.size)) {
|
|
230
|
+
const { bytesRead } = await source.read(buffer, 0, Math.min(buffer.length, Number(stat.size) - position), position);
|
|
231
|
+
if (!bytesRead)
|
|
232
|
+
throw new WakeMomentFault("source_changed");
|
|
233
|
+
let written = 0;
|
|
234
|
+
while (written < bytesRead) {
|
|
235
|
+
const result = await output.write(buffer, written, bytesRead - written, position + written);
|
|
236
|
+
if (!result.bytesWritten)
|
|
237
|
+
throw new WakeMomentFault("short_write");
|
|
238
|
+
written += result.bytesWritten;
|
|
239
|
+
}
|
|
240
|
+
position += bytesRead;
|
|
241
|
+
}
|
|
242
|
+
await output.chmod(Number(stat.mode) & 0o777);
|
|
243
|
+
await output.sync();
|
|
244
|
+
}
|
|
245
|
+
finally {
|
|
246
|
+
await output.close();
|
|
247
|
+
}
|
|
248
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noopolis/daimon",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Noopolis native per-agent runtime harness built on Pi.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
],
|
|
34
34
|
"repository": {
|
|
35
35
|
"type": "git",
|
|
36
|
-
"url": "git+ssh://git@github.com/noopolis/daimon.git"
|
|
36
|
+
"url": "git+ssh://git@github.com/noopolis/daimon-harness.git"
|
|
37
37
|
},
|
|
38
38
|
"publishConfig": {
|
|
39
39
|
"access": "public"
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"clean": "rm -rf dist",
|
|
45
45
|
"prepack": "npm run build",
|
|
46
46
|
"prepublishOnly": "npm run typecheck && npm test",
|
|
47
|
-
"typecheck": "tsc --project tsconfig.json --noEmit && tsc --project scripts/tsconfig.json --noEmit",
|
|
47
|
+
"typecheck": "tsc --project tsconfig.json --noEmit && tsc --project scripts/tsconfig.json --noEmit && tsc --project .github/scripts/ci/tsconfig.json",
|
|
48
48
|
"verify:contract-manifest": "node --import tsx scripts/emitRuntimeContractManifest.ts --check",
|
|
49
49
|
"verify:native": "node --experimental-strip-types src/runtime/native/verifyArtifacts.ts",
|
|
50
50
|
"verify:production-closure": "node --experimental-strip-types scripts/verifyProductionClosure.ts",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"@earendil-works/pi-ai": "^0.79.10",
|
|
66
66
|
"@earendil-works/pi-coding-agent": "^0.79.10",
|
|
67
67
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
68
|
-
"@noopolis/mneme": "^0.1.
|
|
68
|
+
"@noopolis/mneme": "^0.1.3",
|
|
69
69
|
"ajv": "^8.17.1",
|
|
70
70
|
"zod": "^4.4.3"
|
|
71
71
|
},
|