@plurnk/plurnk-service 1.14.2 → 1.16.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/.env.defaults +2 -2
- package/SPEC.md +243 -173
- package/digest-sql/curation/curation.sql +1 -1
- package/dist/build-info.json +1 -1
- package/dist/content/byte-view.d.ts +14 -0
- package/dist/content/byte-view.d.ts.map +1 -0
- package/dist/content/byte-view.js +33 -0
- package/dist/content/byte-view.js.map +1 -0
- package/dist/content/edit-receipt.d.ts.map +1 -1
- package/dist/content/edit-receipt.js +12 -1
- package/dist/content/edit-receipt.js.map +1 -1
- package/dist/content/line-marker.d.ts +2 -1
- package/dist/content/line-marker.d.ts.map +1 -1
- package/dist/content/line-marker.js +1 -0
- package/dist/content/line-marker.js.map +1 -1
- package/dist/content/matcher.d.ts +1 -0
- package/dist/content/matcher.d.ts.map +1 -1
- package/dist/content/matcher.js +1 -0
- package/dist/content/matcher.js.map +1 -1
- package/dist/content/read-projector.d.ts +4 -1
- package/dist/content/read-projector.d.ts.map +1 -1
- package/dist/content/read-projector.js +80 -3
- package/dist/content/read-projector.js.map +1 -1
- package/dist/core/AdmittedTurnExecutor.d.ts +43 -0
- package/dist/core/AdmittedTurnExecutor.d.ts.map +1 -0
- package/dist/core/AdmittedTurnExecutor.js +245 -0
- package/dist/core/AdmittedTurnExecutor.js.map +1 -0
- package/dist/core/BareBatchRunner.d.ts +26 -0
- package/dist/core/BareBatchRunner.d.ts.map +1 -0
- package/dist/core/BareBatchRunner.js +104 -0
- package/dist/core/BareBatchRunner.js.map +1 -0
- package/dist/core/BudgetReadout.d.ts +1 -1
- package/dist/core/BudgetReadout.d.ts.map +1 -1
- package/dist/core/BudgetReadout.js +42 -47
- package/dist/core/BudgetReadout.js.map +1 -1
- package/dist/core/CapabilityResolver.d.ts +2 -1
- package/dist/core/CapabilityResolver.d.ts.map +1 -1
- package/dist/core/CapabilityResolver.js +8 -9
- package/dist/core/CapabilityResolver.js.map +1 -1
- package/dist/core/ChannelWrite.d.ts +1 -1
- package/dist/core/ChannelWrite.d.ts.map +1 -1
- package/dist/core/DataStatementRunner.d.ts +35 -0
- package/dist/core/DataStatementRunner.d.ts.map +1 -0
- package/dist/core/DataStatementRunner.js +252 -0
- package/dist/core/DataStatementRunner.js.map +1 -0
- package/dist/core/Dispatcher.d.ts +8 -3
- package/dist/core/Dispatcher.d.ts.map +1 -1
- package/dist/core/Dispatcher.js +88 -738
- package/dist/core/Dispatcher.js.map +1 -1
- package/dist/core/EditMutations.d.ts +39 -0
- package/dist/core/EditMutations.d.ts.map +1 -0
- package/dist/core/EditMutations.js +418 -0
- package/dist/core/EditMutations.js.map +1 -0
- package/dist/core/Engine.d.ts +2 -23
- package/dist/core/Engine.d.ts.map +1 -1
- package/dist/core/Engine.js +18 -240
- package/dist/core/Engine.js.map +1 -1
- package/dist/core/Engine.sql +24 -23
- package/dist/core/KillHandler.d.ts +32 -0
- package/dist/core/KillHandler.d.ts.map +1 -0
- package/dist/core/KillHandler.js +179 -0
- package/dist/core/KillHandler.js.map +1 -0
- package/dist/core/LogVisibility.d.ts +1 -1
- package/dist/core/LogVisibility.d.ts.map +1 -1
- package/dist/core/LogVisibility.js +3 -4
- package/dist/core/LogVisibility.js.map +1 -1
- package/dist/core/LogWriter.d.ts +42 -0
- package/dist/core/LogWriter.d.ts.map +1 -0
- package/dist/core/LogWriter.js +136 -0
- package/dist/core/LogWriter.js.map +1 -0
- package/dist/core/LoopDriver.d.ts +46 -0
- package/dist/core/LoopDriver.d.ts.map +1 -0
- package/dist/core/LoopDriver.js +263 -0
- package/dist/core/LoopDriver.js.map +1 -0
- package/dist/core/LoopLifecycle.d.ts +2 -1
- package/dist/core/LoopLifecycle.d.ts.map +1 -1
- package/dist/core/MembershipMaterialization.d.ts +7 -0
- package/dist/core/MembershipMaterialization.d.ts.map +1 -0
- package/dist/core/MembershipMaterialization.js +283 -0
- package/dist/core/MembershipMaterialization.js.map +1 -0
- package/dist/core/MutationEffects.d.ts +29 -0
- package/dist/core/MutationEffects.d.ts.map +1 -0
- package/dist/core/MutationEffects.js +318 -0
- package/dist/core/MutationEffects.js.map +1 -0
- package/dist/core/OverflowTurn.d.ts +4 -4
- package/dist/core/OverflowTurn.d.ts.map +1 -1
- package/dist/core/OverflowTurn.js +6 -7
- package/dist/core/OverflowTurn.js.map +1 -1
- package/dist/core/PacketBuilder.d.ts.map +1 -1
- package/dist/core/PacketBuilder.js +31 -9
- package/dist/core/PacketBuilder.js.map +1 -1
- package/dist/core/ResourceMutations.d.ts +12 -36
- package/dist/core/ResourceMutations.d.ts.map +1 -1
- package/dist/core/ResourceMutations.js +27 -1351
- package/dist/core/ResourceMutations.js.map +1 -1
- package/dist/core/ResourceSelector.d.ts +21 -0
- package/dist/core/ResourceSelector.d.ts.map +1 -0
- package/dist/core/ResourceSelector.js +233 -0
- package/dist/core/ResourceSelector.js.map +1 -0
- package/dist/core/ResourceTransfers.d.ts +55 -0
- package/dist/core/ResourceTransfers.d.ts.map +1 -0
- package/dist/core/ResourceTransfers.js +525 -0
- package/dist/core/ResourceTransfers.js.map +1 -0
- package/dist/core/SchemeRegistry.js +2 -2
- package/dist/core/SchemeRegistry.js.map +1 -1
- package/dist/core/SendBroadcastHandler.d.ts +40 -0
- package/dist/core/SendBroadcastHandler.d.ts.map +1 -0
- package/dist/core/SendBroadcastHandler.js +159 -0
- package/dist/core/SendBroadcastHandler.js.map +1 -0
- package/dist/core/StoredPacket.d.ts +11 -0
- package/dist/core/StoredPacket.d.ts.map +1 -1
- package/dist/core/StoredPacket.js +22 -1
- package/dist/core/StoredPacket.js.map +1 -1
- package/dist/core/StrikeRail.d.ts.map +1 -1
- package/dist/core/StrikeRail.js +19 -9
- package/dist/core/StrikeRail.js.map +1 -1
- package/dist/core/TokenCalibration.d.ts +16 -0
- package/dist/core/TokenCalibration.d.ts.map +1 -0
- package/dist/core/TokenCalibration.js +35 -0
- package/dist/core/TokenCalibration.js.map +1 -0
- package/dist/core/ToolResources.d.ts.map +1 -1
- package/dist/core/ToolResources.js +15 -12
- package/dist/core/ToolResources.js.map +1 -1
- package/dist/core/TurnMaterialization.d.ts +37 -0
- package/dist/core/TurnMaterialization.d.ts.map +1 -0
- package/dist/core/TurnMaterialization.js +296 -0
- package/dist/core/TurnMaterialization.js.map +1 -0
- package/dist/core/TurnOps.d.ts.map +1 -1
- package/dist/core/TurnOps.js +6 -8
- package/dist/core/TurnOps.js.map +1 -1
- package/dist/core/TurnRunner.d.ts +15 -27
- package/dist/core/TurnRunner.d.ts.map +1 -1
- package/dist/core/TurnRunner.js +76 -670
- package/dist/core/TurnRunner.js.map +1 -1
- package/dist/core/WorkerControlHandler.d.ts +15 -0
- package/dist/core/WorkerControlHandler.d.ts.map +1 -0
- package/dist/core/WorkerControlHandler.js +89 -0
- package/dist/core/WorkerControlHandler.js.map +1 -0
- package/dist/core/attachments.d.ts +14 -0
- package/dist/core/attachments.d.ts.map +1 -0
- package/dist/core/attachments.js +18 -0
- package/dist/core/attachments.js.map +1 -0
- package/dist/core/fork.d.ts.map +1 -1
- package/dist/core/fork.js +0 -4
- package/dist/core/fork.js.map +1 -1
- package/dist/core/fork.sql +5 -16
- package/dist/core/git-membership.d.ts +15 -0
- package/dist/core/git-membership.d.ts.map +1 -1
- package/dist/core/git-membership.js +4 -273
- package/dist/core/git-membership.js.map +1 -1
- package/dist/core/git-state.d.ts +2 -1
- package/dist/core/git-state.d.ts.map +1 -1
- package/dist/core/mutation-types.d.ts +102 -0
- package/dist/core/mutation-types.d.ts.map +1 -0
- package/dist/core/mutation-types.js +2 -0
- package/dist/core/mutation-types.js.map +1 -0
- package/dist/core/operation-target-groups.js +1 -1
- package/dist/core/operation-target-groups.js.map +1 -1
- package/dist/core/packet-wire.d.ts +7 -6
- package/dist/core/packet-wire.d.ts.map +1 -1
- package/dist/core/packet-wire.js +96 -68
- package/dist/core/packet-wire.js.map +1 -1
- package/dist/core/plurnk-uri.d.ts +0 -1
- package/dist/core/plurnk-uri.d.ts.map +1 -1
- package/dist/core/plurnk-uri.js +1 -1
- package/dist/core/plurnk-uri.js.map +1 -1
- package/dist/core/statement-primary.d.ts +4 -0
- package/dist/core/statement-primary.d.ts.map +1 -0
- package/dist/core/statement-primary.js +3 -0
- package/dist/core/statement-primary.js.map +1 -0
- package/dist/core/teaching-corpus.d.ts +0 -1
- package/dist/core/teaching-corpus.d.ts.map +1 -1
- package/dist/core/teaching-corpus.js +0 -9
- package/dist/core/teaching-corpus.js.map +1 -1
- package/dist/core/turn-scheduler.js +3 -3
- package/dist/core/turn-scheduler.js.map +1 -1
- package/dist/core/turn-signals.d.ts +15 -0
- package/dist/core/turn-signals.d.ts.map +1 -0
- package/dist/core/turn-signals.js +19 -0
- package/dist/core/turn-signals.js.map +1 -0
- package/dist/core/worker-settings.d.ts +0 -1
- package/dist/core/worker-settings.d.ts.map +1 -1
- package/dist/core/worker-settings.js +1 -1
- package/dist/core/worker-settings.js.map +1 -1
- package/dist/digest/Digest.d.ts +3 -16
- package/dist/digest/Digest.d.ts.map +1 -1
- package/dist/digest/Digest.js +10 -958
- package/dist/digest/Digest.js.map +1 -1
- package/dist/digest/DigestRender.d.ts +12 -0
- package/dist/digest/DigestRender.d.ts.map +1 -0
- package/dist/digest/DigestRender.js +641 -0
- package/dist/digest/DigestRender.js.map +1 -0
- package/dist/digest/DigestRequiem.d.ts +13 -0
- package/dist/digest/DigestRequiem.d.ts.map +1 -0
- package/dist/digest/DigestRequiem.js +332 -0
- package/dist/digest/DigestRequiem.js.map +1 -0
- package/dist/digest/digest-rows.d.ts +303 -0
- package/dist/digest/digest-rows.d.ts.map +1 -0
- package/dist/digest/digest-rows.js +2 -0
- package/dist/digest/digest-rows.js.map +1 -0
- package/dist/digest/digest.sql +1 -7
- package/dist/observe/api.d.ts +0 -2
- package/dist/observe/api.d.ts.map +1 -1
- package/dist/observe/api.js +2 -2
- package/dist/observe/api.js.map +1 -1
- package/dist/observe/metrics.d.ts +0 -1
- package/dist/observe/metrics.d.ts.map +1 -1
- package/dist/observe/metrics.js +0 -1
- package/dist/observe/metrics.js.map +1 -1
- package/dist/schemes/Exec.d.ts +4 -1
- package/dist/schemes/Exec.d.ts.map +1 -1
- package/dist/schemes/Exec.js +89 -48
- package/dist/schemes/Exec.js.map +1 -1
- package/dist/schemes/ExecOutputScheme.d.ts +2 -1
- package/dist/schemes/ExecOutputScheme.d.ts.map +1 -1
- package/dist/schemes/ExecOutputScheme.js +3 -3
- package/dist/schemes/ExecOutputScheme.js.map +1 -1
- package/dist/schemes/File.d.ts +4 -1
- package/dist/schemes/File.d.ts.map +1 -1
- package/dist/schemes/File.js +100 -13
- package/dist/schemes/File.js.map +1 -1
- package/dist/schemes/Log.d.ts +4 -5
- package/dist/schemes/Log.d.ts.map +1 -1
- package/dist/schemes/Log.js +26 -118
- package/dist/schemes/Log.js.map +1 -1
- package/dist/schemes/Log.sql +1 -66
- package/dist/schemes/Prompt.js +1 -1
- package/dist/schemes/Prompt.js.map +1 -1
- package/dist/schemes/Worker.d.ts.map +1 -1
- package/dist/schemes/Worker.js +1 -13
- package/dist/schemes/Worker.js.map +1 -1
- package/dist/schemes/_entry-crud.d.ts +3 -1
- package/dist/schemes/_entry-crud.d.ts.map +1 -1
- package/dist/schemes/_entry-crud.js +18 -3
- package/dist/schemes/_entry-crud.js.map +1 -1
- package/dist/schemes/_entry-find.d.ts +4 -2
- package/dist/schemes/_entry-find.d.ts.map +1 -1
- package/dist/schemes/_entry-find.js +79 -10
- package/dist/schemes/_entry-find.js.map +1 -1
- package/dist/schemes/_entry-manifest.d.ts +1 -2
- package/dist/schemes/_entry-manifest.d.ts.map +1 -1
- package/dist/schemes/_entry-ops.d.ts +2 -1
- package/dist/schemes/_entry-ops.d.ts.map +1 -1
- package/dist/schemes/_entry-ops.js +20 -2
- package/dist/schemes/_entry-ops.js.map +1 -1
- package/dist/schemes/_entry-semantic.d.ts +1 -0
- package/dist/schemes/_entry-semantic.d.ts.map +1 -1
- package/dist/schemes/_entry-semantic.js +3 -0
- package/dist/schemes/_entry-semantic.js.map +1 -1
- package/dist/schemes/_entry-semantic.sql +2 -2
- package/dist/schemes/_entry-send.d.ts +0 -1
- package/dist/schemes/_entry-send.d.ts.map +1 -1
- package/dist/schemes/_entry-send.js +5 -80
- package/dist/schemes/_entry-send.js.map +1 -1
- package/dist/schemes/exec-runtime.d.ts +7 -0
- package/dist/schemes/exec-runtime.d.ts.map +1 -0
- package/dist/schemes/exec-runtime.js +2 -0
- package/dist/schemes/exec-runtime.js.map +1 -0
- package/dist/server/ClientReads.d.ts +34 -0
- package/dist/server/ClientReads.d.ts.map +1 -0
- package/dist/server/ClientReads.js +210 -0
- package/dist/server/ClientReads.js.map +1 -0
- package/dist/server/Daemon.d.ts +12 -22
- package/dist/server/Daemon.d.ts.map +1 -1
- package/dist/server/Daemon.js +31 -362
- package/dist/server/Daemon.js.map +1 -1
- package/dist/server/DaemonModule.d.ts +6 -5
- package/dist/server/DaemonModule.d.ts.map +1 -1
- package/dist/server/DrainSupervisor.d.ts +3 -2
- package/dist/server/DrainSupervisor.d.ts.map +1 -1
- package/dist/server/DrainSupervisor.js +7 -3
- package/dist/server/DrainSupervisor.js.map +1 -1
- package/dist/server/Functionality.d.ts +0 -12
- package/dist/server/Functionality.d.ts.map +1 -1
- package/dist/server/Functionality.js.map +1 -1
- package/dist/server/FunctionalityManager.d.ts +0 -1
- package/dist/server/FunctionalityManager.d.ts.map +1 -1
- package/dist/server/FunctionalityManager.js +3 -3
- package/dist/server/FunctionalityManager.js.map +1 -1
- package/dist/server/MembersFunctionality.d.ts +2 -13
- package/dist/server/MembersFunctionality.d.ts.map +1 -1
- package/dist/server/MembersFunctionality.js +4 -4
- package/dist/server/MembersFunctionality.js.map +1 -1
- package/dist/server/SkillsFunctionality.d.ts +1 -7
- package/dist/server/SkillsFunctionality.d.ts.map +1 -1
- package/dist/server/SkillsFunctionality.js +3 -3
- package/dist/server/SkillsFunctionality.js.map +1 -1
- package/dist/server/WorkerModelResolver.d.ts +17 -0
- package/dist/server/WorkerModelResolver.d.ts.map +1 -0
- package/dist/server/WorkerModelResolver.js +166 -0
- package/dist/server/WorkerModelResolver.js.map +1 -0
- package/dist/server/daemon-results.d.ts +5 -0
- package/dist/server/daemon-results.d.ts.map +1 -0
- package/dist/server/daemon-results.js +7 -0
- package/dist/server/daemon-results.js.map +1 -0
- package/dist/server/dispatch-as-plurnk.d.ts.map +1 -1
- package/dist/server/dispatch-as-plurnk.js +4 -6
- package/dist/server/dispatch-as-plurnk.js.map +1 -1
- package/dist/server/logEntry.d.ts +0 -1
- package/dist/server/logEntry.d.ts.map +1 -1
- package/dist/server/logEntry.js +1 -13
- package/dist/server/logEntry.js.map +1 -1
- package/dist/server/logEntry.sql +1 -5
- package/dist/server/loopDocs.d.ts.map +1 -1
- package/dist/server/loopDocs.js +11 -2
- package/dist/server/loopDocs.js.map +1 -1
- package/migrations/001_schema.sql +30 -347
- package/package.json +30 -30
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
2
|
+
import Results from "./results.js";
|
|
3
|
+
import { LOOP_TIMEOUT_REASON } from "./TurnRunner.js";
|
|
4
|
+
import { observed } from "../observe/spans.js";
|
|
5
|
+
const readMaxStrikes = () => {
|
|
6
|
+
const raw = process.env.PLURNK_SERVICE_MAX_STRIKES;
|
|
7
|
+
if (raw === undefined || raw.length === 0)
|
|
8
|
+
return DEFAULT_MAX_STRIKES;
|
|
9
|
+
const n = Number.parseInt(raw, 10);
|
|
10
|
+
if (!Number.isFinite(n) || n < 0)
|
|
11
|
+
return DEFAULT_MAX_STRIKES;
|
|
12
|
+
return n;
|
|
13
|
+
};
|
|
14
|
+
const DEFAULT_MIN_CYCLES = 3;
|
|
15
|
+
const DEFAULT_MAX_CYCLE_PERIOD = 4;
|
|
16
|
+
const readPositiveInt = (envVar, fallback) => {
|
|
17
|
+
const raw = process.env[envVar];
|
|
18
|
+
if (raw === undefined || raw.length === 0)
|
|
19
|
+
return fallback;
|
|
20
|
+
const n = Number.parseInt(raw, 10);
|
|
21
|
+
if (!Number.isFinite(n) || n < 1)
|
|
22
|
+
return fallback;
|
|
23
|
+
return n;
|
|
24
|
+
};
|
|
25
|
+
const readLoopTimeoutMs = () => readPositiveInt("PLURNK_SERVICE_LOOP_TIMEOUT", DEFAULT_LOOP_TIMEOUT_MS);
|
|
26
|
+
const DEFAULT_MAX_STRIKES = 3;
|
|
27
|
+
// {§operator-config-loop-timeout} — the loop's wall-clock budget (PLURNK_SERVICE_LOOP_TIMEOUT).
|
|
28
|
+
const DEFAULT_LOOP_TIMEOUT_MS = 86400000;
|
|
29
|
+
export default class LoopDriver {
|
|
30
|
+
#loopAborts;
|
|
31
|
+
#db;
|
|
32
|
+
#lifecycle;
|
|
33
|
+
#schemes;
|
|
34
|
+
#notices;
|
|
35
|
+
#strikes;
|
|
36
|
+
#acquireWorkspaceTurn;
|
|
37
|
+
#workspaceTurnStarting;
|
|
38
|
+
#runTurn;
|
|
39
|
+
constructor({ loopAborts, db, lifecycle, schemes, notices, strikes, acquireWorkspaceTurn, workspaceTurnStarting, runTurn }) {
|
|
40
|
+
this.#loopAborts = loopAborts;
|
|
41
|
+
this.#db = db;
|
|
42
|
+
this.#lifecycle = lifecycle;
|
|
43
|
+
this.#schemes = schemes;
|
|
44
|
+
this.#notices = notices;
|
|
45
|
+
this.#strikes = strikes;
|
|
46
|
+
this.#acquireWorkspaceTurn = acquireWorkspaceTurn;
|
|
47
|
+
this.#workspaceTurnStarting = workspaceTurnStarting;
|
|
48
|
+
this.#runTurn = runTurn;
|
|
49
|
+
}
|
|
50
|
+
async runLoop({ provider, childProvider = provider, messages, recap = "", workspaceId, workerId, loopId, maxTurns = 50, maxStrikes = readMaxStrikes(), minCycles = readPositiveInt("PLURNK_SERVICE_MIN_CYCLES", DEFAULT_MIN_CYCLES), maxCyclePeriod = readPositiveInt("PLURNK_SERVICE_MAX_CYCLE_PERIOD", DEFAULT_MAX_CYCLE_PERIOD), signal, onDispatch, onSettled }) {
|
|
51
|
+
// A 202 park suspends this durable loop and a later wake re-enters runLoop.
|
|
52
|
+
// Its ceiling therefore counts every prior turn, not merely this process-local
|
|
53
|
+
// execution segment.
|
|
54
|
+
const turnIds = await this.#lifecycle.turnIds(loopId);
|
|
55
|
+
let modelTurnCount = await this.#lifecycle.modelTurnCount(loopId);
|
|
56
|
+
let invalidEmissionRecoveryEntryId = null;
|
|
57
|
+
// Per-loop AbortController for scheme-side cancellation propagation.
|
|
58
|
+
// Chained from the caller's `signal` so an external abort cascades.
|
|
59
|
+
const loopAbort = new AbortController();
|
|
60
|
+
if (signal !== undefined) {
|
|
61
|
+
if (signal.aborted)
|
|
62
|
+
loopAbort.abort(signal.reason);
|
|
63
|
+
else
|
|
64
|
+
signal.addEventListener("abort", () => loopAbort.abort(signal.reason), { once: true });
|
|
65
|
+
}
|
|
66
|
+
this.#loopAborts.set(loopId, loopAbort);
|
|
67
|
+
// {§operator-config-loop-timeout} — the wall-clock budget. Expiry aborts the loop signal, so a
|
|
68
|
+
// mid-flight provider call (generate rides this signal) and in-flight spawns tear down; the
|
|
69
|
+
// loop terminates 504 (kin to the exec <T> reap's 504, {§exec-timeout}) — a legible engine
|
|
70
|
+
// terminal, never an outside kill. unref'd: the wall never holds the process open.
|
|
71
|
+
const wall = setTimeout(() => loopAbort.abort(LOOP_TIMEOUT_REASON), readLoopTimeoutMs());
|
|
72
|
+
wall.unref();
|
|
73
|
+
const timedOut = () => loopAbort.signal.aborted && loopAbort.signal.reason === LOOP_TIMEOUT_REASON;
|
|
74
|
+
const ruleTimeout = async () => {
|
|
75
|
+
const failure = Results.failure("engine:rails", "loop-timeout", 504, `The loop exceeded its wall-clock deadline after ${modelTurnCount} model turns.`, {}, {
|
|
76
|
+
turns: modelTurnCount,
|
|
77
|
+
stage: "loop",
|
|
78
|
+
retryable: false
|
|
79
|
+
});
|
|
80
|
+
const result = await this.#lifecycle.finish(loopId, failure);
|
|
81
|
+
if (result === null)
|
|
82
|
+
throw new Error(`loop ${loopId} became terminal before timeout settlement`);
|
|
83
|
+
cleanup("forceful", "loop_timeout");
|
|
84
|
+
return { turnIds, result, hitMaxTurns: false, reason: "loop_timeout" };
|
|
85
|
+
};
|
|
86
|
+
// Cleanup splits by termination kind:
|
|
87
|
+
// - "graceful" (SEND signal 202 Accepted): in-flight streaming-scheme spawns
|
|
88
|
+
// are ALLOWED to outlive the loop — they complete naturally, write final
|
|
89
|
+
// channel state, and wake-on-completion (E.4) opens a fresh loop. 202 is
|
|
90
|
+
// the only terminal that means "keep my async work."
|
|
91
|
+
// - "forceful" (SEND signal 200 done, max_turns, strike, cancel, context-envelope rejection, 4xx/5xx):
|
|
92
|
+
// fire the loop-level abort so leftover spawns tear down. "Done" reaps.
|
|
93
|
+
const cleanup = (kind, reason) => {
|
|
94
|
+
clearTimeout(wall);
|
|
95
|
+
if (kind === "forceful" && !loopAbort.signal.aborted) {
|
|
96
|
+
loopAbort.abort(reason ?? "loop_forceful_termination");
|
|
97
|
+
}
|
|
98
|
+
this.#loopAborts.delete(loopId);
|
|
99
|
+
this.#strikes.delete(loopId);
|
|
100
|
+
this.#notices.delete(loopId);
|
|
101
|
+
};
|
|
102
|
+
while (true) {
|
|
103
|
+
const row = await this.#db.engine_loop_status.get({ loop_id: loopId });
|
|
104
|
+
if (row === undefined)
|
|
105
|
+
throw new Error(`Engine.runLoop: loop ${loopId} not found`);
|
|
106
|
+
if (row.status === 100) {
|
|
107
|
+
// NOT a terminal — a wake re-queued this loop while its own live drain was
|
|
108
|
+
// between turns (a child concluded in the gap between our 202 write and this
|
|
109
|
+
// check, {§worker-lifecycle-wake-requeue-not-terminal}). The wake's intent is KEEP
|
|
110
|
+
// RUNNING: re-claim atomically and continue — the injected prompt is already
|
|
111
|
+
// this loop's next turn. Returning it as "external" broadcast a QUEUED loop
|
|
112
|
+
// as a terminal result with status 100 — the delegation-policy race.
|
|
113
|
+
await this.#db.engine_reclaim_queued_loop.run({ loop_id: loopId });
|
|
114
|
+
continue; // claimed (or a racer flipped it first — the re-read decides)
|
|
115
|
+
}
|
|
116
|
+
if (row.status !== 102) {
|
|
117
|
+
// Only 202 (Accepted) lets spawns outlive — it IS the async wake
|
|
118
|
+
// contract (E.4). Every other terminal, 200 included, reaps: "done"
|
|
119
|
+
// must not leak running execs. Trust the code's declared intent.
|
|
120
|
+
cleanup(row.status === 202 ? "graceful" : "forceful", `loop_terminal_${row.status}`);
|
|
121
|
+
if (row.status === 202) {
|
|
122
|
+
return { turnIds, result: { status: 202 }, hitMaxTurns: false, reason: "external" };
|
|
123
|
+
}
|
|
124
|
+
const result = await this.#lifecycle.result(loopId);
|
|
125
|
+
if (result === null) {
|
|
126
|
+
throw new Error(`terminal loop ${loopId} status ${row.status} has no operation result`);
|
|
127
|
+
}
|
|
128
|
+
return { turnIds, result, hitMaxTurns: false, reason: "external" };
|
|
129
|
+
}
|
|
130
|
+
// Durable disposition outranks a later process-local cancellation observation.
|
|
131
|
+
// SEND may commit 202 immediately before daemon shutdown aborts this drain; reading
|
|
132
|
+
// the abort first launders that lawful park into 499 under load. Only a still-running
|
|
133
|
+
// 102 loop can be cancelled or time out at this boundary.
|
|
134
|
+
if (timedOut())
|
|
135
|
+
return await ruleTimeout();
|
|
136
|
+
signal?.throwIfAborted();
|
|
137
|
+
if (maxTurns >= 0 && modelTurnCount >= maxTurns) {
|
|
138
|
+
const failure = Results.failure("engine:rails", "max-turns", 429, `The configured turn ceiling (${maxTurns}) is exhausted.`, {}, {
|
|
139
|
+
maximumTurns: maxTurns,
|
|
140
|
+
stage: "loop",
|
|
141
|
+
retryable: false
|
|
142
|
+
});
|
|
143
|
+
const result = await this.#lifecycle.finish(loopId, failure);
|
|
144
|
+
if (result === null)
|
|
145
|
+
throw new Error(`loop ${loopId} became terminal before max-turn settlement`);
|
|
146
|
+
cleanup("forceful", "max_turns");
|
|
147
|
+
return { turnIds, result, hitMaxTurns: true, reason: "max_turns" };
|
|
148
|
+
}
|
|
149
|
+
const execHandler = this.#schemes.get("exec");
|
|
150
|
+
// {§exec-hold-until-concluded} — hold matching runtime/effect
|
|
151
|
+
// streams until conclusion or the fail-open cap, then resume the
|
|
152
|
+
// ordinary cycle without altering stream state.
|
|
153
|
+
const holdSet = new Set((process.env.PLURNK_SERVICE_EXEC_HOLD ?? "").split(",").map((x) => x.trim()).filter((x) => x.length > 0));
|
|
154
|
+
const holdCapMs = Number(process.env.PLURNK_SERVICE_EXEC_HOLD_MS ?? "300000");
|
|
155
|
+
if (holdSet.size > 0 && holdCapMs > 0 && execHandler?.hasActiveHoldSpawns !== undefined) {
|
|
156
|
+
const holdStart = Date.now();
|
|
157
|
+
while (execHandler.hasActiveHoldSpawns(workerId, holdSet) && Date.now() - holdStart < holdCapMs) {
|
|
158
|
+
await delay(150, undefined, { signal });
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
let turn;
|
|
162
|
+
const releaseWorkspace = await this.#acquireWorkspaceTurn(workspaceId, workerId);
|
|
163
|
+
try {
|
|
164
|
+
await this.#workspaceTurnStarting?.({ workspaceId, workerId, loopId });
|
|
165
|
+
turn = await observed(// {§observability-boundary}
|
|
166
|
+
"loop.turn", { workerId, "loop.id": loopId }, async (span) => {
|
|
167
|
+
const t = await this.#runTurn({
|
|
168
|
+
provider, childProvider, messages, recap, workspaceId, workerId, loopId, signal, onDispatch, onSettled,
|
|
169
|
+
turnNumber: modelTurnCount + 1, maxTurns,
|
|
170
|
+
invalidEmissionRecoveryEntryId
|
|
171
|
+
});
|
|
172
|
+
span.setAttribute("turn.id", t.turnId);
|
|
173
|
+
span.setAttribute("turn.producer", t.producer);
|
|
174
|
+
span.setAttribute("turn.kind", t.kind);
|
|
175
|
+
return t;
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
// The wall fired mid-turn — the abort tore the turn down (generate rides the loop
|
|
180
|
+
// signal); rule the legible 504, never a generic drain error.
|
|
181
|
+
if (timedOut())
|
|
182
|
+
return await ruleTimeout();
|
|
183
|
+
throw err;
|
|
184
|
+
}
|
|
185
|
+
finally {
|
|
186
|
+
releaseWorkspace();
|
|
187
|
+
}
|
|
188
|
+
turnIds.push(...turn.createdTurnIds);
|
|
189
|
+
// {§overflow-turn-only} — packetless kernel chronology is not a
|
|
190
|
+
// model attempt and never enters emission or strike accounting.
|
|
191
|
+
if (turn.kind === "overflow") {
|
|
192
|
+
if (turn.curationFailure !== undefined) {
|
|
193
|
+
const result = await this.#lifecycle.finish(loopId, turn.curationFailure);
|
|
194
|
+
if (result === null)
|
|
195
|
+
throw new Error(`loop ${loopId} became terminal before token-overflow settlement`);
|
|
196
|
+
cleanup("forceful", "token_budget_overflow");
|
|
197
|
+
return { turnIds, result, hitMaxTurns: false, reason: "token_budget" };
|
|
198
|
+
}
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
modelTurnCount++;
|
|
202
|
+
// {§engine-rails} Contract Strikes: every emission exhaustion is one
|
|
203
|
+
// frame-contract violation. The next turn is always informed (it carries
|
|
204
|
+
// the rejected emission), and the strike rail — not a bespoke terminal —
|
|
205
|
+
// decides how many consecutive violations the loop survives.
|
|
206
|
+
if (turn.emissionExhausted) {
|
|
207
|
+
if (turn.rejectedModelEntryId === undefined) {
|
|
208
|
+
throw new Error("an invalid-emission recovery requires its rejected emissionAttempt identity");
|
|
209
|
+
}
|
|
210
|
+
invalidEmissionRecoveryEntryId = turn.rejectedModelEntryId;
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
invalidEmissionRecoveryEntryId = null;
|
|
214
|
+
}
|
|
215
|
+
// {§provider-surface-capacity}: the provider rejected the changed request for capacity.
|
|
216
|
+
if (turn.capacityHardStop) {
|
|
217
|
+
if (turn.capacityFailure === undefined) {
|
|
218
|
+
throw new Error("a provider-capacity stop requires its exact failure");
|
|
219
|
+
}
|
|
220
|
+
const result = await this.#lifecycle.finish(loopId, turn.capacityFailure);
|
|
221
|
+
if (result === null)
|
|
222
|
+
throw new Error(`loop ${loopId} became terminal before provider-capacity settlement`);
|
|
223
|
+
cleanup("forceful", "provider_capacity");
|
|
224
|
+
return { turnIds, result, hitMaxTurns: false, reason: "provider_capacity" };
|
|
225
|
+
}
|
|
226
|
+
if (turn.providerParked) {
|
|
227
|
+
// {§provider-recovery} — the provider stayed unavailable past the recovery budget:
|
|
228
|
+
// the loop parks like a [202] wait, spawns outlive it, and the ordinary wake resumes it.
|
|
229
|
+
if (!await this.#lifecycle.park(loopId))
|
|
230
|
+
throw new Error(`loop ${loopId} could not park after provider recovery`);
|
|
231
|
+
cleanup("graceful", "provider_unavailable");
|
|
232
|
+
return { turnIds, result: { status: 202 }, hitMaxTurns: false, reason: "provider_unavailable" };
|
|
233
|
+
}
|
|
234
|
+
// {§engine-rails} — per-turn strike accounting (cycle detection,
|
|
235
|
+
// steer coupling, hard operation outcomes). StrikeRail owns the
|
|
236
|
+
// bookkeeping; runLoop owns abandonment.
|
|
237
|
+
const verdict = this.#strikes.assess(loopId, {
|
|
238
|
+
fingerprint: turn.fingerprint,
|
|
239
|
+
outcomes: turn.outcomes,
|
|
240
|
+
steerStruck: turn.steerStruck,
|
|
241
|
+
minCycles, maxCyclePeriod, maxStrikes
|
|
242
|
+
});
|
|
243
|
+
if (verdict.thresholdCrossed) {
|
|
244
|
+
// {§engine-rails} — the source on the crossing turn classifies
|
|
245
|
+
// the engine verdict: cycle-driven is 508; every other strike is 500.
|
|
246
|
+
const status = verdict.cycleDetected ? 508 : 500;
|
|
247
|
+
const failure = Results.failure("engine:rails", "strike-threshold", status, verdict.cycleDetected
|
|
248
|
+
? `The loop reached its strike threshold after ${modelTurnCount} model turns because its operation pattern repeated.`
|
|
249
|
+
: `The loop reached its strike threshold after ${modelTurnCount} model turns because consecutive turns failed.`, {}, {
|
|
250
|
+
turns: modelTurnCount,
|
|
251
|
+
stage: "loop",
|
|
252
|
+
retryable: false
|
|
253
|
+
});
|
|
254
|
+
const result = await this.#lifecycle.finish(loopId, failure);
|
|
255
|
+
if (result === null)
|
|
256
|
+
throw new Error(`loop ${loopId} became terminal before strike settlement`);
|
|
257
|
+
cleanup("forceful", "strike_threshold");
|
|
258
|
+
return { turnIds, result, hitMaxTurns: false, reason: "strike_threshold" };
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
//# sourceMappingURL=LoopDriver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LoopDriver.js","sourceRoot":"","sources":["../../src/core/LoopDriver.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Db } from "./Db.ts";
|
|
2
2
|
import { type SchemeResult } from "./results.ts";
|
|
3
|
-
|
|
3
|
+
interface CancelledLoop {
|
|
4
4
|
loopId: number;
|
|
5
5
|
workerId: number;
|
|
6
6
|
result: SchemeResult;
|
|
@@ -24,4 +24,5 @@ export default class LoopLifecycle {
|
|
|
24
24
|
modelTurnCount(loopId: number): Promise<number>;
|
|
25
25
|
cancelTree(workerId: number, reason: string, includeRoot: boolean): Promise<CancelledTree>;
|
|
26
26
|
}
|
|
27
|
+
export {};
|
|
27
28
|
//# sourceMappingURL=LoopLifecycle.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LoopLifecycle.d.ts","sourceRoot":"","sources":["../../src/core/LoopLifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAClC,OAAgB,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAG1D,
|
|
1
|
+
{"version":3,"file":"LoopLifecycle.d.ts","sourceRoot":"","sources":["../../src/core/LoopLifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAClC,OAAgB,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAG1D,UAAU,aAAa;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,YAAY,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC1B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,MAAM,CAAC,OAAO,OAAO,aAAa;;IAG9B,YAAY,EAAE,EAAE,EAAE,EAEjB;IAMD,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAQ3C;IAEK,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAI3C;IAEK,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAI3C;IAEK,MAAM,CACR,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,YAAY,EACpB,OAAO,GAAE;QAAE,YAAY,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAA;KAAO,GACjD,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAa9B;IAEK,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAM5C;IAEK,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAQzD;IAEK,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAK/C;IAEK,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMpD;IAEK,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,CAmC/F;CACJ"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { PlurnkSchemeContext } from "./scheme-types.ts";
|
|
2
|
+
import type { FsDivergence } from "./git-membership.ts";
|
|
3
|
+
export default class MembershipMaterialization {
|
|
4
|
+
#private;
|
|
5
|
+
static materializeMember(pathname: string, root: string, ctx: PlurnkSchemeContext, identities: Map<string, Promise<string>>): Promise<FsDivergence | null>;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=MembershipMaterialization.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MembershipMaterialization.d.ts","sourceRoot":"","sources":["../../src/core/MembershipMaterialization.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAI7D,OAAO,KAAK,EAAE,YAAY,EAA4C,MAAM,qBAAqB,CAAC;AAqClG,MAAM,CAAC,OAAO,OAAO,yBAAyB;;IAU1C,OAAa,iBAAiB,CAC1B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,mBAAmB,EACxB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,GACzC,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAqI9B;CAoKJ"}
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
// Materializing one tracked member from disk into its body channel, text or binary. Split out of GitMembership.
|
|
2
|
+
import { readFile, stat } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { MimetypeInputLimitError } from "@plurnk/plurnk-mimetypes";
|
|
5
|
+
import { MimetypeBinary } from "../content/index.js";
|
|
6
|
+
import Owner from "./Owner.js";
|
|
7
|
+
import EntryCrud from "../schemes/_entry-crud.js";
|
|
8
|
+
import FileMaterialization from "./file-materialization.js";
|
|
9
|
+
const ABSENT_SIG = "absent";
|
|
10
|
+
const sourceProjectionFrom = (encoded) => {
|
|
11
|
+
const attributes = JSON.parse(encoded);
|
|
12
|
+
if (attributes === null || typeof attributes !== "object" || Array.isArray(attributes)) {
|
|
13
|
+
throw new TypeError("GitMembership: entry attributes must be a JSON object");
|
|
14
|
+
}
|
|
15
|
+
const candidate = attributes.sourceProjection;
|
|
16
|
+
if (candidate === undefined)
|
|
17
|
+
return null;
|
|
18
|
+
if (candidate === null || typeof candidate !== "object" || Array.isArray(candidate)) {
|
|
19
|
+
throw new TypeError("GitMembership: sourceProjection must be a JSON object");
|
|
20
|
+
}
|
|
21
|
+
const projection = candidate;
|
|
22
|
+
if (typeof projection.mimetype !== "string"
|
|
23
|
+
|| projection.mimetype.length === 0
|
|
24
|
+
|| typeof projection.identity !== "string"
|
|
25
|
+
|| projection.identity.length === 0
|
|
26
|
+
|| !["projected", "unavailable", "input-limit"].includes(projection.disposition ?? "")) {
|
|
27
|
+
throw new TypeError("GitMembership: sourceProjection metadata is malformed");
|
|
28
|
+
}
|
|
29
|
+
if (projection.facts !== undefined && (projection.facts === null || typeof projection.facts !== "object" || Array.isArray(projection.facts))) {
|
|
30
|
+
throw new TypeError("GitMembership: sourceProjection facts must be a JSON object");
|
|
31
|
+
}
|
|
32
|
+
const hasLimit = Number.isSafeInteger(projection.maximumBytes)
|
|
33
|
+
&& (projection.maximumBytes ?? 0) > 0
|
|
34
|
+
&& Number.isSafeInteger(projection.observedBytes)
|
|
35
|
+
&& (projection.observedBytes ?? 0) > (projection.maximumBytes ?? 0);
|
|
36
|
+
if ((projection.disposition === "input-limit") !== hasLimit) {
|
|
37
|
+
throw new TypeError("GitMembership: sourceProjection input-limit evidence is malformed");
|
|
38
|
+
}
|
|
39
|
+
return projection;
|
|
40
|
+
};
|
|
41
|
+
export default class MembershipMaterialization {
|
|
42
|
+
// Materialize a member's model-readable snapshot into a body channel via writeEntry (the
|
|
43
|
+
// entry-write paradigm) — so it appears in the manifest catalog and is READ-able
|
|
44
|
+
// (D4/D5). Change-gated: text changes with mtime:size; binary projections also
|
|
45
|
+
// change when their opaque reader identity changes. A binary source persists
|
|
46
|
+
// only derived Unicode when its installed handler provides it, otherwise an
|
|
47
|
+
// empty typed marker ({§membership-source-projection}).
|
|
48
|
+
// A tracked path missing on disk retains membership but loses its stale
|
|
49
|
+
// readable channels; its explicit absent signature makes a later
|
|
50
|
+
// reappearance another observable divergence.
|
|
51
|
+
static async materializeMember(pathname, root, ctx, identities) {
|
|
52
|
+
const canonical = join(root, pathname); // pathname is namespace-absolute (`/src/foo.ts`); join roots it at the workspace
|
|
53
|
+
const commonsId = await Owner.commonsId(ctx.db, ctx.workspaceId);
|
|
54
|
+
const known = await ctx.db.crud_get_member_sig.get({
|
|
55
|
+
workspace_id: ctx.workspaceId, owner_id: commonsId, scheme: "file", authority: "", pathname,
|
|
56
|
+
});
|
|
57
|
+
// SPEC {§membership-change-gated-sync} — the cheap detect is a stat (mtime:size),
|
|
58
|
+
// never a content read: a member whose signature matches its last sync is a
|
|
59
|
+
// no-op (not re-read, re-tokenized, or rewritten). Coverage stays exhaustive
|
|
60
|
+
// (every member is stat'd); work is proportional to change.
|
|
61
|
+
let sig;
|
|
62
|
+
let sourceBytes;
|
|
63
|
+
try {
|
|
64
|
+
const st = await stat(canonical);
|
|
65
|
+
// A directory-shaped member — an embedded-repo boundary the untracked scan lists as
|
|
66
|
+
// `dir/` (native + iso alike) — is a membership marker: disk truth is a directory,
|
|
67
|
+
// nothing to materialize. Mirrors missing-on-disk: membership stands, no channel.
|
|
68
|
+
if (st.isDirectory())
|
|
69
|
+
return null;
|
|
70
|
+
sig = `${st.mtimeMs}:${st.size}`;
|
|
71
|
+
sourceBytes = st.size;
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
if (err.code === "ENOENT") {
|
|
75
|
+
if (known === undefined || known.synced_sig === ABSENT_SIG)
|
|
76
|
+
return null;
|
|
77
|
+
const prior = await ctx.db.ops_read_channel.get({
|
|
78
|
+
workspace_id: ctx.workspaceId,
|
|
79
|
+
owner_id: commonsId,
|
|
80
|
+
scheme: "file",
|
|
81
|
+
authority: "",
|
|
82
|
+
pathname,
|
|
83
|
+
channel: "body",
|
|
84
|
+
});
|
|
85
|
+
await ctx.db.crud_delete_channels.run({ entry_id: known.id });
|
|
86
|
+
await ctx.db.crud_mark_member_absent.run({ entry_id: known.id });
|
|
87
|
+
return prior === undefined ? null : {
|
|
88
|
+
pathname,
|
|
89
|
+
entryId: known.id,
|
|
90
|
+
channel: "body",
|
|
91
|
+
before: prior.content,
|
|
92
|
+
after: "",
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
throw err;
|
|
96
|
+
}
|
|
97
|
+
if (known !== undefined && known.synced_sig === sig) {
|
|
98
|
+
const sourceMaterialization = FileMaterialization.fromAttributes(known.attributes);
|
|
99
|
+
if (sourceMaterialization !== null) {
|
|
100
|
+
if (FileMaterialization.matchesCurrent(sourceMaterialization, sourceBytes))
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
const sourceProjection = sourceProjectionFrom(known.attributes);
|
|
105
|
+
if (sourceProjection !== null) {
|
|
106
|
+
const currentIdentity = await MembershipMaterialization.#projectionIdentity(sourceProjection.mimetype, ctx.mimetypes, identities);
|
|
107
|
+
if (currentIdentity === sourceProjection.identity)
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const mimetype = await MembershipMaterialization.#detectMimetype(canonical, ctx.mimetypes);
|
|
113
|
+
const sourceMaterialization = FileMaterialization.classify(sourceBytes);
|
|
114
|
+
if (sourceMaterialization.disposition === "input-limit") {
|
|
115
|
+
return MembershipMaterialization.#materializeLimited(pathname, mimetype, sig, known?.synced_sig !== sig, known?.synced_sig === ABSENT_SIG, sourceMaterialization, ctx);
|
|
116
|
+
}
|
|
117
|
+
if (await MimetypeBinary.isBinaryMimetype(mimetype, ctx.mimetypes)) {
|
|
118
|
+
return MembershipMaterialization.#materializeBinary(pathname, { path: canonical }, mimetype, sig, known?.synced_sig !== sig, known?.synced_sig === ABSENT_SIG, ctx, identities);
|
|
119
|
+
}
|
|
120
|
+
let buf;
|
|
121
|
+
try {
|
|
122
|
+
buf = await readFile(canonical);
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
if (err.code === "ENOENT")
|
|
126
|
+
return null;
|
|
127
|
+
throw err;
|
|
128
|
+
}
|
|
129
|
+
// {§membership-binary-sniff} — the extension map can lie (.wasm fell through to
|
|
130
|
+
// the markdown DEFAULT and a 3.3MB blob entered the corpus as prose, three copies,
|
|
131
|
+
// ~10M tokens). NUL bytes in the head are binary truth regardless of the label:
|
|
132
|
+
// re-stamp octet-stream and take the same bounded projection-or-marker arm.
|
|
133
|
+
if (buf.subarray(0, 8192).includes(0)) {
|
|
134
|
+
return MembershipMaterialization.#materializeBinary(pathname, { content: buf, hint: "application/octet-stream" }, "application/octet-stream", sig, known?.synced_sig !== sig, known?.synced_sig === ABSENT_SIG, ctx, identities);
|
|
135
|
+
}
|
|
136
|
+
const content = buf.toString("utf8");
|
|
137
|
+
// {§env-delta-filesystem-narration} — capture the prior snapshot before
|
|
138
|
+
// materialization replaces it, then journal the resulting net span.
|
|
139
|
+
const diskChanged = known?.synced_sig !== sig;
|
|
140
|
+
const prior = diskChanged
|
|
141
|
+
? await ctx.db.ops_read_channel.get({
|
|
142
|
+
workspace_id: ctx.workspaceId, owner_id: commonsId, scheme: "file", authority: "", pathname, channel: "body",
|
|
143
|
+
})
|
|
144
|
+
: undefined;
|
|
145
|
+
const result = await EntryCrud.writeEntry({ authority: "", pathname }, {
|
|
146
|
+
channels: { body: { content, mimetype } },
|
|
147
|
+
attributes: FileMaterialization.attributes(sourceMaterialization),
|
|
148
|
+
}, ctx, "file", commonsId);
|
|
149
|
+
if (result.entryId !== null)
|
|
150
|
+
await ctx.db.crud_set_synced_sig.run({ entry_id: result.entryId, synced_sig: sig });
|
|
151
|
+
const changed = prior !== undefined && prior.content !== content;
|
|
152
|
+
if ((changed || known?.synced_sig === ABSENT_SIG) && result.entryId !== null) {
|
|
153
|
+
return { pathname, entryId: result.entryId, channel: "body", before: prior?.content ?? "", after: content };
|
|
154
|
+
}
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
static async #materializeBinary(pathname, input, mimetype, sig, diskChanged, previouslyAbsent, ctx, identities) {
|
|
158
|
+
const mimetypes = ctx.mimetypes;
|
|
159
|
+
if (mimetypes === undefined)
|
|
160
|
+
throw new Error("GitMembership: configured mimetype registry is required");
|
|
161
|
+
let content = "";
|
|
162
|
+
let outputMimetype = mimetype;
|
|
163
|
+
let metadata;
|
|
164
|
+
try {
|
|
165
|
+
const projected = await mimetypes.projectReadable(input);
|
|
166
|
+
if (projected === null) {
|
|
167
|
+
metadata = {
|
|
168
|
+
mimetype,
|
|
169
|
+
identity: await MembershipMaterialization.#projectionIdentity(mimetype, mimetypes, identities),
|
|
170
|
+
disposition: "unavailable",
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
content = projected.content;
|
|
175
|
+
outputMimetype = "text/markdown";
|
|
176
|
+
metadata = {
|
|
177
|
+
mimetype: projected.sourceMimetype,
|
|
178
|
+
identity: projected.projectionIdentity,
|
|
179
|
+
disposition: "projected",
|
|
180
|
+
...(projected.facts !== null && typeof projected.facts === "object" && !Array.isArray(projected.facts)
|
|
181
|
+
? { facts: projected.facts }
|
|
182
|
+
: {}),
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
catch (cause) {
|
|
187
|
+
if (!(cause instanceof MimetypeInputLimitError))
|
|
188
|
+
throw cause;
|
|
189
|
+
metadata = {
|
|
190
|
+
mimetype,
|
|
191
|
+
identity: await MembershipMaterialization.#projectionIdentity(mimetype, mimetypes, identities),
|
|
192
|
+
disposition: "input-limit",
|
|
193
|
+
maximumBytes: cause.maximumBytes,
|
|
194
|
+
observedBytes: cause.observedBytes,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
const prior = diskChanged && metadata.disposition === "projected"
|
|
198
|
+
? await ctx.db.ops_read_channel.get({
|
|
199
|
+
workspace_id: ctx.workspaceId,
|
|
200
|
+
owner_id: await Owner.commonsId(ctx.db, ctx.workspaceId),
|
|
201
|
+
scheme: "file",
|
|
202
|
+
authority: "",
|
|
203
|
+
pathname,
|
|
204
|
+
channel: "body",
|
|
205
|
+
})
|
|
206
|
+
: undefined;
|
|
207
|
+
const result = await EntryCrud.writeEntry({ authority: "", pathname }, {
|
|
208
|
+
channels: { body: { content, mimetype: outputMimetype } },
|
|
209
|
+
attributes: { sourceProjection: metadata },
|
|
210
|
+
}, ctx, "file", await Owner.commonsId(ctx.db, ctx.workspaceId));
|
|
211
|
+
if (result.entryId !== null) {
|
|
212
|
+
await ctx.db.crud_set_synced_sig.run({ entry_id: result.entryId, synced_sig: sig });
|
|
213
|
+
}
|
|
214
|
+
const changed = prior !== undefined && prior.content !== content;
|
|
215
|
+
if ((changed || previouslyAbsent) && result.entryId !== null) {
|
|
216
|
+
return {
|
|
217
|
+
pathname,
|
|
218
|
+
entryId: result.entryId,
|
|
219
|
+
channel: "body",
|
|
220
|
+
before: prior?.content ?? "",
|
|
221
|
+
after: content,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
static #projectionIdentity(mimetype, mimetypes, identities) {
|
|
227
|
+
if (mimetypes === undefined)
|
|
228
|
+
throw new Error("GitMembership: configured mimetype registry is required");
|
|
229
|
+
let identity = identities.get(mimetype);
|
|
230
|
+
if (identity === undefined) {
|
|
231
|
+
identity = mimetypes.projectionIdentity(mimetype);
|
|
232
|
+
identities.set(mimetype, identity);
|
|
233
|
+
}
|
|
234
|
+
return identity;
|
|
235
|
+
}
|
|
236
|
+
// Detect a tracked file's mimetype (mirrors File.detectFileMimetype) through
|
|
237
|
+
// the configured registry, normalizing auto-derived text/plain to the text
|
|
238
|
+
// primitive.
|
|
239
|
+
static async #detectMimetype(canonical, mimetypes) {
|
|
240
|
+
if (mimetypes === undefined)
|
|
241
|
+
throw new Error("GitMembership: configured mimetype registry is required");
|
|
242
|
+
const detected = await mimetypes.detect({ path: canonical });
|
|
243
|
+
return MimetypeBinary.normalizeAutoTextMimetype(detected);
|
|
244
|
+
}
|
|
245
|
+
static async #materializeLimited(pathname, mimetype, sig, diskChanged, previouslyAbsent, metadata, ctx) {
|
|
246
|
+
const commonsId = await Owner.commonsId(ctx.db, ctx.workspaceId);
|
|
247
|
+
const prior = diskChanged
|
|
248
|
+
? await ctx.db.ops_read_channel.get({
|
|
249
|
+
workspace_id: ctx.workspaceId,
|
|
250
|
+
owner_id: commonsId,
|
|
251
|
+
scheme: "file",
|
|
252
|
+
authority: "",
|
|
253
|
+
pathname,
|
|
254
|
+
channel: "body",
|
|
255
|
+
})
|
|
256
|
+
: undefined;
|
|
257
|
+
const result = await EntryCrud.writeEntry({ authority: "", pathname }, {
|
|
258
|
+
channels: {
|
|
259
|
+
body: {
|
|
260
|
+
content: "",
|
|
261
|
+
mimetype,
|
|
262
|
+
producerResult: FileMaterialization.failure(pathname, metadata),
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
attributes: FileMaterialization.attributes(metadata),
|
|
266
|
+
}, ctx, "file", commonsId);
|
|
267
|
+
if (result.entryId !== null) {
|
|
268
|
+
await ctx.db.crud_set_synced_sig.run({ entry_id: result.entryId, synced_sig: sig });
|
|
269
|
+
}
|
|
270
|
+
const changed = prior !== undefined && prior.content !== "";
|
|
271
|
+
if ((changed || previouslyAbsent) && result.entryId !== null) {
|
|
272
|
+
return {
|
|
273
|
+
pathname,
|
|
274
|
+
entryId: result.entryId,
|
|
275
|
+
channel: "body",
|
|
276
|
+
before: prior?.content ?? "",
|
|
277
|
+
after: "",
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
//# sourceMappingURL=MembershipMaterialization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MembershipMaterialization.js","sourceRoot":"","sources":["../../src/core/MembershipMaterialization.ts"],"names":[],"mappings":"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"}
|