@north-light/crouter 0.3.226 → 0.3.228

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 (288) hide show
  1. package/dist/api/client.d.ts +5 -5
  2. package/dist/api/client.js +3 -3
  3. package/dist/api/dto/broker-ops.d.ts +8 -0
  4. package/dist/api/dto/memory.d.ts +8 -7
  5. package/dist/api/dto/memory.js +2 -2
  6. package/dist/builtin-memory/05-kinds/design/00-base.md +3 -4
  7. package/dist/builtin-memory/05-kinds/design/01-orchestrator.md +4 -3
  8. package/dist/builtin-memory/05-kinds/design/design-contract.md +3 -6
  9. package/dist/builtin-memory/05-kinds/plan/00-base.md +3 -4
  10. package/dist/builtin-memory/05-kinds/plan/01-orchestrator.md +4 -5
  11. package/dist/builtin-memory/05-kinds/plan/plan-contract.md +5 -13
  12. package/dist/builtin-memory/design/guide.md +38 -16
  13. package/dist/builtin-memory/design/roadmap.md +4 -4
  14. package/dist/builtin-memory/insights/init.md +5 -5
  15. package/dist/builtin-memory/internal/INDEX.md +1 -1
  16. package/dist/builtin-memory/internal/examples/INDEX.md +1 -1
  17. package/dist/builtin-memory/internal/memory-loading.md +6 -6
  18. package/dist/builtin-memory/internal/plugins.md +1 -1
  19. package/dist/builtin-memory/plan/guide.md +53 -0
  20. package/dist/builtin-memory/plan/roadmap.md +10 -8
  21. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +50 -37
  22. package/dist/clients/attach/__tests__/pane-tag-successor.test.js +56 -0
  23. package/dist/clients/attach/__tests__/profile-files.test.js +21 -0
  24. package/dist/clients/attach/chrome/inbox-strip.js +11 -7
  25. package/dist/clients/attach/session/pane-tag.d.ts +28 -2
  26. package/dist/clients/attach/session/pane-tag.js +48 -22
  27. package/dist/clients/attach/session/profile-files.d.ts +6 -0
  28. package/dist/clients/attach/session/profile-files.js +44 -11
  29. package/dist/clients/attach/slash/dispatch.js +4 -7
  30. package/dist/clients/attach/viewer.js +588 -596
  31. package/dist/commands/__tests__/surface-reload-target.test.js +21 -0
  32. package/dist/commands/api-client.d.ts +3 -7
  33. package/dist/commands/api-client.js +7 -12
  34. package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.js +292 -0
  35. package/dist/commands/memory/__tests__/repository-root-lint.test.js +146 -0
  36. package/dist/commands/memory/delete.js +51 -24
  37. package/dist/commands/memory/edit.js +50 -10
  38. package/dist/commands/memory/find.js +105 -56
  39. package/dist/commands/memory/history.js +51 -31
  40. package/dist/commands/memory/lint.d.ts +0 -9
  41. package/dist/commands/memory/lint.js +78 -322
  42. package/dist/commands/memory/list.d.ts +12 -4
  43. package/dist/commands/memory/list.js +64 -25
  44. package/dist/commands/memory/move.js +103 -73
  45. package/dist/commands/memory/origin.js +35 -5
  46. package/dist/commands/memory/read.d.ts +4 -0
  47. package/dist/commands/memory/read.js +132 -80
  48. package/dist/commands/memory/shared.d.ts +115 -25
  49. package/dist/commands/memory/shared.js +331 -74
  50. package/dist/commands/memory/write.js +72 -21
  51. package/dist/commands/memory.js +2 -2
  52. package/dist/commands/node/lifecycle.js +2 -2
  53. package/dist/commands/pkg/market-manage.js +25 -24
  54. package/dist/commands/pkg/plugin-manage.d.ts +22 -6
  55. package/dist/commands/pkg/plugin-manage.js +118 -25
  56. package/dist/commands/pkg/shared.d.ts +8 -0
  57. package/dist/commands/pkg/shared.js +23 -20
  58. package/dist/commands/surface-reload.d.ts +5 -0
  59. package/dist/commands/surface-reload.js +9 -1
  60. package/dist/commands/sys/__tests__/migrate.test.js +1140 -22
  61. package/dist/commands/sys/__tests__/sync-project-guidance.test.js +218 -0
  62. package/dist/commands/sys/migrate.js +126 -140
  63. package/dist/commands/sys/panels/profiles-panel.d.ts +66 -0
  64. package/dist/commands/sys/panels/profiles-panel.js +599 -0
  65. package/dist/commands/sys/settings-shell.d.ts +4 -2
  66. package/dist/commands/sys/settings-shell.js +35 -4
  67. package/dist/commands/sys/settings.js +21 -5
  68. package/dist/commands/sys/sync-deps.d.ts +2 -0
  69. package/dist/commands/sys/sync-deps.js +26 -15
  70. package/dist/commands/sys/sync-project-guidance.js +228 -145
  71. package/dist/commands/sys/sync-skills.js +28 -17
  72. package/dist/commands/sys/update.js +11 -3
  73. package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +15 -2
  74. package/dist/core/__tests__/config-change-delta.test.js +106 -0
  75. package/dist/core/__tests__/context-intro.test.js +13 -9
  76. package/dist/core/__tests__/daemon-boot.test.js +22 -16
  77. package/dist/core/__tests__/fixtures/memory-slash-live-probe.js +5 -1
  78. package/dist/core/__tests__/human-deliver.test.js +19 -0
  79. package/dist/core/__tests__/inline-memory-refs.test.js +50 -46
  80. package/dist/core/__tests__/{serial → integration}/broker-fork-seam.test.js +1 -1
  81. package/dist/core/__tests__/{serial → integration}/broker-sdk-wiring.test.js +1 -1
  82. package/dist/core/__tests__/{serial → integration}/broker-snapshot-history.test.js +1 -1
  83. package/dist/core/__tests__/{serial → integration}/command-plugins.test.js +94 -3
  84. package/dist/core/__tests__/{serial → integration}/deferred-no-wake.test.js +1 -1
  85. package/dist/core/__tests__/{serial → integration}/flagship-lifecycle.test.js +13 -27
  86. package/dist/core/__tests__/{serial → integration}/host-teardown-process-group.test.js +1 -1
  87. package/dist/core/__tests__/{serial → integration}/human-deliver-e2e.test.js +1 -1
  88. package/dist/core/__tests__/{live-mutation-verbs.test.js → integration/live-mutation-verbs.test.js} +22 -33
  89. package/dist/core/__tests__/{serial → integration}/live-mutation.test.js +21 -41
  90. package/dist/core/__tests__/integration/refresh-stall-recycle.test.d.ts +1 -0
  91. package/dist/core/__tests__/{serial → integration}/refresh-stall-recycle.test.js +1 -1
  92. package/dist/core/__tests__/integration/revive.test.d.ts +1 -0
  93. package/dist/core/__tests__/{serial → integration}/revive.test.js +38 -19
  94. package/dist/core/__tests__/integration/spawn-root.test.d.ts +1 -0
  95. package/dist/core/__tests__/{serial → integration}/spawn-root.test.js +104 -1
  96. package/dist/core/__tests__/integration/subscription-delivery.test.d.ts +1 -0
  97. package/dist/core/__tests__/{serial → integration}/subscription-delivery.test.js +1 -1
  98. package/dist/core/__tests__/integration/tmux-surface.test.d.ts +1 -0
  99. package/dist/core/__tests__/{serial → integration}/tmux-surface.test.js +1 -1
  100. package/dist/core/__tests__/integration/worktree-land.test.d.ts +1 -0
  101. package/dist/core/__tests__/integration/worktree-land.test.js +400 -0
  102. package/dist/core/__tests__/integration/worktree-reap.test.d.ts +1 -0
  103. package/dist/core/__tests__/{serial/worktree.test.js → integration/worktree-reap.test.js} +6 -338
  104. package/dist/core/__tests__/kickoff.test.js +16 -5
  105. package/dist/core/__tests__/memory-resolver-precedence.test.js +122 -91
  106. package/dist/core/__tests__/nested-store-discovery.test.js +5 -3
  107. package/dist/core/__tests__/on-read-crouter-home-fence.test.js +2 -1
  108. package/dist/core/__tests__/on-read-dedup-resume.test.js +39 -27
  109. package/dist/core/__tests__/on-read-nested-store.test.js +19 -13
  110. package/dist/core/__tests__/profile-project-memory-delivery.test.js +138 -44
  111. package/dist/core/__tests__/repository-association.test.d.ts +1 -0
  112. package/dist/core/__tests__/repository-association.test.js +153 -0
  113. package/dist/core/__tests__/repository-root-identity.test.d.ts +1 -0
  114. package/dist/core/__tests__/repository-root-identity.test.js +219 -0
  115. package/dist/core/__tests__/seam/memory-slash-node-relative-inventory.test.js +27 -11
  116. package/dist/core/__tests__/warm-claim-preference-snapshot.test.d.ts +1 -0
  117. package/dist/core/__tests__/warm-claim-preference-snapshot.test.js +40 -0
  118. package/dist/core/canvas/canvas.d.ts +3 -0
  119. package/dist/core/canvas/canvas.js +30 -10
  120. package/dist/core/canvas/db.js +28 -1
  121. package/dist/core/canvas/paths.d.ts +4 -6
  122. package/dist/core/canvas/paths.js +8 -6
  123. package/dist/core/canvas/render-source.js +2 -2
  124. package/dist/core/canvas/types.d.ts +9 -13
  125. package/dist/core/exclusive-lock.d.ts +2 -0
  126. package/dist/core/exclusive-lock.js +21 -0
  127. package/dist/core/git.d.ts +0 -1
  128. package/dist/core/git.js +0 -3
  129. package/dist/core/human/__tests__/integration/inbox-core.test.d.ts +1 -0
  130. package/dist/core/human/feedback-companion.js +3 -0
  131. package/dist/core/human/scan.js +8 -1
  132. package/dist/core/keybindings/catalog.d.ts +2 -2
  133. package/dist/core/keybindings/catalog.js +2 -1
  134. package/dist/core/memory/doc-link-grammar.js +2 -2
  135. package/dist/core/memory/history.d.ts +24 -0
  136. package/dist/core/memory/history.js +66 -1
  137. package/dist/core/memory/identity.d.ts +65 -0
  138. package/dist/core/memory/identity.js +185 -0
  139. package/dist/core/memory/inline-ref-guidance.d.ts +1 -1
  140. package/dist/core/memory/inline-ref-guidance.js +1 -1
  141. package/dist/core/memory/inline-ref-inventory.d.ts +3 -10
  142. package/dist/core/memory/inline-ref-inventory.js +30 -62
  143. package/dist/core/memory/lint.d.ts +129 -0
  144. package/dist/core/memory/lint.js +517 -0
  145. package/dist/core/memory/project-namespace.d.ts +31 -0
  146. package/dist/core/memory/project-namespace.js +85 -0
  147. package/dist/core/memory/repository-association.d.ts +31 -0
  148. package/dist/core/memory/repository-association.js +129 -0
  149. package/dist/core/memory/tree.d.ts +39 -0
  150. package/dist/core/memory/tree.js +93 -0
  151. package/dist/core/memory-resolver.d.ts +193 -90
  152. package/dist/core/memory-resolver.js +461 -375
  153. package/dist/core/nested-stores.js +6 -13
  154. package/dist/core/profiles/select.d.ts +4 -1
  155. package/dist/core/profiles/select.js +108 -48
  156. package/dist/core/review/__tests__/capture-origin.test.js +2 -2
  157. package/dist/core/review/__tests__/stage-identity.test.js +2 -2
  158. package/dist/core/review/companion.js +11 -2
  159. package/dist/core/runtime/bearings.d.ts +2 -2
  160. package/dist/core/runtime/bearings.js +3 -3
  161. package/dist/core/runtime/broker/daemon-ops.d.ts +2 -2
  162. package/dist/core/runtime/broker/rebind.js +5 -0
  163. package/dist/core/runtime/broker-extension-render.d.ts +7 -3
  164. package/dist/core/runtime/broker-extension-render.js +10 -5
  165. package/dist/core/runtime/broker-persona-guidance.d.ts +19 -5
  166. package/dist/core/runtime/broker-persona-guidance.js +122 -27
  167. package/dist/core/runtime/deliver-live.d.ts +16 -4
  168. package/dist/core/runtime/deliver-live.js +29 -15
  169. package/dist/core/runtime/kickoff.d.ts +3 -3
  170. package/dist/core/runtime/kickoff.js +8 -16
  171. package/dist/core/runtime/lifecycle.js +2 -3
  172. package/dist/core/runtime/nodes.d.ts +3 -4
  173. package/dist/core/runtime/nodes.js +3 -4
  174. package/dist/core/runtime/persona.d.ts +8 -12
  175. package/dist/core/runtime/persona.js +24 -96
  176. package/dist/core/runtime/promote.d.ts +2 -2
  177. package/dist/core/runtime/promote.js +8 -21
  178. package/dist/core/runtime/revive.js +20 -17
  179. package/dist/core/runtime/spawn.js +18 -7
  180. package/dist/core/runtime/tmux-bindings.js +2 -3
  181. package/dist/core/runtime/warm-pool.js +3 -4
  182. package/dist/core/scope.js +2 -0
  183. package/dist/core/self-update.d.ts +0 -2
  184. package/dist/core/self-update.js +2 -35
  185. package/dist/core/substrate/__tests__/surface-match-memory-read.test.d.ts +1 -0
  186. package/dist/core/substrate/__tests__/surface-match-memory-read.test.js +28 -0
  187. package/dist/core/substrate/index.d.ts +2 -2
  188. package/dist/core/substrate/index.js +1 -1
  189. package/dist/core/substrate/injected-store.d.ts +43 -27
  190. package/dist/core/substrate/injected-store.js +208 -104
  191. package/dist/core/substrate/listings.d.ts +19 -12
  192. package/dist/core/substrate/listings.js +75 -52
  193. package/dist/core/substrate/on-read-node.d.ts +4 -7
  194. package/dist/core/substrate/on-read-node.js +6 -8
  195. package/dist/core/substrate/on-read.d.ts +22 -25
  196. package/dist/core/substrate/on-read.js +103 -147
  197. package/dist/core/substrate/render-node.d.ts +4 -7
  198. package/dist/core/substrate/render-node.js +5 -7
  199. package/dist/core/substrate/render.d.ts +21 -3
  200. package/dist/core/substrate/render.js +291 -223
  201. package/dist/core/substrate/schema.d.ts +1 -13
  202. package/dist/core/substrate/schema.js +5 -40
  203. package/dist/core/substrate/session-cache.d.ts +14 -4
  204. package/dist/core/substrate/session-cache.js +40 -22
  205. package/dist/core/substrate/surface-match.d.ts +9 -7
  206. package/dist/core/substrate/surface-match.js +26 -25
  207. package/dist/daemon/__tests__/helpers/source-daemon.d.ts +30 -0
  208. package/dist/daemon/__tests__/helpers/source-daemon.js +174 -0
  209. package/dist/daemon/__tests__/integration/migration-startup.test.d.ts +1 -0
  210. package/dist/daemon/__tests__/integration/migration-startup.test.js +97 -0
  211. package/dist/daemon/api/__tests__/bridge-heartbeat.test.js +37 -9
  212. package/dist/daemon/api/bridge.d.ts +35 -4
  213. package/dist/daemon/api/bridge.js +50 -8
  214. package/dist/daemon/api/handlers/broker-ops.js +21 -16
  215. package/dist/daemon/api/handlers/memory.js +2 -0
  216. package/dist/daemon/crtrd.js +2 -0
  217. package/dist/daemon/human/finish.js +8 -1
  218. package/dist/daemon/manage.d.ts +0 -1
  219. package/dist/daemon/manage.js +7 -16
  220. package/dist/daemon/startup-policy.d.ts +1 -0
  221. package/dist/daemon/startup-policy.js +1 -0
  222. package/dist/migrations/001-surfaces-frontmatter.js +21 -109
  223. package/dist/migrations/002-profile-project-memory.js +1 -0
  224. package/dist/migrations/003-repository-root-memory-identity/front-door.d.ts +26 -0
  225. package/dist/migrations/003-repository-root-memory-identity/front-door.js +231 -0
  226. package/dist/migrations/003-repository-root-memory-identity/index.d.ts +2 -0
  227. package/dist/migrations/003-repository-root-memory-identity/index.js +513 -0
  228. package/dist/migrations/003-repository-root-memory-identity/references.d.ts +95 -0
  229. package/dist/migrations/003-repository-root-memory-identity/references.js +469 -0
  230. package/dist/migrations/003-repository-root-memory-identity/repository-facts.d.ts +39 -0
  231. package/dist/migrations/003-repository-root-memory-identity/repository-facts.js +349 -0
  232. package/dist/migrations/__tests__/activation-concurrency.test.d.ts +1 -0
  233. package/dist/migrations/__tests__/activation-concurrency.test.js +145 -0
  234. package/dist/migrations/__tests__/activation.test.d.ts +1 -0
  235. package/dist/migrations/__tests__/activation.test.js +149 -0
  236. package/dist/migrations/__tests__/deletion-and-root-declaration.test.d.ts +1 -0
  237. package/dist/migrations/__tests__/deletion-and-root-declaration.test.js +149 -0
  238. package/dist/migrations/activation.d.ts +16 -0
  239. package/dist/migrations/activation.js +78 -0
  240. package/dist/migrations/convergent.d.ts +14 -3
  241. package/dist/migrations/convergent.js +21 -10
  242. package/dist/migrations/corpus.d.ts +78 -0
  243. package/dist/migrations/corpus.js +497 -0
  244. package/dist/migrations/frontmatter-splice.d.ts +15 -0
  245. package/dist/migrations/frontmatter-splice.js +176 -0
  246. package/dist/migrations/registry.d.ts +6 -1
  247. package/dist/migrations/registry.js +7 -2
  248. package/dist/migrations/runner.d.ts +41 -0
  249. package/dist/migrations/runner.js +81 -0
  250. package/dist/migrations/types.d.ts +148 -9
  251. package/dist/migrations/types.js +9 -2
  252. package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +225 -17
  253. package/dist/pi-extensions/__tests__/canvas-goal-capture-envelope.test.js +11 -3
  254. package/dist/pi-extensions/canvas-context-intro.d.ts +3 -5
  255. package/dist/pi-extensions/canvas-context-intro.js +50 -46
  256. package/dist/pi-extensions/canvas-doc-substrate.d.ts +1 -8
  257. package/dist/pi-extensions/canvas-doc-substrate.js +55 -122
  258. package/dist/pi-extensions/canvas-stophook.js +6 -13
  259. package/dist/shared/generated-context.d.ts +0 -3
  260. package/dist/shared/generated-context.js +0 -57
  261. package/dist/shared/tool-groups.js +2 -3
  262. package/package.json +5 -4
  263. package/runtime.lock.json +2 -2
  264. /package/dist/api/__tests__/{serial → integration}/client.test.d.ts +0 -0
  265. /package/dist/api/__tests__/{serial → integration}/client.test.js +0 -0
  266. /package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/{serial → integration}/provider-rotation.test.ts +0 -0
  267. /package/dist/clients/{inbox/__tests__/serial/inbox-controller.test.d.ts → attach/__tests__/pane-tag-successor.test.d.ts} +0 -0
  268. /package/dist/clients/{inbox/__tests__/serial/mount-panel.test.d.ts → attach/__tests__/profile-files.test.d.ts} +0 -0
  269. /package/dist/{core/__tests__/live-mutation-verbs.test.d.ts → clients/inbox/__tests__/integration/inbox-controller.test.d.ts} +0 -0
  270. /package/dist/clients/inbox/__tests__/{serial → integration}/inbox-controller.test.js +0 -0
  271. /package/dist/{core/__tests__/serial/broker-fork-seam.test.d.ts → clients/inbox/__tests__/integration/mount-panel.test.d.ts} +0 -0
  272. /package/dist/clients/inbox/__tests__/{serial → integration}/mount-panel.test.js +0 -0
  273. /package/dist/{core/__tests__/serial/broker-sdk-wiring.test.d.ts → commands/__tests__/surface-reload-target.test.d.ts} +0 -0
  274. /package/dist/{core/__tests__/serial/broker-snapshot-history.test.d.ts → commands/memory/__tests__/command-selector-and-mutation-guards.test.d.ts} +0 -0
  275. /package/dist/{core/__tests__/serial/command-plugins.test.d.ts → commands/memory/__tests__/repository-root-lint.test.d.ts} +0 -0
  276. /package/dist/{core/__tests__/serial/deferred-no-wake.test.d.ts → commands/sys/__tests__/sync-project-guidance.test.d.ts} +0 -0
  277. /package/dist/core/__tests__/{serial/flagship-lifecycle.test.d.ts → config-change-delta.test.d.ts} +0 -0
  278. /package/dist/core/__tests__/{serial/host-teardown-process-group.test.d.ts → integration/broker-fork-seam.test.d.ts} +0 -0
  279. /package/dist/core/__tests__/{serial/human-deliver-e2e.test.d.ts → integration/broker-sdk-wiring.test.d.ts} +0 -0
  280. /package/dist/core/__tests__/{serial/live-mutation.test.d.ts → integration/broker-snapshot-history.test.d.ts} +0 -0
  281. /package/dist/core/__tests__/{serial/refresh-stall-recycle.test.d.ts → integration/command-plugins.test.d.ts} +0 -0
  282. /package/dist/core/__tests__/{serial/revive.test.d.ts → integration/deferred-no-wake.test.d.ts} +0 -0
  283. /package/dist/core/__tests__/{serial/spawn-root.test.d.ts → integration/flagship-lifecycle.test.d.ts} +0 -0
  284. /package/dist/core/__tests__/{serial/subscription-delivery.test.d.ts → integration/host-teardown-process-group.test.d.ts} +0 -0
  285. /package/dist/core/__tests__/{serial/tmux-surface.test.d.ts → integration/human-deliver-e2e.test.d.ts} +0 -0
  286. /package/dist/core/__tests__/{serial/worktree.test.d.ts → integration/live-mutation-verbs.test.d.ts} +0 -0
  287. /package/dist/core/{human/__tests__/serial/inbox-core.test.d.ts → __tests__/integration/live-mutation.test.d.ts} +0 -0
  288. /package/dist/core/human/__tests__/{serial → integration}/inbox-core.test.js +0 -0
