@lapxo/bound 0.2.4 → 0.2.6

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 (333) hide show
  1. package/CITATION.cff +1 -1
  2. package/README.md +20 -3
  3. package/TARGET.bound +85 -47
  4. package/dist/cli/accept.js +61 -590
  5. package/dist/cli/act-result.js +3 -103
  6. package/dist/cli/args.js +3 -44
  7. package/dist/cli/custodian.js +2 -29
  8. package/dist/cli/host.js +4 -32
  9. package/dist/cli/names.js +1 -12
  10. package/dist/cli/native-descendant.js +1 -19
  11. package/dist/cli/native.js +3 -60
  12. package/dist/cli/observe.js +1 -13
  13. package/dist/cli/owner.js +3 -139
  14. package/dist/cli/pass.js +22 -321
  15. package/dist/cli/place.js +6 -282
  16. package/dist/cli/release-result.js +3 -80
  17. package/dist/cli/retained-judgment.js +1 -25
  18. package/dist/cli/standing-result.js +4 -19
  19. package/dist/cli/takes.js +10 -112
  20. package/dist/cli/verb.d.ts +1 -2
  21. package/dist/cli/verb.js +85 -684
  22. package/dist/engine/computation.js +2 -0
  23. package/dist/engine/conformance.js +4 -0
  24. package/dist/engine/encoding.js +1 -2
  25. package/dist/engine/index.d.ts +1 -13
  26. package/dist/engine/index.js +2 -11
  27. package/dist/engine/object.js +1 -38
  28. package/dist/engine/ports.js +2 -117
  29. package/dist/fold/admission-history.js +1 -17
  30. package/dist/fold/bootstrap-anchor.js +1 -28
  31. package/dist/fold/ceilings.js +1 -142
  32. package/dist/fold/claims.js +2 -132
  33. package/dist/fold/closed.js +24 -235
  34. package/dist/fold/configures.js +1 -25
  35. package/dist/fold/digests.js +10 -226
  36. package/dist/fold/evidence.js +1 -22
  37. package/dist/fold/fold-worker.js +1 -13
  38. package/dist/fold/kept.js +12 -173
  39. package/dist/fold/keys.js +3 -91
  40. package/dist/fold/laid.js +3 -90
  41. package/dist/fold/nos.js +1 -48
  42. package/dist/fold/object.js +1 -2
  43. package/dist/fold/observed.js +28 -534
  44. package/dist/fold/opened.js +1 -33
  45. package/dist/fold/own.js +3 -217
  46. package/dist/fold/paid.js +1 -92
  47. package/dist/fold/place-inputs.js +1 -70
  48. package/dist/fold/places.js +3 -100
  49. package/dist/fold/rank.js +1 -9
  50. package/dist/fold/reach.js +1 -83
  51. package/dist/fold/readers.js +6 -142
  52. package/dist/fold/receipts.js +1 -47
  53. package/dist/fold/region-declarations.js +1 -13
  54. package/dist/fold/region.js +8 -286
  55. package/dist/fold/release-policy.js +1 -101
  56. package/dist/fold/resolved.js +6 -145
  57. package/dist/fold/roles.js +2 -59
  58. package/dist/fold/second.js +4 -71
  59. package/dist/fold/shards.js +12 -100
  60. package/dist/fold/signed.js +3 -81
  61. package/dist/fold/signers.js +1 -54
  62. package/dist/fold/stranger.js +6 -24
  63. package/dist/fold/views.js +1 -66
  64. package/dist/fold/wire.js +1 -46
  65. package/dist/fold/zoom.js +3 -81
  66. package/dist/host/act-cost.js +1 -25
  67. package/dist/host/adapters/keys/ed25519.js +1 -30
  68. package/dist/host/adapters/modules/javascript.js +1 -50
  69. package/dist/host/adapters/transport/http.js +1 -28
  70. package/dist/host/admitted-place.js +1 -35
  71. package/dist/host/archive.js +1 -152
  72. package/dist/host/call-context.js +1 -14
  73. package/dist/host/capsule-process.js +2 -62
  74. package/dist/host/capsule.js +9 -171
  75. package/dist/host/cell-receipts.js +12 -128
  76. package/dist/host/command-server.js +4 -0
  77. package/dist/host/commit-result.js +1 -5
  78. package/dist/host/content-needed.js +1 -8
  79. package/dist/host/content-store.js +1 -31
  80. package/dist/host/contextual-place.js +2 -72
  81. package/dist/host/digest.js +2 -15
  82. package/dist/host/hash.js +1 -9
  83. package/dist/host/host-controls.js +1 -19
  84. package/dist/host/in-process-act.js +3 -84
  85. package/dist/host/in-process-context.js +3 -91
  86. package/dist/host/in-process-root.js +6 -84
  87. package/dist/host/in-process.js +4 -55
  88. package/dist/host/index.d.ts +1 -15
  89. package/dist/host/index.js +1 -7
  90. package/dist/host/io.js +1 -11
  91. package/dist/host/lifetime.js +1 -79
  92. package/dist/host/located.js +6 -105
  93. package/dist/host/native/authority-card-view.js +5 -0
  94. package/dist/host/native/authority-card.js +1 -0
  95. package/dist/host/native/bounded-file.js +1 -32
  96. package/dist/host/native/command.js +1 -91
  97. package/dist/host/native/control-bridge-worker.js +2 -88
  98. package/dist/host/native/control-bridge.js +1 -110
  99. package/dist/host/native/control-selection.js +1 -32
  100. package/dist/host/native/custody.js +1 -91
  101. package/dist/host/native/deadline.js +1 -28
  102. package/dist/host/native/descendants.js +1 -528
  103. package/dist/host/native/generated-custodian.js +5 -267
  104. package/dist/host/native/generated.js +1 -379
  105. package/dist/host/native/image.js +1 -45
  106. package/dist/host/native/installed-package.d.ts +1 -0
  107. package/dist/host/native/installed-package.js +5 -0
  108. package/dist/host/native/jobs.js +2 -148
  109. package/dist/host/native/loader.js +1 -269
  110. package/dist/host/native/materialize.js +1 -175
  111. package/dist/host/native/module-closure.js +1 -130
  112. package/dist/host/native/module-delivery.d.ts +1 -62
  113. package/dist/host/native/module-delivery.js +1 -151
  114. package/dist/host/native/module-inventory.js +2 -0
  115. package/dist/host/native/module-syntax.js +1 -69
  116. package/dist/host/native/native-binary.js +1 -115
  117. package/dist/host/native/native-program.js +1 -72
  118. package/dist/host/native/node-jobs.js +3 -187
  119. package/dist/host/native/node-launch.js +1 -159
  120. package/dist/host/native/preload.js +1 -45
  121. package/dist/host/native/probes.js +1 -0
  122. package/dist/host/native/reading-witness-admission.js +5 -0
  123. package/dist/host/native/reading.js +1 -249
  124. package/dist/host/native/receipt-environment.js +1 -41
  125. package/dist/host/native/references.js +1 -30
  126. package/dist/host/native/root.js +1 -37
  127. package/dist/host/native/route.js +1 -216
  128. package/dist/host/native/runtime.js +1 -9
  129. package/dist/host/native-place-state.js +1 -0
  130. package/dist/host/native-reader-context.js +1 -8
  131. package/dist/host/native-receiver.js +1 -25
  132. package/dist/host/objects.js +1 -38
  133. package/dist/host/order.js +1 -2
  134. package/dist/host/persistent-host.js +1 -0
  135. package/dist/host/physical-lines.d.ts +1 -0
  136. package/dist/host/physical-lines.js +1 -0
  137. package/dist/host/place-act-transaction.js +4 -78
  138. package/dist/host/place-clock-selection.js +5 -124
  139. package/dist/host/ports/ingress.js +2 -57
  140. package/dist/host/ports/local-act.js +5 -183
  141. package/dist/host/ports/place-act.js +1 -134
  142. package/dist/host/ports/publication.js +1 -56
  143. package/dist/host/ports/signing.js +1 -74
  144. package/dist/host/ports/store.js +1 -18
  145. package/dist/host/ports/transport.js +1 -48
  146. package/dist/host/process-lifetime.js +1 -17
  147. package/dist/host/profile-composition.d.ts +1 -0
  148. package/dist/host/profile-composition.js +2 -0
  149. package/dist/host/provide.js +1 -183
  150. package/dist/host/read-only.js +1 -9
  151. package/dist/host/reading-closures.js +7 -227
  152. package/dist/host/reading-context.js +1 -53
  153. package/dist/host/reading-identity-types.js +0 -0
  154. package/dist/host/reading-identity.js +3 -0
  155. package/dist/host/reading-preparation.js +6 -0
  156. package/dist/host/reference-authenticated.d.ts +1 -40
  157. package/dist/host/reference-authenticated.js +3 -100
  158. package/dist/host/reference-contracts.js +1 -6
  159. package/dist/host/reference-export.js +6 -81
  160. package/dist/host/reference-native-api.d.ts +1 -3
  161. package/dist/host/reference-native-api.js +1 -3
  162. package/dist/host/reference-native.js +1 -74
  163. package/dist/host/reference-profile.js +1 -63
  164. package/dist/host/reference-standing.js +2 -18
  165. package/dist/host/reference.js +1 -24
  166. package/dist/host/refusals.js +2 -43
  167. package/dist/host/release.js +4 -256
  168. package/dist/host/root-clock-source.js +1 -307
  169. package/dist/host/selected-capsules.js +1 -50
  170. package/dist/host/selected-topos.js +1 -80
  171. package/dist/host/signature-era.js +1 -12
  172. package/dist/host/signing.js +2 -48
  173. package/dist/host/source-content.js +2 -111
  174. package/dist/host/standing-carrier.js +1 -18
  175. package/dist/host/standing-projection.js +1 -50
  176. package/dist/host/timing.js +1 -7
  177. package/dist/host/walk.js +20 -193
  178. package/dist/host/work-trace.js +1 -0
  179. package/dist/judge/late.js +1 -33
  180. package/dist/judge/take.js +2 -75
  181. package/dist/judge/widening.js +1 -25
  182. package/dist/land/act.js +8 -336
  183. package/dist/land/alias.js +1 -41
  184. package/dist/land/held.js +1 -23
  185. package/dist/land/inert.js +1 -33
  186. package/dist/land/leaving.js +1 -55
  187. package/dist/land/ledger.js +6 -188
  188. package/dist/land/owned.js +4 -66
  189. package/dist/land/sign.js +1 -53
  190. package/dist/land/standing-pin.js +1 -49
  191. package/dist/land/vouched.js +1 -112
  192. package/dist/land/withdraw.js +1 -24
  193. package/dist/observe/files.js +1 -88
  194. package/dist/observe/identity.js +1 -61
  195. package/dist/observe/match.js +1 -8
  196. package/dist/observe/regions.js +7 -306
  197. package/dist/observe/run.js +1 -41
  198. package/dist/observe/runner.js +4 -101
  199. package/dist/public-types.d.ts +2019 -0
  200. package/dist/render/capsule.js +1 -30
  201. package/dist/render/field.js +1 -40
  202. package/dist/render/names.js +1 -4
  203. package/dist/render/open.js +1 -61
  204. package/dist/render/page.js +1 -7
  205. package/dist/render/receipt-projection.js +1 -0
  206. package/dist/render/receipts.js +1 -47
  207. package/dist/render/shape.js +1 -74
  208. package/dist/render/target.js +4 -52
  209. package/dist/render/view.js +7 -197
  210. package/dist/vendor/bundle.json +1 -0
  211. package/dist/vendor/library14.js +1 -0
  212. package/dist/vendor/object-provider.js +42 -0
  213. package/dist/vendor/runtime.js +61 -0
  214. package/dist/wasm/adapter.d.ts +1 -51
  215. package/dist/wasm/adapter.js +1 -180
  216. package/dist/wasm/node-worker.js +1 -13
  217. package/dist/wasm/object.js +1 -76
  218. package/dist/wasm/worker.js +1 -7
  219. package/docs/contracts/authenticated-reference.publication.json +1 -1
  220. package/docs/contracts/authority-preflight.md +17 -0
  221. package/docs/contracts/authority-preflight.publication.json +25 -0
  222. package/docs/contracts/closure-delivery.md +1 -1
  223. package/docs/contracts/closure-delivery.publication.json +1 -1
  224. package/docs/contracts/conformance.json +142 -0
  225. package/docs/contracts/determinism.bound +9 -0
  226. package/docs/contracts/engine-object-projection.publication.json +1 -1
  227. package/docs/contracts/engine.md +21 -1
  228. package/docs/contracts/installed-package.md +21 -0
  229. package/docs/contracts/installed-package.publication.json +25 -0
  230. package/docs/contracts/materialized-leaf-sequence.md +15 -0
  231. package/docs/contracts/materialized-leaf-sequence.publication.json +25 -0
  232. package/docs/contracts/module-inventory.md +15 -0
  233. package/docs/contracts/module-inventory.publication.json +25 -0
  234. package/docs/contracts/native-host.md +29 -1
  235. package/docs/contracts/native-host.publication.json +4 -4
  236. package/docs/contracts/native-probes.md +13 -0
  237. package/docs/contracts/native-probes.publication.json +25 -0
  238. package/docs/contracts/native-publication.inventory.json +10 -1
  239. package/docs/contracts/native-view-batch.md +17 -0
  240. package/docs/contracts/native-view-batch.publication.json +25 -0
  241. package/docs/contracts/optional-wasm-adapter.publication.json +1 -1
  242. package/docs/contracts/physical-lines.md +19 -0
  243. package/docs/contracts/physical-lines.publication.json +25 -0
  244. package/docs/contracts/profile-composition.md +17 -0
  245. package/docs/contracts/profile-composition.publication.json +25 -0
  246. package/docs/contracts/profile-preparation-native-meaning.md +9 -0
  247. package/docs/contracts/publication.md +12 -0
  248. package/docs/contracts/reading-identity.md +61 -0
  249. package/docs/contracts/reading-identity.publication.json +25 -0
  250. package/docs/contracts/reading-witness-admission.md +49 -0
  251. package/docs/contracts/readme.publication.json +1 -1
  252. package/docs/contracts/reference-port.md +11 -0
  253. package/docs/contracts/reference-port.publication.json +1 -1
  254. package/docs/contracts/refusals.bound +346 -94
  255. package/docs/contracts/refusals.md +119 -39
  256. package/docs/contracts/refusals.publication.json +2 -2
  257. package/docs/contracts/views.md +8 -0
  258. package/docs/reference.md +9 -0
  259. package/licenses/wasm/{fast-text-encoding.txt → NOTICE.txt} +111 -0
  260. package/package.json +84 -34
  261. package/receipts.bound +12952 -10449
  262. package/samples/authority-preflight/no.json +6 -0
  263. package/samples/authority-preflight/yes.json +30 -0
  264. package/samples/engine-alphabet/reader.js +3 -1457
  265. package/samples/engine-alphabet/receipts.bound +7 -7
  266. package/samples/engine-interval/reader.js +3 -1457
  267. package/samples/engine-interval/receipts.bound +7 -7
  268. package/samples/installed-package/consumer.mjs +29 -0
  269. package/samples/installed-package/fixture.json +48 -0
  270. package/samples/installed-package/no.json +10 -0
  271. package/samples/installed-package/yes.json +52 -0
  272. package/samples/materialized-leaf-sequence/no.json +11 -0
  273. package/samples/materialized-leaf-sequence/yes.json +10 -0
  274. package/samples/module-inventory/yes.json +28 -0
  275. package/samples/native/physical-line-reader.mjs +1 -0
  276. package/samples/native/physical-line-reader.source.mjs +13 -0
  277. package/samples/native-host/no.json +6 -1
  278. package/samples/native-host/yes.json +18 -1
  279. package/samples/native-probes/inputs/inspection.json +28 -0
  280. package/samples/native-probes/no.json +7 -0
  281. package/samples/native-probes/yes.json +28 -0
  282. package/samples/native-view-batch/no.json +14 -0
  283. package/samples/native-view-batch/yes.json +10 -0
  284. package/samples/no/engine-order/reader.js +3 -1457
  285. package/samples/no/module-inventory/no.json +10 -0
  286. package/samples/physical-lines/no.json +5 -0
  287. package/samples/physical-lines/yes.json +9 -0
  288. package/samples/profile-composition/no.json +6 -0
  289. package/samples/profile-composition/yes.json +14 -0
  290. package/samples/reading-identity/no.json +26 -0
  291. package/samples/reading-identity/yes.json +69 -0
  292. package/vectors/native/authority-preflight.vector.json +55 -0
  293. package/vectors/native/installed-package.vector.json +31 -0
  294. package/vectors/native/materialized-leaf-sequence.vector.json +31 -0
  295. package/vectors/native/module-inventory.vector.json +56 -0
  296. package/vectors/native/native-host.vector.json +214 -0
  297. package/vectors/native/native-probes.vector.json +31 -0
  298. package/vectors/native/native-view-batch.vector.json +31 -0
  299. package/vectors/native/physical-lines.vector.json +105 -0
  300. package/vectors/native/profile-composition.vector.json +53 -0
  301. package/vectors/native/reading-identity.vector.json +139 -0
  302. package/vectors/native/refusals.vector.json +138 -0
  303. package/vendor/syntax/LICENSE.md +7 -0
  304. package/vendor/syntax/parser.js +1 -0
  305. package/.github/workflows/release.yml +0 -67
  306. package/.github/workflows/test.yml +0 -35
  307. package/dist/engine/object.d.ts +0 -17
  308. package/dist/engine/ports.d.ts +0 -37
  309. package/dist/fold/claims.d.ts +0 -29
  310. package/dist/host/call-context.d.ts +0 -20
  311. package/dist/host/commit-result.d.ts +0 -6
  312. package/dist/host/in-process-act.d.ts +0 -82
  313. package/dist/host/in-process-context.d.ts +0 -46
  314. package/dist/host/in-process-root.d.ts +0 -117
  315. package/dist/host/in-process.d.ts +0 -41
  316. package/dist/host/native/module-closure.d.ts +0 -35
  317. package/dist/host/native-receiver.d.ts +0 -19
  318. package/dist/host/place-act-transaction.d.ts +0 -24
  319. package/dist/host/place-clock-selection.d.ts +0 -55
  320. package/dist/host/ports/local-act.d.ts +0 -44
  321. package/dist/host/ports/place-act.d.ts +0 -49
  322. package/dist/host/ports/publication.d.ts +0 -10
  323. package/dist/host/reference-export.d.ts +0 -33
  324. package/dist/host/reference-native.d.ts +0 -30
  325. package/dist/host/reference-profile.d.ts +0 -23
  326. package/dist/host/refusals.d.ts +0 -14
  327. package/dist/host/root-clock-source.d.ts +0 -86
  328. package/licenses/wasm/jitl-quickjs-ffi-types.txt +0 -21
  329. package/licenses/wasm/jitl-quickjs-wasmfile-release-sync.txt +0 -47
  330. package/licenses/wasm/quickjs-emscripten-core.txt +0 -21
  331. package/licenses/wasm/topos.txt +0 -21
  332. /package/{licenses/wasm/bound.txt → dist/vendor/28cba430228db1c04f446c93f81b09a2705d6bf3e222d35adbe5a4cee4061884.LICENSE} +0 -0
  333. /package/{licenses/wasm/obligations.txt → dist/vendor/7aca161279d14bc0e054dcc281cd110aeb95be2e026b42fdf527a260e58b2aae.LICENSE} +0 -0
