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.
- package/.claude/hooks/log-assistant-reply.sh +85 -0
- package/.claude/hooks/log-session-end.sh +85 -0
- package/.claude/hooks/log-user-prompt.sh +85 -0
- package/.claude/hooks/mirror-inject.sh +85 -0
- package/.claude/hooks/session-start.sh +85 -0
- package/.gemini/hooks/log-assistant.sh +85 -0
- package/.gemini/hooks/log-user.sh +85 -0
- package/.gemini/hooks/session-end.sh +85 -0
- package/.gemini/hooks/session-start.sh +85 -0
- package/.pi/extensions/mirror-logger.ts +646 -0
- package/.pi/skills/mm-backup/SKILL.md +21 -0
- package/.pi/skills/mm-build/SKILL.md +1206 -0
- package/.pi/skills/mm-consolidate/SKILL.md +112 -0
- package/.pi/skills/mm-consult/SKILL.md +70 -0
- package/.pi/skills/mm-conversations/SKILL.md +16 -0
- package/.pi/skills/mm-discard/SKILL.md +39 -0
- package/.pi/skills/mm-explore/SKILL.md +255 -0
- package/.pi/skills/mm-help/SKILL.md +74 -0
- package/.pi/skills/mm-identity/SKILL.md +96 -0
- package/.pi/skills/mm-journal/SKILL.md +16 -0
- package/.pi/skills/mm-journey/SKILL.md +23 -0
- package/.pi/skills/mm-journeys/SKILL.md +15 -0
- package/.pi/skills/mm-memories/SKILL.md +17 -0
- package/.pi/skills/mm-mirror/SKILL.md +98 -0
- package/.pi/skills/mm-mute/SKILL.md +18 -0
- package/.pi/skills/mm-new/SKILL.md +18 -0
- package/.pi/skills/mm-recall/SKILL.md +17 -0
- package/.pi/skills/mm-release-notes/SKILL.md +52 -0
- package/.pi/skills/mm-seed/SKILL.md +19 -0
- package/.pi/skills/mm-shadow/SKILL.md +117 -0
- package/.pi/skills/mm-soul/SKILL.md +502 -0
- package/.pi/skills/mm-tasks/SKILL.md +24 -0
- package/.pi/skills/mm-update/SKILL.md +32 -0
- package/.pi/skills/mm-week/SKILL.md +28 -0
- package/.pi/skills/mm-welcome/SKILL.md +24 -0
- package/AGENTS.md +188 -0
- package/README.md +126 -9
- package/bin/loader.js +67 -0
- package/bin/mirror-hook.js +7 -0
- package/bin/mirror.js +7 -0
- package/docs/releases/index.md +100 -0
- package/docs/releases/pending-cutoffs.md +510 -0
- package/docs/releases/v0.10.0.md +123 -0
- package/docs/releases/v0.10.1.md +66 -0
- package/docs/releases/v0.10.10.md +51 -0
- package/docs/releases/v0.10.11.md +39 -0
- package/docs/releases/v0.10.12.md +57 -0
- package/docs/releases/v0.10.13.md +35 -0
- package/docs/releases/v0.10.14.md +42 -0
- package/docs/releases/v0.10.15.md +53 -0
- package/docs/releases/v0.10.16.md +35 -0
- package/docs/releases/v0.10.17.md +43 -0
- package/docs/releases/v0.10.2.md +64 -0
- package/docs/releases/v0.10.3.md +78 -0
- package/docs/releases/v0.10.4.md +42 -0
- package/docs/releases/v0.10.5.md +57 -0
- package/docs/releases/v0.10.6.md +47 -0
- package/docs/releases/v0.10.7.md +53 -0
- package/docs/releases/v0.10.8.md +49 -0
- package/docs/releases/v0.10.9.md +37 -0
- package/docs/releases/v0.11.0.md +86 -0
- package/docs/releases/v0.12.0.md +67 -0
- package/docs/releases/v0.13.0.md +64 -0
- package/docs/releases/v0.14.0.md +68 -0
- package/docs/releases/v0.15.0.md +48 -0
- package/docs/releases/v0.16.0.md +50 -0
- package/docs/releases/v0.16.1.md +55 -0
- package/docs/releases/v0.16.2.md +36 -0
- package/docs/releases/v0.17.0.md +50 -0
- package/docs/releases/v0.17.1.md +58 -0
- package/docs/releases/v0.17.2.md +42 -0
- package/docs/releases/v0.17.3.md +58 -0
- package/docs/releases/v0.18.0.md +84 -0
- package/docs/releases/v0.18.1.md +51 -0
- package/docs/releases/v0.18.2.md +69 -0
- package/docs/releases/v0.19.0.md +85 -0
- package/docs/releases/v0.19.1.md +46 -0
- package/docs/releases/v0.20.0.md +85 -0
- package/docs/releases/v0.21.0.md +61 -0
- package/docs/releases/v0.21.1.md +47 -0
- package/docs/releases/v0.22.0.md +77 -0
- package/docs/releases/v0.22.1.md +42 -0
- package/docs/releases/v0.23.0.md +105 -0
- package/docs/releases/v0.24.0.md +125 -0
- package/docs/releases/v0.25.0.md +107 -0
- package/docs/releases/v0.26.0.md +139 -0
- package/docs/releases/v0.26.1.md +65 -0
- package/docs/releases/v0.26.2.md +43 -0
- package/docs/releases/v0.27.0.md +63 -0
- package/docs/releases/v0.28.0.md +59 -0
- package/docs/releases/v0.29.0.md +61 -0
- package/docs/releases/v0.29.1.md +59 -0
- package/docs/releases/v0.29.2.md +59 -0
- package/docs/releases/v0.29.3.md +93 -0
- package/docs/releases/v0.30.0.md +75 -0
- package/docs/releases/v0.30.1.md +93 -0
- package/docs/releases/v0.30.2.md +66 -0
- package/docs/releases/v0.31.0.md +122 -0
- package/docs/releases/v0.31.1.md +142 -0
- package/docs/releases/v0.31.10.md +118 -0
- package/docs/releases/v0.31.11.md +88 -0
- package/docs/releases/v0.31.12.md +105 -0
- package/docs/releases/v0.31.13.md +99 -0
- package/docs/releases/v0.31.14.md +97 -0
- package/docs/releases/v0.31.2.md +115 -0
- package/docs/releases/v0.31.3.md +142 -0
- package/docs/releases/v0.31.4.md +117 -0
- package/docs/releases/v0.31.5.md +155 -0
- package/docs/releases/v0.31.6.md +132 -0
- package/docs/releases/v0.31.7.md +132 -0
- package/docs/releases/v0.31.8.md +120 -0
- package/docs/releases/v0.31.9.md +120 -0
- package/docs/releases/v0.32.0.md +261 -0
- package/docs/releases/v0.32.1.md +59 -0
- package/docs/releases/v0.33.0.md +164 -0
- package/docs/releases/v0.8.0.md +118 -0
- package/docs/releases/v0.9.0.md +98 -0
- package/docs/releases/v0.9.1.md +83 -0
- package/package.json +102 -6
- package/plugins/mirror-mind/.claude-plugin/plugin.json +17 -0
- package/plugins/mirror-mind/hooks/hooks.json +62 -0
- package/plugins/mirror-mind/hooks/log-assistant-reply.sh +98 -0
- package/plugins/mirror-mind/hooks/log-session-end.sh +98 -0
- package/plugins/mirror-mind/hooks/log-user-prompt.sh +98 -0
- package/plugins/mirror-mind/hooks/mirror-inject.sh +98 -0
- package/plugins/mirror-mind/hooks/session-start.sh +98 -0
- package/plugins/mirror-mind/skills/mm-backup/SKILL.md +27 -0
- package/plugins/mirror-mind/skills/mm-build/SKILL.md +1206 -0
- package/plugins/mirror-mind/skills/mm-consolidate/SKILL.md +112 -0
- package/plugins/mirror-mind/skills/mm-consult/SKILL.md +83 -0
- package/plugins/mirror-mind/skills/mm-conversations/SKILL.md +17 -0
- package/plugins/mirror-mind/skills/mm-discard/SKILL.md +40 -0
- package/plugins/mirror-mind/skills/mm-explore/SKILL.md +241 -0
- package/plugins/mirror-mind/skills/mm-help/SKILL.md +104 -0
- package/plugins/mirror-mind/skills/mm-identity/SKILL.md +96 -0
- package/plugins/mirror-mind/skills/mm-journal/SKILL.md +21 -0
- package/plugins/mirror-mind/skills/mm-journey/SKILL.md +37 -0
- package/plugins/mirror-mind/skills/mm-journeys/SKILL.md +15 -0
- package/plugins/mirror-mind/skills/mm-memories/SKILL.md +20 -0
- package/plugins/mirror-mind/skills/mm-mirror/SKILL.md +67 -0
- package/plugins/mirror-mind/skills/mm-mute/SKILL.md +18 -0
- package/plugins/mirror-mind/skills/mm-new/SKILL.md +18 -0
- package/plugins/mirror-mind/skills/mm-recall/SKILL.md +17 -0
- package/plugins/mirror-mind/skills/mm-release-notes/SKILL.md +31 -0
- package/plugins/mirror-mind/skills/mm-seed/SKILL.md +15 -0
- package/plugins/mirror-mind/skills/mm-shadow/SKILL.md +117 -0
- package/plugins/mirror-mind/skills/mm-soul/SKILL.md +488 -0
- package/plugins/mirror-mind/skills/mm-tasks/SKILL.md +36 -0
- package/plugins/mirror-mind/skills/mm-update/SKILL.md +30 -0
- package/plugins/mirror-mind/skills/mm-week/SKILL.md +46 -0
- package/plugins/mirror-mind/skills/mm-welcome/SKILL.md +22 -0
- package/scripts/codex-hooks/session-end.sh +85 -0
- package/scripts/codex-hooks/session-start.sh +85 -0
- package/scripts/codex-mirror.sh +48 -0
- package/templates/identity/README.md +119 -0
- package/templates/identity/ego/behavior.yaml +52 -0
- package/templates/identity/ego/constraints.yaml +15 -0
- package/templates/identity/ego/identity.yaml +43 -0
- package/templates/identity/journeys/personal-growth.yaml +39 -0
- package/templates/identity/organization/identity.yaml +24 -0
- package/templates/identity/organization/principles.yaml +17 -0
- package/templates/identity/personas/coach.yaml +94 -0
- package/templates/identity/personas/designer.yaml +93 -0
- package/templates/identity/personas/doctor.yaml +96 -0
- package/templates/identity/personas/engineer.yaml +77 -0
- package/templates/identity/personas/financial.yaml +97 -0
- package/templates/identity/personas/prompt-engineer.yaml +122 -0
- package/templates/identity/personas/researcher.yaml +88 -0
- package/templates/identity/personas/strategist.yaml +91 -0
- package/templates/identity/personas/teacher.yaml +95 -0
- package/templates/identity/personas/therapist.yaml +91 -0
- package/templates/identity/personas/thinker.yaml +74 -0
- package/templates/identity/personas/writer.yaml +76 -0
- package/templates/identity/self/config.yaml +16 -0
- package/templates/identity/self/soul.yaml +105 -0
- package/templates/identity/user/identity.yaml +30 -0
- package/ts/src/backup/staging.ts +62 -0
- package/ts/src/backup/zipBackup.ts +267 -0
- package/ts/src/backup/zipReader.ts +109 -0
- package/ts/src/backup/zipWriter.ts +148 -0
- package/ts/src/builder/activeCheckpoint.ts +134 -0
- package/ts/src/builder/aggregateStatus.ts +34 -0
- package/ts/src/builder/approve.ts +149 -0
- package/ts/src/builder/argv.ts +292 -0
- package/ts/src/builder/ariadMethod.ts +536 -0
- package/ts/src/builder/artifacts/artifactSurfaces.ts +106 -0
- package/ts/src/builder/artifacts/artifactWriter.ts +113 -0
- package/ts/src/builder/artifacts/closureArtifacts.ts +199 -0
- package/ts/src/builder/artifacts/deliveryStoryArtifacts.ts +316 -0
- package/ts/src/builder/artifacts/planArtifacts.ts +242 -0
- package/ts/src/builder/artifacts/scaffoldSections.ts +273 -0
- package/ts/src/builder/artifacts/scaffoldState.ts +227 -0
- package/ts/src/builder/artifacts/storyFiles.ts +61 -0
- package/ts/src/builder/artifacts/storyIndex.ts +166 -0
- package/ts/src/builder/cadence.ts +59 -0
- package/ts/src/builder/card.ts +192 -0
- package/ts/src/builder/checkpointRefused.ts +66 -0
- package/ts/src/builder/closure.ts +964 -0
- package/ts/src/builder/commands.ts +2053 -0
- package/ts/src/builder/cursorPosition.ts +176 -0
- package/ts/src/builder/cursorTransitions.ts +77 -0
- package/ts/src/builder/deliveryCursor.ts +577 -0
- package/ts/src/builder/deliveryStoryClosure.ts +521 -0
- package/ts/src/builder/deliveryStoryPlan.ts +536 -0
- package/ts/src/builder/deliveryStoryReady.ts +160 -0
- package/ts/src/builder/deliveryStoryRoadmapClosure.ts +151 -0
- package/ts/src/builder/expand.ts +336 -0
- package/ts/src/builder/flowUnit.ts +339 -0
- package/ts/src/builder/homeSurface.ts +122 -0
- package/ts/src/builder/implementationGuard.ts +125 -0
- package/ts/src/builder/index.ts +11 -0
- package/ts/src/builder/lifecycleRefusal.ts +92 -0
- package/ts/src/builder/lifecycleRibbon.ts +159 -0
- package/ts/src/builder/load.ts +313 -0
- package/ts/src/builder/methodAdoption.ts +113 -0
- package/ts/src/builder/methodDefinition.ts +429 -0
- package/ts/src/builder/methodInspection.ts +371 -0
- package/ts/src/builder/plan.ts +408 -0
- package/ts/src/builder/planPreauthorization.ts +265 -0
- package/ts/src/builder/prepare.ts +225 -0
- package/ts/src/builder/projectPaths.ts +64 -0
- package/ts/src/builder/pull.ts +356 -0
- package/ts/src/builder/pullCandidates.ts +463 -0
- package/ts/src/builder/pullCandidatesRender.ts +238 -0
- package/ts/src/builder/refinementField.ts +93 -0
- package/ts/src/builder/releaseIntent.ts +173 -0
- package/ts/src/builder/resumeState.ts +84 -0
- package/ts/src/builder/resumeSurface.ts +149 -0
- package/ts/src/builder/roadmapGrammar.ts +300 -0
- package/ts/src/builder/roadmapScan.ts +97 -0
- package/ts/src/builder/roadmapScope.ts +210 -0
- package/ts/src/builder/scopePhrases.ts +146 -0
- package/ts/src/builder/storyPaths.ts +196 -0
- package/ts/src/builder/storyPlanPreauthorization.ts +287 -0
- package/ts/src/builder/surfaceProtocol.ts +42 -0
- package/ts/src/builder/templateGeneration.ts +148 -0
- package/ts/src/builder/transition.ts +178 -0
- package/ts/src/consult/args.ts +99 -0
- package/ts/src/consult/core.ts +122 -0
- package/ts/src/consult/modelCatalog.ts +55 -0
- package/ts/src/consult/render.ts +47 -0
- package/ts/src/conversation/append.ts +414 -0
- package/ts/src/conversation/backfill.ts +387 -0
- package/ts/src/conversation/closeTail.ts +467 -0
- package/ts/src/conversation/extraction.ts +333 -0
- package/ts/src/conversation/extractionDriver.ts +130 -0
- package/ts/src/conversation/extractionRun.ts +70 -0
- package/ts/src/conversation/hookPayload.ts +51 -0
- package/ts/src/conversation/journeyInference.ts +165 -0
- package/ts/src/conversation/journeyRepair.ts +114 -0
- package/ts/src/conversation/lifecycleFaces.ts +197 -0
- package/ts/src/conversation/lifecycleWrites.ts +313 -0
- package/ts/src/conversation/listing.ts +77 -0
- package/ts/src/conversation/logger.ts +851 -0
- package/ts/src/conversation/loggerCli.ts +321 -0
- package/ts/src/conversation/loggerRuntime.ts +259 -0
- package/ts/src/conversation/metadataLifecycle.ts +443 -0
- package/ts/src/conversation/recall.ts +66 -0
- package/ts/src/conversation/sessionComposites.ts +258 -0
- package/ts/src/conversation/sessionImport.ts +90 -0
- package/ts/src/conversation/transcriptBackfill.ts +141 -0
- package/ts/src/cultivation/applyActions.ts +241 -0
- package/ts/src/cultivation/cluster.ts +86 -0
- package/ts/src/cultivation/consolidationStore.ts +281 -0
- package/ts/src/cultivation/promptContext.ts +62 -0
- package/ts/src/cultivation/propose.ts +305 -0
- package/ts/src/cultivation/scan.ts +155 -0
- package/ts/src/db/backupGate.ts +47 -0
- package/ts/src/db/bootstrap.ts +108 -0
- package/ts/src/db/bootstrapLock.ts +223 -0
- package/ts/src/db/copyGuard.ts +60 -0
- package/ts/src/db/database.ts +397 -0
- package/ts/src/db/decode.ts +66 -0
- package/ts/src/db/ftsIntegrity.ts +41 -0
- package/ts/src/db/migrateOnOpen.ts +214 -0
- package/ts/src/db/migrations.ts +576 -0
- package/ts/src/db/readyOnOpen.ts +35 -0
- package/ts/src/db/rowDecode.ts +42 -0
- package/ts/src/db/schema.ts +432 -0
- package/ts/src/db/schemaInventory.ts +225 -0
- package/ts/src/db/schemaInventorySnapshot.ts +2107 -0
- package/ts/src/db/schemaState.ts +91 -0
- package/ts/src/db/schemaTsDivergence.ts +114 -0
- package/ts/src/descriptor/descriptorRead.ts +49 -0
- package/ts/src/docs/docsLint.ts +265 -0
- package/ts/src/explorer/handoff.ts +522 -0
- package/ts/src/explorer/render.ts +335 -0
- package/ts/src/explorer/story.ts +769 -0
- package/ts/src/explorer/transition.ts +72 -0
- package/ts/src/extensions/bindings.ts +170 -0
- package/ts/src/extensions/catalog.ts +249 -0
- package/ts/src/extensions/catalogCommands.ts +513 -0
- package/ts/src/extensions/catalogWrites.ts +652 -0
- package/ts/src/extensions/contextRuntime.ts +325 -0
- package/ts/src/extensions/dispatch.ts +374 -0
- package/ts/src/extensions/errors.ts +24 -0
- package/ts/src/extensions/manifest.ts +356 -0
- package/ts/src/extensions/migrations.ts +350 -0
- package/ts/src/extraction/conversation.ts +304 -0
- package/ts/src/extraction/conversationMetadata.ts +206 -0
- package/ts/src/extraction/fencing.ts +106 -0
- package/ts/src/extraction/json.ts +17 -0
- package/ts/src/extraction/prompts.ts +470 -0
- package/ts/src/frontDoor/args.ts +30 -0
- package/ts/src/frontDoor/argvShape.ts +106 -0
- package/ts/src/frontDoor/buildLoadRuntime.ts +139 -0
- package/ts/src/frontDoor/buildRoute.ts +398 -0
- package/ts/src/frontDoor/cli.ts +1872 -0
- package/ts/src/frontDoor/cloneRoleGuard.ts +98 -0
- package/ts/src/frontDoor/consultRoute.ts +50 -0
- package/ts/src/frontDoor/contentTailRoute.ts +239 -0
- package/ts/src/frontDoor/conversationLoggerRoute.ts +83 -0
- package/ts/src/frontDoor/cultivationRoute.ts +210 -0
- package/ts/src/frontDoor/dbPath.ts +131 -0
- package/ts/src/frontDoor/dbSafetyToolsRoute.ts +240 -0
- package/ts/src/frontDoor/exploreRoute.ts +572 -0
- package/ts/src/frontDoor/extensionCatalogRoute.ts +252 -0
- package/ts/src/frontDoor/frontDoorLog.ts +57 -0
- package/ts/src/frontDoor/identityWrite.ts +36 -0
- package/ts/src/frontDoor/journeyWriteRoute.ts +26 -0
- package/ts/src/frontDoor/lifecycleWriteRoute.ts +110 -0
- package/ts/src/frontDoor/liveBackup.ts +100 -0
- package/ts/src/frontDoor/mirrorModeRoute.ts +163 -0
- package/ts/src/frontDoor/namedRefusal.ts +35 -0
- package/ts/src/frontDoor/nodeSupport.ts +24 -0
- package/ts/src/frontDoor/render/consolidate.ts +199 -0
- package/ts/src/frontDoor/render/conversations.ts +33 -0
- package/ts/src/frontDoor/render/cultivationShared.ts +21 -0
- package/ts/src/frontDoor/render/descriptor.ts +20 -0
- package/ts/src/frontDoor/render/detectPersona.ts +50 -0
- package/ts/src/frontDoor/render/icons.ts +13 -0
- package/ts/src/frontDoor/render/identity.ts +59 -0
- package/ts/src/frontDoor/render/identityRows.ts +17 -0
- package/ts/src/frontDoor/render/inspectPersona.ts +53 -0
- package/ts/src/frontDoor/render/journeyStatus.ts +78 -0
- package/ts/src/frontDoor/render/journeys.ts +79 -0
- package/ts/src/frontDoor/render/list.ts +41 -0
- package/ts/src/frontDoor/render/memories.ts +67 -0
- package/ts/src/frontDoor/render/recall.ts +49 -0
- package/ts/src/frontDoor/render/shadow.ts +155 -0
- package/ts/src/frontDoor/render/tasks.ts +99 -0
- package/ts/src/frontDoor/render/tasksImportSync.ts +63 -0
- package/ts/src/frontDoor/render/week.ts +113 -0
- package/ts/src/frontDoor/routing.ts +1001 -0
- package/ts/src/frontDoor/runtimeRoute.ts +623 -0
- package/ts/src/frontDoor/searchRoute.ts +166 -0
- package/ts/src/frontDoor/seedPaths.ts +98 -0
- package/ts/src/frontDoor/sessionStartWelcomeRoute.ts +166 -0
- package/ts/src/frontDoor/soulRoute.ts +433 -0
- package/ts/src/frontDoor/stdinSource.ts +37 -0
- package/ts/src/frontDoor/tasksImportSyncRoute.ts +110 -0
- package/ts/src/frontDoor/tasksWriteRoute.ts +101 -0
- package/ts/src/frontDoor/usage.ts +176 -0
- package/ts/src/guards/claudePlugin.ts +298 -0
- package/ts/src/guards/packContents.ts +306 -0
- package/ts/src/guards/piSourcedSkills.ts +70 -0
- package/ts/src/guards/retiredRouteShadows.ts +57 -0
- package/ts/src/guards/retiredSurfaces.ts +564 -0
- package/ts/src/hooks/claude.ts +214 -0
- package/ts/src/hooks/codex.ts +45 -0
- package/ts/src/hooks/gemini.ts +126 -0
- package/ts/src/hooks/main.ts +109 -0
- package/ts/src/hooks/mirrorState.ts +71 -0
- package/ts/src/hooks/payload.ts +73 -0
- package/ts/src/hooks/runtime.ts +179 -0
- package/ts/src/hooks/runtimeDetection.ts +34 -0
- package/ts/src/identity/applyConsolidationIdentityUpdate.ts +67 -0
- package/ts/src/identity/descriptorGenerate.ts +162 -0
- package/ts/src/identity/identityEdit.ts +143 -0
- package/ts/src/identity/identityKey.ts +77 -0
- package/ts/src/identity/identityRead.ts +69 -0
- package/ts/src/identity/identityStore.ts +80 -0
- package/ts/src/identity/journeyListing.ts +53 -0
- package/ts/src/identity/personaInspect.ts +44 -0
- package/ts/src/identity/personaListing.ts +37 -0
- package/ts/src/identity/setIdentity.ts +64 -0
- package/ts/src/index.ts +231 -0
- package/ts/src/init/init.ts +111 -0
- package/ts/src/journey/journeyOptions.ts +131 -0
- package/ts/src/journey/journeyRemoval.ts +158 -0
- package/ts/src/journey/journeyStatus.ts +149 -0
- package/ts/src/journey/journeySyncFile.ts +87 -0
- package/ts/src/journey/journeyWrite.ts +203 -0
- package/ts/src/journey/parentJourney.ts +41 -0
- package/ts/src/journey/validateParentJourney.ts +55 -0
- package/ts/src/mcp/boundary.ts +151 -0
- package/ts/src/mcp/guards.ts +244 -0
- package/ts/src/mcp/main.ts +121 -0
- package/ts/src/mcp/payload.ts +141 -0
- package/ts/src/mcp/protocol.ts +141 -0
- package/ts/src/mcp/readModels.ts +241 -0
- package/ts/src/mcp/registry.ts +201 -0
- package/ts/src/mcp/serve.ts +120 -0
- package/ts/src/mcp/tools/deterministic.ts +137 -0
- package/ts/src/mcp/tools/providerCrossing.ts +187 -0
- package/ts/src/mcp/wire.ts +8 -0
- package/ts/src/memory/journal.ts +180 -0
- package/ts/src/memory/listing.ts +107 -0
- package/ts/src/memory/memoryWrite.ts +88 -0
- package/ts/src/memory/reinforcement.ts +35 -0
- package/ts/src/mirror/context.ts +161 -0
- package/ts/src/mirror/defaultResolution.ts +199 -0
- package/ts/src/mirror/mirrorForm.ts +43 -0
- package/ts/src/mirror/orchestration.ts +364 -0
- package/ts/src/mirror/reception.ts +194 -0
- package/ts/src/mirror/render.ts +75 -0
- package/ts/src/mirror/runtimeSession.ts +205 -0
- package/ts/src/mode/operatingMode.ts +148 -0
- package/ts/src/observability/callOutcome.ts +115 -0
- package/ts/src/observability/inspectLedger.ts +329 -0
- package/ts/src/observability/ledgerHooks.ts +126 -0
- package/ts/src/observability/llmCalls.ts +154 -0
- package/ts/src/persona/detectPersona.ts +81 -0
- package/ts/src/planning/promptAssembly.ts +111 -0
- package/ts/src/planning/weekPending.ts +81 -0
- package/ts/src/planning/weekPlan.ts +183 -0
- package/ts/src/planning/weekSave.ts +117 -0
- package/ts/src/providers/config.ts +189 -0
- package/ts/src/providers/cost.ts +64 -0
- package/ts/src/providers/credits.ts +204 -0
- package/ts/src/providers/embedding.ts +321 -0
- package/ts/src/providers/familyProviders.ts +147 -0
- package/ts/src/providers/llm.ts +334 -0
- package/ts/src/providers/openrouter.ts +244 -0
- package/ts/src/providers/redaction.ts +110 -0
- package/ts/src/providers/replay.ts +15 -0
- package/ts/src/providers/transport.ts +410 -0
- package/ts/src/repair/encodingRepair.ts +253 -0
- package/ts/src/runtime/backup.ts +151 -0
- package/ts/src/runtime/channel.ts +146 -0
- package/ts/src/runtime/config.ts +168 -0
- package/ts/src/runtime/diagnose.ts +686 -0
- package/ts/src/runtime/git.ts +510 -0
- package/ts/src/runtime/installKind.ts +220 -0
- package/ts/src/runtime/migrate.ts +154 -0
- package/ts/src/runtime/packageIdentity.ts +102 -0
- package/ts/src/runtime/releaseNotes.ts +244 -0
- package/ts/src/runtime/status.ts +557 -0
- package/ts/src/runtime/strategies/clone.ts +200 -0
- package/ts/src/runtime/strategies/package.ts +328 -0
- package/ts/src/runtime/treeRoot.ts +30 -0
- package/ts/src/runtime/update.ts +445 -0
- package/ts/src/runtime/updateGate.ts +40 -0
- package/ts/src/runtime/updatePipeline.ts +159 -0
- package/ts/src/runtime/version.ts +36 -0
- package/ts/src/runtime/wiring.ts +130 -0
- package/ts/src/search/memorySearch.ts +338 -0
- package/ts/src/search/ranker.ts +154 -0
- package/ts/src/seed/seed.ts +256 -0
- package/ts/src/seed/seedYaml.ts +133 -0
- package/ts/src/soul/apply.ts +218 -0
- package/ts/src/soul/harvest.ts +267 -0
- package/ts/src/soul/prompts/soul_beauty_voice.md +103 -0
- package/ts/src/soul/prompts/soul_self_voice.md +219 -0
- package/ts/src/soul/prompts/soul_wisdom_voice.md +121 -0
- package/ts/src/soul/prompts.ts +85 -0
- package/ts/src/soul/render.ts +358 -0
- package/ts/src/soul/state.ts +212 -0
- package/ts/src/soul/transition.ts +37 -0
- package/ts/src/tasks/journeyPathParse.ts +113 -0
- package/ts/src/tasks/taskImportSync.ts +142 -0
- package/ts/src/tasks/taskStore.ts +312 -0
- package/ts/src/tasks/weekView.ts +120 -0
- package/ts/src/util/clipCodePoints.ts +26 -0
- package/ts/src/util/paths.ts +63 -0
- package/ts/src/util/program.ts +9 -0
- package/ts/src/util/pyGenerators.ts +144 -0
- package/ts/src/util/pythonText.ts +317 -0
- package/ts/src/util/semver.ts +45 -0
- package/ts/src/util/shellWord.ts +25 -0
- package/ts/src/util/slug.ts +64 -0
- package/ts/src/welcome/card.ts +339 -0
- package/ts/src/welcome/statusLine.ts +101 -0
- package/ts/src/welcome/updateCache.ts +129 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
// CV22.DS7.US8 plateau 3 — the three files Plan materializes.
|
|
2
|
+
//
|
|
3
|
+
// Port of `_write_story_package` and its renderers from
|
|
4
|
+
// `src/memory/builder/lifecycle.py`.
|
|
5
|
+
//
|
|
6
|
+
// `writeStoryPackage` is the preservation rule in code: `if not path.exists()`, per
|
|
7
|
+
// FILE, so a package where a Driver authored `plan.md` but not `test-guide.md` gets
|
|
8
|
+
// the guide created and the plan left alone. A port that writes unconditionally
|
|
9
|
+
// destroys authored work silently, in someone else's git history — the worst defect
|
|
10
|
+
// available in this story, and the subject of CR004/CR015/CR079.
|
|
11
|
+
//
|
|
12
|
+
// The generated `plan.md` is also read back by `planSectionsToAuthor`
|
|
13
|
+
// (`scaffoldState.ts`), the rule both approval routes apply, so its `## ` headings
|
|
14
|
+
// are a contract with the approval rule, not decoration: rename one and a freshly
|
|
15
|
+
// scaffolded Plan reads as incomplete forever.
|
|
16
|
+
|
|
17
|
+
import { mkdirSync } from "node:fs";
|
|
18
|
+
import { dirname, join } from "node:path";
|
|
19
|
+
import type { ContractDefinition } from "../methodDefinition.ts";
|
|
20
|
+
import {
|
|
21
|
+
existingArtifact,
|
|
22
|
+
type MaterializedArtifact,
|
|
23
|
+
materializedArtifact,
|
|
24
|
+
} from "./artifactSurfaces.ts";
|
|
25
|
+
import { requireProjectRoot, writeBuilderArtifact } from "./artifactWriter.ts";
|
|
26
|
+
import { type ArtifactName, artifactState, describeArtifactState } from "./scaffoldState.ts";
|
|
27
|
+
|
|
28
|
+
/** Python `_markdown_list`: an empty list renders the literal fallback line. */
|
|
29
|
+
export function markdownList(items: readonly string[]): string {
|
|
30
|
+
return items.length > 0 ? items.map((item) => `- ${item}`).join("\n") : "- None declared.";
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
import { NAVIGATOR_VALIDATION_GUIDANCE, VALIDATION_EVIDENCE_PENDING } from "./scaffoldSections.ts";
|
|
34
|
+
/** Python `_user_story_statement` / `_technical_story_statement`, shared with Expand. */
|
|
35
|
+
import { technicalStoryStatement, userStoryStatement } from "./storyIndex.ts";
|
|
36
|
+
|
|
37
|
+
/** The subset of the Plan report these renderers read. */
|
|
38
|
+
export interface PlanArtifactInput {
|
|
39
|
+
readonly activeItem: string;
|
|
40
|
+
readonly activeItemTitle: string | null;
|
|
41
|
+
readonly activeItemLevel: string | null;
|
|
42
|
+
readonly objective: string;
|
|
43
|
+
readonly scope: readonly string[];
|
|
44
|
+
readonly nonGoals: readonly string[];
|
|
45
|
+
readonly acceptanceBehavior: readonly string[];
|
|
46
|
+
readonly validationRoute: readonly string[];
|
|
47
|
+
readonly e2eDecision: string;
|
|
48
|
+
readonly localRules: readonly string[];
|
|
49
|
+
readonly implementContract: ContractDefinition;
|
|
50
|
+
readonly activeCheckpoint: string | null;
|
|
51
|
+
readonly pendingConfirmation: string | null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Python `_render_story_index_artifact`. */
|
|
55
|
+
export function renderStoryIndexArtifact(report: PlanArtifactInput): string {
|
|
56
|
+
// `"technical_story".replace("_", " ").title()` -> `Technical Story`; a null level
|
|
57
|
+
// becomes the literal `Story`.
|
|
58
|
+
const storyType = (report.activeItemLevel ?? "story")
|
|
59
|
+
.replaceAll("_", " ")
|
|
60
|
+
.replace(/\p{L}+/gu, (word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase());
|
|
61
|
+
const title = report.activeItemTitle ?? report.activeItem;
|
|
62
|
+
const statement =
|
|
63
|
+
report.activeItemLevel === "technical_story"
|
|
64
|
+
? technicalStoryStatement(title)
|
|
65
|
+
: userStoryStatement(title);
|
|
66
|
+
return `[< Parent](../index.md)
|
|
67
|
+
|
|
68
|
+
# ${report.activeItem} — ${title}
|
|
69
|
+
|
|
70
|
+
**Status:** 🟡 Planned
|
|
71
|
+
**Type:** ${storyType}
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Outcome
|
|
76
|
+
|
|
77
|
+
${report.objective}
|
|
78
|
+
|
|
79
|
+
## Story Statement
|
|
80
|
+
|
|
81
|
+
${statement}
|
|
82
|
+
|
|
83
|
+
## Acceptance Behavior
|
|
84
|
+
|
|
85
|
+
\`\`\`text
|
|
86
|
+
${report.acceptanceBehavior.join("\n")}
|
|
87
|
+
\`\`\`
|
|
88
|
+
|
|
89
|
+
## Scope
|
|
90
|
+
|
|
91
|
+
${markdownList(report.scope)}
|
|
92
|
+
|
|
93
|
+
## Out Of Scope
|
|
94
|
+
|
|
95
|
+
${markdownList(report.nonGoals)}
|
|
96
|
+
|
|
97
|
+
## Validation
|
|
98
|
+
|
|
99
|
+
${markdownList(report.validationRoute)}
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Artifacts
|
|
104
|
+
|
|
105
|
+
- [Plan](plan.md)
|
|
106
|
+
- [Test Guide](test-guide.md)
|
|
107
|
+
`;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Ariad's own rule for staging, a method line in every Plan: the card and the
|
|
112
|
+
* scaffold both print it from here (CR019).
|
|
113
|
+
*/
|
|
114
|
+
export const STORY_SCOPED_COMMIT_RULE = "Do not use git add .; commit only story-scoped files.";
|
|
115
|
+
|
|
116
|
+
/** Python `_render_plan_artifact`. */
|
|
117
|
+
export function renderPlanArtifact(report: PlanArtifactInput): string {
|
|
118
|
+
// The project's own rules follow the method lines; none is an honest empty (CR019).
|
|
119
|
+
const contract = [
|
|
120
|
+
"- Use TDD or characterization tests for behavior changes when testable.",
|
|
121
|
+
`- Keep changes scoped to \`${report.activeItem}\`.`,
|
|
122
|
+
`- ${STORY_SCOPED_COMMIT_RULE}`,
|
|
123
|
+
...report.localRules.map((rule) => `- ${rule}`),
|
|
124
|
+
].join("\n");
|
|
125
|
+
const stopConditions = report.implementContract.stopConditions
|
|
126
|
+
.map((condition) => `- ${condition}`)
|
|
127
|
+
.join("\n");
|
|
128
|
+
return `# Plan — ${report.activeItem}
|
|
129
|
+
|
|
130
|
+
## Objective
|
|
131
|
+
|
|
132
|
+
${report.objective}
|
|
133
|
+
|
|
134
|
+
## Scope
|
|
135
|
+
|
|
136
|
+
${markdownList(report.scope)}
|
|
137
|
+
|
|
138
|
+
## Non-Goals
|
|
139
|
+
|
|
140
|
+
${markdownList(report.nonGoals)}
|
|
141
|
+
|
|
142
|
+
## Acceptance Behavior
|
|
143
|
+
|
|
144
|
+
\`\`\`text
|
|
145
|
+
${report.acceptanceBehavior.join("\n")}
|
|
146
|
+
\`\`\`
|
|
147
|
+
|
|
148
|
+
## Validation Route
|
|
149
|
+
|
|
150
|
+
${markdownList(report.validationRoute)}
|
|
151
|
+
|
|
152
|
+
E2E decision: ${report.e2eDecision}
|
|
153
|
+
|
|
154
|
+
## Implementation Contract
|
|
155
|
+
|
|
156
|
+
${contract}
|
|
157
|
+
|
|
158
|
+
## Stop Conditions
|
|
159
|
+
|
|
160
|
+
${stopConditions}
|
|
161
|
+
|
|
162
|
+
## Approval Gate
|
|
163
|
+
|
|
164
|
+
- active checkpoint: \`${report.activeCheckpoint}\`
|
|
165
|
+
- pending confirmation: \`${report.pendingConfirmation}\`
|
|
166
|
+
- implementation remains blocked until Navigator approval.
|
|
167
|
+
`;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** Python `_render_test_guide_artifact`. */
|
|
171
|
+
export function renderTestGuideArtifact(report: PlanArtifactInput): string {
|
|
172
|
+
return `[< Story](index.md)
|
|
173
|
+
|
|
174
|
+
# Test Guide — ${report.activeItem}
|
|
175
|
+
|
|
176
|
+
## Automated Validation
|
|
177
|
+
|
|
178
|
+
${markdownList(report.validationRoute)}
|
|
179
|
+
|
|
180
|
+
## E2E Decision
|
|
181
|
+
|
|
182
|
+
${report.e2eDecision}
|
|
183
|
+
|
|
184
|
+
## Navigator Validation
|
|
185
|
+
|
|
186
|
+
${NAVIGATOR_VALIDATION_GUIDANCE}
|
|
187
|
+
|
|
188
|
+
## Validation Evidence
|
|
189
|
+
|
|
190
|
+
${VALIDATION_EVIDENCE_PENDING}
|
|
191
|
+
`;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Python `_plan_package_artifacts`: what Plan did to each file of the package.
|
|
196
|
+
*
|
|
197
|
+
* A file that existed before Plan is left alone (CR079) and named with what it is
|
|
198
|
+
* (CR112): a scaffold nobody authored, an incomplete file, or an authored one, so the
|
|
199
|
+
* reader of the artifacts card can tell which. The command and the recorded corpus
|
|
200
|
+
* both call this, so the card they print cannot differ.
|
|
201
|
+
*/
|
|
202
|
+
export function planPackageArtifacts(
|
|
203
|
+
planPath: string | null,
|
|
204
|
+
existedBefore: ReadonlyMap<string, boolean>,
|
|
205
|
+
): MaterializedArtifact[] {
|
|
206
|
+
if (planPath === null) return [];
|
|
207
|
+
const directory = dirname(planPath);
|
|
208
|
+
const triple: [string, string, ArtifactName][] = [
|
|
209
|
+
["story index", join(directory, "index.md"), "index.md"],
|
|
210
|
+
["plan", planPath, "plan.md"],
|
|
211
|
+
["test guide", join(directory, "test-guide.md"), "test-guide.md"],
|
|
212
|
+
];
|
|
213
|
+
return triple.map(([kind, path, name]) =>
|
|
214
|
+
existedBefore.get(path) === true
|
|
215
|
+
? existingArtifact(kind, path, describeArtifactState(artifactState(name, path).state))
|
|
216
|
+
: materializedArtifact(kind, path, { existedBefore: false }),
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Python `_write_story_package`.
|
|
222
|
+
*
|
|
223
|
+
* The directory is created unconditionally, the FILES conditionally. Both halves
|
|
224
|
+
* matter: a missing directory would make the whole package fail, while an existing
|
|
225
|
+
* file must survive untouched.
|
|
226
|
+
*/
|
|
227
|
+
export function writeStoryPackage(
|
|
228
|
+
directory: string,
|
|
229
|
+
projectRoot: string | null | undefined,
|
|
230
|
+
report: PlanArtifactInput,
|
|
231
|
+
): void {
|
|
232
|
+
const root = requireProjectRoot(projectRoot, directory);
|
|
233
|
+
mkdirSync(directory, { recursive: true });
|
|
234
|
+
const artifacts: [string, string][] = [
|
|
235
|
+
[join(directory, "index.md"), renderStoryIndexArtifact(report)],
|
|
236
|
+
[join(directory, "plan.md"), renderPlanArtifact(report)],
|
|
237
|
+
[join(directory, "test-guide.md"), renderTestGuideArtifact(report)],
|
|
238
|
+
];
|
|
239
|
+
for (const [path, content] of artifacts) {
|
|
240
|
+
writeBuilderArtifact({ path, content, policy: "create-only", projectRoot: root });
|
|
241
|
+
}
|
|
242
|
+
}
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
// CR112 — the one home of every sentence a story scaffold carries.
|
|
2
|
+
//
|
|
3
|
+
// Expand writes a child story's `index.md`; Plan writes `index.md`, `plan.md`, and
|
|
4
|
+
// `test-guide.md`. Until CR112 the sentences those files carry lived where each
|
|
5
|
+
// writer happened to compose them: the statement and outcome in `storyIndex.ts`,
|
|
6
|
+
// the Plan context in `commands.ts`, and a second set of Plan defaults in `plan.ts`,
|
|
7
|
+
// reached only when a caller passed no sections. Nothing could read a file back and
|
|
8
|
+
// say whether it was still the scaffold, because nothing held the scaffold's lines in
|
|
9
|
+
// a form a reader could compare against.
|
|
10
|
+
//
|
|
11
|
+
// This module holds them as TEMPLATES: fixed text with a `{title}` slot.
|
|
12
|
+
// The writers fill them (`fill`) and produce the same bytes they always did; the
|
|
13
|
+
// reader (`scaffoldState.ts`) matches a file's lines against them with the slots
|
|
14
|
+
// wildcarded (`matchesTemplate`), so the check reads nothing but the file and this
|
|
15
|
+
// module -- not the cursor's title, which a re-pull can change, and not the roadmap.
|
|
16
|
+
//
|
|
17
|
+
// Every section also carries a KIND. A `placeholder` section is where the scaffold
|
|
18
|
+
// stands in for content the Driver must write. A `default` section is a rule or a
|
|
19
|
+
// default that may legitimately stand as written: keeping "Do not use git add ."
|
|
20
|
+
// verbatim leaves no placeholder behind; keeping "Deliver X as an observable slice"
|
|
21
|
+
// does.
|
|
22
|
+
//
|
|
23
|
+
// One Plan vocabulary, `PRODUCT_PLAN`, which `planLifecycleItem` fills for every
|
|
24
|
+
// caller. CR112 recorded a second one, the defaults Python's `plan_lifecycle_item`
|
|
25
|
+
// wrote when a caller passed no sections; no product path wrote it, only the recorded
|
|
26
|
+
// corpus and the tests, so the corpus graded a scaffold no user received. CR111 (D3)
|
|
27
|
+
// retired it.
|
|
28
|
+
|
|
29
|
+
export type SectionKind = "placeholder" | "default";
|
|
30
|
+
|
|
31
|
+
/** A `## ` section of a scaffold: its heading, its kind, and the template lines it may hold. */
|
|
32
|
+
export interface SectionSpec {
|
|
33
|
+
readonly header: string;
|
|
34
|
+
readonly kind: SectionKind;
|
|
35
|
+
/** Template lines a scaffold writes under this heading; empty for a `default` section. */
|
|
36
|
+
readonly lines: readonly string[];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** The slot a template may carry: the item's title, the one thing a scaffold varies by. */
|
|
40
|
+
export interface SlotValues {
|
|
41
|
+
readonly title?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const SLOT_RE = /\{(title)\}/g;
|
|
45
|
+
|
|
46
|
+
/** Fill a template's slots. A slot with no value is left as written. */
|
|
47
|
+
export function fill(template: string, values: SlotValues): string {
|
|
48
|
+
return template.replace(SLOT_RE, (whole) => values.title ?? whole);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* True when `line` is `template` with anything in its slots: the fixed text before,
|
|
53
|
+
* between, and after the slots must appear in order, at the ends where the template
|
|
54
|
+
* has them. A template with no slot matches only itself.
|
|
55
|
+
*/
|
|
56
|
+
export function matchesTemplate(line: string, template: string): boolean {
|
|
57
|
+
const parts = template.split(SLOT_RE).filter((_, index) => index % 2 === 0);
|
|
58
|
+
if (parts.length === 1) return line === template;
|
|
59
|
+
const first = parts[0] as string;
|
|
60
|
+
const last = parts[parts.length - 1] as string;
|
|
61
|
+
if (!line.startsWith(first) || !line.endsWith(last)) return false;
|
|
62
|
+
if (line.length < first.length + last.length) return false;
|
|
63
|
+
let cursor = first.length;
|
|
64
|
+
const end = line.length - last.length;
|
|
65
|
+
for (const part of parts.slice(1, -1)) {
|
|
66
|
+
const at = line.indexOf(part, cursor);
|
|
67
|
+
if (at === -1 || at + part.length > end) return false;
|
|
68
|
+
cursor = at + part.length;
|
|
69
|
+
}
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// --- the statement and outcome templates (Expand's `index.md`, and Plan's) ---
|
|
74
|
+
|
|
75
|
+
/** Python `_user_story_statement`, as a template. */
|
|
76
|
+
export const USER_STORY_STATEMENT: readonly string[] = [
|
|
77
|
+
"As a user,",
|
|
78
|
+
"I want to {title},",
|
|
79
|
+
"So that I can receive the value of this story.",
|
|
80
|
+
];
|
|
81
|
+
|
|
82
|
+
/** Python `_technical_story_statement`, as a template. */
|
|
83
|
+
export const TECHNICAL_STORY_STATEMENT: readonly string[] = [
|
|
84
|
+
"In order to support the delivery capability,",
|
|
85
|
+
"As an engineering team/system component,",
|
|
86
|
+
"I want to {title},",
|
|
87
|
+
"So that the expected technical outcome is available.",
|
|
88
|
+
];
|
|
89
|
+
|
|
90
|
+
/** Python `_user_story_outcome`, as a template. */
|
|
91
|
+
export const STORY_OUTCOME = "Navigator can validate {title} as an observable behavior.";
|
|
92
|
+
|
|
93
|
+
/** The acceptance block Expand writes for a User Story. */
|
|
94
|
+
export const USER_STORY_ACCEPTANCE: readonly string[] = [
|
|
95
|
+
"Given the user is ready for {title}",
|
|
96
|
+
"When the user performs the planned action",
|
|
97
|
+
"Then the expected observable behavior is visible",
|
|
98
|
+
"And unrelated Delivery Story scope remains untouched",
|
|
99
|
+
];
|
|
100
|
+
|
|
101
|
+
/** The acceptance block Expand writes for a Technical Story. */
|
|
102
|
+
export const TECHNICAL_STORY_ACCEPTANCE: readonly string[] = [
|
|
103
|
+
"Given the system is ready for {title}",
|
|
104
|
+
"When the planned technical change is applied",
|
|
105
|
+
"Then the expected technical outcome is observable",
|
|
106
|
+
"And unrelated Delivery Story scope remains untouched",
|
|
107
|
+
];
|
|
108
|
+
|
|
109
|
+
// --- the Plan vocabularies ---
|
|
110
|
+
|
|
111
|
+
/** The sentences a Plan scaffold carries, before its slots are filled. */
|
|
112
|
+
export interface PlanVocabulary {
|
|
113
|
+
readonly objective: string;
|
|
114
|
+
readonly scope: readonly string[];
|
|
115
|
+
readonly nonGoals: readonly string[];
|
|
116
|
+
readonly acceptanceBehavior: readonly string[];
|
|
117
|
+
readonly validationRoute: readonly string[];
|
|
118
|
+
readonly e2eDecision: string;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** The Plan scaffold's sentences: Python `cmd_plan_item`'s roadmap context. */
|
|
122
|
+
export const PRODUCT_PLAN: PlanVocabulary = {
|
|
123
|
+
objective: "Plan the smallest coherent, testable slice for {title}.",
|
|
124
|
+
scope: [
|
|
125
|
+
"Deliver {title} as an observable slice.",
|
|
126
|
+
"Keep the implementation narrow enough to validate at the Plan-defined checkpoint.",
|
|
127
|
+
],
|
|
128
|
+
nonGoals: ["Do not silently absorb adjacent roadmap work."],
|
|
129
|
+
acceptanceBehavior: [
|
|
130
|
+
"Given the starting state needed for {title}",
|
|
131
|
+
"When the Navigator exercises {title}",
|
|
132
|
+
"Then the planned observable behavior is visible",
|
|
133
|
+
"And out-of-scope sibling roadmap items remain untouched",
|
|
134
|
+
],
|
|
135
|
+
validationRoute: [
|
|
136
|
+
"Run automated tests that cover the planned behavior.",
|
|
137
|
+
"Provide a Navigator-visible route with expected observation, pass condition, and fail condition.",
|
|
138
|
+
],
|
|
139
|
+
e2eDecision:
|
|
140
|
+
"required unless Navigator explicitly accepts a narrower fixture-level validation route",
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
/** The Non-Goals line the front door writes for each sibling roadmap item. */
|
|
144
|
+
export const SIBLING_NON_GOAL = "Do not implement sibling roadmap item: {title}.";
|
|
145
|
+
|
|
146
|
+
/** A vocabulary with its slots filled for one item. */
|
|
147
|
+
export function fillPlanVocabulary(vocabulary: PlanVocabulary, values: SlotValues): PlanVocabulary {
|
|
148
|
+
const fillAll = (lines: readonly string[]): string[] => lines.map((line) => fill(line, values));
|
|
149
|
+
return {
|
|
150
|
+
objective: fill(vocabulary.objective, values),
|
|
151
|
+
scope: fillAll(vocabulary.scope),
|
|
152
|
+
nonGoals: fillAll(vocabulary.nonGoals),
|
|
153
|
+
acceptanceBehavior: fillAll(vocabulary.acceptanceBehavior),
|
|
154
|
+
validationRoute: fillAll(vocabulary.validationRoute),
|
|
155
|
+
e2eDecision: fill(vocabulary.e2eDecision, values),
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** The sentence a test guide's Navigator Validation section holds until it is authored. */
|
|
160
|
+
export const NAVIGATOR_VALIDATION_GUIDANCE =
|
|
161
|
+
"Provide the Navigator-visible route with expected observation, pass condition, and fail condition before the story can pass Validation.";
|
|
162
|
+
|
|
163
|
+
/** The sentence a test guide's Validation Evidence section holds until validation. */
|
|
164
|
+
export const VALIDATION_EVIDENCE_PENDING = "Pending implementation and validation.";
|
|
165
|
+
|
|
166
|
+
// --- the section tables, one per artifact ---
|
|
167
|
+
|
|
168
|
+
const FENCE_OPEN = "```text";
|
|
169
|
+
const FENCE_CLOSE = "```";
|
|
170
|
+
|
|
171
|
+
function bullets(lines: readonly string[]): string[] {
|
|
172
|
+
return lines.map((line) => `- ${line}`);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** The sections of `plan.md`, in the order Plan writes them. */
|
|
176
|
+
export const PLAN_SECTIONS: readonly SectionSpec[] = [
|
|
177
|
+
{ header: "Objective", kind: "placeholder", lines: [PRODUCT_PLAN.objective] },
|
|
178
|
+
{ header: "Scope", kind: "placeholder", lines: bullets(PRODUCT_PLAN.scope) },
|
|
179
|
+
{ header: "Non-Goals", kind: "default", lines: [] },
|
|
180
|
+
{
|
|
181
|
+
header: "Acceptance Behavior",
|
|
182
|
+
kind: "placeholder",
|
|
183
|
+
lines: [FENCE_OPEN, ...PRODUCT_PLAN.acceptanceBehavior, FENCE_CLOSE],
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
header: "Validation Route",
|
|
187
|
+
kind: "placeholder",
|
|
188
|
+
lines: [...bullets(PRODUCT_PLAN.validationRoute), `E2E decision: ${PRODUCT_PLAN.e2eDecision}`],
|
|
189
|
+
},
|
|
190
|
+
{ header: "Implementation Contract", kind: "default", lines: [] },
|
|
191
|
+
{ header: "Stop Conditions", kind: "default", lines: [] },
|
|
192
|
+
{ header: "Approval Gate", kind: "default", lines: [] },
|
|
193
|
+
];
|
|
194
|
+
|
|
195
|
+
/** Python `STORY_PLAN_REQUIRED_SECTIONS`, in declaration order: the Plan contract's headings. */
|
|
196
|
+
export const STORY_PLAN_REQUIRED_SECTIONS = [
|
|
197
|
+
"Scope",
|
|
198
|
+
"Non-Goals",
|
|
199
|
+
"Acceptance Behavior",
|
|
200
|
+
"Validation Route",
|
|
201
|
+
"Implementation Contract",
|
|
202
|
+
] as const;
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* The sections a Plan approval requires authored, on either route (CR112): every
|
|
206
|
+
* placeholder section of the story scaffold and every section the Plan contract
|
|
207
|
+
* requires, in the order the plan file has them, so a refusal lists them as the reader
|
|
208
|
+
* will find them. A placeholder section counts until it is authored; a required
|
|
209
|
+
* `default` section counts until it is not empty or pending.
|
|
210
|
+
*
|
|
211
|
+
* One list for every surface that says what a `plan.md` still needs: both approval
|
|
212
|
+
* routes, `build show`, and the Plan checkpoint read it through `scaffoldState.ts`
|
|
213
|
+
* (CR111 D4). It lives here, with the sections it names, so the reader below the
|
|
214
|
+
* approval layer can use it without depending on that layer.
|
|
215
|
+
*/
|
|
216
|
+
export const PLAN_APPROVAL_SECTIONS: readonly string[] = [
|
|
217
|
+
...PLAN_SECTIONS.filter(
|
|
218
|
+
(section) =>
|
|
219
|
+
section.kind === "placeholder" ||
|
|
220
|
+
(STORY_PLAN_REQUIRED_SECTIONS as readonly string[]).includes(section.header),
|
|
221
|
+
).map((section) => section.header),
|
|
222
|
+
...STORY_PLAN_REQUIRED_SECTIONS.filter(
|
|
223
|
+
(header) => !PLAN_SECTIONS.some((section) => section.header === header),
|
|
224
|
+
),
|
|
225
|
+
];
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* The sections of a story `index.md`. Expand's scaffold heads the statement
|
|
229
|
+
* `## User Story` or `## Technical Story`; Plan's heads it `## Story Statement` and
|
|
230
|
+
* puts the objective under `## Outcome`. A file carries one of the three statement
|
|
231
|
+
* headings; the reader judges whichever it finds.
|
|
232
|
+
*/
|
|
233
|
+
export const STORY_INDEX_SECTIONS: readonly SectionSpec[] = [
|
|
234
|
+
{ header: "User Story", kind: "placeholder", lines: USER_STORY_STATEMENT },
|
|
235
|
+
{ header: "Technical Story", kind: "placeholder", lines: TECHNICAL_STORY_STATEMENT },
|
|
236
|
+
{
|
|
237
|
+
header: "Story Statement",
|
|
238
|
+
kind: "placeholder",
|
|
239
|
+
lines: [...USER_STORY_STATEMENT, ...TECHNICAL_STORY_STATEMENT],
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
header: "Outcome",
|
|
243
|
+
kind: "placeholder",
|
|
244
|
+
lines: [STORY_OUTCOME, PRODUCT_PLAN.objective],
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
header: "Acceptance Behavior",
|
|
248
|
+
kind: "placeholder",
|
|
249
|
+
lines: [
|
|
250
|
+
FENCE_OPEN,
|
|
251
|
+
...USER_STORY_ACCEPTANCE,
|
|
252
|
+
...TECHNICAL_STORY_ACCEPTANCE,
|
|
253
|
+
...PRODUCT_PLAN.acceptanceBehavior,
|
|
254
|
+
FENCE_CLOSE,
|
|
255
|
+
],
|
|
256
|
+
},
|
|
257
|
+
{ header: "Scope", kind: "default", lines: [] },
|
|
258
|
+
{ header: "Out Of Scope", kind: "default", lines: [] },
|
|
259
|
+
{ header: "Validation", kind: "default", lines: [] },
|
|
260
|
+
{ header: "Artifacts", kind: "default", lines: [] },
|
|
261
|
+
];
|
|
262
|
+
|
|
263
|
+
/** The sections of `test-guide.md`, in the order Plan writes them. */
|
|
264
|
+
export const TEST_GUIDE_SECTIONS: readonly SectionSpec[] = [
|
|
265
|
+
{
|
|
266
|
+
header: "Automated Validation",
|
|
267
|
+
kind: "placeholder",
|
|
268
|
+
lines: bullets(PRODUCT_PLAN.validationRoute),
|
|
269
|
+
},
|
|
270
|
+
{ header: "E2E Decision", kind: "default", lines: [] },
|
|
271
|
+
{ header: "Navigator Validation", kind: "placeholder", lines: [NAVIGATOR_VALIDATION_GUIDANCE] },
|
|
272
|
+
{ header: "Validation Evidence", kind: "default", lines: [] },
|
|
273
|
+
];
|