@@ -1,36 +1,33 @@
1
- import { type InjectedDocs } from './injected-store.js';
1
+ import { type ExposureTarget } from './injected-store.js';
2
2
  import { type Rung, type SubstrateDoc } from './schema.js';
3
3
  import type { NodeConfigSubject } from './subject-fields.js';
4
- /** Render candidates at their matched rungs, gate-checked and deduped against
5
- * the transcript set (higher rungs pierce lower; a delivery records at its
6
- * rendered rung). A `null` subject means no node identity is available for
7
- * gate evaluation: gated docs are skipped, ungated docs still deliver. */
8
- export declare function renderCandidateBlocks(subject: NodeConfigSubject | null, candidates: Array<{
4
+ interface EventCandidate {
9
5
  doc: SubstrateDoc;
10
6
  rung: Rung;
11
- }>, seen: InjectedDocs): string[];
7
+ }
8
+ /** Render the selected candidates not already loaded at their matched rung. */
9
+ export declare function renderCandidateBlocks(subject: NodeConfigSubject | null, candidates: EventCandidate[], target: ExposureTarget): string[];
12
10
  /** Surface docs whose `read` entries match a successfully read file, using
13
11
  * the caller-supplied daemon snapshot subject. */
14
- export declare function renderOnReadDocsForSubject(subject: NodeConfigSubject, readFilePath: string, seen?: InjectedDocs): string;
12
+ export declare function renderOnReadDocsForSubject(subject: NodeConfigSubject, readFilePath: string, target?: ExposureTarget): string;
15
13
  /** Workspace boot docs using the snapshot's cwd/profile instead of a canvas
16
- * lookup. `seen` is the transcript-scoped dedup set shared with the on-read
17
- * hook, so a front door delivered here never re-delivers on a later read
18
- * beneath its store.
14
+ * lookup. The shared exposure target prevents a later read from repeating a
15
+ * document already loaded here.
19
16
  *
20
17
  * Each candidate's authored rung is clamped to its project's profile
21
- * relationship cap BEFORE the `none` filter, the ordering, the render, and the
22
- * seen-map recording — so a capped doc never renders above its cap, a `none`
23
- * project contributes nothing, and a later explicit `crtr memory read` can
24
- * still upgrade what workspace-open disclosed at a lower rung. */
25
- export declare function renderWorkspaceOpenDocsForSubject(subject: NodeConfigSubject, cwd: string, profileId: string | null, seen?: InjectedDocs): string;
18
+ * relationship cap BEFORE filtering, ordering, rendering, and exposure
19
+ * registration. A later explicit `crtr memory read` can still raise a document
20
+ * that workspace-open disclosed at a lower rung. */
21
+ export declare function renderWorkspaceOpenDocsForSubject(subject: NodeConfigSubject, cwd: string, profileId: string | null, target?: ExposureTarget): string;
26
22
  /** Inner `<memory>` blocks for the memory-read event: docs whose
27
23
  * `memory-read` entries match the doc a `crtr memory read` just resolved
28
- * (known by `targetNames`; `excludeRealpath` keeps the resolved doc from
29
- * delivering itself). Returns unwrapped blocks — the read leaf composes one
30
- * `<auto-loaded-context>` envelope from these plus the directory listings. */
31
- export declare function memoryReadDocBlocks(subject: NodeConfigSubject | null, excludeRealpath: string, targetNames: string[], seen: InjectedDocs): string[];
32
- /** Surface docs whose `command` entries match an executed bash command
33
- * string. The corpus is the resolved cwd/profile set only — a command has no
34
- * file to walk enclosing stores from. `seen` is the same transcript-scoped
35
- * dedup set as the other channels. */
36
- export declare function renderOnCommandDocsForSubject(subject: NodeConfigSubject, command: string, seen?: InjectedDocs): string;
24
+ * (known by its exact canonical `name` — no mount-stripped or other alias;
25
+ * `excludeRealpath` keeps the resolved doc from delivering itself). Returns
26
+ * unwrapped blocks — the read leaf composes one `<auto-loaded-context>`
27
+ * envelope from these plus the directory listings. */
28
+ export declare function memoryReadDocBlocks(subject: NodeConfigSubject | null, excludeRealpath: string, name: string, target: ExposureTarget): string[];
29
+ /** Surface docs whose `command` entries match an executed bash command.
30
+ * The corpus is the resolved cwd/profile set; a command has no file from which
31
+ * to discover enclosing project stores. */
32
+ export declare function renderOnCommandDocsForSubject(subject: NodeConfigSubject, command: string, target?: ExposureTarget): string;
33
+ export {};
@@ -22,24 +22,24 @@
22
22
  // • `command` — a `bash` tool call evaluates the executed command string
