@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.
Files changed (250) hide show
  1. package/CITATION.cff +1 -1
  2. package/TARGET.bound +44 -39
  3. package/dist/cli/accept.js +72 -590
  4. package/dist/cli/act-result.js +3 -103
  5. package/dist/cli/args.js +3 -44
  6. package/dist/cli/custodian.js +2 -29
  7. package/dist/cli/host.js +4 -32
  8. package/dist/cli/names.js +1 -12
  9. package/dist/cli/native-descendant.js +1 -19
  10. package/dist/cli/native.js +3 -60
  11. package/dist/cli/observe.js +1 -13
  12. package/dist/cli/owner.js +3 -139
  13. package/dist/cli/pass.js +21 -321
  14. package/dist/cli/place.js +6 -282
  15. package/dist/cli/release-result.js +3 -80
  16. package/dist/cli/retained-judgment.js +1 -25
  17. package/dist/cli/standing-result.js +4 -19
  18. package/dist/cli/takes.js +10 -112
  19. package/dist/cli/verb.d.ts +1 -2
  20. package/dist/cli/verb.js +83 -684
  21. package/dist/engine/computation.js +2 -0
  22. package/dist/engine/conformance.js +4 -0
  23. package/dist/engine/encoding.js +1 -2
  24. package/dist/engine/index.d.ts +1 -13
  25. package/dist/engine/index.js +2 -11
  26. package/dist/engine/object.js +1 -38
  27. package/dist/engine/ports.js +2 -117
  28. package/dist/fold/admission-history.js +1 -17
  29. package/dist/fold/bootstrap-anchor.js +1 -28
  30. package/dist/fold/ceilings.js +1 -142
  31. package/dist/fold/claims.js +2 -132
  32. package/dist/fold/closed.js +24 -235
  33. package/dist/fold/configures.js +1 -25
  34. package/dist/fold/digests.js +10 -226
  35. package/dist/fold/evidence.js +1 -22
  36. package/dist/fold/fold-worker.js +1 -13
  37. package/dist/fold/kept.js +12 -173
  38. package/dist/fold/keys.js +3 -91
  39. package/dist/fold/laid.js +3 -90
  40. package/dist/fold/nos.js +1 -48
  41. package/dist/fold/object.js +1 -2
  42. package/dist/fold/observed.js +27 -534
  43. package/dist/fold/opened.js +1 -33
  44. package/dist/fold/own.js +3 -217
  45. package/dist/fold/paid.js +1 -92
  46. package/dist/fold/place-inputs.js +1 -70
  47. package/dist/fold/places.js +3 -100
  48. package/dist/fold/rank.js +1 -9
  49. package/dist/fold/reach.js +1 -83
  50. package/dist/fold/readers.js +6 -142
  51. package/dist/fold/receipts.js +1 -47
  52. package/dist/fold/region-declarations.js +1 -13
  53. package/dist/fold/region.js +8 -286
  54. package/dist/fold/release-policy.js +1 -101
  55. package/dist/fold/resolved.js +6 -145
  56. package/dist/fold/roles.js +2 -59
  57. package/dist/fold/second.js +4 -71
  58. package/dist/fold/shards.js +12 -100
  59. package/dist/fold/signed.js +3 -81
  60. package/dist/fold/signers.js +1 -54
  61. package/dist/fold/stranger.js +6 -24
  62. package/dist/fold/views.js +1 -66
  63. package/dist/fold/wire.js +1 -46
  64. package/dist/fold/zoom.js +3 -81
  65. package/dist/host/act-cost.js +1 -25
  66. package/dist/host/adapters/keys/ed25519.js +1 -30
  67. package/dist/host/adapters/modules/javascript.js +1 -50
  68. package/dist/host/adapters/transport/http.js +1 -28
  69. package/dist/host/admitted-place.js +1 -35
  70. package/dist/host/archive.js +1 -152
  71. package/dist/host/call-context.js +1 -14
  72. package/dist/host/capsule-process.js +2 -62
  73. package/dist/host/capsule.js +9 -171
  74. package/dist/host/cell-receipts.js +12 -128
  75. package/dist/host/commit-result.js +1 -5
  76. package/dist/host/content-needed.js +1 -8
  77. package/dist/host/content-store.js +1 -31
  78. package/dist/host/contextual-place.js +2 -72
  79. package/dist/host/digest.js +2 -15
  80. package/dist/host/hash.js +1 -9
  81. package/dist/host/host-controls.js +1 -19
  82. package/dist/host/in-process-act.js +3 -84
  83. package/dist/host/in-process-context.js +3 -91
  84. package/dist/host/in-process-root.js +6 -84
  85. package/dist/host/in-process.js +4 -55
  86. package/dist/host/index.d.ts +1 -15
  87. package/dist/host/index.js +1 -7
  88. package/dist/host/io.js +1 -11
  89. package/dist/host/lifetime.js +1 -79
  90. package/dist/host/located.js +6 -105
  91. package/dist/host/native/bounded-file.js +1 -32
  92. package/dist/host/native/command.js +1 -91
  93. package/dist/host/native/control-bridge-worker.js +2 -88
  94. package/dist/host/native/control-bridge.js +1 -110
  95. package/dist/host/native/control-selection.js +1 -32
  96. package/dist/host/native/custody.js +1 -91
  97. package/dist/host/native/deadline.js +1 -28
  98. package/dist/host/native/descendants.js +1 -528
  99. package/dist/host/native/generated-custodian.js +5 -267
  100. package/dist/host/native/generated.js +1 -379
  101. package/dist/host/native/image.js +1 -45
  102. package/dist/host/native/jobs.js +2 -148
  103. package/dist/host/native/loader.js +1 -269
  104. package/dist/host/native/materialize.js +1 -175
  105. package/dist/host/native/module-closure.js +1 -130
  106. package/dist/host/native/module-delivery.d.ts +1 -62
  107. package/dist/host/native/module-delivery.js +1 -151
  108. package/dist/host/native/module-syntax.js +1 -69
  109. package/dist/host/native/native-binary.js +1 -115
  110. package/dist/host/native/native-program.js +1 -72
  111. package/dist/host/native/node-jobs.js +3 -187
  112. package/dist/host/native/node-launch.js +1 -159
  113. package/dist/host/native/preload.js +1 -45
  114. package/dist/host/native/reading.js +1 -249
  115. package/dist/host/native/receipt-environment.js +1 -41
  116. package/dist/host/native/references.js +1 -30
  117. package/dist/host/native/root.js +1 -37
  118. package/dist/host/native/route.js +1 -216
  119. package/dist/host/native/runtime.js +1 -9
  120. package/dist/host/native-reader-context.js +1 -8
  121. package/dist/host/native-receiver.js +1 -25
  122. package/dist/host/objects.js +1 -38
  123. package/dist/host/order.js +1 -2
  124. package/dist/host/place-act-transaction.js +4 -78
  125. package/dist/host/place-clock-selection.js +5 -124
  126. package/dist/host/ports/ingress.js +2 -57
  127. package/dist/host/ports/local-act.js +5 -183
  128. package/dist/host/ports/place-act.js +1 -134
  129. package/dist/host/ports/publication.js +1 -56
  130. package/dist/host/ports/signing.js +1 -74
  131. package/dist/host/ports/store.js +1 -18
  132. package/dist/host/ports/transport.js +1 -48
  133. package/dist/host/process-lifetime.js +1 -17
  134. package/dist/host/provide.js +1 -183
  135. package/dist/host/read-only.js +1 -9
  136. package/dist/host/reading-closures.js +7 -227
  137. package/dist/host/reading-context.js +1 -53
  138. package/dist/host/reading-identity-types.js +0 -0
  139. package/dist/host/reading-identity.js +3 -0
  140. package/dist/host/reading-preparation.js +6 -0
  141. package/dist/host/reference-authenticated.d.ts +1 -40
  142. package/dist/host/reference-authenticated.js +3 -100
  143. package/dist/host/reference-contracts.js +1 -6
  144. package/dist/host/reference-export.js +6 -81
  145. package/dist/host/reference-native-api.d.ts +1 -3
  146. package/dist/host/reference-native-api.js +1 -3
  147. package/dist/host/reference-native.js +1 -74
  148. package/dist/host/reference-profile.js +1 -63
  149. package/dist/host/reference-standing.js +2 -18
  150. package/dist/host/reference.js +1 -24
  151. package/dist/host/refusals.js +2 -43
  152. package/dist/host/release.js +4 -256
  153. package/dist/host/root-clock-source.js +1 -307
  154. package/dist/host/selected-capsules.js +1 -50
  155. package/dist/host/selected-topos.js +1 -80
  156. package/dist/host/signature-era.js +1 -12
  157. package/dist/host/signing.js +2 -48
  158. package/dist/host/source-content.js +2 -111
  159. package/dist/host/standing-carrier.js +1 -18
  160. package/dist/host/standing-projection.js +1 -50
  161. package/dist/host/timing.js +1 -7
  162. package/dist/host/walk.js +20 -193
  163. package/dist/judge/late.js +1 -33
  164. package/dist/judge/take.js +2 -75
  165. package/dist/judge/widening.js +1 -25
  166. package/dist/land/act.js +8 -336
  167. package/dist/land/alias.js +1 -41
  168. package/dist/land/held.js +1 -23
  169. package/dist/land/inert.js +1 -33
  170. package/dist/land/leaving.js +1 -55
  171. package/dist/land/ledger.js +7 -188
  172. package/dist/land/owned.js +4 -66
  173. package/dist/land/sign.js +1 -53
  174. package/dist/land/standing-pin.js +1 -49
  175. package/dist/land/vouched.js +1 -112
  176. package/dist/land/withdraw.js +1 -24
  177. package/dist/observe/files.js +1 -88
  178. package/dist/observe/identity.js +1 -61
  179. package/dist/observe/match.js +1 -8
  180. package/dist/observe/regions.js +7 -306
  181. package/dist/observe/run.js +2 -41
  182. package/dist/observe/runner.js +4 -101
  183. package/dist/public-types.d.ts +1114 -0
  184. package/dist/render/capsule.js +1 -30
  185. package/dist/render/field.js +1 -40
  186. package/dist/render/names.js +1 -4
  187. package/dist/render/open.js +1 -61
  188. package/dist/render/page.js +1 -7
  189. package/dist/render/receipts.js +1 -47
  190. package/dist/render/shape.js +1 -74
  191. package/dist/render/target.js +4 -52
  192. package/dist/render/view.js +7 -197
  193. package/dist/vendor/50086958553b9376d600583f7dff354196bfeb41170fc6d1482ca7bea7c493e2.LICENSE +21 -0
  194. package/dist/vendor/b3e938d28f88a1851af303a40c749e12ebd5a686daac4f0b343b5cdd2e040419.LICENSE +21 -0
  195. package/dist/vendor/bundle.json +1 -0
  196. package/dist/vendor/library11.js +1 -0
  197. package/dist/vendor/object-provider.js +42 -0
  198. package/dist/vendor/runtime.js +38 -0
  199. package/dist/vendor/sources.json +1 -0
  200. package/dist/wasm/adapter.d.ts +1 -51
  201. package/dist/wasm/adapter.js +1 -180
  202. package/dist/wasm/node-worker.js +1 -13
  203. package/dist/wasm/object.js +1 -76
  204. package/dist/wasm/worker.js +1 -7
  205. package/docs/contracts/closure-delivery.md +1 -1
  206. package/docs/contracts/closure-delivery.publication.json +1 -1
  207. package/docs/contracts/conformance.json +142 -0
  208. package/docs/contracts/determinism.bound +9 -0
  209. package/docs/contracts/engine-object-projection.publication.json +1 -1
  210. package/docs/contracts/engine.md +21 -1
  211. package/docs/contracts/native-publication.inventory.json +2 -1
  212. package/docs/contracts/optional-wasm-adapter.publication.json +1 -1
  213. package/docs/contracts/reading-identity.md +37 -0
  214. package/docs/contracts/reading-identity.publication.json +25 -0
  215. package/docs/contracts/refusals.bound +51 -0
  216. package/docs/contracts/refusals.md +18 -3
  217. package/docs/contracts/refusals.publication.json +2 -2
  218. package/docs/contracts/views.md +8 -0
  219. package/docs/reference.md +1 -0
  220. package/package.json +23 -34
  221. package/receipts.bound +11627 -10323
  222. package/samples/reading-identity/no.json +20 -0
  223. package/samples/reading-identity/yes.json +46 -0
  224. package/vectors/native/reading-identity.vector.json +101 -0
  225. package/vectors/native/refusals.vector.json +104 -0
  226. package/vendor/syntax/LICENSE.md +7 -0
  227. package/vendor/syntax/parser.js +1 -0
  228. package/.github/workflows/release.yml +0 -67
  229. package/.github/workflows/test.yml +0 -35
  230. package/dist/engine/object.d.ts +0 -17
  231. package/dist/engine/ports.d.ts +0 -37
  232. package/dist/fold/claims.d.ts +0 -29
  233. package/dist/host/call-context.d.ts +0 -20
  234. package/dist/host/commit-result.d.ts +0 -6
  235. package/dist/host/in-process-act.d.ts +0 -82
  236. package/dist/host/in-process-context.d.ts +0 -46
  237. package/dist/host/in-process-root.d.ts +0 -117
  238. package/dist/host/in-process.d.ts +0 -41
  239. package/dist/host/native/module-closure.d.ts +0 -35
  240. package/dist/host/native-receiver.d.ts +0 -19
  241. package/dist/host/place-act-transaction.d.ts +0 -24
  242. package/dist/host/place-clock-selection.d.ts +0 -55
  243. package/dist/host/ports/local-act.d.ts +0 -44
  244. package/dist/host/ports/place-act.d.ts +0 -49
  245. package/dist/host/ports/publication.d.ts +0 -10
  246. package/dist/host/reference-export.d.ts +0 -33
  247. package/dist/host/reference-native.d.ts +0 -30
  248. package/dist/host/reference-profile.d.ts +0 -23
  249. package/dist/host/refusals.d.ts +0 -14
  250. package/dist/host/root-clock-source.d.ts +0 -86
