@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
package/dist/cli/verb.js
CHANGED
|
@@ -1,685 +1,84 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { BoundRefusal,
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const said = (measure) => {
|
|
86
|
-
const values = new Set(today.filter((line) => fieldOf(line, 'scope') === `keys/${owner}` && fieldOf(line, 'measure') === measure && fieldOf(line, 'value') !== 'withdraw').map((line) => fieldOf(line, 'value')));
|
|
87
|
-
if (values.size !== 1)
|
|
88
|
-
throw new Error(`REFUSE·bootstrap root key ${owner} must declare one ${measure}`);
|
|
89
|
-
return [...values][0];
|
|
90
|
-
};
|
|
91
|
-
if (said('class') !== 'authorize')
|
|
92
|
-
throw new Error('REFUSE·bootstrap the root key must authorize');
|
|
93
|
-
const publicKey = said('public-key');
|
|
94
|
-
const coverage = said('coverage').split('|').filter(Boolean);
|
|
95
|
-
if (!publicKey || !coverage.length)
|
|
96
|
-
throw new Error('REFUSE·bootstrap the root key must declare its public key and coverage');
|
|
97
|
-
const drafted = today.filter(line => !fieldOf(line, 'sig'));
|
|
98
|
-
if (drafted.length) {
|
|
99
|
-
const invoke = signerFor(today, keyId, valueOf(args, FLAGS.signer), valueOf(args, FLAGS.keyFile));
|
|
100
|
-
const got = await signConsentLot(drafted, { epoch: 1, by: keyId, algorithm: config.era }, publicKey, config.admitted, invoke);
|
|
101
|
-
if (got.kind === 'refuse')
|
|
102
|
-
throw new Error(got.why);
|
|
103
|
-
let i = 0;
|
|
104
|
-
today.splice(0, today.length, ...today.map(line => fieldOf(line, 'sig') ? line : got.lines[i++]));
|
|
105
|
-
}
|
|
106
|
-
const authority = authorityFor(today, { ...releaseSigner(today), id: owner, publicKey, coverage }, config.admitted);
|
|
107
|
-
for (const line of today) {
|
|
108
|
-
const verdict = authority.of(line);
|
|
109
|
-
if (verdict.kind !== 'admitted')
|
|
110
|
-
throw new Error(`REFUSE·bootstrap ${fieldOf(line, 'scope')} is not admitted: ${verdict.why ?? verdict.kind}`);
|
|
111
|
-
verified += 1;
|
|
112
|
-
}
|
|
113
|
-
// Source receipts require admitted instrument coordinates before the root commit.
|
|
114
|
-
vouching(today);
|
|
115
|
-
sourced(today);
|
|
116
|
-
born = bootstrapDigest(today.map((line) => line.replace(/ sig="[^"]*"/, '')).sort(), algorithm);
|
|
117
|
-
anchored = { [owner]: { id: owner, publicKey, coverage } };
|
|
118
|
-
}
|
|
119
|
-
catch (error) {
|
|
120
|
-
process.stderr.write(`${selfName()}: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
121
|
-
return EXIT.refuse;
|
|
122
|
-
}
|
|
123
|
-
// Preflight above performs no writes. Only an admitted batch may establish its root of trust.
|
|
124
|
-
return underTheLock(store, 'bootstrap', () => {
|
|
125
|
-
if (ledgerLines(store, owner).length || observeText(targetFile(root)) !== proposed) {
|
|
126
|
-
process.stderr.write(`${selfName()}: REFUSE·bootstrap the proposed lock or owner ledger changed before commit\n`);
|
|
127
|
-
return EXIT.refuse;
|
|
128
|
-
}
|
|
129
|
-
const landed = land(store, owner, today);
|
|
130
|
-
if (keyId !== owner)
|
|
131
|
-
land(store, keyId, today);
|
|
132
|
-
const file = join(store, `${selfName()}.keys`);
|
|
133
|
-
mkdirSync(dirname(file), { recursive: true });
|
|
134
|
-
writeFileSync(file, `${JSON.stringify(anchored, null, 2)}\n`);
|
|
135
|
-
const signedLines = today.filter((line) => /\bsig=/.test(line));
|
|
136
|
-
const failing = signedLines.length - verified;
|
|
137
|
-
land(store, 'land', [canonical({
|
|
138
|
-
scope: 'bootstrap', role: 'writes', form: 'alphabet', measure: 'status', value: 'present', by: 'land', at: `bootstrap:${born}`,
|
|
139
|
-
about: 'the lines this clone was born from: one land per clone, and a second is a fork of the same cell',
|
|
140
|
-
})]);
|
|
141
|
-
const rendered = renderInto(root, store);
|
|
142
|
-
process.stdout.write(`FACT landed ${landed.appended} unique lines from ${today.length} in TARGET`
|
|
143
|
-
+ ` · ${failing} of ${signedLines.length} signed lines fail admission by declared authority\n`
|
|
144
|
-
+ `TARGET ${rendered.standing} claims · ${rendered.superseded.length} superseded · ${Date.now() - started} ms\n`);
|
|
145
|
-
for (const line of rendered.superseded)
|
|
146
|
-
process.stdout.write(`SUPERSEDED ${line}\n`);
|
|
147
|
-
if (!hasVouchedTree(store)) {
|
|
148
|
-
const locations = new Set();
|
|
149
|
-
const refused = new Set();
|
|
150
|
-
for (const line of signedDemands(store)) {
|
|
151
|
-
const got = locationsOf(fieldOf(line, 'needs'));
|
|
152
|
-
for (const l of got.locations)
|
|
153
|
-
locations.add(l);
|
|
154
|
-
for (const r of got.refused)
|
|
155
|
-
refused.add(r);
|
|
156
|
-
}
|
|
157
|
-
const coordinates = new Map();
|
|
158
|
-
const roleOf = rolesOf(store);
|
|
159
|
-
for (const location of locations)
|
|
160
|
-
for (const [path, digest] of coordinatesOf(root, location, roleOf))
|
|
161
|
-
coordinates.set(path, digest);
|
|
162
|
-
const vouched = landCoordinates(store, coordinates, [], 'origin:land');
|
|
163
|
-
process.stdout.write(`FACT vouched · ${vouched} sources under ${locations.size} locations · ${refused.size} needs refused as globs\n`);
|
|
164
|
-
}
|
|
165
|
-
return EXIT.closed;
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
/** What one fold cost, where it was taken and whether its points had already been folded: a beat of the instrument. */
|
|
169
|
-
function beat(root, fold, ms) {
|
|
170
|
-
const folder = writerFor(fold.standing, 'fold');
|
|
171
|
-
const seconds = (n) => `${(n / 1000).toFixed(n < 100 ? 2 : 1)} s`;
|
|
172
|
-
process.stderr.write(`BEAT fold ${fold.key.slice(0, 8)} ${fold.kept ? 'kept' : 'folded'} ${seconds(ms)}`
|
|
173
|
-
+ `${fold.beats.kept ? ` · ${seconds(fold.beats.kept)} kept` : ''}${fold.beats.folded ? ` · ${seconds(fold.beats.folded)} folded` : ''}\n`);
|
|
174
|
-
if (folder === undefined)
|
|
175
|
-
return;
|
|
176
|
-
if (!fold.kept) {
|
|
177
|
-
const moved = movedPoints(storeOf(root), foldPoints(storeOf(root), fold.standing, fold.under, folder, fold.instrument), fold.key);
|
|
178
|
-
const named = moved === undefined ? 'no fold was kept before this one'
|
|
179
|
-
: `${moved.gone.length} points gone · ${moved.came.length} came · ${[...moved.gone, ...moved.came].slice(0, 3).map((one) => one.split(' ')[0]).join(' ') || 'none'}`;
|
|
180
|
-
process.stderr.write(`KEPT fold ${fold.key.slice(0, 8)} miss · ${named}\n`);
|
|
181
|
-
}
|
|
182
|
-
land(storeOf(root), folder, [canonical({
|
|
183
|
-
scope: `beat/${fold.under ?? '.'}`, role: 'writes', form: 'interval', measure: 'ms',
|
|
184
|
-
value: `${ms}..${ms}`, by: folder, at: `place:${fold.kept ? 'kept' : 'folded'}`,
|
|
185
|
-
})]);
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
* A view of a place, rendered from its fold; a shaped one writes the coordinate its shape names. With a batch named, it is the view of the tree
|
|
189
|
-
* as if the batch had landed: the batch is signed and folded, never landed, and nothing is written — `--as rank <batch>`
|
|
190
|
-
* is what a batch would move, read before land.
|
|
191
|
-
*/
|
|
192
|
-
async function view(root, under, asked, told = [], coord, key, includePolicy = true, authorityHeld = false) {
|
|
193
|
-
const [name = asked, depth] = asked.split('@');
|
|
194
|
-
if (name === NAMED_VIEWS.help) {
|
|
195
|
-
process.stdout.write(`${helpLines().join('\n')}\n`);
|
|
196
|
-
return EXIT.closed;
|
|
197
|
-
}
|
|
198
|
-
// A declared executable reader holds the acting Root's authority throughout
|
|
199
|
-
// observation and publication. This predicate acquires exclusion only; the
|
|
200
|
-
// native route authenticates the actual declaration before use.
|
|
201
|
-
if (!authorityHeld && !told.length && !readOnly() && lockStanding(storeOf(root)).some(line => /^reader\/.+\/port$/.test(fieldOf(line, 'scope')) && fieldOf(line, 'role') === 'writes' && fieldOf(line, 'value') !== 'withdraw')) {
|
|
202
|
-
return underRootAuthority(storeOf(root), 'view reader authority', () => view(root, under, asked, told, coord, key, includePolicy, true));
|
|
203
|
-
}
|
|
204
|
-
if (!lockLines(storeOf(root)).length) {
|
|
205
|
-
process.stderr.write(`${selfName()}: the owner ledger is empty; land it before rendering a view\n`);
|
|
206
|
-
return EXIT.refuse;
|
|
207
|
-
}
|
|
208
|
-
if (name === 'act') {
|
|
209
|
-
if (under || told.length)
|
|
210
|
-
throw Error('REFUSE·act committed identity query only');
|
|
211
|
-
printActResult(root, coord);
|
|
212
|
-
return EXIT.closed;
|
|
213
|
-
}
|
|
214
|
-
if (name === 'standing') {
|
|
215
|
-
if (under || told.length || coord || depth !== undefined)
|
|
216
|
-
throw new BoundRefusal('standing/query', 'REFUSE·standing local committed projection only');
|
|
217
|
-
printStandingResult(root);
|
|
218
|
-
return EXIT.closed;
|
|
219
|
-
}
|
|
220
|
-
if (name === 'evidence' && !under && !told.length && ingressBundles(storeOf(root)).length) {
|
|
221
|
-
const declared = viewsOf(lockStanding(storeOf(root))).get(name);
|
|
222
|
-
if (!declared || declared.shape || !declared.regions.some(region => region.name === 'evidence'))
|
|
223
|
-
throw Error('REFUSE·view foreign evidence requires a declared evidence view');
|
|
224
|
-
const received = await foreignWalkLines(root), authority = authorityFor(lockLines(storeOf(root)), rootSigner(root), signaturesOf(storeOf(root)).admitted);
|
|
225
|
-
const local = [...new Set(authority.admitted.flatMap(key => ledgerLines(storeOf(root), key.id)))].filter(line => authority.of(line).kind === 'admitted');
|
|
226
|
-
for (const line of [...new Set([...local, ...ingressReceipts(storeOf(root)), ...received])])
|
|
227
|
-
process.stdout.write(line + '\n');
|
|
228
|
-
process.stdout.write('FACT authenticated histories · readings · no encounters computed\n');
|
|
229
|
-
return EXIT.closed;
|
|
230
|
-
}
|
|
231
|
-
const at = Date.now();
|
|
232
|
-
const place = under?.replace(/\/$/, '');
|
|
233
|
-
const released = releaseOf(storeOf(root));
|
|
234
|
-
const authority = authorityFor([...released ?? lockLines(storeOf(root)), ...told], released ? releaseSigner(released) : rootSigner(root), signaturesOf(storeOf(root), told).admitted);
|
|
235
|
-
const ledger = told.filter((line) => authority.of(line).kind === 'admitted');
|
|
236
|
-
const rest = told.filter((line) => !ledger.includes(line));
|
|
237
|
-
if (place && rest.length)
|
|
238
|
-
tellOwn(place, rest);
|
|
239
|
-
if (name === NAMED_VIEWS.lines && (told.length || depth === undefined)) {
|
|
240
|
-
const text = standingOf(root, under, ledger).standing.filter(isWire).join('\n');
|
|
241
|
-
process.stdout.write(text ? `${text}\n` : '');
|
|
242
|
-
return EXIT.closed;
|
|
243
|
-
}
|
|
244
|
-
if (told.length) {
|
|
245
|
-
const selected = viewsOf(standingOf(root, under, ledger).standing).get(name);
|
|
246
|
-
if (selected && !selected.shape && selected.regions.some(region => region.name === 'cells')) {
|
|
247
|
-
const history = [...signedOwnerLines(storeOf(root)), ...ledger];
|
|
248
|
-
const held = await admittedObjects(root, history);
|
|
249
|
-
process.stdout.write(`TOLD ${told.length} lines folded as if landed · nothing written\n`);
|
|
250
|
-
for (const line of renderCells(objectFold(held.records, held.context)))
|
|
251
|
-
process.stdout.write(line + '\n');
|
|
252
|
-
return EXIT.closed;
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
const own = place ? rest.filter((line) => admittedIn(root, place, line)) : [];
|
|
256
|
-
// Executed views use the place's declared mounts before observation, as pass
|
|
257
|
-
// does. Prospective folds and public standing queries do not lay releases.
|
|
258
|
-
if (!told.length && !readOnly())
|
|
259
|
-
layReleases(storeOf(root), root, standingOf(root, under).standing, storeOf(root));
|
|
260
|
-
const fold = told.length
|
|
261
|
-
? foldPlace(root, entryOf(root), under, false, { standing: standingOf(root, under, ledger), observed: observedClaims(root, storeOf(root), { wait: false }), free: true })
|
|
262
|
-
: foldPlace(root, entryOf(root), under, true);
|
|
263
|
-
if (!told.length && readerRefusals().length) {
|
|
264
|
-
for (const why of readerRefusals())
|
|
265
|
-
process.stderr.write(`${selfName()}: ${why}\n`);
|
|
266
|
-
return EXIT.refuse;
|
|
267
|
-
}
|
|
268
|
-
if (coord)
|
|
269
|
-
askWhy(fold, coord);
|
|
270
|
-
if (name === NAMED_VIEWS.lines) {
|
|
271
|
-
if (!told.length)
|
|
272
|
-
beat(root, fold, Date.now() - at);
|
|
273
|
-
const text = fold.standing.filter(isWire).join('\n');
|
|
274
|
-
process.stdout.write(text ? `${text}\n` : '');
|
|
275
|
-
if (depth === '1')
|
|
276
|
-
for (const line of readingsIn([...fold.standing.filter(isCeiling), ...ownCeilings(under)], fold))
|
|
277
|
-
process.stdout.write(`${line}\n`);
|
|
278
|
-
return EXIT.closed;
|
|
279
|
-
}
|
|
280
|
-
const views = viewsOf(fold.standing);
|
|
281
|
-
const cellsView = [...views.entries()].find(([, one]) => !one.shape && one.regions.some((region) => region.name === 'cells'));
|
|
282
|
-
if (cellsView && name === cellsView[0]) {
|
|
283
|
-
const history = signedOwnerLines(storeOf(root));
|
|
284
|
-
const { objectHistory } = await import('@lapxo/topos/wire');
|
|
285
|
-
const parsed = objectHistory(history);
|
|
286
|
-
if (parsed.kind !== 'fact')
|
|
287
|
-
throw Error(`REFUSE·wire ${parsed.why}`);
|
|
288
|
-
if (parsed.value.objects.length) {
|
|
289
|
-
await cellsWithReceipts(root, history, text => process.stdout.write(text + '\n'));
|
|
290
|
-
if (includePolicy)
|
|
291
|
-
for (const line of releasePolicyLines(fold.release))
|
|
292
|
-
process.stdout.write(line + '\n');
|
|
293
|
-
if (!told.length)
|
|
294
|
-
beat(root, fold, Date.now() - at);
|
|
295
|
-
return EXIT.closed;
|
|
296
|
-
}
|
|
297
|
-
if (!told.length)
|
|
298
|
-
beat(root, fold, Date.now() - at);
|
|
299
|
-
const cells = fold.open ?? [];
|
|
300
|
-
const mine = key ? cells.filter((cell) => cell.origins.includes(key)) : cells;
|
|
301
|
-
const cards = openCards(mine);
|
|
302
|
-
if (key)
|
|
303
|
-
process.stdout.write(`KEY ${key}\n`);
|
|
304
|
-
if (cards.length)
|
|
305
|
-
process.stdout.write(`${cards.join('\n')}\n`);
|
|
306
|
-
return EXIT.closed;
|
|
307
|
-
}
|
|
308
|
-
if (!told.length)
|
|
309
|
-
beat(root, fold, Date.now() - at);
|
|
310
|
-
if (name === 'rank') {
|
|
311
|
-
const asked = place ? [place] : placesIn(root);
|
|
312
|
-
const reds = asked.flatMap((one) => sharedShapes(ownLockOf(root, one)).map((said) => `${one} ${said}`));
|
|
313
|
-
if (reds.length) {
|
|
314
|
-
process.stderr.write(`${selfName()}: REFUSE·rank ${reds.join(' · ')}: two views naming the same shape in one place\n`);
|
|
315
|
-
return EXIT.refuse;
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
const signed = views.get(name);
|
|
319
|
-
if (!signed) {
|
|
320
|
-
process.stderr.write(`${selfName()}: no view/${name} is signed; the lock signs ${[...views.keys()].sort().map((v) => `view/${v}`).join(' · ') || 'no view'}\n`);
|
|
321
|
-
return EXIT.usage;
|
|
322
|
-
}
|
|
323
|
-
const missing = unrendered(fold, signed);
|
|
324
|
-
if (missing.length) {
|
|
325
|
-
process.stderr.write(`${selfName()}: REFUSE·view view/${name} asks regions nothing renders: ${missing.join(' ')} · none is the instrument's own and no capsule ${under ?? 'the root'} can run declares it\n`);
|
|
326
|
-
return EXIT.refuse;
|
|
327
|
-
}
|
|
328
|
-
const bound = placesOf(fold.standing, signed);
|
|
329
|
-
if (bound.length && !bound.includes(under ?? '')) {
|
|
330
|
-
process.stderr.write(`${selfName()}: view/${name} writes ${bound.map((place) => `${place}${signed.shape}`).join(' · ')}, and nothing of ${under ?? 'this place'}\n`);
|
|
331
|
-
return EXIT.usage;
|
|
332
|
-
}
|
|
333
|
-
const folder = writerFor(fold.standing, 'fold');
|
|
334
|
-
if (folder !== undefined && !told.length) {
|
|
335
|
-
const spent = Date.now() - at;
|
|
336
|
-
land(storeOf(root), folder, [canonical({
|
|
337
|
-
scope: `beat/${under ?? '.'}`, role: 'writes', form: 'interval', measure: 'ms',
|
|
338
|
-
value: `${spent}..${spent}`, by: folder, at: `place:command-${fold.kept ? 'kept' : 'folded'}`,
|
|
339
|
-
})]);
|
|
340
|
-
}
|
|
341
|
-
const shown = (fold) => {
|
|
342
|
-
const text = viewOf(fold, Number.isFinite(Number(depth)) && depth !== undefined ? { ...signed, regions: signed.regions.map((one) => (one.called ? { ...one, at: Number(depth) } : one)) } : signed);
|
|
343
|
-
if (process.argv.includes(FLAGS.check)) {
|
|
344
|
-
const coordinate = join(root, under ?? '', signed.shape || '');
|
|
345
|
-
const held = signed.shape ? observeText(coordinate) : undefined;
|
|
346
|
-
const same = held !== undefined && held === text;
|
|
347
|
-
if (same) {
|
|
348
|
-
process.stdout.write(`SAME ${signed.shape || `view/${name}`}\n`);
|
|
349
|
-
return EXIT.closed;
|
|
350
|
-
}
|
|
351
|
-
const heldLines = (held ?? '').split('\n');
|
|
352
|
-
const next = text.split('\n');
|
|
353
|
-
const found = heldLines.findIndex((line, i) => line !== next[i]);
|
|
354
|
-
const at = found < 0 ? Math.min(heldLines.length, next.length) : found;
|
|
355
|
-
const line = (found < 0 ? next[at] : heldLines[at]) ?? next[at] ?? '';
|
|
356
|
-
process.stdout.write(`DIFFERS ${signed.shape || `view/${name}`}${held === undefined ? ' · this place holds no such region' : ` · line ${at + 1} · ${line}`}\n`);
|
|
357
|
-
return EXIT.refuse;
|
|
358
|
-
}
|
|
359
|
-
if (!signed.shape || told.length) {
|
|
360
|
-
if (told.length) {
|
|
361
|
-
process.stdout.write(`TOLD ${told.length} lines folded as if landed · ${ledger.length} in the ledger · ${own.length} in ${place ?? 'the root'}'s own lock`
|
|
362
|
-
+ `${rest.length - own.length ? ` · ${rest.length - own.length} admitted nowhere` : ''} · the batch lands nothing and nothing is written\n`);
|
|
363
|
-
}
|
|
364
|
-
process.stdout.write(text);
|
|
365
|
-
if (depth === '1')
|
|
366
|
-
for (const line of readingsIn(told.length ? told.filter(isCeiling) : [...fold.standing.filter(isCeiling), ...ownCeilings(under)], fold))
|
|
367
|
-
process.stdout.write(`${line}\n`);
|
|
368
|
-
return EXIT.closed;
|
|
369
|
-
}
|
|
370
|
-
const coordinate = join(root, under ?? '', signed.shape);
|
|
371
|
-
return underTheRegions(storeOf(root), [under ?? ''], `view/${name}`, () => {
|
|
372
|
-
mkdirSync(dirname(coordinate), { recursive: true });
|
|
373
|
-
writeFileSync(coordinate, text);
|
|
374
|
-
process.stdout.write(`RENDERED ${relative(root, coordinate).split(sep).join('/')} · view/${name} · ${text.split('\n').length - 1} lines\n`);
|
|
375
|
-
return EXIT.closed;
|
|
376
|
-
});
|
|
377
|
-
};
|
|
378
|
-
return shown(fold);
|
|
379
|
-
}
|
|
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
|
-
}
|
|
390
|
-
const batch = await signedBatch(root, rest, positionalsOf(rest));
|
|
391
|
-
if (batch.kind === 'exit')
|
|
392
|
-
return batch.code;
|
|
393
|
-
if (batch.kind === 'once') {
|
|
394
|
-
process.stderr.write(`ONCE ${batch.proposed.length} lines · every one already landed: nothing to sign\n`);
|
|
395
|
-
return EXIT.closed;
|
|
396
|
-
}
|
|
397
|
-
for (const place of namedPlaces(rest))
|
|
398
|
-
process.stdout.write(`# place ${place}\n`);
|
|
399
|
-
for (const line of batch.signed)
|
|
400
|
-
process.stdout.write(`${line}\n`);
|
|
401
|
-
process.stderr.write(`SIGNED ${batch.signed.length} lines · epoch ${batch.epoch}${namedPlaces(rest).length ? ` · own lines for ${namedPlaces(rest).join(', ')}` : ''} · they land together, before the lock moves\n`);
|
|
402
|
-
return EXIT.closed;
|
|
403
|
-
}
|
|
404
|
-
async function landVerb(root, rest) {
|
|
405
|
-
const lock = resolve(targetFile(root));
|
|
406
|
-
const batch = positionalsOf(rest).filter((one) => {
|
|
407
|
-
const at = resolve(one);
|
|
408
|
-
return existsSync(at) && !lstatSync(at).isDirectory() && at !== lock;
|
|
409
|
-
});
|
|
410
|
-
if (!batch.length) {
|
|
411
|
-
const store = storeOf(root);
|
|
412
|
-
if (existsSync(join(store, 'ledger')) && ledgerLines(store, ownerOf(store)).length) {
|
|
413
|
-
process.stderr.write(`${selfName()}: REFUSE·bootstrap the owner ledger already holds claims; provide an explicit signed batch to change it\n`);
|
|
414
|
-
return EXIT.refuse;
|
|
415
|
-
}
|
|
416
|
-
return firstLand(root, rest);
|
|
417
|
-
}
|
|
418
|
-
const die = (why) => {
|
|
419
|
-
process.stderr.write(`${selfName()}: ${why.startsWith('REFUSE·') ? why : `REFUSE·crash ${why}`}\n`);
|
|
420
|
-
process.exitCode = EXIT.refuse;
|
|
421
|
-
};
|
|
422
|
-
process.once('SIGINT', () => die('SIGINT'));
|
|
423
|
-
process.once('SIGHUP', () => die('SIGHUP'));
|
|
424
|
-
process.once('uncaughtException', (error) => die(error instanceof Error ? error.message : String(error)));
|
|
425
|
-
process.once('unhandledRejection', (error) => die(error instanceof Error ? error.message : String(error)));
|
|
426
|
-
try {
|
|
427
|
-
const proposed = batch.flatMap(claimLinesIn);
|
|
428
|
-
if (proposed.some(isWalkHeader)) {
|
|
429
|
-
for (const line of await landWalk(root, proposed, valueOf(rest, FLAGS.key), valueOf(rest, FLAGS.keyFile), valueOf(rest, FLAGS.signer)))
|
|
430
|
-
process.stdout.write(line + '\n');
|
|
431
|
-
return EXIT.closed;
|
|
432
|
-
}
|
|
433
|
-
return await accept(root, rest);
|
|
434
|
-
}
|
|
435
|
-
catch (error) {
|
|
436
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
437
|
-
process.stderr.write(`${selfName()}: ${message.startsWith('REFUSE·') ? message : `REFUSE·crash ${message}`}\n`);
|
|
438
|
-
return EXIT.refuse;
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
function foldFile(at) {
|
|
442
|
-
const lines = claimLinesIn(at);
|
|
443
|
-
const folded = foldClaims(lines);
|
|
444
|
-
const fields = folded.standing.flatMap(line => { const got = parseWire(line); return got.kind === 'fact' ? [got.value.fields] : []; });
|
|
445
|
-
const isTopos = fields.some(f => f.scope?.startsWith('region/') && f.measure === 'reads');
|
|
446
|
-
if (isTopos && folded.forks.length)
|
|
447
|
-
throw Error('REFUSE·topos incompatible live claims in declared fold');
|
|
448
|
-
const selected = isTopos ? toposStanding(folded.standing) : undefined;
|
|
449
|
-
if (selected !== undefined) {
|
|
450
|
-
const wire = wireAt(ownLock().flatMap(line => { const got = parseWire(line); return got.kind === 'fact' ? [got.value.fields] : []; }), Number.MAX_SAFE_INTEGER);
|
|
451
|
-
const algorithm = wire?.digests.values().next().value;
|
|
452
|
-
if (!algorithm)
|
|
453
|
-
throw Error('REFUSE·topos instrument names no digest algorithm');
|
|
454
|
-
process.stdout.write(selected.split('\n').filter(Boolean).map(line => 'TOPOS ' + line).join('\n') + '\n');
|
|
455
|
-
process.stdout.write('PIN ' + bootstrapDigest([selected], algorithm) + '\n');
|
|
456
|
-
}
|
|
457
|
-
for (const line of folded.standing)
|
|
458
|
-
process.stdout.write(`${line}\n`);
|
|
459
|
-
for (const fork of folded.forks)
|
|
460
|
-
process.stdout.write(`FORK ${fork.key}${fork.state ? ` · ${fork.state}` : ''}\n`);
|
|
461
|
-
process.stdout.write(`FACT ${folded.standing.length} standing · ${folded.forks.length} forks · ${basename(at)} · readings · no encounters computed\n`);
|
|
462
|
-
return EXIT.closed;
|
|
463
|
-
}
|
|
464
|
-
function foldVerb(root, rest) {
|
|
465
|
-
const references = positionalsOf(rest).filter(one => /^#bound(?::|$)/.test(one));
|
|
466
|
-
if (references.length) {
|
|
467
|
-
if (references.length !== 1 || positionalsOf(rest).length !== 1 || rest.some(one => one.startsWith('--')))
|
|
468
|
-
throw Error('REFUSE·reference name one reference without view, check or signing options');
|
|
469
|
-
if (authenticatedReferenceSelected(standingOf(root).standing))
|
|
470
|
-
return openAuthenticatedReference(root, references[0]).then(result => {
|
|
471
|
-
process.stdout.write(`SOURCE ${result.reference.source}\n`);
|
|
472
|
-
for (const line of result.semanticStanding.split('\n').filter(Boolean))
|
|
473
|
-
process.stdout.write(`TOPOS ${line}\n`);
|
|
474
|
-
for (const cell of result.readings)
|
|
475
|
-
process.stdout.write('CELL ' + JSON.stringify(cell) + '\n');
|
|
476
|
-
process.stdout.write(`AUTHENTICATED standing ${result.semanticIdentity} · authority ${result.authorityContextIdentity} · no effects committed\n`);
|
|
477
|
-
return EXIT.closed;
|
|
478
|
-
});
|
|
479
|
-
return inspectReference(references[0], standingOf(root).standing).then(result => {
|
|
480
|
-
process.stdout.write(`SOURCE ${result.reference.source}\n`);
|
|
481
|
-
for (const line of result.lines)
|
|
482
|
-
process.stdout.write(`TOPOS ${line}\n`);
|
|
483
|
-
process.stdout.write(`INSPECT standing sha256:${result.reference.digest} · blob ${result.reference.blob} · no encounters computed · unauthenticated\n`);
|
|
484
|
-
return EXIT.closed;
|
|
485
|
-
});
|
|
486
|
-
}
|
|
487
|
-
const files = positionalsOf(rest).filter((one) => existsSync(resolve(one)) && !lstatSync(resolve(one)).isDirectory() && one.endsWith(EXTENSION));
|
|
488
|
-
const places = positionalsOf(rest).filter((one) => existsSync(resolve(one)) && lstatSync(resolve(one)).isDirectory());
|
|
489
|
-
if (files.length === 1 && !places.length && valueOf(rest, FLAGS.as) === undefined) {
|
|
490
|
-
const at = resolve(files[0]);
|
|
491
|
-
if (!at.endsWith(`/${LOCK}`) && at !== LOCK)
|
|
492
|
-
return foldFile(at);
|
|
493
|
-
return foldAt(dirname(at), undefined, rest);
|
|
494
|
-
}
|
|
495
|
-
const under = places[0];
|
|
496
|
-
// A prospective lot is data, not the place whose authority admits it.
|
|
497
|
-
const tree = files.length ? root : resolve('.');
|
|
498
|
-
const place = under ? relative(tree, resolve(under)).split(sep).join('/') : '';
|
|
499
|
-
return foldAt(tree, place ? `${place}/` : undefined, rest);
|
|
500
|
-
}
|
|
501
|
-
async function foldAt(root, under, argv) {
|
|
502
|
-
return withContentStore(storeOf(root), () => foldRequested(root, under, argv), () => standingOf(root, under).standing);
|
|
503
|
-
}
|
|
504
|
-
async function foldRequested(root, under, argv) {
|
|
505
|
-
const as = valueOf(argv, FLAGS.as);
|
|
506
|
-
const prospective = as !== undefined && positionalsOf(argv).some(one => existsSync(resolve(one)) && !lstatSync(resolve(one)).isDirectory());
|
|
507
|
-
if (as === 'release' || as?.split('@')[0] === 'act' || as === NAMED_VIEWS.help || prospective || argv.includes(FLAGS.check))
|
|
508
|
-
return foldResolved(root, under, argv);
|
|
509
|
-
return resolveRequested(digest => resolveSources(standingOf(root, under).standing, [digest]), () => foldResolved(root, under, argv));
|
|
510
|
-
}
|
|
511
|
-
async function foldResolved(root, under, argv) {
|
|
512
|
-
const as = valueOf(argv, FLAGS.as);
|
|
513
|
-
if (as === 'release') {
|
|
514
|
-
const approvals = positionalsOf(argv).filter(one => !(existsSync(resolve(one)) && lstatSync(resolve(one)).isDirectory()));
|
|
515
|
-
if (approvals.length !== 1 || argv.includes(FLAGS.check))
|
|
516
|
-
throw Error('REFUSE·release name one approval file; check does not authorize delivery');
|
|
517
|
-
return withoutEffects(() => { printReleaseApproval(under ? resolve(root, under) : root, resolve(approvals[0])); return EXIT.closed; });
|
|
518
|
-
}
|
|
519
|
-
const inputs = positionalsOf(argv).filter(one => existsSync(resolve(one)) && !lstatSync(resolve(one)).isDirectory());
|
|
520
|
-
// Public content is authenticated by its digest, independently of owner history.
|
|
521
|
-
// A named view does not request mounting every release of the instrument.
|
|
522
|
-
const receiptCheck = as === undefined && argv.includes(FLAGS.check);
|
|
523
|
-
if (as?.split('@')[0] === 'walk') {
|
|
524
|
-
if (argv.includes(FLAGS.check))
|
|
525
|
-
throw Error('REFUSE·walk check does not initiate or sign an exchange');
|
|
526
|
-
if (under || inputs.length > 1)
|
|
527
|
-
throw Error('REFUSE·walk one place and one authenticated peer inventory per fold');
|
|
528
|
-
const depth = as.split('@')[1];
|
|
529
|
-
if (depth !== undefined && (!/^(0|[1-9][0-9]*)$/.test(depth) || !Number.isSafeInteger(Number(depth))))
|
|
530
|
-
throw Error('REFUSE·walk invalid resolution');
|
|
531
|
-
const peer = inputs.length ? claimLinesIn(inputs[0]) : [];
|
|
532
|
-
for (const line of await renderWalk(root, depth === undefined ? undefined : Number(depth), peer, valueOf(argv, FLAGS.key), valueOf(argv, FLAGS.keyFile), valueOf(argv, FLAGS.signer)))
|
|
533
|
-
process.stdout.write(line + '\n');
|
|
534
|
-
return EXIT.closed;
|
|
535
|
-
}
|
|
536
|
-
if (as === OBJECT_VIEW) {
|
|
537
|
-
const inputs = positionalsOf(argv).filter(one => existsSync(resolve(one)) && !lstatSync(resolve(one)).isDirectory());
|
|
538
|
-
if (inputs.length > 1)
|
|
539
|
-
throw Error('REFUSE·object one history snapshot per fold');
|
|
540
|
-
const history = inputs.length ? claimLinesIn(inputs[0]) : signedOwnerLines(storeOf(root));
|
|
541
|
-
const held = await admittedObjects(root, history, text => process.stdout.write(text + '\n'));
|
|
542
|
-
let cells;
|
|
543
|
-
if (usesWasmObject(held.configuration)) {
|
|
544
|
-
const cancellation = new AbortController(), interrupt = () => cancellation.abort();
|
|
545
|
-
process.once('SIGINT', interrupt);
|
|
546
|
-
try {
|
|
547
|
-
cells = await foldObjectsWithWasm(root, held.records, held.context, held.configuration, cancellation.signal);
|
|
548
|
-
}
|
|
549
|
-
finally {
|
|
550
|
-
process.removeListener('SIGINT', interrupt);
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
else
|
|
554
|
-
cells = objectFold(held.records, held.context);
|
|
555
|
-
for (const cell of cells)
|
|
556
|
-
process.stdout.write('CELL ' + JSON.stringify(cell) + '\n');
|
|
557
|
-
process.stdout.write(`FACT object fold ${cells.length} cells\n`);
|
|
558
|
-
return EXIT.closed;
|
|
559
|
-
}
|
|
560
|
-
const key = valueOf(argv, FLAGS.key);
|
|
561
|
-
if (as === undefined) {
|
|
562
|
-
const exit = await pass(root, entryOf(root), under, argv.includes(FLAGS.check));
|
|
563
|
-
if (receiptCheck)
|
|
564
|
-
return exit;
|
|
565
|
-
if (exit !== 0)
|
|
566
|
-
return exit;
|
|
567
|
-
const history = signedOwnerLines(storeOf(root));
|
|
568
|
-
const { objectHistory } = await import('@lapxo/topos/wire');
|
|
569
|
-
const parsed = objectHistory(history);
|
|
570
|
-
if (parsed.kind !== 'fact')
|
|
571
|
-
throw Error(`REFUSE·wire ${parsed.why}`);
|
|
572
|
-
if (parsed.value.objects.length) {
|
|
573
|
-
const signedCells = [...viewsOf(history).values()].find(one => !one.shape && one.regions.some(region => region.name === 'cells'));
|
|
574
|
-
if (!signedCells)
|
|
575
|
-
throw Error('REFUSE·view object cells require a signed cells view');
|
|
576
|
-
return view(root, under, signedCells.name, [], undefined, undefined, false);
|
|
577
|
-
}
|
|
578
|
-
return exit;
|
|
579
|
-
}
|
|
580
|
-
const named = inputs;
|
|
581
|
-
const coord = positionalsOf(argv).find((one) => one !== under?.replace(/\/$/, '') && !one.startsWith('-') && !(existsSync(resolve(one)) && lstatSync(resolve(one)).isDirectory()));
|
|
582
|
-
if (as === 'act') {
|
|
583
|
-
if (positionalsOf(argv).length !== 1)
|
|
584
|
-
throw Error('REFUSE·act name one committed identity');
|
|
585
|
-
return view(root, under, as, [], coord);
|
|
586
|
-
}
|
|
587
|
-
if ((as === 'why' || as === NAMED_VIEWS.because || as.split('@')[0] === 'why') && coord !== undefined)
|
|
588
|
-
return view(root, under, as === NAMED_VIEWS.because ? 'why' : as, [], coord, key);
|
|
589
|
-
if (!named.length)
|
|
590
|
-
return view(root, under, as, [], undefined, key);
|
|
591
|
-
const batch = await signedBatch(root, argv, named);
|
|
592
|
-
if (batch.kind === 'exit')
|
|
593
|
-
return batch.code;
|
|
594
|
-
if (batch.kind === 'once')
|
|
595
|
-
process.stdout.write(`ONCE ${batch.proposed.length} lines · every one already landed: the view folds the tree as it stands\n`);
|
|
596
|
-
return withoutEffects(() => view(root, under, as, batch.kind === 'signed' ? batch.signed : batch.proposed, undefined, key));
|
|
597
|
-
}
|
|
598
|
-
const VERBS = {
|
|
599
|
-
fold: (root, rest) => foldVerb(root, rest),
|
|
600
|
-
land: (root, rest) => landVerb(root, rest),
|
|
601
|
-
sign: (root, rest) => signVerb(root, rest),
|
|
602
|
-
};
|
|
603
|
-
function main(argv) {
|
|
604
|
-
for (let i = 0; i < argv.length; i += 1) {
|
|
605
|
-
const arg = argv[i];
|
|
606
|
-
if (!arg.startsWith('--'))
|
|
607
|
-
continue;
|
|
608
|
-
if (!Object.values(FLAGS).includes(arg)) {
|
|
609
|
-
process.stderr.write(`${selfName()}: REFUSE·flag unknown option ${arg}\n`);
|
|
610
|
-
return EXIT.usage;
|
|
611
|
-
}
|
|
612
|
-
if (arg !== FLAGS.check) {
|
|
613
|
-
if (argv[i + 1] === undefined || argv[i + 1].startsWith('--')) {
|
|
614
|
-
process.stderr.write(`${selfName()}: REFUSE·flag ${arg} needs a value\n`);
|
|
615
|
-
return EXIT.usage;
|
|
616
|
-
}
|
|
617
|
-
i += 1;
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
const verb = argv[0] ?? '';
|
|
621
|
-
const run = verb in VERBS ? VERBS[verb] : undefined;
|
|
622
|
-
const places = positionalsOf(run === undefined ? argv : argv.slice(1)).filter((one) => existsSync(resolve(one)) && lstatSync(resolve(one)).isDirectory());
|
|
623
|
-
if (run !== undefined) {
|
|
624
|
-
const rest = argv.slice(1);
|
|
625
|
-
const roots = positionalIndexes(rest).filter(index => {
|
|
626
|
-
const path = resolve(rest[index]);
|
|
627
|
-
return existsSync(path) && lstatSync(path).isDirectory();
|
|
628
|
-
});
|
|
629
|
-
if (roots.length > 1) {
|
|
630
|
-
process.stderr.write(`${selfName()}: REFUSE·root name one acting directory\n`);
|
|
631
|
-
return EXIT.usage;
|
|
632
|
-
}
|
|
633
|
-
const selected = roots[0];
|
|
634
|
-
const root = resolve(selected === undefined ? '.' : rest[selected]);
|
|
635
|
-
const normalized = selected === undefined ? rest : rest.filter((_, index) => index !== selected);
|
|
636
|
-
return withContentStore(storeOf(root), () => verb === 'fold' && selected !== undefined && !positionalsOf(normalized).some(one => /^#bound(?::|$)/.test(one))
|
|
637
|
-
? foldAt(root, undefined, normalized)
|
|
638
|
-
: run(root, normalized, [verb, ...normalized]), () => standingOf(root).standing);
|
|
639
|
-
}
|
|
640
|
-
const under = argv[0] ?? '';
|
|
641
|
-
if (under && !under.startsWith('-') && places.includes(under)) {
|
|
642
|
-
const root = resolve('.');
|
|
643
|
-
const place = relative(root, resolve(under)).split(sep).join('/');
|
|
644
|
-
return foldAt(root, place ? `${place}/` : undefined, argv);
|
|
645
|
-
}
|
|
646
|
-
process.stderr.write(`${selfName()}: ${helpLines().join(' · ')}\n`);
|
|
647
|
-
return EXIT.usage;
|
|
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
|
-
}
|
|
668
|
-
// The same refusal boundary covers synchronous operations and asynchronous processes.
|
|
669
|
-
const refused = (error) => {
|
|
670
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
671
|
-
process.stderr.write(`${selfName()}: ${message.startsWith('REFUSE·') ? message : `REFUSE·crash ${message}`}\n`);
|
|
672
|
-
printRefusal(error instanceof BoundRefusal ? error : new BoundRefusal('operation/failed', message));
|
|
673
|
-
process.exitCode = EXIT.refuse;
|
|
674
|
-
};
|
|
675
|
-
installActSignalHandler();
|
|
676
|
-
try {
|
|
677
|
-
const ran = main(process.argv.slice(2));
|
|
678
|
-
if (ran instanceof Promise)
|
|
679
|
-
ran.then(finished).catch(refused);
|
|
680
|
-
else
|
|
681
|
-
finished(ran);
|
|
682
|
-
}
|
|
683
|
-
catch (error) {
|
|
684
|
-
refused(error);
|
|
685
|
-
}
|
|
2
|
+
var et=Object.defineProperty;var w=(e,t)=>et(e,"name",{value:t,configurable:!0});import{prepareNativeReadingIdentity as tt,prepareNativeViewIdentity as nt,declaredReadingIdentityLimits as st}from"../host/reading-identity.js";import{nativeHostInstrument as Re}from"../host/native-receiver.js";import{ownRoot as le,processOf as fe}from"../observe/runner.js";import{BoundRefusal as A,describeRefusal as it,readRefusalCatalog as rt}from"../host/refusals.js";import{readFileSync as ve}from"node:fs";import{sha256 as K}from"../host/hash.js";import{printReleaseApproval as ot}from"./release-result.js";import{inspectReference as ct}from"../host/reference.js";import{exportAuthenticatedReference as at}from"../host/reference-export.js";import{authenticatedReferenceSelected as dt,openAuthenticatedReference as lt}from"../host/reference-native.js";import{printActResult as ft}from"./act-result.js";import{printStandingResult as pt}from"./standing-result.js";import{withContentStore as Fe}from"../host/content-store.js";import{readOnly as Oe,withoutEffects as Ue}from"../host/read-only.js";import{layReleases as ut}from"../host/release.js";import{resolveSources as mt,resolveRequested as ht}from"../host/source-content.js";import{cellsWithReceipts as gt}from"../host/cell-receipts.js";import{library9_renderCells as wt}from"../vendor/runtime.js";import{releasePolicyLines as yt}from"../fold/release-policy.js";import{admittedObjects as xe}from"../host/objects.js";import{objectFold as Ie,executeComputation as Et}from"../engine/index.js";import{readingEnvironment as $t}from"../host/reading-context.js";import{verifyBytes as St}from"../host/adapters/keys/ed25519.js";import{instrumentDigest as bt}from"../fold/digests.js";import{library11_authorityAtEpoch as kt}from"../vendor/runtime.js";import{toposAt as Rt,contentAt as vt}from"../host/selected-topos.js";import{foldObjectsWithWasm as Ft,usesWasmObject as Ne}from"../wasm/object.js";import{library11_OBJECT_VIEW as Ot}from"../vendor/runtime.js";import{library7_toposStanding as Ut}from"../vendor/runtime.js";import{library11_wireAt as xt,library11_parse as Te}from"../vendor/runtime.js";import{lockStanding as pe}from"../fold/keys.js";import{ownStore as It,ownLock as je}from"../observe/runner.js";import{signedOwnerLines as te}from"./owner.js";import{existsSync as J,lstatSync as G,mkdirSync as Ce,writeFileSync as De}from"node:fs";import{basename as Nt,dirname as ue,join as ne,relative as me,resolve as $,sep as he}from"node:path";import{eraOf as Tt,signaturesOf as ge}from"../fold/digests.js";import{fullDigest as Ae}from"../host/digest.js";import{library11_canonical as Q}from"../vendor/runtime.js";import{EXTENSION as jt,LOCK as Le,fieldOf as L,foldClaims as Ct,isWire as We,selfName as j}from"../fold/claims.js";import{observedClaims as Dt,readerRefusals as Pe}from"../fold/observed.js";import{rolesOf as At}from"../fold/roles.js";import{authorityFor as se,releaseSigner as Be,rootSigner as we,writerFor as ye}from"../fold/signers.js";import{land as Z,ledgerLines as ie,storeOf as m}from"../land/ledger.js";import{lockLines as Ee,releaseOf as Lt}from"../fold/keys.js";import{signConsentLot as Wt}from"../land/sign.js";import{signerFor as Pt,frameSignerFor as Bt}from"../host/signing.js";import{admittedIn as _t,ownLockOf as Jt,tellOwn as Mt}from"../fold/signed.js";import{hasVouchedTree as Gt,landCoordinates as Vt,coordinatesOf as qt,locationsOf as zt,vouching as Ht,sourced as Kt}from"../land/vouched.js";import{observeText as $e}from"../observe/files.js";import{askWhy as Xt,unrendered as Yt,viewOf as Qt}from"../render/view.js";import{openCards as Zt}from"../render/open.js";import{foldPlace as _e,ownCeilings as Je,standingOf as V}from"./place.js";import{foldPoints as en,movedPoints as tn}from"../fold/kept.js";import{placesOf as nn,sharedShapes as sn,viewsOf as re}from"../fold/views.js";import{placesIn as rn}from"../fold/places.js";import{isCeiling as Se}from"../fold/configures.js";import{readingsIn as Me}from"../land/inert.js";import{pass as on}from"./pass.js";import{installActSignalHandler as cn,underTheLock as an,underTheRegions as dn,underRootAuthority as ln}from"../land/act.js";import{ownerOf as fn,renderInto as pn,signedDemands as un,targetFile as oe}from"./owner.js";import{claimLinesIn as ee,entryOf as be,namedPlaces as ke,positionalIndexes as mn,positionalsOf as W,valueOf as U}from"./args.js";import{EXIT as d,FLAGS as u,NAMED_VIEWS as X,helpLines as Ge}from"./names.js";import{accept as hn,signedBatch as Ve}from"./accept.js";import{renderWalk as gn,landWalk as wn,foreignWalkLines as yn}from"../host/walk.js";import{library10_isWalkHeader as En}from"../vendor/runtime.js";import{ingressBundles as $n,ingressReceipts as Sn}from"../host/ports/ingress.js";async function bn(e,t){const o=Date.now(),n=m(e),i=ee(oe(e)),s=$e(oe(e));let c,y,r,f=0,l;try{if(!i.length)throw new Error("REFUSE\xB7bootstrap the proposed lock holds no claims");const h=Tt(i),S=i.find(p=>["wire/digest-algorithms","audit/wire/digest-algorithms"].includes(L(p,"scope"))&&L(p,"value")!=="withdraw"),F=L(S??"","value").split("|").filter(Boolean)[0]?.split(":")[0]??"";if(!F)throw new Error("REFUSE\xB7bootstrap the proposed lock names no digest algorithm");if(c=ye(i,"authorize")??"",!c)throw new Error("REFUSE\xB7bootstrap the proposed lock declares no root authorizer");if(y=U(t,u.key)??c,ie(n,c).length)throw new Error("REFUSE\xB7bootstrap the owner ledger already holds claims; the first land happens once");const D=w(p=>{const O=new Set(i.filter(C=>L(C,"scope")===`keys/${c}`&&L(C,"measure")===p&&L(C,"value")!=="withdraw").map(C=>L(C,"value")));if(O.size!==1)throw new Error(`REFUSE\xB7bootstrap root key ${c} must declare one ${p}`);return[...O][0]},"said");if(D("class")!=="authorize")throw new Error("REFUSE\xB7bootstrap the root key must authorize");const g=D("public-key"),b=D("coverage").split("|").filter(Boolean);if(!g||!b.length)throw new Error("REFUSE\xB7bootstrap the root key must declare its public key and coverage");const I=i.filter(p=>!L(p,"sig"));if(I.length){const p=Pt(i,y,U(t,u.signer),U(t,u.keyFile)),O=await Wt(I,{epoch:1,by:y,algorithm:h.era},g,h.admitted,p);if(O.kind==="refuse")throw new Error(O.why);let C=0;i.splice(0,i.length,...i.map(R=>L(R,"sig")?R:O.lines[C++]))}const B=se(i,{...Be(i),id:c,publicKey:g,coverage:b},h.admitted);for(const p of i){const O=B.of(p);if(O.kind!=="admitted")throw new Error(`REFUSE\xB7bootstrap ${L(p,"scope")} is not admitted: ${O.why??O.kind}`);f+=1}Ht(i),Kt(i),r=Ae(i.map(p=>p.replace(/ sig="[^"]*"/,"")).sort(),F),l={[c]:{id:c,publicKey:g,coverage:b}}}catch(h){return process.stderr.write(`${j()}: ${h instanceof Error?h.message:String(h)}
|
|
3
|
+
`),d.refuse}return an(n,"bootstrap",()=>{if(ie(n,c).length||$e(oe(e))!==s)return process.stderr.write(`${j()}: REFUSE\xB7bootstrap the proposed lock or owner ledger changed before commit
|
|
4
|
+
`),d.refuse;const h=Z(n,c,i);y!==c&&Z(n,y,i);const S=ne(n,`${j()}.keys`);Ce(ue(S),{recursive:!0}),De(S,`${JSON.stringify(l,null,2)}
|
|
5
|
+
`);const F=i.filter(b=>/\bsig=/.test(b)),D=F.length-f;Z(n,"land",[Q({scope:"bootstrap",role:"writes",form:"alphabet",measure:"status",value:"present",by:"land",at:`bootstrap:${r}`,about:"the lines this clone was born from: one land per clone, and a second is a fork of the same cell"})]);const g=pn(e,n);process.stdout.write(`FACT landed ${h.appended} unique lines from ${i.length} in TARGET \xB7 ${D} of ${F.length} signed lines fail admission by declared authority
|
|
6
|
+
TARGET ${g.standing} claims \xB7 ${g.superseded.length} superseded \xB7 ${Date.now()-o} ms
|
|
7
|
+
`);for(const b of g.superseded)process.stdout.write(`SUPERSEDED ${b}
|
|
8
|
+
`);if(!Gt(n)){const b=new Set,I=new Set;for(const C of un(n)){const R=zt(L(C,"needs"));for(const M of R.locations)b.add(M);for(const M of R.refused)I.add(M)}const B=new Map,p=At(n);for(const C of b)for(const[R,M]of qt(e,C,p))B.set(R,M);const O=Vt(n,B,[],"origin:land");process.stdout.write(`FACT vouched \xB7 ${O} sources under ${b.size} locations \xB7 ${I.size} needs refused as globs
|
|
9
|
+
`)}return d.closed})}w(bn,"firstLand");function ce(e,t,o){const n=ye(t.standing,"fold"),i=w(s=>`${(s/1e3).toFixed(s<100?2:1)} s`,"seconds");if(process.stderr.write(`BEAT fold ${t.key.slice(0,8)} ${t.kept?"kept":"folded"} ${i(o)}${t.beats.kept?` \xB7 ${i(t.beats.kept)} kept`:""}${t.beats.folded?` \xB7 ${i(t.beats.folded)} folded`:""}
|
|
10
|
+
`),n!==void 0){if(!t.kept){const s=tn(m(e),en(m(e),t.standing,t.under,n,t.instrument),t.key),c=s===void 0?"no fold was kept before this one":`${s.gone.length} points gone \xB7 ${s.came.length} came \xB7 ${[...s.gone,...s.came].slice(0,3).map(y=>y.split(" ")[0]).join(" ")||"none"}`;process.stderr.write(`KEPT fold ${t.key.slice(0,8)} miss \xB7 ${c}
|
|
11
|
+
`)}Z(m(e),n,[Q({scope:`beat/${t.under??"."}`,role:"writes",form:"interval",measure:"ms",value:`${o}..${o}`,by:n,at:`place:${t.kept?"kept":"folded"}`})])}}w(ce,"beat");async function Y(e,t,o,n=[],i,s,c=!0,y=!1){const[r=o,f,l,...h]=o.split("@");if(r===X.help)return process.stdout.write(`${Ge().join(`
|
|
12
|
+
`)}
|
|
13
|
+
`),d.closed;if(r==="reading-identity"&&f!==void 0){if(t||n.length||i||h.length||l==="")throw new A("reading-identity/selection","REFUSE\xB7native view identity requires one local place and a declared selector");const a=nt({place:e,instrument:Re(le(),fe("verb")),view:f,...l?{expectedIdentity:l}:{}});if(a.kind==="refuse")throw new A(a.code,a.diagnostic);return process.stdout.write(JSON.stringify(l===void 0?{kind:a.kind,view:a.view,identity:a.identity}:a)+`
|
|
14
|
+
`),d.closed}if(r==="reading-identity"){if(t||n.length||i||f!==void 0)throw new A("host/context","REFUSE\xB7reading identity requires one local admitted place");const a=st(pe(m(e))),E=await tt({place:e,instrument:Re(le(),fe("verb")),limits:a});if(E.kind==="refuse")throw new A(E.code,E.diagnostic);return process.stdout.write(JSON.stringify(E)+`
|
|
15
|
+
`),d.closed}if(!y&&!n.length&&!Oe()&&pe(m(e)).some(a=>/^reader\/.+\/port$/.test(L(a,"scope"))&&L(a,"role")==="writes"&&L(a,"value")!=="withdraw"))return ln(m(e),"view reader authority",()=>Y(e,t,o,n,i,s,c,!0));if(!Ee(m(e)).length)return process.stderr.write(`${j()}: the owner ledger is empty; land it before rendering a view
|
|
16
|
+
`),d.refuse;if(r==="act"){if(t||n.length)throw Error("REFUSE\xB7act committed identity query only");return ft(e,i),d.closed}if(r==="standing"){if(t||n.length||i||f!==void 0)throw new A("standing/query","REFUSE\xB7standing local committed projection only");return pt(e),d.closed}if(r==="evidence"&&!t&&!n.length&&$n(m(e)).length){const a=re(pe(m(e))).get(r);if(!a||a.shape||!a.regions.some(T=>T.name==="evidence"))throw Error("REFUSE\xB7view foreign evidence requires a declared evidence view");const E=await yn(e),N=se(Ee(m(e)),we(e),ge(m(e)).admitted),x=[...new Set(N.admitted.flatMap(T=>ie(m(e),T.id)))].filter(T=>N.of(T).kind==="admitted");for(const T of[...new Set([...x,...Sn(m(e)),...E])])process.stdout.write(T+`
|
|
17
|
+
`);return process.stdout.write(`FACT authenticated histories \xB7 readings \xB7 no encounters computed
|
|
18
|
+
`),d.closed}const S=Date.now(),F=t?.replace(/\/$/,""),D=Lt(m(e)),g=se([...D??Ee(m(e)),...n],D?Be(D):we(e),ge(m(e),n).admitted),b=n.filter(a=>g.of(a).kind==="admitted"),I=n.filter(a=>!b.includes(a));if(F&&I.length&&Mt(F,I),r===X.lines&&(n.length||f===void 0)){const a=V(e,t,b).standing.filter(We).join(`
|
|
19
|
+
`);return process.stdout.write(a?`${a}
|
|
20
|
+
`:""),d.closed}if(n.length){const a=re(V(e,t,b).standing).get(r);if(a&&!a.shape&&a.regions.some(E=>E.name==="cells")){const E=[...te(m(e)),...b],N=await xe(e,E);process.stdout.write(`TOLD ${n.length} lines folded as if landed \xB7 nothing written
|
|
21
|
+
`);for(const x of wt(Ie(N.records,N.context)))process.stdout.write(x+`
|
|
22
|
+
`);return d.closed}}const B=F?I.filter(a=>_t(e,F,a)):[];!n.length&&!Oe()&&ut(m(e),e,V(e,t).standing,m(e));const p=n.length?_e(e,be(e),t,!1,{standing:V(e,t,b),observed:Dt(e,m(e),{wait:!1}),free:!0}):_e(e,be(e),t,!0);if(!n.length&&Pe().length){for(const a of Pe())process.stderr.write(`${j()}: ${a}
|
|
23
|
+
`);return d.refuse}if(i&&Xt(p,i),r===X.lines){n.length||ce(e,p,Date.now()-S);const a=p.standing.filter(We).join(`
|
|
24
|
+
`);if(process.stdout.write(a?`${a}
|
|
25
|
+
`:""),f==="1")for(const E of Me([...p.standing.filter(Se),...Je(t)],p))process.stdout.write(`${E}
|
|
26
|
+
`);return d.closed}const O=re(p.standing),C=[...O.entries()].find(([,a])=>!a.shape&&a.regions.some(E=>E.name==="cells"));if(C&&r===C[0]){const a=te(m(e)),{objectHistory:E}=await import("../vendor/library11.js"),N=E(a);if(N.kind!=="fact")throw Error(`REFUSE\xB7wire ${N.why}`);if(N.value.objects.length){if(await gt(e,a,k=>process.stdout.write(k+`
|
|
27
|
+
`)),c)for(const k of yt(p.release))process.stdout.write(k+`
|
|
28
|
+
`);return n.length||ce(e,p,Date.now()-S),d.closed}n.length||ce(e,p,Date.now()-S);const x=p.open??[],T=s?x.filter(k=>k.origins.includes(s)):x,v=Zt(T);return s&&process.stdout.write(`KEY ${s}
|
|
29
|
+
`),v.length&&process.stdout.write(`${v.join(`
|
|
30
|
+
`)}
|
|
31
|
+
`),d.closed}if(n.length||ce(e,p,Date.now()-S),r==="rank"){const E=(F?[F]:rn(e)).flatMap(N=>sn(Jt(e,N)).map(x=>`${N} ${x}`));if(E.length)return process.stderr.write(`${j()}: REFUSE\xB7rank ${E.join(" \xB7 ")}: two views naming the same shape in one place
|
|
32
|
+
`),d.refuse}const R=O.get(r);if(!R)return process.stderr.write(`${j()}: no view/${r} is signed; the lock signs ${[...O.keys()].sort().map(a=>`view/${a}`).join(" \xB7 ")||"no view"}
|
|
33
|
+
`),d.usage;const M=Yt(p,R);if(M.length)return process.stderr.write(`${j()}: REFUSE\xB7view view/${r} asks regions nothing renders: ${M.join(" ")} \xB7 none is the instrument's own and no capsule ${t??"the root"} can run declares it
|
|
34
|
+
`),d.refuse;const q=nn(p.standing,R);if(q.length&&!q.includes(t??""))return process.stderr.write(`${j()}: view/${r} writes ${q.map(a=>`${a}${R.shape}`).join(" \xB7 ")}, and nothing of ${t??"this place"}
|
|
35
|
+
`),d.usage;const z=ye(p.standing,"fold");if(z!==void 0&&!n.length){const a=Date.now()-S;Z(m(e),z,[Q({scope:`beat/${t??"."}`,role:"writes",form:"interval",measure:"ms",value:`${a}..${a}`,by:z,at:`place:command-${p.kept?"kept":"folded"}`})])}return w(a=>{const E=Qt(a,Number.isFinite(Number(f))&&f!==void 0?{...R,regions:R.regions.map(x=>x.called?{...x,at:Number(f)}:x)}:R);if(process.argv.includes(u.check)){const x=ne(e,t??"",R.shape||""),T=R.shape?$e(x):void 0;if(T!==void 0&&T===E)return process.stdout.write(`SAME ${R.shape||`view/${r}`}
|
|
36
|
+
`),d.closed;const k=(T??"").split(`
|
|
37
|
+
`),P=E.split(`
|
|
38
|
+
`),H=k.findIndex((Qe,Ze)=>Qe!==P[Ze]),_=H<0?Math.min(k.length,P.length):H,Ye=(H<0?P[_]:k[_])??P[_]??"";return process.stdout.write(`DIFFERS ${R.shape||`view/${r}`}${T===void 0?" \xB7 this place holds no such region":` \xB7 line ${_+1} \xB7 ${Ye}`}
|
|
39
|
+
`),d.refuse}if(!R.shape||n.length){if(n.length&&process.stdout.write(`TOLD ${n.length} lines folded as if landed \xB7 ${b.length} in the ledger \xB7 ${B.length} in ${F??"the root"}'s own lock${I.length-B.length?` \xB7 ${I.length-B.length} admitted nowhere`:""} \xB7 the batch lands nothing and nothing is written
|
|
40
|
+
`),process.stdout.write(E),f==="1")for(const x of Me(n.length?n.filter(Se):[...a.standing.filter(Se),...Je(t)],a))process.stdout.write(`${x}
|
|
41
|
+
`);return d.closed}const N=ne(e,t??"",R.shape);return dn(m(e),[t??""],`view/${r}`,()=>(Ce(ue(N),{recursive:!0}),De(N,E),process.stdout.write(`RENDERED ${me(e,N).split(he).join("/")} \xB7 view/${r} \xB7 ${E.split(`
|
|
42
|
+
`).length-1} lines
|
|
43
|
+
`),d.closed))},"shown")(p)}w(Y,"view");async function kn(e,t){const o=U(t,u.as);if(o!==void 0){const i=W(t);if(o!=="reference"||i.length!==1||t.includes(u.check))throw new A("reference-export/usage","REFUSE\xB7reference-export usage: sign --as reference <source-url>");const s=await at(e,i[0],{key:U(t,u.key),keyFile:U(t,u.keyFile),signer:U(t,u.signer)});return process.stdout.write(JSON.stringify(s)+`
|
|
44
|
+
`),d.closed}const n=await Ve(e,t,W(t));if(n.kind==="exit")return n.code;if(n.kind==="once")return process.stderr.write(`ONCE ${n.proposed.length} lines \xB7 every one already landed: nothing to sign
|
|
45
|
+
`),d.closed;for(const i of ke(t))process.stdout.write(`# place ${i}
|
|
46
|
+
`);for(const i of n.signed)process.stdout.write(`${i}
|
|
47
|
+
`);return process.stderr.write(`SIGNED ${n.signed.length} lines \xB7 epoch ${n.epoch}${ke(t).length?` \xB7 own lines for ${ke(t).join(", ")}`:""} \xB7 they land together, before the lock moves
|
|
48
|
+
`),d.closed}w(kn,"signVerb");async function Rn(e,t){const o=$(oe(e)),n=W(t).filter(s=>{const c=$(s);return J(c)&&!G(c).isDirectory()&&c!==o});if(!n.length){const s=m(e);return J(ne(s,"ledger"))&&ie(s,fn(s)).length?(process.stderr.write(`${j()}: REFUSE\xB7bootstrap the owner ledger already holds claims; provide an explicit signed batch to change it
|
|
49
|
+
`),d.refuse):bn(e,t)}const i=w(s=>{process.stderr.write(`${j()}: ${s.startsWith("REFUSE\xB7")?s:`REFUSE\xB7crash ${s}`}
|
|
50
|
+
`),process.exitCode=d.refuse},"die");process.once("SIGINT",()=>i("SIGINT")),process.once("SIGHUP",()=>i("SIGHUP")),process.once("uncaughtException",s=>i(s instanceof Error?s.message:String(s))),process.once("unhandledRejection",s=>i(s instanceof Error?s.message:String(s)));try{const s=n.flatMap(ee);if(s.some(En)){for(const c of await wn(e,s,U(t,u.key),U(t,u.keyFile),U(t,u.signer)))process.stdout.write(c+`
|
|
51
|
+
`);return d.closed}return await hn(e,t)}catch(s){const c=s instanceof Error?s.message:String(s);return process.stderr.write(`${j()}: ${c.startsWith("REFUSE\xB7")?c:`REFUSE\xB7crash ${c}`}
|
|
52
|
+
`),d.refuse}}w(Rn,"landVerb");function vn(e){const t=ee(e),o=Ct(t),i=o.standing.flatMap(c=>{const y=Te(c);return y.kind==="fact"?[y.value.fields]:[]}).some(c=>c.scope?.startsWith("region/")&&c.measure==="reads");if(i&&o.forks.length)throw Error("REFUSE\xB7topos incompatible live claims in declared fold");const s=i?Ut(o.standing):void 0;if(s!==void 0){const y=xt(je().flatMap(r=>{const f=Te(r);return f.kind==="fact"?[f.value.fields]:[]}),Number.MAX_SAFE_INTEGER)?.digests.values().next().value;if(!y)throw Error("REFUSE\xB7topos instrument names no digest algorithm");process.stdout.write(s.split(`
|
|
53
|
+
`).filter(Boolean).map(r=>"TOPOS "+r).join(`
|
|
54
|
+
`)+`
|
|
55
|
+
`),process.stdout.write("PIN "+Ae([s],y)+`
|
|
56
|
+
`)}for(const c of o.standing)process.stdout.write(`${c}
|
|
57
|
+
`);for(const c of o.forks)process.stdout.write(`FORK ${c.key}${c.state?` \xB7 ${c.state}`:""}
|
|
58
|
+
`);return process.stdout.write(`FACT ${o.standing.length} standing \xB7 ${o.forks.length} forks \xB7 ${Nt(e)} \xB7 readings \xB7 no encounters computed
|
|
59
|
+
`),d.closed}w(vn,"foldFile");function Fn(e,t){const o=W(t).filter(r=>/^#bound(?::|$)/.test(r));if(o.length){if(o.length!==1||W(t).length!==1||t.some(r=>r.startsWith("--")))throw Error("REFUSE\xB7reference name one reference without view, check or signing options");return dt(V(e).standing)?lt(e,o[0]).then(r=>{process.stdout.write(`SOURCE ${r.reference.source}
|
|
60
|
+
`);for(const f of r.semanticStanding.split(`
|
|
61
|
+
`).filter(Boolean))process.stdout.write(`TOPOS ${f}
|
|
62
|
+
`);for(const f of r.readings)process.stdout.write("CELL "+JSON.stringify(f)+`
|
|
63
|
+
`);return process.stdout.write(`AUTHENTICATED standing ${r.semanticIdentity} \xB7 authority ${r.authorityContextIdentity} \xB7 no effects committed
|
|
64
|
+
`),d.closed}):ct(o[0],V(e).standing).then(r=>{process.stdout.write(`SOURCE ${r.reference.source}
|
|
65
|
+
`);for(const f of r.lines)process.stdout.write(`TOPOS ${f}
|
|
66
|
+
`);return process.stdout.write(`INSPECT standing sha256:${r.reference.digest} \xB7 blob ${r.reference.blob} \xB7 no encounters computed \xB7 unauthenticated
|
|
67
|
+
`),d.closed})}const n=W(t).filter(r=>J($(r))&&!G($(r)).isDirectory()&&r.endsWith(jt)),i=W(t).filter(r=>J($(r))&&G($(r)).isDirectory());if(n.length===1&&!i.length&&U(t,u.as)===void 0){const r=$(n[0]);return!r.endsWith(`/${Le}`)&&r!==Le?vn(r):ae(ue(r),void 0,t)}const s=i[0],c=n.length?e:$("."),y=s?me(c,$(s)).split(he).join("/"):"";return ae(c,y?`${y}/`:void 0,t)}w(Fn,"foldVerb");async function ae(e,t,o){return Fe(m(e),()=>On(e,t,o),()=>V(e,t).standing)}w(ae,"foldAt");async function On(e,t,o){const n=U(o,u.as),i=n!==void 0&&W(o).some(s=>J($(s))&&!G($(s)).isDirectory());if(n?.split("@")[0]==="reading-identity"&&(i||t||o.includes(u.check)))throw new A("reading-identity/selection","REFUSE\xB7reading-identity/selection preparation does not sign batches or check rendered output");return n?.split("@")[0]==="reading-identity"||n==="release"||n?.split("@")[0]==="act"||n===X.help||i||o.includes(u.check)?qe(e,t,o):ht(s=>mt(V(e,t).standing,[s]),()=>qe(e,t,o))}w(On,"foldRequested");async function qe(e,t,o){const n=U(o,u.as);if(n==="release"){const l=W(o).filter(h=>!(J($(h))&&G($(h)).isDirectory()));if(l.length!==1||o.includes(u.check))throw Error("REFUSE\xB7release name one approval file; check does not authorize delivery");return Ue(()=>(ot(t?$(e,t):e,$(l[0])),d.closed))}const i=W(o).filter(l=>J($(l))&&!G($(l)).isDirectory()),s=n===void 0&&o.includes(u.check);if(n?.split("@")[0]==="walk"){if(o.includes(u.check))throw Error("REFUSE\xB7walk check does not initiate or sign an exchange");if(t||i.length>1)throw Error("REFUSE\xB7walk one place and one authenticated peer inventory per fold");const l=n.split("@")[1];if(l!==void 0&&(!/^(0|[1-9][0-9]*)$/.test(l)||!Number.isSafeInteger(Number(l))))throw Error("REFUSE\xB7walk invalid resolution");const h=i.length?ee(i[0]):[];for(const S of await gn(e,l===void 0?void 0:Number(l),h,U(o,u.key),U(o,u.keyFile),U(o,u.signer)))process.stdout.write(S+`
|
|
68
|
+
`);return d.closed}if(n===Ot||n==="computation"){const l=W(o).filter(g=>J($(g))&&!G($(g)).isDirectory());if(l.length>1)throw Error("REFUSE\xB7object one history snapshot per fold");const h=l.length?ee(l[0]):te(m(e)),S=await xe(e,h,g=>(n==="computation"?process.stderr:process.stdout).write(g+`
|
|
69
|
+
`)),F=w(async()=>{if(Ne(S.configuration)){const g=new AbortController,b=w(()=>g.abort(),"interrupt");process.once("SIGINT",b);try{return await Ft(e,S.records,S.context,S.configuration,g.signal)}finally{process.removeListener("SIGINT",b)}}return Ie(S.records,S.context)},"project");if(n==="computation"){if(t||o.includes(u.check))throw new A("computation/context","REFUSE\xB7computation/context");const g=w(v=>{const k=S.configuration.filter(P=>P.scope===v&&P.value!=="withdraw");if(k.length!==1)throw new A("computation/context","REFUSE\xB7computation/context");return k[0].value},"one");if(g("view/computation")!=="computation@1")throw new A("computation/context","REFUSE\xB7computation/context");const b=w(v=>{const k=/^0\.\.([1-9][0-9]*)$/.exec(g(v)),P=Number(k?.[1]);if(!k||!Number.isSafeInteger(P))throw new A("computation/budget","REFUSE\xB7computation/budget");return P},"resource"),I=U(o,u.key),B=ge(m(e)),p=se(h,we(e),B.admitted),O=p.admitted.find(v=>v.id===I),C=Math.max(...h.map(v=>Number(L(v,"epoch")||0)));if(!I||!O||kt({scope:"computation",by:I},O,C,"computation","authority").kind!=="admitted")throw new A("computation/authority","REFUSE\xB7computation/authority");const R=new TextEncoder().encode(h.join(`
|
|
70
|
+
`)+`
|
|
71
|
+
`),M=K(S.configuration.map(v=>Q(v)).join(`
|
|
72
|
+
`)),q=new Map;for(const v of new Set(S.records.filter(k=>k.record==="cell").map(k=>k.fields.topos))){q.set("form/"+v,v);const k=Rt(v),P=k.parts.find(H=>H.scope==="wire/topos/context-view")?.value;for(const H of k.parts.filter(_=>_.kind==="check"&&_.view===P))for(const _ of(H.restsOn??"").split("|").filter(Boolean))vt(_),q.set("form-module/"+_,_)}const z=bt(It(),fe("verb"),je(),le()),de=Ne(S.configuration)?["manifest.json","runtime.js","runtime.wasm","guest.js"].map(v=>[v,K(ve(new URL("../../assets/wasm/"+v,import.meta.url)))]):[],a=de.length?K(JSON.stringify([z,de])):z,E=Bt(S.configuration.map(v=>Q(v)),I,U(o,u.signer),U(o,u.keyFile)),N={maxBytes:b("computation/bytes"),timeoutMs:b("computation/milliseconds")},x={contract:g("computation/contract"),numericPolicy:g("computation/numeric-policy"),reading:{instrument:z,implementation:a,policy:M,inputs:[...q],environment:$t(K)},keyId:I,algorithm:B.era},T=await Et(x,R,{digest:K,evaluate:w(async()=>new TextEncoder().encode(JSON.stringify(await F())+`
|
|
73
|
+
`),"evaluate"),sign:E,verify:w(async(v,k,P)=>k.keyId===I&&St(v,O.publicKey,k.signature,[P]),"verify")},N);return process.stdout.write(JSON.stringify({profile:"bound-computation-delivery@1",context:x,input:new TextDecoder().decode(R),statement:T.statement,output:new TextDecoder().decode(T.output)})+`
|
|
74
|
+
`),d.closed}const D=await F();for(const g of D)process.stdout.write("CELL "+JSON.stringify(g)+`
|
|
75
|
+
`);return process.stdout.write(`FACT object fold ${D.length} cells
|
|
76
|
+
`),d.closed}const c=U(o,u.key);if(n===void 0){const l=await on(e,be(e),t,o.includes(u.check));if(s||l!==0)return l;const h=te(m(e)),{objectHistory:S}=await import("../vendor/library11.js"),F=S(h);if(F.kind!=="fact")throw Error(`REFUSE\xB7wire ${F.why}`);if(F.value.objects.length){const D=[...re(h).values()].find(g=>!g.shape&&g.regions.some(b=>b.name==="cells"));if(!D)throw Error("REFUSE\xB7view object cells require a signed cells view");return Y(e,t,D.name,[],void 0,void 0,!1)}return l}const y=i,r=W(o).find(l=>l!==t?.replace(/\/$/,"")&&!l.startsWith("-")&&!(J($(l))&&G($(l)).isDirectory()));if(n==="act"){if(W(o).length!==1)throw Error("REFUSE\xB7act name one committed identity");return Y(e,t,n,[],r)}if((n==="why"||n===X.because||n.split("@")[0]==="why")&&r!==void 0)return Y(e,t,n===X.because?"why":n,[],r,c);if(!y.length)return Y(e,t,n,[],void 0,c);const f=await Ve(e,o,y);return f.kind==="exit"?f.code:(f.kind==="once"&&process.stdout.write(`ONCE ${f.proposed.length} lines \xB7 every one already landed: the view folds the tree as it stands
|
|
77
|
+
`),Ue(()=>Y(e,t,n,f.kind==="signed"?f.signed:f.proposed,void 0,c)))}w(qe,"foldResolved");const ze={fold:w((e,t)=>Fn(e,t),"fold"),land:w((e,t)=>Rn(e,t),"land"),sign:w((e,t)=>kn(e,t),"sign")};function Un(e){for(let s=0;s<e.length;s+=1){const c=e[s];if(c.startsWith("--")){if(!Object.values(u).includes(c))return process.stderr.write(`${j()}: REFUSE\xB7flag unknown option ${c}
|
|
78
|
+
`),d.usage;if(c!==u.check){if(e[s+1]===void 0||e[s+1].startsWith("--"))return process.stderr.write(`${j()}: REFUSE\xB7flag ${c} needs a value
|
|
79
|
+
`),d.usage;s+=1}}}const t=e[0]??"",o=t in ze?ze[t]:void 0,n=W(o===void 0?e:e.slice(1)).filter(s=>J($(s))&&G($(s)).isDirectory());if(o!==void 0){const s=e.slice(1),c=mn(s).filter(l=>{const h=$(s[l]);return J(h)&&G(h).isDirectory()});if(c.length>1)return process.stderr.write(`${j()}: REFUSE\xB7root name one acting directory
|
|
80
|
+
`),d.usage;const y=c[0],r=$(y===void 0?".":s[y]),f=y===void 0?s:s.filter((l,h)=>h!==y);return Fe(m(r),()=>t==="fold"&&y!==void 0&&!W(f).some(l=>/^#bound(?::|$)/.test(l))?ae(r,void 0,f):o(r,f,[t,...f]),()=>V(r).standing)}const i=e[0]??"";if(i&&!i.startsWith("-")&&n.includes(i)){const s=$("."),c=me(s,$(i)).split(he).join("/");return ae(s,c?`${c}/`:void 0,e)}return process.stderr.write(`${j()}: ${Ge().join(" \xB7 ")}
|
|
81
|
+
`),d.usage}w(Un,"main");function He(e){try{const t=ve(new URL("../../docs/contracts/refusals.bound",import.meta.url),"utf8"),o=it(e,rt(t));process.stderr.write(JSON.stringify({profile:"bound-refusal@1",...o,catalog:K(t)})+`
|
|
82
|
+
`)}catch{process.stderr.write(JSON.stringify({profile:"bound-refusal@1",code:"catalog/invalid",unmeasured:["category","meaning","next","catalog"]})+`
|
|
83
|
+
`)}}w(He,"printRefusal");function Ke(e){(e===d.refuse||e===d.usage)&&He(new A(e===d.usage?"operation/usage":"operation/failed","")),process.exitCode=e}w(Ke,"finished");const Xe=w(e=>{const t=e instanceof Error?e.message:String(e);process.stderr.write(`${j()}: ${t.startsWith("REFUSE\xB7")?t:`REFUSE\xB7crash ${t}`}
|
|
84
|
+
`),He(e instanceof A?e:new A("operation/failed",t)),process.exitCode=d.refuse},"refused");cn();try{const e=Un(process.argv.slice(2));e instanceof Promise?e.then(Ke).catch(Xe):Ke(e)}catch(e){Xe(e)}
|