23
23
  // against every doc's `command` entries (string globs, `*` crossing `/`).
24
24
  //
25
- // All channels share one transcript-scoped (realpath → rung rank) dedup set,
26
- // so a doc delivered by one never re-delivers at the same or lower rung
27
- // through another. Each candidate renders at its matched rung — the highest
28
- // `at` over its matching entries for the event.
29
- import { createHash } from 'node:crypto';
25
+ // All channels register through one context exposure target, so a document
26
+ // already loaded at the same or a higher rung does not repeat. Each candidate
27
+ // renders at the highest rung matched by that event.
28
+ //
29
+ // Equal-canonical candidates (the same identity in two physical stores) do not
30
+ // each deliver: `selectEventCandidates` collapses them to the first one
31
+ // ELIGIBLE for that event, in source order.
30
32
  import { homedir } from 'node:os';
31
- import { dirname, parse, relative, sep } from 'node:path';
32
- import { CRTR_DIR_NAME } from '../../types.js';
33
- import { pathExists, readText, walkFiles } from '../fs-utils.js';
33
+ import { dirname, parse, sep } from 'node:path';
34
+ import { readText, realpathOrSelf } from '../fs-utils.js';
34
35
  import { parseFrontmatterGeneric } from '../frontmatter.js';
35
- import { listAllMemoryDocs, listProjectMemoryDocs } from '../memory-resolver.js';
36
- import { NEUTRAL_PROJECT_MEMORY, userScopeRoot } from '../scope.js';
36
+ import { listAllMemoryDocs, listProjectMemoryDocs, loadStoreMemoryDocs, openProjectMemoryStore } from '../memory-resolver.js';
37
+ import { userScopeRoot } from '../scope.js';
37
38
  import { gatePasses } from './gate.js';
