pi-daddy 0.22.0 → 0.23.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/CHANGELOG.md +30 -0
- package/contracts/daily-view/v1/README.md +114 -0
- package/contracts/daily-view/v1/fixtures/view.json +525 -0
- package/contracts/daily-view/v1/fixtures/view.txt +75 -0
- package/contracts/daily-view/v1/fixtures/work.jsonl +17 -0
- package/contracts/daily-view/v1/p03/README.md +26 -0
- package/contracts/daily-view/v1/p03/fixtures/retained-executions.json +241 -0
- package/contracts/daily-view/v1/p03/projection.schema.json +194 -0
- package/contracts/daily-view/v1/p03/provenance.json +21 -0
- package/contracts/dashboard-host/v1/README.md +176 -0
- package/contracts/debrief/v1/README.md +146 -0
- package/contracts/debrief/v1/intervention/README.md +32 -0
- package/contracts/debrief/v1/intervention/fixtures/artifact-3ee11136beb864f518252e5024dae9197421fbf97b6e981d3243c782b5c44bd0.txt +1 -0
- package/contracts/debrief/v1/intervention/fixtures/artifact-58905d872dd3c54a9705f67b05fa82edbad7af6476ae8993faf1a7b9fadfb905.txt +1 -0
- package/contracts/debrief/v1/intervention/fixtures/assessment.json +29 -0
- package/contracts/debrief/v1/intervention/fixtures/blind-view.json +20 -0
- package/contracts/debrief/v1/intervention/fixtures/choice.json +7 -0
- package/contracts/debrief/v1/intervention/fixtures/manifest.json +57 -0
- package/contracts/debrief/v1/intervention/fixtures/reveal.json +39 -0
- package/contracts/debrief/v1/provenance.json +89 -0
- package/contracts/debrief/v1/work-capture/README.md +38 -0
- package/contracts/debrief/v1/work-capture/fixtures/batch.json +17 -0
- package/contracts/debrief/v1/work-capture/fixtures/cases.json +184 -0
- package/contracts/debrief/v1/work-capture/fixtures/review.json +184 -0
- package/contracts/debrief/v1/work-capture/review-request.schema.json +41 -0
- package/contracts/debrief/v1/work-capture/work-case.schema.json +190 -0
- package/contracts/debrief/v2/README.md +71 -0
- package/contracts/debrief/v2/input-pin.json +66 -0
- package/contracts/debrief/v2/intervention-upstream.md +40 -0
- package/contracts/debrief/v2/work-signals-upstream.md +22 -0
- package/contracts/dispatch-control/v1/README.md +109 -0
- package/contracts/dispatch-control/v1/request.schema.json +19 -0
- package/contracts/effect-profile/v1/README.md +124 -0
- package/contracts/execution-retention/v1/README.md +109 -0
- package/contracts/execution-retention/v2/README.md +148 -0
- package/contracts/execution-retention/v2/fixtures/interrupted-native-bytes.json +91 -0
- package/contracts/execution-retention/v2/fixtures/missing-native-session.json +91 -0
- package/contracts/execution-retention/v2/fixtures/native-file-unknown-branch.json +91 -0
- package/contracts/execution-retention/v2/fixtures/native-id-without-bytes.json +91 -0
- package/contracts/execution-retention/v2/fixtures/native-live-branch.json +90 -0
- package/contracts/execution-retention/v2/fixtures/replaced-native-session.json +92 -0
- package/contracts/execution-retention/v2/fixtures/result-82c620cdfeb8ca6b858cf653d7f5e2eedca5315d6244216d60e8b36f03223d6a.bin +1 -0
- package/contracts/execution-retention/v2/fixtures/session-2ec1f134bc739984434f7fca689e1c3d1c39fce2dcadae709e9b6faedfcc4ac7.bin +3 -0
- package/contracts/execution-retention/v2/fixtures/session-9bdb4bd16a901da31580acf056bda525225259e15ec409e0410480109011772f.bin +3 -0
- package/contracts/execution-retention/v2/manifest.schema.json +858 -0
- package/contracts/experiment/v1/README.md +164 -0
- package/contracts/factory-order/v1/README.md +151 -0
- package/contracts/factory-order/v1/adoption-pin.json +8 -0
- package/contracts/intent-control/v1/README.md +135 -0
- package/contracts/intent-control/v1/request.schema.json +1096 -0
- package/contracts/intent-control/v2/README.md +34 -0
- package/contracts/intent-control/v2/request.schema.json +1070 -0
- package/contracts/ledger/v4/README.md +241 -0
- package/contracts/ledger/v4/fixtures/layout-options.json +428 -0
- package/contracts/ledger/v4/fixtures/work-acceptance.json +57 -0
- package/contracts/ledger/v4/fixtures/work-occurrence.json +44 -0
- package/contracts/ledger/v4/fixtures/work-revision.json +26 -0
- package/contracts/ledger/v4/fixtures/work-snapshot.json +73 -0
- package/contracts/ledger/v4/ledger-event.schema.json +162 -0
- package/contracts/ordinary-control/v1/README.md +59 -0
- package/contracts/producer-ipc/v1/README.md +137 -0
- package/dist/check-runner.d.ts +5 -0
- package/dist/check-runner.d.ts.map +1 -1
- package/dist/check-runner.js +16 -2
- package/dist/check-runner.js.map +1 -1
- package/dist/control-journal.d.ts +20 -0
- package/dist/control-journal.d.ts.map +1 -0
- package/dist/control-journal.js +73 -0
- package/dist/control-journal.js.map +1 -0
- package/dist/daily-view-input.d.ts +44 -0
- package/dist/daily-view-input.d.ts.map +1 -0
- package/dist/daily-view-input.js +68 -0
- package/dist/daily-view-input.js.map +1 -0
- package/dist/daily-view-render.d.ts +4 -0
- package/dist/daily-view-render.d.ts.map +1 -0
- package/dist/daily-view-render.js +41 -0
- package/dist/daily-view-render.js.map +1 -0
- package/dist/daily-view.d.ts +74 -0
- package/dist/daily-view.d.ts.map +1 -0
- package/dist/daily-view.js +170 -0
- package/dist/daily-view.js.map +1 -0
- package/dist/dashboard-cli.d.ts +26 -1
- package/dist/dashboard-cli.d.ts.map +1 -1
- package/dist/dashboard-cli.js +121 -3
- package/dist/dashboard-cli.js.map +1 -1
- package/dist/dashboard-harness.d.ts +19 -0
- package/dist/dashboard-harness.d.ts.map +1 -0
- package/dist/dashboard-harness.js +75 -0
- package/dist/dashboard-harness.js.map +1 -0
- package/dist/dashboard-herdr.d.ts.map +1 -1
- package/dist/dashboard-herdr.js +7 -2
- package/dist/dashboard-herdr.js.map +1 -1
- package/dist/dashboard-host-contract.d.ts +111 -0
- package/dist/dashboard-host-contract.d.ts.map +1 -0
- package/dist/dashboard-host-contract.js +14 -0
- package/dist/dashboard-host-contract.js.map +1 -0
- package/dist/dashboard-host-transport.d.ts +15 -0
- package/dist/dashboard-host-transport.d.ts.map +1 -0
- package/dist/dashboard-host-transport.js +122 -0
- package/dist/dashboard-host-transport.js.map +1 -0
- package/dist/dashboard-host.d.ts +149 -0
- package/dist/dashboard-host.d.ts.map +1 -0
- package/dist/dashboard-host.js +329 -0
- package/dist/dashboard-host.js.map +1 -0
- package/dist/dashboard-observation.d.ts +28 -0
- package/dist/dashboard-observation.d.ts.map +1 -0
- package/dist/dashboard-observation.js +86 -0
- package/dist/dashboard-observation.js.map +1 -0
- package/dist/debrief-contract.d.ts +65 -0
- package/dist/debrief-contract.d.ts.map +1 -0
- package/dist/debrief-contract.js +151 -0
- package/dist/debrief-contract.js.map +1 -0
- package/dist/debrief-fixture.d.ts +16 -0
- package/dist/debrief-fixture.d.ts.map +1 -0
- package/dist/debrief-fixture.js +41 -0
- package/dist/debrief-fixture.js.map +1 -0
- package/dist/debrief-host.d.ts +59 -0
- package/dist/debrief-host.d.ts.map +1 -0
- package/dist/debrief-host.js +49 -0
- package/dist/debrief-host.js.map +1 -0
- package/dist/debrief-render.d.ts +5 -0
- package/dist/debrief-render.d.ts.map +1 -0
- package/dist/debrief-render.js +65 -0
- package/dist/debrief-render.js.map +1 -0
- package/dist/debrief.d.ts +90 -0
- package/dist/debrief.d.ts.map +1 -0
- package/dist/debrief.js +263 -0
- package/dist/debrief.js.map +1 -0
- package/dist/delegate-types.d.ts +2 -0
- package/dist/delegate-types.d.ts.map +1 -1
- package/dist/delegate-types.js.map +1 -1
- package/dist/delegate.d.ts.map +1 -1
- package/dist/delegate.js +1 -0
- package/dist/delegate.js.map +1 -1
- package/dist/dispatch-control.d.ts +45 -0
- package/dist/dispatch-control.d.ts.map +1 -0
- package/dist/dispatch-control.js +76 -0
- package/dist/dispatch-control.js.map +1 -0
- package/dist/effect-profile-runtime.d.ts +40 -0
- package/dist/effect-profile-runtime.d.ts.map +1 -0
- package/dist/effect-profile-runtime.js +51 -0
- package/dist/effect-profile-runtime.js.map +1 -0
- package/dist/effect-profile.d.ts +40 -0
- package/dist/effect-profile.d.ts.map +1 -0
- package/dist/effect-profile.js +152 -0
- package/dist/effect-profile.js.map +1 -0
- package/dist/execution-retention.d.ts +90 -0
- package/dist/execution-retention.d.ts.map +1 -0
- package/dist/execution-retention.js +247 -0
- package/dist/execution-retention.js.map +1 -0
- package/dist/experiment-contract.d.ts +56 -0
- package/dist/experiment-contract.d.ts.map +1 -0
- package/dist/experiment-contract.js +80 -0
- package/dist/experiment-contract.js.map +1 -0
- package/dist/experiment-state.d.ts +22 -0
- package/dist/experiment-state.d.ts.map +1 -0
- package/dist/experiment-state.js +79 -0
- package/dist/experiment-state.js.map +1 -0
- package/dist/experiment-store.d.ts +28 -0
- package/dist/experiment-store.d.ts.map +1 -0
- package/dist/experiment-store.js +130 -0
- package/dist/experiment-store.js.map +1 -0
- package/dist/experiment.d.ts +65 -0
- package/dist/experiment.d.ts.map +1 -0
- package/dist/experiment.js +357 -0
- package/dist/experiment.js.map +1 -0
- package/dist/factory-contract.d.ts +79 -0
- package/dist/factory-contract.d.ts.map +1 -0
- package/dist/factory-contract.js +89 -0
- package/dist/factory-contract.js.map +1 -0
- package/dist/factory-migration.d.ts +20 -0
- package/dist/factory-migration.d.ts.map +1 -0
- package/dist/factory-migration.js +55 -0
- package/dist/factory-migration.js.map +1 -0
- package/dist/factory-order.d.ts +848 -0
- package/dist/factory-order.d.ts.map +1 -0
- package/dist/factory-order.js +83 -0
- package/dist/factory-order.js.map +1 -0
- package/dist/factory-registry.d.ts +121 -0
- package/dist/factory-registry.d.ts.map +1 -0
- package/dist/factory-registry.js +133 -0
- package/dist/factory-registry.js.map +1 -0
- package/dist/file-lock.d.ts +8 -2
- package/dist/file-lock.d.ts.map +1 -1
- package/dist/file-lock.js +78 -19
- package/dist/file-lock.js.map +1 -1
- package/dist/herdr-poll.d.ts +8 -0
- package/dist/herdr-poll.d.ts.map +1 -1
- package/dist/herdr-poll.js +23 -0
- package/dist/herdr-poll.js.map +1 -1
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -1
- package/dist/intent-application.d.ts +17 -0
- package/dist/intent-application.d.ts.map +1 -0
- package/dist/intent-application.js +113 -0
- package/dist/intent-application.js.map +1 -0
- package/dist/intent-control.d.ts +201 -0
- package/dist/intent-control.d.ts.map +1 -0
- package/dist/intent-control.js +110 -0
- package/dist/intent-control.js.map +1 -0
- package/dist/intent-scheduling.d.ts +9 -0
- package/dist/intent-scheduling.d.ts.map +1 -0
- package/dist/intent-scheduling.js +15 -0
- package/dist/intent-scheduling.js.map +1 -0
- package/dist/ledger-append.d.ts +15 -0
- package/dist/ledger-append.d.ts.map +1 -0
- package/dist/ledger-append.js +94 -0
- package/dist/ledger-append.js.map +1 -0
- package/dist/ledger.d.ts +11 -0
- package/dist/ledger.d.ts.map +1 -1
- package/dist/ledger.js +3 -7
- package/dist/ledger.js.map +1 -1
- package/dist/native-session-target.d.ts +9 -0
- package/dist/native-session-target.d.ts.map +1 -0
- package/dist/native-session-target.js +29 -0
- package/dist/native-session-target.js.map +1 -0
- package/dist/native-session.d.ts +59 -0
- package/dist/native-session.d.ts.map +1 -0
- package/dist/native-session.js +154 -0
- package/dist/native-session.js.map +1 -0
- package/dist/order-schedule.d.ts +37 -0
- package/dist/order-schedule.d.ts.map +1 -0
- package/dist/order-schedule.js +81 -0
- package/dist/order-schedule.js.map +1 -0
- package/dist/ordinary-children.d.ts +52 -0
- package/dist/ordinary-children.d.ts.map +1 -0
- package/dist/ordinary-children.js +93 -0
- package/dist/ordinary-children.js.map +1 -0
- package/dist/producer-ipc-contract.d.ts +29 -0
- package/dist/producer-ipc-contract.d.ts.map +1 -0
- package/dist/producer-ipc-contract.js +29 -0
- package/dist/producer-ipc-contract.js.map +1 -0
- package/dist/producer-ipc.d.ts +55 -0
- package/dist/producer-ipc.d.ts.map +1 -0
- package/dist/producer-ipc.js +143 -0
- package/dist/producer-ipc.js.map +1 -0
- package/dist/resource-budget.d.ts +334 -0
- package/dist/resource-budget.d.ts.map +1 -0
- package/dist/resource-budget.js +415 -0
- package/dist/resource-budget.js.map +1 -0
- package/dist/retention-contract.d.ts +73 -0
- package/dist/retention-contract.d.ts.map +1 -0
- package/dist/retention-contract.js +104 -0
- package/dist/retention-contract.js.map +1 -0
- package/dist/retention-json.d.ts +3 -0
- package/dist/retention-json.d.ts.map +1 -0
- package/dist/retention-json.js +32 -0
- package/dist/retention-json.js.map +1 -0
- package/dist/run-child.d.ts +4 -0
- package/dist/run-child.d.ts.map +1 -1
- package/dist/run-child.js +16 -2
- package/dist/run-child.js.map +1 -1
- package/dist/run-herdr.d.ts +6 -0
- package/dist/run-herdr.d.ts.map +1 -1
- package/dist/run-herdr.js +19 -6
- package/dist/run-herdr.js.map +1 -1
- package/dist/vendor/adoption.d.ts +129 -0
- package/dist/vendor/adoption.d.ts.map +1 -0
- package/dist/vendor/adoption.js +102 -0
- package/dist/vendor/adoption.js.map +1 -0
- package/dist/work-ledger-destination.d.ts +20 -0
- package/dist/work-ledger-destination.d.ts.map +1 -0
- package/dist/work-ledger-destination.js +131 -0
- package/dist/work-ledger-destination.js.map +1 -0
- package/dist/work-ledger-json.d.ts +25 -0
- package/dist/work-ledger-json.d.ts.map +1 -0
- package/dist/work-ledger-json.js +267 -0
- package/dist/work-ledger-json.js.map +1 -0
- package/dist/work-ledger-occurrences.d.ts +227 -0
- package/dist/work-ledger-occurrences.d.ts.map +1 -0
- package/dist/work-ledger-occurrences.js +115 -0
- package/dist/work-ledger-occurrences.js.map +1 -0
- package/dist/work-ledger-projection.d.ts +295 -0
- package/dist/work-ledger-projection.d.ts.map +1 -0
- package/dist/work-ledger-projection.js +237 -0
- package/dist/work-ledger-projection.js.map +1 -0
- package/dist/work-ledger-snapshot.d.ts +29 -0
- package/dist/work-ledger-snapshot.d.ts.map +1 -0
- package/dist/work-ledger-snapshot.js +267 -0
- package/dist/work-ledger-snapshot.js.map +1 -0
- package/dist/work-ledger-types.d.ts +261 -0
- package/dist/work-ledger-types.d.ts.map +1 -0
- package/dist/work-ledger-types.js +13 -0
- package/dist/work-ledger-types.js.map +1 -0
- package/dist/work-ledger-validation.d.ts +14 -0
- package/dist/work-ledger-validation.d.ts.map +1 -0
- package/dist/work-ledger-validation.js +226 -0
- package/dist/work-ledger-validation.js.map +1 -0
- package/dist/work-ledger.d.ts +43 -0
- package/dist/work-ledger.d.ts.map +1 -0
- package/dist/work-ledger.js +225 -0
- package/dist/work-ledger.js.map +1 -0
- package/extensions/delegate-chain.ts +1 -0
- package/extensions/delegation-native.ts +12 -0
- package/extensions/delegation.ts +4 -3
- package/extensions/execute-child.ts +34 -4
- package/extensions/grants.ts +2 -0
- package/extensions/ordinary-runtime.ts +14 -0
- package/extensions/run-delegation.ts +7 -7
- package/extensions/session.ts +3 -1
- package/package.json +78 -4
- package/src/check-runner.ts +20 -2
- package/src/control-journal.ts +26 -0
- package/src/daily-view-input.ts +59 -0
- package/src/daily-view-render.ts +44 -0
- package/src/daily-view.ts +152 -0
- package/src/dashboard-cli.ts +103 -4
- package/src/dashboard-harness.ts +28 -0
- package/src/dashboard-herdr.ts +7 -2
- package/src/dashboard-host-contract.ts +42 -0
- package/src/dashboard-host-transport.ts +38 -0
- package/src/dashboard-host.ts +168 -0
- package/src/dashboard-observation.ts +44 -0
- package/src/debrief-contract.ts +127 -0
- package/src/debrief-fixture.ts +29 -0
- package/src/debrief-host.ts +53 -0
- package/src/debrief-render.ts +49 -0
- package/src/debrief.ts +198 -0
- package/src/delegate-types.ts +2 -0
- package/src/delegate.ts +1 -0
- package/src/dispatch-control.ts +81 -0
- package/src/effect-profile-runtime.ts +46 -0
- package/src/effect-profile.ts +129 -0
- package/src/execution-retention.ts +230 -0
- package/src/experiment-contract.ts +66 -0
- package/src/experiment-state.ts +44 -0
- package/src/experiment-store.ts +90 -0
- package/src/experiment.ts +231 -0
- package/src/factory-contract.ts +47 -0
- package/src/factory-migration.ts +29 -0
- package/src/factory-order.ts +56 -0
- package/src/factory-registry.ts +60 -0
- package/src/file-lock.ts +47 -11
- package/src/herdr-poll.ts +18 -0
- package/src/index.ts +32 -0
- package/src/intent-application.ts +90 -0
- package/src/intent-control.ts +107 -0
- package/src/intent-scheduling.ts +14 -0
- package/src/ledger-append.ts +72 -0
- package/src/ledger.ts +3 -9
- package/src/native-session-target.ts +23 -0
- package/src/native-session.ts +139 -0
- package/src/order-schedule.ts +42 -0
- package/src/ordinary-children.ts +59 -0
- package/src/producer-ipc-contract.ts +26 -0
- package/src/producer-ipc.ts +107 -0
- package/src/resource-budget.ts +349 -0
- package/src/retention-contract.ts +84 -0
- package/src/retention-json.ts +20 -0
- package/src/run-child.ts +13 -2
- package/src/run-herdr.ts +11 -7
- package/src/vendor/adoption.ts +109 -0
- package/src/work-ledger-destination.ts +113 -0
- package/src/work-ledger-json.ts +228 -0
- package/src/work-ledger-occurrences.ts +99 -0
- package/src/work-ledger-projection.ts +262 -0
- package/src/work-ledger-snapshot.ts +246 -0
- package/src/work-ledger-types.ts +229 -0
- package/src/work-ledger-validation.ts +174 -0
- package/src/work-ledger.ts +186 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/** Opt-in work-v4 evidence. No default emission or built-in acceptance authority. */
|
|
2
|
+
import { isDate } from "node:util/types";
|
|
3
|
+
import { open, stat } from "node:fs/promises";
|
|
4
|
+
import { constants } from "node:fs";
|
|
5
|
+
import { appendLedgerLine, readWorkBytes, closeWorkHandle } from "./ledger-append.js";
|
|
6
|
+
import { workDestination, workFsError, validWorkPath } from "./work-ledger-destination.js";
|
|
7
|
+
import { LockTimeoutError } from "./file-lock.js";
|
|
8
|
+
import { canonicalWorkJson, copyWorkJson, freezeWork, ownWorkFields, parseWorkJson, WORK_EVENT_BYTES, WORK_TEXT_BYTES, WORK_RECORDS, mergeWorkConflicts, } from "./work-ledger-json.js";
|
|
9
|
+
import { validateWorkEvent, validateWorkContext } from "./work-ledger-validation.js";
|
|
10
|
+
import { indexWorkLedgerText, indexWorkReceipts, projectWorkAcceptance } from "./work-ledger-projection.js";
|
|
11
|
+
import { resolveWorkSnapshotText } from "./work-ledger-snapshot.js";
|
|
12
|
+
import { foldWorkOccurrences } from "./work-ledger-occurrences.js";
|
|
13
|
+
import { WorkInputError, WorkLedgerWriteError, } from "./work-ledger-types.js";
|
|
14
|
+
export * from "./work-ledger-types.js";
|
|
15
|
+
function build(args, kind, field) {
|
|
16
|
+
const fields = ownWorkFields(args);
|
|
17
|
+
const required = ["eventId", "now", field];
|
|
18
|
+
if (Object.keys(fields).length !== required.length || required.some(key => !Object.hasOwn(fields, key))) {
|
|
19
|
+
throw new WorkInputError("WORK_SCHEMA_INVALID");
|
|
20
|
+
}
|
|
21
|
+
const now = fields.now.value;
|
|
22
|
+
if (!isDate(now) || Object.getPrototypeOf(now) !== Date.prototype || Reflect.ownKeys(now).length !== 0 ||
|
|
23
|
+
!Number.isFinite(Date.prototype.getTime.call(now)))
|
|
24
|
+
throw new WorkInputError("WORK_SCHEMA_INVALID");
|
|
25
|
+
const content = copyWorkJson(fields[field].value);
|
|
26
|
+
const candidate = copyWorkJson({ ledgerVersion: 4, event: kind, eventId: fields.eventId.value,
|
|
27
|
+
ts: Date.prototype.toISOString.call(now), payload: field === "payload" ? content : { [field]: content } });
|
|
28
|
+
const event = validateWorkEvent(candidate, true);
|
|
29
|
+
if (Buffer.byteLength(canonicalWorkJson(event), "utf8") > WORK_EVENT_BYTES)
|
|
30
|
+
throw new WorkInputError("WORK_LIMIT_EXCEEDED");
|
|
31
|
+
return freezeWork(event);
|
|
32
|
+
}
|
|
33
|
+
export function buildWorkRevisionEvent(args) {
|
|
34
|
+
return build(args, "work_revision", "revision");
|
|
35
|
+
}
|
|
36
|
+
export function buildWorkSnapshotEvent(args) {
|
|
37
|
+
return build(args, "work_snapshot", "snapshot");
|
|
38
|
+
}
|
|
39
|
+
export function buildWorkOccurrenceEvent(args) {
|
|
40
|
+
return build(args, "work_occurrence", "payload");
|
|
41
|
+
}
|
|
42
|
+
export function buildWorkAcceptanceEvent(args) {
|
|
43
|
+
return build(args, "work_acceptance", "payload");
|
|
44
|
+
}
|
|
45
|
+
function* lines(text) {
|
|
46
|
+
let start = 0, line = 1;
|
|
47
|
+
while (start < text.length) {
|
|
48
|
+
const end = text.indexOf("\n", start);
|
|
49
|
+
yield { text: text.slice(start, end === -1 ? text.length : end), line: line++ };
|
|
50
|
+
if (end === -1)
|
|
51
|
+
return;
|
|
52
|
+
start = end + 1;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const blank = (text) => /^[ \t\r]*$/.test(text);
|
|
56
|
+
/** Diagnostic boundary: retain physical valid deliveries, never rewrite, deduplicate or elect a winner. */
|
|
57
|
+
export function parseWorkLedgerText(text) {
|
|
58
|
+
const wholeError = (code) => freezeWork({ events: [], errors: [{ line: null, code }], complete: false });
|
|
59
|
+
if (typeof text !== "string")
|
|
60
|
+
return wholeError("WORK_SCHEMA_INVALID");
|
|
61
|
+
if (Buffer.byteLength(text, "utf8") > WORK_TEXT_BYTES)
|
|
62
|
+
return wholeError("WORK_LIMIT_EXCEEDED");
|
|
63
|
+
let records = 0;
|
|
64
|
+
for (const row of lines(text))
|
|
65
|
+
if (!blank(row.text) && ++records > WORK_RECORDS)
|
|
66
|
+
return wholeError("WORK_LIMIT_EXCEEDED");
|
|
67
|
+
const events = [], errors = [];
|
|
68
|
+
for (const row of lines(text)) {
|
|
69
|
+
if (blank(row.text))
|
|
70
|
+
continue;
|
|
71
|
+
try {
|
|
72
|
+
events.push(validateWorkEvent(parseWorkJson(row.text)));
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
if (!(error instanceof WorkInputError))
|
|
76
|
+
throw error;
|
|
77
|
+
errors.push({ line: row.line, code: error.code });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return freezeWork({ events, errors, complete: errors.length === 0 });
|
|
81
|
+
}
|
|
82
|
+
/** Public opt-in projection: strict text, detached host context, exact selection, actual runtime,
|
|
83
|
+
* then conditional authority binding. No I/O, authenticator, ambient trust or acceptance callback. */
|
|
84
|
+
export function projectWorkLedger(text, context = { selectedSnapshot: null, authority: null }) {
|
|
85
|
+
const index = indexWorkLedgerText(text);
|
|
86
|
+
const errors = [...index.ingestion.errors];
|
|
87
|
+
let copied = null;
|
|
88
|
+
try {
|
|
89
|
+
const value = copyWorkJson(context);
|
|
90
|
+
validateWorkContext(value);
|
|
91
|
+
copied = JSON.parse(canonicalWorkJson(value));
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
if (!(error instanceof WorkInputError))
|
|
95
|
+
throw error;
|
|
96
|
+
errors.push({ line: null, code: "WORK_CONTEXT_INVALID" });
|
|
97
|
+
}
|
|
98
|
+
errors.sort((a, b) => (a.line ?? Infinity) - (b.line ?? Infinity) || (a.code < b.code ? -1 : a.code > b.code ? 1 : 0));
|
|
99
|
+
const conflicts = mergeWorkConflicts([
|
|
100
|
+
...index.conflictingEvents.map(ref => ({ kind: "event", id: ref.eventId, digests: [ref.digest], affectedObligations: [] })),
|
|
101
|
+
...indexWorkReceipts(copied?.authority ?? null).conflicts,
|
|
102
|
+
]);
|
|
103
|
+
const identities = { selectedSnapshot: copied?.selectedSnapshot?.snapshot ?? null, authoritySnapshot: copied?.authority?.snapshot ?? null };
|
|
104
|
+
function empty(scopeState, problems, retained = conflicts) {
|
|
105
|
+
return freezeWork({ ...identities, scopeState, progress: null, obligations: [], claims: [], supersededClaims: 0,
|
|
106
|
+
conflicts: mergeWorkConflicts([...retained, ...conflicts]), problems, errors, runtime: null });
|
|
107
|
+
}
|
|
108
|
+
if (errors.length)
|
|
109
|
+
return empty("unresolved", [{ code: "INPUT_INCOMPLETE", reference: null, affectedObligations: [] }]);
|
|
110
|
+
const structure = resolveWorkSnapshotText(text, copied.selectedSnapshot);
|
|
111
|
+
if (structure.scopeState !== "valid")
|
|
112
|
+
return empty(structure.scopeState, structure.problems, structure.conflicts);
|
|
113
|
+
const runtime = foldWorkOccurrences(index, structure.snapshot);
|
|
114
|
+
const acceptance = projectWorkAcceptance(index, structure, copied.authority, runtime);
|
|
115
|
+
return freezeWork({ ...identities, scopeState: "valid", ...acceptance, errors, runtime: runtime.runtime });
|
|
116
|
+
}
|
|
117
|
+
/** Always opt-in, strict, and detached before the first filesystem await. No environment defaults. */
|
|
118
|
+
export function appendWorkLedgerEvent(options, event) {
|
|
119
|
+
return appendWorkEvent(options, event, false);
|
|
120
|
+
}
|
|
121
|
+
/** Explicit controller application seam: exact ID/digest redelivery does not append a second event. */
|
|
122
|
+
export function appendWorkLedgerEventOnce(options, event) {
|
|
123
|
+
return appendWorkEvent(options, event, true);
|
|
124
|
+
}
|
|
125
|
+
async function appendWorkEvent(options, event, once) {
|
|
126
|
+
const fields = ownWorkFields(options);
|
|
127
|
+
if (Object.keys(fields).length !== 2 || !Object.hasOwn(fields, "path") || !Object.hasOwn(fields, "grantLedgerPath") || typeof fields.path.value !== "string" ||
|
|
128
|
+
(fields.grantLedgerPath.value !== null && typeof fields.grantLedgerPath.value !== "string"))
|
|
129
|
+
throw new WorkInputError("WORK_SCHEMA_INVALID");
|
|
130
|
+
const path = fields.path.value, grant = fields.grantLedgerPath.value;
|
|
131
|
+
const candidate = validateWorkEvent(copyWorkJson(event));
|
|
132
|
+
const canonical = canonicalWorkJson(candidate);
|
|
133
|
+
if (Buffer.byteLength(canonical, "utf8") > WORK_EVENT_BYTES)
|
|
134
|
+
throw new WorkInputError("WORK_LIMIT_EXCEEDED");
|
|
135
|
+
try {
|
|
136
|
+
const destination = await workDestination(path, grant);
|
|
137
|
+
await appendLedgerLine({ path: destination.path }, canonical + "\n", destination, once ? { eventId: candidate.eventId, digest: candidate.digest } : undefined);
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
if (error instanceof LockTimeoutError || workFsError(error))
|
|
141
|
+
throw new WorkLedgerWriteError("WORK_LEDGER_WRITE_FAILED");
|
|
142
|
+
throw error;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/** Read-only regular-file inspection; a successful read is not a content-validity or acceptance claim. */
|
|
146
|
+
export async function inspectWorkLedger(options, context = { selectedSnapshot: null, authority: null }) {
|
|
147
|
+
let exists = null;
|
|
148
|
+
const failure = (code) => freezeWork({
|
|
149
|
+
version: 4, status: "error", exists, ingestion: null, projection: null, errors: [{ line: null, code }],
|
|
150
|
+
});
|
|
151
|
+
const missing = () => freezeWork({ version: 4, status: "missing", exists: false,
|
|
152
|
+
ingestion: null, projection: null, errors: [] });
|
|
153
|
+
let path, copied;
|
|
154
|
+
try {
|
|
155
|
+
const fields = ownWorkFields(options);
|
|
156
|
+
if (Object.keys(fields).length !== 2 || !Object.hasOwn(fields, "path") || !Object.hasOwn(fields, "version") || typeof fields.path.value !== "string")
|
|
157
|
+
throw new WorkInputError("WORK_SCHEMA_INVALID");
|
|
158
|
+
if (fields.version.value !== 4)
|
|
159
|
+
throw new WorkInputError("WORK_VERSION_UNSUPPORTED");
|
|
160
|
+
path = fields.path.value;
|
|
161
|
+
try {
|
|
162
|
+
const value = copyWorkJson(context);
|
|
163
|
+
validateWorkContext(value);
|
|
164
|
+
copied = value;
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
if (error instanceof WorkInputError)
|
|
168
|
+
throw new WorkInputError("WORK_CONTEXT_INVALID");
|
|
169
|
+
throw error;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
if (error instanceof WorkInputError)
|
|
174
|
+
return failure(error.code);
|
|
175
|
+
throw error;
|
|
176
|
+
}
|
|
177
|
+
if (!validWorkPath(path))
|
|
178
|
+
return failure("WORK_INSPECTION_PATH_INVALID");
|
|
179
|
+
try {
|
|
180
|
+
let info;
|
|
181
|
+
try {
|
|
182
|
+
info = await stat(path);
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
if (workFsError(error) && error.code === "ENOENT")
|
|
186
|
+
return missing();
|
|
187
|
+
throw error;
|
|
188
|
+
}
|
|
189
|
+
exists = true;
|
|
190
|
+
if (!info.isFile())
|
|
191
|
+
return failure("WORK_INSPECTION_NOT_REGULAR");
|
|
192
|
+
let handle;
|
|
193
|
+
try {
|
|
194
|
+
handle = await open(path, constants.O_RDONLY | constants.O_NONBLOCK);
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
if (workFsError(error) && error.code === "ENOENT")
|
|
198
|
+
return missing();
|
|
199
|
+
throw error;
|
|
200
|
+
}
|
|
201
|
+
let failed = false, bytes;
|
|
202
|
+
try {
|
|
203
|
+
if (!(await handle.stat()).isFile())
|
|
204
|
+
return failure("WORK_INSPECTION_NOT_REGULAR");
|
|
205
|
+
bytes = await readWorkBytes(handle);
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
failed = true;
|
|
209
|
+
throw error;
|
|
210
|
+
}
|
|
211
|
+
finally {
|
|
212
|
+
await closeWorkHandle(handle, failed);
|
|
213
|
+
}
|
|
214
|
+
const text = bytes.toString("utf8");
|
|
215
|
+
return freezeWork({ version: 4, status: "read", exists: true, ingestion: parseWorkLedgerText(text), projection: projectWorkLedger(text, copied), errors: [] });
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
if (error instanceof WorkInputError)
|
|
219
|
+
return failure(error.code);
|
|
220
|
+
if (workFsError(error))
|
|
221
|
+
return failure("WORK_INSPECTION_READ_FAILED");
|
|
222
|
+
throw error;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=work-ledger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"work-ledger.js","sourceRoot":"","sources":["../src/work-ledger.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACtF,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC3F,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EACL,iBAAiB,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EACzE,gBAAgB,EAAE,eAAe,EAAE,YAAY,EAAE,kBAAkB,GACpE,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AACrF,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAC5G,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EACL,cAAc,EAIuB,oBAAoB,GAC1D,MAAM,wBAAwB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AAEvC,SAAS,KAAK,CAAC,IAAa,EAAE,IAAmB,EAAE,KAA0C;IAC3F,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,QAAQ,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC3C,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;QACxG,MAAM,IAAI,cAAc,CAAC,qBAAqB,CAAC,CAAC;IAClD,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;IAC7B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC;QAClG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAAE,MAAM,IAAI,cAAc,CAAC,qBAAqB,CAAC,CAAC;IACxG,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,YAAY,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK;QAC3F,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;IAC7G,MAAM,KAAK,GAAG,iBAAiB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACjD,IAAI,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,GAAG,gBAAgB;QAAE,MAAM,IAAI,cAAc,CAAC,qBAAqB,CAAC,CAAC;IAC5H,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,IAA4E;IACjH,OAAO,KAAK,CAAC,IAAI,EAAE,eAAe,EAAE,UAAU,CAAkC,CAAC;AACnF,CAAC;AACD,MAAM,UAAU,sBAAsB,CAAC,IAA4E;IACjH,OAAO,KAAK,CAAC,IAAI,EAAE,eAAe,EAAE,UAAU,CAAkC,CAAC;AACnF,CAAC;AACD,MAAM,UAAU,wBAAwB,CAAC,IAAoE;IAC3G,OAAO,KAAK,CAAC,IAAI,EAAE,iBAAiB,EAAE,SAAS,CAAoC,CAAC;AACtF,CAAC;AACD,MAAM,UAAU,wBAAwB,CAAC,IAAoE;IAC3G,OAAO,KAAK,CAAC,IAAI,EAAE,iBAAiB,EAAE,SAAS,CAAoC,CAAC;AACtF,CAAC;AAED,QAAQ,CAAC,CAAC,KAAK,CAAC,IAAY;IAC1B,IAAI,KAAK,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC;IACxB,OAAO,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACtC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC;QAChF,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,OAAO;QACvB,KAAK,GAAG,GAAG,GAAG,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AACD,MAAM,KAAK,GAAG,CAAC,IAAY,EAAW,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEjE,2GAA2G;AAC3G,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,MAAM,UAAU,GAAG,CAAC,IAA4B,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IACjI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,UAAU,CAAC,qBAAqB,CAAC,CAAC;IACvE,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,eAAe;QAAE,OAAO,UAAU,CAAC,qBAAqB,CAAC,CAAC;IAChG,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC;QAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY;YAAE,OAAO,UAAU,CAAC,qBAAqB,CAAC,CAAC;IAC1H,MAAM,MAAM,GAAsB,EAAE,EAAE,MAAM,GAAqB,EAAE,CAAC;IACpE,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS;QAC9B,IAAI,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAC,CAAC;QAChE,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,CAAC,KAAK,YAAY,cAAc,CAAC;gBAAE,MAAM,KAAK,CAAC;YACpD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IACD,OAAO,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC,CAAC;AACvE,CAAC;AAED;sGACsG;AACtG,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,UAA6C,EAAE,gBAAgB,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE;IACtI,MAAM,KAAK,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,MAAM,GAAiC,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACzE,IAAI,MAAM,GAA6C,IAAI,CAAC;IAC5D,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;QACpC,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAC3B,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAA0B,CAAC;IACzE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,CAAC,KAAK,YAAY,cAAc,CAAC;YAAE,MAAM,KAAK,CAAC;QACpD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,sBAAsB,EAAE,CAAC,CAAC;IAC5D,CAAC;IACD,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvH,MAAM,SAAS,GAAG,kBAAkB,CAAC;QACnC,GAAG,KAAK,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAgB,EAAE,EAAE,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,mBAAmB,EAAE,EAAE,EAAE,CAAC,CAAC;QACpI,GAAG,iBAAiB,CAAC,MAAM,EAAE,SAAS,IAAI,IAAI,CAAC,CAAC,SAAS;KAC1D,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,EAAE,gBAAgB,EAAE,MAAM,EAAE,gBAAgB,EAAE,QAAQ,IAAI,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,IAAI,IAAI,EAAE,CAAC;IAC5I,SAAS,KAAK,CAAC,UAAwC,EAAE,QAA4C,EAAE,WAAgD,SAAS;QAC9J,OAAO,UAAU,CAAC,EAAE,GAAG,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,gBAAgB,EAAE,CAAC;YAC7G,SAAS,EAAE,kBAAkB,CAAC,CAAC,GAAG,QAAQ,EAAE,GAAG,SAAS,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IACnG,CAAC;IACD,IAAI,MAAM,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC,YAAY,EAAE,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,SAAS,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IACxH,MAAM,SAAS,GAAG,uBAAuB,CAAC,IAAI,EAAE,MAAO,CAAC,gBAAgB,CAAC,CAAC;IAC1E,IAAI,SAAS,CAAC,UAAU,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC,SAAS,CAAC,UAAU,EAAE,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAClH,MAAM,OAAO,GAAG,mBAAmB,CAAC,KAAK,EAAE,SAAS,CAAC,QAAS,CAAC,CAAC;IAChE,MAAM,UAAU,GAAG,qBAAqB,CAAC,KAAK,EAAE,SAAS,EAAE,MAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACvF,OAAO,UAAU,CAAC,EAAE,GAAG,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;AAC7G,CAAC;AAED,sGAAsG;AACtG,MAAM,UAAU,qBAAqB,CAAC,OAAyD,EAAE,KAAkC;IACjI,OAAO,eAAe,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AAChD,CAAC;AACD,uGAAuG;AACvG,MAAM,UAAU,yBAAyB,CAAC,OAAyD,EAAE,KAAkC;IACrI,OAAO,eAAe,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;AAC/C,CAAC;AACD,KAAK,UAAU,eAAe,CAAC,OAAyD,EAAE,KAAkC,EAAE,IAAa;IACzI,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACtC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,KAAK,QAAQ;QACxJ,CAAC,MAAM,CAAC,eAAe,CAAC,KAAK,KAAK,IAAI,IAAI,OAAO,MAAM,CAAC,eAAe,CAAC,KAAK,KAAK,QAAQ,CAAC;QAAE,MAAM,IAAI,cAAc,CAAC,qBAAqB,CAAC,CAAC;IACjJ,MAAM,IAAI,GAAW,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,GAAkB,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC;IAC5F,MAAM,SAAS,GAAG,iBAAiB,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;IACzD,MAAM,SAAS,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAC/C,IAAI,MAAM,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,GAAG,gBAAgB;QAAE,MAAM,IAAI,cAAc,CAAC,qBAAqB,CAAC,CAAC;IAC7G,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACvD,MAAM,gBAAgB,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,EAAE,SAAS,GAAG,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACjK,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,gBAAgB,IAAI,WAAW,CAAC,KAAK,CAAC;YAAE,MAAM,IAAI,oBAAoB,CAAC,0BAA0B,CAAC,CAAC;QACxH,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,0GAA0G;AAC1G,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAAqC,EAC3E,UAA6C,EAAE,gBAAgB,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE;IACxF,IAAI,MAAM,GAAmB,IAAI,CAAC;IAClC,MAAM,OAAO,GAAG,CAAC,IAAsC,EAAoC,EAAE,CAAC,UAAU,CAAC;QACvG,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;KACvG,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,GAAqC,EAAE,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK;QAC/G,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;IACnD,IAAI,IAAY,EAAE,MAAyC,CAAC;IAC5D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,KAAK,QAAQ;YAAE,MAAM,IAAI,cAAc,CAAC,qBAAqB,CAAC,CAAC;QACtM,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,KAAK,CAAC;YAAE,MAAM,IAAI,cAAc,CAAC,0BAA0B,CAAC,CAAC;QACrF,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;QACzB,IAAI,CAAC;YAAC,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;YAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;YAAC,MAAM,GAAG,KAAqD,CAAC;QAAC,CAAC;QACxI,OAAO,KAAK,EAAE,CAAC;YAAC,IAAI,KAAK,YAAY,cAAc;gBAAE,MAAM,IAAI,cAAc,CAAC,sBAAsB,CAAC,CAAC;YAAC,MAAM,KAAK,CAAC;QAAC,CAAC;IACvH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAAC,IAAI,KAAK,YAAY,cAAc;YAAE,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAAC,MAAM,KAAK,CAAC;IAAC,CAAC;IACjG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;QAAE,OAAO,OAAO,CAAC,8BAA8B,CAAC,CAAC;IACzE,IAAI,CAAC;QACH,IAAI,IAAI,CAAC;QACT,IAAI,CAAC;YAAC,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;QAAC,CAAC;QAChC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO,OAAO,EAAE,CAAC;YACpE,MAAM,KAAK,CAAC;QACd,CAAC;QACD,MAAM,GAAG,IAAI,CAAC;QACd,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAAE,OAAO,OAAO,CAAC,6BAA6B,CAAC,CAAC;QAClE,IAAI,MAAwC,CAAC;QAC7C,IAAI,CAAC;YAAC,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;QAAC,CAAC;QAC7E,OAAO,KAAK,EAAE,CAAC;YAAC,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO,OAAO,EAAE,CAAC;YAAC,MAAM,KAAK,CAAC;QAAC,CAAC;QACnG,IAAI,MAAM,GAAG,KAAK,EAAE,KAAa,CAAC;QAClC,IAAI,CAAC;YACH,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;gBAAE,OAAO,OAAO,CAAC,6BAA6B,CAAC,CAAC;YACnF,KAAK,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAAC,MAAM,GAAG,IAAI,CAAC;YAAC,MAAM,KAAK,CAAC;QAAC,CAAC;gBACvC,CAAC;YAAC,MAAM,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,CAAC;QAClD,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACpC,OAAO,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,mBAAmB,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;IACjK,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,cAAc;YAAE,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChE,IAAI,WAAW,CAAC,KAAK,CAAC;YAAE,OAAO,OAAO,CAAC,6BAA6B,CAAC,CAAC;QACtE,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -251,6 +251,7 @@ export function registerChainTool(pi: ExtensionAPI, session: GrantsSession): voi
|
|
|
251
251
|
signal,
|
|
252
252
|
{
|
|
253
253
|
preApproved: availableForStep,
|
|
254
|
+
toolCallId: _toolCallId,
|
|
254
255
|
// Only approvals actually offered to this step are attributed or consumed here.
|
|
255
256
|
approvalFacts: chainApprovalFacts(approvalAudit, availableForStep, step.agent ?? DELEGATE_SUBJECT),
|
|
256
257
|
onProgress: (update) => {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { allocateNativeSessionTarget } from "../src/native-session-target.ts";
|
|
2
|
+
import type { GrantsSession } from "./session.ts";
|
|
3
|
+
import type { ExecutionOccurrenceIds } from "./execution-occurrence.ts";
|
|
4
|
+
/** Shared delegate/all/chain host setup, before planning/audit; no tool-schema destination parameter. */
|
|
5
|
+
export async function nativeDelegationContext(session:GrantsSession,ids:ExecutionOccurrenceIds,budget:number|undefined,refused:boolean){
|
|
6
|
+
let sessionFile:string|undefined,refusal:string|undefined;
|
|
7
|
+
if(!refused&&session.nativeSessionRoot!==undefined){
|
|
8
|
+
try{sessionFile=await allocateNativeSessionTarget(session.nativeSessionRoot,ids.executionId);}
|
|
9
|
+
catch(error){refusal=`native retention target refused (${String(error)})`;}
|
|
10
|
+
}
|
|
11
|
+
return {extra:{fanoutBudget:budget,spawnId:ids.parentId,childSpawnId:ids.childId,childExecutionId:ids.executionId,sessionFile},refusal};
|
|
12
|
+
}
|
package/extensions/delegation.ts
CHANGED
|
@@ -241,7 +241,7 @@ export function registerDelegationTools(pi: ExtensionAPI, session: GrantsSession
|
|
|
241
241
|
session.fanoutBudget,
|
|
242
242
|
ctx,
|
|
243
243
|
signal,
|
|
244
|
-
{ onProgress: progress.sink(0) },
|
|
244
|
+
{ onProgress: progress.sink(0), toolCallId: _toolCallId },
|
|
245
245
|
);
|
|
246
246
|
progress.settle([outcome]);
|
|
247
247
|
|
|
@@ -259,7 +259,7 @@ export function registerDelegationTools(pi: ExtensionAPI, session: GrantsSession
|
|
|
259
259
|
|
|
260
260
|
return {
|
|
261
261
|
content: [{ type: "text", text: outcome.text || "(no output)" }],
|
|
262
|
-
details: { granted: outcome.granted, depth: outcome.depth, exitCode: outcome.exitCode },
|
|
262
|
+
details: { granted: outcome.granted, depth: outcome.depth, exitCode: outcome.exitCode, retention: outcome.retention },
|
|
263
263
|
};
|
|
264
264
|
},
|
|
265
265
|
});
|
|
@@ -317,7 +317,7 @@ export function registerDelegationTools(pi: ExtensionAPI, session: GrantsSession
|
|
|
317
317
|
return await runOneDelegation(
|
|
318
318
|
session, child,
|
|
319
319
|
newDelegationOccurrence(session, index),
|
|
320
|
-
split.perChild, ctx, signal, { onProgress: progress.sink(index) },
|
|
320
|
+
split.perChild, ctx, signal, { onProgress: progress.sink(index), toolCallId: _toolCallId },
|
|
321
321
|
);
|
|
322
322
|
} catch (error) {
|
|
323
323
|
infrastructureErrors.push(error);
|
|
@@ -353,6 +353,7 @@ export function registerDelegationTools(pi: ExtensionAPI, session: GrantsSession
|
|
|
353
353
|
budgetPerChild: split.perChild,
|
|
354
354
|
granted: outcomes.map((o) => o.granted),
|
|
355
355
|
refusals: outcomes.map((o) => o.refusal ?? null),
|
|
356
|
+
retention: outcomes.map((o) => o.retention ?? null),
|
|
356
357
|
},
|
|
357
358
|
};
|
|
358
359
|
},
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { withOrdinaryChild } from "./ordinary-runtime.ts";
|
|
1
2
|
import type { Delegation } from "../src/delegate.ts";
|
|
3
|
+
import { beginExecutionRetention, retentionConfigurationDigest, type RetentionStatus } from "../src/execution-retention.ts";
|
|
2
4
|
import { appendLedgerEvent, buildChildLifecycleEvent } from "../src/ledger.ts";
|
|
3
5
|
import { hasFinalizerError } from "../src/finalization.ts";
|
|
4
6
|
import { mergeChildEnv } from "../src/propagation.ts";
|
|
@@ -23,6 +25,9 @@ export interface DelegationOutcome {
|
|
|
23
25
|
aborted?: boolean;
|
|
24
26
|
truncated?: boolean;
|
|
25
27
|
spawnFailed?: boolean;
|
|
28
|
+
retention?: RetentionStatus;
|
|
29
|
+
/** A loud best-effort post-execution observation failure; execution ownership is still settled. */
|
|
30
|
+
control?: "failed";
|
|
26
31
|
}
|
|
27
32
|
|
|
28
33
|
/**
|
|
@@ -78,13 +83,17 @@ export interface ChildProgressUpdate {
|
|
|
78
83
|
* has already run, so failing closed there prevents nothing and used to discard completed work while
|
|
79
84
|
* blaming "ledger" (R-99). The failure is reported alongside the outcome instead of replacing it.
|
|
80
85
|
*/
|
|
81
|
-
export
|
|
86
|
+
export function executePlannedChild(input: Parameters<typeof executeChildBody>[0]): Promise<DelegationOutcome> {
|
|
87
|
+
return withOrdinaryChild(input, signal => executeChildBody({ ...input, signal }));
|
|
88
|
+
}
|
|
89
|
+
async function executeChildBody(input: {
|
|
82
90
|
session: GrantsSession;
|
|
83
91
|
plan: Delegation;
|
|
84
92
|
agent?: string;
|
|
85
93
|
childId: string;
|
|
86
94
|
executionId: string;
|
|
87
95
|
parentExecutionId: string | null;
|
|
96
|
+
toolCallId?: string;
|
|
88
97
|
cwd: string;
|
|
89
98
|
preparedWorkspace?: PreparedWorkspace;
|
|
90
99
|
signal?: AbortSignal;
|
|
@@ -134,6 +143,13 @@ export async function executePlannedChild(input: {
|
|
|
134
143
|
const executionSignal = signal
|
|
135
144
|
? AbortSignal.any([signal, leaseAbort.signal])
|
|
136
145
|
: writerLease ? leaseAbort.signal : undefined;
|
|
146
|
+
const retention = beginExecutionRetention({ executionId, parentExecutionId, childId,
|
|
147
|
+
toolCallId: input.toolCallId ?? null, executor: session.executor.kind, taskDigest: plan.taskDigest,
|
|
148
|
+
definitionDigest: plan.definitionDigest?.sha256 ?? null,
|
|
149
|
+
configurationDigest: retentionConfigurationDigest({ args: plan.args, effective: plan.effective, timeoutMs: configuredTimeoutMs }),
|
|
150
|
+
workspaceId: preparedWorkspace?.workspace.workspaceId ?? null });
|
|
151
|
+
const sessionFlag = plan.args.indexOf("--session");
|
|
152
|
+
if (sessionFlag >= 0) retention.observeSession({ source: "pi-session-file", value: plan.args[sessionFlag + 1] });
|
|
137
153
|
let releaseReason = "failed";
|
|
138
154
|
let retainWriterLease = false;
|
|
139
155
|
let terminalAttempted = false;
|
|
@@ -171,7 +187,12 @@ export async function executePlannedChild(input: {
|
|
|
171
187
|
timeoutMs: remainingTimeoutMs,
|
|
172
188
|
keepPane: writerLease ? false : process.env[ENV_HERDR_KEEP_PANE] === "1",
|
|
173
189
|
closeOnSettle: Boolean(writerLease),
|
|
174
|
-
onPane: (paneId, agentName) =>
|
|
190
|
+
onPane: (paneId, agentName) => {
|
|
191
|
+
retention.native({ paneId, agentName });
|
|
192
|
+
onProgress?.({ paneId, agentName, state: "starting" });
|
|
193
|
+
},
|
|
194
|
+
onObservation: (bytes) => retention.capture("paneSnapshot", bytes, true),
|
|
195
|
+
onSessionReference: (reference) => retention.observeSession(reference),
|
|
175
196
|
onRunning: (paneId, agentName) => {
|
|
176
197
|
// Record first: runHerdrPane isolates this display callback, so a renderer exception after the
|
|
177
198
|
// observation cannot suppress the authoritative running event.
|
|
@@ -179,6 +200,7 @@ export async function executePlannedChild(input: {
|
|
|
179
200
|
onProgress?.({ paneId, agentName, state: "running" });
|
|
180
201
|
},
|
|
181
202
|
onTab: preparedWorkspace ? (tabId) => preparedWorkspace.lease.attachHerdrTab(tabId) : undefined,
|
|
203
|
+
onNativeTab: (tabId) => retention.native({ tabId }),
|
|
182
204
|
onSnapshot: onProgress ? (snapshot) => onProgress({ snapshot }) : undefined,
|
|
183
205
|
})
|
|
184
206
|
: await runChild({
|
|
@@ -192,17 +214,23 @@ export async function executePlannedChild(input: {
|
|
|
192
214
|
timeoutMs: Math.max(1, remainingTimeoutMs - terminationGraceMs),
|
|
193
215
|
hardDeadlineAt: Date.parse(deadlineAt),
|
|
194
216
|
onOutput: onProgress ? (chunk) => onProgress({ chunk }) : undefined,
|
|
217
|
+
onObservation: (stream, bytes) => retention.capture(stream, bytes),
|
|
195
218
|
onSpawn: (pid) => {
|
|
196
219
|
// Lease attachment is a security hook and may fail the spawn. The shared reporters isolate
|
|
197
220
|
// display exceptions before they reach this callback; runChild deliberately kills on any error
|
|
198
221
|
// here, so presentation must never be added directly without that reporter boundary.
|
|
199
222
|
preparedWorkspace?.lease.attachProcess(pid);
|
|
223
|
+
retention.native({ pid });
|
|
200
224
|
recordRunning("process");
|
|
201
225
|
onProgress?.({ state: "running" });
|
|
202
226
|
},
|
|
203
227
|
});
|
|
204
228
|
|
|
229
|
+
if (sessionFlag >= 0) retention.observeSession({ source: "pi-session-file", value: plan.args[sessionFlag + 1] });
|
|
230
|
+
retention.capture("result", Buffer.from(output.text), true);
|
|
205
231
|
const childFailed = Boolean(output.spawnError || output.aborted || output.timedOut || output.code !== 0);
|
|
232
|
+
retention.finish({ code: output.code, signal: output.signal ?? null, timedOut: output.timedOut,
|
|
233
|
+
aborted: output.aborted, truncated: output.truncated, failed: childFailed });
|
|
206
234
|
releaseReason = output.timedOut ? "timeout" : output.aborted ? "cancelled" : childFailed ? "failed" : "completed";
|
|
207
235
|
if (ledgerPath) {
|
|
208
236
|
terminalAttempted = true;
|
|
@@ -286,6 +314,7 @@ export async function executePlannedChild(input: {
|
|
|
286
314
|
await teardown();
|
|
287
315
|
return withTeardownNotes(succeeded);
|
|
288
316
|
} catch (error) {
|
|
317
|
+
retention.finish({ code: null, signal: null, timedOut: false, aborted: Boolean(signal?.aborted), truncated: false, failed: true });
|
|
289
318
|
retainWriterLease = Boolean(writerLease && isHerdrWriterCloseFailure(error));
|
|
290
319
|
if (ledgerPath && !terminalAttempted) {
|
|
291
320
|
// Best-effort: this records the failure, so it must not REPLACE the failure. A strict append that
|
|
@@ -338,8 +367,9 @@ function errorWithTeardownNotes(error: unknown, notes: readonly string[]): unkno
|
|
|
338
367
|
}
|
|
339
368
|
|
|
340
369
|
function withTeardownNotes(outcome: DelegationOutcome): DelegationOutcome {
|
|
341
|
-
|
|
342
|
-
|
|
370
|
+
const observed = { ...outcome, retention: retention.status() };
|
|
371
|
+
if (teardownFailures.length === 0) return observed;
|
|
372
|
+
return { ...observed, control: "failed", reason: [outcome.reason, ...teardownFailures].filter(Boolean).join("; ") };
|
|
343
373
|
}
|
|
344
374
|
|
|
345
375
|
async function teardown(): Promise<void> {
|
package/extensions/grants.ts
CHANGED
|
@@ -47,6 +47,7 @@ import {
|
|
|
47
47
|
openDashboardCommand,
|
|
48
48
|
} from "../src/dashboard-handshake.ts";
|
|
49
49
|
|
|
50
|
+
import { associateOrdinaryHost } from "../src/ordinary-children.ts";
|
|
50
51
|
export default function (pi: ExtensionAPI) {
|
|
51
52
|
// The path pi loads as the extension, so a child granted `tool:delegate` can be started with `-e <this>`.
|
|
52
53
|
// Only this file can say so about itself, which is why the session takes it rather than deriving it.
|
|
@@ -59,6 +60,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
59
60
|
})();
|
|
60
61
|
|
|
61
62
|
const session = createGrantsSession(extensionPath);
|
|
63
|
+
associateOrdinaryHost(pi,session);
|
|
62
64
|
const dashboardPluginRoot = fileURLToPath(new URL("../herdr-plugin/", import.meta.url));
|
|
63
65
|
const dashboardPaths = defaultDashboardPaths(
|
|
64
66
|
process.env.PI_CODING_AGENT_DIR?.trim() || join(homedir(), ".pi", "agent"),
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { retainSessionChild } from "../src/ordinary-children.ts";
|
|
2
|
+
import { dataDigest } from "../src/debrief-contract.ts";
|
|
3
|
+
import { runWithFinalizers } from "../src/finalization.ts";
|
|
4
|
+
import { releaseDelegationWorkspace,type PreparedWorkspace } from "./workspace-runtime.ts";
|
|
5
|
+
import type { GrantsSession } from "./session.ts";
|
|
6
|
+
import type { DelegationOutcome } from "./execute-child.ts";
|
|
7
|
+
/** One wrapper around the original executor. It neither consumes nor replaces the caller's promise. */
|
|
8
|
+
export async function withOrdinaryChild(input:{session:GrantsSession;executionId:string;parentExecutionId:string|null;childId:string;toolCallId?:string;signal?:AbortSignal;preparedWorkspace?:PreparedWorkspace},operation:(signal?:AbortSignal)=>Promise<DelegationOutcome>){
|
|
9
|
+
let retained:ReturnType<typeof retainSessionChild>;
|
|
10
|
+
try{retained=retainSessionChild(input.session,{executionId:input.executionId,parentExecutionId:input.parentExecutionId,toolCallId:input.toolCallId??null},input.signal);}
|
|
11
|
+
catch(error){return runWithFinalizers(async()=>{throw error;},[{label:"ordinary admission workspace release",run:async()=>{await releaseDelegationWorkspace({prepared:input.preparedWorkspace,childId:input.childId,executionId:input.executionId,parentExecutionId:input.parentExecutionId,ledgerPath:input.session.ledgerPath,reason:"refused"});}}]);}
|
|
12
|
+
try{const outcome=await operation(retained?.signal??input.signal);retained?.settle({ok:outcome.ok,exitCode:outcome.exitCode,aborted:outcome.aborted??false,outputDigest:dataDigest(outcome.text)},outcome.control??"not-assessed",outcome.control==="failed"?"not-assessed":outcome.control??"not-assessed");return outcome;}
|
|
13
|
+
catch(error){retained?.settle({failure:"original executor threw; inspect original caller"},"unknown");throw error;}
|
|
14
|
+
}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* tool surface is observed.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
+
import { nativeDelegationContext } from "./delegation-native.ts";
|
|
14
15
|
import { DELEGATE_SUBJECT, shouldSeekApproval } from "../src/approval.ts";
|
|
15
16
|
import { planDelegation } from "../src/delegate.ts";
|
|
16
17
|
import {
|
|
@@ -201,6 +202,8 @@ export async function runOneDelegation(
|
|
|
201
202
|
* mistake unspellable.
|
|
202
203
|
*/
|
|
203
204
|
options: {
|
|
205
|
+
/** Actual public execute argument, never read from model-authored correlation or output. */
|
|
206
|
+
toolCallId?: string;
|
|
204
207
|
/** Progress for the parent's status block (ADR-0032). Display only. */
|
|
205
208
|
onProgress?: (update: {
|
|
206
209
|
/** Appended (process executor: a genuine byte stream). */
|
|
@@ -254,12 +257,6 @@ export async function runOneDelegation(
|
|
|
254
257
|
boundWorkspaceId: spec.workspace?.workspace_id,
|
|
255
258
|
boundContextId: spec.correlation?.context_id,
|
|
256
259
|
};
|
|
257
|
-
const extra = {
|
|
258
|
-
fanoutBudget: budget,
|
|
259
|
-
spawnId: ids.parentId,
|
|
260
|
-
childSpawnId: ids.childId,
|
|
261
|
-
childExecutionId: ids.executionId,
|
|
262
|
-
};
|
|
263
260
|
|
|
264
261
|
// ADR-0031: herdr was DEMANDED (`PI_GRANTS_HERDR=1`) and is not answering. Refused rather than relocated —
|
|
265
262
|
// the operator chose that over falling back, so the ledger can never name a child that ran somewhere nobody
|
|
@@ -275,13 +272,15 @@ export async function runOneDelegation(
|
|
|
275
272
|
// `ctx: null` rather than skipping the plan entirely: the ledger still gets a full, honest record of what was
|
|
276
273
|
// requested and refused, and stored approvals still count toward it — nothing is *hidden*, only nobody is
|
|
277
274
|
// *asked*. It is the same argument `/grants` uses for its preview.
|
|
278
|
-
|
|
275
|
+
let executorRefusal = session.executor.refusal;
|
|
279
276
|
const modelRefusal = preflightModel(
|
|
280
277
|
request.model,
|
|
281
278
|
ctx.modelRegistry,
|
|
282
279
|
session.modelResolutionCache,
|
|
283
280
|
session.allowUnresolvedModels,
|
|
284
281
|
);
|
|
282
|
+
const {extra,refusal:nativeRefusal}=await nativeDelegationContext(session,ids,budget,Boolean(executorRefusal||modelRefusal));
|
|
283
|
+
executorRefusal ||= nativeRefusal;
|
|
285
284
|
let preparedWorkspace: PreparedWorkspace | undefined;
|
|
286
285
|
let approvalOutcome: ApprovalOutcome | undefined;
|
|
287
286
|
let plan: ReturnType<typeof planDelegation>;
|
|
@@ -388,6 +387,7 @@ export async function runOneDelegation(
|
|
|
388
387
|
childId: ids.childId,
|
|
389
388
|
executionId: ids.executionId,
|
|
390
389
|
parentExecutionId: ids.parentExecutionId,
|
|
390
|
+
toolCallId: options.toolCallId,
|
|
391
391
|
cwd: ctx.cwd,
|
|
392
392
|
preparedWorkspace,
|
|
393
393
|
signal,
|
package/extensions/session.ts
CHANGED
|
@@ -47,6 +47,7 @@ import { ENV_WORKSPACE_REGISTRY } from "../src/workspace.ts";
|
|
|
47
47
|
import type { GrantStoreRefusalReason } from "../src/grant-store.ts";
|
|
48
48
|
import { republishable } from "./approvals.ts";
|
|
49
49
|
import { storedGrantSessionState } from "./stored-grant-session.ts";
|
|
50
|
+
import { nativeSessionRootFromEnv, type NativeSessionHost } from "../src/native-session-target.ts";
|
|
50
51
|
import { ENV_ALLOW_UNRESOLVED_MODELS } from "../src/model-preflight.ts";
|
|
51
52
|
|
|
52
53
|
/**
|
|
@@ -79,7 +80,7 @@ export { ENV_HERDR_WORKSPACE } from "../src/herdr-cli.ts";
|
|
|
79
80
|
/** Keep each child's pane after it finishes, for inspection. Off by default: fan-out would flood it. */
|
|
80
81
|
export const ENV_HERDR_KEEP_PANE = "PI_GRANTS_HERDR_KEEP_PANE";
|
|
81
82
|
|
|
82
|
-
export interface GrantsSession {
|
|
83
|
+
export interface GrantsSession extends NativeSessionHost {
|
|
83
84
|
/**
|
|
84
85
|
* False when neither `PI_GRANTS_GRANT` nor a stored grant applies: the session holds the wildcard and
|
|
85
86
|
* nothing is governed.
|
|
@@ -318,6 +319,7 @@ export function createGrantsSession(extensionPath: string | undefined): GrantsSe
|
|
|
318
319
|
*/
|
|
319
320
|
mayDelegate: !governed || inherited.includes(DELEGATE_CAPABILITY) || inherited.includes(WILDCARD),
|
|
320
321
|
allowUnresolvedModels: process.env[ENV_ALLOW_UNRESOLVED_MODELS] === "1",
|
|
322
|
+
nativeSessionRoot: nativeSessionRootFromEnv(process.env),
|
|
321
323
|
modelResolutionCache: new Map<string, boolean>(),
|
|
322
324
|
extensionPath,
|
|
323
325
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-daddy",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "Capability governance for pi sub-agents: spawn Agent Skills (SKILL.md) definitions whose allowed-tools becomes a grant that can only narrow going down a delegation tree, enforced by pi's own --tools allowlist, with an append-only ledger.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
@@ -37,6 +37,67 @@
|
|
|
37
37
|
"types": "./dist/ledger.d.ts",
|
|
38
38
|
"default": "./dist/ledger.js"
|
|
39
39
|
},
|
|
40
|
+
"./work-ledger": {
|
|
41
|
+
"types": "./dist/work-ledger.d.ts",
|
|
42
|
+
"default": "./dist/work-ledger.js"
|
|
43
|
+
},
|
|
44
|
+
"./factory-order": {
|
|
45
|
+
"types": "./dist/factory-order.d.ts",
|
|
46
|
+
"default": "./dist/factory-order.js"
|
|
47
|
+
},
|
|
48
|
+
"./experiment": {
|
|
49
|
+
"types": "./dist/experiment.d.ts",
|
|
50
|
+
"default": "./dist/experiment.js"
|
|
51
|
+
},
|
|
52
|
+
"./dashboard-harness": {
|
|
53
|
+
"types": "./dist/dashboard-harness.d.ts",
|
|
54
|
+
"default": "./dist/dashboard-harness.js"
|
|
55
|
+
},
|
|
56
|
+
"./dashboard-host": {
|
|
57
|
+
"types": "./dist/dashboard-host.d.ts",
|
|
58
|
+
"default": "./dist/dashboard-host.js"
|
|
59
|
+
},
|
|
60
|
+
"./dashboard-host-transport": {
|
|
61
|
+
"types": "./dist/dashboard-host-transport.d.ts",
|
|
62
|
+
"default": "./dist/dashboard-host-transport.js"
|
|
63
|
+
},
|
|
64
|
+
"./debrief-host": {
|
|
65
|
+
"types": "./dist/debrief-host.d.ts",
|
|
66
|
+
"default": "./dist/debrief-host.js"
|
|
67
|
+
},
|
|
68
|
+
"./contracts/debrief/v2/*": "./contracts/debrief/v2/*",
|
|
69
|
+
"./debrief": {
|
|
70
|
+
"types": "./dist/debrief.d.ts",
|
|
71
|
+
"default": "./dist/debrief.js"
|
|
72
|
+
},
|
|
73
|
+
"./daily-view": {
|
|
74
|
+
"types": "./dist/daily-view.d.ts",
|
|
75
|
+
"default": "./dist/daily-view.js"
|
|
76
|
+
},
|
|
77
|
+
"./intent-control": {
|
|
78
|
+
"types": "./dist/intent-control.d.ts",
|
|
79
|
+
"default": "./dist/intent-control.js"
|
|
80
|
+
},
|
|
81
|
+
"./dispatch-control": {
|
|
82
|
+
"types": "./dist/dispatch-control.d.ts",
|
|
83
|
+
"default": "./dist/dispatch-control.js"
|
|
84
|
+
},
|
|
85
|
+
"./resource-budget": {
|
|
86
|
+
"types": "./dist/resource-budget.d.ts",
|
|
87
|
+
"default": "./dist/resource-budget.js"
|
|
88
|
+
},
|
|
89
|
+
"./producer-ipc": {
|
|
90
|
+
"types": "./dist/producer-ipc.d.ts",
|
|
91
|
+
"default": "./dist/producer-ipc.js"
|
|
92
|
+
},
|
|
93
|
+
"./effect-profile": {
|
|
94
|
+
"types": "./dist/effect-profile.d.ts",
|
|
95
|
+
"default": "./dist/effect-profile.js"
|
|
96
|
+
},
|
|
97
|
+
"./execution-retention": {
|
|
98
|
+
"types": "./dist/execution-retention.d.ts",
|
|
99
|
+
"default": "./dist/execution-retention.js"
|
|
100
|
+
},
|
|
40
101
|
"./spawn": {
|
|
41
102
|
"types": "./dist/spawn.d.ts",
|
|
42
103
|
"default": "./dist/spawn.js"
|
|
@@ -137,6 +198,19 @@
|
|
|
137
198
|
"types": "./dist/dashboard-render.d.ts",
|
|
138
199
|
"default": "./dist/dashboard-render.js"
|
|
139
200
|
},
|
|
201
|
+
"./contracts/factory-order/v1/*": "./contracts/factory-order/v1/*",
|
|
202
|
+
"./contracts/experiment/v1/*": "./contracts/experiment/v1/*",
|
|
203
|
+
"./contracts/producer-ipc/v1/*": "./contracts/producer-ipc/v1/*",
|
|
204
|
+
"./contracts/debrief/v1/*": "./contracts/debrief/v1/*",
|
|
205
|
+
"./contracts/intent-control/v2/request.schema.json": "./contracts/intent-control/v2/request.schema.json",
|
|
206
|
+
"./contracts/intent-control/v1/request.schema.json": "./contracts/intent-control/v1/request.schema.json",
|
|
207
|
+
"./contracts/dispatch-control/v1/request.schema.json": "./contracts/dispatch-control/v1/request.schema.json",
|
|
208
|
+
"./contracts/daily-view/v1/fixtures/*": "./contracts/daily-view/v1/fixtures/*",
|
|
209
|
+
"./contracts/daily-view/v1/p03/projection.schema.json": "./contracts/daily-view/v1/p03/projection.schema.json",
|
|
210
|
+
"./contracts/execution-retention/v2/manifest.schema.json": "./contracts/execution-retention/v2/manifest.schema.json",
|
|
211
|
+
"./contracts/execution-retention/v2/fixtures/*": "./contracts/execution-retention/v2/fixtures/*",
|
|
212
|
+
"./contracts/ledger/v4/ledger-event.schema.json": "./contracts/ledger/v4/ledger-event.schema.json",
|
|
213
|
+
"./contracts/ledger/v4/fixtures/*.json": "./contracts/ledger/v4/fixtures/*.json",
|
|
140
214
|
"./contracts/ledger/v3/ledger-event.schema.json": "./contracts/ledger/v3/ledger-event.schema.json",
|
|
141
215
|
"./contracts/ledger/v3/fixtures/*.json": "./contracts/ledger/v3/fixtures/*.json",
|
|
142
216
|
"./contracts/ledger/v2/ledger-event.schema.json": "./contracts/ledger/v2/ledger-event.schema.json",
|
|
@@ -159,13 +233,13 @@
|
|
|
159
233
|
"scripts": {
|
|
160
234
|
"build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json",
|
|
161
235
|
"typecheck": "tsc -p tsconfig.check.json",
|
|
162
|
-
"test": "node
|
|
236
|
+
"test": "node scripts/unit-tests.ts",
|
|
163
237
|
"test:integration": "node --test test-integration/*.it.ts",
|
|
164
238
|
"test:integration:ci": "node --test test-integration/approval.it.ts test-integration/governance.it.ts",
|
|
165
239
|
"contracts:generate": "node scripts/generate-ledger-v3-contract.ts",
|
|
240
|
+
"contracts:generate:v4": "node scripts/generate-ledger-v4-contract.ts contracts/ledger/v4",
|
|
166
241
|
"prepack": "npm run build",
|
|
167
|
-
"test:smoke": "node scripts/smoke-installed.mjs"
|
|
168
|
-
"test:mutation": "node scripts/mutation-audit.mjs"
|
|
242
|
+
"test:smoke": "node scripts/smoke-installed.mjs"
|
|
169
243
|
},
|
|
170
244
|
"main": "./dist/index.js",
|
|
171
245
|
"types": "./dist/index.d.ts",
|