@@ -1,101 +1 @@
1
- import { verdictDemand } from '@lapxo/topos/authority';
2
- import { matches, parse } from '@lapxo/topos/wire';
3
- const fields = (line) => {
4
- const got = parse(line);
5
- return got.kind === 'fact' ? got.value.fields : {};
6
- };
7
- const f = (line, name) => fields(line)[name] ?? '';
8
- const words = (value) => [...new Set(value.split('|').filter(Boolean))];
9
- const active = (line) => f(line, 'value') !== 'withdraw';
10
- const declaration = (line) => active(line) && f(line, 'role') === 'writes' && f(line, 'form') === 'alphabet' && f(line, 'measure') === 'id';
11
- /** Preserve actual fold faults; none gets a release category from its spelling. */
12
- export function releaseFaults(fold) {
13
- return [
14
- ...fold.forks.map((one) => ({ kind: 'fork', evidence: [one.key, ...one.lines] })),
15
- ...fold.refused.map((line) => ({ kind: 'refused', evidence: [line] })),
16
- ...fold.grey.map((line) => ({ kind: 'grey', evidence: [line] })),
17
- ...fold.orphans.map((line) => ({ kind: 'orphan', evidence: [line] })),
18
- ...(fold.second.verdict === 'forks' ? [{ kind: 'second-fork', evidence: [fold.second.verdict] }] : []),
19
- ];
20
- }
21
- /** Select declared obligations, never categories inferred from their names or paths. */
22
- export function releasePolicy(input) {
23
- const policy = [...new Set(input.standing.filter((line) => f(line, 'scope') === 'release/blocks' && declaration(line)))];
24
- const debt = [...new Set([...input.demands, ...input.ceilings])];
25
- const gateLines = input.standing.filter(line => active(line) && f(line, 'role') === 'demands' && f(line, 'form') === 'alphabet' && f(line, 'measure') === 'verdict');
26
- const gates = gateLines.map(line => verdictDemand(fields(line), input.verdicts ?? []));
27
- const base = { snapshot: input.snapshot, policy, debt, gates };
28
- if (!policy.length)
29
- return { ...base, status: 'absent', categories: [], unresolved: [] };
30
- const values = new Set(policy.map((line) => [...words(f(line, 'value'))].sort().join('|')));
31
- const unresolved = [];
32
- for (const fault of input.faults ?? []) {
33
- if (fault.obligation === undefined || !debt.includes(fault.obligation))
34
- unresolved.push(`unclassified ${fault.kind}: ${fault.evidence.join(' | ')}`);
35
- }
36
- if (values.size !== 1)
37
- unresolved.push('release/blocks has conflicting standing values');
38
- const labels = words(f(policy[0], 'value'));
39
- if (!labels.length)
40
- unresolved.push('release/blocks selects no category');
41
- const categories = labels.map((name) => {
42
- const links = [...new Set(input.standing.filter((line) => f(line, 'scope') === `release/category/${name}` && declaration(line)))];
43
- if (!links.length)
44
- unresolved.push(`release/category/${name} has no admitted link`);
45
- if (new Set(links.map((line) => [...words(f(line, 'value'))].sort().join('|'))).size > 1)
46
- unresolved.push(`release/category/${name} has conflicting standing values`);
47
- const selected = new Set();
48
- for (const selector of words(f(links[0] ?? '', 'value'))) {
49
- const met = debt.filter((line) => matches(selector, f(line, 'scope')));
50
- if (!met.length)
51
- unresolved.push(`release/category/${name} selector ${selector} names no obligation`);
52
- met.forEach((line) => selected.add(line));
53
- }
54
- if (!selected.size)
55
- unresolved.push(`release/category/${name} selects no obligation`);
56
- const failures = [];
57
- for (const line of selected) {
58
- for (const fault of input.faults ?? [])
59
- if (fault.obligation === line)
60
- failures.push({ line, reason: fault.kind, evidence: [...fault.evidence] });
61
- if (input.demands.includes(line)) {
62
- const gate = gateLines.includes(line) ? verdictDemand(fields(line), input.verdicts ?? []) : undefined;
63
- if (gate) {
64
- if (gate.status !== 'met')
65
- failures.push({ line, reason: gate.status, evidence: gate.evidence.map(e => `${e.coordinate}=${e.value}`) });
66
- continue;
67
- }
68
- if (!input.paid.includes(line))
69
- failures.push({ line, reason: 'missing', evidence: [] });
70
- continue;
71
- }
72
- const scope = f(line, 'scope');
73
- const over = input.readings.over.filter((one) => one.ceiling === scope);
74
- if (over.length && input.ceilings.filter((one) => f(one, 'scope') === scope).length !== 1)
75
- unresolved.push(`ceiling evidence for ${scope} does not identify one obligation`);
76
- if (over.length)
77
- failures.push({ line, reason: 'outside', evidence: over.map((one) => `${one.side} ${one.question} ${one.got}`) });
78
- if (input.readings.unread.includes(line))
79
- failures.push({ line, reason: 'unread', evidence: [] });
80
- if (input.readings.vacuous.includes(line))
81
- failures.push({ line, reason: 'vacuous', evidence: [] });
82
- if (!input.readings.read.includes(line) && !input.readings.unread.includes(line) && !input.readings.vacuous.includes(line)) {
83
- unresolved.push(`ceiling ${scope} has no result in this fold`);
84
- }
85
- }
86
- return { name, links, selected: [...selected], failures };
87
- });
88
- return { ...base, categories, unresolved: [...new Set(unresolved)], status: unresolved.length ? 'incomplete' : categories.some((one) => one.failures.length) ? 'blocked' : 'ready' };
89
- }
90
- /** Existing fold output can show the policy without a new view or a release action. */
91
- export function releasePolicyLines(result) {
92
- if (result === undefined)
93
- return [];
94
- const gates = (result.gates ?? []).map(g => `GATE ${g.scope} ${g.status} · requires=${g.required.join('|')} · ${g.evidence.map(e => `${e.coordinate}=${e.value}`).join(' | ') || g.reason || 'no evidence'}`);
95
- return [
96
- ...gates,
97
- `RELEASE policy ${result.status} · fold ${result.snapshot.fold} · instrument ${result.snapshot.instrument}`,
98
- ...result.unresolved.map((one) => `UNRESOLVED release · ${one}`),
99
- ...result.categories.flatMap((one) => one.failures.map((failure) => `BLOCK ${one.name} · ${f(failure.line, 'scope')} · ${failure.reason}${failure.evidence.length ? ` · ${failure.evidence.join(' | ')}` : ''}`)),
100
- ];
101
- }
1
+ var L=Object.defineProperty;var d=(e,o)=>L(e,"name",{value:o,configurable:!0});import{library3_verdictDemand as y}from"../vendor/runtime.js";import{library14_matches as q,library14_parse as x}from"../vendor/runtime.js";const p=d(e=>{const o=x(e);return o.kind==="fact"?o.value.fields:{}},"fields"),i=d((e,o)=>p(e)[o]??"","f"),h=d(e=>[...new Set(e.split("|").filter(Boolean))],"words"),w=d(e=>i(e,"value")!=="withdraw","active"),S=d(e=>w(e)&&i(e,"role")==="writes"&&i(e,"form")==="alphabet"&&i(e,"measure")==="id","declaration");function A(e){return[...e.forks.map(o=>({kind:"fork",evidence:[o.key,...o.lines]})),...e.refused.map(o=>({kind:"refused",evidence:[o]})),...e.grey.map(o=>({kind:"grey",evidence:[o]})),...e.orphans.map(o=>({kind:"orphan",evidence:[o]})),...e.second.verdict==="forks"?[{kind:"second-fork",evidence:[e.second.verdict]}]:[]]}d(A,"releaseFaults");function B(e){const o=[...new Set(e.standing.filter(s=>i(s,"scope")==="release/blocks"&&S(s)))],t=[...new Set([...e.demands,...e.ceilings])],r=e.standing.filter(s=>w(s)&&i(s,"role")==="demands"&&i(s,"form")==="alphabet"&&i(s,"measure")==="verdict"),E=r.map(s=>y(p(s),e.verdicts??[])),m={snapshot:e.snapshot,policy:o,debt:t,gates:E};if(!o.length)return{...m,status:"absent",categories:[],unresolved:[]};const j=new Set(o.map(s=>[...h(i(s,"value"))].sort().join("|"))),c=[];for(const s of e.faults??[])(s.obligation===void 0||!t.includes(s.obligation))&&c.push(`unclassified ${s.kind}: ${s.evidence.join(" | ")}`);j.size!==1&&c.push("release/blocks has conflicting standing values");const $=h(i(o[0],"value"));$.length||c.push("release/blocks selects no category");const b=$.map(s=>{const g=[...new Set(e.standing.filter(n=>i(n,"scope")===`release/category/${s}`&&S(n)))];g.length||c.push(`release/category/${s} has no admitted link`),new Set(g.map(n=>[...h(i(n,"value"))].sort().join("|"))).size>1&&c.push(`release/category/${s} has conflicting standing values`);const v=new Set;for(const n of h(i(g[0]??"","value"))){const f=t.filter(u=>q(n,i(u,"scope")));f.length||c.push(`release/category/${s} selector ${n} names no obligation`),f.forEach(u=>v.add(u))}v.size||c.push(`release/category/${s} selects no obligation`);const l=[];for(const n of v){for(const a of e.faults??[])a.obligation===n&&l.push({line:n,reason:a.kind,evidence:[...a.evidence]});if(e.demands.includes(n)){const a=r.includes(n)?y(p(n),e.verdicts??[]):void 0;if(a){a.status!=="met"&&l.push({line:n,reason:a.status,evidence:a.evidence.map(k=>`${k.coordinate}=${k.value}`)});continue}e.paid.includes(n)||l.push({line:n,reason:"missing",evidence:[]});continue}const f=i(n,"scope"),u=e.readings.over.filter(a=>a.ceiling===f);u.length&&e.ceilings.filter(a=>i(a,"scope")===f).length!==1&&c.push(`ceiling evidence for ${f} does not identify one obligation`),u.length&&l.push({line:n,reason:"outside",evidence:u.map(a=>`${a.side} ${a.question} ${a.got}`)}),e.readings.unread.includes(n)&&l.push({line:n,reason:"unread",evidence:[]}),e.readings.vacuous.includes(n)&&l.push({line:n,reason:"vacuous",evidence:[]}),!e.readings.read.includes(n)&&!e.readings.unread.includes(n)&&!e.readings.vacuous.includes(n)&&c.push(`ceiling ${f} has no result in this fold`)}return{name:s,links:g,selected:[...v],failures:l}});return{...m,categories:b,unresolved:[...new Set(c)],status:c.length?"incomplete":b.some(s=>s.failures.length)?"blocked":"ready"}}d(B,"releasePolicy");function O(e){return e===void 0?[]:[...(e.gates??[]).map(t=>`GATE ${t.scope} ${t.status} \xB7 requires=${t.required.join("|")} \xB7 ${t.evidence.map(r=>`${r.coordinate}=${r.value}`).join(" | ")||t.reason||"no evidence"}`),`RELEASE policy ${e.status} \xB7 fold ${e.snapshot.fold} \xB7 instrument ${e.snapshot.instrument}`,...e.unresolved.map(t=>`UNRESOLVED release \xB7 ${t}`),...e.categories.flatMap(t=>t.failures.map(r=>`BLOCK ${t.name} \xB7 ${i(r.line,"scope")} \xB7 ${r.reason}${r.evidence.length?` \xB7 ${r.evidence.join(" | ")}`:""}`))]}d(O,"releasePolicyLines");export{A as releaseFaults,B as releasePolicy,O as releasePolicyLines};
@@ -1,145 +1,6 @@
1
- import { readOnly } from "../host/read-only.js";
2
- import { createHash, dirname, existsSync, join, linkSync, mkdirSync, readdirSync, renameSync, writeFileSync } from "../host/io.js";
3
- import { canonical, parse } from '@lapxo/topos/wire';
4
- import { RECEIPTS, fieldOf, isWire } from "./claims.js";
5
- import { bytesDigest } from "./digests.js";
6
- import { carriesOnly } from "./observed.js";
7
- import { writerFor } from "./signers.js";
8
- import { viewsOf } from "./views.js";
9
- import { zoomed } from "./zoom.js";
10
- import { ledgerLines, storeAt } from "../land/ledger.js";
11
- import { sourced } from "../land/vouched.js";
12
- import { entriesIn, observeFile, observeText } from "../observe/files.js";
13
- export const bytesOnly = (line) => {
14
- const got = parse(line);
15
- // Authenticated evidence is delivered verbatim. A shortened observation is
16
- // a different signed message, even when it describes the same input.
17
- if (got.kind === 'fact' && got.value.fields.sig)
18
- return line;
19
- return got.kind === 'fact' && fieldOf(line, 'measure') === 'observed' ? canonical({ ...got.value.fields, value: fieldOf(line, 'at').replace(/^.*:/, '').slice(0, 16) }) : line;
20
- };
21
- const held = new WeakMap();
22
- /**
23
- * Every receipt of a place, @8: the bytes of what it observed that a reading ran over, those readings, the verdicts its
24
- * paid demands were taken with, and at the root the digest of each place's own receipts. The attest is none of them:
25
- * it stands in the root lock and the release, naming the root these lines resolve to. The fold keeps the set in the
26
- * root's store under the digest of its bytes, which every line that resolves it names, and what a place with no reader
27
- * carries is read back from there, never from a file the place ships.
28
- */
29
- export function receiptsOf(fold) {
30
- const kept = held.get(fold);
31
- if (kept !== undefined)
32
- return kept;
33
- if (!fold.observed.length && carriesOnly(fold.root, fold.store))
34
- return held.set(fold, [...new Set(carriedIn(fold.store).flatMap((file) => (observeText(file) ?? '').split('\n').filter(isWire)))]).get(fold);
35
- const under = fold.under ?? '';
36
- const shape = [...viewsOf(fold.standing).values()].flatMap((view) => ('regions' in view && view.regions.some((one) => one.name === 'receipts') ? [view.shape] : []))[0] ?? '';
37
- const closed = under || !shape ? [] : entriesIn(fold.root).filter((entry) => entry.dir && observeText(join(fold.root, entry.name, shape)) !== undefined).map((entry) => `${entry.name}/`).sort();
38
- const own = (place) => place.startsWith(under) && !closed.some((one) => place.startsWith(one)) && (!shape || !place.endsWith(shape));
39
- const mine = new Set(fold.observed.filter((line) => fieldOf(line, 'measure') === 'observed' && own(fieldOf(line, 'scope')))
40
- .map((line) => `${fieldOf(line, 'by')} ${fieldOf(line, 'at')}`));
41
- const ran = [...new Set(fold.observed.filter((line) => fieldOf(line, 'measure') !== 'observed'
42
- && mine.has(`${fieldOf(line, 'by')} ${fieldOf(line, 'at')}`)))];
43
- const ranAt = new Set(ran.map((line) => `${fieldOf(line, 'by')} ${fieldOf(line, 'at')}`));
44
- const cones = new Set(fold.observed.filter((line) => {
45
- if (fieldOf(line, 'measure') !== 'observed')
46
- return false;
47
- const at = fieldOf(line, 'at'), by = fieldOf(line, 'by');
48
- // A physical input witnesses an owned reading's base, without becoming
49
- // another location of its result. Even a foreign input belongs in that
50
- // reading's portable carrier; its own child place is not the reader.
51
- if (at.startsWith('witness:'))
52
- return ranAt.has(`${by} place:${at.slice('witness:'.length)}`);
53
- return own(fieldOf(line, 'scope')) && ranAt.has(`${by} ${at}`);
54
- }).map(bytesOnly));
55
- const paid = ledgerLines(fold.store, 'judge').filter((line) => fold.paid.some((demand) => fieldOf(demand, 'scope') === fieldOf(line, 'scope')
56
- && !(closed.length > 0 && fieldOf(demand, 'needs').split('|').filter(Boolean).length > 0
57
- && fieldOf(demand, 'needs').split('|').filter(Boolean).every((need) => closed.some((one) => need.startsWith(one))))));
58
- const named = closed.map((place) => {
59
- const digest = bytesDigest(fold.store, observeFile(join(fold.root, place, shape)) ?? new Uint8Array());
60
- return canonical({ scope: `${sourced(fold.standing)}/${place}${shape}`, role: 'writes', form: 'alphabet', measure: 'digest', value: digest, by: writerFor(fold.standing, 'fold') ?? '', at: `place:${digest}` });
61
- });
62
- const place = under.replace(/\/$/, '');
63
- const lines = [...new Set([...named, ...[...cones].sort(), ...[...ran].sort(), ...paid, ...(fold.receiptHistory ?? [])])]
64
- .map((line) => (place && !fieldOf(line, 'sig') ? zoomed(line, place) : line));
65
- if (!lines.length) {
66
- const shipped = (observeText(join(fold.root, under, RECEIPTS)) ?? '').split('\n').filter(isWire);
67
- const carried = carriedFrom(fold.store, shipped);
68
- if (carried !== undefined && carried.length)
69
- return held.set(fold, carried).get(fold);
70
- }
71
- held.set(fold, lines);
72
- keepCarried(fold.store, lines);
73
- return lines;
74
- }
75
- export function keepCarried(store, lines, from) {
76
- const text = lines.map((line) => `${line}\n`).join('');
77
- const digest = createHash('sha256').update(text).digest('hex');
78
- const at = storeAt(store, 'cas', 'carried', digest);
79
- if (existsSync(at)) {
80
- verifiedCarried(at, digest);
81
- }
82
- else {
83
- if (readOnly())
84
- return `sha256:${digest}`;
85
- mkdirSync(dirname(at), { recursive: true });
86
- const src = from === undefined ? '' : storeAt(from, 'cas', 'carried', digest);
87
- if (src && existsSync(src)) {
88
- verifiedCarried(src, digest);
89
- try {
90
- linkSync(src, at);
91
- return `sha256:${digest}`;
92
- }
93
- catch {
94
- // Cross-device stores still keep the authenticated bytes below.
95
- }
96
- }
97
- writeFileSync(`${at}.${process.pid}`, text);
98
- renameSync(`${at}.${process.pid}`, at);
99
- }
100
- return `sha256:${digest}`;
101
- }
102
- /**
103
- * What a copy of a place reads back of its receipts: the lines it shipped when they are the whole set, or, when they
104
- * name a root at the digest of its bytes, the set the store keeps there; a root the store does not keep is no set, and
105
- * the caller refuses rather than read the lines that only name it.
106
- */
107
- export function carriedFrom(store, shipped) {
108
- // Signed receipts inside the observed set are evidence, not its framing.
109
- const headerOf = (line) => fieldOf(line, 'scope') === 'receipts' && fieldOf(line, 'measure') === 'digest' && fieldOf(line, 'by') === 'bound' && !fieldOf(line, 'sig');
110
- const named = shipped.find(headerOf);
111
- if (named === undefined)
112
- return shipped;
113
- // Resolution 8 may precede its authenticated summary in the same public file.
114
- // It is evidence only if its exact bytes meet the summary's carrier digest.
115
- for (let i = 1; i < shipped.length; i += 1) {
116
- const header = shipped[i];
117
- if (!headerOf(header))
118
- continue;
119
- const digest = fieldOf(header, 'at').replace(/^place:sha256:/, '');
120
- const body = shipped.slice(0, i);
121
- if (/^[0-9a-f]{64}$/.test(digest) && createHash('sha256').update(body.map(line => `${line}\n`).join('')).digest('hex') === digest)
122
- return body;
123
- }
124
- if (shipped.indexOf(named) > 0)
125
- throw Error('REFUSE·receipt public carrier bytes mismatch; a cached carrier cannot replace supplied evidence');
126
- const hex = fieldOf(named, 'at').replace(/^place:(?:sha256:)?/, '');
127
- const text = /^[0-9a-f]{64}$/.test(hex) ? verifiedCarried(storeAt(store, 'cas', 'carried', hex), hex) : undefined;
128
- return text === undefined ? undefined : text.split('\n').filter(isWire);
129
- }
130
- export const carriedIn = (store) => ((dir) => (existsSync(dir)
131
- ? readdirSync(dir).filter((name) => /^[0-9a-f]{64}$/.test(name)).sort().map((name) => {
132
- const at = join(dir, name);
133
- verifiedCarried(at, name);
134
- return at;
135
- }) : []))(storeAt(store, 'cas', 'carried'));
136
- /** Authenticate the existing SHA-256 receipt carrier before interpreting any lines. */
137
- function verifiedCarried(at, expected) {
138
- const bytes = observeFile(at);
139
- if (bytes === undefined)
140
- return undefined;
141
- const actual = createHash('sha256').update(bytes).digest('hex');
142
- if (actual !== expected)
143
- throw Error(`REFUSE·receipt carried bytes mismatch · expected sha256:${expected} · got sha256:${actual}`);
144
- return new TextDecoder('utf-8', { fatal: true }).decode(bytes);
145
- }
1
+ var A=Object.defineProperty;var u=(e,s)=>A(e,"name",{value:s,configurable:!0});import{readOnly as C}from"../host/read-only.js";import{createHash as w,dirname as I,existsSync as x,join as $,linkSync as M,mkdirSync as R,readdirSync as T,renameSync as U,writeFileSync as B}from"../host/io.js";import{library14_canonical as k,library14_parse as D}from"../vendor/runtime.js";import{RECEIPTS as H,fieldOf as r,isWire as S}from"./claims.js";import{bytesDigest as _}from"./digests.js";import{carriesOnly as z}from"./observed.js";import{writerFor as L}from"./signers.js";import{viewsOf as P}from"./views.js";import{zoomed as q}from"./zoom.js";import{ledgerLines as G,storeAt as b}from"../land/ledger.js";import{sourced as J}from"../land/vouched.js";import{entriesIn as K,observeFile as W,observeText as E}from"../observe/files.js";const N=u(e=>{const s=D(e);return s.kind==="fact"&&s.value.fields.sig?e:s.kind==="fact"&&r(e,"measure")==="observed"?k({...s.value.fields,value:r(e,"at").replace(/^.*:/,"").slice(0,16)}):e},"bytesOnly"),y=new WeakMap;function de(e){const s=y.get(e);if(s!==void 0)return s;if(!e.observed.length&&z(e.root,e.store))return y.set(e,[...new Set(X(e.store).flatMap(t=>(E(t)??"").split(`
2
+ `).filter(S)))]).get(e);const n=e.under??"",a=[...P(e.standing).values()].flatMap(t=>"regions"in t&&t.regions.some(o=>o.name==="receipts")?[t.shape]:[])[0]??"",c=n||!a?[]:K(e.root).filter(t=>t.dir&&E($(e.root,t.name,a))!==void 0).map(t=>`${t.name}/`).sort(),p=u(t=>t.startsWith(n)&&!c.some(o=>t.startsWith(o))&&(!a||!t.endsWith(a)),"own"),i=new Set(e.observed.filter(t=>r(t,"measure")==="observed"&&p(r(t,"scope"))).map(t=>`${r(t,"by")} ${r(t,"at")}`)),d=[...new Set(e.observed.filter(t=>r(t,"measure")!=="observed"&&i.has(`${r(t,"by")} ${r(t,"at")}`)))],m=new Set(d.map(t=>`${r(t,"by")} ${r(t,"at")}`)),f=new Set(e.observed.filter(t=>{if(r(t,"measure")!=="observed")return!1;const o=r(t,"at"),g=r(t,"by");return o.startsWith("witness:")?m.has(`${g} place:${o.slice(8)}`):p(r(t,"scope"))&&m.has(`${g} ${o}`)}).map(N)),v=G(e.store,"judge").filter(t=>e.paid.some(o=>r(o,"scope")===r(t,"scope")&&!(c.length>0&&r(o,"needs").split("|").filter(Boolean).length>0&&r(o,"needs").split("|").filter(Boolean).every(g=>c.some(j=>g.startsWith(j)))))),F=c.map(t=>{const o=_(e.store,W($(e.root,t,a))??new Uint8Array);return k({scope:`${J(e.standing)}/${t}${a}`,role:"writes",form:"alphabet",measure:"digest",value:o,by:L(e.standing,"fold")??"",at:`place:${o}`})}),O=n.replace(/\/$/,""),h=[...new Set([...F,...[...f].sort(),...[...d].sort(),...v,...e.receiptHistory??[]])].map(t=>O&&!r(t,"sig")?q(t,O):t);if(!h.length){const t=(E($(e.root,n,H))??"").split(`
3
+ `).filter(S),o=V(e.store,t);if(o!==void 0&&o.length)return y.set(e,o).get(e)}return y.set(e,h),Q(e.store,h),h}u(de,"receiptsOf");function Q(e,s,n){const a=s.map(i=>`${i}
4
+ `).join(""),c=w("sha256").update(a).digest("hex"),p=b(e,"cas","carried",c);if(x(p))l(p,c);else{if(C())return`sha256:${c}`;R(I(p),{recursive:!0});const i=n===void 0?"":b(n,"cas","carried",c);if(i&&x(i)){l(i,c);try{return M(i,p),`sha256:${c}`}catch{}}B(`${p}.${process.pid}`,a),U(`${p}.${process.pid}`,p)}return`sha256:${c}`}u(Q,"keepCarried");function V(e,s){const n=u(i=>r(i,"scope")==="receipts"&&r(i,"measure")==="digest"&&r(i,"by")==="bound"&&!r(i,"sig"),"headerOf"),a=s.find(n);if(a===void 0)return s;for(let i=1;i<s.length;i+=1){const d=s[i];if(!n(d))continue;const m=r(d,"at").replace(/^place:sha256:/,""),f=s.slice(0,i);if(/^[0-9a-f]{64}$/.test(m)&&w("sha256").update(f.map(v=>`${v}
5
+ `).join("")).digest("hex")===m)return f}if(s.indexOf(a)>0)throw Error("REFUSE\xB7receipt public carrier bytes mismatch; a cached carrier cannot replace supplied evidence");const c=r(a,"at").replace(/^place:(?:sha256:)?/,""),p=/^[0-9a-f]{64}$/.test(c)?l(b(e,"cas","carried",c),c):void 0;return p===void 0?void 0:p.split(`
6
+ `).filter(S)}u(V,"carriedFrom");const X=u(e=>(s=>x(s)?T(s).filter(n=>/^[0-9a-f]{64}$/.test(n)).sort().map(n=>{const a=$(s,n);return l(a,n),a}):[])(b(e,"cas","carried")),"carriedIn");function l(e,s){const n=W(e);if(n===void 0)return;const a=w("sha256").update(n).digest("hex");if(a!==s)throw Error(`REFUSE\xB7receipt carried bytes mismatch \xB7 expected sha256:${s} \xB7 got sha256:${a}`);return new TextDecoder("utf-8",{fatal:!0}).decode(n)}u(l,"verifiedCarried");export{N as bytesOnly,V as carriedFrom,X as carriedIn,Q as keepCarried,de as receiptsOf};
@@ -1,59 +1,2 @@
1
- import { createHash, dirname, join } from "../host/io.js";
2
- import { parse, roleClaimsOf } from '@lapxo/topos/wire';
3
- import { namesAt, roleAt } from "./wire.js";
4
- import { lockStanding } from "./keys.js";
5
- import { placesIn } from "./places.js";
6
- import { ownLockOf } from "./signed.js";
7
- import { observeText } from "../observe/files.js";
8
- import { fieldOf, isWire } from "./claims.js";
9
- /** A lock line that gives a coordinate its role: every walk of the tree reads it. */
10
- export function isRoleLock(line) {
11
- const got = parse(line);
12
- return got.kind === 'fact' && roleClaimsOf([got.value.fields]).length > 0;
13
- }
14
- /** A lock the owner signs by digest and a capsule writes: its lines stand while the bytes are the ones that were signed. */
15
- export function inheritedRoles(store) {
16
- const root = dirname(store);
17
- const claims = [];
18
- const stale = [];
19
- for (const line of lockStanding(store)) {
20
- if (fieldOf(line, 'measure') !== 'role' || !fieldOf(line, 'scope').startsWith('roles/'))
21
- continue;
22
- const at = fieldOf(line, 'needs');
23
- const held = at ? observeText(join(root, at)) : undefined;
24
- const digest = held === undefined ? '' : `sha256:${createHash('sha256').update(held).digest('hex')}`;
25
- if (held === undefined || digest !== fieldOf(line, 'restsOn')) {
26
- stale.push(fieldOf(line, 'scope'));
27
- continue;
28
- }
29
- for (const one of held.split('\n').filter(isWire).map((row) => parse(row))) {
30
- if (one.kind === 'fact')
31
- claims.push(one.value.fields);
32
- }
33
- }
34
- return { claims: roleClaimsOf(claims), stale };
35
- }
36
- /**
37
- * What each coordinate of the tree is: the capsule that knows a world writes the roles of that world, the owner signs the
38
- * capsule's lock by digest, and this fold reads both. The instrument reads claims and never a name, and a coordinate no
39
- * standing claim names is source. The steps a walk must not enter are read the same way: the claims that name a whole
40
- * folder foreign or derived, as a set the walk can ask in one step instead of matching every claim at every step.
41
- */
42
- export function stepsOutside(store) {
43
- const own = roleClaimsOf(lockStanding(store)
44
- .map((line) => parse(line))
45
- .flatMap((got) => (got.kind === 'fact' ? [got.value.fields] : [])));
46
- return new Set([...own, ...inheritedRoles(store).claims]
47
- .filter((claim) => (claim.role === 'foreign' || claim.role === 'derived') && !claim.name.includes('/') && !claim.name.includes('*'))
48
- .map((claim) => claim.name));
49
- }
50
- export function rolesOf(store) {
51
- const fields = (lines) => lines.map((line) => parse(line)).flatMap((got) => (got.kind === 'fact' ? [got.value.fields] : []));
52
- const claims = [...roleClaimsOf(fields(lockStanding(store))), ...inheritedRoles(store).claims];
53
- const root = dirname(store);
54
- const placed = new Map(placesIn(root).map((place) => [place, roleClaimsOf(fields(ownLockOf(root, place)))]));
55
- return (coordinate) => {
56
- const own = coordinate.includes('/') ? placed.get(coordinate.slice(0, coordinate.indexOf('/'))) ?? [] : [];
57
- return roleAt(coordinate, own.some((claim) => namesAt(coordinate, claim.name)) ? own : claims);
58
- };
59
- }
1
+ var k=Object.defineProperty;var r=(n,o)=>k(n,"name",{value:o,configurable:!0});import{createHash as x,dirname as u,join as v}from"../host/io.js";import{library14_parse as c,library14_roleClaimsOf as a}from"../vendor/runtime.js";import{namesAt as g,roleAt as w}from"./wire.js";import{lockStanding as p}from"./keys.js";import{placesIn as b}from"./places.js";import{ownLockOf as M}from"./signed.js";import{observeText as y}from"../observe/files.js";import{fieldOf as l,isWire as A}from"./claims.js";function T(n){const o=c(n);return o.kind==="fact"&&a([o.value.fields]).length>0}r(T,"isRoleLock");function h(n){const o=u(n),e=[],f=[];for(const i of p(n)){if(l(i,"measure")!=="role"||!l(i,"scope").startsWith("roles/"))continue;const s=l(i,"needs"),t=s?y(v(o,s)):void 0,m=t===void 0?"":`sha256:${x("sha256").update(t).digest("hex")}`;if(t===void 0||m!==l(i,"restsOn")){f.push(l(i,"scope"));continue}for(const d of t.split(`
2
+ `).filter(A).map(O=>c(O)))d.kind==="fact"&&e.push(d.value.fields)}return{claims:a(e),stale:f}}r(h,"inheritedRoles");function $(n){const o=a(p(n).map(e=>c(e)).flatMap(e=>e.kind==="fact"?[e.value.fields]:[]));return new Set([...o,...h(n).claims].filter(e=>(e.role==="foreign"||e.role==="derived")&&!e.name.includes("/")&&!e.name.includes("*")).map(e=>e.name))}r($,"stepsOutside");function q(n){const o=r(s=>s.map(t=>c(t)).flatMap(t=>t.kind==="fact"?[t.value.fields]:[]),"fields"),e=[...a(o(p(n))),...h(n).claims],f=u(n),i=new Map(b(f).map(s=>[s,a(o(M(f,s)))]));return s=>{const t=s.includes("/")?i.get(s.slice(0,s.indexOf("/")))??[]:[];return w(s,t.some(m=>g(s,m.name))?t:e)}}r(q,"rolesOf");export{h as inheritedRoles,T as isRoleLock,q as rolesOf,$ as stepsOutside};
@@ -1,71 +1,4 @@
1
- import { readOnly } from "../host/read-only.js";
2
- import { snapshotVerdict } from "./evidence.js";
3
- import { dirname, resolve, spawnSync } from "../host/io.js";
4
- import { ledgerLines } from "../land/ledger.js";
5
- import { ownLock } from "../observe/runner.js";
6
- import { fieldOf } from "./claims.js";
7
- import { keyOf, lockLines } from "./keys.js";
8
- import { digestsOf, finerOf, regionsOf } from "./region.js";
9
- import { said } from "./wire.js";
10
- import { sha } from "../host/hash.js";
11
- const asked = new Map();
12
- function askedNow(store, rests) {
13
- if (readOnly())
14
- return undefined;
15
- const root = dirname(store);
16
- const key = `${root} ${rests}`;
17
- if (asked.has(key))
18
- return asked.get(key);
19
- const argv = said(ownLock(), 'head/second');
20
- const got = argv.length ? spawnSync(process.execPath, ['--disable-warning=ExperimentalWarning', '--disable-warning=MODULE_TYPELESS_PACKAGE_JSON',
21
- resolve(root, argv[0]), ...argv.slice(1), root], { cwd: root, encoding: 'utf8', maxBuffer: 1 << 26 }) : undefined;
22
- const line = got === undefined || got.status !== 0 || typeof got.stdout !== 'string' ? undefined : got.stdout.split('\n').find((one) => one.startsWith('VERIFY'));
23
- const word = line === undefined ? undefined : line.slice('VERIFY'.length).trim().split(' ')[0];
24
- const verdict = word === 'agrees' || word === 'forks' ? word : undefined;
25
- asked.set(key, verdict);
26
- return verdict;
27
- }
28
- /**
29
- * The second head's word, read against this fold. It attests the digest of the lines it found standing and the digest
30
- * of the lines of the ledger it folded, in whatever order a store landed them, so a clone that lands the same lines
31
- * agrees; agreement is an encounter, disagreement a fork. A word about another lock is not read as this one's: the head
32
- * bound's own lock names is asked now over the ledger as it stands, with no key, and what it says is read, never kept.
33
- */
34
- export function secondHead(store, standing, admitted, owned = lockLines(store)) {
35
- const head = keyOf(store, 'attest');
36
- const said = head === undefined ? [] : ledgerLines(store, head).filter((line) => fieldOf(line, 'scope') === `${head}/target`);
37
- const last = said.at(-1);
38
- const lines = owned.filter((line) => /\bsig=/.test(line));
39
- const rests = `sha256:${sha([...new Set(lines)].sort().join('\n'))}`;
40
- const epoch = lines.reduce((most, line) => Math.max(most, Number(fieldOf(line, 'epoch')) || 0), 0);
41
- const input = {
42
- declared: head !== undefined,
43
- expected: { set: lines.length ? rests : undefined, standing: `place:sha256:${sha([...new Set(standing)].sort().join('\n'))}`, epoch },
44
- ...(last ? { statement: { admitted: admitted(last), set: fieldOf(last, 'restsOn'), standing: fieldOf(last, 'at'), epoch: Number(fieldOf(last, 'epoch')) || 0 } } : {}),
45
- priorDisagreement: said.some(line => fieldOf(line, 'value') === 'forks' && admitted(line)),
46
- };
47
- let result = snapshotVerdict(input);
48
- if (result.verdict === 'stale' && last && lines.length) {
49
- const now = askedNow(store, rests);
50
- if (now !== undefined)
51
- result = snapshotVerdict({ ...input, comparison: { admitted: true, set: rests, verdict: now, epoch } });
52
- }
53
- if (result.verdict !== 'forks' || head === undefined || last === undefined || fieldOf(last, 'restsOn') !== rests)
54
- return result;
55
- const theirs = new Map(ledgerLines(store, head).filter((line) => fieldOf(line, 'scope').startsWith(`${head}/region/`) && fieldOf(line, 'restsOn') === fieldOf(last, 'restsOn'))
56
- .map((line) => [fieldOf(line, 'scope').slice(`${head}/region/`.length).replace(/^\.$/, ''), fieldOf(line, 'value')]));
57
- if (!theirs.size)
58
- return result;
59
- const regions = regionsOf(standing, standing, []);
60
- const [ours, finer] = [digestsOf(regions), finerOf(regions)];
61
- const apart = [];
62
- const descend = (region) => {
63
- if (theirs.get(region) === ours.get(region))
64
- return;
65
- apart.push(region || '.');
66
- for (const one of finer.get(region) ?? [])
67
- descend(one);
68
- };
69
- descend('');
70
- return { ...result, apart };
71
- }
1
+ var y=Object.defineProperty;var m=(r,i)=>y(r,"name",{value:i,configurable:!0});import{readOnly as L}from"../host/read-only.js";import{snapshotVerdict as $}from"./evidence.js";import{dirname as M,resolve as N,spawnSync as P}from"../host/io.js";import{ledgerLines as E}from"../land/ledger.js";import{ownLock as V}from"../observe/runner.js";import{fieldOf as s}from"./claims.js";import{keyOf as W,lockLines as Y}from"./keys.js";import{digestsOf as _,finerOf as j,regionsOf as A}from"./region.js";import{said as D}from"./wire.js";import{sha as x}from"../host/hash.js";const g=new Map;function F(r,i){if(L())return;const d=M(r),u=`${d} ${i}`;if(g.has(u))return g.get(u);const t=D(V(),"head/second"),c=t.length?P(process.execPath,["--disable-warning=ExperimentalWarning","--disable-warning=MODULE_TYPELESS_PACKAGE_JSON",N(d,t[0]),...t.slice(1),d],{cwd:d,encoding:"utf8",maxBuffer:1<<26}):void 0,n=c===void 0||c.status!==0||typeof c.stdout!="string"?void 0:c.stdout.split(`
2
+ `).find(p=>p.startsWith("VERIFY")),o=n===void 0?void 0:n.slice(6).trim().split(" ")[0],f=o==="agrees"||o==="forks"?o:void 0;return g.set(u,f),f}m(F,"askedNow");function q(r,i,d,u=Y(r)){const t=W(r,"attest"),c=t===void 0?[]:E(r,t).filter(e=>s(e,"scope")===`${t}/target`),n=c.at(-1),o=u.filter(e=>/\bsig=/.test(e)),f=`sha256:${x([...new Set(o)].sort().join(`
3
+ `))}`,p=o.reduce((e,l)=>Math.max(e,Number(s(l,"epoch"))||0),0),h={declared:t!==void 0,expected:{set:o.length?f:void 0,standing:`place:sha256:${x([...new Set(i)].sort().join(`
4
+ `))}`,epoch:p},...n?{statement:{admitted:d(n),set:s(n,"restsOn"),standing:s(n,"at"),epoch:Number(s(n,"epoch"))||0}}:{},priorDisagreement:c.some(e=>s(e,"value")==="forks"&&d(e))};let a=$(h);if(a.verdict==="stale"&&n&&o.length){const e=F(r,f);e!==void 0&&(a=$({...h,comparison:{admitted:!0,set:f,verdict:e,epoch:p}}))}if(a.verdict!=="forks"||t===void 0||n===void 0||s(n,"restsOn")!==f)return a;const w=new Map(E(r,t).filter(e=>s(e,"scope").startsWith(`${t}/region/`)&&s(e,"restsOn")===s(n,"restsOn")).map(e=>[s(e,"scope").slice(`${t}/region/`.length).replace(/^\.$/,""),s(e,"value")]));if(!w.size)return a;const O=A(i,i,[]),[S,b]=[_(O),j(O)],k=[],v=m(e=>{if(w.get(e)!==S.get(e)){k.push(e||".");for(const l of b.get(e)??[])v(l)}},"descend");return v(""),{...a,apart:k}}m(q,"secondHead");export{q as secondHead};
@@ -1,100 +1,12 @@
1
- import { dirname, existsSync, mkdirSync, renameSync, writeFileSync } from "../host/io.js";
2
- import { canonical } from '@lapxo/topos/wire';
3
- import { bytesDigest } from "./digests.js";
4
- import { blobAt, landShard, ledgerLines, shardFile, shardLines, storeAt, writerFile } from "../land/ledger.js";
5
- import { fieldOf, isWire } from "./claims.js";
6
- import { observeFile, observeText } from "../observe/files.js";
7
- export const OBSERVED = / measure=observed /;
8
- export const LEVEL = /(?:^|\s)scope=(?:cost\/)?reader\//;
9
- export const readerOf = (line) => /(?:^|\s)by=reader:([0-9a-f]+)/.exec(line)?.[1];
10
- export const trimmed = (where) => where.replace(/\/+$/, '');
11
- import { sha } from "../host/hash.js";
12
- export { sha } from "../host/hash.js";
13
- /**
14
- * What a reader said is kept by region: the region a place lies in is the longest a reader's lock names that holds it,
15
- * the stamps and digests it was observed at are lines of that region's shard, and what the reader answered for the
16
- * region is one observation, stored under its reader's extension, the region, the digest of the region's places and
17
- * the resolution it was read at. A fold opens the shards of the regions it reaches and reads each observation by its
18
- * key: nothing is scanned, the same bytes are never read twice, and an observation found under its key is the reading.
19
- */
20
- export function regionIn(regions, place) {
21
- let best = '';
22
- for (const region of regions)
23
- if (region.length > best.length && (place === region || place.startsWith(`${region}/`)))
24
- best = region;
25
- return best;
26
- }
27
- const observationAt = (store, key) => storeAt(store, 'cas', 'observations', key);
28
- export const keyOf = (by, region, pairs, resolution = '1') => sha(`${by}\n${region}\n${sha([...pairs].sort().join('\n'))}\n${resolution}`);
29
- export const observed = (store, key) => existsSync(observationAt(store, key));
30
- export function observation(store, key) {
31
- return observeText(observationAt(store, key))?.split('\n').filter(isWire);
32
- }
33
- export function keepObservation(store, key, lines) {
34
- const at = observationAt(store, key);
35
- if (existsSync(at))
36
- return;
37
- mkdirSync(dirname(at), { recursive: true });
38
- writeFileSync(`${at}.${process.pid}`, `${[...new Set(lines)].sort().join('\n')}\n`);
39
- renameSync(`${at}.${process.pid}`, at);
40
- }
41
- export function opened(store, speaker, region, alive) {
42
- const places = new Map();
43
- const keys = new Map();
44
- const pointers = new Map();
45
- const lines = shardLines(store, speaker, region);
46
- for (const line of lines) {
47
- if (OBSERVED.test(line))
48
- places.set(`${readerOf(line) ?? ''} ${fieldOf(line, 'scope')}`, { at: fieldOf(line, 'at'), line });
49
- else if (line.includes(' measure=observation ')) {
50
- keys.set(readerOf(line) ?? '', fieldOf(line, 'value'));
51
- pointers.set(readerOf(line) ?? '', line);
52
- }
53
- }
54
- const live = [...lines.filter((line) => LEVEL.test(line)), ...[...places].filter(([name]) => alive.has(name.slice(0, name.indexOf(' ')))).map(([, one]) => one.line),
55
- ...[...pointers].filter(([by]) => alive.has(by)).map(([, line]) => line)];
56
- if (lines.length > 2 * live.length + 500) {
57
- const at = shardFile(store, speaker, region);
58
- writeFileSync(`${at}.${process.pid}`, `${live.join('\n')}\n`);
59
- renameSync(`${at}.${process.pid}`, at);
60
- }
61
- return { region, places, keys };
62
- }
63
- export const pointer = (speaker, by, region, key, pairs) => canonical({ scope: region || '.', role: 'writes', form: 'alphabet', measure: 'observation', value: key, by: `${speaker}:${by}`, at: `place:${sha([...pairs].sort().join('\n'))}` });
64
- export function legacyOf(store, speaker, regions) {
65
- if (!existsSync(writerFile(store, speaker)))
66
- return undefined;
67
- const latest = new Map();
68
- const readings = new Map();
69
- const level = new Map();
70
- for (const line of ledgerLines(store, speaker)) {
71
- if (OBSERVED.test(line))
72
- latest.set(`${readerOf(line) ?? ''} ${fieldOf(line, 'scope')}`, line);
73
- else if (LEVEL.test(line)) {
74
- const region = regionIn(regions, fieldOf(line, 'scope').replace(/^(?:cost\/)?reader\//, ''));
75
- level.set(region, [...(level.get(region) ?? []), line]);
76
- }
77
- else {
78
- const key = `${readerOf(line) ?? ''} ${fieldOf(line, 'at')}`;
79
- readings.set(key, [...(readings.get(key) ?? []), line]);
80
- }
81
- }
82
- const shards = new Map(level);
83
- for (const line of latest.values()) {
84
- const region = regionIn(regions, fieldOf(line, 'scope'));
85
- shards.set(region, [...(shards.get(region) ?? []), line]);
86
- }
87
- for (const [region, lines] of shards)
88
- landShard(store, speaker, region, lines);
89
- return readings;
90
- }
91
- export function setAside(store, speaker) {
92
- const at = writerFile(store, speaker);
93
- if (!existsSync(at))
94
- return;
95
- const bytes = observeFile(at) ?? new Uint8Array();
96
- const kept = blobAt(store, bytesDigest(store, bytes));
97
- mkdirSync(dirname(kept), { recursive: true });
98
- renameSync(at, kept);
99
- process.stderr.write(`SHARDED ${speaker} · one file of ${bytes.length} bytes laid out by region · kept as ${bytesDigest(store, bytes)}\n`);
100
- }
1
+ var M=Object.defineProperty;var c=(e,t)=>M(e,"name",{value:t,configurable:!0});import{hostOutput as A}from"../host/call-context.js";import{dirname as x,existsSync as u,mkdirSync as h,renameSync as $,writeFileSync as v}from"../host/io.js";import{library14_canonical as E}from"../vendor/runtime.js";import{bytesDigest as y}from"./digests.js";import{blobAt as j,landShard as D,ledgerLines as F,shardFile as L,shardLines as k,storeAt as R,writerFile as g}from"../land/ledger.js";import{fieldOf as p,isWire as V}from"./claims.js";import{observeFile as W,observeText as B}from"../observe/files.js";const w=/ measure=observed /,O=/(?:^|\s)scope=(?:cost\/)?reader\//,d=c(e=>/(?:^|\s)by=reader:([0-9a-f]+)/.exec(e)?.[1],"readerOf"),G=c(e=>e.replace(/\/+$/,""),"trimmed");import{sha as m}from"../host/hash.js";import{sha as ne}from"../host/hash.js";function S(e,t){let r="";for(const n of e)n.length>r.length&&(t===n||t.startsWith(`${n}/`))&&(r=n);return r}c(S,"regionIn");const b=c((e,t)=>R(e,"cas","observations",t),"observationAt"),K=c((e,t,r,n="1")=>m(`${e}
2
+ ${t}
3
+ ${m([...r].sort().join(`
4
+ `))}
5
+ ${n}`),"keyOf"),N=c((e,t)=>u(b(e,t)),"observed");function P(e,t){return B(b(e,t))?.split(`
6
+ `).filter(V)}c(P,"observation");function Q(e,t,r){const n=b(e,t);u(n)||(h(x(n),{recursive:!0}),v(`${n}.${process.pid}`,`${[...new Set(r)].sort().join(`
7
+ `)}
8
+ `),$(`${n}.${process.pid}`,n))}c(Q,"keepObservation");function X(e,t,r,n){const a=new Map,f=new Map,l=new Map,s=k(e,t,r);for(const o of s)w.test(o)?a.set(`${d(o)??""} ${p(o,"scope")}`,{at:p(o,"at"),line:o}):o.includes(" measure=observation ")&&(f.set(d(o)??"",p(o,"value")),l.set(d(o)??"",o));const i=[...s.filter(o=>O.test(o)),...[...a].filter(([o])=>n.has(o.slice(0,o.indexOf(" ")))).map(([,o])=>o.line),...[...l].filter(([o])=>n.has(o)).map(([,o])=>o)];if(s.length>2*i.length+500){const o=L(e,t,r);v(`${o}.${process.pid}`,`${i.join(`
9
+ `)}
10
+ `),$(`${o}.${process.pid}`,o)}return{region:r,places:a,keys:f}}c(X,"opened");const Y=c((e,t,r,n,a)=>E({scope:r||".",role:"writes",form:"alphabet",measure:"observation",value:n,by:`${e}:${t}`,at:`place:${m([...a].sort().join(`
11
+ `))}`}),"pointer");function Z(e,t,r){if(!u(g(e,t)))return;const n=new Map,a=new Map,f=new Map;for(const s of F(e,t))if(w.test(s))n.set(`${d(s)??""} ${p(s,"scope")}`,s);else if(O.test(s)){const i=S(r,p(s,"scope").replace(/^(?:cost\/)?reader\//,""));f.set(i,[...f.get(i)??[],s])}else{const i=`${d(s)??""} ${p(s,"at")}`;a.set(i,[...a.get(i)??[],s])}const l=new Map(f);for(const s of n.values()){const i=S(r,p(s,"scope"));l.set(i,[...l.get(i)??[],s])}for(const[s,i]of l)D(e,t,s,i);return a}c(Z,"legacyOf");function ee(e,t){const r=g(e,t);if(!u(r))return;const n=W(r)??new Uint8Array,a=j(e,y(e,n));h(x(a),{recursive:!0}),$(r,a),A("error",`SHARDED ${t} \xB7 one file of ${n.length} bytes laid out by region \xB7 kept as ${y(e,n)}
12
+ `)}c(ee,"setAside");export{O as LEVEL,w as OBSERVED,Q as keepObservation,K as keyOf,Z as legacyOf,P as observation,N as observed,X as opened,Y as pointer,d as readerOf,S as regionIn,ee as setAside,ne as sha,G as trimmed};