@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,287 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
rs-math.py -- Shared math helpers for the Reverse Salient Engine (Phase 89)
|
|
4
|
+
==============================================================================
|
|
5
|
+
|
|
6
|
+
Ports the authoritative Hughes 1983 / Kwan 2023 reverse-salient algorithm into
|
|
7
|
+
reusable pure functions. Consumed by:
|
|
8
|
+
- scripts/rs-engine.py (Plan 89-01, Mode A single-room)
|
|
9
|
+
- scripts/rs-engine.py Mode B/C (Plans 89-04, 89-05)
|
|
10
|
+
|
|
11
|
+
Authoritative source: .planning/phases/89-reverse-salient-engine/source/lsa.py
|
|
12
|
+
(Newton Kwan et al., 2023). The distinguishing property of this algorithm is
|
|
13
|
+
TOPIC-KEYWORD-MEMBERSHIP COUNTING + signed abs-diff detection -- NOT
|
|
14
|
+
cosine-on-SVD, NOT MiniLM cosine. Do not replace these with more modern
|
|
15
|
+
defaults; ALGORITHM-SOURCE.md documents why the keyword-membership signal is
|
|
16
|
+
load-bearing.
|
|
17
|
+
|
|
18
|
+
License: BSL-1.1 (see LICENSE at repo root).
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
from typing import Iterable, List, Sequence, Tuple
|
|
24
|
+
|
|
25
|
+
import numpy as np
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# ---------------------------------------------------------------------------
|
|
29
|
+
# Step 1: TF-IDF + Truncated SVD
|
|
30
|
+
# ---------------------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
def build_tfidf_svd(
|
|
33
|
+
texts: Sequence[str],
|
|
34
|
+
n_components: int = 80,
|
|
35
|
+
max_features: int = 2000,
|
|
36
|
+
max_df: float = 0.5,
|
|
37
|
+
random_state: int = 256,
|
|
38
|
+
) -> Tuple[object, object, object]:
|
|
39
|
+
"""Fit TF-IDF + TruncatedSVD on a corpus.
|
|
40
|
+
|
|
41
|
+
Ports source/lsa.py lines 39-55 faithfully. Parameter choices
|
|
42
|
+
(2000 features, max_df=0.5, 80 components, n_iter=10, seed=256) are taken
|
|
43
|
+
verbatim from the authoritative source. For corpora smaller than 80 docs,
|
|
44
|
+
n_components is clamped to max(1, N-1) to avoid SVD underflow.
|
|
45
|
+
|
|
46
|
+
Returns (vectorizer, svd_model, X) where X is the sparse TF-IDF matrix.
|
|
47
|
+
"""
|
|
48
|
+
# Imported lazily so rs-math.py can be imported without sklearn for tests
|
|
49
|
+
# that exercise only abs_diff_topk / classify_direction.
|
|
50
|
+
from sklearn.decomposition import TruncatedSVD
|
|
51
|
+
from sklearn.feature_extraction.text import TfidfVectorizer
|
|
52
|
+
|
|
53
|
+
vectorizer = TfidfVectorizer(
|
|
54
|
+
stop_words="english",
|
|
55
|
+
max_features=max_features,
|
|
56
|
+
max_df=max_df,
|
|
57
|
+
smooth_idf=True,
|
|
58
|
+
)
|
|
59
|
+
X = vectorizer.fit_transform(texts)
|
|
60
|
+
|
|
61
|
+
n_rows, n_terms = X.shape
|
|
62
|
+
effective_components = max(1, min(n_components, n_rows - 1, n_terms - 1))
|
|
63
|
+
svd_model = TruncatedSVD(
|
|
64
|
+
n_components=effective_components,
|
|
65
|
+
algorithm="randomized",
|
|
66
|
+
n_iter=10,
|
|
67
|
+
random_state=random_state,
|
|
68
|
+
)
|
|
69
|
+
svd_model.fit(X)
|
|
70
|
+
|
|
71
|
+
return vectorizer, svd_model, X
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
# ---------------------------------------------------------------------------
|
|
75
|
+
# Step 2: Extract top-k keywords per SVD component
|
|
76
|
+
# ---------------------------------------------------------------------------
|
|
77
|
+
|
|
78
|
+
def extract_topic_keywords(svd_model, terms: Sequence[str], top_k: int = 7) -> List[List[str]]:
|
|
79
|
+
"""For each SVD component, return the top_k terms by weight descending.
|
|
80
|
+
|
|
81
|
+
Ports source/lsa.py lines 59-72 faithfully. `terms` is typically the
|
|
82
|
+
output of `vectorizer.get_feature_names_out()`.
|
|
83
|
+
"""
|
|
84
|
+
topics: List[List[str]] = []
|
|
85
|
+
for comp in svd_model.components_:
|
|
86
|
+
sorted_terms = sorted(
|
|
87
|
+
zip(terms, comp), key=lambda pair: pair[1], reverse=True
|
|
88
|
+
)[:top_k]
|
|
89
|
+
topics.append([t for t, _ in sorted_terms])
|
|
90
|
+
return topics
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
# ---------------------------------------------------------------------------
|
|
94
|
+
# Step 3: Topic-keyword-membership counting (the authoritative signature)
|
|
95
|
+
# ---------------------------------------------------------------------------
|
|
96
|
+
|
|
97
|
+
def count_topic_membership(
|
|
98
|
+
tokenized_papers: Sequence[Sequence[str]],
|
|
99
|
+
topics: Sequence[Sequence[str]],
|
|
100
|
+
) -> np.ndarray:
|
|
101
|
+
"""Count how many of each paper's tokens appear in each topic's keyword set.
|
|
102
|
+
|
|
103
|
+
Ports source/lsa.py lines 80-98 faithfully.
|
|
104
|
+
|
|
105
|
+
CRITICAL: this is NOT cosine-on-SVD. It measures whether papers share
|
|
106
|
+
topic-level keywords (top 7 terms per SVD component). ALGORITHM-SOURCE.md
|
|
107
|
+
line 72 warns that swapping this for cosine-on-SVD changes the signal
|
|
108
|
+
entirely. Do not optimize this.
|
|
109
|
+
|
|
110
|
+
Returns a (n_papers, n_topics) float32 matrix.
|
|
111
|
+
"""
|
|
112
|
+
n_papers = len(tokenized_papers)
|
|
113
|
+
n_topics = len(topics)
|
|
114
|
+
|
|
115
|
+
# Precompute topic keyword sets for O(1) membership lookup per token.
|
|
116
|
+
topic_sets = [set(t) for t in topics]
|
|
117
|
+
|
|
118
|
+
counts = np.zeros((n_papers, n_topics), dtype=np.float32)
|
|
119
|
+
for i, tokens in enumerate(tokenized_papers):
|
|
120
|
+
for word in tokens:
|
|
121
|
+
for j, kw_set in enumerate(topic_sets):
|
|
122
|
+
if word in kw_set:
|
|
123
|
+
counts[i, j] += 1.0
|
|
124
|
+
return counts
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
# ---------------------------------------------------------------------------
|
|
128
|
+
# Step 4: Row-normalize + pairwise L1 distance + invert to similarity
|
|
129
|
+
# ---------------------------------------------------------------------------
|
|
130
|
+
|
|
131
|
+
def normalize_and_l1_similarity(topic_count_matrix: np.ndarray) -> np.ndarray:
|
|
132
|
+
"""Row-normalize, compute pairwise L1 distance, invert, and rescale.
|
|
133
|
+
|
|
134
|
+
Ports source/lsa.py lines 102-126 faithfully. Steps:
|
|
135
|
+
1. Row-normalize (each paper becomes a topic distribution summing to 1)
|
|
136
|
+
2. Pairwise L1 distance via broadcast
|
|
137
|
+
3. Invert: sim = max(dist) - dist (closer pairs score higher)
|
|
138
|
+
4. Rescale to [0, 1] centered at 0.5
|
|
139
|
+
|
|
140
|
+
Diagonal entries should be ~1.0 (self-similarity maximum) after rescaling.
|
|
141
|
+
|
|
142
|
+
Returns a (N, N) float32 similarity matrix.
|
|
143
|
+
"""
|
|
144
|
+
matrix = np.asarray(topic_count_matrix, dtype=np.float32)
|
|
145
|
+
n = matrix.shape[0]
|
|
146
|
+
|
|
147
|
+
row_sums = matrix.sum(axis=1)
|
|
148
|
+
# Papers with zero keyword hits would divide by zero; substitute 1.0 so the
|
|
149
|
+
# row stays all-zeros after normalization (most-dissimilar bucket). This
|
|
150
|
+
# matches the np.nan_to_num behavior in source/lsa.py line 106.
|
|
151
|
+
safe_row_sums = np.where(row_sums == 0.0, 1.0, row_sums)
|
|
152
|
+
normalized = (matrix.T / safe_row_sums).T
|
|
153
|
+
|
|
154
|
+
# Pairwise L1 distance: |normalized[i] - normalized[j]| summed across
|
|
155
|
+
# topics, same broadcast trick as the authoritative source.
|
|
156
|
+
diff = np.abs(normalized[:, None, :] - normalized[None, :, :])
|
|
157
|
+
sum_matrix = diff.sum(axis=2).astype(np.float32)
|
|
158
|
+
|
|
159
|
+
# Invert so that smaller distances become larger similarities.
|
|
160
|
+
sum_matrix = sum_matrix.max() - sum_matrix
|
|
161
|
+
|
|
162
|
+
# Rescale to [0, 1] centered at 0.5 (authoritative step).
|
|
163
|
+
rng = sum_matrix.max() - sum_matrix.min()
|
|
164
|
+
if rng == 0:
|
|
165
|
+
# Degenerate corpus (all identical) -- return identity-like matrix so
|
|
166
|
+
# abs_diff_topk still produces deterministic output.
|
|
167
|
+
return np.eye(n, dtype=np.float32)
|
|
168
|
+
midpoint = (sum_matrix.max() + sum_matrix.min()) / 2.0
|
|
169
|
+
return ((sum_matrix - midpoint) / rng) + 0.5
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
# ---------------------------------------------------------------------------
|
|
173
|
+
# Step 5: abs-diff top-k iterative argmax with symmetric cleanup
|
|
174
|
+
# ---------------------------------------------------------------------------
|
|
175
|
+
|
|
176
|
+
def abs_diff_topk(
|
|
177
|
+
lsa_matrix: np.ndarray,
|
|
178
|
+
semantic_matrix: np.ndarray,
|
|
179
|
+
k: int = 1000,
|
|
180
|
+
skip_diagonal: bool = True,
|
|
181
|
+
) -> List[Tuple[int, int, float, float]]:
|
|
182
|
+
"""Return the top-k pairs by |semantic - lsa| differential.
|
|
183
|
+
|
|
184
|
+
Ports source/comparison.py lines 130-147 faithfully. The whole innovation
|
|
185
|
+
detection is this single signal: where do semantic and structural
|
|
186
|
+
similarity disagree most?
|
|
187
|
+
|
|
188
|
+
Each returned tuple is (i, j, signed_diff, abs_diff) where:
|
|
189
|
+
- signed_diff = semantic_matrix[i, j] - lsa_matrix[i, j]
|
|
190
|
+
- abs_diff = |signed_diff|
|
|
191
|
+
- signed_diff > 0 -> structural_transfer (different words, similar meaning)
|
|
192
|
+
- signed_diff < 0 -> semantic_implementation (same words, different meaning)
|
|
193
|
+
|
|
194
|
+
`skip_diagonal=True` zeroes out self-pairs before iteration so
|
|
195
|
+
(i, i) never wins. Symmetric cleanup ensures (j, i) is suppressed when
|
|
196
|
+
(i, j) is selected, preventing duplicate reporting.
|
|
197
|
+
"""
|
|
198
|
+
lsa = np.asarray(lsa_matrix, dtype=np.float64)
|
|
199
|
+
sem = np.asarray(semantic_matrix, dtype=np.float64)
|
|
200
|
+
if lsa.shape != sem.shape:
|
|
201
|
+
raise ValueError(
|
|
202
|
+
f"shape mismatch: lsa {lsa.shape} vs semantic {sem.shape}"
|
|
203
|
+
)
|
|
204
|
+
n = lsa.shape[0]
|
|
205
|
+
if n < 2:
|
|
206
|
+
return []
|
|
207
|
+
|
|
208
|
+
signed_diff = sem - lsa
|
|
209
|
+
abs_diff = np.abs(signed_diff).copy()
|
|
210
|
+
|
|
211
|
+
if skip_diagonal:
|
|
212
|
+
np.fill_diagonal(abs_diff, -np.inf)
|
|
213
|
+
|
|
214
|
+
# Upper triangle only: symmetric matrix means (i,j) == (j,i); the
|
|
215
|
+
# authoritative source handles this by suppressing the mirror after each
|
|
216
|
+
# pick. We precompute mask so argmax never returns lower-triangle.
|
|
217
|
+
iu = np.tril_indices(n, k=-1)
|
|
218
|
+
abs_diff[iu] = -np.inf
|
|
219
|
+
|
|
220
|
+
results: List[Tuple[int, int, float, float]] = []
|
|
221
|
+
k = max(0, min(k, (n * (n - 1)) // 2))
|
|
222
|
+
for _ in range(k):
|
|
223
|
+
flat_index = int(np.argmax(abs_diff))
|
|
224
|
+
i, j = np.unravel_index(flat_index, abs_diff.shape)
|
|
225
|
+
max_val = float(abs_diff[i, j])
|
|
226
|
+
if max_val == -np.inf or max_val <= 0.0:
|
|
227
|
+
break
|
|
228
|
+
results.append((int(i), int(j), float(signed_diff[i, j]), float(max_val)))
|
|
229
|
+
# Symmetric cleanup: source/comparison.py lines 145-146 subtract the
|
|
230
|
+
# max-val so the mirror never wins next iteration. We mask to -inf
|
|
231
|
+
# directly since we already restrict to upper triangle.
|
|
232
|
+
abs_diff[i, j] = -np.inf
|
|
233
|
+
abs_diff[j, i] = -np.inf
|
|
234
|
+
|
|
235
|
+
return results
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
# ---------------------------------------------------------------------------
|
|
239
|
+
# Step 6: Direction classification
|
|
240
|
+
# ---------------------------------------------------------------------------
|
|
241
|
+
|
|
242
|
+
def classify_direction(signed_diff: float) -> str:
|
|
243
|
+
"""Classify an RS pair by the sign of (semantic - lsa).
|
|
244
|
+
|
|
245
|
+
Based on ALGORITHM-SOURCE.md lines 150-153:
|
|
246
|
+
- signed > 0 -> structural_transfer (different keywords, similar meaning)
|
|
247
|
+
- signed <= 0 -> semantic_implementation (same keywords, different meaning)
|
|
248
|
+
|
|
249
|
+
The zero case is rare in practice (post-rescaling); we bucket it with
|
|
250
|
+
semantic_implementation for deterministic output.
|
|
251
|
+
"""
|
|
252
|
+
return "structural_transfer" if float(signed_diff) > 0.0 else "semantic_implementation"
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
# ---------------------------------------------------------------------------
|
|
256
|
+
# Convenience: full LSA pipeline on raw text corpus
|
|
257
|
+
# ---------------------------------------------------------------------------
|
|
258
|
+
|
|
259
|
+
def build_lsa_matrix(texts: Sequence[str], n_components: int = 80, top_k: int = 7) -> np.ndarray:
|
|
260
|
+
"""Run the full authoritative LSA pipeline end-to-end.
|
|
261
|
+
|
|
262
|
+
Equivalent to running build_tfidf_svd + extract_topic_keywords +
|
|
263
|
+
count_topic_membership + normalize_and_l1_similarity in sequence. Provided
|
|
264
|
+
as a single entry point so scripts/rs-engine.py and plans 89-04/89-05 can
|
|
265
|
+
call one function and not re-wire the pipeline.
|
|
266
|
+
|
|
267
|
+
Tokenization mirrors source/lsa.py lines 14-17: simple whitespace split on
|
|
268
|
+
the raw text, so topic-keyword matching compares against the same tokens
|
|
269
|
+
that TF-IDF saw. Do not pre-strip punctuation (see ALGORITHM-SOURCE.md
|
|
270
|
+
Pitfall 1 in RESEARCH.md line 569-573).
|
|
271
|
+
"""
|
|
272
|
+
tokenized = [t.split() for t in texts]
|
|
273
|
+
vec, svd, _X = build_tfidf_svd(texts, n_components=n_components)
|
|
274
|
+
topics = extract_topic_keywords(svd, vec.get_feature_names_out(), top_k=top_k)
|
|
275
|
+
counts = count_topic_membership(tokenized, topics)
|
|
276
|
+
return normalize_and_l1_similarity(counts)
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
__all__ = [
|
|
280
|
+
"build_tfidf_svd",
|
|
281
|
+
"extract_topic_keywords",
|
|
282
|
+
"count_topic_membership",
|
|
283
|
+
"normalize_and_l1_similarity",
|
|
284
|
+
"abs_diff_topk",
|
|
285
|
+
"classify_direction",
|
|
286
|
+
"build_lsa_matrix",
|
|
287
|
+
]
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
rs_rooms.py -- Multi-room artifact loader for the Reverse Salient Engine
|
|
4
|
+
==============================================================================
|
|
5
|
+
|
|
6
|
+
Plan 89-04 Mode A extension: load artifacts from N user rooms simultaneously
|
|
7
|
+
and tag every artifact with its source room_id so the engine can filter
|
|
8
|
+
pairs to cross-room bridges only. Rediscovers the Yissum x CU x Hopkins
|
|
9
|
+
connections the user found manually.
|
|
10
|
+
|
|
11
|
+
Design notes:
|
|
12
|
+
- Room artifacts live on the filesystem (room/section/artifact.md), NOT in
|
|
13
|
+
a SQLite `artifacts` table. The Phase 89 baseline (Plan 89-01, scripts/
|
|
14
|
+
rs-engine.py:discover_artifacts) walks the filesystem because
|
|
15
|
+
lib/core/lazygraph-ops.cjs has no such table. This module follows that
|
|
16
|
+
same pattern per-room and aggregates into one flat corpus.
|
|
17
|
+
- global_id = "{room_id}::{artifact_id}" guarantees uniqueness across
|
|
18
|
+
rooms even when two rooms name their artifacts identically. This is the
|
|
19
|
+
plan's explicit risk-mitigation.
|
|
20
|
+
- Missing/unreadable rooms are skipped with a stderr warning; the engine
|
|
21
|
+
continues with whatever rooms successfully loaded. Mode B/C and Mode A
|
|
22
|
+
single-room require artifacts; cross-room requires >= 2 rooms actually
|
|
23
|
+
contributing artifacts for any cross-room pair to exist.
|
|
24
|
+
|
|
25
|
+
Authoritative source invariants preserved:
|
|
26
|
+
- Empty body filter (>= 50 chars of real content, matching discover_artifacts).
|
|
27
|
+
- Skip dirs (.git, .lazygraph, .mindrian, node_modules, .obsidian).
|
|
28
|
+
- Skip files (STATE.md, ROOM.md, MINTO.md -- metadata, not venture content).
|
|
29
|
+
- Section = first-segment of relative path (same as discover_artifacts).
|
|
30
|
+
|
|
31
|
+
License: BSL-1.1 (see LICENSE at repo root).
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
from __future__ import annotations
|
|
35
|
+
|
|
36
|
+
import os
|
|
37
|
+
import re
|
|
38
|
+
import sys
|
|
39
|
+
from pathlib import Path
|
|
40
|
+
from typing import Dict, List, Sequence
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
# --- Constants (kept in sync with scripts/rs-engine.py discover_artifacts) ---
|
|
44
|
+
|
|
45
|
+
SKIP_FILES = {"STATE.md", "ROOM.md", "MINTO.md"}
|
|
46
|
+
SKIP_DIRS = {".lazygraph", ".git", ".mindrian", "node_modules", ".obsidian"}
|
|
47
|
+
MIN_BODY_CHARS = 50
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# --- Helpers (minimal local copies so rs_rooms does not import from scripts/) -
|
|
51
|
+
|
|
52
|
+
def _extract_title(content: str, filepath: Path) -> str:
|
|
53
|
+
match = re.search(r"^# (.+)$", content, re.MULTILINE)
|
|
54
|
+
if match:
|
|
55
|
+
return match.group(1).strip()
|
|
56
|
+
return filepath.stem.replace("-", " ").title()
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _extract_body(content: str) -> str:
|
|
60
|
+
fm_match = re.match(r"^---\n[\s\S]*?\n---\n?", content)
|
|
61
|
+
if fm_match:
|
|
62
|
+
return content[fm_match.end():]
|
|
63
|
+
return content
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
# --- Public API -------------------------------------------------------------
|
|
67
|
+
|
|
68
|
+
def load_multi_room_corpus(room_paths: Sequence[str]) -> List[Dict]:
|
|
69
|
+
"""Load artifacts from N rooms, tagging each with its source room_id.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
room_paths: list of filesystem paths, each pointing to one room root.
|
|
73
|
+
Room root = the directory that contains section subdirectories
|
|
74
|
+
(e.g. `~/rooms/yissum-deeptech`, not `~/rooms/yissum-deeptech/room`).
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
Flat list of artifact dicts. Each artifact carries:
|
|
78
|
+
- global_id : f"{room_id}::{artifact_id}" (unique across corpus)
|
|
79
|
+
- room_id : basename of the room path (e.g. "yissum-deeptech")
|
|
80
|
+
- artifact_id : per-room id (section/stem), same shape as 89-01
|
|
81
|
+
- section : first path segment under the room root
|
|
82
|
+
- title : H1 header or humanized filename
|
|
83
|
+
- text : body text (post-frontmatter strip)
|
|
84
|
+
- path : absolute filesystem path to the source .md
|
|
85
|
+
- source_room_path: absolute path to the room root (debugging)
|
|
86
|
+
|
|
87
|
+
Behavior:
|
|
88
|
+
- Missing rooms (no directory) print a stderr note and are skipped.
|
|
89
|
+
Not fatal: the engine may still have enough artifacts from other rooms.
|
|
90
|
+
- Rooms with zero usable artifacts (empty sections, files < 50 chars)
|
|
91
|
+
are silently skipped.
|
|
92
|
+
- Artifact order is deterministic: rooms in input order, files sorted
|
|
93
|
+
by filesystem walk. This matters because index-based pair lookups
|
|
94
|
+
in rs-engine.py assume the artifact list is stable across runs.
|
|
95
|
+
"""
|
|
96
|
+
corpus: List[Dict] = []
|
|
97
|
+
seen_room_ids: Dict[str, int] = {}
|
|
98
|
+
|
|
99
|
+
for rp in room_paths:
|
|
100
|
+
room_path = Path(rp).resolve()
|
|
101
|
+
if not room_path.exists():
|
|
102
|
+
print(
|
|
103
|
+
f"[rs-rooms] Skip {rp}: path does not exist",
|
|
104
|
+
file=sys.stderr,
|
|
105
|
+
)
|
|
106
|
+
continue
|
|
107
|
+
if not room_path.is_dir():
|
|
108
|
+
print(
|
|
109
|
+
f"[rs-rooms] Skip {rp}: not a directory",
|
|
110
|
+
file=sys.stderr,
|
|
111
|
+
)
|
|
112
|
+
continue
|
|
113
|
+
|
|
114
|
+
room_id = room_path.name
|
|
115
|
+
# Disambiguate if two different paths share a basename. The second
|
|
116
|
+
# occurrence gets a suffix so global_id uniqueness survives.
|
|
117
|
+
seen_count = seen_room_ids.get(room_id, 0)
|
|
118
|
+
if seen_count > 0:
|
|
119
|
+
room_id = f"{room_id}-{seen_count + 1}"
|
|
120
|
+
seen_room_ids[room_path.name] = seen_count + 1
|
|
121
|
+
|
|
122
|
+
room_contribution = _load_single_room(room_path, room_id)
|
|
123
|
+
if not room_contribution:
|
|
124
|
+
print(
|
|
125
|
+
f"[rs-rooms] Skip {rp}: no usable artifacts (>= {MIN_BODY_CHARS} chars)",
|
|
126
|
+
file=sys.stderr,
|
|
127
|
+
)
|
|
128
|
+
continue
|
|
129
|
+
corpus.extend(room_contribution)
|
|
130
|
+
|
|
131
|
+
return corpus
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def _load_single_room(room_path: Path, room_id: str) -> List[Dict]:
|
|
135
|
+
"""Walk one room and return artifact dicts tagged with room_id."""
|
|
136
|
+
artifacts: List[Dict] = []
|
|
137
|
+
for root, dirs, files in os.walk(room_path):
|
|
138
|
+
dirs[:] = [d for d in dirs if d not in SKIP_DIRS]
|
|
139
|
+
rel_root = Path(root).relative_to(room_path)
|
|
140
|
+
if str(rel_root) == ".":
|
|
141
|
+
# Skip room-root files -- not part of any section.
|
|
142
|
+
continue
|
|
143
|
+
section = str(rel_root).split(os.sep)[0]
|
|
144
|
+
for fname in sorted(files):
|
|
145
|
+
if not fname.endswith(".md"):
|
|
146
|
+
continue
|
|
147
|
+
if fname in SKIP_FILES:
|
|
148
|
+
continue
|
|
149
|
+
fpath = Path(root) / fname
|
|
150
|
+
try:
|
|
151
|
+
content = fpath.read_text(encoding="utf-8")
|
|
152
|
+
except (OSError, UnicodeDecodeError):
|
|
153
|
+
continue
|
|
154
|
+
body = _extract_body(content).strip()
|
|
155
|
+
if len(body) < MIN_BODY_CHARS:
|
|
156
|
+
continue
|
|
157
|
+
artifact_id = str(rel_root / Path(fname).stem).replace(os.sep, "/")
|
|
158
|
+
global_id = f"{room_id}::{artifact_id}"
|
|
159
|
+
artifacts.append({
|
|
160
|
+
"global_id": global_id,
|
|
161
|
+
"room_id": room_id,
|
|
162
|
+
"artifact_id": artifact_id,
|
|
163
|
+
"section": section,
|
|
164
|
+
"title": _extract_title(content, fpath),
|
|
165
|
+
"text": body,
|
|
166
|
+
"path": str(fpath),
|
|
167
|
+
"source_room_path": str(room_path),
|
|
168
|
+
})
|
|
169
|
+
return artifacts
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def summarize_corpus(corpus: Sequence[Dict]) -> Dict[str, int]:
|
|
173
|
+
"""Return {room_id: artifact_count} for a loaded corpus.
|
|
174
|
+
|
|
175
|
+
Used by the engine to warn when a single room dominates the corpus
|
|
176
|
+
(>= 95% share would skew LSA toward that room's vocabulary and make
|
|
177
|
+
cross-room pair discovery unreliable). The 5% warning threshold is
|
|
178
|
+
documented in the plan's Risks section.
|
|
179
|
+
"""
|
|
180
|
+
counts: Dict[str, int] = {}
|
|
181
|
+
for art in corpus:
|
|
182
|
+
rid = art.get("room_id") or "unknown"
|
|
183
|
+
counts[rid] = counts.get(rid, 0) + 1
|
|
184
|
+
return counts
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
__all__ = [
|
|
188
|
+
"load_multi_room_corpus",
|
|
189
|
+
"summarize_corpus",
|
|
190
|
+
"MIN_BODY_CHARS",
|
|
191
|
+
"SKIP_FILES",
|
|
192
|
+
"SKIP_DIRS",
|
|
193
|
+
]
|