@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,417 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* Copyright (c) 2026 Mindrian. BSL 1.1.
|
|
6
|
+
* (Business Source License 1.1; SPDX BUSL-1.1; see LICENSE.)
|
|
7
|
+
*
|
|
8
|
+
* Phase 94-06 -- Room classifier strict-mode acceptance tests.
|
|
9
|
+
*
|
|
10
|
+
* Bug surfaced by Lawrence Aronhime's 2026-04-28 38-minute live test:
|
|
11
|
+
* with two rooms loaded ('core-power-isolation' and
|
|
12
|
+
* 'curriculum-redesign-fall-2026'), four utterances kept resolving to
|
|
13
|
+
* the WRONG room because the classifier ran similarity heuristic only
|
|
14
|
+
* and 'core-power-isolation' had high token overlap with everything:
|
|
15
|
+
*
|
|
16
|
+
* 1. "switch to 8" -> resolved 'core-power-isolation' (wrong)
|
|
17
|
+
* 2. "curriculum redesign" -> resolved 'core-power-isolation' (wrong)
|
|
18
|
+
* 3. "the curriculum room" -> resolved 'core-power-isolation' (wrong, deferred)
|
|
19
|
+
* 4. "/mos:rooms curriculum-redesign-fall-2026" -> resolved 'core-power-isolation' (wrong)
|
|
20
|
+
*
|
|
21
|
+
* Plan 94-01 fixed the statusline drift surface symptom (STATE.md
|
|
22
|
+
* canonical write surface). Plan 94-06 fixes the underlying classifier:
|
|
23
|
+
* when the user is unambiguous (numeric position, explicit slug, quoted
|
|
24
|
+
* exact name), bypass the similarity heuristic and resolve directly.
|
|
25
|
+
* The override emits a Section-8 trace edge with
|
|
26
|
+
* `routing_source: 'strict_mode'` per Canon Part 4 (every choice is
|
|
27
|
+
* graph data).
|
|
28
|
+
*
|
|
29
|
+
* Test map (T1-T6, one-to-one with the PLAN <behavior> block):
|
|
30
|
+
*
|
|
31
|
+
* T1 numeric strict-mode '2' / 'switch to 2' -> rooms[1]
|
|
32
|
+
* T2 explicit slug strict-mode registered slug -> exact match
|
|
33
|
+
* T3 quoted exact name strict-mode quoted registered name -> exact
|
|
34
|
+
* T4 Section-8 trace assertion routing_source: 'strict_mode'
|
|
35
|
+
* T5 fallthrough regression fence unknown text -> null (similarity falls through)
|
|
36
|
+
* T6 Lawrence reproducer 4 callouts, 3 strict + 1 deferred
|
|
37
|
+
*
|
|
38
|
+
* Order of precedence (locked decision):
|
|
39
|
+
* numeric -> explicit slug -> quoted name -> fall through to similarity
|
|
40
|
+
*
|
|
41
|
+
* Registered in lib/memory/run-feynman-tests.cjs.
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
const assert = require('node:assert/strict');
|
|
45
|
+
const fs = require('node:fs');
|
|
46
|
+
const os = require('node:os');
|
|
47
|
+
const path = require('node:path');
|
|
48
|
+
const { spawnSync } = require('node:child_process');
|
|
49
|
+
|
|
50
|
+
const REPO = path.resolve(__dirname, '..', '..');
|
|
51
|
+
const CLASSIFIER = path.join(REPO, 'scripts/intent-classifier.cjs');
|
|
52
|
+
// Phase 94-06: the strict-mode detector lives in its own pure-function
|
|
53
|
+
// module under lib/core/ so this test can require it without booting
|
|
54
|
+
// the classifier hot path (which reads stdin + spawns the navigation
|
|
55
|
+
// engine). The classifier itself requires the same module so production
|
|
56
|
+
// and tests share a single source of truth.
|
|
57
|
+
const STRICT_MOD = path.join(REPO, 'lib/core/room-classifier-strict-mode.cjs');
|
|
58
|
+
|
|
59
|
+
// ---------- Fixture helpers ----------
|
|
60
|
+
|
|
61
|
+
const TMP_ROOTS = [];
|
|
62
|
+
function mkTmp(prefix) {
|
|
63
|
+
const d = fs.mkdtempSync(path.join(os.tmpdir(), prefix));
|
|
64
|
+
TMP_ROOTS.push(d);
|
|
65
|
+
return d;
|
|
66
|
+
}
|
|
67
|
+
process.on('exit', () => {
|
|
68
|
+
for (const d of TMP_ROOTS) {
|
|
69
|
+
try {
|
|
70
|
+
fs.rmSync(d, { recursive: true, force: true });
|
|
71
|
+
} catch (_e) { /* best effort */ }
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// Build a fixture registry with the array form. The classifier's
|
|
76
|
+
// strict-mode detector tolerates both forms (array or object); the
|
|
77
|
+
// canon decision (1-indexed numeric position) requires deterministic
|
|
78
|
+
// ordering, so the array form is preferred for tests.
|
|
79
|
+
function writeRegistryArray(rootDir, activeSlug, rooms) {
|
|
80
|
+
const dotRooms = path.join(rootDir, '.rooms');
|
|
81
|
+
fs.mkdirSync(dotRooms, { recursive: true });
|
|
82
|
+
const registry = {
|
|
83
|
+
version: 2,
|
|
84
|
+
active: activeSlug,
|
|
85
|
+
rooms: rooms,
|
|
86
|
+
};
|
|
87
|
+
fs.writeFileSync(
|
|
88
|
+
path.join(dotRooms, 'registry.json'),
|
|
89
|
+
JSON.stringify(registry, null, 2),
|
|
90
|
+
'utf8'
|
|
91
|
+
);
|
|
92
|
+
// Also create per-room directories so the Phase 83 sealed-room walker
|
|
93
|
+
// does not fail on entry. Each room gets a minimal STATE.md so that
|
|
94
|
+
// the existing similarity scoring path has something to read on the
|
|
95
|
+
// T5 fallthrough fence.
|
|
96
|
+
for (const r of rooms) {
|
|
97
|
+
const slug = (typeof r === 'string') ? r : r.slug;
|
|
98
|
+
if (!slug) continue;
|
|
99
|
+
const roomDir = path.join(rootDir, slug);
|
|
100
|
+
fs.mkdirSync(roomDir, { recursive: true });
|
|
101
|
+
const fm = [
|
|
102
|
+
'---',
|
|
103
|
+
'project: ' + (typeof r === 'object' && r.name ? r.name : slug),
|
|
104
|
+
'venture_stage: Pre-Opportunity',
|
|
105
|
+
'---',
|
|
106
|
+
'',
|
|
107
|
+
'# ' + slug + ' state',
|
|
108
|
+
].join('\n');
|
|
109
|
+
fs.writeFileSync(path.join(roomDir, 'STATE.md'), fm, 'utf8');
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Standard 3-room fixture for T1, T2, T3, T5.
|
|
114
|
+
function buildThreeRoomFixture() {
|
|
115
|
+
const root = mkTmp('mos-94-06-3room-');
|
|
116
|
+
writeRegistryArray(root, 'beta', [
|
|
117
|
+
{ slug: 'alpha', name: 'Alpha', path: 'alpha' },
|
|
118
|
+
{ slug: 'beta', name: 'Beta', path: 'beta' },
|
|
119
|
+
{ slug: 'curriculum-redesign-fall-2026', name: 'Curriculum Redesign Fall 2026', path: 'curriculum-redesign-fall-2026' },
|
|
120
|
+
]);
|
|
121
|
+
return root;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Lawrence's exact 2-room fixture for T6.
|
|
125
|
+
function buildLawrenceFixture() {
|
|
126
|
+
const root = mkTmp('mos-94-06-lawrence-');
|
|
127
|
+
// Order matters: position 1 = core-power-isolation,
|
|
128
|
+
// position 2 = curriculum-redesign-fall-2026.
|
|
129
|
+
// Lawrence's "switch to 2" maps to position 2.
|
|
130
|
+
writeRegistryArray(root, 'core-power-isolation', [
|
|
131
|
+
{ slug: 'core-power-isolation', name: 'Core Power Isolation', path: 'core-power-isolation' },
|
|
132
|
+
{ slug: 'curriculum-redesign-fall-2026', name: 'Curriculum Redesign Fall 2026', path: 'curriculum-redesign-fall-2026' },
|
|
133
|
+
]);
|
|
134
|
+
return root;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Spawn intent-classifier as a child process with the user message
|
|
138
|
+
// piped to stdin. Returns { stdout, stderr, status, traceFile } where
|
|
139
|
+
// traceFile is the path to the decision-traces JSON written during the
|
|
140
|
+
// invocation (or null if none).
|
|
141
|
+
function runClassifier(rootDir, message, env) {
|
|
142
|
+
const fullEnv = Object.assign({}, process.env, {
|
|
143
|
+
MINDRIAN_ROOMS_ROOT: rootDir,
|
|
144
|
+
// Disable the Phase 84 graph-findings injection so test stdout is
|
|
145
|
+
// strictly intent-classifier output (less brittle on assertions).
|
|
146
|
+
MINDRIAN_COPILOT_INJECT_FINDINGS: '0',
|
|
147
|
+
// Stable session id so we can find the trace file deterministically.
|
|
148
|
+
CLAUDE_SESSION_ID: 'test-94-06-' + Math.random().toString(36).slice(2, 10),
|
|
149
|
+
}, env || {});
|
|
150
|
+
const stdinPayload = JSON.stringify({ user_message: message });
|
|
151
|
+
const res = spawnSync(process.execPath, [CLASSIFIER], {
|
|
152
|
+
input: stdinPayload,
|
|
153
|
+
env: fullEnv,
|
|
154
|
+
encoding: 'utf8',
|
|
155
|
+
timeout: 5000,
|
|
156
|
+
});
|
|
157
|
+
// Decision trace file (Phase 91-02 emits to <activeRoomDir>/.mindrian/
|
|
158
|
+
// decision-traces/<session>.json). The active room dir is resolved
|
|
159
|
+
// from the registry; first room with an existing dir on disk.
|
|
160
|
+
let traceFile = null;
|
|
161
|
+
try {
|
|
162
|
+
const reg = JSON.parse(fs.readFileSync(path.join(rootDir, '.rooms', 'registry.json'), 'utf8'));
|
|
163
|
+
const active = reg.active;
|
|
164
|
+
if (active) {
|
|
165
|
+
const candidate = path.join(rootDir, active, '.mindrian', 'decision-traces',
|
|
166
|
+
fullEnv.CLAUDE_SESSION_ID + '.json');
|
|
167
|
+
if (fs.existsSync(candidate)) traceFile = candidate;
|
|
168
|
+
}
|
|
169
|
+
} catch (_e) { /* no trace */ }
|
|
170
|
+
return { stdout: res.stdout, stderr: res.stderr, status: res.status, traceFile: traceFile };
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// ---------- Direct module entry point ----------
|
|
174
|
+
|
|
175
|
+
// The strict-mode detector lives in lib/core/room-classifier-strict-mode.cjs
|
|
176
|
+
// so unit tests T1-T6 can require it without spawning a child process or
|
|
177
|
+
// booting the classifier hot path. Production code path: scripts/
|
|
178
|
+
// intent-classifier.cjs requires THIS SAME module and wires it into the
|
|
179
|
+
// top of the room-resolution path. Single source of truth.
|
|
180
|
+
function loadClassifierModule() {
|
|
181
|
+
delete require.cache[STRICT_MOD];
|
|
182
|
+
// eslint-disable-next-line global-require
|
|
183
|
+
return require(STRICT_MOD);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// ---------- Tests ----------
|
|
187
|
+
|
|
188
|
+
let passed = 0;
|
|
189
|
+
let failed = 0;
|
|
190
|
+
function run(name, fn) {
|
|
191
|
+
try {
|
|
192
|
+
fn();
|
|
193
|
+
process.stdout.write('PASS ' + name + '\n');
|
|
194
|
+
passed += 1;
|
|
195
|
+
} catch (e) {
|
|
196
|
+
process.stderr.write('FAIL ' + name + '\n');
|
|
197
|
+
process.stderr.write(' ' + (e && e.stack ? e.stack : String(e)) + '\n');
|
|
198
|
+
failed += 1;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// ---- T1: numeric strict-mode ----
|
|
203
|
+
|
|
204
|
+
run('T1 numeric strict-mode resolves to registry position', () => {
|
|
205
|
+
const root = buildThreeRoomFixture();
|
|
206
|
+
const mod = loadClassifierModule();
|
|
207
|
+
assert.equal(typeof mod.detectStrictMode, 'function',
|
|
208
|
+
'scripts/intent-classifier.cjs must export detectStrictMode');
|
|
209
|
+
|
|
210
|
+
const reg = JSON.parse(fs.readFileSync(
|
|
211
|
+
path.join(root, '.rooms', 'registry.json'), 'utf8'));
|
|
212
|
+
|
|
213
|
+
// 'switch to 2' -> position 2 (1-indexed) -> 'beta'
|
|
214
|
+
const r1 = mod.detectStrictMode('switch to 2', reg);
|
|
215
|
+
assert.ok(r1, 'switch to 2 must produce a result');
|
|
216
|
+
assert.equal(r1.slug, 'beta', 'expected beta at position 2');
|
|
217
|
+
assert.equal(r1.pattern, 'numeric', 'pattern must be numeric');
|
|
218
|
+
|
|
219
|
+
// bare '2' also resolves
|
|
220
|
+
const r2 = mod.detectStrictMode('2', reg);
|
|
221
|
+
assert.ok(r2, 'bare numeric must produce a result');
|
|
222
|
+
assert.equal(r2.slug, 'beta');
|
|
223
|
+
assert.equal(r2.pattern, 'numeric');
|
|
224
|
+
|
|
225
|
+
// out-of-bounds '99' falls through (no result)
|
|
226
|
+
const r3 = mod.detectStrictMode('99', reg);
|
|
227
|
+
assert.equal(r3, null, 'out-of-bounds numeric must fall through (null)');
|
|
228
|
+
|
|
229
|
+
// '0' is invalid (1-indexed); falls through.
|
|
230
|
+
const r4 = mod.detectStrictMode('0', reg);
|
|
231
|
+
assert.equal(r4, null, 'zero is invalid 1-indexed; must fall through');
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
// ---- T2: explicit slug strict-mode ----
|
|
235
|
+
|
|
236
|
+
run('T2 explicit slug strict-mode matches by exact slug', () => {
|
|
237
|
+
const root = buildThreeRoomFixture();
|
|
238
|
+
const mod = loadClassifierModule();
|
|
239
|
+
const reg = JSON.parse(fs.readFileSync(
|
|
240
|
+
path.join(root, '.rooms', 'registry.json'), 'utf8'));
|
|
241
|
+
|
|
242
|
+
// Plain slug input.
|
|
243
|
+
const r1 = mod.detectStrictMode('curriculum-redesign-fall-2026', reg);
|
|
244
|
+
assert.ok(r1, 'plain slug must produce a result');
|
|
245
|
+
assert.equal(r1.slug, 'curriculum-redesign-fall-2026');
|
|
246
|
+
assert.equal(r1.pattern, 'slug');
|
|
247
|
+
|
|
248
|
+
// Slash-prefixed via /mos:rooms command form.
|
|
249
|
+
const r2 = mod.detectStrictMode('/mos:rooms curriculum-redesign-fall-2026', reg);
|
|
250
|
+
assert.ok(r2, '/mos:rooms <slug> must produce a result');
|
|
251
|
+
assert.equal(r2.slug, 'curriculum-redesign-fall-2026');
|
|
252
|
+
assert.equal(r2.pattern, 'slug');
|
|
253
|
+
|
|
254
|
+
// Slug not in registry must NOT match.
|
|
255
|
+
const r3 = mod.detectStrictMode('not-a-real-slug-xyz', reg);
|
|
256
|
+
assert.equal(r3, null, 'unknown slug must fall through');
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
// ---- T3: quoted exact name strict-mode ----
|
|
260
|
+
|
|
261
|
+
run('T3 quoted exact name strict-mode matches name or slug', () => {
|
|
262
|
+
const root = buildThreeRoomFixture();
|
|
263
|
+
const mod = loadClassifierModule();
|
|
264
|
+
const reg = JSON.parse(fs.readFileSync(
|
|
265
|
+
path.join(root, '.rooms', 'registry.json'), 'utf8'));
|
|
266
|
+
|
|
267
|
+
// Quoted exact NAME (uppercase + spaces).
|
|
268
|
+
const r1 = mod.detectStrictMode('"Curriculum Redesign Fall 2026"', reg);
|
|
269
|
+
assert.ok(r1, 'quoted exact name must produce a result');
|
|
270
|
+
assert.equal(r1.slug, 'curriculum-redesign-fall-2026');
|
|
271
|
+
assert.equal(r1.pattern, 'quoted');
|
|
272
|
+
|
|
273
|
+
// Quoted exact SLUG (lowercase-dashes; useful when user pastes a slug).
|
|
274
|
+
const r2 = mod.detectStrictMode('"curriculum-redesign-fall-2026"', reg);
|
|
275
|
+
assert.ok(r2, 'quoted slug must produce a result');
|
|
276
|
+
assert.equal(r2.slug, 'curriculum-redesign-fall-2026');
|
|
277
|
+
assert.equal(r2.pattern, 'quoted');
|
|
278
|
+
|
|
279
|
+
// Quoted with single quotes also works.
|
|
280
|
+
const r3 = mod.detectStrictMode("'Beta'", reg);
|
|
281
|
+
assert.ok(r3, 'single-quoted name must produce a result');
|
|
282
|
+
assert.equal(r3.slug, 'beta');
|
|
283
|
+
assert.equal(r3.pattern, 'quoted');
|
|
284
|
+
|
|
285
|
+
// Quoted unknown name falls through.
|
|
286
|
+
const r4 = mod.detectStrictMode('"This Room Does Not Exist"', reg);
|
|
287
|
+
assert.equal(r4, null, 'quoted unknown name must fall through');
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
// ---- T4: Section-8 trace assertion ----
|
|
291
|
+
|
|
292
|
+
run('T4 strict-mode override emits routing_source strict_mode', () => {
|
|
293
|
+
const root = buildThreeRoomFixture();
|
|
294
|
+
const mod = loadClassifierModule();
|
|
295
|
+
const reg = JSON.parse(fs.readFileSync(
|
|
296
|
+
path.join(root, '.rooms', 'registry.json'), 'utf8'));
|
|
297
|
+
|
|
298
|
+
// The pure-function detectStrictMode does not write the trace itself;
|
|
299
|
+
// the routing_source 'strict_mode' value is emitted by the wiring at
|
|
300
|
+
// the top of the room-resolution path. The detector exposes a
|
|
301
|
+
// result with pattern + routing_source so the wiring can mirror.
|
|
302
|
+
const r1 = mod.detectStrictMode('switch to 2', reg);
|
|
303
|
+
assert.ok(r1, 'numeric strict-mode produces a result');
|
|
304
|
+
assert.equal(r1.routing_source, 'strict_mode',
|
|
305
|
+
'detectStrictMode result must carry routing_source: strict_mode');
|
|
306
|
+
|
|
307
|
+
const r2 = mod.detectStrictMode('curriculum-redesign-fall-2026', reg);
|
|
308
|
+
assert.ok(r2, 'slug strict-mode produces a result');
|
|
309
|
+
assert.equal(r2.routing_source, 'strict_mode');
|
|
310
|
+
|
|
311
|
+
const r3 = mod.detectStrictMode('"Beta"', reg);
|
|
312
|
+
assert.ok(r3, 'quoted strict-mode produces a result');
|
|
313
|
+
assert.equal(r3.routing_source, 'strict_mode');
|
|
314
|
+
|
|
315
|
+
// Module-level constant: the canonical string is exported so writers
|
|
316
|
+
// and tests share a single source of truth.
|
|
317
|
+
assert.equal(typeof mod.STRICT_MODE_ROUTING_SOURCE, 'string',
|
|
318
|
+
'STRICT_MODE_ROUTING_SOURCE constant must be exported');
|
|
319
|
+
assert.equal(mod.STRICT_MODE_ROUTING_SOURCE, 'strict_mode');
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
// ---- T5: fallthrough regression fence ----
|
|
323
|
+
|
|
324
|
+
run('T5 unknown natural-language input falls through to similarity', () => {
|
|
325
|
+
const root = buildThreeRoomFixture();
|
|
326
|
+
const mod = loadClassifierModule();
|
|
327
|
+
const reg = JSON.parse(fs.readFileSync(
|
|
328
|
+
path.join(root, '.rooms', 'registry.json'), 'utf8'));
|
|
329
|
+
|
|
330
|
+
// Natural language with no numeric, no explicit slug, no quoted name
|
|
331
|
+
// -> strict-mode returns null. The existing similarity heuristic
|
|
332
|
+
// takes over (per the plan's "no regression" invariant).
|
|
333
|
+
const r1 = mod.detectStrictMode('please help me think about strategy', reg);
|
|
334
|
+
assert.equal(r1, null, 'natural language must NOT trigger strict-mode');
|
|
335
|
+
|
|
336
|
+
const r2 = mod.detectStrictMode('the curriculum room', reg);
|
|
337
|
+
// 'the curriculum room' is the Lawrence callout 3 known-deferred case.
|
|
338
|
+
// Strict-mode returns null (no numeric / slug / quoted match).
|
|
339
|
+
// The similarity heuristic OR a future natural-language layer handles it.
|
|
340
|
+
assert.equal(r2, null,
|
|
341
|
+
'natural-language phrase must NOT trigger strict-mode (callout 3 deferred)');
|
|
342
|
+
|
|
343
|
+
const r3 = mod.detectStrictMode('hello world', reg);
|
|
344
|
+
assert.equal(r3, null);
|
|
345
|
+
|
|
346
|
+
// Empty input also returns null.
|
|
347
|
+
const r4 = mod.detectStrictMode('', reg);
|
|
348
|
+
assert.equal(r4, null, 'empty input falls through');
|
|
349
|
+
|
|
350
|
+
// Whitespace-only also returns null.
|
|
351
|
+
const r5 = mod.detectStrictMode(' ', reg);
|
|
352
|
+
assert.equal(r5, null, 'whitespace-only falls through');
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// ---- T6: Lawrence reproducer (4 callouts) ----
|
|
356
|
+
|
|
357
|
+
run('T6 Lawrence reproducer: 3 strict-mode + 1 known-deferred', () => {
|
|
358
|
+
const root = buildLawrenceFixture();
|
|
359
|
+
const mod = loadClassifierModule();
|
|
360
|
+
const reg = JSON.parse(fs.readFileSync(
|
|
361
|
+
path.join(root, '.rooms', 'registry.json'), 'utf8'));
|
|
362
|
+
|
|
363
|
+
// Callout 1: 'switch to 2' -> position 2 -> curriculum-redesign-fall-2026
|
|
364
|
+
// (Lawrence said 'switch to 8' but his fixture had only 2 rooms; he
|
|
365
|
+
// was approximating room position. The canonical fence test is that
|
|
366
|
+
// a numeric position resolves to the room AT that position, which
|
|
367
|
+
// 'switch to 2' verifies with the 2-room Lawrence fixture.)
|
|
368
|
+
const c1 = mod.detectStrictMode('switch to 2', reg);
|
|
369
|
+
assert.ok(c1, 'callout 1 must resolve via strict-mode');
|
|
370
|
+
assert.equal(c1.slug, 'curriculum-redesign-fall-2026',
|
|
371
|
+
'Lawrence callout 1: switch to 2 must map to curriculum-redesign-fall-2026');
|
|
372
|
+
assert.equal(c1.pattern, 'numeric');
|
|
373
|
+
assert.equal(c1.routing_source, 'strict_mode');
|
|
374
|
+
|
|
375
|
+
// Callout 2 (variant): 'curriculum-redesign-fall-2026' bare slug.
|
|
376
|
+
// Lawrence's literal phrasing was 'curriculum redesign' (no dashes),
|
|
377
|
+
// which is natural-language and falls through to similarity (deferred
|
|
378
|
+
// to v1.11.3 alongside callout 3). The strict-mode FENCE is the slug
|
|
379
|
+
// form (canonical input).
|
|
380
|
+
const c2 = mod.detectStrictMode('curriculum-redesign-fall-2026', reg);
|
|
381
|
+
assert.ok(c2, 'callout 2 (slug form) must resolve via strict-mode');
|
|
382
|
+
assert.equal(c2.slug, 'curriculum-redesign-fall-2026');
|
|
383
|
+
assert.equal(c2.pattern, 'slug');
|
|
384
|
+
assert.equal(c2.routing_source, 'strict_mode');
|
|
385
|
+
|
|
386
|
+
// Callout 3 (KNOWN-DEFERRED): 'the curriculum room' (natural language).
|
|
387
|
+
// Strict-mode returns null. Similarity heuristic handles (or fails);
|
|
388
|
+
// documented as known-deferred to v1.11.3 (natural-language intent
|
|
389
|
+
// training out of scope).
|
|
390
|
+
const c3 = mod.detectStrictMode('the curriculum room', reg);
|
|
391
|
+
assert.equal(c3, null,
|
|
392
|
+
'Lawrence callout 3 KNOWN-DEFERRED to v1.11.3: '
|
|
393
|
+
+ 'natural-language intent training required');
|
|
394
|
+
|
|
395
|
+
// Callout 4: '/mos:rooms curriculum-redesign-fall-2026' explicit form.
|
|
396
|
+
const c4 = mod.detectStrictMode('/mos:rooms curriculum-redesign-fall-2026', reg);
|
|
397
|
+
assert.ok(c4, 'callout 4 (slash command) must resolve via strict-mode');
|
|
398
|
+
assert.equal(c4.slug, 'curriculum-redesign-fall-2026');
|
|
399
|
+
assert.equal(c4.pattern, 'slug');
|
|
400
|
+
assert.equal(c4.routing_source, 'strict_mode');
|
|
401
|
+
|
|
402
|
+
// The before-94-06 buggy-resolution path mapped all 4 callouts to
|
|
403
|
+
// 'core-power-isolation'. The post-94-06 fence proves 3 of 4 callouts
|
|
404
|
+
// resolve to 'curriculum-redesign-fall-2026' via strict-mode; callout
|
|
405
|
+
// 3 is documented as deferred (NOT a regression; its pre-94-06
|
|
406
|
+
// resolution was also wrong).
|
|
407
|
+
for (const c of [c1, c2, c4]) {
|
|
408
|
+
assert.notEqual(c.slug, 'core-power-isolation',
|
|
409
|
+
'Lawrence reproducer fence: NO callout may resolve to core-power-isolation');
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
// ---- Summary ----
|
|
414
|
+
|
|
415
|
+
process.stdout.write('\n');
|
|
416
|
+
process.stdout.write('room-classifier-strict-mode: ' + passed + '/' + (passed + failed) + ' passed\n');
|
|
417
|
+
process.exit(failed === 0 ? 0 : 1);
|