@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,7 +1,7 @@
1
- import { existsSync, readFileSync, readdirSync } from "../../core/files.js";
1
+ import { existsSync, readFileSync, readdirSync } from '../../integrations/disk.js';
2
2
  import { resolve } from 'node:path';
3
- import { foldersGoverned, here, islandsDeclared, rowsIn } from "./sl_unthreaded.js";
4
- import { findTree } from "../../core/tree.js";
3
+ import { foldersGoverned, here, islandsDeclared, rowsIn } from './sl_unthreaded.js';
4
+ import { findTree } from '../../core/tree.js';
5
5
  const ROOT = findTree().at;
6
6
  const TREE = `${findTree().name}/`;
7
7
  const seeding = (one) => {
@@ -1,4 +1,4 @@
1
- import { existsSync, readFileSync, readdirSync } from '../../core/files.ts'
1
+ import { existsSync, readFileSync, readdirSync } from '../../integrations/disk.ts'
2
2
  import { resolve } from 'node:path'
3
3
 
4
4
  import type { Sourced } from '../constraint.ts'
@@ -1,8 +1,8 @@
1
- import { existsSync, readFileSync } from "../../core/files.js";
1
+ import { existsSync, readFileSync } from '../../integrations/disk.js';
2
2
  import { join, resolve } from 'node:path';
3
- import { SEEDED, SHIPPED, slopnatorName } from "../slopnator.js";
4
- import { here } from "./sl_unthreaded.js";
5
- import { findTree } from "../../core/tree.js";
3
+ import { SEEDED, SHIPPED, slopnatorName } from '../slopnator.js';
4
+ import { here } from './sl_unthreaded.js';
5
+ import { findTree } from '../../core/tree.js';
6
6
  const ROOT = findTree().at;
7
7
  const TREE = `${findTree().name}/`;
8
8
  const ID = /^ {4}id:\s*'([^']+)'/gm;
@@ -1,4 +1,4 @@
1
- import { existsSync, readFileSync } from '../../core/files.ts'
1
+ import { existsSync, readFileSync } from '../../integrations/disk.ts'
2
2
  import { join, resolve } from 'node:path'
3
3
 
4
4
  import { SEEDED, SHIPPED, slopnatorName, type Slopnator } from '../slopnator.ts'
@@ -1,38 +1,12 @@
1
- import { inCode, listBounds, matched } from "../../core/rows.js";
2
- import { PREFIXES } from "../../core/thread.js";
3
- import { here, parses, unreadable } from "./sl_unthreaded.js";
1
+ import { inCode, listBounds, matched } from '../../core/rows.js';
2
+ import { PREFIXES } from '../../core/thread.js';
3
+ import { here, parses, unreadable } from './sl_unthreaded.js';
4
4
  const MEMBERS = 'MEMBERS';
5
- /*
6
- * Which prefixes a tree file's member list may hold.
7
- *
8
- * The file is the key because the list is named the same in both: `MEMBERS` in the operations tree
9
- * holds what an app can be asked to do, and `MEMBERS` in the nodes tree holds the spans an operation
10
- * is built from. Nothing in TypeScript separates them — both are arrays of rows carrying a string id
11
- * — so an operation declared among the nodes, or a node among the operations, typechecks, attaches,
12
- * seeds a body and reads as agreed by everything downstream.
13
- *
14
- * What an operation may wear is not written here. `@thread/core/thread` pairs each word an
15
- * operation can be with the prefix its id takes, and `thread create` puts that prefix on — so the
16
- * command that makes them and the law that refuses them read one list. Written out again here,
17
- * a kind added over there would be a kind this refuses.
18
- */
19
5
  const TAKES = {
20
6
  'operations.ts': Object.values(PREFIXES),
21
- 'nodes.ts': ['nd_', 'sm_'],
7
+ 'nodes.ts': ['nd_'],
22
8
  };
23
9
  const ID = /\bid:\s*'((?:[^'\\]|\\.)*)'/;
