@prestack/thread 0.1.3 → 0.1.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 (270) hide show
  1. package/CHANGELOG.md +563 -0
  2. package/dist/core/actor.d.ts +1 -1
  3. package/dist/core/actor.js +5 -4
  4. package/dist/core/actor.ts +5 -4
  5. package/dist/core/attach.d.ts +0 -7
  6. package/dist/core/attach.js +38 -67
  7. package/dist/core/attach.ts +34 -80
  8. package/dist/core/chain.js +13 -17
  9. package/dist/core/chain.ts +11 -15
  10. package/dist/core/condition.d.ts +4 -4
  11. package/dist/core/condition.js +2 -2
  12. package/dist/core/descend.d.ts +4 -2
  13. package/dist/core/descend.js +91 -23
  14. package/dist/core/descend.ts +90 -21
  15. package/dist/core/errors/catalogue.d.ts +52 -0
  16. package/dist/{operations/errors/errors.js → core/errors/catalogue.js} +1 -1
  17. package/dist/{operations/errors/errors.ts → core/errors/catalogue.ts} +1 -1
  18. package/dist/{operations/errors/catalog.d.ts → core/errors/error.d.ts} +2 -3
  19. package/dist/{operations/errors/catalog.js → core/errors/error.js} +1 -16
  20. package/dist/{operations/errors/catalog.ts → core/errors/error.ts} +3 -19
  21. package/dist/core/errors/namespaces.d.ts +3 -0
  22. package/dist/core/errors/namespaces.js +15 -0
  23. package/dist/core/errors/namespaces.ts +19 -0
  24. package/dist/core/finding.js +2 -2
  25. package/dist/core/finding.ts +1 -2
  26. package/dist/core/init.d.ts +1 -1
  27. package/dist/core/init.js +51 -5
  28. package/dist/core/init.ts +58 -5
  29. package/dist/core/invoked.d.ts +1 -1
  30. package/dist/core/invoked.js +3 -1
  31. package/dist/core/invoked.ts +5 -2
  32. package/dist/core/round.js +36 -22
  33. package/dist/core/round.ts +26 -9
  34. package/dist/core/rows.d.ts +4 -0
  35. package/dist/core/rows.js +31 -2
  36. package/dist/core/rows.ts +33 -1
  37. package/dist/core/scope.d.ts +1 -0
  38. package/dist/core/scope.js +1 -0
  39. package/dist/core/scope.ts +2 -0
  40. package/dist/core/thread.d.ts +3 -3
  41. package/dist/core/tree.d.ts +4 -1
  42. package/dist/core/tree.js +26 -6
  43. package/dist/core/tree.ts +29 -6
  44. package/dist/core/types.d.ts +3 -3
  45. package/dist/core/types.js +3 -1
  46. package/dist/core/types.ts +2 -1
  47. package/dist/derivation/attach.js +3 -2
  48. package/dist/derivation/attach.ts +2 -1
  49. package/dist/derivation/generators/build.js +6 -6
  50. package/dist/derivation/generators/build.ts +1 -1
  51. package/dist/derivation/generators/check.js +1 -1
  52. package/dist/derivation/generators/determinism.js +1 -1
  53. package/dist/derivation/generators/release.js +60 -47
  54. package/dist/derivation/generators/release.ts +66 -43
  55. package/dist/derivation/release.d.ts +7 -3
  56. package/dist/derivation/release.js +14 -1
  57. package/dist/derivation/release.ts +22 -2
  58. package/dist/integrations/attach.d.ts +4 -0
  59. package/dist/integrations/attach.js +37 -56
  60. package/dist/integrations/attach.ts +54 -60
  61. package/dist/integrations/cli.d.ts +37 -0
  62. package/dist/integrations/cli.js +440 -0
  63. package/dist/integrations/cli.ts +543 -0
  64. package/dist/{core/files.d.ts → integrations/disk.d.ts} +16 -24
  65. package/dist/integrations/disk.js +435 -0
  66. package/dist/integrations/disk.ts +465 -0
  67. package/dist/integrations/generators/read.js +6 -6
  68. package/dist/integrations/generators/read.ts +4 -4
  69. package/dist/integrations/generators/vault.js +10 -11
  70. package/dist/integrations/generators/vault.ts +4 -5
  71. package/dist/{operations/http.d.ts → integrations/https.d.ts} +10 -6
  72. package/dist/integrations/https.js +170 -0
  73. package/dist/integrations/https.ts +216 -0
  74. package/dist/integrations/pglite.d.ts +26 -0
  75. package/dist/integrations/pglite.js +143 -0
  76. package/dist/integrations/pglite.ts +206 -0
  77. package/dist/integrations/secret.d.ts +8 -2
  78. package/dist/integrations/secret.js +3 -5
  79. package/dist/integrations/secret.ts +10 -6
  80. package/dist/integrations/target.d.ts +155 -14
  81. package/dist/integrations/target.js +171 -50
  82. package/dist/integrations/target.ts +377 -61
  83. package/dist/integrations/vault.d.ts +1 -0
  84. package/dist/integrations/vault.js +20 -5
  85. package/dist/integrations/vault.ts +17 -5
  86. package/dist/integrity/attach.js +8 -77
  87. package/dist/integrity/attach.ts +7 -76
  88. package/dist/integrity/check-threads.js +5 -5
  89. package/dist/integrity/check-threads.ts +2 -2
  90. package/dist/integrity/constraint.d.ts +0 -1
  91. package/dist/integrity/constraint.js +267 -366
  92. package/dist/integrity/constraint.ts +267 -375
  93. package/dist/integrity/generators/compiler.js +14 -17
  94. package/dist/integrity/generators/compiler.ts +10 -15
  95. package/dist/integrity/generators/gate.js +15 -15
  96. package/dist/integrity/generators/gate.ts +10 -10
  97. package/dist/integrity/generators/issues.js +7 -7
  98. package/dist/integrity/generators/publish.js +39 -57
  99. package/dist/integrity/generators/publish.ts +44 -55
  100. package/dist/integrity/generators/trial.d.ts +3 -3
  101. package/dist/integrity/generators/trial.js +133 -165
  102. package/dist/integrity/generators/trial.ts +145 -169
  103. package/dist/integrity/lint.js +9 -13
  104. package/dist/integrity/lint.ts +7 -10
  105. package/dist/integrity/lsp/bin.js +5 -4
  106. package/dist/integrity/lsp/bin.ts +3 -1
  107. package/dist/integrity/lsp/diagnostics.js +3 -3
  108. package/dist/integrity/lsp/diagnostics.ts +1 -1
  109. package/dist/integrity/lsp/lint.js +19 -30
  110. package/dist/integrity/lsp/lint.ts +16 -32
  111. package/dist/integrity/lsp/server.js +3 -3
  112. package/dist/integrity/slopnator.d.ts +3 -13
  113. package/dist/integrity/slopnator.js +59 -38
  114. package/dist/integrity/slopnator.ts +54 -38
  115. package/dist/integrity/slopnators/sl_broken_lineage.js +2 -2
  116. package/dist/integrity/slopnators/sl_declared_elsewhere.js +1 -1
  117. package/dist/integrity/slopnators/sl_derived_drift.js +4 -4
  118. package/dist/integrity/slopnators/sl_derived_drift.ts +1 -1
  119. package/dist/integrity/slopnators/sl_door_in_a_node.js +220 -0
  120. package/dist/integrity/slopnators/sl_door_in_a_node.ts +250 -0
  121. package/dist/integrity/slopnators/sl_inert_island.js +10 -8
  122. package/dist/integrity/slopnators/sl_inert_island.ts +8 -6
  123. package/dist/integrity/slopnators/sl_missing_row.js +6 -51
  124. package/dist/integrity/slopnators/sl_missing_row.ts +4 -50
  125. package/dist/integrity/slopnators/sl_no_barrel.js +1 -1
  126. package/dist/integrity/slopnators/sl_no_child_process.js +36 -18
  127. package/dist/integrity/slopnators/sl_no_child_process.ts +44 -18
  128. package/dist/integrity/slopnators/sl_no_dispatch_bypass.js +80 -149
  129. package/dist/integrity/slopnators/sl_no_dispatch_bypass.ts +95 -147
  130. package/dist/integrity/slopnators/sl_no_import_cycle.js +15 -4
  131. package/dist/integrity/slopnators/sl_no_import_cycle.ts +20 -4
  132. package/dist/integrity/slopnators/sl_no_such_command.js +2 -2
  133. package/dist/integrity/slopnators/sl_no_such_command.ts +1 -1
  134. package/dist/integrity/slopnators/sl_outside_an_operation.js +20 -0
  135. package/dist/integrity/slopnators/sl_outside_an_operation.ts +25 -0
  136. package/dist/integrity/slopnators/sl_screen_holds_only_declared.d.ts +2 -0
  137. package/dist/integrity/slopnators/sl_screen_holds_only_declared.js +61 -0
  138. package/dist/integrity/slopnators/sl_screen_holds_only_declared.ts +70 -0
  139. package/dist/integrity/slopnators/sl_secret_literal.js +1 -33
  140. package/dist/integrity/slopnators/sl_secret_literal.ts +1 -33
  141. package/dist/integrity/slopnators/sl_stale_path.js +5 -22
  142. package/dist/integrity/slopnators/sl_stale_path.ts +4 -20
  143. package/dist/integrity/slopnators/sl_twice_meant.js +1 -1
  144. package/dist/integrity/slopnators/sl_twice_parented.js +29 -5
  145. package/dist/integrity/slopnators/sl_twice_parented.ts +28 -4
  146. package/dist/integrity/slopnators/sl_undeclared_crossing.d.ts +4 -1
  147. package/dist/integrity/slopnators/sl_undeclared_crossing.js +426 -62
  148. package/dist/integrity/slopnators/sl_undeclared_crossing.ts +454 -70
  149. package/dist/integrity/slopnators/sl_undeclared_destination.js +59 -25
  150. package/dist/integrity/slopnators/sl_undeclared_destination.ts +69 -21
  151. package/dist/integrity/slopnators/sl_undeclared_list.d.ts +2 -0
  152. package/dist/integrity/slopnators/sl_undeclared_list.js +363 -0
  153. package/dist/integrity/slopnators/sl_undeclared_list.ts +358 -0
  154. package/dist/integrity/slopnators/sl_undeclared_node.js +1 -11
  155. package/dist/integrity/slopnators/sl_undeclared_node.ts +0 -10
  156. package/dist/integrity/slopnators/sl_undeclared_operation.js +111 -29
  157. package/dist/integrity/slopnators/sl_undeclared_operation.ts +134 -26
  158. package/dist/integrity/slopnators/sl_undeclared_variant.js +2 -2
  159. package/dist/integrity/slopnators/sl_undeclared_webhook.d.ts +2 -0
  160. package/dist/integrity/slopnators/sl_undeclared_webhook.js +90 -0
  161. package/dist/integrity/slopnators/sl_undeclared_webhook.ts +108 -0
  162. package/dist/integrity/slopnators/sl_underived_route.d.ts +2 -0
  163. package/dist/integrity/slopnators/sl_underived_route.js +61 -0
  164. package/dist/integrity/slopnators/sl_underived_route.ts +72 -0
  165. package/dist/integrity/slopnators/sl_ungoverned_island.js +3 -3
  166. package/dist/integrity/slopnators/sl_ungoverned_island.ts +1 -1
  167. package/dist/integrity/slopnators/sl_unlisted_program.d.ts +2 -0
  168. package/dist/integrity/slopnators/sl_unlisted_program.js +39 -0
  169. package/dist/integrity/slopnators/sl_unlisted_program.ts +40 -0
  170. package/dist/integrity/slopnators/sl_unnamed_island.js +1 -1
  171. package/dist/integrity/slopnators/sl_unpaired_member.js +3 -3
  172. package/dist/integrity/slopnators/sl_unpaired_member.ts +1 -1
  173. package/dist/integrity/slopnators/sl_unpaired_slopnator.js +4 -4
  174. package/dist/integrity/slopnators/sl_unpaired_slopnator.ts +1 -1
  175. package/dist/integrity/slopnators/sl_unprefixed_member.js +5 -31
  176. package/dist/integrity/slopnators/sl_unprefixed_member.ts +2 -28
  177. package/dist/integrity/slopnators/sl_unthreaded.js +11 -7
  178. package/dist/integrity/slopnators/sl_unthreaded.ts +6 -7
  179. package/dist/integrity/slopnators/sl_untranslated_key.js +2 -25
  180. package/dist/integrity/slopnators/sl_untranslated_key.ts +1 -25
  181. package/dist/integrity/slopnators/sl_unvaulted_secret.d.ts +2 -0
  182. package/dist/integrity/slopnators/sl_unvaulted_secret.js +107 -0
  183. package/dist/integrity/slopnators/sl_unvaulted_secret.ts +132 -0
  184. package/dist/integrity/slopnators/sl_unversioned.js +6 -4
  185. package/dist/integrity/slopnators/sl_unversioned.ts +5 -3
  186. package/dist/integrity/sweep.d.ts +1 -0
  187. package/dist/integrity/sweep.js +105 -42
  188. package/dist/integrity/sweep.ts +115 -42
  189. package/dist/knowledge/attach.js +4 -3
  190. package/dist/knowledge/attach.ts +3 -2
  191. package/dist/knowledge/generators/docsgen.js +8 -6
  192. package/dist/knowledge/generators/docsgen.ts +4 -2
  193. package/dist/knowledge/generators/glossary.js +4 -4
  194. package/dist/knowledge/generators/glossary.ts +1 -1
  195. package/dist/operations/access.d.ts +23 -0
  196. package/dist/operations/access.js +28 -1
  197. package/dist/operations/access.ts +43 -0
  198. package/dist/operations/attach.js +33 -113
  199. package/dist/operations/attach.ts +51 -117
  200. package/dist/operations/capabilities.d.ts +14 -5
  201. package/dist/operations/capabilities.js +13 -4
  202. package/dist/operations/capabilities.ts +27 -8
  203. package/dist/operations/dispatch.d.ts +8 -2
  204. package/dist/operations/dispatch.js +128 -185
  205. package/dist/operations/dispatch.ts +138 -191
  206. package/dist/operations/error-results.d.ts +1 -1
  207. package/dist/operations/error-results.js +2 -2
  208. package/dist/operations/error-results.ts +2 -2
  209. package/dist/operations/generators/capability.d.ts +11 -1
  210. package/dist/operations/generators/capability.js +481 -224
  211. package/dist/operations/generators/capability.ts +562 -233
  212. package/dist/operations/generators/compile.js +66 -39
  213. package/dist/operations/generators/compile.ts +78 -39
  214. package/dist/operations/generators/permits.js +11 -12
  215. package/dist/operations/generators/permits.ts +3 -4
  216. package/dist/operations/generators/seed.d.ts +1 -0
  217. package/dist/operations/generators/seed.js +19 -17
  218. package/dist/operations/generators/seed.ts +22 -14
  219. package/dist/operations/generators/trial.d.ts +6 -8
  220. package/dist/operations/generators/trial.js +200 -70
  221. package/dist/operations/generators/trial.ts +230 -93
  222. package/dist/operations/nodes.d.ts +15 -16
  223. package/dist/operations/nodes.ts +16 -17
  224. package/dist/operations/operations.d.ts +40 -4
  225. package/dist/operations/operations.js +1 -0
  226. package/dist/operations/operations.ts +61 -4
  227. package/dist/operations/result.d.ts +2 -2
  228. package/dist/operations/result.ts +2 -2
  229. package/package.json +1 -4
  230. package/dist/core/answers.d.ts +0 -171
  231. package/dist/core/answers.js +0 -789
  232. package/dist/core/answers.ts +0 -999
  233. package/dist/core/client.d.ts +0 -63
  234. package/dist/core/client.js +0 -249
  235. package/dist/core/client.ts +0 -289
  236. package/dist/core/files.js +0 -171
  237. package/dist/core/files.ts +0 -222
  238. package/dist/integrations/module.d.ts +0 -6
  239. package/dist/integrations/module.js +0 -153
  240. package/dist/integrations/module.ts +0 -191
  241. package/dist/integrity/slopnators/sl_unkept_rows.js +0 -104
  242. package/dist/integrity/slopnators/sl_unkept_rows.ts +0 -111
  243. package/dist/integrity/slopnators/sl_unseamed_reach.js +0 -73
  244. package/dist/integrity/slopnators/sl_unseamed_reach.ts +0 -79
  245. package/dist/operations/cost.d.ts +0 -14
  246. package/dist/operations/cost.js +0 -37
  247. package/dist/operations/cost.ts +0 -58
  248. package/dist/operations/errors/errors.d.ts +0 -52
  249. package/dist/operations/http.js +0 -124
  250. package/dist/operations/http.ts +0 -169
  251. package/dist/operations/memory.d.ts +0 -104
  252. package/dist/operations/memory.js +0 -365
  253. package/dist/operations/memory.ts +0 -470
  254. package/dist/operations/metering.d.ts +0 -55
  255. package/dist/operations/metering.js +0 -247
  256. package/dist/operations/metering.ts +0 -328
  257. package/dist/operations/queue-policy.d.ts +0 -3
  258. package/dist/operations/queue-policy.js +0 -8
  259. package/dist/operations/queue-policy.ts +0 -10
  260. package/dist/operations/seams.d.ts +0 -239
  261. package/dist/operations/seams.js +0 -45
  262. package/dist/operations/seams.ts +0 -364
  263. package/dist/operations/store.d.ts +0 -14
  264. package/dist/operations/store.js +0 -1
  265. package/dist/operations/store.ts +0 -29
  266. /package/dist/{operations → core}/errors/classes.d.ts +0 -0
  267. /package/dist/{operations → core}/errors/classes.js +0 -0
  268. /package/dist/{operations → core}/errors/classes.ts +0 -0
  269. /package/dist/integrity/slopnators/{sl_unkept_rows.d.ts → sl_door_in_a_node.d.ts} +0 -0
  270. /package/dist/integrity/slopnators/{sl_unseamed_reach.d.ts → sl_outside_an_operation.d.ts} +0 -0
