@lapxo/bound 0.2.4 → 0.2.6
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/README.md +20 -3
- package/TARGET.bound +85 -47
- package/dist/cli/accept.js +61 -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 +22 -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 +85 -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 +28 -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/command-server.js +4 -0
- 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/authority-card-view.js +5 -0
- package/dist/host/native/authority-card.js +1 -0
- 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/installed-package.d.ts +1 -0
- package/dist/host/native/installed-package.js +5 -0
- 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-inventory.js +2 -0
- 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/probes.js +1 -0
- package/dist/host/native/reading-witness-admission.js +5 -0
- 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-place-state.js +1 -0
- 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/persistent-host.js +1 -0
- package/dist/host/physical-lines.d.ts +1 -0
- package/dist/host/physical-lines.js +1 -0
- 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/profile-composition.d.ts +1 -0
- package/dist/host/profile-composition.js +2 -0
- 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/host/work-trace.js +1 -0
- 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 +6 -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 +1 -41
- package/dist/observe/runner.js +4 -101
- package/dist/public-types.d.ts +2019 -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/receipt-projection.js +1 -0
- 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/bundle.json +1 -0
- package/dist/vendor/library14.js +1 -0
- package/dist/vendor/object-provider.js +42 -0
- package/dist/vendor/runtime.js +61 -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/authenticated-reference.publication.json +1 -1
- package/docs/contracts/authority-preflight.md +17 -0
- package/docs/contracts/authority-preflight.publication.json +25 -0
- 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/installed-package.md +21 -0
- package/docs/contracts/installed-package.publication.json +25 -0
- package/docs/contracts/materialized-leaf-sequence.md +15 -0
- package/docs/contracts/materialized-leaf-sequence.publication.json +25 -0
- package/docs/contracts/module-inventory.md +15 -0
- package/docs/contracts/module-inventory.publication.json +25 -0
- package/docs/contracts/native-host.md +29 -1
- package/docs/contracts/native-host.publication.json +4 -4
- package/docs/contracts/native-probes.md +13 -0
- package/docs/contracts/native-probes.publication.json +25 -0
- package/docs/contracts/native-publication.inventory.json +10 -1
- package/docs/contracts/native-view-batch.md +17 -0
- package/docs/contracts/native-view-batch.publication.json +25 -0
- package/docs/contracts/optional-wasm-adapter.publication.json +1 -1
- package/docs/contracts/physical-lines.md +19 -0
- package/docs/contracts/physical-lines.publication.json +25 -0
- package/docs/contracts/profile-composition.md +17 -0
- package/docs/contracts/profile-composition.publication.json +25 -0
- package/docs/contracts/profile-preparation-native-meaning.md +9 -0
- package/docs/contracts/publication.md +12 -0
- package/docs/contracts/reading-identity.md +61 -0
- package/docs/contracts/reading-identity.publication.json +25 -0
- package/docs/contracts/reading-witness-admission.md +49 -0
- package/docs/contracts/readme.publication.json +1 -1
- package/docs/contracts/reference-port.md +11 -0
- package/docs/contracts/reference-port.publication.json +1 -1
- package/docs/contracts/refusals.bound +346 -94
- package/docs/contracts/refusals.md +119 -39
- package/docs/contracts/refusals.publication.json +2 -2
- package/docs/contracts/views.md +8 -0
- package/docs/reference.md +9 -0
- package/licenses/wasm/{fast-text-encoding.txt → NOTICE.txt} +111 -0
- package/package.json +84 -34
- package/receipts.bound +12952 -10449
- package/samples/authority-preflight/no.json +6 -0
- package/samples/authority-preflight/yes.json +30 -0
- package/samples/engine-alphabet/reader.js +3 -1457
- package/samples/engine-alphabet/receipts.bound +7 -7
- package/samples/engine-interval/reader.js +3 -1457
- package/samples/engine-interval/receipts.bound +7 -7
- package/samples/installed-package/consumer.mjs +29 -0
- package/samples/installed-package/fixture.json +48 -0
- package/samples/installed-package/no.json +10 -0
- package/samples/installed-package/yes.json +52 -0
- package/samples/materialized-leaf-sequence/no.json +11 -0
- package/samples/materialized-leaf-sequence/yes.json +10 -0
- package/samples/module-inventory/yes.json +28 -0
- package/samples/native/physical-line-reader.mjs +1 -0
- package/samples/native/physical-line-reader.source.mjs +13 -0
- package/samples/native-host/no.json +6 -1
- package/samples/native-host/yes.json +18 -1
- package/samples/native-probes/inputs/inspection.json +28 -0
- package/samples/native-probes/no.json +7 -0
- package/samples/native-probes/yes.json +28 -0
- package/samples/native-view-batch/no.json +14 -0
- package/samples/native-view-batch/yes.json +10 -0
- package/samples/no/engine-order/reader.js +3 -1457
- package/samples/no/module-inventory/no.json +10 -0
- package/samples/physical-lines/no.json +5 -0
- package/samples/physical-lines/yes.json +9 -0
- package/samples/profile-composition/no.json +6 -0
- package/samples/profile-composition/yes.json +14 -0
- package/samples/reading-identity/no.json +26 -0
- package/samples/reading-identity/yes.json +69 -0
- package/vectors/native/authority-preflight.vector.json +55 -0
- package/vectors/native/installed-package.vector.json +31 -0
- package/vectors/native/materialized-leaf-sequence.vector.json +31 -0
- package/vectors/native/module-inventory.vector.json +56 -0
- package/vectors/native/native-host.vector.json +214 -0
- package/vectors/native/native-probes.vector.json +31 -0
- package/vectors/native/native-view-batch.vector.json +31 -0
- package/vectors/native/physical-lines.vector.json +105 -0
- package/vectors/native/profile-composition.vector.json +53 -0
- package/vectors/native/reading-identity.vector.json +139 -0
- package/vectors/native/refusals.vector.json +138 -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
- package/licenses/wasm/jitl-quickjs-ffi-types.txt +0 -21
- package/licenses/wasm/jitl-quickjs-wasmfile-release-sync.txt +0 -47
- package/licenses/wasm/quickjs-emscripten-core.txt +0 -21
- package/licenses/wasm/topos.txt +0 -21
- /package/{licenses/wasm/bound.txt → dist/vendor/28cba430228db1c04f446c93f81b09a2705d6bf3e222d35adbe5a4cee4061884.LICENSE} +0 -0
- /package/{licenses/wasm/obligations.txt → dist/vendor/7aca161279d14bc0e054dcc281cd110aeb95be2e026b42fdf527a260e58b2aae.LICENSE} +0 -0
|
@@ -1,216 +1 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { sha256 as hash } from "../hash.js";
|
|
3
|
-
/** Instrument-only native route. The caller holds the existing Root lease
|
|
4
|
-
* across selection, cache authorization and this complete bounded child act.
|
|
5
|
-
*/
|
|
6
|
-
import { dirname } from 'node:path';
|
|
7
|
-
import { realpathSync } from 'node:fs';
|
|
8
|
-
import { nativeBinaryOrigin } from "./native-binary.js";
|
|
9
|
-
import { selectedHostControl } from "./control-selection.js";
|
|
10
|
-
import { authorityAtEpoch } from '@lapxo/topos/wire';
|
|
11
|
-
import { parsedLine as parse } from "../../fold/claims.js";
|
|
12
|
-
import { authorityFor } from "../../fold/signers.js";
|
|
13
|
-
import { authenticatedRootStanding } from "../admitted-place.js";
|
|
14
|
-
import { nativeExecutorInputs } from "./materialize.js";
|
|
15
|
-
export { materializeNativeRoute } from "./materialize.js";
|
|
16
|
-
import { assertNativeRuntime } from "./runtime.js";
|
|
17
|
-
import { nativeReferenceInputs } from "./references.js";
|
|
18
|
-
import { rootAuthorityProtection } from "../../land/act.js";
|
|
19
|
-
import { currentNativeRoot, inheritedNativeRoot } from "./root.js";
|
|
20
|
-
import { authenticateSignedPort, authenticateNativeProfile, canonicalJson } from "./reading.js";
|
|
21
|
-
import { boundedProcess } from "../process-lifetime.js";
|
|
22
|
-
import { validResponse, CapsuleProcessError } from "../capsule-process.js";
|
|
23
|
-
import { processOf } from "../../observe/runner.js";
|
|
24
|
-
const fail = (why) => { throw Error('REFUSE·native route ' + why); };
|
|
25
|
-
const routes = new WeakMap();
|
|
26
|
-
/** Shared origins are one exact input; individual signed selectors remain separate. */
|
|
27
|
-
export function nativeBinaryOriginInputs(binaries) {
|
|
28
|
-
const seen = new Map(), inputs = [];
|
|
29
|
-
for (const binary of binaries) {
|
|
30
|
-
if (!binary.origin)
|
|
31
|
-
continue;
|
|
32
|
-
const coordinate = 'native/binary-origin/' + binary.origin.coordinate, digest = hash(binary.origin.line), prior = seen.get(coordinate);
|
|
33
|
-
if (prior !== undefined) {
|
|
34
|
-
if (prior !== digest)
|
|
35
|
-
fail('conflicting binary origin input ' + coordinate);
|
|
36
|
-
continue;
|
|
37
|
-
}
|
|
38
|
-
seen.set(coordinate, digest);
|
|
39
|
-
inputs.push([coordinate, digest]);
|
|
40
|
-
}
|
|
41
|
-
return Object.freeze(inputs);
|
|
42
|
-
}
|
|
43
|
-
/** Inputs are semantic logical references. Fixed instrument/host graph and
|
|
44
|
-
* runtime-supervisor chain must also be supplied by the calling identity builder.
|
|
45
|
-
* Locations and lock-token/PID are operational custody, never these inputs.
|
|
46
|
-
*/
|
|
47
|
-
export function prepareNativeRoute(store, coordinate, readerMapping) {
|
|
48
|
-
const proof = rootAuthorityProtection(store), current = currentNativeRoot(store, process.pid, proof);
|
|
49
|
-
return prepareAtCurrentRoot(store, coordinate, readerMapping, current);
|
|
50
|
-
}
|
|
51
|
-
/** Private same-call reuse only: callers cannot supply a standing as authority. */
|
|
52
|
-
function prepareAtCurrentRoot(store, coordinate, readerMapping, current) {
|
|
53
|
-
const { root, context } = current, selected = authenticateNativeProfile(root, coordinate), profile = selected.profile;
|
|
54
|
-
// The Root cursor authorizes today's act under the held lease. It is not a
|
|
55
|
-
// semantic input to every program: unrelated Root acts do not reopen it.
|
|
56
|
-
// Exact selected grants and the authenticated reader mapping remain inputs.
|
|
57
|
-
const binaries = authenticatedNativeBinaries(root, profile), control = selectedHostControl(root, profile), identity = hash(canonicalJson([coordinate, selected.line, profile, binaries, readerMapping ?? null, ...(control ? [control] : [])])), inputs = [['native/selection', identity], ...(readerMapping ? [['native/reader-mapping', hash(readerMapping)]] : []), ...profile.selection.members.map(m => ['native/' + m.coordinate, m.digest]), ...binaries.map(b => ['native/binary/' + b.coordinate, hash(b.line)])];
|
|
58
|
-
inputs.push(...nativeBinaryOriginInputs(binaries));
|
|
59
|
-
if (control)
|
|
60
|
-
inputs.push(['native/control-profile', hash(control.line)], ['native/control-worker', control.profile.worker.digest], ['native/control-runtime', control.profile.runtime.digest]);
|
|
61
|
-
const route = { identity, profile, binaries, ...(control ? { control } : {}), inputs: inputs };
|
|
62
|
-
routes.set(route, { store, coordinate, context, profile });
|
|
63
|
-
inputs.push(...nativeExecutorInputs(route));
|
|
64
|
-
if (control && inputs.find(([name]) => name === control.profile.worker.coordinate)?.[1] !== control.profile.worker.digest)
|
|
65
|
-
fail('control worker differs from sealed executor');
|
|
66
|
-
Object.freeze(inputs);
|
|
67
|
-
return Object.freeze(route);
|
|
68
|
-
}
|
|
69
|
-
/** Recheck authority before both a current retained answer and fresh execution.
|
|
70
|
-
* Historical public --check uses the existing receipt-inspection path, not this
|
|
71
|
-
* command authorization route.
|
|
72
|
-
*/
|
|
73
|
-
export function assertNativeRouteCurrent(route) {
|
|
74
|
-
const held = routes.get(route);
|
|
75
|
-
if (!held)
|
|
76
|
-
return fail('unknown prepared route');
|
|
77
|
-
const proof = rootAuthorityProtection(held.store), root = inheritedNativeRoot({ store: held.store, parent: process.pid, expected: held.context }, proof);
|
|
78
|
-
const profile = authenticateSignedPort(root, held.coordinate).profile;
|
|
79
|
-
if (canonicalJson(profile) !== canonicalJson(held.profile) || canonicalJson(authenticatedNativeBinaries(root, held.profile)) !== canonicalJson(route.binaries) || canonicalJson(selectedHostControl(root, held.profile) ?? null) !== canonicalJson(route.control ?? null))
|
|
80
|
-
fail('current port changed');
|
|
81
|
-
}
|
|
82
|
-
export function invokeNativeRoute(route, input) {
|
|
83
|
-
const held = routes.get(route);
|
|
84
|
-
if (!held)
|
|
85
|
-
return fail('unknown prepared route');
|
|
86
|
-
assertNativeRouteCurrent(route);
|
|
87
|
-
assertNativeRuntime(input.execution.env, input.execution.flags);
|
|
88
|
-
if (input.execution.context.implementation !== held.profile.selection.archive)
|
|
89
|
-
fail('reading implementation differs');
|
|
90
|
-
nativeReferenceInputs(input.execution.context.inputs, route.inputs);
|
|
91
|
-
if (input.limits.timeoutMs > held.profile.port.timeoutMs || input.limits.responseBytes > held.profile.port.responseBytes)
|
|
92
|
-
fail('reader limits exceed current command grant');
|
|
93
|
-
const proof = rootAuthorityProtection(held.store), frame = { proof, archive: input.archive, locations: input.locations, requests: input.requests };
|
|
94
|
-
const args = [processOf('native'), held.store, held.coordinate, JSON.stringify(held.context), 'reserved', String(held.profile.selection.budget.bytes), 'act', String(process.pid), JSON.stringify(input.execution)];
|
|
95
|
-
const result = boundedProcess(process.execPath, args, JSON.stringify(frame), input.limits, input.execution.cwd, input.execution.env);
|
|
96
|
-
if (result.signal !== null || result.status !== 0)
|
|
97
|
-
throw new CapsuleProcessError('native child exited ' + String(result.status ?? result.signal), result);
|
|
98
|
-
let values;
|
|
99
|
-
try {
|
|
100
|
-
values = JSON.parse(result.stdout.trimEnd());
|
|
101
|
-
}
|
|
102
|
-
catch {
|
|
103
|
-
return fail('native child malformed batch');
|
|
104
|
-
}
|
|
105
|
-
if (!Array.isArray(values) || values.length !== input.requests.length || !values.every((value, index) => validResponse(value, input.requests[index])))
|
|
106
|
-
fail('native child invalid batch');
|
|
107
|
-
assertNativeRouteCurrent(route);
|
|
108
|
-
return values;
|
|
109
|
-
}
|
|
110
|
-
/** This predicate only schedules an outer lease. It grants no command. */
|
|
111
|
-
export function declaredNativeReaderPorts(lines) { return lines.some(line => { const got = parse(line); return got.kind === 'fact' && got.value.fields.scope.startsWith('reader/') && got.value.fields.scope.split('/').at(-1) === 'port' && got.value.fields.value !== 'withdraw'; }); }
|
|
112
|
-
export function prepareNativeReaderRoute(store, reader) {
|
|
113
|
-
const expectedScope = ['reader', reader.module, 'port'].join('/');
|
|
114
|
-
const declared = authenticatedRootStanding(dirname(store));
|
|
115
|
-
if (!declared.some(line => { const got = parse(line); return got.kind === 'fact' && got.value.fields.scope === expectedScope && got.value.fields.value !== 'withdraw'; }))
|
|
116
|
-
return undefined;
|
|
117
|
-
const proof = rootAuthorityProtection(store), currentRoot = currentNativeRoot(store, process.pid, proof), root = currentRoot.root;
|
|
118
|
-
const rows = root.live.filter(line => { const got = parse(line); return got.kind === 'fact' && got.value.fields.scope === expectedScope; });
|
|
119
|
-
if (!rows.length)
|
|
120
|
-
return undefined;
|
|
121
|
-
if (rows.length !== 1)
|
|
122
|
-
fail('ambiguous reader port ' + expectedScope);
|
|
123
|
-
const got = parse(rows[0]);
|
|
124
|
-
if (got.kind !== 'fact')
|
|
125
|
-
return fail('invalid reader port ' + expectedScope);
|
|
126
|
-
const f = got.value.fields;
|
|
127
|
-
if (f.role !== 'writes' || f.form !== 'alphabet' || f.measure !== 'id' || typeof f.value !== 'string' || !/^port\/[^\s]+$/.test(f.value))
|
|
128
|
-
fail('malformed reader port ' + expectedScope);
|
|
129
|
-
const auth = authorityFor(root.history, root.signer, root.eras), signed = auth.of(rows[0]);
|
|
130
|
-
if (signed.kind !== 'admitted' || signed.signer !== root.signer.id)
|
|
131
|
-
fail('reader port is not Root signed ' + expectedScope);
|
|
132
|
-
if (signed.kind !== 'admitted')
|
|
133
|
-
return fail('reader port signature not admitted');
|
|
134
|
-
const signer = auth.admitted.find(one => one.id === signed.signer);
|
|
135
|
-
if (!signer)
|
|
136
|
-
return fail('reader port signer absent');
|
|
137
|
-
const current = authorityAtEpoch(f, signer, root.epoch, expectedScope, 'authority');
|
|
138
|
-
if (current.kind !== 'admitted')
|
|
139
|
-
fail('reader port current eligibility ' + current.why);
|
|
140
|
-
return prepareAtCurrentRoot(store, f.value, rows[0], currentRoot);
|
|
141
|
-
}
|
|
142
|
-
export function nativeRouteStore(route) { const held = routes.get(route); if (!held)
|
|
143
|
-
return fail('unknown prepared route'); return held.store; }
|
|
144
|
-
/** Quiet-pass gate: authenticate grants/cursor only, no image/materialization or
|
|
145
|
-
* program execution. Historical --check remains its separate receipt path. */
|
|
146
|
-
export function assertNativeReaderGrantsCurrent(store) { currentNativeReaderSelections(store); }
|
|
147
|
-
/** Executable kinds come only from current authenticated Root declarations. A
|
|
148
|
-
* matching JSON hint identifies a candidate, but is never permission to execute. */
|
|
149
|
-
export function authenticatedNativeBinaries(root, profile) {
|
|
150
|
-
const out = [], names = new Set();
|
|
151
|
-
const keys = fieldNames;
|
|
152
|
-
for (const line of root.live) {
|
|
153
|
-
const row = parse(line);
|
|
154
|
-
if (row.kind !== 'fact' || !row.value.fields.scope.startsWith('port/'))
|
|
155
|
-
continue;
|
|
156
|
-
let hint;
|
|
157
|
-
try {
|
|
158
|
-
hint = JSON.parse(row.value.fields.about ?? '');
|
|
159
|
-
}
|
|
160
|
-
catch {
|
|
161
|
-
continue;
|
|
162
|
-
}
|
|
163
|
-
if (!['host-native-binary@1', 'host-native-binary-origin@1'].includes(hint?.profile) || hint.selector?.port !== profile.port.coordinate)
|
|
164
|
-
continue;
|
|
165
|
-
const coordinate = row.value.fields.scope, auth = authenticateSignedPort(root, coordinate), p = auth.profile;
|
|
166
|
-
if (keys(p) !== (p.profile === 'host-native-binary-origin@1' ? 'alias,condition,coordinate,entry,limits,origin,profile,selector' : 'alias,condition,coordinate,entry,limits,profile,selector') || p.coordinate !== coordinate || typeof p.alias !== 'string' || !p.alias.length || p.alias.includes('\0') || typeof p.condition !== 'string' || !p.condition.length || keys(p.selector ?? {}) !== 'binding,implementation,port' || p.selector.implementation !== profile.port.implementation || !profile.selection.bindings.some(b => b.id === p.selector.binding))
|
|
167
|
-
fail('binary declaration differs from selected parent ' + coordinate);
|
|
168
|
-
const entry = p.entry, member = profile.selection.members.find(m => m.coordinate === entry?.path);
|
|
169
|
-
if (keys(entry ?? {}) !== 'bytes,digest,path' || !member || entry.path === profile.selection.runtime || member.digest !== entry.digest || !Number.isSafeInteger(entry.bytes) || entry.bytes < 1 || keys(p.limits ?? {}) !== 'bytes' || !Number.isSafeInteger(p.limits.bytes) || p.limits.bytes < entry.bytes || p.limits.bytes > profile.selection.budget.bytes)
|
|
170
|
-
fail('binary outside selected image resources ' + coordinate);
|
|
171
|
-
if (names.has(coordinate))
|
|
172
|
-
fail('ambiguous binary declaration ' + coordinate);
|
|
173
|
-
names.add(coordinate);
|
|
174
|
-
if (entry.digest === profile.selection.members.find(m => m.coordinate === profile.selection.runtime)?.digest)
|
|
175
|
-
fail('binary aliases selected runtime');
|
|
176
|
-
const origin = nativeBinaryOrigin(root, p, auth.line);
|
|
177
|
-
if (origin?.path === realpathSync(process.execPath))
|
|
178
|
-
fail('binary origin aliases actual runtime');
|
|
179
|
-
out.push(Object.freeze({ line: auth.line, coordinate, profile: p, ...(origin ? { origin } : {}) }));
|
|
180
|
-
}
|
|
181
|
-
return Object.freeze(out);
|
|
182
|
-
}
|
|
183
|
-
/** Same semantic image identity for preparation, retained mount and quiet checks. */
|
|
184
|
-
export function nativeMountIdentity(profile, binaries, control) { return hash(canonicalJson(['logical-native-image/2', profile.selection, binaries, ...(control ? [control] : [])])); }
|
|
185
|
-
/** Current eligibility only: no executor graph, image load or materialization. */
|
|
186
|
-
export function currentNativeReaderSelections(store) {
|
|
187
|
-
const declared = authenticatedRootStanding(dirname(store));
|
|
188
|
-
if (!declaredNativeReaderPorts(declared))
|
|
189
|
-
return [];
|
|
190
|
-
const proof = rootAuthorityProtection(store), currentRoot = currentNativeRoot(store, process.pid, proof), root = currentRoot.root;
|
|
191
|
-
const mappings = root.live.flatMap(line => { const row = parse(line); return row.kind === 'fact' && row.value.fields.scope.startsWith('reader/') && row.value.fields.scope.split('/').at(-1) === 'port' ? [{ line, fields: row.value.fields }] : []; });
|
|
192
|
-
const seen = new Set(), auth = authorityFor(root.history, root.signer, root.eras), out = [];
|
|
193
|
-
for (const { line, fields: f } of mappings) {
|
|
194
|
-
if (seen.has(f.scope))
|
|
195
|
-
fail('ambiguous reader port ' + f.scope);
|
|
196
|
-
seen.add(f.scope);
|
|
197
|
-
if (f.role !== 'writes' || f.form !== 'alphabet' || f.measure !== 'id' || typeof f.value !== 'string' || !/^port\/[^\s]+$/.test(f.value))
|
|
198
|
-
fail('malformed reader port ' + f.scope);
|
|
199
|
-
const signed = auth.of(line);
|
|
200
|
-
if (signed.kind !== 'admitted' || signed.signer !== root.signer.id)
|
|
201
|
-
fail('reader port is not Root signed ' + f.scope);
|
|
202
|
-
if (signed.kind !== 'admitted')
|
|
203
|
-
return fail('reader mapping not admitted');
|
|
204
|
-
const signer = auth.admitted.find(one => one.id === signed.signer);
|
|
205
|
-
if (!signer)
|
|
206
|
-
return fail('reader mapping signer absent');
|
|
207
|
-
const current = authorityAtEpoch(f, signer, root.epoch, f.scope, 'authority');
|
|
208
|
-
if (current.kind !== 'admitted')
|
|
209
|
-
fail('reader port current eligibility ' + current.why);
|
|
210
|
-
const { profile } = authenticateNativeProfile(root, f.value);
|
|
211
|
-
const control = selectedHostControl(root, profile);
|
|
212
|
-
out.push({ profile, binaries: authenticatedNativeBinaries(root, profile), ...(control ? { control } : {}) });
|
|
213
|
-
}
|
|
214
|
-
return out;
|
|
215
|
-
}
|
|
216
|
-
export function currentNativeReaderProfiles(store) { return currentNativeReaderSelections(store).map(selection => selection.profile); }
|
|
1
|
+
var q=Object.defineProperty;var m=(t,e)=>q(t,"name",{value:e,configurable:!0});import{fieldNames as M}from"./reading.js";import{sha256 as b}from"../hash.js";import{dirname as O}from"node:path";import{realpathSync as W}from"node:fs";import{nativeBinaryOrigin as F}from"./native-binary.js";import{selectedHostControl as R}from"./control-selection.js";import{library14_authorityAtEpoch as P}from"../../vendor/runtime.js";import{parsedLine as x}from"../../fold/claims.js";import{authorityFor as E}from"../../fold/signers.js";import{authenticatedRootStanding as j}from"../admitted-place.js";import{nativeExecutorInputs as $}from"./materialize.js";import{materializeNativeRoute as Se}from"./materialize.js";import{assertNativeRuntime as G}from"./runtime.js";import{nativeReferenceInputs as H}from"./references.js";import{rootAuthorityProtection as w}from"../../land/act.js";import{currentNativeRoot as N,inheritedNativeRoot as L}from"./root.js";import{authenticateSignedPort as z,authenticateNativeProfile as A,canonicalJson as y}from"./reading.js";import{boundedProcess as U}from"../process-lifetime.js";import{validResponse as _,CapsuleProcessError as D}from"../capsule-process.js";import{processOf as K}from"../../observe/runner.js";const s=m(t=>{throw Error("REFUSE\xB7native route "+t)},"fail"),k=new WeakMap;function Q(t){const e=new Map,i=[];for(const f of t){if(!f.origin)continue;const o="native/binary-origin/"+f.origin.coordinate,g=b(f.origin.line),a=e.get(o);if(a!==void 0){a!==g&&s("conflicting binary origin input "+o);continue}e.set(o,g),i.push([o,g])}return Object.freeze(i)}m(Q,"nativeBinaryOriginInputs");function he(t,e,i){const f=w(t),o=N(t,process.pid,f);return I(t,e,i,o)}m(he,"prepareNativeRoute");function I(t,e,i,f){const{root:o,context:g}=f,a=A(o,e),c=a.profile,l=S(o,c),n=R(o,c),r=b(y([e,a.line,c,l,i??null,...n?[n]:[]])),d=[["native/selection",r],...i?[["native/reader-mapping",b(i)]]:[],...c.selection.members.map(p=>["native/"+p.coordinate,p.digest]),...l.map(p=>["native/binary/"+p.coordinate,b(p.line)])];d.push(...Q(l)),n&&d.push(["native/control-profile",b(n.line)],["native/control-worker",n.profile.worker.digest],["native/control-runtime",n.profile.runtime.digest]);const h={identity:r,profile:c,binaries:l,...n?{control:n}:{},inputs:d};return k.set(h,{store:t,coordinate:e,context:g,profile:c}),d.push(...$(h)),n&&d.find(([p])=>p===n.profile.worker.coordinate)?.[1]!==n.profile.worker.digest&&s("control worker differs from sealed executor"),Object.freeze(d),Object.freeze(h)}m(I,"prepareAtCurrentRoot");function J(t){const e=k.get(t);if(!e)return s("unknown prepared route");const i=w(e.store),f=L({store:e.store,parent:process.pid,expected:e.context},i),o=z(f,e.coordinate).profile;(y(o)!==y(e.profile)||y(S(f,e.profile))!==y(t.binaries)||y(R(f,e.profile)??null)!==y(t.control??null))&&s("current port changed")}m(J,"assertNativeRouteCurrent");function ve(t,e){const i=k.get(t);if(!i)return s("unknown prepared route");J(t),G(e.execution.env,e.execution.flags),e.execution.context.implementation!==i.profile.selection.archive&&s("reading implementation differs"),H(e.execution.context.inputs,t.inputs),(e.limits.timeoutMs>i.profile.port.timeoutMs||e.limits.responseBytes>i.profile.port.responseBytes)&&s("reader limits exceed current command grant");const f=w(i.store),o={proof:f,archive:e.archive,locations:e.locations,requests:e.requests},g=[K("native"),i.store,i.coordinate,JSON.stringify(i.context),"reserved",String(i.profile.selection.budget.bytes),"act",String(process.pid),JSON.stringify(e.execution)],a=U(process.execPath,g,JSON.stringify(o),e.limits,e.execution.cwd,e.execution.env);if(a.signal!==null||a.status!==0)throw new D("native child exited "+String(a.status??a.signal),a);let c;try{c=JSON.parse(a.stdout.trimEnd())}catch{return s("native child malformed batch")}return(!Array.isArray(c)||c.length!==e.requests.length||!c.every((l,n)=>_(l,e.requests[n])))&&s("native child invalid batch"),J(t),c}m(ve,"invokeNativeRoute");function T(t){return t.some(e=>{const i=x(e);return i.kind==="fact"&&i.value.fields.scope.startsWith("reader/")&&i.value.fields.scope.split("/").at(-1)==="port"&&i.value.fields.value!=="withdraw"})}m(T,"declaredNativeReaderPorts");function ye(t,e){const i=["reader",e.module,"port"].join("/");if(!j(O(t)).some(u=>{const v=x(u);return v.kind==="fact"&&v.value.fields.scope===i&&v.value.fields.value!=="withdraw"}))return;const o=w(t),g=N(t,process.pid,o),a=g.root,c=a.live.filter(u=>{const v=x(u);return v.kind==="fact"&&v.value.fields.scope===i});if(!c.length)return;c.length!==1&&s("ambiguous reader port "+i);const l=x(c[0]);if(l.kind!=="fact")return s("invalid reader port "+i);const n=l.value.fields;(n.role!=="writes"||n.form!=="alphabet"||n.measure!=="id"||typeof n.value!="string"||!/^port\/[^\s]+$/.test(n.value))&&s("malformed reader port "+i);const r=E(a.history,a.signer,a.eras),d=r.of(c[0]);if((d.kind!=="admitted"||d.signer!==a.signer.id)&&s("reader port is not Root signed "+i),d.kind!=="admitted")return s("reader port signature not admitted");const h=r.admitted.find(u=>u.id===d.signer);if(!h)return s("reader port signer absent");const p=P(n,h,a.epoch,i,"authority");return p.kind!=="admitted"&&s("reader port current eligibility "+p.why),I(t,n.value,c[0],g)}m(ye,"prepareNativeReaderRoute");function be(t){const e=k.get(t);return e?e.store:s("unknown prepared route")}m(be,"nativeRouteStore");function xe(t){B(t)}m(xe,"assertNativeReaderGrantsCurrent");function S(t,e){const i=[],f=new Set,o=M;for(const g of t.live){const a=x(g);if(a.kind!=="fact"||!a.value.fields.scope.startsWith("port/"))continue;let c;try{c=JSON.parse(a.value.fields.about??"")}catch{continue}if(!["host-native-binary@1","host-native-binary-origin@1"].includes(c?.profile)||c.selector?.port!==e.port.coordinate)continue;const l=a.value.fields.scope,n=z(t,l),r=n.profile;(o(r)!==(r.profile==="host-native-binary-origin@1"?"alias,condition,coordinate,entry,limits,origin,profile,selector":"alias,condition,coordinate,entry,limits,profile,selector")||r.coordinate!==l||typeof r.alias!="string"||!r.alias.length||r.alias.includes("\0")||typeof r.condition!="string"||!r.condition.length||o(r.selector??{})!=="binding,implementation,port"||r.selector.implementation!==e.port.implementation||!e.selection.bindings.some(u=>u.id===r.selector.binding))&&s("binary declaration differs from selected parent "+l);const d=r.entry,h=e.selection.members.find(u=>u.coordinate===d?.path);(o(d??{})!=="bytes,digest,path"||!h||d.path===e.selection.runtime||h.digest!==d.digest||!Number.isSafeInteger(d.bytes)||d.bytes<1||o(r.limits??{})!=="bytes"||!Number.isSafeInteger(r.limits.bytes)||r.limits.bytes<d.bytes||r.limits.bytes>e.selection.budget.bytes)&&s("binary outside selected image resources "+l),f.has(l)&&s("ambiguous binary declaration "+l),f.add(l),d.digest===e.selection.members.find(u=>u.coordinate===e.selection.runtime)?.digest&&s("binary aliases selected runtime");const p=F(t,r,n.line);p?.path===W(process.execPath)&&s("binary origin aliases actual runtime"),i.push(Object.freeze({line:n.line,coordinate:l,profile:r,...p?{origin:p}:{}}))}return Object.freeze(i)}m(S,"authenticatedNativeBinaries");function we(t,e,i){return b(y(["logical-native-image/2",t.selection,e,...i?[i]:[]]))}m(we,"nativeMountIdentity");function B(t){const e=j(O(t));if(!T(e))return[];const i=w(t),f=N(t,process.pid,i),o=f.root,g=o.live.flatMap(n=>{const r=x(n);return r.kind==="fact"&&r.value.fields.scope.startsWith("reader/")&&r.value.fields.scope.split("/").at(-1)==="port"?[{line:n,fields:r.value.fields}]:[]}),a=new Set,c=E(o.history,o.signer,o.eras),l=[];for(const{line:n,fields:r}of g){a.has(r.scope)&&s("ambiguous reader port "+r.scope),a.add(r.scope),(r.role!=="writes"||r.form!=="alphabet"||r.measure!=="id"||typeof r.value!="string"||!/^port\/[^\s]+$/.test(r.value))&&s("malformed reader port "+r.scope);const d=c.of(n);if((d.kind!=="admitted"||d.signer!==o.signer.id)&&s("reader port is not Root signed "+r.scope),d.kind!=="admitted")return s("reader mapping not admitted");const h=c.admitted.find(C=>C.id===d.signer);if(!h)return s("reader mapping signer absent");const p=P(r,h,o.epoch,r.scope,"authority");p.kind!=="admitted"&&s("reader port current eligibility "+p.why);const{profile:u}=A(o,r.value),v=R(o,u);l.push({profile:u,binaries:S(o,u),...v?{control:v}:{}})}return l}m(B,"currentNativeReaderSelections");function ke(t){return B(t).map(e=>e.profile)}m(ke,"currentNativeReaderProfiles");export{xe as assertNativeReaderGrantsCurrent,J as assertNativeRouteCurrent,S as authenticatedNativeBinaries,ke as currentNativeReaderProfiles,B as currentNativeReaderSelections,T as declaredNativeReaderPorts,ve as invokeNativeRoute,Se as materializeNativeRoute,Q as nativeBinaryOriginInputs,we as nativeMountIdentity,be as nativeRouteStore,ye as prepareNativeReaderRoute,he as prepareNativeRoute};
|
|
@@ -1,9 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* preloads. The fixed native entry currently has no ambient loader contract.
|
|
3
|
-
*/
|
|
4
|
-
export function assertNativeRuntime(environment, flags) {
|
|
5
|
-
if ((environment.NODE_OPTIONS ?? '').trim() !== '')
|
|
6
|
-
throw Error('REFUSE·native runtime NODE_OPTIONS has no fixed verified loader configuration');
|
|
7
|
-
if (flags.length)
|
|
8
|
-
throw Error('REFUSE·native runtime startup flags differ from the fixed dispatcher');
|
|
9
|
-
}
|
|
1
|
+
var e=Object.defineProperty;var t=(r,i)=>e(r,"name",{value:i,configurable:!0});function n(r,i){if((r.NODE_OPTIONS??"").trim()!=="")throw Error("REFUSE\xB7native runtime NODE_OPTIONS has no fixed verified loader configuration");if(i.length)throw Error("REFUSE\xB7native runtime startup flags differ from the fixed dispatcher")}t(n,"assertNativeRuntime");export{n as assertNativeRuntime};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var i=Object.defineProperty;var o=(t,r)=>i(t,"name",{value:r,configurable:!0});import{existsSync as n}from"node:fs";import{storeOf as e}from"../land/ledger.js";import{admissionAnchor as a}from"../fold/admission-history.js";import{authenticatedStanding as m}from"./admitted-place.js";import{BoundRefusal as f}from"./refusals.js";function S(t){if(!n(e(t)))return"birth";try{if(a(t),!m(t).length)throw Error("no admitted history");return"admitted"}catch{throw new f("host/foundation-state","REFUSE\xB7host/foundation-state")}}o(S,"nativePlaceState");export{S as nativePlaceState};
|
|
@@ -1,8 +1 @@
|
|
|
1
|
-
|
|
2
|
-
// An opaque instrument selection travels with one observation. A request or a
|
|
3
|
-
// world's response cannot select its executor or replace another reader's port.
|
|
4
|
-
const active = new AsyncLocalStorage();
|
|
5
|
-
export const nativeReaderRoute = active.getStore.bind(active);
|
|
6
|
-
export function withNativeReaderRoute(route, run) {
|
|
7
|
-
return route === undefined ? run() : active.run(route, run);
|
|
8
|
-
}
|
|
1
|
+
var r=Object.defineProperty;var o=(e,t)=>r(e,"name",{value:t,configurable:!0});import{AsyncLocalStorage as i}from"node:async_hooks";const n=new i,d=n.getStore.bind(n);function u(e,t){return e===void 0?t():n.run(e,t)}o(u,"withNativeReaderRoute");export{d as nativeReaderRoute,u as withNativeReaderRoute};
|
|
@@ -1,25 +1 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { basename, dirname, extname, isAbsolute, join, relative } from 'node:path';
|
|
3
|
-
import { publicLock } from '@lapxo/topos/wire';
|
|
4
|
-
import { foldClaims, wireLinesOf } from "../fold/claims.js";
|
|
5
|
-
import { declaredRootClockSource } from "./root-clock-source.js";
|
|
6
|
-
import { withHostCall } from "./call-context.js";
|
|
7
|
-
import { BoundRefusal } from "./refusals.js";
|
|
8
|
-
/** Explicit installed/source ESM selection, never consumer argv or packet data.
|
|
9
|
-
* Identity and public configuration do not certify implementation correctness. */
|
|
10
|
-
export function nativeHostInstrument(root, entry) {
|
|
11
|
-
const at = realpathSync(root), file = realpathSync(entry), inside = relative(at, file), extension = extname(file);
|
|
12
|
-
if (!isAbsolute(root) || !isAbsolute(entry) || inside.startsWith('..') || isAbsolute(inside) || !['.ts', '.js'].includes(extension))
|
|
13
|
-
throw new BoundRefusal('host/context', 'REFUSE·host/context');
|
|
14
|
-
const published = publicLock(wireLinesOf(readFileSync(join(at, 'TARGET.bound'), 'utf8')));
|
|
15
|
-
if (!published)
|
|
16
|
-
throw new BoundRefusal('host/context', 'REFUSE·host requires a public instrument lock');
|
|
17
|
-
return { name: basename(at), runtime: { root: at, entry: file, directory: dirname(dirname(file)), extension: extension, lock: foldClaims(published).standing } };
|
|
18
|
-
}
|
|
19
|
-
/** Bind existing native authority construction to an explicit instrument for
|
|
20
|
-
* every later current/historical observation, not only the constructor call. */
|
|
21
|
-
export function nativePlaceActReceiver(root, instrument) {
|
|
22
|
-
const call = { instrumentName: instrument.name, runtime: structuredClone(instrument.runtime), output: () => { } };
|
|
23
|
-
const selected = withHostCall(call, () => declaredRootClockSource(root)), original = selected.trust;
|
|
24
|
-
return { selection: selected.selection, trust: { ...original, current: () => withHostCall(call, () => original.current()), historical: (encoded) => withHostCall(call, () => original.historical(encoded)) } };
|
|
25
|
-
}
|
|
1
|
+
var b=Object.defineProperty;var o=(e,i)=>b(e,"name",{value:i,configurable:!0});import{readFileSync as x,realpathSync as c}from"node:fs";import{basename as w,dirname as p,extname as v,isAbsolute as a,join as E,relative as C}from"node:path";import{library14_publicLock as R}from"../vendor/runtime.js";import{foldClaims as k,wireLinesOf as S}from"../fold/claims.js";import{declaredRootClockSource as I}from"./root-clock-source.js";import{withHostCall as m}from"./call-context.js";import{BoundRefusal as d}from"./refusals.js";import{installedPackageIdentity as g}from"./native/installed-package.js";let y;function F(e,i){const t=c(e),n=c(i),r=C(t,n),s=v(n);if(!a(e)||!a(i)||r.startsWith("..")||a(r)||![".ts",".js"].includes(s))throw new d("host/context","REFUSE\xB7host/context");const l=x(E(t,"TARGET.bound"),"utf8"),u=y;if(u?.root===t&&u.file===n&&u.text===l)return structuredClone(u.value);const f=R(S(l));if(!f?.length)throw new d("host/context","REFUSE\xB7host requires a public instrument lock");const h={name:w(t),runtime:{root:t,entry:n,directory:p(p(n)),extension:s,lock:k(f).standing}};return Buffer.byteLength(l)<=2*1024*1024&&(y={root:t,file:n,text:l,value:structuredClone(h)}),h}o(F,"nativeHostInstrument");function G(e,i){const t={instrumentName:i.name,runtime:structuredClone(i.runtime),output:o(()=>{},"output")},n=m(t,()=>I(e)),r=n.trust;return{selection:n.selection,trust:{...r,current:o(()=>m(t,()=>r.current()),"current"),historical:o(s=>m(t,()=>r.historical(s)),"historical")}}}o(G,"nativePlaceActReceiver");function N(e,i){const t=e.limits?.signal,n=structuredClone({...e,limits:{...e.limits,signal:void 0}}),r={...n,limits:{...n.limits,...t?{signal:t}:{}}},s=g(r);return{...F(r.directory,i),digest:s.digest,installed:{digest:s.digest,request:r}}}o(N,"installedHostInstrument");function O(e,i){try{const t=e.installed;if(!t||!/^sha256:[a-f0-9]{64}$/.test(i)||t.digest!==i||c(t.request.directory)!==c(e.runtime.root)||g(t.request).digest!==i)throw Error("installed pin differs")}catch{throw new d("host/instrument-pin","REFUSE\xB7host/instrument-pin")}}o(O,"verifyHostInstrument");export{N as installedHostInstrument,F as nativeHostInstrument,G as nativePlaceActReceiver,O as verifyHostInstrument};
|
package/dist/host/objects.js
CHANGED
|
@@ -1,38 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { objectProvider } from '@lapxo/topos/object-provider';
|
|
3
|
-
import { authorityFor, rootSigner } from "../fold/signers.js";
|
|
4
|
-
import { signaturesOf } from "../fold/digests.js";
|
|
5
|
-
import { storeOf } from "../land/ledger.js";
|
|
6
|
-
import { toposAt, contextModuleAt } from "./selected-topos.js";
|
|
7
|
-
import { foldClaims } from "../fold/claims.js";
|
|
8
|
-
import { usesWasmObject } from "../wasm/object.js";
|
|
9
|
-
/** Bound supplies host authority and I/O; topos owns grammar, selection and context validation. */
|
|
10
|
-
export async function admittedObjects(root, lines, emit = () => { }, requireContextClosure = false) {
|
|
11
|
-
const history = objectHistory(lines);
|
|
12
|
-
if (history.kind !== 'fact')
|
|
13
|
-
throw Error(`REFUSE·wire ${history.why}`);
|
|
14
|
-
const authority = authorityFor(lines, rootSigner(root), signaturesOf(storeOf(root)).admitted);
|
|
15
|
-
const admittedConfiguration = history.value.configuration.filter(fields => authority.of(canonical(fields)).kind === 'admitted').map(fields => canonical(fields));
|
|
16
|
-
const configuration = foldClaims(admittedConfiguration).standing.flatMap(line => { const got = parse(line); return got.kind === 'fact' ? [got.value.fields] : []; });
|
|
17
|
-
const verifyClosure = requireContextClosure || usesWasmObject(configuration), declaredModules = new Map();
|
|
18
|
-
const context = await objectProvider(history.value.objects, history.value.configuration, { admit: fields => authority.of(canonical(fields)).kind === 'admitted', emit, topos: digest => {
|
|
19
|
-
const selected = toposAt(digest, storeOf(root));
|
|
20
|
-
if (verifyClosure)
|
|
21
|
-
for (const offer of selected.parts.filter(fields => fields.kind === 'check' && fields.value)) {
|
|
22
|
-
const dependencies = [...new Set((offer.restsOn ?? '').split('|').filter(Boolean))].sort(), prior = declaredModules.get(offer.value);
|
|
23
|
-
if (prior && JSON.stringify(prior) !== JSON.stringify(dependencies))
|
|
24
|
-
throw Error('REFUSE·context module has conflicting declared closures');
|
|
25
|
-
declaredModules.set(offer.value, dependencies);
|
|
26
|
-
}
|
|
27
|
-
return selected;
|
|
28
|
-
}, module: digest => {
|
|
29
|
-
const dependencies = declaredModules.get(digest);
|
|
30
|
-
if (verifyClosure && dependencies === undefined)
|
|
31
|
-
throw Error('REFUSE·context module has no declared closure');
|
|
32
|
-
return contextModuleAt(digest, storeOf(root), verifyClosure ? dependencies : undefined);
|
|
33
|
-
} });
|
|
34
|
-
const checked = validateObjectContext(history.value.objects, context);
|
|
35
|
-
if (checked.kind !== 'fact')
|
|
36
|
-
throw Error(`REFUSE·context ${checked.why}`);
|
|
37
|
-
return { records: checked.value, context, configuration };
|
|
38
|
-
}
|
|
1
|
+
var b=Object.defineProperty;var e=(r,i)=>b(r,"name",{value:i,configurable:!0});import{library14_canonical as n,library14_parse as p,library14_objectHistory as y,library14_validateObjectContext as v}from"../vendor/runtime.js";import{objectProvider as g}from"../vendor/object-provider.js";import{authorityFor as h,rootSigner as j}from"../fold/signers.js";import{signaturesOf as x}from"../fold/digests.js";import{storeOf as d}from"../land/ledger.js";import{contextProviderServices as k}from"./selected-topos.js";import{foldClaims as w}from"../fold/claims.js";async function U(r,i,m=()=>{},C=!1){const o=y(i);if(o.kind!=="fact")throw Error(`REFUSE\xB7wire ${o.why}`);const c=h(i,j(r),x(d(r)).admitted),l=o.value.configuration.filter(t=>c.of(n(t)).kind==="admitted").map(t=>n(t)),u=w(l).standing.flatMap(t=>{const f=p(t);return f.kind==="fact"?[f.value.fields]:[]}),s=await g(o.value.objects,o.value.configuration,{admit:e(t=>c.of(n(t)).kind==="admitted","admit"),emit:m,...k(d(r))}),a=v(o.value.objects,s);if(a.kind!=="fact")throw Error(`REFUSE\xB7context ${a.why}`);return{records:a.value,context:s,configuration:u}}e(U,"admittedObjects");export{U as admittedObjects};
|
package/dist/host/order.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export const compareStrings = (a, b) => a < b ? -1 : a > b ? 1 : 0;
|
|
1
|
+
var c=Object.defineProperty;var t=(o,r)=>c(o,"name",{value:r,configurable:!0});const n=t((o,r)=>o<r?-1:o>r?1:0,"compareStrings");export{n as compareStrings};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var A=Object.defineProperty;var u=(t,i)=>A(t,"name",{value:i,configurable:!0});import{spawn as C}from"node:child_process";import{mkdtempSync as D,rmSync as N,realpathSync as V}from"node:fs";import{tmpdir as K}from"node:os";import{join as Q,basename as W}from"node:path";import{BoundRefusal as s}from"./refusals.js";import{nativePlaceState as X}from"./native-place-state.js";import{invokeSigningPort as Y}from"../engine/ports.js";import{verifyHostInstrument as T}from"./native-receiver.js";function Z(t){return Object.fromEntries(Object.entries(t).filter(i=>i[1]!==void 0&&!/^(NODE_|UV_)/.test(i[0])))}u(Z,"nativeHostEnvironment");const b=new Set;async function ce(t){T(t.instrument,t.expectedInstrument);const i=V(t.place),o={...t.limits};X(i);const a=new Map(t.signers??[]);if(t.signer){if(a.has(t.signer.keyId))throw new s("host/context","REFUSE\xB7host/context");a.set(t.signer.keyId,{name:t.signer.name,sign:t.signer.sign})}for(const[e,r]of a)if(typeof e!="string"||!e||typeof r.name!="string"||!r.name||typeof r.sign!="function")throw new s("host/context","REFUSE\xB7host/context");for(const e of Object.values(o))if(!Number.isSafeInteger(e)||e<1)throw new s("host/budget","REFUSE\xB7host/budget");if(o.timeoutMs>2147483647||o.heapMiB<16||o.heapMiB>4096)throw new s("host/budget","REFUSE\xB7host/budget");if(b.has(i))throw new s("host/busy","REFUSE\xB7host/busy");b.add(i);const R=Object.freeze(Z(t.environment)),v=Object.freeze(["--max-old-space-size="+o.heapMiB]),g=D(Q(t.scratchParent??K(),"bound-native-host-"));let n;try{n=C(process.execPath,[...v,t.instrument.runtime.entry],{cwd:i,env:R,stdio:["ignore","pipe","pipe","ipc"],serialization:"advanced",shell:!1})}catch(e){throw b.delete(i),N(g,{recursive:!0,force:!0}),e}let m=!1,z=0,y=0,w=0,k=Promise.resolve(),d,U,h;const L=new Promise((e,r)=>{U=e,h=r});let x;const F=new Promise(e=>{x=e}),B=u(()=>{m=!0,b.delete(i),N(g,{recursive:!0,force:!0}),d?.abort.abort(),d?.dispose(),d?.reject(new s("host/closed","REFUSE\xB7host/closed")),d=void 0,x()},"cleanup");n.once("error",e=>{h(e),B()}),n.once("exit",()=>{h(new s("host/closed","REFUSE\xB7host/closed")),B()});let I=0;const M=u(e=>{I+=e.length,I>o.responseBytes&&n.kill("SIGTERM")},"drain");n.stdout.on("data",M),n.stderr.on("data",M),n.on("message",async e=>{if(e?.kind==="ready"){U();return}const r=d;if(!(!r||e?.id!==r.id)){if(e.kind==="sign"){try{if(e.lot?.keyId!==r.signer)throw new s("host/signer-mismatch","REFUSE\xB7host/signer-mismatch");const c=r.signer===void 0?void 0:a.get(r.signer);if(!c)throw new s("host/unbound-signer","REFUSE\xB7host/unbound-signer");const f=await Y(e.lot,c.sign,{timeoutMs:o.timeoutMs,maxBytes:o.responseBytes},r.abort.signal);n.connected&&n.send({kind:"signed",id:r.id,records:f})}catch(c){n.connected&&n.send({kind:"signed",id:r.id,error:{code:c instanceof s?c.code:"host-port/failed"}})}return}if(e.kind==="result"){if(r.dispose(),d=void 0,typeof e.stdout!="string"||typeof e.stderr!="string"||!Number.isSafeInteger(e.status)||Buffer.byteLength(e.stdout)+Buffer.byteLength(e.stderr)>o.responseBytes){r.reject(new s("host/budget","REFUSE\xB7host/budget"));return}r.resolve({status:e.status,stdout:e.stdout,stderr:e.stderr})}}});const G=setTimeout(()=>{h(new s("host/timeout","REFUSE\xB7host/timeout")),n.kill("SIGTERM")},o.timeoutMs);n.send({kind:"configure",place:i,scratch:g,limits:o,instrumentName:W(t.instrument.runtime.root),instrumentRoot:t.instrument.runtime.root});try{await L,T(t.instrument,t.expectedInstrument)}catch(e){throw n.kill("SIGTERM"),await F,e}finally{clearTimeout(G)}return{pid:n.pid,environment:R,flags:v,request(e,r){const c=JSON.stringify(e),f=Buffer.byteLength(c);if(y>=o.queuedRequests||w+f>o.requestBytes)return Promise.reject(new s("host/budget","REFUSE\xB7host/budget"));const q=JSON.parse(c);y++,w+=f;const H=u(()=>new Promise((J,E)=>{if(m||!n.connected){E(new s("host/closed","REFUSE\xB7host/closed"));return}if(r?.aborted){E(new s("host/cancelled","REFUSE\xB7host/cancelled"));return}const p=++z,j=new AbortController,S=u(()=>{j.abort(),n.connected&&n.send({kind:"cancel",id:p})},"cancel"),_=setTimeout(S,o.timeoutMs);r?.addEventListener("abort",S,{once:!0});const l=q.signer,O=l===void 0?void 0:a.get(l);d={id:p,signer:l,resolve:J,reject:E,abort:j,dispose:u(()=>{clearTimeout(_),r?.removeEventListener("abort",S)},"dispose")},n.send({kind:"request",id:p,command:q,...l!==void 0||a.size?{signer:{keyId:l??"",name:O?.name??"",bound:!!O}}:{}})}),"run"),P=k.then(H).finally(()=>{y--,w-=f});return k=P.catch(()=>{}),P},async close(){m||(m=!0,d?.abort.abort(),n.connected&&n.send({kind:"close"})),await F}}}u(ce,"startNativeHost");export{Z as nativeHostEnvironment,ce as startNativeHost};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {public5_PhysicalLinesPlaceInput as PhysicalLinesPlaceInput,public5_PhysicalLinesPolicy as PhysicalLinesPolicy,public5_PhysicalLinesReading as PhysicalLinesReading,public5_PhysicalLinesRegion as PhysicalLinesRegion,public5_PhysicalLinesWitnessAuthority as PhysicalLinesWitnessAuthority,public5_ReadingProducerPolicy as ReadingProducerPolicy,public5_authenticatePhysicalLinesWitness as authenticatePhysicalLinesWitness,public5_judgePhysicalLines as judgePhysicalLines,public5_physicalLinesRegions as physicalLinesRegions,public5_readPlacePhysicalLines as readPlacePhysicalLines} from "../public-types.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var $=Object.defineProperty;var w=(e,t)=>$(e,"name",{value:t,configurable:!0});import{BoundRefusal as k}from"./refusals.js";import{sha256 as h,isSha256 as G}from"./hash.js";import{lstatSync as j,opendirSync as K,readSync as T,realpathSync as A,openSync as X,closeSync as Q,fstatSync as V,constants as M}from"node:fs";import{join as W,relative as Z,resolve as ee,sep as R}from"node:path";import{library5_PHYSICAL_LINES_PROFILE as D,library5_PHYSICAL_LINES_MODEL as C,library5_readPhysicalLines as J,library5_encodeReadingWitness as te,library5_decodeReadingWitness as ne,library5_readingWitnessStatementBytes as re}from"../vendor/runtime.js";import{library14_canonical as se,library14_byBytes as P,library14_steps as Y}from"../vendor/runtime.js";import{fieldOf as c,fieldsOf as ie}from"../fold/claims.js";import{foldCeilings as oe}from"../fold/ceilings.js";import{widenedWithoutWitness as ae}from"../judge/widening.js";const x=new WeakSet;function U(e){if(e&&typeof e=="object"){Object.freeze(e);for(const t of Object.values(e))U(t)}return e}w(U,"freeze");const a=w(e=>{const t=e.split("/")[0],o=["inventory-policy","inventory-boundary","context","run","outside-inventory","inventory-size"].includes(t)?"context":["region-declaration","region-selectors"].includes(t)?"selection":["inventory-moved","per-file-reading","witness-binding"].includes(t)?"integrity":t==="actual-reading-required"||t.startsWith("witness-")?"witness":"failed";throw new k("physical-lines/"+o,"REFUSE\xB7physical-lines/"+e)},"fail"),ce=w(e=>typeof e=="string"&&e.length>0&&!e.includes("\\")&&!/[\u0000-\u001f\u007f]/.test(e)&&e.split("/").every(t=>t!==""&&t!=="."&&t!==".."&&!t.includes("*")),"named");function Se(e){const t=e.filter(o=>c(o,"scope").startsWith("region/")&&c(o,"measure")==="coordinates"&&c(o,"value")!=="withdraw");return e.filter(o=>c(o,"role")==="reads"&&c(o,"form")==="interval"&&["lines","file-lines"].includes(c(o,"measure"))).map(o=>{const r=c(o,"scope"),u=Y(r),i=u.length>1&&u.at(-1)==="lines"?Y(u.slice(0,-1)):r,l=t.filter(s=>c(s,"scope")==="region/"+i);if(l.length!==1)return a("region-declaration/"+r);const B=c(l[0],"value").split("|").filter(Boolean);return B.length?{scope:r,selectors:B}:a("region-selectors/"+r)})}w(Se,"physicalLinesRegions");function Be(e){try{return le(e)}catch(t){throw t instanceof k?t:new k("physical-lines/failed","REFUSE\xB7physical-lines/failed "+(t instanceof Error?t.message:"native inventory unavailable"))}}w(Be,"readPlacePhysicalLines");function le(e){if(!e||!e.policy||!Number.isSafeInteger(e.policy.entryBudget)||e.policy.entryBudget<0||!/^\d+$/.test(e.policy.byteBudget)||!/^\d+$/.test(e.policy.rowBudget))return a("inventory-policy");if(!Array.isArray(e.inventory)||!e.inventory.length||!e.inventory.every(ce)||new Set(e.inventory).size!==e.inventory.length)return a("inventory-boundary");for(const n of[e.context,e.reader,e.implementation])if(!G(n))return a("context");if(typeof e.run!="string"||!e.run||/\s/.test(e.run))return a("run");const t=A(e.root),o=[],r=new Set;let u=0,i=0n;const l=[];function B(n){if(r.has(n))return;if(r.add(n),++u>e.policy.entryBudget){l.push({name:n,cause:"entry-budget"});return}const g=ee(t,n),N=Z(t,g);if(N===".."||N.startsWith(".."+R))return a("outside-inventory");let d;try{d=j(g)}catch{l.push({name:n,cause:"inventory-absent"});return}if(d.isSymbolicLink()){l.push({name:n,cause:"inventory-link"});return}if(d.isDirectory()){const O=K(g),S=[];try{let b;for(;(b=O.readSync())!==null;){if(S.length>=e.policy.entryBudget-u){l.push({name:W(n,b.name).split(R).join("/"),cause:"entry-budget"});return}S.push(b.name)}}finally{O.closeSync()}S.sort(P);for(const b of S){if(u>=e.policy.entryBudget){l.push({name:W(n,b).split(R).join("/"),cause:"entry-budget"});break}B(W(n,b).split(R).join("/"))}const m=j(g);if(m.isSymbolicLink()||d.dev!==m.dev||d.ino!==m.ino||d.mtimeMs!==m.mtimeMs)return a("inventory-moved")}else if(d.isFile()){if(!Number.isSafeInteger(d.size)||d.size<0)return a("inventory-size");if(i+BigInt(d.size)>BigInt(e.policy.byteBudget)){l.push({name:n,cause:"byte-budget"});return}if(A(g)!==g)return a("inventory-link");const O=X(g,M.O_RDONLY|M.O_NOFOLLOW);let S,m;try{const b=Buffer.alloc(d.size+1);let _=0,F=0;for(;_<b.length&&(F=T(O,b,_,b.length-_,null))>0;)_+=F;S=b.subarray(0,_),m=V(O)}finally{Q(O)}if(m.isSymbolicLink()||d.dev!==m.dev||d.ino!==m.ino||d.size!==m.size||d.mtimeMs!==m.mtimeMs||S.length!==m.size||(i+=BigInt(S.length),i>BigInt(e.policy.byteBudget)))return a("inventory-moved");o.push({name:n,digest:h(S),bytes:S})}else l.push({name:n,cause:"inventory-special-file"})}w(B,"visit");for(const n of[...e.inventory].sort(P))B(n);if(l.length)return{status:"unmeasured",cause:"inventory-incomplete",unavailable:l};o.sort((n,g)=>P(n.name,g.name));const s=h(JSON.stringify(o.map(({name:n,digest:g})=>({name:n,digest:g})))),f=J({profile:D,snapshot:s,files:o,regions:e.regions,policy:{byteBudget:e.policy.byteBudget,rowBudget:e.policy.rowBudget}},h);if(f.status!=="read")return f;const p=h(JSON.stringify(f.regions.map(({scope:n,selectors:g,selections:N,members:d})=>({scope:n,selectors:g,selections:N,members:d})))),L=h(JSON.stringify({inventory:[...e.inventory].sort(P),policy:e.policy,textDomain:f.textDomain})),E=J({profile:D,snapshot:s,files:o,regions:o.map(n=>({scope:n.name,selectors:[n.name]})),policy:{byteBudget:e.policy.byteBudget,rowBudget:e.policy.rowBudget}},h);if(E.status!=="read")return E;const y=h(JSON.stringify({reading:f,perFile:E})),v={contract:C.contract,model:h(JSON.stringify(C)),params:L,inputs:s,selection:p,unit:"physical-lines/utf8-lf@1",scale:h("finite-nonnegative-atomic-valuation@1"),resolution:h("whole-physical-lines@1"),reader:e.reader,implementation:e.implementation,context:e.context,run:e.run,result:y},I=h(JSON.stringify(v)),H=new Set(f.regions.flatMap(n=>n.members)),q=f.inputFiles.filter(n=>!H.has(n.name)).map(n=>n.name),z=U({status:"read",identity:I,bindings:{reading:I,...v},reading:f,perFile:E,stray:q});return x.add(z),z}w(le,"readPhysicalLinesInPlace");function de(e,t,o){if(!x.has(e))return a("actual-reading-required");let r;try{r=ne(t)}catch(i){throw new k("physical-lines/witness","REFUSE\xB7physical-lines/witness "+(i instanceof Error?i.message:"invalid witness record"))}for(const[i,l]of Object.entries(e.bindings))if(r[i]!==l)return a("witness-binding/"+i);const u=o.producers.find(i=>i.authentication!==r.authentication?!1:i.authentication==="key-covered"&&r.authentication==="key-covered"?i.key===r.key&&i.coverage===r.coverage:i.authentication==="ci-run-unkeyed"&&r.authentication==="ci-run-unkeyed"?i.repository===r.repository&&i.commit===r.commit&&i.workflow===r.workflow&&i.run===r.run&&i.attempt===r.attempt:!1);return u?o.verify({witness:r,statementBytes:re(r),producer:u})!==!0?a("witness-authentication"):"attest:"+h(te(r)):a("witness-producer-not-admitted")}w(de,"authenticatePhysicalLinesWitness");function Le(e){if(!x.has(e.reading))return a("actual-reading-required");const t=w(s=>c(s,"form")==="interval"&&c(s,"role")==="reads"&&["lines","file-lines"].includes(c(s,"measure")),"isLineCeiling");let o;if(e.witness!==void 0){if(!e.authority)return a("witness-authority-absent");o=de(e.reading,e.witness,e.authority)}const r=e.proposed.filter(s=>{const f=e.standing.find(L=>c(L,"scope")===c(s,"scope"));if(!f||!t(s))return!1;const p=se({...ie(s),at:"none"});return ae([p],[f],t,"attest").length>0&&(!o||c(s,"at")!==o)}),u=new Map(e.standing.filter(t).map(s=>[c(s,"scope"),s]));for(const s of e.proposed.filter(t))r.includes(s)||u.set(c(s,"scope"),s);const i=[],l=[],B=[];for(const s of u.values()){const f=c(s,"scope"),p=e.reading.reading.regions.find(y=>y.scope===f);if(!p||p.status!=="measured"||p.selections.some(y=>y.status==="unmeasured")){B.push({scope:f,cause:"selector-no-match",selectors:p?.selections.filter(y=>y.status==="unmeasured").map(y=>y.selector)??[]});continue}const L=c(s,"measure"),E=L==="file-lines"?p.members.map(y=>{const v=e.reading.perFile.regions.find(I=>I.scope===y);return!v||v.status!=="measured"?a("per-file-reading"):v.value}):[p.value];for(const[y,v]of E.entries()){if(l.push({scope:f,...L==="file-lines"?{file:p.members[y]}:{},value:v.numerator}),v.denominator!=="1"||BigInt(v.numerator)>BigInt(Number.MAX_SAFE_INTEGER))return a("threshold-number-resolution");i.push(oe({standing:e.standing,ceilings:[s],observed:[],own:{[L]:Number(v.numerator)},epoch:0}))}}return{status:r.length||i.some(s=>s.over.length)?"BLOCK":!u.size||B.length||e.reading.stray.length?"UNMEASURED":"READY",rejected:r,unmeasured:B,stray:e.reading.stray,observations:l,thresholds:i,reading:e.reading.identity}}w(Le,"judgePhysicalLines");export{de as authenticatePhysicalLinesWitness,Le as judgePhysicalLines,Se as physicalLinesRegions,Be as readPlacePhysicalLines};
|
|
@@ -1,78 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import { assertHostNotCancelled as cancelled, receiverClock, placeRegionOf } from "./host-controls.js";
|
|
6
|
-
export { ActCommitUnknown as PlaceActCommitUnknown } from "./commit-result.js";
|
|
7
|
-
/** The visibility point may have happened. Only an authenticated result query
|
|
8
|
-
* or replay can resolve this; the error never asserts rollback. */
|
|
9
|
-
const fail = (why) => { throw new BoundRefusal('host/act', 'REFUSE·place act ' + why); };
|
|
10
|
-
const rootBytes = (r) => JSON.stringify([r.namespace, r.snapshot, r.epoch, r.prefix, r.head, r.policies]);
|
|
11
|
-
/** Shared transaction, including historical replay, current authorization and
|
|
12
|
-
* atomic publication. Signing may await; current Root and receiver heads are
|
|
13
|
-
* checked again afterwards while the same exclusion remains held. */
|
|
14
|
-
export async function transactPlaceAct(encoded, source, trust, limits, persistence, signal) {
|
|
15
|
-
requireEffects('place act commitment');
|
|
16
|
-
cancelled(signal);
|
|
17
|
-
if (!limits || !Number.isSafeInteger(limits.acts) || limits.acts < 1 || !Number.isSafeInteger(limits.bytes) || limits.bytes < 1)
|
|
18
|
-
fail('missing storage budget');
|
|
19
|
-
const decoded = readPlaceActContext(encoded, trust.contract.budget), id = trust.contract.digest(encoded);
|
|
20
|
-
const regions = decoded.places.map(p => placeRegionOf(p.place));
|
|
21
|
-
return persistence.exclusive(regions, async () => {
|
|
22
|
-
cancelled(signal);
|
|
23
|
-
const prior = persistence.result(id, trust, limits);
|
|
24
|
-
if (prior) {
|
|
25
|
-
if (prior.context !== encoded)
|
|
26
|
-
fail('replay bytes differ');
|
|
27
|
-
// A signing callback is never invoked for a historically authenticated replay.
|
|
28
|
-
if (typeof source !== 'function')
|
|
29
|
-
placeActReceiptsOf(encoded, source, trust.historical(encoded));
|
|
30
|
-
return { ...prior, identity: id, kind: 'once' };
|
|
31
|
-
}
|
|
32
|
-
const verified = verifyPlaceActContext(encoded, trust.contract);
|
|
33
|
-
const originals = decoded.places.map(p => p.records);
|
|
34
|
-
const capacity = (size) => {
|
|
35
|
-
const inventory = persistence.inventory(limits);
|
|
36
|
-
if (inventory.bytes + size > limits.bytes)
|
|
37
|
-
fail('publication byte budget');
|
|
38
|
-
if (inventory.names.length >= limits.acts)
|
|
39
|
-
fail('publication act budget');
|
|
40
|
-
};
|
|
41
|
-
const sizeOf = (files) => Object.values(files).reduce((n, v) => n + new TextEncoder().encode(v).length, 0);
|
|
42
|
-
capacity(sizeOf({ 'context.json': encoded, 'originals.json': JSON.stringify(originals) + '\n' }));
|
|
43
|
-
const assertCurrent = () => {
|
|
44
|
-
const current = trust.current();
|
|
45
|
-
if (rootBytes(current.root) !== rootBytes(verified.dependencies))
|
|
46
|
-
fail('authority changed before publication');
|
|
47
|
-
if (new Set(current.heads.map(h => h.place)).size !== current.heads.length)
|
|
48
|
-
fail('ambiguous receiver heads');
|
|
49
|
-
const stored = persistence.heads(trust, limits);
|
|
50
|
-
for (const p of decoded.places) {
|
|
51
|
-
const actual = stored.find(h => h.place === p.place), selected = current.heads.find(h => h.place === p.place);
|
|
52
|
-
if (!actual || !selected || actual.identity !== selected.identity || actual.epoch !== selected.epoch)
|
|
53
|
-
fail('receiver snapshot is not committed head ' + p.place);
|
|
54
|
-
if (selected.identity !== p.previous)
|
|
55
|
-
fail('receiver head moved ' + p.place);
|
|
56
|
-
const next = receiverClock(selected.epoch, fail) + 1;
|
|
57
|
-
if (!Number.isSafeInteger(next) || receiverClock(p.epoch, fail) !== next)
|
|
58
|
-
fail('receiver epoch not next ' + p.place);
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
assertCurrent();
|
|
62
|
-
cancelled(signal);
|
|
63
|
-
const receipts = structuredClone(typeof source === 'function' ? await source() : source);
|
|
64
|
-
cancelled(signal);
|
|
65
|
-
placeActReceiptsOf(encoded, receipts, trust.contract);
|
|
66
|
-
const files = { 'context.json': encoded, 'receipts.json': JSON.stringify(receipts) + '\n', 'originals.json': JSON.stringify(originals) + '\n' };
|
|
67
|
-
capacity(sizeOf(files));
|
|
68
|
-
assertCurrent();
|
|
69
|
-
cancelled(signal);
|
|
70
|
-
try {
|
|
71
|
-
persistence.publish(id, files);
|
|
72
|
-
}
|
|
73
|
-
catch (error) {
|
|
74
|
-
throw new ActCommitUnknown(id, error);
|
|
75
|
-
}
|
|
76
|
-
return { context: encoded, receipts, originals, identity: id, kind: 'landed' };
|
|
77
|
-
});
|
|
78
|
-
}
|
|
1
|
+
var R=Object.defineProperty;var r=(e,i)=>R(e,"name",{value:i,configurable:!0});import{library6_readPlaceActContext as E,library6_verifyPlaceActContext as J,library6_placeActReceiptsOf as S}from"../vendor/runtime.js";import{requireEffects as U}from"./read-only.js";import{BoundRefusal as I}from"./refusals.js";import{ActCommitUnknown as _}from"./commit-result.js";import{assertHostNotCancelled as h,receiverClock as N,placeRegionOf as z}from"./host-controls.js";import{ActCommitUnknown as M}from"./commit-result.js";const n=r(e=>{throw new I("host/act","REFUSE\xB7place act "+e)},"fail"),j=r(e=>JSON.stringify([e.namespace,e.snapshot,e.epoch,e.prefix,e.head,e.policies]),"rootBytes");async function G(e,i,a,o,p,f){U("place act commitment"),h(f),(!o||!Number.isSafeInteger(o.acts)||o.acts<1||!Number.isSafeInteger(o.bytes)||o.bytes<1)&&n("missing storage budget");const m=E(e,a.contract.budget),l=a.contract.digest(e),k=m.places.map(y=>z(y.place));return p.exclusive(k,async()=>{h(f);const y=p.result(l,a,o);if(y)return y.context!==e&&n("replay bytes differ"),typeof i!="function"&&S(e,i,a.historical(e)),{...y,identity:l,kind:"once"};const P=J(e,a.contract),b=m.places.map(t=>t.records),v=r(t=>{const s=p.inventory(o);s.bytes+t>o.bytes&&n("publication byte budget"),s.names.length>=o.acts&&n("publication act budget")},"capacity"),C=r(t=>Object.values(t).reduce((s,c)=>s+new TextEncoder().encode(c).length,0),"sizeOf");v(C({"context.json":e,"originals.json":JSON.stringify(b)+`
|
|
2
|
+
`}));const w=r(()=>{const t=a.current();j(t.root)!==j(P.dependencies)&&n("authority changed before publication"),new Set(t.heads.map(c=>c.place)).size!==t.heads.length&&n("ambiguous receiver heads");const s=p.heads(a,o);for(const c of m.places){const g=s.find(x=>x.place===c.place),d=t.heads.find(x=>x.place===c.place);(!g||!d||g.identity!==d.identity||g.epoch!==d.epoch)&&n("receiver snapshot is not committed head "+c.place),d.identity!==c.previous&&n("receiver head moved "+c.place);const O=N(d.epoch,n)+1;(!Number.isSafeInteger(O)||N(c.epoch,n)!==O)&&n("receiver epoch not next "+c.place)}},"assertCurrent");w(),h(f);const u=structuredClone(typeof i=="function"?await i():i);h(f),S(e,u,a.contract);const A={"context.json":e,"receipts.json":JSON.stringify(u)+`
|
|
3
|
+
`,"originals.json":JSON.stringify(b)+`
|
|
4
|
+
`};v(C(A)),w(),h(f);try{p.publish(l,A)}catch(t){throw new _(l,t)}return{context:e,receipts:u,originals:b,identity:l,kind:"landed"}})}r(G,"transactPlaceAct");export{M as PlaceActCommitUnknown,G as transactPlaceAct};
|