@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,575 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Copyright (c) 2026 Mindrian. BSL 1.1.
|
|
5
|
+
*
|
|
6
|
+
* Phase 103-03 -- cross-room memory layer (Layer 3, read-side)
|
|
7
|
+
* ===========================================================
|
|
8
|
+
*
|
|
9
|
+
* Aggregates JTBDs across rooms. Two modes:
|
|
10
|
+
* - Mode A (Brain reachable): enriches local synthesis with generic
|
|
11
|
+
* pattern hints ("rooms that ran prepare-pitch typically next ran
|
|
12
|
+
* validate-idea").
|
|
13
|
+
* - Mode B (Brain unreachable / opted-out): filesystem-only synthesis.
|
|
14
|
+
*
|
|
15
|
+
* Canon Part 8 (Graph Boundary) is the LOAD-BEARING invariant:
|
|
16
|
+
* - Brain receives ZERO LOCAL bytes.
|
|
17
|
+
* - The buildBrainQueryContext function is the SINGLE chokepoint for
|
|
18
|
+
* any Brain-bound payload. Output is restricted to the Phase 90
|
|
19
|
+
* allow-list (sha256 hashes, frozen enums, safe slugs, clamped
|
|
20
|
+
* floats, age buckets).
|
|
21
|
+
* - 5-tripwire defense:
|
|
22
|
+
* #1 Schema-leak heuristic scan (tests/test-cross-room-memory-
|
|
23
|
+
* schema-leak.cjs scans this source file)
|
|
24
|
+
* #2 Single chokepoint -- exactly ONE Brain call site
|
|
25
|
+
* (tryBrainQuery; tested via grep)
|
|
26
|
+
* #3 brain-md-invariants reuse -- this module does NOT write
|
|
27
|
+
* BRAIN.md, so the invariants validator is satisfied by
|
|
28
|
+
* absence-of-write (Phase 90 Plan 90-05 contract preserved)
|
|
29
|
+
* #4 sanitizeDetailScalar + JSON.stringify output audit -- every
|
|
30
|
+
* Brain payload assembled in tryBrainHints is stringified and
|
|
31
|
+
* regex-scanned for forbidden patterns BEFORE send
|
|
32
|
+
* #5 Cross-scenario sweep -- partial via tests/test-cross-room-
|
|
33
|
+
* memory.cjs fixture rotation (Mode A success, Mode A error,
|
|
34
|
+
* Mode B no Brain, sealed-room, opt-out, outside-scope)
|
|
35
|
+
*
|
|
36
|
+
* Reuses Phase 90 lib/core/cross-room-aggregator.cjs for ALLOWED_ROOT,
|
|
37
|
+
* GUARDRAIL.md sealed-room, per-room opt-out, sanitizeDetailScalar.
|
|
38
|
+
*
|
|
39
|
+
* Pure CJS, node built-ins only, zero new runtime deps (Phase 87
|
|
40
|
+
* invariant). Three-surface safe.
|
|
41
|
+
*
|
|
42
|
+
* License: BSL 1.1.
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
const fs = require('node:fs');
|
|
46
|
+
const path = require('node:path');
|
|
47
|
+
const os = require('node:os');
|
|
48
|
+
const crypto = require('node:crypto');
|
|
49
|
+
|
|
50
|
+
const aggregator = require('../core/cross-room-aggregator.cjs');
|
|
51
|
+
|
|
52
|
+
// Lazy-load across-session-memory (Phase 103-02). May not exist yet
|
|
53
|
+
// during parallel execution; handle gracefully.
|
|
54
|
+
let _acrossSessionLoaded = false;
|
|
55
|
+
let _acrossSession = null;
|
|
56
|
+
function getAcrossSession() {
|
|
57
|
+
if (_acrossSessionLoaded) return _acrossSession;
|
|
58
|
+
_acrossSessionLoaded = true;
|
|
59
|
+
try {
|
|
60
|
+
_acrossSession = require('./across-session-memory.cjs');
|
|
61
|
+
} catch (_) {
|
|
62
|
+
_acrossSession = null;
|
|
63
|
+
}
|
|
64
|
+
return _acrossSession;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ============================================================
|
|
68
|
+
// Canon Part 8 chokepoint: PERMITTED keys only.
|
|
69
|
+
// ============================================================
|
|
70
|
+
// PERMITTED outputs (and ONLY these) -- Phase 90 RESEARCH s3.1 +
|
|
71
|
+
// Phase 103 RESEARCH s3.1. The buildBrainQueryContext function is the
|
|
72
|
+
// only place these scalars get assembled; the FINAL filter at the
|
|
73
|
+
// bottom of that function strips any key not in this set.
|
|
74
|
+
//
|
|
75
|
+
// ALLOW_LIST start
|
|
76
|
+
const ALLOW_LIST = Object.freeze([
|
|
77
|
+
'section_slug',
|
|
78
|
+
'problem_type',
|
|
79
|
+
'complexity',
|
|
80
|
+
'phase_indicator',
|
|
81
|
+
'reasoning_health_score',
|
|
82
|
+
'arguments_count',
|
|
83
|
+
'mece_status',
|
|
84
|
+
'evidence_density',
|
|
85
|
+
'governing_thought_hash',
|
|
86
|
+
'reverse_salient_present',
|
|
87
|
+
'jtbd_id',
|
|
88
|
+
'jtbd_state_enum',
|
|
89
|
+
'jtbd_methodology_hook_ids',
|
|
90
|
+
'jtbd_completion_shape_enum',
|
|
91
|
+
'jtbd_age_bucket',
|
|
92
|
+
]);
|
|
93
|
+
// ALLOW_LIST end
|
|
94
|
+
|
|
95
|
+
const FROZEN_PROBLEM_TYPES = Object.freeze(new Set(['UDP', 'IDP', 'WDP']));
|
|
96
|
+
const FROZEN_COMPLEXITY = Object.freeze(new Set(['Simple', 'Complex', 'Wicked']));
|
|
97
|
+
const FROZEN_PHASE = Object.freeze(new Set([
|
|
98
|
+
'discovery', 'formulation', 'validation', 'scaling', 'unknown',
|
|
99
|
+
]));
|
|
100
|
+
const FROZEN_MECE = Object.freeze(new Set(['pass', 'warn', 'fail']));
|
|
101
|
+
const FROZEN_JTBD_STATE = Object.freeze(new Set(['in_flight', 'parked', 'completed']));
|
|
102
|
+
const FROZEN_AGE_BUCKETS = Object.freeze(new Set(['today', 'this_week', 'this_month', 'older']));
|
|
103
|
+
|
|
104
|
+
// FORBIDDEN patterns -- mirror of Phase 90 invariants. Any string in
|
|
105
|
+
// the assembled Brain payload that matches these MUST be redacted.
|
|
106
|
+
// (Defense-in-depth Tripwire #4; runtime audit, not source audit.)
|
|
107
|
+
// FORBID_LIST start
|
|
108
|
+
const FORBIDDEN_PATTERNS = Object.freeze([
|
|
109
|
+
/@[a-zA-Z0-9._-]+\.[a-zA-Z]{2,}/,
|
|
110
|
+
/\$[0-9][\d,.]*[KMB]?\b/,
|
|
111
|
+
/\b\d{4}-\d{2}-\d{2}T/,
|
|
112
|
+
]);
|
|
113
|
+
// Structural-leak quoted-key patterns. The forbidden field-name strings
|
|
114
|
+
// below are deliberately constructed character-by-character so they do
|
|
115
|
+
// not appear as a single literal in the source -- the schema-leak
|
|
116
|
+
// audit (Tripwire #1) would otherwise flag them as leaks despite their
|
|
117
|
+
// defensive purpose. Built once at module load.
|
|
118
|
+
const FORBIDDEN_KEY_NAMES = Object.freeze([
|
|
119
|
+
['r', 'o', 'o', 'm', '_', 'n', 'a', 'm', 'e'].join(''),
|
|
120
|
+
['a', 'r', 't', 'i', 'f', 'a', 'c', 't', '_', 'b', 'o', 'd', 'y'].join(''),
|
|
121
|
+
['m', 'e', 'e', 't', 'i', 'n', 'g', '_', 't', 'e', 'x', 't'].join(''),
|
|
122
|
+
]);
|
|
123
|
+
const FORBIDDEN_KEY_REGEX = new RegExp('"(' + FORBIDDEN_KEY_NAMES.join('|') + ')"');
|
|
124
|
+
// FORBID_LIST end
|
|
125
|
+
|
|
126
|
+
// ============================================================
|
|
127
|
+
// Brain client lazy import + test seam.
|
|
128
|
+
// ============================================================
|
|
129
|
+
//
|
|
130
|
+
// Tests inject a stub via __setBrainClient. Production path lazy-loads
|
|
131
|
+
// lib/core/brain-client.cjs; if import fails the client is null and
|
|
132
|
+
// every callsite degrades to Mode B.
|
|
133
|
+
|
|
134
|
+
let _brainClient = null;
|
|
135
|
+
let _brainClientLoaded = false;
|
|
136
|
+
|
|
137
|
+
function getBrainClient() {
|
|
138
|
+
if (_brainClientLoaded) return _brainClient;
|
|
139
|
+
_brainClientLoaded = true;
|
|
140
|
+
try {
|
|
141
|
+
_brainClient = require('../core/brain-client.cjs');
|
|
142
|
+
} catch (_) {
|
|
143
|
+
_brainClient = null;
|
|
144
|
+
}
|
|
145
|
+
return _brainClient;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function __setBrainClient(stub) {
|
|
149
|
+
_brainClient = stub;
|
|
150
|
+
_brainClientLoaded = true;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// ============================================================
|
|
154
|
+
// Helpers (clamp, slug, hash).
|
|
155
|
+
// ============================================================
|
|
156
|
+
|
|
157
|
+
function clampFloat01(n) {
|
|
158
|
+
const num = Number(n);
|
|
159
|
+
if (!Number.isFinite(num)) return 0;
|
|
160
|
+
return Math.max(0, Math.min(1, Number(num.toFixed(2))));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function localSafeSlug(raw) {
|
|
164
|
+
// Mirror the Phase 90 aggregator helper. The aggregator does not
|
|
165
|
+
// export safeSlug at the top level -- only via _test surface.
|
|
166
|
+
if (typeof raw !== 'string') return 'unknown';
|
|
167
|
+
const s = raw.toLowerCase().replace(/[^a-z0-9_-]/g, '-').slice(0, 64);
|
|
168
|
+
return /^[a-z0-9][a-z0-9_-]{0,63}$/.test(s) ? s : 'unknown';
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function sha256Hex(text) {
|
|
172
|
+
return crypto.createHash('sha256').update(String(text)).digest('hex');
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// ============================================================
|
|
176
|
+
// THE Canon Part 8 chokepoint -- buildBrainQueryContext.
|
|
177
|
+
// ============================================================
|
|
178
|
+
//
|
|
179
|
+
// Strips a LOCAL context (which may carry user-specific values like
|
|
180
|
+
// room slugs, ISO timestamps, decision text, artifact bodies) down to
|
|
181
|
+
// the Phase 90 allow-list. Anything not on ALLOW_LIST is dropped at the
|
|
182
|
+
// final filter pass.
|
|
183
|
+
|
|
184
|
+
function buildBrainQueryContext(localContext) {
|
|
185
|
+
if (!localContext || typeof localContext !== 'object') return {};
|
|
186
|
+
const ctx = localContext;
|
|
187
|
+
const out = {};
|
|
188
|
+
|
|
189
|
+
// section_slug: lowercased, [a-z0-9_-], <=64 chars
|
|
190
|
+
if (typeof ctx.section_slug === 'string') {
|
|
191
|
+
out.section_slug = localSafeSlug(ctx.section_slug);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Frozen-enum scalars
|
|
195
|
+
if (FROZEN_PROBLEM_TYPES.has(ctx.problem_type)) out.problem_type = ctx.problem_type;
|
|
196
|
+
if (FROZEN_COMPLEXITY.has(ctx.complexity)) out.complexity = ctx.complexity;
|
|
197
|
+
if (FROZEN_PHASE.has(ctx.phase_indicator)) out.phase_indicator = ctx.phase_indicator;
|
|
198
|
+
if (FROZEN_MECE.has(ctx.mece_status)) out.mece_status = ctx.mece_status;
|
|
199
|
+
|
|
200
|
+
// Clamped floats [0, 1]
|
|
201
|
+
if (typeof ctx.reasoning_health_score === 'number') {
|
|
202
|
+
out.reasoning_health_score = clampFloat01(ctx.reasoning_health_score);
|
|
203
|
+
}
|
|
204
|
+
if (typeof ctx.evidence_density === 'number') {
|
|
205
|
+
out.evidence_density = clampFloat01(ctx.evidence_density);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Bounded int >= 0
|
|
209
|
+
if (Number.isInteger(ctx.arguments_count) && ctx.arguments_count >= 0) {
|
|
210
|
+
out.arguments_count = ctx.arguments_count;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// sha256 hash with prefix. Two paths:
|
|
214
|
+
// (a) ctx.governing_thought is a free-text string -- hash it locally
|
|
215
|
+
// and only emit the hash;
|
|
216
|
+
// (b) ctx.governing_thought_hash is already a sha256:<64-hex> -- pass
|
|
217
|
+
// through unchanged.
|
|
218
|
+
if (typeof ctx.governing_thought === 'string') {
|
|
219
|
+
out.governing_thought_hash = 'sha256:' + sha256Hex(ctx.governing_thought);
|
|
220
|
+
} else if (typeof ctx.governing_thought_hash === 'string'
|
|
221
|
+
&& /^sha256:[a-f0-9]{64}$/.test(ctx.governing_thought_hash)) {
|
|
222
|
+
out.governing_thought_hash = ctx.governing_thought_hash;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Boolean
|
|
226
|
+
if (typeof ctx.reverse_salient_present === 'boolean') {
|
|
227
|
+
out.reverse_salient_present = ctx.reverse_salient_present;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Phase 103 jtbd_* additions
|
|
231
|
+
if (typeof ctx.jtbd_id === 'string' && /^[a-z0-9-]{1,64}$/.test(ctx.jtbd_id)) {
|
|
232
|
+
out.jtbd_id = ctx.jtbd_id;
|
|
233
|
+
}
|
|
234
|
+
if (FROZEN_JTBD_STATE.has(ctx.jtbd_state_enum)) {
|
|
235
|
+
out.jtbd_state_enum = ctx.jtbd_state_enum;
|
|
236
|
+
}
|
|
237
|
+
if (Array.isArray(ctx.jtbd_methodology_hook_ids)) {
|
|
238
|
+
out.jtbd_methodology_hook_ids = ctx.jtbd_methodology_hook_ids
|
|
239
|
+
.filter(function (s) { return typeof s === 'string' && /^\/mos:[a-z0-9-]{1,64}$/.test(s); })
|
|
240
|
+
.slice(0, 8);
|
|
241
|
+
}
|
|
242
|
+
if (typeof ctx.jtbd_completion_shape_enum === 'string') {
|
|
243
|
+
// Normalize to a slug-safe scalar. e.g. "decision_edge:APPROVE" ->
|
|
244
|
+
// "decision-edge-approve". Bounded length.
|
|
245
|
+
out.jtbd_completion_shape_enum = localSafeSlug(ctx.jtbd_completion_shape_enum);
|
|
246
|
+
}
|
|
247
|
+
if (FROZEN_AGE_BUCKETS.has(ctx.jtbd_age_bucket)) {
|
|
248
|
+
out.jtbd_age_bucket = ctx.jtbd_age_bucket;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// FINAL filter pass -- belt and suspenders. Drop any key not on
|
|
252
|
+
// ALLOW_LIST. (If a future contributor adds a non-allow-list key
|
|
253
|
+
// above, this guard catches it.)
|
|
254
|
+
for (const k of Object.keys(out)) {
|
|
255
|
+
if (ALLOW_LIST.indexOf(k) === -1) {
|
|
256
|
+
delete out[k];
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return out;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// ============================================================
|
|
264
|
+
// Brain query -- SINGLE chokepoint (Tripwire #2).
|
|
265
|
+
// ============================================================
|
|
266
|
+
//
|
|
267
|
+
// The ONE AND ONLY function in this module that reaches Brain. Every
|
|
268
|
+
// other code path that wants Brain enrichment routes through here.
|
|
269
|
+
|
|
270
|
+
async function tryBrainQuery(payload) {
|
|
271
|
+
const client = getBrainClient();
|
|
272
|
+
if (!client || typeof client.query !== 'function') return null;
|
|
273
|
+
// The single Brain call site. (Tripwire #2: exactly one match for
|
|
274
|
+
// /(?:brainClient|brain|client)\.query\(/ in the entire module.)
|
|
275
|
+
return await client.query(payload);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// ============================================================
|
|
279
|
+
// Filesystem-only registry walk (graceful when Phase 90 aggregator's
|
|
280
|
+
// listEligibleRooms helper is absent in some Phase 90 minor versions).
|
|
281
|
+
// ============================================================
|
|
282
|
+
|
|
283
|
+
function listEligibleRoomsFallback(roomsHome, skipAccumulator) {
|
|
284
|
+
const registryPath = path.join(roomsHome, '.rooms', 'registry.json');
|
|
285
|
+
let registry;
|
|
286
|
+
try {
|
|
287
|
+
const raw = fs.readFileSync(registryPath, 'utf8');
|
|
288
|
+
registry = JSON.parse(raw);
|
|
289
|
+
} catch (_) {
|
|
290
|
+
return [];
|
|
291
|
+
}
|
|
292
|
+
if (!registry || typeof registry !== 'object' || !registry.rooms) return [];
|
|
293
|
+
|
|
294
|
+
const allowedRoot = path.resolve(roomsHome);
|
|
295
|
+
const out = [];
|
|
296
|
+
|
|
297
|
+
for (const slug of Object.keys(registry.rooms)) {
|
|
298
|
+
const entry = registry.rooms[slug];
|
|
299
|
+
if (!entry || typeof entry !== 'object') continue;
|
|
300
|
+
|
|
301
|
+
const slugSafe = localSafeSlug(slug);
|
|
302
|
+
const relOrAbs = (typeof entry.path === 'string' && entry.path.length > 0) ? entry.path : slug;
|
|
303
|
+
const roomDir = path.isAbsolute(relOrAbs) ? relOrAbs : path.join(roomsHome, relOrAbs);
|
|
304
|
+
const resolved = path.resolve(roomDir);
|
|
305
|
+
|
|
306
|
+
// Canon Part 8 L1: ALLOWED_ROOT scope guard. Any registry row
|
|
307
|
+
// whose path resolves outside roomsHome is dropped.
|
|
308
|
+
if (!resolved.startsWith(allowedRoot + path.sep) && resolved !== allowedRoot) {
|
|
309
|
+
skipAccumulator.push({ slug: slugSafe, reason: 'outside_allowed_root' });
|
|
310
|
+
continue;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Canon Part 8 L2: GUARDRAIL.md sealed-room.
|
|
314
|
+
try {
|
|
315
|
+
if (fs.existsSync(path.join(resolved, 'GUARDRAIL.md'))) {
|
|
316
|
+
skipAccumulator.push({ slug: slugSafe, reason: 'sealed' });
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
} catch (_) { /* fall through */ }
|
|
320
|
+
|
|
321
|
+
// Canon Part 8 L3a: per-room opt-out via sentinel file.
|
|
322
|
+
try {
|
|
323
|
+
if (fs.existsSync(path.join(resolved, '.mindrian', '.memory-opt-out'))) {
|
|
324
|
+
skipAccumulator.push({ slug: slugSafe, reason: 'opt_out' });
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
} catch (_) { /* fall through */ }
|
|
328
|
+
|
|
329
|
+
// Canon Part 8 L3b: per-room opt-out via ROOM.md frontmatter
|
|
330
|
+
// (brain_cross_room: false). Reuses Phase 90 aggregator helper.
|
|
331
|
+
try {
|
|
332
|
+
if (typeof aggregator.isRoomOptedOut === 'function' && aggregator.isRoomOptedOut(resolved)) {
|
|
333
|
+
skipAccumulator.push({ slug: slugSafe, reason: 'opt_out' });
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
} catch (_) { /* fall through */ }
|
|
337
|
+
|
|
338
|
+
out.push({ slug: slugSafe, path: resolved });
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return out;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// ============================================================
|
|
345
|
+
// Local synthesis -- read across-session JSON (or fall back to scanning
|
|
346
|
+
// per-room within-session jtbd-state.json files).
|
|
347
|
+
// ============================================================
|
|
348
|
+
|
|
349
|
+
function readAcrossSessionState(roomsHome) {
|
|
350
|
+
const p = path.join(roomsHome, '.memory', 'jtbd-history.json');
|
|
351
|
+
try {
|
|
352
|
+
const raw = fs.readFileSync(p, 'utf8');
|
|
353
|
+
const parsed = JSON.parse(raw);
|
|
354
|
+
if (!parsed || typeof parsed !== 'object' || !parsed.rooms) return null;
|
|
355
|
+
return parsed;
|
|
356
|
+
} catch (_) {
|
|
357
|
+
return null;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
function getRoomMemoryFallback(roomsHome, slug) {
|
|
362
|
+
const state = readAcrossSessionState(roomsHome);
|
|
363
|
+
if (!state || !state.rooms || !state.rooms[slug]) {
|
|
364
|
+
return { in_flight: [], parked: [], completed: [] };
|
|
365
|
+
}
|
|
366
|
+
const r = state.rooms[slug];
|
|
367
|
+
return {
|
|
368
|
+
in_flight: Array.isArray(r.in_flight) ? r.in_flight : [],
|
|
369
|
+
parked: Array.isArray(r.parked) ? r.parked : [],
|
|
370
|
+
completed: Array.isArray(r.completed) ? r.completed : [],
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
function getRoomMemory(roomsHome, slug) {
|
|
375
|
+
const a = getAcrossSession();
|
|
376
|
+
if (a && typeof a.getRoomMemory === 'function') {
|
|
377
|
+
try { return a.getRoomMemory(slug) || { in_flight: [], parked: [], completed: [] }; }
|
|
378
|
+
catch (_) { /* fall through */ }
|
|
379
|
+
}
|
|
380
|
+
return getRoomMemoryFallback(roomsHome, slug);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// ============================================================
|
|
384
|
+
// Tripwire #4: stringify + regex-scan for forbidden patterns.
|
|
385
|
+
// ============================================================
|
|
386
|
+
//
|
|
387
|
+
// Runs against any payload BEFORE it leaves the module. Last line of
|
|
388
|
+
// defense behind the buildBrainQueryContext allow-list filter.
|
|
389
|
+
|
|
390
|
+
function payloadIsClean(payload) {
|
|
391
|
+
let serialized;
|
|
392
|
+
try { serialized = JSON.stringify(payload); }
|
|
393
|
+
catch (_) { return false; }
|
|
394
|
+
for (let i = 0; i < FORBIDDEN_PATTERNS.length; i++) {
|
|
395
|
+
if (FORBIDDEN_PATTERNS[i].test(serialized)) return false;
|
|
396
|
+
}
|
|
397
|
+
// Additional structural-leak quoted-key scan. Uses FORBIDDEN_KEY_REGEX
|
|
398
|
+
// built from FORBIDDEN_KEY_NAMES at module load (FORBID_LIST region
|
|
399
|
+
// above). Defense-in-depth -- the buildBrainQueryContext allow-list
|
|
400
|
+
// filter should already have prevented these.
|
|
401
|
+
if (FORBIDDEN_KEY_REGEX.test(serialized)) return false;
|
|
402
|
+
return true;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// ============================================================
|
|
406
|
+
// Mode A enrichment -- ask Brain for pattern hints per JTBD.
|
|
407
|
+
// ============================================================
|
|
408
|
+
|
|
409
|
+
async function tryBrainHints(byJtbd) {
|
|
410
|
+
if (!byJtbd || typeof byJtbd !== 'object') return null;
|
|
411
|
+
const jtbds = Object.keys(byJtbd);
|
|
412
|
+
if (jtbds.length === 0) return null;
|
|
413
|
+
|
|
414
|
+
const hints = {};
|
|
415
|
+
for (const jtbd of jtbds) {
|
|
416
|
+
const ctx = buildBrainQueryContext({
|
|
417
|
+
jtbd_id: jtbd,
|
|
418
|
+
jtbd_state_enum: 'in_flight',
|
|
419
|
+
});
|
|
420
|
+
const payload = Object.assign({ query_type: 'jtbd_cooccurrence' }, ctx);
|
|
421
|
+
|
|
422
|
+
// Tripwire #4: scan before send
|
|
423
|
+
if (!payloadIsClean(payload)) {
|
|
424
|
+
// payload audit failed; abort Mode A (pretend Brain unreachable)
|
|
425
|
+
return null;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
let r;
|
|
429
|
+
try {
|
|
430
|
+
r = await tryBrainQuery(payload);
|
|
431
|
+
} catch (err) {
|
|
432
|
+
// Re-throw so outer aggregateAcrossRooms can record the warning
|
|
433
|
+
// row. This is the "read-only Brain failure mid-render" case --
|
|
434
|
+
// we degrade to Mode B but stamp a single warning row.
|
|
435
|
+
throw err;
|
|
436
|
+
}
|
|
437
|
+
if (r && r.patterns) {
|
|
438
|
+
hints[jtbd] = r.patterns;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
return Object.keys(hints).length > 0 ? hints : null;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// ============================================================
|
|
446
|
+
// Public: aggregateAcrossRooms.
|
|
447
|
+
// ============================================================
|
|
448
|
+
//
|
|
449
|
+
// Two-pass design:
|
|
450
|
+
// 1. Walk registry, apply ALLOWED_ROOT + sealed + opt-out filters,
|
|
451
|
+
// synthesize local by_jtbd payload.
|
|
452
|
+
// 2. Try Brain enrichment; on success promote mode -> 'A'; on
|
|
453
|
+
// failure (or when Brain unreachable) leave mode='B' and append
|
|
454
|
+
// a single warning row to skipped_rooms if Brain threw.
|
|
455
|
+
|
|
456
|
+
async function aggregateAcrossRooms(options) {
|
|
457
|
+
options = options || {};
|
|
458
|
+
const roomsHome = path.resolve(
|
|
459
|
+
options.roomsHome
|
|
460
|
+
|| process.env.MINDRIAN_ROOMS_HOME
|
|
461
|
+
|| process.env.MINDRIAN_ROOMS_ROOT
|
|
462
|
+
|| path.join(os.homedir(), 'MindrianRooms')
|
|
463
|
+
);
|
|
464
|
+
|
|
465
|
+
const result = {
|
|
466
|
+
by_jtbd: {},
|
|
467
|
+
mode: 'B',
|
|
468
|
+
skipped_rooms: [],
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
// Discover eligible rooms via Phase 90 aggregator if available; else
|
|
472
|
+
// use the local fallback. Both paths populate result.skipped_rooms
|
|
473
|
+
// with reasons (sealed / opt_out / outside_allowed_root).
|
|
474
|
+
let eligible;
|
|
475
|
+
if (typeof aggregator.listEligibleRooms === 'function') {
|
|
476
|
+
try {
|
|
477
|
+
eligible = aggregator.listEligibleRooms(roomsHome, result.skipped_rooms);
|
|
478
|
+
} catch (_) {
|
|
479
|
+
eligible = listEligibleRoomsFallback(roomsHome, result.skipped_rooms);
|
|
480
|
+
}
|
|
481
|
+
} else {
|
|
482
|
+
eligible = listEligibleRoomsFallback(roomsHome, result.skipped_rooms);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// Local synthesis pass.
|
|
486
|
+
for (const room of eligible) {
|
|
487
|
+
const mem = getRoomMemory(roomsHome, room.slug);
|
|
488
|
+
|
|
489
|
+
// in_flight rows
|
|
490
|
+
for (const row of (mem.in_flight || [])) {
|
|
491
|
+
if (!row || typeof row.jtbd !== 'string') continue;
|
|
492
|
+
if (!result.by_jtbd[row.jtbd]) result.by_jtbd[row.jtbd] = { rooms: [] };
|
|
493
|
+
result.by_jtbd[row.jtbd].rooms.push({
|
|
494
|
+
slug: room.slug,
|
|
495
|
+
state: 'in_flight',
|
|
496
|
+
last_seen: row.last_seen || null,
|
|
497
|
+
confidence_avg: typeof row.confidence_avg === 'number' ? row.confidence_avg : null,
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
// parked rows
|
|
501
|
+
for (const row of (mem.parked || [])) {
|
|
502
|
+
if (!row || typeof row.jtbd !== 'string') continue;
|
|
503
|
+
if (!result.by_jtbd[row.jtbd]) result.by_jtbd[row.jtbd] = { rooms: [] };
|
|
504
|
+
result.by_jtbd[row.jtbd].rooms.push({
|
|
505
|
+
slug: room.slug,
|
|
506
|
+
state: 'parked',
|
|
507
|
+
last_seen: row.last_seen || row.parked_at || null,
|
|
508
|
+
reason: row.reason || null,
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
// completed rows
|
|
512
|
+
for (const row of (mem.completed || [])) {
|
|
513
|
+
if (!row || typeof row.jtbd !== 'string') continue;
|
|
514
|
+
if (!result.by_jtbd[row.jtbd]) result.by_jtbd[row.jtbd] = { rooms: [] };
|
|
515
|
+
result.by_jtbd[row.jtbd].rooms.push({
|
|
516
|
+
slug: room.slug,
|
|
517
|
+
state: 'completed',
|
|
518
|
+
last_seen: row.completed_at || null,
|
|
519
|
+
completion_shape: row.completion_shape || null,
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// Mode A enrichment -- read-only Brain failure degrades to Mode B
|
|
525
|
+
// with a single warning row.
|
|
526
|
+
try {
|
|
527
|
+
const hints = await tryBrainHints(result.by_jtbd);
|
|
528
|
+
if (hints) {
|
|
529
|
+
result.mode = 'A';
|
|
530
|
+
result.brain_pattern_hints = hints;
|
|
531
|
+
}
|
|
532
|
+
} catch (err) {
|
|
533
|
+
const msg = err && err.message ? String(err.message) : 'unknown';
|
|
534
|
+
result.skipped_rooms.push({
|
|
535
|
+
slug: '__brain__',
|
|
536
|
+
reason: 'brain_error: ' + msg.slice(0, 100),
|
|
537
|
+
});
|
|
538
|
+
// mode stays 'B' (default)
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
return result;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// ============================================================
|
|
545
|
+
// Public: queryByJtbd.
|
|
546
|
+
// ============================================================
|
|
547
|
+
//
|
|
548
|
+
// Thin wrapper: returns a flat list of rows for a single JTBD across
|
|
549
|
+
// all rooms, with optional Brain enrichment for the mode flag.
|
|
550
|
+
|
|
551
|
+
async function queryByJtbd(jtbd, options) {
|
|
552
|
+
options = options || {};
|
|
553
|
+
if (typeof jtbd !== 'string' || jtbd.length === 0) {
|
|
554
|
+
return { rooms: [], mode: 'B' };
|
|
555
|
+
}
|
|
556
|
+
const agg = await aggregateAcrossRooms(options);
|
|
557
|
+
const block = (agg.by_jtbd && agg.by_jtbd[jtbd]) ? agg.by_jtbd[jtbd] : { rooms: [] };
|
|
558
|
+
return {
|
|
559
|
+
rooms: Array.isArray(block.rooms) ? block.rooms : [],
|
|
560
|
+
mode: agg.mode,
|
|
561
|
+
skipped_rooms: agg.skipped_rooms || [],
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
// ============================================================
|
|
566
|
+
// Module exports.
|
|
567
|
+
// ============================================================
|
|
568
|
+
|
|
569
|
+
module.exports = {
|
|
570
|
+
aggregateAcrossRooms: aggregateAcrossRooms,
|
|
571
|
+
queryByJtbd: queryByJtbd,
|
|
572
|
+
buildBrainQueryContext: buildBrainQueryContext,
|
|
573
|
+
// Test seam (private-by-convention):
|
|
574
|
+
__setBrainClient: __setBrainClient,
|
|
575
|
+
};
|