@@ -1,69 +1,77 @@
1
1
  import { ANONYMOUS, ENVIRONMENT } from '../core/actor.ts'
2
- import { errorDefForResult } from './error-results.ts'
3
- import { DbConflict } from './errors/errors.ts'
4
- import { quoted, runtime } from './generators/seed.ts'
2
+ import { HOLDS, type Holds, type Reach } from '../integrations/target.ts'
3
+ import { PERMITS_AT } from './access.ts'
4
+ import { DbConflict } from '../core/errors/catalogue.ts'
5
+ import { beside, quoted, runtime } from './generators/seed.ts'
5
6
  import type { ResultCode } from './result.ts'
6
- import { SUPPLY, type AuditOutcome } from './seams.ts'
7
7
 
8
- export const DISPATCH_AT = 'operations/_dispatch.ts'
8
+ const reaching = (holds: (one: Holds) => boolean): readonly Reach[] =>
9
+ (Object.keys(HOLDS) as Reach[]).filter((one) => holds(HOLDS[one]))
9
10
 
10
- const identity = (code: ResultCode): { readonly code: string; readonly class: string } => {
11
- const def = errorDefForResult(code)
12
- return { code: def.code, class: def.class }
13
- }
11
+ const KEEPS = reaching((one) => one.takes === 'entities')
12
+
13
+ const ANSWERS = reaching((one) => one.takes === null)
14
+
15
+ const RUNS = reaching((one) => one.takes === 'calls' && one.addressed === 'nothing')
14
16
 
