@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,4 +1,4 @@
1
- import { mentionsActor, walkOperands } from "../core/condition.js";
1
+ import { mentionsActor, walkOperands } from '../core/condition.js';
2
2
  export const PERMITS_AT = 'src/_generated/permits.ts';
3
3
  export function declaredWords(entities, which, everybody) {
4
4
  const found = entities.flatMap((one) => {
@@ -21,6 +21,33 @@ export function undeclared(answered, offers, which) {
21
21
  'name that value, give it the `choice` format, and state its options'
22
22
  : `it declares ${offers.map((one) => `\`${one}\``).join(', ')}`));
23
23
  }
24
+ export const keyIn = (one) => (one.must ?? []).flatMap((each) => (each.unique?.length === 1 ? [each.unique[0]] : []))[0];
25
+ const wordsFrom = (held) => {
26
+ if (typeof held === 'string')
27
+ return [held];
28
+ if (Array.isArray(held))
29
+ return held.filter((each) => typeof each === 'string');
30
+ return [];
31
+ };
32
+ export const declaredCallers = (entities) => entities.flatMap((one) => {
33
+ const said = one.actor;
34
+ const key = keyIn(one);
35
+ if (said === undefined || key === undefined)
36
+ return [];
37
+ return (one.rows ?? []).flatMap((row) => {
38
+ const named = row[key];
39
+ if (typeof named !== 'string')
40
+ return [];
41
+ return [
42
+ {
43
+ id: named,
44
+ entity: one.id,
45
+ roles: wordsFrom(row[said.roles]),
46
+ entitlements: said.entitlements === undefined ? [] : wordsFrom(row[said.entitlements]),
47
+ },
48
+ ];
49
+ });
50
+ });
24
51
  export function opensToEverybody(grants) {
25
52
  return grants.filter((one) => one.to === undefined && (one.when === undefined || !mentionsActor(one.when)));
26
53
  }
@@ -36,6 +36,49 @@ export function undeclared(answered: string, offers: readonly string[], which: '
36
36
  )
37
37
  }
38
38
 
39
+ export interface Declaring {
40
+ readonly id: string
41
+ readonly holds: readonly { readonly id: string; readonly options?: readonly string[] }[]
42
+ readonly rows?: readonly Record<string, unknown>[]
43
+ readonly must?: readonly { readonly unique?: readonly string[] }[]
44
+ readonly actor?: { readonly roles: string; readonly entitlements?: string }
45
+ }
46
+
47
+ export interface Caller {
48
+ readonly id: string
49
+ readonly entity: string
50
+ readonly roles: readonly string[]
51
+ readonly entitlements: readonly string[]
52
+ }
53
+
54
+ export const keyIn = (one: Declaring): string | undefined =>
55
+ (one.must ?? []).flatMap((each) => (each.unique?.length === 1 ? [each.unique[0] as string] : []))[0]
56
+
57
+ const wordsFrom = (held: unknown): readonly string[] => {
58
+ if (typeof held === 'string') return [held]
59
+ if (Array.isArray(held)) return held.filter((each): each is string => typeof each === 'string')
60
+ return []
61
+ }
62
+
63
+ export const declaredCallers = (entities: readonly Declaring[]): readonly Caller[] =>
64
+ entities.flatMap((one) => {
65
+ const said = one.actor
66
+ const key = keyIn(one)
67
+ if (said === undefined || key === undefined) return []
68
+ return (one.rows ?? []).flatMap((row): readonly Caller[] => {
69
+ const named = row[key]
70
+ if (typeof named !== 'string') return []
71
+ return [
72
+ {
73
+ id: named,
74
+ entity: one.id,
75
+ roles: wordsFrom(row[said.roles]),
76
+ entitlements: said.entitlements === undefined ? [] : wordsFrom(row[said.entitlements]),
77
+ },
78
+ ]
79
+ })
80
+ })
81
+
39
82
  export interface Grant extends Member {
40
83
 
41
84
  readonly may: readonly string[]
@@ -1,12 +1,12 @@
1
- import { named } from "../core/scope.js";
2
- import { LISTS } from "../core/descend.js";
3
- import { quoted } from "../core/rows.js";
4
- import { PERMITS_AT } from "./access.js";
5
- import { CAPABILITIES_AT, CLIENT_AT, DECLARED_SEAMS_AT, DISPATCHING_AT, MCP_AT, OPENAPI_AT, SEAMS_AT } from "./capabilities.js";
6
- import { DISPATCH_AT } from "./dispatch.js";
7
- import { TRIALS_AT } from "./operations.js";
8
- import { MEMBERS_LIST, NODES_FILE, OPERATIONS_FILE } from "./operations.js";
9
- import { SUPPLIES } from "./seams.js";
1
+ import { SHAPED } from '../core/init.js';
2
+ import { NAMED, named } from '../core/scope.js';
3
+ import { LISTS } from '../core/descend.js';
4
+ import { quoted } from '../core/rows.js';
5
+ import { PERMITS_AT } from './access.js';
6
+ import { CAPABILITIES_AT, CLIENT_AT, DEFAULTS_AT, DISPATCHING_AT, MCP_AT, OPENAPI_AT } from './capabilities.js';
7
+ import { DISPATCH_AT } from './dispatch.js';
8
+ import { TRIALS_AT } from './operations.js';
9
+ import { MEMBERS_LIST, NODES_FILE, OPERATIONS_FILE } from './operations.js';
10
10
  const HOME = `node_modules/${named('operations')}/dist`;
11
11
  const VERSION = 1;
12
12
  const ROOT = 'operations';
@@ -16,31 +16,13 @@ const DESCRIBES = 'Everything this app can be asked to do. Each operation is a n
16
16
  export const TAKES = 'What one operation needs before it will run: the shape of its input, what it is expected to cost, and who is allowed to ask for it. Written once when the operation is created, then yours to change.';
17
17
  export const WOVEN = 'The operation written out as one function. `thread compile` builds it from the steps declared for it, so nothing here is edited by hand — anything added here is gone the next time it is compiled.';
18
18
  const NODES = 'Every kind of step an operation can be built from — a read, a branch, a loop. A step holds no code of its own: the work goes in a file written beside the operation that uses it.';
19
- const HANDS = 'What each kind of step hands the code inside it to work with. These live in the package rather than in this app, so a step of the same kind means the same thing in every tree.';
20
19
  const DISPATCH = 'Every operation runs through here and nowhere else. `thread compile` writes it for this app: before a run starts it checks who is asking, what the run may cost and whether the input is valid, then runs the operation and records what happened.';
21
20
  const PROGRAM = 'Every row this package adds to an app, listed in one place so what it put there can be read rather than guessed at. `thread attach` writes back anything missing or edited.';
22
21
  const TRIALS = 'What each operation actually did when it was run, recorded rather than written by hand. `thread trials` runs them against their example inputs and keeps the results; `thread trials --check` runs them again and refuses anything that has changed since.';
23
- const CAPABILITIES = 'Which of this app\'s operations can be reached from outside, and how — as an MCP tool, a terminal command, or a web route. Everything here is worked out from the operations themselves except whether a surface is switched on, which is yours to set.';
22
+ const CAPABILITIES = 'Which of this app\'s operations can be reached from outside, and how — as an MCP tool, a terminal command, or a web route. Everything here is worked out, and nothing here is yours to set: which surfaces are on comes from _threads/defaults.ts and from `off` on each operation row, and `thread create capability` changes either.';
24
23
  const OPENAPI = 'This app\'s web API written as an OpenAPI document: the route, the verb and the input shape of every operation that answers on the web. Generated rather than written, so it cannot describe a route that is not there.';
25
24
  const TOOLS = 'The tools an MCP client is offered: every operation switched on for that surface, with its own sentence and the shape of its input. Switching `mcp` off for an operation is how an agent is told it may not call it.';
26
25
  const CLIENT = 'Every operation a page in this app may call. An operation that is switched off is absent from this file rather than listed and disabled, as is any operation needing a credential a browser must not hold.';
27
- const SAID = {
28
- sm_store: 'Reading and writing rows. An operation that requires it is handed get, list, insert, update and remove already bound to whoever asked, so every row it touches is written under the caller the log names.',
29
- sm_search: 'Indexing a row and querying an index. Required by an operation that has to find something it cannot address by id.',
30
- sm_queue: 'Handing work to something else to run later. Required by an operation that finishes before its effect does.',
31
- sm_events: 'Announcing that something happened, to whoever is listening. Required by an operation other parts of an app react to.',
32
- sm_clock: 'The current time. Required rather than read off the runtime, because an operation that reads the wall clock directly cannot be replayed and its trial cannot be trusted.',
33
- sm_random: 'Randomness. Required for the same reason as the clock: a run nobody can reproduce is a run nobody can check.',
34
- sm_vault: 'Resolving a secret by name, for the rare thing that is not a call — signing a webhook, checking a shared token. An operation that reaches a target does not need this: requiring the target hands its nodes calls with the credential already in them, which is the whole point of declaring one.',
35
- sm_views: 'Reading through a declared view rather than a table. Required by an operation that reads what somebody else composed.',
36
- sm_files: 'Putting a file somewhere, fetching one back, or handing out a signed link to one. Required rather than reached for, because a node that opens a path directly is doing work no record names.',
37
- };
38
- const OFFERED = SUPPLIES.map((id) => ({
39
- id,
40
- at: NODES_AT,
41
- describes: SAID[id],
42
- version: VERSION,
43
- }));
44
26
  const valued = (one) => {
45
27
  if (typeof one === 'string')
46
28
  return quoted(one);
@@ -69,12 +51,20 @@ export const said = (one, pad) => {
69
51
  };
70
52
  const ACCESS = 'Who may ask this app to do what. A row says which operations it permits, on what, to whom, and under what condition. Nothing is permitted by default: an operation no row grants here cannot be run at all.';
71
53
  const PERMITS = 'The check compiled from the grants in _threads/access.ts: one branch per grant, so who may ask for what comes from one statement. Nobody edits it, because an edit here widens or narrows access nobody granted. An app that grants nothing permits nothing.';
72
- const SEAMS = 'What this app hands its operations, written once and then yours. It starts by handing on everything src/_generated/seams.ts settles from your declarations. Replace a seam or add one by naming it in SEAMS: the queue, the events, telemetry, whatever a real deployment needs.';
73
- const DECLARED_SEAMS = 'The seams your declarations settle. Rows go to the store each target derived, and until one does no store is handed, so an operation that needs one is refused; who is calling is read off the entity that names the caller; calls leave through http with credentials the vault opens. Nobody edits it: `thread capabilities` writes it again from the rows.';
74
- const ACCESS_SOURCE = `import type { Grant } from './access.ts'
54
+ const ACCESS_SOURCE = `import type { Grant } from '${NAMED}/operations/access'
75
55
 
76
56
  export const GRANTS: readonly Grant[] = []
77
57
  `;
58
+ const DEFAULTS = 'Which surfaces every operation in this app answers on, stated once for all of them. An operation turns one off with `off` on its own row and can never turn on one this row leaves off. With no `live` stated, every operation answers on cli alone, so nothing is reachable from outside the machine until this row says so. `thread create capability edit defaults` changes it.';
59
+ const DEFAULTS_SOURCE = `import type { Defaults } from '${NAMED}/operations/capabilities'
60
+
61
+ export const DEFAULTS: Defaults = {
62
+ id: 'defaults',
63
+ at: ${quoted(DEFAULTS_AT)},
64
+ describes: ${quoted(DEFAULTS)},
65
+ version: ${String(VERSION)},
66
+ }
67
+ `;
78
68
  const shipped = () => ({
79
69
  id: 'shipped',
80
70
  at: `${HOME}/attach.js`,
@@ -99,6 +89,12 @@ const shipped = () => ({
99
89
  describes: ACCESS,
100
90
  version: VERSION,
101
91
  },
92
+ {
93
+ id: 'defaults',
94
+ at: DEFAULTS_AT,
95
+ describes: DEFAULTS,
96
+ version: VERSION,
97
+ },
102
98
  {
103
99
  id: 'permits',
104
100
  at: PERMITS_AT,
@@ -115,12 +111,6 @@ const shipped = () => ({
115
111
  by: 'thread compile',
116
112
  runs: 'thread compile --check',
117
113
  },
118
- {
119
- id: 'hands',
120
- at: `${HOME}/nodes.js`,
121
- describes: HANDS,
122
- version: VERSION,
123
- },
124
114
  {
125
115
  id: 'trials',
126
116
  at: TRIALS_AT,
@@ -169,21 +159,6 @@ const shipped = () => ({
169
159
  by: 'thread capabilities',
170
160
  runs: 'thread capabilities --check',
171
161
  },
172
- {
173
- id: 'seams',
174
- at: SEAMS_AT,
175
- describes: SEAMS,
176
- version: VERSION,
177
- by: 'thread capabilities',
178
- },
179
- {
180
- id: 'declared-seams',
181
- at: DECLARED_SEAMS_AT,
182
- describes: DECLARED_SEAMS,
183
- version: VERSION,
184
- by: 'thread capabilities',
185
- runs: 'thread capabilities --check',
186
- },
187
162
  {
188
163
  id: 'nd_read',
189
164
  at: NODES_AT,
@@ -226,7 +201,6 @@ const shipped = () => ({
226
201
  describes: 'A step that ends the operation early with an answer. Whatever its block returns becomes the result, and nothing after it runs.',
227
202
  version: VERSION,
228
203
  },
229
- ...OFFERED,
230
204
  ],
231
205
  });
232
206
  const SHIPS = shipped();
@@ -234,20 +208,19 @@ const WHERE = {
234
208
  nodes: { into: OPERATIONS_FILE, list: 'declares' },
235
209
  dispatch: { into: OPERATIONS_FILE, list: 'declares' },
236
210
  access: { into: OPERATIONS_FILE, list: 'declares' },
211
+ defaults: { into: OPERATIONS_FILE, list: 'declares' },
237
212
  permits: { into: OPERATIONS_FILE, list: 'declares' },
238
- 'declared-seams': { into: OPERATIONS_FILE, list: 'declares' },
239
213
  trials: { into: OPERATIONS_FILE, list: 'declares' },
240
214
  capabilities: { into: OPERATIONS_FILE, list: 'declares' },
241
215
  openapi: { into: OPERATIONS_FILE, list: 'declares' },
242
216
  tools: { into: OPERATIONS_FILE, list: 'declares' },
243
217
  client: { into: OPERATIONS_FILE, list: 'declares' },
244
218
  dispatching: { into: OPERATIONS_FILE, list: 'declares' },
245
- seams: { into: OPERATIONS_FILE, list: 'declares' },
246
- hands: { into: NODES_FILE, list: 'declares' },
219
+ reaching: { into: OPERATIONS_FILE, list: 'declares' },
247
220
  };
248
221
  const placed = (id) => WHERE[id] ?? { into: NODES_FILE, list: MEMBERS_LIST };
249
- const NODES_SOURCE = `import type { Threaded } from '../core/thread.ts'
250
- import type { Node } from './nodes.ts'
222
+ const NODES_SOURCE = `import type { Threaded } from '${SHAPED}'
223
+ import type { Node } from '${NAMED}/operations/nodes'
251
224
 
252
225
  export const NODES: Threaded = {
253
226
  id: 'nodes',
@@ -259,7 +232,7 @@ export const NODES: Threaded = {
259
232
 
260
233
  export const ${MEMBERS_LIST}: readonly Node[] = []
261
234
  `;
262
- const OPERATIONS_SOURCE = `import type { Member, Threaded } from '../core/thread.ts'
235
+ const OPERATIONS_SOURCE = `import type { Member, Threaded } from '${SHAPED}'
263
236
 
264
237
  export const OPERATIONS: Threaded = {
265
238
  id: 'operations',
@@ -323,60 +296,7 @@ export const ATTACH = {
323
296
  { file: OPERATIONS_FILE, source: OPERATIONS_SOURCE },
324
297
  { file: NODES_FILE, source: NODES_SOURCE },
325
298
  { file: 'access.ts', source: ACCESS_SOURCE },
326
- ],
327
- retires: [
328
- {
329
- into: 'operations.ts',
330
- list: 'declares',
331
- id: 'reference',
332
- made: `${ROOT}/_docs.md`,
333
- why: `the page stating what this app declares is written by \`${named('knowledge')}\` now, at docs.md, and it states every node rather than operations alone — a package documenting what another package declares would be one package authoring another's`,
334
- },
335
- {
336
- into: 'derivation.ts',
337
- list: 'GENERATORS',
338
- id: 'create-generator',
339
- why: '`thread create` is a command of the CLI itself now, so no row declares it. This package still makes operations, through the `operation-noun` row beside this one',
340
- },
341
- {
342
- into: 'operations.ts',
343
- list: 'declares',
344
- id: 'identity',
345
- made: `src/identity.${'ts'}`,
346
- why: 'who is calling is answered in `src/seams.ts` now, beside the store it reads the caller\'s row from. One derived file says both, because both are read off the same rows',
347
- },
348
- {
349
- into: 'operations.ts',
350
- list: 'declares',
351
- id: 'store',
352
- made: `src/store.${'ts'}`,
353
- why: 'where rows go is decided in `src/seams.ts` now, read off the targets this app declares. A second file that only re-exported one name said nothing the seams did not',
354
- },
355
- {
356
- into: 'operations.ts',
357
- list: 'declares',
358
- id: 'rules-gate',
359
- made: `src/rules.${'ts'}`,
360
- why: '`rules` is what this app refuses, declared in _threads/rules.ts with `thread create rule`. Who may ask for what is `permits`, compiled from the grants and handed to dispatch by src/_generated/seams.ts, so a second file wearing the word said nothing the grants did not',
361
- },
362
- {
363
- into: 'derivation.ts',
364
- list: 'GENERATORS',
365
- id: 'rules-generator',
366
- why: 'the check compiled from the grants is `permits`, and `thread permits` writes it now, through the `permits-generator` row beside this one. A generator called `rules` read as the app\'s own rules, which are declared in _threads/rules.ts with `thread create rule`',
367
- },
368
- {
369
- into: NODES_FILE,
370
- list: MEMBERS_LIST,
371
- id: 'sm_http',
372
- why: 'a call goes to a place, and a place is a target — declare it with `thread create target` and require that instead. Asking for a bare transport is what made an operation impossible to try, because nothing said where it went',
373
- },
374
- {
375
- into: NODES_FILE,
376
- list: MEMBERS_LIST,
377
- id: 'sm_llm',
378
- why: 'a model is reached over https like any other vendor, so it is an `ht_` target with its calls declared beside it. Nothing was lost: its address and its key are now under the same rules as every other credential, and an operation that asks a model can now be tried',
379
- },
299
+ { file: 'defaults.ts', source: DEFAULTS_SOURCE },
380
300
  ],
381
301
  rows: [
382
302
  ...(SHIPS.declares ?? [])
@@ -1,16 +1,16 @@
1
1
  import type { Attaching } from '../core/attach.ts'
2
- import { named } from '../core/scope.ts'
2
+ import { SHAPED } from '../core/init.ts'
3
+ import { NAMED, named } from '../core/scope.ts'
3
4
 
4
5
  import { LISTS } from '../core/descend.ts'
5
6
  import { quoted } from '../core/rows.ts'
6
7
  import type { Threaded } from '../core/thread.ts'
7
8
 
8
9
  import { PERMITS_AT } from './access.ts'
9
- import { CAPABILITIES_AT, CLIENT_AT, DECLARED_SEAMS_AT, DISPATCHING_AT, MCP_AT, OPENAPI_AT, SEAMS_AT } from './capabilities.ts'
10
+ import { CAPABILITIES_AT, CLIENT_AT, DEFAULTS_AT, DISPATCHING_AT, MCP_AT, OPENAPI_AT } from './capabilities.ts'
10
11
  import { DISPATCH_AT } from './dispatch.ts'
11
12
  import { TRIALS_AT } from './operations.ts'
12
13
  import { MEMBERS_LIST, NODES_FILE, OPERATIONS_FILE } from './operations.ts'
13
- import { SUPPLIES, type Supplied } from './seams.ts'
14
14
 
15
15
  const HOME = `node_modules/${named('operations')}/dist`
16
16
 
@@ -34,9 +34,6 @@ export const WOVEN =
34
34
  const NODES =
35
35
  'Every kind of step an operation can be built from — a read, a branch, a loop. A step holds no code of its own: the work goes in a file written beside the operation that uses it.'
36
36
 
37
- const HANDS =
38
- 'What each kind of step hands the code inside it to work with. These live in the package rather than in this app, so a step of the same kind means the same thing in every tree.'
39
-
40
37
  const DISPATCH =
41
38
  'Every operation runs through here and nowhere else. `thread compile` writes it for this app: before a run starts it checks who is asking, what the run may cost and whether the input is valid, then runs the operation and records what happened.'
42
39
 
@@ -47,7 +44,7 @@ const TRIALS =
47
44
  'What each operation actually did when it was run, recorded rather than written by hand. `thread trials` runs them against their example inputs and keeps the results; `thread trials --check` runs them again and refuses anything that has changed since.'
48
45
 
49
46
  const CAPABILITIES =
50
- 'Which of this app\'s operations can be reached from outside, and how — as an MCP tool, a terminal command, or a web route. Everything here is worked out from the operations themselves except whether a surface is switched on, which is yours to set.'
47
+ 'Which of this app\'s operations can be reached from outside, and how — as an MCP tool, a terminal command, or a web route. Everything here is worked out, and nothing here is yours to set: which surfaces are on comes from _threads/defaults.ts and from `off` on each operation row, and `thread create capability` changes either.'
51
48
 
52
49
  const OPENAPI =
53
50
  'This app\'s web API written as an OpenAPI document: the route, the verb and the input shape of every operation that answers on the web. Generated rather than written, so it cannot describe a route that is not there.'
@@ -58,28 +55,28 @@ const TOOLS =
58
55
  const CLIENT =
59
56
  'Every operation a page in this app may call. An operation that is switched off is absent from this file rather than listed and disabled, as is any operation needing a credential a browser must not hold.'
60
57
 
61
- const SAID: Readonly<Record<Supplied, string>> = {
62
- sm_store:
63
- 'Reading and writing rows. An operation that requires it is handed get, list, insert, update and remove already bound to whoever asked, so every row it touches is written under the caller the log names.',
64
- sm_search: 'Indexing a row and querying an index. Required by an operation that has to find something it cannot address by id.',
65
- sm_queue: 'Handing work to something else to run later. Required by an operation that finishes before its effect does.',
66
- sm_events: 'Announcing that something happened, to whoever is listening. Required by an operation other parts of an app react to.',
67
- sm_clock:
68
- 'The current time. Required rather than read off the runtime, because an operation that reads the wall clock directly cannot be replayed and its trial cannot be trusted.',
69
- sm_random: 'Randomness. Required for the same reason as the clock: a run nobody can reproduce is a run nobody can check.',
70
- sm_vault:
71
- 'Resolving a secret by name, for the rare thing that is not a call — signing a webhook, checking a shared token. An operation that reaches a target does not need this: requiring the target hands its nodes calls with the credential already in them, which is the whole point of declaring one.',
72
- sm_views: 'Reading through a declared view rather than a table. Required by an operation that reads what somebody else composed.',
73
- sm_files:
74
- 'Putting a file somewhere, fetching one back, or handing out a signed link to one. Required rather than reached for, because a node that opens a path directly is doing work no record names.',
75
- }
76
58
 
77
- const OFFERED: readonly Threaded[] = SUPPLIES.map((id) => ({
78
- id,
79
- at: NODES_AT,
80
- describes: SAID[id],
81
- version: VERSION,
82
- }))
59
+
60
+
61
+
62
+
63
+
64
+
65
+
66
+
67
+
68
+
69
+
70
+
71
+
72
+
73
+
74
+
75
+
76
+
77
+
78
+
79
+
83
80
 
84
81
  const valued = (one: unknown): string => {
85
82
  if (typeof one === 'string') return quoted(one)
@@ -110,15 +107,22 @@ const ACCESS =
110
107
  const PERMITS =
111
108
  'The check compiled from the grants in _threads/access.ts: one branch per grant, so who may ask for what comes from one statement. Nobody edits it, because an edit here widens or narrows access nobody granted. An app that grants nothing permits nothing.'
112
109
 
113
- const SEAMS =
114
- 'What this app hands its operations, written once and then yours. It starts by handing on everything src/_generated/seams.ts settles from your declarations. Replace a seam or add one by naming it in SEAMS: the queue, the events, telemetry, whatever a real deployment needs.'
110
+ const ACCESS_SOURCE = `import type { Grant } from '${NAMED}/operations/access'
115
111
 
116
- const DECLARED_SEAMS =
117
- 'The seams your declarations settle. Rows go to the store each target derived, and until one does no store is handed, so an operation that needs one is refused; who is calling is read off the entity that names the caller; calls leave through http with credentials the vault opens. Nobody edits it: `thread capabilities` writes it again from the rows.'
112
+ export const GRANTS: readonly Grant[] = []
113
+ `
118
114
 
119
- const ACCESS_SOURCE = `import type { Grant } from './access.ts'
115
+ const DEFAULTS =
116
+ 'Which surfaces every operation in this app answers on, stated once for all of them. An operation turns one off with `off` on its own row and can never turn on one this row leaves off. With no `live` stated, every operation answers on cli alone, so nothing is reachable from outside the machine until this row says so. `thread create capability edit defaults` changes it.'
120
117
 
121
- export const GRANTS: readonly Grant[] = []
118
+ const DEFAULTS_SOURCE = `import type { Defaults } from '${NAMED}/operations/capabilities'
119
+
120
+ export const DEFAULTS: Defaults = {
121
+ id: 'defaults',
122
+ at: ${quoted(DEFAULTS_AT)},
123
+ describes: ${quoted(DEFAULTS)},
124
+ version: ${String(VERSION)},
125
+ }
122
126
  `
123
127
 
124
128
  const shipped = (): Threaded => ({
@@ -145,6 +149,12 @@ const shipped = (): Threaded => ({
145
149
  describes: ACCESS,
146
150
  version: VERSION,
147
151
  },
152
+ {
153
+ id: 'defaults',
154
+ at: DEFAULTS_AT,
155
+ describes: DEFAULTS,
156
+ version: VERSION,
157
+ },
148
158
  {
149
159
  id: 'permits',
150
160
  at: PERMITS_AT,
@@ -161,12 +171,6 @@ const shipped = (): Threaded => ({
161
171
  by: 'thread compile',
162
172
  runs: 'thread compile --check',
163
173
  },
164
- {
165
- id: 'hands',
166
- at: `${HOME}/nodes.js`,
167
- describes: HANDS,
168
- version: VERSION,
169
- },
170
174
  {
171
175
  id: 'trials',
172
176
  at: TRIALS_AT,
@@ -217,21 +221,6 @@ const shipped = (): Threaded => ({
217
221
  by: 'thread capabilities',
218
222
  runs: 'thread capabilities --check',
219
223
  },
220
- {
221
- id: 'seams',
222
- at: SEAMS_AT,
223
- describes: SEAMS,
224
- version: VERSION,
225
- by: 'thread capabilities',
226
- },
227
- {
228
- id: 'declared-seams',
229
- at: DECLARED_SEAMS_AT,
230
- describes: DECLARED_SEAMS,
231
- version: VERSION,
232
- by: 'thread capabilities',
233
- runs: 'thread capabilities --check',
234
- },
235
224
  {
236
225
  id: 'nd_read',
237
226
  at: NODES_AT,
@@ -274,7 +263,7 @@ const shipped = (): Threaded => ({
274
263
  describes: 'A step that ends the operation early with an answer. Whatever its block returns becomes the result, and nothing after it runs.',
275
264
  version: VERSION,
276
265
  },
277
- ...OFFERED,
266
+
278
267
  ],
279
268
  })
280
269
 
@@ -285,23 +274,22 @@ const WHERE: Readonly<Record<string, { readonly into: string; readonly list: str
285
274
 
286
275
  dispatch: { into: OPERATIONS_FILE, list: 'declares' },
287
276
  access: { into: OPERATIONS_FILE, list: 'declares' },
277
+ defaults: { into: OPERATIONS_FILE, list: 'declares' },
288
278
  permits: { into: OPERATIONS_FILE, list: 'declares' },
289
- 'declared-seams': { into: OPERATIONS_FILE, list: 'declares' },
290
279
  trials: { into: OPERATIONS_FILE, list: 'declares' },
291
280
  capabilities: { into: OPERATIONS_FILE, list: 'declares' },
292
281
  openapi: { into: OPERATIONS_FILE, list: 'declares' },
293
282
  tools: { into: OPERATIONS_FILE, list: 'declares' },
294
283
  client: { into: OPERATIONS_FILE, list: 'declares' },
295
284
  dispatching: { into: OPERATIONS_FILE, list: 'declares' },
296
- seams: { into: OPERATIONS_FILE, list: 'declares' },
297
- hands: { into: NODES_FILE, list: 'declares' },
285
+ reaching: { into: OPERATIONS_FILE, list: 'declares' },
298
286
  }
299
287
 
300
288
  const placed = (id: string): { readonly into: string; readonly list: string } =>
301
289
  WHERE[id] ?? { into: NODES_FILE, list: MEMBERS_LIST }
302
290
 
303
- const NODES_SOURCE = `import type { Threaded } from '../core/thread.ts'
304
- import type { Node } from './nodes.ts'
291
+ const NODES_SOURCE = `import type { Threaded } from '${SHAPED}'
292
+ import type { Node } from '${NAMED}/operations/nodes'
305
293
 
306
294
  export const NODES: Threaded = {
307
295
  id: 'nodes',
@@ -314,7 +302,7 @@ export const NODES: Threaded = {
314
302
  export const ${MEMBERS_LIST}: readonly Node[] = []
315
303
  `
316
304
 
317
- const OPERATIONS_SOURCE = `import type { Member, Threaded } from '../core/thread.ts'
305
+ const OPERATIONS_SOURCE = `import type { Member, Threaded } from '${SHAPED}'
318
306
 
319
307
  export const OPERATIONS: Threaded = {
320
308
  id: 'operations',
@@ -381,63 +369,9 @@ export const ATTACH: Attaching = {
381
369
  { file: NODES_FILE, source: NODES_SOURCE },
382
370
 
383
371
  { file: 'access.ts', source: ACCESS_SOURCE },
372
+ { file: 'defaults.ts', source: DEFAULTS_SOURCE },
384
373
  ],
385
374
 
386
- retires: [
387
- {
388
- into: 'operations.ts',
389
- list: 'declares',
390
- id: 'reference',
391
- made: `${ROOT}/_docs.md`,
392
- why: `the page stating what this app declares is written by \`${named('knowledge')}\` now, at docs.md, and it states every node rather than operations alone — a package documenting what another package declares would be one package authoring another's`,
393
- },
394
- {
395
- into: 'derivation.ts',
396
- list: 'GENERATORS',
397
- id: 'create-generator',
398
- why: '`thread create` is a command of the CLI itself now, so no row declares it. This package still makes operations, through the `operation-noun` row beside this one',
399
- },
400
- {
401
- into: 'operations.ts',
402
- list: 'declares',
403
- id: 'identity',
404
- made: `src/identity.${'ts'}`,
405
- why: 'who is calling is answered in `src/seams.ts` now, beside the store it reads the caller\'s row from. One derived file says both, because both are read off the same rows',
406
- },
407
- {
408
- into: 'operations.ts',
409
- list: 'declares',
410
- id: 'store',
411
- made: `src/store.${'ts'}`,
412
- why: 'where rows go is decided in `src/seams.ts` now, read off the targets this app declares. A second file that only re-exported one name said nothing the seams did not',
413
- },
414
- {
415
- into: 'operations.ts',
416
- list: 'declares',
417
- id: 'rules-gate',
418
- made: `src/rules.${'ts'}`,
419
- why: '`rules` is what this app refuses, declared in _threads/rules.ts with `thread create rule`. Who may ask for what is `permits`, compiled from the grants and handed to dispatch by src/_generated/seams.ts, so a second file wearing the word said nothing the grants did not',
420
- },
421
- {
422
- into: 'derivation.ts',
423
- list: 'GENERATORS',
424
- id: 'rules-generator',
425
- why: 'the check compiled from the grants is `permits`, and `thread permits` writes it now, through the `permits-generator` row beside this one. A generator called `rules` read as the app\'s own rules, which are declared in _threads/rules.ts with `thread create rule`',
426
- },
427
-
428
- {
429
- into: NODES_FILE,
430
- list: MEMBERS_LIST,
431
- id: 'sm_http',
432
- why: 'a call goes to a place, and a place is a target — declare it with `thread create target` and require that instead. Asking for a bare transport is what made an operation impossible to try, because nothing said where it went',
433
- },
434
- {
435
- into: NODES_FILE,
436
- list: MEMBERS_LIST,
437
- id: 'sm_llm',
438
- why: 'a model is reached over https like any other vendor, so it is an `ht_` target with its calls declared beside it. Nothing was lost: its address and its key are now under the same rules as every other credential, and an operation that asks a model can now be tried',
439
- },
440
- ],
441
375
  rows: [
442
376
  ...(SHIPS.declares ?? [])
443
377
  .filter((one) => one.id !== ROOT)
@@ -1,13 +1,21 @@
1
- export declare const SURFACES: readonly ["cli", "api", "mcp"];
1
+ import type { Threaded } from '../core/thread.ts';
2
+ export declare const SURFACES: readonly ['cli', 'api', 'mcp', 'webhook'];
2
3
  export type Surface = (typeof SURFACES)[number];
3
4
  export declare const isSurface: (one: string) => one is Surface;
5
+ export declare const MEANS: Readonly<Record<Surface, string>>;
6
+ export declare const DEFAULTS_AT = "_threads/defaults.ts";
7
+ export declare const UNSTATED: readonly Surface[];
8
+ export interface Defaults extends Threaded {
9
+ readonly live?: readonly Surface[];
10
+ }
4
11
  export declare const CAPABILITIES_AT = "operations/_capabilities.json";
5
12
  export declare const CLIENT_AT = "operations/_client.ts";
6
13
  export declare const DISPATCHING_AT = "app/_generated/dispatching.ts";
14
+ export declare const REACHING_AT = "src/_generated/reaching.ts";
15
+ export declare const ACTOR_AT = "src/_generated/actor.ts";
7
16
  export declare const routeAt: (operation: string) => string;
8
- export declare const ROUTE = "The file that answers a request for this one operation. It imports the operation by name, hands it to this app's own dispatch with the seams and the caller its seams file supplies, and answers with the result \u2014 or with the status matching whatever dispatch refused it for. One per operation rather than one for all of them: a route that looked its operation up by a name off the path would hand dispatch something no check had ever seen, which reads exactly like a name that was checked. Switching the `api` surface off in the capabilities table stops this file being written at all, so the operation stops being served rather than being served and turned away.";
9
- export declare const SEAMS_AT = "src/seams.ts";
10
- export declare const DECLARED_SEAMS_AT = "src/_generated/seams.ts";
17
+ export declare const ROUTE = "The file that answers a request for this one operation. It imports the operation by name, hands it to this app's own dispatch along with what this app hands its operations and the caller worked out from the request, and answers with the result \u2014 or with the status matching whatever dispatch refused it for. One per operation rather than one for all of them: a route that looked its operation up by a name off the path would hand dispatch something no check had ever seen, which reads exactly like a name that was checked. An operation that does not answer on api, because its own row turns api off or the defaults sheet leaves it off, has neither this file nor this row: `thread capabilities` takes both out, so it is not served at all rather than served and turned away.";
18
+ export declare const inboundAt: (webhook: string) => string;
11
19
  export declare const OPENAPI_AT = "operations/_openapi.json";
12
20
  export declare const MCP_AT = "operations/_mcp.json";
13
21
  export interface Capability {
@@ -17,8 +25,9 @@ export interface Capability {
17
25
  readonly nodes: readonly string[];
18
26
  readonly input: unknown;
19
27
  readonly live: readonly Surface[];
28
+ readonly webhooks: readonly string[];
29
+ readonly signed: boolean;
20
30
  readonly browsable: boolean;
21
- readonly local: boolean;
22
31
  readonly mcp: {
23
32
  readonly name: string;
24
33
  readonly description: string;