24
- /*
25
- * The id of every row sitting directly in the list, and no deeper.
26
- *
27
- * Depth is the whole of it: a member row states its own id, and the `seeds` and `derives` rows under
28
- * it state theirs, which are neither operations nor nodes — `wf_send_invoice_body` is a body, not
29
- * something an app can be asked to do. Reading every id in the list would refuse those children for
30
- * lacking a prefix they were never meant to wear.
31
- *
32
- * The braces are read off `inCode`, not off the raw text. Counting characters directly desynced on a
33
- * `describes:` holding a brace, and this package already ships the mask and the matcher for exactly
34
- * that — a second, weaker walker beside them is the drift they exist to prevent.
35
- */
36
10
  function directly(text, open, close) {
37
11
  const code = inCode(text);
38
12
  const found = [];
@@ -107,7 +81,7 @@ export const slopnator = {
107
81
  files: [
108
82
  {
109
83
  at: '_threads/operations.ts',
110
- source: "import type { Member, Threaded } from '../../core/thread.ts'\n\nexport const OPERATIONS: Threaded = {\n id: 'operations',\n at: '_threads/operations.ts',\n describes: 'what an app can be asked to do',\n version: 1,\n}\n\nexport const MEMBERS: readonly Member[] = [\n {\n id: 'wf_send_invoice',\n at: '_threads/operations.ts',\n describes: 'sends an invoice',\n version: 1,\n seeds: [\n {\n id: 'wf_send_invoice_body',\n at: 'operations/wf_send_invoice.ts',\n describes: 'the operation itself',\n },\n ],\n },\n]\n",
84
+ source: "import type { Member, Threaded } from '../../core/thread.ts'\n\nexport const OPERATIONS: Threaded = {\n id: 'operations',\n at: '_threads/operations.ts',\n describes: 'what an app can be asked to do',\n version: 1,\n}\n\nexport const MEMBERS: readonly Member[] = [\n {\n id: 'wf_prestack_client',\n at: '_threads/operations.ts',\n describes: 'sends what you typed to the agent',\n version: 1,\n seeds: [\n {\n id: 'wf_prestack_client_body',\n at: 'operations/wf_prestack_client.ts',\n describes: 'the operation itself',\n },\n ],\n },\n]\n",
111
85
  },
112
86
  ],
113
87
  at: '_threads/operations.ts',
@@ -6,39 +6,13 @@ import { here, parses, unreadable } from './sl_unthreaded.ts'
6
6
 
7
7
  const MEMBERS = 'MEMBERS'
8
8
 
9
- /*
10
- * Which prefixes a tree file's member list may hold.
11
- *
12
- * The file is the key because the list is named the same in both: `MEMBERS` in the operations tree
13
- * holds what an app can be asked to do, and `MEMBERS` in the nodes tree holds the spans an operation
14
- * is built from. Nothing in TypeScript separates them — both are arrays of rows carrying a string id
15
- * — so an operation declared among the nodes, or a node among the operations, typechecks, attaches,
16
- * seeds a body and reads as agreed by everything downstream.
17
- *
18
- * What an operation may wear is not written here. `@thread/core/thread` pairs each word an
19
- * operation can be with the prefix its id takes, and `thread create` puts that prefix on — so the
20
- * command that makes them and the law that refuses them read one list. Written out again here,
21
- * a kind added over there would be a kind this refuses.
22
- */
23
9
  const TAKES: Readonly<Record<string, readonly string[]>> = {
24
10
  'operations.ts': Object.values(PREFIXES),
25
- 'nodes.ts': ['nd_', 'sm_'],
11
+ 'nodes.ts': ['nd_'],
26
12
  }
27
13
 
28
14
  const ID = /\bid:\s*'((?:[^'\\]|\\.)*)'/
29
15
 
