@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,61 +1 @@
1
- import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
2
- import { tmpdir } from 'node:os';
3
- import { basename, dirname, join, resolve } from 'node:path';
4
- import { canonical } from '@lapxo/topos/wire';
5
- import { bytesDigest } from "../fold/digests.js";
6
- import { fieldOf, selfName } from "../fold/claims.js";
7
- import { observeText } from "./files.js";
8
- import { runReader } from "./run.js";
9
- import { wordOf } from "../fold/wire.js";
10
- import { lockStanding } from "../fold/keys.js";
11
- /** Where a reader's vectors lie: in its package, beside its source, under the name of its module, the folder the wire's vector family names. */
12
- export const vectorsOf = (module, standing) => join(module.split('/')[0] ?? '', `${wordOf(standing, 'families', 'vector')}s`, `${basename(module).replace(/\.[^.]+$/, '')}.json`);
13
- export const withoutVectors = (root, modules, standing) => [...new Set(modules)].filter((module) => observeText(resolve(root, vectorsOf(module, standing))) === undefined).length;
14
- export function resetsOnEqualEmits(lines) {
15
- const named = new Map();
16
- for (const line of lines.filter((one) => fieldOf(one, 'measure') === 'emits')) {
17
- const key = `${fieldOf(line, 'scope')} ${fieldOf(line, 'value')}`;
18
- named.set(key, (named.get(key) ?? new Set()).add(fieldOf(line, 'at')));
19
- }
20
- return [...named.values()].filter((ats) => ats.size > 1).length;
21
- }
22
- function emitted(store, root, module, kind, cases, lifetime) {
23
- const laid = kind === 'process' ? mkdtempSync(join(tmpdir(), `${selfName()}-vectors-`)) : root;
24
- try {
25
- for (const one of kind === 'process' ? cases : []) {
26
- for (const [name, text] of Object.entries(one.files ?? {})) {
27
- mkdirSync(dirname(join(laid, one.place, name)), { recursive: true });
28
- writeFileSync(join(laid, one.place, name), text);
29
- }
30
- }
31
- const rows = runReader(resolve(root, module), laid, cases.map((one) => ({ place: one.place, ...(kind === 'js' ? { text: one.text ?? '' } : {}) })), lifetime);
32
- if (cases.length && rows.every((mine) => !mine.length))
33
- return undefined;
34
- const said = rows.map((mine) => mine.filter((row) => !/^(cost|derived|vector-memo)\//.test(row.scope)).map((row) => JSON.stringify(row)).sort());
35
- return bytesDigest(store, new TextEncoder().encode(JSON.stringify(said))).replace(/^[^:]*:/, '');
36
- }
37
- finally {
38
- if (laid !== root)
39
- rmSync(laid, { recursive: true, force: true });
40
- }
41
- }
42
- /** The executable keys the reader; its vector results describe only the cases measured. */
43
- export function identityOf(input) {
44
- const text = observeText(resolve(input.root, vectorsOf(input.module, lockStanding(input.store))));
45
- if (text === undefined)
46
- return { by: input.code, lines: [] };
47
- const short = (value) => bytesDigest(input.store, new TextEncoder().encode(value)).replace(/^[^:]*:/, '').slice(0, 12);
48
- const key = short(`${input.code} ${short(text)}`);
49
- const mine = input.kept.filter((line) => fieldOf(line, 'scope') === `reader/${input.module}`);
50
- const known = mine.find((line) => fieldOf(line, 'measure') === 'extension' && fieldOf(line, 'at') === `place:${key}`);
51
- if (known !== undefined && fieldOf(known, 'value') === input.code)
52
- return { by: input.code, lines: [] };
53
- const emits = emitted(input.store, input.root, input.module, input.kind, JSON.parse(text).cases ?? [], input.lifetime);
54
- if (emits === undefined)
55
- return { by: input.code, lines: [] };
56
- const by = input.code;
57
- const line = (measure, value, at) => canonical({
58
- scope: `reader/${input.module}`, role: 'writes', form: 'alphabet', measure, value, by: `${input.speaker}:${by}`, at: `place:${at}`,
59
- });
60
- return { by, lines: [line('extension', by, key), line('emits', emits, by)] };
61
- }
1
+ var b=Object.defineProperty;var i=(e,o)=>b(e,"name",{value:o,configurable:!0});import{mkdirSync as w,mkdtempSync as S,rmSync as g,writeFileSync as O}from"node:fs";import{tmpdir as h}from"node:os";import{basename as k,dirname as j,join as p,resolve as $}from"node:path";import{library11_canonical as E}from"../vendor/runtime.js";import{bytesDigest as u}from"../fold/digests.js";import{fieldOf as m,selfName as N}from"../fold/claims.js";import{observeText as v}from"./files.js";import{runReader as J}from"./run.js";import{wordOf as T}from"../fold/wire.js";import{lockStanding as q}from"../fold/keys.js";const x=i((e,o)=>p(e.split("/")[0]??"",`${T(o,"families","vector")}s`,`${k(e).replace(/\.[^.]+$/,"")}.json`),"vectorsOf"),I=i((e,o,s)=>[...new Set(o)].filter(t=>v($(e,x(t,s)))===void 0).length,"withoutVectors");function K(e){const o=new Map;for(const s of e.filter(t=>m(t,"measure")==="emits")){const t=`${m(s,"scope")} ${m(s,"value")}`;o.set(t,(o.get(t)??new Set).add(m(s,"at")))}return[...o.values()].filter(s=>s.size>1).length}i(K,"resetsOnEqualEmits");function z(e,o,s,t,l,a){const n=t==="process"?S(p(h(),`${N()}-vectors-`)):o;try{for(const r of t==="process"?l:[])for(const[c,y]of Object.entries(r.files??{}))w(j(p(n,r.place,c)),{recursive:!0}),O(p(n,r.place,c),y);const f=J($(o,s),n,l.map(r=>({place:r.place,...t==="js"?{text:r.text??""}:{}})),a);if(l.length&&f.every(r=>!r.length))return;const d=f.map(r=>r.filter(c=>!/^(cost|derived|vector-memo)\//.test(c.scope)).map(c=>JSON.stringify(c)).sort());return u(e,new TextEncoder().encode(JSON.stringify(d))).replace(/^[^:]*:/,"")}finally{n!==o&&g(n,{recursive:!0,force:!0})}}i(z,"emitted");function L(e){const o=v($(e.root,x(e.module,q(e.store))));if(o===void 0)return{by:e.code,lines:[]};const s=i(r=>u(e.store,new TextEncoder().encode(r)).replace(/^[^:]*:/,"").slice(0,12),"short"),t=s(`${e.code} ${s(o)}`),a=e.kept.filter(r=>m(r,"scope")===`reader/${e.module}`).find(r=>m(r,"measure")==="extension"&&m(r,"at")===`place:${t}`);if(a!==void 0&&m(a,"value")===e.code)return{by:e.code,lines:[]};const n=z(e.store,e.root,e.module,e.kind,JSON.parse(o).cases??[],e.lifetime);if(n===void 0)return{by:e.code,lines:[]};const f=e.code,d=i((r,c,y)=>E({scope:`reader/${e.module}`,role:"writes",form:"alphabet",measure:r,value:c,by:`${e.speaker}:${f}`,at:`place:${y}`}),"line");return{by:f,lines:[d("extension",f,t),d("emits",n,f)]}}i(L,"identityOf");export{L as identityOf,K as resetsOnEqualEmits,x as vectorsOf,I as withoutVectors};
@@ -1,8 +1 @@
1
- import * as wire from '@lapxo/topos/wire';
2
- const { matches } = wire;
3
- export const fits = (read, coordinate) => {
4
- const glob = read.includes('@') ? read.slice(0, read.indexOf('@')) : read;
5
- const [bare, tail] = coordinate.endsWith('/') ? [coordinate.slice(0, -1), '/'] : [coordinate, ''];
6
- const steps = bare.split('/');
7
- return steps.some((_, i) => matches(glob, `${steps.slice(i).join('/')}${tail}`));
8
- };
1
+ var m=Object.defineProperty;var c=(s,t)=>m(s,"name",{value:t,configurable:!0});import*as p from"../vendor/library11.js";const{matches:f}=p,r=c((s,t)=>{const e=s.includes("@")?s.slice(0,s.indexOf("@")):s,[n,l]=t.endsWith("/")?[t.slice(0,-1),"/"]:[t,""],i=n.split("/");return i.some((b,o)=>f(e,`${i.slice(o).join("/")}${l}`))},"fits");export{r as fits};
@@ -1,306 +1,7 @@
1
- import { childFlags } from "../host/capsule.js";
2
- import { readingProfile, readingExecution, withReadingBoundary } from "../host/reading-context.js";
3
- import { readingIdentityBytes } from '@lapxo/topos/contract';
4
- import { portableReadingReceipt, verifiedReadingReceipts } from "../host/reading-closures.js";
5
- import { bytesDigest, instrumentCoordinates } from "../fold/digests.js";
6
- import { ownRoot, processOf } from "./runner.js";
7
- import { contentPolicy } from "../host/content-store.js";
8
- import { carriedFrom } from "../fold/resolved.js";
9
- import { selectedCapsules } from "../host/selected-capsules.js";
10
- import { selectionLines, projectionLines } from "../fold/reach.js";
11
- export { selectionLines } from "../fold/reach.js";
12
- import { createHash } from 'node:crypto';
13
- import { basename, dirname, join, relative } from 'node:path';
14
- import { CAPSULE, LOCK, canonical, matches, PROTOCOL } from '@lapxo/topos/wire';
15
- import { handed, readsOf } from '@lapxo/topos/capsule';
16
- import { foldCeilings } from "../fold/ceilings.js";
17
- import { fieldOf, wireLinesOf as linesOf } from "../fold/claims.js";
18
- import { isCeiling } from "../fold/configures.js";
19
- import { keyFor } from "../fold/keys.js";
20
- import { casesHeld, placedReadings } from "../fold/observed.js";
21
- import { capsuleAt as isWorld, placesIn, spoken } from "../fold/places.js";
22
- import { rolesOf } from "../fold/roles.js";
23
- import { ownLockOf } from "../fold/signed.js";
24
- import { wordOn } from "../fold/wire.js";
25
- import { placesOf, viewsOf } from "../fold/views.js";
26
- import { zoomed } from "../fold/zoom.js";
27
- import { sourced } from "../land/vouched.js";
28
- import { coordinatesUnder, observeText } from "./files.js";
29
- import { ownLock } from "./runner.js";
30
- import { nameOf } from "../render/page.js";
31
- import { placeLines, takenFor } from "../fold/place-inputs.js";
32
- import { isRegionDeclaration } from "../fold/region-declarations.js";
33
- const receiptHasher = (store) => (text) => bytesDigest(store, new TextEncoder().encode(text));
34
- const fact = (scope, value, form = 'alphabet', measure = 'fact') => canonical({ scope, role: 'writes', form, measure, value, by: 'fold', at: 'place:fold' });
35
- const described = (local = []) => {
36
- const lock = ownLock();
37
- const eligible = (line) => isRegionDeclaration(line, lock);
38
- const key = (line) => `${fieldOf(line, 'scope')} ${fieldOf(line, 'measure')}`;
39
- const supplied = local.filter(eligible);
40
- const overridden = new Set(supplied.map(key));
41
- return [...lock.filter(eligible).filter((line) => !overridden.has(key(line))), ...supplied];
42
- };
43
- /** A declared selector keeps its contract token while the host binds only offered, concretely named regions. */
44
- export function regionNames(reads, descriptions) {
45
- const names = [...new Set(descriptions.map((line) => fieldOf(line, 'scope')).filter((scope) => scope.startsWith('region/') && !/[?*]/.test(scope)))];
46
- return names.filter((scope) => reads.some((read) => read.startsWith('region/') && matches(read, scope))).map((scope) => scope.slice('region/'.length));
47
- }
48
- export const describedReceipts = () => described().filter((line) => fieldOf(line, 'measure') === 'receipts')
49
- .flatMap((line) => fieldOf(line, 'value').split('|').filter(Boolean));
50
- function factsOf(fold) {
51
- const here = join(fold.root, fold.under ?? '');
52
- const written = [...viewsOf(fold.standing).values()].flatMap((view) => ('regions' in view && view.shape && observeText(join(here, view.shape)) !== undefined ? [view.shape] : []));
53
- return [fact('cases/held', String(casesHeld(fold.observed))), ...(fold.second ? [fact('second/verdict', fold.second.verdict)] : []),
54
- ...[...new Set(written)].map((shape) => fact(`${sourced(fold.standing)}/${shape}`, 'present')), ...('ceilings' in fold ? [...readingsOf(fold), ...verdictOf(fold), ...(released(fold) ? [] : askedOf(fold))] : []), ...coordinatesOf(fold)];
55
- }
56
- /** The place's own ceilings as the fold reads them, one line a ceiling at the scope the place speaks it: the bound stays its line's. */
57
- function readingsOf(fold) {
58
- const held = fold.standing.filter((line) => fieldOf(line, 'value') !== 'withdraw');
59
- const ceilings = held.filter((line) => isCeiling(line) && (!fold.under || takenFor(held, `${nameOf(fold)}/`)(line)));
60
- const read = foldCeilings({ standing: fold.standing, ceilings, observed: fold.observed, own: fold.own, epoch: fold.epoch }).readings;
61
- const spans = (got) => got.map((one) => (one.split(' ').at(-1) ?? '').split('..').map(Number)).filter((span) => span.every(Number.isFinite));
62
- return ceilings.flatMap((line) => ((got) => (got === undefined ? [] : [canonical({ scope: fieldOf(fold.under ? zoomed(line, nameOf(fold)) : line, 'scope'), role: 'reads', measure: fieldOf(line, 'measure'), by: 'fold', at: 'place:fold',
63
- ...(spans(got).length === got.length ? { form: 'interval', value: `${Math.min(...spans(got).map((span) => span[0]))}..${Math.max(...spans(got).map((span) => span.at(-1)))}` } : { form: 'alphabet', value: [...new Set(got)].join('|') }) })]))(read.get(fieldOf(line, 'scope'))));
64
- }
65
- const released = (fold) => fold.standing.some((line) => [`publish/${nameOf(fold)}/bootstrap`, 'publish/bootstrap'].includes(fieldOf(line, 'scope')) && fieldOf(line, 'value') !== 'withdraw');
66
- const pinnersOf = (fold) => [...new Set(fold.standing.filter((line) => fieldOf(line, 'value') !== 'withdraw')
67
- .flatMap((line) => ((steps) => (steps.length === 3 && steps[1] === 'uses' && steps[2] === nameOf(fold) ? [steps[0]] : []))(fieldOf(line, 'scope').split('/'))))];
68
- const capsuleOf = (fold) => [CAPSULE, LOCK].map((file) => linesOf(observeText(join(fold.root, fold.under ?? '', file))))
69
- .find((lines) => lines.some((line) => fieldOf(line, 'scope').startsWith('capsule/'))) ?? [];
70
- const coordinatesOf = (fold) => ((here, role) => (!isWorld(fold.root, (fold.under ?? '').replace(/\/$/, '')) || (fold.under === undefined && !released(fold)) ? []
71
- : coordinatesUnder(here, here, (dir) => dir === '' || (!basename(dir).startsWith('.') && role(relative(dirname(fold.store), join(here, dir))) !== 'foreign'))
72
- .map((file) => fact(`coordinate/${file}`, neededBy(fold.standing, fold.under ?? '', file) ? 'needed' : 'present'))))(join(fold.root, fold.under ?? ''), rolesOf(fold.store));
73
- const neededBy = (standing, under, file) => standing.some((line) => fieldOf(line, 'value') !== 'withdraw' && fieldOf(line, 'measure') !== 'reader'
74
- && fieldOf(line, 'needs').split('|').some((need) => !['', './', under].includes(need) && (need === `${under}${file}` || (need.endsWith('/') && `${under}${file}`.startsWith(need)) || matches(need, `${under}${file}`))));
75
- function askedOf(fold) {
76
- const at = (place) => ((lines) => ((views) => new Set(views.filter((view) => placesOf(lines, view).includes(`${place}/`) || (!placesOf(lines, view).length
77
- && observeText(join(fold.root, place, view.shape)) !== undefined && !views.some((other) => other.shape === view.shape && placesOf(lines, other).includes(`${place}/`)))).flatMap((view) => view.regions.map((one) => one.name))))([...viewsOf(lines).values()].flatMap((view) => ('regions' in view && view.shape ? [view] : []))))([...ownLockOf(fold.root, place, true), ...fold.standing]);
78
- return fold.under ? [...new Set(capsuleOf(fold).filter((line) => fieldOf(line, 'scope').startsWith('region/') && fieldOf(line, 'role') === 'render').map((line) => fieldOf(line, 'scope').slice('region/'.length)))]
79
- .map((name) => ((n) => fact(`asked/${name}`, `${n}..${n}`, 'interval', 'count'))(pinnersOf(fold).map(at).filter((names) => names.has(name)).length)) : [];
80
- }
81
- /** File-fold readings and their ceilings; this path computes no object encounters. */
82
- function verdictOf(fold) {
83
- const named = (line) => ((cut) => [line.slice(0, cut < 0 ? line.length : cut).trim(), line.slice(cut < 0 ? line.length : cut + 3).trim() || line])(line.indexOf(' · '));
84
- const here = (fold.under ?? '').replace(/\/$/, '');
85
- const others = new Set(here ? placesIn(fold.root).filter((place) => place !== here) : []);
86
- const mine = (scope) => {
87
- if (!here)
88
- return true;
89
- if (scope === here || scope.startsWith(`${here}/`))
90
- return true;
91
- const head = scope.split('/')[0] ?? '';
92
- return !others.has(head);
93
- };
94
- return [['claims', fold.claims], ['forks', fold.forks.length + (fold.second.verdict === 'forks' ? 1 : 0)], ['refused', fold.refused.length], ['vacuous', fold.vacuous], ['history', fold.history.length],
95
- ['met', fold.ceilings.read], ['short', fold.ceilings.short.length], ['over', fold.ceilings.over.length]].map(([name, n]) => fact(`verdict/${name}`, `${n}..${n}`, 'interval', 'count'))
96
- .concat([fact('verdict/computation', 'readings'), fact('verdict/encounters', 'uncomputed')])
97
- .concat(fold.ceilings.short.filter((one) => mine(named(one)[0])).map((one) => (([scope, reading]) => fact(`unpaid/${scope}`, reading))(named(one))))
98
- .concat(fold.ceilings.over.filter((one) => mine(named(one)[0])).map((one) => (([scope, reading]) => fact(`outside/${scope}`, reading))(named(one))))
99
- .concat(fold.ceilings.unread.filter(mine).map((scope) => fact(`unpaid/${scope}`, 'unread')))
100
- .concat(fold.missing.filter((line) => mine(fieldOf(line, 'scope'))).map((line) => fact(`unpaid/${fieldOf(line, 'scope')}`, 'unpaid')))
101
- .concat([
102
- fact('walk/read', `${fold.own['walk-read'] ?? 0}..${fold.own['walk-read'] ?? 0}`, 'interval', 'count'),
103
- fact('walk/ms', `${fold.own['walk-ms'] ?? 0}..${fold.own['walk-ms'] ?? 0}`, 'interval', 'count'),
104
- ]);
105
- }
106
- function regionOf(fold, name, lines, facts) {
107
- const here = fold.under ?? '';
108
- const said = (measure) => handed([`region/${name}`], lines).filter((fields) => fields['measure'] === measure)
109
- .flatMap((fields) => (fields['value'] ?? '').split('|').filter(Boolean));
110
- const globs = said('receipts');
111
- const placed = placedReadings(fold.observed).filter((one) => one.place.startsWith(here) && globs.some((glob) => matches(glob, one.question)))
112
- .map((one) => canonical({ scope: one.question, role: 'reads', form: 'alphabet', measure: one.measure, value: one.value, by: one.by, evidence: one.at, at: `place:${one.place.slice(here.length).replace(/^\.\/$/, '')}` }));
113
- const role = rolesOf(fold.store);
114
- const walked = coordinatesUnder(join(fold.root, here), fold.root, (dir) => dir === '' || (!basename(dir).startsWith('.') && role(relative(dirname(fold.store), join(fold.root, dir))) !== 'foreign'));
115
- const named = wordOn(fold.standing, 'region-coordinate', ownLock());
116
- const files = said(named).flatMap((glob) => walked.filter((file) => matches(glob, file.slice(here.length)) || matches(glob, file)));
117
- const saidLines = files.flatMap((file) => {
118
- if (basename(file) === 'TARGET.bound' || basename(file) === 'receipts.bound')
119
- return [];
120
- const lock = linesOf(observeText(join(fold.root, file)));
121
- return lock.length ? [canonical({ scope: 'said/lines', role: 'reads', form: 'alphabet', measure: 'lines', value: lock.join('\n'), by: 'reader', at: `place:${file}` })] : [];
122
- });
123
- return {
124
- lines: said('lines').flatMap((coordinate) => linesOf(observeText(join(fold.root, here, coordinate)))),
125
- receipts: [...placed, ...saidLines, ...(globs.length ? facts() : []).filter((line) => globs.some((glob) => matches(glob, fieldOf(line, 'scope'))))],
126
- };
127
- }
128
- /** A local selection belongs to its own lock; tree-qualified selections retain their explicit owner. */
129
- const heldCapsules = new WeakMap();
130
- /** Execution is supplied only by explicit capsule offers of the selected standing. */
131
- export function capsulesOf(fold) {
132
- const cached = heldCapsules.get(fold);
133
- if (cached !== undefined)
134
- return cached;
135
- const got = selectedCapsules(selectionLines(fold), undefined, undefined, projectionLines(fold)).map(one => one.capsule);
136
- heldCapsules.set(fold, got);
137
- return got;
138
- }
139
- export const declaredBy = (fold) => [...new Set(capsulesOf(fold).flatMap((capsule) => capsule.declaration.renders))];
140
- const asks = new WeakMap();
141
- /**
142
- * What a region of a capsule is handed: of the reads its line declares, every read of the place's lines, and each region
143
- * a line of the instrument's lock describes, with its lines and its receipts; a region no line describes is not handed,
144
- * and a region handed less than it declares is refused by its capsule, which is every capsule's no. Nothing is handed
145
- * as a file: the lines are the place as its published lock holds them, and each region is read once for the fold,
146
- * however many views ask it.
147
- */
148
- export const askingOf = (fold) => asks.get(fold) ?? asks.set(fold, handing(fold)).get(fold);
149
- function handing(fold) {
150
- const capsule = linesOf(observeText(join(fold.root, fold.under ?? '', CAPSULE))).filter((line) => fieldOf(line, 'scope').startsWith('region/'));
151
- const seen = handed(['**'], fold.under ? placeLines(fold) : fold.standing);
152
- const lines = described(seen.map((fields) => canonical(fields)));
153
- let held;
154
- const facts = () => (held ?? (held = factsOf(fold)));
155
- const regions = new Map();
156
- const region = (name) => regions.get(name) ?? regions.set(name, regionOf(fold, name, lines, facts)).get(name);
157
- return (declaration, one, verb, shape) => {
158
- const declared = readsOf(declaration, one.name);
159
- if (declared === undefined)
160
- return undefined;
161
- const reads = declared.filter((read) => !read.startsWith('region/') || handed([read], lines).length > 0 || (matches(read, 'region/capsule') && capsule.length > 0));
162
- const names = [...new Set([...regionNames(reads, lines), ...(capsule.length && reads.some((read) => matches(read, 'region/capsule')) ? ['capsule'] : [])])];
163
- return { protocol: PROTOCOL, verb, rootScope: fold.under ?? '', files: [], region: one.name, at: one.at, shape, name: nameOf(fold) || basename(fold.root),
164
- lines: seen
165
- .filter((fields) => reads.some((read) => matches(read, fields['scope'] ?? ''))).map((fields) => canonical(fields)), reads,
166
- regions: Object.fromEntries(names.map((name) => [name, name === 'capsule' && capsule.length ? { lines: capsule, receipts: [] } : region(name)])) };
167
- };
168
- }
169
- const read = new WeakMap();
170
- function capsuleReadings(fold) {
171
- const place = fold.under || './';
172
- const known = read.get(fold.observed) ?? read.set(fold.observed, new Map()).get(fold.observed);
173
- return known.get(place) ?? known.set(place, readingsAt(fold, place)).get(place);
174
- }
175
- function readingsAt(fold, place) {
176
- const speaker = keyFor(fold.store, 'read');
177
- return capsulesOf(fold).flatMap((capsule) => {
178
- const writing = new Set(capsule.lines.filter((line) => fieldOf(line, 'scope').startsWith('region/') && fieldOf(line, 'measure') === 'writes').map((line) => fieldOf(line, 'scope').slice('region/'.length)));
179
- const receipts = Object.keys(capsule.declaration.writes).filter((name) => capsule.declaration.writes[name] === 'receipt' && !writing.has(name)).sort();
180
- const target = modernReceiptInputs(fold, capsule.selection ?? capsule.digest);
181
- const asking = askingOf({ ...fold, observed: target.current });
182
- const requests = receipts.flatMap((name) => ((request) => (request === undefined ? [] : [request]))(asking(capsule.declaration, { name, at: 3 }, 'read', '')));
183
- const modern = readingProfile(fold.standing, fieldOf);
184
- if (modern && requests.length) {
185
- const hash = receiptHasher(fold.store);
186
- const batch = hash(JSON.stringify([capsule.selection ?? capsule.digest, capsule.digest, receipts]));
187
- const coordinates = instrumentCoordinates(fold.store, processOf('verb'), [], ownRoot(), ownLock(), true), instrument = hash([...coordinates.values()].sort().join('\n'));
188
- const legacy = target.legacy;
189
- return requests.flatMap(request => {
190
- const execution = readingExecution({ instrument, implementation: capsule.digest, policy: hash(JSON.stringify([contentPolicy(), capsule.selection ?? null, capsule.lines])), inputs: [['world', capsule.selection ?? capsule.digest], ['batch', batch], ['request', hash(JSON.stringify(request))], ...legacy, ...[...coordinates].map(([name, id]) => ['host/' + relative(ownRoot(), name), id])] }, hash, { env: process.env, cwd: fold.root, flags: childFlags() });
191
- const closure = new TextDecoder().decode(readingIdentityBytes(execution.context)), input = hash(closure), said = withReadingBoundary(input, execution, () => capsule.ask([request]))[0];
192
- if (said?.kind !== 'fact')
193
- throw Error(`REFUSE·capsule ${capsule.digest} · ${request.region} · ${said?.why ?? 'no answer'}`);
194
- const by = speaker + ':' + batch.slice(7), at = 'place:' + input;
195
- const lines = (said.claims ?? []).map((row) => canonical({ scope: row.scope, role: row.role, measure: row.measure, form: row.bound.kind === 'interval' ? 'interval' : 'alphabet', value: row.bound.kind === 'interval' ? `${row.bound.lo ?? 0}..${row.bound.hi ?? 0}` : (row.bound.values ?? []).join('|'), by, at }));
196
- const output = lines.join('\n') + (lines.length ? '\n' : ''), scope = 'receipts/readings/' + hash(request.region ?? '').slice(7) + '/' + input.slice(7);
197
- return [canonical({ scope: place, role: 'writes', form: 'alphabet', measure: 'observed', value: input.slice(7, 23), by, at }), ...lines, ...portableReadingReceipt(scope, by, closure, output, hash)];
198
- });
199
- }
200
- const answers = capsule.ask(requests);
201
- const refused = requests.filter((_, i) => answers[i]?.kind !== 'fact');
202
- if (refused.length)
203
- throw new Error(`REFUSE·capsule ${capsule.digest} · ${place} · ${refused.length} of ${requests.length} regions: ${refused.map((one) => one.region).join(' ')} · ${answers[requests.indexOf(refused[0])]?.why ?? 'no answer'}`);
204
- return requests.flatMap((request, i) => {
205
- const said = answers[i];
206
- if (said?.kind !== 'fact')
207
- return [];
208
- const digest = createHash('sha256').update(JSON.stringify(request)).digest('hex');
209
- const at = `place:sha256:${digest}`;
210
- const by = `${speaker}:${capsule.digest.slice(7, 19)}`;
211
- const line = (row) => canonical({ scope: row.scope, role: row.role, form: row.bound.kind === 'interval' ? 'interval' : 'alphabet', measure: row.measure,
212
- value: row.bound.kind === 'interval' ? `${row.bound.lo ?? 0}..${row.bound.hi ?? 0}` : (row.bound.values ?? []).join('|'), by, at });
213
- return [canonical({ scope: place, role: 'writes', form: 'alphabet', measure: 'observed', value: digest.slice(0, 16), by, at }),
214
- ...(said.claims ?? []).map(line)];
215
- });
216
- });
217
- }
218
- export function capsuleReadingsOver(fold) {
219
- if (fold.under)
220
- return capsuleReadings(fold);
221
- const said = spoken(fold.root);
222
- const places = [...new Set(fold.standing.flatMap((line) => /^([^/]+)\/uses\//.exec(fieldOf(line, 'scope'))?.[1] ?? []))];
223
- return [...capsuleReadings(fold), ...places.flatMap((place) => capsuleReadings({ ...fold, under: `${place}/`,
224
- standing: [...new Set([...said.filter((one) => one.place === place).map((one) => one.line), ...fold.standing])] }))];
225
- }
226
- /** Current judgement excludes authenticated outcomes of the selected producer batches; retained evidence stays in its carrier. */
227
- export const currentReceiptObservations = (fold) => modernReceiptInputs(fold).current;
228
- /** Preserve prior producer outcomes in the owning place's public carrier, independently of current judgement. */
229
- export const retiredReceiptHistory = (fold) => { const carried = carriedFrom(fold.store, (observeText(join(fold.root, fold.under ?? '', 'receipts.bound')) ?? '').split('\n').filter(line => line.startsWith('bound-lock/'))) ?? []; const all = [...new Set([...fold.observed, ...carried])], current = new Set(modernReceiptInputs({ ...fold, observed: all }).current); return all.filter(line => !current.has(line)); };
230
- /** A modern capsule batch cannot consume its own retained outcomes. Full context units bind history; legacy conversion never supplies a current answer. */
231
- function modernReceiptInputs(fold, target) {
232
- if (!readingProfile(fold.standing, fieldOf))
233
- return { current: fold.observed, legacy: [] };
234
- const observed = [...new Set(fold.observed)];
235
- const hash = receiptHasher(fold.store), allSelected = capsulesOf(fold), selected = allSelected.filter(c => { const writing = new Set(c.lines.filter(l => fieldOf(l, 'measure') === 'writes').map(l => fieldOf(l, 'scope').slice(7))); return Object.keys(c.declaration.writes).some(n => c.declaration.writes[n] === 'receipt' && !writing.has(n)); });
236
- if (!selected.length)
237
- return { current: fold.observed, legacy: [] };
238
- const speaker = keyFor(fold.store, 'read'), removed = new Set(), refs = [];
239
- const units = observed.filter(l => fieldOf(l, 'scope').startsWith('receipts/readings/') && fieldOf(l, 'measure') === 'bytes' && fieldOf(l, 'role') === 'writes');
240
- if (verifiedReadingReceipts(fold.store, observed, hash, undefined, true) === undefined)
241
- throw Error('REFUSE·capsule receipt carrier context invalid');
242
- for (const capsule of selected) {
243
- if (target !== undefined && (capsule.selection ?? capsule.digest) !== target)
244
- continue;
245
- const writing = new Set(capsule.lines.filter(l => fieldOf(l, 'measure') === 'writes').map(l => fieldOf(l, 'scope').slice(7))), receipts = Object.keys(capsule.declaration.writes).filter(n => capsule.declaration.writes[n] === 'receipt' && !writing.has(n)).sort();
246
- if (!receipts.length)
247
- continue;
248
- const batch = hash(JSON.stringify([capsule.selection ?? capsule.digest, capsule.digest, receipts])), knownLegacy = new Set();
249
- for (const unit of units) {
250
- const about = fieldOf(unit, 'about');
251
- if (!about)
252
- continue;
253
- let c;
254
- try {
255
- c = JSON.parse(about);
256
- }
257
- catch {
258
- continue;
259
- }
260
- if (!Array.isArray(c) || c[0] !== 'reading-context@1' || c[2] !== capsule.digest || !Array.isArray(c[4]) || !c[4].some(([n, id]) => n === 'batch' && id === batch) || !c[4].some(([n, id]) => n === 'world' && id === (capsule.selection ?? capsule.digest)))
261
- continue;
262
- const expectedBy = speaker + ':' + batch.slice(7);
263
- if (fieldOf(unit, 'by') !== expectedBy)
264
- continue;
265
- if (fold.standing.some(line => fieldOf(line, 'scope') === 'keys/' + expectedBy && fieldOf(line, 'value') !== 'withdraw'))
266
- throw Error('REFUSE·modern capsule receipt producer ambiguous');
267
- const namedScope = fieldOf(unit, 'scope'), inputIdentity = fieldOf(unit, 'value');
268
- if (!receipts.some(name => namedScope === 'receipts/readings/' + hash(name).slice(7) + '/' + inputIdentity.slice(7)))
269
- throw Error('REFUSE·modern capsule receipt scope differs from declared region');
270
- for (const [n, id] of c[4])
271
- if (typeof n === 'string' && n.startsWith('legacy/output/') && n === 'legacy/output/' + id) {
272
- knownLegacy.add(id);
273
- refs.push([n, id]);
274
- }
275
- const by = fieldOf(unit, 'by'), input = fieldOf(unit, 'value'), scope = fieldOf(unit, 'scope'), output = observed.find(l => fieldOf(l, 'scope') === scope && fieldOf(l, 'by') === by && fieldOf(l, 'measure') === 'count');
276
- const payload = output ? fieldOf(output, 'at') : '';
277
- for (const l of observed)
278
- if (fieldOf(l, 'by') === by && (fieldOf(l, 'at') === 'place:' + input || fieldOf(l, 'at') === payload || fieldOf(l, 'scope') === scope || fieldOf(l, 'scope') === [scope, 'identity'].join('/')))
279
- removed.add(l);
280
- }
281
- const alias = capsule.digest.slice(7, 19), by = speaker + ':' + alias, groups = new Map();
282
- for (const l of observed)
283
- if (fieldOf(l, 'by') === by) {
284
- const at = fieldOf(l, 'at');
285
- groups.set(at, [...(groups.get(at) ?? []), l]);
286
- }
287
- if (groups.size) {
288
- if (selected.filter(c => c.digest === capsule.digest).length !== 1 || receipts.length !== 1 || new Set(allSelected.filter(c => c.digest.slice(7, 19) === alias).map(c => c.digest)).size !== 1 || fold.standing.some(l => fieldOf(l, 'scope') === 'keys/' + by && fieldOf(l, 'value') !== 'withdraw'))
289
- throw Error('REFUSE·legacy capsule receipt producer ambiguous');
290
- for (const [at, group] of groups) {
291
- if (!/^place:sha256:[a-f0-9]{64}$/.test(at) || group.filter(l => fieldOf(l, 'measure') === 'observed' && fieldOf(l, 'scope') === (fold.under || './')).length !== 1)
292
- throw Error('REFUSE·legacy capsule receipt occurrence ambiguous');
293
- const id = hash(group.join('\n'));
294
- if (!knownLegacy.has(id)) {
295
- const candidate = observed.filter(l => !removed.has(l) && !group.includes(l)), request = askingOf({ ...fold, observed: candidate })(capsule.declaration, { name: receipts[0], at: 3 }, 'read', '');
296
- if (!request || at !== 'place:' + hash(JSON.stringify(request)))
297
- throw Error('REFUSE·legacy capsule receipt context unavailable · expected ' + at + ' · current ' + (request ? hash(JSON.stringify(request)) : 'absent'));
298
- }
299
- refs.push(['legacy/output/' + id, id]);
300
- for (const l of group)
301
- removed.add(l);
302
- }
303
- }
304
- }
305
- return { current: observed.filter(l => !removed.has(l)), legacy: [...new Map(refs.map(([n, id]) => [n + ' ' + id, [n, id]])).values()] };
306
- }
1
+ var pe=Object.defineProperty;var l=(e,r)=>pe(e,"name",{value:r,configurable:!0});import{childFlags as ue}from"../host/capsule.js";import{readingProfile as G,readingExecution as le,withReadingBoundary as de}from"../host/reading-context.js";import{library2_readingIdentityBytes as me}from"../vendor/runtime.js";import{portableReadingReceipt as ge,verifiedReadingReceipts as he}from"../host/reading-closures.js";import{bytesDigest as fe,instrumentCoordinates as be}from"../fold/digests.js";import{ownRoot as Q,processOf as we}from"./runner.js";import{contentPolicy as ye}from"../host/content-store.js";import{carriedFrom as ve}from"../fold/resolved.js";import{selectedCapsules as $e}from"../host/selected-capsules.js";import{selectionLines as Oe,projectionLines as ke}from"../fold/reach.js";import{selectionLines as Jt}from"../fold/reach.js";import{createHash as Se}from"node:crypto";import{basename as A,dirname as V,join as E,relative as P}from"node:path";import{library11_CAPSULE as X,library11_LOCK as Ee,library11_canonical as x,library11_matches as W,library11_PROTOCOL as Me}from"../vendor/runtime.js";import{library1_handed as I,library1_readsOf as xe}from"../vendor/runtime.js";import{foldCeilings as Re}from"../fold/ceilings.js";import{fieldOf as i,wireLinesOf as B}from"../fold/claims.js";import{isCeiling as We}from"../fold/configures.js";import{keyFor as Y}from"../fold/keys.js";import{casesHeld as je,placedReadings as Le}from"../fold/observed.js";import{capsuleAt as Fe,placesIn as Ce,spoken as Ne}from"../fold/places.js";import{rolesOf as Z}from"../fold/roles.js";import{ownLockOf as Ue}from"../fold/signed.js";import{wordOn as Ae}from"../fold/wire.js";import{placesOf as H,viewsOf as ee}from"../fold/views.js";import{zoomed as _e}from"../fold/zoom.js";import{sourced as Be}from"../land/vouched.js";import{coordinatesUnder as te,observeText as C}from"./files.js";import{ownLock as z}from"./runner.js";import{nameOf as _}from"../render/page.js";import{placeLines as Je,takenFor as Te}from"../fold/place-inputs.js";import{isRegionDeclaration as Pe}from"../fold/region-declarations.js";const re=l(e=>r=>fe(e,new TextEncoder().encode(r)),"receiptHasher"),$=l((e,r,s="alphabet",t="fact")=>x({scope:e,role:"writes",form:s,measure:t,value:r,by:"fold",at:"place:fold"}),"fact"),se=l((e=[])=>{const r=z(),s=l(o=>Pe(o,r),"eligible"),t=l(o=>`${i(o,"scope")} ${i(o,"measure")}`,"key"),a=e.filter(s),n=new Set(a.map(t));return[...r.filter(s).filter(o=>!n.has(t(o))),...a]},"described");function Ie(e,r){return[...new Set(r.map(t=>i(t,"scope")).filter(t=>t.startsWith("region/")&&!/[?*]/.test(t)))].filter(t=>e.some(a=>a.startsWith("region/")&&W(a,t))).map(t=>t.slice(7))}l(Ie,"regionNames");const Ft=l(()=>se().filter(e=>i(e,"measure")==="receipts").flatMap(e=>i(e,"value").split("|").filter(Boolean)),"describedReceipts");function He(e){const r=E(e.root,e.under??""),s=[...ee(e.standing).values()].flatMap(t=>"regions"in t&&t.shape&&C(E(r,t.shape))!==void 0?[t.shape]:[]);return[$("cases/held",String(je(e.observed))),...e.second?[$("second/verdict",e.second.verdict)]:[],...[...new Set(s)].map(t=>$(`${Be(e.standing)}/${t}`,"present")),..."ceilings"in e?[...ze(e),...Ve(e),...ne(e)?[]:Qe(e)]:[],...qe(e)]}l(He,"factsOf");function ze(e){const r=e.standing.filter(n=>i(n,"value")!=="withdraw"),s=r.filter(n=>We(n)&&(!e.under||Te(r,`${_(e)}/`)(n))),t=Re({standing:e.standing,ceilings:s,observed:e.observed,own:e.own,epoch:e.epoch}).readings,a=l(n=>n.map(o=>(o.split(" ").at(-1)??"").split("..").map(Number)).filter(o=>o.every(Number.isFinite)),"spans");return s.flatMap(n=>(o=>o===void 0?[]:[x({scope:i(e.under?_e(n,_(e)):n,"scope"),role:"reads",measure:i(n,"measure"),by:"fold",at:"place:fold",...a(o).length===o.length?{form:"interval",value:`${Math.min(...a(o).map(w=>w[0]))}..${Math.max(...a(o).map(w=>w.at(-1)))}`}:{form:"alphabet",value:[...new Set(o)].join("|")}})])(t.get(i(n,"scope"))))}l(ze,"readingsOf");const ne=l(e=>e.standing.some(r=>[`publish/${_(e)}/bootstrap`,"publish/bootstrap"].includes(i(r,"scope"))&&i(r,"value")!=="withdraw"),"released"),De=l(e=>[...new Set(e.standing.filter(r=>i(r,"value")!=="withdraw").flatMap(r=>(s=>s.length===3&&s[1]==="uses"&&s[2]===_(e)?[s[0]]:[])(i(r,"scope").split("/"))))],"pinnersOf"),Ke=l(e=>[X,Ee].map(r=>B(C(E(e.root,e.under??"",r)))).find(r=>r.some(s=>i(s,"scope").startsWith("capsule/")))??[],"capsuleOf"),qe=l(e=>((r,s)=>!Fe(e.root,(e.under??"").replace(/\/$/,""))||e.under===void 0&&!ne(e)?[]:te(r,r,t=>t===""||!A(t).startsWith(".")&&s(P(V(e.store),E(r,t)))!=="foreign").map(t=>$(`coordinate/${t}`,Ge(e.standing,e.under??"",t)?"needed":"present")))(E(e.root,e.under??""),Z(e.store)),"coordinatesOf"),Ge=l((e,r,s)=>e.some(t=>i(t,"value")!=="withdraw"&&i(t,"measure")!=="reader"&&i(t,"needs").split("|").some(a=>!["","./",r].includes(a)&&(a===`${r}${s}`||a.endsWith("/")&&`${r}${s}`.startsWith(a)||W(a,`${r}${s}`)))),"neededBy");function Qe(e){const r=l(s=>(t=>(a=>new Set(a.filter(n=>H(t,n).includes(`${s}/`)||!H(t,n).length&&C(E(e.root,s,n.shape))!==void 0&&!a.some(o=>o.shape===n.shape&&H(t,o).includes(`${s}/`))).flatMap(n=>n.regions.map(o=>o.name))))([...ee(t).values()].flatMap(a=>"regions"in a&&a.shape?[a]:[])))([...Ue(e.root,s,!0),...e.standing]),"at");return e.under?[...new Set(Ke(e).filter(s=>i(s,"scope").startsWith("region/")&&i(s,"role")==="render").map(s=>i(s,"scope").slice(7)))].map(s=>(t=>$(`asked/${s}`,`${t}..${t}`,"interval","count"))(De(e).map(r).filter(t=>t.has(s)).length)):[]}l(Qe,"askedOf");function Ve(e){const r=l(n=>(o=>[n.slice(0,o<0?n.length:o).trim(),n.slice(o<0?n.length:o+3).trim()||n])(n.indexOf(" \xB7 ")),"named"),s=(e.under??"").replace(/\/$/,""),t=new Set(s?Ce(e.root).filter(n=>n!==s):[]),a=l(n=>{if(!s||n===s||n.startsWith(`${s}/`))return!0;const o=n.split("/")[0]??"";return!t.has(o)},"mine");return[["claims",e.claims],["forks",e.forks.length+(e.second.verdict==="forks"?1:0)],["refused",e.refused.length],["vacuous",e.vacuous],["history",e.history.length],["met",e.ceilings.read],["short",e.ceilings.short.length],["over",e.ceilings.over.length]].map(([n,o])=>$(`verdict/${n}`,`${o}..${o}`,"interval","count")).concat([$("verdict/computation","readings"),$("verdict/encounters","uncomputed")]).concat(e.ceilings.short.filter(n=>a(r(n)[0])).map(n=>(([o,w])=>$(`unpaid/${o}`,w))(r(n)))).concat(e.ceilings.over.filter(n=>a(r(n)[0])).map(n=>(([o,w])=>$(`outside/${o}`,w))(r(n)))).concat(e.ceilings.unread.filter(a).map(n=>$(`unpaid/${n}`,"unread"))).concat(e.missing.filter(n=>a(i(n,"scope"))).map(n=>$(`unpaid/${i(n,"scope")}`,"unpaid"))).concat([$("walk/read",`${e.own["walk-read"]??0}..${e.own["walk-read"]??0}`,"interval","count"),$("walk/ms",`${e.own["walk-ms"]??0}..${e.own["walk-ms"]??0}`,"interval","count")])}l(Ve,"verdictOf");function Xe(e,r,s,t){const a=e.under??"",n=l(c=>I([`region/${r}`],s).filter(g=>g.measure===c).flatMap(g=>(g.value??"").split("|").filter(Boolean)),"said"),o=n("receipts"),w=Le(e.observed).filter(c=>c.place.startsWith(a)&&o.some(g=>W(g,c.question))).map(c=>x({scope:c.question,role:"reads",form:"alphabet",measure:c.measure,value:c.value,by:c.by,evidence:c.at,at:`place:${c.place.slice(a.length).replace(/^\.\/$/,"")}`})),m=Z(e.store),j=te(E(e.root,a),e.root,c=>c===""||!A(c).startsWith(".")&&m(P(V(e.store),E(e.root,c)))!=="foreign"),d=Ae(e.standing,"region-coordinate",z()),p=n(d).flatMap(c=>j.filter(g=>W(c,g.slice(a.length))||W(c,g))).flatMap(c=>{if(A(c)==="TARGET.bound"||A(c)==="receipts.bound")return[];const g=B(C(E(e.root,c)));return g.length?[x({scope:"said/lines",role:"reads",form:"alphabet",measure:"lines",value:g.join(`
2
+ `),by:"reader",at:`place:${c}`})]:[]});return{lines:n("lines").flatMap(c=>B(C(E(e.root,a,c)))),receipts:[...w,...p,...(o.length?t():[]).filter(c=>o.some(g=>W(g,i(c,"scope"))))]}}l(Xe,"regionOf");const ie=new WeakMap;function D(e){const r=ie.get(e);if(r!==void 0)return r;const s=$e(Oe(e),void 0,void 0,ke(e)).map(t=>t.capsule);return ie.set(e,s),s}l(D,"capsulesOf");const Ct=l(e=>[...new Set(D(e).flatMap(r=>r.declaration.renders))],"declaredBy"),ae=new WeakMap,oe=l(e=>ae.get(e)??ae.set(e,Ye(e)).get(e),"askingOf");function Ye(e){const r=B(C(E(e.root,e.under??"",X))).filter(m=>i(m,"scope").startsWith("region/")),s=I(["**"],e.under?Je(e):e.standing),t=se(s.map(m=>x(m)));let a;const n=l(()=>a??(a=He(e)),"facts"),o=new Map,w=l(m=>o.get(m)??o.set(m,Xe(e,m,t,n)).get(m),"region");return(m,j,d,v)=>{const p=xe(m,j.name);if(p===void 0)return;const c=p.filter(b=>!b.startsWith("region/")||I([b],t).length>0||W(b,"region/capsule")&&r.length>0),g=[...new Set([...Ie(c,t),...r.length&&c.some(b=>W(b,"region/capsule"))?["capsule"]:[]])];return{protocol:Me,verb:d,rootScope:e.under??"",files:[],region:j.name,at:j.at,shape:v,name:_(e)||A(e.root),lines:s.filter(b=>c.some(R=>W(R,b.scope??""))).map(b=>x(b)),reads:c,regions:Object.fromEntries(g.map(b=>[b,b==="capsule"&&r.length?{lines:r,receipts:[]}:w(b)]))}}}l(Ye,"handing");const ce=new WeakMap;function K(e){const r=e.under||"./",s=ce.get(e.observed)??ce.set(e.observed,new Map).get(e.observed);return s.get(r)??s.set(r,Ze(e,r)).get(r)}l(K,"capsuleReadings");function Ze(e,r){const s=Y(e.store,"read");return D(e).flatMap(t=>{const a=new Set(t.lines.filter(p=>i(p,"scope").startsWith("region/")&&i(p,"measure")==="writes").map(p=>i(p,"scope").slice(7))),n=Object.keys(t.declaration.writes).filter(p=>t.declaration.writes[p]==="receipt"&&!a.has(p)).sort(),o=q(e,t.selection??t.digest),w=oe({...e,observed:o.current}),m=n.flatMap(p=>(c=>c===void 0?[]:[c])(w(t.declaration,{name:p,at:3},"read","")));if(G(e.standing,i)&&m.length){const p=re(e.store),c=p(JSON.stringify([t.selection??t.digest,t.digest,n])),g=be(e.store,we("verb"),[],Q(),z(),!0),b=p([...g.values()].sort().join(`
3
+ `)),R=o.legacy;return m.flatMap(S=>{const u=le({instrument:b,implementation:t.digest,policy:p(JSON.stringify([ye(),t.selection??null,t.lines])),inputs:[["world",t.selection??t.digest],["batch",c],["request",p(JSON.stringify(S))],...R,...[...g].map(([k,T])=>["host/"+P(Q(),k),T])]},p,{env:process.env,cwd:e.root,flags:ue()}),f=new TextDecoder().decode(me(u.context)),y=p(f),O=de(y,u,()=>t.ask([S]))[0];if(O?.kind!=="fact")throw Error(`REFUSE\xB7capsule ${t.digest} \xB7 ${S.region} \xB7 ${O?.why??"no answer"}`);const M=s+":"+c.slice(7),L="place:"+y,N=(O.claims??[]).map(k=>x({scope:k.scope,role:k.role,measure:k.measure,form:k.bound.kind==="interval"?"interval":"alphabet",value:k.bound.kind==="interval"?`${k.bound.lo??0}..${k.bound.hi??0}`:(k.bound.values??[]).join("|"),by:M,at:L})),J=N.join(`
4
+ `)+(N.length?`
5
+ `:""),U="receipts/readings/"+p(S.region??"").slice(7)+"/"+y.slice(7);return[x({scope:r,role:"writes",form:"alphabet",measure:"observed",value:y.slice(7,23),by:M,at:L}),...N,...ge(U,M,f,J,p)]})}const d=t.ask(m),v=m.filter((p,c)=>d[c]?.kind!=="fact");if(v.length)throw new Error(`REFUSE\xB7capsule ${t.digest} \xB7 ${r} \xB7 ${v.length} of ${m.length} regions: ${v.map(p=>p.region).join(" ")} \xB7 ${d[m.indexOf(v[0])]?.why??"no answer"}`);return m.flatMap((p,c)=>{const g=d[c];if(g?.kind!=="fact")return[];const b=Se("sha256").update(JSON.stringify(p)).digest("hex"),R=`place:sha256:${b}`,S=`${s}:${t.digest.slice(7,19)}`,u=l(f=>x({scope:f.scope,role:f.role,form:f.bound.kind==="interval"?"interval":"alphabet",measure:f.measure,value:f.bound.kind==="interval"?`${f.bound.lo??0}..${f.bound.hi??0}`:(f.bound.values??[]).join("|"),by:S,at:R}),"line");return[x({scope:r,role:"writes",form:"alphabet",measure:"observed",value:b.slice(0,16),by:S,at:R}),...(g.claims??[]).map(u)]})})}l(Ze,"readingsAt");function Nt(e){if(e.under)return K(e);const r=Ne(e.root),s=[...new Set(e.standing.flatMap(t=>/^([^/]+)\/uses\//.exec(i(t,"scope"))?.[1]??[]))];return[...K(e),...s.flatMap(t=>K({...e,under:`${t}/`,standing:[...new Set([...r.filter(a=>a.place===t).map(a=>a.line),...e.standing])]}))]}l(Nt,"capsuleReadingsOver");const Ut=l(e=>q(e).current,"currentReceiptObservations"),At=l(e=>{const r=ve(e.store,(C(E(e.root,e.under??"","receipts.bound"))??"").split(`
6
+ `).filter(a=>a.startsWith("bound-lock/")))??[],s=[...new Set([...e.observed,...r])],t=new Set(q({...e,observed:s}).current);return s.filter(a=>!t.has(a))},"retiredReceiptHistory");function q(e,r){if(!G(e.standing,i))return{current:e.observed,legacy:[]};const s=[...new Set(e.observed)],t=re(e.store),a=D(e),n=a.filter(d=>{const v=new Set(d.lines.filter(p=>i(p,"measure")==="writes").map(p=>i(p,"scope").slice(7)));return Object.keys(d.declaration.writes).some(p=>d.declaration.writes[p]==="receipt"&&!v.has(p))});if(!n.length)return{current:e.observed,legacy:[]};const o=Y(e.store,"read"),w=new Set,m=[],j=s.filter(d=>i(d,"scope").startsWith("receipts/readings/")&&i(d,"measure")==="bytes"&&i(d,"role")==="writes");if(he(e.store,s,t,void 0,!0)===void 0)throw Error("REFUSE\xB7capsule receipt carrier context invalid");for(const d of n){if(r!==void 0&&(d.selection??d.digest)!==r)continue;const v=new Set(d.lines.filter(u=>i(u,"measure")==="writes").map(u=>i(u,"scope").slice(7))),p=Object.keys(d.declaration.writes).filter(u=>d.declaration.writes[u]==="receipt"&&!v.has(u)).sort();if(!p.length)continue;const c=t(JSON.stringify([d.selection??d.digest,d.digest,p])),g=new Set;for(const u of j){const f=i(u,"about");if(!f)continue;let y;try{y=JSON.parse(f)}catch{continue}if(!Array.isArray(y)||y[0]!=="reading-context@1"||y[2]!==d.digest||!Array.isArray(y[4])||!y[4].some(([h,F])=>h==="batch"&&F===c)||!y[4].some(([h,F])=>h==="world"&&F===(d.selection??d.digest)))continue;const O=o+":"+c.slice(7);if(i(u,"by")!==O)continue;if(e.standing.some(h=>i(h,"scope")==="keys/"+O&&i(h,"value")!=="withdraw"))throw Error("REFUSE\xB7modern capsule receipt producer ambiguous");const M=i(u,"scope"),L=i(u,"value");if(!p.some(h=>M==="receipts/readings/"+t(h).slice(7)+"/"+L.slice(7)))throw Error("REFUSE\xB7modern capsule receipt scope differs from declared region");for(const[h,F]of y[4])typeof h=="string"&&h.startsWith("legacy/output/")&&h==="legacy/output/"+F&&(g.add(F),m.push([h,F]));const N=i(u,"by"),J=i(u,"value"),U=i(u,"scope"),k=s.find(h=>i(h,"scope")===U&&i(h,"by")===N&&i(h,"measure")==="count"),T=k?i(k,"at"):"";for(const h of s)i(h,"by")===N&&(i(h,"at")==="place:"+J||i(h,"at")===T||i(h,"scope")===U||i(h,"scope")===[U,"identity"].join("/"))&&w.add(h)}const b=d.digest.slice(7,19),R=o+":"+b,S=new Map;for(const u of s)if(i(u,"by")===R){const f=i(u,"at");S.set(f,[...S.get(f)??[],u])}if(S.size){if(n.filter(u=>u.digest===d.digest).length!==1||p.length!==1||new Set(a.filter(u=>u.digest.slice(7,19)===b).map(u=>u.digest)).size!==1||e.standing.some(u=>i(u,"scope")==="keys/"+R&&i(u,"value")!=="withdraw"))throw Error("REFUSE\xB7legacy capsule receipt producer ambiguous");for(const[u,f]of S){if(!/^place:sha256:[a-f0-9]{64}$/.test(u)||f.filter(O=>i(O,"measure")==="observed"&&i(O,"scope")===(e.under||"./")).length!==1)throw Error("REFUSE\xB7legacy capsule receipt occurrence ambiguous");const y=t(f.join(`
7
+ `));if(!g.has(y)){const O=s.filter(L=>!w.has(L)&&!f.includes(L)),M=oe({...e,observed:O})(d.declaration,{name:p[0],at:3},"read","");if(!M||u!=="place:"+t(JSON.stringify(M)))throw Error("REFUSE\xB7legacy capsule receipt context unavailable \xB7 expected "+u+" \xB7 current "+(M?t(JSON.stringify(M)):"absent"))}m.push(["legacy/output/"+y,y]);for(const O of f)w.add(O)}}}return{current:s.filter(d=>!w.has(d)),legacy:[...new Map(m.map(([d,v])=>[d+" "+v,[d,v]])).values()]}}l(q,"modernReceiptInputs");export{oe as askingOf,Nt as capsuleReadingsOver,D as capsulesOf,Ut as currentReceiptObservations,Ct as declaredBy,Ft as describedReceipts,Ie as regionNames,At as retiredReceiptHistory,Jt as selectionLines};
@@ -1,41 +1,2 @@
1
- import { hostOutput } from "../host/call-context.js";
2
- import { boundedProcess } from "../host/process-lifetime.js";
3
- import { spawnSync } from 'node:child_process';
4
- import { existsSync } from 'node:fs';
5
- import { PROTOCOL } from '@lapxo/topos/wire';
6
- import { responsesOf } from '@lapxo/topos/contract';
7
- import { processOf, readerOf } from "./runner.js";
8
- /** The kinds this host starts. A reader of any other kind is signed and stays potential: nothing here runs it. */
9
- export const runs = (kind) => kind === 'js' || kind === 'process';
10
- /** The host end of the contract, beside the command that started this process: a module runs in a process of its own. */
11
- export const hostOf = () => processOf('host');
12
- /**
13
- * A reader runs as a process of its own, started by the runtime from the module its lock names, in the root its places
14
- * are named from: the instrument loads no capsule into itself. It is asked through the one contract, each place with
15
- * the file it is handed or alone when it reads the place by running it, as the region it was matched for when its
16
- * capsule reads with several, and answers one list of claims per place.
17
- */
18
- export function runReader(module, root, inputs, limits) {
19
- if (!inputs.length)
20
- return [];
21
- const requests = inputs.map((input) => ({
22
- protocol: PROTOCOL, verb: 'read', rootScope: input.place, files: input.text === undefined ? [] : [{ place: input.place, text: input.text }], ...(input.held ? { held: input.held } : {}),
23
- ...(input.region ? { region: input.region } : {}),
24
- }));
25
- const reader = readerOf(module);
26
- if (!existsSync(reader.path))
27
- throw new Error(`REFUSE·reader ${module} unavailable; its declared capability needs an admitted provider`);
28
- const args = [...reader.flags, hostOf(), reader.path, module];
29
- const ran = limits === undefined ? spawnSync(process.execPath, args, { cwd: root, input: JSON.stringify(requests), encoding: 'utf8', maxBuffer: 1 << 28 }) : boundedProcess(process.execPath, args, JSON.stringify(requests), limits, root);
30
- if ('error' in ran && ran.error)
31
- throw Object.assign(new Error(`${module}: reader process failed: ${ran.error.message}`), { cause: ran.error });
32
- if (ran.status !== 0)
33
- throw new Error(`${module}: reader exited ${ran.status ?? `with signal ${ran.signal}`}\n${ran.stderr ?? ''}${ran.stdout ?? ''}`);
34
- if (ran.stderr)
35
- hostOutput('error', ran.stderr);
36
- return responsesOf(ran.stdout ?? '', inputs.length).map((answer) => {
37
- if (answer.kind !== 'fact')
38
- throw new Error(`REFUSE·reader ${module} · ${answer.why ?? 'no reading answered'}`);
39
- return (answer.claims ?? []);
40
- });
41
- }
1
+ var d=Object.defineProperty;var s=(t,o)=>d(t,"name",{value:o,configurable:!0});import{hostOutput as p}from"../host/call-context.js";import{boundedProcess as h}from"../host/process-lifetime.js";import{spawnSync as g}from"node:child_process";import{existsSync as l}from"node:fs";import{library11_PROTOCOL as O}from"../vendor/runtime.js";import{library2_responsesOf as m}from"../vendor/runtime.js";import{processOf as w,readerOf as x}from"./runner.js";const j=s(t=>t==="js"||t==="process","runs"),$=s(()=>w("host"),"hostOf");function C(t,o,a,i){if(!a.length)return[];const c=a.map(e=>({protocol:O,verb:"read",rootScope:e.place,files:e.text===void 0?[]:[{place:e.place,text:e.text}],...e.held?{held:e.held}:{},...e.region?{region:e.region}:{}})),n=x(t);if(!l(n.path))throw new Error(`REFUSE\xB7reader ${t} unavailable; its declared capability needs an admitted provider`);const f=[...n.flags,$(),n.path,t],r=i===void 0?g(process.execPath,f,{cwd:o,input:JSON.stringify(c),encoding:"utf8",maxBuffer:1<<28}):h(process.execPath,f,JSON.stringify(c),i,o);if("error"in r&&r.error)throw Object.assign(new Error(`${t}: reader process failed: ${r.error.message}`),{cause:r.error});if(r.status!==0)throw new Error(`${t}: reader exited ${r.status??`with signal ${r.signal}`}
2
+ ${r.stderr??""}${r.stdout??""}`);return r.stderr&&p("error",r.stderr),m(r.stdout??"",a.length).map(e=>{if(e.kind!=="fact")throw new Error(`REFUSE\xB7reader ${t} \xB7 ${e.why??"no reading answered"}`);return e.claims??[]})}s(C,"runReader");export{$ as hostOf,C as runReader,j as runs};
@@ -1,101 +1,4 @@
1
- import { hostInstrumentRuntime } from "../host/call-context.js";
2
- import { spawnSync } from 'node:child_process';
3
- import { sha } from "../host/hash.js";
4
- import { existsSync, mkdirSync, realpathSync, rmSync, statSync, writeFileSync } from 'node:fs';
5
- import { basename, dirname, extname, join, resolve } from 'node:path';
6
- import { fileURLToPath } from 'node:url';
7
- import { fieldOf } from "../fold/claims.js";
8
- import { observeFile, observeText } from "./files.js";
9
- import { ownLockOf } from "../fold/signed.js";
10
- import { landBlob } from "../land/ledger.js";
11
- import { EXTENSION, LOCK, publicLock } from '@lapxo/topos/wire';
12
- import { foldClaims, isWire } from "../fold/claims.js";
13
- const self = () => process.argv[1] ?? '';
14
- const fromBlob = () => hostInstrumentRuntime() !== undefined ? false : extname(existsSync(self()) ? realpathSync(self()) : self()) === '';
15
- /**
16
- * Where the instrument lies and what it is run from: from source or compiled modules, bound is two steps above this runner module; as a blob, the command is a blob of the tree's store, named by the digest bound's own lock names for
17
- * it, and bound lies beside that store. Other processes use the same runtime directory and extension; only source readers receive source conditions. A name that resolves to no blob beside it is refused by name
18
- * before anything is started, never handed to the runtime as the store's own directory.
19
- */
20
- // Blob bundles have no module URL; source and compiled modules carry their own entry location.
21
- // Native library imports do not inspect the embedding application's argv.
22
- // The CLI discovers its default runtime only when a CLI operation requests it.
23
- const moduleAt = () => fromBlob() ? undefined : fileURLToPath(import.meta.url);
24
- const runtimeAt = () => { const explicit = hostInstrumentRuntime(); if (explicit)
25
- return explicit.directory; const at = moduleAt(); return at === undefined ? '' : resolve(dirname(at), '..'); };
26
- const runtimeExtension = () => { const explicit = hostInstrumentRuntime(); if (explicit)
27
- return explicit.extension; const at = moduleAt(); return at === undefined ? '' : extname(at); };
28
- export const ownRoot = () => hostInstrumentRuntime()?.root ?? (fromBlob() ? join(resolve(dirname(self()), '..', '..', '..'), 'bound') : resolve(runtimeAt(), '..'));
29
- /** A published instrument carries its own content store even before any ledger
30
- * exists. Public-lock recognition grants no authority; legacy signed delivery
31
- * trees retain their historical colocated-ledger or sibling-store layout. */
32
- export function instrumentStoreAt(root) {
33
- const lines = (observeText(join(root, LOCK)) ?? '').split('\n').filter(isWire);
34
- const published = lines.length > 0 && publicLock(lines) !== undefined;
35
- return published || existsSync(join(root, EXTENSION, 'ledger')) ? join(root, EXTENSION) : join(root, '..', EXTENSION);
36
- }
37
- export const ownStore = () => instrumentStoreAt(ownRoot());
38
- /** The colocated public artifact is read without an unrelated parent's authority store. */
39
- // An act is judged by the instrument it started with, even when that act changes its colocated lock.
40
- let instrumentLock;
41
- export const ownLock = () => {
42
- const explicit = hostInstrumentRuntime();
43
- if (explicit)
44
- return explicit.lock;
45
- if (instrumentLock !== undefined)
46
- return instrumentLock;
47
- const lines = (observeText(join(ownRoot(), LOCK)) ?? '').split('\n').filter(isWire);
48
- const published = publicLock(lines);
49
- instrumentLock = published === undefined
50
- ? dirname(ownStore()) === ownRoot() ? ownLockOf(ownRoot(), '', true) : ownLockOf(join(ownRoot(), '..'), basename(ownRoot()), true)
51
- : foldClaims(published).standing;
52
- return instrumentLock;
53
- };
54
- export const sourceOf = () => hostInstrumentRuntime()?.entry ?? (fromBlob() ? join(ownRoot(), 'src', 'cli', 'verb.ts') : self());
55
- export function processOf(name, folder) {
56
- if (!fromBlob())
57
- return join(runtimeAt(), folder ?? 'cli', `${name}${runtimeExtension()}`);
58
- const named = ownLock().find((line) => fieldOf(line, 'scope') === `runner/${name}`);
59
- const blob = fieldOf(named ?? '', 'value').replace(/^[^:]*:/, '');
60
- if (!blob || !existsSync(join(dirname(self()), blob))) {
61
- throw new Error(`${basename(ownRoot())}: REFUSE·alias runner/${name} resolves to no blob: ${named === undefined ? 'no signed line of the instrument\'s own lock names it' : `${fieldOf(named, 'value')} is not beside ${basename(self())}`}`);
62
- }
63
- return join(dirname(self()), blob);
64
- }
65
- /**
66
- * A reader's code is what the bundler takes of it: its module and every file that module imports, wherever it lies, as
67
- * one blob of the tree's store named by the digest of its bytes. The files the bundler read, at the stamps they had, key
68
- * the blob, so it is built again only when one of them moved, and a helper a step above the module is one of them.
69
- */
70
- export function bundleOf(module) {
71
- const tree = join(ownRoot(), '..');
72
- const named = fieldOf(ownLock().find((line) => fieldOf(line, 'scope') === 'host/bundler') ?? '', 'value');
73
- const bundler = named && existsSync(join(tree, named)) ? join(tree, named) : '';
74
- if (!bundler)
75
- return undefined;
76
- const store = join(tree, EXTENSION);
77
- const stamp = (coordinate) => ((at) => (at === undefined ? '' : `${at.mtimeMs} ${at.size}`))(statSync(join(tree, coordinate), { throwIfNoEntry: false }));
78
- const index = join(store, 'cas', 'built', sha(`bundle ${module}`));
79
- const held = JSON.parse(observeText(index) ?? 'null');
80
- if (held !== null && existsSync(join(store, 'cas', 'blobs', held.blob)) && held.inputs.every(([coordinate, was]) => stamp(coordinate) === was))
81
- return held.blob;
82
- const [meta, out] = [`${index}.${process.pid}.json`, `${index}.${process.pid}.js`];
83
- mkdirSync(dirname(index), { recursive: true });
84
- const built = spawnSync(bundler, [module, '--bundle', '--platform=node', '--format=cjs', '--external:typescript', '--log-level=error', `--metafile=${meta}`, `--outfile=${out}`], { cwd: tree });
85
- const inputs = Object.keys(JSON.parse(observeText(meta) ?? '{}').inputs ?? {}).sort();
86
- const bytes = observeFile(out);
87
- rmSync(meta, { force: true });
88
- rmSync(out, { force: true });
89
- if (built.status !== 0 || bytes === undefined || !bytes.length || !inputs.length)
90
- return undefined;
91
- const hex = sha(bytes);
92
- landBlob(store, `sha256:${hex}`, bytes);
93
- writeFileSync(index, `${JSON.stringify({ blob: hex, inputs: inputs.map((coordinate) => [coordinate, stamp(coordinate)]) })}\n`);
94
- return hex;
95
- }
96
- /** A reader run by a blob is a blob itself: its bundle, with everything it imports but the compiler. */
97
- export function readerOf(module) {
98
- const source = { path: module, flags: runtimeExtension() === '.ts' ? ['--disable-warning=ExperimentalWarning', '--disable-warning=MODULE_TYPELESS_PACKAGE_JSON'] : [] };
99
- const hex = fromBlob() ? bundleOf(module) : undefined;
100
- return hex === undefined ? source : { path: join(ownStore(), 'cas', 'blobs', hex), flags: [] };
101
- }
1
+ var M=Object.defineProperty;var r=(e,n)=>M(e,"name",{value:n,configurable:!0});import{hostInstrumentRuntime as u}from"../host/call-context.js";import{spawnSync as W}from"node:child_process";import{sha as _}from"../host/hash.js";import{existsSync as m,mkdirSync as X,realpathSync as z,rmSync as j,statSync as D,writeFileSync as G}from"node:fs";import{basename as v,dirname as f,extname as A,join as t,resolve as L}from"node:path";import{fileURLToPath as Y}from"node:url";import{fieldOf as b}from"../fold/claims.js";import{observeFile as q,observeText as y}from"./files.js";import{ownLockOf as T}from"../fold/signed.js";import{landBlob as H}from"../land/ledger.js";import{library11_EXTENSION as S,library11_LOCK as C,library11_publicLock as I}from"../vendor/runtime.js";import{foldClaims as Q,isWire as J}from"../fold/claims.js";const c=r(()=>process.argv[1]??"","self"),x=r(()=>u()!==void 0?!1:A(m(c())?z(c()):c())==="","fromBlob"),R=r(()=>x()?void 0:Y(import.meta.url),"moduleAt"),F=r(()=>{const e=u();if(e)return e.directory;const n=R();return n===void 0?"":L(f(n),"..")},"runtimeAt"),K=r(()=>{const e=u();if(e)return e.extension;const n=R();return n===void 0?"":A(n)},"runtimeExtension"),s=r(()=>u()?.root??(x()?t(L(f(c()),"..","..",".."),"bound"):L(F(),"..")),"ownRoot");function V(e){const n=(y(t(e,C))??"").split(`
2
+ `).filter(J);return n.length>0&&I(n)!==void 0||m(t(e,S,"ledger"))?t(e,S):t(e,"..",S)}r(V,"instrumentStoreAt");const P=r(()=>V(s()),"ownStore");let O;const U=r(()=>{const e=u();if(e)return e.lock;if(O!==void 0)return O;const n=(y(t(s(),C))??"").split(`
3
+ `).filter(J),o=I(n);return O=o===void 0?f(P())===s()?T(s(),"",!0):T(t(s(),".."),v(s()),!0):Q(o).standing,O},"ownLock"),ae=r(()=>u()?.entry??(x()?t(s(),"src","cli","verb.ts"):c()),"sourceOf");function me(e,n){if(!x())return t(F(),n??"cli",`${e}${K()}`);const o=U().find(d=>b(d,"scope")===`runner/${e}`),l=b(o??"","value").replace(/^[^:]*:/,"");if(!l||!m(t(f(c()),l)))throw new Error(`${v(s())}: REFUSE\xB7alias runner/${e} resolves to no blob: ${o===void 0?"no signed line of the instrument's own lock names it":`${b(o,"value")} is not beside ${v(c())}`}`);return t(f(c()),l)}r(me,"processOf");function Z(e){const n=t(s(),".."),o=b(U().find(i=>b(i,"scope")==="host/bundler")??"","value"),l=o&&m(t(n,o))?t(n,o):"";if(!l)return;const d=t(n,S),k=r(i=>(a=>a===void 0?"":`${a.mtimeMs} ${a.size}`)(D(t(n,i),{throwIfNoEntry:!1})),"stamp"),p=t(d,"cas","built",_(`bundle ${e}`)),h=JSON.parse(y(p)??"null");if(h!==null&&m(t(d,"cas","blobs",h.blob))&&h.inputs.every(([i,a])=>k(i)===a))return h.blob;const[g,E]=[`${p}.${process.pid}.json`,`${p}.${process.pid}.js`];X(f(p),{recursive:!0});const B=W(l,[e,"--bundle","--platform=node","--format=cjs","--external:typescript","--log-level=error",`--metafile=${g}`,`--outfile=${E}`],{cwd:n}),N=Object.keys(JSON.parse(y(g)??"{}").inputs??{}).sort(),$=q(E);if(j(g,{force:!0}),j(E,{force:!0}),B.status!==0||$===void 0||!$.length||!N.length)return;const w=_($);return H(d,`sha256:${w}`,$),G(p,`${JSON.stringify({blob:w,inputs:N.map(i=>[i,k(i)])})}
4
+ `),w}r(Z,"bundleOf");function be(e){const n={path:e,flags:K()===".ts"?["--disable-warning=ExperimentalWarning","--disable-warning=MODULE_TYPELESS_PACKAGE_JSON"]:[]},o=x()?Z(e):void 0;return o===void 0?n:{path:t(P(),"cas","blobs",o),flags:[]}}r(be,"readerOf");export{Z as bundleOf,V as instrumentStoreAt,U as ownLock,s as ownRoot,P as ownStore,me as processOf,be as readerOf,ae as sourceOf};