@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,433 @@
|
|
|
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 Plan 05 -- mcp-stack fallback chain RED -> GREEN fixture suite.
|
|
9
|
+
*
|
|
10
|
+
* Per the user-approved plan amendment dated 2026-04-28 (commit 66a1a34),
|
|
11
|
+
* the original "4 fetchers all currently call Tavily/Firecrawl/Exa via
|
|
12
|
+
* mcp__* prefixes" framing was rewritten to match the actual module
|
|
13
|
+
* landscape:
|
|
14
|
+
*
|
|
15
|
+
* - rs-fetcher-academic.cjs: 6 sources, 3 free + 3 keyed. Free tier
|
|
16
|
+
* already works. Envelope wrap only.
|
|
17
|
+
* - rs-fetcher-patents.cjs: 2 sources, both keyless. Free tier
|
|
18
|
+
* already works. Envelope wrap only.
|
|
19
|
+
* - rs-fetcher-industry.cjs: 1 source, TAVILY_API_KEY required. THIS
|
|
20
|
+
* IS THE TRUE Tavily-only gap. Gets opts.
|
|
21
|
+
* tavily / opts.webSearch / opts.cacheReader
|
|
22
|
+
* injection seams.
|
|
23
|
+
* - rs-fetcher-experts.cjs: Post-processor over academic papers[].
|
|
24
|
+
* Already works without keys. Envelope
|
|
25
|
+
* wrap only with tier='derived'.
|
|
26
|
+
*
|
|
27
|
+
* - commands/research.md: frontmatter ALREADY declares WebSearch +
|
|
28
|
+
* WebFetch in allowed-tools (lines 6-7).
|
|
29
|
+
* What's missing: body has a hard-stop
|
|
30
|
+
* "Requires Brain MCP. Then stop." which
|
|
31
|
+
* blocks fresh installs.
|
|
32
|
+
*
|
|
33
|
+
* Test map (7 cases, one-to-one with the amendment <action> block):
|
|
34
|
+
*
|
|
35
|
+
* T1 Industry happy paid: opts.tavily mock returns results,
|
|
36
|
+
* envelope shape is
|
|
37
|
+
* {tier:'paid', source:'tavily',
|
|
38
|
+
* results:[...], signals:[...],
|
|
39
|
+
* telemetry:[...]}.
|
|
40
|
+
* T2 Industry native fallback: no TAVILY_API_KEY, opts.webSearch
|
|
41
|
+
* mock returns; envelope is
|
|
42
|
+
* {tier:'native', source:'websearch',
|
|
43
|
+
* results:[...], signals:[...]}.
|
|
44
|
+
* T3 Industry cache fallback: no TAVILY_API_KEY, no opts.webSearch,
|
|
45
|
+
* opts.cacheReader returns cached;
|
|
46
|
+
* envelope is {tier:'cache',
|
|
47
|
+
* source:'cache', results:[...]}.
|
|
48
|
+
* T4 Industry all-tiers-down: no source; returns empty results,
|
|
49
|
+
* never throws. tier='cache' source='cache'
|
|
50
|
+
* results=[]. signals preserved (empty).
|
|
51
|
+
* T5 Envelope shape uniformity: academic / patents / experts each
|
|
52
|
+
* return {tier, source, results} with
|
|
53
|
+
* tier in valid set + source in valid
|
|
54
|
+
* set, AND domain-specific keys
|
|
55
|
+
* preserved (papers / patents / experts)
|
|
56
|
+
* for backward compat with rs-discovery-
|
|
57
|
+
* engine line 380 industry.signals
|
|
58
|
+
* consumer pattern.
|
|
59
|
+
* T6 Section-8 schema field: lib/core/section-8-trace-schema.cjs
|
|
60
|
+
* exports a schema literal containing
|
|
61
|
+
* web_research_tier somewhere reachable.
|
|
62
|
+
* T7 commands/research.md body: frontmatter already declares both
|
|
63
|
+
* WebSearch AND WebFetch (verified once);
|
|
64
|
+
* body must NO LONGER contain the
|
|
65
|
+
* "Requires Brain MCP" + "Then stop."
|
|
66
|
+
* hard-stop directive.
|
|
67
|
+
*
|
|
68
|
+
* Pure CJS, zero npm deps. Registered in lib/memory/run-feynman-tests.cjs.
|
|
69
|
+
*/
|
|
70
|
+
|
|
71
|
+
const assert = require('node:assert/strict');
|
|
72
|
+
const fs = require('node:fs');
|
|
73
|
+
const os = require('node:os');
|
|
74
|
+
const path = require('node:path');
|
|
75
|
+
|
|
76
|
+
const REPO = path.resolve(__dirname, '..', '..');
|
|
77
|
+
|
|
78
|
+
const PATH_INDUSTRY = path.join(REPO, 'lib/core/rs-fetcher-industry.cjs');
|
|
79
|
+
const PATH_ACADEMIC = path.join(REPO, 'lib/core/rs-fetcher-academic.cjs');
|
|
80
|
+
const PATH_PATENTS = path.join(REPO, 'lib/core/rs-fetcher-patents.cjs');
|
|
81
|
+
const PATH_EXPERTS = path.join(REPO, 'lib/core/rs-fetcher-experts.cjs');
|
|
82
|
+
const PATH_SCHEMA = path.join(REPO, 'lib/core/section-8-trace-schema.cjs');
|
|
83
|
+
const PATH_RESEARCH_MD = path.join(REPO, 'commands/research.md');
|
|
84
|
+
|
|
85
|
+
// ---------- Frozen invariants ----------
|
|
86
|
+
|
|
87
|
+
const VALID_TIERS = Object.freeze(['paid', 'native', 'cache', 'derived']);
|
|
88
|
+
const VALID_SOURCES = Object.freeze([
|
|
89
|
+
'tavily',
|
|
90
|
+
'firecrawl',
|
|
91
|
+
'exa',
|
|
92
|
+
'websearch',
|
|
93
|
+
'cache',
|
|
94
|
+
'openalex',
|
|
95
|
+
'arxiv',
|
|
96
|
+
'pubmed',
|
|
97
|
+
'scopus',
|
|
98
|
+
'ieee',
|
|
99
|
+
'nature',
|
|
100
|
+
'google_patents',
|
|
101
|
+
'uspto',
|
|
102
|
+
'derived',
|
|
103
|
+
]);
|
|
104
|
+
|
|
105
|
+
// ---------- Fixture helpers ----------
|
|
106
|
+
|
|
107
|
+
const TMP_ROOTS = [];
|
|
108
|
+
function mkTmp(prefix) {
|
|
109
|
+
const d = fs.mkdtempSync(path.join(os.tmpdir(), prefix));
|
|
110
|
+
TMP_ROOTS.push(d);
|
|
111
|
+
return d;
|
|
112
|
+
}
|
|
113
|
+
process.on('exit', function () {
|
|
114
|
+
for (const d of TMP_ROOTS) {
|
|
115
|
+
try {
|
|
116
|
+
fs.rmSync(d, { recursive: true, force: true });
|
|
117
|
+
} catch (_e) { /* best effort */ }
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// Reload a module from disk (drops require.cache so per-test env-var
|
|
122
|
+
// mutations are honored on next require).
|
|
123
|
+
function freshRequire(modulePath) {
|
|
124
|
+
delete require.cache[require.resolve(modulePath)];
|
|
125
|
+
return require(modulePath);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// ---------- Mock factories ----------
|
|
129
|
+
|
|
130
|
+
function makeTavilyMock(results) {
|
|
131
|
+
return async function tavilyMock(query, opts) {
|
|
132
|
+
return {
|
|
133
|
+
results: results.map(function (r) { return Object.assign({}, r); }),
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function makeWebSearchMock(results) {
|
|
139
|
+
return async function webSearchMock(query) {
|
|
140
|
+
return {
|
|
141
|
+
results: results.map(function (r) { return Object.assign({}, r); }),
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function makeCacheReader(payload) {
|
|
147
|
+
return function cacheReaderMock(roomDir) {
|
|
148
|
+
return payload;
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// ---------- Helpers to assert envelope shape ----------
|
|
153
|
+
|
|
154
|
+
function assertEnvelope(env, expectedTier, expectedSource, label) {
|
|
155
|
+
assert.ok(env && typeof env === 'object', label + ': envelope is object');
|
|
156
|
+
assert.ok(VALID_TIERS.indexOf(env.tier) >= 0,
|
|
157
|
+
label + ': tier "' + env.tier + '" must be in ' + JSON.stringify(VALID_TIERS));
|
|
158
|
+
assert.ok(VALID_SOURCES.indexOf(env.source) >= 0,
|
|
159
|
+
label + ': source "' + env.source + '" must be in valid set');
|
|
160
|
+
assert.ok(Array.isArray(env.results),
|
|
161
|
+
label + ': results must be an array');
|
|
162
|
+
if (expectedTier !== null) {
|
|
163
|
+
assert.strictEqual(env.tier, expectedTier, label + ': tier matches expected');
|
|
164
|
+
}
|
|
165
|
+
if (expectedSource !== null) {
|
|
166
|
+
assert.strictEqual(env.source, expectedSource, label + ': source matches expected');
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// ---------- Tests ----------
|
|
171
|
+
|
|
172
|
+
async function test_1_industry_happy_paid() {
|
|
173
|
+
// T1: opts.tavily injected; happy path returns paid envelope.
|
|
174
|
+
// Backward-compat: signals[] preserved alongside results[].
|
|
175
|
+
const mod = freshRequire(PATH_INDUSTRY);
|
|
176
|
+
if (typeof mod.fetchIndustry !== 'function') {
|
|
177
|
+
throw new Error('T1: fetchIndustry export missing');
|
|
178
|
+
}
|
|
179
|
+
// Set TAVILY_API_KEY so the chokepoint won't short-circuit on
|
|
180
|
+
// api_key_missing; opts.tavily will short-circuit before any real fetch.
|
|
181
|
+
const prev = process.env.TAVILY_API_KEY;
|
|
182
|
+
process.env.TAVILY_API_KEY = 'test-key';
|
|
183
|
+
let env;
|
|
184
|
+
try {
|
|
185
|
+
env = await mod.fetchIndustry(['quantum biotech'], {
|
|
186
|
+
tavily: makeTavilyMock([
|
|
187
|
+
{
|
|
188
|
+
company: 'AcmeQuantum',
|
|
189
|
+
signal: 'Series A funding for quantum imaging',
|
|
190
|
+
url: 'https://acmequantum.com/news',
|
|
191
|
+
source: 'tavily',
|
|
192
|
+
fetched_at: new Date().toISOString(),
|
|
193
|
+
},
|
|
194
|
+
]),
|
|
195
|
+
});
|
|
196
|
+
} finally {
|
|
197
|
+
if (prev === undefined) delete process.env.TAVILY_API_KEY;
|
|
198
|
+
else process.env.TAVILY_API_KEY = prev;
|
|
199
|
+
}
|
|
200
|
+
assertEnvelope(env, 'paid', 'tavily', 'T1');
|
|
201
|
+
assert.ok(env.results.length >= 1, 'T1: results non-empty');
|
|
202
|
+
// Backward-compat: rs-discovery-engine line 380 reads industry.signals.
|
|
203
|
+
assert.ok(Array.isArray(env.signals), 'T1: signals[] preserved for backward compat');
|
|
204
|
+
assert.ok(env.signals.length >= 1, 'T1: signals[] non-empty');
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
async function test_2_industry_native_fallback() {
|
|
208
|
+
// T2: no TAVILY_API_KEY; opts.webSearch returns native results.
|
|
209
|
+
const mod = freshRequire(PATH_INDUSTRY);
|
|
210
|
+
const prev = process.env.TAVILY_API_KEY;
|
|
211
|
+
delete process.env.TAVILY_API_KEY;
|
|
212
|
+
let env;
|
|
213
|
+
try {
|
|
214
|
+
env = await mod.fetchIndustry(['quantum biotech'], {
|
|
215
|
+
webSearch: makeWebSearchMock([
|
|
216
|
+
{
|
|
217
|
+
url: 'https://example.com/quantum',
|
|
218
|
+
title: 'Quantum Imaging Startup',
|
|
219
|
+
snippet: 'Series A round closed Q1 2026.',
|
|
220
|
+
},
|
|
221
|
+
]),
|
|
222
|
+
});
|
|
223
|
+
} finally {
|
|
224
|
+
if (prev !== undefined) process.env.TAVILY_API_KEY = prev;
|
|
225
|
+
}
|
|
226
|
+
assertEnvelope(env, 'native', 'websearch', 'T2');
|
|
227
|
+
assert.ok(env.results.length >= 1, 'T2: native results non-empty');
|
|
228
|
+
assert.ok(Array.isArray(env.signals), 'T2: signals[] preserved');
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
async function test_3_industry_cache_fallback() {
|
|
232
|
+
// T3: no TAVILY_API_KEY, no webSearch; cacheReader returns cached envelope.
|
|
233
|
+
const mod = freshRequire(PATH_INDUSTRY);
|
|
234
|
+
const prev = process.env.TAVILY_API_KEY;
|
|
235
|
+
delete process.env.TAVILY_API_KEY;
|
|
236
|
+
let env;
|
|
237
|
+
try {
|
|
238
|
+
env = await mod.fetchIndustry(['quantum biotech'], {
|
|
239
|
+
cacheReader: makeCacheReader({
|
|
240
|
+
results: [
|
|
241
|
+
{ company: 'CachedCorp', signal: 'cached signal', url: 'https://cached.example/' },
|
|
242
|
+
],
|
|
243
|
+
signals: [
|
|
244
|
+
{ company: 'CachedCorp', signal: 'cached signal', url: 'https://cached.example/' },
|
|
245
|
+
],
|
|
246
|
+
}),
|
|
247
|
+
});
|
|
248
|
+
} finally {
|
|
249
|
+
if (prev !== undefined) process.env.TAVILY_API_KEY = prev;
|
|
250
|
+
}
|
|
251
|
+
assertEnvelope(env, 'cache', 'cache', 'T3');
|
|
252
|
+
assert.ok(env.results.length >= 1, 'T3: cache results non-empty');
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
async function test_4_industry_all_tiers_down() {
|
|
256
|
+
// T4: no TAVILY_API_KEY, no webSearch, no cacheReader -> empty results,
|
|
257
|
+
// tier='cache' source='cache', never throws, signals[] still present.
|
|
258
|
+
const mod = freshRequire(PATH_INDUSTRY);
|
|
259
|
+
const prev = process.env.TAVILY_API_KEY;
|
|
260
|
+
delete process.env.TAVILY_API_KEY;
|
|
261
|
+
let env;
|
|
262
|
+
try {
|
|
263
|
+
env = await mod.fetchIndustry(['quantum biotech']);
|
|
264
|
+
} catch (err) {
|
|
265
|
+
throw new Error('T4: fetchIndustry threw on all-tiers-down: ' + err.message);
|
|
266
|
+
} finally {
|
|
267
|
+
if (prev !== undefined) process.env.TAVILY_API_KEY = prev;
|
|
268
|
+
}
|
|
269
|
+
assertEnvelope(env, 'cache', 'cache', 'T4');
|
|
270
|
+
assert.deepStrictEqual(env.results, [], 'T4: results is empty array');
|
|
271
|
+
assert.ok(Array.isArray(env.signals), 'T4: signals preserved as array');
|
|
272
|
+
assert.strictEqual(env.signals.length, 0, 'T4: signals empty');
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
async function test_5_envelope_shape_uniformity() {
|
|
276
|
+
// T5: academic / patents / experts must return {tier, source, results}
|
|
277
|
+
// with backward-compat domain-specific keys preserved (papers, patents,
|
|
278
|
+
// experts).
|
|
279
|
+
//
|
|
280
|
+
// These three modules already work without keys for free-tier paths.
|
|
281
|
+
// Plan amendment scope: envelope wrap only -- no new injection seams
|
|
282
|
+
// required (the modules already exist with their own logic). The wrap
|
|
283
|
+
// adds tier+source+results on top of existing shape.
|
|
284
|
+
|
|
285
|
+
// Academic: free tier (openalex / arxiv / pubmed) returns papers[]
|
|
286
|
+
// even with no env vars. We don't actually fetch the network here;
|
|
287
|
+
// we mock by setting all source budgets to 0 and asserting the
|
|
288
|
+
// module's wrap layer still emits an envelope.
|
|
289
|
+
{
|
|
290
|
+
const mod = freshRequire(PATH_ACADEMIC);
|
|
291
|
+
if (typeof mod.fetchAcademic !== 'function') {
|
|
292
|
+
throw new Error('T5: fetchAcademic export missing');
|
|
293
|
+
}
|
|
294
|
+
const env = await mod.fetchAcademic(['NV diamond'], {
|
|
295
|
+
// Zero every source budget so no real fetch fires; the wrap
|
|
296
|
+
// layer still must emit the envelope shape.
|
|
297
|
+
budget: {
|
|
298
|
+
openalex: 0,
|
|
299
|
+
arxiv: 0,
|
|
300
|
+
pubmed: 0,
|
|
301
|
+
scopus: 0,
|
|
302
|
+
ieee: 0,
|
|
303
|
+
nature: 0,
|
|
304
|
+
},
|
|
305
|
+
});
|
|
306
|
+
assertEnvelope(env, null, null, 'T5/academic');
|
|
307
|
+
assert.ok(Array.isArray(env.papers), 'T5/academic: papers[] preserved for backward compat');
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Patents: free tier (google_patents / uspto). Same pattern.
|
|
311
|
+
{
|
|
312
|
+
const mod = freshRequire(PATH_PATENTS);
|
|
313
|
+
if (typeof mod.fetchPatents !== 'function') {
|
|
314
|
+
throw new Error('T5: fetchPatents export missing');
|
|
315
|
+
}
|
|
316
|
+
const env = await mod.fetchPatents(['NV diamond'], {
|
|
317
|
+
budget: { google_patents: 0, uspto: 0 },
|
|
318
|
+
});
|
|
319
|
+
assertEnvelope(env, null, null, 'T5/patents');
|
|
320
|
+
assert.ok(Array.isArray(env.patents), 'T5/patents: patents[] preserved for backward compat');
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Experts: post-processor over papers[]. Pass empty papers; should
|
|
324
|
+
// return Array-with-envelope-properties hybrid (tier='derived',
|
|
325
|
+
// source='derived', experts[] preserved). The hybrid pattern means
|
|
326
|
+
// existing consumers (.length, .find, indexing) keep working AND the
|
|
327
|
+
// envelope contract holds.
|
|
328
|
+
{
|
|
329
|
+
const mod = freshRequire(PATH_EXPERTS);
|
|
330
|
+
if (typeof mod.mapExperts !== 'function') {
|
|
331
|
+
throw new Error('T5: mapExperts export missing');
|
|
332
|
+
}
|
|
333
|
+
const env = mod.mapExperts([]);
|
|
334
|
+
// Hybrid: must be an Array AND carry envelope properties.
|
|
335
|
+
if (!Array.isArray(env)) {
|
|
336
|
+
throw new Error('T5/experts: mapExperts must still return an Array (backward compat)');
|
|
337
|
+
}
|
|
338
|
+
if (typeof env.tier === 'undefined') {
|
|
339
|
+
throw new Error('T5/experts: mapExperts return missing tier envelope property');
|
|
340
|
+
}
|
|
341
|
+
assertEnvelope(env, 'derived', 'derived', 'T5/experts');
|
|
342
|
+
assert.ok(Array.isArray(env.experts), 'T5/experts: experts[] preserved for backward compat');
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
function test_6_section8_schema_field() {
|
|
347
|
+
// T6: lib/core/section-8-trace-schema.cjs exports a schema literal
|
|
348
|
+
// containing 'web_research_tier' somewhere reachable.
|
|
349
|
+
if (!fs.existsSync(PATH_SCHEMA)) {
|
|
350
|
+
throw new Error('T6: lib/core/section-8-trace-schema.cjs does not exist (RED)');
|
|
351
|
+
}
|
|
352
|
+
let mod;
|
|
353
|
+
try {
|
|
354
|
+
mod = freshRequire(PATH_SCHEMA);
|
|
355
|
+
} catch (err) {
|
|
356
|
+
throw new Error('T6: failed to require schema module: ' + err.message);
|
|
357
|
+
}
|
|
358
|
+
// Walk the export and look for the field anywhere reachable.
|
|
359
|
+
const seen = new Set();
|
|
360
|
+
function walk(node) {
|
|
361
|
+
if (node === null || node === undefined) return false;
|
|
362
|
+
if (typeof node === 'string') return node === 'web_research_tier';
|
|
363
|
+
if (typeof node !== 'object') return false;
|
|
364
|
+
if (seen.has(node)) return false;
|
|
365
|
+
seen.add(node);
|
|
366
|
+
for (const key of Object.keys(node)) {
|
|
367
|
+
if (key === 'web_research_tier') return true;
|
|
368
|
+
if (walk(node[key])) return true;
|
|
369
|
+
}
|
|
370
|
+
return false;
|
|
371
|
+
}
|
|
372
|
+
if (!walk(mod)) {
|
|
373
|
+
// Also search the source text as a fallback (the schema may
|
|
374
|
+
// expose the field via a JSON Schema that doesn't surface as a key).
|
|
375
|
+
const src = fs.readFileSync(PATH_SCHEMA, 'utf8');
|
|
376
|
+
if (src.indexOf('web_research_tier') < 0) {
|
|
377
|
+
throw new Error('T6: web_research_tier not found in schema export or source');
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
function test_7_research_md_body() {
|
|
383
|
+
// T7: commands/research.md frontmatter declares both WebSearch and
|
|
384
|
+
// WebFetch (verified) AND the body MUST NO LONGER contain the
|
|
385
|
+
// "Requires Brain MCP. Then stop." hard-stop that blocks fresh installs.
|
|
386
|
+
const src = fs.readFileSync(PATH_RESEARCH_MD, 'utf8');
|
|
387
|
+
// Frontmatter declarations (already correct pre-94-05; verified here).
|
|
388
|
+
assert.ok(/^\s*-\s+WebSearch\s*$/m.test(src),
|
|
389
|
+
'T7: allowed-tools must list WebSearch');
|
|
390
|
+
assert.ok(/^\s*-\s+WebFetch\s*$/m.test(src),
|
|
391
|
+
'T7: allowed-tools must list WebFetch');
|
|
392
|
+
// The hard-stop must be removed from the body.
|
|
393
|
+
if (/Requires Brain MCP/.test(src)) {
|
|
394
|
+
throw new Error('T7: body still contains "Requires Brain MCP" hard-stop');
|
|
395
|
+
}
|
|
396
|
+
if (/Then stop\./.test(src)) {
|
|
397
|
+
throw new Error('T7: body still contains "Then stop." directive');
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// ---------- Test runner ----------
|
|
402
|
+
|
|
403
|
+
const TESTS = [
|
|
404
|
+
['T1 industry happy paid', test_1_industry_happy_paid],
|
|
405
|
+
['T2 industry native fallback', test_2_industry_native_fallback],
|
|
406
|
+
['T3 industry cache fallback', test_3_industry_cache_fallback],
|
|
407
|
+
['T4 industry all-tiers-down', test_4_industry_all_tiers_down],
|
|
408
|
+
['T5 envelope shape uniformity', test_5_envelope_shape_uniformity],
|
|
409
|
+
['T6 section-8 schema web_research_tier', test_6_section8_schema_field],
|
|
410
|
+
['T7 research.md body hard-stop removed', test_7_research_md_body],
|
|
411
|
+
];
|
|
412
|
+
|
|
413
|
+
(async function main() {
|
|
414
|
+
let passed = 0;
|
|
415
|
+
let failed = 0;
|
|
416
|
+
for (const entry of TESTS) {
|
|
417
|
+
const name = entry[0];
|
|
418
|
+
const fn = entry[1];
|
|
419
|
+
try {
|
|
420
|
+
const r = fn();
|
|
421
|
+
if (r && typeof r.then === 'function') {
|
|
422
|
+
await r;
|
|
423
|
+
}
|
|
424
|
+
process.stdout.write('PASS ' + name + '\n');
|
|
425
|
+
passed += 1;
|
|
426
|
+
} catch (err) {
|
|
427
|
+
process.stderr.write('FAIL ' + name + ': ' + (err && err.message ? err.message : String(err)) + '\n');
|
|
428
|
+
failed += 1;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
process.stdout.write('\nmcp-stack-fallback: ' + passed + '/' + (passed + failed) + ' passed\n');
|
|
432
|
+
process.exit(failed === 0 ? 0 : 1);
|
|
433
|
+
})();
|