@lapxo/bound 0.1.7 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -20
- package/TARGET.bound +27 -27
- package/dist/cli/accept.js +83 -59
- package/dist/cli/act-result.d.ts +9 -0
- package/dist/cli/act-result.js +68 -13
- package/dist/cli/args.d.ts +1 -0
- package/dist/cli/args.js +5 -2
- package/dist/cli/custodian.d.ts +1 -0
- package/dist/cli/custodian.js +29 -0
- package/dist/cli/native-descendant.d.ts +1 -0
- package/dist/cli/native-descendant.js +19 -0
- package/dist/cli/native.d.ts +1 -0
- package/dist/cli/native.js +60 -0
- package/dist/cli/observe.js +9 -2
- package/dist/cli/pass.js +6 -1
- package/dist/cli/standing-result.js +7 -26
- package/dist/cli/takes.js +5 -2
- package/dist/cli/verb.js +24 -5
- package/dist/fold/admission-history.js +2 -2
- package/dist/fold/claims.d.ts +4 -0
- package/dist/fold/claims.js +23 -3
- package/dist/fold/closed.d.ts +1 -1
- package/dist/fold/closed.js +16 -4
- package/dist/fold/digests.d.ts +1 -1
- package/dist/fold/digests.js +3 -2
- package/dist/fold/evidence.d.ts +1 -1
- package/dist/fold/kept.js +2 -1
- package/dist/fold/observed.d.ts +1 -0
- package/dist/fold/observed.js +54 -9
- package/dist/fold/readers.d.ts +4 -3
- package/dist/fold/readers.js +18 -13
- package/dist/fold/resolved.js +11 -1
- package/dist/fold/signers.js +2 -2
- package/dist/host/adapters/modules/javascript.d.ts +2 -0
- package/dist/host/adapters/modules/javascript.js +8 -6
- package/dist/host/admitted-place.d.ts +5 -0
- package/dist/host/admitted-place.js +54 -0
- package/dist/host/capsule-process.d.ts +1 -1
- package/dist/host/capsule-process.js +4 -1
- package/dist/host/capsule.d.ts +4 -0
- package/dist/host/capsule.js +16 -2
- package/dist/host/contextual-place.d.ts +59 -0
- package/dist/host/contextual-place.js +77 -0
- package/dist/host/hash.d.ts +7 -0
- package/dist/host/hash.js +6 -0
- package/dist/host/io.d.ts +2 -0
- package/dist/host/io.js +2 -0
- package/dist/host/lifetime.js +61 -22
- package/dist/host/native/bounded-file.d.ts +8 -0
- package/dist/host/native/bounded-file.js +32 -0
- package/dist/host/native/command.d.ts +36 -0
- package/dist/host/native/command.js +91 -0
- package/dist/host/native/control-bridge-worker.d.ts +1 -0
- package/dist/host/native/control-bridge-worker.js +88 -0
- package/dist/host/native/control-bridge.d.ts +30 -0
- package/dist/host/native/control-bridge.js +110 -0
- package/dist/host/native/control-selection.d.ts +29 -0
- package/dist/host/native/control-selection.js +32 -0
- package/dist/host/native/custody.d.ts +5 -0
- package/dist/host/native/custody.js +91 -0
- package/dist/host/native/deadline.d.ts +12 -0
- package/dist/host/native/deadline.js +28 -0
- package/dist/host/native/descendants.d.ts +1 -0
- package/dist/host/native/descendants.js +528 -0
- package/dist/host/native/generated-custodian.d.ts +122 -0
- package/dist/host/native/generated-custodian.js +267 -0
- package/dist/host/native/generated.d.ts +217 -0
- package/dist/host/native/generated.js +379 -0
- package/dist/host/native/image.d.ts +36 -0
- package/dist/host/native/image.js +45 -0
- package/dist/host/native/jobs.d.ts +75 -0
- package/dist/host/native/jobs.js +148 -0
- package/dist/host/native/loader.d.ts +80 -0
- package/dist/host/native/loader.js +269 -0
- package/dist/host/native/materialize.d.ts +22 -0
- package/dist/host/native/materialize.js +175 -0
- package/dist/host/native/module-closure.d.ts +27 -0
- package/dist/host/native/module-closure.js +99 -0
- package/dist/host/native/module-syntax.d.ts +8 -0
- package/dist/host/native/module-syntax.js +63 -0
- package/dist/host/native/native-binary.d.ts +54 -0
- package/dist/host/native/native-binary.js +115 -0
- package/dist/host/native/native-program.d.ts +56 -0
- package/dist/host/native/native-program.js +72 -0
- package/dist/host/native/node-jobs.d.ts +84 -0
- package/dist/host/native/node-jobs.js +187 -0
- package/dist/host/native/node-launch.d.ts +72 -0
- package/dist/host/native/node-launch.js +159 -0
- package/dist/host/native/preload.d.ts +1 -0
- package/dist/host/native/preload.js +45 -0
- package/dist/host/native/reading.d.ts +91 -0
- package/dist/host/native/reading.js +249 -0
- package/dist/host/native/receipt-environment.d.ts +3 -0
- package/dist/host/native/receipt-environment.js +41 -0
- package/dist/host/native/references.d.ts +5 -0
- package/dist/host/native/references.js +30 -0
- package/dist/host/native/root.d.ts +17 -0
- package/dist/host/native/root.js +37 -0
- package/dist/host/native/route.d.ts +66 -0
- package/dist/host/native/route.js +216 -0
- package/dist/host/native/runtime.d.ts +4 -0
- package/dist/host/native/runtime.js +9 -0
- package/dist/host/native-reader-context.d.ts +3 -0
- package/dist/host/native-reader-context.js +8 -0
- package/dist/host/place-clock-selection.d.ts +55 -0
- package/dist/host/place-clock-selection.js +124 -0
- package/dist/host/ports/local-act.d.ts +10 -0
- package/dist/host/ports/local-act.js +78 -6
- package/dist/host/ports/place-act.d.ts +46 -0
- package/dist/host/ports/place-act.js +169 -0
- package/dist/host/process-lifetime.js +8 -3
- package/dist/host/provide.d.ts +25 -0
- package/dist/host/provide.js +115 -13
- package/dist/host/reading-closures.d.ts +15 -1
- package/dist/host/reading-closures.js +88 -6
- package/dist/host/reading-context.d.ts +29 -0
- package/dist/host/reading-context.js +53 -0
- package/dist/host/root-clock-source.d.ts +85 -0
- package/dist/host/root-clock-source.js +305 -0
- package/dist/host/selected-capsules.js +3 -2
- package/dist/judge/take.d.ts +2 -0
- package/dist/judge/take.js +1 -1
- package/dist/land/act.d.ts +26 -0
- package/dist/land/act.js +96 -3
- package/dist/land/ledger.d.ts +4 -0
- package/dist/land/ledger.js +20 -2
- package/dist/observe/runner.d.ts +4 -0
- package/dist/observe/runner.js +9 -2
- package/docs/contracts/cli.md +13 -0
- package/package.json +2 -2
- package/receipts.bound +607 -567
package/dist/land/act.js
CHANGED
|
@@ -59,7 +59,7 @@ const lockFiles = (locks) => coordinatesUnder(locks, locks).filter((file) => {
|
|
|
59
59
|
});
|
|
60
60
|
const overlaps = (a, b) => !a || !b || a === b || a.startsWith(`${b}/`) || b.startsWith(`${a}/`);
|
|
61
61
|
const treeAt = (store) => join(store, 'lock');
|
|
62
|
-
const named = (at) => (basename(at) === 'lock' ? 'the store' : `region ${basename(at) === ROOT ? '.' : basename(at)}`);
|
|
62
|
+
const named = (at) => (basename(at) === 'lock' ? 'the store' : basename(at).startsWith('@authority-') ? 'root authority' : basename(at) === '@projection' ? 'root projection' : `region ${basename(at) === ROOT ? '.' : basename(at)}`);
|
|
63
63
|
const owns = (at) => {
|
|
64
64
|
for (let frame = context.getStore(); frame !== undefined; frame = frame.parent) {
|
|
65
65
|
const token = frame.locks.get(at);
|
|
@@ -69,6 +69,8 @@ const owns = (at) => {
|
|
|
69
69
|
return false;
|
|
70
70
|
};
|
|
71
71
|
const ownsRegion = (store) => [...held.keys()].some((at) => at.startsWith(`${join(store, 'locks')}/`) && owns(at));
|
|
72
|
+
const ownsAuthority = (store) => [...held.keys()].some((at) => dirname(at) === join(store, 'locks') && basename(at).startsWith('@authority-') && owns(at));
|
|
73
|
+
const projectionAt = (store) => join(store, 'locks', '@projection');
|
|
72
74
|
/** Reentry belongs to an awaited act's context. Another process or async act has no inherited authority. */
|
|
73
75
|
async function hold(at, what) {
|
|
74
76
|
if (owns(at))
|
|
@@ -142,10 +144,12 @@ async function framed(takes, act) {
|
|
|
142
144
|
}
|
|
143
145
|
});
|
|
144
146
|
}
|
|
145
|
-
|
|
147
|
+
function guardedRegions(store, regions, what, act, rootAuthority) {
|
|
146
148
|
return framed(async () => {
|
|
147
149
|
const tree = treeAt(store);
|
|
148
150
|
const asked = [...new Set((regions.length ? regions : ['']).map((one) => one.replace(/\/+$/, '')))];
|
|
151
|
+
if (rootAuthority && (asked.includes('') || (ownsRegion(store) && !owns(tree) && !ownsAuthority(store))))
|
|
152
|
+
throw new Error(`${selfName()}: REFUSE·lock authority dependencies and child regions must be declared together`);
|
|
149
153
|
if (owns(tree) || asked.every((region) => owns(regionAt(store, region)))) {
|
|
150
154
|
for (const region of asked)
|
|
151
155
|
await hold(regionAt(store, region), what);
|
|
@@ -159,18 +163,32 @@ export function underTheRegions(store, regions, what, act) {
|
|
|
159
163
|
try {
|
|
160
164
|
const locks = join(store, 'locks');
|
|
161
165
|
for (;;) {
|
|
162
|
-
const conflict = lockFiles(locks).find((file) =>
|
|
166
|
+
const conflict = lockFiles(locks).find((file) => !owns(join(locks, file))
|
|
167
|
+
&& (file.startsWith('@authority-') || file === '@projection' ? asked.includes('')
|
|
168
|
+
: asked.some((region) => overlaps(region, file) || overlaps(region, coordinateOf(file)))));
|
|
163
169
|
if (conflict === undefined)
|
|
164
170
|
break;
|
|
165
171
|
const at = join(locks, conflict);
|
|
166
172
|
const began = Date.now();
|
|
173
|
+
let told = false;
|
|
167
174
|
for (let holder = holderOf(at); holder !== undefined; holder = holderOf(at)) {
|
|
168
175
|
if (!alive(holder.pid))
|
|
169
176
|
throw new Error(`${selfName()}: REFUSE·stale ${named(at)} belongs to exited process ${holder.pid}; host recovery required`);
|
|
170
177
|
overAMinute(at, began, holder);
|
|
178
|
+
if (!told) {
|
|
179
|
+
process.stderr.write(`WAIT ${named(at)} is held by ${holder.pid} · ${holder.what} since ${holder.since}\n`);
|
|
180
|
+
told = true;
|
|
181
|
+
}
|
|
171
182
|
await pauseFor(250);
|
|
172
183
|
}
|
|
184
|
+
if (told)
|
|
185
|
+
process.stderr.write(`HELD ${named(at)} after ${Date.now() - began} ms waiting\n`);
|
|
173
186
|
}
|
|
187
|
+
// Registered under the same acquisition gate as every legacy writer.
|
|
188
|
+
// Root writes overlap all locks; siblings keep distinct region locks.
|
|
189
|
+
// '@' is encoded for real region coordinates, so this is host bookkeeping.
|
|
190
|
+
if (rootAuthority)
|
|
191
|
+
await hold(join(store, 'locks', `@authority-${randomUUID()}`), what);
|
|
174
192
|
for (const region of asked.filter(Boolean).sort())
|
|
175
193
|
await hold(regionAt(store, region), what);
|
|
176
194
|
if (asked.includes(''))
|
|
@@ -188,6 +206,81 @@ export function underTheRegions(store, regions, what, act) {
|
|
|
188
206
|
}
|
|
189
207
|
}, act);
|
|
190
208
|
}
|
|
209
|
+
export function underTheRegions(store, regions, what, act) {
|
|
210
|
+
return guardedRegions(store, regions, what, act, false);
|
|
211
|
+
}
|
|
212
|
+
/** Protect the root authority/policy read through child publication. This is
|
|
213
|
+
* exclusion only: callers must authenticate contexts and compare prepared heads
|
|
214
|
+
* while held. It creates no grant, clock advance, lease or automatic recovery. */
|
|
215
|
+
export function underAuthorityRegions(store, regions, what, act) {
|
|
216
|
+
return guardedRegions(store, regions, what, act, true);
|
|
217
|
+
}
|
|
218
|
+
/** Protect an authority snapshot without taking a child region. The acquisition
|
|
219
|
+
* gate and temporary root marker exclude a root mutation while registering the
|
|
220
|
+
* shared read; existing child acts continue independently. This is exclusion,
|
|
221
|
+
* never authorization or a clock advance. */
|
|
222
|
+
export function underRootAuthority(store, what, act) {
|
|
223
|
+
return framed(async () => {
|
|
224
|
+
const tree = treeAt(store), root = regionAt(store, '');
|
|
225
|
+
if (owns(tree) || owns(root) || ownsAuthority(store))
|
|
226
|
+
return;
|
|
227
|
+
if (ownsRegion(store))
|
|
228
|
+
throw new Error(`${selfName()}: REFUSE·lock authority dependencies must be declared before entering a region act`);
|
|
229
|
+
await hold(tree, what);
|
|
230
|
+
try {
|
|
231
|
+
await hold(root, what);
|
|
232
|
+
await hold(join(store, 'locks', `@authority-${randomUUID()}`), what);
|
|
233
|
+
}
|
|
234
|
+
finally {
|
|
235
|
+
const frame = context.getStore();
|
|
236
|
+
for (const at of [root, tree]) {
|
|
237
|
+
const token = frame.locks.get(at);
|
|
238
|
+
if (token !== undefined) {
|
|
239
|
+
release(at, token);
|
|
240
|
+
frame.locks.delete(at);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}, act);
|
|
245
|
+
}
|
|
246
|
+
/** The fixed host may hand its child evidence of an actual held exclusion.
|
|
247
|
+
* It is an operational envelope, not a grant, signer or receipt identity. */
|
|
248
|
+
export function rootAuthorityProtection(store) {
|
|
249
|
+
const locks = [treeAt(store), regionAt(store, ''), ...held.keys()].filter(at => at === treeAt(store) || at === regionAt(store, '') || dirname(at) === join(store, 'locks') && basename(at).startsWith('@authority-'));
|
|
250
|
+
const lock = locks.find(owns);
|
|
251
|
+
if (lock === undefined)
|
|
252
|
+
throw Error(`${selfName()}: REFUSE·lock root authority is not protected`);
|
|
253
|
+
const holder = holderOf(lock);
|
|
254
|
+
if (holder?.pid !== process.pid || holder.token !== held.get(lock))
|
|
255
|
+
throw Error(`${selfName()}: REFUSE·lock authority protection changed`);
|
|
256
|
+
return Object.freeze({ store, lock, pid: holder.pid, token: holder.token });
|
|
257
|
+
}
|
|
258
|
+
/** expectedStore and expectedParent come from the fixed host's inheritance
|
|
259
|
+
* channel, never from world data. Matching a live lock proves exclusion only;
|
|
260
|
+
* signature, coverage and current context still require verification. */
|
|
261
|
+
export function assertRootAuthorityProtection(proof, expectedStore, expectedParent) {
|
|
262
|
+
if (!proof || proof.store !== expectedStore || !Number.isSafeInteger(expectedParent) || expectedParent <= 0 || proof.pid !== expectedParent
|
|
263
|
+
|| typeof proof.lock !== 'string' || typeof proof.token !== 'string' || !proof.token
|
|
264
|
+
|| !(proof.lock === treeAt(expectedStore) || proof.lock === regionAt(expectedStore, '')
|
|
265
|
+
|| dirname(proof.lock) === join(expectedStore, 'locks') && basename(proof.lock).startsWith('@authority-'))) {
|
|
266
|
+
throw Error(`${selfName()}: REFUSE·lock invalid inherited authority protection`);
|
|
267
|
+
}
|
|
268
|
+
const holder = holderOf(proof.lock);
|
|
269
|
+
if (!alive(expectedParent) || holder?.pid !== proof.pid || holder.token !== proof.token)
|
|
270
|
+
throw Error(`${selfName()}: REFUSE·lock inherited authority protection ended`);
|
|
271
|
+
}
|
|
272
|
+
/** A child can publish independently, but the joined root projection and its
|
|
273
|
+
* derived ledger appends have one writer. Authority protection already excludes
|
|
274
|
+
* root mutations, so this lock needs no acquisition-gate upgrade. */
|
|
275
|
+
export function underRootProjection(store, what, act) {
|
|
276
|
+
return framed(async () => {
|
|
277
|
+
if (owns(treeAt(store)) || owns(regionAt(store, '')))
|
|
278
|
+
return;
|
|
279
|
+
if (!ownsAuthority(store))
|
|
280
|
+
throw new Error(`${selfName()}: REFUSE·lock root projection requires authority protection`);
|
|
281
|
+
await hold(projectionAt(store), what);
|
|
282
|
+
}, act);
|
|
283
|
+
}
|
|
191
284
|
export const holdRoot = async (store, what) => {
|
|
192
285
|
if (!owns(treeAt(store)))
|
|
193
286
|
await hold(regionAt(store, ''), what);
|
package/dist/land/ledger.d.ts
CHANGED
|
@@ -11,6 +11,10 @@ export declare function ledgerLines(store: string, writer: string): readonly str
|
|
|
11
11
|
export declare function shardFile(store: string, writer: string, region: string): string;
|
|
12
12
|
export declare const shardLines: (store: string, writer: string, region: string) => readonly string[];
|
|
13
13
|
export declare function ledgerWriters(store: string): readonly string[];
|
|
14
|
+
/** One synchronous root-history read, not a retained authority snapshot.
|
|
15
|
+
* Preserve writer order and each writer's legacy-before-committed ordering.
|
|
16
|
+
* Every call rereads the complete committed inventory exactly once. */
|
|
17
|
+
export declare function rootLedgerLines(store: string): readonly string[];
|
|
14
18
|
export declare function landShard(store: string, writer: string, region: string, lines: readonly string[]): number;
|
|
15
19
|
export declare function signedLines(store: string, writer: string): string[];
|
|
16
20
|
export declare function blobAt(store: string, digest: string): string;
|
package/dist/land/ledger.js
CHANGED
|
@@ -40,12 +40,30 @@ function journalLines(store, writer, place, legacy) {
|
|
|
40
40
|
journalMemo.set(key, lines);
|
|
41
41
|
return lines;
|
|
42
42
|
}
|
|
43
|
-
|
|
43
|
+
function legacyWriters(store) {
|
|
44
44
|
const at = join(store, 'ledger');
|
|
45
|
-
|
|
45
|
+
return existsSync(at) ? readdirSync(at).filter(name => name.endsWith(EXTENSION)).map(name => name.slice(0, -EXTENSION.length)) : [];
|
|
46
|
+
}
|
|
47
|
+
export function ledgerWriters(store) {
|
|
48
|
+
const legacy = legacyWriters(store);
|
|
46
49
|
const committed = committedLocalActs(store).flatMap(act => act.bundle.placements?.filter(p => p.place === '.').flatMap(p => actLines(p.records).map(line => fieldOf(line, 'by'))) ?? []);
|
|
47
50
|
return [...new Set([...legacy, ...committed])];
|
|
48
51
|
}
|
|
52
|
+
/** One synchronous root-history read, not a retained authority snapshot.
|
|
53
|
+
* Preserve writer order and each writer's legacy-before-committed ordering.
|
|
54
|
+
* Every call rereads the complete committed inventory exactly once. */
|
|
55
|
+
export function rootLedgerLines(store) {
|
|
56
|
+
const legacy = legacyWriters(store), acts = committedLocalActs(store);
|
|
57
|
+
const fresh = acts.flatMap(act => act.bundle.placements?.filter(p => p.place === '.').flatMap(p => actLines(p.records)) ?? []);
|
|
58
|
+
const writers = [...new Set([...legacy, ...fresh.map(line => fieldOf(line, 'by'))])];
|
|
59
|
+
return writers.flatMap(writer => {
|
|
60
|
+
// Authority-history identity needs actual bytes. A writer's size and mtime
|
|
61
|
+
// cannot distinguish a same-size edit or stand in for an admission proof.
|
|
62
|
+
const at = writerFile(store, writer), prior = existsSync(at) ? readFileSync(at, 'utf8').split('\n').filter(line => line.startsWith(PROTOCOL)) : [];
|
|
63
|
+
const committed = fresh.filter(line => fieldOf(line, 'by') === writer);
|
|
64
|
+
return committed.length ? [...new Set([...prior, ...committed])] : prior;
|
|
65
|
+
});
|
|
66
|
+
}
|
|
49
67
|
export function landShard(store, writer, region, lines) {
|
|
50
68
|
return appendNew(shardFile(store, writer, region), lines);
|
|
51
69
|
}
|
package/dist/observe/runner.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export declare const ownRoot: () => string;
|
|
2
|
+
/** A published instrument carries its own content store even before any ledger
|
|
3
|
+
* exists. Public-lock recognition grants no authority; legacy signed delivery
|
|
4
|
+
* trees retain their historical colocated-ledger or sibling-store layout. */
|
|
5
|
+
export declare function instrumentStoreAt(root: string): string;
|
|
2
6
|
export declare const ownStore: () => string;
|
|
3
7
|
export declare const ownLock: () => readonly string[];
|
|
4
8
|
export declare const sourceOf: () => string;
|
package/dist/observe/runner.js
CHANGED
|
@@ -21,8 +21,15 @@ const moduleAt = fromBlob() ? undefined : fileURLToPath(import.meta.url);
|
|
|
21
21
|
const runtimeAt = moduleAt === undefined ? '' : resolve(dirname(moduleAt), '..');
|
|
22
22
|
const runtimeExtension = moduleAt === undefined ? '' : extname(moduleAt);
|
|
23
23
|
export const ownRoot = () => (fromBlob() ? join(resolve(dirname(self()), '..', '..', '..'), 'bound') : resolve(runtimeAt, '..'));
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
/** A published instrument carries its own content store even before any ledger
|
|
25
|
+
* exists. Public-lock recognition grants no authority; legacy signed delivery
|
|
26
|
+
* trees retain their historical colocated-ledger or sibling-store layout. */
|
|
27
|
+
export function instrumentStoreAt(root) {
|
|
28
|
+
const lines = (observeText(join(root, LOCK)) ?? '').split('\n').filter(isWire);
|
|
29
|
+
const published = lines.length > 0 && publicLock(lines) !== undefined;
|
|
30
|
+
return published || existsSync(join(root, EXTENSION, 'ledger')) ? join(root, EXTENSION) : join(root, '..', EXTENSION);
|
|
31
|
+
}
|
|
32
|
+
export const ownStore = () => instrumentStoreAt(ownRoot());
|
|
26
33
|
/** The colocated public artifact is read without an unrelated parent's authority store. */
|
|
27
34
|
// An act is judged by the instrument it started with, even when that act changes its colocated lock.
|
|
28
35
|
let instrumentLock;
|
package/docs/contracts/cli.md
CHANGED
|
@@ -25,3 +25,16 @@ The query verifies the record signatures and coverage against the authority snap
|
|
|
25
25
|
## Standing admission
|
|
26
26
|
|
|
27
27
|
A uses/ selection admits canonical standing bytes, never an archive. The bytes must already be held under their verified digest or in the single local coordinate explicitly named by needs. Admission checks identity and canonical form without fetching, executing or writing the content store. Missing or corrupt bytes refuse the whole lot. A corrupt held copy cannot be hidden by another source. Archives remain separate dependency declarations.
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
## Declared reading identity
|
|
31
|
+
|
|
32
|
+
A place selects both `wire/reading-context value=reading-context@1` and `wire/reading-receipt value=reading-receipt@1`. Partial or conflicting selections refuse. Every reader under this profile declares an input projection; a legacy reader is refused by name instead of receiving a new identity without its closure.
|
|
33
|
+
|
|
34
|
+
The host commits the full instrument reference, the verified capsule implementation, effective reader policy, declared transitive references, each input's actual bytes and dependent receipt identities. The process environment is captured explicitly: inherited variable values (hashed, never printed), the place working directory, child flags, runtime bytes and platform conditions. The same captured boundary is handed to execution and keys the capsule cache. These references grant neither authority nor independence and cannot prove undeclared inputs absent.
|
|
35
|
+
|
|
36
|
+
An unchanged cross-process fold reads retained receipts with zero opened readings. Changed input reopens that reading and its dependents; changing shared implementation, policy or execution conditions invalidates the readings that depend on them. The semantic receipt names the reading and result together; elapsed time and signature envelopes remain separate. Old receipts are not promoted.
|
|
37
|
+
|
|
38
|
+
Retained evidence may be inspected without asserting a current response. Reusing a current response also requires the existing snapshot-access contract: matching principal, authorization, request, implementation and snapshot, declared freshness, and both inspection and reuse permission. Unknown or expired freshness, withdrawn permission or changed context refuse before running a provider. A new observation needs its own admitted act.
|
|
39
|
+
|
|
40
|
+
`fold --check` verifies the retained published evidence and instrument. It opens no reader and grants no permission to assert an old response today. A live fold additionally compares the current captured execution boundary.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lapxo/bound",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Read the bounds you already wrote, fold them, and name the contradictions.",
|
|
6
6
|
"main": "dist/cli/verb.js",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"license": "MIT",
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@lapxo/obligations": "0.3.5",
|
|
36
|
-
"@lapxo/topos": "0.1.
|
|
36
|
+
"@lapxo/topos": "^0.1.17",
|
|
37
37
|
"acorn": "8.19.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|