@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,467 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2026 Mindrian. BSL 1.1.
|
|
3
|
+
* Phase 89.3 Plan 04 -- expert mapper Cypher resolver.
|
|
4
|
+
*
|
|
5
|
+
* mapAuthorsToAura(experts, opts) is the Cypher MATCH-then-MERGE-and-resolve
|
|
6
|
+
* module that takes Plan 89.2-05 mapExperts output and resolves authors,
|
|
7
|
+
* institutions, and citation edges in the user's own Aura.
|
|
8
|
+
*
|
|
9
|
+
* Tier 1 (Aura connected): full Cypher resolution. For each expert: MATCH
|
|
10
|
+
* existing Author by composite name+orcid key; if not found, MERGE a new
|
|
11
|
+
* Author + Institution + AFFILIATED_WITH edge. Then run a CO_AUTHORED
|
|
12
|
+
* multi-hop query to populate citation_edges from any pair of authors
|
|
13
|
+
* sharing a Paper in the user's Aura.
|
|
14
|
+
*
|
|
15
|
+
* Tier 0 (no Aura) graceful degradation: per CONTEXT.md "Claude's Discretion
|
|
16
|
+
* path 3" decision, return partial data from rs-sqlite-mirror's Author +
|
|
17
|
+
* Institution rows in room.db with resolution_quality='degraded' AND a
|
|
18
|
+
* friendly note. This is more useful to the caller than an empty array.
|
|
19
|
+
*
|
|
20
|
+
* Output shape:
|
|
21
|
+
* {
|
|
22
|
+
* resolved_authors: [{name, orcid, institution, h_index_estimate,
|
|
23
|
+
* paper_count, aura_node_id?}],
|
|
24
|
+
* resolved_institutions: [{name, author_count, aura_node_id?}],
|
|
25
|
+
* citation_edges: [{source_author, target_author, paper_id,
|
|
26
|
+
* type: 'CO_AUTHORED' | 'CITED'}],
|
|
27
|
+
* missed_count: N,
|
|
28
|
+
* resolution_quality: 'full' | 'degraded',
|
|
29
|
+
* tier: 'aura' | 'sqlite',
|
|
30
|
+
* schema_version: '1.0',
|
|
31
|
+
* note?: string // present when degraded; absent when full
|
|
32
|
+
* }
|
|
33
|
+
*
|
|
34
|
+
* Canon Part 7 (Reuse Before Build):
|
|
35
|
+
* - Reuses lazygraph.openGraph + closeGraph for Tier 0 reads (no new
|
|
36
|
+
* SQLite wrapper)
|
|
37
|
+
* - Reuses AuraUnreachableError from Plan 89.3-01 rs-neo4j-writer (re-throws
|
|
38
|
+
* on backend failure -- clean tier-dispatch signal for Plan 89.3-05)
|
|
39
|
+
* - Reuses ExternalEgressViolation + auditQueryObject from 89.2 chokepoints
|
|
40
|
+
* - Author MERGE pattern mirrors rs-neo4j-writer.cjs (composite
|
|
41
|
+
* name_orcid_key with __no_orcid__ sentinel)
|
|
42
|
+
*
|
|
43
|
+
* Canon Part 8 (Graph Boundary -- defense-in-depth) at TWO seams:
|
|
44
|
+
* - Layer 1 (pre-Cypher): auditQueryObject(cypher_params, 'rs-expert-mapper')
|
|
45
|
+
* runs BEFORE every session.run call. Catches forbidden patterns in
|
|
46
|
+
* expert.name, expert.orcid, expert.institution. Throws
|
|
47
|
+
* ExternalEgressViolation; session.run NEVER runs.
|
|
48
|
+
* - Layer 2 (pre-return): auditQueryObject(result, 'rs-expert-mapper-output')
|
|
49
|
+
* runs BEFORE returning to catch any forbidden patterns that smuggled
|
|
50
|
+
* through. Conservative because the resolved_authors array flows
|
|
51
|
+
* downstream into Plan 89.3-03 mind-map rendering AND any future
|
|
52
|
+
* expert-network UI.
|
|
53
|
+
*
|
|
54
|
+
* Tier dispatch is opt-in (caller passes opts.tier explicitly OR auto-detect
|
|
55
|
+
* from opts.driver vs opts.roomDir). Throws TypeError if neither.
|
|
56
|
+
*
|
|
57
|
+
* Pure CJS, zero npm deps, node built-ins only.
|
|
58
|
+
*/
|
|
59
|
+
'use strict';
|
|
60
|
+
|
|
61
|
+
const { ExternalEgressViolation } = require('./rs-egress-violations.cjs');
|
|
62
|
+
const { auditQueryObject } = require('./rs-egress-prompts.cjs');
|
|
63
|
+
const { AuraUnreachableError } = require('./rs-neo4j-writer.cjs');
|
|
64
|
+
const lazygraph = require('./lazygraph-ops.cjs');
|
|
65
|
+
|
|
66
|
+
const SURFACE_PRE = 'rs-expert-mapper';
|
|
67
|
+
const SURFACE_POST = 'rs-expert-mapper-output';
|
|
68
|
+
const SCHEMA_VERSION = '1.0';
|
|
69
|
+
const DEGRADED_NOTE = 'Expert resolution from local SQLite mirror only. Connect LazyGraph Aura for full multi-hop citation graph.';
|
|
70
|
+
|
|
71
|
+
// ---------- buildAuthorKey ----------
|
|
72
|
+
//
|
|
73
|
+
// Composite key mirrors Plan 89.2-05 mapExperts AND Plan 89.3-01
|
|
74
|
+
// rs-neo4j-writer (name_orcid_key in Cypher MERGE). __no_orcid__ sentinel
|
|
75
|
+
// disambiguates authors who lack ORCID by name alone.
|
|
76
|
+
|
|
77
|
+
function buildAuthorKey(expert) {
|
|
78
|
+
const name = (expert && typeof expert.name === 'string') ? expert.name : '';
|
|
79
|
+
const orcid = (expert && typeof expert.orcid === 'string' && expert.orcid.length > 0) ? expert.orcid : '__no_orcid__';
|
|
80
|
+
return name + '|' + orcid;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// ---------- buildCypherParamsForExpert ----------
|
|
84
|
+
//
|
|
85
|
+
// Per-expert params object passed to session.run for MATCH/MERGE. The audit
|
|
86
|
+
// surface (Layer 1) JSON.stringify-walks this object.
|
|
87
|
+
|
|
88
|
+
function buildCypherParamsForExpert(expert) {
|
|
89
|
+
return {
|
|
90
|
+
key: buildAuthorKey(expert),
|
|
91
|
+
name: typeof expert.name === 'string' ? expert.name : '',
|
|
92
|
+
orcid: typeof expert.orcid === 'string' ? expert.orcid : null,
|
|
93
|
+
institution: typeof expert.institution === 'string' ? expert.institution : null,
|
|
94
|
+
h_index_estimate: typeof expert.h_index_estimate === 'number' ? expert.h_index_estimate : 0,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ---------- detectTier ----------
|
|
99
|
+
//
|
|
100
|
+
// Tier dispatch surface: caller passes opts.tier explicitly OR auto-detect
|
|
101
|
+
// from opts.driver (aura) vs opts.roomDir (sqlite). Throws TypeError if
|
|
102
|
+
// neither, so the caller surfaces a precise error to the user.
|
|
103
|
+
|
|
104
|
+
async function detectTier(opts) {
|
|
105
|
+
if (opts && (opts.tier === 'aura' || opts.tier === 'sqlite')) return opts.tier;
|
|
106
|
+
if (opts && opts.driver && typeof opts.driver.session === 'function') return 'aura';
|
|
107
|
+
if (opts && typeof opts.roomDir === 'string' && opts.roomDir.length > 0) return 'sqlite';
|
|
108
|
+
throw new TypeError(SURFACE_PRE + ': opts.tier OR opts.driver OR opts.roomDir required');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ---------- Cypher templates ----------
|
|
112
|
+
|
|
113
|
+
const MATCH_AUTHOR_CYPHER = [
|
|
114
|
+
'MATCH (a:Author {name_orcid_key: $key})',
|
|
115
|
+
'RETURN a.name AS name, a.orcid AS orcid, id(a) AS aura_node_id',
|
|
116
|
+
].join('\n');
|
|
117
|
+
|
|
118
|
+
const MERGE_AUTHOR_CYPHER = [
|
|
119
|
+
'MERGE (a:Author {name_orcid_key: $key})',
|
|
120
|
+
' SET a.name = $name,',
|
|
121
|
+
' a.orcid = $orcid,',
|
|
122
|
+
' a.h_index_estimate = $h_index_estimate',
|
|
123
|
+
'WITH a',
|
|
124
|
+
'WHERE $institution IS NOT NULL',
|
|
125
|
+
' MERGE (inst:Institution {name: $institution})',
|
|
126
|
+
' MERGE (a)-[:AFFILIATED_WITH]->(inst)',
|
|
127
|
+
'RETURN a.name AS name, id(a) AS aura_node_id',
|
|
128
|
+
].join('\n');
|
|
129
|
+
|
|
130
|
+
const CO_AUTHORED_CYPHER = [
|
|
131
|
+
'MATCH (a1:Author)-[:AUTHORED_BY]-(p:Paper)-[:AUTHORED_BY]-(a2:Author)',
|
|
132
|
+
'WHERE id(a1) < id(a2)',
|
|
133
|
+
'RETURN a1.name AS source_author, a2.name AS target_author, p.id AS paper_id',
|
|
134
|
+
].join('\n');
|
|
135
|
+
|
|
136
|
+
// ---------- resolveAuraExpert ----------
|
|
137
|
+
//
|
|
138
|
+
// Per-expert Aura resolver: MATCH first; if 0 rows, MERGE. Returns the
|
|
139
|
+
// per-expert resolution record.
|
|
140
|
+
// {name, orcid, institution, h_index_estimate, paper_count, aura_node_id?,
|
|
141
|
+
// matched, merged, missed}
|
|
142
|
+
|
|
143
|
+
async function resolveAuraExpert(expert, driver) {
|
|
144
|
+
const params = buildCypherParamsForExpert(expert);
|
|
145
|
+
const session = driver.session();
|
|
146
|
+
let matched = false;
|
|
147
|
+
let merged = false;
|
|
148
|
+
let missed = false;
|
|
149
|
+
let aura_node_id;
|
|
150
|
+
try {
|
|
151
|
+
const matchResult = await session.run(MATCH_AUTHOR_CYPHER, params);
|
|
152
|
+
const records = (matchResult && Array.isArray(matchResult.records)) ? matchResult.records : [];
|
|
153
|
+
if (records.length > 0) {
|
|
154
|
+
matched = true;
|
|
155
|
+
const r = records[0];
|
|
156
|
+
const id = (typeof r.get === 'function') ? r.get('aura_node_id') : null;
|
|
157
|
+
if (id !== undefined && id !== null) aura_node_id = id;
|
|
158
|
+
} else {
|
|
159
|
+
// Unmatched: try MERGE.
|
|
160
|
+
try {
|
|
161
|
+
const mergeResult = await session.run(MERGE_AUTHOR_CYPHER, params);
|
|
162
|
+
const mRecords = (mergeResult && Array.isArray(mergeResult.records)) ? mergeResult.records : [];
|
|
163
|
+
if (mRecords.length > 0) {
|
|
164
|
+
merged = true;
|
|
165
|
+
const r = mRecords[0];
|
|
166
|
+
const id = (typeof r.get === 'function') ? r.get('aura_node_id') : null;
|
|
167
|
+
if (id !== undefined && id !== null) aura_node_id = id;
|
|
168
|
+
} else {
|
|
169
|
+
missed = true;
|
|
170
|
+
}
|
|
171
|
+
} catch (mergeErr) {
|
|
172
|
+
// MERGE failure (e.g. constraint violation) -> count as missed,
|
|
173
|
+
// do NOT propagate (this is per-expert resilience). However, if
|
|
174
|
+
// the error is a connection-level failure, surface it so the
|
|
175
|
+
// outer try/catch can convert to AuraUnreachableError.
|
|
176
|
+
if (/ECONNREFUSED|ETIMEDOUT|ECONNRESET|connect\s+E/i.test(mergeErr.message || '')) {
|
|
177
|
+
throw mergeErr;
|
|
178
|
+
}
|
|
179
|
+
missed = true;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
} finally {
|
|
183
|
+
if (session && typeof session.close === 'function') {
|
|
184
|
+
try {
|
|
185
|
+
await session.close();
|
|
186
|
+
} catch (_e) { /* best effort */ }
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
name: expert.name,
|
|
191
|
+
orcid: expert.orcid || null,
|
|
192
|
+
institution: expert.institution || null,
|
|
193
|
+
h_index_estimate: typeof expert.h_index_estimate === 'number' ? expert.h_index_estimate : 0,
|
|
194
|
+
paper_count: typeof expert.paper_count === 'number' ? expert.paper_count : 0,
|
|
195
|
+
aura_node_id: aura_node_id,
|
|
196
|
+
matched: matched,
|
|
197
|
+
merged: merged,
|
|
198
|
+
missed: missed,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// ---------- fetchAuraCitationEdges ----------
|
|
203
|
+
//
|
|
204
|
+
// Multi-hop CO_AUTHORED query against the user's Aura. Returns an array of
|
|
205
|
+
// {source_author, target_author, paper_id, type: 'CO_AUTHORED'} records.
|
|
206
|
+
// Best-effort -- if the query returns zero rows (e.g. no Paper nodes carry
|
|
207
|
+
// AUTHORED_BY edges yet), the array is empty.
|
|
208
|
+
|
|
209
|
+
async function fetchAuraCitationEdges(driver) {
|
|
210
|
+
const session = driver.session();
|
|
211
|
+
try {
|
|
212
|
+
const result = await session.run(CO_AUTHORED_CYPHER, {});
|
|
213
|
+
const records = (result && Array.isArray(result.records)) ? result.records : [];
|
|
214
|
+
const edges = [];
|
|
215
|
+
for (const r of records) {
|
|
216
|
+
if (typeof r.get !== 'function') continue;
|
|
217
|
+
edges.push({
|
|
218
|
+
source_author: r.get('source_author'),
|
|
219
|
+
target_author: r.get('target_author'),
|
|
220
|
+
paper_id: r.get('paper_id'),
|
|
221
|
+
type: 'CO_AUTHORED',
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
return edges;
|
|
225
|
+
} finally {
|
|
226
|
+
if (session && typeof session.close === 'function') {
|
|
227
|
+
try {
|
|
228
|
+
await session.close();
|
|
229
|
+
} catch (_e) { /* best effort */ }
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// ---------- resolveSqliteExperts ----------
|
|
235
|
+
//
|
|
236
|
+
// Tier 0 path: open the user's room.db via lazygraph.openGraph (Canon Part 7
|
|
237
|
+
// reuse), SELECT all Author + Institution rows, walk the experts[] input,
|
|
238
|
+
// match by composite key. Build citation_edges best-effort from
|
|
239
|
+
// AUTHORED_BY edges (any pair sharing a Paper).
|
|
240
|
+
//
|
|
241
|
+
// Returns {resolved, missed, citation_edges, resolved_institutions}.
|
|
242
|
+
|
|
243
|
+
async function resolveSqliteExperts(experts, roomDir) {
|
|
244
|
+
const handle = await lazygraph.openGraph(roomDir);
|
|
245
|
+
try {
|
|
246
|
+
// SELECT all Author rows (id is the composite key).
|
|
247
|
+
const authorRows = handle.conn.prepare("SELECT id, properties FROM nodes WHERE type = 'Author'").all();
|
|
248
|
+
const authorIdSet = new Set(authorRows.map(function (r) { return r.id; }));
|
|
249
|
+
|
|
250
|
+
// Walk experts[]; match by composite key.
|
|
251
|
+
const resolved = [];
|
|
252
|
+
let missed = 0;
|
|
253
|
+
for (const e of experts) {
|
|
254
|
+
const key = buildAuthorKey(e);
|
|
255
|
+
if (authorIdSet.has(key)) {
|
|
256
|
+
resolved.push({
|
|
257
|
+
name: e.name,
|
|
258
|
+
orcid: e.orcid || null,
|
|
259
|
+
institution: e.institution || null,
|
|
260
|
+
h_index_estimate: typeof e.h_index_estimate === 'number' ? e.h_index_estimate : 0,
|
|
261
|
+
paper_count: typeof e.paper_count === 'number' ? e.paper_count : 0,
|
|
262
|
+
});
|
|
263
|
+
} else {
|
|
264
|
+
missed += 1;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Aggregate institutions from resolved authors.
|
|
269
|
+
const instCounts = new Map();
|
|
270
|
+
for (const a of resolved) {
|
|
271
|
+
if (a.institution) {
|
|
272
|
+
instCounts.set(a.institution, (instCounts.get(a.institution) || 0) + 1);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
const resolved_institutions = [];
|
|
276
|
+
instCounts.forEach(function (count, name) {
|
|
277
|
+
resolved_institutions.push({ name: name, author_count: count });
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
// Best-effort citation_edges from AUTHORED_BY edges. SELECT pairs of
|
|
281
|
+
// authors sharing a Paper (i.e. two AUTHORED_BY edges with the same
|
|
282
|
+
// source paper).
|
|
283
|
+
const coAuthorRows = handle.conn.prepare(
|
|
284
|
+
"SELECT e1.source AS paper_id, e1.target AS author1, e2.target AS author2 " +
|
|
285
|
+
"FROM edges e1, edges e2 " +
|
|
286
|
+
"WHERE e1.type = 'AUTHORED_BY' AND e2.type = 'AUTHORED_BY' " +
|
|
287
|
+
"AND e1.source = e2.source AND e1.target < e2.target"
|
|
288
|
+
).all();
|
|
289
|
+
|
|
290
|
+
// Resolve author keys back to names via the authorRows we already loaded.
|
|
291
|
+
const keyToName = new Map();
|
|
292
|
+
for (const r of authorRows) {
|
|
293
|
+
try {
|
|
294
|
+
const props = JSON.parse(r.properties);
|
|
295
|
+
keyToName.set(r.id, props.name || r.id);
|
|
296
|
+
} catch (_e) {
|
|
297
|
+
keyToName.set(r.id, r.id);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
const citation_edges = [];
|
|
301
|
+
for (const row of coAuthorRows) {
|
|
302
|
+
citation_edges.push({
|
|
303
|
+
source_author: keyToName.get(row.author1) || row.author1,
|
|
304
|
+
target_author: keyToName.get(row.author2) || row.author2,
|
|
305
|
+
paper_id: row.paper_id,
|
|
306
|
+
type: 'CO_AUTHORED',
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
return {
|
|
311
|
+
resolved: resolved,
|
|
312
|
+
missed: missed,
|
|
313
|
+
citation_edges: citation_edges,
|
|
314
|
+
resolved_institutions: resolved_institutions,
|
|
315
|
+
};
|
|
316
|
+
} finally {
|
|
317
|
+
await lazygraph.closeGraph(handle.db);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// ---------- mapAuthorsToAura ----------
|
|
322
|
+
//
|
|
323
|
+
// The public entry point. Orchestration:
|
|
324
|
+
// 1. Validate experts is an array (throws TypeError)
|
|
325
|
+
// 2. Detect tier (throws TypeError if neither opts.tier/driver/roomDir)
|
|
326
|
+
// 3. Empty experts -> early return shape (Layer 2 audit always runs)
|
|
327
|
+
// 4. Layer 1 audit: scan every per-expert cypher params object pre-Cypher
|
|
328
|
+
// (covers expert.name + expert.orcid + expert.institution leak vectors)
|
|
329
|
+
// 5. Tier 1 (aura): per-expert MATCH-then-MERGE; CO_AUTHORED query;
|
|
330
|
+
// AuraUnreachableError on backend failure
|
|
331
|
+
// 6. Tier 0 (sqlite): SELECT from room.db; degraded result + DEGRADED_NOTE
|
|
332
|
+
// 7. Layer 2 audit: scan output object pre-return (defense-in-depth)
|
|
333
|
+
// 8. Return result
|
|
334
|
+
|
|
335
|
+
async function mapAuthorsToAura(experts, opts) {
|
|
336
|
+
opts = opts || {};
|
|
337
|
+
if (!Array.isArray(experts)) {
|
|
338
|
+
throw new TypeError(SURFACE_PRE + ': experts must be an array');
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
const tier = await detectTier(opts);
|
|
342
|
+
|
|
343
|
+
// Empty input early return.
|
|
344
|
+
if (experts.length === 0) {
|
|
345
|
+
const empty = {
|
|
346
|
+
resolved_authors: [],
|
|
347
|
+
resolved_institutions: [],
|
|
348
|
+
citation_edges: [],
|
|
349
|
+
missed_count: 0,
|
|
350
|
+
resolution_quality: tier === 'aura' ? 'full' : 'degraded',
|
|
351
|
+
tier: tier,
|
|
352
|
+
schema_version: SCHEMA_VERSION,
|
|
353
|
+
};
|
|
354
|
+
if (tier === 'sqlite') empty.note = DEGRADED_NOTE;
|
|
355
|
+
// Layer 2 audit: even empty -- defense-in-depth always runs.
|
|
356
|
+
auditQueryObject(empty, SURFACE_POST);
|
|
357
|
+
return empty;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// Layer 1 audit: per-expert pre-Cypher Canon Part 8 scan.
|
|
361
|
+
for (const e of experts) {
|
|
362
|
+
auditQueryObject(buildCypherParamsForExpert(e), SURFACE_PRE);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
let resolved_authors;
|
|
366
|
+
let resolved_institutions;
|
|
367
|
+
let citation_edges;
|
|
368
|
+
let missed_count;
|
|
369
|
+
|
|
370
|
+
if (tier === 'aura') {
|
|
371
|
+
if (!opts.driver || typeof opts.driver.session !== 'function') {
|
|
372
|
+
throw new TypeError(SURFACE_PRE + ': opts.driver required for tier=aura');
|
|
373
|
+
}
|
|
374
|
+
try {
|
|
375
|
+
const results = [];
|
|
376
|
+
for (const e of experts) {
|
|
377
|
+
const r = await resolveAuraExpert(e, opts.driver);
|
|
378
|
+
results.push(r);
|
|
379
|
+
}
|
|
380
|
+
resolved_authors = results
|
|
381
|
+
.filter(function (r) { return !r.missed; })
|
|
382
|
+
.map(function (r) {
|
|
383
|
+
return {
|
|
384
|
+
name: r.name,
|
|
385
|
+
orcid: r.orcid,
|
|
386
|
+
institution: r.institution,
|
|
387
|
+
h_index_estimate: r.h_index_estimate,
|
|
388
|
+
paper_count: r.paper_count,
|
|
389
|
+
aura_node_id: r.aura_node_id,
|
|
390
|
+
};
|
|
391
|
+
});
|
|
392
|
+
missed_count = results.filter(function (r) { return r.missed; }).length;
|
|
393
|
+
// Aggregate institutions from resolved authors.
|
|
394
|
+
const instCounts = new Map();
|
|
395
|
+
for (const a of resolved_authors) {
|
|
396
|
+
if (a.institution) {
|
|
397
|
+
instCounts.set(a.institution, (instCounts.get(a.institution) || 0) + 1);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
resolved_institutions = [];
|
|
401
|
+
instCounts.forEach(function (count, name) {
|
|
402
|
+
resolved_institutions.push({ name: name, author_count: count });
|
|
403
|
+
});
|
|
404
|
+
// Multi-hop CO_AUTHORED query (best-effort).
|
|
405
|
+
try {
|
|
406
|
+
citation_edges = await fetchAuraCitationEdges(opts.driver);
|
|
407
|
+
} catch (cxErr) {
|
|
408
|
+
if (cxErr instanceof ExternalEgressViolation) throw cxErr;
|
|
409
|
+
if (cxErr instanceof AuraUnreachableError) throw cxErr;
|
|
410
|
+
// Connection-level errors during CO_AUTHORED bubble up as Aura unreachable.
|
|
411
|
+
throw new AuraUnreachableError(
|
|
412
|
+
'Aura backend unreachable during CO_AUTHORED query: ' + cxErr.message,
|
|
413
|
+
{ original: cxErr.message }
|
|
414
|
+
);
|
|
415
|
+
}
|
|
416
|
+
} catch (err) {
|
|
417
|
+
if (err instanceof ExternalEgressViolation) throw err;
|
|
418
|
+
if (err instanceof AuraUnreachableError) throw err;
|
|
419
|
+
throw new AuraUnreachableError(
|
|
420
|
+
'Aura backend unreachable in rs-expert-mapper: ' + (err && err.message ? err.message : String(err)),
|
|
421
|
+
{ original: err && err.message ? err.message : String(err) }
|
|
422
|
+
);
|
|
423
|
+
}
|
|
424
|
+
} else {
|
|
425
|
+
// tier === 'sqlite'
|
|
426
|
+
const sql = await resolveSqliteExperts(experts, opts.roomDir);
|
|
427
|
+
resolved_authors = sql.resolved;
|
|
428
|
+
missed_count = sql.missed;
|
|
429
|
+
citation_edges = sql.citation_edges;
|
|
430
|
+
resolved_institutions = sql.resolved_institutions;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
const result = {
|
|
434
|
+
resolved_authors: resolved_authors,
|
|
435
|
+
resolved_institutions: resolved_institutions,
|
|
436
|
+
citation_edges: citation_edges,
|
|
437
|
+
missed_count: missed_count,
|
|
438
|
+
resolution_quality: tier === 'aura' ? 'full' : 'degraded',
|
|
439
|
+
tier: tier,
|
|
440
|
+
schema_version: SCHEMA_VERSION,
|
|
441
|
+
};
|
|
442
|
+
if (tier === 'sqlite') result.note = DEGRADED_NOTE;
|
|
443
|
+
|
|
444
|
+
// Layer 2 audit: pre-return Canon Part 8 scan. Throws on hit.
|
|
445
|
+
auditQueryObject(result, SURFACE_POST);
|
|
446
|
+
|
|
447
|
+
return result;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// ---------- Exports ----------
|
|
451
|
+
|
|
452
|
+
module.exports = {
|
|
453
|
+
mapAuthorsToAura,
|
|
454
|
+
DEGRADED_NOTE,
|
|
455
|
+
SCHEMA_VERSION,
|
|
456
|
+
_test: {
|
|
457
|
+
detectTier,
|
|
458
|
+
buildAuthorKey,
|
|
459
|
+
buildCypherParamsForExpert,
|
|
460
|
+
resolveAuraExpert,
|
|
461
|
+
fetchAuraCitationEdges,
|
|
462
|
+
resolveSqliteExperts,
|
|
463
|
+
MATCH_AUTHOR_CYPHER,
|
|
464
|
+
MERGE_AUTHOR_CYPHER,
|
|
465
|
+
CO_AUTHORED_CYPHER,
|
|
466
|
+
},
|
|
467
|
+
};
|