15
- const CODES: readonly ResultCode[] = ['denied', 'invalid', 'rate_limited', 'feature_denied', 'quota_exceeded', 'error']
17
+ const asked = (reaches: readonly Reach[]): string => reaches.map((one) => "reach === '" + one + "'").join(' || ')
16
18
 
17
- const REFUSAL: Readonly<Record<ResultCode, { readonly said: string; readonly outcome: AuditOutcome }>> = {
18
- denied: { said: 'not allowed', outcome: 'denied' },
19
- invalid: { said: 'invalid input', outcome: 'failed' },
20
- rate_limited: { said: 'rate limited', outcome: 'rate_limited' },
21
- feature_denied: { said: 'not in plan', outcome: 'feature_denied' },
22
- quota_exceeded: { said: 'quota exceeded', outcome: 'quota_exceeded' },
23
- error: { said: 'failed', outcome: 'failed' },
19
+ export const DISPATCH_AT = 'operations/_dispatch.ts'
20
+
21
+ const REFUSAL: Readonly<Record<ResultCode, string>> = {
22
+ denied: 'not allowed',
23
+ invalid: 'invalid input',
24
+ rate_limited: 'rate limited',
25
+ feature_denied: 'not in plan',
26
+ quota_exceeded: 'quota exceeded',
27
+ error: 'failed',
24
28
  }
25
29
 
26
30
  const printed = (value: unknown): string => JSON.stringify(value, null, 2)
27
31
 
28
- const DEFS = Object.fromEntries(CODES.map((code) => [code, identity(code)]))
29
-
30
32
  export const dispatched = (
31
33
  reached: Readonly<
32
34
  Record<
33
35
  string,
34
36
  {
35
37
  readonly reach: string
36
- readonly address: string | null
37
- readonly sends: readonly { readonly secret: string; readonly header: string; readonly prefix: string }[]
38
- readonly calls: Readonly<Record<string, { readonly method: string; readonly path: string }>>
38
+ readonly address?: string
39
+ readonly headers: Readonly<Record<string, string>>
40
+ readonly sends: readonly { readonly secret: string; readonly header: string; readonly prefix: string }[]
41
+ readonly signs: readonly { readonly secret: string; readonly header: string; readonly prefix: string }[]
42
+ readonly calls: Readonly<Record<string, { readonly method: string | null; readonly path: string }>>
39
43
  }
40
44
  >
41
45
  >,
42
46
  ): string => [
47
+ "import { createHmac } from 'node:crypto'",
48
+ '',
43
49
  `import type { Actor } from ${quoted(runtime(DISPATCH_AT, '../../core/actor.ts'))}`,
44
- `import type { Operation } from ${quoted(runtime(DISPATCH_AT, '../operations.ts'))}`,
50
+ `import type { Allowance, Counting, Operation } from ${quoted(runtime(DISPATCH_AT, '../operations.ts'))}`,
45
51
  `import type { FailureIdentity, Result, ResultCode } from ${quoted(runtime(DISPATCH_AT, '../result.ts'))}`,
46
- `import type { AuditOutcome, Handed, LogLevel, QuotaHold, Seams } from ${quoted(runtime(DISPATCH_AT, '../seams.ts'))}`,
52
+ 'import type { Opened } from ' + quoted(runtime(DISPATCH_AT, '../operations.ts')),
53
+ 'import type { Vault } from ' + quoted(runtime(DISPATCH_AT, '../../integrations/secret.ts')),
54
+ `import { permits } from ${quoted(beside(DISPATCH_AT, PERMITS_AT))}`,
47
55
  '',
48
56
  `const ANONYMOUS: Actor = ${printed(ANONYMOUS)}`,
49
57
  '',
50
58
  `const ENVIRONMENT: readonly string[] = ${printed(ENVIRONMENT.map(([fact]) => fact))}`,
51
59
  '',
52
- `const REFUSAL: Readonly<Record<ResultCode, { readonly said: string; readonly outcome: AuditOutcome }>> = ${printed(REFUSAL)}`,
53
- '',
54
- `const DEFS = ${printed(DEFS)} as Readonly<Record<ResultCode, FailureIdentity>>`,
60
+ `const REFUSAL: Readonly<Record<ResultCode, string>> = ${printed(REFUSAL)}`,
55
61
  '',
56
62
  `const CONFLICT = ${printed({ code: DbConflict.def.code, class: DbConflict.def.class })} as FailureIdentity`,
57
63
  '',
58
- `const SUPPLY: Readonly<Record<string, string>> = ${printed(SUPPLY)}`,
59
- '',
60
64
  'type Reached = Readonly<Record<string, {',
61
65
  ' readonly reach: string',
62
- ' readonly address: string | null',
66
+ ' readonly address?: string',
67
+ ' readonly headers: Readonly<Record<string, string>>',
63
68
  ' readonly sends: readonly { readonly secret: string; readonly header: string; readonly prefix: string }[]',
64
- ' readonly calls: Readonly<Record<string, { readonly method: string; readonly path: string }>>',
69
+ ' readonly signs: readonly { readonly secret: string; readonly header: string; readonly prefix: string }[]',
70
+ ' readonly calls: Readonly<Record<string, { readonly method: string | null; readonly path: string }>>',
65
71
  '}>>',
66
72
  '',
73
+ 'type Reaches = Readonly<Record<string, unknown>>',
74
+ '',
67
75
  `const REACHED: Reached = ${printed(reached)}`,
68
76
  '',
69
77
  "const STOPPED = Symbol.for('thread.operation.stopped')",
@@ -78,6 +86,22 @@ export const dispatched = (
78
86
  ' ...(identity === undefined ? {} : { errorCode: identity.code, errorClass: identity.class }),',
79
87
  '}) as Result<never>',
80
88
  '',
89
+ 'const allowance = async (',
90
+ ' id: string,',
91
+ ' actor: Actor,',
92
+ ' counting: Counting | undefined,',
93
+ ' held: Allowance | undefined,',
94
+ ' code: ResultCode,',
95
+ '): Promise<Result<never> | undefined> => {',
96
+ ' if (held === undefined) return undefined',
97
+ ' if (counting === undefined) {',
98
+ " return fail('error', REFUSAL['error'], id + ' allows ' + String(held.runs) + ' run(s) per ' + held.per + ' and this dispatch was handed nothing to count with. An operation that states an allowance is handed a counter or it does not run')",
99
+ ' }',
100
+ " const seen = await counting['seen'](id + '/' + String(actor.id ?? 'anonymous') + '/' + code, held.per)",
101
+ ' if (seen <= held.runs) return undefined',
102
+ " return fail(code, REFUSAL[code], String(seen) + ' of ' + String(held.runs) + ' allowed per ' + held.per)",
103
+ '}',
104
+ '',
81
105
  "const strings = (value: unknown): value is string[] => Array.isArray(value) && value.every((one) => typeof one === 'string')",
82
106
  '',
83
107
  'const person = (value: unknown): Actor | undefined => {',
@@ -110,12 +134,6 @@ export const dispatched = (
110
134
  " return one[STOPPED] === true ? { value: one['value'] } : undefined",
111
135
  '}',
112
136
  '',
113
- 'const marked = (thrown: unknown): string | undefined => {',
114
- " if (typeof thrown !== 'object' || thrown === null) return undefined",
115
- ' const said = (thrown as { readonly node?: unknown }).node',
116
- " return typeof said === 'string' ? said : undefined",
117
- '}',
118
- '',
119
137
  'const platform = (thrown: unknown): string | undefined => {',
120
138
  " if (typeof thrown !== 'object' || thrown === null) return undefined",
121
139
  ' const said = (thrown as { readonly because?: unknown }).because',
@@ -130,60 +148,88 @@ export const dispatched = (
130
148
  ' return held',
131
149
  '}',
132
150
  '',
133
- 'const bound = (word: string, wired: Reached[string], seams: Seams): Record<string, unknown> | string => {',
151
+ 'const bound = (word: string, wired: Reached[string], opened: Reaches, opening: Vault | undefined, within: number): Record<string, unknown> | string => {',
152
+ ' const reached = opened[word]',
153
+ ' const { reach } = wired',
154
+ ' if (' + asked(ANSWERS) + ') {',
155
+ ' const held = reached',
156
+ ' if (held === undefined) {',
157
+ " return word + ' is a disk this operation requires, and this dispatch was handed none under that name. The disk under this process is written in by thread capabilities; one at the other end of a connection is handed in by whoever opened it'",
158
+ ' }',
159
+ ' return held as unknown as Record<string, unknown>',
160
+ ' }',
161
+ ' if (' + asked(KEEPS) + ') {',
162
+ ' if (reached === undefined) {',
163
+ " return word + ' keeps rows for this app, and this dispatch was handed no store. A store is written in by thread capabilities, out of the target that keeps the entity'",
164
+ ' }',
165
+ ' return reached as unknown as Record<string, unknown>',
166
+ ' }',
167
+ '',
134
168
  ' const names = Object.keys(wired.calls)',
135
169
  ' if (names.length === 0) {',
136
170
  ' return `\\`${word}\\` is required and takes no call, so there is nothing to hand a node. Declare one with \\`thread create target call\\``',
137
171
  ' }',
138
- ' if (seams.http === undefined) {',
139
- ' return `\\`${word}\\` is reached over ${wired.reach} and the seams this dispatch was handed hold no \\`http\\` — wire one, or take \\`${word}\\` off that operation\'s row`',
172
+ ' if (' + asked(RUNS) + ') {',
173
+ ' const held = reached',
174
+ ' if (held === undefined) {',
175
+ " return word + ' is a program this operation requires, and this dispatch was handed none under that name. A program is written in by thread capabilities, out of the calls declared beside the target'",
176
+ ' }',
177
+ ' const out: Record<string, unknown> = {}',
178
+ ' for (const name of names) {',
179
+ ' const doing = (held as unknown as Record<string, unknown>)[name]',
180
+ " if (typeof doing !== 'function') {",
181
+ " return word + ' takes ' + name + ' and the program handed in under that name does not answer to it, so a node would be handed a word that does nothing'",
182
+ ' }',
183
+ ' out[name] = (args: readonly string[], shows?: boolean, sooner?: number, how?: unknown) => (doing as (a: readonly string[], s?: boolean, w?: number, h?: unknown) => unknown)(args, shows, sooner === undefined ? within : Math.min(sooner, within), how)',
184
+ ' }',
185
+ ' return out',
140
186
  ' }',
141
- ' const wanted = [...(wired.address === null ? [] : [wired.address]), ...wired.sends.map((one) => one.secret)]',
142
- ' if (wanted.length > 0 && seams.vault === undefined) {',
143
- ' return `\\`${word}\\` needs ${wanted.join(\', \')} and the seams this dispatch was handed hold no \\`vault\\` to open them. A target is reached with what opens it or not at all`',
187
+ ' if (reached === undefined) {',
188
+ " return word + ' is reached over ' + wired.reach + ', and this dispatch was handed nothing to send an outward call through. thread capabilities writes that in; or take that word off the row that requires it'",
189
+ ' }',
190
+ ' const wanted = [...wired.sends.map((one) => one.secret), ...wired.signs.map((one) => one.secret)]',
191
+ ' if (wanted.length > 0 && opening === undefined) {',
192
+ " return word + ' needs ' + wanted.join(', ') + ' and this dispatch was handed no vault to open them. A target is reached with what opens it or not at all'",
144
193
  ' }',
145
194
  ' const out: Record<string, unknown> = {}',
146
195
  ' for (const name of names) {',
147
196
  ' const call = wired.calls[name]',
148
197
  ' if (call === undefined) continue',
149
- ' out[name] = async (given?: { fills?: Readonly<Record<string, string | number>>; json?: unknown; body?: Uint8Array; contentType?: string }) => {',
150
- ' const values = wanted.length === 0 ? {} : await seams.vault!.resolve(wanted)',
198
+ ' out[name] = async (given?: { fills?: Readonly<Record<string, string | number>>; json?: unknown; body?: Uint8Array; contentType?: string; told?: (said: unknown) => void }) => {',
199
+ " const values = wanted.length === 0 ? {} : await opening!['resolve'](wanted)",
151
200
  ' const headers: Record<string, string> = {}',
201
+ ' for (const [name, value] of Object.entries(wired.headers)) headers[name] = value',
152
202
  ' for (const one of wired.sends) headers[one.header] = `${one.prefix}${values[one.secret] ?? \'\'}`',
153
203
  ' const body = given?.json === undefined ? given?.body : new TextEncoder().encode(JSON.stringify(given.json))',
154
- ' return await seams.http!.call({',
204
+ ' for (const one of wired.signs) {',
205
+ " const mac = createHmac('sha256', values[one.secret] ?? '').update(body ?? new Uint8Array()).digest('hex')",
206
+ ' headers[one.header] = one.prefix + mac',
207
+ ' }',
208
+ " const send = reached as { call: (request: unknown, within?: number) => Promise<unknown> }",
209
+ " return await send['call']({",
155
210
  ' target: word,',
156
- ' address: wired.address === null ? \'\' : (values[wired.address] ?? \'\'),',
211
+ ' address: wired.address ?? \'\',',
157
212
  " method: call.method as 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',",
158
213
  ' path: filled(call.path, given?.fills),',
159
214
  ' headers,',
160
215
  ' ...(body === undefined ? {} : { body, contentType: given?.contentType ?? \'application/json\' }),',
161
- ' })',
216
+ ' ...(given?.told === undefined ? {} : { told: given.told }),',
217
+ ' }, within)',
162
218
  ' }',
163
219
  ' }',
164
220
  ' return out',
165
221
  '}',
166
222
  '',
167
-
168
- 'const given = (operation: Operation<unknown, string>, actor: Actor, seams: Seams): Record<string, unknown> | string => {',
169
- ' const held: Record<string, unknown> = { actor }',
223
+ 'const given = (operation: Operation<unknown, string>, actor: Actor, opened: Reaches, opening: Vault | undefined, telling: (said: unknown) => void): Record<string, unknown> | string => {',
224
+ ' const held: Record<string, unknown> = { actor, tell: telling }',
170
225
  ' for (const word of operation.requires) {',
171
- ' const key = SUPPLY[word]',
172
- ' if (key === undefined) {',
173
- ' const wired = REACHED[word]',
174
- ' if (wired === undefined) {',
175
- ' return `\\`${operation.id}\\` requires \\`${word}\\`, and nothing here supplies it — what may be required is ${[...Object.keys(SUPPLY), ...Object.keys(REACHED)].join(\', \')}`',
176
- ' }',
177
- ' const reached = bound(word, wired, seams)',
178
- " if (typeof reached === 'string') return reached",
179
- ' held[word] = reached',
180
- ' continue',
181
- ' }',
182
- ' const seam = (seams as unknown as Record<string, unknown>)[key]',
183
- ' if (seam === undefined) {',
184
- ' return `\\`${operation.id}\\` requires \\`${word}\\`, and the seams this dispatch was handed hold no \\`${key}\\` — wire one, or take \\`${word}\\` off that operation\'s row. An operation does not run short of what it declared`',
226
+ ' const wired = REACHED[word]',
227
+ ' if (wired === undefined) {',
228
+ ' return `\\`${operation[\'id\']}\\` requires \\`${word}\\`, and this app declares no target by that name. An operation requires targets: declare one with \\`thread create target\\`, or take that word off its row`',
185
229
  ' }',
186
- ' held[key] = seam',
230
+ ' const reached = bound(word, wired, opened, opening, operation.timeout)',
231
+ " if (typeof reached === 'string') return reached",
232
+ ' held[word] = reached',
187
233
  ' }',
188
234
  ' return held',
189
235
  '}',
@@ -192,155 +238,56 @@ export const dispatched = (
192
238
  ' operation: Operation<I, R>,',
193
239
  ' rawInput: unknown,',
194
240
  ' asking: Actor,',
195
- ' seams: Seams,',
241
+ ' opened: Reaches,',
242
+ ' opening: Vault | undefined,',
243
+ ' counting?: Counting,',
244
+ ' telling?: (said: unknown) => void,',
196
245
  '): Promise<Result<unknown>> {',
197
246
  ' const id = operation.id',
198
247
  ' const who = person(asking)',
199
- ' const run = who?.run ?? seams.random.uuid()',
200
- ' const actor: Actor = { ...(who ?? ANONYMOUS), run }',
201
- ' const span = seams.telemetry?.start(id, run, { ...actor })',
202
- '',
203
- ' const gates = { rate: seams.rateLimiter !== undefined, replay: seams.idempotency !== undefined, quota: seams.quotas !== undefined, telemetry: seams.telemetry !== undefined }',
204
- '',
205
- ' let hold: QuotaHold | null = null',
206
- ' let granted: string | undefined',
207
- '',
208
- ' const sank = (what: string) => (thrown: unknown): void => {',
209
- " seams.log.write('error', id, actor, {",
210
- ' [`${what}_failed`]: thrown instanceof Error ? thrown.message : String(thrown),',
211
- ' })',
212
- ' }',
213
- '',
214
- ' const settled = async (held: Result<unknown>, because?: string): Promise<Result<unknown>> => {',
215
- " const outcome: AuditOutcome = held.ok ? 'ok' : REFUSAL[held.code].outcome",
216
- ' const detail = because === undefined ? {} : { because }',
217
- '',
218
- ' const reserved = hold === null ? null : operation.estimate',
219
- ' let consumed: number | null = null',
220
- '',
221
- ' if (hold !== null) {',
222
- ' const settling = held.ok ? hold.commit(operation.estimate) : hold.release()',
223
- ' consumed = held.ok ? operation.estimate : 0',
224
- ' hold = null',
225
- " await settling.catch(sank('quota'))",
226
- ' }',
227
- '',
228
- " seams.log.write(held.ok ? 'info' : 'warn', id, actor, {",
229
- ' outcome,',
230
- ' ...detail,',
231
- " access: { roles: actor.roles, entitlements: actor.entitlements, granted: granted ?? 'not reached' },",
232
- ' quota: { meter: id, reserved, consumed },',
233
- ' gates,',
234
- ' })',
235
- ' if (held.ok) span?.ok()',
236
- ' else span?.error(outcome)',
237
- '',
238
- ' await seams.audit',
239
- " .append(actor, { action: id, outcome, subject: { type: 'operation', id }, ...detail })",
240
- " .catch(sank('audit'))",
241
- '',
242
- ' if (!held.ok) {',
243
- ' const identity: FailureIdentity =',
244
- ' held.errorCode === undefined || held.errorClass === undefined',
245
- ' ? DEFS[held.code]',
246
- ' : { code: held.errorCode, class: held.errorClass }',
247
- '',
248
- ' await seams.errors',
249
- ' .record(actor, { code: identity.code, class: identity.class, action: id, ...detail })',
250
- " .catch(sank('errors'))",
251
- ' }',
252
- '',
253
- ' return held',
254
- ' }',
255
- '',
256
- ' const refused = (code: ResultCode, because?: string): Promise<Result<unknown>> =>',
257
- ' settled(fail(code, REFUSAL[code].said, because), because)',
258
- '',
259
- ' const recorded = (began: number, ok: boolean, at: string | undefined, because?: string): void => {',
260
- ' const took = seams.clock.now() - began',
261
- ' const sections = {',
262
- ' node: { at: at ?? null },',
263
- ' audit: { actor, when: began },',
264
- ' observability: { ms: took, ok, ...(because === undefined ? {} : { because }) },',
265
- ' }',
266
- '',
267
- " seams.log.write(ok ? 'info' : 'warn', id, actor, sections)",
268
- ' seams.telemetry?.record?.({',
269
- ' key: id,',
270
- ' traceId: run,',
271
- ' spanId: run,',
272
- ' durationMs: took,',
273
- ' ok,',
274
- ' attrs: sections,',
275
- ' actor,',
276
- ' ...(at === undefined ? {} : { nodeId: at }),',
277
- ' workflowId: id,',
278
- ' ...(because === undefined ? {} : { error: because }),',
279
- ' })',
280
- ' }',
281
- '',
248
+ ' const actor: Actor = who ?? ANONYMOUS',
282
249
  ' try {',
283
- " if (who === undefined) return await refused('denied', 'identity_invalid')",
284
- '',
285
- " if (seams.rateLimiter !== undefined && !(await seams.rateLimiter.check(actor, id))) return await refused('rate_limited')",
286
- '',
287
- ' const replayed = seams.idempotency === undefined ? null : await seams.idempotency.check(actor.replay, id)',
288
- " if (replayed !== null && replayed !== undefined) return await settled(ok(replayed), 'replayed')",
289
- '',
250
+ " if (who === undefined) return fail('denied', REFUSAL['denied'], 'identity_invalid')",
290
251
  ' const parsed = operation.input.safeParse(rawInput)',
291
252
  ' if (!parsed.success) {',
292
- " return await refused('invalid', parsed.error.issues.map((one) => one.message).join('; '))",
293
- ' }',
294
- '',
295
- ' if (seams.quotas) {',
296
- ' const reserved = await seams.quotas.reserve(actor, id, operation.estimate)',
297
- " if (!reserved.ok) return await refused('quota_exceeded', reserved.behavior ?? 'block')",
298
- ' hold = reserved',
253
+ " return fail('invalid', REFUSAL['invalid'], String(parsed['error']))",
299
254
  ' }',
300
- '',
301
- ' if (seams.permits === undefined) {',
302
- " return await refused('denied', 'no permits check is wired, so nothing can permit this operation')",
255
+ ' const { resource } = operation',
256
+ ' const ruled = permits(actor, id, resource(parsed[\'data\']))',
257
+ ' const { allow, because: why } = ruled',
258
+ " if (!allow) return fail('denied', REFUSAL['denied'], why)",
259
+ '',
260
+ ' const { entitled } = operation',
261
+ ' if (entitled !== undefined && !actor.entitlements.includes(entitled)) {',
262
+ " return fail('feature_denied', REFUSAL['feature_denied'], id + ' is offered on ' + entitled + ', which this caller does not hold')",
303
263
  ' }',
304
264
  '',
305
- ' const ruled = await seams.permits.check(actor, id, operation.resource(parsed.data))',
306
- " if (!ruled.allow) return await refused('denied', ruled.because)",
307
- ' granted = ruled.because',
265
+ " const limited = await allowance(id, actor, counting, operation.rate, 'rate_limited')",
266
+ ' if (limited !== undefined) return limited',
267
+ " const over = await allowance(id, actor, counting, operation.quota, 'quota_exceeded')",
268
+ ' if (over !== undefined) return over',
308
269
  '',
309
- ' const hands = given(operation as Operation<unknown, string>, actor, seams)',
310
- " if (typeof hands === 'string') return await refused('error', hands)",
270
+ ' const handed = given(operation as Operation<unknown, string>, actor, opened, opening, telling ?? (() => undefined))',
271
+ " if (typeof handed === 'string') return fail('error', REFUSAL['error'], handed)",
311
272
  '',
312
273
  ' const held: { readonly input: I } & Record<string, unknown> = { input: parsed.data }',
313
- ' const began = seams.clock.now()',
314
- ' let value: unknown',
315
- ' try {',
316
- ' value = await operation.run(hands as Handed<R>, held)',
317
- ' } catch (thrown) {',
318
- ' recorded(began, stopped(thrown) !== undefined, marked(thrown), thrown instanceof Error ? thrown.message : String(thrown))',
319
- ' throw thrown',
320
- ' }',
321
- ' recorded(began, true, undefined)',
322
- '',
323
- " if (seams.idempotency !== undefined) await seams.idempotency.store(actor.replay, id, value).catch(sank('idempotency'))",
324
- '',
325
- ' return await settled(ok(value))',
274
+ ' const value = await operation.run(handed as Opened<R>, held)',
275
+ ' return ok(value)',
326
276
  ' } catch (thrown) {',
327
277
  ' const early = stopped(thrown)',
328
278
  ' if (early !== undefined) {',
329
- " if (seams.idempotency !== undefined) await seams.idempotency.store(actor.replay, id, early.value).catch(sank('idempotency'))",
330
- " return await settled(ok(early.value), 'stopped')",
279
+ ' return ok(early[\'value\'])',
331
280
  ' }',
332
281
  '',
333
282
  ' const message = thrown instanceof Error ? thrown.message : String(thrown)',
334
283
  '',
335
284
  " if (named(thrown, 'VersionConflictError')) {",
336
- " return await settled(fail('invalid', message, 'version_conflict', CONFLICT), 'version_conflict')",
285
+ " return fail('invalid', message, 'version_conflict', CONFLICT)",
337
286
  ' }',
338
287
  '',
339
288
  " const code: ResultCode = named(thrown, 'ValidationError') ? 'invalid' : 'error'",
340
289
  ' const because = platform(thrown) ?? message',
341
- ' return await settled(fail(code, message, because), because)',
342
- ' } finally {',
343
- ' span?.end()',
290
+ ' return fail(code, message, because)',
344
291
  ' }',
345
292
  '}',
346
293
  '',
@@ -1,4 +1,4 @@
1
- import { PlatformError, type ErrorDef } from './errors/catalog.ts';
1
+ import { PlatformError, type ErrorDef } from '../core/errors/error.ts';
2
2
  import type { Result, ResultCode } from './result.ts';
3
3
  export declare function errorDefForResult(code: ResultCode): ErrorDef;
4
4
  export declare function platformErrorForResult(result: Result<unknown>, run: string): PlatformError;
@@ -1,5 +1,5 @@
1
- import { PlatformError, catalog } from "./errors/catalog.js";
2
- import { AuthDenied, FeatureNotInPlan, InternalInvalidArgument, InternalUnexpected, QuotaExceeded, RateLimitExceeded } from "./errors/errors.js";
1
+ import { PlatformError, catalog } from '../core/errors/error.js';
2
+ import { AuthDenied, FeatureNotInPlan, InternalInvalidArgument, InternalUnexpected, QuotaExceeded, RateLimitExceeded } from '../core/errors/catalogue.js';
3
3
  const RESULT_ERROR_DEFS = {
4
4
  invalid: InternalInvalidArgument.def,
5
5
  denied: AuthDenied.def,
@@ -1,5 +1,5 @@
1
- import { PlatformError, catalog, type ErrorDef } from './errors/catalog.ts'
2
- import { AuthDenied, FeatureNotInPlan, InternalInvalidArgument, InternalUnexpected, QuotaExceeded, RateLimitExceeded } from './errors/errors.ts'
1
+ import { PlatformError, catalog, type ErrorDef } from '../core/errors/error.ts'
2
+ import { AuthDenied, FeatureNotInPlan, InternalInvalidArgument, InternalUnexpected, QuotaExceeded, RateLimitExceeded } from '../core/errors/catalogue.ts'
3
3
 
4
4
  import type { Result, ResultCode } from './result.ts'
5
5
 
@@ -1,5 +1,15 @@
1
- import { type Capability } from '../capabilities.ts';
1
+ import { type Call, type Target } from '../../integrations/target.ts';
2
+ import { type Capability, type Surface } from '../capabilities.ts';
3
+ export interface Surfaced {
4
+ readonly live: readonly Surface[];
5
+ readonly stated: boolean;
6
+ readonly wrong: readonly string[];
7
+ }
8
+ export declare function defaulted(): Surfaced | undefined;
2
9
  export declare function derive(): Promise<{
3
10
  readonly found: readonly Capability[];
4
11
  readonly refusals: readonly string[];
12
+ readonly live: readonly Surface[];
5
13
  }>;
14
+ export declare function reaching(targets: readonly Target[], calls: readonly Call[], stores: readonly string[], vaulted: boolean, carried: boolean): string;
15
+ export declare const asArray: (surfaces: readonly Surface[]) => string;