@lapxo/bound 0.2.4 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CITATION.cff +1 -1
- package/TARGET.bound +44 -39
- package/dist/cli/accept.js +72 -590
- package/dist/cli/act-result.js +3 -103
- package/dist/cli/args.js +3 -44
- package/dist/cli/custodian.js +2 -29
- package/dist/cli/host.js +4 -32
- package/dist/cli/names.js +1 -12
- package/dist/cli/native-descendant.js +1 -19
- package/dist/cli/native.js +3 -60
- package/dist/cli/observe.js +1 -13
- package/dist/cli/owner.js +3 -139
- package/dist/cli/pass.js +21 -321
- package/dist/cli/place.js +6 -282
- package/dist/cli/release-result.js +3 -80
- package/dist/cli/retained-judgment.js +1 -25
- package/dist/cli/standing-result.js +4 -19
- package/dist/cli/takes.js +10 -112
- package/dist/cli/verb.d.ts +1 -2
- package/dist/cli/verb.js +83 -684
- package/dist/engine/computation.js +2 -0
- package/dist/engine/conformance.js +4 -0
- package/dist/engine/encoding.js +1 -2
- package/dist/engine/index.d.ts +1 -13
- package/dist/engine/index.js +2 -11
- package/dist/engine/object.js +1 -38
- package/dist/engine/ports.js +2 -117
- package/dist/fold/admission-history.js +1 -17
- package/dist/fold/bootstrap-anchor.js +1 -28
- package/dist/fold/ceilings.js +1 -142
- package/dist/fold/claims.js +2 -132
- package/dist/fold/closed.js +24 -235
- package/dist/fold/configures.js +1 -25
- package/dist/fold/digests.js +10 -226
- package/dist/fold/evidence.js +1 -22
- package/dist/fold/fold-worker.js +1 -13
- package/dist/fold/kept.js +12 -173
- package/dist/fold/keys.js +3 -91
- package/dist/fold/laid.js +3 -90
- package/dist/fold/nos.js +1 -48
- package/dist/fold/object.js +1 -2
- package/dist/fold/observed.js +27 -534
- package/dist/fold/opened.js +1 -33
- package/dist/fold/own.js +3 -217
- package/dist/fold/paid.js +1 -92
- package/dist/fold/place-inputs.js +1 -70
- package/dist/fold/places.js +3 -100
- package/dist/fold/rank.js +1 -9
- package/dist/fold/reach.js +1 -83
- package/dist/fold/readers.js +6 -142
- package/dist/fold/receipts.js +1 -47
- package/dist/fold/region-declarations.js +1 -13
- package/dist/fold/region.js +8 -286
- package/dist/fold/release-policy.js +1 -101
- package/dist/fold/resolved.js +6 -145
- package/dist/fold/roles.js +2 -59
- package/dist/fold/second.js +4 -71
- package/dist/fold/shards.js +12 -100
- package/dist/fold/signed.js +3 -81
- package/dist/fold/signers.js +1 -54
- package/dist/fold/stranger.js +6 -24
- package/dist/fold/views.js +1 -66
- package/dist/fold/wire.js +1 -46
- package/dist/fold/zoom.js +3 -81
- package/dist/host/act-cost.js +1 -25
- package/dist/host/adapters/keys/ed25519.js +1 -30
- package/dist/host/adapters/modules/javascript.js +1 -50
- package/dist/host/adapters/transport/http.js +1 -28
- package/dist/host/admitted-place.js +1 -35
- package/dist/host/archive.js +1 -152
- package/dist/host/call-context.js +1 -14
- package/dist/host/capsule-process.js +2 -62
- package/dist/host/capsule.js +9 -171
- package/dist/host/cell-receipts.js +12 -128
- package/dist/host/commit-result.js +1 -5
- package/dist/host/content-needed.js +1 -8
- package/dist/host/content-store.js +1 -31
- package/dist/host/contextual-place.js +2 -72
- package/dist/host/digest.js +2 -15
- package/dist/host/hash.js +1 -9
- package/dist/host/host-controls.js +1 -19
- package/dist/host/in-process-act.js +3 -84
- package/dist/host/in-process-context.js +3 -91
- package/dist/host/in-process-root.js +6 -84
- package/dist/host/in-process.js +4 -55
- package/dist/host/index.d.ts +1 -15
- package/dist/host/index.js +1 -7
- package/dist/host/io.js +1 -11
- package/dist/host/lifetime.js +1 -79
- package/dist/host/located.js +6 -105
- package/dist/host/native/bounded-file.js +1 -32
- package/dist/host/native/command.js +1 -91
- package/dist/host/native/control-bridge-worker.js +2 -88
- package/dist/host/native/control-bridge.js +1 -110
- package/dist/host/native/control-selection.js +1 -32
- package/dist/host/native/custody.js +1 -91
- package/dist/host/native/deadline.js +1 -28
- package/dist/host/native/descendants.js +1 -528
- package/dist/host/native/generated-custodian.js +5 -267
- package/dist/host/native/generated.js +1 -379
- package/dist/host/native/image.js +1 -45
- package/dist/host/native/jobs.js +2 -148
- package/dist/host/native/loader.js +1 -269
- package/dist/host/native/materialize.js +1 -175
- package/dist/host/native/module-closure.js +1 -130
- package/dist/host/native/module-delivery.d.ts +1 -62
- package/dist/host/native/module-delivery.js +1 -151
- package/dist/host/native/module-syntax.js +1 -69
- package/dist/host/native/native-binary.js +1 -115
- package/dist/host/native/native-program.js +1 -72
- package/dist/host/native/node-jobs.js +3 -187
- package/dist/host/native/node-launch.js +1 -159
- package/dist/host/native/preload.js +1 -45
- package/dist/host/native/reading.js +1 -249
- package/dist/host/native/receipt-environment.js +1 -41
- package/dist/host/native/references.js +1 -30
- package/dist/host/native/root.js +1 -37
- package/dist/host/native/route.js +1 -216
- package/dist/host/native/runtime.js +1 -9
- package/dist/host/native-reader-context.js +1 -8
- package/dist/host/native-receiver.js +1 -25
- package/dist/host/objects.js +1 -38
- package/dist/host/order.js +1 -2
- package/dist/host/place-act-transaction.js +4 -78
- package/dist/host/place-clock-selection.js +5 -124
- package/dist/host/ports/ingress.js +2 -57
- package/dist/host/ports/local-act.js +5 -183
- package/dist/host/ports/place-act.js +1 -134
- package/dist/host/ports/publication.js +1 -56
- package/dist/host/ports/signing.js +1 -74
- package/dist/host/ports/store.js +1 -18
- package/dist/host/ports/transport.js +1 -48
- package/dist/host/process-lifetime.js +1 -17
- package/dist/host/provide.js +1 -183
- package/dist/host/read-only.js +1 -9
- package/dist/host/reading-closures.js +7 -227
- package/dist/host/reading-context.js +1 -53
- package/dist/host/reading-identity-types.js +0 -0
- package/dist/host/reading-identity.js +3 -0
- package/dist/host/reading-preparation.js +6 -0
- package/dist/host/reference-authenticated.d.ts +1 -40
- package/dist/host/reference-authenticated.js +3 -100
- package/dist/host/reference-contracts.js +1 -6
- package/dist/host/reference-export.js +6 -81
- package/dist/host/reference-native-api.d.ts +1 -3
- package/dist/host/reference-native-api.js +1 -3
- package/dist/host/reference-native.js +1 -74
- package/dist/host/reference-profile.js +1 -63
- package/dist/host/reference-standing.js +2 -18
- package/dist/host/reference.js +1 -24
- package/dist/host/refusals.js +2 -43
- package/dist/host/release.js +4 -256
- package/dist/host/root-clock-source.js +1 -307
- package/dist/host/selected-capsules.js +1 -50
- package/dist/host/selected-topos.js +1 -80
- package/dist/host/signature-era.js +1 -12
- package/dist/host/signing.js +2 -48
- package/dist/host/source-content.js +2 -111
- package/dist/host/standing-carrier.js +1 -18
- package/dist/host/standing-projection.js +1 -50
- package/dist/host/timing.js +1 -7
- package/dist/host/walk.js +20 -193
- package/dist/judge/late.js +1 -33
- package/dist/judge/take.js +2 -75
- package/dist/judge/widening.js +1 -25
- package/dist/land/act.js +8 -336
- package/dist/land/alias.js +1 -41
- package/dist/land/held.js +1 -23
- package/dist/land/inert.js +1 -33
- package/dist/land/leaving.js +1 -55
- package/dist/land/ledger.js +7 -188
- package/dist/land/owned.js +4 -66
- package/dist/land/sign.js +1 -53
- package/dist/land/standing-pin.js +1 -49
- package/dist/land/vouched.js +1 -112
- package/dist/land/withdraw.js +1 -24
- package/dist/observe/files.js +1 -88
- package/dist/observe/identity.js +1 -61
- package/dist/observe/match.js +1 -8
- package/dist/observe/regions.js +7 -306
- package/dist/observe/run.js +2 -41
- package/dist/observe/runner.js +4 -101
- package/dist/public-types.d.ts +1114 -0
- package/dist/render/capsule.js +1 -30
- package/dist/render/field.js +1 -40
- package/dist/render/names.js +1 -4
- package/dist/render/open.js +1 -61
- package/dist/render/page.js +1 -7
- package/dist/render/receipts.js +1 -47
- package/dist/render/shape.js +1 -74
- package/dist/render/target.js +4 -52
- package/dist/render/view.js +7 -197
- package/dist/vendor/50086958553b9376d600583f7dff354196bfeb41170fc6d1482ca7bea7c493e2.LICENSE +21 -0
- package/dist/vendor/b3e938d28f88a1851af303a40c749e12ebd5a686daac4f0b343b5cdd2e040419.LICENSE +21 -0
- package/dist/vendor/bundle.json +1 -0
- package/dist/vendor/library11.js +1 -0
- package/dist/vendor/object-provider.js +42 -0
- package/dist/vendor/runtime.js +38 -0
- package/dist/vendor/sources.json +1 -0
- package/dist/wasm/adapter.d.ts +1 -51
- package/dist/wasm/adapter.js +1 -180
- package/dist/wasm/node-worker.js +1 -13
- package/dist/wasm/object.js +1 -76
- package/dist/wasm/worker.js +1 -7
- package/docs/contracts/closure-delivery.md +1 -1
- package/docs/contracts/closure-delivery.publication.json +1 -1
- package/docs/contracts/conformance.json +142 -0
- package/docs/contracts/determinism.bound +9 -0
- package/docs/contracts/engine-object-projection.publication.json +1 -1
- package/docs/contracts/engine.md +21 -1
- package/docs/contracts/native-publication.inventory.json +2 -1
- package/docs/contracts/optional-wasm-adapter.publication.json +1 -1
- package/docs/contracts/reading-identity.md +37 -0
- package/docs/contracts/reading-identity.publication.json +25 -0
- package/docs/contracts/refusals.bound +51 -0
- package/docs/contracts/refusals.md +18 -3
- package/docs/contracts/refusals.publication.json +2 -2
- package/docs/contracts/views.md +8 -0
- package/docs/reference.md +1 -0
- package/package.json +23 -34
- package/receipts.bound +11627 -10323
- package/samples/reading-identity/no.json +20 -0
- package/samples/reading-identity/yes.json +46 -0
- package/vectors/native/reading-identity.vector.json +101 -0
- package/vectors/native/refusals.vector.json +104 -0
- package/vendor/syntax/LICENSE.md +7 -0
- package/vendor/syntax/parser.js +1 -0
- package/.github/workflows/release.yml +0 -67
- package/.github/workflows/test.yml +0 -35
- package/dist/engine/object.d.ts +0 -17
- package/dist/engine/ports.d.ts +0 -37
- package/dist/fold/claims.d.ts +0 -29
- package/dist/host/call-context.d.ts +0 -20
- package/dist/host/commit-result.d.ts +0 -6
- package/dist/host/in-process-act.d.ts +0 -82
- package/dist/host/in-process-context.d.ts +0 -46
- package/dist/host/in-process-root.d.ts +0 -117
- package/dist/host/in-process.d.ts +0 -41
- package/dist/host/native/module-closure.d.ts +0 -35
- package/dist/host/native-receiver.d.ts +0 -19
- package/dist/host/place-act-transaction.d.ts +0 -24
- package/dist/host/place-clock-selection.d.ts +0 -55
- package/dist/host/ports/local-act.d.ts +0 -44
- package/dist/host/ports/place-act.d.ts +0 -49
- package/dist/host/ports/publication.d.ts +0 -10
- package/dist/host/reference-export.d.ts +0 -33
- package/dist/host/reference-native.d.ts +0 -30
- package/dist/host/reference-profile.d.ts +0 -23
- package/dist/host/refusals.d.ts +0 -14
- package/dist/host/root-clock-source.d.ts +0 -86
|
@@ -1,100 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import { referenceStanding, referenceContracts, referenceContextBytes } from "./reference-standing.js";
|
|
5
|
-
function fail(code, why) { throw new BoundRefusal('authenticated-reference/' + code, 'REFUSE·authenticated-reference ' + why); }
|
|
6
|
-
const utf8 = (s) => new TextEncoder().encode(s);
|
|
7
|
-
/** Prospective authenticated-standing@1 host composition; no effects and no authority from transport. */
|
|
8
|
-
export async function inspectAuthenticatedReference(fragment, trust) {
|
|
9
|
-
if (new Set(trust.signers.map(s => s.id)).size !== trust.signers.length)
|
|
10
|
-
fail('context', 'duplicate host signer');
|
|
11
|
-
const reference = decodeReference(fragment);
|
|
12
|
-
if (!Number.isSafeInteger(trust.maxBytes) || trust.maxBytes < 1 || !Number.isSafeInteger(trust.maxRecords) || trust.maxRecords < 1)
|
|
13
|
-
fail('budget', 'resource budget');
|
|
14
|
-
if (trust.contracts !== undefined) {
|
|
15
|
-
if (!referenceContracts(trust.contracts))
|
|
16
|
-
fail('context', 'contract identities');
|
|
17
|
-
const snapshot = await trust.digestBytes(referenceContextBytes({ ...trust, semanticIdentity: 'sha256:' + reference.digest, contracts: trust.contracts }));
|
|
18
|
-
if (snapshot !== trust.snapshot)
|
|
19
|
-
fail('context', 'context snapshot');
|
|
20
|
-
}
|
|
21
|
-
let received;
|
|
22
|
-
try {
|
|
23
|
-
received = await trust.fetchBytes(reference.source, reference.blob);
|
|
24
|
-
}
|
|
25
|
-
catch {
|
|
26
|
-
return fail('transport', 'content port failed');
|
|
27
|
-
}
|
|
28
|
-
if (received.byteLength > trust.maxBytes)
|
|
29
|
-
fail('budget', 'bytes budget');
|
|
30
|
-
if (typeof SharedArrayBuffer !== 'undefined' && received.buffer instanceof SharedArrayBuffer)
|
|
31
|
-
fail('transport', 'shared transport bytes');
|
|
32
|
-
const bytes = new Uint8Array(received);
|
|
33
|
-
if (await trust.digestBytes(bytes) !== reference.blob)
|
|
34
|
-
fail('integrity', 'blob integrity');
|
|
35
|
-
let text;
|
|
36
|
-
try {
|
|
37
|
-
text = new TextDecoder('utf-8', { fatal: true }).decode(bytes);
|
|
38
|
-
}
|
|
39
|
-
catch {
|
|
40
|
-
return fail('framing', 'carrier UTF-8');
|
|
41
|
-
}
|
|
42
|
-
let packet;
|
|
43
|
-
try {
|
|
44
|
-
packet = JSON.parse(text);
|
|
45
|
-
}
|
|
46
|
-
catch {
|
|
47
|
-
fail('framing', 'carrier framing');
|
|
48
|
-
}
|
|
49
|
-
if (!Array.isArray(packet) || packet.length !== 3 || packet[0] !== 'authenticated-standing@1' || !Array.isArray(packet[1]) || packet[1].length < 1 || packet[1].length > trust.maxRecords || packet[1].some((x) => typeof x !== 'string') || typeof packet[2] !== 'string' || JSON.stringify(packet) + '\n' !== text)
|
|
50
|
-
fail('framing', 'carrier framing');
|
|
51
|
-
const originals = packet[1], proofLine = packet[2];
|
|
52
|
-
const parsed = [...originals, proofLine].map(line => { const p = parse(line); if (p.kind !== 'fact' || canonical(p.value.fields) !== line)
|
|
53
|
-
fail('wire', 'original canonical'); return p.value.fields; });
|
|
54
|
-
const proof = parsed[parsed.length - 1];
|
|
55
|
-
if (proof.scope !== trust.proofScope || proof.at !== 'witness:' + trust.snapshot || proof.role !== 'writes' || proof.form !== 'alphabet' || proof.measure !== 'digest' || proof.epoch !== String(trust.epoch))
|
|
56
|
-
fail('context', 'untrusted snapshot binding');
|
|
57
|
-
if (proof.value !== await trust.digestBytes(utf8(JSON.stringify(['authenticated-standing@1', originals]) + '\n')))
|
|
58
|
-
fail('integrity', 'snapshot commitment');
|
|
59
|
-
// Async crypto port is called on exact native signed bytes; authorityOf consumes only those results.
|
|
60
|
-
const verifiedCrypto = new Set();
|
|
61
|
-
const key = (f, pub) => JSON.stringify([signedBytes(f), pub, f.sig, trust.algorithms]);
|
|
62
|
-
for (const f of parsed)
|
|
63
|
-
for (const s of trust.signers)
|
|
64
|
-
if (s.id === f.by && await trust.verifyBytes(signedBytes(f), s.publicKey, f.sig, trust.algorithms))
|
|
65
|
-
verifiedCrypto.add(key(f, s.publicKey));
|
|
66
|
-
const verifies = (f, pub) => verifiedCrypto.has(key(f, pub));
|
|
67
|
-
const authentic = authorityOf(proof, trust.signers, verifies);
|
|
68
|
-
if (authentic.kind !== 'admitted')
|
|
69
|
-
fail('authority', 'proof ' + authentic.kind + ' ' + authentic.why);
|
|
70
|
-
const signer = trust.signers.find(s => s.id === proof.by);
|
|
71
|
-
if (!signer)
|
|
72
|
-
fail('authority', 'proof signer');
|
|
73
|
-
const current = authorityAtEpoch(proof, signer, trust.epoch, trust.proofScope, 'authority');
|
|
74
|
-
if (current.kind !== 'admitted')
|
|
75
|
-
fail('authority', 'current proof ' + current.kind + ' ' + current.why);
|
|
76
|
-
const verified = new Set();
|
|
77
|
-
for (let i = 0; i < originals.length; i++) {
|
|
78
|
-
const admitted = authorityOf(parsed[i], trust.signers, verifies);
|
|
79
|
-
if (admitted.kind !== 'admitted')
|
|
80
|
-
fail('authority', 'original ' + admitted.kind + ' ' + admitted.why);
|
|
81
|
-
verified.add(originals[i]);
|
|
82
|
-
}
|
|
83
|
-
const history = objectHistory(originals);
|
|
84
|
-
if (history.kind !== 'fact')
|
|
85
|
-
fail('wire', 'wire ' + history.why);
|
|
86
|
-
if (history.value.configuration.some(f => f.value === 'withdraw'))
|
|
87
|
-
fail('history', 'configuration history requires admitted standing fold');
|
|
88
|
-
const context = { ...trust.objects, admit: (r) => verified.has(canonical(r.fields)) && trust.objects.admit(r) };
|
|
89
|
-
const checked = validateObjectContext(history.value.objects, context);
|
|
90
|
-
if (checked.kind !== 'fact')
|
|
91
|
-
throw new BoundRefusal('authenticated-reference/object-context', 'REFUSE·' + checked.why);
|
|
92
|
-
const semantic = referenceStanding(originals, checked.value), semanticIdentity = await trust.digestBytes(utf8(semantic));
|
|
93
|
-
if (semanticIdentity !== 'sha256:' + reference.digest)
|
|
94
|
-
fail('identity', 'standing identity');
|
|
95
|
-
const authorityContextIdentity = await trust.digestBytes(utf8(JSON.stringify(trust.contracts ? ['reference-inspection-trust@2', trust.snapshot, trust.epoch, trust.proofScope, trust.policy, trust.formImplementation, trust.signers, trust.algorithms, trust.contracts] : ['reference-inspection-trust@1', trust.snapshot, trust.epoch, trust.proofScope, trust.policy, trust.formImplementation, trust.signers, trust.algorithms])));
|
|
96
|
-
return { reference, records: checked.value, semanticIdentity, authorityContextIdentity, semanticStanding: semantic, originalRecords: originals, ...(trust.contracts ? { contracts: { ...trust.contracts } } : {}) };
|
|
97
|
-
}
|
|
98
|
-
export { encodeReference, decodeReference } from "./reference-profile.js";
|
|
99
|
-
export { BoundRefusal, readRefusalCatalog, describeRefusal } from "./refusals.js";
|
|
100
|
-
export { readContent, retainContent, invokeSigningPort } from "../engine/ports.js";
|
|
1
|
+
var _=Object.defineProperty;var s=(r,e)=>_(r,"name",{value:e,configurable:!0});import{BoundRefusal as A}from"./refusals.js";import{library11_parse as J,library11_canonical as C,library11_authorityOf as O,library11_authorityAtEpoch as U,library11_signedBytes as j,library11_objectHistory as F,library11_validateObjectContext as T}from"../vendor/runtime.js";import{decodeReference as H}from"./reference-profile.js";import{referenceStanding as K,referenceContracts as L,referenceContextBytes as q}from"./reference-standing.js";function t(r,e){throw new A("authenticated-reference/"+r,"REFUSE\xB7authenticated-reference "+e)}s(t,"fail");const b=s(r=>new TextEncoder().encode(r),"utf8");async function Q(r,e){new Set(e.signers.map(i=>i.id)).size!==e.signers.length&&t("context","duplicate host signer");const f=H(r);(!Number.isSafeInteger(e.maxBytes)||e.maxBytes<1||!Number.isSafeInteger(e.maxRecords)||e.maxRecords<1)&&t("budget","resource budget"),e.contracts!==void 0&&(L(e.contracts)||t("context","contract identities"),await e.digestBytes(q({...e,semanticIdentity:"sha256:"+f.digest,contracts:e.contracts}))!==e.snapshot&&t("context","context snapshot"));let d;try{d=await e.fetchBytes(f.source,f.blob)}catch{return t("transport","content port failed")}d.byteLength>e.maxBytes&&t("budget","bytes budget"),typeof SharedArrayBuffer<"u"&&d.buffer instanceof SharedArrayBuffer&&t("transport","shared transport bytes");const w=new Uint8Array(d);await e.digestBytes(w)!==f.blob&&t("integrity","blob integrity");let p;try{p=new TextDecoder("utf-8",{fatal:!0}).decode(w)}catch{return t("framing","carrier UTF-8")}let o;try{o=JSON.parse(p)}catch{t("framing","carrier framing")}(!Array.isArray(o)||o.length!==3||o[0]!=="authenticated-standing@1"||!Array.isArray(o[1])||o[1].length<1||o[1].length>e.maxRecords||o[1].some(i=>typeof i!="string")||typeof o[2]!="string"||JSON.stringify(o)+`
|
|
2
|
+
`!==p)&&t("framing","carrier framing");const c=o[1],E=o[2],y=[...c,E].map(i=>{const n=J(i);return(n.kind!=="fact"||C(n.value.fields)!==i)&&t("wire","original canonical"),n.value.fields}),a=y[y.length-1];(a.scope!==e.proofScope||a.at!=="witness:"+e.snapshot||a.role!=="writes"||a.form!=="alphabet"||a.measure!=="digest"||a.epoch!==String(e.epoch))&&t("context","untrusted snapshot binding"),a.value!==await e.digestBytes(b(JSON.stringify(["authenticated-standing@1",c])+`
|
|
3
|
+
`))&&t("integrity","snapshot commitment");const x=new Set,S=s((i,n)=>JSON.stringify([j(i),n,i.sig,e.algorithms]),"key");for(const i of y)for(const n of e.signers)n.id===i.by&&await e.verifyBytes(j(i),n.publicKey,i.sig,e.algorithms)&&x.add(S(i,n.publicKey));const B=s((i,n)=>x.has(S(i,n)),"verifies"),l=O(a,e.signers,B);l.kind!=="admitted"&&t("authority","proof "+l.kind+" "+l.why);const u=e.signers.find(i=>i.id===a.by);u||t("authority","proof signer");const m=U(a,u,e.epoch,e.proofScope,"authority");m.kind!=="admitted"&&t("authority","current proof "+m.kind+" "+m.why);const v=new Set;for(let i=0;i<c.length;i++){const n=O(y[i],e.signers,B);n.kind!=="admitted"&&t("authority","original "+n.kind+" "+n.why),v.add(c[i])}const g=F(c);g.kind!=="fact"&&t("wire","wire "+g.why),g.value.configuration.some(i=>i.value==="withdraw")&&t("history","configuration history requires admitted standing fold");const I={...e.objects,admit:s(i=>v.has(C(i.fields))&&e.objects.admit(i),"admit")},h=T(g.value.objects,I);if(h.kind!=="fact")throw new A("authenticated-reference/object-context","REFUSE\xB7"+h.why);const R=K(c,h.value),k=await e.digestBytes(b(R));k!=="sha256:"+f.digest&&t("identity","standing identity");const N=await e.digestBytes(b(JSON.stringify(e.contracts?["reference-inspection-trust@2",e.snapshot,e.epoch,e.proofScope,e.policy,e.formImplementation,e.signers,e.algorithms,e.contracts]:["reference-inspection-trust@1",e.snapshot,e.epoch,e.proofScope,e.policy,e.formImplementation,e.signers,e.algorithms])));return{reference:f,records:h.value,semanticIdentity:k,authorityContextIdentity:N,semanticStanding:R,originalRecords:c,...e.contracts?{contracts:{...e.contracts}}:{}}}s(Q,"inspectAuthenticatedReference");import{encodeReference as X,decodeReference as Y}from"./reference-profile.js";import{BoundRefusal as $,readRefusalCatalog as ee,describeRefusal as ie}from"./refusals.js";import{readContent as ne,retainContent as oe,invokeSigningPort as ae}from"../engine/ports.js";export{$ as BoundRefusal,Y as decodeReference,ie as describeRefusal,X as encodeReference,Q as inspectAuthenticatedReference,ae as invokeSigningPort,ne as readContent,ee as readRefusalCatalog,oe as retainContent};
|
|
@@ -1,6 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { sha256 } from "./hash.js";
|
|
3
|
-
/** Exact shipped interpretation contracts; this helper grants no authority. */
|
|
4
|
-
export function installedReferenceContracts() {
|
|
5
|
-
return { refusals: sha256(readFileSync(new URL('../../docs/contracts/refusals.bound', import.meta.url))), standing: sha256(readFileSync(new URL('../../docs/contracts/standing.bound', import.meta.url))) };
|
|
6
|
-
}
|
|
1
|
+
var s=Object.defineProperty;var r=(e,o)=>s(e,"name",{value:o,configurable:!0});import{readFileSync as t}from"node:fs";import{sha256 as n}from"./hash.js";function d(){return{refusals:n(t(new URL("../../docs/contracts/refusals.bound",import.meta.url))),standing:n(t(new URL("../../docs/contracts/standing.bound",import.meta.url)))}}r(d,"installedReferenceContracts");export{d as installedReferenceContracts};
|
|
@@ -1,81 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import { signConsentLot } from "../land/sign.js";
|
|
8
|
-
import { underRootAuthority } from "../land/act.js";
|
|
9
|
-
import { storeOf } from "../land/ledger.js";
|
|
10
|
-
import { authorityFor, rootSigner } from "../fold/signers.js";
|
|
11
|
-
import { admissionAnchor, admissionHistoryAt } from "../fold/admission-history.js";
|
|
12
|
-
import { authenticatedRootStanding } from "./admitted-place.js";
|
|
13
|
-
import { eraOf } from "../fold/digests.js";
|
|
14
|
-
import { epochOf } from "../cli/owner.js";
|
|
15
|
-
import { fieldOf } from "../fold/claims.js";
|
|
16
|
-
import { prepareNativeReference } from "./reference-native.js";
|
|
17
|
-
import { referenceContextBytes, referenceContracts, referenceStanding } from "./reference-standing.js";
|
|
18
|
-
import { encodeReference } from "./reference-profile.js";
|
|
19
|
-
const catalog = () => readFileSync(new URL('../../docs/contracts/refusals.bound', import.meta.url), 'utf8');
|
|
20
|
-
export { BoundRefusal as ReferenceExportRefusal } from "./refusals.js";
|
|
21
|
-
function fail(code) {
|
|
22
|
-
const refusal = new BoundRefusal('reference-export/' + code, 'REFUSE·reference-export/' + code);
|
|
23
|
-
const entry = describeRefusal(refusal, readRefusalCatalog(catalog()));
|
|
24
|
-
throw new BoundRefusal(entry.code, 'REFUSE·' + entry.code + ' ' + entry.meaning);
|
|
25
|
-
}
|
|
26
|
-
/** Signs a public snapshot proof; never lands, refreshes evidence or changes the Root. */
|
|
27
|
-
export async function exportAuthenticatedReference(root, source, options = {}) {
|
|
28
|
-
try {
|
|
29
|
-
encodeReference({ class: 'standing', algorithm: 'sha256', digest: '0'.repeat(64), blob: 'sha256:' + '0'.repeat(64), source });
|
|
30
|
-
}
|
|
31
|
-
catch {
|
|
32
|
-
fail('source');
|
|
33
|
-
}
|
|
34
|
-
return underRootAuthority(storeOf(root), 'reference export', async () => {
|
|
35
|
-
const history = admissionHistoryAt(root, Number.MAX_SAFE_INTEGER), standing = authenticatedRootStanding(root), epoch = epochOf(history), era = eraOf(standing);
|
|
36
|
-
const authority = authorityFor(history, admissionAnchor(root), era.admitted);
|
|
37
|
-
const one = (scope, measure = 'id', form = 'alphabet') => { const rows = standing.filter(line => fieldOf(line, 'scope') === scope && fieldOf(line, 'value') !== 'withdraw'); if (rows.length !== 1 || fieldOf(rows[0], 'role') !== 'writes' || fieldOf(rows[0], 'measure') !== measure || fieldOf(rows[0], 'form') !== form || authority.of(rows[0]).kind !== 'admitted')
|
|
38
|
-
fail('context'); return fieldOf(rows[0], 'value'); };
|
|
39
|
-
if (one('reference/authentication') !== 'authenticated-standing@1')
|
|
40
|
-
fail('context');
|
|
41
|
-
const proofScope = one('reference/proof-scope'), contracts = { refusals: one('reference/contracts/refusals'), standing: one('reference/contracts/standing') };
|
|
42
|
-
const installed = installedReferenceContracts();
|
|
43
|
-
if (!referenceContracts(contracts) || contracts.refusals !== installed.refusals || contracts.standing !== installed.standing)
|
|
44
|
-
fail('context');
|
|
45
|
-
const count = one('reference/records'), maxRecords = Number(count), range = /^(0|[1-9][0-9]*)\.\.(0|[1-9][0-9]*)$/.exec(one('reference/export-bytes', 'bytes', 'interval'));
|
|
46
|
-
if (!/^(0|[1-9][0-9]*)$/.test(count) || !Number.isSafeInteger(maxRecords) || maxRecords < 1 || !range || Number(range[1]) > Number(range[2]) || !Number.isSafeInteger(Number(range[2])) || Number(range[2]) < 1)
|
|
47
|
-
fail('budget');
|
|
48
|
-
const maxBytes = Number(range[2]);
|
|
49
|
-
const originals = standing.filter(line => fieldOf(line, 'value') !== 'withdraw' || fieldOf(line, 'type') !== '');
|
|
50
|
-
if (!originals.length || originals.length > maxRecords || Buffer.byteLength(originals.join('\n')) > maxBytes)
|
|
51
|
-
fail('budget');
|
|
52
|
-
if (originals.some(line => authority.of(line).kind !== 'admitted'))
|
|
53
|
-
fail('history');
|
|
54
|
-
const key = options.key ?? rootSigner(root).id, signer = authority.admitted.find(s => s.id === key);
|
|
55
|
-
const stamp = canonical({ scope: proofScope, role: 'writes', form: 'alphabet', measure: 'digest', value: hash(JSON.stringify(['authenticated-standing@1', originals]) + '\n'), by: 'target', at: 'witness:' + 'sha256:' + '0'.repeat(64) });
|
|
56
|
-
const probe = parse(stamp);
|
|
57
|
-
if (!signer || probe.kind !== 'fact' || authorityAtEpoch({ ...probe.value.fields, by: key, epoch: String(epoch) }, signer, epoch, proofScope, 'authority').kind !== 'admitted')
|
|
58
|
-
fail('authority');
|
|
59
|
-
const held = await prepareNativeReference(root), semantic = referenceStanding(originals, held.records), semanticIdentity = hash(semantic);
|
|
60
|
-
const context = { profile: 'reference-export-context@1', semanticIdentity, epoch, proofScope, policy: held.policy, formImplementation: held.formImplementation, signers: authority.admitted, algorithms: era.admitted, contracts, maxBytes, maxRecords };
|
|
61
|
-
const snapshot = hash(referenceContextBytes(context));
|
|
62
|
-
if (Buffer.byteLength(JSON.stringify({ originals, context, snapshot }) + '\n') > maxBytes)
|
|
63
|
-
fail('budget');
|
|
64
|
-
const drafted = canonical({ ...probe.value.fields, at: 'witness:' + snapshot });
|
|
65
|
-
let signed;
|
|
66
|
-
try {
|
|
67
|
-
signed = await signConsentLot([drafted], { epoch, by: key, algorithm: era.era }, signer.publicKey, era.admitted, signerFor(standing, key, options.signer, options.keyFile, options.hostSigner));
|
|
68
|
-
}
|
|
69
|
-
catch {
|
|
70
|
-
fail('signer');
|
|
71
|
-
}
|
|
72
|
-
if (signed.kind !== 'fact')
|
|
73
|
-
fail('signer');
|
|
74
|
-
const carrier = JSON.stringify(['authenticated-standing@1', originals, signed.lines[0]]) + '\n';
|
|
75
|
-
const reference = encodeReference({ class: 'standing', algorithm: 'sha256', digest: semanticIdentity.slice(7), blob: hash(carrier), source });
|
|
76
|
-
const result = { profile: 'reference-export@1', reference, carrier, context: { ...context, snapshot } };
|
|
77
|
-
if (Buffer.byteLength(JSON.stringify(result) + '\n') > maxBytes)
|
|
78
|
-
fail('budget');
|
|
79
|
-
return result;
|
|
80
|
-
});
|
|
81
|
-
}
|
|
1
|
+
var M=Object.defineProperty;var m=(t,a)=>M(t,"name",{value:a,configurable:!0});import{installedReferenceContracts as T}from"./reference-contracts.js";import{BoundRefusal as _,describeRefusal as X,readRefusalCatalog as q}from"./refusals.js";import{readFileSync as z}from"node:fs";import{library11_authorityAtEpoch as D,library11_canonical as J,library11_parse as P}from"../vendor/runtime.js";import{sha256 as x}from"./hash.js";import{signerFor as Q}from"./signing.js";import{signConsentLot as V}from"../land/sign.js";import{underRootAuthority as W}from"../land/act.js";import{storeOf as Y}from"../land/ledger.js";import{authorityFor as Z,rootSigner as ee}from"../fold/signers.js";import{admissionAnchor as te,admissionHistoryAt as re}from"../fold/admission-history.js";import{authenticatedRootStanding as ne}from"./admitted-place.js";import{eraOf as oe}from"../fold/digests.js";import{epochOf as ie}from"../cli/owner.js";import{fieldOf as i}from"../fold/claims.js";import{prepareNativeReference as ae}from"./reference-native.js";import{referenceContextBytes as se,referenceContracts as ce,referenceStanding as fe}from"./reference-standing.js";import{encodeReference as U}from"./reference-profile.js";const me=m(()=>z(new URL("../../docs/contracts/refusals.bound",import.meta.url),"utf8"),"catalog");import{BoundRefusal as _e}from"./refusals.js";function e(t){const a=new _("reference-export/"+t,"REFUSE\xB7reference-export/"+t),r=X(a,q(me()));throw new _(r.code,"REFUSE\xB7"+r.code+" "+r.meaning)}m(e,"fail");async function Ie(t,a,r={}){try{U({class:"standing",algorithm:"sha256",digest:"0".repeat(64),blob:"sha256:"+"0".repeat(64),source:a})}catch{e("source")}return W(Y(t),"reference export",async()=>{const A=re(t,Number.MAX_SAFE_INTEGER),d=ne(t),l=ie(A),u=oe(d),p=Z(A,te(t),u.admitted),s=m((o,H="id",K="alphabet")=>{const f=d.filter(L=>i(L,"scope")===o&&i(L,"value")!=="withdraw");return(f.length!==1||i(f[0],"role")!=="writes"||i(f[0],"measure")!==H||i(f[0],"form")!==K||p.of(f[0]).kind!=="admitted")&&e("context"),i(f[0],"value")},"one");s("reference/authentication")!=="authenticated-standing@1"&&e("context");const R=s("reference/proof-scope"),g={refusals:s("reference/contracts/refusals"),standing:s("reference/contracts/standing")},O=T();(!ce(g)||g.refusals!==O.refusals||g.standing!==O.standing)&&e("context");const B=s("reference/records"),h=Number(B),c=/^(0|[1-9][0-9]*)\.\.(0|[1-9][0-9]*)$/.exec(s("reference/export-bytes","bytes","interval"));(!/^(0|[1-9][0-9]*)$/.test(B)||!Number.isSafeInteger(h)||h<1||!c||Number(c[1])>Number(c[2])||!Number.isSafeInteger(Number(c[2]))||Number(c[2])<1)&&e("budget");const y=Number(c[2]),n=d.filter(o=>i(o,"value")!=="withdraw"||i(o,"type")!=="");(!n.length||n.length>h||Buffer.byteLength(n.join(`
|
|
2
|
+
`))>y)&&e("budget"),n.some(o=>p.of(o).kind!=="admitted")&&e("history");const b=r.key??ee(t).id,S=p.admitted.find(o=>o.id===b),$=J({scope:R,role:"writes",form:"alphabet",measure:"digest",value:x(JSON.stringify(["authenticated-standing@1",n])+`
|
|
3
|
+
`),by:"target",at:"witness:sha256:"+"0".repeat(64)}),w=P($);(!S||w.kind!=="fact"||D({...w.value.fields,by:b,epoch:String(l)},S,l,R,"authority").kind!=="admitted")&&e("authority");const N=await ae(t),j=fe(n,N.records),F=x(j),E={profile:"reference-export-context@1",semanticIdentity:F,epoch:l,proofScope:R,policy:N.policy,formImplementation:N.formImplementation,signers:p.admitted,algorithms:u.admitted,contracts:g,maxBytes:y,maxRecords:h},k=x(se(E));Buffer.byteLength(JSON.stringify({originals:n,context:E,snapshot:k})+`
|
|
4
|
+
`)>y&&e("budget");const G=J({...w.value.fields,at:"witness:"+k});let v;try{v=await V([G],{epoch:l,by:b,algorithm:u.era},S.publicKey,u.admitted,Q(d,b,r.signer,r.keyFile,r.hostSigner))}catch{e("signer")}v.kind!=="fact"&&e("signer");const I=JSON.stringify(["authenticated-standing@1",n,v.lines[0]])+`
|
|
5
|
+
`,C={profile:"reference-export@1",reference:U({class:"standing",algorithm:"sha256",digest:F.slice(7),blob:x(I),source:a}),carrier:I,context:{...E,snapshot:k}};return Buffer.byteLength(JSON.stringify(C)+`
|
|
6
|
+
`)>y&&e("budget"),C})}m(Ie,"exportAuthenticatedReference");export{_e as ReferenceExportRefusal,Ie as exportAuthenticatedReference};
|
|
@@ -1,3 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { openAuthenticatedReference } from './reference-native.ts';
|
|
3
|
-
export { exportAuthenticatedReference } from './reference-export.ts';
|
|
1
|
+
export {public5_exportAuthenticatedReference as exportAuthenticatedReference,public5_inspectReference as inspectReference,public5_openAuthenticatedReference as openAuthenticatedReference} from "../public-types.js";
|
|
@@ -1,3 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { openAuthenticatedReference } from "./reference-native.js";
|
|
3
|
-
export { exportAuthenticatedReference } from "./reference-export.js";
|
|
1
|
+
import{openAuthenticatedReference as r}from"./reference-native.js";import{exportAuthenticatedReference as n}from"./reference-export.js";import{inspectReference as f}from"./reference.js";export{n as exportAuthenticatedReference,f as inspectReference,r as openAuthenticatedReference};
|
|
@@ -1,74 +1 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { installedReferenceContracts } from "./reference-contracts.js";
|
|
3
|
-
import { BoundRefusal } from "./refusals.js";
|
|
4
|
-
import { foldObjectsWithWasm } from "../wasm/object.js";
|
|
5
|
-
/** Native ports for authenticated #bound opening; trusted policy belongs to the selected local place. */
|
|
6
|
-
import { sha256 as hash, isSha256 } from "./hash.js";
|
|
7
|
-
import { canonical, parse, transportSelection } from '@lapxo/topos/wire';
|
|
8
|
-
import { semanticStandingBytes } from '@lapxo/topos/standing';
|
|
9
|
-
import { authorityFor, rootSigner } from "../fold/signers.js";
|
|
10
|
-
import { eraOf } from "../fold/digests.js";
|
|
11
|
-
import { lockStanding, lockLines } from "../fold/keys.js";
|
|
12
|
-
import { signedOwnerLines } from "../cli/owner.js";
|
|
13
|
-
import { admittedObjects } from "./objects.js";
|
|
14
|
-
import { storeOf } from "../land/ledger.js";
|
|
15
|
-
import { objectFold } from "../engine/index.js";
|
|
16
|
-
import { toposAt, contentAt } from "./selected-topos.js";
|
|
17
|
-
import { transportBytes } from "./ports/transport.js";
|
|
18
|
-
import { decodeReference } from "./reference-profile.js";
|
|
19
|
-
import { inspectAuthenticatedReference } from "./reference-authenticated.js";
|
|
20
|
-
import { verifyBytes } from "./adapters/keys/ed25519.js";
|
|
21
|
-
export function authenticatedReferenceSelected(standing) {
|
|
22
|
-
const selected = standing.flatMap(line => { const p = parse(line); return p.kind === 'fact' && p.value.fields.scope === 'reference/authentication' ? [p.value.fields] : []; });
|
|
23
|
-
if (!selected.length)
|
|
24
|
-
return false;
|
|
25
|
-
if (selected.length !== 1 || selected[0].value !== 'authenticated-standing@1')
|
|
26
|
-
throw Error('REFUSE·reference conflicting or unknown authentication profile');
|
|
27
|
-
return true;
|
|
28
|
-
}
|
|
29
|
-
/** One context preparation shared by native export and native inspection. */
|
|
30
|
-
export async function prepareNativeReference(root) {
|
|
31
|
-
const store = storeOf(root), held = await admittedObjects(root, signedOwnerLines(store), () => { }, true);
|
|
32
|
-
const policy = held.configuration.map(fields => canonical(fields));
|
|
33
|
-
const implementations = [...new Set(held.records.filter(r => r.record === 'cell').map(r => r.fields.topos))].sort().map(pin => { const selected = toposAt(pin, store), selectors = selected.parts.filter(f => f.scope === 'wire/topos/context-view'); if (selectors.length !== 1)
|
|
34
|
-
throw Error('REFUSE·reference host context selector'); const offers = selected.parts.filter(f => f.kind === 'check' && f.view === selectors[0].value); if (offers.length !== 1)
|
|
35
|
-
throw Error('REFUSE·reference host context offer'); const offer = offers[0], closure = [...new Set((offer.restsOn ?? '').split('|').filter(Boolean))].sort(); for (const digest of closure)
|
|
36
|
-
contentAt(digest, store); return [pin, offer.value, closure]; });
|
|
37
|
-
return { ...held, policy: hash(semanticStandingBytes(policy)), formImplementation: hash(JSON.stringify(implementations)) };
|
|
38
|
-
}
|
|
39
|
-
export async function openAuthenticatedReference(root, fragment, options = {}) {
|
|
40
|
-
const store = storeOf(root), standing = lockStanding(store), era = eraOf(standing), authority = authorityFor(lockLines(store), rootSigner(root), era.admitted);
|
|
41
|
-
if (!authenticatedReferenceSelected(standing))
|
|
42
|
-
throw Error('REFUSE·reference no admitted authenticated-standing@1 profile');
|
|
43
|
-
const one = (scope) => { const found = standing.flatMap(line => { const p = parse(line); return p.kind === 'fact' && p.value.fields.scope === scope ? [{ line, fields: p.value.fields }] : []; }); if (found.length !== 1 || found[0].fields.role !== 'writes' || found[0].fields.measure !== 'id' || found[0].fields.form !== 'alphabet' || authority.of(found[0].line).kind !== 'admitted')
|
|
44
|
-
throw new BoundRefusal(scope === 'engine/object' ? 'reference/backend' : 'authenticated-reference/context', 'REFUSE·reference missing, conflicting or unauthenticated ' + scope); return found[0].fields.value; };
|
|
45
|
-
if (one('reference/authentication') !== 'authenticated-standing@1')
|
|
46
|
-
throw Error('REFUSE·reference authentication profile');
|
|
47
|
-
const snapshot = one('reference/snapshot'), epochText = one('reference/epoch'), proofScope = one('reference/proof-scope'), recordsText = one('reference/records');
|
|
48
|
-
if (!isSha256(snapshot) || !/^\d+$/.test(epochText) || !Number.isSafeInteger(Number(epochText)) || !/^\d+$/.test(recordsText) || !Number.isSafeInteger(Number(recordsText)) || Number(recordsText) < 1 || !proofScope)
|
|
49
|
-
throw Error('REFUSE·reference authority snapshot or resource contract');
|
|
50
|
-
const backend = one('engine/object');
|
|
51
|
-
if (!['esm@1', 'wasm@1'].includes(backend))
|
|
52
|
-
throw new BoundRefusal('reference/backend', 'REFUSE·reference unsupported declared backend');
|
|
53
|
-
if (options.signal?.aborted)
|
|
54
|
-
throw new BoundRefusal('reference/cancelled', 'REFUSE·reference cancelled');
|
|
55
|
-
const reference = decodeReference(fragment);
|
|
56
|
-
// Provider selection is made from HOST-declared cells/configuration, never carrier-picked code.
|
|
57
|
-
const held = await prepareNativeReference(root);
|
|
58
|
-
if (!held.records.some(r => r.record === 'cell'))
|
|
59
|
-
throw Error('REFUSE·reference host has no declared object interpretation');
|
|
60
|
-
const context = held.context, policy = held.configuration.map(fields => canonical(fields)), selection = transportSelection(held.configuration, new URL(reference.source).protocol.slice(0, -1));
|
|
61
|
-
if (!selection)
|
|
62
|
-
throw Error('REFUSE·reference no admitted transport policy');
|
|
63
|
-
if (options.content && options.content.name !== selection.name)
|
|
64
|
-
throw new BoundRefusal('authenticated-reference/transport', 'REFUSE·reference injected content binding conflicts with declaration');
|
|
65
|
-
const contracts = { refusals: one('reference/contracts/refusals'), standing: one('reference/contracts/standing') }, expectedPolicy = one('reference/policy'), expectedImplementation = one('reference/form-implementation');
|
|
66
|
-
const installed = installedReferenceContracts();
|
|
67
|
-
if (contracts.refusals !== installed.refusals || contracts.standing !== installed.standing || !isSha256(expectedPolicy) || expectedImplementation !== held.formImplementation)
|
|
68
|
-
throw new BoundRefusal('authenticated-reference/context', 'REFUSE·reference expected interpretation differs');
|
|
69
|
-
const result = await inspectAuthenticatedReference(fragment, { snapshot, epoch: Number(epochText), proofScope, contracts, policy: expectedPolicy, formImplementation: expectedImplementation, signers: authority.admitted, algorithms: era.admitted, objects: context, maxBytes: selection.responseBytes, maxRecords: Number(recordsText), digestBytes: hash, verifyBytes, fetchBytes: (source, blob) => options.content ? readContent(source, blob, { read: options.content.read, digestBytes: hash }, { timeoutMs: selection.timeoutMs, maxBytes: selection.responseBytes }, options.signal) : transportBytes(source, blob, policy) });
|
|
70
|
-
if (options.signal?.aborted)
|
|
71
|
-
throw new BoundRefusal('reference/cancelled', 'REFUSE·reference cancelled');
|
|
72
|
-
const readings = backend === 'wasm@1' ? await foldObjectsWithWasm(root, result.records, context, held.configuration, options.signal) : objectFold(result.records, context);
|
|
73
|
-
return { ...result, backend, readings };
|
|
74
|
-
}
|
|
1
|
+
var _=Object.defineProperty;var d=(n,r)=>_(n,"name",{value:r,configurable:!0});import{readContent as L}from"../engine/ports.js";import{installedReferenceContracts as C}from"./reference-contracts.js";import{BoundRefusal as m}from"./refusals.js";import{foldObjectsWithWasm as T}from"../wasm/object.js";import{sha256 as E,isSha256 as v}from"./hash.js";import{library11_canonical as N,library11_parse as j,library11_transportSelection as W}from"../vendor/runtime.js";import{library7_semanticStandingBytes as $}from"../vendor/runtime.js";import{authorityFor as J,rootSigner as P}from"../fold/signers.js";import{eraOf as q}from"../fold/digests.js";import{lockStanding as z,lockLines as D}from"../fold/keys.js";import{signedOwnerLines as G}from"../cli/owner.js";import{admittedObjects as H}from"./objects.js";import{storeOf as O}from"../land/ledger.js";import{objectFold as K}from"../engine/index.js";import{toposAt as Q,contentAt as V}from"./selected-topos.js";import{transportBytes as X}from"./ports/transport.js";import{decodeReference as Y}from"./reference-profile.js";import{inspectAuthenticatedReference as Z}from"./reference-authenticated.js";import{verifyBytes as ee}from"./adapters/keys/ed25519.js";function te(n){const r=n.flatMap(e=>{const s=j(e);return s.kind==="fact"&&s.value.fields.scope==="reference/authentication"?[s.value.fields]:[]});if(!r.length)return!1;if(r.length!==1||r[0].value!=="authenticated-standing@1")throw Error("REFUSE\xB7reference conflicting or unknown authentication profile");return!0}d(te,"authenticatedReferenceSelected");async function re(n){const r=O(n),e=await H(n,G(r),()=>{},!0),s=e.configuration.map(o=>N(o)),p=[...new Set(e.records.filter(o=>o.record==="cell").map(o=>o.fields.topos))].sort().map(o=>{const u=Q(o,r),t=u.parts.filter(c=>c.scope==="wire/topos/context-view");if(t.length!==1)throw Error("REFUSE\xB7reference host context selector");const h=u.parts.filter(c=>c.kind==="check"&&c.view===t[0].value);if(h.length!==1)throw Error("REFUSE\xB7reference host context offer");const f=h[0],g=[...new Set((f.restsOn??"").split("|").filter(Boolean))].sort();for(const c of g)V(c,r);return[o,f.value,g]});return{...e,policy:E($(s)),formImplementation:E(JSON.stringify(p))}}d(re,"prepareNativeReference");async function xe(n,r,e={}){const s=O(n),p=z(s),o=q(p),u=J(D(s),P(n),o.admitted);if(!te(p))throw Error("REFUSE\xB7reference no admitted authenticated-standing@1 profile");const t=d(i=>{const a=p.flatMap(k=>{const x=j(k);return x.kind==="fact"&&x.value.fields.scope===i?[{line:k,fields:x.value.fields}]:[]});if(a.length!==1||a[0].fields.role!=="writes"||a[0].fields.measure!=="id"||a[0].fields.form!=="alphabet"||u.of(a[0].line).kind!=="admitted")throw new m(i==="engine/object"?"reference/backend":"authenticated-reference/context","REFUSE\xB7reference missing, conflicting or unauthenticated "+i);return a[0].fields.value},"one");if(t("reference/authentication")!=="authenticated-standing@1")throw Error("REFUSE\xB7reference authentication profile");const h=t("reference/snapshot"),f=t("reference/epoch"),g=t("reference/proof-scope"),c=t("reference/records");if(!v(h)||!/^\d+$/.test(f)||!Number.isSafeInteger(Number(f))||!/^\d+$/.test(c)||!Number.isSafeInteger(Number(c))||Number(c)<1||!g)throw Error("REFUSE\xB7reference authority snapshot or resource contract");const y=t("engine/object");if(!["esm@1","wasm@1"].includes(y))throw new m("reference/backend","REFUSE\xB7reference unsupported declared backend");if(e.signal?.aborted)throw new m("reference/cancelled","REFUSE\xB7reference cancelled");const I=Y(r),l=await re(n);if(!l.records.some(i=>i.record==="cell"))throw Error("REFUSE\xB7reference host has no declared object interpretation");const S=l.context,A=l.configuration.map(i=>N(i)),w=W(l.configuration,new URL(I.source).protocol.slice(0,-1));if(!w)throw Error("REFUSE\xB7reference no admitted transport policy");if(e.content&&e.content.name!==w.name)throw new m("authenticated-reference/transport","REFUSE\xB7reference injected content binding conflicts with declaration");const b={refusals:t("reference/contracts/refusals"),standing:t("reference/contracts/standing")},F=t("reference/policy"),U=t("reference/form-implementation"),B=C();if(b.refusals!==B.refusals||b.standing!==B.standing||!v(F)||U!==l.formImplementation)throw new m("authenticated-reference/context","REFUSE\xB7reference expected interpretation differs");const R=await Z(r,{snapshot:h,epoch:Number(f),proofScope:g,contracts:b,policy:F,formImplementation:U,signers:u.admitted,algorithms:o.admitted,objects:S,maxBytes:w.responseBytes,maxRecords:Number(c),digestBytes:E,verifyBytes:ee,fetchBytes:d((i,a)=>e.content?L(i,a,{read:e.content.read,digestBytes:E},{timeoutMs:w.timeoutMs,maxBytes:w.responseBytes},e.signal):X(i,a,A),"fetchBytes")});if(e.signal?.aborted)throw new m("reference/cancelled","REFUSE\xB7reference cancelled");const M=y==="wasm@1"?await T(n,R.records,S,l.configuration,e.signal):K(R.records,S);return{...R,backend:y,readings:M}}d(xe,"openAuthenticatedReference");export{te as authenticatedReferenceSelected,xe as openAuthenticatedReference,re as prepareNativeReference};
|
|
@@ -1,63 +1 @@
|
|
|
1
|
-
|
|
2
|
-
const hex = /^[0-9a-f]{64}$/;
|
|
3
|
-
const refuse = (cause) => { throw new BoundRefusal('reference/format', `REFUSE·reference ${cause}`); };
|
|
4
|
-
const keys = ['class', 'algorithm', 'digest', 'blob', 'source'];
|
|
5
|
-
function check(reference) {
|
|
6
|
-
if (Object.keys(reference).length !== keys.length || keys.some(key => !Object.prototype.hasOwnProperty.call(reference, key)))
|
|
7
|
-
refuse('fields');
|
|
8
|
-
if (reference.class !== 'standing')
|
|
9
|
-
refuse('unknown class');
|
|
10
|
-
if (reference.algorithm !== 'sha256')
|
|
11
|
-
refuse('unknown algorithm');
|
|
12
|
-
if (!hex.test(reference.digest) || !/^sha256:[0-9a-f]{64}$/.test(reference.blob))
|
|
13
|
-
refuse('digest');
|
|
14
|
-
let source;
|
|
15
|
-
try {
|
|
16
|
-
source = new URL(reference.source);
|
|
17
|
-
}
|
|
18
|
-
catch {
|
|
19
|
-
return refuse('source URL');
|
|
20
|
-
}
|
|
21
|
-
if (source.username || source.password || source.hash)
|
|
22
|
-
refuse('source credentials or fragment');
|
|
23
|
-
if (source.href !== reference.source)
|
|
24
|
-
refuse('noncanonical source URL');
|
|
25
|
-
return reference;
|
|
26
|
-
}
|
|
27
|
-
export function encodeReference(reference) {
|
|
28
|
-
check(reference);
|
|
29
|
-
return '#bound:1?' + keys.map(key => key + '=' + encodeURIComponent(reference[key])).join('&');
|
|
30
|
-
}
|
|
31
|
-
export function decodeReference(fragment) {
|
|
32
|
-
if (!fragment.startsWith('#bound:1?'))
|
|
33
|
-
refuse('profile');
|
|
34
|
-
const parameters = new URLSearchParams(fragment.slice('#bound:1?'.length));
|
|
35
|
-
if ([...parameters].length !== keys.length || new Set(parameters.keys()).size !== keys.length)
|
|
36
|
-
refuse('duplicate or missing field');
|
|
37
|
-
const reference = check(Object.fromEntries(parameters));
|
|
38
|
-
if (encodeReference(reference) !== fragment)
|
|
39
|
-
refuse('noncanonical encoding');
|
|
40
|
-
return Object.freeze(reference);
|
|
41
|
-
}
|
|
42
|
-
export function inspectReferenceBytes(reference, bytes, { maxBytes, readSemanticStanding, semanticStandingBytes, digestBytes }) {
|
|
43
|
-
if (bytes.byteLength > maxBytes)
|
|
44
|
-
refuse('bytes budget');
|
|
45
|
-
if (digestBytes(bytes) !== reference.blob.slice(7))
|
|
46
|
-
refuse('blob integrity');
|
|
47
|
-
let document;
|
|
48
|
-
try {
|
|
49
|
-
document = JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(bytes));
|
|
50
|
-
}
|
|
51
|
-
catch {
|
|
52
|
-
refuse('document');
|
|
53
|
-
}
|
|
54
|
-
if (document === null || typeof document !== 'object' || document.profile !== 'semantic-standing@1' || typeof document.standing !== 'string' || Object.keys(document).length !== 2)
|
|
55
|
-
refuse('document profile');
|
|
56
|
-
if (new TextDecoder('utf-8', { fatal: true }).decode(bytes) !== JSON.stringify({ profile: document.profile, standing: document.standing }))
|
|
57
|
-
refuse('noncanonical document wrapper');
|
|
58
|
-
const lines = readSemanticStanding(document.standing);
|
|
59
|
-
const semantic = semanticStandingBytes(lines);
|
|
60
|
-
if (digestBytes(new TextEncoder().encode(semantic)) !== reference.digest)
|
|
61
|
-
refuse('standing identity');
|
|
62
|
-
return { reference, lines, standing: semantic, authentication: 'not demonstrated; inspect only' };
|
|
63
|
-
}
|
|
1
|
+
var g=Object.defineProperty;var s=(t,n)=>g(t,"name",{value:n,configurable:!0});import{BoundRefusal as h}from"./refusals.js";const p=/^[0-9a-f]{64}$/,e=s(t=>{throw new h("reference/format",`REFUSE\xB7reference ${t}`)},"refuse"),c=["class","algorithm","digest","blob","source"];function d(t){(Object.keys(t).length!==c.length||c.some(i=>!Object.prototype.hasOwnProperty.call(t,i)))&&e("fields"),t.class!=="standing"&&e("unknown class"),t.algorithm!=="sha256"&&e("unknown algorithm"),(!p.test(t.digest)||!/^sha256:[0-9a-f]{64}$/.test(t.blob))&&e("digest");let n;try{n=new URL(t.source)}catch{return e("source URL")}return(n.username||n.password||n.hash)&&e("source credentials or fragment"),n.href!==t.source&&e("noncanonical source URL"),t}s(d,"check");function m(t){return d(t),"#bound:1?"+c.map(n=>n+"="+encodeURIComponent(t[n])).join("&")}s(m,"encodeReference");function y(t){t.startsWith("#bound:1?")||e("profile");const n=new URLSearchParams(t.slice(9));([...n].length!==c.length||new Set(n.keys()).size!==c.length)&&e("duplicate or missing field");const i=d(Object.fromEntries(n));return m(i)!==t&&e("noncanonical encoding"),Object.freeze(i)}s(y,"decodeReference");function R(t,n,{maxBytes:i,readSemanticStanding:u,semanticStandingBytes:f,digestBytes:a}){n.byteLength>i&&e("bytes budget"),a(n)!==t.blob.slice(7)&&e("blob integrity");let o;try{o=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(n))}catch{e("document")}(o===null||typeof o!="object"||o.profile!=="semantic-standing@1"||typeof o.standing!="string"||Object.keys(o).length!==2)&&e("document profile"),new TextDecoder("utf-8",{fatal:!0}).decode(n)!==JSON.stringify({profile:o.profile,standing:o.standing})&&e("noncanonical document wrapper");const r=u(o.standing),l=f(r);return a(new TextEncoder().encode(l))!==t.digest&&e("standing identity"),{reference:t,lines:r,standing:l,authentication:"not demonstrated; inspect only"}}s(R,"inspectReferenceBytes");export{y as decodeReference,m as encodeReference,R as inspectReferenceBytes};
|
|
@@ -1,18 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import { semanticStandingBytes } from '@lapxo/topos/standing';
|
|
4
|
-
/** Shared projection after admission; transport order never replaces effective order. */
|
|
5
|
-
export function referenceStanding(originals, records) {
|
|
6
|
-
const membership = new Set([...cellInputs(records, 'semantic-live@2').values()].flat().map(line => semanticStandingBytes([line])));
|
|
7
|
-
const fields = (line) => { const p = parse(line); if (p.kind !== 'fact')
|
|
8
|
-
throw Error('REFUSE·authenticated-reference original parse'); return p.value.fields; };
|
|
9
|
-
const effective = [...originals].sort((a, b) => Number(fields(a).epoch) - Number(fields(b).epoch));
|
|
10
|
-
return semanticStandingBytes(effective.filter(line => fields(line).type === undefined || membership.has(semanticStandingBytes([line]))));
|
|
11
|
-
}
|
|
12
|
-
export function referenceContracts(value) {
|
|
13
|
-
return value !== null && typeof value === 'object' && !Array.isArray(value) && Object.keys(value).length === 2 && /^sha256:[a-f0-9]{64}$/.test(value.refusals) && /^sha256:[a-f0-9]{64}$/.test(value.standing);
|
|
14
|
-
}
|
|
15
|
-
/** This versioned context frame binds interpretation contracts without changing wire fields. */
|
|
16
|
-
export function referenceContextBytes(context) {
|
|
17
|
-
return new TextEncoder().encode(JSON.stringify(['reference-export-context@1', context.semanticIdentity, context.epoch, context.proofScope, context.policy, context.formImplementation, context.signers, context.algorithms, context.contracts.refusals, context.contracts.standing, context.maxBytes, context.maxRecords]) + '\n');
|
|
18
|
-
}
|
|
1
|
+
var c=Object.defineProperty;var t=(e,s)=>c(e,"name",{value:s,configurable:!0});import{library11_parse as p}from"../vendor/runtime.js";import{library8_cellInputs as m}from"../vendor/runtime.js";import{library7_semanticStandingBytes as i}from"../vendor/runtime.js";function h(e,s){const o=new Set([...m(s,"semantic-live@2").values()].flat().map(r=>i([r]))),a=t(r=>{const n=p(r);if(n.kind!=="fact")throw Error("REFUSE\xB7authenticated-reference original parse");return n.value.fields},"fields"),f=[...e].sort((r,n)=>Number(a(r).epoch)-Number(a(n).epoch));return i(f.filter(r=>a(r).type===void 0||o.has(i([r]))))}t(h,"referenceStanding");function g(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&Object.keys(e).length===2&&/^sha256:[a-f0-9]{64}$/.test(e.refusals)&&/^sha256:[a-f0-9]{64}$/.test(e.standing)}t(g,"referenceContracts");function b(e){return new TextEncoder().encode(JSON.stringify(["reference-export-context@1",e.semanticIdentity,e.epoch,e.proofScope,e.policy,e.formImplementation,e.signers,e.algorithms,e.contracts.refusals,e.contracts.standing,e.maxBytes,e.maxRecords])+`
|
|
2
|
+
`)}t(b,"referenceContextBytes");export{b as referenceContextBytes,g as referenceContracts,h as referenceStanding};
|
package/dist/host/reference.js
CHANGED
|
@@ -1,24 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { createHash } from 'node:crypto';
|
|
3
|
-
import { readSemanticStanding, semanticStandingBytes } from '@lapxo/topos/core';
|
|
4
|
-
import { parse, transportSelection } from '@lapxo/topos/wire';
|
|
5
|
-
import { transportBytes } from "./ports/transport.js";
|
|
6
|
-
import { decodeReference, inspectReferenceBytes } from "./reference-profile.js";
|
|
7
|
-
export async function inspectReference(fragment, policy) {
|
|
8
|
-
const reference = decodeReference(fragment), scheme = new URL(reference.source).protocol.slice(0, -1);
|
|
9
|
-
const fields = policy.flatMap(line => { const got = parse(line); return got.kind === 'fact' ? [got.value.fields] : []; });
|
|
10
|
-
const selected = transportSelection(fields, scheme);
|
|
11
|
-
if (selected === undefined)
|
|
12
|
-
throw Error(`REFUSE·transport ${scheme} no admitted content-request/1 policy`);
|
|
13
|
-
let bytes;
|
|
14
|
-
try {
|
|
15
|
-
bytes = await transportBytes(reference.source, reference.blob, policy);
|
|
16
|
-
}
|
|
17
|
-
catch (error) {
|
|
18
|
-
const cause = error instanceof Error ? error.message : 'transport failed';
|
|
19
|
-
if (cause.startsWith('REFUSE·'))
|
|
20
|
-
throw error;
|
|
21
|
-
throw Error(`REFUSE·transport ${scheme} ${cause}`);
|
|
22
|
-
}
|
|
23
|
-
return inspectReferenceBytes(reference, bytes, { maxBytes: selected.responseBytes, readSemanticStanding, semanticStandingBytes, digestBytes: value => createHash('sha256').update(value).digest('hex') });
|
|
24
|
-
}
|
|
1
|
+
var p=Object.defineProperty;var o=(n,r)=>p(n,"name",{value:r,configurable:!0});import{createHash as f}from"node:crypto";import{library3_readSemanticStanding as m,library3_semanticStandingBytes as l}from"../vendor/runtime.js";import{library11_parse as y,library11_transportSelection as S}from"../vendor/runtime.js";import{transportBytes as u}from"./ports/transport.js";import{decodeReference as h,inspectReferenceBytes as E}from"./reference-profile.js";async function _(n,r){const s=h(n),a=new URL(s.source).protocol.slice(0,-1),d=r.flatMap(e=>{const t=y(e);return t.kind==="fact"?[t.value.fields]:[]}),i=S(d,a);if(i===void 0)throw Error(`REFUSE\xB7transport ${a} no admitted content-request/1 policy`);let c;try{c=await u(s.source,s.blob,r)}catch(e){const t=e instanceof Error?e.message:"transport failed";throw t.startsWith("REFUSE\xB7")?e:Error(`REFUSE\xB7transport ${a} ${t}`)}return E(s,c,{maxBytes:i.responseBytes,readSemanticStanding:m,semanticStandingBytes:l,digestBytes:o(e=>f("sha256").update(e).digest("hex"),"digestBytes")})}o(_,"inspectReference");export{_ as inspectReference};
|
package/dist/host/refusals.js
CHANGED
|
@@ -1,43 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export class BoundRefusal extends Error {
|
|
4
|
-
constructor(code, diagnostic) { super(diagnostic); this.name = 'BoundRefusal'; this.code = code; }
|
|
5
|
-
}
|
|
6
|
-
/** Pure machine contract reader. A catalog is data, never an authority grant. */
|
|
7
|
-
export function readRefusalCatalog(text) {
|
|
8
|
-
const groups = new Map();
|
|
9
|
-
let profile = false;
|
|
10
|
-
for (const line of text.trimEnd().split('\n')) {
|
|
11
|
-
const parsed = parse(line);
|
|
12
|
-
if (parsed.kind !== 'fact' || canonical(parsed.value.fields) !== line)
|
|
13
|
-
throw new BoundRefusal('catalog/invalid', 'REFUSE·invalid refusal catalog line');
|
|
14
|
-
const f = parsed.value.fields;
|
|
15
|
-
if (f.scope === 'refusal/catalog' && f.measure === 'id' && f.value === 'bound-refusals@1' && f.role === 'writes' && f.form === 'alphabet' && !profile) {
|
|
16
|
-
profile = true;
|
|
17
|
-
continue;
|
|
18
|
-
}
|
|
19
|
-
if (f.role !== 'writes' || f.form !== 'alphabet' || !f.scope?.startsWith('refusal/') || !['code', 'class', 'next'].includes(f.measure ?? ''))
|
|
20
|
-
throw new BoundRefusal('catalog/invalid', 'REFUSE·invalid refusal catalog record');
|
|
21
|
-
const group = groups.get(f.scope) ?? new Map();
|
|
22
|
-
if (group.has(f.measure))
|
|
23
|
-
throw new BoundRefusal('catalog/invalid', 'REFUSE·duplicate refusal catalog field');
|
|
24
|
-
group.set(f.measure, f);
|
|
25
|
-
groups.set(f.scope, group);
|
|
26
|
-
}
|
|
27
|
-
const entries = [];
|
|
28
|
-
for (const [scope, group] of groups) {
|
|
29
|
-
const code = group.get('code')?.value, category = group.get('class')?.value, meaning = group.get('class')?.about, next = group.get('next')?.value;
|
|
30
|
-
if (group.size !== 3 || !code || scope !== 'refusal/' + code || !category || !meaning || !next)
|
|
31
|
-
throw new BoundRefusal('catalog/invalid', 'REFUSE·incomplete refusal catalog entry');
|
|
32
|
-
entries.push(Object.freeze({ code, category, meaning, next }));
|
|
33
|
-
}
|
|
34
|
-
if (!profile || !entries.length)
|
|
35
|
-
throw new BoundRefusal('catalog/invalid', 'REFUSE·missing refusal catalog profile');
|
|
36
|
-
return Object.freeze(entries);
|
|
37
|
-
}
|
|
38
|
-
export function describeRefusal(error, catalog) {
|
|
39
|
-
const entry = catalog.find(row => row.code === error.code);
|
|
40
|
-
if (!entry)
|
|
41
|
-
throw new BoundRefusal('catalog/invalid', 'REFUSE·undeclared refusal code');
|
|
42
|
-
return entry;
|
|
43
|
-
}
|
|
1
|
+
var d=Object.defineProperty;var c=(s,a)=>d(s,"name",{value:a,configurable:!0});import{library11_parse as p,library11_canonical as g}from"../vendor/runtime.js";class l extends Error{static{c(this,"BoundRefusal")}constructor(a,o){super(o),this.name="BoundRefusal",this.code=a}}function v(s){const a=new Map;let o=!1;for(const i of s.trimEnd().split(`
|
|
2
|
+
`)){const t=p(i);if(t.kind!=="fact"||g(t.value.fields)!==i)throw new l("catalog/invalid","REFUSE\xB7invalid refusal catalog line");const e=t.value.fields;if(e.scope==="refusal/catalog"&&e.measure==="id"&&e.value==="bound-refusals@1"&&e.role==="writes"&&e.form==="alphabet"&&!o){o=!0;continue}if(e.role!=="writes"||e.form!=="alphabet"||!e.scope?.startsWith("refusal/")||!["code","class","next"].includes(e.measure??""))throw new l("catalog/invalid","REFUSE\xB7invalid refusal catalog record");const r=a.get(e.scope)??new Map;if(r.has(e.measure))throw new l("catalog/invalid","REFUSE\xB7duplicate refusal catalog field");r.set(e.measure,e),a.set(e.scope,r)}const n=[];for(const[i,t]of a){const e=t.get("code")?.value,r=t.get("class")?.value,u=t.get("class")?.about,f=t.get("next")?.value;if(t.size!==3||!e||i!=="refusal/"+e||!r||!u||!f)throw new l("catalog/invalid","REFUSE\xB7incomplete refusal catalog entry");n.push(Object.freeze({code:e,category:r,meaning:u,next:f}))}if(!o||!n.length)throw new l("catalog/invalid","REFUSE\xB7missing refusal catalog profile");return Object.freeze(n)}c(v,"readRefusalCatalog");function E(s,a){const o=a.find(n=>n.code===s.code);if(!o)throw new l("catalog/invalid","REFUSE\xB7undeclared refusal code");return o}c(E,"describeRefusal");export{l as BoundRefusal,E as describeRefusal,v as readRefusalCatalog};
|