mirror-mind 0.0.1 → 0.32.1

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 (467) hide show
  1. package/.claude/hooks/log-session-end.sh +85 -0
  2. package/.claude/hooks/log-user-prompt.sh +85 -0
  3. package/.claude/hooks/mirror-inject.sh +85 -0
  4. package/.claude/hooks/session-start.sh +85 -0
  5. package/.gemini/hooks/log-assistant.sh +85 -0
  6. package/.gemini/hooks/log-user.sh +85 -0
  7. package/.gemini/hooks/session-end.sh +85 -0
  8. package/.gemini/hooks/session-start.sh +85 -0
  9. package/.pi/extensions/mirror-logger.ts +561 -0
  10. package/.pi/skills/mm-backup/SKILL.md +21 -0
  11. package/.pi/skills/mm-build/SKILL.md +1206 -0
  12. package/.pi/skills/mm-consolidate/SKILL.md +112 -0
  13. package/.pi/skills/mm-consult/SKILL.md +70 -0
  14. package/.pi/skills/mm-conversations/SKILL.md +16 -0
  15. package/.pi/skills/mm-discard/SKILL.md +39 -0
  16. package/.pi/skills/mm-explore/SKILL.md +255 -0
  17. package/.pi/skills/mm-help/SKILL.md +74 -0
  18. package/.pi/skills/mm-identity/SKILL.md +96 -0
  19. package/.pi/skills/mm-journal/SKILL.md +16 -0
  20. package/.pi/skills/mm-journey/SKILL.md +23 -0
  21. package/.pi/skills/mm-journeys/SKILL.md +15 -0
  22. package/.pi/skills/mm-memories/SKILL.md +17 -0
  23. package/.pi/skills/mm-mirror/SKILL.md +98 -0
  24. package/.pi/skills/mm-mute/SKILL.md +18 -0
  25. package/.pi/skills/mm-new/SKILL.md +18 -0
  26. package/.pi/skills/mm-recall/SKILL.md +17 -0
  27. package/.pi/skills/mm-release-notes/SKILL.md +52 -0
  28. package/.pi/skills/mm-seed/SKILL.md +19 -0
  29. package/.pi/skills/mm-shadow/SKILL.md +117 -0
  30. package/.pi/skills/mm-soul/SKILL.md +502 -0
  31. package/.pi/skills/mm-tasks/SKILL.md +24 -0
  32. package/.pi/skills/mm-update/SKILL.md +32 -0
  33. package/.pi/skills/mm-week/SKILL.md +28 -0
  34. package/.pi/skills/mm-welcome/SKILL.md +24 -0
  35. package/AGENTS.md +188 -0
  36. package/README.md +126 -9
  37. package/bin/loader.js +67 -0
  38. package/bin/mirror-hook.js +7 -0
  39. package/bin/mirror.js +7 -0
  40. package/docs/releases/index.md +99 -0
  41. package/docs/releases/pending-cutoffs.md +510 -0
  42. package/docs/releases/v0.10.0.md +123 -0
  43. package/docs/releases/v0.10.1.md +66 -0
  44. package/docs/releases/v0.10.10.md +51 -0
  45. package/docs/releases/v0.10.11.md +39 -0
  46. package/docs/releases/v0.10.12.md +57 -0
  47. package/docs/releases/v0.10.13.md +35 -0
  48. package/docs/releases/v0.10.14.md +42 -0
  49. package/docs/releases/v0.10.15.md +53 -0
  50. package/docs/releases/v0.10.16.md +35 -0
  51. package/docs/releases/v0.10.17.md +43 -0
  52. package/docs/releases/v0.10.2.md +64 -0
  53. package/docs/releases/v0.10.3.md +78 -0
  54. package/docs/releases/v0.10.4.md +42 -0
  55. package/docs/releases/v0.10.5.md +57 -0
  56. package/docs/releases/v0.10.6.md +47 -0
  57. package/docs/releases/v0.10.7.md +53 -0
  58. package/docs/releases/v0.10.8.md +49 -0
  59. package/docs/releases/v0.10.9.md +37 -0
  60. package/docs/releases/v0.11.0.md +86 -0
  61. package/docs/releases/v0.12.0.md +67 -0
  62. package/docs/releases/v0.13.0.md +64 -0
  63. package/docs/releases/v0.14.0.md +68 -0
  64. package/docs/releases/v0.15.0.md +48 -0
  65. package/docs/releases/v0.16.0.md +50 -0
  66. package/docs/releases/v0.16.1.md +55 -0
  67. package/docs/releases/v0.16.2.md +36 -0
  68. package/docs/releases/v0.17.0.md +50 -0
  69. package/docs/releases/v0.17.1.md +58 -0
  70. package/docs/releases/v0.17.2.md +42 -0
  71. package/docs/releases/v0.17.3.md +58 -0
  72. package/docs/releases/v0.18.0.md +84 -0
  73. package/docs/releases/v0.18.1.md +51 -0
  74. package/docs/releases/v0.18.2.md +69 -0
  75. package/docs/releases/v0.19.0.md +85 -0
  76. package/docs/releases/v0.19.1.md +46 -0
  77. package/docs/releases/v0.20.0.md +85 -0
  78. package/docs/releases/v0.21.0.md +61 -0
  79. package/docs/releases/v0.21.1.md +47 -0
  80. package/docs/releases/v0.22.0.md +77 -0
  81. package/docs/releases/v0.22.1.md +42 -0
  82. package/docs/releases/v0.23.0.md +105 -0
  83. package/docs/releases/v0.24.0.md +125 -0
  84. package/docs/releases/v0.25.0.md +107 -0
  85. package/docs/releases/v0.26.0.md +139 -0
  86. package/docs/releases/v0.26.1.md +65 -0
  87. package/docs/releases/v0.26.2.md +43 -0
  88. package/docs/releases/v0.27.0.md +63 -0
  89. package/docs/releases/v0.28.0.md +59 -0
  90. package/docs/releases/v0.29.0.md +61 -0
  91. package/docs/releases/v0.29.1.md +59 -0
  92. package/docs/releases/v0.29.2.md +59 -0
  93. package/docs/releases/v0.29.3.md +93 -0
  94. package/docs/releases/v0.30.0.md +75 -0
  95. package/docs/releases/v0.30.1.md +93 -0
  96. package/docs/releases/v0.30.2.md +66 -0
  97. package/docs/releases/v0.31.0.md +122 -0
  98. package/docs/releases/v0.31.1.md +142 -0
  99. package/docs/releases/v0.31.10.md +118 -0
  100. package/docs/releases/v0.31.11.md +88 -0
  101. package/docs/releases/v0.31.12.md +105 -0
  102. package/docs/releases/v0.31.13.md +99 -0
  103. package/docs/releases/v0.31.14.md +97 -0
  104. package/docs/releases/v0.31.2.md +115 -0
  105. package/docs/releases/v0.31.3.md +142 -0
  106. package/docs/releases/v0.31.4.md +117 -0
  107. package/docs/releases/v0.31.5.md +155 -0
  108. package/docs/releases/v0.31.6.md +132 -0
  109. package/docs/releases/v0.31.7.md +132 -0
  110. package/docs/releases/v0.31.8.md +120 -0
  111. package/docs/releases/v0.31.9.md +120 -0
  112. package/docs/releases/v0.32.0.md +261 -0
  113. package/docs/releases/v0.32.1.md +59 -0
  114. package/docs/releases/v0.8.0.md +118 -0
  115. package/docs/releases/v0.9.0.md +98 -0
  116. package/docs/releases/v0.9.1.md +83 -0
  117. package/package.json +102 -6
  118. package/plugins/mirror-mind/.claude-plugin/plugin.json +13 -0
  119. package/plugins/mirror-mind/hooks/hooks.json +50 -0
  120. package/plugins/mirror-mind/hooks/log-session-end.sh +98 -0
  121. package/plugins/mirror-mind/hooks/log-user-prompt.sh +98 -0
  122. package/plugins/mirror-mind/hooks/mirror-inject.sh +98 -0
  123. package/plugins/mirror-mind/hooks/session-start.sh +98 -0
  124. package/plugins/mirror-mind/mcp/launch.sh +52 -0
  125. package/plugins/mirror-mind/skills/mm-backup/SKILL.md +27 -0
  126. package/plugins/mirror-mind/skills/mm-build/SKILL.md +1206 -0
  127. package/plugins/mirror-mind/skills/mm-consolidate/SKILL.md +112 -0
  128. package/plugins/mirror-mind/skills/mm-consult/SKILL.md +83 -0
  129. package/plugins/mirror-mind/skills/mm-conversations/SKILL.md +17 -0
  130. package/plugins/mirror-mind/skills/mm-discard/SKILL.md +40 -0
  131. package/plugins/mirror-mind/skills/mm-explore/SKILL.md +241 -0
  132. package/plugins/mirror-mind/skills/mm-help/SKILL.md +104 -0
  133. package/plugins/mirror-mind/skills/mm-identity/SKILL.md +96 -0
  134. package/plugins/mirror-mind/skills/mm-journal/SKILL.md +21 -0
  135. package/plugins/mirror-mind/skills/mm-journey/SKILL.md +37 -0
  136. package/plugins/mirror-mind/skills/mm-journeys/SKILL.md +15 -0
  137. package/plugins/mirror-mind/skills/mm-memories/SKILL.md +20 -0
  138. package/plugins/mirror-mind/skills/mm-mirror/SKILL.md +65 -0
  139. package/plugins/mirror-mind/skills/mm-mute/SKILL.md +18 -0
  140. package/plugins/mirror-mind/skills/mm-new/SKILL.md +18 -0
  141. package/plugins/mirror-mind/skills/mm-recall/SKILL.md +17 -0
  142. package/plugins/mirror-mind/skills/mm-release-notes/SKILL.md +31 -0
  143. package/plugins/mirror-mind/skills/mm-seed/SKILL.md +15 -0
  144. package/plugins/mirror-mind/skills/mm-shadow/SKILL.md +117 -0
  145. package/plugins/mirror-mind/skills/mm-soul/SKILL.md +488 -0
  146. package/plugins/mirror-mind/skills/mm-tasks/SKILL.md +36 -0
  147. package/plugins/mirror-mind/skills/mm-update/SKILL.md +30 -0
  148. package/plugins/mirror-mind/skills/mm-week/SKILL.md +46 -0
  149. package/plugins/mirror-mind/skills/mm-welcome/SKILL.md +22 -0
  150. package/scripts/codex-hooks/session-end.sh +85 -0
  151. package/scripts/codex-hooks/session-start.sh +85 -0
  152. package/scripts/codex-mirror.sh +48 -0
  153. package/templates/identity/README.md +119 -0
  154. package/templates/identity/ego/behavior.yaml +52 -0
  155. package/templates/identity/ego/constraints.yaml +15 -0
  156. package/templates/identity/ego/identity.yaml +43 -0
  157. package/templates/identity/journeys/personal-growth.yaml +39 -0
  158. package/templates/identity/organization/identity.yaml +24 -0
  159. package/templates/identity/organization/principles.yaml +17 -0
  160. package/templates/identity/personas/coach.yaml +94 -0
  161. package/templates/identity/personas/designer.yaml +93 -0
  162. package/templates/identity/personas/doctor.yaml +96 -0
  163. package/templates/identity/personas/engineer.yaml +77 -0
  164. package/templates/identity/personas/financial.yaml +97 -0
  165. package/templates/identity/personas/prompt-engineer.yaml +122 -0
  166. package/templates/identity/personas/researcher.yaml +88 -0
  167. package/templates/identity/personas/strategist.yaml +91 -0
  168. package/templates/identity/personas/teacher.yaml +95 -0
  169. package/templates/identity/personas/therapist.yaml +91 -0
  170. package/templates/identity/personas/thinker.yaml +74 -0
  171. package/templates/identity/personas/writer.yaml +76 -0
  172. package/templates/identity/self/config.yaml +16 -0
  173. package/templates/identity/self/soul.yaml +105 -0
  174. package/templates/identity/user/identity.yaml +30 -0
  175. package/ts/src/backup/staging.ts +62 -0
  176. package/ts/src/backup/zipBackup.ts +267 -0
  177. package/ts/src/backup/zipReader.ts +109 -0
  178. package/ts/src/backup/zipWriter.ts +148 -0
  179. package/ts/src/builder/activeCheckpoint.ts +134 -0
  180. package/ts/src/builder/aggregateStatus.ts +34 -0
  181. package/ts/src/builder/approve.ts +149 -0
  182. package/ts/src/builder/argv.ts +292 -0
  183. package/ts/src/builder/ariadMethod.ts +536 -0
  184. package/ts/src/builder/artifacts/artifactSurfaces.ts +106 -0
  185. package/ts/src/builder/artifacts/artifactWriter.ts +113 -0
  186. package/ts/src/builder/artifacts/closureArtifacts.ts +199 -0
  187. package/ts/src/builder/artifacts/deliveryStoryArtifacts.ts +316 -0
  188. package/ts/src/builder/artifacts/planArtifacts.ts +242 -0
  189. package/ts/src/builder/artifacts/scaffoldSections.ts +273 -0
  190. package/ts/src/builder/artifacts/scaffoldState.ts +227 -0
  191. package/ts/src/builder/artifacts/storyFiles.ts +61 -0
  192. package/ts/src/builder/artifacts/storyIndex.ts +166 -0
  193. package/ts/src/builder/cadence.ts +59 -0
  194. package/ts/src/builder/card.ts +192 -0
  195. package/ts/src/builder/checkpointRefused.ts +66 -0
  196. package/ts/src/builder/closure.ts +964 -0
  197. package/ts/src/builder/commands.ts +2053 -0
  198. package/ts/src/builder/cursorPosition.ts +176 -0
  199. package/ts/src/builder/cursorTransitions.ts +77 -0
  200. package/ts/src/builder/deliveryCursor.ts +577 -0
  201. package/ts/src/builder/deliveryStoryClosure.ts +521 -0
  202. package/ts/src/builder/deliveryStoryPlan.ts +536 -0
  203. package/ts/src/builder/deliveryStoryReady.ts +160 -0
  204. package/ts/src/builder/deliveryStoryRoadmapClosure.ts +151 -0
  205. package/ts/src/builder/expand.ts +336 -0
  206. package/ts/src/builder/flowUnit.ts +339 -0
  207. package/ts/src/builder/homeSurface.ts +122 -0
  208. package/ts/src/builder/implementationGuard.ts +125 -0
  209. package/ts/src/builder/index.ts +11 -0
  210. package/ts/src/builder/lifecycleRefusal.ts +92 -0
  211. package/ts/src/builder/lifecycleRibbon.ts +159 -0
  212. package/ts/src/builder/load.ts +313 -0
  213. package/ts/src/builder/methodAdoption.ts +113 -0
  214. package/ts/src/builder/methodDefinition.ts +429 -0
  215. package/ts/src/builder/methodInspection.ts +371 -0
  216. package/ts/src/builder/plan.ts +408 -0
  217. package/ts/src/builder/planPreauthorization.ts +265 -0
  218. package/ts/src/builder/prepare.ts +225 -0
  219. package/ts/src/builder/projectPaths.ts +64 -0
  220. package/ts/src/builder/pull.ts +356 -0
  221. package/ts/src/builder/pullCandidates.ts +463 -0
  222. package/ts/src/builder/pullCandidatesRender.ts +238 -0
  223. package/ts/src/builder/refinementField.ts +93 -0
  224. package/ts/src/builder/releaseIntent.ts +173 -0
  225. package/ts/src/builder/resumeState.ts +84 -0
  226. package/ts/src/builder/resumeSurface.ts +149 -0
  227. package/ts/src/builder/roadmapGrammar.ts +300 -0
  228. package/ts/src/builder/roadmapScan.ts +97 -0
  229. package/ts/src/builder/roadmapScope.ts +210 -0
  230. package/ts/src/builder/scopePhrases.ts +146 -0
  231. package/ts/src/builder/storyPaths.ts +196 -0
  232. package/ts/src/builder/storyPlanPreauthorization.ts +287 -0
  233. package/ts/src/builder/surfaceProtocol.ts +42 -0
  234. package/ts/src/builder/templateGeneration.ts +148 -0
  235. package/ts/src/builder/transition.ts +178 -0
  236. package/ts/src/consult/args.ts +99 -0
  237. package/ts/src/consult/core.ts +122 -0
  238. package/ts/src/consult/modelCatalog.ts +55 -0
  239. package/ts/src/consult/render.ts +47 -0
  240. package/ts/src/conversation/append.ts +414 -0
  241. package/ts/src/conversation/backfill.ts +387 -0
  242. package/ts/src/conversation/closeTail.ts +467 -0
  243. package/ts/src/conversation/extraction.ts +333 -0
  244. package/ts/src/conversation/extractionDriver.ts +130 -0
  245. package/ts/src/conversation/extractionRun.ts +70 -0
  246. package/ts/src/conversation/journeyInference.ts +165 -0
  247. package/ts/src/conversation/journeyRepair.ts +114 -0
  248. package/ts/src/conversation/lifecycleFaces.ts +197 -0
  249. package/ts/src/conversation/lifecycleWrites.ts +313 -0
  250. package/ts/src/conversation/listing.ts +77 -0
  251. package/ts/src/conversation/logger.ts +576 -0
  252. package/ts/src/conversation/loggerCli.ts +282 -0
  253. package/ts/src/conversation/loggerRuntime.ts +259 -0
  254. package/ts/src/conversation/metadataLifecycle.ts +443 -0
  255. package/ts/src/conversation/recall.ts +66 -0
  256. package/ts/src/conversation/sessionComposites.ts +258 -0
  257. package/ts/src/conversation/sessionImport.ts +90 -0
  258. package/ts/src/conversation/transcriptBackfill.ts +141 -0
  259. package/ts/src/cultivation/applyActions.ts +241 -0
  260. package/ts/src/cultivation/cluster.ts +86 -0
  261. package/ts/src/cultivation/consolidationStore.ts +281 -0
  262. package/ts/src/cultivation/promptContext.ts +62 -0
  263. package/ts/src/cultivation/propose.ts +305 -0
  264. package/ts/src/cultivation/scan.ts +155 -0
  265. package/ts/src/db/backupGate.ts +47 -0
  266. package/ts/src/db/bootstrap.ts +108 -0
  267. package/ts/src/db/bootstrapLock.ts +223 -0
  268. package/ts/src/db/copyGuard.ts +60 -0
  269. package/ts/src/db/database.ts +397 -0
  270. package/ts/src/db/decode.ts +66 -0
  271. package/ts/src/db/ftsIntegrity.ts +41 -0
  272. package/ts/src/db/migrateOnOpen.ts +214 -0
  273. package/ts/src/db/migrations.ts +576 -0
  274. package/ts/src/db/readyOnOpen.ts +35 -0
  275. package/ts/src/db/rowDecode.ts +42 -0
  276. package/ts/src/db/schema.ts +432 -0
  277. package/ts/src/db/schemaInventory.ts +225 -0
  278. package/ts/src/db/schemaInventorySnapshot.ts +2107 -0
  279. package/ts/src/db/schemaState.ts +91 -0
  280. package/ts/src/db/schemaTsDivergence.ts +114 -0
  281. package/ts/src/descriptor/descriptorRead.ts +49 -0
  282. package/ts/src/docs/docsLint.ts +265 -0
  283. package/ts/src/explorer/handoff.ts +522 -0
  284. package/ts/src/explorer/render.ts +335 -0
  285. package/ts/src/explorer/story.ts +769 -0
  286. package/ts/src/explorer/transition.ts +72 -0
  287. package/ts/src/extensions/bindings.ts +170 -0
  288. package/ts/src/extensions/catalog.ts +249 -0
  289. package/ts/src/extensions/catalogCommands.ts +513 -0
  290. package/ts/src/extensions/catalogWrites.ts +652 -0
  291. package/ts/src/extensions/contextRuntime.ts +325 -0
  292. package/ts/src/extensions/dispatch.ts +374 -0
  293. package/ts/src/extensions/errors.ts +24 -0
  294. package/ts/src/extensions/manifest.ts +356 -0
  295. package/ts/src/extensions/migrations.ts +350 -0
  296. package/ts/src/extraction/conversation.ts +304 -0
  297. package/ts/src/extraction/conversationMetadata.ts +206 -0
  298. package/ts/src/extraction/fencing.ts +106 -0
  299. package/ts/src/extraction/json.ts +17 -0
  300. package/ts/src/extraction/prompts.ts +470 -0
  301. package/ts/src/frontDoor/args.ts +30 -0
  302. package/ts/src/frontDoor/argvShape.ts +106 -0
  303. package/ts/src/frontDoor/buildLoadRuntime.ts +139 -0
  304. package/ts/src/frontDoor/buildRoute.ts +398 -0
  305. package/ts/src/frontDoor/cli.ts +1865 -0
  306. package/ts/src/frontDoor/cloneRoleGuard.ts +98 -0
  307. package/ts/src/frontDoor/consultRoute.ts +50 -0
  308. package/ts/src/frontDoor/contentTailRoute.ts +239 -0
  309. package/ts/src/frontDoor/conversationLoggerRoute.ts +73 -0
  310. package/ts/src/frontDoor/cultivationRoute.ts +210 -0
  311. package/ts/src/frontDoor/dbPath.ts +131 -0
  312. package/ts/src/frontDoor/dbSafetyToolsRoute.ts +240 -0
  313. package/ts/src/frontDoor/exploreRoute.ts +572 -0
  314. package/ts/src/frontDoor/extensionCatalogRoute.ts +252 -0
  315. package/ts/src/frontDoor/frontDoorLog.ts +57 -0
  316. package/ts/src/frontDoor/identityWrite.ts +36 -0
  317. package/ts/src/frontDoor/journeyWriteRoute.ts +26 -0
  318. package/ts/src/frontDoor/lifecycleWriteRoute.ts +110 -0
  319. package/ts/src/frontDoor/liveBackup.ts +100 -0
  320. package/ts/src/frontDoor/mirrorModeRoute.ts +163 -0
  321. package/ts/src/frontDoor/namedRefusal.ts +35 -0
  322. package/ts/src/frontDoor/nodeSupport.ts +24 -0
  323. package/ts/src/frontDoor/render/consolidate.ts +199 -0
  324. package/ts/src/frontDoor/render/conversations.ts +33 -0
  325. package/ts/src/frontDoor/render/cultivationShared.ts +21 -0
  326. package/ts/src/frontDoor/render/descriptor.ts +20 -0
  327. package/ts/src/frontDoor/render/detectPersona.ts +50 -0
  328. package/ts/src/frontDoor/render/icons.ts +13 -0
  329. package/ts/src/frontDoor/render/identity.ts +59 -0
  330. package/ts/src/frontDoor/render/identityRows.ts +17 -0
  331. package/ts/src/frontDoor/render/inspectPersona.ts +53 -0
  332. package/ts/src/frontDoor/render/journeyStatus.ts +78 -0
  333. package/ts/src/frontDoor/render/journeys.ts +79 -0
  334. package/ts/src/frontDoor/render/list.ts +41 -0
  335. package/ts/src/frontDoor/render/memories.ts +67 -0
  336. package/ts/src/frontDoor/render/recall.ts +49 -0
  337. package/ts/src/frontDoor/render/shadow.ts +155 -0
  338. package/ts/src/frontDoor/render/tasks.ts +99 -0
  339. package/ts/src/frontDoor/render/tasksImportSync.ts +63 -0
  340. package/ts/src/frontDoor/render/week.ts +113 -0
  341. package/ts/src/frontDoor/routing.ts +999 -0
  342. package/ts/src/frontDoor/runtimeRoute.ts +623 -0
  343. package/ts/src/frontDoor/searchRoute.ts +166 -0
  344. package/ts/src/frontDoor/seedPaths.ts +98 -0
  345. package/ts/src/frontDoor/soulRoute.ts +433 -0
  346. package/ts/src/frontDoor/tasksImportSyncRoute.ts +110 -0
  347. package/ts/src/frontDoor/tasksWriteRoute.ts +101 -0
  348. package/ts/src/frontDoor/usage.ts +176 -0
  349. package/ts/src/guards/claudePlugin.ts +252 -0
  350. package/ts/src/guards/packContents.ts +306 -0
  351. package/ts/src/guards/piSourcedSkills.ts +70 -0
  352. package/ts/src/guards/retiredRouteShadows.ts +57 -0
  353. package/ts/src/guards/retiredSurfaces.ts +564 -0
  354. package/ts/src/hooks/claude.ts +176 -0
  355. package/ts/src/hooks/codex.ts +45 -0
  356. package/ts/src/hooks/gemini.ts +126 -0
  357. package/ts/src/hooks/main.ts +109 -0
  358. package/ts/src/hooks/mirrorState.ts +71 -0
  359. package/ts/src/hooks/payload.ts +68 -0
  360. package/ts/src/hooks/runtime.ts +159 -0
  361. package/ts/src/identity/applyConsolidationIdentityUpdate.ts +67 -0
  362. package/ts/src/identity/descriptorGenerate.ts +162 -0
  363. package/ts/src/identity/identityEdit.ts +143 -0
  364. package/ts/src/identity/identityKey.ts +77 -0
  365. package/ts/src/identity/identityRead.ts +69 -0
  366. package/ts/src/identity/identityStore.ts +80 -0
  367. package/ts/src/identity/journeyListing.ts +53 -0
  368. package/ts/src/identity/personaInspect.ts +44 -0
  369. package/ts/src/identity/personaListing.ts +37 -0
  370. package/ts/src/identity/setIdentity.ts +64 -0
  371. package/ts/src/index.ts +231 -0
  372. package/ts/src/init/init.ts +111 -0
  373. package/ts/src/journey/journeyOptions.ts +131 -0
  374. package/ts/src/journey/journeyRemoval.ts +158 -0
  375. package/ts/src/journey/journeyStatus.ts +149 -0
  376. package/ts/src/journey/journeySyncFile.ts +87 -0
  377. package/ts/src/journey/journeyWrite.ts +203 -0
  378. package/ts/src/journey/parentJourney.ts +41 -0
  379. package/ts/src/journey/validateParentJourney.ts +55 -0
  380. package/ts/src/mcp/boundary.ts +151 -0
  381. package/ts/src/mcp/guards.ts +244 -0
  382. package/ts/src/mcp/main.ts +121 -0
  383. package/ts/src/mcp/payload.ts +141 -0
  384. package/ts/src/mcp/protocol.ts +141 -0
  385. package/ts/src/mcp/readModels.ts +241 -0
  386. package/ts/src/mcp/registry.ts +201 -0
  387. package/ts/src/mcp/serve.ts +120 -0
  388. package/ts/src/mcp/tools/deterministic.ts +137 -0
  389. package/ts/src/mcp/tools/providerCrossing.ts +187 -0
  390. package/ts/src/mcp/wire.ts +8 -0
  391. package/ts/src/memory/journal.ts +180 -0
  392. package/ts/src/memory/listing.ts +107 -0
  393. package/ts/src/memory/memoryWrite.ts +88 -0
  394. package/ts/src/memory/reinforcement.ts +35 -0
  395. package/ts/src/mirror/context.ts +161 -0
  396. package/ts/src/mirror/defaultResolution.ts +199 -0
  397. package/ts/src/mirror/orchestration.ts +364 -0
  398. package/ts/src/mirror/reception.ts +194 -0
  399. package/ts/src/mirror/render.ts +75 -0
  400. package/ts/src/mirror/runtimeSession.ts +205 -0
  401. package/ts/src/mode/operatingMode.ts +148 -0
  402. package/ts/src/observability/callOutcome.ts +115 -0
  403. package/ts/src/observability/inspectLedger.ts +329 -0
  404. package/ts/src/observability/ledgerHooks.ts +126 -0
  405. package/ts/src/observability/llmCalls.ts +154 -0
  406. package/ts/src/persona/detectPersona.ts +81 -0
  407. package/ts/src/planning/promptAssembly.ts +111 -0
  408. package/ts/src/planning/weekPending.ts +81 -0
  409. package/ts/src/planning/weekPlan.ts +183 -0
  410. package/ts/src/planning/weekSave.ts +117 -0
  411. package/ts/src/providers/config.ts +189 -0
  412. package/ts/src/providers/cost.ts +64 -0
  413. package/ts/src/providers/credits.ts +204 -0
  414. package/ts/src/providers/embedding.ts +321 -0
  415. package/ts/src/providers/familyProviders.ts +147 -0
  416. package/ts/src/providers/llm.ts +334 -0
  417. package/ts/src/providers/openrouter.ts +244 -0
  418. package/ts/src/providers/redaction.ts +110 -0
  419. package/ts/src/providers/replay.ts +15 -0
  420. package/ts/src/providers/transport.ts +410 -0
  421. package/ts/src/repair/encodingRepair.ts +253 -0
  422. package/ts/src/runtime/backup.ts +151 -0
  423. package/ts/src/runtime/channel.ts +146 -0
  424. package/ts/src/runtime/config.ts +168 -0
  425. package/ts/src/runtime/diagnose.ts +686 -0
  426. package/ts/src/runtime/git.ts +510 -0
  427. package/ts/src/runtime/installKind.ts +220 -0
  428. package/ts/src/runtime/migrate.ts +154 -0
  429. package/ts/src/runtime/packageIdentity.ts +102 -0
  430. package/ts/src/runtime/releaseNotes.ts +244 -0
  431. package/ts/src/runtime/status.ts +557 -0
  432. package/ts/src/runtime/strategies/clone.ts +200 -0
  433. package/ts/src/runtime/strategies/package.ts +328 -0
  434. package/ts/src/runtime/treeRoot.ts +30 -0
  435. package/ts/src/runtime/update.ts +445 -0
  436. package/ts/src/runtime/updateGate.ts +40 -0
  437. package/ts/src/runtime/updatePipeline.ts +159 -0
  438. package/ts/src/runtime/version.ts +36 -0
  439. package/ts/src/runtime/wiring.ts +130 -0
  440. package/ts/src/search/memorySearch.ts +338 -0
  441. package/ts/src/search/ranker.ts +154 -0
  442. package/ts/src/seed/seed.ts +256 -0
  443. package/ts/src/seed/seedYaml.ts +133 -0
  444. package/ts/src/soul/apply.ts +218 -0
  445. package/ts/src/soul/harvest.ts +267 -0
  446. package/ts/src/soul/prompts/soul_beauty_voice.md +103 -0
  447. package/ts/src/soul/prompts/soul_self_voice.md +219 -0
  448. package/ts/src/soul/prompts/soul_wisdom_voice.md +121 -0
  449. package/ts/src/soul/prompts.ts +85 -0
  450. package/ts/src/soul/render.ts +358 -0
  451. package/ts/src/soul/state.ts +212 -0
  452. package/ts/src/soul/transition.ts +37 -0
  453. package/ts/src/tasks/journeyPathParse.ts +113 -0
  454. package/ts/src/tasks/taskImportSync.ts +142 -0
  455. package/ts/src/tasks/taskStore.ts +312 -0
  456. package/ts/src/tasks/weekView.ts +120 -0
  457. package/ts/src/util/clipCodePoints.ts +26 -0
  458. package/ts/src/util/paths.ts +63 -0
  459. package/ts/src/util/program.ts +9 -0
  460. package/ts/src/util/pyGenerators.ts +144 -0
  461. package/ts/src/util/pythonText.ts +317 -0
  462. package/ts/src/util/semver.ts +45 -0
  463. package/ts/src/util/shellWord.ts +25 -0
  464. package/ts/src/util/slug.ts +64 -0
  465. package/ts/src/welcome/card.ts +339 -0
  466. package/ts/src/welcome/statusLine.ts +101 -0
  467. package/ts/src/welcome/updateCache.ts +129 -0
