mirror-mind 0.0.1 → 0.33.0

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 (474) hide show
  1. package/.claude/hooks/log-assistant-reply.sh +85 -0
  2. package/.claude/hooks/log-session-end.sh +85 -0
  3. package/.claude/hooks/log-user-prompt.sh +85 -0
  4. package/.claude/hooks/mirror-inject.sh +85 -0
  5. package/.claude/hooks/session-start.sh +85 -0
  6. package/.gemini/hooks/log-assistant.sh +85 -0
  7. package/.gemini/hooks/log-user.sh +85 -0
  8. package/.gemini/hooks/session-end.sh +85 -0
  9. package/.gemini/hooks/session-start.sh +85 -0
  10. package/.pi/extensions/mirror-logger.ts +646 -0
  11. package/.pi/skills/mm-backup/SKILL.md +21 -0
  12. package/.pi/skills/mm-build/SKILL.md +1206 -0
  13. package/.pi/skills/mm-consolidate/SKILL.md +112 -0
  14. package/.pi/skills/mm-consult/SKILL.md +70 -0
  15. package/.pi/skills/mm-conversations/SKILL.md +16 -0
  16. package/.pi/skills/mm-discard/SKILL.md +39 -0
  17. package/.pi/skills/mm-explore/SKILL.md +255 -0
  18. package/.pi/skills/mm-help/SKILL.md +74 -0
  19. package/.pi/skills/mm-identity/SKILL.md +96 -0
  20. package/.pi/skills/mm-journal/SKILL.md +16 -0
  21. package/.pi/skills/mm-journey/SKILL.md +23 -0
  22. package/.pi/skills/mm-journeys/SKILL.md +15 -0
  23. package/.pi/skills/mm-memories/SKILL.md +17 -0
  24. package/.pi/skills/mm-mirror/SKILL.md +98 -0
  25. package/.pi/skills/mm-mute/SKILL.md +18 -0
  26. package/.pi/skills/mm-new/SKILL.md +18 -0
  27. package/.pi/skills/mm-recall/SKILL.md +17 -0
  28. package/.pi/skills/mm-release-notes/SKILL.md +52 -0
  29. package/.pi/skills/mm-seed/SKILL.md +19 -0
  30. package/.pi/skills/mm-shadow/SKILL.md +117 -0
  31. package/.pi/skills/mm-soul/SKILL.md +502 -0
  32. package/.pi/skills/mm-tasks/SKILL.md +24 -0
  33. package/.pi/skills/mm-update/SKILL.md +32 -0
  34. package/.pi/skills/mm-week/SKILL.md +28 -0
  35. package/.pi/skills/mm-welcome/SKILL.md +24 -0
  36. package/AGENTS.md +188 -0
  37. package/README.md +126 -9
  38. package/bin/loader.js +67 -0
  39. package/bin/mirror-hook.js +7 -0
  40. package/bin/mirror.js +7 -0
  41. package/docs/releases/index.md +100 -0
  42. package/docs/releases/pending-cutoffs.md +510 -0
  43. package/docs/releases/v0.10.0.md +123 -0
  44. package/docs/releases/v0.10.1.md +66 -0
  45. package/docs/releases/v0.10.10.md +51 -0
  46. package/docs/releases/v0.10.11.md +39 -0
  47. package/docs/releases/v0.10.12.md +57 -0
  48. package/docs/releases/v0.10.13.md +35 -0
  49. package/docs/releases/v0.10.14.md +42 -0
  50. package/docs/releases/v0.10.15.md +53 -0
  51. package/docs/releases/v0.10.16.md +35 -0
  52. package/docs/releases/v0.10.17.md +43 -0
  53. package/docs/releases/v0.10.2.md +64 -0
  54. package/docs/releases/v0.10.3.md +78 -0
  55. package/docs/releases/v0.10.4.md +42 -0
  56. package/docs/releases/v0.10.5.md +57 -0
  57. package/docs/releases/v0.10.6.md +47 -0
  58. package/docs/releases/v0.10.7.md +53 -0
  59. package/docs/releases/v0.10.8.md +49 -0
  60. package/docs/releases/v0.10.9.md +37 -0
  61. package/docs/releases/v0.11.0.md +86 -0
  62. package/docs/releases/v0.12.0.md +67 -0
  63. package/docs/releases/v0.13.0.md +64 -0
  64. package/docs/releases/v0.14.0.md +68 -0
  65. package/docs/releases/v0.15.0.md +48 -0
  66. package/docs/releases/v0.16.0.md +50 -0
  67. package/docs/releases/v0.16.1.md +55 -0
  68. package/docs/releases/v0.16.2.md +36 -0
  69. package/docs/releases/v0.17.0.md +50 -0
  70. package/docs/releases/v0.17.1.md +58 -0
  71. package/docs/releases/v0.17.2.md +42 -0
  72. package/docs/releases/v0.17.3.md +58 -0
  73. package/docs/releases/v0.18.0.md +84 -0
  74. package/docs/releases/v0.18.1.md +51 -0
  75. package/docs/releases/v0.18.2.md +69 -0
  76. package/docs/releases/v0.19.0.md +85 -0
  77. package/docs/releases/v0.19.1.md +46 -0
  78. package/docs/releases/v0.20.0.md +85 -0
  79. package/docs/releases/v0.21.0.md +61 -0
  80. package/docs/releases/v0.21.1.md +47 -0
  81. package/docs/releases/v0.22.0.md +77 -0
  82. package/docs/releases/v0.22.1.md +42 -0
  83. package/docs/releases/v0.23.0.md +105 -0
  84. package/docs/releases/v0.24.0.md +125 -0
  85. package/docs/releases/v0.25.0.md +107 -0
  86. package/docs/releases/v0.26.0.md +139 -0
  87. package/docs/releases/v0.26.1.md +65 -0
  88. package/docs/releases/v0.26.2.md +43 -0
  89. package/docs/releases/v0.27.0.md +63 -0
  90. package/docs/releases/v0.28.0.md +59 -0
  91. package/docs/releases/v0.29.0.md +61 -0
  92. package/docs/releases/v0.29.1.md +59 -0
  93. package/docs/releases/v0.29.2.md +59 -0
  94. package/docs/releases/v0.29.3.md +93 -0
  95. package/docs/releases/v0.30.0.md +75 -0
  96. package/docs/releases/v0.30.1.md +93 -0
  97. package/docs/releases/v0.30.2.md +66 -0
  98. package/docs/releases/v0.31.0.md +122 -0
  99. package/docs/releases/v0.31.1.md +142 -0
  100. package/docs/releases/v0.31.10.md +118 -0
  101. package/docs/releases/v0.31.11.md +88 -0
  102. package/docs/releases/v0.31.12.md +105 -0
  103. package/docs/releases/v0.31.13.md +99 -0
  104. package/docs/releases/v0.31.14.md +97 -0
  105. package/docs/releases/v0.31.2.md +115 -0
  106. package/docs/releases/v0.31.3.md +142 -0
  107. package/docs/releases/v0.31.4.md +117 -0
  108. package/docs/releases/v0.31.5.md +155 -0
  109. package/docs/releases/v0.31.6.md +132 -0
  110. package/docs/releases/v0.31.7.md +132 -0
  111. package/docs/releases/v0.31.8.md +120 -0
  112. package/docs/releases/v0.31.9.md +120 -0
  113. package/docs/releases/v0.32.0.md +261 -0
  114. package/docs/releases/v0.32.1.md +59 -0
  115. package/docs/releases/v0.33.0.md +164 -0
  116. package/docs/releases/v0.8.0.md +118 -0
  117. package/docs/releases/v0.9.0.md +98 -0
  118. package/docs/releases/v0.9.1.md +83 -0
  119. package/package.json +102 -6
  120. package/plugins/mirror-mind/.claude-plugin/plugin.json +17 -0
  121. package/plugins/mirror-mind/hooks/hooks.json +62 -0
  122. package/plugins/mirror-mind/hooks/log-assistant-reply.sh +98 -0
  123. package/plugins/mirror-mind/hooks/log-session-end.sh +98 -0
  124. package/plugins/mirror-mind/hooks/log-user-prompt.sh +98 -0
  125. package/plugins/mirror-mind/hooks/mirror-inject.sh +98 -0
  126. package/plugins/mirror-mind/hooks/session-start.sh +98 -0
  127. package/plugins/mirror-mind/skills/mm-backup/SKILL.md +27 -0
  128. package/plugins/mirror-mind/skills/mm-build/SKILL.md +1206 -0
  129. package/plugins/mirror-mind/skills/mm-consolidate/SKILL.md +112 -0
  130. package/plugins/mirror-mind/skills/mm-consult/SKILL.md +83 -0
  131. package/plugins/mirror-mind/skills/mm-conversations/SKILL.md +17 -0
  132. package/plugins/mirror-mind/skills/mm-discard/SKILL.md +40 -0
  133. package/plugins/mirror-mind/skills/mm-explore/SKILL.md +241 -0
  134. package/plugins/mirror-mind/skills/mm-help/SKILL.md +104 -0
  135. package/plugins/mirror-mind/skills/mm-identity/SKILL.md +96 -0
  136. package/plugins/mirror-mind/skills/mm-journal/SKILL.md +21 -0
  137. package/plugins/mirror-mind/skills/mm-journey/SKILL.md +37 -0
  138. package/plugins/mirror-mind/skills/mm-journeys/SKILL.md +15 -0
  139. package/plugins/mirror-mind/skills/mm-memories/SKILL.md +20 -0
  140. package/plugins/mirror-mind/skills/mm-mirror/SKILL.md +67 -0
  141. package/plugins/mirror-mind/skills/mm-mute/SKILL.md +18 -0
  142. package/plugins/mirror-mind/skills/mm-new/SKILL.md +18 -0
  143. package/plugins/mirror-mind/skills/mm-recall/SKILL.md +17 -0
  144. package/plugins/mirror-mind/skills/mm-release-notes/SKILL.md +31 -0
  145. package/plugins/mirror-mind/skills/mm-seed/SKILL.md +15 -0
  146. package/plugins/mirror-mind/skills/mm-shadow/SKILL.md +117 -0
  147. package/plugins/mirror-mind/skills/mm-soul/SKILL.md +488 -0
  148. package/plugins/mirror-mind/skills/mm-tasks/SKILL.md +36 -0
  149. package/plugins/mirror-mind/skills/mm-update/SKILL.md +30 -0
  150. package/plugins/mirror-mind/skills/mm-week/SKILL.md +46 -0
  151. package/plugins/mirror-mind/skills/mm-welcome/SKILL.md +22 -0
  152. package/scripts/codex-hooks/session-end.sh +85 -0
  153. package/scripts/codex-hooks/session-start.sh +85 -0
  154. package/scripts/codex-mirror.sh +48 -0
  155. package/templates/identity/README.md +119 -0
  156. package/templates/identity/ego/behavior.yaml +52 -0
  157. package/templates/identity/ego/constraints.yaml +15 -0
  158. package/templates/identity/ego/identity.yaml +43 -0
  159. package/templates/identity/journeys/personal-growth.yaml +39 -0
  160. package/templates/identity/organization/identity.yaml +24 -0
  161. package/templates/identity/organization/principles.yaml +17 -0
  162. package/templates/identity/personas/coach.yaml +94 -0
  163. package/templates/identity/personas/designer.yaml +93 -0
  164. package/templates/identity/personas/doctor.yaml +96 -0
  165. package/templates/identity/personas/engineer.yaml +77 -0
  166. package/templates/identity/personas/financial.yaml +97 -0
  167. package/templates/identity/personas/prompt-engineer.yaml +122 -0
  168. package/templates/identity/personas/researcher.yaml +88 -0
  169. package/templates/identity/personas/strategist.yaml +91 -0
  170. package/templates/identity/personas/teacher.yaml +95 -0
  171. package/templates/identity/personas/therapist.yaml +91 -0
  172. package/templates/identity/personas/thinker.yaml +74 -0
  173. package/templates/identity/personas/writer.yaml +76 -0
  174. package/templates/identity/self/config.yaml +16 -0
  175. package/templates/identity/self/soul.yaml +105 -0
  176. package/templates/identity/user/identity.yaml +30 -0
  177. package/ts/src/backup/staging.ts +62 -0
  178. package/ts/src/backup/zipBackup.ts +267 -0
  179. package/ts/src/backup/zipReader.ts +109 -0
  180. package/ts/src/backup/zipWriter.ts +148 -0
  181. package/ts/src/builder/activeCheckpoint.ts +134 -0
  182. package/ts/src/builder/aggregateStatus.ts +34 -0
  183. package/ts/src/builder/approve.ts +149 -0
  184. package/ts/src/builder/argv.ts +292 -0
  185. package/ts/src/builder/ariadMethod.ts +536 -0
  186. package/ts/src/builder/artifacts/artifactSurfaces.ts +106 -0
  187. package/ts/src/builder/artifacts/artifactWriter.ts +113 -0
  188. package/ts/src/builder/artifacts/closureArtifacts.ts +199 -0
  189. package/ts/src/builder/artifacts/deliveryStoryArtifacts.ts +316 -0
  190. package/ts/src/builder/artifacts/planArtifacts.ts +242 -0
  191. package/ts/src/builder/artifacts/scaffoldSections.ts +273 -0
  192. package/ts/src/builder/artifacts/scaffoldState.ts +227 -0
  193. package/ts/src/builder/artifacts/storyFiles.ts +61 -0
  194. package/ts/src/builder/artifacts/storyIndex.ts +166 -0
  195. package/ts/src/builder/cadence.ts +59 -0
  196. package/ts/src/builder/card.ts +192 -0
  197. package/ts/src/builder/checkpointRefused.ts +66 -0
  198. package/ts/src/builder/closure.ts +964 -0
  199. package/ts/src/builder/commands.ts +2053 -0
  200. package/ts/src/builder/cursorPosition.ts +176 -0
  201. package/ts/src/builder/cursorTransitions.ts +77 -0
  202. package/ts/src/builder/deliveryCursor.ts +577 -0
  203. package/ts/src/builder/deliveryStoryClosure.ts +521 -0
  204. package/ts/src/builder/deliveryStoryPlan.ts +536 -0
  205. package/ts/src/builder/deliveryStoryReady.ts +160 -0
  206. package/ts/src/builder/deliveryStoryRoadmapClosure.ts +151 -0
  207. package/ts/src/builder/expand.ts +336 -0
  208. package/ts/src/builder/flowUnit.ts +339 -0
  209. package/ts/src/builder/homeSurface.ts +122 -0
  210. package/ts/src/builder/implementationGuard.ts +125 -0
  211. package/ts/src/builder/index.ts +11 -0
  212. package/ts/src/builder/lifecycleRefusal.ts +92 -0
  213. package/ts/src/builder/lifecycleRibbon.ts +159 -0
  214. package/ts/src/builder/load.ts +313 -0
  215. package/ts/src/builder/methodAdoption.ts +113 -0
  216. package/ts/src/builder/methodDefinition.ts +429 -0
  217. package/ts/src/builder/methodInspection.ts +371 -0
  218. package/ts/src/builder/plan.ts +408 -0
  219. package/ts/src/builder/planPreauthorization.ts +265 -0
  220. package/ts/src/builder/prepare.ts +225 -0
  221. package/ts/src/builder/projectPaths.ts +64 -0
  222. package/ts/src/builder/pull.ts +356 -0
  223. package/ts/src/builder/pullCandidates.ts +463 -0
  224. package/ts/src/builder/pullCandidatesRender.ts +238 -0
  225. package/ts/src/builder/refinementField.ts +93 -0
  226. package/ts/src/builder/releaseIntent.ts +173 -0
  227. package/ts/src/builder/resumeState.ts +84 -0
  228. package/ts/src/builder/resumeSurface.ts +149 -0
  229. package/ts/src/builder/roadmapGrammar.ts +300 -0
  230. package/ts/src/builder/roadmapScan.ts +97 -0
  231. package/ts/src/builder/roadmapScope.ts +210 -0
  232. package/ts/src/builder/scopePhrases.ts +146 -0
  233. package/ts/src/builder/storyPaths.ts +196 -0
  234. package/ts/src/builder/storyPlanPreauthorization.ts +287 -0
  235. package/ts/src/builder/surfaceProtocol.ts +42 -0
  236. package/ts/src/builder/templateGeneration.ts +148 -0
  237. package/ts/src/builder/transition.ts +178 -0
  238. package/ts/src/consult/args.ts +99 -0
  239. package/ts/src/consult/core.ts +122 -0
  240. package/ts/src/consult/modelCatalog.ts +55 -0
  241. package/ts/src/consult/render.ts +47 -0
  242. package/ts/src/conversation/append.ts +414 -0
  243. package/ts/src/conversation/backfill.ts +387 -0
  244. package/ts/src/conversation/closeTail.ts +467 -0
  245. package/ts/src/conversation/extraction.ts +333 -0
  246. package/ts/src/conversation/extractionDriver.ts +130 -0
  247. package/ts/src/conversation/extractionRun.ts +70 -0
  248. package/ts/src/conversation/hookPayload.ts +51 -0
  249. package/ts/src/conversation/journeyInference.ts +165 -0
  250. package/ts/src/conversation/journeyRepair.ts +114 -0
  251. package/ts/src/conversation/lifecycleFaces.ts +197 -0
  252. package/ts/src/conversation/lifecycleWrites.ts +313 -0
  253. package/ts/src/conversation/listing.ts +77 -0
  254. package/ts/src/conversation/logger.ts +851 -0
  255. package/ts/src/conversation/loggerCli.ts +321 -0
  256. package/ts/src/conversation/loggerRuntime.ts +259 -0
  257. package/ts/src/conversation/metadataLifecycle.ts +443 -0
  258. package/ts/src/conversation/recall.ts +66 -0
  259. package/ts/src/conversation/sessionComposites.ts +258 -0
  260. package/ts/src/conversation/sessionImport.ts +90 -0
  261. package/ts/src/conversation/transcriptBackfill.ts +141 -0
  262. package/ts/src/cultivation/applyActions.ts +241 -0
  263. package/ts/src/cultivation/cluster.ts +86 -0
  264. package/ts/src/cultivation/consolidationStore.ts +281 -0
  265. package/ts/src/cultivation/promptContext.ts +62 -0
  266. package/ts/src/cultivation/propose.ts +305 -0
  267. package/ts/src/cultivation/scan.ts +155 -0
  268. package/ts/src/db/backupGate.ts +47 -0
  269. package/ts/src/db/bootstrap.ts +108 -0
  270. package/ts/src/db/bootstrapLock.ts +223 -0
  271. package/ts/src/db/copyGuard.ts +60 -0
  272. package/ts/src/db/database.ts +397 -0
  273. package/ts/src/db/decode.ts +66 -0
  274. package/ts/src/db/ftsIntegrity.ts +41 -0
  275. package/ts/src/db/migrateOnOpen.ts +214 -0
  276. package/ts/src/db/migrations.ts +576 -0
  277. package/ts/src/db/readyOnOpen.ts +35 -0
  278. package/ts/src/db/rowDecode.ts +42 -0
  279. package/ts/src/db/schema.ts +432 -0
  280. package/ts/src/db/schemaInventory.ts +225 -0
  281. package/ts/src/db/schemaInventorySnapshot.ts +2107 -0
  282. package/ts/src/db/schemaState.ts +91 -0
  283. package/ts/src/db/schemaTsDivergence.ts +114 -0
  284. package/ts/src/descriptor/descriptorRead.ts +49 -0
  285. package/ts/src/docs/docsLint.ts +265 -0
  286. package/ts/src/explorer/handoff.ts +522 -0
  287. package/ts/src/explorer/render.ts +335 -0
  288. package/ts/src/explorer/story.ts +769 -0
  289. package/ts/src/explorer/transition.ts +72 -0
  290. package/ts/src/extensions/bindings.ts +170 -0
  291. package/ts/src/extensions/catalog.ts +249 -0
  292. package/ts/src/extensions/catalogCommands.ts +513 -0
  293. package/ts/src/extensions/catalogWrites.ts +652 -0
  294. package/ts/src/extensions/contextRuntime.ts +325 -0
  295. package/ts/src/extensions/dispatch.ts +374 -0
  296. package/ts/src/extensions/errors.ts +24 -0
  297. package/ts/src/extensions/manifest.ts +356 -0
  298. package/ts/src/extensions/migrations.ts +350 -0
  299. package/ts/src/extraction/conversation.ts +304 -0
  300. package/ts/src/extraction/conversationMetadata.ts +206 -0
  301. package/ts/src/extraction/fencing.ts +106 -0
  302. package/ts/src/extraction/json.ts +17 -0
  303. package/ts/src/extraction/prompts.ts +470 -0
  304. package/ts/src/frontDoor/args.ts +30 -0
  305. package/ts/src/frontDoor/argvShape.ts +106 -0
  306. package/ts/src/frontDoor/buildLoadRuntime.ts +139 -0
  307. package/ts/src/frontDoor/buildRoute.ts +398 -0
  308. package/ts/src/frontDoor/cli.ts +1872 -0
  309. package/ts/src/frontDoor/cloneRoleGuard.ts +98 -0
  310. package/ts/src/frontDoor/consultRoute.ts +50 -0
  311. package/ts/src/frontDoor/contentTailRoute.ts +239 -0
  312. package/ts/src/frontDoor/conversationLoggerRoute.ts +83 -0
  313. package/ts/src/frontDoor/cultivationRoute.ts +210 -0
  314. package/ts/src/frontDoor/dbPath.ts +131 -0
  315. package/ts/src/frontDoor/dbSafetyToolsRoute.ts +240 -0
  316. package/ts/src/frontDoor/exploreRoute.ts +572 -0
  317. package/ts/src/frontDoor/extensionCatalogRoute.ts +252 -0
  318. package/ts/src/frontDoor/frontDoorLog.ts +57 -0
  319. package/ts/src/frontDoor/identityWrite.ts +36 -0
  320. package/ts/src/frontDoor/journeyWriteRoute.ts +26 -0
  321. package/ts/src/frontDoor/lifecycleWriteRoute.ts +110 -0
  322. package/ts/src/frontDoor/liveBackup.ts +100 -0
  323. package/ts/src/frontDoor/mirrorModeRoute.ts +163 -0
  324. package/ts/src/frontDoor/namedRefusal.ts +35 -0
  325. package/ts/src/frontDoor/nodeSupport.ts +24 -0
  326. package/ts/src/frontDoor/render/consolidate.ts +199 -0
  327. package/ts/src/frontDoor/render/conversations.ts +33 -0
  328. package/ts/src/frontDoor/render/cultivationShared.ts +21 -0
  329. package/ts/src/frontDoor/render/descriptor.ts +20 -0
  330. package/ts/src/frontDoor/render/detectPersona.ts +50 -0
  331. package/ts/src/frontDoor/render/icons.ts +13 -0
  332. package/ts/src/frontDoor/render/identity.ts +59 -0
  333. package/ts/src/frontDoor/render/identityRows.ts +17 -0
  334. package/ts/src/frontDoor/render/inspectPersona.ts +53 -0
  335. package/ts/src/frontDoor/render/journeyStatus.ts +78 -0
  336. package/ts/src/frontDoor/render/journeys.ts +79 -0
  337. package/ts/src/frontDoor/render/list.ts +41 -0
  338. package/ts/src/frontDoor/render/memories.ts +67 -0
  339. package/ts/src/frontDoor/render/recall.ts +49 -0
  340. package/ts/src/frontDoor/render/shadow.ts +155 -0
  341. package/ts/src/frontDoor/render/tasks.ts +99 -0
  342. package/ts/src/frontDoor/render/tasksImportSync.ts +63 -0
  343. package/ts/src/frontDoor/render/week.ts +113 -0
  344. package/ts/src/frontDoor/routing.ts +1001 -0
  345. package/ts/src/frontDoor/runtimeRoute.ts +623 -0
  346. package/ts/src/frontDoor/searchRoute.ts +166 -0
  347. package/ts/src/frontDoor/seedPaths.ts +98 -0
  348. package/ts/src/frontDoor/sessionStartWelcomeRoute.ts +166 -0
  349. package/ts/src/frontDoor/soulRoute.ts +433 -0
  350. package/ts/src/frontDoor/stdinSource.ts +37 -0
  351. package/ts/src/frontDoor/tasksImportSyncRoute.ts +110 -0
  352. package/ts/src/frontDoor/tasksWriteRoute.ts +101 -0
  353. package/ts/src/frontDoor/usage.ts +176 -0
  354. package/ts/src/guards/claudePlugin.ts +298 -0
  355. package/ts/src/guards/packContents.ts +306 -0
  356. package/ts/src/guards/piSourcedSkills.ts +70 -0
  357. package/ts/src/guards/retiredRouteShadows.ts +57 -0
  358. package/ts/src/guards/retiredSurfaces.ts +564 -0
  359. package/ts/src/hooks/claude.ts +214 -0
  360. package/ts/src/hooks/codex.ts +45 -0
  361. package/ts/src/hooks/gemini.ts +126 -0
  362. package/ts/src/hooks/main.ts +109 -0
  363. package/ts/src/hooks/mirrorState.ts +71 -0
  364. package/ts/src/hooks/payload.ts +73 -0
  365. package/ts/src/hooks/runtime.ts +179 -0
  366. package/ts/src/hooks/runtimeDetection.ts +34 -0
  367. package/ts/src/identity/applyConsolidationIdentityUpdate.ts +67 -0
  368. package/ts/src/identity/descriptorGenerate.ts +162 -0
  369. package/ts/src/identity/identityEdit.ts +143 -0
  370. package/ts/src/identity/identityKey.ts +77 -0
  371. package/ts/src/identity/identityRead.ts +69 -0
  372. package/ts/src/identity/identityStore.ts +80 -0
  373. package/ts/src/identity/journeyListing.ts +53 -0
  374. package/ts/src/identity/personaInspect.ts +44 -0
  375. package/ts/src/identity/personaListing.ts +37 -0
  376. package/ts/src/identity/setIdentity.ts +64 -0
  377. package/ts/src/index.ts +231 -0
  378. package/ts/src/init/init.ts +111 -0
  379. package/ts/src/journey/journeyOptions.ts +131 -0
  380. package/ts/src/journey/journeyRemoval.ts +158 -0
  381. package/ts/src/journey/journeyStatus.ts +149 -0
  382. package/ts/src/journey/journeySyncFile.ts +87 -0
  383. package/ts/src/journey/journeyWrite.ts +203 -0
  384. package/ts/src/journey/parentJourney.ts +41 -0
  385. package/ts/src/journey/validateParentJourney.ts +55 -0
  386. package/ts/src/mcp/boundary.ts +151 -0
  387. package/ts/src/mcp/guards.ts +244 -0
  388. package/ts/src/mcp/main.ts +121 -0
  389. package/ts/src/mcp/payload.ts +141 -0
  390. package/ts/src/mcp/protocol.ts +141 -0
  391. package/ts/src/mcp/readModels.ts +241 -0
  392. package/ts/src/mcp/registry.ts +201 -0
  393. package/ts/src/mcp/serve.ts +120 -0
  394. package/ts/src/mcp/tools/deterministic.ts +137 -0
  395. package/ts/src/mcp/tools/providerCrossing.ts +187 -0
  396. package/ts/src/mcp/wire.ts +8 -0
  397. package/ts/src/memory/journal.ts +180 -0
  398. package/ts/src/memory/listing.ts +107 -0
  399. package/ts/src/memory/memoryWrite.ts +88 -0
  400. package/ts/src/memory/reinforcement.ts +35 -0
  401. package/ts/src/mirror/context.ts +161 -0
  402. package/ts/src/mirror/defaultResolution.ts +199 -0
  403. package/ts/src/mirror/mirrorForm.ts +43 -0
  404. package/ts/src/mirror/orchestration.ts +364 -0
  405. package/ts/src/mirror/reception.ts +194 -0
  406. package/ts/src/mirror/render.ts +75 -0
  407. package/ts/src/mirror/runtimeSession.ts +205 -0
  408. package/ts/src/mode/operatingMode.ts +148 -0
  409. package/ts/src/observability/callOutcome.ts +115 -0
  410. package/ts/src/observability/inspectLedger.ts +329 -0
  411. package/ts/src/observability/ledgerHooks.ts +126 -0
  412. package/ts/src/observability/llmCalls.ts +154 -0
  413. package/ts/src/persona/detectPersona.ts +81 -0
  414. package/ts/src/planning/promptAssembly.ts +111 -0
  415. package/ts/src/planning/weekPending.ts +81 -0
  416. package/ts/src/planning/weekPlan.ts +183 -0
  417. package/ts/src/planning/weekSave.ts +117 -0
  418. package/ts/src/providers/config.ts +189 -0
  419. package/ts/src/providers/cost.ts +64 -0
  420. package/ts/src/providers/credits.ts +204 -0
  421. package/ts/src/providers/embedding.ts +321 -0
  422. package/ts/src/providers/familyProviders.ts +147 -0
  423. package/ts/src/providers/llm.ts +334 -0
  424. package/ts/src/providers/openrouter.ts +244 -0
  425. package/ts/src/providers/redaction.ts +110 -0
  426. package/ts/src/providers/replay.ts +15 -0
  427. package/ts/src/providers/transport.ts +410 -0
  428. package/ts/src/repair/encodingRepair.ts +253 -0
  429. package/ts/src/runtime/backup.ts +151 -0
  430. package/ts/src/runtime/channel.ts +146 -0
  431. package/ts/src/runtime/config.ts +168 -0
  432. package/ts/src/runtime/diagnose.ts +686 -0
  433. package/ts/src/runtime/git.ts +510 -0
  434. package/ts/src/runtime/installKind.ts +220 -0
  435. package/ts/src/runtime/migrate.ts +154 -0
  436. package/ts/src/runtime/packageIdentity.ts +102 -0
  437. package/ts/src/runtime/releaseNotes.ts +244 -0
  438. package/ts/src/runtime/status.ts +557 -0
  439. package/ts/src/runtime/strategies/clone.ts +200 -0
  440. package/ts/src/runtime/strategies/package.ts +328 -0
  441. package/ts/src/runtime/treeRoot.ts +30 -0
  442. package/ts/src/runtime/update.ts +445 -0
  443. package/ts/src/runtime/updateGate.ts +40 -0
  444. package/ts/src/runtime/updatePipeline.ts +159 -0
  445. package/ts/src/runtime/version.ts +36 -0
  446. package/ts/src/runtime/wiring.ts +130 -0
  447. package/ts/src/search/memorySearch.ts +338 -0
  448. package/ts/src/search/ranker.ts +154 -0
  449. package/ts/src/seed/seed.ts +256 -0
  450. package/ts/src/seed/seedYaml.ts +133 -0
  451. package/ts/src/soul/apply.ts +218 -0
  452. package/ts/src/soul/harvest.ts +267 -0
  453. package/ts/src/soul/prompts/soul_beauty_voice.md +103 -0
  454. package/ts/src/soul/prompts/soul_self_voice.md +219 -0
  455. package/ts/src/soul/prompts/soul_wisdom_voice.md +121 -0
  456. package/ts/src/soul/prompts.ts +85 -0
  457. package/ts/src/soul/render.ts +358 -0
  458. package/ts/src/soul/state.ts +212 -0
  459. package/ts/src/soul/transition.ts +37 -0
  460. package/ts/src/tasks/journeyPathParse.ts +113 -0
  461. package/ts/src/tasks/taskImportSync.ts +142 -0
  462. package/ts/src/tasks/taskStore.ts +312 -0
  463. package/ts/src/tasks/weekView.ts +120 -0
  464. package/ts/src/util/clipCodePoints.ts +26 -0
  465. package/ts/src/util/paths.ts +63 -0
  466. package/ts/src/util/program.ts +9 -0
  467. package/ts/src/util/pyGenerators.ts +144 -0
  468. package/ts/src/util/pythonText.ts +317 -0
  469. package/ts/src/util/semver.ts +45 -0
  470. package/ts/src/util/shellWord.ts +25 -0
  471. package/ts/src/util/slug.ts +64 -0
  472. package/ts/src/welcome/card.ts +339 -0
  473. package/ts/src/welcome/statusLine.ts +101 -0
  474. package/ts/src/welcome/updateCache.ts +129 -0