30
- /*
31
- * The id of every row sitting directly in the list, and no deeper.
32
- *
33
- * Depth is the whole of it: a member row states its own id, and the `seeds` and `derives` rows under
34
- * it state theirs, which are neither operations nor nodes — `wf_send_invoice_body` is a body, not
35
- * something an app can be asked to do. Reading every id in the list would refuse those children for
36
- * lacking a prefix they were never meant to wear.
37
- *
38
- * The braces are read off `inCode`, not off the raw text. Counting characters directly desynced on a
39
- * `describes:` holding a brace, and this package already ships the mask and the matcher for exactly
40
- * that — a second, weaker walker beside them is the drift they exist to prevent.
41
- */
42
16
  function directly(text: string, open: number, close: number): readonly string[] {
43
17
  const code = inCode(text)
44
18
  const found: string[] = []
@@ -116,7 +90,7 @@ export const slopnator: Slopnator = {
116
90
  {
117
91
  at: '_threads/operations.ts',
118
92
  source:
119
- "import type { Member, Threaded } from '../../core/thread.ts'\n\nexport const OPERATIONS: Threaded = {\n id: 'operations',\n at: '_threads/operations.ts',\n describes: 'what an app can be asked to do',\n version: 1,\n}\n\nexport const MEMBERS: readonly Member[] = [\n {\n id: 'wf_send_invoice',\n at: '_threads/operations.ts',\n describes: 'sends an invoice',\n version: 1,\n seeds: [\n {\n id: 'wf_send_invoice_body',\n at: 'operations/wf_send_invoice.ts',\n describes: 'the operation itself',\n },\n ],\n },\n]\n",
93
+ "import type { Member, Threaded } from '../../core/thread.ts'\n\nexport const OPERATIONS: Threaded = {\n id: 'operations',\n at: '_threads/operations.ts',\n describes: 'what an app can be asked to do',\n version: 1,\n}\n\nexport const MEMBERS: readonly Member[] = [\n {\n id: 'wf_prestack_client',\n at: '_threads/operations.ts',\n describes: 'sends what you typed to the agent',\n version: 1,\n seeds: [\n {\n id: 'wf_prestack_client_body',\n at: 'operations/wf_prestack_client.ts',\n describes: 'the operation itself',\n },\n ],\n },\n]\n",
120
94
  },
121
95
  ],
122
96
  at: '_threads/operations.ts',
@@ -1,6 +1,6 @@
1
1
  import { parser } from 'typescript-eslint';
2
- import { LISTS as LINEAGE, descend, forget as forgetDescent, read, reached as fromThread, threading } from "../../core/descend.js";
3
- import { findTree } from "../../core/tree.js";
2
+ import { LISTS as LINEAGE, descend, forget as forgetDescent, read, reached as fromThread, threading } from '../../core/descend.js';
3
+ import { findTree } from '../../core/tree.js';
4
4
  const TREE_AT = findTree();
5
5
  const ROOT = `${TREE_AT.at.split('\\').join('/')}/`;
6
6
  const TREE = TREE_AT.name;
@@ -11,7 +11,6 @@ let threaders;
11
11
  let tree;
12
12
  const parsed = new Map();
13
13
  const broke = new Map();
14
- const SAID = new Set(['at', 'id', 'describes']);
15
14
  const keyOf = (property) => {
16
15
  if (property.computed === true)
17
16
  return undefined;
@@ -38,13 +37,13 @@ function rows(node, list, found, hoisted) {
38
37
  const element = one?.type === 'Identifier' && one.name !== undefined ? hoisted.get(one.name) : one;
39
38
  if (element === null || element === undefined || element.type !== 'ObjectExpression')
40
39
  continue;
40
+ const strings = {};
41
41
  const said = {};
42
42
  for (const property of element.properties ?? []) {
43
43
  const key = keyOf(property);
44
44
  const held = property.value;
45
- if (key !== undefined && SAID.has(key) && held?.type === 'Literal' && typeof held.value === 'string') {
46
- said[key] = held.value;
47
- }
45
+ if (key !== undefined && held?.type === 'Literal' && typeof held.value === 'string')
46
+ strings[key] = held.value;
48
47
  if ((key === 'governs' || key === 'wears') && held?.type === 'ArrayExpression') {
49
48
  said[key] = (held.elements ?? [])
50
49
  .map((one) => (one?.type === 'Literal' && typeof one.value === 'string' ? one.value : undefined))
@@ -53,6 +52,12 @@ function rows(node, list, found, hoisted) {
53
52
  if (key !== undefined && LISTS.has(key) && held?.type === 'ArrayExpression')
54
53
  rows(held, key, found, hoisted);
55
54
  }
55
+ if (strings['at'] !== undefined)
56
+ said.at = strings['at'];
57
+ if (strings['id'] !== undefined)
58
+ said.id = strings['id'];
59
+ if (strings['describes'] !== undefined)
60
+ said.describes = strings['describes'];
56
61
  if (said.at !== undefined || said.id !== undefined)
57
62
  found.push({ list, ...said });
58
63
  }
@@ -335,7 +340,6 @@ export const slopnator = {
335
340
  },
336
341
  ],
337
342
  right: [
338
- "export const HELD: Threaded = {\n declares: [\n {\n at: 'threads/probe.tsx',\n },\n ],\n}",
339
343
  {
340
344
  files: [
341
345
  { at: 'thread/core/thread.ts', source: "export interface Threaded {\n readonly id?: string\n readonly at?: string\n readonly describes?: string\n readonly declares?: readonly Threaded[]\n readonly derives?: readonly Threaded[]\n readonly seeds?: readonly Threaded[]\n}\n" },
@@ -1,4 +1,4 @@
1
- import { readFileSync } from '../../core/files.ts'
1
+ import { readFileSync } from '../../integrations/disk.ts'
2
2
  import { resolve } from 'node:path'
3
3
 
4
4
  import { parser } from 'typescript-eslint'
@@ -35,8 +35,6 @@ export interface Meaning {
35
35
  readonly describes: string
36
36
  }
37
37
 
38
- const SAID = new Set(['at', 'id', 'describes'])
39
-
40
38
  interface Held {
41
39
  readonly type?: string
42
40
  readonly kind?: string
@@ -83,13 +81,12 @@ function rows(node: Held, list: Reach['list'], found: Reach[], hoisted: Readonly
83
81
  for (const one of node.elements ?? []) {
84
82
  const element = one?.type === 'Identifier' && one.name !== undefined ? hoisted.get(one.name) : one
85
83
  if (element === null || element === undefined || element.type !== 'ObjectExpression') continue
84
+ const strings: Record<string, string> = {}
86
85
  const said: { at?: string; id?: string; describes?: string; governs?: readonly string[]; wears?: readonly string[] } = {}
87
86
  for (const property of element.properties ?? []) {
88
87
  const key = keyOf(property)
89
88
  const held = property.value as Held | undefined
90
- if (key !== undefined && SAID.has(key) && held?.type === 'Literal' && typeof held.value === 'string') {
91
- said[key as 'at' | 'id' | 'describes'] = held.value
92
- }
89
+ if (key !== undefined && held?.type === 'Literal' && typeof held.value === 'string') strings[key] = held.value
93
90
  if ((key === 'governs' || key === 'wears') && held?.type === 'ArrayExpression') {
94
91
  said[key] = (held.elements ?? [])
95
92
  .map((one) => (one?.type === 'Literal' && typeof one.value === 'string' ? one.value : undefined))
@@ -97,6 +94,9 @@ function rows(node: Held, list: Reach['list'], found: Reach[], hoisted: Readonly
97
94
  }
98
95
  if (key !== undefined && LISTS.has(key) && held?.type === 'ArrayExpression') rows(held, key as Reach['list'], found, hoisted)
99
96
  }
97
+ if (strings['at'] !== undefined) said.at = strings['at']
98
+ if (strings['id'] !== undefined) said.id = strings['id']
99
+ if (strings['describes'] !== undefined) said.describes = strings['describes']
100
100
  if (said.at !== undefined || said.id !== undefined) found.push({ list, ...said })
101
101
  }
102
102
  }
@@ -402,7 +402,6 @@ export const slopnator: Slopnator = {
402
402
  },
403
403
  ],
404
404
  right: [
405
- "export const HELD: Threaded = {\n declares: [\n {\n at: 'threads/probe.tsx',\n },\n ],\n}",
406
405
  {
407
406
  files: [
408
407
  { at: 'thread/core/thread.ts', source: "export interface Threaded {\n readonly id?: string\n readonly at?: string\n readonly describes?: string\n readonly declares?: readonly Threaded[]\n readonly derives?: readonly Threaded[]\n readonly seeds?: readonly Threaded[]\n}\n" },
@@ -1,31 +1,8 @@
1
- import { existsSync, readFileSync, readdirSync } from "../../core/files.js";
1
+ import { existsSync, readFileSync, readdirSync } from '../../integrations/disk.js';
2
2
  import { join } from 'node:path';
3
- import { named as packageOf } from "../../core/scope.js";
4
- /*
5
- * A KEY THE INTERFACE NAMES AND A LANGUAGE DOES NOT ANSWER.
6
- *
7
- * "i18n keys must be translated OR ITS AN ERROR ... a new constraint.ts row and slopnator that
8
- * checks i18n entries against the keys in the UI and if there's anything missing in whatever
9
- * file, it's a build error, compile error, gate error, everything. Cannot be allowed."
10
- * — founder, 2026-08-29
11
- *
12
- * The generator already writes a line into every language file for every key it finds, so a key is
13
- * never structurally absent — what it cannot do is invent the sentence. This is the half that
14
- * refuses: a line holding nothing is a key nobody has answered, and an app that ships one shows a
15
- * person an empty button.
16
- *
17
- * Deliberately independent of the generator rather than calling it. A check that runs the thing it
18
- * is checking passes whenever that thing passes, which is no check at all — this reads the files
19
- * that are actually on disk and compares them to the markup that is actually there.
20
- */
3
+ import { named as packageOf } from '../../core/scope.js';
21
4
  const SKIP = new Set(['node_modules', '.next', '.git', 'dist', '_generated']);
22
5
  const CODE = /\.(tsx?|jsx?)$/;
23
- /*
24
- * Which props carry a key, read off the installed package's own declarations.
25
- *
26
- * A list written here would go stale the first time an element gained a prop — silently, by finding
27
- * fewer keys than there are, which is the failure this whole law exists to prevent.
28
- */
29
6
  const TYPED = /readonly\s+([A-Za-z][A-Za-z0-9]*)\??\s*:\s*MessageKey\b/g;
30
7
  function walk(at, found = []) {
31
8
  let entries;
@@ -1,37 +1,13 @@
1
- import { existsSync, readFileSync, readdirSync } from '../../core/files.ts'
1
+ import { existsSync, readFileSync, readdirSync } from '../../integrations/disk.ts'
2
2
  import { join } from 'node:path'
3
3
 
4
4
  import type { Slopnator } from '../slopnator.ts'
5
5
  import { named as packageOf } from '../../core/scope.ts'
6
6
 
7
- /*
8
- * A KEY THE INTERFACE NAMES AND A LANGUAGE DOES NOT ANSWER.
9
- *
10
- * "i18n keys must be translated OR ITS AN ERROR ... a new constraint.ts row and slopnator that
11
- * checks i18n entries against the keys in the UI and if there's anything missing in whatever
12
- * file, it's a build error, compile error, gate error, everything. Cannot be allowed."
13
- * — founder, 2026-08-29
14
- *
15
- * The generator already writes a line into every language file for every key it finds, so a key is
16
- * never structurally absent — what it cannot do is invent the sentence. This is the half that
17
- * refuses: a line holding nothing is a key nobody has answered, and an app that ships one shows a
18
- * person an empty button.
19
- *
20
- * Deliberately independent of the generator rather than calling it. A check that runs the thing it
21
- * is checking passes whenever that thing passes, which is no check at all — this reads the files
22
- * that are actually on disk and compares them to the markup that is actually there.
23
- */
24
-
25
7
  const SKIP = new Set(['node_modules', '.next', '.git', 'dist', '_generated'])
26
8
 
27
9
  const CODE = /\.(tsx?|jsx?)$/
28
10
 
29
- /*
30
- * Which props carry a key, read off the installed package's own declarations.
31
- *
32
- * A list written here would go stale the first time an element gained a prop — silently, by finding
33
- * fewer keys than there are, which is the failure this whole law exists to prevent.
34
- */
35
11
  const TYPED = /readonly\s+([A-Za-z][A-Za-z0-9]*)\??\s*:\s*MessageKey\b/g
36
12
 
37
13
  function walk(at: string, found: string[] = []): readonly string[] {
@@ -0,0 +1,2 @@
1
+ import type { Slopnator } from '../slopnator.ts';
2
+ export declare const slopnator: Slopnator;
@@ -0,0 +1,107 @@
1
+ import { descend, read, reached } from '../../core/descend.js';
2
+ import { rowsIn } from './sl_unthreaded.js';
3
+ const SECRETS = 'secrets';
4
+ function wears() {
5
+ const found = new Set();
6
+ descend();
7
+ for (const at of reached()) {
8
+ const text = read(at);
9
+ if (text === undefined)
10
+ continue;
11
+ let waiting = [];
12
+ for (const one of rowsIn(text)) {
13
+ if (one.id === undefined)
14
+ continue;
15
+ if (one.list === 'declares') {
16
+ waiting.push(one.id);
17
+ continue;
18
+ }
19
+ if (one.list !== undefined)
20
+ continue;
21
+ if (one.id === SECRETS) {
22
+ for (const id of waiting) {
23
+ const cut = id.indexOf('_');
24
+ if (cut > 0)
25
+ found.add(id.slice(0, cut + 1));
26
+ }
27
+ }
28
+ waiting = [];
29
+ }
30
+ }
31
+ return [...found];
32
+ }
33
+ const HOLDS = 'process';
34
+ const ENV = 'env';
35
+ const isEnv = (one) => one?.type === 'MemberExpression' &&
36
+ one.object?.type === 'Identifier' &&
37
+ one.object.name === HOLDS &&
38
+ one.property?.type === 'Identifier' &&
39
+ one.property.name === ENV;
40
+ function stated(node, ancestors) {
41
+ if (node === undefined)
42
+ return undefined;
43
+ if (node.type === 'Literal' && typeof node.value === 'string')
44
+ return node.value;
45
+ if (node.type !== 'Identifier' || node.name === undefined)
46
+ return undefined;
47
+ for (const one of ancestors) {
48
+ const body = one.body;
49
+ for (const each of Array.isArray(body) ? body : []) {
50
+ const line = each;
51
+ const held = line.type === 'ExportNamedDeclaration' ? line.declaration : line;
52
+ if (held?.type !== 'VariableDeclaration')
53
+ continue;
54
+ for (const said of held.declarations ?? []) {
55
+ if (said.id?.type !== 'Identifier' || said.id.name !== node.name)
56
+ continue;
57
+ return said.init?.type === 'Literal' && typeof said.init.value === 'string' ? said.init.value : undefined;
58
+ }
59
+ }
60
+ }
61
+ return undefined;
62
+ }
63
+ export const slopnator = {
64
+ on: ['MemberExpression'],
65
+ holds: (node, at) => {
66
+ const held = node;
67
+ if (!isEnv(held.object))
68
+ return false;
69
+ const up = at.ancestors();
70
+ const parent = up[up.length - 1];
71
+ if (parent?.type === 'AssignmentExpression' && parent.left === held)
72
+ return false;
73
+ const name = held.computed === true ? stated(held.property, up) : held.property?.name;
74
+ if (name === undefined) {
75
+ return ('this takes a value out of the environment under a name nobody reading the file can see, so it can name ' +
76
+ 'any secret this app declares. A declared value is opened by the vault, which refuses a name no row states ' +
77
+ 'and a value nothing sealed, and neither of those refusals can happen here');
78
+ }
79
+ const wearing = wears().find((one) => name.toLowerCase().startsWith(one));
80
+ if (wearing === undefined)
81
+ return false;
82
+ return (name +
83
+ ' wears the prefix ' +
84
+ wearing +
85
+ ', so it names a secret, and this takes it from the environment instead of the vault — past the check that a ' +
86
+ 'row declares it, and past the sealed store the value was written to');
87
+ },
88
+ proves: {
89
+ wrong: [
90
+ 'const key = process.env[named.toUpperCase()]',
91
+ {
92
+ files: [
93
+ { at: 'thread/core/thread.ts', source: "export interface Threaded {\n readonly id?: string\n readonly at?: string\n readonly describes?: string\n readonly declares?: readonly Threaded[]\n readonly derives?: readonly Threaded[]\n readonly seeds?: readonly Threaded[]\n}\n" },
94
+ { at: 'threads/thread.ts', source: "import type { Threaded } from '../thread/core/thread.ts'\n\nexport const THREAD: Threaded = {\n declares: [\n {\n at: 'threads/_probe_secrets.ts',\n },\n ],\n}\n" },
95
+ { at: 'threads/_probe_secrets.ts', source: "import type { Threaded } from '../thread/core/thread.ts'\n\nexport const SECRETS: Threaded = {\n id: 'secrets',\n declares: [\n {\n id: 'sec_model',\n at: 'threads/_probe_secrets.ts',\n },\n ],\n}\n" },
96
+ { at: 'probe.tsx', source: "const key = process.env['SEC_MODEL']\n" },
97
+ ],
98
+ at: 'probe.tsx',
99
+ },
100
+ ],
101
+ right: [
102
+ "const mode = process.env['NODE_ENV']",
103
+ "const DEPTH = 'THREAD_DEPTH'\n\nconst depth = Number(process.env[DEPTH] ?? '0')",
104
+ "const held = opened(['sec_model'])",
105
+ ],
106
+ },
107
+ };
@@ -0,0 +1,132 @@
1
+ import type { Slopnator } from '../slopnator.ts'
2
+
3
+ import { descend, read, reached } from '../../core/descend.ts'
4
+ import { rowsIn } from './sl_unthreaded.ts'
5
+
6
+ interface Held {
7
+ readonly type?: string
8
+ readonly name?: string
9
+ readonly value?: unknown
10
+ readonly computed?: boolean
11
+ readonly object?: Held
12
+ readonly property?: Held
13
+ readonly init?: Held
14
+ readonly id?: Held
15
+ readonly declaration?: Held
16
+ readonly declarations?: readonly Held[]
17
+ readonly left?: Held
18
+ }
19
+
20
+ const SECRETS = 'secrets'
21
+
22
+ function wears(): readonly string[] {
23
+ const found = new Set<string>()
24
+
25
+ descend()
26
+
27
+ for (const at of reached()) {
28
+ const text = read(at)
29
+ if (text === undefined) continue
30
+
31
+ let waiting: string[] = []
32
+ for (const one of rowsIn(text)) {
33
+ if (one.id === undefined) continue
34
+ if (one.list === 'declares') {
35
+ waiting.push(one.id)
36
+ continue
37
+ }
38
+ if (one.list !== undefined) continue
39
+ if (one.id === SECRETS) {
40
+ for (const id of waiting) {
41
+ const cut = id.indexOf('_')
42
+ if (cut > 0) found.add(id.slice(0, cut + 1))
43
+ }
44
+ }
45
+ waiting = []
46
+ }
47
+ }
48
+
49
+ return [...found]
50
+ }
51
+
52
+ const HOLDS = 'process'
53
+
54
+ const ENV = 'env'
55
+
56
+ const isEnv = (one: Held | undefined): boolean =>
57
+ one?.type === 'MemberExpression' &&
58
+ one.object?.type === 'Identifier' &&
59
+ one.object.name === HOLDS &&
60
+ one.property?.type === 'Identifier' &&
61
+ one.property.name === ENV
62
+
63
+ function stated(node: Held | undefined, ancestors: readonly unknown[]): string | undefined {
64
+ if (node === undefined) return undefined
65
+ if (node.type === 'Literal' && typeof node.value === 'string') return node.value
66
+ if (node.type !== 'Identifier' || node.name === undefined) return undefined
67
+ for (const one of ancestors) {
68
+ const body = (one as { readonly body?: unknown }).body
69
+ for (const each of Array.isArray(body) ? (body as readonly unknown[]) : []) {
70
+ const line = each as Held
71
+ const held = line.type === 'ExportNamedDeclaration' ? line.declaration : line
72
+ if (held?.type !== 'VariableDeclaration') continue
73
+ for (const said of held.declarations ?? []) {
74
+ if (said.id?.type !== 'Identifier' || said.id.name !== node.name) continue
75
+ return said.init?.type === 'Literal' && typeof said.init.value === 'string' ? said.init.value : undefined
76
+ }
77
+ }
78
+ }
79
+ return undefined
80
+ }
81
+
82
+ export const slopnator: Slopnator = {
83
+ on: ['MemberExpression'],
84
+ holds: (node, at) => {
85
+ const held = node as Held
86
+ if (!isEnv(held.object)) return false
87
+
88
+ const up = at.ancestors()
89
+ const parent = up[up.length - 1] as Held | undefined
90
+ if (parent?.type === 'AssignmentExpression' && parent.left === held) return false
91
+
92
+ const name = held.computed === true ? stated(held.property, up) : held.property?.name
93
+
94
+ if (name === undefined) {
95
+ return (
96
+ 'this takes a value out of the environment under a name nobody reading the file can see, so it can name ' +
97
+ 'any secret this app declares. A declared value is opened by the vault, which refuses a name no row states ' +
98
+ 'and a value nothing sealed, and neither of those refusals can happen here'
99
+ )
100
+ }
101
+
102
+ const wearing = wears().find((one) => name.toLowerCase().startsWith(one))
103
+ if (wearing === undefined) return false
104
+
105
+ return (
106
+ name +
107
+ ' wears the prefix ' +
108
+ wearing +
109
+ ', so it names a secret, and this takes it from the environment instead of the vault — past the check that a ' +
110
+ 'row declares it, and past the sealed store the value was written to'
111
+ )
112
+ },
113
+ proves: {
114
+ wrong: [
115
+ 'const key = process.env[named.toUpperCase()]',
116
+ {
117
+ files: [
118
+ { at: 'thread/core/thread.ts', source: "export interface Threaded {\n readonly id?: string\n readonly at?: string\n readonly describes?: string\n readonly declares?: readonly Threaded[]\n readonly derives?: readonly Threaded[]\n readonly seeds?: readonly Threaded[]\n}\n" },
119
+ { at: 'threads/thread.ts', source: "import type { Threaded } from '../thread/core/thread.ts'\n\nexport const THREAD: Threaded = {\n declares: [\n {\n at: 'threads/_probe_secrets.ts',\n },\n ],\n}\n" },
120
+ { at: 'threads/_probe_secrets.ts', source: "import type { Threaded } from '../thread/core/thread.ts'\n\nexport const SECRETS: Threaded = {\n id: 'secrets',\n declares: [\n {\n id: 'sec_model',\n at: 'threads/_probe_secrets.ts',\n },\n ],\n}\n" },
121
+ { at: 'probe.tsx', source: "const key = process.env['SEC_MODEL']\n" },
122
+ ],
123
+ at: 'probe.tsx',
124
+ },
125
+ ],
126
+ right: [
127
+ "const mode = process.env['NODE_ENV']",
128
+ "const DEPTH = 'THREAD_DEPTH'\n\nconst depth = Number(process.env[DEPTH] ?? '0')",
129
+ "const held = opened(['sec_model'])",
130
+ ],
131
+ },
132
+ }
@@ -1,4 +1,4 @@
1
- import { here, parses, rowsIn } from "./sl_unthreaded.js";
1
+ import { here, parses, rowsIn } from './sl_unthreaded.js';
2
2
  export const slopnator = {
3
3
  holds: (_node, at) => {
4
4
  const path = here(at.filename);
@@ -25,7 +25,8 @@ export const slopnator = {
25
25
  files: [
26
26
  { at: 'thread/core/thread.ts', source: "export interface Threaded {\n readonly id?: string\n readonly at?: string\n readonly describes?: string\n readonly declares?: readonly Threaded[]\n readonly derives?: readonly Threaded[]\n readonly seeds?: readonly Threaded[]\n}\n" },
27
27
  { at: 'threads/thread.ts', source: "import type { Threaded } from '../thread/core/thread.ts'\n\nexport const THREAD: Threaded = {\n declares: [\n {\n at: 'threads/_unversioned_probe.ts',\n },\n ],\n}\n" },
28
- { at: 'threads/_unversioned_probe.ts', source: "import type { Threaded } from '../thread/core/thread.ts'\n\nexport const L: Threaded = {\n id: 'a-law',\n at: 'packages/core/integrity/src/constraint.ts',\n describes: 'A rule that must be enforced.',\n}\n" },
28
+ { at: 'threads/_unversioned_probe.ts', source: "import type { Threaded } from '../thread/core/thread.ts'\n\nexport const L: Threaded = {\n id: 'a-law',\n at: 'thread/integrity/constraint.ts',\n describes: 'A rule that must be enforced.',\n}\n" },
29
+ { at: 'thread/integrity/constraint.ts', source: 'export const CONSTRAINTS = []\n' },
29
30
  ],
30
31
  at: 'threads/_unversioned_probe.ts',
31
32
  },
@@ -35,11 +36,12 @@ export const slopnator = {
35
36
  files: [
36
37
  { at: 'thread/core/thread.ts', source: "export interface Threaded {\n readonly id?: string\n readonly at?: string\n readonly describes?: string\n readonly declares?: readonly Threaded[]\n readonly derives?: readonly Threaded[]\n readonly seeds?: readonly Threaded[]\n}\n" },
37
38
  { at: 'threads/thread.ts', source: "import type { Threaded } from '../thread/core/thread.ts'\n\nexport const THREAD: Threaded = {\n declares: [\n {\n at: 'threads/_unversioned_probe.ts',\n },\n ],\n}\n" },
38
- { at: 'threads/_unversioned_probe.ts', source: "import type { Threaded } from '../thread/core/thread.ts'\n\nexport const L: Threaded = {\n id: 'a-law',\n at: 'packages/core/integrity/src/constraint.ts',\n describes: 'A rule that must be enforced.',\n version: 3,\n}\n" },
39
+ { at: 'threads/_unversioned_probe.ts', source: "import type { Threaded } from '../thread/core/thread.ts'\n\nexport const L: Threaded = {\n id: 'a-law',\n at: 'thread/integrity/constraint.ts',\n describes: 'A rule that must be enforced.',\n version: 3,\n}\n" },
40
+ { at: 'thread/integrity/constraint.ts', source: 'export const CONSTRAINTS = []\n' },
39
41
  ],
40
42
  at: 'threads/_unversioned_probe.ts',
41
43
  },
42
- "export const HELPER = {\n id: 'a-helper',\n at: 'threads/meta.ts',\n describes: 'Nothing conforms to this.',\n}",
44
+ "export const HELPER = {\n id: 'a-helper',\n at: 'threads/core.ts',\n describes: 'Nothing conforms to this.',\n}",
43
45
  ],
44
46
  },
45
47
  };
@@ -30,7 +30,8 @@ export const slopnator: Slopnator = {
30
30
  files: [
31
31
  { at: 'thread/core/thread.ts', source: "export interface Threaded {\n readonly id?: string\n readonly at?: string\n readonly describes?: string\n readonly declares?: readonly Threaded[]\n readonly derives?: readonly Threaded[]\n readonly seeds?: readonly Threaded[]\n}\n" },
32
32
  { at: 'threads/thread.ts', source: "import type { Threaded } from '../thread/core/thread.ts'\n\nexport const THREAD: Threaded = {\n declares: [\n {\n at: 'threads/_unversioned_probe.ts',\n },\n ],\n}\n" },
33
- { at: 'threads/_unversioned_probe.ts', source: "import type { Threaded } from '../thread/core/thread.ts'\n\nexport const L: Threaded = {\n id: 'a-law',\n at: 'packages/core/integrity/src/constraint.ts',\n describes: 'A rule that must be enforced.',\n}\n" },
33
+ { at: 'threads/_unversioned_probe.ts', source: "import type { Threaded } from '../thread/core/thread.ts'\n\nexport const L: Threaded = {\n id: 'a-law',\n at: 'thread/integrity/constraint.ts',\n describes: 'A rule that must be enforced.',\n}\n" },
34
+ { at: 'thread/integrity/constraint.ts', source: 'export const CONSTRAINTS = []\n' },
34
35
  ],
35
36
  at: 'threads/_unversioned_probe.ts',
36
37
  },
@@ -40,11 +41,12 @@ export const slopnator: Slopnator = {
40
41
  files: [
41
42
  { at: 'thread/core/thread.ts', source: "export interface Threaded {\n readonly id?: string\n readonly at?: string\n readonly describes?: string\n readonly declares?: readonly Threaded[]\n readonly derives?: readonly Threaded[]\n readonly seeds?: readonly Threaded[]\n}\n" },
42
43
  { at: 'threads/thread.ts', source: "import type { Threaded } from '../thread/core/thread.ts'\n\nexport const THREAD: Threaded = {\n declares: [\n {\n at: 'threads/_unversioned_probe.ts',\n },\n ],\n}\n" },
43
- { at: 'threads/_unversioned_probe.ts', source: "import type { Threaded } from '../thread/core/thread.ts'\n\nexport const L: Threaded = {\n id: 'a-law',\n at: 'packages/core/integrity/src/constraint.ts',\n describes: 'A rule that must be enforced.',\n version: 3,\n}\n" },
44
+ { at: 'threads/_unversioned_probe.ts', source: "import type { Threaded } from '../thread/core/thread.ts'\n\nexport const L: Threaded = {\n id: 'a-law',\n at: 'thread/integrity/constraint.ts',\n describes: 'A rule that must be enforced.',\n version: 3,\n}\n" },
45
+ { at: 'thread/integrity/constraint.ts', source: 'export const CONSTRAINTS = []\n' },
44
46
  ],
45
47
  at: 'threads/_unversioned_probe.ts',
46
48
  },
47
- "export const HELPER = {\n id: 'a-helper',\n at: 'threads/meta.ts',\n describes: 'Nothing conforms to this.',\n}",
49
+ "export const HELPER = {\n id: 'a-helper',\n at: 'threads/core.ts',\n describes: 'Nothing conforms to this.',\n}",
48
50
  ],
49
51
  },
50
52
  }
@@ -20,5 +20,6 @@ export declare function sweep(root: string, all: readonly Constraint[], slopnato
20
20
  readonly unrun: readonly string[];
21
21
  readonly unmet: readonly string[];
22
22
  readonly linted: readonly string[];
23
+ readonly spent: ReadonlyMap<string, number>;
23
24
  };
24
25
  export {};