@@ -0,0 +1,339 @@
1
+ // CV22.DS7.US8 — the Navigator flow unit.
2
+ //
3
+ // Port of `src/memory/builder/flow_unit.py`. Plateau 3 took the read side, because
4
+ // Plan needs the EFFECTIVE flow unit before it can record story authority (bounded
5
+ // story authority exists only under `story_by_story`). Plateau 5 completes it: the
6
+ // write side was re-sequenced out of Scope F by the panel, since the DS smoke opens
7
+ // with `set-flow-unit` and seeding the flow unit by a raw cursor write instead
8
+ // would be the unrecorded mutation plateau 3a ruled out.
9
+ //
10
+ // The selection surface is CHOSEN by the unit, not fixed: `delivery_story` renders
11
+ // DELIVERY_STORY_SCOPE_CONFIRMATION over the child work packages, `story_by_story`
12
+ // renders NEXT_STORY_CONFIRMATION over the first child as the recommended story.
13
+ // One function, two surface ids — a port that hard-codes either one fails the
14
+ // corpus guard that compares each recorded id against its own wrapped marker.
15
+ //
16
+ // CR105: choosing also RECORDS the question its surface asks, as the cursor's
17
+ // checkpoint and pending confirmation, and only at a Delivery Story's flow
18
+ // decision: after Prepare or Expand, before its Plan. Until then, Expand's
19
+ // story-by-story stop survived a choice of Delivery Story flow, and every surface
20
+ // that reads the cursor reported a question that flow never asks.
21
+
22
+ import type { WritableDatabase } from "#db/database.ts";
23
+ import { pyStrip } from "#util/pythonText.ts";
24
+ import { hasDeliveryStoryPlan } from "./aggregateStatus.ts";
25
+ import { cardPrefixed, cardText, cardWrapped } from "./card.ts";
26
+ import { deliveryStoryCodeForItem } from "./cursorTransitions.ts";
27
+ import {
28
+ type BuilderDeliveryCursor,
29
+ type CursorWriteDeps,
30
+ getDeliveryCursor,
31
+ setDeliveryCursor,
32
+ } from "./deliveryCursor.ts";
33
+ import { wrapAriadSurface } from "./surfaceProtocol.ts";
34
+
35
+ export const FLOW_UNIT_STORY_BY_STORY = "story_by_story";
36
+ export const FLOW_UNIT_DELIVERY_STORY = "delivery_story";
37
+ export const ALLOWED_FLOW_UNITS = [FLOW_UNIT_STORY_BY_STORY, FLOW_UNIT_DELIVERY_STORY] as const;
38
+
39
+ /** A Navigator stop as the cursor records it: the checkpoint, and what the Navigator owes. */
40
+ export interface FlowStop {
41
+ readonly checkpoint: string;
42
+ readonly confirmation: string;
43
+ }
44
+
45
+ /**
46
+ * CR105: the question each flow unit's surface asks, as the cursor records it. The
47
+ * checkpoint is the surface's own id. Expand records the story-by-story stop, since
48
+ * its next-story question is the default flow's; choosing a flow unit records its
49
+ * own. The Delivery Story Plan replaces the scope stop, and nothing enforces it:
50
+ * CR001 declined a runtime-enforced scope stop, and this is recorded, not enforced.
51
+ */
52
+ export const FLOW_STOPS: Readonly<Record<(typeof ALLOWED_FLOW_UNITS)[number], FlowStop>> = {
53
+ story_by_story: {
54
+ checkpoint: "next_story_confirmation",
55
+ confirmation: "navigator_story_confirmation",
56
+ },
57
+ delivery_story: {
58
+ checkpoint: "delivery_story_scope_confirmation",
59
+ confirmation: "navigator_scope_confirmation",
60
+ },
61
+ };
62
+
63
+ const FLOW_CONFIRMATIONS: ReadonlySet<string> = new Set(
64
+ Object.values(FLOW_STOPS).map((stop) => stop.confirmation),
65
+ );
66
+
67
+ /**
68
+ * CR105: why a flow unit cannot be chosen on this cursor, or null at a Delivery
69
+ * Story's flow decision: after Prepare or Expand, before its Plan. The active item is
70
+ * a Delivery Story, its Plan is not recorded, and nothing is pending but a flow stop,
71
+ * or nothing at all. Anywhere else the choice would print a question the cursor is not
72
+ * at, and after a Delivery Story Plan it stranded the Delivery Story: approval started
73
+ * its implementation under story-by-story flow, and its closure then refused.
74
+ *
75
+ * The sentence leads with the consequence, for the agent reading it.
76
+ */
77
+ export function flowDecisionRefusal(cursor: BuilderDeliveryCursor): string | null {
78
+ const refused = "no flow unit was chosen";
79
+ const item = cursor.activeItem;
80
+ if (!item) {
81
+ return `${refused}: no item has been pulled yet, and a flow unit is chosen for an active Delivery Story.`;
82
+ }
83
+ if (cursor.activeItemLevel !== "delivery_story") {
84
+ const level = cursor.activeItemLevel
85
+ ? `is a ${cursor.activeItemLevel.replaceAll("_", " ")}`
86
+ : "is not a Delivery Story";
87
+ const deliveryStory = deliveryStoryCodeForItem(item);
88
+ const whose = deliveryStory ? `its Delivery Story, ${deliveryStory},` : "its Delivery Story";
89
+ return `${refused}: the active item, ${item}, ${level}. The flow unit is chosen for ${whose} before that Delivery Story's Plan.`;
90
+ }
91
+ if (hasDeliveryStoryPlan(cursor.aggregateCheckpointStatus)) {
92
+ return `${refused}: ${item}'s Delivery Story Plan is already recorded, and the flow unit is chosen before it.`;
93
+ }
94
+ const pending = cursor.pendingConfirmation;
95
+ if (pending !== null && !FLOW_CONFIRMATIONS.has(pending)) {
96
+ return `${refused}: ${item} is waiting for ${pending}, and the flow unit is chosen before its Plan.`;
97
+ }
98
+ return null;
99
+ }
100
+
101
+ /**
102
+ * Python `effective_navigator_flow_unit`.
103
+ *
104
+ * An unset or UNRECOGNIZED value falls back to `story_by_story` with source
105
+ * `default`, rather than raising — so a cursor written by a newer engine, or one
106
+ * carrying a typo, still yields a usable flow unit instead of blocking the
107
+ * lifecycle. The source is returned because the Navigator-facing surfaces
108
+ * distinguish "you chose this" from "this is the default".
109
+ */
110
+ export function effectiveNavigatorFlowUnit(cursor: BuilderDeliveryCursor): {
111
+ flowUnit: string;
112
+ source: string;
113
+ } {
114
+ const current = cursor.navigatorFlowUnit;
115
+ if (current !== null && (ALLOWED_FLOW_UNITS as readonly string[]).includes(current)) {
116
+ return { flowUnit: current, source: "cursor" };
117
+ }
118
+ return { flowUnit: FLOW_UNIT_STORY_BY_STORY, source: "default" };
119
+ }
120
+
121
+ export interface NavigatorFlowUnitReport {
122
+ readonly journey: string;
123
+ readonly method: string;
124
+ readonly activeItem: string | null;
125
+ readonly activeItemTitle: string | null;
126
+ readonly activeItemLevel: string | null;
127
+ readonly flowUnit: string;
128
+ readonly source: string;
129
+ readonly cursor: BuilderDeliveryCursor;
130
+ }
131
+
132
+ /**
133
+ * Python `set_navigator_flow_unit`.
134
+ *
135
+ * Validation BEFORE the cursor read, so an unknown unit reports the allowed values
136
+ * even when no cursor exists. The choice is made only at the Delivery Story's flow
137
+ * decision, and anywhere else it refuses before writing (`flowDecisionRefusal`). It
138
+ * is not a lifecycle transition: it writes the unit, `last_delivery_event`, and the
139
+ * stop its surface asks (CR105). Everything else on the cursor carries forward.
140
+ */
141
+ export function setNavigatorFlowUnit(
142
+ db: WritableDatabase,
143
+ options: { journey: string; method: string; flowUnit: string },
144
+ deps: CursorWriteDeps,
145
+ ): NavigatorFlowUnitReport {
146
+ if (!(ALLOWED_FLOW_UNITS as readonly string[]).includes(options.flowUnit)) {
147
+ throw new Error(`navigator flow unit must be one of: ${ALLOWED_FLOW_UNITS.join(", ")}`);
148
+ }
149
+ const existing = getDeliveryCursor(db, options.journey);
150
+ if (existing === null) {
151
+ throw new Error("delivery cursor is required before choosing navigator flow unit");
152
+ }
153
+ const refusal = flowDecisionRefusal(existing);
154
+ if (refusal !== null) throw new Error(refusal);
155
+ const stop = FLOW_STOPS[options.flowUnit as (typeof ALLOWED_FLOW_UNITS)[number]];
156
+ const updated = setDeliveryCursor(
157
+ db,
158
+ {
159
+ journey: options.journey,
160
+ method: options.method,
161
+ activeItem: existing.activeItem,
162
+ activeItemTitle: existing.activeItemTitle,
163
+ activeItemLevel: existing.activeItemLevel,
164
+ activeCheckpoint: stop.checkpoint,
165
+ pendingConfirmation: stop.confirmation,
166
+ lastDeliveryEvent: "navigator_flow_unit_selected",
167
+ cadenceProfile: existing.cadenceProfile,
168
+ cadenceLimits: existing.cadenceLimits,
169
+ granularityDecision: existing.granularityDecision,
170
+ navigatorFlowUnit: options.flowUnit,
171
+ childWorkItems: existing.childWorkItems,
172
+ aggregateCheckpointStatus: existing.aggregateCheckpointStatus,
173
+ },
174
+ deps,
175
+ );
176
+ return {
177
+ journey: options.journey,
178
+ method: options.method,
179
+ activeItem: updated.activeItem,
180
+ activeItemTitle: updated.activeItemTitle,
181
+ activeItemLevel: updated.activeItemLevel,
182
+ flowUnit: options.flowUnit,
183
+ source: "cursor",
184
+ cursor: updated,
185
+ };
186
+ }
187
+
188
+ /** Python `inspect_navigator_flow_unit`. */
189
+ export function inspectNavigatorFlowUnit(
190
+ db: WritableDatabase,
191
+ options: { journey: string; method: string },
192
+ ): NavigatorFlowUnitReport {
193
+ const cursor = getDeliveryCursor(db, options.journey);
194
+ if (cursor === null) {
195
+ throw new Error("delivery cursor is required before inspecting navigator flow unit");
196
+ }
197
+ const { flowUnit, source } = effectiveNavigatorFlowUnit(cursor);
198
+ return {
199
+ journey: options.journey,
200
+ method: options.method,
201
+ activeItem: cursor.activeItem,
202
+ activeItemTitle: cursor.activeItemTitle,
203
+ activeItemLevel: cursor.activeItemLevel,
204
+ flowUnit,
205
+ source,
206
+ cursor,
207
+ };
208
+ }
209
+
210
+ /** Python `_active_delivery`. */
211
+ function activeDelivery(report: NavigatorFlowUnitReport): string {
212
+ if (report.activeItem === null) return "none";
213
+ const title = report.activeItemTitle ? ` — ${report.activeItemTitle}` : "";
214
+ return `🟦[${report.activeItem}]${title}`;
215
+ }
216
+
217
+ /** Python `_scope_item_lines`: an EMPTY list renders nothing, not `none`. */
218
+ function scopeItemLines(label: string, items: readonly string[]): string[] {
219
+ if (items.length === 0) return [];
220
+ return [
221
+ "│ │",
222
+ cardText(label),
223
+ ...cardPrefixed(items, "-"),
224
+ ];
225
+ }
226
+
227
+ /**
228
+ * Python `_delivery_story_scope_hypothesis`.
229
+ *
230
+ * The checkout/address special case is product copy, not a heuristic worth
231
+ * generalizing: it is reproduced verbatim because the surface is graded byte for
232
+ * byte.
233
+ */
234
+ function deliveryStoryScopeHypothesis(report: NavigatorFlowUnitReport): string {
235
+ const title = pyStrip(report.activeItemTitle ?? "");
236
+ const normalized = title.toLowerCase();
237
+ if (normalized.includes("checkout") && normalized.includes("address")) {
238
+ return (
239
+ "This Delivery Story should let the customer enter checkout, provide or confirm " +
240
+ "a delivery address, and leave the order ready for the next checkout step."
241
+ );
242
+ }
243
+ if (title) return `This Delivery Story should deliver the scope implied by: ${title}.`;
244
+ return (
245
+ "I will infer a complete Delivery Story plan from the roadmap and project context; " +
246
+ "correct or add any scope details before I proceed."
247
+ );
248
+ }
249
+
250
+ /** Python `render_flow_unit_scope_confirmation_report`. */
251
+ export function renderFlowUnitScopeConfirmationReport(report: NavigatorFlowUnitReport): string {
252
+ const deliveryStory = report.flowUnit === FLOW_UNIT_DELIVERY_STORY;
253
+ const surfaceName = deliveryStory
254
+ ? "delivery_story_scope_confirmation"
255
+ : "next_story_confirmation";
256
+ const title = deliveryStory
257
+ ? " 🧭 DELIVERY STORY SCOPE CONFIRMATION"
258
+ : " 🧭 NEXT STORY CONFIRMATION";
259
+ const understanding = deliveryStory
260
+ ? deliveryStoryScopeHypothesis(report)
261
+ : "We will continue story by story. The next step is to confirm which child story " +
262
+ "becomes the next Navigator-facing lifecycle unit.";
263
+ const scopeLabel = deliveryStory ? "Work packages in scope" : "Recommended story";
264
+ const scopeItems = deliveryStory
265
+ ? report.cursor.childWorkItems
266
+ : report.cursor.childWorkItems.slice(0, 1);
267
+ const prompt = deliveryStory
268
+ ? "Before I create the DS Plan, correct or add anything:"
269
+ : "Before I create the Story Plan, correct or add anything:";
270
+ const question = deliveryStory
271
+ ? "1. Is this the right scope?"
272
+ : "1. Is this the right next story?";
273
+ const body = [
274
+ "Delivery",
275
+ "",
276
+ "╭────────────────────────────────────────────────────────╮",
277
+ cardText(title),
278
+ "│ │",
279
+ cardText("My understanding"),
280
+ ...cardWrapped(understanding),
281
+ "│ │",
282
+ cardText("Active delivery"),
283
+ ...cardWrapped(activeDelivery(report)),
284
+ ...scopeItemLines(scopeLabel, scopeItems),
285
+ "│ │",
286
+ ...cardWrapped(prompt),
287
+ ...cardWrapped(question),
288
+ "│ │",
289
+ ...cardWrapped("Choose the next move when ready."),
290
+ "╰────────────────────────────────────────────────────────╯",
291
+ ];
292
+ return wrapAriadSurface(surfaceName, `${body.join("\n")}\n`);
293
+ }
294
+
295
+ /** Python `_flow_unit_change_summary` / `_description` / `_next_movement`. */
296
+ function flowUnitChangeSummary(flowUnit: string): string {
297
+ return flowUnit === FLOW_UNIT_DELIVERY_STORY
298
+ ? "Navigator-facing lifecycle will continue at Delivery Story level."
299
+ : "Navigator-facing lifecycle will continue story by story.";
300
+ }
301
+
302
+ function flowUnitDescription(flowUnit: string): string {
303
+ return flowUnit === FLOW_UNIT_DELIVERY_STORY
304
+ ? "the Delivery Story becomes the lifecycle unit; child stories remain traceable work packages"
305
+ : "child stories get their own Navigator checkpoints";
306
+ }
307
+
308
+ function flowUnitNextMovement(flowUnit: string): string {
309
+ return flowUnit === FLOW_UNIT_DELIVERY_STORY
310
+ ? "Plan the Delivery Story as the Navigator-facing unit."
311
+ : "Confirm the recommended child story, then Plan.";
312
+ }
313
+
314
+ /** Python `render_navigator_flow_unit_report`: the READ face. */
315
+ export function renderNavigatorFlowUnitReport(report: NavigatorFlowUnitReport): string {
316
+ const body = [
317
+ "Delivery",
318
+ "",
319
+ "╭────────────────────────────────────────────────────────╮",
320
+ "│ 🧭 FLOW UNIT SELECTED │",
321
+ "│ │",
322
+ cardText("What changed?"),
323
+ ...cardWrapped(flowUnitChangeSummary(report.flowUnit)),
324
+ "│ │",
325
+ cardText("Active delivery"),
326
+ ...cardWrapped(activeDelivery(report)),
327
+ "│ │",
328
+ cardText("Selected flow unit"),
329
+ cardText(report.flowUnit),
330
+ ...cardWrapped(flowUnitDescription(report.flowUnit)),
331
+ "│ │",
332
+ cardText("Next movement"),
333
+ ...cardWrapped(flowUnitNextMovement(report.flowUnit)),
334
+ "│ │",
335
+ ...cardWrapped("Choose the next move when ready."),
336
+ "╰────────────────────────────────────────────────────────╯",
337
+ ];
338
+ return wrapAriadSurface("navigator_flow_unit", `${body.join("\n")}\n`);
339
+ }
@@ -0,0 +1,122 @@
1
+ // CV22.DS7.US8 plateau 1 — the Builder Orientation surface.
2
+ //
3
+ // Port of `render_builder_orientation_surface` in
4
+ // `src/memory/builder/home_surface.py`. This is what `build load` shows an Ariad
5
+ // journey with no active item, and it is almost entirely branches — which is what
6
+ // a port collapses. Three of them are worth naming because each is a silent
7
+ // behavior change if merged:
8
+ //
9
+ // * `_available_refinement_moves` RETURNS EARLY for a canonical index, so the
10
+ // Workbench-storage move below it is unreachable in that state. An
11
+ // `if/elif` chain written without the early return appends it.
12
+ // * `_refinement_orientation_lines` has two shapes since CV22.DS10.TS4: a
13
+ // canonical index, and none.
14
+ // * It renders only without an active item, so since CR002 it takes the raw
15
+ // project-wide report, never a scope. Python placed the journey in the CV of
16
+ // a project-wide recommendation, synthesizing `🟪[CV99] roadmap focus` when
17
+ // that CV was absent from the snapshot. Now the journey is told no item was
18
+ // pulled, the list is labelled project-wide, and the first move is the
19
+ // literal Pull command. Its scoped branches were unreachable and went in
20
+ // CR002's handoff review.
21
+ //
22
+ // `render_builder_home_surface` was ported and never called: `build load`
23
+ // renders `PROJECT_POSITION` and this surface. CR002 deleted it rather than
24
+ // scope a surface no journey could see, whose one distinctive line was a
25
+ // project-wide "recommended pull".
26
+ //
27
+ // CR115: it asks how the next item will run, and answers with the journey's cadence,
28
+ // which shapes the next Plan; `build load` passes the cursor's, so every caller decides.
29
+
30
+ import { type CadenceView, cadenceOrientationLines } from "./cadence.ts";
31
+ import { cardPrefixed, cardText, cardWrapped } from "./card.ts";
32
+ import type { PullCandidatesReport } from "./pullCandidates.ts";
33
+ import { CANONICAL_REFINEMENT_INDEX, type RefinementFieldSnapshot } from "./refinementField.ts";
34
+ import { NO_ITEM_PULLED_YET, PROJECT_WIDE_CANDIDATES, pullExplicitly } from "./scopePhrases.ts";
35
+ import { wrapAriadSurface } from "./surfaceProtocol.ts";
36
+
37
+ const FRAME_TOP = "╭────────────────────────────────────────────────────────╮";
38
+ const FRAME_BOTTOM = "╰────────────────────────────────────────────────────────╯";
39
+ const FRAME_BLANK = "│ │";
40
+
41
+ /**
42
+ * Python `_pull_candidate_lines`, project-wide. Python marked its project-wide
43
+ * recommendation with `▸`; without a journey scope there is none, so every
44
+ * candidate is a `·`.
45
+ */
46
+ function pullCandidateLines(report: PullCandidatesReport): string[] {
47
+ const lines = [cardText(PROJECT_WIDE_CANDIDATES)];
48
+ if (report.candidates.length === 0) lines.push(cardText("none"));
49
+ for (const candidate of report.candidates) {
50
+ lines.push(...cardWrapped(`· ${candidate.code} ${candidate.title}`));
51
+ }
52
+ return lines;
53
+ }
54
+
55
+ /** Python `_refinement_orientation_lines`. Two shapes since CV22.DS10.TS4. */
56
+ function refinementOrientationLines(refinement: RefinementFieldSnapshot): string[] {
57
+ if (refinement.canonicalIndex) {
58
+ return [
59
+ cardText("authority: project files"),
60
+ ...cardWrapped(`index: ${refinement.canonicalIndex}`),
61
+ ];
62
+ }
63
+ return [
64
+ cardText("authority: project files (not started)"),
65
+ ...cardWrapped(`create: ${CANONICAL_REFINEMENT_INDEX}`),
66
+ ];
67
+ }
68
+
69
+ /**
70
+ * Python `_available_refinement_moves`. The canonical-index path returns after
71
+ * three moves; the legacy path always appends a fourth. The first move is the
72
+ * literal Pull command: the surface renders only when no item has been pulled.
73
+ */
74
+ export function availableRefinementMoves(
75
+ refinement: RefinementFieldSnapshot,
76
+ journey: string,
77
+ ): string[] {
78
+ const moves = [pullExplicitly(journey), "inspect roadmap"];
79
+ if (refinement.canonicalIndex) {
80
+ moves.push("inspect canonical Refinement index");
81
+ return moves;
82
+ }
83
+ moves.push(`create ${CANONICAL_REFINEMENT_INDEX}`);
84
+ return moves;
85
+ }
86
+
87
+ /**
88
+ * Python `render_builder_orientation_surface`, for a journey with no active item:
89
+ * `build load`'s only caller. `candidates` is the raw project-wide scan.
90
+ */
91
+ export function renderBuilderOrientationSurface(options: {
92
+ candidates: PullCandidatesReport;
93
+ refinement: RefinementFieldSnapshot;
94
+ cadence: CadenceView;
95
+ }): string {
96
+ const { candidates, refinement, cadence } = options;
97
+ const lines: string[] = [
98
+ "Builder Orientation",
99
+ "",
100
+ FRAME_TOP,
101
+ "│ ■ BUILDER ORIENTATION │",
102
+ FRAME_BLANK,
103
+ cardText("Where are we in the roadmap?"),
104
+ cardText(NO_ITEM_PULLED_YET),
105
+ FRAME_BLANK,
106
+ cardText("What can be pulled next?"),
107
+ ...pullCandidateLines(candidates),
108
+ FRAME_BLANK,
109
+ cardText("What is open for refinement?"),
110
+ ...refinementOrientationLines(refinement),
111
+ FRAME_BLANK,
112
+ cardText("How will the next item run?"),
113
+ ...cadenceOrientationLines(cadence),
114
+ FRAME_BLANK,
115
+ cardText("What can we do now?"),
116
+ ...cardPrefixed(availableRefinementMoves(refinement, candidates.journey), "-"),
117
+ FRAME_BLANK,
118
+ ...cardWrapped("Choose a move when ready."),
119
+ FRAME_BOTTOM,
120
+ ];
121
+ return wrapAriadSurface("builder_orientation", `${lines.join("\n")}\n`);
122
+ }
@@ -0,0 +1,125 @@
1
+ // CV22.DS7.US8 plateau 2 — the implementation guard.
2
+ //
3
+ // Port of `assert_implementation_allowed`,
4
+ // `render_implementation_guard_allowed`, and
5
+ // `render_implementation_guard_blocked` from `src/memory/builder/lifecycle.py`.
6
+ // This is the leaf `build check-implementation` answers, and the reason it moved
7
+ // out of plateau 1: it reads the delivery cursor.
8
+ //
9
+ // It is not a boolean. Four outcomes, and the order of the checks decides which
10
+ // message a Navigator sees:
11
+ //
12
+ // 1. no cursor at all -> requires a delivery cursor
13
+ // 2. ANY pending confirmation -> blocked on that confirmation,
14
+ // even when the Plan is approved, because an unanswered checkpoint outranks
15
+ // an approval
16
+ // 3. `last_delivery_event == "plan_approved"` -> allowed
17
+ // 4. the Delivery Story combination -> allowed, but only with ALL FOUR
18
+ // conditions: event `delivery_story_plan_approved`, level `delivery_story`,
19
+ // flow unit `delivery_story`, and `plan:approved` present in the aggregate
20
+ // checkpoint status. Miss any one and the generic refusal is what prints.
21
+ //
22
+ // Note what is NOT required: an active item. A cursor whose event is
23
+ // `plan_approved` with no active item is ALLOWED, and the surface renders
24
+ // `active item / none`. That reads like an oversight and is Python's behavior.
25
+
26
+ import type { Database } from "#db/database.ts";
27
+ import { cardText, cardWrapped } from "./card.ts";
28
+ import type { BuilderDeliveryCursor } from "./deliveryCursor.ts";
29
+ import { getDeliveryCursor } from "./deliveryCursor.ts";
30
+ import { renderLifecycleRibbon } from "./lifecycleRibbon.ts";
31
+ import { wrapAriadSurface } from "./surfaceProtocol.ts";
32
+
33
+ const FRAME_TOP = "╭────────────────────────────────────────────────────────╮";
34
+ const FRAME_BOTTOM = "╰────────────────────────────────────────────────────────╯";
35
+ const FRAME_BLANK = "│ │";
36
+ const GUARD_TITLE = "│ 🟧■ IMPLEMENTATION GUARD │";
37
+
38
+ /** Python's `PermissionError` from the guard. */
39
+ export class ImplementationBlockedError extends Error {
40
+ constructor(message: string) {
41
+ super(message);
42
+ this.name = "ImplementationBlockedError";
43
+ }
44
+ }
45
+
46
+ /** Python `_has_approved_delivery_story_plan`: all four conditions. */
47
+ export function hasApprovedDeliveryStoryPlan(cursor: BuilderDeliveryCursor): boolean {
48
+ return (
49
+ cursor.lastDeliveryEvent === "delivery_story_plan_approved" &&
50
+ cursor.activeItemLevel === "delivery_story" &&
51
+ cursor.navigatorFlowUnit === "delivery_story" &&
52
+ cursor.aggregateCheckpointStatus.includes("plan:approved")
53
+ );
54
+ }
55
+
56
+ /** Python `assert_implementation_allowed`. */
57
+ export function assertImplementationAllowed(db: Database, journey: string): BuilderDeliveryCursor {
58
+ const normalized = typeof journey === "string" ? journey.trim() : "";
59
+ if (!normalized) throw new Error("journey must not be empty");
60
+ const cursor = getDeliveryCursor(db, normalized);
61
+ if (cursor === null) {
62
+ throw new ImplementationBlockedError("Implementation requires a Builder delivery cursor");
63
+ }
64
+ if (cursor.pendingConfirmation) {
65
+ throw new ImplementationBlockedError(
66
+ `Implementation is blocked: pending confirmation ${cursor.pendingConfirmation}.`,
67
+ );
68
+ }
69
+ if (cursor.lastDeliveryEvent === "plan_approved") return cursor;
70
+ if (hasApprovedDeliveryStoryPlan(cursor)) return cursor;
71
+ throw new ImplementationBlockedError(
72
+ "Implementation is blocked: approved Plan is required before Implement.",
73
+ );
74
+ }
75
+
76
+ /** Python `render_implementation_guard_allowed`. */
77
+ export function renderImplementationGuardAllowed(cursor: BuilderDeliveryCursor): string {
78
+ const body = [
79
+ "Delivery",
80
+ renderLifecycleRibbon("implement", cursor.activeItemLevel),
81
+ "",
82
+ FRAME_TOP,
83
+ GUARD_TITLE,
84
+ FRAME_BLANK,
85
+ cardText("status"),
86
+ cardText("allowed"),
87
+ FRAME_BLANK,
88
+ cardText("active item"),
89
+ cardText(cursor.activeItem || "none"),
90
+ FRAME_BLANK,
91
+ cardText("last delivery event"),
92
+ cardText(cursor.lastDeliveryEvent || "none"),
93
+ FRAME_BLANK,
94
+ cardText("boundary"),
95
+ ...cardWrapped("Implementation may begin under the approved Plan contract."),
96
+ FRAME_BOTTOM,
97
+ ].join("\n");
98
+ return wrapAriadSurface("implementation_guard", `${body}\n`);
99
+ }
100
+
101
+ /**
102
+ * Python `render_implementation_guard_blocked`. The level is the cursor's, when there
103
+ * is one: the refusal carries only its reason, and a story's ribbon must still say
104
+ * Expand never applied (CR113).
105
+ */
106
+ export function renderImplementationGuardBlocked(reason: string, level: string | null): string {
107
+ const body = [
108
+ "Delivery",
109
+ renderLifecycleRibbon("implement", level),
110
+ "",
111
+ FRAME_TOP,
112
+ GUARD_TITLE,
113
+ FRAME_BLANK,
114
+ cardText("status"),
115
+ cardText("blocked"),
116
+ FRAME_BLANK,
117
+ cardText("missing checkpoint"),
118
+ ...cardWrapped(reason),
119
+ FRAME_BLANK,
120
+ cardText("boundary"),
121
+ ...cardWrapped("No implementation files may be mutated until the guard allows Implement."),
122
+ FRAME_BOTTOM,
123
+ ].join("\n");
124
+ return wrapAriadSurface("implementation_guard", `${body}\n`);
125
+ }
@@ -0,0 +1,11 @@
1
+ // Lazy Builder boundary for the front door (CV22.DS7.US8 plateau 8).
2
+ //
3
+ // `frontDoor/cli.ts` imports this module only when a `build` command is routed.
4
+ // Keeping the whole Builder command tree behind one module is what keeps every
5
+ // other command working when this one cannot load.
6
+
7
+ export {
8
+ invokeBuilderArgv,
9
+ invokeReadOnlyBuilderArgv,
10
+ READ_ONLY_BUILDER_SUBCOMMANDS,
11
+ } from "./argv.ts";