@@ -0,0 +1,227 @@
1
+ // CR112 — reading a story-package artifact back and saying what it is.
2
+ //
3
+ // Plan and Expand write scaffolds where no file exists and never touch a file that
4
+ // does (CR079). Until CR112 that was the whole story: `build show` said present or
5
+ // missing, and no approval read a file, so a scaffold nobody had authored was
6
+ // approvable on both story routes. This module answers the question the surfaces
7
+ // and the approvals need: is this file still the scaffold, and which of its sections
8
+ // are still waiting to be written?
9
+ //
10
+ // The verdict is structural, never a judgement of prose. A section is
11
+ //
12
+ // * `missing` -- the file, or the `## ` heading, is not there;
13
+ // * `unfilled` -- empty, or holding a line that starts with `pending`, is a
14
+ // throwaway token, or matches the placeholder pattern: the rule
15
+ // Python's `unfilled_plan_sections_for` applied;
16
+ // * `scaffold` -- every non-blank line is one the scaffold would write under this
17
+ // heading, with the `{title}` slot wildcarded;
18
+ // * `authored` -- anything else. One real line under a heading is authored.
19
+ //
20
+ // `unfilled` is judged before `scaffold`, so a section that holds a `TODO` beside the
21
+ // template is unfilled, not scaffold, and either way not authored.
22
+ //
23
+ // Only `placeholder` sections decide the file's word. A `default` section is a rule
24
+ // the Driver may keep verbatim. For `plan.md` every placeholder heading is required and
25
+ // a missing one counts against the file, as the Plan contract has always required; for
26
+ // `index.md` and `test-guide.md` a missing heading is the Driver's structure, not a
27
+ // scaffold, and only sections that are present and still the scaffold's count.
28
+ //
29
+ // The file's word follows its judged sections: `authored` when nothing is left to
30
+ // write, `partly authored` when some are authored, `scaffold` when none is and the file
31
+ // still carries the scaffold's text, and `incomplete` when none is and none of it is
32
+ // the scaffold's -- a file a person wrote without the sections the contract requires.
33
+ // Calling that file a scaffold would say Ariad wrote what it did not.
34
+ //
35
+ // CR111 D4: for `plan.md` the LIST of sections still to write is what approval would
36
+ // refuse: `PLAN_APPROVAL_SECTIONS`, which adds the two required `default` sections,
37
+ // Non-Goals and the Implementation Contract, while they are missing or empty. Until
38
+ // then `build show` could say `authored` over an approval that refused. The two
39
+ // required defaults lengthen the list; they never decide the word, or an untouched
40
+ // scaffold, whose defaults are filled, would read `partly authored`. Approval reads
41
+ // the same list (`planSectionsToAuthor`), so no surface can disagree with it.
42
+
43
+ import { existsSync, readFileSync } from "node:fs";
44
+ import { pySplitLines, pyStrip } from "#util/pythonText.ts";
45
+ import {
46
+ matchesTemplate,
47
+ PLAN_APPROVAL_SECTIONS,
48
+ PLAN_SECTIONS,
49
+ type SectionSpec,
50
+ STORY_INDEX_SECTIONS,
51
+ TEST_GUIDE_SECTIONS,
52
+ } from "./scaffoldSections.ts";
53
+
54
+ export type SectionState = "missing" | "unfilled" | "scaffold" | "authored";
55
+ export type ArtifactState = "missing" | "scaffold" | "incomplete" | "partly_authored" | "authored";
56
+ export type ArtifactName = "index.md" | "plan.md" | "test-guide.md";
57
+
58
+ /** The state word a surface prints beside an artifact's name. */
59
+ export function describeArtifactState(state: ArtifactState): string {
60
+ return state === "partly_authored" ? "partly authored" : state;
61
+ }
62
+
63
+ export interface SectionVerdict {
64
+ readonly header: string;
65
+ readonly state: SectionState;
66
+ }
67
+
68
+ export interface ArtifactVerdict {
69
+ readonly name: ArtifactName;
70
+ readonly state: ArtifactState;
71
+ /** Every placeholder section the reader judged, in the artifact's own order. */
72
+ readonly sections: readonly SectionVerdict[];
73
+ /**
74
+ * The sections still to be written, by their exact `## ` text, in the file's order:
75
+ * the placeholder sections not authored and, for `plan.md`, the required default
76
+ * sections missing or empty -- exactly what a Plan approval would refuse on.
77
+ */
78
+ readonly toAuthor: readonly string[];
79
+ }
80
+
81
+ /**
82
+ * Python `_PLACEHOLDER_LINE_RE`.
83
+ *
84
+ * `^(?:[-*]\s+)?(?:this (?:section )?is (?:a )?)?placeholder(?:\b|$)`, case
85
+ * insensitive. `\s` is Python's, which matches more than JavaScript's — but this
86
+ * pattern's `\s+` sits between an ASCII bullet and the word, where the two agree.
87
+ * The `\b` alternative is what keeps "placeholder story" a placeholder while
88
+ * "placeholders" is not; and the whole point is that it anchors at the START, so
89
+ * "Do not implement the sibling Payment placeholder story" is product vocabulary,
90
+ * not an unfilled section.
91
+ */
92
+ export const PLACEHOLDER_LINE_RE =
93
+ /^(?:[-*]\s+)?(?:this (?:section )?is (?:a )?)?placeholder(?:\b|$)/i;
94
+
95
+ const THROWAWAY = new Set(["todo", "tbd", "...", "n/a", "none"]);
96
+
97
+ /**
98
+ * Python `_level_two_sections`.
99
+ *
100
+ * `setdefault` means a REPEATED `## Scope` heading appends to the first section
101
+ * rather than replacing it, so a Plan with two Scope headings is complete if either
102
+ * carries content.
103
+ */
104
+ export function levelTwoSections(text: string): Map<string, string> {
105
+ const sections = new Map<string, string[]>();
106
+ let current: string | null = null;
107
+ for (const line of pySplitLines(text)) {
108
+ if (line.startsWith("## ")) {
109
+ current = pyStrip(line.slice(3));
110
+ if (!sections.has(current)) sections.set(current, []);
111
+ } else if (current !== null) {
112
+ sections.get(current)?.push(line);
113
+ }
114
+ }
115
+ const joined = new Map<string, string>();
116
+ for (const [header, lines] of sections) joined.set(header, lines.join("\n"));
117
+ return joined;
118
+ }
119
+
120
+ /** The unfilled rule, Python's `unfilled_plan_sections_for`, for one section's body. */
121
+ export function isUnfilledBody(body: string): boolean {
122
+ const stripped = pyStrip(body);
123
+ if (!stripped) return true;
124
+ const lines = pySplitLines(stripped)
125
+ .map((line) => pyStrip(line).toLowerCase())
126
+ .filter((line) => line !== "");
127
+ return (
128
+ lines.some((line) => line.startsWith("pending")) ||
129
+ lines.some((line) => THROWAWAY.has(line)) ||
130
+ lines.some((line) => PLACEHOLDER_LINE_RE.test(line))
131
+ );
132
+ }
133
+
134
+ /** True when every non-blank line of `body` is a line the scaffold writes for `spec`. */
135
+ export function isScaffoldBody(body: string, spec: SectionSpec): boolean {
136
+ const lines = pySplitLines(body)
137
+ .map((line) => pyStrip(line))
138
+ .filter((line) => line !== "");
139
+ if (lines.length === 0) return false;
140
+ return lines.every((line) => spec.lines.some((template) => matchesTemplate(line, template)));
141
+ }
142
+
143
+ /** The state of one section, given the file's sections. */
144
+ export function sectionState(sections: Map<string, string>, spec: SectionSpec): SectionState {
145
+ const body = sections.get(spec.header);
146
+ if (body === undefined) return "missing";
147
+ if (isUnfilledBody(body)) return "unfilled";
148
+ if (isScaffoldBody(body, spec)) return "scaffold";
149
+ return "authored";
150
+ }
151
+
152
+ const SPECS: Readonly<Record<ArtifactName, readonly SectionSpec[]>> = {
153
+ "index.md": STORY_INDEX_SECTIONS,
154
+ "plan.md": PLAN_SECTIONS,
155
+ "test-guide.md": TEST_GUIDE_SECTIONS,
156
+ };
157
+
158
+ /**
159
+ * Which placeholder sections decide `name`. `plan.md` requires every one of its
160
+ * placeholder headings; the other two judge only the placeholder headings the file
161
+ * has, so a Driver's own structure is never called a scaffold.
162
+ */
163
+ function judgedSections(name: ArtifactName, sections: Map<string, string>): SectionSpec[] {
164
+ const placeholders = SPECS[name].filter((spec) => spec.kind === "placeholder");
165
+ if (name === "plan.md") return placeholders;
166
+ return placeholders.filter((spec) => sections.has(spec.header));
167
+ }
168
+
169
+ /** The `PLAN_SECTIONS` entry for `header`; a heading the table lacks is a default. */
170
+ function planSpec(header: string): SectionSpec {
171
+ return (
172
+ PLAN_SECTIONS.find((candidate) => candidate.header === header) ?? {
173
+ header,
174
+ kind: "default",
175
+ lines: [],
176
+ }
177
+ );
178
+ }
179
+
180
+ /** What approval would refuse on in a `plan.md` whose sections are `sections`. */
181
+ function planToAuthor(sections: Map<string, string>): string[] {
182
+ return PLAN_APPROVAL_SECTIONS.filter(
183
+ (header) => sectionState(sections, planSpec(header)) !== "authored",
184
+ );
185
+ }
186
+
187
+ /** The verdict for artifact text already read; `null` text means the file is missing. */
188
+ export function judgeArtifact(name: ArtifactName, text: string | null): ArtifactVerdict {
189
+ if (text === null) return { name, state: "missing", sections: [], toAuthor: [] };
190
+ const sections = levelTwoSections(text);
191
+ const verdicts = judgedSections(name, sections).map((spec) => ({
192
+ header: spec.header,
193
+ state: sectionState(sections, spec),
194
+ }));
195
+ const toAuthor =
196
+ name === "plan.md"
197
+ ? planToAuthor(sections)
198
+ : verdicts.filter((verdict) => verdict.state !== "authored").map((verdict) => verdict.header);
199
+ // The word comes from the placeholder sections alone (D4): the required defaults
200
+ // lengthen the list, never turn a scaffold into a partly authored file.
201
+ const state: ArtifactState =
202
+ toAuthor.length === 0
203
+ ? "authored"
204
+ : verdicts.some((verdict) => verdict.state === "authored")
205
+ ? "partly_authored"
206
+ : verdicts.some((verdict) => verdict.state === "scaffold")
207
+ ? "scaffold"
208
+ : "incomplete";
209
+ return { name, state, sections: verdicts, toAuthor };
210
+ }
211
+
212
+ /** The verdict for the artifact at `path`. */
213
+ export function artifactState(name: ArtifactName, path: string): ArtifactVerdict {
214
+ if (!existsSync(path)) return judgeArtifact(name, null);
215
+ return judgeArtifact(name, readFileSync(path, "utf8"));
216
+ }
217
+
218
+ /**
219
+ * The sections of `plan.md` a Plan approval must see authored, on either route: the
220
+ * `toAuthor` list `build show` and the Plan checkpoint print for the same file (CR111
221
+ * D4). A missing file, or no file to read, leaves every one of them to write, which is
222
+ * what makes a receipt unusable before the Driver writes the Plan.
223
+ */
224
+ export function planSectionsToAuthor(planPath: string | null): string[] {
225
+ if (planPath === null || !existsSync(planPath)) return [...PLAN_APPROVAL_SECTIONS];
226
+ return [...judgeArtifact("plan.md", readFileSync(planPath, "utf8")).toAuthor];
227
+ }
@@ -0,0 +1,61 @@
1
+ // CR111 — the Plan-stage story files, judged and rendered once for every surface that
2
+ // names them.
3
+ //
4
+ // `build show` lists a story package's `index.md`, `plan.md`, and `test-guide.md`, each
5
+ // with its state and, while it is not authored, the sections still to write (CR112).
6
+ // The Plan checkpoint names the same three files the same way. Both import these lines
7
+ // from here, so the two surfaces cannot say different things about one file: the card
8
+ // does not reach into `build show`'s module, and neither keeps its own copy.
9
+ //
10
+ // The glyph carries only done or not; the word carries the state.
11
+
12
+ import { join } from "node:path";
13
+ import { CARD_WIDTH, cardText } from "../card.ts";
14
+ import { type ArtifactVerdict, artifactState, describeArtifactState } from "./scaffoldState.ts";
15
+
16
+ /** The artifacts Plan and Expand scaffold, in the order Plan writes them. */
17
+ export const PLAN_STAGE_ARTIFACTS = ["index.md", "plan.md", "test-guide.md"] as const;
18
+
19
+ /** The Plan-stage files of the package at `directory`, judged, in `PLAN_STAGE_ARTIFACTS` order. */
20
+ export function judgeStoryFiles(directory: string): ArtifactVerdict[] {
21
+ return PLAN_STAGE_ARTIFACTS.map((name) => artifactState(name, join(directory, name)));
22
+ }
23
+
24
+ const TO_AUTHOR = "to author: ";
25
+ const TO_AUTHOR_INDENT = " ";
26
+
27
+ /**
28
+ * The sections still to write, wrapped BETWEEN headings, never inside one, with every
29
+ * row after the first starting under the first heading. A heading cut in two reads as
30
+ * two items: the first render printed `Navigator` over `Validation` (CR112's handoff
31
+ * review). The headings are the scaffold tables' own, all far shorter than a row.
32
+ */
33
+ export function toAuthorLines(headers: readonly string[]): string[] {
34
+ const width = CARD_WIDTH - TO_AUTHOR_INDENT.length - TO_AUTHOR.length;
35
+ const rows: string[] = [];
36
+ let row = "";
37
+ headers.forEach((header, index) => {
38
+ const item = index < headers.length - 1 ? `${header},` : header;
39
+ const joined = row === "" ? item : `${row} ${item}`;
40
+ if (row !== "" && joined.length > width) {
41
+ rows.push(row);
42
+ row = item;
43
+ } else {
44
+ row = joined;
45
+ }
46
+ });
47
+ if (row !== "") rows.push(row);
48
+ const hanging = " ".repeat(TO_AUTHOR.length);
49
+ return rows.map((text, index) =>
50
+ cardText(`${TO_AUTHOR_INDENT}${index === 0 ? TO_AUTHOR : hanging}${text}`),
51
+ );
52
+ }
53
+
54
+ /** One file's card rows: its glyph, name, and state, then the sections still to write. */
55
+ export function storyFileLines(verdict: ArtifactVerdict): string[] {
56
+ const glyph = verdict.state === "authored" ? "✓" : "○";
57
+ return [
58
+ cardText(`${glyph} ${verdict.name} — ${describeArtifactState(verdict.state)}`),
59
+ ...toAuthorLines(verdict.toAuthor),
60
+ ];
61
+ }
@@ -0,0 +1,166 @@
1
+ // CV22.DS7.US8 plateau 3 — the story-package `index.md` scaffolds Expand writes.
2
+ //
3
+ // Port of the `_render_*_index` half of `src/memory/builder/lifecycle.py`.
4
+ //
5
+ // These bodies are written into the Navigator's repository and then read by
6
+ // humans, by `resolve_story_directory` (which locates a package by the heading
7
+ // these render), and by Expand's own candidate-table parser. So they are graded as
8
+ // bytes, not as structure: a changed dash, a dropped blank line, or a `—` turned
9
+ // into `--` moves a heading out of the grammar that finds it again.
10
+ //
11
+ // The Delivery Story scaffold is the one that closes the loop: it emits the
12
+ // canonical five-column candidate table, which is exactly the shape
13
+ // `parseCandidateStories` requires. A port that drifts here produces a package
14
+ // whose own Expand refuses it.
15
+
16
+ import { tableCell } from "../roadmapGrammar.ts";
17
+ import { storyFolderName } from "../storyPaths.ts";
18
+ import {
19
+ fill,
20
+ STORY_OUTCOME,
21
+ TECHNICAL_STORY_ACCEPTANCE,
22
+ TECHNICAL_STORY_STATEMENT,
23
+ USER_STORY_ACCEPTANCE,
24
+ USER_STORY_STATEMENT,
25
+ } from "./scaffoldSections.ts";
26
+
27
+ // Every sentence below is a template in `scaffoldSections.ts` (CR112): the reader
28
+ // that tells a scaffold from an authored file matches against the same lines these
29
+ // writers fill, so neither can drift from the other.
30
+
31
+ function fillLines(lines: readonly string[], title: string): string {
32
+ return lines.map((line) => fill(line, { title })).join("\n");
33
+ }
34
+
35
+ /** Python `_user_story_statement`. */
36
+ export function userStoryStatement(title: string): string {
37
+ return fillLines(USER_STORY_STATEMENT, title);
38
+ }
39
+
40
+ /** Python `_technical_story_statement`. */
41
+ export function technicalStoryStatement(title: string): string {
42
+ return fillLines(TECHNICAL_STORY_STATEMENT, title);
43
+ }
44
+
45
+ /** Python `_user_story_outcome`. */
46
+ export function userStoryOutcome(title: string): string {
47
+ return fill(STORY_OUTCOME, { title });
48
+ }
49
+
50
+ /** Python `_render_delivery_story_index`. */
51
+ export function renderDeliveryStoryIndex(
52
+ code: string,
53
+ title: string,
54
+ recommendedCode: string,
55
+ recommendedTitle: string,
56
+ ): string {
57
+ const link = `${storyFolderName(recommendedCode, recommendedTitle)}/index.md`;
58
+ return `[< Parent](../index.md)
59
+
60
+ # ${code} — ${title}
61
+
62
+ **Status:** 🟡 Planned
63
+ **Type:** Delivery Story
64
+
65
+ ---
66
+
67
+ ## Outcome
68
+
69
+ ${title}
70
+
71
+ ## Candidate Stories
72
+
73
+ | Code | Story | Type | Outcome | Status |
74
+ |------|-------|------|---------|--------|
75
+ | [${recommendedCode}](${link}) | ${tableCell(recommendedTitle)} | User Story | ${tableCell(userStoryOutcome(recommendedTitle))} | 🟡 Planned |
76
+
77
+ ## Done Condition
78
+
79
+ The Delivery Story is done when child User/Technical Stories produce a coherent delivery outcome.
80
+ `;
81
+ }
82
+
83
+ /** Python `_render_technical_story_index`. */
84
+ export function renderTechnicalStoryIndex(code: string, title: string): string {
85
+ return `[< Parent](../index.md)
86
+
87
+ # ${code} — ${title}
88
+
89
+ **Status:** 🟡 Planned
90
+ **Type:** Technical Story
91
+
92
+ ---
93
+
94
+ ## Technical Story
95
+
96
+ ${technicalStoryStatement(title)}
97
+
98
+ ## Outcome
99
+
100
+ ${userStoryOutcome(title)}
101
+
102
+ ## Acceptance Behavior
103
+
104
+ \`\`\`text
105
+ ${fillLines(TECHNICAL_STORY_ACCEPTANCE, title)}
106
+ \`\`\`
107
+
108
+ ## Scope
109
+
110
+ - ${title}
111
+
112
+ ## Out Of Scope
113
+
114
+ - Sibling Delivery Story scope.
115
+
116
+ ## Validation
117
+
118
+ Navigator-visible validation route plus automated checks.
119
+ `;
120
+ }
121
+
122
+ /** Python `_render_user_story_index`. */
123
+ export function renderUserStoryIndex(code: string, title: string): string {
124
+ return `[< Parent](../index.md)
125
+
126
+ # ${code} — ${title}
127
+
128
+ **Status:** 🟡 Planned
129
+ **Type:** User Story
130
+
131
+ ---
132
+
133
+ ## User Story
134
+
135
+ ${userStoryStatement(title)}
136
+
137
+ ## Outcome
138
+
139
+ ${userStoryOutcome(title)}
140
+
141
+ ## Acceptance Behavior
142
+
143
+ \`\`\`text
144
+ ${fillLines(USER_STORY_ACCEPTANCE, title)}
145
+ \`\`\`
146
+
147
+ ## Scope
148
+
149
+ - ${title}
150
+
151
+ ## Out Of Scope
152
+
153
+ - Sibling Delivery Story scope.
154
+
155
+ ## Validation
156
+
157
+ Navigator-visible validation route plus automated checks.
158
+ `;
159
+ }
160
+
161
+ /** Python `_render_story_index`: the level chooses the scaffold. */
162
+ export function renderStoryIndex(code: string, title: string, level: string): string {
163
+ return level === "technical_story"
164
+ ? renderTechnicalStoryIndex(code, title)
165
+ : renderUserStoryIndex(code, title);
166
+ }
@@ -0,0 +1,59 @@
1
+ // CR115 — the cadence a journey runs at, and the rows that print it.
2
+ //
3
+ // A journey's cadence changes what Plan does: under `accelerated`, Plan records a story
4
+ // preauthorization and the Driver continues into implementation without a Navigator
5
+ // turn. The cursor stores the profile and, for `autonomous`, its limits, and only the
6
+ // cursor sync report printed them, when the cadence was being changed. Every surface
7
+ // that orients the Navigator now prints them, from this module: the Builder resume and
8
+ // `build show` in their label-and-value pairs, the Builder orientation in its own rows.
9
+ //
10
+ // A cursor that stores no profile runs `stepwise`. The sync report and
11
+ // `continue-lifecycle` each held that default before; they read it here now.
12
+ //
13
+ // This module reads two fields and declares them itself, so it imports nothing from the
14
+ // cursor's persistence module, which imports it.
15
+
16
+ import { cardText, cardWrapped } from "./card.ts";
17
+
18
+ const FRAME_BLANK = cardText("");
19
+
20
+ /** The cursor fields the cadence is read from. */
21
+ export interface CadenceView {
22
+ readonly cadenceProfile: string | null;
23
+ readonly cadenceLimits: readonly string[];
24
+ }
25
+
26
+ /** The profile the runtime applies: a cursor that stores none runs `stepwise`. */
27
+ export function effectiveCadenceProfile(cursor: CadenceView): string {
28
+ return cursor.cadenceProfile || "stepwise";
29
+ }
30
+
31
+ /**
32
+ * The limits as one line, or `none`. They bound continuation only under `autonomous`,
33
+ * so only that profile prints them: a limit stored beside another profile bounds
34
+ * nothing, and printing it would say it did.
35
+ */
36
+ function limitsUnder(cursor: CadenceView): string | null {
37
+ if (effectiveCadenceProfile(cursor) !== "autonomous") return null;
38
+ return cursor.cadenceLimits.length > 0 ? cursor.cadenceLimits.join(", ") : "none";
39
+ }
40
+
41
+ /**
42
+ * The resume's and `build show`'s rows: `cadence profile` and the profile, and under
43
+ * `autonomous`, `cadence limits` and the limits. With no cursor there is no cadence.
44
+ */
45
+ export function cadenceCardLines(cursor: CadenceView | null): string[] {
46
+ if (cursor === null) return [cardText("cadence profile"), cardText("none")];
47
+ const lines = [cardText("cadence profile"), cardText(effectiveCadenceProfile(cursor))];
48
+ const limits = limitsUnder(cursor);
49
+ if (limits !== null) lines.push(FRAME_BLANK, cardText("cadence limits"), ...cardWrapped(limits));
50
+ return lines;
51
+ }
52
+
53
+ /** The orientation's rows, in its `label: value` form, as it answers the Refinement question. */
54
+ export function cadenceOrientationLines(cursor: CadenceView): string[] {
55
+ const lines = cardWrapped(`cadence profile: ${effectiveCadenceProfile(cursor)}`);
56
+ const limits = limitsUnder(cursor);
57
+ if (limits !== null) lines.push(...cardWrapped(`cadence limits: ${limits}`));
58
+ return lines;
59
+ }