@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,388 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2026 Mindrian. BSL 1.1.
|
|
3
|
+
* Phase 89.3 Plan 01 -- Aura Cypher writer for canonical RS schema.
|
|
4
|
+
*
|
|
5
|
+
* writeDiscovery(pair, opts) is the Tier 1 (Aura-connected) writer in the
|
|
6
|
+
* dual-tier output layer. Takes a scored+classified+thesis-bearing pair
|
|
7
|
+
* (from Plan 89.2-07 generateThesis output) and persists it into the user's
|
|
8
|
+
* own LazyGraph Aura via idempotent MERGE Cypher.
|
|
9
|
+
*
|
|
10
|
+
* Schema (per kickoff section 5):
|
|
11
|
+
* Nodes: RSDiscovery + ReverseSalient + Innovation + Paper + Author + Institution
|
|
12
|
+
* Edges: DISCOVERED + DERIVED_FROM + ENABLES + AUTHORED_BY + AFFILIATED_WITH
|
|
13
|
+
*
|
|
14
|
+
* REAL idempotency in Aura (not mock-state tracking): the 3 core node ids
|
|
15
|
+
* (discovery_id, rs_id, innovation_id) are deterministically derived via
|
|
16
|
+
* sha256 over {query_concept, doc_concept, classification}, so the same
|
|
17
|
+
* pair always produces the same ids and Cypher MERGE matches existing
|
|
18
|
+
* nodes by id PRIMARY KEY. The aura_op_id is random per-op telemetry,
|
|
19
|
+
* NOT a node identifier.
|
|
20
|
+
*
|
|
21
|
+
* The buildDeterministicIds helper mirrors Plan 89.3-02 (rs-sqlite-mirror)
|
|
22
|
+
* byte-for-byte so the dual-tier dedup contract is consistent across
|
|
23
|
+
* writers. Both backends produce the same ids for the same pair.
|
|
24
|
+
*
|
|
25
|
+
* Canon Part 7 (Reuse Before Build): consumes EDGE_TYPES from
|
|
26
|
+
* lazygraph-ops.cjs (extended in this plan, not forked); shares
|
|
27
|
+
* ExternalEgressViolation + auditQueryObject with 89.2 fetchers.
|
|
28
|
+
*
|
|
29
|
+
* Canon Part 8 (Graph Boundary -- defense-in-depth): even though writes
|
|
30
|
+
* go to the user's OWN graph (not Brain), auditQueryObject runs over the
|
|
31
|
+
* full Cypher params object BEFORE every session.run call. Catches
|
|
32
|
+
* forbidden patterns smuggled through node properties OR UNWIND input
|
|
33
|
+
* collections (papers / experts / paper_author_pairs). Throws
|
|
34
|
+
* ExternalEgressViolation on hit.
|
|
35
|
+
*
|
|
36
|
+
* Tier dispatch is NOT this module's responsibility. The writer assumes
|
|
37
|
+
* Aura is reachable. If the backend returns a connection error, throws
|
|
38
|
+
* AuraUnreachableError (a SEPARATE class, NOT ExternalEgressViolation).
|
|
39
|
+
* Caller (Plan 89.3-05 dispatch) reads this error to fall back to
|
|
40
|
+
* rs-sqlite-mirror.
|
|
41
|
+
*
|
|
42
|
+
* Mockable backend: opts.driver is the injection point. Tests pass a mock
|
|
43
|
+
* driver; production callers (Plan 89.3-05) pass the live Aura driver.
|
|
44
|
+
*
|
|
45
|
+
* Pure CJS, zero npm deps, node built-ins only (crypto).
|
|
46
|
+
*/
|
|
47
|
+
'use strict';
|
|
48
|
+
|
|
49
|
+
const crypto = require('crypto');
|
|
50
|
+
const { ExternalEgressViolation } = require('./rs-egress-violations.cjs');
|
|
51
|
+
const { auditQueryObject } = require('./rs-egress-prompts.cjs');
|
|
52
|
+
const { EDGE_TYPES } = require('./lazygraph-ops.cjs');
|
|
53
|
+
|
|
54
|
+
const SURFACE = 'rs-neo4j-writer';
|
|
55
|
+
const SCHEMA_VERSION = '1.0';
|
|
56
|
+
const REQUIRED_FIELDS = Object.freeze(['query_concept', 'doc_concept', 'classification', 'thesis']);
|
|
57
|
+
|
|
58
|
+
// ---------- AuraUnreachableError ----------
|
|
59
|
+
//
|
|
60
|
+
// Tier-dispatch signal (NOT a security violation). Caller catches this and
|
|
61
|
+
// falls back to rs-sqlite-mirror (Tier 0). Distinct from ExternalEgressViolation
|
|
62
|
+
// so the two error classes never get conflated in stack traces or audit logs.
|
|
63
|
+
|
|
64
|
+
class AuraUnreachableError extends Error {
|
|
65
|
+
constructor(message, meta) {
|
|
66
|
+
super(message);
|
|
67
|
+
this.name = 'AuraUnreachableError';
|
|
68
|
+
this.meta = meta || {};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ---------- buildDeterministicIds ----------
|
|
73
|
+
//
|
|
74
|
+
// The dedup contract shared with Plan 89.3-02 (rs-sqlite-mirror). The
|
|
75
|
+
// implementation MUST be byte-identical across both writers so the same
|
|
76
|
+
// pair produces the same 3 core ids regardless of which tier is active.
|
|
77
|
+
//
|
|
78
|
+
// stableKey is JSON.stringify of {q, d, c} (in fixed key order so the
|
|
79
|
+
// resulting bytes are stable across Node versions). sha256 then hex-slice
|
|
80
|
+
// the first 16 chars gives a 64-bit collision space (sufficient for
|
|
81
|
+
// per-room discovery counts; collision probability negligible).
|
|
82
|
+
|
|
83
|
+
function buildDeterministicIds(pair) {
|
|
84
|
+
const stableKey = JSON.stringify({
|
|
85
|
+
q: pair.query_concept,
|
|
86
|
+
d: pair.doc_concept,
|
|
87
|
+
c: pair.classification,
|
|
88
|
+
});
|
|
89
|
+
const hash = crypto.createHash('sha256').update(stableKey).digest('hex').slice(0, 16);
|
|
90
|
+
return {
|
|
91
|
+
discovery_id: 'rsd-' + hash,
|
|
92
|
+
rs_id: 'rs-' + hash,
|
|
93
|
+
innovation_id: 'inn-' + hash,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// ---------- generateOpId ----------
|
|
98
|
+
//
|
|
99
|
+
// Random per-op telemetry id (NOT a node id). Caller may journal this for
|
|
100
|
+
// rollback bookkeeping. The id is intentionally non-deterministic so two
|
|
101
|
+
// re-runs of the same pair produce DIFFERENT op ids (proving the call
|
|
102
|
+
// happened twice even though the underlying nodes were MERGE-matched).
|
|
103
|
+
|
|
104
|
+
function generateOpId() {
|
|
105
|
+
return 'op-' + new Date().toISOString().slice(0, 10) + '-' + crypto.randomUUID();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// ---------- validateRequiredFields ----------
|
|
109
|
+
//
|
|
110
|
+
// Shape gate. Runs BEFORE audit + driver call. Throws TypeError naming the
|
|
111
|
+
// missing field so callers can surface a precise error to the user.
|
|
112
|
+
|
|
113
|
+
function validateRequiredFields(pair) {
|
|
114
|
+
if (!pair || typeof pair !== 'object') {
|
|
115
|
+
throw new TypeError(SURFACE + ': pair must be an object');
|
|
116
|
+
}
|
|
117
|
+
for (const f of REQUIRED_FIELDS) {
|
|
118
|
+
if (typeof pair[f] !== 'string' || pair[f].length === 0) {
|
|
119
|
+
throw new TypeError(SURFACE + ': missing required field: ' + f);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// ---------- buildCypherParams ----------
|
|
125
|
+
//
|
|
126
|
+
// Assemble the params object passed to session.run. Includes all node
|
|
127
|
+
// properties (RSDiscovery + ReverseSalient + Innovation core; Paper +
|
|
128
|
+
// Author + Institution conditional on opts.context).
|
|
129
|
+
//
|
|
130
|
+
// CRITICAL: paper_author_pairs is constructed from
|
|
131
|
+
// ctx.papers.flatMap(p => (p.authors || []).map(a => ({
|
|
132
|
+
// paper_id: p.id,
|
|
133
|
+
// author_key: a.name + '|' + (a.orcid || '__no_orcid__')
|
|
134
|
+
// })))
|
|
135
|
+
// so the AUTHORED_BY UNWIND has ready-to-MATCH tuples. The author_key
|
|
136
|
+
// shape mirrors the Author MERGE key (name + '|' + orcid-or-sentinel)
|
|
137
|
+
// so MATCH succeeds without a JOIN.
|
|
138
|
+
//
|
|
139
|
+
// paper_author_pairs is ALWAYS present (possibly []) so the Cypher does
|
|
140
|
+
// not need an IF guard around the UNWIND.
|
|
141
|
+
|
|
142
|
+
function buildCypherParams(pair, ctx, ids) {
|
|
143
|
+
const breakthrough = pair.breakthrough || {};
|
|
144
|
+
const breakdown = breakthrough.breakdown || {};
|
|
145
|
+
const created_at = new Date().toISOString();
|
|
146
|
+
|
|
147
|
+
const papers = Array.isArray(ctx.papers) ? ctx.papers : [];
|
|
148
|
+
const experts = Array.isArray(ctx.experts) ? ctx.experts : [];
|
|
149
|
+
|
|
150
|
+
const paper_author_pairs = papers.reduce(function (acc, p) {
|
|
151
|
+
const authors = Array.isArray(p.authors) ? p.authors : [];
|
|
152
|
+
for (const a of authors) {
|
|
153
|
+
acc.push({
|
|
154
|
+
paper_id: p.id,
|
|
155
|
+
author_key: (a.name || '') + '|' + (a.orcid || '__no_orcid__'),
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
return acc;
|
|
159
|
+
}, []);
|
|
160
|
+
|
|
161
|
+
return {
|
|
162
|
+
// Core RS node ids (deterministic).
|
|
163
|
+
discovery_id: ids.discovery_id,
|
|
164
|
+
rs_id: ids.rs_id,
|
|
165
|
+
innovation_id: ids.innovation_id,
|
|
166
|
+
// RSDiscovery properties.
|
|
167
|
+
classification: pair.classification,
|
|
168
|
+
breakthrough_score: typeof breakthrough.score === 'number' ? breakthrough.score : 0,
|
|
169
|
+
dominant_dimension: typeof breakthrough.dominant_dimension === 'string' ? breakthrough.dominant_dimension : '',
|
|
170
|
+
thesis: pair.thesis,
|
|
171
|
+
bridge_concept: typeof pair.bridge_concept === 'string' ? pair.bridge_concept : '',
|
|
172
|
+
diff: typeof pair.diff === 'number' ? pair.diff : 0,
|
|
173
|
+
lsa: typeof pair.lsa === 'number' ? pair.lsa : 0,
|
|
174
|
+
bert: typeof pair.bert === 'number' ? pair.bert : 0,
|
|
175
|
+
feasibility: typeof breakdown.feasibility === 'number' ? breakdown.feasibility : 0,
|
|
176
|
+
market: typeof breakdown.market === 'number' ? breakdown.market : 0,
|
|
177
|
+
magnitude: typeof breakdown.magnitude === 'number' ? breakdown.magnitude : 0,
|
|
178
|
+
advantage: typeof breakdown.advantage === 'number' ? breakdown.advantage : 0,
|
|
179
|
+
impact: typeof breakdown.impact === 'number' ? breakdown.impact : 0,
|
|
180
|
+
created_at: created_at,
|
|
181
|
+
// ReverseSalient properties.
|
|
182
|
+
query_concept: pair.query_concept,
|
|
183
|
+
doc_concept: pair.doc_concept,
|
|
184
|
+
// Context UNWIND inputs (always present; may be empty arrays).
|
|
185
|
+
papers: papers,
|
|
186
|
+
experts: experts,
|
|
187
|
+
paper_author_pairs: paper_author_pairs,
|
|
188
|
+
// Optional context metadata.
|
|
189
|
+
room_id: typeof ctx.room_id === 'string' ? ctx.room_id : '',
|
|
190
|
+
domain: typeof ctx.domain === 'string' ? ctx.domain : '',
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// ---------- buildMergeCypher ----------
|
|
195
|
+
//
|
|
196
|
+
// Returns one of two pre-built Cypher strings: core-only when no context,
|
|
197
|
+
// core+context when papers/experts present. Both use MERGE for
|
|
198
|
+
// idempotency. The core+context version includes the AUTHORED_BY UNWIND
|
|
199
|
+
// over $paper_author_pairs.
|
|
200
|
+
//
|
|
201
|
+
// Cypher style: MERGE primary keys explicitly per node so re-runs match
|
|
202
|
+
// existing nodes by PRIMARY KEY (discovery_id, rs_id, innovation_id are
|
|
203
|
+
// deterministic; paper.id is from external source; author name_orcid_key
|
|
204
|
+
// composite handles the missing-orcid case via __no_orcid__ sentinel;
|
|
205
|
+
// institution.name is the natural key).
|
|
206
|
+
|
|
207
|
+
const CORE_CYPHER = [
|
|
208
|
+
'MERGE (d:RSDiscovery {id: $discovery_id})',
|
|
209
|
+
' SET d.classification = $classification,',
|
|
210
|
+
' d.breakthrough_score = $breakthrough_score,',
|
|
211
|
+
' d.dominant_dimension = $dominant_dimension,',
|
|
212
|
+
' d.thesis = $thesis,',
|
|
213
|
+
' d.bridge_concept = $bridge_concept,',
|
|
214
|
+
' d.diff = $diff,',
|
|
215
|
+
' d.lsa = $lsa,',
|
|
216
|
+
' d.bert = $bert,',
|
|
217
|
+
' d.feasibility = $feasibility,',
|
|
218
|
+
' d.market = $market,',
|
|
219
|
+
' d.magnitude = $magnitude,',
|
|
220
|
+
' d.advantage = $advantage,',
|
|
221
|
+
' d.impact = $impact,',
|
|
222
|
+
' d.created_at = $created_at',
|
|
223
|
+
'MERGE (rs:ReverseSalient {id: $rs_id})',
|
|
224
|
+
' SET rs.query_concept = $query_concept,',
|
|
225
|
+
' rs.doc_concept = $doc_concept,',
|
|
226
|
+
' rs.classification = $classification',
|
|
227
|
+
'MERGE (i:Innovation {id: $innovation_id})',
|
|
228
|
+
' SET i.thesis = $thesis,',
|
|
229
|
+
' i.breakthrough_score = $breakthrough_score',
|
|
230
|
+
'MERGE (d)-[:DISCOVERED]->(rs)',
|
|
231
|
+
'MERGE (rs)-[:DERIVED_FROM]->(i)',
|
|
232
|
+
'MERGE (d)-[:ENABLES]->(i)',
|
|
233
|
+
].join('\n');
|
|
234
|
+
|
|
235
|
+
const CONTEXT_CYPHER = [
|
|
236
|
+
CORE_CYPHER,
|
|
237
|
+
'',
|
|
238
|
+
'// Paper nodes (UNWIND $papers)',
|
|
239
|
+
'WITH d',
|
|
240
|
+
'UNWIND $papers AS p',
|
|
241
|
+
' MERGE (paper:Paper {id: p.id})',
|
|
242
|
+
' SET paper.title = p.title,',
|
|
243
|
+
' paper.doi = p.doi,',
|
|
244
|
+
' paper.source = p.source',
|
|
245
|
+
' MERGE (d)-[:DERIVED_FROM]->(paper)',
|
|
246
|
+
'',
|
|
247
|
+
'// Author + Institution nodes (UNWIND $experts)',
|
|
248
|
+
'WITH d',
|
|
249
|
+
'UNWIND $experts AS e',
|
|
250
|
+
' MERGE (a:Author {name_orcid_key: e.name + \'|\' + coalesce(e.orcid, \'__no_orcid__\')})',
|
|
251
|
+
' SET a.name = e.name,',
|
|
252
|
+
' a.orcid = e.orcid,',
|
|
253
|
+
' a.h_index_estimate = e.h_index_estimate',
|
|
254
|
+
' WITH a, e',
|
|
255
|
+
' WHERE e.institution IS NOT NULL',
|
|
256
|
+
' MERGE (inst:Institution {name: e.institution})',
|
|
257
|
+
' MERGE (a)-[:AFFILIATED_WITH]->(inst)',
|
|
258
|
+
'',
|
|
259
|
+
'// AUTHORED_BY edges (UNWIND $paper_author_pairs)',
|
|
260
|
+
'WITH 1 AS _step',
|
|
261
|
+
'UNWIND $paper_author_pairs AS pa',
|
|
262
|
+
' MATCH (paper:Paper {id: pa.paper_id})',
|
|
263
|
+
' MATCH (author:Author {name_orcid_key: pa.author_key})',
|
|
264
|
+
' MERGE (paper)-[:AUTHORED_BY]->(author)',
|
|
265
|
+
].join('\n');
|
|
266
|
+
|
|
267
|
+
function buildMergeCypher(hasContext) {
|
|
268
|
+
return hasContext ? CONTEXT_CYPHER : CORE_CYPHER;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// ---------- buildRollbackCypher ----------
|
|
272
|
+
//
|
|
273
|
+
// Inverse DELETE for the 3 core nodes only. Shared Paper/Author/Institution
|
|
274
|
+
// nodes are NOT torn down by rollback because they may be referenced by
|
|
275
|
+
// other RSDiscoveries; only the RS-specific nodes are removed. DETACH
|
|
276
|
+
// ensures all incident edges are removed atomically with each node.
|
|
277
|
+
//
|
|
278
|
+
// Returned as a multi-statement string (caller can split on ';' or pass
|
|
279
|
+
// to driver.session().run as separate statements). Format mirrors the
|
|
280
|
+
// schema exactly so callers can journal verbatim for manual rollback.
|
|
281
|
+
|
|
282
|
+
function buildRollbackCypher(ids) {
|
|
283
|
+
return [
|
|
284
|
+
'DETACH DELETE (d:RSDiscovery {id: "' + ids.discovery_id + '"});',
|
|
285
|
+
'DETACH DELETE (rs:ReverseSalient {id: "' + ids.rs_id + '"});',
|
|
286
|
+
'DETACH DELETE (i:Innovation {id: "' + ids.innovation_id + '"});',
|
|
287
|
+
].join('\n');
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// ---------- writeDiscovery ----------
|
|
291
|
+
//
|
|
292
|
+
// The public entry point. Orchestration:
|
|
293
|
+
// 1. Validate pair shape (throws TypeError on missing required field)
|
|
294
|
+
// 2. Validate opts.driver presence (throws TypeError if absent)
|
|
295
|
+
// 3. Build deterministic ids (sha256-derived)
|
|
296
|
+
// 4. Build Cypher params (includes paper_author_pairs always)
|
|
297
|
+
// 5. Run auditQueryObject pre-write (Canon Part 8 defense-in-depth;
|
|
298
|
+
// throws ExternalEgressViolation on FORBIDDEN_PATTERNS hit; covers
|
|
299
|
+
// UNWIND inputs via JSON.stringify walk)
|
|
300
|
+
// 6. Build Cypher (core OR core+context)
|
|
301
|
+
// 7. session.run(cypher, params); catch ConnectionError; throw
|
|
302
|
+
// AuraUnreachableError on backend failure (clean tier-dispatch signal)
|
|
303
|
+
// 8. Return {wrote_node_count, wrote_edge_count, rollback_cypher,
|
|
304
|
+
// aura_op_id, schema_version}
|
|
305
|
+
|
|
306
|
+
async function writeDiscovery(pair, opts) {
|
|
307
|
+
opts = opts || {};
|
|
308
|
+
validateRequiredFields(pair);
|
|
309
|
+
|
|
310
|
+
if (!opts.driver || typeof opts.driver.session !== 'function') {
|
|
311
|
+
throw new TypeError(SURFACE + ': opts.driver required (call rs-output-dispatch from Plan 89.3-05 if you need tier auto-resolution)');
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
const ids = buildDeterministicIds(pair);
|
|
315
|
+
const ctx = (opts.context && typeof opts.context === 'object') ? opts.context : {};
|
|
316
|
+
const params = buildCypherParams(pair, ctx, ids);
|
|
317
|
+
|
|
318
|
+
// Canon Part 8 defense-in-depth: audit BEFORE Cypher execution. Covers
|
|
319
|
+
// UNWIND inputs ($experts, $papers, $paper_author_pairs) via the
|
|
320
|
+
// JSON.stringify walk in auditQueryObject.
|
|
321
|
+
auditQueryObject(params, SURFACE);
|
|
322
|
+
|
|
323
|
+
const hasContext = (Array.isArray(ctx.papers) && ctx.papers.length > 0) ||
|
|
324
|
+
(Array.isArray(ctx.experts) && ctx.experts.length > 0);
|
|
325
|
+
const cypher = buildMergeCypher(hasContext);
|
|
326
|
+
|
|
327
|
+
const session = opts.driver.session();
|
|
328
|
+
let result;
|
|
329
|
+
try {
|
|
330
|
+
result = await session.run(cypher, params);
|
|
331
|
+
} catch (err) {
|
|
332
|
+
if (err instanceof ExternalEgressViolation) {
|
|
333
|
+
// Bubble up unchanged.
|
|
334
|
+
throw err;
|
|
335
|
+
}
|
|
336
|
+
throw new AuraUnreachableError(
|
|
337
|
+
'Aura backend unreachable: ' + (err && err.message ? err.message : String(err)),
|
|
338
|
+
{ original: err && err.message ? err.message : String(err) }
|
|
339
|
+
);
|
|
340
|
+
} finally {
|
|
341
|
+
if (session && typeof session.close === 'function') {
|
|
342
|
+
try {
|
|
343
|
+
await session.close();
|
|
344
|
+
} catch (_e) { /* best effort */ }
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
const counters = (result && result.summary && result.summary.counters) || {};
|
|
349
|
+
return {
|
|
350
|
+
wrote_node_count: typeof counters.nodesCreated === 'number' ? counters.nodesCreated : 0,
|
|
351
|
+
wrote_edge_count: typeof counters.relationshipsCreated === 'number' ? counters.relationshipsCreated : 0,
|
|
352
|
+
rollback_cypher: buildRollbackCypher(ids),
|
|
353
|
+
aura_op_id: generateOpId(),
|
|
354
|
+
schema_version: SCHEMA_VERSION,
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// ---------- Edge type registry consumption ----------
|
|
359
|
+
//
|
|
360
|
+
// Defensive guard: refuse to load if the EDGE_TYPES extension Plan 89.3-01
|
|
361
|
+
// Task 1 shipped is missing. This guarantees the writer cannot ship
|
|
362
|
+
// against a stale lazygraph-ops.cjs. Non-throwing in production (warn on
|
|
363
|
+
// stderr) so the writer remains usable while the upstream is fixed; in
|
|
364
|
+
// tests this can be tightened to throw if desired.
|
|
365
|
+
|
|
366
|
+
const REQUIRED_EDGE_TYPES = ['DISCOVERED', 'DERIVED_FROM', 'ENABLES', 'AUTHORED_BY', 'AFFILIATED_WITH'];
|
|
367
|
+
for (const t of REQUIRED_EDGE_TYPES) {
|
|
368
|
+
if (!EDGE_TYPES.includes(t)) {
|
|
369
|
+
process.stderr.write(SURFACE + ': WARNING -- EDGE_TYPES missing required type: ' + t + '\n');
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// ---------- Exports ----------
|
|
374
|
+
|
|
375
|
+
module.exports = {
|
|
376
|
+
writeDiscovery,
|
|
377
|
+
AuraUnreachableError,
|
|
378
|
+
SCHEMA_VERSION,
|
|
379
|
+
REQUIRED_FIELDS,
|
|
380
|
+
_test: {
|
|
381
|
+
buildDeterministicIds,
|
|
382
|
+
generateOpId,
|
|
383
|
+
buildCypherParams,
|
|
384
|
+
buildMergeCypher,
|
|
385
|
+
buildRollbackCypher,
|
|
386
|
+
validateRequiredFields,
|
|
387
|
+
},
|
|
388
|
+
};
|