@lapxo/bound 0.2.4 → 0.2.5
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/CITATION.cff +1 -1
- package/TARGET.bound +44 -39
- package/dist/cli/accept.js +72 -590
- package/dist/cli/act-result.js +3 -103
- package/dist/cli/args.js +3 -44
- package/dist/cli/custodian.js +2 -29
- package/dist/cli/host.js +4 -32
- package/dist/cli/names.js +1 -12
- package/dist/cli/native-descendant.js +1 -19
- package/dist/cli/native.js +3 -60
- package/dist/cli/observe.js +1 -13
- package/dist/cli/owner.js +3 -139
- package/dist/cli/pass.js +21 -321
- package/dist/cli/place.js +6 -282
- package/dist/cli/release-result.js +3 -80
- package/dist/cli/retained-judgment.js +1 -25
- package/dist/cli/standing-result.js +4 -19
- package/dist/cli/takes.js +10 -112
- package/dist/cli/verb.d.ts +1 -2
- package/dist/cli/verb.js +83 -684
- package/dist/engine/computation.js +2 -0
- package/dist/engine/conformance.js +4 -0
- package/dist/engine/encoding.js +1 -2
- package/dist/engine/index.d.ts +1 -13
- package/dist/engine/index.js +2 -11
- package/dist/engine/object.js +1 -38
- package/dist/engine/ports.js +2 -117
- package/dist/fold/admission-history.js +1 -17
- package/dist/fold/bootstrap-anchor.js +1 -28
- package/dist/fold/ceilings.js +1 -142
- package/dist/fold/claims.js +2 -132
- package/dist/fold/closed.js +24 -235
- package/dist/fold/configures.js +1 -25
- package/dist/fold/digests.js +10 -226
- package/dist/fold/evidence.js +1 -22
- package/dist/fold/fold-worker.js +1 -13
- package/dist/fold/kept.js +12 -173
- package/dist/fold/keys.js +3 -91
- package/dist/fold/laid.js +3 -90
- package/dist/fold/nos.js +1 -48
- package/dist/fold/object.js +1 -2
- package/dist/fold/observed.js +27 -534
- package/dist/fold/opened.js +1 -33
- package/dist/fold/own.js +3 -217
- package/dist/fold/paid.js +1 -92
- package/dist/fold/place-inputs.js +1 -70
- package/dist/fold/places.js +3 -100
- package/dist/fold/rank.js +1 -9
- package/dist/fold/reach.js +1 -83
- package/dist/fold/readers.js +6 -142
- package/dist/fold/receipts.js +1 -47
- package/dist/fold/region-declarations.js +1 -13
- package/dist/fold/region.js +8 -286
- package/dist/fold/release-policy.js +1 -101
- package/dist/fold/resolved.js +6 -145
- package/dist/fold/roles.js +2 -59
- package/dist/fold/second.js +4 -71
- package/dist/fold/shards.js +12 -100
- package/dist/fold/signed.js +3 -81
- package/dist/fold/signers.js +1 -54
- package/dist/fold/stranger.js +6 -24
- package/dist/fold/views.js +1 -66
- package/dist/fold/wire.js +1 -46
- package/dist/fold/zoom.js +3 -81
- package/dist/host/act-cost.js +1 -25
- package/dist/host/adapters/keys/ed25519.js +1 -30
- package/dist/host/adapters/modules/javascript.js +1 -50
- package/dist/host/adapters/transport/http.js +1 -28
- package/dist/host/admitted-place.js +1 -35
- package/dist/host/archive.js +1 -152
- package/dist/host/call-context.js +1 -14
- package/dist/host/capsule-process.js +2 -62
- package/dist/host/capsule.js +9 -171
- package/dist/host/cell-receipts.js +12 -128
- package/dist/host/commit-result.js +1 -5
- package/dist/host/content-needed.js +1 -8
- package/dist/host/content-store.js +1 -31
- package/dist/host/contextual-place.js +2 -72
- package/dist/host/digest.js +2 -15
- package/dist/host/hash.js +1 -9
- package/dist/host/host-controls.js +1 -19
- package/dist/host/in-process-act.js +3 -84
- package/dist/host/in-process-context.js +3 -91
- package/dist/host/in-process-root.js +6 -84
- package/dist/host/in-process.js +4 -55
- package/dist/host/index.d.ts +1 -15
- package/dist/host/index.js +1 -7
- package/dist/host/io.js +1 -11
- package/dist/host/lifetime.js +1 -79
- package/dist/host/located.js +6 -105
- package/dist/host/native/bounded-file.js +1 -32
- package/dist/host/native/command.js +1 -91
- package/dist/host/native/control-bridge-worker.js +2 -88
- package/dist/host/native/control-bridge.js +1 -110
- package/dist/host/native/control-selection.js +1 -32
- package/dist/host/native/custody.js +1 -91
- package/dist/host/native/deadline.js +1 -28
- package/dist/host/native/descendants.js +1 -528
- package/dist/host/native/generated-custodian.js +5 -267
- package/dist/host/native/generated.js +1 -379
- package/dist/host/native/image.js +1 -45
- package/dist/host/native/jobs.js +2 -148
- package/dist/host/native/loader.js +1 -269
- package/dist/host/native/materialize.js +1 -175
- package/dist/host/native/module-closure.js +1 -130
- package/dist/host/native/module-delivery.d.ts +1 -62
- package/dist/host/native/module-delivery.js +1 -151
- package/dist/host/native/module-syntax.js +1 -69
- package/dist/host/native/native-binary.js +1 -115
- package/dist/host/native/native-program.js +1 -72
- package/dist/host/native/node-jobs.js +3 -187
- package/dist/host/native/node-launch.js +1 -159
- package/dist/host/native/preload.js +1 -45
- package/dist/host/native/reading.js +1 -249
- package/dist/host/native/receipt-environment.js +1 -41
- package/dist/host/native/references.js +1 -30
- package/dist/host/native/root.js +1 -37
- package/dist/host/native/route.js +1 -216
- package/dist/host/native/runtime.js +1 -9
- package/dist/host/native-reader-context.js +1 -8
- package/dist/host/native-receiver.js +1 -25
- package/dist/host/objects.js +1 -38
- package/dist/host/order.js +1 -2
- package/dist/host/place-act-transaction.js +4 -78
- package/dist/host/place-clock-selection.js +5 -124
- package/dist/host/ports/ingress.js +2 -57
- package/dist/host/ports/local-act.js +5 -183
- package/dist/host/ports/place-act.js +1 -134
- package/dist/host/ports/publication.js +1 -56
- package/dist/host/ports/signing.js +1 -74
- package/dist/host/ports/store.js +1 -18
- package/dist/host/ports/transport.js +1 -48
- package/dist/host/process-lifetime.js +1 -17
- package/dist/host/provide.js +1 -183
- package/dist/host/read-only.js +1 -9
- package/dist/host/reading-closures.js +7 -227
- package/dist/host/reading-context.js +1 -53
- package/dist/host/reading-identity-types.js +0 -0
- package/dist/host/reading-identity.js +3 -0
- package/dist/host/reading-preparation.js +6 -0
- package/dist/host/reference-authenticated.d.ts +1 -40
- package/dist/host/reference-authenticated.js +3 -100
- package/dist/host/reference-contracts.js +1 -6
- package/dist/host/reference-export.js +6 -81
- package/dist/host/reference-native-api.d.ts +1 -3
- package/dist/host/reference-native-api.js +1 -3
- package/dist/host/reference-native.js +1 -74
- package/dist/host/reference-profile.js +1 -63
- package/dist/host/reference-standing.js +2 -18
- package/dist/host/reference.js +1 -24
- package/dist/host/refusals.js +2 -43
- package/dist/host/release.js +4 -256
- package/dist/host/root-clock-source.js +1 -307
- package/dist/host/selected-capsules.js +1 -50
- package/dist/host/selected-topos.js +1 -80
- package/dist/host/signature-era.js +1 -12
- package/dist/host/signing.js +2 -48
- package/dist/host/source-content.js +2 -111
- package/dist/host/standing-carrier.js +1 -18
- package/dist/host/standing-projection.js +1 -50
- package/dist/host/timing.js +1 -7
- package/dist/host/walk.js +20 -193
- package/dist/judge/late.js +1 -33
- package/dist/judge/take.js +2 -75
- package/dist/judge/widening.js +1 -25
- package/dist/land/act.js +8 -336
- package/dist/land/alias.js +1 -41
- package/dist/land/held.js +1 -23
- package/dist/land/inert.js +1 -33
- package/dist/land/leaving.js +1 -55
- package/dist/land/ledger.js +7 -188
- package/dist/land/owned.js +4 -66
- package/dist/land/sign.js +1 -53
- package/dist/land/standing-pin.js +1 -49
- package/dist/land/vouched.js +1 -112
- package/dist/land/withdraw.js +1 -24
- package/dist/observe/files.js +1 -88
- package/dist/observe/identity.js +1 -61
- package/dist/observe/match.js +1 -8
- package/dist/observe/regions.js +7 -306
- package/dist/observe/run.js +2 -41
- package/dist/observe/runner.js +4 -101
- package/dist/public-types.d.ts +1114 -0
- package/dist/render/capsule.js +1 -30
- package/dist/render/field.js +1 -40
- package/dist/render/names.js +1 -4
- package/dist/render/open.js +1 -61
- package/dist/render/page.js +1 -7
- package/dist/render/receipts.js +1 -47
- package/dist/render/shape.js +1 -74
- package/dist/render/target.js +4 -52
- package/dist/render/view.js +7 -197
- package/dist/vendor/50086958553b9376d600583f7dff354196bfeb41170fc6d1482ca7bea7c493e2.LICENSE +21 -0
- package/dist/vendor/b3e938d28f88a1851af303a40c749e12ebd5a686daac4f0b343b5cdd2e040419.LICENSE +21 -0
- package/dist/vendor/bundle.json +1 -0
- package/dist/vendor/library11.js +1 -0
- package/dist/vendor/object-provider.js +42 -0
- package/dist/vendor/runtime.js +38 -0
- package/dist/vendor/sources.json +1 -0
- package/dist/wasm/adapter.d.ts +1 -51
- package/dist/wasm/adapter.js +1 -180
- package/dist/wasm/node-worker.js +1 -13
- package/dist/wasm/object.js +1 -76
- package/dist/wasm/worker.js +1 -7
- package/docs/contracts/closure-delivery.md +1 -1
- package/docs/contracts/closure-delivery.publication.json +1 -1
- package/docs/contracts/conformance.json +142 -0
- package/docs/contracts/determinism.bound +9 -0
- package/docs/contracts/engine-object-projection.publication.json +1 -1
- package/docs/contracts/engine.md +21 -1
- package/docs/contracts/native-publication.inventory.json +2 -1
- package/docs/contracts/optional-wasm-adapter.publication.json +1 -1
- package/docs/contracts/reading-identity.md +37 -0
- package/docs/contracts/reading-identity.publication.json +25 -0
- package/docs/contracts/refusals.bound +51 -0
- package/docs/contracts/refusals.md +18 -3
- package/docs/contracts/refusals.publication.json +2 -2
- package/docs/contracts/views.md +8 -0
- package/docs/reference.md +1 -0
- package/package.json +23 -34
- package/receipts.bound +11627 -10323
- package/samples/reading-identity/no.json +20 -0
- package/samples/reading-identity/yes.json +46 -0
- package/vectors/native/reading-identity.vector.json +101 -0
- package/vectors/native/refusals.vector.json +104 -0
- package/vendor/syntax/LICENSE.md +7 -0
- package/vendor/syntax/parser.js +1 -0
- package/.github/workflows/release.yml +0 -67
- package/.github/workflows/test.yml +0 -35
- package/dist/engine/object.d.ts +0 -17
- package/dist/engine/ports.d.ts +0 -37
- package/dist/fold/claims.d.ts +0 -29
- package/dist/host/call-context.d.ts +0 -20
- package/dist/host/commit-result.d.ts +0 -6
- package/dist/host/in-process-act.d.ts +0 -82
- package/dist/host/in-process-context.d.ts +0 -46
- package/dist/host/in-process-root.d.ts +0 -117
- package/dist/host/in-process.d.ts +0 -41
- package/dist/host/native/module-closure.d.ts +0 -35
- package/dist/host/native-receiver.d.ts +0 -19
- package/dist/host/place-act-transaction.d.ts +0 -24
- package/dist/host/place-clock-selection.d.ts +0 -55
- package/dist/host/ports/local-act.d.ts +0 -44
- package/dist/host/ports/place-act.d.ts +0 -49
- package/dist/host/ports/publication.d.ts +0 -10
- package/dist/host/reference-export.d.ts +0 -33
- package/dist/host/reference-native.d.ts +0 -30
- package/dist/host/reference-profile.d.ts +0 -23
- package/dist/host/refusals.d.ts +0 -14
- package/dist/host/root-clock-source.d.ts +0 -86
|
@@ -1,267 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import { join } from 'node:path';
|
|
7
|
-
import { randomBytes } from 'node:crypto';
|
|
8
|
-
import { canonicalJson } from "./reading.js";
|
|
9
|
-
import { verifyNativeBinary, nativeBinaryProjection } from "./native-binary.js";
|
|
10
|
-
import { commandRequest, commandResponse } from '@lapxo/topos/contract';
|
|
11
|
-
import { assertProducerInterpretation, chargeProducerRequest, createGeneratedProducer, readBounded, validateDescendantInvocation, sealGeneratedFile, sealNativeEval, sealInterpretation, recordProducerEmission, recordProducerEmissions, registerProducerCandidates, gateDerived, producerTransport, producerUsage } from "./generated.js";
|
|
12
|
-
import { retainedNativeEvalMatches } from "./node-launch.js";
|
|
13
|
-
import { verifyNativeProgram, nativeProgramProjection } from "./native-program.js";
|
|
14
|
-
/** Refusal transport is bounded too; an undersized channel closes without a
|
|
15
|
-
* frame while the parent retains the named refusal. No truncation is success. */
|
|
16
|
-
export function boundedRefusalFrame(endpoint, why) { if (why.length > endpoint.responseBytes || Buffer.byteLength(why) > endpoint.responseBytes)
|
|
17
|
-
return; const frame = JSON.stringify({ protocol: 'command-lot/1', coordinate: endpoint.coordinate, implementation: endpoint.implementation, identity: endpoint.identity, responses: [{ kind: 'refuse', why }] }) + '\n'; return Buffer.byteLength(frame) <= endpoint.responseBytes ? frame : undefined; }
|
|
18
|
-
export async function startProducerCustodian(handle, snapshot, nativeImplementations, directory, inputNativePrograms = []) {
|
|
19
|
-
const nativePrograms = inputNativePrograms.map(grant => ({ identity: grant.identity, program: { ...grant.program } }));
|
|
20
|
-
if (nativePrograms.some(g => !/^sha256:[0-9a-f]{64}$/.test(g.identity) || g.program.kind !== 'native-binary' || typeof g.program.alias !== 'string' || !g.program.alias.length || !g.program.entry.startsWith('/') || !/^sha256:[0-9a-f]{64}$/.test(g.program.entryDigest) || !Number.isSafeInteger(g.program.entryBytes) || g.program.entryBytes < 1 || g.program.entryBytes > snapshot.budget.bytes || !g.program.condition) || new Set(nativePrograms.map(g => g.program.alias)).size !== nativePrograms.length)
|
|
21
|
-
throw Error('REFUSE·producer native program selection ambiguous/over budget');
|
|
22
|
-
const selected = producerTransport(handle), endpoint = { ...selected, deadlineMs: Date.now() + selected.timeoutMs, socket: join(directory, 'p-' + randomBytes(6).toString('hex')), token: randomBytes(32).toString('hex') }, connections = new Set(), unfinishedRequests = new Set(), refusals = [], knownDigests = new Set(snapshot.members.map(m => m.digest));
|
|
23
|
-
const retainedContexts = new Map(), retainedValues = new Map();
|
|
24
|
-
let contextBytes = 0;
|
|
25
|
-
const reconstruct = (compact) => { const full = { ...compact }; for (const key of ['invocation', 'edges'])
|
|
26
|
-
if (full[key]?.retainedValue) {
|
|
27
|
-
const value = retainedValues.get(full[key].retainedValue);
|
|
28
|
-
if (value === undefined)
|
|
29
|
-
throw Error('REFUSE·producer retained value absent');
|
|
30
|
-
full[key] = value;
|
|
31
|
-
} return full; };
|
|
32
|
-
const retainContext = (context) => { const held = retainedContexts.get(context.identity); if (held) {
|
|
33
|
-
if (canonicalJson(reconstruct(held)) !== canonicalJson(context))
|
|
34
|
-
throw Error('REFUSE·producer context identity collision');
|
|
35
|
-
return;
|
|
36
|
-
} const compact = { ...context }, fresh = new Map(); for (const key of ['invocation', 'edges']) {
|
|
37
|
-
const value = context[key];
|
|
38
|
-
if (value && typeof value === 'object') {
|
|
39
|
-
const encoded = canonicalJson(value), id = sha(encoded), prior = retainedValues.get(id);
|
|
40
|
-
if (prior !== undefined && canonicalJson(prior) !== encoded)
|
|
41
|
-
throw Error('REFUSE·producer retained value collision');
|
|
42
|
-
if (prior === undefined && !fresh.has(id))
|
|
43
|
-
fresh.set(id, JSON.parse(encoded));
|
|
44
|
-
compact[key] = { retainedValue: id };
|
|
45
|
-
}
|
|
46
|
-
} let bytes = Buffer.byteLength(canonicalJson(compact)); for (const [id, value] of fresh)
|
|
47
|
-
bytes += Buffer.byteLength(canonicalJson([id, value])); if (bytes > selected.responseBytes - contextBytes)
|
|
48
|
-
throw Error('REFUSE·producer retained contexts bytes'); for (const [id, value] of fresh)
|
|
49
|
-
retainedValues.set(id, value); retainedContexts.set(context.identity, compact); contextBytes += bytes; };
|
|
50
|
-
const server = createServer(socket => {
|
|
51
|
-
try {
|
|
52
|
-
chargeProducerRequest(handle);
|
|
53
|
-
if (Date.now() >= endpoint.deadlineMs)
|
|
54
|
-
throw Error('REFUSE·producer parent deadline');
|
|
55
|
-
}
|
|
56
|
-
catch (error) {
|
|
57
|
-
refusals.push(error instanceof Error ? error.message : String(error));
|
|
58
|
-
socket.destroy();
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
connections.add(socket);
|
|
62
|
-
unfinishedRequests.add(socket);
|
|
63
|
-
const finishReply = (reply) => { const done = () => unfinishedRequests.delete(socket); if (reply === undefined)
|
|
64
|
-
socket.end(done);
|
|
65
|
-
else
|
|
66
|
-
socket.end(reply, done); };
|
|
67
|
-
socket.once('error', () => { if (!refusals.length)
|
|
68
|
-
refusals.push('REFUSE·producer IPC response interrupted'); });
|
|
69
|
-
socket.setTimeout(Math.max(1, endpoint.deadlineMs - Date.now()), () => { refusals.push('REFUSE·producer IPC timeout'); socket.destroy(); });
|
|
70
|
-
const chunks = [];
|
|
71
|
-
let bytes = 0, handled = false;
|
|
72
|
-
socket.on('data', chunk => {
|
|
73
|
-
bytes += chunk.length;
|
|
74
|
-
if (bytes > endpoint.responseBytes) {
|
|
75
|
-
refusals.push('REFUSE·producer IPC request bytes');
|
|
76
|
-
socket.destroy();
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
chunks.push(chunk);
|
|
80
|
-
if (!chunk.includes(10))
|
|
81
|
-
return;
|
|
82
|
-
if (handled)
|
|
83
|
-
return;
|
|
84
|
-
handled = true;
|
|
85
|
-
socket.pause();
|
|
86
|
-
try {
|
|
87
|
-
const raw = Buffer.concat(chunks).toString('utf8');
|
|
88
|
-
if (refusals.length)
|
|
89
|
-
throw Error(refusals[0]);
|
|
90
|
-
const frame = JSON.parse(raw.trim());
|
|
91
|
-
if (frame.protocol !== 'command-lot/1' || frame.coordinate !== endpoint.coordinate || frame.implementation !== endpoint.implementation || frame.identity !== endpoint.identity || !Array.isArray(frame.requests) || frame.requests.length !== 1)
|
|
92
|
-
throw Error('REFUSE·producer IPC frame');
|
|
93
|
-
const body = JSON.parse(frame.requests[0]);
|
|
94
|
-
if (body.token !== endpoint.token || !['entry', 'emission', 'emission-batch', 'native-program', 'interpretation', 'eval-context', 'violation'].includes(body.operation))
|
|
95
|
-
throw Error('REFUSE·producer IPC capability');
|
|
96
|
-
if (body.operation === 'violation') {
|
|
97
|
-
if (typeof body.why !== 'string' || body.why.length > endpoint.responseBytes || Buffer.byteLength(body.why) > endpoint.responseBytes)
|
|
98
|
-
throw Error('REFUSE·producer violation bytes');
|
|
99
|
-
throw Error('REFUSE·producer pre-entry ' + body.why);
|
|
100
|
-
}
|
|
101
|
-
let context;
|
|
102
|
-
if (body.operation === 'eval-context') {
|
|
103
|
-
const actual = body.request;
|
|
104
|
-
const matches = [...retainedContexts.values()].map(reconstruct).filter(record => retainedNativeEvalMatches(record, actual));
|
|
105
|
-
if (matches.length !== 1)
|
|
106
|
-
throw Error('REFUSE·producer retained eval context ' + (matches.length ? 'ambiguous' : 'absent'));
|
|
107
|
-
context = matches[0];
|
|
108
|
-
}
|
|
109
|
-
else if (body.operation === 'emission-batch') {
|
|
110
|
-
const request = body.request;
|
|
111
|
-
if (!request || !Array.isArray(request.outputs) || request.outputs.length > selected.limits.work)
|
|
112
|
-
throw Error('REFUSE·producer emission batch context/count absent');
|
|
113
|
-
context = recordProducerEmissions(handle, request.outputs, request.invocation);
|
|
114
|
-
}
|
|
115
|
-
else if (body.operation === 'emission') {
|
|
116
|
-
const request = body.request;
|
|
117
|
-
if (!request || typeof request.path !== 'string')
|
|
118
|
-
throw Error('REFUSE·producer emission context absent');
|
|
119
|
-
context = recordProducerEmission(handle, request.path, request.invocation);
|
|
120
|
-
}
|
|
121
|
-
else if (body.operation === 'native-program') {
|
|
122
|
-
const request = body.request;
|
|
123
|
-
if (!request || typeof request.alias !== 'string' || typeof request.path !== 'string')
|
|
124
|
-
throw Error('REFUSE·producer native invocation absent');
|
|
125
|
-
const grant = nativePrograms.find(g => g.program.alias === request.alias);
|
|
126
|
-
if (!grant)
|
|
127
|
-
throw Error('REFUSE·producer native program alias undeclared ' + request.alias);
|
|
128
|
-
const invocation = validateDescendantInvocation(handle, request.invocation);
|
|
129
|
-
let actual;
|
|
130
|
-
try {
|
|
131
|
-
actual = realpathSync(request.path);
|
|
132
|
-
}
|
|
133
|
-
catch {
|
|
134
|
-
throw Error('REFUSE·producer native program target absent');
|
|
135
|
-
}
|
|
136
|
-
if (actual !== grant.program.entry)
|
|
137
|
-
throw Error('REFUSE·producer native program route differs');
|
|
138
|
-
const bytes = readBounded(actual, grant.program.entryBytes), digest = sha(bytes);
|
|
139
|
-
if (bytes.length !== grant.program.entryBytes || digest !== grant.program.entryDigest)
|
|
140
|
-
throw Error('REFUSE·producer native program bytes differ');
|
|
141
|
-
const transaction = { kind: 'native-program-transaction/1', parent: selected.parent, producer: selected.identity, program: grant.identity, alias: grant.program.alias, target: actual, digest, byteLength: bytes.length, invocation, condition: grant.program.condition };
|
|
142
|
-
context = { ...transaction, identity: sha(JSON.stringify(transaction)) };
|
|
143
|
-
}
|
|
144
|
-
else if (body.operation === 'interpretation') {
|
|
145
|
-
const request = body.request;
|
|
146
|
-
if (!request || typeof request.path !== 'string' || typeof request.interpretation !== 'string')
|
|
147
|
-
throw Error('REFUSE·producer interpretation context absent');
|
|
148
|
-
context = sealInterpretation(handle, request.path, request.interpretation, request.invocation);
|
|
149
|
-
}
|
|
150
|
-
else {
|
|
151
|
-
const request = body.request;
|
|
152
|
-
if (!request || !['module', 'commonjs'].includes(request.mode))
|
|
153
|
-
throw Error('REFUSE·producer unknown entry mode');
|
|
154
|
-
if (request.candidates !== undefined)
|
|
155
|
-
registerProducerCandidates(handle, request.candidates);
|
|
156
|
-
if (request.kind === 'file') {
|
|
157
|
-
if (request.interpretation !== undefined) {
|
|
158
|
-
assertProducerInterpretation(handle, request.interpretation);
|
|
159
|
-
if (request.interpretation !== 'node-ambiguous-javascript@1')
|
|
160
|
-
throw Error('REFUSE·producer entry interpretation unsupported');
|
|
161
|
-
}
|
|
162
|
-
if (!request.path)
|
|
163
|
-
throw Error('REFUSE·producer missing path');
|
|
164
|
-
const path = realpathSync(request.path), actual = readBounded(path, snapshot.budget.bytes);
|
|
165
|
-
if (actual.length > snapshot.budget.bytes)
|
|
166
|
-
throw Error('REFUSE·producer static input bytes');
|
|
167
|
-
const digest = sha(actual);
|
|
168
|
-
if (knownDigests.has(digest)) {
|
|
169
|
-
context = { kind: 'mounted-executable/1', parent: selected.parent, producer: selected.identity, path, digest, mode: request.mode, ...(request.interpretation === undefined ? {} : { interpretation: request.interpretation }), invocation: validateDescendantInvocation(handle, request.invocation), identity: sha(JSON.stringify([selected.parent, selected.identity, path, digest, request.mode, request.invocation, ...(request.interpretation === undefined ? [] : [request.interpretation])])), qualification: nativeImplementations.has(digest) ? 'separately selected privileged native implementation' : 'same sealed content mounted at actual path' };
|
|
170
|
-
}
|
|
171
|
-
else {
|
|
172
|
-
const record = sealGeneratedFile(handle, path, request.mode, request.invocation, request.interpretation), edges = gateDerived(handle, record, { path }, snapshot, nativeImplementations);
|
|
173
|
-
context = { ...record, edges };
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
else if (request.kind === 'eval') {
|
|
177
|
-
if (!request.argv || !request.rootPrefix)
|
|
178
|
-
throw Error('REFUSE·producer missing eval binding');
|
|
179
|
-
const record = sealNativeEval(handle, request.argv, request.rootPrefix, request.invocation);
|
|
180
|
-
if (record.mode !== request.mode)
|
|
181
|
-
throw Error('REFUSE·producer eval mode differs from argv');
|
|
182
|
-
const edges = gateDerived(handle, record, { argv: request.argv }, snapshot, nativeImplementations);
|
|
183
|
-
context = { ...record, edges };
|
|
184
|
-
}
|
|
185
|
-
else
|
|
186
|
-
throw Error('REFUSE·producer unknown entry kind');
|
|
187
|
-
}
|
|
188
|
-
retainContext(context);
|
|
189
|
-
const reply = JSON.stringify({ protocol: 'command-lot/1', coordinate: endpoint.coordinate, implementation: endpoint.implementation, identity: endpoint.identity, responses: [{ kind: 'entry-context', context, usage: producerUsage(handle) }] }) + '\n';
|
|
190
|
-
if (Buffer.byteLength(reply) > endpoint.responseBytes)
|
|
191
|
-
throw Error('REFUSE·producer IPC response bytes');
|
|
192
|
-
finishReply(reply);
|
|
193
|
-
}
|
|
194
|
-
catch (error) {
|
|
195
|
-
const why = error instanceof Error ? error.message : String(error);
|
|
196
|
-
if (!refusals.length)
|
|
197
|
-
refusals.push(why);
|
|
198
|
-
const refusal = boundedRefusalFrame(endpoint, why);
|
|
199
|
-
if (refusal === undefined) {
|
|
200
|
-
finishReply();
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
finishReply(refusal);
|
|
204
|
-
}
|
|
205
|
-
});
|
|
206
|
-
socket.once('close', () => { if (unfinishedRequests.delete(socket) && !refusals.length)
|
|
207
|
-
refusals.push('REFUSE·producer IPC interrupted before bounded reply'); connections.delete(socket); });
|
|
208
|
-
});
|
|
209
|
-
await new Promise((resolve, reject) => { server.once('error', reject); server.listen(endpoint.socket, () => { chmodSync(endpoint.socket, 0o600); resolve(); }); });
|
|
210
|
-
const deadline = setTimeout(() => { refusals.push('REFUSE·producer parent deadline'); for (const socket of connections)
|
|
211
|
-
socket.destroy(); }, endpoint.timeoutMs);
|
|
212
|
-
return { endpoint, get contexts() { return [...retainedContexts.values()].map(reconstruct); }, retention: () => ({ bytes: contextBytes, contexts: [...retainedContexts.values()].map(value => JSON.parse(canonicalJson(value))), values: [...retainedValues].map(([id, value]) => [id, JSON.parse(canonicalJson(value))]) }), assertClosed: () => { if (Date.now() >= endpoint.deadlineMs)
|
|
213
|
-
throw Error('REFUSE·producer parent deadline'); if (refusals.length)
|
|
214
|
-
throw Error(refusals[0]); if (unfinishedRequests.size)
|
|
215
|
-
throw Error('REFUSE·producer IPC unfinished'); }, refusals, usage: () => producerUsage(handle), close: async () => { clearTimeout(deadline); for (const socket of connections)
|
|
216
|
-
socket.destroy(); await new Promise(resolve => server.close(() => resolve())); rmSync(endpoint.socket, { force: true }); } };
|
|
217
|
-
}
|
|
218
|
-
/** Asynchronous client for original async native APIs. Original sync APIs use
|
|
219
|
-
* the fixed client executable; both address this SAME custodian/counters. */
|
|
220
|
-
export async function requestRetainedEvalContext(endpoint, actual) { return requestProducerOperation(endpoint, 'eval-context', actual); }
|
|
221
|
-
export async function requestProducerEntry(endpoint, request) { return requestProducerOperation(endpoint, 'entry', request); }
|
|
222
|
-
export async function requestProducerInterpretation(endpoint, request) { return requestProducerOperation(endpoint, 'interpretation', request); }
|
|
223
|
-
export async function requestNativeProgram(endpoint, request) { return requestProducerOperation(endpoint, 'native-program', request); }
|
|
224
|
-
export async function requestProducerEmission(endpoint, request) { return requestProducerOperation(endpoint, 'emission', request); }
|
|
225
|
-
export async function requestProducerEmissionBatch(endpoint, request) { return requestProducerOperation(endpoint, 'emission-batch', request); }
|
|
226
|
-
async function requestProducerOperation(endpoint, operation, request) { const port = { coordinate: endpoint.coordinate, implementation: endpoint.implementation, closure: [endpoint.implementation], timeoutMs: endpoint.timeoutMs, responseBytes: endpoint.responseBytes, environment: [], stderr: 'reject' }, lot = { identity: endpoint.identity, requests: [JSON.stringify({ operation, token: endpoint.token, request })] }, frame = commandRequest(port, lot); if (Buffer.byteLength(frame) > endpoint.responseBytes)
|
|
227
|
-
throw Error('REFUSE·producer IPC request bytes'); const raw = await new Promise((resolve, reject) => { const socket = createConnection(endpoint.socket), chunks = [], timer = setTimeout(() => socket.destroy(Error('REFUSE·producer IPC timeout')), Math.max(1, Math.min(endpoint.timeoutMs, endpoint.deadlineMs - Date.now()))); let bytes = 0; socket.on('connect', () => socket.write(frame + '\n')); socket.on('data', c => { bytes += c.length; if (bytes > endpoint.responseBytes)
|
|
228
|
-
socket.destroy(Error('REFUSE·producer IPC response bytes'));
|
|
229
|
-
else
|
|
230
|
-
chunks.push(c); }); socket.once('error', reject); socket.once('close', () => { clearTimeout(timer); resolve(Buffer.concat(chunks).toString('utf8')); }); }); const values = commandResponse(port, lot, { status: 0, interrupted: false, stdout: raw, stderr: '' }, value => !!value && typeof value === 'object' && ['entry-context', 'refuse'].includes(value.kind)); const one = values[0]; if (one.kind === 'refuse')
|
|
231
|
-
throw Error(one.why); return one.context; }
|
|
232
|
-
/** Bound's guarded host constructs this factory, not a world. The transport path
|
|
233
|
-
* is selected by the sealed native preload configuration, not a grant in data.
|
|
234
|
-
* A shared context file cannot be multiplexed across simultaneous bindings. */
|
|
235
|
-
export function createProducerJobCustody(input) { let active = false; return { async open(parent) { if (active || existsSync(input.contextFile))
|
|
236
|
-
throw Error('REFUSE·producer execution context occupied'); active = true; let service; const temporary = input.contextFile + '.' + randomBytes(6).toString('hex'); try {
|
|
237
|
-
const programs = (input.programSelections ?? []).map(selected => nativeProgramProjection(verifyNativeProgram(input.root, selected.coordinate, parent, selected.runtimeBinding)));
|
|
238
|
-
const handle = createGeneratedProducer(input.root, input.coordinate, parent, input.implementationBytes);
|
|
239
|
-
const nativePrograms = (input.nativeBinaries ?? []).map(binding => { const verified = verifyNativeBinary(input.root, binding.coordinate, parent, binding.privateBinding); return { identity: verified.identity, program: nativeBinaryProjection(verified) }; });
|
|
240
|
-
service = await startProducerCustodian(handle, input.snapshot, input.nativeImplementations, input.directory, nativePrograms);
|
|
241
|
-
const declaredPrograms = [...programs, ...nativePrograms.map(g => g.program)];
|
|
242
|
-
if (new Set(declaredPrograms.map(p => p.alias)).size !== declaredPrograms.length)
|
|
243
|
-
throw Error('REFUSE·producer native alias ambiguous');
|
|
244
|
-
const text = JSON.stringify({ endpoint: service.endpoint, parentExecution: parent, programs: declaredPrograms });
|
|
245
|
-
if (Buffer.byteLength(text) > parent.responseBytes)
|
|
246
|
-
throw Error('REFUSE·producer execution context bytes');
|
|
247
|
-
writeFileSync(temporary, text, { flag: 'wx', mode: 0o600 });
|
|
248
|
-
renameSync(temporary, input.contextFile);
|
|
249
|
-
const held = service;
|
|
250
|
-
return { assertClosed: () => held.assertClosed(), async close() { try {
|
|
251
|
-
await held.close();
|
|
252
|
-
}
|
|
253
|
-
finally {
|
|
254
|
-
rmSync(input.contextFile, { force: true });
|
|
255
|
-
active = false;
|
|
256
|
-
} } };
|
|
257
|
-
}
|
|
258
|
-
catch (error) {
|
|
259
|
-
rmSync(temporary, { force: true });
|
|
260
|
-
await service?.close();
|
|
261
|
-
active = false;
|
|
262
|
-
throw error;
|
|
263
|
-
} } }; }
|
|
264
|
-
/** Fixed Root preload reports a local before-entry refusal to the SAME parent
|
|
265
|
-
* custodian. A caught child error therefore cannot become a success receipt. */
|
|
266
|
-
export async function reportProducerViolation(endpoint, why) { if (typeof why !== 'string' || why.length > endpoint.responseBytes || Buffer.byteLength(why) > endpoint.responseBytes)
|
|
267
|
-
throw Error('REFUSE·producer violation bytes'); const frame = JSON.stringify({ protocol: 'command-lot/1', coordinate: endpoint.coordinate, implementation: endpoint.implementation, identity: endpoint.identity, requests: [JSON.stringify({ operation: 'violation', token: endpoint.token, why })] }); await new Promise((resolve, reject) => { const socket = createConnection(endpoint.socket), timer = setTimeout(() => socket.destroy(Error('REFUSE·producer IPC timeout')), Math.max(1, endpoint.deadlineMs - Date.now())); socket.once('connect', () => socket.write(frame + '\n')); socket.on('data', () => { }); socket.once('error', reject); socket.once('close', () => { clearTimeout(timer); resolve(); }); }); throw Error('REFUSE·producer pre-entry ' + why); }
|
|
1
|
+
var Q=Object.defineProperty;var a=(e,o)=>Q(e,"name",{value:o,configurable:!0});import{sha256 as I}from"../hash.js";import{createServer as X,createConnection as V}from"node:net";import{chmodSync as Y,rmSync as D,realpathSync as A,writeFileSync as Z,renameSync as ee,existsSync as re}from"node:fs";import{join as te}from"node:path";import{randomBytes as L}from"node:crypto";import{canonicalJson as B}from"./reading.js";import{verifyNativeBinary as oe,nativeBinaryProjection as ne}from"./native-binary.js";import{library2_commandRequest as ie,library2_commandResponse as se}from"../../vendor/runtime.js";import{assertProducerInterpretation as ae,chargeProducerRequest as ce,createGeneratedProducer as de,readBounded as z,validateDescendantInvocation as G,sealGeneratedFile as ue,sealNativeEval as pe,sealInterpretation as me,recordProducerEmission as fe,recordProducerEmissions as le,registerProducerCandidates as ye,gateDerived as _,producerTransport as Ee,producerUsage as $}from"./generated.js";import{retainedNativeEvalMatches as ge}from"./node-launch.js";import{verifyNativeProgram as he,nativeProgramProjection as ve}from"./native-program.js";function Se(e,o){if(o.length>e.responseBytes||Buffer.byteLength(o)>e.responseBytes)return;const m=JSON.stringify({protocol:"command-lot/1",coordinate:e.coordinate,implementation:e.implementation,identity:e.identity,responses:[{kind:"refuse",why:o}]})+`
|
|
2
|
+
`;return Buffer.byteLength(m)<=e.responseBytes?m:void 0}a(Se,"boundedRefusalFrame");async function we(e,o,m,S,b=[]){const u=b.map(t=>({identity:t.identity,program:{...t.program}}));if(u.some(t=>!/^sha256:[0-9a-f]{64}$/.test(t.identity)||t.program.kind!=="native-binary"||typeof t.program.alias!="string"||!t.program.alias.length||!t.program.entry.startsWith("/")||!/^sha256:[0-9a-f]{64}$/.test(t.program.entryDigest)||!Number.isSafeInteger(t.program.entryBytes)||t.program.entryBytes<1||t.program.entryBytes>o.budget.bytes||!t.program.condition)||new Set(u.map(t=>t.program.alias)).size!==u.length)throw Error("REFUSE\xB7producer native program selection ambiguous/over budget");const f=Ee(e),i={...f,deadlineMs:Date.now()+f.timeoutMs,socket:te(S,"p-"+L(6).toString("hex")),token:L(32).toString("hex")},v=new Set,h=new Set,c=[],d=new Set(o.members.map(t=>t.digest)),w=new Map,P=new Map;let q=0;const C=a(t=>{const y={...t};for(const R of["invocation","edges"])if(y[R]?.retainedValue){const F=P.get(y[R].retainedValue);if(F===void 0)throw Error("REFUSE\xB7producer retained value absent");y[R]=F}return y},"reconstruct"),W=a(t=>{const y=w.get(t.identity);if(y){if(B(C(y))!==B(t))throw Error("REFUSE\xB7producer context identity collision");return}const R={...t},F=new Map;for(const p of["invocation","edges"]){const l=t[p];if(l&&typeof l=="object"){const E=B(l),n=I(E),g=P.get(n);if(g!==void 0&&B(g)!==E)throw Error("REFUSE\xB7producer retained value collision");g===void 0&&!F.has(n)&&F.set(n,JSON.parse(E)),R[p]={retainedValue:n}}}let k=Buffer.byteLength(B(R));for(const[p,l]of F)k+=Buffer.byteLength(B([p,l]));if(k>f.responseBytes-q)throw Error("REFUSE\xB7producer retained contexts bytes");for(const[p,l]of F)P.set(p,l);w.set(t.identity,R),q+=k},"retainContext"),O=X(t=>{try{if(ce(e),Date.now()>=i.deadlineMs)throw Error("REFUSE\xB7producer parent deadline")}catch(p){c.push(p instanceof Error?p.message:String(p)),t.destroy();return}v.add(t),h.add(t);const y=a(p=>{const l=a(()=>h.delete(t),"done");p===void 0?t.end(l):t.end(p,l)},"finishReply");t.once("error",()=>{c.length||c.push("REFUSE\xB7producer IPC response interrupted")}),t.setTimeout(Math.max(1,i.deadlineMs-Date.now()),()=>{c.push("REFUSE\xB7producer IPC timeout"),t.destroy()});const R=[];let F=0,k=!1;t.on("data",p=>{if(F+=p.length,F>i.responseBytes){c.push("REFUSE\xB7producer IPC request bytes"),t.destroy();return}if(R.push(p),!!p.includes(10)&&!k){k=!0,t.pause();try{const l=Buffer.concat(R).toString("utf8");if(c.length)throw Error(c[0]);const E=JSON.parse(l.trim());if(E.protocol!=="command-lot/1"||E.coordinate!==i.coordinate||E.implementation!==i.implementation||E.identity!==i.identity||!Array.isArray(E.requests)||E.requests.length!==1)throw Error("REFUSE\xB7producer IPC frame");const n=JSON.parse(E.requests[0]);if(n.token!==i.token||!["entry","emission","emission-batch","native-program","interpretation","eval-context","violation"].includes(n.operation))throw Error("REFUSE\xB7producer IPC capability");if(n.operation==="violation")throw typeof n.why!="string"||n.why.length>i.responseBytes||Buffer.byteLength(n.why)>i.responseBytes?Error("REFUSE\xB7producer violation bytes"):Error("REFUSE\xB7producer pre-entry "+n.why);let g;if(n.operation==="eval-context"){const r=n.request,s=[...w.values()].map(C).filter(U=>ge(U,r));if(s.length!==1)throw Error("REFUSE\xB7producer retained eval context "+(s.length?"ambiguous":"absent"));g=s[0]}else if(n.operation==="emission-batch"){const r=n.request;if(!r||!Array.isArray(r.outputs)||r.outputs.length>f.limits.work)throw Error("REFUSE\xB7producer emission batch context/count absent");g=le(e,r.outputs,r.invocation)}else if(n.operation==="emission"){const r=n.request;if(!r||typeof r.path!="string")throw Error("REFUSE\xB7producer emission context absent");g=fe(e,r.path,r.invocation)}else if(n.operation==="native-program"){const r=n.request;if(!r||typeof r.alias!="string"||typeof r.path!="string")throw Error("REFUSE\xB7producer native invocation absent");const s=u.find(K=>K.program.alias===r.alias);if(!s)throw Error("REFUSE\xB7producer native program alias undeclared "+r.alias);const U=G(e,r.invocation);let x;try{x=A(r.path)}catch{throw Error("REFUSE\xB7producer native program target absent")}if(x!==s.program.entry)throw Error("REFUSE\xB7producer native program route differs");const M=z(x,s.program.entryBytes),J=I(M);if(M.length!==s.program.entryBytes||J!==s.program.entryDigest)throw Error("REFUSE\xB7producer native program bytes differ");const T={kind:"native-program-transaction/1",parent:f.parent,producer:f.identity,program:s.identity,alias:s.program.alias,target:x,digest:J,byteLength:M.length,invocation:U,condition:s.program.condition};g={...T,identity:I(JSON.stringify(T))}}else if(n.operation==="interpretation"){const r=n.request;if(!r||typeof r.path!="string"||typeof r.interpretation!="string")throw Error("REFUSE\xB7producer interpretation context absent");g=me(e,r.path,r.interpretation,r.invocation)}else{const r=n.request;if(!r||!["module","commonjs"].includes(r.mode))throw Error("REFUSE\xB7producer unknown entry mode");if(r.candidates!==void 0&&ye(e,r.candidates),r.kind==="file"){if(r.interpretation!==void 0&&(ae(e,r.interpretation),r.interpretation!=="node-ambiguous-javascript@1"))throw Error("REFUSE\xB7producer entry interpretation unsupported");if(!r.path)throw Error("REFUSE\xB7producer missing path");const s=A(r.path),U=z(s,o.budget.bytes);if(U.length>o.budget.bytes)throw Error("REFUSE\xB7producer static input bytes");const x=I(U);if(d.has(x))g={kind:"mounted-executable/1",parent:f.parent,producer:f.identity,path:s,digest:x,mode:r.mode,...r.interpretation===void 0?{}:{interpretation:r.interpretation},invocation:G(e,r.invocation),identity:I(JSON.stringify([f.parent,f.identity,s,x,r.mode,r.invocation,...r.interpretation===void 0?[]:[r.interpretation]])),qualification:m.has(x)?"separately selected privileged native implementation":"same sealed content mounted at actual path"};else{const M=ue(e,s,r.mode,r.invocation,r.interpretation),J=_(e,M,{path:s},o,m);g={...M,edges:J}}}else if(r.kind==="eval"){if(!r.argv||!r.rootPrefix)throw Error("REFUSE\xB7producer missing eval binding");const s=pe(e,r.argv,r.rootPrefix,r.invocation);if(s.mode!==r.mode)throw Error("REFUSE\xB7producer eval mode differs from argv");const U=_(e,s,{argv:r.argv},o,m);g={...s,edges:U}}else throw Error("REFUSE\xB7producer unknown entry kind")}W(g);const j=JSON.stringify({protocol:"command-lot/1",coordinate:i.coordinate,implementation:i.implementation,identity:i.identity,responses:[{kind:"entry-context",context:g,usage:$(e)}]})+`
|
|
3
|
+
`;if(Buffer.byteLength(j)>i.responseBytes)throw Error("REFUSE\xB7producer IPC response bytes");y(j)}catch(l){const E=l instanceof Error?l.message:String(l);c.length||c.push(E);const n=Se(i,E);if(n===void 0){y();return}y(n)}}}),t.once("close",()=>{h.delete(t)&&!c.length&&c.push("REFUSE\xB7producer IPC interrupted before bounded reply"),v.delete(t)})});await new Promise((t,y)=>{O.once("error",y),O.listen(i.socket,()=>{Y(i.socket,384),t()})});const H=setTimeout(()=>{c.push("REFUSE\xB7producer parent deadline");for(const t of v)t.destroy()},i.timeoutMs);return{endpoint:i,get contexts(){return[...w.values()].map(C)},retention:a(()=>({bytes:q,contexts:[...w.values()].map(t=>JSON.parse(B(t))),values:[...P].map(([t,y])=>[t,JSON.parse(B(y))])}),"retention"),assertClosed:a(()=>{if(Date.now()>=i.deadlineMs)throw Error("REFUSE\xB7producer parent deadline");if(c.length)throw Error(c[0]);if(h.size)throw Error("REFUSE\xB7producer IPC unfinished")},"assertClosed"),refusals:c,usage:a(()=>$(e),"usage"),close:a(async()=>{clearTimeout(H);for(const t of v)t.destroy();await new Promise(t=>O.close(()=>t())),D(i.socket,{force:!0})},"close")}}a(we,"startProducerCustodian");async function Ie(e,o){return N(e,"eval-context",o)}a(Ie,"requestRetainedEvalContext");async function Je(e,o){return N(e,"entry",o)}a(Je,"requestProducerEntry");async function Oe(e,o){return N(e,"interpretation",o)}a(Oe,"requestProducerInterpretation");async function De(e,o){return N(e,"native-program",o)}a(De,"requestNativeProgram");async function Le(e,o){return N(e,"emission",o)}a(Le,"requestProducerEmission");async function je(e,o){return N(e,"emission-batch",o)}a(je,"requestProducerEmissionBatch");async function N(e,o,m){const S={coordinate:e.coordinate,implementation:e.implementation,closure:[e.implementation],timeoutMs:e.timeoutMs,responseBytes:e.responseBytes,environment:[],stderr:"reject"},b={identity:e.identity,requests:[JSON.stringify({operation:o,token:e.token,request:m})]},u=ie(S,b);if(Buffer.byteLength(u)>e.responseBytes)throw Error("REFUSE\xB7producer IPC request bytes");const f=await new Promise((h,c)=>{const d=V(e.socket),w=[],P=setTimeout(()=>d.destroy(Error("REFUSE\xB7producer IPC timeout")),Math.max(1,Math.min(e.timeoutMs,e.deadlineMs-Date.now())));let q=0;d.on("connect",()=>d.write(u+`
|
|
4
|
+
`)),d.on("data",C=>{q+=C.length,q>e.responseBytes?d.destroy(Error("REFUSE\xB7producer IPC response bytes")):w.push(C)}),d.once("error",c),d.once("close",()=>{clearTimeout(P),h(Buffer.concat(w).toString("utf8"))})}),v=se(S,b,{status:0,interrupted:!1,stdout:f,stderr:""},h=>!!h&&typeof h=="object"&&["entry-context","refuse"].includes(h.kind))[0];if(v.kind==="refuse")throw Error(v.why);return v.context}a(N,"requestProducerOperation");function Te(e){let o=!1;return{async open(m){if(o||re(e.contextFile))throw Error("REFUSE\xB7producer execution context occupied");o=!0;let S;const b=e.contextFile+"."+L(6).toString("hex");try{const u=(e.programSelections??[]).map(d=>ve(he(e.root,d.coordinate,m,d.runtimeBinding))),f=de(e.root,e.coordinate,m,e.implementationBytes),i=(e.nativeBinaries??[]).map(d=>{const w=oe(e.root,d.coordinate,m,d.privateBinding);return{identity:w.identity,program:ne(w)}});S=await we(f,e.snapshot,e.nativeImplementations,e.directory,i);const v=[...u,...i.map(d=>d.program)];if(new Set(v.map(d=>d.alias)).size!==v.length)throw Error("REFUSE\xB7producer native alias ambiguous");const h=JSON.stringify({endpoint:S.endpoint,parentExecution:m,programs:v});if(Buffer.byteLength(h)>m.responseBytes)throw Error("REFUSE\xB7producer execution context bytes");Z(b,h,{flag:"wx",mode:384}),ee(b,e.contextFile);const c=S;return{assertClosed:a(()=>c.assertClosed(),"assertClosed"),async close(){try{await c.close()}finally{D(e.contextFile,{force:!0}),o=!1}}}}catch(u){throw D(b,{force:!0}),await S?.close(),o=!1,u}}}}a(Te,"createProducerJobCustody");async function Ve(e,o){if(typeof o!="string"||o.length>e.responseBytes||Buffer.byteLength(o)>e.responseBytes)throw Error("REFUSE\xB7producer violation bytes");const m=JSON.stringify({protocol:"command-lot/1",coordinate:e.coordinate,implementation:e.implementation,identity:e.identity,requests:[JSON.stringify({operation:"violation",token:e.token,why:o})]});throw await new Promise((S,b)=>{const u=V(e.socket),f=setTimeout(()=>u.destroy(Error("REFUSE\xB7producer IPC timeout")),Math.max(1,e.deadlineMs-Date.now()));u.once("connect",()=>u.write(m+`
|
|
5
|
+
`)),u.on("data",()=>{}),u.once("error",b),u.once("close",()=>{clearTimeout(f),S()})}),Error("REFUSE\xB7producer pre-entry "+o)}a(Ve,"reportProducerViolation");export{Se as boundedRefusalFrame,Te as createProducerJobCustody,Ve as reportProducerViolation,De as requestNativeProgram,Le as requestProducerEmission,je as requestProducerEmissionBatch,Je as requestProducerEntry,Oe as requestProducerInterpretation,Ie as requestRetainedEvalContext,we as startProducerCustodian};
|