@mindrian_os/install 1.13.0-beta.11
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-plugin/plugin.json +21 -0
- package/.mcp.json +9 -0
- package/CHANGELOG.md +3333 -0
- package/LICENSE +123 -0
- package/README.md +673 -0
- package/agents/brain-query.md +80 -0
- package/agents/framework-runner.md +237 -0
- package/agents/grading.md +188 -0
- package/agents/investor.md +128 -0
- package/agents/larry-extended.md +135 -0
- package/agents/opportunity-scanner.md +91 -0
- package/agents/persona-analyst.md +132 -0
- package/agents/research.md +89 -0
- package/agents/reverse-salient-agent.md +27 -0
- package/bin/cli.js +142 -0
- package/bin/mindrian-mcp-server.cjs +182 -0
- package/bin/mindrian-tools.cjs +765 -0
- package/commands/act.md +439 -0
- package/commands/admin.md +404 -0
- package/commands/analyze-needs.md +42 -0
- package/commands/analyze-systems.md +39 -0
- package/commands/analyze-timing.md +42 -0
- package/commands/auto-explore.md +64 -0
- package/commands/beautiful-question.md +40 -0
- package/commands/brain-derive.md +78 -0
- package/commands/build-knowledge.md +42 -0
- package/commands/build-thesis.md +46 -0
- package/commands/causal.md +234 -0
- package/commands/challenge-assumptions.md +33 -0
- package/commands/compare-ventures.md +83 -0
- package/commands/dashboard.md +110 -0
- package/commands/deep-grade.md +82 -0
- package/commands/diagnose.md +58 -0
- package/commands/diagnostics.md +151 -0
- package/commands/doctor.md +151 -0
- package/commands/dominant-designs.md +40 -0
- package/commands/explain-decision.md +87 -0
- package/commands/explore-domains.md +42 -0
- package/commands/explore-futures.md +40 -0
- package/commands/explore-trends.md +42 -0
- package/commands/export.md +103 -0
- package/commands/file-meeting.md +724 -0
- package/commands/find-analogies.md +188 -0
- package/commands/find-bottlenecks.md +62 -0
- package/commands/find-connections.md +76 -0
- package/commands/funding.md +81 -0
- package/commands/grade.md +203 -0
- package/commands/graph.md +128 -0
- package/commands/hat-briefing.md +125 -0
- package/commands/heal.md +196 -0
- package/commands/help.md +399 -0
- package/commands/hmi-status.md +172 -0
- package/commands/jtbd.md +241 -0
- package/commands/leadership.md +73 -0
- package/commands/lean-canvas.md +40 -0
- package/commands/macro-trends.md +40 -0
- package/commands/map-unknowns.md +40 -0
- package/commands/memory.md +173 -0
- package/commands/models.md +175 -0
- package/commands/mos-reason.md +285 -0
- package/commands/mullins.md +120 -0
- package/commands/new-project.md +481 -0
- package/commands/onboard.md +434 -0
- package/commands/operator.md +149 -0
- package/commands/opportunities.md +144 -0
- package/commands/organize.md +497 -0
- package/commands/persona.md +198 -0
- package/commands/pipeline.md +112 -0
- package/commands/present.md +91 -0
- package/commands/publish.md +201 -0
- package/commands/query.md +124 -0
- package/commands/radar.md +72 -0
- package/commands/reanalyze.md +91 -0
- package/commands/research.md +196 -0
- package/commands/room.md +352 -0
- package/commands/rooms.md +598 -0
- package/commands/root-cause.md +40 -0
- package/commands/rs-experts.md +85 -0
- package/commands/rs-explain.md +100 -0
- package/commands/rs-fetch.md +94 -0
- package/commands/rs-thesis.md +85 -0
- package/commands/scenario-plan.md +40 -0
- package/commands/scheduled-tasks.md +285 -0
- package/commands/score-innovation.md +43 -0
- package/commands/scout.md +239 -0
- package/commands/setup.md +618 -0
- package/commands/snapshot.md +147 -0
- package/commands/speakers.md +84 -0
- package/commands/splash.md +28 -0
- package/commands/status.md +75 -0
- package/commands/structure-argument.md +42 -0
- package/commands/suggest-next.md +80 -0
- package/commands/systems-thinking.md +40 -0
- package/commands/think-hats.md +42 -0
- package/commands/update.md +181 -0
- package/commands/user-needs.md +40 -0
- package/commands/validate.md +40 -0
- package/commands/value-proposition.md +61 -0
- package/commands/vault.md +180 -0
- package/commands/visualize.md +52 -0
- package/commands/whitespace.md +507 -0
- package/commands/wiki.md +69 -0
- package/hooks/hooks.json +381 -0
- package/hooks/run-hook.cmd +64 -0
- package/lib/__init__.py +0 -0
- package/lib/__pycache__/__init__.cpython-312.pyc +0 -0
- package/lib/agents/auto-explore-agent.cjs +1043 -0
- package/lib/agents/reverse-salient-agent.cjs +679 -0
- package/lib/agents/tension-hook-agent.cjs +544 -0
- package/lib/brain/ROOM.md +44 -0
- package/lib/brain/chain-recommender.cjs +301 -0
- package/lib/chat/chat-context.js +185 -0
- package/lib/chat/chat-panel.js +721 -0
- package/lib/chat/fabric-chat.cjs +288 -0
- package/lib/chat/generative-tools.js +219 -0
- package/lib/conversation/ROOM.md +39 -0
- package/lib/conversation/classifier-rules.json +38 -0
- package/lib/conversation/classifier.cjs +264 -0
- package/lib/conversation/operator.cjs +287 -0
- package/lib/copy/115-spec-strings.cjs +55 -0
- package/lib/core/__init__.py +0 -0
- package/lib/core/__nav-stub.cjs +14 -0
- package/lib/core/__pycache__/__init__.cpython-312.pyc +0 -0
- package/lib/core/__pycache__/rs-math.cpython-312.pyc +0 -0
- package/lib/core/__pycache__/rs_cache.cpython-312.pyc +0 -0
- package/lib/core/__pycache__/rs_corpus.cpython-312.pyc +0 -0
- package/lib/core/__pycache__/rs_hybrid.cpython-312.pyc +0 -0
- package/lib/core/__pycache__/rs_math.cpython-312.pyc +0 -0
- package/lib/core/__pycache__/rs_rooms.cpython-312.pyc +0 -0
- package/lib/core/artifact-id.cjs +148 -0
- package/lib/core/asset-ops.cjs +151 -0
- package/lib/core/auto-commit-throttle.cjs +129 -0
- package/lib/core/bearer-token.cjs +199 -0
- package/lib/core/brain-client.cjs +865 -0
- package/lib/core/brain-derivation-prompts.cjs +326 -0
- package/lib/core/brain-derivation-queue.cjs +431 -0
- package/lib/core/brain-derivation.cjs +580 -0
- package/lib/core/brain-md-schema.cjs +528 -0
- package/lib/core/brain-md-staleness.cjs +357 -0
- package/lib/core/brain-response-sanitize.cjs +188 -0
- package/lib/core/bridge-writer.cjs +477 -0
- package/lib/core/chat-context-builder.cjs +253 -0
- package/lib/core/cross-room-aggregator.cjs +762 -0
- package/lib/core/daily-briefing.cjs +438 -0
- package/lib/core/decision-capture.cjs +618 -0
- package/lib/core/deep-links.cjs +82 -0
- package/lib/core/dispatch-optimizer.cjs +354 -0
- package/lib/core/dual-path-detector.cjs +84 -0
- package/lib/core/dual-path-detector.test.cjs +334 -0
- package/lib/core/exports-log.cjs +79 -0
- package/lib/core/feynman-minto-invariants.cjs +605 -0
- package/lib/core/folder-memory-async.cjs +338 -0
- package/lib/core/folder-memory-shared.cjs +890 -0
- package/lib/core/folder-memory.cjs +416 -0
- package/lib/core/framework-chain-composer.cjs +411 -0
- package/lib/core/frontmatter-schemas.cjs +330 -0
- package/lib/core/git-ops.cjs +141 -0
- package/lib/core/graph-ops.cjs +258 -0
- package/lib/core/hat-persistence.cjs +362 -0
- package/lib/core/index.cjs +60 -0
- package/lib/core/integration-registry.cjs +232 -0
- package/lib/core/intelligence-cascade.cjs +661 -0
- package/lib/core/lazygraph-ops.cjs +1057 -0
- package/lib/core/lru-cache.cjs +139 -0
- package/lib/core/mcp-profiles.cjs +182 -0
- package/lib/core/meeting-ops.cjs +54 -0
- package/lib/core/memory-ops.cjs +600 -0
- package/lib/core/migrations/ROOM.md +33 -0
- package/lib/core/migrations/phase-109-nodes-provenance.cjs +339 -0
- package/lib/core/migrations/phase-109-session-focus.cjs +99 -0
- package/lib/core/model-profiles.cjs +246 -0
- package/lib/core/mullins-scaffold.cjs +160 -0
- package/lib/core/nav-dial.cjs +316 -0
- package/lib/core/navigation/ROOM.md +15 -0
- package/lib/core/navigation/explanation.cjs +43 -0
- package/lib/core/navigation/focus.cjs +135 -0
- package/lib/core/navigation/ingestion.cjs +82 -0
- package/lib/core/navigation/insights.cjs +350 -0
- package/lib/core/navigation/memory-events.cjs +118 -0
- package/lib/core/navigation/neighborhood.cjs +78 -0
- package/lib/core/navigation/packet.cjs +182 -0
- package/lib/core/navigation/room-home.cjs +127 -0
- package/lib/core/navigation/transitions.cjs +82 -0
- package/lib/core/navigation-engine-shared.cjs +242 -0
- package/lib/core/navigation-engine.cjs +664 -0
- package/lib/core/navigation.cjs +60 -0
- package/lib/core/nl-graph-queries.cjs +164 -0
- package/lib/core/offer-presenter.cjs +406 -0
- package/lib/core/opportunity-extractor.cjs +183 -0
- package/lib/core/opportunity-ops.cjs +1371 -0
- package/lib/core/persona-ops.cjs +537 -0
- package/lib/core/persona-taxonomy.cjs +190 -0
- package/lib/core/platform-gates.cjs +120 -0
- package/lib/core/platform.cjs +257 -0
- package/lib/core/proactive-intelligence.cjs +528 -0
- package/lib/core/problem-type-router.cjs +315 -0
- package/lib/core/reasoning-ops.cjs +639 -0
- package/lib/core/reverse-salient-persona-suffix.cjs +115 -0
- package/lib/core/room-classifier-strict-mode.cjs +229 -0
- package/lib/core/room-db.cjs +127 -0
- package/lib/core/room-ops-async.cjs +92 -0
- package/lib/core/room-ops-shared.cjs +64 -0
- package/lib/core/room-ops-sync.cjs +70 -0
- package/lib/core/room-ops.cjs +32 -0
- package/lib/core/room-type-detector.cjs +386 -0
- package/lib/core/rs-brain-substrate-prompts.cjs +129 -0
- package/lib/core/rs-brain-substrate.cjs +570 -0
- package/lib/core/rs-breakthrough-scorer.cjs +255 -0
- package/lib/core/rs-canon-violations.cjs +82 -0
- package/lib/core/rs-chain-feeder.cjs +343 -0
- package/lib/core/rs-commercial-assessor.cjs +280 -0
- package/lib/core/rs-differential-scorer.cjs +376 -0
- package/lib/core/rs-domain-analyzer.cjs +385 -0
- package/lib/core/rs-egress-prompts.cjs +113 -0
- package/lib/core/rs-egress-telemetry.cjs +225 -0
- package/lib/core/rs-egress-violations.cjs +53 -0
- package/lib/core/rs-expert-mapper.cjs +467 -0
- package/lib/core/rs-fetcher-academic.cjs +697 -0
- package/lib/core/rs-fetcher-experts.cjs +314 -0
- package/lib/core/rs-fetcher-industry.cjs +731 -0
- package/lib/core/rs-fetcher-patents.cjs +564 -0
- package/lib/core/rs-innovation-classifier.cjs +194 -0
- package/lib/core/rs-mind-map.cjs +656 -0
- package/lib/core/rs-neo4j-writer.cjs +388 -0
- package/lib/core/rs-nl-to-query.cjs +425 -0
- package/lib/core/rs-pinecone-bridge.cjs +303 -0
- package/lib/core/rs-preprocessor.cjs +350 -0
- package/lib/core/rs-query-matrix.cjs +316 -0
- package/lib/core/rs-query-to-text.cjs +438 -0
- package/lib/core/rs-sqlite-mirror.cjs +443 -0
- package/lib/core/rs-thesis-generator.cjs +188 -0
- package/lib/core/rs_cache.py +479 -0
- package/lib/core/rs_corpus.py +468 -0
- package/lib/core/rs_hybrid.py +586 -0
- package/lib/core/rs_math.py +287 -0
- package/lib/core/rs_rooms.py +193 -0
- package/lib/core/scheduled-scanner.cjs +463 -0
- package/lib/core/scratchpad-ops.cjs +201 -0
- package/lib/core/section-8-trace-schema.cjs +138 -0
- package/lib/core/section-registry.cjs +111 -0
- package/lib/core/session-state.cjs +144 -0
- package/lib/core/shallow-doc-parser.cjs +174 -0
- package/lib/core/shallow-doc-parser.test.cjs +226 -0
- package/lib/core/skill-activation-router.cjs +284 -0
- package/lib/core/state-ops.cjs +46 -0
- package/lib/core/statusline-cache.cjs +266 -0
- package/lib/core/token-estimator.cjs +348 -0
- package/lib/core/user-archetype.cjs +239 -0
- package/lib/core/user-md-ops.cjs +524 -0
- package/lib/core/visual-ops.cjs +624 -0
- package/lib/core/write-lock.cjs +149 -0
- package/lib/graph/canvas-graph.js +467 -0
- package/lib/graph/constellation-config.cjs +299 -0
- package/lib/graph/graph-detail-panel.js +165 -0
- package/lib/hmi/ROOM.md +47 -0
- package/lib/hmi/across-session-memory.cjs +604 -0
- package/lib/hmi/cross-room-memory.cjs +575 -0
- package/lib/hmi/decoy-tier.cjs +395 -0
- package/lib/hmi/jtbd-classifier.cjs +219 -0
- package/lib/hmi/jtbd-state.cjs +199 -0
- package/lib/hmi/jtbd-taxonomy.json +392 -0
- package/lib/hmi/selector-dispatcher.cjs +546 -0
- package/lib/hmi/selector-telemetry.cjs +263 -0
- package/lib/hmi/shape-f0-renderer.cjs +139 -0
- package/lib/hmi/shape-f1-fallback.cjs +80 -0
- package/lib/hmi/shape-f1-renderer.cjs +138 -0
- package/lib/hmi/shape-f2-renderer.cjs +132 -0
- package/lib/hmi/shape-f3-renderer.cjs +66 -0
- package/lib/hmi/shape-f4-renderer.cjs +72 -0
- package/lib/hmi/shape-f5-renderer.cjs +155 -0
- package/lib/hmi/shape-f6-plan-review-renderer.cjs +312 -0
- package/lib/hmi/shape-f6-renderer.cjs +144 -0
- package/lib/hmi/shape-g-renderer.cjs +219 -0
- package/lib/hmi/shape-h-renderer.cjs +222 -0
- package/lib/hmi/tier-check.cjs +63 -0
- package/lib/import/PRECONDITIONS.md +41 -0
- package/lib/import/branding.cjs +210 -0
- package/lib/import/branding.test.cjs +235 -0
- package/lib/import/classifications-sync.cjs +104 -0
- package/lib/import/classifications-sync.test.cjs +129 -0
- package/lib/import/enricher.cjs +296 -0
- package/lib/import/enricher.test.cjs +273 -0
- package/lib/import/integration.test.cjs +376 -0
- package/lib/import/manifest.cjs +129 -0
- package/lib/import/manifest.schema.json +185 -0
- package/lib/import/manifest.test.cjs +123 -0
- package/lib/import/meeting-detector.cjs +92 -0
- package/lib/import/meeting-detector.test.cjs +100 -0
- package/lib/import/person-detector.cjs +229 -0
- package/lib/import/person-detector.test.cjs +149 -0
- package/lib/import/report.cjs +186 -0
- package/lib/import/report.test.cjs +186 -0
- package/lib/import/room-md-scaffolder.cjs +49 -0
- package/lib/import/router.cjs +224 -0
- package/lib/import/router.test.cjs +356 -0
- package/lib/import/run-all-tests.cjs +36 -0
- package/lib/import/smoke-test.cjs +213 -0
- package/lib/import/smoke-test.test.cjs +148 -0
- package/lib/import/test-fixtures/collision-vault/preexisting-room/STATE.md +8 -0
- package/lib/import/test-fixtures/collision-vault/preexisting-room/problem-definition/onboarding/onboarding.md +7 -0
- package/lib/import/test-fixtures/collision-vault/source/onboarding.md +5 -0
- package/lib/import/test-fixtures/obsidian-vault/.obsidian/workspace.json +1 -0
- package/lib/import/test-fixtures/obsidian-vault/notes/with-wikilinks.md +4 -0
- package/lib/import/test-fixtures/tiny-vault/notes/2026-01-15-team-sync.md +9 -0
- package/lib/import/test-fixtures/tiny-vault/notes/empty.md +3 -0
- package/lib/import/test-fixtures/tiny-vault/notes/onboarding.md +5 -0
- package/lib/import/test-fixtures/tiny-vault/notes/pricing.md +5 -0
- package/lib/import/test-fixtures/tiny-vault/notes/random.md +4 -0
- package/lib/import/undo.test.cjs +199 -0
- package/lib/import/vault-scanner.cjs +105 -0
- package/lib/import/vault-scanner.test.cjs +67 -0
- package/lib/mcp/app-html/dashboard.html +316 -0
- package/lib/mcp/app-html/graph.html +428 -0
- package/lib/mcp/app-html/mindrian-platform.html +1841 -0
- package/lib/mcp/app-html/wiki.html +383 -0
- package/lib/mcp/app-views.cjs +322 -0
- package/lib/mcp/brain-router.cjs +418 -0
- package/lib/mcp/capability-registry.cjs +62 -0
- package/lib/mcp/larry-context.cjs +46 -0
- package/lib/mcp/larry-server-instructions.md +114 -0
- package/lib/mcp/pipeline-state.cjs +275 -0
- package/lib/mcp/prompts.cjs +302 -0
- package/lib/mcp/resources.cjs +227 -0
- package/lib/mcp/session-catchup.cjs +327 -0
- package/lib/mcp/surface-detect.cjs +75 -0
- package/lib/mcp/tool-router.cjs +1034 -0
- package/lib/memory/aaak-compress.cjs +403 -0
- package/lib/memory/aaak-compress.test.cjs +288 -0
- package/lib/memory/async-artifact-auto-commit.test.cjs +223 -0
- package/lib/memory/bearer-token.test.cjs +315 -0
- package/lib/memory/brain-cache-lru.test.cjs +259 -0
- package/lib/memory/brain-client-query-shape.test.cjs +160 -0
- package/lib/memory/brain-derivation-graceful-degradation.test.cjs +1019 -0
- package/lib/memory/brain-derivation-queue.test.cjs +539 -0
- package/lib/memory/brain-derivation.test.cjs +634 -0
- package/lib/memory/brain-derive-command.test.cjs +534 -0
- package/lib/memory/brain-md-invariants-validator.test.cjs +704 -0
- package/lib/memory/brain-md-schema.test.cjs +467 -0
- package/lib/memory/brain-md-staleness.test.cjs +525 -0
- package/lib/memory/brain-server-resolution.test.cjs +314 -0
- package/lib/memory/chain-recommender.test.cjs +233 -0
- package/lib/memory/chat-context.test.cjs +128 -0
- package/lib/memory/command-registry.test.cjs +220 -0
- package/lib/memory/cross-room-aggregator.test.cjs +909 -0
- package/lib/memory/dashboard-server.test.cjs +256 -0
- package/lib/memory/debouncer-drain-at-prompt.test.cjs +389 -0
- package/lib/memory/decision-capture.test.cjs +632 -0
- package/lib/memory/decision-capture.worker.cjs +70 -0
- package/lib/memory/explain-decision-command.test.cjs +521 -0
- package/lib/memory/explain-decision-footer.test.cjs +316 -0
- package/lib/memory/explored-materials-store.cjs +392 -0
- package/lib/memory/feynman-minto-guardian.test.cjs +736 -0
- package/lib/memory/feynman-minto-invariants.test.cjs +511 -0
- package/lib/memory/feynman-prompts-drift.test.cjs +144 -0
- package/lib/memory/feynman-prompts.cjs +151 -0
- package/lib/memory/feynman-prompts.test.cjs +96 -0
- package/lib/memory/folder-memory-quadruple.test.cjs +548 -0
- package/lib/memory/folder-memory.test.cjs +503 -0
- package/lib/memory/framework-chain-composer.test.cjs +515 -0
- package/lib/memory/frontmatter-schema-validator.test.cjs +290 -0
- package/lib/memory/heal-command.test.cjs +604 -0
- package/lib/memory/index-artifact-transaction.test.cjs +333 -0
- package/lib/memory/lazygraph-rs-discoveries-view.test.cjs +122 -0
- package/lib/memory/mcp-input-validation.test.cjs +240 -0
- package/lib/memory/mcp-server-brain-deps.test.cjs +270 -0
- package/lib/memory/mcp-stack-fallback.test.cjs +433 -0
- package/lib/memory/minto-debouncer.test.cjs +407 -0
- package/lib/memory/minto-debouncer.worker.cjs +46 -0
- package/lib/memory/minto-migration-v88.test.cjs +265 -0
- package/lib/memory/minto-schema-v88.test.cjs +390 -0
- package/lib/memory/mos-status-renderer.test.cjs +631 -0
- package/lib/memory/narrative-schema.cjs +376 -0
- package/lib/memory/narrative-schema.test.cjs +209 -0
- package/lib/memory/nav-dial.test.cjs +414 -0
- package/lib/memory/navigation-engine-core.test.cjs +722 -0
- package/lib/memory/navigation-invariants.test.cjs +483 -0
- package/lib/memory/offer-presenter.test.cjs +554 -0
- package/lib/memory/on-stop-snapshot.test.cjs +404 -0
- package/lib/memory/pending-tension-store.cjs +373 -0
- package/lib/memory/post-compact-reinjection.test.cjs +854 -0
- package/lib/memory/post-write-triple.test.cjs +317 -0
- package/lib/memory/pre-compact-snapshot.test.cjs +495 -0
- package/lib/memory/problem-type-router.test.cjs +656 -0
- package/lib/memory/query-efficiency-telemetry.test.cjs +370 -0
- package/lib/memory/recompile-room-references.test.cjs +392 -0
- package/lib/memory/recompile-room-references.worker.cjs +42 -0
- package/lib/memory/record-decision-dual-write.test.cjs +454 -0
- package/lib/memory/room-classifier-strict-mode.test.cjs +417 -0
- package/lib/memory/room-minto-hook.test.cjs +398 -0
- package/lib/memory/rs-discovery-engine.test.cjs +323 -0
- package/lib/memory/run-feynman-tests.cjs +1247 -0
- package/lib/memory/security-trifecta.test.cjs +312 -0
- package/lib/memory/session-start-brain-staleness.test.cjs +363 -0
- package/lib/memory/session-start-triple-injection.test.cjs +514 -0
- package/lib/memory/sessionstart-banner-formatter.cjs +318 -0
- package/lib/memory/sessionstart-minto-banner.test.cjs +373 -0
- package/lib/memory/skill-activation-router.test.cjs +419 -0
- package/lib/memory/stamp-artifact-write.test.cjs +304 -0
- package/lib/memory/statusline-active-room.test.cjs +315 -0
- package/lib/memory/statusline-minto-segment.test.cjs +292 -0
- package/lib/memory/sync-async-entry-points.test.cjs +204 -0
- package/lib/memory/test-bridge-writer-enhanced.cjs +452 -0
- package/lib/memory/test-rs-brain-substrate-shape.cjs +529 -0
- package/lib/memory/test-rs-brain-substrate.cjs +636 -0
- package/lib/memory/test-rs-breakthrough-scorer.cjs +375 -0
- package/lib/memory/test-rs-canon-violations.cjs +218 -0
- package/lib/memory/test-rs-chain-feeder-core.cjs +344 -0
- package/lib/memory/test-rs-chain-feeder-skill-spawn.cjs +297 -0
- package/lib/memory/test-rs-commercial-assessor.cjs +385 -0
- package/lib/memory/test-rs-differential-scorer.cjs +480 -0
- package/lib/memory/test-rs-discovery-engine.cjs +603 -0
- package/lib/memory/test-rs-domain-analyzer.cjs +492 -0
- package/lib/memory/test-rs-egress-primitives.cjs +420 -0
- package/lib/memory/test-rs-expert-mapper.cjs +547 -0
- package/lib/memory/test-rs-explain-command.cjs +443 -0
- package/lib/memory/test-rs-fetcher-academic.cjs +848 -0
- package/lib/memory/test-rs-fetcher-experts.cjs +496 -0
- package/lib/memory/test-rs-fetcher-industry.cjs +702 -0
- package/lib/memory/test-rs-fetcher-patents.cjs +674 -0
- package/lib/memory/test-rs-innovation-classifier.cjs +301 -0
- package/lib/memory/test-rs-mind-map.cjs +646 -0
- package/lib/memory/test-rs-neo4j-writer.cjs +518 -0
- package/lib/memory/test-rs-nl-to-query.cjs +449 -0
- package/lib/memory/test-rs-pinecone-bridge.cjs +277 -0
- package/lib/memory/test-rs-preprocessor.cjs +433 -0
- package/lib/memory/test-rs-query-matrix.cjs +391 -0
- package/lib/memory/test-rs-query-to-text.cjs +551 -0
- package/lib/memory/test-rs-sqlite-mirror.cjs +649 -0
- package/lib/memory/test-rs-thesis-generator.cjs +360 -0
- package/lib/memory/triple-context-formatter.cjs +473 -0
- package/lib/memory/triple-context-formatter.test.cjs +442 -0
- package/lib/memory/user-md-persona.test.cjs +565 -0
- package/lib/memory/userpromptsubmit-integration.test.cjs +690 -0
- package/lib/memory/validators/README.md +157 -0
- package/lib/memory/validators/brain-md-invariants.cjs +475 -0
- package/lib/memory/validators/brain-substrate-invariants.cjs +285 -0
- package/lib/memory/validators/external-academic-invariants.cjs +249 -0
- package/lib/memory/validators/external-industry-invariants.cjs +271 -0
- package/lib/memory/validators/external-patents-invariants.cjs +266 -0
- package/lib/memory/validators/minto-invariants.cjs +62 -0
- package/lib/memory/validators/navigation-invariants.cjs +340 -0
- package/lib/memory/validators/queue-health.cjs +95 -0
- package/lib/memory/validators/snapshot-integrity.cjs +129 -0
- package/lib/memory/validators/stale-lifecycle.cjs +116 -0
- package/lib/memory/vault-section-minto-generator-atomic.test.cjs +556 -0
- package/lib/memory/vault-section-minto-generator-atomic.worker.cjs +73 -0
- package/lib/memory/write-lock-atomic.test.cjs +137 -0
- package/lib/memory/write-lock-atomic.worker.cjs +55 -0
- package/lib/parity/check-parity.cjs +83 -0
- package/lib/presentation/presentation-server.cjs +101 -0
- package/lib/presentation/presentation-watcher.cjs +123 -0
- package/lib/quickview/hub-server.cjs +719 -0
- package/lib/quickview/server.cjs +533 -0
- package/lib/render/JTBD-PALETTES.md +145 -0
- package/lib/render/ROOM.md +59 -0
- package/lib/render/render-v2.cjs +486 -0
- package/lib/render/render-v2.test.cjs +267 -0
- package/lib/render/render.cjs +65 -0
- package/lib/state/ROOM.md +46 -0
- package/lib/state/state-md-parser.cjs +215 -0
- package/lib/statusline/ROOM.md +38 -0
- package/lib/statusline/banner-suppression.cjs +50 -0
- package/lib/statusline/surface-detect.cjs +85 -0
- package/lib/update-bootstrap.sh.template +145 -0
- package/lib/vault/frontmatter-schema.cjs +297 -0
- package/lib/vault/room-scanner.cjs +352 -0
- package/lib/vault/wikilink-builder.cjs +231 -0
- package/lib/vault/wikilink-builder.test.cjs +182 -0
- package/lib/wiki/graph-links.cjs +281 -0
- package/lib/wiki/page-renderer.cjs +229 -0
- package/lib/wiki/wiki-chat.cjs +81 -0
- package/lib/wiki/wiki-layout.cjs +1459 -0
- package/lib/wiki/wiki-search.cjs +142 -0
- package/lib/wiki/wiki-server.cjs +678 -0
- package/lib/wiki/wiki-watcher.cjs +105 -0
- package/lib/workflow/ROOM.md +47 -0
- package/lib/workflow/command-resolver.cjs +155 -0
- package/lib/workflow/command-resolver.test.cjs +235 -0
- package/package.json +44 -0
- package/pipelines/analogy/01-decompose.md +80 -0
- package/pipelines/analogy/02-abstract.md +87 -0
- package/pipelines/analogy/03-search.md +135 -0
- package/pipelines/analogy/04-transfer.md +101 -0
- package/pipelines/analogy/05-validate.md +106 -0
- package/pipelines/analogy/CHAIN.md +56 -0
- package/pipelines/discovery/01-explore-domains.md +44 -0
- package/pipelines/discovery/02-think-hats.md +50 -0
- package/pipelines/discovery/03-analyze-needs.md +54 -0
- package/pipelines/discovery/CHAIN.md +37 -0
- package/pipelines/thesis/01-structure-argument.md +45 -0
- package/pipelines/thesis/02-challenge-assumptions.md +48 -0
- package/pipelines/thesis/03-build-thesis.md +54 -0
- package/pipelines/thesis/CHAIN.md +37 -0
- package/references/brain/causal-directives.md +91 -0
- package/references/brain/causal-enrichment.cypher +165 -0
- package/references/brain/command-triggers-schema.md +226 -0
- package/references/brain/graph-architecture.md +317 -0
- package/references/brain/query-patterns.md +460 -0
- package/references/brain/room-hierarchy-schema.md +218 -0
- package/references/brain/schema.md +76 -0
- package/references/capability-radar/capabilities-index.md +241 -0
- package/references/capability-radar/changelog-cache.md +81 -0
- package/references/causal/causal-schema.md +103 -0
- package/references/design/email-template-standard.md +155 -0
- package/references/design/graph-visualization-standard.md +178 -0
- package/references/document-generation.md +179 -0
- package/references/hsi/HSI-TOOLS-REFERENCE.md +222 -0
- package/references/import-config.md +141 -0
- package/references/integrations/detection-patterns.md +101 -0
- package/references/meeting/artifact-template.md +377 -0
- package/references/meeting/cross-meeting-intelligence.md +216 -0
- package/references/meeting/cross-relationship-patterns.md +202 -0
- package/references/meeting/live-join-interface.md +244 -0
- package/references/meeting/section-mapping.md +192 -0
- package/references/meeting/segment-classification.md +258 -0
- package/references/meeting/speaker-profile-template.md +219 -0
- package/references/meeting/summary-template.md +348 -0
- package/references/meeting/transcript-patterns.md +226 -0
- package/references/methodology/analyze-needs.md +135 -0
- package/references/methodology/analyze-systems.md +121 -0
- package/references/methodology/analyze-timing.md +149 -0
- package/references/methodology/beautiful-question.md +109 -0
- package/references/methodology/build-knowledge.md +161 -0
- package/references/methodology/build-thesis.md +237 -0
- package/references/methodology/challenge-assumptions.md +127 -0
- package/references/methodology/diagnose.md +169 -0
- package/references/methodology/dominant-designs.md +212 -0
- package/references/methodology/explore-domains.md +147 -0
- package/references/methodology/explore-futures.md +163 -0
- package/references/methodology/explore-trends.md +129 -0
- package/references/methodology/find-bottlenecks.md +131 -0
- package/references/methodology/grade.md +211 -0
- package/references/methodology/index.md +97 -0
- package/references/methodology/leadership.md +200 -0
- package/references/methodology/lean-canvas.md +116 -0
- package/references/methodology/macro-trends.md +192 -0
- package/references/methodology/map-unknowns.md +137 -0
- package/references/methodology/mullins-7-domains.md +104 -0
- package/references/methodology/problem-types.md +65 -0
- package/references/methodology/root-cause.md +178 -0
- package/references/methodology/sapphire-encoding.md +355 -0
- package/references/methodology/scenario-plan.md +178 -0
- package/references/methodology/score-innovation.md +154 -0
- package/references/methodology/structure-argument.md +158 -0
- package/references/methodology/systems-thinking.md +159 -0
- package/references/methodology/think-hats.md +147 -0
- package/references/methodology/triz-matrix.json +751 -0
- package/references/methodology/triz-principles.md +501 -0
- package/references/methodology/user-needs.md +199 -0
- package/references/methodology/validate.md +163 -0
- package/references/methodology/value-proposition.md +244 -0
- package/references/opportunities/funding-lifecycle.md +103 -0
- package/references/opportunities/grant-api-patterns.md +99 -0
- package/references/opportunities/opportunity-template.md +84 -0
- package/references/personality/assessment-philosophy.md +72 -0
- package/references/personality/lexicon.md +100 -0
- package/references/personality/persona-chains.md +56 -0
- package/references/personality/pws-lexicon-full.md +499 -0
- package/references/personality/voice-dna.md +156 -0
- package/references/personas/hat-perspectives.md +76 -0
- package/references/personas/persona-template.md +63 -0
- package/references/pipeline/act-output-contract.md +88 -0
- package/references/pipeline/chains-index.md +39 -0
- package/references/pws-profile-generation.md +79 -0
- package/references/reasoning/reasoning-schema.md +143 -0
- package/references/reasoning/reasoning-template.md +68 -0
- package/references/reasoning/run-template.md +38 -0
- package/references/research/RESEARCH_14_CLAUDE_CODE_SOURCE_ARCHITECTURE.md +209 -0
- package/references/research/RESEARCH_15_V1.8_OPTIMIZATION_JTBD.md +375 -0
- package/references/research/RESEARCH_16_NATIVE_FIRST_PLUGIN_ARCHITECTURE.md +575 -0
- package/references/research/RESEARCH_17_MCP_UI_FRAMEWORKS.md +272 -0
- package/references/taxonomy/TAXONOMY.md +192 -0
- package/references/templates/MINTO.md +36 -0
- package/references/user-research/2026-04-05-leah-lawrence-session.md +202 -0
- package/references/vault-kit/README.md +35 -0
- package/references/vault-kit/app.json +12 -0
- package/references/vault-kit/appearance.json +12 -0
- package/references/vault-kit/graph.json +35 -0
- package/references/vault-kit/snippets/mindrian-destijl.css +297 -0
- package/references/vault-kit/templates/new-artifact.md +37 -0
- package/references/vault-kit/templates/new-meeting-note.md +35 -0
- package/references/vault-kit/templates/new-team-profile.md +29 -0
- package/references/vault-kit/templates/new-xref.md +35 -0
- package/references/visual/symbol-system.md +151 -0
- package/skills/MOSDeckEngine/SKILL.md +325 -0
- package/skills/brain-connector/SKILL.md +114 -0
- package/skills/context-engine/SKILL.md +147 -0
- package/skills/conversation-mode/SKILL.md +102 -0
- package/skills/larry-personality/SKILL.md +219 -0
- package/skills/larry-personality/framework-chains.md +92 -0
- package/skills/larry-personality/mode-engine.md +185 -0
- package/skills/mullins-scaffold/SKILL.md +61 -0
- package/skills/mullins-scaffold/scaffold.json +146 -0
- package/skills/pws-methodology/SKILL.md +49 -0
- package/skills/room-passive/SKILL.md +165 -0
- package/skills/room-proactive/SKILL.md +250 -0
- package/skills/ui-system/SKILL.md +277 -0
|
@@ -0,0 +1,600 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MindrianOS Plugin -- Memory Layer Operations
|
|
3
|
+
* Persistent memory tables on the same room/.mindrian/room.db as lazygraph-ops.cjs.
|
|
4
|
+
* Covers L0 Identity, L1 Facts, and schema for L2 Sessions, L3 Fragments, Assumptions.
|
|
5
|
+
*
|
|
6
|
+
* Exports: initMemorySchema, getIdentity, setIdentity, addFact, getValidFacts, invalidateFact,
|
|
7
|
+
* startSession, endSession, addFragment, getSessionHistory,
|
|
8
|
+
* createAssumption, updateAssumptionValidity, getAssumptions
|
|
9
|
+
*
|
|
10
|
+
* All functions use prepared statements with ? parameters (no string interpolation).
|
|
11
|
+
* Async wrappers for backward compatibility with callers that use await.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
'use strict';
|
|
15
|
+
|
|
16
|
+
// --- Schema ---
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Create all 5 memory tables and 5 indexes. Idempotent (CREATE IF NOT EXISTS).
|
|
20
|
+
* Call after openGraph() on the same db instance.
|
|
21
|
+
* @param {import('node:sqlite').DatabaseSync} db - node:sqlite DatabaseSync instance
|
|
22
|
+
*/
|
|
23
|
+
function initMemorySchema(db) {
|
|
24
|
+
db.exec(`
|
|
25
|
+
CREATE TABLE IF NOT EXISTS identity (
|
|
26
|
+
key TEXT PRIMARY KEY,
|
|
27
|
+
value TEXT NOT NULL,
|
|
28
|
+
updated_at TEXT NOT NULL
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
CREATE TABLE IF NOT EXISTS facts (
|
|
32
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
33
|
+
subject TEXT NOT NULL,
|
|
34
|
+
predicate TEXT NOT NULL,
|
|
35
|
+
object TEXT NOT NULL,
|
|
36
|
+
confidence REAL DEFAULT 1.0,
|
|
37
|
+
source_artifact TEXT,
|
|
38
|
+
source_meeting TEXT,
|
|
39
|
+
valid_from TEXT NOT NULL,
|
|
40
|
+
invalidated_at TEXT,
|
|
41
|
+
invalidated_by TEXT
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
CREATE TABLE IF NOT EXISTS sessions (
|
|
45
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
46
|
+
started_at TEXT NOT NULL,
|
|
47
|
+
ended_at TEXT,
|
|
48
|
+
summary TEXT,
|
|
49
|
+
key_decisions TEXT DEFAULT '[]',
|
|
50
|
+
open_questions TEXT DEFAULT '[]',
|
|
51
|
+
methodology_used TEXT,
|
|
52
|
+
artifacts_filed TEXT DEFAULT '[]'
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
CREATE TABLE IF NOT EXISTS fragments (
|
|
56
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
57
|
+
session_id INTEGER NOT NULL REFERENCES sessions(id),
|
|
58
|
+
role TEXT NOT NULL,
|
|
59
|
+
content TEXT NOT NULL,
|
|
60
|
+
timestamp TEXT NOT NULL,
|
|
61
|
+
section_context TEXT
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
CREATE TABLE IF NOT EXISTS assumptions (
|
|
65
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
66
|
+
claim TEXT NOT NULL,
|
|
67
|
+
section TEXT,
|
|
68
|
+
validity TEXT NOT NULL DEFAULT 'untested' CHECK(validity IN ('untested','supported','contradicted','stale')),
|
|
69
|
+
evidence_for TEXT DEFAULT '[]',
|
|
70
|
+
evidence_against TEXT DEFAULT '[]',
|
|
71
|
+
created_at TEXT NOT NULL,
|
|
72
|
+
last_tested TEXT,
|
|
73
|
+
invalidated_at TEXT
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
CREATE INDEX IF NOT EXISTS idx_facts_subject ON facts(subject);
|
|
77
|
+
CREATE INDEX IF NOT EXISTS idx_facts_invalidated_at ON facts(invalidated_at);
|
|
78
|
+
CREATE INDEX IF NOT EXISTS idx_fragments_session_id ON fragments(session_id);
|
|
79
|
+
CREATE INDEX IF NOT EXISTS idx_assumptions_section ON assumptions(section);
|
|
80
|
+
CREATE INDEX IF NOT EXISTS idx_assumptions_validity ON assumptions(validity);
|
|
81
|
+
|
|
82
|
+
CREATE TABLE IF NOT EXISTS scaffold_log (
|
|
83
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
84
|
+
timestamp TEXT NOT NULL,
|
|
85
|
+
action TEXT NOT NULL,
|
|
86
|
+
section TEXT NOT NULL,
|
|
87
|
+
collection TEXT,
|
|
88
|
+
user_reason TEXT,
|
|
89
|
+
surface TEXT NOT NULL
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
CREATE TABLE IF NOT EXISTS voice_log (
|
|
93
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
94
|
+
timestamp TEXT NOT NULL,
|
|
95
|
+
command TEXT NOT NULL,
|
|
96
|
+
question TEXT,
|
|
97
|
+
answer_summary TEXT,
|
|
98
|
+
artifacts_cited TEXT,
|
|
99
|
+
confidence INTEGER,
|
|
100
|
+
contradictions_flagged TEXT
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
CREATE TABLE IF NOT EXISTS held_contradictions (
|
|
104
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
105
|
+
created_at TEXT NOT NULL,
|
|
106
|
+
source_artifact TEXT,
|
|
107
|
+
target_artifact TEXT,
|
|
108
|
+
tension_summary TEXT,
|
|
109
|
+
status TEXT NOT NULL DEFAULT 'open',
|
|
110
|
+
resolved_at TEXT
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
CREATE TABLE IF NOT EXISTS decisions_index (
|
|
114
|
+
id TEXT PRIMARY KEY,
|
|
115
|
+
decision TEXT NOT NULL,
|
|
116
|
+
rationale TEXT,
|
|
117
|
+
reversibility TEXT,
|
|
118
|
+
witnesses TEXT,
|
|
119
|
+
date TEXT,
|
|
120
|
+
pressure_context TEXT,
|
|
121
|
+
status TEXT,
|
|
122
|
+
artifact_path TEXT
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
CREATE INDEX IF NOT EXISTS idx_scaffold_log_section ON scaffold_log(section);
|
|
126
|
+
CREATE INDEX IF NOT EXISTS idx_voice_log_timestamp ON voice_log(timestamp);
|
|
127
|
+
CREATE INDEX IF NOT EXISTS idx_held_contradictions_status ON held_contradictions(status);
|
|
128
|
+
CREATE INDEX IF NOT EXISTS idx_decisions_index_status ON decisions_index(status);
|
|
129
|
+
`);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// --- L0 Identity ---
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Set (upsert) an identity key-value pair.
|
|
136
|
+
* @param {import('node:sqlite').DatabaseSync} db - node:sqlite DatabaseSync instance
|
|
137
|
+
* @param {string} key - Identity key (e.g. 'venture_name', 'founder', 'stage')
|
|
138
|
+
* @param {string} value - Identity value
|
|
139
|
+
* @returns {Promise<void>}
|
|
140
|
+
*/
|
|
141
|
+
async function setIdentity(db, key, value) {
|
|
142
|
+
const updatedAt = new Date().toISOString();
|
|
143
|
+
db.prepare(
|
|
144
|
+
'INSERT INTO identity (key, value, updated_at) VALUES (?, ?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at'
|
|
145
|
+
).run(key, value, updatedAt);
|
|
146
|
+
return Promise.resolve();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Get all identity key-value pairs as a plain object.
|
|
151
|
+
* @param {import('node:sqlite').DatabaseSync} db - node:sqlite DatabaseSync instance
|
|
152
|
+
* @returns {Promise<object>} e.g. { venture_name: 'Acme', founder: 'Jane' }
|
|
153
|
+
*/
|
|
154
|
+
async function getIdentity(db) {
|
|
155
|
+
const rows = db.prepare('SELECT key, value FROM identity').all();
|
|
156
|
+
const identity = {};
|
|
157
|
+
for (const row of rows) {
|
|
158
|
+
identity[row.key] = row.value;
|
|
159
|
+
}
|
|
160
|
+
return Promise.resolve(identity);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// --- L1 Facts ---
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Add a new fact with auto-generated valid_from timestamp.
|
|
167
|
+
* @param {import('node:sqlite').DatabaseSync} db - node:sqlite DatabaseSync instance
|
|
168
|
+
* @param {object} fact - Fact to add
|
|
169
|
+
* @param {string} fact.subject - Fact subject (e.g. 'market', 'team')
|
|
170
|
+
* @param {string} fact.predicate - Fact predicate (e.g. 'size', 'count')
|
|
171
|
+
* @param {string} fact.object - Fact object value (e.g. '$1B', '5')
|
|
172
|
+
* @param {number} [fact.confidence=1.0] - Confidence score (0-1)
|
|
173
|
+
* @param {string} [fact.source_artifact] - Source artifact ID
|
|
174
|
+
* @param {string} [fact.source_meeting] - Source meeting ID
|
|
175
|
+
* @returns {Promise<{id: number, subject: string, predicate: string, object: string, confidence: number, valid_from: string}>}
|
|
176
|
+
*/
|
|
177
|
+
async function addFact(db, fact) {
|
|
178
|
+
const validFrom = new Date().toISOString();
|
|
179
|
+
const confidence = typeof fact.confidence === 'number' ? fact.confidence : 1.0;
|
|
180
|
+
const sourceArtifact = fact.source_artifact || null;
|
|
181
|
+
const sourceMeeting = fact.source_meeting || null;
|
|
182
|
+
|
|
183
|
+
const info = db.prepare(
|
|
184
|
+
'INSERT INTO facts (subject, predicate, object, confidence, source_artifact, source_meeting, valid_from) VALUES (?, ?, ?, ?, ?, ?, ?)'
|
|
185
|
+
).run(fact.subject, fact.predicate, fact.object, confidence, sourceArtifact, sourceMeeting, validFrom);
|
|
186
|
+
|
|
187
|
+
return Promise.resolve({
|
|
188
|
+
id: Number(info.lastInsertRowid),
|
|
189
|
+
subject: fact.subject,
|
|
190
|
+
predicate: fact.predicate,
|
|
191
|
+
object: fact.object,
|
|
192
|
+
confidence,
|
|
193
|
+
valid_from: validFrom,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Get all valid (non-invalidated) facts, optionally filtered by subject.
|
|
199
|
+
* @param {import('node:sqlite').DatabaseSync} db - node:sqlite DatabaseSync instance
|
|
200
|
+
* @param {string} [subject] - Optional subject filter
|
|
201
|
+
* @returns {Promise<Array<object>>}
|
|
202
|
+
*/
|
|
203
|
+
async function getValidFacts(db, subject) {
|
|
204
|
+
let rows;
|
|
205
|
+
if (subject) {
|
|
206
|
+
rows = db.prepare('SELECT * FROM facts WHERE invalidated_at IS NULL AND subject = ?').all(subject);
|
|
207
|
+
} else {
|
|
208
|
+
rows = db.prepare('SELECT * FROM facts WHERE invalidated_at IS NULL').all();
|
|
209
|
+
}
|
|
210
|
+
return Promise.resolve(rows);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Invalidate a fact by setting invalidated_at and invalidated_by.
|
|
215
|
+
* @param {import('node:sqlite').DatabaseSync} db - node:sqlite DatabaseSync instance
|
|
216
|
+
* @param {number} factId - Fact ID to invalidate
|
|
217
|
+
* @param {string} invalidatedBy - Reason/source for invalidation
|
|
218
|
+
* @returns {Promise<{success: boolean, id: number}>}
|
|
219
|
+
*/
|
|
220
|
+
async function invalidateFact(db, factId, invalidatedBy) {
|
|
221
|
+
const invalidatedAt = new Date().toISOString();
|
|
222
|
+
db.prepare(
|
|
223
|
+
'UPDATE facts SET invalidated_at = ?, invalidated_by = ? WHERE id = ?'
|
|
224
|
+
).run(invalidatedAt, invalidatedBy, factId);
|
|
225
|
+
return Promise.resolve({ success: true, id: factId });
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// --- L2 Sessions ---
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Start a new session. Creates a row with started_at = now.
|
|
232
|
+
* @param {import('node:sqlite').DatabaseSync} db - node:sqlite DatabaseSync instance
|
|
233
|
+
* @returns {Promise<{id: number, started_at: string}>}
|
|
234
|
+
*/
|
|
235
|
+
async function startSession(db) {
|
|
236
|
+
const startedAt = new Date().toISOString();
|
|
237
|
+
const info = db.prepare(
|
|
238
|
+
'INSERT INTO sessions (started_at) VALUES (?)'
|
|
239
|
+
).run(startedAt);
|
|
240
|
+
return Promise.resolve({
|
|
241
|
+
id: Number(info.lastInsertRowid),
|
|
242
|
+
started_at: startedAt,
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* End a session by setting ended_at and optional metadata fields.
|
|
248
|
+
* @param {import('node:sqlite').DatabaseSync} db - node:sqlite DatabaseSync instance
|
|
249
|
+
* @param {number} sessionId - Session ID to end
|
|
250
|
+
* @param {object} [opts={}] - Optional fields
|
|
251
|
+
* @param {string} [opts.summary] - Session summary
|
|
252
|
+
* @param {Array|string} [opts.key_decisions] - Key decisions (array or JSON string)
|
|
253
|
+
* @param {Array|string} [opts.open_questions] - Open questions (array or JSON string)
|
|
254
|
+
* @param {string} [opts.methodology_used] - Methodology used
|
|
255
|
+
* @param {Array|string} [opts.artifacts_filed] - Artifacts filed (array or JSON string)
|
|
256
|
+
* @returns {Promise<{success: boolean, id: number, ended_at: string}>}
|
|
257
|
+
*/
|
|
258
|
+
async function endSession(db, sessionId, opts = {}) {
|
|
259
|
+
const endedAt = new Date().toISOString();
|
|
260
|
+
const summary = opts.summary || null;
|
|
261
|
+
const methodologyUsed = opts.methodology_used || null;
|
|
262
|
+
|
|
263
|
+
// JSON fields: if array, stringify; if string, use as-is; if undefined, use default '[]'
|
|
264
|
+
const keyDecisions = Array.isArray(opts.key_decisions)
|
|
265
|
+
? JSON.stringify(opts.key_decisions)
|
|
266
|
+
: (typeof opts.key_decisions === 'string' ? opts.key_decisions : '[]');
|
|
267
|
+
const openQuestions = Array.isArray(opts.open_questions)
|
|
268
|
+
? JSON.stringify(opts.open_questions)
|
|
269
|
+
: (typeof opts.open_questions === 'string' ? opts.open_questions : '[]');
|
|
270
|
+
const artifactsFiled = Array.isArray(opts.artifacts_filed)
|
|
271
|
+
? JSON.stringify(opts.artifacts_filed)
|
|
272
|
+
: (typeof opts.artifacts_filed === 'string' ? opts.artifacts_filed : '[]');
|
|
273
|
+
|
|
274
|
+
db.prepare(
|
|
275
|
+
'UPDATE sessions SET ended_at = ?, summary = ?, key_decisions = ?, open_questions = ?, methodology_used = ?, artifacts_filed = ? WHERE id = ?'
|
|
276
|
+
).run(endedAt, summary, keyDecisions, openQuestions, methodologyUsed, artifactsFiled, sessionId);
|
|
277
|
+
|
|
278
|
+
return Promise.resolve({ success: true, id: sessionId, ended_at: endedAt });
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// --- L3 Fragments ---
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Add a conversation fragment linked to a session.
|
|
285
|
+
* @param {import('node:sqlite').DatabaseSync} db - node:sqlite DatabaseSync instance
|
|
286
|
+
* @param {object} fragment - Fragment data
|
|
287
|
+
* @param {number} fragment.session_id - Parent session ID (FK)
|
|
288
|
+
* @param {string} fragment.role - Speaker role (e.g. 'user', 'assistant')
|
|
289
|
+
* @param {string} fragment.content - Message content
|
|
290
|
+
* @param {string} [fragment.section_context] - Room section context
|
|
291
|
+
* @returns {Promise<{id: number, session_id: number, timestamp: string}>}
|
|
292
|
+
*/
|
|
293
|
+
async function addFragment(db, fragment) {
|
|
294
|
+
const timestamp = new Date().toISOString();
|
|
295
|
+
const sectionContext = fragment.section_context || null;
|
|
296
|
+
|
|
297
|
+
const info = db.prepare(
|
|
298
|
+
'INSERT INTO fragments (session_id, role, content, timestamp, section_context) VALUES (?, ?, ?, ?, ?)'
|
|
299
|
+
).run(fragment.session_id, fragment.role, fragment.content, timestamp, sectionContext);
|
|
300
|
+
|
|
301
|
+
return Promise.resolve({
|
|
302
|
+
id: Number(info.lastInsertRowid),
|
|
303
|
+
session_id: fragment.session_id,
|
|
304
|
+
timestamp,
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Get session history with nested fragments, ordered by started_at DESC.
|
|
310
|
+
* @param {import('node:sqlite').DatabaseSync} db - node:sqlite DatabaseSync instance
|
|
311
|
+
* @param {number} [limit=10] - Maximum number of sessions to return
|
|
312
|
+
* @returns {Promise<Array<object>>} Sessions with fragments array property
|
|
313
|
+
*/
|
|
314
|
+
async function getSessionHistory(db, limit) {
|
|
315
|
+
const effectiveLimit = typeof limit === 'number' ? limit : 10;
|
|
316
|
+
|
|
317
|
+
const sessions = db.prepare(
|
|
318
|
+
'SELECT * FROM sessions ORDER BY started_at DESC LIMIT ?'
|
|
319
|
+
).all(effectiveLimit);
|
|
320
|
+
|
|
321
|
+
const fragStmt = db.prepare(
|
|
322
|
+
'SELECT * FROM fragments WHERE session_id = ? ORDER BY timestamp ASC'
|
|
323
|
+
);
|
|
324
|
+
|
|
325
|
+
for (const session of sessions) {
|
|
326
|
+
session.fragments = fragStmt.all(session.id);
|
|
327
|
+
// Parse JSON fields
|
|
328
|
+
try { session.key_decisions = JSON.parse(session.key_decisions); } catch { session.key_decisions = []; }
|
|
329
|
+
try { session.open_questions = JSON.parse(session.open_questions); } catch { session.open_questions = []; }
|
|
330
|
+
try { session.artifacts_filed = JSON.parse(session.artifacts_filed); } catch { session.artifacts_filed = []; }
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
return Promise.resolve(sessions);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// --- Assumptions ---
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Create an assumption with validity = 'untested'.
|
|
340
|
+
* @param {import('node:sqlite').DatabaseSync} db - node:sqlite DatabaseSync instance
|
|
341
|
+
* @param {object} opts - Assumption data
|
|
342
|
+
* @param {string} opts.claim - The assumption claim text
|
|
343
|
+
* @param {string} [opts.section] - Room section this assumption belongs to
|
|
344
|
+
* @returns {Promise<{id: number, claim: string, section: string|null, validity: string, created_at: string}>}
|
|
345
|
+
*/
|
|
346
|
+
async function createAssumption(db, opts) {
|
|
347
|
+
const createdAt = new Date().toISOString();
|
|
348
|
+
const section = opts.section || null;
|
|
349
|
+
|
|
350
|
+
const info = db.prepare(
|
|
351
|
+
'INSERT INTO assumptions (claim, section, created_at) VALUES (?, ?, ?)'
|
|
352
|
+
).run(opts.claim, section, createdAt);
|
|
353
|
+
|
|
354
|
+
return Promise.resolve({
|
|
355
|
+
id: Number(info.lastInsertRowid),
|
|
356
|
+
claim: opts.claim,
|
|
357
|
+
section,
|
|
358
|
+
validity: 'untested',
|
|
359
|
+
created_at: createdAt,
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Update an assumption's validity status and evidence arrays.
|
|
365
|
+
* @param {import('node:sqlite').DatabaseSync} db - node:sqlite DatabaseSync instance
|
|
366
|
+
* @param {number} assumptionId - Assumption ID to update
|
|
367
|
+
* @param {string} newValidity - New validity ('supported', 'contradicted', 'stale')
|
|
368
|
+
* @param {object} [opts={}] - Options
|
|
369
|
+
* @param {string} [opts.evidence] - Evidence artifact/source that changed validity
|
|
370
|
+
* @returns {Promise<{success: boolean, id: number, validity: string}>}
|
|
371
|
+
*/
|
|
372
|
+
async function updateAssumptionValidity(db, assumptionId, newValidity, opts = {}) {
|
|
373
|
+
const lastTested = new Date().toISOString();
|
|
374
|
+
|
|
375
|
+
// Read current assumption
|
|
376
|
+
const current = db.prepare('SELECT * FROM assumptions WHERE id = ?').get(assumptionId);
|
|
377
|
+
if (!current) {
|
|
378
|
+
throw new Error(`Assumption ${assumptionId} not found`);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// Parse existing evidence arrays
|
|
382
|
+
let evidenceFor;
|
|
383
|
+
let evidenceAgainst;
|
|
384
|
+
try { evidenceFor = JSON.parse(current.evidence_for); } catch { evidenceFor = []; }
|
|
385
|
+
try { evidenceAgainst = JSON.parse(current.evidence_against); } catch { evidenceAgainst = []; }
|
|
386
|
+
|
|
387
|
+
// Append evidence based on validity direction
|
|
388
|
+
if (newValidity === 'supported' && opts.evidence) {
|
|
389
|
+
evidenceFor.push(opts.evidence);
|
|
390
|
+
} else if (newValidity === 'contradicted' && opts.evidence) {
|
|
391
|
+
evidenceAgainst.push(opts.evidence);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Set invalidated_at for stale
|
|
395
|
+
const invalidatedAt = newValidity === 'stale' ? lastTested : current.invalidated_at;
|
|
396
|
+
|
|
397
|
+
db.prepare(
|
|
398
|
+
'UPDATE assumptions SET validity = ?, evidence_for = ?, evidence_against = ?, last_tested = ?, invalidated_at = ? WHERE id = ?'
|
|
399
|
+
).run(newValidity, JSON.stringify(evidenceFor), JSON.stringify(evidenceAgainst), lastTested, invalidatedAt, assumptionId);
|
|
400
|
+
|
|
401
|
+
return Promise.resolve({ success: true, id: assumptionId, validity: newValidity });
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Get assumptions, optionally filtered by section and/or validity.
|
|
406
|
+
* @param {import('node:sqlite').DatabaseSync} db - node:sqlite DatabaseSync instance
|
|
407
|
+
* @param {object} [filters={}] - Optional filters
|
|
408
|
+
* @param {string} [filters.section] - Filter by room section
|
|
409
|
+
* @param {string} [filters.validity] - Filter by validity status
|
|
410
|
+
* @returns {Promise<Array<object>>}
|
|
411
|
+
*/
|
|
412
|
+
async function getAssumptions(db, filters = {}) {
|
|
413
|
+
let query = 'SELECT * FROM assumptions';
|
|
414
|
+
const conditions = [];
|
|
415
|
+
const params = [];
|
|
416
|
+
|
|
417
|
+
if (filters.section) {
|
|
418
|
+
conditions.push('section = ?');
|
|
419
|
+
params.push(filters.section);
|
|
420
|
+
}
|
|
421
|
+
if (filters.validity) {
|
|
422
|
+
conditions.push('validity = ?');
|
|
423
|
+
params.push(filters.validity);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
if (conditions.length > 0) {
|
|
427
|
+
query += ' WHERE ' + conditions.join(' AND ');
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
const rows = db.prepare(query).all(...params);
|
|
431
|
+
|
|
432
|
+
// Parse JSON evidence fields
|
|
433
|
+
for (const row of rows) {
|
|
434
|
+
try { row.evidence_for = JSON.parse(row.evidence_for); } catch { row.evidence_for = []; }
|
|
435
|
+
try { row.evidence_against = JSON.parse(row.evidence_against); } catch { row.evidence_against = []; }
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
return Promise.resolve(rows);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// --- Scaffold + Voice Log Helpers (Phase 84) ---
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* Insert a row into scaffold_log. Records a materialization audit event.
|
|
445
|
+
* @param {import('node:sqlite').DatabaseSync} db - node:sqlite DatabaseSync instance
|
|
446
|
+
* @param {object} opts
|
|
447
|
+
* @param {string} opts.action - e.g. 'materialize', 'dematerialize'
|
|
448
|
+
* @param {string} opts.section - Room section name
|
|
449
|
+
* @param {string} [opts.collection] - Optional collection identifier
|
|
450
|
+
* @param {string} [opts.user_reason] - Optional user-provided reason
|
|
451
|
+
* @param {string} opts.surface - 'cli' | 'desktop' | 'cowork'
|
|
452
|
+
* @returns {Promise<{id: number, timestamp: string}>}
|
|
453
|
+
*/
|
|
454
|
+
async function logScaffoldAction(db, opts) {
|
|
455
|
+
const timestamp = new Date().toISOString();
|
|
456
|
+
const collection = opts.collection || null;
|
|
457
|
+
const userReason = opts.user_reason || null;
|
|
458
|
+
|
|
459
|
+
const info = db.prepare(
|
|
460
|
+
'INSERT INTO scaffold_log (timestamp, action, section, collection, user_reason, surface) VALUES (?, ?, ?, ?, ?, ?)'
|
|
461
|
+
).run(timestamp, opts.action, opts.section, collection, userReason, opts.surface);
|
|
462
|
+
|
|
463
|
+
return Promise.resolve({
|
|
464
|
+
id: Number(info.lastInsertRowid),
|
|
465
|
+
timestamp,
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Insert a structured row into voice_log built from a closing session's
|
|
471
|
+
* fragments. Phase 84-07 writer half: replaces the stub call in
|
|
472
|
+
* memory-lifecycle.cjs stop with a row that captures the session's question,
|
|
473
|
+
* answer summary, cited artifacts, and any contradictions flagged by the
|
|
474
|
+
* proactive-intelligence layer. Additive alongside writeVoiceLogStub, which
|
|
475
|
+
* remains the fallback for sessions with zero captured fragments.
|
|
476
|
+
*
|
|
477
|
+
* Truncation is codepoint-safe (Array.from -> slice -> join) so multi-byte
|
|
478
|
+
* characters are not cut mid-sequence. JSON arrays are stringified before
|
|
479
|
+
* insert. confidence stays null in v1.10.8; a future analysis pass will
|
|
480
|
+
* populate it.
|
|
481
|
+
*
|
|
482
|
+
* @param {import('node:sqlite').DatabaseSync} db - node:sqlite DatabaseSync instance
|
|
483
|
+
* @param {object} opts
|
|
484
|
+
* @param {string} opts.command - Command/context the session was for
|
|
485
|
+
* @param {string} [opts.question] - First user fragment content
|
|
486
|
+
* @param {string} [opts.answer_summary] - Last assistant fragment or summary
|
|
487
|
+
* @param {Array<string>} [opts.artifacts_cited] - Artifact IDs referenced
|
|
488
|
+
* @param {number|null} [opts.confidence] - 1-5 integer or null
|
|
489
|
+
* @param {Array<string>} [opts.contradictions_flagged] - Contradiction IDs
|
|
490
|
+
* @returns {Promise<{id: number, timestamp: string}>}
|
|
491
|
+
*/
|
|
492
|
+
async function writeVoiceLogRow(db, opts) {
|
|
493
|
+
const TRUNCATE = 200;
|
|
494
|
+
function truncCodepoints(s, n) {
|
|
495
|
+
if (typeof s !== 'string' || s.length === 0) return null;
|
|
496
|
+
const arr = Array.from(s);
|
|
497
|
+
if (arr.length <= n) return s;
|
|
498
|
+
return arr.slice(0, n).join('');
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
try {
|
|
502
|
+
const timestamp = new Date().toISOString();
|
|
503
|
+
const command = (opts && typeof opts.command === 'string' && opts.command) || 'session-summary';
|
|
504
|
+
const question = truncCodepoints(opts && opts.question, TRUNCATE);
|
|
505
|
+
const answerSummary = truncCodepoints(opts && opts.answer_summary, TRUNCATE);
|
|
506
|
+
const artifactsCited = JSON.stringify(
|
|
507
|
+
Array.isArray(opts && opts.artifacts_cited) ? opts.artifacts_cited : []
|
|
508
|
+
);
|
|
509
|
+
const confidence = (opts && typeof opts.confidence === 'number') ? opts.confidence : null;
|
|
510
|
+
const contradictionsFlagged = JSON.stringify(
|
|
511
|
+
Array.isArray(opts && opts.contradictions_flagged) ? opts.contradictions_flagged : []
|
|
512
|
+
);
|
|
513
|
+
|
|
514
|
+
const info = db.prepare(
|
|
515
|
+
'INSERT INTO voice_log (timestamp, command, question, answer_summary, artifacts_cited, confidence, contradictions_flagged) VALUES (?, ?, ?, ?, ?, ?, ?)'
|
|
516
|
+
).run(timestamp, command, question, answerSummary, artifactsCited, confidence, contradictionsFlagged);
|
|
517
|
+
|
|
518
|
+
return Promise.resolve({
|
|
519
|
+
id: Number(info.lastInsertRowid),
|
|
520
|
+
timestamp,
|
|
521
|
+
});
|
|
522
|
+
} catch (_) {
|
|
523
|
+
return Promise.resolve({ id: 0, timestamp: new Date().toISOString() });
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Read the latest voice_log row for a given session. Phase 84-07 reader half.
|
|
529
|
+
* Returns null when no row exists. Errors are swallowed (advisory contract:
|
|
530
|
+
* the on-stop hook must never crash because voice-log read failed).
|
|
531
|
+
*
|
|
532
|
+
* The voice_log table has no session_id column in v1.10.8 (the schema in
|
|
533
|
+
* 84-01 keys voice rows by timestamp). This helper returns the most recent
|
|
534
|
+
* row globally for the active room db, which in the on-stop flow is the row
|
|
535
|
+
* just written by writeVoiceLogRow for the closing session. Future schema
|
|
536
|
+
* iterations may add a session_id FK; until then "latest row" is the
|
|
537
|
+
* advisory contract.
|
|
538
|
+
*
|
|
539
|
+
* @param {import('node:sqlite').DatabaseSync} db
|
|
540
|
+
* @returns {Promise<object|null>}
|
|
541
|
+
*/
|
|
542
|
+
async function readVoiceLogTail(db) {
|
|
543
|
+
try {
|
|
544
|
+
const row = db.prepare(
|
|
545
|
+
'SELECT id, timestamp, command, question, answer_summary, artifacts_cited, confidence, contradictions_flagged FROM voice_log ORDER BY id DESC LIMIT 1'
|
|
546
|
+
).get();
|
|
547
|
+
if (!row) return Promise.resolve(null);
|
|
548
|
+
try { row.artifacts_cited = JSON.parse(row.artifacts_cited); } catch { row.artifacts_cited = []; }
|
|
549
|
+
try { row.contradictions_flagged = JSON.parse(row.contradictions_flagged); } catch { row.contradictions_flagged = []; }
|
|
550
|
+
return Promise.resolve(row);
|
|
551
|
+
} catch (_) {
|
|
552
|
+
return Promise.resolve(null);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
/**
|
|
557
|
+
* Insert a stub row into voice_log. Used by PostCompact/Stop hooks in v1.10.8
|
|
558
|
+
* to reserve schema space for the synthesis voice. question/confidence are null,
|
|
559
|
+
* artifacts_cited and contradictions_flagged default to '[]'.
|
|
560
|
+
* @param {import('node:sqlite').DatabaseSync} db - node:sqlite DatabaseSync instance
|
|
561
|
+
* @param {object} opts
|
|
562
|
+
* @param {string} opts.command - Command that triggered the stub write
|
|
563
|
+
* @param {string} [opts.answer_summary] - Optional summary text
|
|
564
|
+
* @returns {Promise<{id: number, timestamp: string}>}
|
|
565
|
+
*/
|
|
566
|
+
async function writeVoiceLogStub(db, opts) {
|
|
567
|
+
const timestamp = new Date().toISOString();
|
|
568
|
+
const answerSummary = opts.answer_summary || null;
|
|
569
|
+
|
|
570
|
+
const info = db.prepare(
|
|
571
|
+
'INSERT INTO voice_log (timestamp, command, question, answer_summary, artifacts_cited, confidence, contradictions_flagged) VALUES (?, ?, ?, ?, ?, ?, ?)'
|
|
572
|
+
).run(timestamp, opts.command, null, answerSummary, '[]', null, '[]');
|
|
573
|
+
|
|
574
|
+
return Promise.resolve({
|
|
575
|
+
id: Number(info.lastInsertRowid),
|
|
576
|
+
timestamp,
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// --- Exports ---
|
|
581
|
+
|
|
582
|
+
module.exports = {
|
|
583
|
+
initMemorySchema,
|
|
584
|
+
setIdentity,
|
|
585
|
+
getIdentity,
|
|
586
|
+
addFact,
|
|
587
|
+
getValidFacts,
|
|
588
|
+
invalidateFact,
|
|
589
|
+
startSession,
|
|
590
|
+
endSession,
|
|
591
|
+
addFragment,
|
|
592
|
+
getSessionHistory,
|
|
593
|
+
createAssumption,
|
|
594
|
+
updateAssumptionValidity,
|
|
595
|
+
getAssumptions,
|
|
596
|
+
logScaffoldAction,
|
|
597
|
+
writeVoiceLogStub,
|
|
598
|
+
writeVoiceLogRow,
|
|
599
|
+
readVoiceLogTail,
|
|
600
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# lib/core/migrations/
|
|
2
|
+
|
|
3
|
+
ICM Layer 0 identity for the Phase 109 migrations directory.
|
|
4
|
+
|
|
5
|
+
Phase-scoped idempotent SQLite migrations for room.db. Each migration is a CJS
|
|
6
|
+
module exporting runMigration(db) that:
|
|
7
|
+
|
|
8
|
+
1. Checks an identity table sentinel row (key = 'phase_NNN_migration_vN').
|
|
9
|
+
2. If present, returns { applied: false } without touching the schema.
|
|
10
|
+
3. If absent, runs the migration in a single BEGIN/COMMIT transaction and
|
|
11
|
+
inserts the sentinel row at the end.
|
|
12
|
+
|
|
13
|
+
Migrations are CALLED from lib/core/room-db.cjs openRoomDb composition entry
|
|
14
|
+
point. Every caller of openRoomDb sees migrated schema. Cold and warm calls
|
|
15
|
+
return identical handles.
|
|
16
|
+
|
|
17
|
+
## Current migrations
|
|
18
|
+
|
|
19
|
+
- phase-109-nodes-provenance.cjs: 9-column provenance addition to nodes table
|
|
20
|
+
per PROVENANCE.md (Plan 108-02); status_aliases backfill of assumptions to
|
|
21
|
+
graph nodes per TRUTH-STATES.md (Plan 108-03); 6 new indices; closed-enum
|
|
22
|
+
CHECK constraints on created_by and review_status.
|
|
23
|
+
|
|
24
|
+
## Invariants (Canon Part 8)
|
|
25
|
+
|
|
26
|
+
- Migrations write only to room.db.
|
|
27
|
+
- Zero Brain queries.
|
|
28
|
+
- Zero remote egress.
|
|
29
|
+
- Sentinel row in identity table is local-only.
|
|
30
|
+
|
|
31
|
+
## Owner
|
|
32
|
+
|
|
33
|
+
Phase 109 SQL Context-Memory Navigation Spine.
|