@@ -1,235 +1,24 @@
1
- import { hostOutput } from "../host/call-context.js";
2
- import { actCosts } from "../host/act-cost.js";
3
- import { verifiedReadingReceipts } from "../host/reading-closures.js";
4
- import { readingProfile } from "../host/reading-context.js";
5
- import { currentReadingEnvironment } from "../host/native/receipt-environment.js";
6
- import { childFlags } from "../host/capsule.js";
7
- import { dirname, existsSync, join, mkdirSync, relative, resolve, statSync, writeFileSync } from "../host/io.js";
8
- import { byBytes, canonical, LOCK, parse, publicationOf, roleAt, roleClaimsOf } from '@lapxo/topos/wire';
9
- import { RECEIPTS, fieldOf, foldClaims, isConfig, isWire } from "./claims.js";
10
- import { bytesDigest as hashBytes, fullDigest as hashFull } from "../host/digest.js";
11
- import { mountedCoordinatesIn, worldAt } from "./places.js";
12
- import { ownLockOf } from "./signed.js";
13
- import { viewsOf } from "./views.js";
14
- import { keptPlace } from "./kept.js";
15
- import { storeAt, storeOf } from "../land/ledger.js";
16
- import { coordinatesUnder, observeFile, observeText } from "../observe/files.js";
17
- import { bytesOnly, carriedFrom } from "./resolved.js";
18
- import { takenFor } from "../fold/place-inputs.js";
19
- /** A region is closed when the digest of its bytes is the one its receipt names. Folding a closed region is idle: idleCount is how many were already closed, actSeconds the largest measured act or unpartitioned host work, receiptsSeen how many receipts were read and how long that took. */
20
- let idle = 0;
21
- let seen = { count: 0, ms: 0 };
22
- export const idleCount = () => idle;
23
- export const noteIdle = () => {
24
- idle += 1;
25
- };
26
- export const actSeconds = () => actCosts.seconds();
27
- export const receiptsSeen = () => seen;
28
- const algorithmIn = (text) => text.match(/(?:value=|place:)([a-z0-9]+):[0-9a-f]{64}/)?.[1] ?? '';
29
- const lockStamp = (root, place) => {
30
- const name = place.replace(/\/$/, '');
31
- try {
32
- const st = statSync(join(root, name, LOCK));
33
- return `${st.mtimeMs}:${st.size}`;
34
- }
35
- catch {
36
- return 'none';
37
- }
38
- };
39
- const publishedMounts = (root) => mountedCoordinatesIn(root, (observeText(join(root, LOCK)) ?? '').split('\n').filter(isWire));
40
- function filesOf(root, place, region, inputs) {
41
- const step = region.replace(/^receipts\//, '').replace(/\/$/, '');
42
- const here = join(root, place);
43
- const name = place.replace(/\/$/, '');
44
- const own = existsSync(join(here, LOCK)) ? [name ? `${name}/${LOCK}` : LOCK] : [];
45
- const receipt = `${name ? `${name}/` : ''}${RECEIPTS}`;
46
- const claims = roleClaimsOf((observeText(join(here, LOCK)) ?? '').split('\n').filter(isWire).flatMap(line => {
47
- const record = parse(line);
48
- return record.kind === 'fact' ? [record.value.fields] : [];
49
- }));
50
- const localMounts = [...mountedCoordinatesIn(here), ...publishedMounts(here)];
51
- const mounts = [...new Set([...mountedCoordinatesIn(root), ...publishedMounts(root), ...localMounts.map(coordinate => relative(root, join(here, coordinate)))])];
52
- const owned = coordinatesUnder(join(here, step), root).filter(rel => roleAt(relative(here, join(root, rel)), claims) !== 'foreign'
53
- && !mounts.some(mount => rel === mount || rel.startsWith(`${mount}/`)));
54
- // Foreign worlds are not the place's tree. Retain the external files actually handed to its readers.
55
- const observed = inputs.filter(line => fieldOf(line, 'measure') === 'observed').flatMap(line => {
56
- const coordinate = fieldOf(line, 'scope');
57
- const at = resolve(here, coordinate);
58
- const local = relative(here, at);
59
- if (local === '..' || local.startsWith('../') || resolve(at) === resolve(here))
60
- return [];
61
- if (step !== '.' && step !== '' && local !== step && !local.startsWith(`${step}/`))
62
- return [];
63
- return existsSync(at) && statSync(at).isFile() ? [relative(root, at)] : [];
64
- });
65
- return [...new Set([...owned, ...observed, ...own])].filter(rel => rel !== receipt && !rel.split('/').some(part => part === '.bound' || part === '.cache' || part === '.git'));
66
- }
67
- const rooted = new Map();
68
- let lastConfiguration;
69
- function publicConfiguration(lines) {
70
- const input = lines.join('\n');
71
- // Retain only this pure projection. Callers still read and hash the actual
72
- // files; neither a timestamp nor a previous seal proves their current bytes.
73
- if (lastConfiguration?.input === input)
74
- return lastConfiguration.output;
75
- if (!lines.length || !lines.every(isConfig))
76
- return lines;
77
- const folded = foldClaims(lines);
78
- if (folded.forks.length)
79
- throw Error('REFUSE·receipt disputed configuration standing');
80
- const output = publicationOf(folded.standing.filter(line => fieldOf(line, 'value') !== 'withdraw'));
81
- lastConfiguration = { input, output };
82
- return output;
83
- }
84
- function rootLines(root, place) {
85
- const name = place.replace(/\/$/, '');
86
- if (!name)
87
- return [];
88
- const key = `${root}\0${name}\0${lockStamp(root, '')}`;
89
- const held = rooted.get(key);
90
- if (held !== undefined)
91
- return held;
92
- const standing = publicConfiguration((observeText(join(root, LOCK)) ?? '').split('\n').filter(isWire));
93
- // Authority validates admission separately; it is not a rendered file input.
94
- const lines = standing.filter((line) => fieldOf(line, 'value') !== 'withdraw' && !fieldOf(line, 'scope').startsWith('keys/'));
95
- const take = takenFor(lines, `${name}/`, worldAt(root, name) ? { own: ownLockOf(root, name), tree: viewsOf(standing) } : undefined);
96
- const got = lines.filter(take).map((line) => `root ${line}`);
97
- rooted.set(key, got);
98
- return got;
99
- }
100
- /** File-fold identity uses public inputs; admission history stays in its separate ledger guard. */
101
- export function fileRegionDigest(root, place, region, algorithm, inputs = []) {
102
- const files = [...filesOf(root, place, region, inputs)].sort(byBytes);
103
- const own = join(root, place, LOCK);
104
- const bytesOf = (rel) => {
105
- const at = join(root, rel), bytes = observeFile(at) ?? new Uint8Array();
106
- if (resolve(at) !== resolve(own))
107
- return bytes;
108
- const lines = new TextDecoder().decode(bytes).split('\n').filter(isWire);
109
- // Object history keeps its own contract. Configuration's public identity is
110
- // the existing Topos publication projection, not its admission envelopes.
111
- if (!lines.length || !lines.every(isConfig))
112
- return bytes;
113
- return new TextEncoder().encode(publicConfiguration(lines).join('\n') + '\n');
114
- };
115
- return hashFull([...files.map((rel) => `${relative(join(root, place), join(root, rel))} ${hashBytes(bytesOf(rel), algorithm)}`), ...rootLines(root, place)], algorithm);
116
- }
117
- function namedReceipts(root, store) {
118
- const text = observeText(join(root, RECEIPTS));
119
- const carried = carriedFrom(store, (text ?? '').split('\n').filter(isWire));
120
- const out = new Map();
121
- const mounted = new Set(mountedCoordinatesIn(root));
122
- for (const line of carried ?? []) {
123
- if (!isWire(line) || fieldOf(line, 'measure') !== 'digest')
124
- continue;
125
- const place = /^write\/([^/]+)\/receipts\.bound$/.exec(fieldOf(line, 'scope'))?.[1];
126
- // A retained dependency receipt is input evidence, not a child-place closure.
127
- if (place && !mounted.has(place))
128
- out.set(place, fieldOf(line, 'value'));
129
- }
130
- return out;
131
- }
132
- // Only the instrument's file seals describe file-region bytes. Reader receipts keep their own semantic identity.
133
- const fileSeal = (line) => isWire(line) && fieldOf(line, 'measure') === 'bytes' && fieldOf(line, 'by') === 'bound';
134
- function ownBytes(root) {
135
- return (observeText(join(root, RECEIPTS)) ?? '').split('\n').filter(fileSeal);
136
- }
137
- function bytesMeet(root, place) {
138
- const shipped = (observeText(join(root, place, RECEIPTS)) ?? '').split('\n').filter(isWire);
139
- const inputs = carriedFrom(storeOf(root), shipped) ?? [];
140
- const lines = shipped.filter(fileSeal);
141
- const algorithm = algorithmIn(lines.join('\n'));
142
- return lines.length > 0 && algorithm !== '' && lines.map((line) => fieldOf(line, 'value')).join('\n') === lines.map((line) => fileRegionDigest(root, place, fieldOf(line, 'scope'), algorithm, inputs)).join('\n');
143
- }
144
- const stampAt = (store) => storeAt(store, 'cas', 'instrument');
145
- export const instrumentKept = (store) => (observeText(stampAt(store)) ?? '').trim();
146
- export function instrumentKeep(store, id) {
147
- mkdirSync(dirname(stampAt(store)), { recursive: true });
148
- writeFileSync(stampAt(store), `${id}\n`);
149
- }
150
- export function receiptPlaces(root, store) {
151
- const children = [...namedReceipts(root, store).keys()];
152
- return ownBytes(root).length ? ['', ...children] : children;
153
- }
154
- function rewritePlace(root, place) {
155
- const at = join(root, place, RECEIPTS);
156
- const text = observeText(at) ?? '';
157
- const algorithm = algorithmIn(text);
158
- if (algorithm === '')
159
- return;
160
- const kept = text.split('\n').filter((line) => line === '' || !fileSeal(line));
161
- const regions = kept.filter((line) => isWire(line) && fieldOf(line, 'measure') === 'count' && fieldOf(line, 'by') === 'bound' && fieldOf(line, 'scope').startsWith('receipts/'));
162
- const bytes = regions.map((line) => {
163
- const scope = fieldOf(line, 'scope');
164
- const inputs = carriedFrom(storeOf(root), kept.filter(isWire)) ?? [];
165
- const now = fileRegionDigest(root, place, scope, algorithm, inputs);
166
- return canonical({ scope, role: 'writes', form: 'alphabet', measure: 'bytes', value: now, at: `place:${now}`, by: fieldOf(line, 'by') || 'bound' });
167
- });
168
- writeFileSync(at, `${[...kept.filter((line) => line !== ''), ...bytes].join('\n')}\n`);
169
- }
170
- export async function closeReceipts(root, store, semantic) {
171
- if (semantic) {
172
- const lines = (observeText(join(root, RECEIPTS)) ?? '').split('\n').filter(isWire);
173
- return [...semantic].filter(([scope, digest]) => !lines.some(line => fieldOf(line, 'scope') === scope && fieldOf(line, 'measure') === 'bytes' && fieldOf(line, 'value') === digest)).map(([scope]) => scope);
174
- }
175
- const open = receiptPlaces(root, store).filter((place) => !meets(root, store, `${place}/`));
176
- for (const place of open) {
177
- rewritePlace(root, place);
178
- await new Promise((resolve) => { setImmediate(resolve); });
179
- }
180
- return open;
181
- }
182
- /** One comparison. A place meets its receipt; the root meets when every receipt it names meets. */
183
- export function meets(root, store, place, current = true, active) {
184
- const name = place.replace(/\/$/, '');
185
- if (name === '') {
186
- const at = Date.now();
187
- const named = namedReceipts(root, store);
188
- const own = ownBytes(root);
189
- const carried = own.length ? carriedFrom(store, (observeText(join(root, RECEIPTS)) ?? '').split('\n').filter(isWire)) : undefined;
190
- const ownClosed = own.length > 0 && carried !== undefined && carried.length > 0 && bytesMeet(root, '');
191
- let closed = (own.length > 0 ? ownClosed : named.size > 0) && [...named].every(([one, expected]) => {
192
- const bytes = observeFile(join(root, one, RECEIPTS));
193
- const algorithm = expected.split(':')[0];
194
- return bytes !== undefined && hashBytes(bytes, algorithm) === expected && meets(root, store, `${one}/`, current);
195
- });
196
- if (closed && carried) {
197
- const algorithm = algorithmIn(own.join('\n')), hash = (text) => hashFull(text, algorithm);
198
- const profile = readingProfile((observeText(join(root, LOCK)) ?? '').split('\n').filter(isWire), fieldOf);
199
- // History keeps its canonical identity and bytes. It does not become a
200
- // current execution merely because it shares a public carrier with one.
201
- const readings = verifiedReadingReceipts(store, carried, hash, undefined, profile);
202
- if (readings === undefined)
203
- closed = false;
204
- else if (current && profile && readings) {
205
- const stamp = instrumentKept(store);
206
- const snapshot = active ?? (stamp ? keptPlace(store, undefined, stamp)?.observed : undefined);
207
- if (snapshot === undefined)
208
- closed = false;
209
- else {
210
- const units = snapshot.filter(line => fieldOf(line, 'scope').startsWith('receipts/readings/') && fieldOf(line, 'role') === 'writes');
211
- const supplied = new Set(carried);
212
- const present = units.length > 0 && units.every(line => supplied.has(line) || (fieldOf(line, 'measure') === 'observed' && supplied.has(bytesOnly(line))));
213
- const fresh = present ? verifiedReadingReceipts(store, snapshot, hash, currentReadingEnvironment(store, root, hash, childFlags()), profile) : undefined;
214
- if (!fresh)
215
- closed = false;
216
- }
217
- }
218
- if (closed && readings)
219
- hostOutput('error', `RECEIPTS ${readings} read · 0 opened · reading closures\n`);
220
- }
221
- seen = { count: named.size + (own.length > 0 ? 1 : 0), ms: Date.now() - at };
222
- return closed;
223
- }
224
- const lines = (observeText(join(root, place, RECEIPTS)) ?? '').split('\n').filter((line) => isWire(line) && fieldOf(line, 'measure') === 'bytes');
225
- const lock = existsSync(join(root, name, LOCK));
226
- if (lines.length > 0)
227
- return bytesMeet(root, place);
228
- if (lock)
229
- return false;
230
- const expected = namedReceipts(root, store).get(name);
231
- const file = expected !== undefined ? observeFile(join(root, place, RECEIPTS)) : undefined;
232
- const algorithm = file === undefined ? '' : algorithmIn(new TextDecoder().decode(file));
233
- const closed = file !== undefined && algorithm !== '' && hashBytes(file, algorithm) === expected;
234
- return closed;
235
- }
1
+ var ce=Object.defineProperty;var c=(e,t)=>ce(e,"name",{value:t,configurable:!0});import{hostOutput as ae}from"../host/call-context.js";import{actCosts as fe}from"../host/act-cost.js";import{verifiedReadingReceipts as H}from"../host/reading-closures.js";import{readingProfile as le}from"../host/reading-context.js";import{currentReadingEnvironment as ue}from"../host/native/receipt-environment.js";import{childFlags as pe}from"../host/capsule.js";import{dirname as de,existsSync as I,join as f,mkdirSync as me,relative as j,resolve as F,statSync as J,writeFileSync as N}from"../host/io.js";import{library11_byBytes as he,library11_canonical as ge,library11_LOCK as w,library11_parse as ye,library11_publicationOf as be,library11_roleAt as we,library11_roleClaimsOf as $e}from"../vendor/runtime.js";import{RECEIPTS as $,fieldOf as a,foldClaims as ve,isConfig as Q,isWire as h}from"./claims.js";import{bytesDigest as T,fullDigest as V}from"../host/digest.js";import{mountedCoordinatesIn as P,worldAt as xe}from"./places.js";import{ownLockOf as Se}from"./signed.js";import{viewsOf as Ce}from"./views.js";import{keptPlace as Oe}from"./kept.js";import{storeAt as ke,storeOf as X}from"../land/ledger.js";import{coordinatesUnder as Ee,observeFile as z,observeText as g}from"../observe/files.js";import{bytesOnly as Re,carriedFrom as W}from"./resolved.js";import{takenFor as je}from"../fold/place-inputs.js";let Y=0,Z={count:0,ms:0};const st=c(()=>Y,"idleCount"),it=c(()=>{Y+=1},"noteIdle"),rt=c(()=>fe.seconds(),"actSeconds"),ot=c(()=>Z,"receiptsSeen"),_=c(e=>e.match(/(?:value=|place:)([a-z0-9]+):[0-9a-f]{64}/)?.[1]??"","algorithmIn"),Fe=c((e,t)=>{const s=t.replace(/\/$/,"");try{const r=J(f(e,s,w));return`${r.mtimeMs}:${r.size}`}catch{return"none"}},"lockStamp"),ee=c(e=>P(e,(g(f(e,w))??"").split(`
2
+ `).filter(h)),"publishedMounts");function Me(e,t,s,r){const i=s.replace(/^receipts\//,"").replace(/\/$/,""),n=f(e,t),l=t.replace(/\/$/,""),p=I(f(n,w))?[l?`${l}/${w}`:w]:[],o=`${l?`${l}/`:""}${$}`,d=$e((g(f(n,w))??"").split(`
3
+ `).filter(h).flatMap(u=>{const m=ye(u);return m.kind==="fact"?[m.value.fields]:[]})),b=[...P(n),...ee(n)],v=[...new Set([...P(e),...ee(e),...b.map(u=>j(e,f(n,u)))])],S=Ee(f(n,i),e).filter(u=>we(j(n,f(e,u)),d)!=="foreign"&&!v.some(m=>u===m||u.startsWith(`${m}/`))),R=r.filter(u=>a(u,"measure")==="observed").flatMap(u=>{const m=a(u,"scope"),x=F(n,m),y=j(n,x);return y===".."||y.startsWith("../")||F(x)===F(n)?[]:i!=="."&&i!==""&&y!==i&&!y.startsWith(`${i}/`)?[]:I(x)&&J(x).isFile()?[j(e,x)]:[]});return[...new Set([...S,...R,...p])].filter(u=>u!==o&&!u.split("/").some(m=>m===".bound"||m===".cache"||m===".git"))}c(Me,"filesOf");const te=new Map;let B;function ne(e){const t=e.join(`
4
+ `);if(B?.input===t)return B.output;if(!e.length||!e.every(Q))return e;const s=ve(e);if(s.forks.length)throw Error("REFUSE\xB7receipt disputed configuration standing");const r=be(s.standing.filter(i=>a(i,"value")!=="withdraw"));return B={input:t,output:r},r}c(ne,"publicConfiguration");function De(e,t){const s=t.replace(/\/$/,"");if(!s)return[];const r=`${e}\0${s}\0${Fe(e,"")}`,i=te.get(r);if(i!==void 0)return i;const n=ne((g(f(e,w))??"").split(`
5
+ `).filter(h)),l=n.filter(d=>a(d,"value")!=="withdraw"&&!a(d,"scope").startsWith("keys/")),p=je(l,`${s}/`,xe(e,s)?{own:Se(e,s),tree:Ce(n)}:void 0),o=l.filter(p).map(d=>`root ${d}`);return te.set(r,o),o}c(De,"rootLines");function se(e,t,s,r,i=[]){const n=[...Me(e,t,s,i)].sort(he),l=f(e,t,w),p=c(o=>{const d=f(e,o),b=z(d)??new Uint8Array;if(F(d)!==F(l))return b;const v=new TextDecoder().decode(b).split(`
6
+ `).filter(h);return!v.length||!v.every(Q)?b:new TextEncoder().encode(ne(v).join(`
7
+ `)+`
8
+ `)},"bytesOf");return V([...n.map(o=>`${j(f(e,t),f(e,o))} ${T(p(o),r)}`),...De(e,t)],r)}c(se,"fileRegionDigest");function K(e,t){const s=g(f(e,$)),r=W(t,(s??"").split(`
9
+ `).filter(h)),i=new Map,n=new Set(P(e));for(const l of r??[]){if(!h(l)||a(l,"measure")!=="digest")continue;const p=/^write\/([^/]+)\/receipts\.bound$/.exec(a(l,"scope"))?.[1];p&&!n.has(p)&&i.set(p,a(l,"value"))}return i}c(K,"namedReceipts");const L=c(e=>h(e)&&a(e,"measure")==="bytes"&&a(e,"by")==="bound","fileSeal");function ie(e){return(g(f(e,$))??"").split(`
10
+ `).filter(L)}c(ie,"ownBytes");function re(e,t){const s=(g(f(e,t,$))??"").split(`
11
+ `).filter(h),r=W(X(e),s)??[],i=s.filter(L),n=_(i.join(`
12
+ `));return i.length>0&&n!==""&&i.map(l=>a(l,"value")).join(`
13
+ `)===i.map(l=>se(e,t,a(l,"scope"),n,r)).join(`
14
+ `)}c(re,"bytesMeet");const U=c(e=>ke(e,"cas","instrument"),"stampAt"),Pe=c(e=>(g(U(e))??"").trim(),"instrumentKept");function ct(e,t){me(de(U(e)),{recursive:!0}),N(U(e),`${t}
15
+ `)}c(ct,"instrumentKeep");function We(e,t){const s=[...K(e,t).keys()];return ie(e).length?["",...s]:s}c(We,"receiptPlaces");function _e(e,t){const s=f(e,t,$),r=g(s)??"",i=_(r);if(i==="")return;const n=r.split(`
16
+ `).filter(o=>o===""||!L(o)),p=n.filter(o=>h(o)&&a(o,"measure")==="count"&&a(o,"by")==="bound"&&a(o,"scope").startsWith("receipts/")).map(o=>{const d=a(o,"scope"),b=W(X(e),n.filter(h))??[],v=se(e,t,d,i,b);return ge({scope:d,role:"writes",form:"alphabet",measure:"bytes",value:v,at:`place:${v}`,by:a(o,"by")||"bound"})});N(s,`${[...n.filter(o=>o!==""),...p].join(`
17
+ `)}
18
+ `)}c(_e,"rewritePlace");async function at(e,t,s){if(s){const i=(g(f(e,$))??"").split(`
19
+ `).filter(h);return[...s].filter(([n,l])=>!i.some(p=>a(p,"scope")===n&&a(p,"measure")==="bytes"&&a(p,"value")===l)).map(([n])=>n)}const r=We(e,t).filter(i=>!oe(e,t,`${i}/`));for(const i of r)_e(e,i),await new Promise(n=>{setImmediate(n)});return r}c(at,"closeReceipts");function oe(e,t,s,r=!0,i){const n=s.replace(/\/$/,"");if(n===""){const S=Date.now(),R=K(e,t),u=ie(e),m=u.length?W(t,(g(f(e,$))??"").split(`
20
+ `).filter(h)):void 0,x=u.length>0&&m!==void 0&&m.length>0&&re(e,"");let y=(u.length>0?x:R.size>0)&&[...R].every(([M,C])=>{const O=z(f(e,M,$)),k=C.split(":")[0];return O!==void 0&&T(O,k)===C&&oe(e,t,`${M}/`,r)});if(y&&m){const M=_(u.join(`
21
+ `)),C=c(D=>V(D,M),"hash"),O=le((g(f(e,w))??"").split(`
22
+ `).filter(h),a),k=H(t,m,C,void 0,O);if(k===void 0)y=!1;else if(r&&O&&k){const D=Pe(t),A=i??(D?Oe(t,void 0,D)?.observed:void 0);if(A===void 0)y=!1;else{const q=A.filter(E=>a(E,"scope").startsWith("receipts/readings/")&&a(E,"role")==="writes"),G=new Set(m);q.length>0&&q.every(E=>G.has(E)||a(E,"measure")==="observed"&&G.has(Re(E)))&&H(t,A,C,ue(t,e,C,pe()),O)||(y=!1)}}y&&k&&ae("error",`RECEIPTS ${k} read \xB7 0 opened \xB7 reading closures
23
+ `)}return Z={count:R.size+(u.length>0?1:0),ms:Date.now()-S},y}const l=(g(f(e,s,$))??"").split(`
24
+ `).filter(S=>h(S)&&a(S,"measure")==="bytes"),p=I(f(e,n,w));if(l.length>0)return re(e,s);if(p)return!1;const o=K(e,t).get(n),d=o!==void 0?z(f(e,s,$)):void 0,b=d===void 0?"":_(new TextDecoder().decode(d));return d!==void 0&&b!==""&&T(d,b)===o}c(oe,"meets");export{rt as actSeconds,at as closeReceipts,se as fileRegionDigest,st as idleCount,ct as instrumentKeep,Pe as instrumentKept,oe as meets,it as noteIdle,We as receiptPlaces,ot as receiptsSeen};
@@ -1,25 +1 @@
1
- import { isWireClaim, parse } from '@lapxo/topos/wire';
2
- import { fieldOf, isConfig } from "./claims.js";
3
- import { isReaderLock } from "./observed.js";
4
- import { isRoleLock } from "./roles.js";
5
- import { isSignerLock } from "./signers.js";
6
- import { isReleaseBinding } from "../host/release.js";
7
- import { isRegionDeclaration } from "./region-declarations.js";
8
- import { ownLock } from "../observe/runner.js";
9
- function isEffectLock(line) {
10
- const got = parse(line);
11
- return got.kind === 'fact' && got.value.fields['measure'] === 'effect';
12
- }
13
- /** A lock line the instrument itself consumes — an effect it runs, a reader it loads, a role it walks by, a signer it admits, the wire it reads by. */
14
- function configures(line) {
15
- const got = parse(line);
16
- return isReleaseBinding(line) || isEffectLock(line) || isReaderLock(line) || isRoleLock(line) || isSignerLock(line) || (got.kind === 'fact' && isWireClaim(got.value.fields)) || isRegionDeclaration(line, ownLock());
17
- }
18
- /** Every reads line that configures nothing is a ceiling: a bound some reading has to meet. */
19
- export function isCeiling(line) {
20
- return isConfig(line) && fieldOf(line, 'role') === 'reads' && fieldOf(line, 'value') !== 'withdraw' && !configures(line);
21
- }
22
- /** A demand that names no place asks nothing of the tree: it tells a render what to write, and no take pays it. */
23
- export function asksThePlace(line) {
24
- return fieldOf(line, 'role') === 'demands' && fieldOf(line, 'needs') !== '';
25
- }
1
+ var s=Object.defineProperty;var i=(r,o)=>s(r,"name",{value:o,configurable:!0});import{library11_isWireClaim as f,library11_parse as t}from"../vendor/runtime.js";import{fieldOf as e,isConfig as a}from"./claims.js";import{isReaderLock as m}from"./observed.js";import{isRoleLock as c}from"./roles.js";import{isSignerLock as n}from"./signers.js";import{isReleaseBinding as u}from"../host/release.js";import{isRegionDeclaration as d}from"./region-declarations.js";import{ownLock as p}from"../observe/runner.js";function g(r){const o=t(r);return o.kind==="fact"&&o.value.fields.measure==="effect"}i(g,"isEffectLock");function k(r){const o=t(r);return u(r)||g(r)||m(r)||c(r)||n(r)||o.kind==="fact"&&f(o.value.fields)||d(r,p())}i(k,"configures");function y(r){return a(r)&&e(r,"role")==="reads"&&e(r,"value")!=="withdraw"&&!k(r)}i(y,"isCeiling");function W(r){return e(r,"role")==="demands"&&e(r,"needs")!==""}i(W,"asksThePlace");export{W as asksThePlace,y as isCeiling};
@@ -1,226 +1,10 @@
1
- import { signatureEraOf } from "../host/signature-era.js";
2
- import { ledgerLines, ledgerWriters } from "../land/ledger.js";
3
- import { readOnly } from "../host/read-only.js";
4
- import { appendFileSync, dirname, join, mkdirSync, readdirSync, realpathSync, relative, resolve } from "../host/io.js";
5
- import { bytesDigest as bytesWith, fullDigest as fullWith } from "../host/digest.js";
6
- import { coordinatesUnder, observeFile, observeText, stampOf } from "../observe/files.js";
7
- import { releaseOf, signedLockLines } from "./keys.js";
8
- import { EXTENSION, fieldOf, foldClaims, selfName } from "./claims.js";
9
- import { wireLine } from "./wire.js";
10
- import { publicLock, LOCK } from '@lapxo/topos/wire';
11
- import { builtinModules, createRequire } from 'node:module';
12
- import { moduleImports } from "../host/adapters/modules/javascript.js";
13
- const held = new Map();
14
- let algorithmMs = 0;
15
- export const algorithmCost = () => algorithmMs;
16
- /**
17
- * The algorithm this tree digests with: the one its wire names, read from the lock and told to the port, which keeps
18
- * none of its own. A lock that names no algorithm is a tree nothing can be digested in, and it is refused as one.
19
- */
20
- function namedAlgorithm(store) {
21
- const needle = 'scope=wire/digest-algorithms';
22
- const older = 'scope=audit/wire/digest-algorithms';
23
- let best = -1;
24
- let name = '';
25
- const release = releaseOf(store);
26
- if (release) {
27
- const said = release.find((line) => (fieldOf(line, 'scope') === 'wire/digest-algorithms' || fieldOf(line, 'scope') === 'audit/wire/digest-algorithms') && fieldOf(line, 'value') !== 'withdraw');
28
- return said === undefined ? undefined : fieldOf(said, 'value').split('|').filter(Boolean)[0]?.split(':')[0];
29
- }
30
- if (!existsLedger(store)) {
31
- const text = observeText(join(dirname(store), LOCK));
32
- const lines = text?.split('\n').filter(line => line.startsWith('bound-lock/'));
33
- const published = lines === undefined ? undefined : publicLock(lines);
34
- const contract = published === undefined ? undefined : wireLine(published, 'digest-algorithms');
35
- return contract === undefined ? undefined : fieldOf(contract, 'value').split('|')[0]?.split(':')[0];
36
- }
37
- for (const writer of ledgerWriters(store)) {
38
- const text = ledgerLines(store, writer).join('\n');
39
- let from = 0;
40
- while (from < text.length) {
41
- const at = (() => {
42
- const next = text.indexOf(needle, from);
43
- const was = text.indexOf(older, from);
44
- if (next < 0)
45
- return was;
46
- if (was < 0)
47
- return next;
48
- return Math.min(next, was);
49
- })();
50
- if (at < 0)
51
- break;
52
- const start = text.lastIndexOf('\n', at) + 1;
53
- const end = text.indexOf('\n', at);
54
- const line = text.slice(start, end < 0 ? undefined : end);
55
- from = end < 0 ? text.length : end + 1;
56
- if (!line.includes(' sig='))
57
- continue;
58
- const epoch = Number(fieldOf(line, 'epoch')) || 0;
59
- if (epoch < best)
60
- continue;
61
- best = epoch;
62
- const value = fieldOf(line, 'value');
63
- name = value === 'withdraw' ? '' : (value.split('|').filter(Boolean)[0]?.split(':')[0] ?? '');
64
- }
65
- }
66
- return name || undefined;
67
- }
68
- function existsLedger(store) {
69
- try {
70
- return readdirSync(join(store, 'ledger')).length > 0;
71
- }
72
- catch (error) {
73
- if (error.code === 'ENOENT')
74
- return false;
75
- throw error;
76
- }
77
- }
78
- function algorithmOf(store) {
79
- const mine = held.get(store);
80
- if (mine !== undefined)
81
- return mine;
82
- const first = namedAlgorithm(store);
83
- if (first === undefined)
84
- throw new Error(`${selfName()}: REFUSE·runtime the lock names no \`wire/digest-algorithms\`: nothing can be digested here`);
85
- held.set(store, first);
86
- return first;
87
- }
88
- /**
89
- * The signature algorithms this tree admits, and the one it signs with now: each carries its era after its name, the
90
- * wire's `era` line names the one that is current, and every other is history, read and never written again. A wire
91
- * that names no era signs with the one that carries a digest, which is how the first era was named.
92
- */
93
- export function signaturesOf(store, told = []) {
94
- return eraOf(foldClaims([...signedLockLines(store, told), ...told]).standing);
95
- }
96
- export function eraOf(standing) {
97
- try {
98
- return signatureEraOf(standing);
99
- }
100
- catch (error) {
101
- throw new Error(`${selfName()}: ${error instanceof Error ? error.message : String(error)}`);
102
- }
103
- }
104
- export const bytesDigest = (store, bytes) => bytesWith(bytes, algorithmOf(store));
105
- export const fullDigest = (store, input) => fullWith(input, algorithmOf(store));
106
- const stamped = new Map();
107
- const memoOf = (store) => stamped.get(store) ?? stamped.set(store, new Map((observeText(join(store, 'cas', `stamps${EXTENSION}`)) ?? '')
108
- .split('\n').flatMap((row) => (row.indexOf('\t') > 0 ? [[row.slice(0, row.indexOf('\t')), row.slice(row.indexOf('\t') + 1)]] : [])))).get(store);
109
- export function coordinateDigest(store, at) {
110
- const stamp = stampOf(at);
111
- if (stamp?.kind !== 'file')
112
- return stamp === undefined ? undefined : bytesDigest(store, observeFile(at) ?? new Uint8Array());
113
- if (readOnly())
114
- return bytesDigest(store, observeFile(at) ?? new Uint8Array());
115
- const key = `${at} ${stamp.stamp}`;
116
- const memo = memoOf(store);
117
- const held = memo.get(key);
118
- if (held !== undefined)
119
- return held;
120
- const digest = bytesDigest(store, observeFile(at) ?? new Uint8Array());
121
- memo.set(key, digest);
122
- if (readOnly())
123
- return digest;
124
- mkdirSync(join(store, 'cas'), { recursive: true });
125
- appendFileSync(join(store, 'cas', `stamps${EXTENSION}`), `${key}\t${digest}\n`);
126
- return digest;
127
- }
128
- export function memoized(store, key, compute) {
129
- const memo = memoOf(store);
130
- const held = memo.get(key);
131
- if (held !== undefined)
132
- return held;
133
- const value = compute();
134
- memo.set(key, value);
135
- if (readOnly())
136
- return value;
137
- mkdirSync(join(store, 'cas'), { recursive: true });
138
- appendFileSync(join(store, 'cas', `stamps${EXTENSION}`), `${key}\t${value}\n`);
139
- return value;
140
- }
141
- const imported = new Map();
142
- const importsOf = (store, at, digest) => {
143
- const key = `imports ${fullDigest(store, importsOf.toString())} ${digest}`;
144
- const memo = memoOf(store);
145
- const held = imported.get(digest) ?? (readOnly() ? undefined : memo.get(key)?.split('|').filter(Boolean));
146
- if (held !== undefined)
147
- return held;
148
- const found = moduleImports(new TextDecoder().decode(observeFile(at) ?? new Uint8Array()), at);
149
- imported.set(digest, found);
150
- memo.set(key, found.join('|'));
151
- if (!readOnly())
152
- appendFileSync(join(store, 'cas', `stamps${EXTENSION}`), `${key}\t${found.join('|')}\n`);
153
- return found;
154
- };
155
- /**
156
- * The digest of the instrument itself: the entry module and everything it imports, by their bytes, and the source of
157
- * every region its lock says it depends on, followed as far as those regions depend — code it runs as much as its own.
158
- * A region its own lock names a release for, laid where it needs it, is that release by digest: what it runs, never a
159
- * sibling rebuilt beside it.
160
- * A fold is a function of its points and the instrument is one of them, so a fold kept by another bound is another
161
- * origin's fold — readable as history, never as this instrument's own state.
162
- */
163
- export function instrumentOf(store, entry, standing = [], root, releases = []) {
164
- const coordinate = root === undefined ? resolve(entry) : resolve(root, entry);
165
- return instrumentDigest(store, coordinate, standing, root ?? dirname(coordinate), releases).replace(/^[^:]*:/, '').slice(0, 12);
166
- }
167
- export function instrumentDigest(store, entry, standing = [], root = dirname(resolve(entry)), releases = []) {
168
- const seen = instrumentCoordinates(store, entry, standing, root, releases);
169
- return bytesDigest(store, new TextEncoder().encode([...seen.values()].sort().join('\n')));
170
- }
171
- export function instrumentCoordinates(store, entry, standing = [], root = dirname(resolve(entry)), releases = [], fresh = false) {
172
- const seen = new Map();
173
- const walk = (at) => {
174
- if (seen.has(at))
175
- return;
176
- const bytes = fresh ? observeFile(at) : undefined;
177
- const digest = fresh ? (bytes === undefined ? undefined : bytesDigest(store, bytes)) : coordinateDigest(store, at);
178
- if (digest === undefined)
179
- return;
180
- // The host loader resolves links before loading a module. Count that module
181
- // once, while retaining distinct modules even when their bytes are equal.
182
- const module = realpathSync(at);
183
- if (seen.has(module))
184
- return;
185
- seen.set(module, digest);
186
- for (const one of importsOf(store, module, digest)) {
187
- if (one.startsWith('node:') || builtinModules.includes(one))
188
- continue;
189
- if (one.startsWith('.'))
190
- walk(resolve(dirname(module), one));
191
- else
192
- walk(createRequire(module).resolve(one));
193
- }
194
- };
195
- walk(resolve(entry));
196
- const deps = standing.filter((line) => fieldOf(line, 'scope').startsWith('dep/') && fieldOf(line, 'value') !== 'withdraw')
197
- .map((line) => ({ region: fieldOf(line, 'scope').slice('dep/'.length).replace(/\*+$/, ''), on: fieldOf(line, 'value').split('|').filter((one) => one && one !== 'none') }));
198
- const released = new Map(releases.filter((line) => fieldOf(line, 'scope').startsWith('dep/') && fieldOf(line, 'role') === 'reads' && fieldOf(line, 'needs') && fieldOf(line, 'value') !== 'withdraw')
199
- .map((line) => [fieldOf(line, 'scope').slice('dep/'.length), fieldOf(line, 'value')]));
200
- const reached = new Set();
201
- const follow = (region) => {
202
- for (const name of deps.find((dep) => dep.region === region)?.on ?? []) {
203
- if (released.has(name)) {
204
- seen.set(`release:${name}`, released.get(name));
205
- continue;
206
- }
207
- for (const next of deps.filter((dep) => dep.region.startsWith(`${name}/`) && !reached.has(dep.region))) {
208
- reached.add(next.region);
209
- for (const coordinate of coordinatesUnder(resolve(root, next.region), root))
210
- walk(resolve(root, coordinate));
211
- follow(next.region);
212
- }
213
- }
214
- };
215
- follow(deps.find((dep) => relative(root, resolve(entry)).startsWith(dep.region))?.region);
216
- const home = relative(root, resolve(entry)).split('/')[0] ?? '';
217
- for (const line of standing.filter((one) => fieldOf(one, 'scope').startsWith(`${home}/process/`) && fieldOf(one, 'kind') === 'process' && fieldOf(one, 'value') !== 'withdraw')) {
218
- for (const need of fieldOf(line, 'needs').split('|').filter(Boolean))
219
- walk(resolve(root, need));
220
- }
221
- for (const line of releases.filter(one => fieldOf(one, 'scope').startsWith('process/') && fieldOf(one, 'kind') === 'process' && fieldOf(one, 'value') !== 'withdraw')) {
222
- for (const need of fieldOf(line, 'needs').split('|').filter(Boolean))
223
- walk(resolve(root, need));
224
- }
225
- return seen;
226
- }
1
+ var K=Object.defineProperty;var l=(n,e)=>K(n,"name",{value:e,configurable:!0});import{preparingView as S}from"../host/reading-context.js";import{signatureEraOf as R}from"../host/signature-era.js";import{ledgerLines as _,ledgerWriters as q}from"../land/ledger.js";import{readOnly as y}from"../host/read-only.js";import{appendFileSync as M,dirname as W,join as w,mkdirSync as D,readdirSync as z,realpathSync as V,relative as U,resolve as m}from"../host/io.js";import{bytesDigest as X,fullDigest as G}from"../host/digest.js";import{coordinatesUnder as H,observeFile as $,observeText as A,stampOf as J}from"../observe/files.js";import{releaseOf as P,signedLockLines as Q}from"./keys.js";import{EXTENSION as E,fieldOf as s,foldClaims as Y,selfName as N}from"./claims.js";import{wireLine as Z}from"./wire.js";import{library11_publicLock as ee,library11_LOCK as ne}from"../vendor/runtime.js";import{builtinModules as te,createRequire as ie}from"node:module";import{moduleImports as T}from"../host/adapters/modules/javascript.js";const j=new Map;let re=0;const Ee=l(()=>re,"algorithmCost");function se(n){const e="scope=wire/digest-algorithms",o="scope=audit/wire/digest-algorithms";let i=-1,a="";const c=P(n);if(c){const d=c.find(f=>(s(f,"scope")==="wire/digest-algorithms"||s(f,"scope")==="audit/wire/digest-algorithms")&&s(f,"value")!=="withdraw");return d===void 0?void 0:s(d,"value").split("|").filter(Boolean)[0]?.split(":")[0]}if(!oe(n)){const f=A(w(W(n),ne))?.split(`
2
+ `).filter(O=>O.startsWith("bound-lock/")),g=f===void 0?void 0:ee(f),h=g===void 0?void 0:Z(g,"digest-algorithms");return h===void 0?void 0:s(h,"value").split("|")[0]?.split(":")[0]}for(const d of q(n)){const f=_(n,d).join(`
3
+ `);let g=0;for(;g<f.length;){const h=(()=>{const p=f.indexOf(e,g),u=f.indexOf(o,g);return p<0?u:u<0?p:Math.min(p,u)})();if(h<0)break;const O=f.lastIndexOf(`
4
+ `,h)+1,x=f.indexOf(`
5
+ `,h),v=f.slice(O,x<0?void 0:x);if(g=x<0?f.length:x+1,!v.includes(" sig="))continue;const t=Number(s(v,"epoch"))||0;if(t<i)continue;i=t;const r=s(v,"value");a=r==="withdraw"?"":r.split("|").filter(Boolean)[0]?.split(":")[0]??""}}return a||void 0}l(se,"namedAlgorithm");function oe(n){try{return z(w(n,"ledger")).length>0}catch(e){if(e.code==="ENOENT")return!1;throw e}}l(oe,"existsLedger");function B(n){const e=j.get(n);if(e!==void 0)return e;const o=se(n);if(o===void 0)throw new Error(`${N()}: REFUSE\xB7runtime the lock names no \`wire/digest-algorithms\`: nothing can be digested here`);return j.set(n,o),o}l(B,"algorithmOf");function Me(n,e=[]){return ce(Y([...Q(n,e),...e]).standing)}l(Me,"signaturesOf");function ce(n){try{return R(n)}catch(e){throw new Error(`${N()}: ${e instanceof Error?e.message:String(e)}`)}}l(ce,"eraOf");const k=l((n,e)=>X(e,B(n)),"bytesDigest"),de=l((n,e)=>G(e,B(n)),"fullDigest"),C=new Map,L=l(n=>C.get(n)??C.set(n,new Map((A(w(n,"cas",`stamps${E}`))??"").split(`
6
+ `).flatMap(e=>e.indexOf(" ")>0?[[e.slice(0,e.indexOf(" ")),e.slice(e.indexOf(" ")+1)]]:[]))).get(n),"memoOf");function fe(n,e){const o=J(e);if(o?.kind!=="file")return o===void 0?void 0:k(n,$(e)??new Uint8Array);if(y())return k(n,$(e)??new Uint8Array);const i=`${e} ${o.stamp}`,a=L(n),c=a.get(i);if(c!==void 0)return c;const d=k(n,$(e)??new Uint8Array);return a.set(i,d),y()||(D(w(n,"cas"),{recursive:!0}),M(w(n,"cas",`stamps${E}`),`${i} ${d}
7
+ `)),d}l(fe,"coordinateDigest");function Le(n,e,o){if(S())return o();const i=L(n),a=i.get(e);if(a!==void 0)return a;const c=o();return i.set(e,c),y()||(D(w(n,"cas"),{recursive:!0}),M(w(n,"cas",`stamps${E}`),`${e} ${c}
8
+ `)),c}l(Le,"memoized");const F=new Map,I=l((n,e,o)=>{if(S())return T(new TextDecoder().decode($(e)??new Uint8Array),e);const i=`imports ${de(n,I.toString())} ${o}`,a=L(n),c=F.get(o)??(y()?void 0:a.get(i)?.split("|").filter(Boolean));if(c!==void 0)return c;const d=T(new TextDecoder().decode($(e)??new Uint8Array),e);return F.set(o,d),a.set(i,d.join("|")),y()||M(w(n,"cas",`stamps${E}`),`${i} ${d.join("|")}
9
+ `),d},"importsOf");function Se(n,e,o=[],i,a=[]){const c=i===void 0?m(e):m(i,e);return ae(n,c,o,i??W(c),a).replace(/^[^:]*:/,"").slice(0,12)}l(Se,"instrumentOf");function ae(n,e,o=[],i=W(m(e)),a=[]){const c=le(n,e,o,i,a);return k(n,new TextEncoder().encode([...c.values()].sort().join(`
10
+ `)))}l(ae,"instrumentDigest");function le(n,e,o=[],i=W(m(e)),a=[],c=!1){const d=new Map,f=l(t=>{if(d.has(t))return;const r=c?$(t):void 0,p=c?r===void 0?void 0:k(n,r):fe(n,t);if(p===void 0)return;const u=V(t);if(!d.has(u)){d.set(u,p);for(const b of I(n,u,p))b.startsWith("node:")||te.includes(b)||(b.startsWith(".")?f(m(W(u),b)):f(ie(u).resolve(b)))}},"walk");f(m(e));const g=o.filter(t=>s(t,"scope").startsWith("dep/")&&s(t,"value")!=="withdraw").map(t=>({region:s(t,"scope").slice(4).replace(/\*+$/,""),on:s(t,"value").split("|").filter(r=>r&&r!=="none")})),h=new Map(a.filter(t=>s(t,"scope").startsWith("dep/")&&s(t,"role")==="reads"&&s(t,"needs")&&s(t,"value")!=="withdraw").map(t=>[s(t,"scope").slice(4),s(t,"value")])),O=new Set,x=l(t=>{for(const r of g.find(p=>p.region===t)?.on??[]){if(h.has(r)){d.set(`release:${r}`,h.get(r));continue}for(const p of g.filter(u=>u.region.startsWith(`${r}/`)&&!O.has(u.region))){O.add(p.region);for(const u of H(m(i,p.region),i))f(m(i,u));x(p.region)}}},"follow");x(g.find(t=>U(i,m(e)).startsWith(t.region))?.region);const v=U(i,m(e)).split("/")[0]??"";for(const t of o.filter(r=>s(r,"scope").startsWith(`${v}/process/`)&&s(r,"kind")==="process"&&s(r,"value")!=="withdraw"))for(const r of s(t,"needs").split("|").filter(Boolean))f(m(i,r));for(const t of a.filter(r=>s(r,"scope").startsWith("process/")&&s(r,"kind")==="process"&&s(r,"value")!=="withdraw"))for(const r of s(t,"needs").split("|").filter(Boolean))f(m(i,r));return d}l(le,"instrumentCoordinates");export{Ee as algorithmCost,k as bytesDigest,fe as coordinateDigest,ce as eraOf,de as fullDigest,le as instrumentCoordinates,ae as instrumentDigest,Se as instrumentOf,Le as memoized,Me as signaturesOf};
@@ -1,22 +1 @@
1
- import { compareEvidence } from '@lapxo/topos/authority';
2
- export function snapshotVerdict(input) {
3
- const statement = input.declared ? input.statement : undefined;
4
- const comparison = input.comparison;
5
- const result = compareEvidence({
6
- expected: { reference: input.expected.set, value: input.expected.standing },
7
- ...(statement ? { statement: { admitted: statement.admitted, reference: statement.set, value: statement.standing } } : {}),
8
- ...(comparison ? { comparison: { admitted: comparison.admitted, reference: comparison.set, equal: comparison.verdict === 'agrees' } } : {}),
9
- });
10
- const words = { absent: 'none', unadmitted: 'grey', unresolved: 'stale', stale: 'stale', equal: 'agrees', different: 'forks' };
11
- return { verdict: words[result.relation], external: result.relation !== 'absent' && (input.priorDisagreement === true || result.relation === 'different'),
12
- epoch: result.source === 'comparison' ? comparison.epoch : statement?.epoch ?? 0 };
13
- }
14
- /** This selector belongs to the instrument, not the SDK's abstract evidence contract. */
15
- export function attestationObservations(configuration, result) {
16
- const values = [...new Set(configuration.filter(f => ['wire/attestation-result', 'audit/wire/attestation-result'].includes(f.scope ?? '') && f.value !== 'withdraw').map(f => f.value))];
17
- if (!values.length)
18
- return [];
19
- if (values.length !== 1 || !values[0] || /[|=\s\\*]/.test(values[0]) || values[0].startsWith('/') || values[0].split('/').some(s => !s || s === '.' || s === '..'))
20
- throw Error('REFUSE·authority conflicting or invalid attestation result coordinate');
21
- return [{ coordinate: values[0], value: result.verdict }];
22
- }
1
+ var o=Object.defineProperty;var n=(r,a)=>o(r,"name",{value:a,configurable:!0});import{library0_compareEvidence as s}from"../vendor/runtime.js";function l(r){const a=r.declared?r.statement:void 0,e=r.comparison,t=s({expected:{reference:r.expected.set,value:r.expected.standing},...a?{statement:{admitted:a.admitted,reference:a.set,value:a.standing}}:{},...e?{comparison:{admitted:e.admitted,reference:e.set,equal:e.verdict==="agrees"}}:{}});return{verdict:{absent:"none",unadmitted:"grey",unresolved:"stale",stale:"stale",equal:"agrees",different:"forks"}[t.relation],external:t.relation!=="absent"&&(r.priorDisagreement===!0||t.relation==="different"),epoch:t.source==="comparison"?e.epoch:a?.epoch??0}}n(l,"snapshotVerdict");function u(r,a){const e=[...new Set(r.filter(t=>["wire/attestation-result","audit/wire/attestation-result"].includes(t.scope??"")&&t.value!=="withdraw").map(t=>t.value))];if(!e.length)return[];if(e.length!==1||!e[0]||/[|=\s\\*]/.test(e[0])||e[0].startsWith("/")||e[0].split("/").some(t=>!t||t==="."||t===".."))throw Error("REFUSE\xB7authority conflicting or invalid attestation result coordinate");return[{coordinate:e[0],value:a.verdict}]}n(u,"attestationObservations");export{u as attestationObservations,l as snapshotVerdict};
@@ -1,13 +1 @@
1
- import { parentPort, workerData } from "../host/io.js";
2
- import { foldPlace, standingOf } from "../cli/place.js";
3
- import { renderedOf, unrendered, viewOf } from "../render/view.js";
4
- const data = workerData;
5
- const standing = standingOf(data.root, data.place || undefined, data.told);
6
- const fold = foldPlace(data.root, data.entry, data.place || undefined, false, { standing, observed: data.observed });
7
- parentPort?.postMessage({
8
- place: data.place,
9
- texts: data.views.map((view) => {
10
- const missing = unrendered(fold, view);
11
- return { shape: view.shape, missing, text: missing.length ? '' : viewOf(fold, view), said: missing.length ? [] : renderedOf(fold, view) };
12
- }),
13
- });
1
+ import{parentPort as r,workerData as s}from"../host/io.js";import{foldPlace as a,standingOf as d}from"../cli/place.js";import{renderedOf as p,unrendered as f,viewOf as l}from"../render/view.js";const e=s,c=d(e.root,e.place||void 0,e.told),n=a(e.root,e.entry,e.place||void 0,!1,{standing:c,observed:e.observed});r?.postMessage({place:e.place,texts:e.views.map(t=>{const o=f(n,t);return{shape:t.shape,missing:o,text:o.length?"":l(n,t),said:o.length?[]:p(n,t)}})});