@lapxo/bound 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -121
- package/TARGET.bound +65 -32
- package/dist/cli/owner.js +2 -1
- package/dist/cli/place.js +7 -26
- package/dist/cli/retained-judgment.js +25 -0
- package/dist/cli/standing-result.js +4 -3
- package/dist/cli/verb.js +36 -3
- package/dist/engine/encoding.js +2 -0
- package/dist/engine/index.d.ts +2 -0
- package/dist/engine/index.js +2 -0
- package/dist/engine/ports.d.ts +32 -0
- package/dist/engine/ports.js +103 -0
- package/dist/fold/admission-history.js +6 -11
- package/dist/fold/bootstrap-anchor.js +28 -0
- package/dist/fold/ceilings.js +13 -0
- package/dist/fold/own.js +7 -5
- package/dist/fold/signers.js +5 -9
- package/dist/host/admitted-place.js +6 -0
- package/dist/host/contextual-place.js +2 -2
- package/dist/host/io.js +2 -2
- package/dist/host/native/module-syntax.js +8 -4
- package/dist/host/reference-authenticated.d.ts +12 -0
- package/dist/host/reference-authenticated.js +47 -31
- package/dist/host/reference-contracts.js +6 -0
- package/dist/host/reference-export.d.ts +33 -0
- package/dist/host/reference-export.js +81 -0
- package/dist/host/reference-native-api.d.ts +3 -0
- package/dist/host/reference-native-api.js +3 -0
- package/dist/host/reference-native.d.ts +21 -1
- package/dist/host/reference-native.js +34 -10
- package/dist/host/reference-profile.js +2 -1
- package/dist/host/reference-standing.js +18 -0
- package/dist/host/refusals.d.ts +14 -0
- package/dist/host/refusals.js +43 -0
- package/dist/host/signing.js +7 -1
- package/dist/observe/files.js +11 -1
- package/dist/wasm/object.js +2 -2
- package/docs/contracts/authenticated-reference.publication.json +2 -2
- package/docs/contracts/host-ports.md +23 -0
- package/docs/contracts/host-ports.publication.json +25 -0
- package/docs/contracts/native-publication.inventory.json +7 -1
- package/docs/contracts/optional-wasm-adapter.publication.json +1 -1
- package/docs/contracts/readme.publication.json +25 -0
- package/docs/contracts/reference-backend.md +24 -0
- package/docs/contracts/reference-backend.publication.json +25 -0
- package/docs/contracts/reference-export.md +31 -0
- package/docs/contracts/reference-export.publication.json +25 -0
- package/docs/contracts/reference-port.md +8 -1
- package/docs/contracts/reference-port.publication.json +1 -1
- package/docs/contracts/refusals.bound +94 -0
- package/docs/contracts/refusals.md +47 -0
- package/docs/contracts/refusals.publication.json +25 -0
- package/docs/contracts/standing.bound +9 -0
- package/docs/contracts/standing.md +24 -0
- package/docs/contracts/standing.publication.json +25 -0
- package/package.json +52 -6
- package/receipts.bound +9703 -7690
- package/samples/authenticated-reference/compatibility.json +306 -0
- package/samples/authenticated-reference/yes.json +2 -2
- package/samples/engine-place/inputs/closure.json +1 -0
- package/samples/host-ports/no.json +16 -0
- package/samples/host-ports/yes.json +9 -0
- package/samples/readme/no.json +1 -0
- package/samples/readme/yes.json +1 -0
- package/samples/reference-backend/no.json +1 -0
- package/samples/reference-backend/world-fixture.json +8 -0
- package/samples/reference-backend/yes.json +1 -0
- package/samples/reference-export/no.json +5 -0
- package/samples/reference-export/yes.json +15 -0
- package/samples/reference-port/no/catalog/TARGET.bound +33 -0
- package/samples/reference-port/no/route-notes/TARGET.bound +33 -0
- package/samples/refusals/no.json +4 -0
- package/samples/refusals/yes.json +9 -0
- package/samples/standing/no.json +4 -0
- package/samples/standing/yes.json +21 -0
- package/vectors/native/authenticated-reference-formation.vector.json +55 -1
- package/vectors/native/authenticated-reference.vector.json +32 -396
- package/vectors/native/host-ports.vector.json +107 -0
- package/vectors/native/readme.vector.json +76 -0
- package/vectors/native/reference-backend.vector.json +84 -0
- package/vectors/native/reference-export.vector.json +78 -0
- package/vectors/native/refusals.vector.json +95 -0
- package/vectors/native/standing.vector.json +116 -0
- package/vectors/wasm-object.cli.json +16 -61
- package/dist/cli/accept.d.ts +0 -28
- package/dist/cli/act-result.d.ts +0 -12
- package/dist/cli/args.d.ts +0 -11
- package/dist/cli/custodian.d.ts +0 -1
- package/dist/cli/host.d.ts +0 -1
- package/dist/cli/names.d.ts +0 -25
- package/dist/cli/native-descendant.d.ts +0 -1
- package/dist/cli/native.d.ts +0 -1
- package/dist/cli/observe.d.ts +0 -1
- package/dist/cli/owner.d.ts +0 -37
- package/dist/cli/pass.d.ts +0 -6
- package/dist/cli/place.d.ts +0 -76
- package/dist/cli/release-result.d.ts +0 -5
- package/dist/cli/standing-result.d.ts +0 -5
- package/dist/cli/takes.d.ts +0 -30
- package/dist/fold/admission-history.d.ts +0 -6
- package/dist/fold/ceilings.d.ts +0 -24
- package/dist/fold/claims.d.ts +0 -29
- package/dist/fold/closed.d.ts +0 -15
- package/dist/fold/configures.d.ts +0 -4
- package/dist/fold/digests.d.ts +0 -29
- package/dist/fold/evidence.d.ts +0 -32
- package/dist/fold/fold-worker.d.ts +0 -1
- package/dist/fold/kept.d.ts +0 -29
- package/dist/fold/keys.d.ts +0 -17
- package/dist/fold/laid.d.ts +0 -17
- package/dist/fold/nos.d.ts +0 -8
- package/dist/fold/object.d.ts +0 -3
- package/dist/fold/observed.d.ts +0 -35
- package/dist/fold/opened.d.ts +0 -5
- package/dist/fold/own.d.ts +0 -24
- package/dist/fold/paid.d.ts +0 -11
- package/dist/fold/place-inputs.d.ts +0 -17
- package/dist/fold/places.d.ts +0 -24
- package/dist/fold/rank.d.ts +0 -3
- package/dist/fold/reach.d.ts +0 -18
- package/dist/fold/readers.d.ts +0 -47
- package/dist/fold/receipts.d.ts +0 -8
- package/dist/fold/region-declarations.d.ts +0 -2
- package/dist/fold/region.d.ts +0 -72
- package/dist/fold/release-policy.d.ts +0 -67
- package/dist/fold/resolved.d.ts +0 -18
- package/dist/fold/roles.d.ts +0 -17
- package/dist/fold/second.d.ts +0 -18
- package/dist/fold/shards.d.ts +0 -29
- package/dist/fold/signed.d.ts +0 -23
- package/dist/fold/signers.d.ts +0 -24
- package/dist/fold/stranger.d.ts +0 -3
- package/dist/fold/views.d.ts +0 -27
- package/dist/fold/wire.d.ts +0 -19
- package/dist/fold/zoom.d.ts +0 -16
- package/dist/host/act-cost.d.ts +0 -13
- package/dist/host/adapters/keys/ed25519.d.ts +0 -7
- package/dist/host/adapters/modules/javascript.d.ts +0 -3
- package/dist/host/adapters/transport/http.d.ts +0 -5
- package/dist/host/admitted-place.d.ts +0 -5
- package/dist/host/archive.d.ts +0 -11
- package/dist/host/capsule-process.d.ts +0 -21
- package/dist/host/capsule.d.ts +0 -19
- package/dist/host/cell-receipts.d.ts +0 -2
- package/dist/host/content-needed.d.ts +0 -5
- package/dist/host/content-store.d.ts +0 -8
- package/dist/host/contextual-place.d.ts +0 -59
- package/dist/host/digest.d.ts +0 -3
- package/dist/host/hash.d.ts +0 -9
- package/dist/host/io.d.ts +0 -11
- package/dist/host/lifetime.d.ts +0 -1
- package/dist/host/located.d.ts +0 -4
- package/dist/host/native/bounded-file.d.ts +0 -8
- package/dist/host/native/command.d.ts +0 -36
- package/dist/host/native/control-bridge-worker.d.ts +0 -1
- package/dist/host/native/control-bridge.d.ts +0 -30
- package/dist/host/native/control-selection.d.ts +0 -29
- package/dist/host/native/custody.d.ts +0 -5
- package/dist/host/native/deadline.d.ts +0 -12
- package/dist/host/native/descendants.d.ts +0 -1
- package/dist/host/native/generated-custodian.d.ts +0 -122
- package/dist/host/native/generated.d.ts +0 -217
- package/dist/host/native/image.d.ts +0 -36
- package/dist/host/native/jobs.d.ts +0 -75
- package/dist/host/native/loader.d.ts +0 -80
- package/dist/host/native/materialize.d.ts +0 -22
- package/dist/host/native/module-closure.d.ts +0 -27
- package/dist/host/native/module-syntax.d.ts +0 -8
- package/dist/host/native/native-binary.d.ts +0 -54
- package/dist/host/native/native-program.d.ts +0 -56
- package/dist/host/native/node-jobs.d.ts +0 -84
- package/dist/host/native/node-launch.d.ts +0 -72
- package/dist/host/native/preload.d.ts +0 -1
- package/dist/host/native/reading.d.ts +0 -91
- package/dist/host/native/receipt-environment.d.ts +0 -3
- package/dist/host/native/references.d.ts +0 -5
- package/dist/host/native/root.d.ts +0 -17
- package/dist/host/native/route.d.ts +0 -66
- package/dist/host/native/runtime.d.ts +0 -4
- package/dist/host/native-reader-context.d.ts +0 -3
- package/dist/host/objects.d.ts +0 -6
- package/dist/host/place-clock-selection.d.ts +0 -55
- package/dist/host/ports/ingress.d.ts +0 -24
- package/dist/host/ports/local-act.d.ts +0 -44
- package/dist/host/ports/place-act.d.ts +0 -46
- package/dist/host/ports/publication.d.ts +0 -10
- package/dist/host/ports/signing.d.ts +0 -31
- package/dist/host/ports/store.d.ts +0 -2
- package/dist/host/ports/transport.d.ts +0 -1
- package/dist/host/process-lifetime.d.ts +0 -11
- package/dist/host/provide.d.ts +0 -48
- package/dist/host/read-only.d.ts +0 -3
- package/dist/host/reading-closures.d.ts +0 -47
- package/dist/host/reading-context.d.ts +0 -29
- package/dist/host/reference.d.ts +0 -6
- package/dist/host/release.d.ts +0 -14
- package/dist/host/root-clock-source.d.ts +0 -85
- package/dist/host/selected-capsules.d.ts +0 -8
- package/dist/host/selected-topos.d.ts +0 -24
- package/dist/host/signing.d.ts +0 -3
- package/dist/host/source-content.d.ts +0 -12
- package/dist/host/timing.d.ts +0 -2
- package/dist/host/walk.d.ts +0 -6
- package/dist/judge/late.d.ts +0 -7
- package/dist/judge/take.d.ts +0 -59
- package/dist/judge/widening.d.ts +0 -1
- package/dist/land/act.d.ts +0 -30
- package/dist/land/alias.d.ts +0 -10
- package/dist/land/held.d.ts +0 -7
- package/dist/land/inert.d.ts +0 -26
- package/dist/land/leaving.d.ts +0 -14
- package/dist/land/ledger.d.ts +0 -33
- package/dist/land/owned.d.ts +0 -23
- package/dist/land/sign.d.ts +0 -15
- package/dist/land/standing-pin.d.ts +0 -3
- package/dist/land/vouched.d.ts +0 -21
- package/dist/land/withdraw.d.ts +0 -14
- package/dist/observe/files.d.ts +0 -14
- package/dist/observe/identity.d.ts +0 -21
- package/dist/observe/match.d.ts +0 -1
- package/dist/observe/regions.d.ts +0 -33
- package/dist/observe/run.d.ts +0 -31
- package/dist/observe/runner.d.ts +0 -20
- package/dist/render/capsule.d.ts +0 -24
- package/dist/render/field.d.ts +0 -3
- package/dist/render/names.d.ts +0 -3
- package/dist/render/open.d.ts +0 -27
- package/dist/render/page.d.ts +0 -3
- package/dist/render/receipts.d.ts +0 -3
- package/dist/render/shape.d.ts +0 -16
- package/dist/render/target.d.ts +0 -18
- package/dist/render/view.d.ts +0 -22
- package/dist/wasm/node-worker.d.ts +0 -1
- package/dist/wasm/object.d.ts +0 -8
- package/dist/wasm/worker.d.ts +0 -1
package/dist/cli/place.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { refreshRetainedJudgment } from "./retained-judgment.js";
|
|
1
2
|
import { timing } from "../host/timing.js";
|
|
2
3
|
import { attestationObservations } from "../fold/evidence.js";
|
|
3
4
|
import { parse as parseEvidenceFields } from '@lapxo/topos/wire';
|
|
@@ -11,7 +12,7 @@ import { meets, instrumentKept } from "../fold/closed.js";
|
|
|
11
12
|
import { foldPoints, keepFold, keptPlace } from "../fold/kept.js";
|
|
12
13
|
import { openCells } from "../render/open.js";
|
|
13
14
|
import { boundOf, packRegions, regionsNamed, regionsOf, unlikeReplay } from "../fold/region.js";
|
|
14
|
-
import { answersElsewhere, foldCeilings } from "../fold/ceilings.js";
|
|
15
|
+
import { answersElsewhere, foldCeilings, ceilingSummary } from "../fold/ceilings.js";
|
|
15
16
|
import { keyOf, keyFor, lockLines, lockStanding } from "../fold/keys.js";
|
|
16
17
|
import { wordFrom, wordOf, wordOn } from "../fold/wire.js";
|
|
17
18
|
import { bytesDigest, instrumentOf, signaturesOf } from "../fold/digests.js";
|
|
@@ -21,7 +22,7 @@ import { classDefaults, kindsOf, placesIn, spoken } from "../fold/places.js";
|
|
|
21
22
|
import { isCeiling } from "../fold/configures.js";
|
|
22
23
|
import { observedClaims, placedReadings } from "../fold/observed.js";
|
|
23
24
|
import { capsuleReadingsOver, currentReceiptObservations, retiredReceiptHistory } from "../observe/regions.js";
|
|
24
|
-
import { costReadings, ownReadings } from "../fold/own.js";
|
|
25
|
+
import { costReadings, ownReadings, currentActReadings } from "../fold/own.js";
|
|
25
26
|
import { paidOf } from "../fold/paid.js";
|
|
26
27
|
import { rolesOf } from "../fold/roles.js";
|
|
27
28
|
import { secondHead } from "../fold/second.js";
|
|
@@ -45,12 +46,6 @@ const costsOf = (store) => ledgerLines(store, 'take').filter((line) => fieldOf(l
|
|
|
45
46
|
function effectStates(_store) {
|
|
46
47
|
return 'none';
|
|
47
48
|
}
|
|
48
|
-
function listed(misses) {
|
|
49
|
-
const by = new Map();
|
|
50
|
-
for (const o of misses)
|
|
51
|
-
by.set(o.ceiling, [...(by.get(o.ceiling) ?? []), o.question === o.ceiling ? o.got : `${o.question}=${o.got}`]);
|
|
52
|
-
return [...by].map(([scope, got]) => `${scope} · ${got.length > 4 ? `${got.slice(0, 4).join(' ')} +${got.length - 4}` : got.join(' ')}`);
|
|
53
|
-
}
|
|
54
49
|
/**
|
|
55
50
|
* The fold of a place: the standing lock and what readers saw, narrowed to the place when one is named. A demand is the
|
|
56
51
|
* place's when every place it asks about lies there; a SHORT on a question also read outside it is not the place's to
|
|
@@ -170,7 +165,7 @@ export function coneOf(root, entry, ceilings, descent) {
|
|
|
170
165
|
if (meets(root, store, '') && instrumentKept(store) === instrumentOf(store, entry, standing, root, ownLock())) {
|
|
171
166
|
const held = keptPlace(store);
|
|
172
167
|
if (held !== undefined)
|
|
173
|
-
return { standing, observed: held.observed, own: held.own, kept: true };
|
|
168
|
+
return { standing, observed: held.observed, own: { ...held.own, ...currentActReadings() }, kept: true };
|
|
174
169
|
}
|
|
175
170
|
const named = regionsNamed(standing);
|
|
176
171
|
const reach = descent !== undefined && descent.length ? [...descent] : [...new Set(ceilings.map((line) => boundOf(named, line).region))];
|
|
@@ -199,7 +194,7 @@ export function foldPlace(root, entry, under, look = true, given) {
|
|
|
199
194
|
const prior = keptPlace(store, under, instrumentOf(store, entry, standingOf(root).standing, root, ownLock()));
|
|
200
195
|
if (prior !== undefined) {
|
|
201
196
|
process.stderr.write(`CLOSED ${under || '.'} · digest ${digestMs} ms\n`);
|
|
202
|
-
return
|
|
197
|
+
return refreshRetainedJudgment(prior, [...prior.standing.filter((line) => isCeiling(line) && !(under && fieldOf(line, 'measure') === 'unread')), ...ownCeilings(under)]);
|
|
203
198
|
}
|
|
204
199
|
}
|
|
205
200
|
const { standing, lock: attested, rendered, owned } = given?.standing ?? standingOf(root, under);
|
|
@@ -244,14 +239,7 @@ export function foldPlace(root, entry, under, look = true, given) {
|
|
|
244
239
|
history: live.history.filter((line) => fieldOf(line, 'needs').split('|').filter(Boolean).some(inside)),
|
|
245
240
|
observed,
|
|
246
241
|
receiptHistory: retiredReceiptHistory({ root, store, ...(under ? { under } : {}), standing, observed: read }),
|
|
247
|
-
ceilings:
|
|
248
|
-
read: folded.read.length,
|
|
249
|
-
total: ceilings.length,
|
|
250
|
-
unread: folded.unread.map((line) => fieldOf(line, 'scope')),
|
|
251
|
-
vacuous: folded.vacuous.map((line) => fieldOf(line, 'scope')),
|
|
252
|
-
short: listed(folded.over.filter((o) => o.side === 'short' && !shared.has(o.question))),
|
|
253
|
-
over: listed(folded.over.filter((o) => o.side === 'over')),
|
|
254
|
-
},
|
|
242
|
+
ceilings: ceilingSummary(folded, ceilings.length, shared),
|
|
255
243
|
orphans,
|
|
256
244
|
lock,
|
|
257
245
|
signed: signedByKey(store, standing, everywhere),
|
|
@@ -284,14 +272,7 @@ export function foldPlace(root, entry, under, look = true, given) {
|
|
|
284
272
|
release: releasePolicy({ standing: policyStanding, demands, paid: finalPaid, ceilings, readings: again, faults, verdicts: attestationObservations(policyStanding.map(line => { const r = parseEvidenceFields(line); return r.kind === 'fact' ? r.value.fields : {}; }), second), snapshot: { fold: taken, instrument: self } }),
|
|
285
273
|
missing: owed,
|
|
286
274
|
own: { ...place.own, ...docs },
|
|
287
|
-
ceilings:
|
|
288
|
-
...place.ceilings,
|
|
289
|
-
read: again.read.length,
|
|
290
|
-
unread: again.unread.map((line) => fieldOf(line, 'scope')),
|
|
291
|
-
vacuous: again.vacuous.map((line) => fieldOf(line, 'scope')),
|
|
292
|
-
short: listed(again.over.filter((o) => o.side === 'short' && !shared.has(o.question))),
|
|
293
|
-
over: listed(again.over.filter((o) => o.side === 'over')),
|
|
294
|
-
},
|
|
275
|
+
ceilings: ceilingSummary(again, ceilings.length, shared),
|
|
295
276
|
};
|
|
296
277
|
if (folder !== undefined && meets(root, store, under ?? '', true, whole.observed))
|
|
297
278
|
took('keep', () => keepFold(store, taken, whole, points, self));
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { foldCeilings, ceilingSummary } from "../fold/ceilings.js";
|
|
2
|
+
import { currentActReadings } from "../fold/own.js";
|
|
3
|
+
import { placedReadings } from "../fold/observed.js";
|
|
4
|
+
import { placesIn } from "../fold/places.js";
|
|
5
|
+
import { releasePolicy, releaseFaults } from "../fold/release-policy.js";
|
|
6
|
+
import { attestationObservations } from "../fold/evidence.js";
|
|
7
|
+
import { parse } from '@lapxo/topos/wire';
|
|
8
|
+
import { point, region, within } from '@lapxo/obligations/field';
|
|
9
|
+
/** A verified semantic fold can be reused. Its previous act's measurements cannot.
|
|
10
|
+
* Keep history intact and judge current measurements with the ordinary interpreters.
|
|
11
|
+
*/
|
|
12
|
+
export function refreshRetainedJudgment(prior, ceilings, current = currentActReadings(prior.under)) {
|
|
13
|
+
const own = { ...prior.own, ...current };
|
|
14
|
+
const readings = foldCeilings({ standing: prior.standing, ceilings, observed: prior.observed,
|
|
15
|
+
own, epoch: prior.epoch, ...(prior.under ? { under: prior.under, places: new Set(placesIn(prior.root)) } : {}) });
|
|
16
|
+
const standing = prior.standing.filter(line => !prior.grey.includes(line) && !prior.refused.includes(line));
|
|
17
|
+
const shared = new Set(prior.under ? placedReadings(prior.observed)
|
|
18
|
+
.filter(reading => !within(point(reading.place.replace(/\/\*$/, '')), region(prior.under)))
|
|
19
|
+
.map(reading => reading.question) : []);
|
|
20
|
+
return { ...prior, kept: true, own, ceilings: ceilingSummary(readings, ceilings.length, shared),
|
|
21
|
+
release: releasePolicy({ standing, demands: prior.demands, paid: prior.paid, ceilings, readings,
|
|
22
|
+
faults: releaseFaults(prior),
|
|
23
|
+
verdicts: attestationObservations(standing.map(line => { const got = parse(line); return got.kind === 'fact' ? got.value.fields : {}; }), prior.second),
|
|
24
|
+
snapshot: { fold: prior.key, instrument: prior.instrument } }) };
|
|
25
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { BoundRefusal } from "../host/refusals.js";
|
|
1
2
|
import { hasContextualPlace, contextualStanding } from "../host/contextual-place.js";
|
|
2
|
-
import {
|
|
3
|
+
import { publicStandingLines } from "../host/admitted-place.js";
|
|
3
4
|
import { viewsOf } from "../fold/views.js";
|
|
4
5
|
import { lockStanding } from "../fold/keys.js";
|
|
5
6
|
import { storeOf } from "../land/ledger.js";
|
|
@@ -10,11 +11,11 @@ import { storeOf } from "../land/ledger.js";
|
|
|
10
11
|
export function printStandingResult(root) {
|
|
11
12
|
const store = storeOf(root), view = viewsOf(lockStanding(store)).get('standing');
|
|
12
13
|
if (!view || view.shape || !view.regions.some(region => region.name === 'standing'))
|
|
13
|
-
throw
|
|
14
|
+
throw new BoundRefusal('standing/view', 'REFUSE·view standing requires a declared standing view');
|
|
14
15
|
if (hasContextualPlace(root)) {
|
|
15
16
|
process.stdout.write(JSON.stringify(contextualStanding(root)) + '\n');
|
|
16
17
|
return;
|
|
17
18
|
}
|
|
18
|
-
const standing =
|
|
19
|
+
const standing = publicStandingLines(root);
|
|
19
20
|
process.stdout.write(standing.length ? standing.join('\n') + '\n' : '');
|
|
20
21
|
}
|
package/dist/cli/verb.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { BoundRefusal, describeRefusal, readRefusalCatalog } from "../host/refusals.js";
|
|
3
|
+
import { readFileSync as readCatalogFile } from 'node:fs';
|
|
4
|
+
import { sha256 as catalogDigest } from "../host/hash.js";
|
|
2
5
|
import { printReleaseApproval } from "./release-result.js";
|
|
3
6
|
import { inspectReference } from "../host/reference.js";
|
|
7
|
+
import { exportAuthenticatedReference } from "../host/reference-export.js";
|
|
4
8
|
import { authenticatedReferenceSelected, openAuthenticatedReference } from "../host/reference-native.js";
|
|
5
9
|
import { printActResult } from "./act-result.js";
|
|
6
10
|
import { printStandingResult } from "./standing-result.js";
|
|
@@ -209,7 +213,7 @@ async function view(root, under, asked, told = [], coord, key, includePolicy = t
|
|
|
209
213
|
}
|
|
210
214
|
if (name === 'standing') {
|
|
211
215
|
if (under || told.length || coord || depth !== undefined)
|
|
212
|
-
throw
|
|
216
|
+
throw new BoundRefusal('standing/query', 'REFUSE·standing local committed projection only');
|
|
213
217
|
printStandingResult(root);
|
|
214
218
|
return EXIT.closed;
|
|
215
219
|
}
|
|
@@ -374,6 +378,15 @@ async function view(root, under, asked, told = [], coord, key, includePolicy = t
|
|
|
374
378
|
return shown(fold);
|
|
375
379
|
}
|
|
376
380
|
async function signVerb(root, rest) {
|
|
381
|
+
const as = valueOf(rest, FLAGS.as);
|
|
382
|
+
if (as !== undefined) {
|
|
383
|
+
const sources = positionalsOf(rest);
|
|
384
|
+
if (as !== 'reference' || sources.length !== 1 || rest.includes(FLAGS.check))
|
|
385
|
+
throw new BoundRefusal('reference-export/usage', 'REFUSE·reference-export usage: sign --as reference <source-url>');
|
|
386
|
+
const result = await exportAuthenticatedReference(root, sources[0], { key: valueOf(rest, FLAGS.key), keyFile: valueOf(rest, FLAGS.keyFile), signer: valueOf(rest, FLAGS.signer) });
|
|
387
|
+
process.stdout.write(JSON.stringify(result) + '\n');
|
|
388
|
+
return EXIT.closed;
|
|
389
|
+
}
|
|
377
390
|
const batch = await signedBatch(root, rest, positionalsOf(rest));
|
|
378
391
|
if (batch.kind === 'exit')
|
|
379
392
|
return batch.code;
|
|
@@ -633,18 +646,38 @@ function main(argv) {
|
|
|
633
646
|
process.stderr.write(`${selfName()}: ${helpLines().join(' · ')}\n`);
|
|
634
647
|
return EXIT.usage;
|
|
635
648
|
}
|
|
649
|
+
function printRefusal(error) {
|
|
650
|
+
try {
|
|
651
|
+
const text = readCatalogFile(new URL('../../docs/contracts/refusals.bound', import.meta.url), 'utf8');
|
|
652
|
+
const entry = describeRefusal(error, readRefusalCatalog(text));
|
|
653
|
+
process.stderr.write(JSON.stringify({ profile: 'bound-refusal@1', ...entry, catalog: catalogDigest(text) }) + '\n');
|
|
654
|
+
}
|
|
655
|
+
catch {
|
|
656
|
+
// A missing/invalid catalog cannot supply trustworthy metadata. Keep the
|
|
657
|
+
// failure named instead of recursively failing while formatting a refusal.
|
|
658
|
+
process.stderr.write(JSON.stringify({ profile: 'bound-refusal@1', code: 'catalog/invalid', unmeasured: ['category', 'meaning', 'next', 'catalog'] }) + '\n');
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
// Legacy numeric refusals receive a generic code by exit result, never by parsing
|
|
662
|
+
// a diagnostic. Specific causes retain their own typed code in the error path.
|
|
663
|
+
function finished(code) {
|
|
664
|
+
if (code === EXIT.refuse || code === EXIT.usage)
|
|
665
|
+
printRefusal(new BoundRefusal(code === EXIT.usage ? 'operation/usage' : 'operation/failed', ''));
|
|
666
|
+
process.exitCode = code;
|
|
667
|
+
}
|
|
636
668
|
// The same refusal boundary covers synchronous operations and asynchronous processes.
|
|
637
669
|
const refused = (error) => {
|
|
638
670
|
const message = error instanceof Error ? error.message : String(error);
|
|
639
671
|
process.stderr.write(`${selfName()}: ${message.startsWith('REFUSE·') ? message : `REFUSE·crash ${message}`}\n`);
|
|
672
|
+
printRefusal(error instanceof BoundRefusal ? error : new BoundRefusal('operation/failed', message));
|
|
640
673
|
process.exitCode = EXIT.refuse;
|
|
641
674
|
};
|
|
642
675
|
try {
|
|
643
676
|
const ran = main(process.argv.slice(2));
|
|
644
677
|
if (ran instanceof Promise)
|
|
645
|
-
ran.then(
|
|
678
|
+
ran.then(finished).catch(refused);
|
|
646
679
|
else
|
|
647
|
-
|
|
680
|
+
finished(ran);
|
|
648
681
|
}
|
|
649
682
|
catch (error) {
|
|
650
683
|
refused(error);
|
package/dist/engine/index.d.ts
CHANGED
|
@@ -9,3 +9,5 @@
|
|
|
9
9
|
export { objectFold } from './object.ts';
|
|
10
10
|
export type { ObjectReading } from './object.ts';
|
|
11
11
|
export type { ObjectRecord, ObjectContext } from '@lapxo/topos/wire';
|
|
12
|
+
export { readContent, retainContent, invokeSigningPort } from './ports.ts';
|
|
13
|
+
export type { PortLimits, ContentReadPort, PersistencePort, DigestPort, SigningPort, SigningLot, SignatureRecord } from './ports.ts';
|
package/dist/engine/index.js
CHANGED
|
@@ -7,3 +7,5 @@
|
|
|
7
7
|
* Object operations delegate to the existing Obligations implementation.
|
|
8
8
|
*/
|
|
9
9
|
export { objectFold } from "./object.js";
|
|
10
|
+
// Optional host operations are explicit and injected; objectFold itself never invokes them.
|
|
11
|
+
export { readContent, retainContent, invokeSigningPort } from "./ports.js";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface PortLimits {
|
|
2
|
+
readonly timeoutMs: number;
|
|
3
|
+
readonly maxBytes: number;
|
|
4
|
+
}
|
|
5
|
+
export interface SigningLot {
|
|
6
|
+
readonly bytes: readonly string[];
|
|
7
|
+
readonly keyId: string;
|
|
8
|
+
readonly algorithm: string;
|
|
9
|
+
}
|
|
10
|
+
export interface SignatureRecord {
|
|
11
|
+
readonly keyId: string;
|
|
12
|
+
readonly signature: string;
|
|
13
|
+
}
|
|
14
|
+
export type SigningPort = (lot: SigningLot, signal: AbortSignal) => Promise<readonly SignatureRecord[]>;
|
|
15
|
+
export type ContentReadPort = (source: string, digest: string, signal: AbortSignal) => Promise<Uint8Array>;
|
|
16
|
+
/** Atomic byte retention supplied by the host. This is neither admission nor a current-answer cache. */
|
|
17
|
+
export type PersistencePort = (digest: string, bytes: Uint8Array, signal: AbortSignal) => Promise<void>;
|
|
18
|
+
export type DigestPort = (bytes: Uint8Array) => string | Promise<string>;
|
|
19
|
+
export declare function readContent(source: string, digest: string, ports: {
|
|
20
|
+
readonly read: ContentReadPort;
|
|
21
|
+
readonly digestBytes: DigestPort;
|
|
22
|
+
}, limits: PortLimits, signal?: AbortSignal): Promise<Uint8Array>;
|
|
23
|
+
/** Verify before invoking retention; no operation automatically writes the projected result. */
|
|
24
|
+
export declare function retainContent(digest: string, bytes: Uint8Array, ports: {
|
|
25
|
+
readonly retain: PersistencePort;
|
|
26
|
+
readonly digestBytes: DigestPort;
|
|
27
|
+
}, limits: PortLimits, signal?: AbortSignal): Promise<{
|
|
28
|
+
readonly digest: string;
|
|
29
|
+
readonly bytes: number;
|
|
30
|
+
}>;
|
|
31
|
+
/** Acquire protocol-shaped signatures only; the existing consent path verifies them and decides authority. */
|
|
32
|
+
export declare function invokeSigningPort(lot: SigningLot, sign: SigningPort, limits: PortLimits, signal?: AbortSignal): Promise<readonly SignatureRecord[]>;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { signerRequestBytes, signerResponseBytes, signerResponseOf } from '@lapxo/topos/wire';
|
|
2
|
+
import { BoundRefusal } from "../host/refusals.js";
|
|
3
|
+
import { encodeUTF8 as encoded } from "./encoding.js";
|
|
4
|
+
class PortFault extends BoundRefusal {
|
|
5
|
+
}
|
|
6
|
+
const fail = (code) => { throw new PortFault('host-port/' + code, 'REFUSE·host-port/' + code); };
|
|
7
|
+
function limitsOf(limits) { if (!limits || !Number.isSafeInteger(limits.timeoutMs) || limits.timeoutMs < 1 || limits.timeoutMs > 2147483647 || !Number.isSafeInteger(limits.maxBytes) || limits.maxBytes < 1)
|
|
8
|
+
fail('budget'); }
|
|
9
|
+
/** The callback must cooperate with cancellation; JavaScript callbacks are not a sandbox. */
|
|
10
|
+
async function bounded(limits, signal, run) {
|
|
11
|
+
limitsOf(limits);
|
|
12
|
+
if (signal?.aborted)
|
|
13
|
+
fail('cancelled');
|
|
14
|
+
return new Promise((resolve, reject) => {
|
|
15
|
+
const controller = new AbortController();
|
|
16
|
+
let done = false;
|
|
17
|
+
const finish = (code, value) => { if (done)
|
|
18
|
+
return; done = true; clearTimeout(timer); signal?.removeEventListener('abort', abort); if (code) {
|
|
19
|
+
controller.abort();
|
|
20
|
+
reject(new BoundRefusal('host-port/' + code, 'REFUSE·host-port/' + code));
|
|
21
|
+
}
|
|
22
|
+
else
|
|
23
|
+
resolve(value); };
|
|
24
|
+
const abort = () => finish('cancelled'), timer = setTimeout(() => finish('timeout'), limits.timeoutMs);
|
|
25
|
+
signal?.addEventListener('abort', abort, { once: true });
|
|
26
|
+
if (signal?.aborted) {
|
|
27
|
+
abort();
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
Promise.resolve().then(() => { if (done)
|
|
31
|
+
fail('cancelled'); return run(controller.signal); }).then(value => finish(undefined, value), error => finish(error instanceof PortFault ? error.code.slice('host-port/'.length) : 'failed'));
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
function owned(bytes, maxBytes) { if (!(bytes instanceof Uint8Array))
|
|
35
|
+
fail('response'); if (bytes.byteLength > maxBytes)
|
|
36
|
+
fail('budget'); if (typeof SharedArrayBuffer !== 'undefined' && bytes.buffer instanceof SharedArrayBuffer)
|
|
37
|
+
fail('response'); return new Uint8Array(bytes); }
|
|
38
|
+
const identity = (digest) => { if (!/^sha256:[a-f0-9]{64}$/.test(digest))
|
|
39
|
+
fail('integrity'); };
|
|
40
|
+
export async function readContent(source, digest, ports, limits, signal) {
|
|
41
|
+
limitsOf(limits);
|
|
42
|
+
identity(digest);
|
|
43
|
+
return bounded(limits, signal, async (s) => { const bytes = owned(await ports.read(source, digest, s), limits.maxBytes); if (s.aborted)
|
|
44
|
+
fail('cancelled'); if (await ports.digestBytes(new Uint8Array(bytes)) !== digest)
|
|
45
|
+
fail('integrity'); if (s.aborted)
|
|
46
|
+
fail('cancelled'); return bytes; });
|
|
47
|
+
}
|
|
48
|
+
/** Verify before invoking retention; no operation automatically writes the projected result. */
|
|
49
|
+
export async function retainContent(digest, bytes, ports, limits, signal) {
|
|
50
|
+
limitsOf(limits);
|
|
51
|
+
identity(digest);
|
|
52
|
+
if (signal?.aborted)
|
|
53
|
+
fail('cancelled');
|
|
54
|
+
const copy = owned(bytes, limits.maxBytes);
|
|
55
|
+
return bounded(limits, signal, async (s) => { if (await ports.digestBytes(new Uint8Array(copy)) !== digest)
|
|
56
|
+
fail('integrity'); if (s.aborted)
|
|
57
|
+
fail('cancelled'); const result = await ports.retain(digest, copy, s); if (result !== undefined)
|
|
58
|
+
fail('response'); return Object.freeze({ digest, bytes: copy.byteLength }); });
|
|
59
|
+
}
|
|
60
|
+
/** Acquire protocol-shaped signatures only; the existing consent path verifies them and decides authority. */
|
|
61
|
+
export async function invokeSigningPort(lot, sign, limits, signal) {
|
|
62
|
+
limitsOf(limits);
|
|
63
|
+
if (!lot || !Array.isArray(lot.bytes))
|
|
64
|
+
fail('budget');
|
|
65
|
+
let size = 0;
|
|
66
|
+
for (const bytes of lot.bytes) {
|
|
67
|
+
if (typeof bytes !== 'string' || bytes.length > limits.maxBytes - size)
|
|
68
|
+
fail('budget');
|
|
69
|
+
size += encoded(bytes).length + 1;
|
|
70
|
+
if (size > limits.maxBytes)
|
|
71
|
+
fail('budget');
|
|
72
|
+
}
|
|
73
|
+
let request;
|
|
74
|
+
try {
|
|
75
|
+
request = signerRequestBytes(lot);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return fail('response');
|
|
79
|
+
}
|
|
80
|
+
if (encoded(request).length > limits.maxBytes)
|
|
81
|
+
fail('budget');
|
|
82
|
+
const input = Object.freeze({ ...lot, bytes: Object.freeze([...lot.bytes]) });
|
|
83
|
+
return bounded(limits, signal, async (s) => {
|
|
84
|
+
const records = await sign(input, s);
|
|
85
|
+
if (!Array.isArray(records) || records.length !== lot.bytes.length || records.some(r => !r || typeof r.signature !== 'string' || r.signature.length > limits.maxBytes))
|
|
86
|
+
fail('response');
|
|
87
|
+
let response;
|
|
88
|
+
try {
|
|
89
|
+
response = signerResponseBytes(records);
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return fail('response');
|
|
93
|
+
}
|
|
94
|
+
if (encoded(response).length > limits.maxBytes)
|
|
95
|
+
fail('budget');
|
|
96
|
+
try {
|
|
97
|
+
return Object.freeze(signerResponseOf(response, lot).map(record => Object.freeze({ ...record })));
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return fail('response');
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { readFileSync } from 'node:fs';
|
|
1
|
+
import { bootstrapAnchor } from "./bootstrap-anchor.js";
|
|
3
2
|
import { rootLedgerLines, storeOf } from "../land/ledger.js";
|
|
4
|
-
import { fieldOf, isConfig
|
|
3
|
+
import { fieldOf, isConfig } from "./claims.js";
|
|
5
4
|
/** Local admission history only. Foreign ingress is evidence, never coverage.
|
|
6
5
|
* The clock cutoff is meaningful for configuration; object clocks stay intact. */
|
|
7
6
|
export function admissionHistoryAt(root, epoch) {
|
|
@@ -9,14 +8,10 @@ export function admissionHistoryAt(root, epoch) {
|
|
|
9
8
|
return [...new Set(rootLedgerLines(store))]
|
|
10
9
|
.filter(line => fieldOf(line, 'sig') !== '' && (!isConfig(line) || Number(fieldOf(line, 'epoch')) <= epoch));
|
|
11
10
|
}
|
|
12
|
-
/** The
|
|
11
|
+
/** The original local bootstrap, never today's key selection. */
|
|
13
12
|
export function admissionAnchor(root) {
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
const anchors = Object.values(keys);
|
|
17
|
-
if (anchors.length !== 1 || !anchors[0]?.publicKey || !anchors[0].coverage.length)
|
|
13
|
+
const anchor = bootstrapAnchor(root);
|
|
14
|
+
if (!anchor)
|
|
18
15
|
throw Error('REFUSE·act historical admission requires one bootstrap anchor');
|
|
19
|
-
|
|
20
|
-
return { id: anchor.id, keyClass: 'authorize', publicKey: anchor.publicKey, coverage: anchor.coverage,
|
|
21
|
-
depth: { lo: 1, hi: 16 }, admittedBy: [] };
|
|
16
|
+
return { id: anchor.id, keyClass: 'authorize', publicKey: anchor.publicKey, coverage: anchor.coverage, depth: { lo: 1, hi: 16 }, admittedBy: [] };
|
|
22
17
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { existsSync, readFileSync, readdirSync } from 'node:fs';
|
|
3
|
+
import { storeOf } from "../land/ledger.js";
|
|
4
|
+
/** Read the existing place-local root of trust. Names and current claims select no authority. */
|
|
5
|
+
export function bootstrapAnchor(root) {
|
|
6
|
+
const store = storeOf(root);
|
|
7
|
+
const files = existsSync(store) ? readdirSync(store).filter(name => name.endsWith('.keys')).sort() : [];
|
|
8
|
+
if (!files.length)
|
|
9
|
+
return undefined;
|
|
10
|
+
const candidates = files.map(name => {
|
|
11
|
+
let keys;
|
|
12
|
+
try {
|
|
13
|
+
keys = JSON.parse(readFileSync(join(store, name), 'utf8'));
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
throw Error('REFUSE·act bootstrap anchor is unreadable');
|
|
17
|
+
}
|
|
18
|
+
const anchors = Object.values(keys ?? {}), anchor = anchors[0];
|
|
19
|
+
if (anchors.length !== 1 || !anchor || typeof anchor.id !== 'string' || !anchor.id || typeof anchor.publicKey !== 'string' || !anchor.publicKey || !Array.isArray(anchor.coverage) || !anchor.coverage.length || anchor.coverage.some(scope => typeof scope !== 'string' || !scope))
|
|
20
|
+
throw Error('REFUSE·act historical admission requires one bootstrap anchor');
|
|
21
|
+
return anchor;
|
|
22
|
+
});
|
|
23
|
+
const identities = new Set(candidates.map(anchor => JSON.stringify([anchor.id, anchor.publicKey, [...new Set(anchor.coverage)].sort()])));
|
|
24
|
+
if (identities.size !== 1)
|
|
25
|
+
throw Error('REFUSE·act conflicting bootstrap anchors');
|
|
26
|
+
const anchor = candidates[0];
|
|
27
|
+
return { id: anchor.id, publicKey: anchor.publicKey, coverage: anchor.coverage };
|
|
28
|
+
}
|
package/dist/fold/ceilings.js
CHANGED
|
@@ -127,3 +127,16 @@ export function foldCeilings(input) {
|
|
|
127
127
|
readings: said,
|
|
128
128
|
};
|
|
129
129
|
}
|
|
130
|
+
function listed(misses) {
|
|
131
|
+
const by = new Map();
|
|
132
|
+
for (const o of misses)
|
|
133
|
+
by.set(o.ceiling, [...(by.get(o.ceiling) ?? []), o.question === o.ceiling ? o.got : `${o.question}=${o.got}`]);
|
|
134
|
+
return [...by].map(([scope, got]) => `${scope} · ${got.length > 4 ? `${got.slice(0, 4).join(' ')} +${got.length - 4}` : got.join(' ')}`);
|
|
135
|
+
}
|
|
136
|
+
/** One summary for fresh and retained judgments over the same declared bounds. */
|
|
137
|
+
export function ceilingSummary(fold, total, shared = new Set()) {
|
|
138
|
+
return { read: fold.read.length, total, unread: fold.unread.map(line => fieldOf(line, 'scope')),
|
|
139
|
+
vacuous: fold.vacuous.map(line => fieldOf(line, 'scope')),
|
|
140
|
+
short: listed(fold.over.filter(one => one.side === 'short' && !shared.has(one.question))),
|
|
141
|
+
over: listed(fold.over.filter(one => one.side === 'over')) };
|
|
142
|
+
}
|
package/dist/fold/own.js
CHANGED
|
@@ -27,6 +27,12 @@ import { writtenIn } from "./signed.js";
|
|
|
27
27
|
import { laidDiffers } from "./laid.js";
|
|
28
28
|
import { heldBytes } from "../land/held.js";
|
|
29
29
|
import { capsuleAt, placesIn, worldAt } from "./places.js";
|
|
30
|
+
/** Measurements of this invocation; never evidence of an earlier kept fold. */
|
|
31
|
+
export function currentActReadings(under) {
|
|
32
|
+
const receipts = receiptsSeen();
|
|
33
|
+
return placeOnly({ idle: idleCount(), s: actSeconds(), 'walk-read': receipts.count, 'walk-ms': receipts.ms,
|
|
34
|
+
'kept-folds-read-under-another-instrument': foldsElsewhere() }, under);
|
|
35
|
+
}
|
|
30
36
|
const entered = { foreign: 0 };
|
|
31
37
|
/** Host and instrument measurements. Domain contracts require their selected readers; missing readings are not fabricated zeroes. */
|
|
32
38
|
function shipped(root, store, standing, under) {
|
|
@@ -193,12 +199,8 @@ export function ownReadings(input) {
|
|
|
193
199
|
...Object.fromEntries(standing.filter((line) => isCeiling(line) && (fieldOf(line, 'measure') === 'reader-modules' || fieldOf(line, 'scope').split('/').pop() === 'reader-modules'))
|
|
194
200
|
.flatMap((line) => ((place) => place === undefined ? [] : [[fieldOf(line, 'scope'), tree(() => exporting(observed, `${place}/`, ['observe', 'run']))]])(fieldOf(line, 'scope').split('/').find((step) => capsuleAt(root, step))))),
|
|
195
201
|
...ownFrom(ceilingsNamed(standing, 'world-lines-outside-their-capsule').find((line) => fieldOf(line, 'form') === 'interval'), 'world-lines-outside-their-capsule', tree(() => outsideTheirCapsule(root, standing, standing).length)),
|
|
196
|
-
|
|
197
|
-
s: actSeconds(),
|
|
202
|
+
...currentActReadings(),
|
|
198
203
|
'cli-verbs': VERB_NAMES.length,
|
|
199
|
-
'walk-read': receiptsSeen().count,
|
|
200
|
-
'walk-ms': receiptsSeen().ms,
|
|
201
|
-
'kept-folds-read-under-another-instrument': tree(() => foldsElsewhere()),
|
|
202
204
|
'accepts-that-refolded': tree(() => counted(store, standing, 'beat/accept', 'folded')),
|
|
203
205
|
...(keyOf(store, 'attest') === undefined ? {} : { [`${keyOf(store, 'attest')}-ms`]: tree(() => attestBeat(store, standing)) }),
|
|
204
206
|
ship: took('ship', () => shipped(root, store, standing, under)),
|
package/dist/fold/signers.js
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { bootstrapAnchor } from "./bootstrap-anchor.js";
|
|
2
2
|
import { authorityOf, isKeyClaim, signersOf } from '@lapxo/topos/wire';
|
|
3
3
|
import { verifiesFields } from "../land/sign.js";
|
|
4
|
-
import { fieldOf,
|
|
4
|
+
import { fieldOf, parsedLine as parse } from "./claims.js";
|
|
5
5
|
import { keyFor, lockStanding } from "./keys.js";
|
|
6
|
-
import { storeRoot } from "../host/ports/store.js";
|
|
7
6
|
import { storeOf } from "../land/ledger.js";
|
|
8
|
-
import { observeText } from "../observe/files.js";
|
|
9
7
|
/** A lock line about the signers: the authority fold reads it. */
|
|
10
8
|
export function isSignerLock(line) {
|
|
11
9
|
const got = parse(line);
|
|
@@ -38,11 +36,9 @@ export function writerFor(standing, kind) {
|
|
|
38
36
|
return undefined;
|
|
39
37
|
}
|
|
40
38
|
export function publicKeyOf(root, keyId) {
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if (anchored !== undefined)
|
|
45
|
-
return anchored;
|
|
39
|
+
const anchor = bootstrapAnchor(root);
|
|
40
|
+
if (anchor?.id === keyId)
|
|
41
|
+
return anchor.publicKey;
|
|
46
42
|
const said = lockStanding(storeOf(root))
|
|
47
43
|
.find((line) => fieldOf(line, 'scope') === `keys/${keyId}` && fieldOf(line, 'measure') === 'public-key' && fieldOf(line, 'value') !== 'withdraw');
|
|
48
44
|
return said === undefined ? undefined : fieldOf(said, 'value');
|
|
@@ -55,3 +55,9 @@ export function authenticatedRootStanding(root) {
|
|
|
55
55
|
}
|
|
56
56
|
/** Legacy Root lines remain unchanged; contextual public output has its own carrier. */
|
|
57
57
|
export const authenticatedStanding = authenticatedRootStanding;
|
|
58
|
+
/** Public current configuration omits withdrawal markers; typed effective history
|
|
59
|
+
* remains intact for the existing typed-object projection. Internal readers keep
|
|
60
|
+
* authenticatedStanding, including its historical markers. */
|
|
61
|
+
export function publicStandingLines(root) {
|
|
62
|
+
return authenticatedRootStanding(root).filter(line => !isConfig(line) || fieldOf(line, 'value') !== 'withdraw');
|
|
63
|
+
}
|
|
@@ -5,7 +5,7 @@ import { commitPlaceAct, placeActResult, committedPlaceActResults } from "./port
|
|
|
5
5
|
import { placesIn } from "../fold/places.js";
|
|
6
6
|
import { appliedHistoryIn } from "../fold/signed.js";
|
|
7
7
|
import { storeOf } from "../land/ledger.js";
|
|
8
|
-
import {
|
|
8
|
+
import { publicStandingLines } from "./admitted-place.js";
|
|
9
9
|
import { foldClaims, fieldOf } from "../fold/claims.js";
|
|
10
10
|
const fail = (s) => { throw Error('REFUSE·contextual place ' + s); };
|
|
11
11
|
function read(path, limit) {
|
|
@@ -73,5 +73,5 @@ export function contextualStanding(root) {
|
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
const legacyPlaces = placesIn(root).map(place => { const history = appliedHistoryIn(root, place), folded = foldClaims(history); return { namespace: 'legacy-global', place: [place, 'TARGET.bound'].join('/'), standing: folded.standing.filter(line => fieldOf(line, 'value') !== 'withdraw'), history }; });
|
|
76
|
-
return { profile: PLACE_ACT_CONTEXT, root:
|
|
76
|
+
return { profile: PLACE_ACT_CONTEXT, root: publicStandingLines(root), legacyPlaces, contexts: acts.map(a => ({ identity: a.identity, context: a.bundle.context, receipts: a.bundle.receipts, authority: selected.authority(a.bundle.context) })), places: [...groups.values()].map(group => { const folded = foldClaims(group.lines); return { namespace: group.namespace, place: group.place, standing: folded.standing.filter(line => fieldOf(line, 'value') !== 'withdraw'), retracted: folded.retracted, superseded: folded.superseded, forks: folded.forks, contexts: group.contexts }; }) };
|
|
77
77
|
}
|
package/dist/host/io.js
CHANGED
|
@@ -7,5 +7,5 @@ export { basename, dirname, join, relative, resolve } from 'node:path';
|
|
|
7
7
|
export { fileURLToPath } from 'node:url';
|
|
8
8
|
export { parentPort, workerData } from 'node:worker_threads';
|
|
9
9
|
export { gzipSync } from 'node:zlib';
|
|
10
|
-
/** UTF-8 encoding
|
|
11
|
-
export
|
|
10
|
+
/** UTF-8 encoding is shared with host-free protocol ports. */
|
|
11
|
+
export { encodeUTF8 } from "../engine/encoding.js";
|
|
@@ -18,12 +18,12 @@ export function moduleImportSyntax(source, coordinate) {
|
|
|
18
18
|
}
|
|
19
19
|
const found = new Set(), unresolved = new Set();
|
|
20
20
|
const literal = stringLiteral;
|
|
21
|
-
const visit = (node, parent, key) => {
|
|
21
|
+
const visit = (node, parent, key, reexportSource = false) => {
|
|
22
22
|
if (!node || typeof node !== 'object')
|
|
23
23
|
return;
|
|
24
24
|
if (Array.isArray(node)) {
|
|
25
25
|
for (const child of node)
|
|
26
|
-
visit(child, parent, key);
|
|
26
|
+
visit(child, parent, key, reexportSource);
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
29
29
|
const n = node;
|
|
@@ -32,7 +32,11 @@ export function moduleImportSyntax(source, coordinate) {
|
|
|
32
32
|
if (n['type'] === 'Identifier' && n['name'] === 'require') {
|
|
33
33
|
const direct = parent?.['type'] === 'CallExpression' && key === 'callee';
|
|
34
34
|
const namedProperty = (parent?.['type'] === 'MemberExpression' && key === 'property' && !parent['computed']) || ((parent?.['type'] === 'Property' || parent?.['type'] === 'MethodDefinition') && key === 'key' && !parent['computed'] && !parent['shorthand']);
|
|
35
|
-
|
|
35
|
+
// Declaration names are not loader references. This does not resolve shadowing:
|
|
36
|
+
// references to a binding named require remain conservative, including local calls.
|
|
37
|
+
const declarationName = ((parent?.['type'] === 'ImportSpecifier' || parent?.['type'] === 'ImportDefaultSpecifier' || parent?.['type'] === 'ImportNamespaceSpecifier') && (key === 'imported' || key === 'local')) || (parent?.['type'] === 'FunctionDeclaration' && key === 'id');
|
|
38
|
+
const reexportName = parent?.['type'] === 'ExportSpecifier' && (key === 'exported' || (key === 'local' && reexportSource));
|
|
39
|
+
if (!direct && !namedProperty && !declarationName && !reexportName)
|
|
36
40
|
unresolved.add('require reference at ' + String(n['start']));
|
|
37
41
|
}
|
|
38
42
|
let specifier;
|
|
@@ -52,7 +56,7 @@ export function moduleImportSyntax(source, coordinate) {
|
|
|
52
56
|
if (specifier !== undefined)
|
|
53
57
|
found.add(specifier);
|
|
54
58
|
for (const [childKey, child] of Object.entries(n))
|
|
55
|
-
visit(child, n, childKey);
|
|
59
|
+
visit(child, n, childKey, n['type'] === 'ExportNamedDeclaration' ? n['source'] !== null && n['source'] !== undefined : reexportSource);
|
|
56
60
|
};
|
|
57
61
|
visit(tree);
|
|
58
62
|
return { imports: [...found], unresolved: [...unresolved] };
|
|
@@ -9,6 +9,10 @@ export interface ReferenceTrust {
|
|
|
9
9
|
readonly formImplementation: string;
|
|
10
10
|
readonly signers: readonly Signer[];
|
|
11
11
|
readonly algorithms: readonly string[];
|
|
12
|
+
readonly contracts?: {
|
|
13
|
+
readonly refusals: string;
|
|
14
|
+
readonly standing: string;
|
|
15
|
+
};
|
|
12
16
|
readonly objects: ObjectContext;
|
|
13
17
|
readonly maxBytes: number;
|
|
14
18
|
readonly maxRecords: number;
|
|
@@ -18,6 +22,10 @@ export interface ReferenceTrust {
|
|
|
18
22
|
}
|
|
19
23
|
/** Prospective authenticated-standing@1 host composition; no effects and no authority from transport. */
|
|
20
24
|
export declare function inspectAuthenticatedReference(fragment: string, trust: ReferenceTrust): Promise<{
|
|
25
|
+
contracts?: {
|
|
26
|
+
refusals: string;
|
|
27
|
+
standing: string;
|
|
28
|
+
} | undefined;
|
|
21
29
|
reference: import("./reference-profile.ts").StandingReference;
|
|
22
30
|
records: readonly import("@lapxo/topos/wire").ObjectRecord[];
|
|
23
31
|
semanticIdentity: string;
|
|
@@ -26,3 +34,7 @@ export declare function inspectAuthenticatedReference(fragment: string, trust: R
|
|
|
26
34
|
originalRecords: readonly string[];
|
|
27
35
|
}>;
|
|
28
36
|
export { encodeReference, decodeReference } from './reference-profile.ts';
|
|
37
|
+
export { BoundRefusal, readRefusalCatalog, describeRefusal } from './refusals.ts';
|
|
38
|
+
export type { RefusalEntry } from './refusals.ts';
|
|
39
|
+
export { readContent, retainContent, invokeSigningPort } from '../engine/ports.ts';
|
|
40
|
+
export type { PortLimits, ContentReadPort, PersistencePort, DigestPort, SigningPort, SigningLot, SignatureRecord } from '../engine/ports.ts';
|