38
39
  import { commandDeliveryRung, memoryReadDeliveryRung, owningRootOf, readDeliveryRung, workspaceOpenRung } from './surface-match.js';
39
- import { deliveredAtOrAbove, recordDelivery } from './injected-store.js';
40
- import { minRung, normalizeDocName, parseSubstrateDoc, parseSubstrateFrontmatter, previewLine, resolveDocName } from './schema.js';
41
- import { cachedSubstrateDocsInclusive } from './session-cache.js';
42
- import { realpathOrSelf } from '../fs-utils.js';
40
+ import { documentExposedAtOrAbove, emptyContextExposureState, exposureTarget, registerDocumentExposure, } from './injected-store.js';
41
+ import { minRung, parseSubstrateDoc, previewLine } from './schema.js';
42
+ import { cachedEventCorpusInclusive } from './session-cache.js';
43
43
  const JUNK_DIRS = new Set(['node_modules', '.git', 'dist', 'build', '.next', '.cache', '.yalc']);
44
44
  function attr(s) {
45
45
  return s
@@ -51,46 +51,14 @@ function attr(s) {
51
51
  function isJunkAncestor(dir) {
52
52
  return dir.split(sep).some((segment) => JUNK_DIRS.has(segment));
53
53
  }
54
- function loadProjectDoc(file, memoryDir) {
55
- try {
56
- const raw = relative(memoryDir, file)
57
- .replace(/\.md$/i, '')
58
- .split(sep)
59
- .join('/');
60
- const fallbackName = normalizeDocName(raw);
61
- if (fallbackName === '')
62
- return null;
63
- const { data, body } = parseFrontmatterGeneric(readText(file));
64
- const schema = parseSubstrateFrontmatter(data);
65
- if (schema === null)
66
- return null;
67
- return {
68
- ...schema,
69
- name: resolveDocName(data, fallbackName),
70
- scope: 'project',
71
- path: file,
72
- body,
73
- // The read event is uncapped by design: this walk is reached only by an
74
- // explicit file read, never by automatic boot/workspace-open delivery.
75
- projectMemory: NEUTRAL_PROJECT_MEMORY,
76
- };
77
- }
78
- catch {
79
- return null;
80
- }
81
- }
82
- function safeWalkMarkdown(dir) {
83
- try {
84
- return walkFiles(dir, (name) => name.toLowerCase().endsWith('.md'));
85
- }
86
- catch {
87
- return [];
88
- }
89
- }
90
- /** Project docs from every workspace store enclosing the read file. This is a
91
- * discovery walk only: each returned doc must still match an explicit trigger. */
54
+ /** Project docs from every workspace store enclosing the read file, nearest
55
+ * first. This is a discovery walk only: each returned doc must still match an
56
+ * explicit trigger. A store that declares no namespace does not mount here
57
+ * either — an unmounted store has no canonical identities to deliver under.
58
+ * The stores carry the neutral ceiling: the read event is uncapped by design,
59
+ * reached only by an explicit file read. */
92
60
  function enclosingProjectDocs(absReadFile) {
93
- const docs = [];
61
+ const out = [];
94
62
  const seen = new Set();
95
63
  const home = realpathOrSelf(homedir());
96
64
  const userRoot = realpathOrSelf(userScopeRoot());
@@ -98,16 +66,13 @@ function enclosingProjectDocs(absReadFile) {
98
66
  let dir = dirname(absReadFile);
99
67
  while (true) {
100
68
  if (dir !== home && dir !== userRoot && !isJunkAncestor(dir)) {
101
- const memoryDir = `${dir}${sep}${CRTR_DIR_NAME}${sep}memory`;
102
- if (pathExists(memoryDir)) {
103
- for (const file of safeWalkMarkdown(memoryDir)) {
104
- const real = realpathOrSelf(file);
105
- if (seen.has(real))
106
- continue;
107
- seen.add(real);
108
- const doc = loadProjectDoc(file, memoryDir);
69
+ const store = openProjectMemoryStore(dir);
70
+ if (store.mountStatus === 'ready' && !seen.has(store.storeRoot)) {
71
+ seen.add(store.storeRoot);
72
+ for (const source of loadStoreMemoryDocs(store, true)) {
73
+ const doc = parseSubstrateDoc(source);
109
74
  if (doc !== null)
110
- docs.push(doc);
75
+ out.push({ doc, source });
111
76
  }
112
77
  }
113
78
  }
@@ -118,33 +83,21 @@ function enclosingProjectDocs(absReadFile) {
118
83
  break;
119
84
  dir = parent;
120
85
  }
121
- return docs;
86
+ return out;
122
87
  }
123
88
  // The event corpus INCLUDES node-scope docs: surfaces entries are explicit
124
89
  // authored routing, so a node-local doc's read/memory-read/command entry
125
90
  // fires like any other store's. Only boot excludes node scope (render.ts's
126
- // nodeLocalDocs owns node-local boot rendering); the shared dedup set keeps
127
- // a boot-rendered doc from re-delivering below its rung here.
91
+ // nodeLocalDocs owns node-local boot rendering); the active exposure state
92
+ // prevents a lower-rung repeat here.
128
93
  function resolvedDocs() {
129
94
  try {
130
- return cachedSubstrateDocsInclusive(listAllMemoryDocs, parseSubstrateDoc);
95
+ return cachedEventCorpusInclusive(listAllMemoryDocs, parseSubstrateDoc);
131
96
  }
132
97
  catch {
133
98
  return [];
134
99
  }
135
100
  }
136
- function dedupeByPhysicalPath(docs) {
137
- const seen = new Set();
138
- const out = [];
139
- for (const doc of docs) {
140
- const real = realpathOrSelf(doc.path);
141
- if (seen.has(real))
142
- continue;
143
- seen.add(real);
144
- out.push(doc);
145
- }
146
- return out;
147
- }
148
101
  function readFileFrontmatter(absReadFile) {
149
102
  if (!/\.(md|mdx|markdown)$/i.test(absReadFile))
150
103
  return {};
@@ -155,14 +108,6 @@ function readFileFrontmatter(absReadFile) {
155
108
  return {};
156
109
  }
157
110
  }
158
- /** Content-identity dedup key, or null for an empty body (name-only docs
159
- * must not collide with each other). */
160
- function docContentKey(doc) {
161
- const body = doc.body.trim();
162
- if (body === '')
163
- return null;
164
- return `content-sha256:${createHash('sha256').update(body).digest('hex')}`;
165
- }
166
111
  // Two shapes: element-with-body means the content is here; self-closing means
167
112
  // it is not — a preview carries its routing line as `readWhen` metadata so the
168
113
  // one-liner can never be mistaken for the document's content. No disk path:
@@ -184,66 +129,77 @@ function renderDocEnvelope(doc, rung) {
184
129
  }
185
130
  return `<memory ${attrs} />`;
186
131
  }
187
- /** Render candidates at their matched rungs, gate-checked and deduped against
188
- * the transcript set (higher rungs pierce lower; a delivery records at its
189
- * rendered rung). A `null` subject means no node identity is available for
190
- * gate evaluation: gated docs are skipped, ungated docs still deliver. */
191
- export function renderCandidateBlocks(subject, candidates, seen) {
192
- const rendered = [];
193
- for (const { doc, rung } of candidates) {
194
- const real = realpathOrSelf(doc.path);
195
- // Byte-identical bodies at different paths (a cloned repo's store) inform
196
- // once; the content key shares the realpath map and its rung semantics.
197
- const contentKey = docContentKey(doc);
198
- if (deliveredAtOrAbove(seen, real, rung))
199
- continue;
200
- if (contentKey !== null && deliveredAtOrAbove(seen, contentKey, rung))
132
+ /** The eligible candidate per canonical identity, in the caller's SOURCE order.
133
+ * Kind and mount are settled by the loader and the profile cap by the caller's
134
+ * rung fold, so what remains is the document gate over candidates the event
135
+ * already gave a delivering rung. A nearer candidate that is gated off or does
136
+ * not deliver never suppresses a farther one — the filter runs before the
137
+ * first-wins collapse, not after it.
138
+ *
139
+ * A `null` subject skips gated documents and still delivers ungated ones. */
140
+ function selectEventCandidates(subject, candidates) {
141
+ const selected = [];
142
+ const seen = new Set();
143
+ for (const candidate of candidates) {
144
+ const { doc, rung } = candidate;
145
+ if (rung === 'none' || seen.has(doc.name))
201
146
  continue;
202
147
  try {
203
148
  if (subject === null ? doc.gate !== undefined : !gatePasses(doc, subject))
204
149
  continue;
205
- const block = renderDocEnvelope(doc, rung);
206
- if (block === null)
207
- continue;
208
- recordDelivery(seen, real, rung);
209
- if (contentKey !== null)
210
- recordDelivery(seen, contentKey, rung);
211
- rendered.push(block);
212
150
  }
213
151
  catch {
214
152
  continue;
215
153
  }
154
+ seen.add(doc.name);
155
+ selected.push(candidate);
156
+ }
157
+ return selected;
158
+ }
159
+ /** Render the selected candidates not already loaded at their matched rung. */
160
+ export function renderCandidateBlocks(subject, candidates, target) {
161
+ const rendered = [];
162
+ for (const { doc, rung } of selectEventCandidates(subject, candidates)) {
163
+ if (documentExposedAtOrAbove(target.state, doc.path, doc.body, rung))
164
+ continue;
165
+ const block = renderDocEnvelope(doc, rung);
166
+ if (block === null)
167
+ continue;
168
+ registerDocumentExposure(target, doc.path, doc.body, rung);
169
+ rendered.push(block);
216
170
  }
217
171
  return rendered;
218
172
  }
219
- function renderCandidates(subject, candidates, seen) {
220
- const rendered = renderCandidateBlocks(subject, candidates, seen);
173
+ function transientTranscriptTarget() {
174
+ return exposureTarget(emptyContextExposureState(), 'transcript');
175
+ }
176
+ function renderCandidates(subject, candidates, target) {
177
+ const rendered = renderCandidateBlocks(subject, candidates, target);
221
178
  return rendered.length === 0
222
179
  ? ''
223
180
  : `<auto-loaded-context>\n${rendered.join('\n')}\n</auto-loaded-context>`;
224
181
  }
225
182
  /** Surface docs whose `read` entries match a successfully read file, using
226
183
  * the caller-supplied daemon snapshot subject. */
227
- export function renderOnReadDocsForSubject(subject, readFilePath, seen = new Map()) {
184
+ export function renderOnReadDocsForSubject(subject, readFilePath, target = transientTranscriptTarget()) {
228
185
  const absReadFile = realpathOrSelf(readFilePath);
229
186
  const readFrontmatter = readFileFrontmatter(absReadFile);
230
- const candidates = dedupeByPhysicalPath([...enclosingProjectDocs(absReadFile), ...resolvedDocs()])
231
- .filter((doc) => realpathOrSelf(doc.path) !== absReadFile)
232
- .map((doc) => ({ doc, rung: readDeliveryRung(doc, subject, absReadFile, readFrontmatter) }))
233
- .filter(({ rung }) => rung !== 'none');
234
- return renderCandidates(subject, candidates, seen);
187
+ // Enclosing stores lead: a store discovered from the read file is the nearest
188
+ // source of an identity the mounted corpus may also carry.
189
+ const candidates = [...enclosingProjectDocs(absReadFile), ...resolvedDocs()]
190
+ .filter(({ doc }) => realpathOrSelf(doc.path) !== absReadFile)
191
+ .map(({ doc }) => ({ doc, rung: readDeliveryRung(doc, subject, absReadFile, readFrontmatter) }));
192
+ return renderCandidates(subject, candidates, target);
235
193
  }
236
194
  /** Workspace boot docs using the snapshot's cwd/profile instead of a canvas
237
- * lookup. `seen` is the transcript-scoped dedup set shared with the on-read
238
- * hook, so a front door delivered here never re-delivers on a later read
239
- * beneath its store.
195
+ * lookup. The shared exposure target prevents a later read from repeating a
196
+ * document already loaded here.
240
197
  *
241
198
  * Each candidate's authored rung is clamped to its project's profile
242
- * relationship cap BEFORE the `none` filter, the ordering, the render, and the
243
- * seen-map recording — so a capped doc never renders above its cap, a `none`
244
- * project contributes nothing, and a later explicit `crtr memory read` can
245
- * still upgrade what workspace-open disclosed at a lower rung. */
246
- export function renderWorkspaceOpenDocsForSubject(subject, cwd, profileId, seen = new Map()) {
199
+ * relationship cap BEFORE filtering, ordering, rendering, and exposure
200
+ * registration. A later explicit `crtr memory read` can still raise a document
201
+ * that workspace-open disclosed at a lower rung. */
202
+ export function renderWorkspaceOpenDocsForSubject(subject, cwd, profileId, target = transientTranscriptTarget()) {
247
203
  let docs;
248
204
  try {
249
205
  docs = listProjectMemoryDocs(cwd, profileId)
@@ -253,36 +209,36 @@ export function renderWorkspaceOpenDocsForSubject(subject, cwd, profileId, seen
253
209
  catch {
254
210
  return '';
255
211
  }
256
- const candidates = dedupeByPhysicalPath(docs)
257
- .map((doc) => ({ doc, rung: minRung(workspaceOpenRung(doc, subject), doc.projectMemory) }))
258
- .filter(({ rung }) => rung !== 'none')
259
- .sort((a, b) => {
212
+ // Selection runs on the corpus's SOURCE order, so the nearest store wins an
213
+ // equal-canonical tie; the sort below is display order only — outermost
214
+ // workspace first, so context arrives general before specific.
215
+ const ordered = selectEventCandidates(subject, docs.map((doc) => ({ doc, rung: minRung(workspaceOpenRung(doc, subject), doc.projectMemory) }))).sort((a, b) => {
260
216
  const aRoot = owningRootOf(a.doc) ?? '';
261
217
  const bRoot = owningRootOf(b.doc) ?? '';
262
218
  const depth = aRoot.split(sep).filter(Boolean).length - bRoot.split(sep).filter(Boolean).length;
263
219
  return depth || aRoot.localeCompare(bRoot) || a.doc.path.localeCompare(b.doc.path);
264
220
  });
265
- return renderCandidates(subject, candidates, seen);
221
+ return renderCandidates(subject, ordered, target);
266
222
  }
267
223
  /** Inner `<memory>` blocks for the memory-read event: docs whose
268
224
  * `memory-read` entries match the doc a `crtr memory read` just resolved
269
- * (known by `targetNames`; `excludeRealpath` keeps the resolved doc from
270
- * delivering itself). Returns unwrapped blocks — the read leaf composes one
271
- * `<auto-loaded-context>` envelope from these plus the directory listings. */
272
- export function memoryReadDocBlocks(subject, excludeRealpath, targetNames, seen) {
273
- const candidates = dedupeByPhysicalPath(resolvedDocs())
274
- .filter((doc) => realpathOrSelf(doc.path) !== excludeRealpath)
275
- .map((doc) => ({ doc, rung: memoryReadDeliveryRung(doc, subject, targetNames) }))
276
- .filter(({ rung }) => rung !== 'none');
277
- return renderCandidateBlocks(subject, candidates, seen);
278
- }
279
- /** Surface docs whose `command` entries match an executed bash command
280
- * string. The corpus is the resolved cwd/profile set only — a command has no
281
- * file to walk enclosing stores from. `seen` is the same transcript-scoped
282
- * dedup set as the other channels. */
283
- export function renderOnCommandDocsForSubject(subject, command, seen = new Map()) {
284
- const candidates = dedupeByPhysicalPath(resolvedDocs())
285
- .map((doc) => ({ doc, rung: commandDeliveryRung(doc, subject, command) }))
286
- .filter(({ rung }) => rung !== 'none');
287
- return renderCandidates(subject, candidates, seen);
225
+ * (known by its exact canonical `name` — no mount-stripped or other alias;
226
+ * `excludeRealpath` keeps the resolved doc from delivering itself). Returns
227
+ * unwrapped blocks — the read leaf composes one `<auto-loaded-context>`
228
+ * envelope from these plus the directory listings. */
229
+ export function memoryReadDocBlocks(subject, excludeRealpath, name, target) {
230
+ const candidates = resolvedDocs()
231
+ .filter(({ doc }) => realpathOrSelf(doc.path) !== excludeRealpath)
232
+ .map(({ doc, source }) => ({
233
+ doc,
234
+ rung: memoryReadDeliveryRung(doc, source.routingAnchor, subject, name),
235
+ }));
236
+ return renderCandidateBlocks(subject, candidates, target);
237
+ }
238
+ /** Surface docs whose `command` entries match an executed bash command.
239
+ * The corpus is the resolved cwd/profile set; a command has no file from which
240
+ * to discover enclosing project stores. */
241
+ export function renderOnCommandDocsForSubject(subject, command, target = transientTranscriptTarget()) {
242
+ const candidates = resolvedDocs().map(({ doc }) => ({ doc, rung: commandDeliveryRung(doc, subject, command) }));
243
+ return renderCandidates(subject, candidates, target);
288
244
  }
@@ -1,4 +1,4 @@
1
- import type { InjectedDocs } from './injected-store.js';
1
+ import { type ExposureTarget } from './injected-store.js';
2
2
  /** The system-prompt substrate splice for `nodeId` — shipped-layer protocol
3
3
  * prose followed by the `<memory kind="preference">` block: assemble
4
4
  * the node's subject from the canvas-db, render the pure splice, then swap the
@@ -7,9 +7,6 @@ import type { InjectedDocs } from './injected-store.js';
7
7
  * interpolateNodePaths). A null subject (unknown id) still renders the
8
8
  * always-present memory-usage guidance frame. */
9
9
  export declare function renderPreferencesSection(nodeId: string): string;
10
- /** The first-message `<memory kind="knowledge">` block for `nodeId`: assemble
11
- * the node's subject from the canvas-db and render the consultable catalog.
12
- * Returns '' for an unknown id or when nothing is eligible. `seen` (optional,
13
- * write-only) receives each rendered doc at its displayed rung — boot
14
- * delivery seeding for the transcript dedup map. */
15
- export declare function renderKnowledgeBlock(nodeId: string, seen?: InjectedDocs): string;
10
+ /** The first-message `<memory kind="knowledge">` block for `nodeId`. Rendered
11
+ * documents register at their displayed rung through `target`. */
12
+ export declare function renderKnowledgeBlock(nodeId: string, target?: ExposureTarget): string;
@@ -7,6 +7,7 @@
7
7
  // canvas-doc-substrate.ts) import these — the canvas-db read is fine there.
8
8
  import { interpolateNodePaths } from '../canvas/paths.js';
9
9
  import { assembleNodeSubject } from './subject.js';
10
+ import { emptyContextExposureState, exposureTarget, } from './injected-store.js';
10
11
  import { renderPreferencesForSubject, renderKnowledgeForSubject } from './render.js';
11
12
  /** The system-prompt substrate splice for `nodeId` — shipped-layer protocol
12
13
  * prose followed by the `<memory kind="preference">` block: assemble
@@ -19,14 +20,11 @@ export function renderPreferencesSection(nodeId) {
19
20
  const subject = assembleNodeSubject(nodeId);
20
21
  return interpolateNodePaths(renderPreferencesForSubject(subject).block, nodeId);
21
22
  }
22
- /** The first-message `<memory kind="knowledge">` block for `nodeId`: assemble
23
- * the node's subject from the canvas-db and render the consultable catalog.
24
- * Returns '' for an unknown id or when nothing is eligible. `seen` (optional,
25
- * write-only) receives each rendered doc at its displayed rung — boot
26
- * delivery seeding for the transcript dedup map. */
27
- export function renderKnowledgeBlock(nodeId, seen) {
23
+ /** The first-message `<memory kind="knowledge">` block for `nodeId`. Rendered
24
+ * documents register at their displayed rung through `target`. */
25
+ export function renderKnowledgeBlock(nodeId, target = exposureTarget(emptyContextExposureState(), 'transcript')) {
28
26
  const subject = assembleNodeSubject(nodeId);
29
27
  if (subject === null)
30
28
  return '';
31
- return renderKnowledgeForSubject(subject, nodeId, seen);
29
+ return renderKnowledgeForSubject(subject, nodeId, target);
32
30
  }
@@ -1,7 +1,15 @@
1
- import { type InjectedDocs } from './injected-store.js';
1
+ import { type ExposureTarget } from './injected-store.js';
2
2
  import { type SubstrateDoc } from './schema.js';
3
3
  import type { NodeConfigSubject } from './subject-fields.js';
4
- export declare function renderPreferencesForSubject(subject: NodeConfigSubject | null, seen?: InjectedDocs): {
4
+ /** The computed "sub-personas you may spawn" menu for a subject's kind — the
5
+ * live restoration of the old `personas/resolve.ts` static menu, now derived
6
+ * at render time from the merged kind registry (`subKindsAvailableTo`) so it
7
+ * can never drift from `sys prompt-review --list`'s `subPersonas` metadata.
8
+ * Returns '' when the kind has zero available sub-kinds (no dangling empty
9
+ * header). Emitted for BOTH base and orchestrator modes per the CTO's ruling —
10
+ * mode is irrelevant to which sub-kinds are spawnable. */
11
+ export declare function buildSubPersonaMenu(kind: string): string;
12
+ export declare function renderPreferencesForSubject(subject: NodeConfigSubject | null, target?: ExposureTarget): {
5
13
  block: string;
6
14
  contentDocs: SubstrateDoc[];
7
15
  tree: string;
@@ -19,4 +27,14 @@ export declare function renderPreferencesForSubject(subject: NodeConfigSubject |
19
27
  * docs never reach the `content` rung). Procedural guidance and factual
20
28
  * references both live here as `knowledge`. Returns '' when nothing is
21
29
  * eligible. */
22
- export declare function renderKnowledgeForSubject(subject: NodeConfigSubject, nodeId: string, seen?: InjectedDocs): string;
30
+ export declare function renderKnowledgeForSubject(subject: NodeConfigSubject, nodeId: string, target?: ExposureTarget): string;
31
+ /** What a node's configuration change newly exposes, rendered as up to three
32
+ * blocks in one string: the shipped protocol prose, a `<memory kind="preference">`
33
+ * block, and a `<memory kind="knowledge">` block — each dropped when empty, ''
34
+ * when the change exposes nothing.
35
+ *
36
+ * Both kinds use the current subject's ordinary winner assembly, then compare
37
+ * against the active exposure maximum. A lower rung or removal yields nothing
38
+ * because content already loaded into this context cannot be withdrawn.
39
+ * Rendered deltas register as transcript exposure through `target`. */
40
+ export declare function renderConfigChangeDelta(subject: NodeConfigSubject, nodeId: string, target: ExposureTarget): string;