@mindrian_os/cli 2.0.0-beta.29 → 2.0.0-beta.31
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 +14 -0
- package/CHANGELOG.md +41 -0
- package/agents/analogy-query-fetcher.md +119 -0
- package/agents/brain-query.md +91 -0
- package/agents/competitor-watch-fetcher.md +94 -0
- package/agents/framework-runner.md +258 -0
- package/agents/grading.md +216 -0
- package/agents/grant-reviewer.md +191 -0
- package/agents/investor.md +141 -0
- package/agents/larry-extended.md +215 -0
- package/agents/meeting-perspective-extractor.md +94 -0
- package/agents/opportunity-scanner.md +105 -0
- package/agents/persona-analyst.md +201 -0
- package/agents/research.md +103 -0
- package/agents/reverse-salient-agent.md +42 -0
- package/agents/vault-section-reviewer.md +107 -0
- package/assets/banner-showcase.html +537 -0
- package/assets/fonts/BebasNeue-Regular.ttf +0 -0
- package/assets/fonts/Inter-Bold.ttf +0 -0
- package/assets/fonts/Inter-Regular.ttf +0 -0
- package/assets/logo.svg +10 -0
- package/bin/local-chain-recommender.cjs +256 -0
- package/bin/mindrian-brain-mcp-client.cjs +319 -0
- package/bin/mindrian-mcp-server.cjs +445 -0
- package/bin/mindrian-mcp-shim.cjs +100 -0
- package/bin/mindrian-tools.cjs +784 -0
- package/commands/act.md +529 -0
- package/commands/admin.md +439 -0
- package/commands/agentshield.md +49 -0
- package/commands/analyze-needs.md +78 -0
- package/commands/analyze-systems.md +73 -0
- package/commands/analyze-timing.md +98 -0
- package/commands/auto-explore.md +85 -0
- package/commands/beautiful-question.md +76 -0
- package/commands/bono.md +152 -0
- package/commands/brain-derive.md +137 -0
- package/commands/build-knowledge.md +121 -0
- package/commands/build-thesis.md +94 -0
- package/commands/causal.md +269 -0
- package/commands/challenge-assumptions.md +78 -0
- package/commands/compare-ventures.md +117 -0
- package/commands/correct-reference-now.md +88 -0
- package/commands/dashboard.md +144 -0
- package/commands/deck.md +117 -0
- package/commands/deep-grade.md +214 -0
- package/commands/diagnose.md +131 -0
- package/commands/diagnostics.md +195 -0
- package/commands/dial-memory-refresh.md +113 -0
- package/commands/diffusion.md +129 -0
- package/commands/discover.md +221 -0
- package/commands/doctor.md +271 -0
- package/commands/dogfood-flush.md +130 -0
- package/commands/dominant-designs.md +76 -0
- package/commands/eureka.md +315 -0
- package/commands/explain-decision.md +135 -0
- package/commands/explore-domains.md +78 -0
- package/commands/explore-futures.md +67 -0
- package/commands/explore-opportunity.md +172 -0
- package/commands/explore-trends.md +78 -0
- package/commands/export.md +128 -0
- package/commands/feynman-timeline-refresh.md +102 -0
- package/commands/file-meeting.md +1195 -0
- package/commands/find-analogies.md +369 -0
- package/commands/find-bottlenecks.md +108 -0
- package/commands/find-connections.md +111 -0
- package/commands/funding.md +114 -0
- package/commands/futures.md +128 -0
- package/commands/grade-grant.md +297 -0
- package/commands/grade.md +257 -0
- package/commands/graph.md +218 -0
- package/commands/hat-briefing.md +163 -0
- package/commands/heal.md +72 -0
- package/commands/help.md +176 -0
- package/commands/hmi-status.md +75 -0
- package/commands/ignite.md +229 -0
- package/commands/ingest-methodology.md +128 -0
- package/commands/intel-pipeline.md +133 -0
- package/commands/jtbd.md +262 -0
- package/commands/leadership.md +113 -0
- package/commands/lean-canvas.md +74 -0
- package/commands/macro-trends.md +88 -0
- package/commands/map-unknowns.md +76 -0
- package/commands/memory-cortex-reach.md +79 -0
- package/commands/memory.md +213 -0
- package/commands/models.md +200 -0
- package/commands/mos-reason.md +489 -0
- package/commands/mos.md +162 -0
- package/commands/mullins.md +155 -0
- package/commands/mva-brief.md +86 -0
- package/commands/mva-option.md +119 -0
- package/commands/mva-report.md +76 -0
- package/commands/new-project.md +633 -0
- package/commands/new-surface.md +116 -0
- package/commands/onboard.md +489 -0
- package/commands/operator.md +168 -0
- package/commands/opportunities.md +177 -0
- package/commands/organize.md +74 -0
- package/commands/persona.md +276 -0
- package/commands/pipeline.md +167 -0
- package/commands/present.md +125 -0
- package/commands/publish.md +227 -0
- package/commands/pws-brain.md +154 -0
- package/commands/qualify-opportunity.md +113 -0
- package/commands/query.md +70 -0
- package/commands/radar.md +110 -0
- package/commands/reanalyze.md +124 -0
- package/commands/research.md +467 -0
- package/commands/room.md +385 -0
- package/commands/rooms.md +682 -0
- package/commands/root-cause.md +77 -0
- package/commands/rs-experts.md +153 -0
- package/commands/rs-explain.md +134 -0
- package/commands/rs-fetch.md +119 -0
- package/commands/rs-thesis.md +131 -0
- package/commands/scenario-plan.md +80 -0
- package/commands/scheduled-tasks.md +308 -0
- package/commands/score-innovation.md +78 -0
- package/commands/scout.md +379 -0
- package/commands/setup.md +658 -0
- package/commands/show.md +71 -0
- package/commands/skill.md +108 -0
- package/commands/snapshot.md +179 -0
- package/commands/speakers.md +118 -0
- package/commands/splash.md +55 -0
- package/commands/stance.md +91 -0
- package/commands/status.md +109 -0
- package/commands/structure-argument.md +82 -0
- package/commands/suggest-next.md +141 -0
- package/commands/systems-thinking.md +224 -0
- package/commands/think-hats.md +86 -0
- package/commands/trending-to-absurd.md +151 -0
- package/commands/update.md +256 -0
- package/commands/user-needs.md +77 -0
- package/commands/validate.md +77 -0
- package/commands/value-proposition.md +116 -0
- package/commands/vault.md +330 -0
- package/commands/visualize.md +71 -0
- package/commands/whitespace.md +541 -0
- package/commands/wiki.md +96 -0
- package/data/ROOM.md +47 -0
- package/data/brain-census.generated.json +2617 -0
- package/data/brain-orchestration-projection.json +4973 -0
- package/data/brain-packet-schema.json +545 -0
- package/data/brain-surface-contract.json +32 -0
- package/data/capability-ledger.json +391 -0
- package/data/capability-map-registry.json +23 -0
- package/data/command-registry.json +2433 -0
- package/data/connector-coverage-ledger.json +1618 -0
- package/data/connector-out-of-spine-allowlist.json +71 -0
- package/data/connector-registry.json +3637 -0
- package/data/corpus-stats-source.json +11 -0
- package/data/corpus-stats.generated.json +10 -0
- package/data/cross-domain-analogues.json +15 -0
- package/data/deck-aliases.json +6 -0
- package/data/deck-styles.json +85 -0
- package/data/deployment-surfaces.json +69 -0
- package/data/dispatch-framework-map.json +18 -0
- package/data/doctor-modules.json +206 -0
- package/data/dual-graph-health-baseline.json +12 -0
- package/data/eureka-critic-tags.json +32 -0
- package/data/first-reward-surfaces.json +66 -0
- package/data/first-touch-surfaces.json +60 -0
- package/data/flagship-floor-set.json +37 -0
- package/data/framework-names.json +121 -0
- package/data/grant-rubric-fixtures/early-stage-pre-seed.json +18 -0
- package/data/grant-rubric-fixtures/early-stage-round-a.json +18 -0
- package/data/grant-rubric-fixtures/early-stage-seed.json +18 -0
- package/data/grant-rubric-fixtures/hybrid-seed-incentive.json +18 -0
- package/data/grant-rubric-fixtures/rd-fund.json +18 -0
- package/data/grant-rubric-fixtures/regional-innovation-incubators.json +18 -0
- package/data/grant-rubric-fixtures/technology-incubators.json +18 -0
- package/data/grant-rubric-fixtures/tnufa.json +167 -0
- package/data/grant-rubric-schema.json +33 -0
- package/data/harness-fixtures/converged-room/.context/ROOM.md +13 -0
- package/data/harness-fixtures/converged-room/.intelligence/ROOM.md +13 -0
- package/data/harness-fixtures/converged-room/.snapshots/ROOM.md +13 -0
- package/data/harness-fixtures/converged-room/MINTO.md +19 -0
- package/data/harness-fixtures/converged-room/STATE.md +73 -0
- package/data/harness-fixtures/converged-room/USER.md +23 -0
- package/data/harness-fixtures/converged-room/assets/ROOM.md +13 -0
- package/data/harness-fixtures/converged-room/business-model/CONTEXT.md +32 -0
- package/data/harness-fixtures/converged-room/business-model/ROOM.md +36 -0
- package/data/harness-fixtures/converged-room/competitive-analysis/CONTEXT.md +33 -0
- package/data/harness-fixtures/converged-room/competitive-analysis/ROOM.md +35 -0
- package/data/harness-fixtures/converged-room/financial-model/CONTEXT.md +30 -0
- package/data/harness-fixtures/converged-room/financial-model/ROOM.md +35 -0
- package/data/harness-fixtures/converged-room/funding/CONTEXT.md +41 -0
- package/data/harness-fixtures/converged-room/funding/ROOM.md +35 -0
- package/data/harness-fixtures/converged-room/legal-ip/CONTEXT.md +30 -0
- package/data/harness-fixtures/converged-room/legal-ip/ROOM.md +35 -0
- package/data/harness-fixtures/converged-room/market-analysis/CONTEXT.md +32 -0
- package/data/harness-fixtures/converged-room/market-analysis/ROOM.md +35 -0
- package/data/harness-fixtures/converged-room/opportunity-bank/CONTEXT.md +39 -0
- package/data/harness-fixtures/converged-room/opportunity-bank/ROOM.md +36 -0
- package/data/harness-fixtures/converged-room/problem-definition/CONTEXT.md +32 -0
- package/data/harness-fixtures/converged-room/problem-definition/ROOM.md +36 -0
- package/data/harness-fixtures/converged-room/references/ROOM.md +13 -0
- package/data/harness-fixtures/converged-room/references/SECTION-SCHEMA.md +213 -0
- package/data/harness-fixtures/converged-room/references/SUB-SCHEMAS.md +91 -0
- package/data/harness-fixtures/converged-room/solution-design/CONTEXT.md +36 -0
- package/data/harness-fixtures/converged-room/solution-design/ROOM.md +36 -0
- package/data/harness-fixtures/converged-room/strategy/CONTEXT.md +35 -0
- package/data/harness-fixtures/converged-room/strategy/ROOM.md +35 -0
- package/data/harness-fixtures/converged-room/team/ROOM.md +13 -0
- package/data/harness-fixtures/converged-room/team-execution/CONTEXT.md +36 -0
- package/data/harness-fixtures/converged-room/team-execution/ROOM.md +35 -0
- package/data/harness-manifest.json +74 -0
- package/data/harness-policies/CONTEXT.md +55 -0
- package/data/harness-policies/_schema.json +42 -0
- package/data/harness-policies/contract-parity-larry.json +63 -0
- package/data/harness-policies/gate-card-fire.json +13 -0
- package/data/harness-policies/gate-graph-derive-health.json +13 -0
- package/data/harness-policies/gate-shape-declaration.json +13 -0
- package/data/harness-policies/gate-tool-honesty.json +13 -0
- package/data/harness-policies/gate-worktree-hygiene.json +13 -0
- package/data/harness-policies/memory-write-policy.json +28 -0
- package/data/harness-policies/registry-drift.json +13 -0
- package/data/harness-policies/release-payload-ceiling.json +13 -0
- package/data/harness-policies/voice-backend-noun-free.json +13 -0
- package/data/harness-policies/voice-fork-as-card.json +13 -0
- package/data/harness-policies/voice-glyph-present.json +13 -0
- package/data/harness-policies/voice-hyphens-only.json +13 -0
- package/data/help-groups.json +236 -0
- package/data/hitl-shape-backfill.json +777 -0
- package/data/hitl-shape-declaration-fixtures/invalid-bad-shape.json +5 -0
- package/data/hitl-shape-declaration-fixtures/invalid-missing-why.json +4 -0
- package/data/hitl-shape-declaration-fixtures/invalid-ranker-contradiction.json +6 -0
- package/data/hitl-shape-declaration-fixtures/invalid-skill-gap.json +3 -0
- package/data/hitl-shape-declaration-fixtures/valid-multi-stage.json +7 -0
- package/data/hitl-shape-declaration-fixtures/valid-single-shape.json +5 -0
- package/data/hitl-shape-declaration-fixtures/valid-skill-exempt.json +5 -0
- package/data/hitl-shape-declaration-schema.json +34 -0
- package/data/hitl-stages-fixtures/bono.json +10 -0
- package/data/hitl-stages-fixtures/pipeline-1.json +9 -0
- package/data/hitl-stages-fixtures/pipeline-2.json +9 -0
- package/data/hitl-stages-fixtures/pipeline-3.json +10 -0
- package/data/hitl-stages-fixtures/research.json +10 -0
- package/data/hitl-stages-fixtures/rs-convergence.json +10 -0
- package/data/hitl-stages-fixtures/rs-family.json +11 -0
- package/data/hitl-stages-fixtures/rs-reverse-salient.json +10 -0
- package/data/hitl-stages-fixtures/trending-to-absurd.json +11 -0
- package/data/hitl-stages-schema.json +26 -0
- package/data/mcp-tool-connectors.json +464 -0
- package/data/mva-agent-prompts.json +31 -0
- package/data/mva-deck-template.html +15 -0
- package/data/mva-heuristic-keywords.json +35 -0
- package/data/orchestration-command-ledger.json +576 -0
- package/data/orchestration-unwired-allowlist.json +6 -0
- package/data/portfolio-ahp-matrix.json +16 -0
- package/data/publish-needs.json +76 -0
- package/data/render-coverage-registry.json +1152 -0
- package/data/research-sources.json +58 -0
- package/data/roadmap-type-chains.json +28 -0
- package/data/room-blueprints.json +156 -0
- package/data/subagent-dispatch-grants.json +150 -0
- package/hooks/hooks.json +493 -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 +1163 -0
- package/lib/agents/mva/brain-classic-traps.cjs +55 -0
- package/lib/agents/mva/brain-cross-domain.cjs +79 -0
- package/lib/agents/mva/brain-similar-ventures.cjs +93 -0
- package/lib/agents/mva/dashboard-graph-neighborhood.cjs +72 -0
- package/lib/agents/mva/index.cjs +42 -0
- package/lib/agents/mva/six-hats-red-black.cjs +137 -0
- package/lib/agents/mva/tavily-funding-scan.cjs +147 -0
- package/lib/agents/mva/test-all-six-agents.cjs +467 -0
- package/lib/agents/reverse-salient-agent.cjs +757 -0
- package/lib/agents/tension-hook-agent.cjs +586 -0
- package/lib/brain/ROOM.md +44 -0
- package/lib/brain/chain-recommender.cjs +784 -0
- package/lib/brain/curation-batch.cjs +519 -0
- package/lib/brain/framework-chain-slice.cjs +252 -0
- package/lib/brain/hypergraph-event-schema.cjs +184 -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-epistemic-cap.test.cjs +156 -0
- package/lib/conversation/operator.cjs +492 -0
- package/lib/conversation/operator.test.cjs +160 -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_corpus_exclude.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/abstraction-gate.cjs +133 -0
- package/lib/core/act-jtbd-blurb.cjs +231 -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/behavioral/observation-schema.cjs +86 -0
- package/lib/core/bono/cell-fanout.cjs +305 -0
- package/lib/core/bono/debate-composition.cjs +495 -0
- package/lib/core/bono/hat-governance.cjs +367 -0
- package/lib/core/bono/persona-research.cjs +288 -0
- package/lib/core/bono/reviewer-governance.cjs +331 -0
- package/lib/core/brain-client.cjs +2365 -0
- package/lib/core/brain-derivation-prompts.cjs +331 -0
- package/lib/core/brain-derivation-queue.cjs +535 -0
- package/lib/core/brain-derivation.cjs +740 -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 +396 -0
- package/lib/core/breakthrough/canary.cjs +134 -0
- package/lib/core/breakthrough/canary.test.cjs +136 -0
- package/lib/core/breakthrough/detectors.cjs +359 -0
- package/lib/core/breakthrough/detectors.test.cjs +333 -0
- package/lib/core/breakthrough/ethics-fence.cjs +129 -0
- package/lib/core/breakthrough/ethics-fence.test.cjs +178 -0
- package/lib/core/breakthrough/resurfacing.cjs +150 -0
- package/lib/core/breakthrough/resurfacing.test.cjs +233 -0
- package/lib/core/breakthrough/review-queue.cjs +168 -0
- package/lib/core/breakthrough/review-queue.test.cjs +160 -0
- package/lib/core/breakthrough/scanner-d17-d18.test.cjs +229 -0
- package/lib/core/breakthrough/scanner.cjs +435 -0
- package/lib/core/breakthrough/scanner.test.cjs +267 -0
- package/lib/core/breakthrough/schema.cjs +180 -0
- package/lib/core/breakthrough/schema.test.cjs +256 -0
- package/lib/core/breakthrough/scoring.cjs +293 -0
- package/lib/core/breakthrough/scoring.test.cjs +423 -0
- package/lib/core/breakthrough/verb-dispatch.cjs +230 -0
- package/lib/core/breakthrough/verb-dispatch.test.cjs +185 -0
- package/lib/core/breakthrough/voice-scaffold.cjs +249 -0
- package/lib/core/breakthrough/voice-scaffold.test.cjs +251 -0
- package/lib/core/bridge-writer.cjs +477 -0
- package/lib/core/cache-prune.cjs +314 -0
- package/lib/core/card-fire-gate.cjs +107 -0
- package/lib/core/card-fire-sidechannel.cjs +518 -0
- package/lib/core/chain-executor.cjs +939 -0
- package/lib/core/chain-retry.cjs +214 -0
- package/lib/core/chain-step-dispatcher.cjs +397 -0
- package/lib/core/chat-context-builder.cjs +253 -0
- package/lib/core/check-plugin-enabled.cjs +145 -0
- package/lib/core/close-loop-writer.cjs +492 -0
- package/lib/core/command-registration-check.cjs +246 -0
- package/lib/core/correlation-label-index.cjs +230 -0
- package/lib/core/correlation.cjs +112 -0
- package/lib/core/coverage-monitor.cjs +183 -0
- package/lib/core/coverage-rollup.cjs +232 -0
- package/lib/core/cross-room-aggregator.cjs +1127 -0
- package/lib/core/cross-room-store.cjs +292 -0
- package/lib/core/cross-room-triggers.cjs +222 -0
- package/lib/core/daily-briefing.cjs +438 -0
- package/lib/core/decision-axes.cjs +178 -0
- package/lib/core/decision-capture.cjs +618 -0
- package/lib/core/deck-design-rules.cjs +211 -0
- package/lib/core/deep-links.cjs +82 -0
- package/lib/core/directive-envelope.cjs +217 -0
- package/lib/core/directive-envelope.test.cjs +225 -0
- package/lib/core/dispatch-optimizer.cjs +354 -0
- package/lib/core/doc-text-extractor.cjs +133 -0
- package/lib/core/doctor/capability-ledger-module.cjs +170 -0
- package/lib/core/doctor/card-fire-health-module.cjs +159 -0
- package/lib/core/doctor/cascade-rooms-active-module.cjs +127 -0
- package/lib/core/doctor/cascade-rooms-module.cjs +184 -0
- package/lib/core/doctor/class-m-brain-smoke.cjs +479 -0
- package/lib/core/doctor/class-m-brain-smoke.test.cjs +448 -0
- package/lib/core/doctor/class-s-eureka-smoke.cjs +380 -0
- package/lib/core/doctor/deployment-surfaces-module.cjs +408 -0
- package/lib/core/doctor/deprecated-usage-module.cjs +155 -0
- package/lib/core/doctor/eureka-fts-health-module.cjs +236 -0
- package/lib/core/doctor/graph-derive-heal-retrofit-module.cjs +148 -0
- package/lib/core/doctor/graph-derive-health-module.cjs +486 -0
- package/lib/core/doctor/install-incomplete-module.cjs +320 -0
- package/lib/core/doctor/install-state-module.cjs +503 -0
- package/lib/core/doctor/mcp-surface-module.cjs +369 -0
- package/lib/core/doctor/mode-select-checkpoint-module.cjs +113 -0
- package/lib/core/doctor/plugin-enabled-state-module.cjs +86 -0
- package/lib/core/doctor/room-graph-density-module.cjs +181 -0
- package/lib/core/doctor/room-md-module.cjs +198 -0
- package/lib/core/doctor/shared.cjs +555 -0
- package/lib/core/doctor/stale-first-touch-copy-module.cjs +83 -0
- package/lib/core/doctor/statusline-visibility-module.cjs +295 -0
- package/lib/core/doctor/ui-compliance-module.cjs +223 -0
- package/lib/core/doctor/umbilical-module.cjs +486 -0
- package/lib/core/doctor/verify-surface-module.cjs +82 -0
- package/lib/core/doctor/voice-style-log-module.cjs +146 -0
- package/lib/core/domain-insight-sweep.cjs +224 -0
- package/lib/core/drift-baseline.cjs +362 -0
- package/lib/core/drift-runtime-reachability.cjs +283 -0
- package/lib/core/dual-path-detector.cjs +84 -0
- package/lib/core/dual-path-detector.test.cjs +334 -0
- package/lib/core/enrichment-queue.cjs +636 -0
- package/lib/core/eureka/ahp-weights.cjs +232 -0
- package/lib/core/eureka/analogy-fitness.cjs +326 -0
- package/lib/core/eureka/compression-meter.cjs +165 -0
- package/lib/core/eureka/embedding-classifier.cjs +226 -0
- package/lib/core/eureka/embedding-spine.cjs +563 -0
- package/lib/core/eureka/entity-classifier.cjs +232 -0
- package/lib/core/eureka/entity-extractor.cjs +356 -0
- package/lib/core/eureka/eureka-enable.cjs +228 -0
- package/lib/core/eureka/eureka-offer.cjs +225 -0
- package/lib/core/eureka/eureka-reach-runner.cjs +430 -0
- package/lib/core/eureka/explore-chain.cjs +834 -0
- package/lib/core/eureka/explored-artifact.cjs +456 -0
- package/lib/core/eureka/fts-index-lifecycle.cjs +265 -0
- package/lib/core/eureka/grade-grant-examine.cjs +544 -0
- package/lib/core/eureka/grade-grant.cjs +596 -0
- package/lib/core/eureka/hybrid-retrieve.cjs +256 -0
- package/lib/core/eureka/lateral-engine-adapter.cjs +118 -0
- package/lib/core/eureka/lexical-overlap.cjs +98 -0
- package/lib/core/eureka/online-pattern-query.cjs +142 -0
- package/lib/core/eureka/opportunity-harvest.cjs +752 -0
- package/lib/core/eureka/opportunity-statement.cjs +519 -0
- package/lib/core/eureka/portfolio-dimensions.cjs +255 -0
- package/lib/core/eureka/qualify-opportunity.cjs +607 -0
- package/lib/core/eureka/reasoning-mode.cjs +481 -0
- package/lib/core/eureka/report-html.cjs +368 -0
- package/lib/core/eureka/research-filing.cjs +547 -0
- package/lib/core/eureka/room-native-substrate.cjs +343 -0
- package/lib/core/eureka/tail-quadrant.cjs +177 -0
- package/lib/core/eureka/tri-modal-index.cjs +564 -0
- package/lib/core/eureka/vector-store.cjs +414 -0
- package/lib/core/eureka-critic.cjs +733 -0
- package/lib/core/eureka-deps-resolver.cjs +179 -0
- package/lib/core/expert-genesis.cjs +437 -0
- package/lib/core/expert-library.cjs +303 -0
- package/lib/core/exports-log.cjs +79 -0
- package/lib/core/feynman/ROOM.md +25 -0
- package/lib/core/feynman/dial-memory-renderer.cjs +279 -0
- package/lib/core/feynman/dial-memory-runner.cjs +173 -0
- package/lib/core/feynman/feynman-seed-writer.cjs +187 -0
- package/lib/core/feynman/timeline-renderer.cjs +197 -0
- package/lib/core/feynman/timeline-runner.cjs +281 -0
- package/lib/core/feynman-minto-invariants.cjs +609 -0
- package/lib/core/findings-wirer.cjs +360 -0
- package/lib/core/first-touch-version-stamper.cjs +113 -0
- package/lib/core/folder-memory-async.cjs +424 -0
- package/lib/core/folder-memory-shared.cjs +890 -0
- package/lib/core/folder-memory.cjs +546 -0
- package/lib/core/framework-chain-composer.cjs +583 -0
- package/lib/core/frontmatter-schemas.cjs +468 -0
- package/lib/core/fusion-router.cjs +540 -0
- package/lib/core/futures/causal-cue.cjs +91 -0
- package/lib/core/futures/orchestrator.cjs +1391 -0
- package/lib/core/futures/subsystem-render.cjs +164 -0
- package/lib/core/gate-relevance.cjs +278 -0
- package/lib/core/git-ops.cjs +141 -0
- package/lib/core/graph-backfill.cjs +562 -0
- package/lib/core/graph-candidate-producer.cjs +235 -0
- package/lib/core/graph-derivation.cjs +546 -0
- package/lib/core/graph-derive-classifier.cjs +352 -0
- package/lib/core/graph-ops.cjs +274 -0
- package/lib/core/graph-refine-loop.cjs +194 -0
- package/lib/core/graph-self-heal.cjs +289 -0
- package/lib/core/greeting-intent-detector.cjs +201 -0
- package/lib/core/grill-engine.cjs +459 -0
- package/lib/core/hat-persistence.cjs +274 -0
- package/lib/core/hsi-engine.cjs +439 -0
- package/lib/core/hsi-lsa.cjs +246 -0
- package/lib/core/hsi-spectral.cjs +554 -0
- package/lib/core/hsi-to-graph.test.cjs +168 -0
- package/lib/core/icm-forest.cjs +703 -0
- package/lib/core/ignite-branch-gate.cjs +66 -0
- package/lib/core/index.cjs +60 -0
- package/lib/core/insight-sensors.cjs +1000 -0
- package/lib/core/install-state.cjs +242 -0
- package/lib/core/integration-registry.cjs +232 -0
- package/lib/core/intel-pipeline.cjs +545 -0
- package/lib/core/intelligence-cascade.cjs +852 -0
- package/lib/core/issue-tree.cjs +269 -0
- package/lib/core/larry-thinness-acknowledgment.cjs +64 -0
- package/lib/core/larry-thinness-acknowledgment.test.cjs +97 -0
- package/lib/core/lazygraph-ops.cjs +1453 -0
- package/lib/core/lens-engine.cjs +434 -0
- package/lib/core/leverage-scan.cjs +218 -0
- package/lib/core/llm-name-suggester.cjs +194 -0
- package/lib/core/llm-name-suggester.test.cjs +132 -0
- package/lib/core/lru-cache.cjs +139 -0
- package/lib/core/mcp-dep-heal.cjs +475 -0
- package/lib/core/mcp-dep-heal.test.cjs +253 -0
- package/lib/core/mcp-profiles.cjs +185 -0
- package/lib/core/meeting-ops.cjs +54 -0
- package/lib/core/memory/governance-candidate-raiser.cjs +205 -0
- package/lib/core/memory/governance-candidate.cjs +95 -0
- package/lib/core/memory/reconcile-memory-runner.cjs +653 -0
- package/lib/core/memory-ops.cjs +641 -0
- package/lib/core/meter/gate-density-reader.cjs +112 -0
- package/lib/core/meter/transfer-reader.cjs +276 -0
- package/lib/core/meter/two-gauge.cjs +245 -0
- package/lib/core/methodology-ingest.cjs +346 -0
- package/lib/core/metrics/larryreach-loop-health.cjs +142 -0
- package/lib/core/migration-snapshot.cjs +287 -0
- package/lib/core/migration-snapshot.test.cjs +174 -0
- package/lib/core/migrations/ROOM.md +33 -0
- package/lib/core/migrations/phase-109-nodes-provenance.cjs +400 -0
- package/lib/core/migrations/phase-109-session-focus.cjs +99 -0
- package/lib/core/migrations/phase-160-nodes-bitemporal.cjs +168 -0
- package/lib/core/migrations/phase-160-nodes-bitemporal.test.cjs +140 -0
- package/lib/core/migrations/phase-162-section-nodes.cjs +156 -0
- package/lib/core/migrations/phase-222-ranker-weights.cjs +62 -0
- package/lib/core/migrations/phase-224-edge-review-status.cjs +87 -0
- package/lib/core/mindrian-brain-shim.test.cjs +221 -0
- package/lib/core/mode-select-sidechannel.cjs +259 -0
- package/lib/core/model-profiles.cjs +246 -0
- package/lib/core/mullins-scaffold.cjs +258 -0
- package/lib/core/mullins-scaffold.test.cjs +128 -0
- package/lib/core/mva-agent-contract.cjs +170 -0
- package/lib/core/mva-agent-contract.test.cjs +169 -0
- package/lib/core/mva-budget.cjs +75 -0
- package/lib/core/mva-budget.test.cjs +68 -0
- package/lib/core/mva-classifier.cjs +392 -0
- package/lib/core/mva-classifier.test.cjs +248 -0
- package/lib/core/mva-deck-builder.cjs +452 -0
- package/lib/core/mva-deck-builder.test.cjs +287 -0
- package/lib/core/mva-detect.smoke.test.cjs +209 -0
- package/lib/core/mva-dispatcher.cjs +110 -0
- package/lib/core/mva-dispatcher.test.cjs +216 -0
- package/lib/core/mva-option-router.cjs +414 -0
- package/lib/core/mva-option-router.test.cjs +483 -0
- package/lib/core/mva-orchestrator.cjs +365 -0
- package/lib/core/mva-orchestrator.test.cjs +916 -0
- package/lib/core/mva-progressive-renderer.cjs +194 -0
- package/lib/core/mva-progressive-renderer.test.cjs +157 -0
- package/lib/core/mva-rule-linter.cjs +458 -0
- package/lib/core/mva-rule-linter.test.cjs +484 -0
- package/lib/core/mva-state.cjs +159 -0
- package/lib/core/mva-telemetry.cjs +58 -0
- package/lib/core/mva-telemetry.test.cjs +196 -0
- package/lib/core/mva-vercel-deploy.cjs +168 -0
- package/lib/core/mva-vercel-deploy.test.cjs +239 -0
- package/lib/core/nav-dial.cjs +440 -0
- package/lib/core/navigation/ROOM.md +15 -0
- package/lib/core/navigation/abstraction-claim.cjs +185 -0
- package/lib/core/navigation/calibration-gate.cjs +284 -0
- package/lib/core/navigation/calibration-log.cjs +141 -0
- package/lib/core/navigation/confirm-node.cjs +73 -0
- package/lib/core/navigation/dashboard-helpers.cjs +145 -0
- package/lib/core/navigation/edges.cjs +1150 -0
- package/lib/core/navigation/evidence-claim.cjs +186 -0
- package/lib/core/navigation/explanation.cjs +48 -0
- package/lib/core/navigation/file-evidence-readback.cjs +242 -0
- package/lib/core/navigation/focus.cjs +155 -0
- package/lib/core/navigation/get-domains-for-trends.cjs +277 -0
- package/lib/core/navigation/governance.cjs +101 -0
- package/lib/core/navigation/grant-rubric.cjs +218 -0
- package/lib/core/navigation/graph-export.cjs +325 -0
- package/lib/core/navigation/ingestion.cjs +109 -0
- package/lib/core/navigation/insights-stale.test.cjs +127 -0
- package/lib/core/navigation/insights.cjs +574 -0
- package/lib/core/navigation/lens-nodes.cjs +315 -0
- package/lib/core/navigation/memory-artifacts.cjs +437 -0
- package/lib/core/navigation/memory-cortex-packet.cjs +274 -0
- package/lib/core/navigation/memory-events.cjs +811 -0
- package/lib/core/navigation/neighborhood.cjs +79 -0
- package/lib/core/navigation/packet.cjs +420 -0
- package/lib/core/navigation/planning-artifacts.cjs +219 -0
- package/lib/core/navigation/projections.cjs +295 -0
- package/lib/core/navigation/ranker-weights.cjs +133 -0
- package/lib/core/navigation/reasoning-write.cjs +211 -0
- package/lib/core/navigation/reconcile-guard.cjs +98 -0
- package/lib/core/navigation/reified-claim.cjs +287 -0
- package/lib/core/navigation/research-preflight.cjs +156 -0
- package/lib/core/navigation/room-birth.cjs +1213 -0
- package/lib/core/navigation/room-context.cjs +380 -0
- package/lib/core/navigation/room-home.cjs +142 -0
- package/lib/core/navigation/spine-events.cjs +548 -0
- package/lib/core/navigation/synthetic-expert.cjs +177 -0
- package/lib/core/navigation/transitions.cjs +253 -0
- package/lib/core/navigation/typed-claim.cjs +208 -0
- package/lib/core/navigation/typed-domain.cjs +249 -0
- package/lib/core/navigation/typed-entity.cjs +236 -0
- package/lib/core/navigation/typed-frame.cjs +257 -0
- package/lib/core/navigation/typed-open-question.cjs +130 -0
- package/lib/core/navigation/typed-opportunity.cjs +418 -0
- package/lib/core/navigation-engine-offer.cjs +776 -0
- package/lib/core/navigation-engine-shared.cjs +256 -0
- package/lib/core/navigation-engine.cjs +1696 -0
- package/lib/core/navigation.cjs +686 -0
- package/lib/core/nl-graph-queries.cjs +164 -0
- package/lib/core/node-insert-epistemic.test.cjs +212 -0
- package/lib/core/node-insert-overrides.test.cjs +273 -0
- package/lib/core/node-insert.cjs +274 -0
- package/lib/core/npm-cli-resolve.cjs +151 -0
- package/lib/core/npm-cli-resolve.test.cjs +153 -0
- package/lib/core/npm-install-lock.cjs +326 -0
- package/lib/core/npm-install-lock.test.cjs +379 -0
- package/lib/core/numeric/sklearn-stopwords-v1.json +325 -0
- package/lib/core/numeric/svd.cjs +377 -0
- package/lib/core/numeric/tfidf.cjs +241 -0
- package/lib/core/offer-presenter.cjs +406 -0
- package/lib/core/opportunity-extractor.cjs +183 -0
- package/lib/core/opportunity-ops.cjs +1423 -0
- package/lib/core/orchestration-candidate-lift.cjs +284 -0
- package/lib/core/part8-egress-guard.cjs +536 -0
- package/lib/core/part8-egress-guard.test.cjs +194 -0
- package/lib/core/part8-egress-ontology.cjs +174 -0
- package/lib/core/part8-egress-ontology.test.cjs +133 -0
- package/lib/core/persona-ops.cjs +692 -0
- package/lib/core/persona-override.cjs +327 -0
- package/lib/core/persona-taxonomy.cjs +328 -0
- package/lib/core/pinecone-inference.cjs +176 -0
- package/lib/core/pitch-feedback-schemas.cjs +303 -0
- package/lib/core/planning/artifact-brain-packet.cjs +212 -0
- package/lib/core/planning/reconcile-runner.cjs +347 -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/publish-needs-default-lane.cjs +110 -0
- package/lib/core/ralph-loop-gate.cjs +48 -0
- package/lib/core/reader/ab-harness.cjs +177 -0
- package/lib/core/reader/decide-projection-reader.cjs +358 -0
- package/lib/core/reasoning-ops.cjs +639 -0
- package/lib/core/recipe-maps.cjs +442 -0
- package/lib/core/recovery/case-file.cjs +358 -0
- package/lib/core/recovery/controller.cjs +1008 -0
- package/lib/core/recovery/dispatcher.cjs +533 -0
- package/lib/core/recovery/result-semantics.cjs +488 -0
- package/lib/core/recovery/stage-envelope.cjs +338 -0
- package/lib/core/refusal-messaging.cjs +569 -0
- package/lib/core/refusal-messaging.test.cjs +220 -0
- package/lib/core/repo-version.cjs +134 -0
- package/lib/core/research-cache.cjs +165 -0
- package/lib/core/research-cache.test.cjs +137 -0
- package/lib/core/research-context-extractor.cjs +283 -0
- package/lib/core/research-corpus.cjs +814 -0
- package/lib/core/research-corpus.test.cjs +280 -0
- package/lib/core/research-filing-selector.cjs +189 -0
- package/lib/core/resolve-active-room.cjs +602 -0
- package/lib/core/resolve-brain-key.cjs +273 -0
- package/lib/core/resolve-umbilical-target.cjs +288 -0
- package/lib/core/resolve-vercel-key.cjs +107 -0
- package/lib/core/resolve-vercel-key.test.cjs +137 -0
- package/lib/core/reverse-salient-persona-suffix.cjs +115 -0
- package/lib/core/room-auto-create.cjs +318 -0
- package/lib/core/room-auto-create.test.cjs +198 -0
- package/lib/core/room-chooser.cjs +244 -0
- package/lib/core/room-classifier-strict-mode.cjs +235 -0
- package/lib/core/room-db.cjs +348 -0
- package/lib/core/room-discard-cascade.cjs +238 -0
- package/lib/core/room-discard-cascade.test.cjs +135 -0
- package/lib/core/room-name-validator.cjs +132 -0
- package/lib/core/room-name-validator.test.cjs +156 -0
- package/lib/core/room-naming-selector.cjs +357 -0
- package/lib/core/room-naming-selector.test.cjs +277 -0
- package/lib/core/room-open.cjs +259 -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-receipt-emit.cjs +63 -0
- package/lib/core/room-root.cjs +93 -0
- package/lib/core/room-skeleton-scaffold.cjs +669 -0
- package/lib/core/room-skeleton-scaffold.test.cjs +296 -0
- package/lib/core/room-type-detector.cjs +386 -0
- package/lib/core/rs-backend-dispatch.cjs +64 -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 +381 -0
- package/lib/core/rs-commercial-assessor.cjs +280 -0
- package/lib/core/rs-corpus-quality-gate.cjs +62 -0
- package/lib/core/rs-differential-scorer.cjs +629 -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-engine.cjs +597 -0
- package/lib/core/rs-expert-brain-projection.cjs +280 -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-math.cjs +458 -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 +435 -0
- package/lib/core/rs-pinecone-bridge.cjs +344 -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 +495 -0
- package/lib/core/rs-thesis-generator.cjs +188 -0
- package/lib/core/rs_cache.py +635 -0
- package/lib/core/rs_corpus.py +562 -0
- package/lib/core/rs_corpus_exclude.py +62 -0
- package/lib/core/rs_hybrid.py +589 -0
- package/lib/core/rs_math.py +287 -0
- package/lib/core/rs_rooms.py +196 -0
- package/lib/core/salient-governance.cjs +315 -0
- package/lib/core/scheduled-scanner.cjs +658 -0
- package/lib/core/scratchpad-ops.cjs +316 -0
- package/lib/core/seam-liveness.cjs +191 -0
- package/lib/core/seam-liveness.test.cjs +177 -0
- package/lib/core/section-8-trace-schema.cjs +138 -0
- package/lib/core/section-registry.cjs +167 -0
- package/lib/core/security/agentshield-adapters.test.cjs +104 -0
- package/lib/core/security/agentshield-run.cjs +343 -0
- package/lib/core/security/agentshield-scanner.cjs +314 -0
- package/lib/core/security/agentshield-scanner.test.cjs +259 -0
- package/lib/core/sensors/hat-scoping-table.cjs +103 -0
- package/lib/core/sensors/sensor-circularity.cjs +278 -0
- package/lib/core/sensors/sensor-content-relevance.cjs +407 -0
- package/lib/core/sensors/sensor-diffusion-adoption.cjs +230 -0
- package/lib/core/sensors/sensor-eureka.cjs +208 -0
- package/lib/core/sensors/sensor-expert-skill.cjs +293 -0
- package/lib/core/sensors/sensor-external-fact.cjs +184 -0
- package/lib/core/sensors/sensor-gate-approach.cjs +104 -0
- package/lib/core/sensors/sensor-jtbd-reweight.cjs +141 -0
- package/lib/core/sensors/sensor-lagging-component.cjs +115 -0
- package/lib/core/sensors/sensor-memory-cortex.cjs +111 -0
- package/lib/core/sensors/sensor-methodology-decision.cjs +131 -0
- package/lib/core/sensors/sensor-opportunity-harvest.cjs +195 -0
- package/lib/core/sensors/sensor-perspective-lock.cjs +174 -0
- package/lib/core/sensors/sensor-priority.cjs +183 -0
- package/lib/core/sensors/sensor-recency.cjs +151 -0
- package/lib/core/sensors/sensor-roadmap-type.cjs +421 -0
- package/lib/core/sensors/sensor-room-pick.cjs +238 -0
- package/lib/core/sensors/sensor-show-share.cjs +215 -0
- package/lib/core/sensors/sensor-temporal-blindness.cjs +123 -0
- package/lib/core/sensors/sensor-types.cjs +294 -0
- package/lib/core/sensors/sensor-url-ingest.cjs +234 -0
- package/lib/core/session-binding.cjs +208 -0
- package/lib/core/session-presence.cjs +404 -0
- package/lib/core/session-register.cjs +138 -0
- package/lib/core/session-state.cjs +144 -0
- package/lib/core/shallow-doc-parser.cjs +353 -0
- package/lib/core/shallow-doc-parser.test.cjs +226 -0
- package/lib/core/skill-activation-router.cjs +284 -0
- package/lib/core/skillopt-schemas.cjs +509 -0
- package/lib/core/stale-copy-scanner.cjs +190 -0
- package/lib/core/stance-state.cjs +153 -0
- package/lib/core/state-aware-router.cjs +78 -0
- package/lib/core/state-ops.cjs +80 -0
- package/lib/core/state-version.cjs +350 -0
- package/lib/core/statusline-cache.cjs +266 -0
- package/lib/core/statusline-liveness-gate.cjs +105 -0
- package/lib/core/surface-fence.cjs +127 -0
- package/lib/core/synthesizers/comparison-matrix.cjs +82 -0
- package/lib/core/synthesizers/convergence-map.cjs +107 -0
- package/lib/core/synthesizers/domain-hierarchy.cjs +138 -0
- package/lib/core/synthesizers/source-comparison.cjs +56 -0
- package/lib/core/synthesizers/tension-map.cjs +119 -0
- package/lib/core/synthetic-expert-behavior-gate.cjs +99 -0
- package/lib/core/synthetic-expert-construction-gate.cjs +170 -0
- package/lib/core/telemetry/schema.cjs +168 -0
- package/lib/core/telemetry/schema.test.cjs +124 -0
- package/lib/core/telemetry/validator.cjs +200 -0
- package/lib/core/telemetry/validator.test.cjs +188 -0
- package/lib/core/telemetry/writer.cjs +141 -0
- package/lib/core/telemetry/writer.test.cjs +331 -0
- package/lib/core/temporal/date-sync-gate.cjs +256 -0
- package/lib/core/temporal/date-sync-gate.test.cjs +191 -0
- package/lib/core/temporal/dual-stamp.cjs +172 -0
- package/lib/core/temporal/dual-stamp.test.cjs +172 -0
- package/lib/core/temporal/point-in-time.cjs +76 -0
- package/lib/core/temporal/point-in-time.test.cjs +169 -0
- package/lib/core/temporal/recency-decay.cjs +119 -0
- package/lib/core/temporal/recency-decay.test.cjs +140 -0
- package/lib/core/temporal/reference-now.cjs +281 -0
- package/lib/core/temporal/reference-now.test.cjs +225 -0
- package/lib/core/temporal/resolve-relative-time.cjs +116 -0
- package/lib/core/temporal/resolve-relative-time.test.cjs +138 -0
- package/lib/core/temporal/supersession.cjs +250 -0
- package/lib/core/temporal/supersession.test.cjs +103 -0
- package/lib/core/terminal-capability.cjs +88 -0
- package/lib/core/token-estimator.cjs +348 -0
- package/lib/core/tone-filter.cjs +147 -0
- package/lib/core/trending-to-absurd/orchestrator.cjs +341 -0
- package/lib/core/trending-to-absurd/stage7-roadmap.cjs +317 -0
- package/lib/core/trending-to-absurd/variance.cjs +169 -0
- package/lib/core/unknowns/bandit.cjs +332 -0
- package/lib/core/unknowns/corpus-adapter.cjs +327 -0
- package/lib/core/unknowns/dsp.cjs +356 -0
- package/lib/core/unknowns/edge-writer.cjs +211 -0
- package/lib/core/unknowns/iface.cjs +212 -0
- package/lib/core/unknowns/orchestrator.cjs +375 -0
- package/lib/core/unknowns/pattern-miner.cjs +214 -0
- package/lib/core/unknowns/rumsfeld-matrix.cjs +155 -0
- package/lib/core/unknowns/verdict.cjs +254 -0
- package/lib/core/update-path.cjs +57 -0
- package/lib/core/url-ingest.cjs +568 -0
- package/lib/core/user-archetype.cjs +284 -0
- package/lib/core/user-md-ops.cjs +578 -0
- package/lib/core/venture-shape-nudge.cjs +178 -0
- package/lib/core/venture-shape-nudge.test.cjs +266 -0
- package/lib/core/verb-reach-affinity.cjs +299 -0
- package/lib/core/visual-ops.cjs +692 -0
- package/lib/core/voice-transition-detector.cjs +125 -0
- package/lib/core/watched-sources.cjs +237 -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 +669 -0
- package/lib/hmi/agentshield-drift-gate.cjs +142 -0
- package/lib/hmi/brain-review-packet.cjs +221 -0
- package/lib/hmi/cortex-reach-adapter.cjs +271 -0
- package/lib/hmi/cross-room-memory.cjs +618 -0
- package/lib/hmi/decoy-tier.cjs +395 -0
- package/lib/hmi/depth-state.cjs +164 -0
- package/lib/hmi/dial-label-composer.cjs +410 -0
- package/lib/hmi/dial-presenter.cjs +508 -0
- package/lib/hmi/dial-reach-orchestrator.cjs +377 -0
- package/lib/hmi/dial-selector.cjs +239 -0
- package/lib/hmi/f1-pick-capture-cli.cjs +131 -0
- package/lib/hmi/f3-depth-capture-cli.cjs +77 -0
- package/lib/hmi/f4-scope-capture-cli.cjs +86 -0
- package/lib/hmi/f8-action-capture-cli.cjs +145 -0
- package/lib/hmi/f8-capture.test.cjs +77 -0
- package/lib/hmi/f9-ordered-capture-cli.cjs +138 -0
- package/lib/hmi/harvest-scope-state.cjs +202 -0
- package/lib/hmi/hats-persona-cache.cjs +142 -0
- package/lib/hmi/jtbd-classifier.cjs +219 -0
- package/lib/hmi/jtbd-state.cjs +263 -0
- package/lib/hmi/jtbd-taxonomy.json +402 -0
- package/lib/hmi/mindrian-ascii-logo.cjs +96 -0
- package/lib/hmi/part8-egress-gate.cjs +149 -0
- package/lib/hmi/reach-component-map.json +47 -0
- package/lib/hmi/reach-relevance-gate.cjs +147 -0
- package/lib/hmi/selector-dispatcher.cjs +1201 -0
- package/lib/hmi/selector-dispatcher.test.cjs +141 -0
- package/lib/hmi/selector-telemetry.cjs +269 -0
- package/lib/hmi/shape-f0-renderer.cjs +145 -0
- package/lib/hmi/shape-f1-fallback.cjs +80 -0
- package/lib/hmi/shape-f1-renderer.cjs +219 -0
- package/lib/hmi/shape-f2-renderer.cjs +132 -0
- package/lib/hmi/shape-f3-parity.test.cjs +64 -0
- package/lib/hmi/shape-f3-renderer.cjs +66 -0
- package/lib/hmi/shape-f4-parity.test.cjs +72 -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 +324 -0
- package/lib/hmi/shape-f6-renderer.cjs +144 -0
- package/lib/hmi/shape-f7-breakthrough-renderer.cjs +234 -0
- package/lib/hmi/shape-f7-breakthrough-renderer.test.cjs +233 -0
- package/lib/hmi/shape-f8-renderer.cjs +150 -0
- package/lib/hmi/shape-f8-renderer.test.cjs +70 -0
- package/lib/hmi/shape-f9-renderer.cjs +187 -0
- package/lib/hmi/shape-f9-renderer.test.cjs +80 -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/hmi/turn-text.cjs +268 -0
- package/lib/hmi/voice-color-mark.cjs +318 -0
- package/lib/hmi/voice-style-log.cjs +276 -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/undo.test.cjs +199 -0
- package/lib/import/vault-scanner.cjs +105 -0
- package/lib/import/vault-scanner.test.cjs +67 -0
- package/lib/lens-engine/correlation-resolver.cjs +174 -0
- package/lib/lens-engine/source-lens-driver.cjs +736 -0
- package/lib/mcp/adapter-client.cjs +103 -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-composition-census.cjs +184 -0
- package/lib/mcp/brain-router.cjs +530 -0
- package/lib/mcp/capability-registry.cjs +62 -0
- package/lib/mcp/contract-version.cjs +59 -0
- package/lib/mcp/daemon-lifecycle.cjs +324 -0
- package/lib/mcp/gate-dedup.cjs +120 -0
- package/lib/mcp/gate-ledger.cjs +145 -0
- package/lib/mcp/gate-render.cjs +483 -0
- package/lib/mcp/hook-adapter-audit.cjs +199 -0
- package/lib/mcp/larry-context.cjs +42 -0
- package/lib/mcp/mcp-first-flag.cjs +147 -0
- package/lib/mcp/no-instructions.test.cjs +270 -0
- package/lib/mcp/pipeline-state.cjs +424 -0
- package/lib/mcp/prompts.cjs +421 -0
- package/lib/mcp/register-core-tools.cjs +78 -0
- package/lib/mcp/resources.cjs +359 -0
- package/lib/mcp/runtime-instructions.cjs +38 -0
- package/lib/mcp/session-catchup.cjs +349 -0
- package/lib/mcp/session-registry.cjs +113 -0
- package/lib/mcp/session-room.cjs +124 -0
- package/lib/mcp/sse-event-bus.cjs +98 -0
- package/lib/mcp/stop-gate-handler.cjs +589 -0
- package/lib/mcp/surface-detect.cjs +186 -0
- package/lib/mcp/tool-router.cjs +2113 -0
- package/lib/mcp/tools/chain.cjs +674 -0
- package/lib/mcp/tools/claim.cjs +180 -0
- package/lib/mcp/tools/context.cjs +92 -0
- package/lib/mcp/tools/dual-path.cjs +79 -0
- package/lib/mcp/tools/gate.cjs +392 -0
- package/lib/mcp/tools/graph-reason.cjs +130 -0
- package/lib/mcp/tools/graph.cjs +321 -0
- package/lib/mcp/tools/identity.cjs +174 -0
- package/lib/mcp/tools/room.cjs +449 -0
- package/lib/mcp/tools/sensors.cjs +450 -0
- package/lib/mcp/tools/status.cjs +183 -0
- package/lib/mcp/tools/stop-gate.cjs +103 -0
- package/lib/mcp/tools/views.cjs +382 -0
- package/lib/mcp/tree-watcher.cjs +199 -0
- package/lib/memory/.mindrian/auto-explore-mat-test-001.json +11 -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/body-shape-coverage.test.cjs +268 -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-cypher-chain-slice.test.cjs +368 -0
- package/lib/memory/brain-derivation-graceful-degradation.test.cjs +1019 -0
- package/lib/memory/brain-derivation-queue.test.cjs +553 -0
- package/lib/memory/brain-derivation.test.cjs +639 -0
- package/lib/memory/brain-derive-command.test.cjs +534 -0
- package/lib/memory/brain-derive-curation.test.cjs +243 -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/brain-suggestion-template.test.cjs +200 -0
- package/lib/memory/chain-recommender-canonical.test.cjs +208 -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/connector-registry.test.cjs +94 -0
- package/lib/memory/correlation-label-index.test.cjs +119 -0
- package/lib/memory/correlation.test.cjs +253 -0
- package/lib/memory/cross-room-aggregator.test.cjs +909 -0
- package/lib/memory/curation-132-03-dedup-held-rename.test.cjs +251 -0
- package/lib/memory/curation-132-05-pseudonymize.test.cjs +205 -0
- package/lib/memory/curation-batch.test.cjs +213 -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/doctor-deprecation-surface.test.cjs +188 -0
- package/lib/memory/dual-graph-health.test.cjs +485 -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/f-selector-ranker.test.cjs +593 -0
- package/lib/memory/feynman-minto-guardian.test.cjs +863 -0
- package/lib/memory/feynman-minto-invariants.test.cjs +554 -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/first-touch-version.test.cjs +198 -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 +549 -0
- package/lib/memory/frontmatter-schema-validator.test.cjs +344 -0
- package/lib/memory/guardian-onstop-reaches-user.test.cjs +396 -0
- package/lib/memory/heal-command.test.cjs +604 -0
- package/lib/memory/help-coverage.test.cjs +108 -0
- package/lib/memory/help-renderer.test.cjs +145 -0
- package/lib/memory/huji-run-one-async-parity.test.cjs +242 -0
- package/lib/memory/hypergraph-event-schema.test.cjs +116 -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/local-chain-recommender.test.cjs +172 -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-debounce-consumer-census.test.cjs +567 -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 +712 -0
- package/lib/memory/navigation-engine-offer.test.cjs +404 -0
- package/lib/memory/navigation-hook-resolver.test.cjs +177 -0
- package/lib/memory/navigation-invariants.test.cjs +483 -0
- package/lib/memory/navigation-projections.test.cjs +241 -0
- package/lib/memory/navigation-write-edge.test.cjs +206 -0
- package/lib/memory/offer-closer.test.cjs +258 -0
- package/lib/memory/offer-presenter.test.cjs +554 -0
- package/lib/memory/on-stop-snapshot.test.cjs +404 -0
- package/lib/memory/orchestration-projection.test.cjs +706 -0
- package/lib/memory/packet-chain-hint.test.cjs +407 -0
- package/lib/memory/packet-schema-validation.test.cjs +317 -0
- package/lib/memory/palette-consistency.test.cjs +127 -0
- package/lib/memory/pending-tension-store.cjs +453 -0
- package/lib/memory/per-command-jtbd-derivation.test.cjs +130 -0
- package/lib/memory/per-command-teaching.test.cjs +110 -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/precommit-real-commit.test.cjs +301 -0
- package/lib/memory/problem-type-router.test.cjs +656 -0
- package/lib/memory/query-efficiency-telemetry.test.cjs +612 -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/render-v2-disposition.test.cjs +199 -0
- package/lib/memory/room-classifier-strict-mode.test.cjs +430 -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 +2101 -0
- package/lib/memory/security-trifecta.test.cjs +329 -0
- package/lib/memory/selector-alias-map.test.cjs +172 -0
- package/lib/memory/selector-decisions.test.cjs +417 -0
- package/lib/memory/selector-miss.test.cjs +290 -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-coordinator.test.cjs +446 -0
- package/lib/memory/sessionstart-minto-banner.test.cjs +373 -0
- package/lib/memory/skill-activation-router.test.cjs +465 -0
- package/lib/memory/skill-vs-code-drift.test.cjs +257 -0
- package/lib/memory/soft-alias.test.cjs +144 -0
- package/lib/memory/spine-events-correlation.test.cjs +198 -0
- package/lib/memory/stale-copy-scanner.test.cjs +294 -0
- package/lib/memory/stamp-artifact-write.test.cjs +304 -0
- package/lib/memory/state-aware-router.test.cjs +90 -0
- package/lib/memory/statusline-active-room-write.test.cjs +245 -0
- package/lib/memory/statusline-active-room.test.cjs +315 -0
- package/lib/memory/statusline-minto-segment.test.cjs +292 -0
- package/lib/memory/statusline-two-row.test.cjs +338 -0
- package/lib/memory/suggest-next-workflow.test.cjs +176 -0
- package/lib/memory/sync-async-entry-points.test.cjs +204 -0
- package/lib/memory/terminal-capability.test.cjs +155 -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 +648 -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 +282 -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 +787 -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/workflow-layer-e2e.test.cjs +262 -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 +111 -0
- package/lib/render/render-v2.cjs +532 -0
- package/lib/render/render-v2.test.cjs +267 -0
- package/lib/render/render.cjs +65 -0
- package/lib/sessionstart/budget-compressor.cjs +130 -0
- package/lib/sessionstart/contributor-interface.cjs +134 -0
- package/lib/sessionstart/contributor-isolator.cjs +128 -0
- package/lib/sessionstart/precedence-ladder.cjs +47 -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/cockpit-renderer.cjs +443 -0
- package/lib/statusline/cockpit-signals.cjs +312 -0
- package/lib/statusline/cockpit-telemetry.cjs +152 -0
- package/lib/statusline/ctx-window.cjs +135 -0
- package/lib/statusline/governing-thought-truncator.cjs +45 -0
- package/lib/statusline/next-move-cache.cjs +235 -0
- package/lib/statusline/ratification-next.cjs +164 -0
- package/lib/statusline/room-health-cache.cjs +200 -0
- package/lib/statusline/surface-detect.cjs +85 -0
- package/lib/statusline/two-row-renderer.cjs +207 -0
- package/lib/statusline/version-resolver.cjs +81 -0
- package/lib/ui/design-system.cjs +19 -0
- package/lib/update-bootstrap.sh.template +145 -0
- package/lib/vault/frontmatter-schema.cjs +297 -0
- package/lib/vault/room-scanner.cjs +365 -0
- package/lib/vault/wikilink-builder.cjs +231 -0
- package/lib/vault/wikilink-builder.test.cjs +182 -0
- package/lib/wiki/briefing.cjs +193 -0
- package/lib/wiki/editor-dist/wiki-editor.css +1 -0
- package/lib/wiki/editor-dist/wiki-editor.js +1327 -0
- package/lib/wiki/graph-links.cjs +281 -0
- package/lib/wiki/page-renderer.cjs +229 -0
- package/lib/wiki/room-home.cjs +353 -0
- package/lib/wiki/wiki-chat.cjs +81 -0
- package/lib/wiki/wiki-export.cjs +364 -0
- package/lib/wiki/wiki-layout.cjs +1143 -0
- package/lib/wiki/wiki-search.cjs +142 -0
- package/lib/wiki/wiki-server.cjs +748 -0
- package/lib/wiki/wiki-watcher.cjs +105 -0
- package/lib/workflow/ROOM.md +47 -0
- package/lib/workflow/chain-source.cjs +179 -0
- package/lib/workflow/command-resolver.cjs +155 -0
- package/lib/workflow/command-resolver.test.cjs +235 -0
- package/lib/workflow/cross-room-umbilical-closer.cjs +364 -0
- package/lib/workflow/dial-close-reach.cjs +405 -0
- package/lib/workflow/f-selector-ranker.cjs +1148 -0
- package/lib/workflow/f1-pick-consumer.cjs +232 -0
- package/lib/workflow/f3-depth-consumer.cjs +98 -0
- package/lib/workflow/f4-scope-consumer.cjs +112 -0
- package/lib/workflow/f8-consumer.test.cjs +82 -0
- package/lib/workflow/f8-fanout-consumer.cjs +208 -0
- package/lib/workflow/f9-consumer.test.cjs +71 -0
- package/lib/workflow/f9-ordered-consumer.cjs +199 -0
- package/lib/workflow/local-chain-recommender.cjs +330 -0
- package/lib/workflow/memory-cascade-f9-adapter.cjs +273 -0
- package/lib/workflow/memory-governance-closer.cjs +384 -0
- package/lib/workflow/offer-closer.cjs +407 -0
- package/lib/workflow/reach-hedge-ranker.cjs +809 -0
- package/lib/workflow/reach-reject-reader.cjs +372 -0
- package/lib/workflow/reconcile-f9-adapter.cjs +299 -0
- package/lib/workflow/selector-decisions.cjs +478 -0
- package/lib/workflow/session-binding-consumer.cjs +249 -0
- package/npm-shrinkwrap.json +1544 -0
- package/output-styles/destijl.md +67 -0
- package/package.json +22 -4
- package/pipelines/PWS_grading/01-deep-grade.md +48 -0
- package/pipelines/PWS_grading/02-mullins.md +50 -0
- package/pipelines/PWS_grading/03-build-thesis.md +60 -0
- package/pipelines/PWS_grading/04-structure-argument.md +77 -0
- package/pipelines/PWS_grading/CHAIN.md +79 -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 +73 -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 +48 -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 +48 -0
- package/references/brain/causal-directives.md +91 -0
- package/references/brain/causal-enrichment.cypher +165 -0
- package/references/brain/command-triggers-schema.md +15 -0
- package/references/brain/graph-architecture.md +317 -0
- package/references/brain/query-patterns.md +504 -0
- package/references/brain/room-hierarchy-schema.md +218 -0
- package/references/brain/schema.md +86 -0
- package/references/capability-radar/capabilities-index.md +269 -0
- package/references/capability-radar/changelog-cache.md +95 -0
- package/references/causal/causal-schema.md +103 -0
- package/references/design/email-template-standard.md +169 -0
- package/references/design/graph-visualization-standard.md +178 -0
- package/references/design/newsletter-email-template.html +307 -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/extraction-perspectives.md +225 -0
- package/references/meeting/filing-protocol.md +222 -0
- package/references/meeting/knowledge-typing.md +242 -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-scored.md +60 -0
- package/references/methodology/build-thesis.md +237 -0
- package/references/methodology/causal-loop-diagrams.md +65 -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/huji-stage-a-intake.md +246 -0
- package/references/methodology/index.md +34 -0
- package/references/methodology/leadership.md +200 -0
- package/references/methodology/lean-canvas.md +116 -0
- package/references/methodology/leverage-scan-signatures.md +83 -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/rubric-huji.md +160 -0
- package/references/methodology/sapphire-encoding.md +355 -0
- package/references/methodology/scenario-plan.md +190 -0
- package/references/methodology/score-innovation.md +154 -0
- package/references/methodology/skillopt-judge-rubric.md +48 -0
- package/references/methodology/skillopt-queries-rubric.md +60 -0
- package/references/methodology/skillopt-refute-rubric.md +59 -0
- package/references/methodology/skillopt-review-rubric.md +72 -0
- package/references/methodology/skillopt-revise-rubric.md +48 -0
- package/references/methodology/structure-argument.md +158 -0
- package/references/methodology/systems-thinking.md +231 -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/opportunities/tnufa-rubric.md +81 -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/security/agentshield-baseline.json +8 -0
- package/references/security/cve-db.json +220 -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/ROOM.md +55 -0
- package/references/visual/palette.json +54 -0
- package/references/visual/symbol-system.md +151 -0
- package/scripts/189-plurai-gate-check.cjs +88 -0
- package/scripts/198-plurai-gate-check.cjs +118 -0
- package/scripts/198-rollback-rehearsal.cjs +233 -0
- package/scripts/83-scope-injection.test.cjs +648 -0
- package/scripts/PYTHON_GATES.md +78 -0
- package/scripts/__pycache__/compute-hsi.cpython-312.pyc +0 -0
- package/scripts/__pycache__/detect-reverse-salients.cpython-312.pyc +0 -0
- package/scripts/__pycache__/rs-engine.cpython-312.pyc +0 -0
- package/scripts/act-command.cjs +518 -0
- package/scripts/admin-brain-write.cjs +442 -0
- package/scripts/admin-command-gate.cjs +178 -0
- package/scripts/agentshield-scan-cli.cjs +226 -0
- package/scripts/agentshield-sessionstart-scan.cjs +282 -0
- package/scripts/analogy-fitness-report.cjs +266 -0
- package/scripts/analyze-room +1079 -0
- package/scripts/apply-teaching-content.cjs +298 -0
- package/scripts/async-artifact-auto-commit.cjs +485 -0
- package/scripts/audit-active-phase-resolver.cjs +160 -0
- package/scripts/audit-body-shape-coverage.cjs +213 -0
- package/scripts/auto-explore-drain.cjs +274 -0
- package/scripts/auto-explore-fingerprint.cjs +354 -0
- package/scripts/auto-explore-fire.cjs +359 -0
- package/scripts/backfill-correlation-id.cjs +425 -0
- package/scripts/backfill-hitl-shape.cjs +276 -0
- package/scripts/backfill-hitl-shape.test.cjs +307 -0
- package/scripts/backup-modifications +68 -0
- package/scripts/banner +182 -0
- package/scripts/brain-derivation-drain.cjs +291 -0
- package/scripts/brain-derive-command.cjs +846 -0
- package/scripts/brain-normalize-books.cypher +505 -0
- package/scripts/brain-normalize-final.cypher +1355 -0
- package/scripts/brain-normalize-problemtype.cypher +475 -0
- package/scripts/brain-normalize-supplement.cypher +449 -0
- package/scripts/brain-normalize-targeted.cypher +344 -0
- package/scripts/brain-normalize-v194.cypher +61 -0
- package/scripts/brain-normalize.cypher +530 -0
- package/scripts/brain-response-sanitize-hook.cjs +165 -0
- package/scripts/build-brain-census.cjs +957 -0
- package/scripts/build-brain-packet-schema.cjs +225 -0
- package/scripts/build-command-registry.cjs +587 -0
- package/scripts/build-connector-registry.cjs +1331 -0
- package/scripts/build-corpus-stats.cjs +408 -0
- package/scripts/build-dist-bundles.cjs +495 -0
- package/scripts/build-ecosystem-graph.cjs +490 -0
- package/scripts/build-graph +1462 -0
- package/scripts/build-graph-from-sqlite.cjs +97 -0
- package/scripts/build-harness-manifest.cjs +1090 -0
- package/scripts/build-jtbd-nudges +205 -0
- package/scripts/build-new-surface.cjs +805 -0
- package/scripts/build-orchestration-projection.cjs +1221 -0
- package/scripts/build-render-coverage.cjs +637 -0
- package/scripts/build-skill-mirrors.cjs +681 -0
- package/scripts/cache-hitrate-report.cjs +216 -0
- package/scripts/causal-to-graph.cjs +163 -0
- package/scripts/check-abstraction-fixture-neutral.cjs +160 -0
- package/scripts/check-admin-identity.cjs +212 -0
- package/scripts/check-brain-tool-liveness.cjs +502 -0
- package/scripts/check-card-fire.cjs +1809 -0
- package/scripts/check-cirs-declaration.cjs +279 -0
- package/scripts/check-deck-design.cjs +104 -0
- package/scripts/check-dual-graph-health.cjs +645 -0
- package/scripts/check-first-touch-drift.cjs +220 -0
- package/scripts/check-flagship-floor.cjs +391 -0
- package/scripts/check-framework-vocabulary-drift.cjs +563 -0
- package/scripts/check-gate-seam.cjs +178 -0
- package/scripts/check-graph-derive-health.cjs +208 -0
- package/scripts/check-graph-export-typemap.cjs +118 -0
- package/scripts/check-help-coverage.cjs +290 -0
- package/scripts/check-hitl-stages.cjs +219 -0
- package/scripts/check-hook-schema-compatibility.cjs +231 -0
- package/scripts/check-hsi-deps +42 -0
- package/scripts/check-kuzu-reintroduction.cjs +251 -0
- package/scripts/check-onboard +43 -0
- package/scripts/check-onboard-statusline.cjs +363 -0
- package/scripts/check-palette-consistency.cjs +106 -0
- package/scripts/check-pending-ambiguous.cjs +244 -0
- package/scripts/check-pending-breakthrough.cjs +189 -0
- package/scripts/check-pending-breakthrough.test.cjs +166 -0
- package/scripts/check-pending-naming-decision.cjs +97 -0
- package/scripts/check-plugin-path-anchoring.cjs +830 -0
- package/scripts/check-publish-needs.cjs +126 -0
- package/scripts/check-registry-drift.cjs +206 -0
- package/scripts/check-release-payload-ceiling.cjs +269 -0
- package/scripts/check-render-coverage.cjs +558 -0
- package/scripts/check-research-isomorphism.cjs +446 -0
- package/scripts/check-reward-before-investment.cjs +261 -0
- package/scripts/check-room-blueprints.cjs +213 -0
- package/scripts/check-schema-aliases.cjs +532 -0
- package/scripts/check-shape-declaration.cjs +958 -0
- package/scripts/check-shape-declaration.test.cjs +185 -0
- package/scripts/check-skill-spec.cjs +312 -0
- package/scripts/check-skill-vs-code-drift.cjs +178 -0
- package/scripts/check-substrate.cjs +513 -0
- package/scripts/check-tool-honesty.cjs +1601 -0
- package/scripts/check-update +60 -0
- package/scripts/check-version-and-sha.cjs +366 -0
- package/scripts/check-voice-style.cjs +184 -0
- package/scripts/check-worktree-hygiene.cjs +530 -0
- package/scripts/classify-insight +59 -0
- package/scripts/coherence-smoke-test.cjs +489 -0
- package/scripts/compute-bayesian-surprise.py +175 -0
- package/scripts/compute-blindspot-mass.py +209 -0
- package/scripts/compute-disruption-index.py +211 -0
- package/scripts/compute-element-novelty.py +254 -0
- package/scripts/compute-external-whitespace.py +563 -0
- package/scripts/compute-hsi.py +947 -0
- package/scripts/compute-meetings-intelligence +716 -0
- package/scripts/compute-opportunity-state +17 -0
- package/scripts/compute-state +393 -0
- package/scripts/compute-team +1112 -0
- package/scripts/compute-whitespace-embeddings.py +464 -0
- package/scripts/compute-whitespace-gaps.py +562 -0
- package/scripts/compute_topic_forest.py +684 -0
- package/scripts/consolidate-pinecone.py +265 -0
- package/scripts/context-monitor +943 -0
- package/scripts/create-speaker-profile +311 -0
- package/scripts/cross-room-detect.cjs +195 -0
- package/scripts/csv-to-idea-graph.cjs +755 -0
- package/scripts/ctxl-eval.cjs +846 -0
- package/scripts/curation-132-03-dedup-held-rename.cjs +395 -0
- package/scripts/curation-132-05-pseudonymize.cjs +189 -0
- package/scripts/derive-verb-reach-affinity.cjs +507 -0
- package/scripts/detect-reverse-salients.py +242 -0
- package/scripts/diagnostics-command.cjs +345 -0
- package/scripts/dial-memory-refresh-command.cjs +147 -0
- package/scripts/discover-analogy-whitespace.py +433 -0
- package/scripts/discover-hsi-whitespace.py +352 -0
- package/scripts/discover-rs-whitespace.py +327 -0
- package/scripts/discovery-cycle.cjs +625 -0
- package/scripts/disposition-render-v2.cjs +229 -0
- package/scripts/doctor-preflight-format.cjs +101 -0
- package/scripts/doctor.cjs +4327 -0
- package/scripts/dogfood-bridge/append-to-queue.sh +59 -0
- package/scripts/dogfood-bridge/path-filter.cjs +86 -0
- package/scripts/dogfood-derive.cjs +158 -0
- package/scripts/dogfood-emit.cjs +126 -0
- package/scripts/empathy-observation-emit.cjs +108 -0
- package/scripts/enrichment-queue-append.cjs +157 -0
- package/scripts/ensure-brain-baseline.cjs +117 -0
- package/scripts/entity-extract.cjs +1135 -0
- package/scripts/eureka-command.cjs +687 -0
- package/scripts/eureka-critic-run.cjs +662 -0
- package/scripts/eureka-portfolio-report.cjs +2038 -0
- package/scripts/eureka-room-report.cjs +419 -0
- package/scripts/explain-decision-command.cjs +499 -0
- package/scripts/export-pinecone-embeddings.cjs +516 -0
- package/scripts/extract-room-intelligence.cjs +714 -0
- package/scripts/fetch-brain-baseline.cjs +190 -0
- package/scripts/fetch-brain-baseline.py +360 -0
- package/scripts/feynman-minto-guardian.cjs +672 -0
- package/scripts/feynman-timeline-refresh-command.cjs +270 -0
- package/scripts/file-asset +253 -0
- package/scripts/fire-sensor-event.cjs +83 -0
- package/scripts/first-install-router.cjs +968 -0
- package/scripts/frontmatter-schema-validator.cjs +339 -0
- package/scripts/fts-index-drain.cjs +221 -0
- package/scripts/generate-chat-embed.cjs +179 -0
- package/scripts/generate-deck.cjs +322 -0
- package/scripts/generate-export.cjs +474 -0
- package/scripts/generate-hub.cjs +2553 -0
- package/scripts/generate-lobby.cjs +718 -0
- package/scripts/generate-presentation.cjs +988 -0
- package/scripts/generate-presentation.test.cjs +405 -0
- package/scripts/generate-section-intelligence.cjs +330 -0
- package/scripts/generate-snapshot.cjs +1410 -0
- package/scripts/generate-standalone +159 -0
- package/scripts/git-ops +211 -0
- package/scripts/graph-heal-pipeline.cjs +321 -0
- package/scripts/gsd-artifact-graph-hook.cjs +219 -0
- package/scripts/gsd-graph-derive-drain.cjs +571 -0
- package/scripts/gsd-graph-derive-sweep.cjs +195 -0
- package/scripts/heal-command.cjs +1365 -0
- package/scripts/hedge-refit-pipeline.cjs +207 -0
- package/scripts/help-renderer.cjs +303 -0
- package/scripts/hmi-compliance-poll.cjs +451 -0
- package/scripts/hmi-status-command.cjs +510 -0
- package/scripts/hooked-rescore-117.cjs +224 -0
- package/scripts/hooks/pre-commit +533 -0
- package/scripts/hooks/pre-commit-room-minto-guard.cmd +43 -0
- package/scripts/hooks/pre-commit-room-minto-guard.sh +533 -0
- package/scripts/hsi-to-graph.cjs +194 -0
- package/scripts/huji-batch.cjs +821 -0
- package/scripts/huji-eval.cjs +1158 -0
- package/scripts/huji-intake.cjs +563 -0
- package/scripts/huji-pin-smoketest.cjs +454 -0
- package/scripts/huji-run-one-async.cjs +305 -0
- package/scripts/huji-run-one.cjs +671 -0
- package/scripts/install-pre-commit.sh +113 -0
- package/scripts/intent-classifier +106 -0
- package/scripts/intent-classifier.cjs +3620 -0
- package/scripts/interpret-whitespace.cjs +691 -0
- package/scripts/jtbd-command.cjs +810 -0
- package/scripts/jtbd-update.cjs +299 -0
- package/scripts/label-topic-forest.cjs +667 -0
- package/scripts/learn-from-usage +168 -0
- package/scripts/lib/__pycache__/ensure_ml_deps.cpython-312.pyc +0 -0
- package/scripts/lib/ensure_ml_deps.py +97 -0
- package/scripts/load-embeddings-into-neo4j.cjs +569 -0
- package/scripts/memory-artifact-graph-hook.cjs +191 -0
- package/scripts/memory-command.cjs +687 -0
- package/scripts/memory-completion-detector.cjs +217 -0
- package/scripts/memory-lifecycle.cjs +620 -0
- package/scripts/memory-resume-nudge.cjs +233 -0
- package/scripts/methodology-ingest-local.sh +36 -0
- package/scripts/migrate-brain-mcp-from-http-to-stdio.cjs +190 -0
- package/scripts/migrate-brain-mcp-from-http-to-stdio.test.cjs +242 -0
- package/scripts/migrate-hats-to-roomdb.cjs +217 -0
- package/scripts/migrate-lazygraph.cjs +250 -0
- package/scripts/migrate-minto-schema-v88.cjs +296 -0
- package/scripts/migrate-plugin-root-refs.cjs +168 -0
- package/scripts/migrate-room-sections-v275.cjs +556 -0
- package/scripts/migrate-rooms +417 -0
- package/scripts/migrate-skill-frontmatter.cjs +472 -0
- package/scripts/migrate-stale-user-settings.cjs +296 -0
- package/scripts/migrate-telemetry-v1.cjs +384 -0
- package/scripts/migrate-telemetry-v1.test.cjs +356 -0
- package/scripts/minto-debouncer.cjs +428 -0
- package/scripts/mos-status.cjs +622 -0
- package/scripts/mva-detect.cjs +229 -0
- package/scripts/mva-run.cjs +36 -0
- package/scripts/on-agent-complete +163 -0
- package/scripts/on-cwd-changed +149 -0
- package/scripts/on-file-changed +68 -0
- package/scripts/on-stop +617 -0
- package/scripts/on-task-complete +194 -0
- package/scripts/operator-command.cjs +858 -0
- package/scripts/operator-update.cjs +308 -0
- package/scripts/part8-egress-guard-hook.cjs +229 -0
- package/scripts/pipeline-command.cjs +271 -0
- package/scripts/post-compact +383 -0
- package/scripts/post-update-activation.cjs +339 -0
- package/scripts/post-write +283 -0
- package/scripts/power-demo-prompt.md +621 -0
- package/scripts/pre-compact +273 -0
- package/scripts/preflight-auto-explore.cjs +314 -0
- package/scripts/preflight-doctor.cjs +225 -0
- package/scripts/preflight-release-drift.cjs +168 -0
- package/scripts/preflight-tension-surface.cjs +414 -0
- package/scripts/probe-brain-contract.cjs +502 -0
- package/scripts/publish-ops +346 -0
- package/scripts/query-efficiency-telemetry.cjs +364 -0
- package/scripts/query-semantic-scholar.cjs +545 -0
- package/scripts/reapply-modifications +49 -0
- package/scripts/reassign-primary.cjs +125 -0
- package/scripts/recompile-room-references.cjs +601 -0
- package/scripts/release-beta-preflight.sh +69 -0
- package/scripts/render-pdf +588 -0
- package/scripts/render-viz +190 -0
- package/scripts/research-speaker +239 -0
- package/scripts/resolve-room +204 -0
- package/scripts/restore-post-compact-context.cjs +320 -0
- package/scripts/room-auto-create-nudge.cjs +136 -0
- package/scripts/room-naming-selector.cjs +201 -0
- package/scripts/room-registry +767 -0
- package/scripts/rs-discovery-engine.cjs +725 -0
- package/scripts/rs-engine.py +2073 -0
- package/scripts/rs-experts-command.cjs +300 -0
- package/scripts/rs-explain-command.cjs +323 -0
- package/scripts/rs-fetch-command.cjs +170 -0
- package/scripts/rs-thesis-command.cjs +203 -0
- package/scripts/rs-vector-bridge.cjs +410 -0
- package/scripts/run-harness.cjs +890 -0
- package/scripts/scout-cadence-guard.cjs +323 -0
- package/scripts/scout-cadence-runner.cjs +509 -0
- package/scripts/scout-telemetry-aggregator.cjs +268 -0
- package/scripts/sealed-walker.py +96 -0
- package/scripts/seed-brain-commands.cjs +324 -0
- package/scripts/self-update +105 -0
- package/scripts/sentinel-deadline-monitor +241 -0
- package/scripts/sentinel-health-check +198 -0
- package/scripts/sentinel-snapshot +42 -0
- package/scripts/serve-dashboard +103 -0
- package/scripts/serve-dashboard-live +932 -0
- package/scripts/serve-presentation +97 -0
- package/scripts/serve-wiki +90 -0
- package/scripts/session-end-presence.cjs +79 -0
- package/scripts/session-start +1942 -0
- package/scripts/sessionstart-coordinator.cjs +249 -0
- package/scripts/sessionstart-npm-reconcile.cjs +111 -0
- package/scripts/sessionstart-post-update-preflight.cjs +303 -0
- package/scripts/sessionstart-reference-now-seed.cjs +137 -0
- package/scripts/setup-hooks.sh +112 -0
- package/scripts/skillopt-codereview.cjs +830 -0
- package/scripts/skillopt-eval.cjs +519 -0
- package/scripts/skillopt-funnel.cjs +1076 -0
- package/scripts/skillopt-genqueries.cjs +571 -0
- package/scripts/skillopt-inventory.cjs +319 -0
- package/scripts/skillopt-merge.cjs +656 -0
- package/scripts/skillopt-triggerloop.cjs +1126 -0
- package/scripts/soft-alias-runner.cjs +116 -0
- package/scripts/stamp-artifact-write.cjs +276 -0
- package/scripts/stamp-firing-block.cjs +325 -0
- package/scripts/state-write.cjs +97 -0
- package/scripts/statusline-fallback-echo.cjs +297 -0
- package/scripts/statusline-mos +116 -0
- package/scripts/statusline-mos-dispatch +127 -0
- package/scripts/suggest-next-command.cjs +416 -0
- package/scripts/sweep-skill-descriptions.cjs +263 -0
- package/scripts/sync-rooms-brain +438 -0
- package/scripts/sync-rooms-graph +264 -0
- package/scripts/telemetry-command-invocation.cjs +120 -0
- package/scripts/test-doctor-recovery.cjs +242 -0
- package/scripts/test-fresh-install.md +140 -0
- package/scripts/track-analytics +156 -0
- package/scripts/transcribe-audio +148 -0
- package/scripts/transcript-ingest.cjs +225 -0
- package/scripts/update-icm-index +153 -0
- package/scripts/v182-brain-optimize.cypher +1191 -0
- package/scripts/validate-model-profiles +93 -0
- package/scripts/vault-content-reformatter.cjs +581 -0
- package/scripts/vault-export-orchestrator.cjs +400 -0
- package/scripts/vault-footer-injector.cjs +315 -0
- package/scripts/vault-import.cjs +839 -0
- package/scripts/vault-integration-test.cjs +318 -0
- package/scripts/vault-regenerate-all.cjs +216 -0
- package/scripts/vault-regenerate-all.test.cjs +138 -0
- package/scripts/vault-rules-generator.cjs +220 -0
- package/scripts/vault-section-minto-generator.cjs +1642 -0
- package/scripts/vault-section-minto-generator.integration.test.cjs +576 -0
- package/scripts/vault-section-minto-generator.test.cjs +291 -0
- package/scripts/vault-section-state-generator.cjs +385 -0
- package/scripts/vault-welcome-generator.cjs +403 -0
- package/scripts/vault-wikilink-injector.cjs +449 -0
- package/scripts/verify-phase-132.cjs +338 -0
- package/scripts/verify-release +744 -0
- package/scripts/whitespace-command.cjs +831 -0
- package/scripts/whitespace-to-brain.cjs +383 -0
- package/scripts/whitespace-to-graph.cjs +220 -0
- package/scripts/wikilink-batch.cjs +102 -0
- package/scripts/wikilink-file.cjs +139 -0
- package/scripts/write-bridge-artifacts.cjs +140 -0
- package/scripts/write-scope-check +12 -0
- package/scripts/write-scope-check.cjs +461 -0
- package/scripts/write-whitespace-sections.cjs +483 -0
- package/settings.json +7 -0
- package/skills/act/SKILL.md +523 -0
- package/skills/admin/SKILL.md +437 -0
- package/skills/agentshield/SKILL.md +50 -0
- package/skills/analyze-needs/SKILL.md +74 -0
- package/skills/analyze-systems/SKILL.md +69 -0
- package/skills/analyze-timing/SKILL.md +94 -0
- package/skills/auto-explore/SKILL.md +84 -0
- package/skills/beautiful-question/SKILL.md +72 -0
- package/skills/bono/SKILL.md +146 -0
- package/skills/brain-connector/SKILL.md +206 -0
- package/skills/brain-derive/SKILL.md +140 -0
- package/skills/build-knowledge/SKILL.md +118 -0
- package/skills/build-thesis/SKILL.md +90 -0
- package/skills/causal/SKILL.md +265 -0
- package/skills/challenge-assumptions/SKILL.md +74 -0
- package/skills/client-discovery-interview/SKILL.md +94 -0
- package/skills/client-discovery-interview/discovery-scaffold.json +41 -0
- package/skills/client-discovery-interview/question-bank.md +149 -0
- package/skills/compare-ventures/SKILL.md +113 -0
- package/skills/context-engine/SKILL.md +169 -0
- package/skills/conversation-mode/SKILL.md +189 -0
- package/skills/correct-reference-now/SKILL.md +86 -0
- package/skills/dashboard/SKILL.md +142 -0
- package/skills/deck/SKILL.md +113 -0
- package/skills/deep-grade/SKILL.md +210 -0
- package/skills/diagnose/SKILL.md +128 -0
- package/skills/diagnostics/SKILL.md +193 -0
- package/skills/dial-memory-refresh/SKILL.md +116 -0
- package/skills/diffusion/SKILL.md +125 -0
- package/skills/discover/SKILL.md +216 -0
- package/skills/doctor/SKILL.md +269 -0
- package/skills/dogfood-flush/SKILL.md +133 -0
- package/skills/dominant-designs/SKILL.md +72 -0
- package/skills/eureka/SKILL.md +313 -0
- package/skills/explain-decision/SKILL.md +138 -0
- package/skills/explore-domains/SKILL.md +74 -0
- package/skills/explore-futures/SKILL.md +64 -0
- package/skills/explore-opportunity/SKILL.md +168 -0
- package/skills/explore-trends/SKILL.md +74 -0
- package/skills/export/SKILL.md +126 -0
- package/skills/feynman-timeline-refresh/SKILL.md +105 -0
- package/skills/file-meeting/SKILL.md +1190 -0
- package/skills/find-analogies/SKILL.md +360 -0
- package/skills/find-bottlenecks/SKILL.md +104 -0
- package/skills/find-connections/SKILL.md +108 -0
- package/skills/funding/SKILL.md +110 -0
- package/skills/futures/SKILL.md +124 -0
- package/skills/grade/SKILL.md +252 -0
- package/skills/grade-grant/SKILL.md +293 -0
- package/skills/graph/SKILL.md +216 -0
- package/skills/hat-briefing/SKILL.md +160 -0
- package/skills/heal/SKILL.md +69 -0
- package/skills/help/SKILL.md +172 -0
- package/skills/hmi-status/SKILL.md +73 -0
- package/skills/ignite/SKILL.md +225 -0
- package/skills/ingest-methodology/SKILL.md +125 -0
- package/skills/intel-pipeline/SKILL.md +128 -0
- package/skills/intelligence-orchestrator/SKILL.md +262 -0
- package/skills/jtbd/SKILL.md +261 -0
- package/skills/larry-personality/SKILL.md +570 -0
- package/skills/larry-personality/framework-chains.md +92 -0
- package/skills/larry-personality/mode-engine.md +185 -0
- package/skills/leadership/SKILL.md +109 -0
- package/skills/lean-canvas/SKILL.md +70 -0
- package/skills/macro-trends/SKILL.md +84 -0
- package/skills/map-unknowns/SKILL.md +72 -0
- package/skills/memory/SKILL.md +212 -0
- package/skills/memory-cortex-reach/SKILL.md +80 -0
- package/skills/models/SKILL.md +197 -0
- package/skills/mos/SKILL.md +160 -0
- package/skills/mos-deck-engine/SKILL.md +329 -0
- package/skills/mos-reason/SKILL.md +484 -0
- package/skills/mullins/SKILL.md +151 -0
- package/skills/mullins-scaffold/SKILL.md +132 -0
- package/skills/mullins-scaffold/scaffold.json +223 -0
- package/skills/mva-brief/SKILL.md +87 -0
- package/skills/mva-option/SKILL.md +120 -0
- package/skills/mva-pipeline/SKILL.md +158 -0
- package/skills/mva-report/SKILL.md +79 -0
- package/skills/new-project/SKILL.md +629 -0
- package/skills/new-surface/SKILL.md +112 -0
- package/skills/onboard/SKILL.md +485 -0
- package/skills/operator/SKILL.md +167 -0
- package/skills/opportunities/SKILL.md +171 -0
- package/skills/organize/SKILL.md +69 -0
- package/skills/persona/SKILL.md +272 -0
- package/skills/pipeline/SKILL.md +164 -0
- package/skills/present/SKILL.md +123 -0
- package/skills/publish/SKILL.md +224 -0
- package/skills/pws-brain/SKILL.md +152 -0
- package/skills/pws-methodology/SKILL.md +92 -0
- package/skills/qualify-opportunity/SKILL.md +111 -0
- package/skills/query/SKILL.md +68 -0
- package/skills/radar/SKILL.md +106 -0
- package/skills/reanalyze/SKILL.md +122 -0
- package/skills/research/SKILL.md +462 -0
- package/skills/room/SKILL.md +381 -0
- package/skills/room-passive/SKILL.md +174 -0
- package/skills/room-proactive/SKILL.md +344 -0
- package/skills/rooms/SKILL.md +678 -0
- package/skills/root-cause/SKILL.md +73 -0
- package/skills/rs-experts/SKILL.md +151 -0
- package/skills/rs-explain/SKILL.md +130 -0
- package/skills/rs-fetch/SKILL.md +115 -0
- package/skills/rs-thesis/SKILL.md +129 -0
- package/skills/scenario-plan/SKILL.md +76 -0
- package/skills/scheduled-tasks/SKILL.md +301 -0
- package/skills/score-innovation/SKILL.md +74 -0
- package/skills/scout/SKILL.md +370 -0
- package/skills/setup/SKILL.md +654 -0
- package/skills/show/SKILL.md +68 -0
- package/skills/skill/SKILL.md +104 -0
- package/skills/snapshot/SKILL.md +178 -0
- package/skills/speakers/SKILL.md +116 -0
- package/skills/splash/SKILL.md +54 -0
- package/skills/stance/SKILL.md +89 -0
- package/skills/status/SKILL.md +107 -0
- package/skills/structure-argument/SKILL.md +78 -0
- package/skills/suggest-next/SKILL.md +137 -0
- package/skills/systems-thinking/SKILL.md +220 -0
- package/skills/think-hats/SKILL.md +82 -0
- package/skills/trending-to-absurd/SKILL.md +100 -0
- package/skills/ui-system/SKILL.md +474 -0
- package/skills/ui-system/design-system/M-OS-DESIGN-SYSTEM.md +273 -0
- package/skills/ui-system/design-system/SPEC.md +72 -0
- package/skills/ui-system/design-system/image-prompt-style.md +29 -0
- package/skills/ui-system/design-system/mos-design-system.css +240 -0
- package/skills/ui-system/rules/design-system.md +60 -0
- package/skills/ui-system/rules/dual-palette.md +156 -0
- package/skills/ui-system/rules/glyph-disambiguation.md +171 -0
- package/skills/ui-system/rules/shape-f-zero-and-six.md +169 -0
- package/skills/update/SKILL.md +254 -0
- package/skills/user-needs/SKILL.md +73 -0
- package/skills/validate/SKILL.md +73 -0
- package/skills/value-proposition/SKILL.md +141 -0
- package/skills/vault/SKILL.md +326 -0
- package/skills/visualize/SKILL.md +69 -0
- package/skills/whitespace/SKILL.md +539 -0
- package/skills/wiki/SKILL.md +94 -0
- package/templates/_base.html +20 -0
- package/templates/chat-panel.html +205 -0
- package/templates/constellation-chat-hooks.js +89 -0
- package/templates/constellation.html +1272 -0
- package/templates/destijl-base.css +268 -0
- package/templates/discovery/discovery-brief-template.md +97 -0
- package/templates/due-diligence.html +49 -0
- package/templates/executive-summary.html +40 -0
- package/templates/icm/CLAUDE.md +31 -0
- package/templates/icm/GROUP-CLAUDE.md +33 -0
- package/templates/icm/INDEX.md +26 -0
- package/templates/import/stage-contracts/01-ingest.md +34 -0
- package/templates/import/stage-contracts/02-classify.md +48 -0
- package/templates/import/stage-contracts/03-route.md +42 -0
- package/templates/import/stage-contracts/04-enrich.md +40 -0
- package/templates/investment-thesis.html +25 -0
- package/templates/meeting-report.html +361 -0
- package/templates/presentation/dashboard.html +1150 -0
- package/templates/presentation/deck.html +540 -0
- package/templates/presentation/diagrams.html +437 -0
- package/templates/presentation/graph.html +391 -0
- package/templates/presentation/insights.html +548 -0
- package/templates/presentation/wiki.html +533 -0
- package/templates/profile.html +136 -0
- package/templates/room-context/last-session.md +56 -0
- package/templates/room-context/methodology-history.md +28 -0
- package/templates/room-context/rejection-log.md +25 -0
- package/templates/room-context/weekly-digest.md +54 -0
- package/templates/room-skeleton/MINTO.md.tmpl +19 -0
- package/templates/room-skeleton/ROOM.md.identity.tmpl +13 -0
- package/templates/room-skeleton/ROOM.md.section.tmpl +33 -0
- package/templates/room-skeleton/STATE.md.tmpl +33 -0
- package/templates/room-skeleton/USER.md.tmpl +23 -0
- package/templates/room-skeleton/references/.gitkeep +0 -0
- package/templates/room-skeleton/references/SECTION-SCHEMA.md +213 -0
- package/templates/room-skeleton/references/SUB-SCHEMAS.md +91 -0
- package/templates/room-skeleton/section-contracts/.gitkeep +0 -0
- package/templates/room-skeleton/section-contracts/business-model.md +32 -0
- package/templates/room-skeleton/section-contracts/competitive-analysis.md +33 -0
- package/templates/room-skeleton/section-contracts/financial-model.md +30 -0
- package/templates/room-skeleton/section-contracts/funding.md +41 -0
- package/templates/room-skeleton/section-contracts/legal-ip.md +30 -0
- package/templates/room-skeleton/section-contracts/market-analysis.md +32 -0
- package/templates/room-skeleton/section-contracts/opportunity-bank.md +39 -0
- package/templates/room-skeleton/section-contracts/problem-definition.md +32 -0
- package/templates/room-skeleton/section-contracts/solution-design.md +36 -0
- package/templates/room-skeleton/section-contracts/strategy.md +35 -0
- package/templates/room-skeleton/section-contracts/team-execution.md +36 -0
- package/templates/shared.css +427 -0
- package/templates/showcase/blueprint.html +432 -0
- package/templates/showcase/library.html +571 -0
- package/templates/showcase/narrative.html +361 -0
- package/templates/showcase/overview.html +468 -0
- package/templates/showcase/synthesis.html +473 -0
- package/templates/signature-footer.html +34 -0
|
@@ -0,0 +1,1601 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* Quick 260903-ljj -- scripts/check-tool-honesty.cjs
|
|
6
|
+
*
|
|
7
|
+
* A LOCAL static heuristic that scans every MCP tool registration and every
|
|
8
|
+
* command branch on the MindrianOS MCP surface (lib/mcp/tool-router.cjs,
|
|
9
|
+
* lib/mcp/tools/*.cjs, lib/mcp/contract-version.cjs) for a description-vs-
|
|
10
|
+
* behavior mismatch: a tool description that makes a first-person "does X"
|
|
11
|
+
* persistence claim over a handler branch that reaches no write primitive.
|
|
12
|
+
*
|
|
13
|
+
* ORIGIN. RCA .planning/debug/meeting-file-meeting-false-success.md found
|
|
14
|
+
* that `meeting` `file-meeting` returned a confident, no-error, filing-shaped
|
|
15
|
+
* response while its handler contained no write call of any kind. That RCA's
|
|
16
|
+
* own Non-Code Follow-ups section names the sweep this script performs: "a
|
|
17
|
+
* broader sweep of every MCP tool in this server whose description makes a
|
|
18
|
+
* first-person 'does X' claim, checked against whether the code actually
|
|
19
|
+
* performs X -- file-meeting is unlikely to be the only instance." The
|
|
20
|
+
* `meeting` tool itself was fixed (quick 260903-kwl) and is the load-bearing
|
|
21
|
+
* NEGATION_REGRESSION fixture this script must never flag again.
|
|
22
|
+
*
|
|
23
|
+
* PRECEDENT (Canon Part 7, reuse before build). CLI/output contract follows
|
|
24
|
+
* scripts/check-shape-declaration.cjs (the closer match under this plan's
|
|
25
|
+
* C-03 decision: advisory-on-introduction, --check WARNs and exits 0 with
|
|
26
|
+
* every violation enumerated, --strict restores hard-fail). Module shape
|
|
27
|
+
* (pure programmatic scan API, never calls process.exit, plus a thin CLI
|
|
28
|
+
* behind require.main === module) and self-allowlisting discipline
|
|
29
|
+
* (ALLOWED_UNVERIFIED, shipped EMPTY) borrow from scripts/check-substrate.cjs.
|
|
30
|
+
*
|
|
31
|
+
* SCOPE GUARD. This script builds and runs the detector. It does NOT fix any
|
|
32
|
+
* finding, and it does NOT harden the gate to blocking -- both are deliberate
|
|
33
|
+
* downstream work (see the plan's threat register T-LJJ-02).
|
|
34
|
+
*
|
|
35
|
+
* Canon Part 8 (Graph Boundary): node:fs and node:path ONLY. Zero network,
|
|
36
|
+
* zero Brain calls. The only `require()` calls this script itself performs
|
|
37
|
+
* against repo modules are of navigation.cjs / navigation/edges.cjs /
|
|
38
|
+
* node-insert.cjs (to enumerate their exported write-primitive names) plus,
|
|
39
|
+
* at scan time, whatever repo-local module a scanned branch's own
|
|
40
|
+
* require('...') statement names (read as TEXT, never evaluated -- this
|
|
41
|
+
* script never requires an MCP tool file itself).
|
|
42
|
+
*
|
|
43
|
+
* ARCHITECTURE (six named stages, mirroring the plan's own breakdown):
|
|
44
|
+
* A. splitTopLevelArgs / maskNonCode / scanBalanced -- a hand-rolled,
|
|
45
|
+
* brace-and-string-aware forward scanner (no JS parser dependency).
|
|
46
|
+
* B. extractCommandVocabulary -- resolves z.enum(IDENT) / z.enum([...]) /
|
|
47
|
+
* z.enum([...A, ...B]) against module-level `const IDENT = [...]`
|
|
48
|
+
* arrays. A schema with no `command` key is single-purpose: vocabulary
|
|
49
|
+
* is the synthetic name '(default)'.
|
|
50
|
+
* C. splitBranches -- locates case/if branch spans inside a handler body.
|
|
51
|
+
* A branch's effective text is its own span concatenated with the
|
|
52
|
+
* shared body (the code outside every branch), because a generic
|
|
53
|
+
* fall-through handler performs its work outside any branch. Fall-
|
|
54
|
+
* through case labels (`case 'a': case 'b': { ... }`) share the
|
|
55
|
+
* following non-empty case's body -- a literal "next label" cut would
|
|
56
|
+
* wrongly starve the earlier label of its real code.
|
|
57
|
+
* D. resolveReachability -- depth 0 (does the effective text match a write
|
|
58
|
+
* primitive) then depth 1 (one hop into a called function's own body,
|
|
59
|
+
* never deeper). UNKNOWN only fires for a genuinely unresolvable
|
|
60
|
+
* repo-local callee -- never promoted to HIGH RISK.
|
|
61
|
+
* E. extractClaims -- sentence-splits the description, classifies STRONG
|
|
62
|
+
* vs WEAK persistence verbs, and applies the negation guard: a global
|
|
63
|
+
* disclaimer sentence cancels every claim for the tool.
|
|
64
|
+
* F. classifyBranch -- the claim x reachability matrix, with an in-band
|
|
65
|
+
* noWriteBanner(/ NO_WRITE_MARKER check that always wins.
|
|
66
|
+
*
|
|
67
|
+
* KNOWN BOUNDARIES (phase 276-06, 276-RESEARCH.md "Detector Boundaries").
|
|
68
|
+
* Six named boundaries this detector does not (fully) close, each stated
|
|
69
|
+
* plainly rather than left to be discovered by a false result:
|
|
70
|
+
*
|
|
71
|
+
* B-1 Argument-gated writes (FALSE NEGATIVE). A write inside a guard on an
|
|
72
|
+
* optional parameter counts as reachable even when no caller supplies
|
|
73
|
+
* it. Example: lib/mcp/tools/dual-path.cjs:52 calls
|
|
74
|
+
* extractShallow(text, sessionId) with two arguments while
|
|
75
|
+
* lib/core/shallow-doc-parser.cjs:191 gates its navigation.setFocus
|
|
76
|
+
* write behind `if (opts && opts.db)`. Not closed by this phase.
|
|
77
|
+
* B-2 Barrel re-exports (FALSE UNKNOWN). lib/core/navigation.cjs is a
|
|
78
|
+
* facade of `NAME: mod.NAME` assignments, so locateFunctionBody finds
|
|
79
|
+
* no local definition and the branch reports UNKNOWN. Systemic,
|
|
80
|
+
* because navigation.cjs is the mandated Canon Part 9 chokepoint.
|
|
81
|
+
* Plan 276-07 is the owner of the one-level re-export follow.
|
|
82
|
+
* B-3 Subprocess-mediated writes (FALSE NEGATIVE). A write performed by a
|
|
83
|
+
* spawned script is invisible. Example: orchestration.rooms-open
|
|
84
|
+
* writes through a spawned room-registry.cjs. ACCEPTED as a
|
|
85
|
+
* documented boundary: a blanket "any spawn counts as a write" rule
|
|
86
|
+
* creates the opposite failure (false positives on every spawn).
|
|
87
|
+
* B-4 Dispatch-shape coverage (FALSE NEGATIVE, half closed phase 276-07).
|
|
88
|
+
* splitBranches recognizes top-level `switch (command)`, top-level
|
|
89
|
+
* `if (command === 'x')`, AND (phase 276-07) top-level
|
|
90
|
+
* `ARRAY.includes(command)` where ARRAY is a locally-defined array
|
|
91
|
+
* literal of string literals resolvable via the same
|
|
92
|
+
* resolveIdentifierArray helper extractCommandVocabulary already
|
|
93
|
+
* uses -- e.g. lib/mcp/tool-router.cjs:1246's
|
|
94
|
+
* `EUREKA_COMPUTE_COMMANDS.includes(command)`. It does NOT recognize
|
|
95
|
+
* `command.startsWith(prefix)`, and that half stays a DOCUMENTED
|
|
96
|
+
* boundary, not a defect: a prefix maps to many commands and a
|
|
97
|
+
* prefix-dispatched tool is intentionally undifferentiated, so there
|
|
98
|
+
* is no single finite command set to resolve statically the way an
|
|
99
|
+
* array literal has one.
|
|
100
|
+
* B-5 Write-primitive semantics (conceptual, not fully tractable). "A
|
|
101
|
+
* write primitive is reachable" does not mean "the write the
|
|
102
|
+
* description promises happens." Example: `analysis` classifies OK
|
|
103
|
+
* for all its commands because pipelineState.recordStep writes a
|
|
104
|
+
* bookkeeping file, not the analysis output the description implies.
|
|
105
|
+
* Consequence stated plainly: an OK verdict means no detectable
|
|
106
|
+
* mismatch, NEVER a positive proof of honesty -- no summary anywhere
|
|
107
|
+
* may present a clean OK count as a clean surface.
|
|
108
|
+
* B-6 Parameter describe strings are never scanned (FALSE NEGATIVE, NEW
|
|
109
|
+
* in phase 276). scanAll reads only the second positional argument to
|
|
110
|
+
* server.tool(, so a claim made inside a zod .describe() string is
|
|
111
|
+
* invisible to the detector. Discovered while tracing graph_write's
|
|
112
|
+
* read_version describe string: lib/mcp/tools/graph.cjs:226 asserts
|
|
113
|
+
* "a lost update is rejected as a conflict instead of silently
|
|
114
|
+
* clobbering" while reconcile-guard.cjs:77-85 fails open on a missing
|
|
115
|
+
* node. Not closed by this phase; the CAS fail-open disclosure is
|
|
116
|
+
* plan 276-11's work.
|
|
117
|
+
*
|
|
118
|
+
* No em-dashes. CJS only. process.argv switch-case routing.
|
|
119
|
+
*/
|
|
120
|
+
|
|
121
|
+
const fs = require('node:fs');
|
|
122
|
+
const path = require('node:path');
|
|
123
|
+
|
|
124
|
+
const REPO_ROOT = path.resolve(__dirname, '..');
|
|
125
|
+
|
|
126
|
+
// ---------------------------------------------------------------------------
|
|
127
|
+
// ALLOWED_UNVERIFIED -- self-allowlist, ships EMPTY (mirrors
|
|
128
|
+
// check-substrate.cjs's ALLOWED_DIRECT_IMPORT discipline). An entry is added
|
|
129
|
+
// ONLY after a human has triaged a HIGH RISK finding and recorded why the
|
|
130
|
+
// mismatch is acceptable. Suppressing a finding before triage defeats the
|
|
131
|
+
// entire purpose of this script -- never pre-populate this array.
|
|
132
|
+
//
|
|
133
|
+
// ENTRY CONTRACT (phase 276-06, documented here at the declaration site
|
|
134
|
+
// rather than left inferable from the consumption site alone). Each entry
|
|
135
|
+
// is a plain object carrying exactly four required fields:
|
|
136
|
+
// tool - the tool name, matched against a row's `tool` field.
|
|
137
|
+
// command - the command/branch name (or '(default)'), matched against a
|
|
138
|
+
// row's `command` field.
|
|
139
|
+
// reason - a human-written explanation of why this specific HIGH RISK
|
|
140
|
+
// finding is a triaged false positive, not a real defect.
|
|
141
|
+
// triaged - who/when the triage happened (a short string; this script
|
|
142
|
+
// does not enforce a format on it beyond presence).
|
|
143
|
+
//
|
|
144
|
+
// MEMBERSHIP RULE. An entry is admissible ONLY for a finding proven to be a
|
|
145
|
+
// false positive that the detector genuinely cannot be made to stop
|
|
146
|
+
// producing. A proven false positive is normally a DETECTOR FIX, not an
|
|
147
|
+
// allowlist entry -- adding an entry here should be the exception, made
|
|
148
|
+
// only when fixing the detector itself is not tractable (see the KNOWN
|
|
149
|
+
// BOUNDARIES block above for the boundaries that fall into this category,
|
|
150
|
+
// e.g. B-3's subprocess-mediated writes).
|
|
151
|
+
//
|
|
152
|
+
// TWO MECHANICAL FACTS a contributor must know before touching this array:
|
|
153
|
+
// 1. Suppression applies to HIGH_RISK rows ONLY. A matching entry
|
|
154
|
+
// rewrites that one row's verdict to OK (see the consumption loop
|
|
155
|
+
// after scanAll's row-building pass, below).
|
|
156
|
+
// 2. MEDIUM and UNKNOWN verdicts are NEVER suppressible by this
|
|
157
|
+
// mechanism, by design, per D-276-2. There is no code path in this
|
|
158
|
+
// file that lets an ALLOWED_UNVERIFIED entry touch a MEDIUM or
|
|
159
|
+
// UNKNOWN row; only a HIGH_RISK row's verdict is ever rewritten.
|
|
160
|
+
// ---------------------------------------------------------------------------
|
|
161
|
+
const ALLOWED_UNVERIFIED = [];
|
|
162
|
+
|
|
163
|
+
// ---------------------------------------------------------------------------
|
|
164
|
+
// JS keyword / pseudo-callee exclusion set for the bare-fn( callee scan in
|
|
165
|
+
// Stage D. Prevents `if (`, `switch (`, `catch (` etc. from being treated as
|
|
166
|
+
// unresolvable callees.
|
|
167
|
+
// ---------------------------------------------------------------------------
|
|
168
|
+
const JS_KEYWORDS = new Set([
|
|
169
|
+
'if', 'for', 'while', 'switch', 'catch', 'function', 'return', 'typeof',
|
|
170
|
+
'new', 'do', 'else', 'async', 'await', 'yield', 'delete', 'void', 'in',
|
|
171
|
+
'of', 'instanceof', 'case', 'default', 'try', 'finally', 'throw', 'const',
|
|
172
|
+
'let', 'var', 'class', 'extends', 'super', 'this', 'null', 'true', 'false',
|
|
173
|
+
'undefined',
|
|
174
|
+
]);
|
|
175
|
+
|
|
176
|
+
// ---------------------------------------------------------------------------
|
|
177
|
+
// The in-band no-write disclosure signal (quick 260903-kwl). A branch whose
|
|
178
|
+
// text carries either of these classifies OK regardless of any claim.
|
|
179
|
+
// ---------------------------------------------------------------------------
|
|
180
|
+
const NO_WRITE_MARKER_LITERAL = '**filed: false**';
|
|
181
|
+
const NO_WRITE_BANNER_CALL_RE = /noWriteBanner\s*\(/;
|
|
182
|
+
|
|
183
|
+
// ---------------------------------------------------------------------------
|
|
184
|
+
// Stage A -- maskNonCode / scanBalanced / splitTopLevelArgs / skipQuotedForward
|
|
185
|
+
//
|
|
186
|
+
// maskNonCode(text) returns a SAME-LENGTH string where every string/template
|
|
187
|
+
// literal's content (including its delimiters) and every comment are
|
|
188
|
+
// replaced with spaces, so structural scanning (brace matching, keyword
|
|
189
|
+
// search) can run on it with simple regexes, immune to a description string
|
|
190
|
+
// that happens to contain a brace or the word "case". Content is always
|
|
191
|
+
// extracted from the ORIGINAL text at the same offsets the masked text's
|
|
192
|
+
// structure locates -- masking never changes length or line breaks.
|
|
193
|
+
// ---------------------------------------------------------------------------
|
|
194
|
+
// Regex-literal detection (Task 3 spot-check finding, fixed per Rule 1).
|
|
195
|
+
// `/` is ambiguous in JS: it opens a regex literal OR is the division
|
|
196
|
+
// operator, decided entirely by what token precedes it. Getting this wrong
|
|
197
|
+
// is not cosmetic -- a regex literal containing a quote character as its
|
|
198
|
+
// PATTERN (e.g. `.replace(/"/g, '\\"')`, a real line in lib/core/
|
|
199
|
+
// user-md-ops.cjs) was being misread as a STRING-LITERAL OPEN QUOTE by the
|
|
200
|
+
// naive quote-scanner, which then hunted forward for the next stray `"`
|
|
201
|
+
// ANYWHERE in the rest of the file and masked everything in between --
|
|
202
|
+
// silently blanking every function definition after that point for the
|
|
203
|
+
// remainder of the file. This surfaced as identity_write.(default)
|
|
204
|
+
// spuriously classifying UNKNOWN (writeUserMdAtomic's own body, containing
|
|
205
|
+
// the real fs.renameSync write, had been masked to nothing). The heuristic
|
|
206
|
+
// below (last significant token before `/` decides regex-vs-division) is
|
|
207
|
+
// the same one V8 and every JS tokenizer uses.
|
|
208
|
+
const REGEX_PRECEDING_KEYWORDS = new Set([
|
|
209
|
+
'return', 'typeof', 'instanceof', 'in', 'of', 'new', 'delete', 'void',
|
|
210
|
+
'throw', 'case', 'yield', 'do', 'else',
|
|
211
|
+
]);
|
|
212
|
+
|
|
213
|
+
function looksLikeRegexStart(out, idx) {
|
|
214
|
+
let j = idx - 1;
|
|
215
|
+
while (j >= 0 && /\s/.test(out[j])) j -= 1;
|
|
216
|
+
if (j < 0) return true; // start of file/expression -- must be a regex
|
|
217
|
+
const prev = out[j];
|
|
218
|
+
if (/[\w$]/.test(prev)) {
|
|
219
|
+
let k = j;
|
|
220
|
+
while (k >= 0 && /[\w$]/.test(out[k])) k -= 1;
|
|
221
|
+
const word = out.slice(k + 1, j + 1).join('');
|
|
222
|
+
return REGEX_PRECEDING_KEYWORDS.has(word);
|
|
223
|
+
}
|
|
224
|
+
if (prev === ')' || prev === ']') return false; // division after a call/index
|
|
225
|
+
return true; // punctuation ( { , ; : = & | ! ? + - * % ^ ~ < > -- a regex can start here
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// skipRegexLiteral(text, i) -- text[i] is the opening '/'. Character-class
|
|
229
|
+
// aware (a `/` inside `[...]` does not close the regex), escape aware,
|
|
230
|
+
// consumes trailing flags. Bails at a raw newline (a regex literal cannot
|
|
231
|
+
// contain one -- malformed source, not this script's problem to fix).
|
|
232
|
+
function skipRegexLiteral(text, i) {
|
|
233
|
+
const n = text.length;
|
|
234
|
+
let j = i + 1;
|
|
235
|
+
let inClass = false;
|
|
236
|
+
while (j < n) {
|
|
237
|
+
const c = text[j];
|
|
238
|
+
if (c === '\\') { j += 2; continue; }
|
|
239
|
+
if (c === '\n') return j; // malformed -- stop masking here, do not consume the newline
|
|
240
|
+
if (c === '[') { inClass = true; j += 1; continue; }
|
|
241
|
+
if (c === ']') { inClass = false; j += 1; continue; }
|
|
242
|
+
if (c === '/' && !inClass) { j += 1; break; }
|
|
243
|
+
j += 1;
|
|
244
|
+
}
|
|
245
|
+
while (j < n && /[a-z]/i.test(text[j])) j += 1; // flags
|
|
246
|
+
return j;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function maskNonCode(text) {
|
|
250
|
+
const out = text.split('');
|
|
251
|
+
let i = 0;
|
|
252
|
+
const n = text.length;
|
|
253
|
+
while (i < n) {
|
|
254
|
+
const c = text[i];
|
|
255
|
+
if (c === '/' && text[i + 1] === '/') {
|
|
256
|
+
let j = i;
|
|
257
|
+
while (j < n && text[j] !== '\n') { out[j] = ' '; j += 1; }
|
|
258
|
+
i = j;
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
if (c === '/' && text[i + 1] === '*') {
|
|
262
|
+
const end = text.indexOf('*/', i + 2);
|
|
263
|
+
const stop = end === -1 ? n : end + 2;
|
|
264
|
+
for (let k = i; k < stop; k += 1) if (text[k] !== '\n') out[k] = ' ';
|
|
265
|
+
i = stop;
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
if (c === '/' && looksLikeRegexStart(out, i)) {
|
|
269
|
+
const stop = skipRegexLiteral(text, i);
|
|
270
|
+
for (let k = i; k < stop && k < n; k += 1) if (text[k] !== '\n') out[k] = ' ';
|
|
271
|
+
i = stop;
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
if (c === "'" || c === '"') {
|
|
275
|
+
let j = i + 1;
|
|
276
|
+
while (j < n) {
|
|
277
|
+
if (text[j] === '\\') { j += 2; continue; }
|
|
278
|
+
if (text[j] === c) { j += 1; break; }
|
|
279
|
+
j += 1;
|
|
280
|
+
}
|
|
281
|
+
for (let k = i; k < j && k < n; k += 1) if (text[k] !== '\n') out[k] = ' ';
|
|
282
|
+
i = j;
|
|
283
|
+
continue;
|
|
284
|
+
}
|
|
285
|
+
if (c === '`') {
|
|
286
|
+
let j = i + 1;
|
|
287
|
+
while (j < n) {
|
|
288
|
+
if (text[j] === '\\') { j += 2; continue; }
|
|
289
|
+
if (text[j] === '`') { j += 1; break; }
|
|
290
|
+
j += 1;
|
|
291
|
+
}
|
|
292
|
+
for (let k = i; k < j && k < n; k += 1) if (text[k] !== '\n') out[k] = ' ';
|
|
293
|
+
i = j;
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
i += 1;
|
|
297
|
+
}
|
|
298
|
+
return out.join('');
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// scanBalanced(maskedStr, startIdx) -- maskedStr[startIdx] must be one of
|
|
302
|
+
// ( { [ (string/comment content already blanked, so brace-matching on the
|
|
303
|
+
// masked text is immune to a brace embedded in a string). Returns the index
|
|
304
|
+
// of the matching close, or -1.
|
|
305
|
+
function scanBalanced(maskedStr, startIdx) {
|
|
306
|
+
const pairMap = { '(': ')', '{': '}', '[': ']' };
|
|
307
|
+
if (!pairMap[maskedStr[startIdx]]) return -1;
|
|
308
|
+
let depth = 0;
|
|
309
|
+
for (let i = startIdx; i < maskedStr.length; i += 1) {
|
|
310
|
+
const c = maskedStr[i];
|
|
311
|
+
if (c === '(' || c === '{' || c === '[') {
|
|
312
|
+
depth += 1;
|
|
313
|
+
} else if (c === ')' || c === '}' || c === ']') {
|
|
314
|
+
depth -= 1;
|
|
315
|
+
if (depth === 0) return i;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return -1;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// computeDepthArray(maskedStr) -- depths[i] is the bracket nesting depth
|
|
322
|
+
// BEFORE the character at i is processed. Lets any position's depth be
|
|
323
|
+
// looked up in O(1) once computed.
|
|
324
|
+
function computeDepthArray(maskedStr) {
|
|
325
|
+
const depths = new Array(maskedStr.length);
|
|
326
|
+
let depth = 0;
|
|
327
|
+
for (let i = 0; i < maskedStr.length; i += 1) {
|
|
328
|
+
depths[i] = depth;
|
|
329
|
+
const c = maskedStr[i];
|
|
330
|
+
if (c === '(' || c === '{' || c === '[') depth += 1;
|
|
331
|
+
else if (c === ')' || c === '}' || c === ']') depth -= 1;
|
|
332
|
+
}
|
|
333
|
+
return depths;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// skipQuotedForward(text, i, q) -- text[i] is the opening quote character q.
|
|
337
|
+
// Returns the index AFTER the matching unescaped closing quote.
|
|
338
|
+
function skipQuotedForward(text, i, q) {
|
|
339
|
+
let j = i + 1;
|
|
340
|
+
while (j < text.length) {
|
|
341
|
+
if (text[j] === '\\') { j += 2; continue; }
|
|
342
|
+
if (text[j] === q) return j + 1;
|
|
343
|
+
j += 1;
|
|
344
|
+
}
|
|
345
|
+
return text.length;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
function unescapeSimple(raw, quoteChar) {
|
|
349
|
+
return raw.replace(/\\(.)/g, (full, ch) => {
|
|
350
|
+
if (ch === 'n') return '\n';
|
|
351
|
+
if (ch === 't') return '\t';
|
|
352
|
+
if (ch === quoteChar) return quoteChar;
|
|
353
|
+
if (ch === '\\') return '\\';
|
|
354
|
+
return ch;
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// extractStringLiteralConcat(text) -- unwraps a string literal, joining any
|
|
359
|
+
// `+` concatenation of adjacent literals (single/double/backtick), ignoring
|
|
360
|
+
// comments and non-literal punctuation (+, whitespace) between them.
|
|
361
|
+
function extractStringLiteralConcat(text) {
|
|
362
|
+
let out = '';
|
|
363
|
+
let i = 0;
|
|
364
|
+
const n = text.length;
|
|
365
|
+
while (i < n) {
|
|
366
|
+
const c = text[i];
|
|
367
|
+
if (c === '/' && text[i + 1] === '/') {
|
|
368
|
+
const nl = text.indexOf('\n', i);
|
|
369
|
+
i = nl === -1 ? n : nl + 1;
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
if (c === '/' && text[i + 1] === '*') {
|
|
373
|
+
const end = text.indexOf('*/', i + 2);
|
|
374
|
+
i = end === -1 ? n : end + 2;
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
if (c === "'" || c === '"') {
|
|
378
|
+
const end = skipQuotedForward(text, i, c);
|
|
379
|
+
const raw = text.slice(i + 1, Math.max(i + 1, end - 1));
|
|
380
|
+
out += unescapeSimple(raw, c);
|
|
381
|
+
i = end;
|
|
382
|
+
continue;
|
|
383
|
+
}
|
|
384
|
+
if (c === '`') {
|
|
385
|
+
let j = i + 1;
|
|
386
|
+
while (j < n) {
|
|
387
|
+
if (text[j] === '\\') { j += 2; continue; }
|
|
388
|
+
if (text[j] === '`') { j += 1; break; }
|
|
389
|
+
j += 1;
|
|
390
|
+
}
|
|
391
|
+
out += text.slice(i + 1, Math.max(i + 1, j - 1));
|
|
392
|
+
i = j;
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
i += 1;
|
|
396
|
+
}
|
|
397
|
+
return out;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// splitTopLevelArgs(text) -- top-level comma split, brace/paren/bracket and
|
|
401
|
+
// string/comment aware (via an internal maskNonCode pass). Returns the raw
|
|
402
|
+
// ORIGINAL-text span of each argument, trimmed, empty entries dropped.
|
|
403
|
+
function splitTopLevelArgs(text) {
|
|
404
|
+
const masked = maskNonCode(text);
|
|
405
|
+
const args = [];
|
|
406
|
+
let depth = 0;
|
|
407
|
+
let start = 0;
|
|
408
|
+
for (let i = 0; i < masked.length; i += 1) {
|
|
409
|
+
const c = masked[i];
|
|
410
|
+
if (c === '(' || c === '{' || c === '[') {
|
|
411
|
+
depth += 1;
|
|
412
|
+
} else if (c === ')' || c === '}' || c === ']') {
|
|
413
|
+
depth -= 1;
|
|
414
|
+
} else if (c === ',' && depth === 0) {
|
|
415
|
+
args.push(text.slice(start, i));
|
|
416
|
+
start = i + 1;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
args.push(text.slice(start));
|
|
420
|
+
return args.map((s) => s.trim()).filter((s) => s.length > 0);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// ---------------------------------------------------------------------------
|
|
424
|
+
// resolveWritePrimitives() -- the run-time-derived write-primitive
|
|
425
|
+
// vocabulary. Requires navigation.cjs, navigation/edges.cjs and
|
|
426
|
+
// node-insert.cjs, takes every EXPORTED FUNCTION whose name matches the
|
|
427
|
+
// prefix set write / log / set / store / promote / confirm / insert at a
|
|
428
|
+
// camelCase word boundary, and unions that with a small fixed Node-builtin
|
|
429
|
+
// list this repo does not own (fs write primitives) plus the two SQLite
|
|
430
|
+
// execution forms '.run(' and '.exec('. Never hardcodes the resulting name
|
|
431
|
+
// list -- a future navigation writer is covered automatically because this
|
|
432
|
+
// enumerates module.exports at run time, every scan.
|
|
433
|
+
// ---------------------------------------------------------------------------
|
|
434
|
+
const WRITE_PRIMITIVE_PREFIXES = ['write', 'log', 'set', 'store', 'promote', 'confirm', 'insert'];
|
|
435
|
+
const FIXED_FS_PRIMITIVES = [
|
|
436
|
+
'writeFileSync', 'writeFile', 'appendFileSync', 'appendFile',
|
|
437
|
+
'mkdirSync', 'rmSync', 'rmdirSync', 'renameSync', 'unlinkSync',
|
|
438
|
+
'copyFileSync', 'cpSync', 'createWriteStream',
|
|
439
|
+
];
|
|
440
|
+
const SQLITE_DOT_FORMS = ['.run(', '.exec('];
|
|
441
|
+
|
|
442
|
+
function isCamelCasePrefixMatch(name, prefix) {
|
|
443
|
+
if (name.length <= prefix.length) return false;
|
|
444
|
+
if (name.slice(0, prefix.length) !== prefix) return false;
|
|
445
|
+
const nextChar = name[prefix.length];
|
|
446
|
+
return nextChar === nextChar.toUpperCase() && nextChar !== nextChar.toLowerCase();
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
function resolveWritePrimitives() {
|
|
450
|
+
const names = new Set(FIXED_FS_PRIMITIVES);
|
|
451
|
+
const sources = [
|
|
452
|
+
path.join(REPO_ROOT, 'lib', 'core', 'navigation.cjs'),
|
|
453
|
+
path.join(REPO_ROOT, 'lib', 'core', 'navigation', 'edges.cjs'),
|
|
454
|
+
path.join(REPO_ROOT, 'lib', 'core', 'node-insert.cjs'),
|
|
455
|
+
];
|
|
456
|
+
for (const src of sources) {
|
|
457
|
+
try {
|
|
458
|
+
// eslint-disable-next-line import/no-dynamic-require
|
|
459
|
+
const mod = require(src);
|
|
460
|
+
for (const key of Object.keys(mod)) {
|
|
461
|
+
if (typeof mod[key] !== 'function') continue;
|
|
462
|
+
for (const prefix of WRITE_PRIMITIVE_PREFIXES) {
|
|
463
|
+
if (isCamelCasePrefixMatch(key, prefix)) {
|
|
464
|
+
names.add(key);
|
|
465
|
+
break;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
} catch (_e) {
|
|
470
|
+
// Module unavailable at scan time -- degrade, never throw (Canon Part 8:
|
|
471
|
+
// this is a read-only static analyzer, not a runtime dependency of the
|
|
472
|
+
// modules it inspects).
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
const escaped = Array.from(names).map((nm) => nm.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
|
|
476
|
+
const combinedRe = escaped.length > 0 ? new RegExp('\\b(?:' + escaped.join('|') + ')\\s*\\(') : null;
|
|
477
|
+
return {
|
|
478
|
+
names,
|
|
479
|
+
dotForms: SQLITE_DOT_FORMS.slice(),
|
|
480
|
+
test(maskedText) {
|
|
481
|
+
if (combinedRe && combinedRe.test(maskedText)) return true;
|
|
482
|
+
for (const form of this.dotForms) {
|
|
483
|
+
if (maskedText.indexOf(form) !== -1) return true;
|
|
484
|
+
}
|
|
485
|
+
return false;
|
|
486
|
+
},
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// ---------------------------------------------------------------------------
|
|
491
|
+
// Stage B -- extractCommandVocabulary(schemaText, fileText)
|
|
492
|
+
// ---------------------------------------------------------------------------
|
|
493
|
+
function resolveIdentifierArray(ident, fileText, fileMasked) {
|
|
494
|
+
const escaped = ident.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
495
|
+
const re = new RegExp('\\bconst\\s+' + escaped + '\\s*=\\s*\\[');
|
|
496
|
+
const m = re.exec(fileMasked);
|
|
497
|
+
if (!m) return [];
|
|
498
|
+
const openIdx = fileMasked.indexOf('[', m.index);
|
|
499
|
+
if (openIdx === -1) return [];
|
|
500
|
+
const closeIdx = scanBalanced(fileMasked, openIdx);
|
|
501
|
+
if (closeIdx === -1) return [];
|
|
502
|
+
const arrText = fileText.slice(openIdx + 1, closeIdx);
|
|
503
|
+
const items = splitTopLevelArgs(arrText);
|
|
504
|
+
const out = [];
|
|
505
|
+
for (const item of items) {
|
|
506
|
+
const s = extractStringLiteralConcat(item);
|
|
507
|
+
if (s) out.push(s);
|
|
508
|
+
}
|
|
509
|
+
return out;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
function resolveCommandVocabulary(innerText, fileText, fileMasked) {
|
|
513
|
+
const trimmed = innerText.trim();
|
|
514
|
+
const maskedInner = maskNonCode(trimmed);
|
|
515
|
+
if (maskedInner.trim().startsWith('[')) {
|
|
516
|
+
const openIdx = maskedInner.indexOf('[');
|
|
517
|
+
const closeIdx = scanBalanced(maskedInner, openIdx);
|
|
518
|
+
const arrInner = trimmed.slice(openIdx + 1, closeIdx === -1 ? trimmed.length : closeIdx);
|
|
519
|
+
const items = splitTopLevelArgs(arrInner);
|
|
520
|
+
const out = [];
|
|
521
|
+
const seen = new Set();
|
|
522
|
+
for (const item of items) {
|
|
523
|
+
const it = item.trim();
|
|
524
|
+
if (it.startsWith('...')) {
|
|
525
|
+
const ident = it.slice(3).trim();
|
|
526
|
+
for (const c of resolveIdentifierArray(ident, fileText, fileMasked)) {
|
|
527
|
+
if (!seen.has(c)) { seen.add(c); out.push(c); }
|
|
528
|
+
}
|
|
529
|
+
} else {
|
|
530
|
+
const s = extractStringLiteralConcat(it);
|
|
531
|
+
if (s && !seen.has(s)) { seen.add(s); out.push(s); }
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
return out;
|
|
535
|
+
}
|
|
536
|
+
return resolveIdentifierArray(trimmed, fileText, fileMasked);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
function extractCommandVocabulary(schemaText, fileText, fileMasked) {
|
|
540
|
+
const masked = maskNonCode(schemaText);
|
|
541
|
+
const re = /command\s*:\s*z\.enum\s*\(/;
|
|
542
|
+
const m = re.exec(masked);
|
|
543
|
+
if (!m) return ['(default)'];
|
|
544
|
+
const parenIdx = masked.indexOf('(', m.index);
|
|
545
|
+
if (parenIdx === -1) return ['(default)'];
|
|
546
|
+
const closeParen = scanBalanced(masked, parenIdx);
|
|
547
|
+
if (closeParen === -1) return ['(default)'];
|
|
548
|
+
const inner = schemaText.slice(parenIdx + 1, closeParen);
|
|
549
|
+
const vocab = resolveCommandVocabulary(inner, fileText, fileMasked);
|
|
550
|
+
return vocab.length > 0 ? vocab : ['(default)'];
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
// ---------------------------------------------------------------------------
|
|
554
|
+
// findServerToolCalls(fileText) -- every `server.tool(` occurrence, brace-
|
|
555
|
+
// matched via the masked file text. Returns [{ innerText }].
|
|
556
|
+
// ---------------------------------------------------------------------------
|
|
557
|
+
function findServerToolCalls(fileText, fileMasked) {
|
|
558
|
+
const calls = [];
|
|
559
|
+
const re = /server\.tool\s*\(/g;
|
|
560
|
+
let m;
|
|
561
|
+
while ((m = re.exec(fileMasked)) !== null) {
|
|
562
|
+
const openParen = fileMasked.indexOf('(', m.index);
|
|
563
|
+
if (openParen === -1) continue;
|
|
564
|
+
const closeParen = scanBalanced(fileMasked, openParen);
|
|
565
|
+
if (closeParen === -1) continue;
|
|
566
|
+
calls.push({ innerText: fileText.slice(openParen + 1, closeParen) });
|
|
567
|
+
}
|
|
568
|
+
return calls;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// extractHandlerBody(handlerArgText) -- the 4th server.tool( argument is
|
|
572
|
+
// `async ({ ... }[, extra]) => { ... }`. Returns the text INSIDE the arrow
|
|
573
|
+
// function's block body, or null if the handler is not block-bodied
|
|
574
|
+
// (unexpected shape for this codebase -- degrade rather than guess).
|
|
575
|
+
function extractHandlerBody(handlerArgText) {
|
|
576
|
+
const masked = maskNonCode(handlerArgText);
|
|
577
|
+
const arrowIdx = masked.indexOf('=>');
|
|
578
|
+
if (arrowIdx === -1) return null;
|
|
579
|
+
let i = arrowIdx + 2;
|
|
580
|
+
while (i < masked.length && /\s/.test(masked[i])) i += 1;
|
|
581
|
+
if (masked[i] !== '{') return null;
|
|
582
|
+
const close = scanBalanced(masked, i);
|
|
583
|
+
if (close === -1) return null;
|
|
584
|
+
return handlerArgText.slice(i + 1, close);
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
// ---------------------------------------------------------------------------
|
|
588
|
+
// Stage C -- splitBranches(handlerBodyText, fileText, fileMasked)
|
|
589
|
+
// fileText/fileMasked are OPTIONAL (phase 276-07): they are only needed to
|
|
590
|
+
// resolve an `ARRAY.includes(command)` dispatch guard's array literal back
|
|
591
|
+
// to its member command names (B-4, half closed). A caller that omits them
|
|
592
|
+
// (e.g. a synthetic fixture string with no owning file) still gets the
|
|
593
|
+
// switch/if recognition unchanged; only the includes() half degrades.
|
|
594
|
+
// Returns { branchMap: { [command]: ownText }, sharedBodyText }.
|
|
595
|
+
// ---------------------------------------------------------------------------
|
|
596
|
+
function splitBranches(handlerBodyText, fileText, fileMasked) {
|
|
597
|
+
const masked = maskNonCode(handlerBodyText);
|
|
598
|
+
const depths = computeDepthArray(masked);
|
|
599
|
+
const consumed = [];
|
|
600
|
+
const branchMap = {};
|
|
601
|
+
|
|
602
|
+
// ---- switch (command) { case 'x': ... } ----
|
|
603
|
+
const switchRe = /\bswitch\s*\(\s*command\s*\)\s*\{/g;
|
|
604
|
+
let sm;
|
|
605
|
+
while ((sm = switchRe.exec(masked)) !== null) {
|
|
606
|
+
if (depths[sm.index] !== 0) continue; // only a top-level switch on command
|
|
607
|
+
const openBrace = masked.indexOf('{', sm.index);
|
|
608
|
+
if (openBrace === -1) continue;
|
|
609
|
+
const closeBrace = scanBalanced(masked, openBrace);
|
|
610
|
+
if (closeBrace === -1) continue;
|
|
611
|
+
const baseDepth = depths[openBrace] + 1;
|
|
612
|
+
|
|
613
|
+
const labelRe = /\bcase\s+|\bdefault\s*:/g;
|
|
614
|
+
labelRe.lastIndex = openBrace + 1;
|
|
615
|
+
const labels = [];
|
|
616
|
+
let lm;
|
|
617
|
+
while ((lm = labelRe.exec(masked)) !== null) {
|
|
618
|
+
if (lm.index >= closeBrace) break;
|
|
619
|
+
if (depths[lm.index] !== baseDepth) continue;
|
|
620
|
+
const isCase = /^case/.test(lm[0]);
|
|
621
|
+
if (isCase) {
|
|
622
|
+
// D-1 fix (phase 276-06): lm[0].length already swallowed the
|
|
623
|
+
// blanked-out quoted command value, because labelRe runs over
|
|
624
|
+
// masked text where every string literal (delimiters included) is
|
|
625
|
+
// replaced by spaces, so \bcase\s+ greedily matches straight
|
|
626
|
+
// through to the following colon. Anchor at lm.index + 4 (the
|
|
627
|
+
// literal length of the token "case") instead, then skip
|
|
628
|
+
// whitespace in the ORIGINAL handlerBodyText, not masked -- both
|
|
629
|
+
// halves are required, changing only one leaves idx still past the
|
|
630
|
+
// real quote character.
|
|
631
|
+
let idx = lm.index + 4;
|
|
632
|
+
while (idx < masked.length && /\s/.test(handlerBodyText[idx])) idx += 1;
|
|
633
|
+
const qc = handlerBodyText[idx];
|
|
634
|
+
if (qc !== "'" && qc !== '"' && qc !== '`') continue;
|
|
635
|
+
const endQ = skipQuotedForward(handlerBodyText, idx, qc);
|
|
636
|
+
const raw = handlerBodyText.slice(idx + 1, Math.max(idx + 1, endQ - 1));
|
|
637
|
+
const value = unescapeSimple(raw, qc);
|
|
638
|
+
let colonIdx = endQ;
|
|
639
|
+
while (colonIdx < masked.length && masked[colonIdx] !== ':') colonIdx += 1;
|
|
640
|
+
labels.push({ isDefault: false, command: value, labelStart: lm.index, bodyStart: colonIdx + 1 });
|
|
641
|
+
} else {
|
|
642
|
+
const colonIdx = lm.index + lm[0].length - 1;
|
|
643
|
+
labels.push({ isDefault: true, command: null, labelStart: lm.index, bodyStart: colonIdx + 1 });
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
labels.sort((a, b) => a.labelStart - b.labelStart);
|
|
647
|
+
for (let li = 0; li < labels.length; li += 1) {
|
|
648
|
+
const nextStart = li + 1 < labels.length ? labels[li + 1].labelStart : closeBrace;
|
|
649
|
+
labels[li].spanEnd = nextStart;
|
|
650
|
+
labels[li].ownRaw = handlerBodyText.slice(labels[li].bodyStart, nextStart);
|
|
651
|
+
}
|
|
652
|
+
// Fall-through grouping: a case label whose own span is empty (a bare
|
|
653
|
+
// `case 'a': case 'b': { ... }` fall-through) shares the body of the
|
|
654
|
+
// NEXT label that actually carries code. A literal "runs to the next
|
|
655
|
+
// case" cut would wrongly starve the earlier label's real behavior and
|
|
656
|
+
// manufacture a false HIGH RISK on ordinary JS fall-through syntax --
|
|
657
|
+
// this is Rule 1 (auto-fix bug). CORRECTION (phase 276-06): this
|
|
658
|
+
// comment previously claimed the grouping was "verified against real
|
|
659
|
+
// fall-through in this codebase (room_content's new-project/setup/
|
|
660
|
+
// update/help group)". That verification could not have happened as
|
|
661
|
+
// stated, because D-1 (the case-label regex running over masked text)
|
|
662
|
+
// made the switch path produce zero labels, so no fall-through group
|
|
663
|
+
// was ever exercised before this phase's fix. What is actually true
|
|
664
|
+
// after the D-1 fix: the grouping IS exercised by room_content's
|
|
665
|
+
// new-project/setup/update/help fall-through group, and it is verified
|
|
666
|
+
// by tests/test-276-tool-honesty-switch-branches.cjs as of phase 276.
|
|
667
|
+
// It was NOT verified before that test existed.
|
|
668
|
+
for (let li = 0; li < labels.length; li += 1) {
|
|
669
|
+
const lab = labels[li];
|
|
670
|
+
if (lab.isDefault) {
|
|
671
|
+
consumed.push([lab.bodyStart, lab.spanEnd]);
|
|
672
|
+
continue;
|
|
673
|
+
}
|
|
674
|
+
let body = lab.ownRaw;
|
|
675
|
+
let endIdx = lab.spanEnd;
|
|
676
|
+
let k = li;
|
|
677
|
+
while (body.trim() === '' && k + 1 < labels.length) {
|
|
678
|
+
k += 1;
|
|
679
|
+
body = labels[k].ownRaw;
|
|
680
|
+
endIdx = labels[k].spanEnd;
|
|
681
|
+
}
|
|
682
|
+
consumed.push([lab.bodyStart, endIdx]);
|
|
683
|
+
const existing = branchMap[lab.command] || '';
|
|
684
|
+
branchMap[lab.command] = existing + '\n' + body;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
// ---- if (command === 'x') / else if (command === 'x') { ... } ----
|
|
689
|
+
const ifRe = /(?:\belse\s+if|\bif)\s*\(/g;
|
|
690
|
+
let im;
|
|
691
|
+
while ((im = ifRe.exec(masked)) !== null) {
|
|
692
|
+
if (depths[im.index] !== 0) continue; // only a top-level if in the handler body
|
|
693
|
+
const parenIdx = masked.indexOf('(', im.index);
|
|
694
|
+
if (parenIdx === -1) continue;
|
|
695
|
+
const closeParen = scanBalanced(masked, parenIdx);
|
|
696
|
+
if (closeParen === -1) continue;
|
|
697
|
+
const condOriginal = handlerBodyText.slice(parenIdx + 1, closeParen);
|
|
698
|
+
const cmdRe = /command\s*===\s*(['"`])([\s\S]*?)\1/g;
|
|
699
|
+
const matchedCommands = [];
|
|
700
|
+
let cm;
|
|
701
|
+
while ((cm = cmdRe.exec(condOriginal)) !== null) {
|
|
702
|
+
matchedCommands.push(cm[2]);
|
|
703
|
+
}
|
|
704
|
+
// B-4 half closed (phase 276-07): `ARRAY.includes(command)` is a
|
|
705
|
+
// dispatch guard exactly like `command === 'x'`, just against a
|
|
706
|
+
// whole array instead of one literal. ARRAY must be a locally-defined
|
|
707
|
+
// array literal of string literals resolvable via resolveIdentifierArray
|
|
708
|
+
// (the SAME helper extractCommandVocabulary already uses for the
|
|
709
|
+
// `...IDENT` spread case) -- a computed or imported array is left
|
|
710
|
+
// unresolved rather than guessed at.
|
|
711
|
+
const includesRe = /([A-Za-z_$][\w$]*)\.includes\s*\(\s*command\s*\)/;
|
|
712
|
+
const incM = includesRe.exec(condOriginal);
|
|
713
|
+
if (incM && fileText && fileMasked) {
|
|
714
|
+
for (const cmd of resolveIdentifierArray(incM[1], fileText, fileMasked)) {
|
|
715
|
+
matchedCommands.push(cmd);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
if (matchedCommands.length === 0) continue; // not a command-comparison if
|
|
719
|
+
let i = closeParen + 1;
|
|
720
|
+
while (i < masked.length && /\s/.test(masked[i])) i += 1;
|
|
721
|
+
if (masked[i] !== '{') continue; // no-brace single statement -- unexpected here, skip
|
|
722
|
+
const blockClose = scanBalanced(masked, i);
|
|
723
|
+
if (blockClose === -1) continue;
|
|
724
|
+
const ownText = handlerBodyText.slice(i + 1, blockClose);
|
|
725
|
+
consumed.push([i + 1, blockClose]);
|
|
726
|
+
for (const cmd of matchedCommands) {
|
|
727
|
+
const existing = branchMap[cmd] || '';
|
|
728
|
+
branchMap[cmd] = existing + '\n' + ownText;
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
consumed.sort((a, b) => a[0] - b[0]);
|
|
733
|
+
let sharedBody = '';
|
|
734
|
+
let cursor = 0;
|
|
735
|
+
for (const [s, e] of consumed) {
|
|
736
|
+
if (s > cursor) sharedBody += handlerBodyText.slice(cursor, s);
|
|
737
|
+
cursor = Math.max(cursor, e);
|
|
738
|
+
}
|
|
739
|
+
sharedBody += handlerBodyText.slice(cursor);
|
|
740
|
+
|
|
741
|
+
return { branchMap, sharedBodyText: sharedBody };
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
// ---------------------------------------------------------------------------
|
|
745
|
+
// Stage D -- resolveReachability
|
|
746
|
+
// ---------------------------------------------------------------------------
|
|
747
|
+
// Matches BOTH `const X = require('path')` and destructured
|
|
748
|
+
// `const { a, b: c } = require('path')` (routers overwhelmingly use the
|
|
749
|
+
// destructured form for one-off helpers, e.g. room-open.cjs's openRoom,
|
|
750
|
+
// user-md-ops.cjs's writeUserMdAtomic -- missing this shape left every such
|
|
751
|
+
// callee unresolvable and produced false HIGH RISK findings, caught by
|
|
752
|
+
// Task 3's own spot-check requirement and fixed here per Rule 1).
|
|
753
|
+
function collectRequireBindings(fileText, fileMasked) {
|
|
754
|
+
const map = {};
|
|
755
|
+
const re = /\b(?:const|let|var)\s*(\{[^}]*\}|[A-Za-z_$][\w$]*)\s*=\s*require\(/g;
|
|
756
|
+
let m;
|
|
757
|
+
while ((m = re.exec(fileMasked)) !== null) {
|
|
758
|
+
const lhs = m[1];
|
|
759
|
+
const openParen = fileMasked.indexOf('(', m.index + m[0].length - 1);
|
|
760
|
+
if (openParen === -1) continue;
|
|
761
|
+
const closeParen = scanBalanced(fileMasked, openParen);
|
|
762
|
+
if (closeParen === -1) continue;
|
|
763
|
+
const argText = fileText.slice(openParen + 1, closeParen);
|
|
764
|
+
const pathVal = extractStringLiteralConcat(argText);
|
|
765
|
+
if (!pathVal) continue;
|
|
766
|
+
if (lhs.startsWith('{')) {
|
|
767
|
+
const inner = lhs.slice(1, lhs.lastIndexOf('}'));
|
|
768
|
+
for (const rawPart of inner.split(',')) {
|
|
769
|
+
const part = rawPart.trim();
|
|
770
|
+
if (!part || part.startsWith('...')) continue;
|
|
771
|
+
const colonIdx = part.indexOf(':');
|
|
772
|
+
const localName = (colonIdx === -1 ? part : part.slice(colonIdx + 1)).split('=')[0].trim();
|
|
773
|
+
if (/^[A-Za-z_$][\w$]*$/.test(localName)) map[localName] = pathVal;
|
|
774
|
+
}
|
|
775
|
+
} else {
|
|
776
|
+
map[lhs] = pathVal;
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
return map;
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
function resolveRepoLocalPath(reqPath, fromFileAbsPath, repoRoot) {
|
|
783
|
+
if (typeof reqPath !== 'string' || reqPath.length === 0) return null;
|
|
784
|
+
if (reqPath.startsWith('node:')) return null;
|
|
785
|
+
if (!reqPath.startsWith('.') && !reqPath.startsWith('/')) return null; // npm package
|
|
786
|
+
const base = path.dirname(fromFileAbsPath);
|
|
787
|
+
const resolved = path.resolve(base, reqPath);
|
|
788
|
+
const rootWithSep = repoRoot.endsWith(path.sep) ? repoRoot : repoRoot + path.sep;
|
|
789
|
+
if (resolved !== repoRoot && !resolved.startsWith(rootWithSep)) return null;
|
|
790
|
+
let candidate = resolved;
|
|
791
|
+
if (!fs.existsSync(candidate)) {
|
|
792
|
+
if (fs.existsSync(candidate + '.cjs')) candidate = candidate + '.cjs';
|
|
793
|
+
else if (fs.existsSync(candidate + '.js')) candidate = candidate + '.js';
|
|
794
|
+
else return null;
|
|
795
|
+
} else if (fs.statSync(candidate).isDirectory()) {
|
|
796
|
+
return null; // no index-resolution needed for this scan's known callees
|
|
797
|
+
}
|
|
798
|
+
return candidate;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
function readModuleCached(absPath, cache) {
|
|
802
|
+
if (cache.has(absPath)) return cache.get(absPath);
|
|
803
|
+
let src = null;
|
|
804
|
+
try {
|
|
805
|
+
src = fs.readFileSync(absPath, 'utf8');
|
|
806
|
+
} catch (_e) {
|
|
807
|
+
src = null;
|
|
808
|
+
}
|
|
809
|
+
cache.set(absPath, src);
|
|
810
|
+
return src;
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
// locateDirectFunctionBody(sourceText, masked, fnName) -- finds `function
|
|
814
|
+
// fn(`, `async function fn(`, `fn: function(`, `fn: (`, `fn = (` (with
|
|
815
|
+
// optional async), or an ES6 shorthand `fn(...) {`. Brace-matches the body
|
|
816
|
+
// via the masked text; for an expression-bodied arrow (no `{`), takes the
|
|
817
|
+
// text up to the next top-level `;`. Returns the body text, or null. Pulled
|
|
818
|
+
// out of locateFunctionBody (phase 276-07) so followReexportHop below can
|
|
819
|
+
// search a HOPPED-TO module's own text for a genuine local definition
|
|
820
|
+
// without re-entering the hop logic itself (the depth-one stop).
|
|
821
|
+
function locateDirectFunctionBody(sourceText, masked, fnName) {
|
|
822
|
+
const escaped = fnName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
823
|
+
const patterns = [
|
|
824
|
+
new RegExp('\\bfunction\\s+' + escaped + '\\s*\\('),
|
|
825
|
+
new RegExp('\\basync\\s+function\\s+' + escaped + '\\s*\\('),
|
|
826
|
+
new RegExp('\\b' + escaped + '\\s*:\\s*(?:async\\s+)?function\\s*\\('),
|
|
827
|
+
new RegExp('\\b' + escaped + '\\s*=\\s*(?:async\\s*)?\\('),
|
|
828
|
+
new RegExp('\\b' + escaped + '\\s*:\\s*(?:async\\s*)?\\('),
|
|
829
|
+
new RegExp('\\b' + escaped + '\\s*\\('), // shorthand method -- loosest, checked last
|
|
830
|
+
];
|
|
831
|
+
|
|
832
|
+
for (const re of patterns) {
|
|
833
|
+
const m = re.exec(masked);
|
|
834
|
+
if (!m) continue;
|
|
835
|
+
const parenIdx = masked.indexOf('(', m.index);
|
|
836
|
+
if (parenIdx === -1) continue;
|
|
837
|
+
const parenClose = scanBalanced(masked, parenIdx);
|
|
838
|
+
if (parenClose === -1) continue;
|
|
839
|
+
let i = parenClose + 1;
|
|
840
|
+
while (i < masked.length && /\s/.test(masked[i])) i += 1;
|
|
841
|
+
if (masked.slice(i, i + 2) === '=>') {
|
|
842
|
+
i += 2;
|
|
843
|
+
while (i < masked.length && /\s/.test(masked[i])) i += 1;
|
|
844
|
+
}
|
|
845
|
+
if (masked[i] === '{') {
|
|
846
|
+
const close = scanBalanced(masked, i);
|
|
847
|
+
if (close === -1) continue;
|
|
848
|
+
return sourceText.slice(i + 1, close);
|
|
849
|
+
}
|
|
850
|
+
// Expression-bodied arrow, or a shorthand-method false match with no
|
|
851
|
+
// body brace at all: only accept if a `{` genuinely follows within a
|
|
852
|
+
// short lookahead; otherwise this pattern candidate is not a real
|
|
853
|
+
// function definition here, try the next.
|
|
854
|
+
if (i < masked.length && masked[i] !== ';' && masked[i] !== ',' && masked[i] !== ')') {
|
|
855
|
+
let depth = 0;
|
|
856
|
+
let j = i;
|
|
857
|
+
while (j < masked.length) {
|
|
858
|
+
const c = masked[j];
|
|
859
|
+
if (c === '(' || c === '{' || c === '[') depth += 1;
|
|
860
|
+
else if (c === ')' || c === '}' || c === ']') {
|
|
861
|
+
if (depth === 0) break;
|
|
862
|
+
depth -= 1;
|
|
863
|
+
} else if (c === ';' && depth === 0) break;
|
|
864
|
+
j += 1;
|
|
865
|
+
}
|
|
866
|
+
return sourceText.slice(i, j);
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
return null;
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
// ---------------------------------------------------------------------------
|
|
873
|
+
// Barrel re-export hop (phase 276-07, F-10 Bug B / boundary B-2).
|
|
874
|
+
// lib/core/navigation.cjs is a facade of `NAME: mod.NAME` (or
|
|
875
|
+
// `NAME: mod.OTHERNAME`) object-literal property ASSIGNMENTS -- not local
|
|
876
|
+
// function definitions -- so locateDirectFunctionBody's six patterns above
|
|
877
|
+
// find nothing and every branch whose only write is a
|
|
878
|
+
// `navigation.<reexport>()` call reports UNKNOWN. Since navigation.cjs is
|
|
879
|
+
// the mandated Canon Part 9 chokepoint, this is systemic: any tool escapes
|
|
880
|
+
// today only because it also calls something else the scanner can resolve
|
|
881
|
+
// (luck, not coverage).
|
|
882
|
+
//
|
|
883
|
+
// DEPTH ONE ONLY: the hop resolves the re-export's OWN module and calls
|
|
884
|
+
// locateDirectFunctionBody there (never followReexportHop again), so a
|
|
885
|
+
// re-export of a re-export stays unresolved rather than being chased
|
|
886
|
+
// further. A one-hop cap matches this scanner's existing depth discipline
|
|
887
|
+
// elsewhere (resolveReachability's own dotted/bare call resolution is one
|
|
888
|
+
// hop from the branch text; bodyReachesWrite's same-file local chase is a
|
|
889
|
+
// SEPARATE, same-file-bounded depth). Recursing through an arbitrary chain
|
|
890
|
+
// of facades would turn a bounded static heuristic into an unbounded graph
|
|
891
|
+
// walk with no stated stopping rule -- out of scope here.
|
|
892
|
+
//
|
|
893
|
+
// CONTAINMENT IS MANDATORY, NOT ASSUMED: the resolved module path is routed
|
|
894
|
+
// through the EXISTING resolveRepoLocalPath and its
|
|
895
|
+
// `startsWith(rootWithSep)` check -- no second path resolver is written
|
|
896
|
+
// for this hop. This scanner runs inside a pre-commit hook; an uncontained
|
|
897
|
+
// file read here, following a `require()` argument the scanner does not
|
|
898
|
+
// control, would be an arbitrary-file-read primitive sitting in every
|
|
899
|
+
// developer's commit path. A negative fixture
|
|
900
|
+
// (tests/fixtures/tool-honesty/reexport-outside-root.cjs) pins this: a
|
|
901
|
+
// re-export naming a path outside the repo root resolves to nothing.
|
|
902
|
+
const REEXPORT_MODULE_CACHE = new Map();
|
|
903
|
+
function readReexportModule(absPath) {
|
|
904
|
+
if (REEXPORT_MODULE_CACHE.has(absPath)) return REEXPORT_MODULE_CACHE.get(absPath);
|
|
905
|
+
let src = null;
|
|
906
|
+
try {
|
|
907
|
+
src = fs.readFileSync(absPath, 'utf8');
|
|
908
|
+
} catch (_e) {
|
|
909
|
+
src = null;
|
|
910
|
+
}
|
|
911
|
+
REEXPORT_MODULE_CACHE.set(absPath, src);
|
|
912
|
+
return src;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
function followReexportHop(sourceText, masked, fnName, moduleAbsPath) {
|
|
916
|
+
if (!moduleAbsPath) return null; // no module-file context (e.g. a synthetic in-memory source) -- hop not applicable
|
|
917
|
+
const escaped = fnName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
918
|
+
const reexportRe = new RegExp('\\b' + escaped + '\\s*:\\s*([A-Za-z_$][\\w$]*)\\.([A-Za-z_$][\\w$]*)\\s*,');
|
|
919
|
+
const rm = reexportRe.exec(masked);
|
|
920
|
+
if (!rm) return null;
|
|
921
|
+
const identName = rm[1];
|
|
922
|
+
const targetFnName = rm[2];
|
|
923
|
+
|
|
924
|
+
const requireBindings = collectRequireBindings(sourceText, masked);
|
|
925
|
+
const reqPath = requireBindings[identName];
|
|
926
|
+
if (!reqPath) return null; // identName is not a require()-bound module identifier in this file
|
|
927
|
+
|
|
928
|
+
const resolvedAbs = resolveRepoLocalPath(reqPath, moduleAbsPath, REPO_ROOT);
|
|
929
|
+
if (!resolvedAbs) return null; // outside the repo root, absolute, or a traversal -- abandon the hop, never read
|
|
930
|
+
|
|
931
|
+
const targetSrc = readReexportModule(resolvedAbs);
|
|
932
|
+
if (targetSrc === null) return null;
|
|
933
|
+
|
|
934
|
+
const targetMasked = maskNonCode(targetSrc);
|
|
935
|
+
return locateDirectFunctionBody(targetSrc, targetMasked, targetFnName);
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
// locateFunctionBody(sourceText, fnName, bodyCache, cacheKeyPrefix) -- tries
|
|
939
|
+
// a direct local definition first (locateDirectFunctionBody), then, ONLY
|
|
940
|
+
// when cacheKeyPrefix is a real module file path, a one-level barrel
|
|
941
|
+
// re-export hop (followReexportHop). Returns the body text, or null.
|
|
942
|
+
function locateFunctionBody(sourceText, fnName, bodyCache, cacheKeyPrefix) {
|
|
943
|
+
const cacheKey = cacheKeyPrefix ? cacheKeyPrefix + '::' + fnName : null;
|
|
944
|
+
if (cacheKey && bodyCache && bodyCache.has(cacheKey)) return bodyCache.get(cacheKey);
|
|
945
|
+
|
|
946
|
+
const masked = maskNonCode(sourceText);
|
|
947
|
+
let result = locateDirectFunctionBody(sourceText, masked, fnName);
|
|
948
|
+
if (result === null) {
|
|
949
|
+
result = followReexportHop(sourceText, masked, fnName, cacheKeyPrefix);
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
if (cacheKey && bodyCache) bodyCache.set(cacheKey, result);
|
|
953
|
+
return result;
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
// bodyReachesWrite -- the depth-1 hop itself. "Test that body at depth 0"
|
|
957
|
+
// (the plan's own words) means testing the RESOLVED function's own text for
|
|
958
|
+
// a write primitive; in practice a resolved function very commonly delegates
|
|
959
|
+
// to a SAME-FILE local helper one more step down (pipeline-state.cjs's
|
|
960
|
+
// recordStep -> write -> fs.writeFileSync; room-open.cjs's openRoom ->
|
|
961
|
+
// several local helpers), and stopping at a flat text match on the directly-
|
|
962
|
+
// resolved body alone missed those, producing a real false HIGH RISK
|
|
963
|
+
// (caught by Task 3's own spot-check requirement, fixed here per Rule 1).
|
|
964
|
+
// This still never crosses a SECOND require() boundary (that would be depth
|
|
965
|
+
// 2, out of scope) -- it only chases bare same-file calls within the ONE
|
|
966
|
+
// already-crossed module, bounded by maxDepth and a visited-set so a
|
|
967
|
+
// mutually-recursive local helper pair cannot loop forever.
|
|
968
|
+
function bodyReachesWrite(bodyText, sourceText, primitives, bodyCache, cacheKeyPrefix, visited, maxDepth) {
|
|
969
|
+
const masked = maskNonCode(bodyText);
|
|
970
|
+
if (primitives.test(masked)) return true;
|
|
971
|
+
if (maxDepth <= 0) return false;
|
|
972
|
+
const bareRe = /(?<![.\w$])([A-Za-z_$][\w$]*)\s*\(/g;
|
|
973
|
+
let m;
|
|
974
|
+
while ((m = bareRe.exec(masked)) !== null) {
|
|
975
|
+
const fnName = m[1];
|
|
976
|
+
if (JS_KEYWORDS.has(fnName) || fnName === 'require') continue;
|
|
977
|
+
const key = cacheKeyPrefix + '::' + fnName;
|
|
978
|
+
if (visited.has(key)) continue;
|
|
979
|
+
visited.add(key);
|
|
980
|
+
const fnBody = locateFunctionBody(sourceText, fnName, bodyCache, cacheKeyPrefix);
|
|
981
|
+
if (fnBody === null) continue;
|
|
982
|
+
if (bodyReachesWrite(fnBody, sourceText, primitives, bodyCache, cacheKeyPrefix, visited, maxDepth - 1)) return true;
|
|
983
|
+
}
|
|
984
|
+
return false;
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
const LOCAL_CHASE_MAX_DEPTH = 3;
|
|
988
|
+
|
|
989
|
+
function resolveReachability(effectiveText, opts) {
|
|
990
|
+
const masked = maskNonCode(effectiveText);
|
|
991
|
+
if (opts.primitives.test(masked)) return 'WRITES';
|
|
992
|
+
|
|
993
|
+
let unresolved = false;
|
|
994
|
+
|
|
995
|
+
const dotRe = /([A-Za-z_$][\w$]*)\.([A-Za-z_$][\w$]*)\s*\(/g;
|
|
996
|
+
let m;
|
|
997
|
+
while ((m = dotRe.exec(masked)) !== null) {
|
|
998
|
+
const modName = m[1];
|
|
999
|
+
const fnName = m[2];
|
|
1000
|
+
const reqPath = opts.fileRequireMap[modName];
|
|
1001
|
+
if (!reqPath) continue; // not a require-bound identifier -- not a candidate
|
|
1002
|
+
const resolvedAbs = resolveRepoLocalPath(reqPath, opts.filePath, opts.repoRoot);
|
|
1003
|
+
if (!resolvedAbs) continue; // external / non-repo-local -- not inspectable, skip
|
|
1004
|
+
const modSrc = readModuleCached(resolvedAbs, opts.moduleCache);
|
|
1005
|
+
if (modSrc === null) { unresolved = true; continue; }
|
|
1006
|
+
const fnBody = locateFunctionBody(modSrc, fnName, opts.bodyCache, resolvedAbs);
|
|
1007
|
+
if (fnBody === null) { unresolved = true; continue; }
|
|
1008
|
+
if (bodyReachesWrite(fnBody, modSrc, opts.primitives, opts.bodyCache, resolvedAbs, new Set(), LOCAL_CHASE_MAX_DEPTH)) {
|
|
1009
|
+
return 'WRITES';
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
const bareRe = /(?<![.\w$])([A-Za-z_$][\w$]*)\s*\(/g;
|
|
1014
|
+
while ((m = bareRe.exec(masked)) !== null) {
|
|
1015
|
+
const fnName = m[1];
|
|
1016
|
+
if (JS_KEYWORDS.has(fnName) || fnName === 'require') continue;
|
|
1017
|
+
|
|
1018
|
+
// A bare call may be a DESTRUCTURED import bound to a repo-local
|
|
1019
|
+
// require() (e.g. `const { openRoom } = require('../core/room-open.cjs')`
|
|
1020
|
+
// then a bare `openRoom(...)` call) -- resolve it exactly like a dotted
|
|
1021
|
+
// external call before falling back to a same-file local definition.
|
|
1022
|
+
const reqPath = opts.fileRequireMap[fnName];
|
|
1023
|
+
if (reqPath) {
|
|
1024
|
+
const resolvedAbs = resolveRepoLocalPath(reqPath, opts.filePath, opts.repoRoot);
|
|
1025
|
+
if (!resolvedAbs) continue; // external (npm/node-builtin) -- not inspectable, skip
|
|
1026
|
+
const modSrc = readModuleCached(resolvedAbs, opts.moduleCache);
|
|
1027
|
+
if (modSrc === null) { unresolved = true; continue; }
|
|
1028
|
+
const fnBody = locateFunctionBody(modSrc, fnName, opts.bodyCache, resolvedAbs);
|
|
1029
|
+
if (fnBody === null) { unresolved = true; continue; }
|
|
1030
|
+
if (bodyReachesWrite(fnBody, modSrc, opts.primitives, opts.bodyCache, resolvedAbs, new Set(), LOCAL_CHASE_MAX_DEPTH)) {
|
|
1031
|
+
return 'WRITES';
|
|
1032
|
+
}
|
|
1033
|
+
continue;
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
const fnBody = locateFunctionBody(opts.fileText, fnName, opts.bodyCache, opts.filePath);
|
|
1037
|
+
if (fnBody === null) continue; // no local definition, no require binding -- builtin/global, skip
|
|
1038
|
+
if (bodyReachesWrite(fnBody, opts.fileText, opts.primitives, opts.bodyCache, opts.filePath, new Set(), LOCAL_CHASE_MAX_DEPTH)) {
|
|
1039
|
+
return 'WRITES';
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
return unresolved ? 'UNKNOWN' : 'NO_WRITE';
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
// ---------------------------------------------------------------------------
|
|
1047
|
+
// Stage E -- extractClaims(description, vocabulary)
|
|
1048
|
+
// ---------------------------------------------------------------------------
|
|
1049
|
+
const STRONG_VERBS = [
|
|
1050
|
+
'file', 'files', 'filed', 'filing', 'write', 'writes', 'writing', 'wrote',
|
|
1051
|
+
'persist', 'save', 'saves', 'saving', 'store', 'stores', 'storing',
|
|
1052
|
+
'insert', 'mint', 'mints', 'archive', 'archives', 'commit',
|
|
1053
|
+
];
|
|
1054
|
+
const WEAK_VERBS = [
|
|
1055
|
+
'generate', 'build', 'index', 'rebuild', 'render', 'update', 'add', 'log',
|
|
1056
|
+
'produce', 'publish', 'snapshot',
|
|
1057
|
+
];
|
|
1058
|
+
const CREATE_NOUNS = ['node', 'entry', 'artifact', 'file', 'room', 'record'];
|
|
1059
|
+
const NEGATION_PATTERNS = [
|
|
1060
|
+
/\bwrites?\s+nothing\b/i,
|
|
1061
|
+
/\bdoes\s+not\s+write\b/i,
|
|
1062
|
+
/\bnever\s+writes?\b/i,
|
|
1063
|
+
/\bnothing\s+is\s+written\b/i,
|
|
1064
|
+
/\bno\s+writes?\s+occurs?\b/i,
|
|
1065
|
+
/\breference\s+only\b/i,
|
|
1066
|
+
// phase 276-07 (D-276-3, plan 276-11's own honest gate_render rewrite
|
|
1067
|
+
// needs this): "nothing is persisted" is the identical global-disclaimer
|
|
1068
|
+
// shape as the existing "nothing is written" entry above, just with the
|
|
1069
|
+
// synonym an in-memory-only mint uses. Added HERE (the detector), never
|
|
1070
|
+
// as a STRONG_VERBS addition of "minted" -- D-276-3 is explicit that an
|
|
1071
|
+
// in-memory gate-ledger mint is not persistence, the fix is a description
|
|
1072
|
+
// correction (owned by 276-11), and widening the verb vocabulary would be
|
|
1073
|
+
// the wrong lever twice over (it would fire on every legitimate use of
|
|
1074
|
+
// "minted" AND treat a vocabulary change as a substitute for saying the
|
|
1075
|
+
// true thing).
|
|
1076
|
+
/\bnothing\s+is\s+persisted\b/i,
|
|
1077
|
+
];
|
|
1078
|
+
|
|
1079
|
+
function sentenceHasNegation(sentence) {
|
|
1080
|
+
return NEGATION_PATTERNS.some((re) => re.test(sentence));
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
// isLocallyNegated -- a verb occurrence immediately preceded OR followed by
|
|
1084
|
+
// a bare negator (no/not/never) is a claim about the ABSENCE of the write,
|
|
1085
|
+
// not a claim of the write itself ("mints no second resolver", "creates not
|
|
1086
|
+
// a single record"). This is distinct from sentenceHasNegation's fixed
|
|
1087
|
+
// GLOBAL-disclaimer phrases: those cancel every claim for the whole tool;
|
|
1088
|
+
// this only voids the ONE verb occurrence it wraps, so a sentence carrying
|
|
1089
|
+
// both a negated verb and a separate genuine claim still registers the
|
|
1090
|
+
// genuine one. Found via Task 3's own spot-check requirement (chain_resolve
|
|
1091
|
+
// /chain_run/framework_run's "mints no second resolver" false HIGH RISK) and
|
|
1092
|
+
// fixed here per Rule 1, not papered over with an ALLOWED_UNVERIFIED entry.
|
|
1093
|
+
function isLocallyNegated(lower, matchIndex, matchLength) {
|
|
1094
|
+
const before = lower.slice(Math.max(0, matchIndex - 20), matchIndex);
|
|
1095
|
+
const after = lower.slice(matchIndex + matchLength, matchIndex + matchLength + 20);
|
|
1096
|
+
return /\b(?:no|not|never)\b\s*$/.test(before) || /^\s*(?:no|not|never)\b/.test(after);
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
// isPartOfHyphenatedToken -- \b treats a hyphen as a word boundary, so a
|
|
1100
|
+
// verb match can land INSIDE a hyphenated command-literal token rather than
|
|
1101
|
+
// standing alone in prose ("rooms-archive" trips a bare \barchive\b match;
|
|
1102
|
+
// "scout-hsi" would trip a hypothetical "hsi" hit the same way). A verb
|
|
1103
|
+
// immediately touching a hyphen on either side is part of a compound
|
|
1104
|
+
// identifier, not a real prose verb usage. Found via Task 3's own spot-check
|
|
1105
|
+
// requirement (orchestration's "Manage rooms (..., rooms-archive, ...)"
|
|
1106
|
+
// parenthetical command list producing a false HIGH RISK for every listed
|
|
1107
|
+
// command) and fixed here per Rule 1, not papered over with an
|
|
1108
|
+
// ALLOWED_UNVERIFIED entry.
|
|
1109
|
+
function isPartOfHyphenatedToken(lower, matchIndex, matchLength) {
|
|
1110
|
+
const before = lower[matchIndex - 1];
|
|
1111
|
+
const after = lower[matchIndex + matchLength];
|
|
1112
|
+
return before === '-' || after === '-';
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
// isEnumeratedCommandName -- a verb-shaped token that is actually one of the
|
|
1116
|
+
// SCANNED TOOL'S OWN command names, sitting inside its own command
|
|
1117
|
+
// enumeration (phase 276-07, F-2 through F-8: `export`'s description names
|
|
1118
|
+
// "publish" and "snapshot" as WEAK_VERBS, but both are literal
|
|
1119
|
+
// EXPORT_COMMANDS entries inside "Choose by audience: dashboard for..., ...,
|
|
1120
|
+
// publish to push an artifact outward, ...", a COMMAND LIST, not a prose
|
|
1121
|
+
// claim about what the tool does). Same disease class as
|
|
1122
|
+
// isPartOfHyphenatedToken (a command-literal token misread as a verb), but
|
|
1123
|
+
// for a BARE unhyphenated command name sitting in its own tool's
|
|
1124
|
+
// parenthetical/enumerated command list rather than inside a hyphenated
|
|
1125
|
+
// compound.
|
|
1126
|
+
//
|
|
1127
|
+
// Two INDEPENDENT signals are both required, so a single command name used
|
|
1128
|
+
// as a genuine verb in an ordinary sentence still counts as a claim:
|
|
1129
|
+
// 1. The token is a member of the tool's OWN resolved command vocabulary
|
|
1130
|
+
// (passed in, already resolved by extractCommandVocabulary -- this
|
|
1131
|
+
// function does not re-derive it).
|
|
1132
|
+
// 2. The token sits in an ENUMERATION CONTEXT: it touches a list separator
|
|
1133
|
+
// (a comma, or the word "and"/"or") on at least one side, OR sits
|
|
1134
|
+
// inside a parenthetical, AND the sentence names at least two OTHER
|
|
1135
|
+
// members of the same command vocabulary (a lone command-shaped word
|
|
1136
|
+
// next to "and" is still ambiguous; a real multi-member enumeration is
|
|
1137
|
+
// not).
|
|
1138
|
+
//
|
|
1139
|
+
// Err toward COUNTING the verb when only one signal holds: a missed guard
|
|
1140
|
+
// leaves a visible false positive (this phase's own subject), while an
|
|
1141
|
+
// over-broad guard hides a real defect invisibly (the disease this whole
|
|
1142
|
+
// phase exists to cure) -- the asymmetry is deliberate, not an oversight.
|
|
1143
|
+
function isEnumeratedCommandName(sentence, matchIndex, matchLength, vocabulary) {
|
|
1144
|
+
if (!vocabulary || vocabulary.length === 0) return false;
|
|
1145
|
+
const lower = sentence.toLowerCase();
|
|
1146
|
+
const word = lower.slice(matchIndex, matchIndex + matchLength);
|
|
1147
|
+
const isVocabMember = vocabulary.some((c) => c !== '(default)' && c.toLowerCase() === word);
|
|
1148
|
+
if (!isVocabMember) return false;
|
|
1149
|
+
|
|
1150
|
+
const before = lower.slice(Math.max(0, matchIndex - 12), matchIndex);
|
|
1151
|
+
const after = lower.slice(matchIndex + matchLength, matchIndex + matchLength + 12);
|
|
1152
|
+
const touchesComma = /,\s*$/.test(before) || /^\s*,/.test(after);
|
|
1153
|
+
const touchesAndOr = /\b(?:and|or)\s*$/.test(before) || /^\s*(?:and|or)\b/.test(after);
|
|
1154
|
+
const openCount = (lower.slice(0, matchIndex).match(/\(/g) || []).length;
|
|
1155
|
+
const closeCount = (lower.slice(0, matchIndex).match(/\)/g) || []).length;
|
|
1156
|
+
const insideParen = openCount > closeCount;
|
|
1157
|
+
if (!touchesComma && !touchesAndOr && !insideParen) return false;
|
|
1158
|
+
|
|
1159
|
+
const namedHere = sentenceNamesCommand(sentence, vocabulary);
|
|
1160
|
+
const others = namedHere.filter((c) => c.toLowerCase() !== word);
|
|
1161
|
+
return others.length >= 2;
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
// FILE_NOUN_DEMOTION_WORDS / isFileNounUsage -- demotes the bare STRONG_VERBS
|
|
1165
|
+
// entry 'file' from a verb reading when immediately followed by a noun that
|
|
1166
|
+
// makes it read as a compound noun phrase ("file contents", "file path",
|
|
1167
|
+
// "file system") rather than the verb "to file" (phase 276-07, F-10 Bug A:
|
|
1168
|
+
// context_assemble's "Never returns raw file contents." was read as a
|
|
1169
|
+
// POSITIVE STRONG persistence claim, because "Never returns raw " intervenes
|
|
1170
|
+
// between the negator and "file", wider than isLocallyNegated's adjacency
|
|
1171
|
+
// window). This narrow noun-phrase demotion is chosen over widening
|
|
1172
|
+
// isLocallyNegated's window repo-wide, because it fixes the exact defect
|
|
1173
|
+
// (a STRONG-verb-shaped noun phrase) without loosening the negation check
|
|
1174
|
+
// for every OTHER sentence on this surface -- narrower effect, per the
|
|
1175
|
+
// plan's own instruction to implement whichever of the two is narrower.
|
|
1176
|
+
// Widening the negation window was evaluated and NOT needed: no other known
|
|
1177
|
+
// finding depends on a negator separated from its verb by intervening
|
|
1178
|
+
// words, so adding that broader change now would be an untested surface
|
|
1179
|
+
// increase with no proven case behind it. Only the bare 'file' entry is
|
|
1180
|
+
// demoted this way; 'files'/'filed'/'filing' are unaffected, and 'file'
|
|
1181
|
+
// itself stays a real write verb everywhere else on this surface --
|
|
1182
|
+
// STRONG_VERBS itself is NOT modified.
|
|
1183
|
+
const FILE_NOUN_DEMOTION_WORDS = ['contents', 'path', 'paths', 'name', 'names', 'system'];
|
|
1184
|
+
function isFileNounUsage(lower, matchIndex, matchLength) {
|
|
1185
|
+
const after = lower.slice(matchIndex + matchLength, matchIndex + matchLength + 12);
|
|
1186
|
+
return new RegExp('^\\s+(?:' + FILE_NOUN_DEMOTION_WORDS.join('|') + ')\\b').test(after);
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
function classifySentenceVerbTier(sentence, vocabulary) {
|
|
1190
|
+
const lower = sentence.toLowerCase();
|
|
1191
|
+
for (const v of STRONG_VERBS) {
|
|
1192
|
+
const re = new RegExp('\\b' + v + '\\b', 'g');
|
|
1193
|
+
let vm;
|
|
1194
|
+
while ((vm = re.exec(lower)) !== null) {
|
|
1195
|
+
if (isPartOfHyphenatedToken(lower, vm.index, vm[0].length)) continue;
|
|
1196
|
+
if (isEnumeratedCommandName(sentence, vm.index, vm[0].length, vocabulary)) continue;
|
|
1197
|
+
if (v === 'file' && isFileNounUsage(lower, vm.index, vm[0].length)) continue;
|
|
1198
|
+
if (!isLocallyNegated(lower, vm.index, vm[0].length)) return 'STRONG';
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
if (/\bcreates?\b/.test(lower)) {
|
|
1202
|
+
const cm = lower.match(/\bcreates?\b/);
|
|
1203
|
+
if (cm && !isPartOfHyphenatedToken(lower, cm.index, cm[0].length) && !isLocallyNegated(lower, cm.index, cm[0].length)) {
|
|
1204
|
+
for (const n of CREATE_NOUNS) {
|
|
1205
|
+
if (new RegExp('\\b' + n + 's?\\b').test(lower)) return 'STRONG';
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
for (const v of WEAK_VERBS) {
|
|
1210
|
+
const re = new RegExp('\\b' + v + '\\b', 'g');
|
|
1211
|
+
let vm;
|
|
1212
|
+
while ((vm = re.exec(lower)) !== null) {
|
|
1213
|
+
if (isPartOfHyphenatedToken(lower, vm.index, vm[0].length)) continue;
|
|
1214
|
+
if (isEnumeratedCommandName(sentence, vm.index, vm[0].length, vocabulary)) continue;
|
|
1215
|
+
if (!isLocallyNegated(lower, vm.index, vm[0].length)) return 'WEAK';
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
return null;
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
function sentenceNamesCommand(sentence, vocabulary) {
|
|
1222
|
+
const named = [];
|
|
1223
|
+
for (const cmd of vocabulary) {
|
|
1224
|
+
if (cmd === '(default)') continue;
|
|
1225
|
+
const escaped = cmd.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
1226
|
+
const re = new RegExp('(?<![\\w-])' + escaped + '(?![\\w-])', 'i');
|
|
1227
|
+
if (re.test(sentence)) named.push(cmd);
|
|
1228
|
+
}
|
|
1229
|
+
return named;
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
function extractClaims(description, vocabulary) {
|
|
1233
|
+
const result = { globalCancel: false, perCommand: {}, toolScoped: null };
|
|
1234
|
+
if (!description) return result;
|
|
1235
|
+
const sentences = description
|
|
1236
|
+
.split(/(?<=[.!?])\s+/)
|
|
1237
|
+
.map((s) => s.trim())
|
|
1238
|
+
.filter(Boolean);
|
|
1239
|
+
for (const sentence of sentences) {
|
|
1240
|
+
if (sentenceHasNegation(sentence)) {
|
|
1241
|
+
result.globalCancel = true;
|
|
1242
|
+
continue;
|
|
1243
|
+
}
|
|
1244
|
+
const tier = classifySentenceVerbTier(sentence, vocabulary);
|
|
1245
|
+
if (!tier) continue;
|
|
1246
|
+
const namedCommands = sentenceNamesCommand(sentence, vocabulary);
|
|
1247
|
+
if (namedCommands.length > 0) {
|
|
1248
|
+
for (const cmd of namedCommands) {
|
|
1249
|
+
const existing = result.perCommand[cmd];
|
|
1250
|
+
if (!existing || (existing.tier === 'WEAK' && tier === 'STRONG')) {
|
|
1251
|
+
result.perCommand[cmd] = { tier, phrase: sentence };
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
} else if (!result.toolScoped || (result.toolScoped.tier === 'WEAK' && tier === 'STRONG')) {
|
|
1255
|
+
result.toolScoped = { tier, phrase: sentence };
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
return result;
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
// ---------------------------------------------------------------------------
|
|
1262
|
+
// Stage F -- classifyBranch
|
|
1263
|
+
//
|
|
1264
|
+
// WEAK-TIER SIBLING-WRITES RULING (phase 276-07, F-15..F-24, decided ONCE
|
|
1265
|
+
// here rather than left as an undecided bucket). The toolClaim/STRONG branch
|
|
1266
|
+
// below discounts a tool-scoped STRONG claim to LOW when ctx.anyBranchWrites
|
|
1267
|
+
// -- a sibling command in the same mixed-mode tool does write, so the whole
|
|
1268
|
+
// tool's persistence claim is explainable even though THIS branch alone
|
|
1269
|
+
// does not write. The question this ruling answers: does a WEAK claim (on
|
|
1270
|
+
// EITHER path -- a per-command cmdClaim or a tool-scoped toolClaim) inherit
|
|
1271
|
+
// that same sibling-writes discount?
|
|
1272
|
+
//
|
|
1273
|
+
// RULED: NO. The discount is NOT extended to the WEAK tier. Left unchanged
|
|
1274
|
+
// on this point; every WEAK claim with no reachable write still lands
|
|
1275
|
+
// MEDIUM regardless of a writing sibling.
|
|
1276
|
+
//
|
|
1277
|
+
// REJECTED ALTERNATIVE, and why it was rejected. room_graph's own ten rows
|
|
1278
|
+
// (F-15..F-24, tool-router.cjs:914) were the concrete test case, and
|
|
1279
|
+
// re-measuring them (rather than trusting 276-RESEARCH.md's characterization
|
|
1280
|
+
// of the claim as "tool-scoped") showed the claim is actually PER-COMMAND:
|
|
1281
|
+
// the description's single sentence names all 13 commands inside four
|
|
1282
|
+
// parenthetical clauses, so extractClaims's sentence-level matching assigns
|
|
1283
|
+
// the SAME WEAK phrase to every named command, including ones whose own
|
|
1284
|
+
// clause verb ("interrogate", "work ... over") is not a persistence verb at
|
|
1285
|
+
// all. Extending the discount looked at first like the obvious fix these
|
|
1286
|
+
// ten rows wanted. Triage found otherwise: two of the ten
|
|
1287
|
+
// (graph-index, graph-rebuild) delegate to lib/core/graph-ops.cjs's
|
|
1288
|
+
// indexArtifact/rebuildGraph, which perform REAL `conn.prepare(...).run(...)`
|
|
1289
|
+
// INSERTs against the room's LazyGraph SQLite substrate (lib/core/
|
|
1290
|
+
// lazygraph-ops.cjs:569) -- a genuine write this detector cannot see, because
|
|
1291
|
+
// resolveReachability's dotted-call resolution is only ONE hop deep and the
|
|
1292
|
+
// real INSERT sits behind a SECOND dotted hop (graph-ops.indexArtifact ->
|
|
1293
|
+
// lazygraph.indexArtifact), a depth this scanner does not chase (a new,
|
|
1294
|
+
// separate reachability-depth boundary, out of this task's four-defect
|
|
1295
|
+
// scope -- not fixed here, named in the plan's own SUMMARY as a discovered
|
|
1296
|
+
// item for a future plan, not silently absorbed into this ruling).
|
|
1297
|
+
// Extending the sibling-writes discount to WEAK would have mapped ALL TEN
|
|
1298
|
+
// rows uniformly to OK (per this plan's own ledger contract for the EXTEND
|
|
1299
|
+
// case), which would have silently hidden those two real, undetected writes
|
|
1300
|
+
// behind "a sibling writes, so this is fine" reasoning -- exactly the
|
|
1301
|
+
// invisible false negative D-276-2 warns against, on the very rows a
|
|
1302
|
+
// blanket rule was supposed to clean up. A blunt tool-wide discount cannot
|
|
1303
|
+
// distinguish "genuinely read-only, over-attributed by sentence-level
|
|
1304
|
+
// coarseness" (8 of the 10) from "genuinely writes, undetected by a
|
|
1305
|
+
// different depth limit" (2 of the 10) without first fixing the second
|
|
1306
|
+
// problem -- which this task does not own. Per D-276-2, a permanently
|
|
1307
|
+
// visible MEDIUM with a written, honest reason is a closed finding under
|
|
1308
|
+
// this phase's own definition; that is the ten room_graph ledger entries'
|
|
1309
|
+
// final disposition (documented-no-action / MEDIUM), not detector-fix / OK.
|
|
1310
|
+
// ---------------------------------------------------------------------------
|
|
1311
|
+
function classifyBranch(ctx) {
|
|
1312
|
+
const hasBanner = NO_WRITE_BANNER_CALL_RE.test(ctx.effectiveText)
|
|
1313
|
+
|| ctx.effectiveText.indexOf(NO_WRITE_MARKER_LITERAL) !== -1;
|
|
1314
|
+
if (hasBanner) {
|
|
1315
|
+
return { verdict: 'OK', reason: 'in-band no-write marker present (noWriteBanner( or ' + NO_WRITE_MARKER_LITERAL + ')' };
|
|
1316
|
+
}
|
|
1317
|
+
if (ctx.claims.globalCancel) {
|
|
1318
|
+
return { verdict: 'OK', reason: 'description carries a global no-write disclaimer' };
|
|
1319
|
+
}
|
|
1320
|
+
if (ctx.reachability === 'WRITES') {
|
|
1321
|
+
return { verdict: 'OK', reason: 'a write primitive is reachable' };
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
const cmdClaim = ctx.claims.perCommand[ctx.command];
|
|
1325
|
+
if (cmdClaim) {
|
|
1326
|
+
if (ctx.reachability === 'UNKNOWN') {
|
|
1327
|
+
return {
|
|
1328
|
+
verdict: 'UNKNOWN',
|
|
1329
|
+
reason: 'claims "' + cmdClaim.phrase + '" but reachability could not be resolved (unresolved callee)',
|
|
1330
|
+
claim: cmdClaim,
|
|
1331
|
+
};
|
|
1332
|
+
}
|
|
1333
|
+
if (cmdClaim.tier === 'STRONG') {
|
|
1334
|
+
return {
|
|
1335
|
+
verdict: 'HIGH_RISK',
|
|
1336
|
+
reason: 'claims "' + cmdClaim.phrase + '" but no write primitive is reachable',
|
|
1337
|
+
claim: cmdClaim,
|
|
1338
|
+
};
|
|
1339
|
+
}
|
|
1340
|
+
return {
|
|
1341
|
+
verdict: 'MEDIUM',
|
|
1342
|
+
reason: 'weak claim "' + cmdClaim.phrase + '" with no reachable write',
|
|
1343
|
+
claim: cmdClaim,
|
|
1344
|
+
};
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1347
|
+
const toolClaim = ctx.claims.toolScoped;
|
|
1348
|
+
if (toolClaim) {
|
|
1349
|
+
if (ctx.reachability === 'UNKNOWN') {
|
|
1350
|
+
return {
|
|
1351
|
+
verdict: 'UNKNOWN',
|
|
1352
|
+
reason: 'tool-scoped claim "' + toolClaim.phrase + '" but reachability could not be resolved',
|
|
1353
|
+
claim: toolClaim,
|
|
1354
|
+
};
|
|
1355
|
+
}
|
|
1356
|
+
if (toolClaim.tier === 'STRONG') {
|
|
1357
|
+
if (ctx.anyBranchWrites) {
|
|
1358
|
+
return {
|
|
1359
|
+
verdict: 'LOW',
|
|
1360
|
+
reason: 'tool-scoped claim "' + toolClaim.phrase + '" -- a sibling command in this tool does write',
|
|
1361
|
+
claim: toolClaim,
|
|
1362
|
+
};
|
|
1363
|
+
}
|
|
1364
|
+
return {
|
|
1365
|
+
verdict: 'HIGH_RISK',
|
|
1366
|
+
reason: 'tool-scoped claim "' + toolClaim.phrase + '" and no command in this tool reaches a write',
|
|
1367
|
+
claim: toolClaim,
|
|
1368
|
+
};
|
|
1369
|
+
}
|
|
1370
|
+
return {
|
|
1371
|
+
verdict: 'MEDIUM',
|
|
1372
|
+
reason: 'weak tool-scoped claim "' + toolClaim.phrase + '" with no reachable write',
|
|
1373
|
+
claim: toolClaim,
|
|
1374
|
+
};
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
return { verdict: 'OK', reason: 'no persistence claim found for this command' };
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
// ---------------------------------------------------------------------------
|
|
1381
|
+
// defaultScanFiles(repoRoot) -- the complete scan set, enumerated at run
|
|
1382
|
+
// time: lib/mcp/tool-router.cjs, lib/mcp/tools/*.cjs (sorted), and
|
|
1383
|
+
// lib/mcp/contract-version.cjs. Nothing else in lib/mcp/ calls server.tool(
|
|
1384
|
+
// (verified by grep during planning).
|
|
1385
|
+
// ---------------------------------------------------------------------------
|
|
1386
|
+
function defaultScanFiles(repoRoot) {
|
|
1387
|
+
const files = [];
|
|
1388
|
+
const toolRouter = path.join(repoRoot, 'lib', 'mcp', 'tool-router.cjs');
|
|
1389
|
+
if (fs.existsSync(toolRouter)) {
|
|
1390
|
+
files.push({ absPath: toolRouter, relPath: 'lib/mcp/tool-router.cjs' });
|
|
1391
|
+
}
|
|
1392
|
+
const toolsDir = path.join(repoRoot, 'lib', 'mcp', 'tools');
|
|
1393
|
+
if (fs.existsSync(toolsDir)) {
|
|
1394
|
+
for (const f of fs.readdirSync(toolsDir).filter((x) => x.endsWith('.cjs')).sort()) {
|
|
1395
|
+
files.push({ absPath: path.join(toolsDir, f), relPath: 'lib/mcp/tools/' + f });
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
const contractVersion = path.join(repoRoot, 'lib', 'mcp', 'contract-version.cjs');
|
|
1399
|
+
if (fs.existsSync(contractVersion)) {
|
|
1400
|
+
files.push({ absPath: contractVersion, relPath: 'lib/mcp/contract-version.cjs' });
|
|
1401
|
+
}
|
|
1402
|
+
return files;
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
// ---------------------------------------------------------------------------
|
|
1406
|
+
// scanAll(opts) -- the pure programmatic scan API. Never calls process.exit.
|
|
1407
|
+
// opts: { repoRoot, primitives, files: [{absPath, relPath}] }
|
|
1408
|
+
// Returns { rows, toolCount, branchCount }.
|
|
1409
|
+
// rows[]: { tool, command, file, verdict, reason, claimPhrase }
|
|
1410
|
+
// verdict in {'OK','LOW','MEDIUM','HIGH_RISK','UNKNOWN'}.
|
|
1411
|
+
// ---------------------------------------------------------------------------
|
|
1412
|
+
function scanAll(opts) {
|
|
1413
|
+
const o = opts || {};
|
|
1414
|
+
const repoRoot = o.repoRoot || REPO_ROOT;
|
|
1415
|
+
const primitives = o.primitives || resolveWritePrimitives();
|
|
1416
|
+
const files = o.files || defaultScanFiles(repoRoot);
|
|
1417
|
+
const moduleCache = new Map();
|
|
1418
|
+
const bodyCache = new Map();
|
|
1419
|
+
const rows = [];
|
|
1420
|
+
let toolCount = 0;
|
|
1421
|
+
let branchCount = 0;
|
|
1422
|
+
|
|
1423
|
+
for (const f of files) {
|
|
1424
|
+
let fileText;
|
|
1425
|
+
try {
|
|
1426
|
+
fileText = fs.readFileSync(f.absPath, 'utf8');
|
|
1427
|
+
} catch (_e) {
|
|
1428
|
+
continue;
|
|
1429
|
+
}
|
|
1430
|
+
const fileMasked = maskNonCode(fileText);
|
|
1431
|
+
const fileRequireMap = collectRequireBindings(fileText, fileMasked);
|
|
1432
|
+
const toolCalls = findServerToolCalls(fileText, fileMasked);
|
|
1433
|
+
|
|
1434
|
+
for (const call of toolCalls) {
|
|
1435
|
+
const args = splitTopLevelArgs(call.innerText);
|
|
1436
|
+
if (args.length < 4) continue;
|
|
1437
|
+
const [nameArg, descArg, schemaArg, handlerArg] = args;
|
|
1438
|
+
const toolName = extractStringLiteralConcat(nameArg);
|
|
1439
|
+
if (!toolName) continue;
|
|
1440
|
+
const description = extractStringLiteralConcat(descArg);
|
|
1441
|
+
const vocabulary = extractCommandVocabulary(schemaArg, fileText, fileMasked);
|
|
1442
|
+
const handlerBodyText = extractHandlerBody(handlerArg);
|
|
1443
|
+
if (handlerBodyText === null) continue;
|
|
1444
|
+
|
|
1445
|
+
toolCount += 1;
|
|
1446
|
+
const claims = extractClaims(description, vocabulary);
|
|
1447
|
+
const { branchMap, sharedBodyText } = splitBranches(handlerBodyText, fileText, fileMasked);
|
|
1448
|
+
|
|
1449
|
+
const reachByCommand = {};
|
|
1450
|
+
for (const cmd of vocabulary) {
|
|
1451
|
+
const ownText = branchMap[cmd] || '';
|
|
1452
|
+
const effectiveText = ownText + '\n' + sharedBodyText;
|
|
1453
|
+
reachByCommand[cmd] = {
|
|
1454
|
+
effectiveText,
|
|
1455
|
+
verdict: resolveReachability(effectiveText, {
|
|
1456
|
+
primitives,
|
|
1457
|
+
fileText,
|
|
1458
|
+
filePath: f.absPath,
|
|
1459
|
+
repoRoot,
|
|
1460
|
+
fileRequireMap,
|
|
1461
|
+
moduleCache,
|
|
1462
|
+
bodyCache,
|
|
1463
|
+
}),
|
|
1464
|
+
};
|
|
1465
|
+
}
|
|
1466
|
+
const anyBranchWrites = Object.keys(reachByCommand).some((cmd) => reachByCommand[cmd].verdict === 'WRITES');
|
|
1467
|
+
|
|
1468
|
+
for (const cmd of vocabulary) {
|
|
1469
|
+
branchCount += 1;
|
|
1470
|
+
const info = reachByCommand[cmd];
|
|
1471
|
+
const verdictInfo = classifyBranch({
|
|
1472
|
+
command: cmd,
|
|
1473
|
+
effectiveText: info.effectiveText,
|
|
1474
|
+
claims,
|
|
1475
|
+
reachability: info.verdict,
|
|
1476
|
+
anyBranchWrites,
|
|
1477
|
+
});
|
|
1478
|
+
rows.push({
|
|
1479
|
+
tool: toolName,
|
|
1480
|
+
command: cmd,
|
|
1481
|
+
file: f.relPath,
|
|
1482
|
+
verdict: verdictInfo.verdict,
|
|
1483
|
+
reason: verdictInfo.reason,
|
|
1484
|
+
claimPhrase: verdictInfo.claim ? verdictInfo.claim.phrase : null,
|
|
1485
|
+
});
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
for (const row of rows) {
|
|
1491
|
+
if (row.verdict !== 'HIGH_RISK') continue;
|
|
1492
|
+
const allowed = ALLOWED_UNVERIFIED.find((a) => a.tool === row.tool && a.command === row.command);
|
|
1493
|
+
if (allowed) {
|
|
1494
|
+
row.verdict = 'OK';
|
|
1495
|
+
row.reason = 'allow-listed (triaged): ' + allowed.reason;
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
return { rows, toolCount, branchCount };
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
// ---------------------------------------------------------------------------
|
|
1503
|
+
// checkTree(opts) -- scanAll() plus the verdict-bucketed summary the CLI and
|
|
1504
|
+
// doctor --acceptance gate consume.
|
|
1505
|
+
// ---------------------------------------------------------------------------
|
|
1506
|
+
function checkTree(opts) {
|
|
1507
|
+
const { rows, toolCount, branchCount } = scanAll(opts);
|
|
1508
|
+
return {
|
|
1509
|
+
rows,
|
|
1510
|
+
toolCount,
|
|
1511
|
+
branchCount,
|
|
1512
|
+
highRisk: rows.filter((r) => r.verdict === 'HIGH_RISK'),
|
|
1513
|
+
medium: rows.filter((r) => r.verdict === 'MEDIUM'),
|
|
1514
|
+
low: rows.filter((r) => r.verdict === 'LOW'),
|
|
1515
|
+
unknown: rows.filter((r) => r.verdict === 'UNKNOWN'),
|
|
1516
|
+
ok: rows.filter((r) => r.verdict === 'OK'),
|
|
1517
|
+
};
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1520
|
+
// ---------------------------------------------------------------------------
|
|
1521
|
+
// CLI, matching scripts/check-shape-declaration.cjs's contract.
|
|
1522
|
+
// --check : ADVISORY. 0 high-risk -> one-line OK, exit 0.
|
|
1523
|
+
// N high-risk -> WARN block enumerating each, exit 0.
|
|
1524
|
+
// --check --strict : N high-risk -> hard-fail block, exit 1.
|
|
1525
|
+
// --report : full per-branch table (every verdict), exit 0.
|
|
1526
|
+
// (no flag) : usage, exit 2.
|
|
1527
|
+
// ---------------------------------------------------------------------------
|
|
1528
|
+
function main() {
|
|
1529
|
+
const argv = process.argv.slice(2);
|
|
1530
|
+
|
|
1531
|
+
if (argv.includes('--report')) {
|
|
1532
|
+
const { rows, toolCount, branchCount } = scanAll();
|
|
1533
|
+
console.log('check-tool-honesty --report: ' + toolCount + ' tool(s), ' + branchCount + ' branch(es) scanned');
|
|
1534
|
+
console.log('');
|
|
1535
|
+
for (const r of rows) {
|
|
1536
|
+
console.log('[' + r.verdict + '] ' + r.tool + '.' + r.command + ' (' + r.file + '): ' + r.reason);
|
|
1537
|
+
}
|
|
1538
|
+
return;
|
|
1539
|
+
}
|
|
1540
|
+
|
|
1541
|
+
if (argv.includes('--check')) {
|
|
1542
|
+
const strict = argv.includes('--strict');
|
|
1543
|
+
const report = checkTree();
|
|
1544
|
+
if (report.highRisk.length === 0) {
|
|
1545
|
+
console.log(
|
|
1546
|
+
'check-tool-honesty: OK (' + report.toolCount + ' tool(s), ' +
|
|
1547
|
+
report.branchCount + ' branch(es) scanned, 0 high-risk)' +
|
|
1548
|
+
(strict ? ' [strict mode]' : '')
|
|
1549
|
+
);
|
|
1550
|
+
return;
|
|
1551
|
+
}
|
|
1552
|
+
if (strict) {
|
|
1553
|
+
console.error('TOOL HONESTY VIOLATION:');
|
|
1554
|
+
for (const f of report.highRisk) {
|
|
1555
|
+
console.error(' - ' + f.tool + '.' + f.command + ': ' + f.verdict + ' -- claims "' + (f.claimPhrase || '') + '" but no write primitive is reachable');
|
|
1556
|
+
}
|
|
1557
|
+
console.error('Recovery: fix the description or wire the write, or add a triaged entry to ALLOWED_UNVERIFIED in scripts/check-tool-honesty.cjs with a stated reason.');
|
|
1558
|
+
console.error('strict mode: exiting 1 (--strict restores the hard-fail contract)');
|
|
1559
|
+
process.exit(1);
|
|
1560
|
+
return;
|
|
1561
|
+
}
|
|
1562
|
+
console.error(
|
|
1563
|
+
'WARN: tool-honesty advisory: ' + report.highRisk.length +
|
|
1564
|
+
' high-risk finding(s) detected; not blocking (run with --strict to restore hard-fail)'
|
|
1565
|
+
);
|
|
1566
|
+
for (const f of report.highRisk) {
|
|
1567
|
+
console.error('WARN: - ' + f.tool + '.' + f.command + ': ' + f.verdict + ' -- claims "' + (f.claimPhrase || '') + '" but no write primitive is reachable');
|
|
1568
|
+
}
|
|
1569
|
+
console.error('Recovery: fix the description or wire the write, or add a triaged entry to ALLOWED_UNVERIFIED in scripts/check-tool-honesty.cjs with a stated reason.');
|
|
1570
|
+
return;
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
console.error('usage: node scripts/check-tool-honesty.cjs [--check [--strict] | --report]');
|
|
1574
|
+
process.exit(2);
|
|
1575
|
+
}
|
|
1576
|
+
|
|
1577
|
+
if (require.main === module) {
|
|
1578
|
+
main();
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1581
|
+
module.exports = {
|
|
1582
|
+
scanAll,
|
|
1583
|
+
checkTree,
|
|
1584
|
+
classifyBranch,
|
|
1585
|
+
extractClaims,
|
|
1586
|
+
resolveWritePrimitives,
|
|
1587
|
+
splitTopLevelArgs,
|
|
1588
|
+
ALLOWED_UNVERIFIED,
|
|
1589
|
+
// Exposed for finer-grained testing / debugging, not part of the load-
|
|
1590
|
+
// bearing nine-assertion contract.
|
|
1591
|
+
maskNonCode,
|
|
1592
|
+
scanBalanced,
|
|
1593
|
+
extractStringLiteralConcat,
|
|
1594
|
+
extractCommandVocabulary,
|
|
1595
|
+
splitBranches,
|
|
1596
|
+
resolveReachability,
|
|
1597
|
+
defaultScanFiles,
|
|
1598
|
+
locateFunctionBody,
|
|
1599
|
+
followReexportHop,
|
|
1600
|
+
resolveRepoLocalPath,
|
|
1601
|
+
};
|