@event4u/agent-config 9.7.0 → 9.9.0
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/marketplace.json +1 -1
- package/CHANGELOG.md +314 -190
- package/CONTRIBUTING.md +23 -7
- package/MIGRATION.md +20 -0
- package/README.md +57 -11
- package/dist/agent-src/commands/agents/audit.md +1 -1
- package/dist/agent-src/commands/agents/optimize.md +2 -2
- package/dist/agent-src/commands/agents/user.md +1 -1
- package/dist/agent-src/commands/agents.md +1 -1
- package/dist/agent-src/commands/check-current-md.md +3 -3
- package/dist/agent-src/commands/commit/in-chunks.md +8 -0
- package/dist/agent-src/commands/commit.md +17 -0
- package/dist/agent-src/commands/fix/portability.md +2 -2
- package/dist/agent-src/commands/fix/pr-comments-loop.md +136 -0
- package/dist/agent-src/commands/fix/refs.md +2 -2
- package/dist/agent-src/commands/fix/route.md +4 -3
- package/dist/agent-src/commands/fix.md +9 -6
- package/dist/agent-src/commands/ghostwriter.md +1 -1
- package/dist/agent-src/commands/image.md +1 -1
- package/dist/agent-src/commands/optimize/augmentignore.md +1 -1
- package/dist/agent-src/commands/optimize/skills.md +2 -2
- package/dist/agent-src/commands/post-as.md +1 -1
- package/dist/agent-src/commands/pr/create.md +4 -0
- package/dist/agent-src/commands/research.md +1 -1
- package/dist/agent-src/commands/roadmap/ai-council.md +1 -1
- package/dist/agent-src/commands/security-audit-config.md +1 -1
- package/dist/agent-src/commands/team/delegate.md +4 -0
- package/dist/agent-src/commands/video.md +1 -1
- package/dist/agent-src/contexts/authority/kernel-rule-edits.md +1 -1
- package/dist/agent-src/contexts/contracts/emergency-triage-block.md +2 -2
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +48 -2
- package/dist/agent-src/contexts/execution/orchestration-telemetry.md +10 -0
- package/dist/agent-src/contexts/execution/subagent-modes-detail.md +109 -8
- package/dist/agent-src/contexts/execution/subagent-response-contract.md +20 -0
- package/dist/agent-src/contexts/execution/subagent-spawn-contract.md +53 -3
- package/dist/agent-src/contexts/override-system.md +75 -5
- package/dist/agent-src/rules/code-provenance.md +112 -0
- package/dist/agent-src/rules/context-hygiene.md +2 -0
- package/dist/agent-src/rules/doc-screenshot-hygiene.md +97 -0
- package/dist/agent-src/rules/domain-safety-pii.md +1 -0
- package/dist/agent-src/rules/external-code-graph-interop.md +13 -3
- package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +2 -0
- package/dist/agent-src/rules/git-history-discipline.md +2 -0
- package/dist/agent-src/rules/history-discipline.md +80 -0
- package/dist/agent-src/rules/language-and-tone.md +2 -0
- package/dist/agent-src/rules/lethal-trifecta-guard.md +3 -0
- package/dist/agent-src/rules/media-governance-routing.md +2 -0
- package/dist/agent-src/rules/minimal-safe-diff.md +2 -0
- package/dist/agent-src/rules/no-roadmap-references.md +4 -1
- package/dist/agent-src/rules/non-destructive-by-default.md +20 -0
- package/dist/agent-src/rules/onboarding-gate.md +2 -0
- package/dist/agent-src/rules/output-discipline.md +2 -0
- package/dist/agent-src/rules/persona-governance.md +2 -0
- package/dist/agent-src/rules/php-coding.md +1 -0
- package/dist/agent-src/rules/preservation-guard.md +3 -0
- package/dist/agent-src/rules/reviewer-awareness.md +1 -0
- package/dist/agent-src/rules/roadmap-ci-steps-policy.md +1 -0
- package/dist/agent-src/rules/roadmap-progress-sync.md +9 -0
- package/dist/agent-src/rules/scale-discipline.md +92 -0
- package/dist/agent-src/rules/secret-vcs-guard.md +106 -0
- package/dist/agent-src/rules/security-sensitive-stop.md +11 -1
- package/dist/agent-src/rules/session-canary.md +77 -0
- package/dist/agent-src/rules/skill-quality.md +2 -0
- package/dist/agent-src/rules/source-confidentiality.md +2 -0
- package/dist/agent-src/rules/source-of-truth.md +2 -0
- package/dist/agent-src/rules/telegraph-speak.md +2 -0
- package/dist/agent-src/rules/token-optimizer-maintenance.md +3 -1
- package/dist/agent-src/rules/tool-safety.md +4 -1
- package/dist/agent-src/rules/untrusted-input-defense.md +10 -0
- package/dist/agent-src/rules/verify-before-complete.md +2 -0
- package/dist/agent-src/skills/adr-create/SKILL.md +17 -1
- package/dist/agent-src/skills/agent-security-review/SKILL.md +1 -1
- package/dist/agent-src/skills/code-intelligence/SKILL.md +97 -0
- package/dist/agent-src/skills/condense-memory/SKILL.md +1 -1
- package/dist/agent-src/skills/corpus-grounding/SKILL.md +0 -3
- package/dist/agent-src/skills/description-assist/SKILL.md +1 -1
- package/dist/agent-src/skills/design-review/SKILL.md +5 -6
- package/dist/agent-src/skills/design-tokens/SKILL.md +0 -1
- package/dist/agent-src/skills/gated-reach/SKILL.md +185 -0
- package/dist/agent-src/skills/gated-reach/evals/triggers.json +72 -0
- package/dist/agent-src/skills/history-design/SKILL.md +101 -0
- package/dist/agent-src/skills/history-design/evals/triggers.json +17 -0
- package/dist/agent-src/skills/humanizer/SKILL.md +3 -3
- package/dist/agent-src/skills/image-analyser/SKILL.md +14 -12
- package/dist/agent-src/skills/image-editing/SKILL.md +2 -1
- package/dist/agent-src/skills/image-generation/SKILL.md +2 -1
- package/dist/agent-src/skills/image-provider-routing/SKILL.md +2 -2
- package/dist/agent-src/skills/launch-readiness/SKILL.md +1 -1
- package/dist/agent-src/skills/license-compliance-audit/SKILL.md +161 -0
- package/dist/agent-src/skills/license-compliance-audit/evals/triggers.json +52 -0
- package/dist/agent-src/skills/license-compliance-borrow-check/SKILL.md +145 -0
- package/dist/agent-src/skills/license-compliance-borrow-check/evals/triggers.json +52 -0
- package/dist/agent-src/skills/license-compliance-credits/SKILL.md +97 -0
- package/dist/agent-src/skills/license-compliance-credits/evals/triggers.json +52 -0
- package/dist/agent-src/skills/md-language-check/SKILL.md +1 -1
- package/dist/agent-src/skills/override-management/SKILL.md +1 -1
- package/dist/agent-src/skills/prediction-pool-optimizer/SKILL.md +7 -7
- package/dist/agent-src/skills/project-analysis-core/SKILL.md +1 -1
- package/dist/agent-src/skills/prompt-engineering-image/SKILL.md +3 -2
- package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +2 -2
- package/dist/agent-src/skills/readme-writing/SKILL.md +6 -1
- package/dist/agent-src/skills/recursive-verification/SKILL.md +6 -0
- package/dist/agent-src/skills/refine-ticket/SKILL.md +3 -3
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +4 -0
- package/dist/agent-src/skills/rtk-output-filtering/SKILL.md +31 -12
- package/dist/agent-src/skills/rule-refactor/SKILL.md +3 -3
- package/dist/agent-src/skills/schema-review/SKILL.md +92 -0
- package/dist/agent-src/skills/schema-review/evals/triggers.json +17 -0
- package/dist/agent-src/skills/screenshot-hygiene/SKILL.md +171 -0
- package/dist/agent-src/skills/secrets-management/SKILL.md +43 -1
- package/dist/agent-src/skills/security-audit/SKILL.md +1 -1
- package/dist/agent-src/skills/security-maturity-assessment/SKILL.md +1 -1
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +3 -3
- package/dist/agent-src/skills/skill-writing/SKILL.md +2 -2
- package/dist/agent-src/skills/source-discovery/SKILL.md +5 -5
- package/dist/agent-src/skills/subagent-orchestration/SKILL.md +45 -85
- package/dist/agent-src/skills/subagent-orchestration/prompts/README.md +5 -4
- package/dist/agent-src/skills/subagent-orchestration/prompts/adversarial-verification-council.md +29 -0
- package/dist/agent-src/skills/subagent-orchestration/prompts/do-and-judge-two-stage.md +29 -0
- package/dist/agent-src/skills/subagent-orchestration/prompts/do-and-judge.md +29 -0
- package/dist/agent-src/skills/subagent-orchestration/prompts/do-competitively.md +29 -0
- package/dist/agent-src/skills/subagent-orchestration/prompts/do-in-parallel.md +29 -0
- package/dist/agent-src/skills/subagent-orchestration/prompts/do-in-steps.md +29 -0
- package/dist/agent-src/skills/subagent-orchestration/prompts/do-in-worktrees.md +29 -0
- package/dist/agent-src/skills/subagent-orchestration/prompts/judge-with-debate.md +29 -0
- package/dist/agent-src/skills/systematic-debugging/SKILL.md +2 -2
- package/dist/agent-src/skills/tailwind-engineer/SKILL.md +2 -3
- package/dist/agent-src/skills/token-optimizer/SKILL.md +4 -4
- package/dist/agent-src/skills/verify-repair-loop/SKILL.md +4 -0
- package/dist/agent-src/skills/worktree-lifecycle/SKILL.md +2 -3
- package/dist/agent-src/templates/AGENTS.md +1 -1
- package/dist/agent-src/templates/agents/.gitattributes.fragment +25 -6
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/command.md +3 -3
- package/dist/agent-src/templates/github-workflows/secret-scan.yml +65 -0
- package/dist/agent-src/templates/persona.md +2 -2
- package/dist/agent-src/templates/rule.md +2 -2
- package/dist/agent-src/templates/scripts/telemetry/engagement.ts +77 -0
- package/dist/agent-src/templates/scripts/telemetry_record.ts +33 -1
- package/dist/cli/commands/doctorShell.js +20 -0
- package/dist/cli/commands/doctorShell.js.map +1 -1
- package/dist/cli/commands/rtkDetect.js +58 -0
- package/dist/cli/commands/rtkDetect.js.map +1 -0
- package/dist/cli/configRoot.js +112 -0
- package/dist/cli/configRoot.js.map +1 -0
- package/dist/cli/configRoot.test.js +97 -0
- package/dist/cli/configRoot.test.js.map +1 -0
- package/dist/cli/firstRunNotice.js +70 -0
- package/dist/cli/firstRunNotice.js.map +1 -0
- package/dist/cli/help.js +4 -1
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/main.js +54 -5
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/registry.js +8 -1
- package/dist/cli/registry.js.map +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +502 -101
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +6 -4
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +95 -8
- package/dist/discovery/trust-report.md +11 -11
- package/dist/discovery/workspaces.json +36 -7
- package/dist/hooks/dispatch.js +19475 -0
- package/dist/install/agentSwitchDetection.js +75 -0
- package/dist/install/agentSwitchDetection.js.map +1 -0
- package/dist/install/agentSwitchProfile.js +117 -0
- package/dist/install/agentSwitchProfile.js.map +1 -0
- package/dist/install/atomic.js +1 -1
- package/dist/install/detect.js +1 -1
- package/dist/install/install.mjs +791 -486
- package/dist/install/rtkDetection.js +213 -0
- package/dist/install/rtkDetection.js.map +1 -0
- package/dist/install/rule_scope.js +2 -1
- package/dist/install/rule_scope.js.map +1 -1
- package/dist/install/types.js +2 -2
- package/dist/install/wizard-plan.js +1 -1
- package/dist/install/wizardDismissals.js +58 -0
- package/dist/install/wizardDismissals.js.map +1 -0
- package/dist/mcp/awesome-mcp-servers.row.md +1 -1
- package/dist/mcp/mcp-cloudflare-catalogue.json +1 -1
- package/dist/mcp/registry-manifest.json +15 -4
- package/dist/mcp/server.json +20 -0
- package/dist/mcp/server.mjs +44292 -0
- package/dist/router.json +1 -1
- package/dist/scripts/condense.js +14 -7
- package/dist/scripts/condense.js.map +1 -1
- package/dist/server/app.js +12 -0
- package/dist/server/app.js.map +1 -1
- package/dist/server/io/sharedWriteCheck.js +101 -0
- package/dist/server/io/sharedWriteCheck.js.map +1 -0
- package/dist/server/routes/ping.js +32 -0
- package/dist/server/routes/ping.js.map +1 -1
- package/dist/server/routes/settings.js +21 -4
- package/dist/server/routes/settings.js.map +1 -1
- package/dist/server/routes/userMd.js +21 -4
- package/dist/server/routes/userMd.js.map +1 -1
- package/dist/server/routes/wizard.js +68 -25
- package/dist/server/routes/wizard.js.map +1 -1
- package/dist/server/schemas/settings.js +12 -2
- package/dist/server/schemas/settings.js.map +1 -1
- package/dist/server/serverInfo.js +6 -2
- package/dist/server/serverInfo.js.map +1 -1
- package/dist/server/token.js +11 -4
- package/dist/server/token.js.map +1 -1
- package/dist/server/writeRoot.js +15 -1
- package/dist/server/writeRoot.js.map +1 -1
- package/dist/shared/capabilities.js +33 -0
- package/dist/shared/capabilities.js.map +1 -0
- package/dist/shared/capabilities.test.js +39 -0
- package/dist/shared/capabilities.test.js.map +1 -0
- package/dist/ui/assets/index-BpSQt5vm.js +40 -0
- package/dist/ui/assets/index-BpSQt5vm.js.map +1 -0
- package/dist/ui/assets/index-jSfMW8_t.css +1 -0
- package/dist/ui/index.html +15 -6
- package/docs/MIGRATION.md +16 -0
- package/docs/guidelines/component-oriented-and-oop-development.md +4 -2
- package/package.json +22 -9
- package/src/agent-src/templates/AGENTS.md +1 -1
- package/src/agent-src/templates/scripts/telemetry/engagement.ts +77 -0
- package/src/agent-src/templates/scripts/telemetry_record.ts +33 -1
- package/src/config/agent-settings.template.yml +94 -13
- package/src/config/discovery/packs.yml +22 -0
- package/src/config/discovery/workspaces.yml +1 -1
- package/src/config/evaluator-budgets.json +47 -0
- package/src/config/hook-latency-budget.json +20 -0
- package/src/config/reach-channels.yml +217 -0
- package/src/config/reach-prescriptions-intake.yml +200 -0
- package/src/install/agentSwitchDetection.ts +90 -0
- package/src/install/agentSwitchProfile.ts +131 -0
- package/src/install/atomic.ts +1 -1
- package/src/install/detect.ts +1 -1
- package/src/install/rtkDetection.ts +274 -0
- package/src/install/rule_scope.ts +9 -2
- package/src/install/types.ts +2 -2
- package/src/install/wizard-plan.ts +1 -1
- package/src/install/wizardDismissals.ts +60 -0
- package/src/scripts/_cli/cmd_doctor.ts +62 -1
- package/src/scripts/_cli/cmd_memory_get.ts +197 -0
- package/src/scripts/_cli/cmd_refresh.ts +30 -0
- package/src/scripts/_dispatch.bash +96 -0
- package/src/scripts/_lib/auto_dispatch.corpus.test.ts +64 -1
- package/src/scripts/_lib/auto_dispatch.ts +76 -0
- package/src/scripts/_lib/detect_target_license.ts +714 -0
- package/src/scripts/_lib/exec_evidence.ts +251 -0
- package/src/scripts/_lib/fixtures/secret-detector/negatives.txt +15 -0
- package/src/scripts/_lib/fixtures/secret-detector/positives.txt +15 -0
- package/src/scripts/_lib/install_drift.ts +194 -0
- package/src/scripts/_lib/kernel_rules.ts +46 -0
- package/src/scripts/_lib/memory_fts_index.ts +390 -0
- package/src/scripts/_lib/orchestration_record.ts +91 -2
- package/src/scripts/_lib/persistence/adapter_raw_sql.ts +443 -0
- package/src/scripts/_lib/persistence/detect_audit_coverage.ts +423 -0
- package/src/scripts/_lib/persistence/detect_bounded_reads.ts +154 -0
- package/src/scripts/_lib/persistence/detect_index_parity.ts +576 -0
- package/src/scripts/_lib/persistence/detect_n1_eloquent.ts +226 -0
- package/src/scripts/_lib/persistence/detect_offload.ts +441 -0
- package/src/scripts/_lib/persistence/detect_prisma_growth.ts +74 -0
- package/src/scripts/_lib/persistence/offload_catalog.ts +73 -0
- package/src/scripts/_lib/persistence/types.ts +109 -0
- package/src/scripts/_lib/reddit_thread_parse.ts +598 -0
- package/src/scripts/_lib/risk_paths.ts +160 -0
- package/src/scripts/_lib/rtk_allowlist.ts +44 -0
- package/src/scripts/_lib/secret_detector.test.ts +108 -0
- package/src/scripts/_lib/secret_detector.ts +328 -0
- package/src/scripts/_lib/secret_detector_adversarial.test.ts +116 -0
- package/src/scripts/_lib/spawn_env.ts +7 -0
- package/src/scripts/_lib/sqlite_guard.ts +191 -0
- package/src/scripts/_lib/subagent_spawn.ts +53 -0
- package/src/scripts/_lib/tool_probe.ts +359 -0
- package/src/scripts/_lib/worker_budget.ts +107 -0
- package/src/scripts/adr/regenerate_index.ts +81 -6
- package/src/scripts/ai_council/blind_review.ts +0 -0
- package/src/scripts/ai_council/config.ts +12 -6
- package/src/scripts/ai_council/orchestrator.ts +73 -3
- package/src/scripts/ai_team/review_gate.ts +8 -10
- package/src/scripts/ai_team/team_dispatch.ts +48 -0
- package/src/scripts/audit_adr_coverage.ts +33 -0
- package/src/scripts/audit_initial_context.ts +1 -1
- package/src/scripts/bench_cross_source_eval.ts +400 -0
- package/src/scripts/bench_honesty_score.ts +1093 -0
- package/src/scripts/bench_hook_latency.ts +218 -0
- package/src/scripts/build_mcp_catalog.ts +275 -0
- package/src/scripts/build_mcp_registry_manifest.ts +46 -0
- package/src/scripts/build_proof.ts +207 -0
- package/src/scripts/chat_history.ts +8 -5
- package/src/scripts/check_adr_frontmatter.ts +195 -0
- package/src/scripts/check_artefact_count_messaging.ts +4 -0
- package/src/scripts/check_backstop_debt.ts +210 -0
- package/src/scripts/check_bundle_path_leakage.ts +343 -0
- package/src/scripts/check_claims.ts +188 -8
- package/src/scripts/check_comparison.ts +12 -0
- package/src/scripts/check_enforcement_coverage.ts +592 -0
- package/src/scripts/check_evaluator_budgets.ts +99 -0
- package/src/scripts/check_kernel_rule_bundle.ts +16 -12
- package/src/scripts/check_knowledge_sharing.ts +12 -1
- package/src/scripts/check_no_external_sources.ts +2 -2
- package/src/scripts/check_reach_channels.ts +407 -0
- package/src/scripts/check_reach_staleness.ts +364 -0
- package/src/scripts/check_secret_leak.test.ts +47 -0
- package/src/scripts/check_secret_leak.ts +290 -0
- package/src/scripts/check_source_pointer_freshness.ts +28 -3
- package/src/scripts/code_graph/build.ts +0 -0
- package/src/scripts/code_graph/cli.ts +379 -0
- package/src/scripts/code_graph/detect.ts +186 -0
- package/src/scripts/code_graph/extract.ts +386 -0
- package/src/scripts/code_graph/intent.ts +45 -0
- package/src/scripts/code_graph/loader.ts +123 -0
- package/src/scripts/code_graph/query.ts +290 -0
- package/src/scripts/code_graph/sanitize.ts +30 -0
- package/src/scripts/code_graph/sqlite_store.ts +174 -0
- package/src/scripts/code_graph/types.ts +83 -0
- package/src/scripts/code_graph/validate.ts +63 -0
- package/src/scripts/condense.ts +14 -6
- package/src/scripts/context_hygiene_hook.ts +8 -5
- package/src/scripts/council_cli.ts +126 -12
- package/src/scripts/detect_target_license.ts +203 -0
- package/src/scripts/evaluator_umbrella.sh +145 -0
- package/src/scripts/external_sources_denylist.json +8 -4
- package/src/scripts/first_run_gate_hook.ts +9 -5
- package/src/scripts/generate_subagent_floor.ts +194 -0
- package/src/scripts/hermetic-install.sh +3 -3
- package/src/scripts/hook_manifest.yaml +65 -16
- package/src/scripts/hooks/block_kernel_rule_writes.ts +212 -0
- package/src/scripts/hooks/block_no_verify.ts +9 -9
- package/src/scripts/hooks/code_graph_nudge_hook.ts +191 -0
- package/src/scripts/hooks/concern_registry.ts +75 -0
- package/src/scripts/hooks/design_slop_hook.ts +8 -5
- package/src/scripts/hooks/dispatch_entry.ts +37 -0
- package/src/scripts/hooks/dispatch_hook.ts +176 -3
- package/src/scripts/hooks/hook_stdin.ts +42 -0
- package/src/scripts/hooks/rtk_wrap_hook.ts +26 -12
- package/src/scripts/hot_context_hook.ts +7 -6
- package/src/scripts/injection_scan_hook.ts +9 -1
- package/src/scripts/install +6 -6
- package/src/scripts/install-hooks.sh +4 -4
- package/src/scripts/install.sh +5 -4
- package/src/scripts/install.ts +264 -23
- package/src/scripts/iron_law_sha.ts +3 -12
- package/src/scripts/learning_sidecar.ts +0 -0
- package/src/scripts/lint_budget_ownership.ts +89 -0
- package/src/scripts/lint_command_routing.ts +35 -5
- package/src/scripts/lint_command_verbs.ts +42 -9
- package/src/scripts/lint_consumer_internal_refs.ts +211 -0
- package/src/scripts/lint_discovery_vocabulary.ts +2 -0
- package/src/scripts/lint_documented_commands.ts +670 -0
- package/src/scripts/lint_framework_leakage.ts +17 -3
- package/src/scripts/lint_framework_leakage_allowlist.json +32 -0
- package/src/scripts/lint_governed_writes.ts +335 -0
- package/src/scripts/lint_hidden_unicode.ts +6 -0
- package/src/scripts/lint_mcp_registry_manifest.ts +26 -1
- package/src/scripts/lint_memory_tripwire.ts +186 -0
- package/src/scripts/lint_override_kernel_guard.ts +267 -0
- package/src/scripts/lint_persistence.ts +171 -0
- package/src/scripts/lint_pre_migration_refs.ts +106 -0
- package/src/scripts/lint_provenance.ts +547 -0
- package/src/scripts/lint_provenance_vocabulary.ts +437 -0
- package/src/scripts/lint_spawn_payload.ts +283 -0
- package/src/scripts/lint_store_boundary.ts +152 -0
- package/src/scripts/lint_versioned_cache.ts +7 -1
- package/src/scripts/mcp_server/__main__.ts +7 -2
- package/src/scripts/mcp_server/catalog.ts +23 -1
- package/src/scripts/mcp_server/consumer_tool_catalog.json +563 -193
- package/src/scripts/mcp_server/prompts.ts +6 -0
- package/src/scripts/mcp_server/tool_catalog_source.ts +332 -0
- package/src/scripts/mcp_server/tools.ts +56 -5
- package/src/scripts/mcp_telemetry_query.ts +2 -33
- package/src/scripts/mcp_telemetry_store.ts +64 -34
- package/src/scripts/measure_rule_budget.ts +3 -12
- package/src/scripts/memory_learn_hook.ts +126 -0
- package/src/scripts/memory_lookup.ts +0 -0
- package/src/scripts/memory_replay_24.ts +312 -0
- package/src/scripts/memory_report.ts +16 -3
- package/src/scripts/memory_signal.ts +48 -0
- package/src/scripts/memory_status.ts +6 -0
- package/src/scripts/minimal_safe_diff_hook.ts +8 -5
- package/src/scripts/onboarding_gate_hook.ts +8 -5
- package/src/scripts/orchestration_record.ts +16 -0
- package/src/scripts/pr_url_reminder_hook.ts +8 -1
- package/src/scripts/prepack-check.mjs +17 -0
- package/src/scripts/prepack_lifecycle_check.d.mts +8 -0
- package/src/scripts/prepack_lifecycle_check.mjs +82 -0
- package/src/scripts/profile_staleness_hook.ts +8 -7
- package/src/scripts/reach_doctor.ts +1651 -0
- package/src/scripts/release.ts +24 -3
- package/src/scripts/report_install_drift.ts +109 -0
- package/src/scripts/risk_escalation_shadow.ts +160 -0
- package/src/scripts/roadmap_progress_hook.ts +8 -5
- package/src/scripts/schemas/agent-settings.schema.json +23 -0
- package/src/scripts/schemas/license-policy.schema.json +89 -0
- package/src/scripts/schemas/provenance-borrow.schema.json +46 -0
- package/src/scripts/schemas/reach-channels.schema.json +134 -0
- package/src/scripts/schemas/reach-doctor-payload.schema.json +220 -0
- package/src/scripts/schemas/rule.schema.json +20 -0
- package/src/scripts/self_review_gate.test.ts +173 -1
- package/src/scripts/self_review_gate.ts +155 -15
- package/src/scripts/session_canary_hook.ts +182 -0
- package/src/scripts/skill_linter.ts +55 -0
- package/src/scripts/smoke_quickstart.ts +2 -2
- package/src/scripts/surface_probe_hook.ts +8 -7
- package/src/scripts/sync_gitattributes.ts +310 -0
- package/src/scripts/team_review_gate_hook.ts +13 -16
- package/src/scripts/validate_reach_prescriptions.ts +751 -0
- package/src/scripts/verify_before_complete_hook.ts +8 -5
- package/src/scripts/wrapper_freshness_hook.ts +8 -7
- package/src/server/schemas/settings.ts +24 -2
- package/src/shared/capabilities.test.ts +43 -0
- package/src/shared/capabilities.ts +75 -0
- package/src/templates/minimal/agents-overrides-readme.md +20 -0
- package/dist/ui/assets/index-BPFMZWUs.css +0 -1
- package/dist/ui/assets/index-BiEZiZ31.js +0 -40
- package/dist/ui/assets/index-BiEZiZ31.js.map +0 -1
- package/docs/CLAIMS.md +0 -261
- package/docs/DISTRIBUTION_CHECKLIST.md +0 -170
- package/docs/RELEASE_STORY_TEMPLATE.md +0 -37
- package/docs/SKILL_CENSUS.md +0 -352
- package/docs/adrs/cost/0001-hard-stop-hook.md +0 -114
- package/docs/adrs/cost/README.md +0 -9
- package/docs/adrs/memory/0001-consumer-side-snapshot.md +0 -119
- package/docs/adrs/memory/README.md +0 -10
- package/docs/adrs/router/0001-three-tier-routing.md +0 -119
- package/docs/adrs/router/README.md +0 -9
- package/docs/adrs/schema/0001-json-schema-frontmatter.md +0 -102
- package/docs/adrs/schema/README.md +0 -9
- package/docs/adrs/smoke/0001-per-tier-smoke-scripts.md +0 -99
- package/docs/adrs/smoke/README.md +0 -9
- package/docs/adrs/telegraph/0001-default-off-until-bench.md +0 -93
- package/docs/adrs/telegraph/README.md +0 -9
- package/docs/announcements/2026-05-non-dev-launch.md +0 -79
- package/docs/announcements/2026-07-honest-cost-sweep-launch.md +0 -84
- package/docs/anti-reskin-gate.md +0 -60
- package/docs/architecture/augment-projection.md +0 -70
- package/docs/architecture/claude-bundle.md +0 -77
- package/docs/architecture/current-onboard-baseline.md +0 -126
- package/docs/architecture/current-safety-behavior.md +0 -137
- package/docs/architecture/multi-tool-projection.md +0 -125
- package/docs/architecture/setup-vs-settings-shared-surface.md +0 -114
- package/docs/architecture/source-projection.md +0 -85
- package/docs/architecture.md +0 -390
- package/docs/archive/CHANGELOG-6.0.0-overview.md +0 -953
- package/docs/archive/CHANGELOG-7.0.0.md +0 -419
- package/docs/archive/CHANGELOG-pre-2.11.0.md +0 -141
- package/docs/archive/CHANGELOG-pre-2.15.0.md +0 -244
- package/docs/archive/CHANGELOG-pre-2.16.0.md +0 -48
- package/docs/archive/CHANGELOG-pre-2.17.0.md +0 -63
- package/docs/archive/CHANGELOG-pre-2.2.0.md +0 -2138
- package/docs/archive/CHANGELOG-pre-2.20.0.md +0 -159
- package/docs/archive/CHANGELOG-pre-2.25.0.md +0 -191
- package/docs/archive/CHANGELOG-pre-2.7.0.md +0 -185
- package/docs/archive/CHANGELOG-pre-3.0.0.md +0 -130
- package/docs/archive/CHANGELOG-pre-3.1.0.md +0 -167
- package/docs/archive/CHANGELOG-pre-3.2.0.md +0 -268
- package/docs/archive/CHANGELOG-pre-4.0.0.md +0 -80
- package/docs/archive/CHANGELOG-pre-4.5.0.md +0 -289
- package/docs/archive/CHANGELOG-pre-5.4.0.md +0 -260
- package/docs/archive/CHANGELOG-pre-5.9.0.md +0 -270
- package/docs/archive/CHANGELOG-pre-6.0.0.md +0 -473
- package/docs/archive/CHANGELOG-pre-7.0.0.md +0 -126
- package/docs/archive/CHANGELOG-pre-8.0.0.md +0 -301
- package/docs/archive/CHANGELOG-pre-8.1.0.md +0 -316
- package/docs/archive/CHANGELOG-pre-8.12.0.md +0 -304
- package/docs/archive/CHANGELOG-pre-8.9.0.md +0 -306
- package/docs/archive/CHANGELOG-pre-9.2.0.md +0 -276
- package/docs/artefact-census.md +0 -71
- package/docs/benchmark.md +0 -648
- package/docs/benchmark.pinned.yml +0 -31
- package/docs/benchmarks.md +0 -85
- package/docs/capability-matrix.md +0 -33
- package/docs/case-studies/_template.md +0 -60
- package/docs/case-studies/frontend-design-positioning.md +0 -86
- package/docs/catalog.md +0 -721
- package/docs/command-flows.md +0 -272
- package/docs/command-naming-audit.md +0 -60
- package/docs/comparison.yaml +0 -45
- package/docs/contracts/CHANGELOG-conventions.md +0 -149
- package/docs/contracts/STABILITY.md +0 -188
- package/docs/contracts/adoption-signal-floor.md +0 -127
- package/docs/contracts/adr-architectural-consensus-mechanism.md +0 -68
- package/docs/contracts/adr-chat-history-split.md +0 -140
- package/docs/contracts/adr-command-suggestion.md +0 -144
- package/docs/contracts/adr-forecast-construction-shape.md +0 -90
- package/docs/contracts/adr-gtm-context-spine.md +0 -116
- package/docs/contracts/adr-implement-ticket-runtime.md +0 -121
- package/docs/contracts/adr-install-user-type-axis.md +0 -107
- package/docs/contracts/adr-layout.md +0 -107
- package/docs/contracts/adr-level-6-productization.md +0 -145
- package/docs/contracts/adr-mcp-runtime.md +0 -128
- package/docs/contracts/adr-product-ui-track.md +0 -381
- package/docs/contracts/adr-prompt-driven-execution.md +0 -186
- package/docs/contracts/adr-settings-sync-engine.md +0 -128
- package/docs/contracts/adr-user-types-axis.md +0 -127
- package/docs/contracts/adr-wing4-context-spine.md +0 -126
- package/docs/contracts/agent-user-schema.md +0 -170
- package/docs/contracts/agents-layout.md +0 -148
- package/docs/contracts/agents-md-tech-stack.md +0 -75
- package/docs/contracts/ai-council-config.md +0 -829
- package/docs/contracts/ai-team-config.md +0 -224
- package/docs/contracts/analysis-memory-loop.md +0 -149
- package/docs/contracts/at-rest-encryption.md +0 -191
- package/docs/contracts/audit-log-v1.md +0 -150
- package/docs/contracts/auto-orchestration-v1.md +0 -70
- package/docs/contracts/benchmark-ab-contract.md +0 -106
- package/docs/contracts/benchmark-corpus-spec.md +0 -125
- package/docs/contracts/benchmark-report-schema.md +0 -113
- package/docs/contracts/branch-protection-policy.md +0 -139
- package/docs/contracts/brand-token-consumption.md +0 -74
- package/docs/contracts/capability-boundary.md +0 -69
- package/docs/contracts/capability-packs.md +0 -217
- package/docs/contracts/ci-cost-budget.md +0 -111
- package/docs/contracts/ci-green-floor.md +0 -141
- package/docs/contracts/command-category-governance.md +0 -84
- package/docs/contracts/command-clusters.md +0 -399
- package/docs/contracts/command-surface-tiers.md +0 -176
- package/docs/contracts/command-taxonomy.md +0 -137
- package/docs/contracts/condensation-default-kill-criterion.md +0 -116
- package/docs/contracts/config-presets.md +0 -144
- package/docs/contracts/conformance.md +0 -84
- package/docs/contracts/consumer-bridge.md +0 -73
- package/docs/contracts/context-paths.md +0 -101
- package/docs/contracts/context-spine.md +0 -179
- package/docs/contracts/cost-dashboard.md +0 -143
- package/docs/contracts/cost-enforcement.md +0 -134
- package/docs/contracts/cost-profile-defaults.md +0 -110
- package/docs/contracts/cost-summary-schema.md +0 -107
- package/docs/contracts/creative-pack-boundary.md +0 -63
- package/docs/contracts/cross-repo-retrieval.md +0 -64
- package/docs/contracts/cross-wing-handoff.md +0 -134
- package/docs/contracts/daily-workspace.md +0 -147
- package/docs/contracts/decision-engine-gates.md +0 -120
- package/docs/contracts/decision-trace-v1.md +0 -177
- package/docs/contracts/design-artifact-lifecycle.md +0 -93
- package/docs/contracts/design-artifact-verification.md +0 -153
- package/docs/contracts/discovery-manifest.md +0 -209
- package/docs/contracts/discovery-manifest.schema.json +0 -254
- package/docs/contracts/evidence-based-pruning.md +0 -102
- package/docs/contracts/explain-modes.md +0 -187
- package/docs/contracts/explain-trace.schema.json +0 -144
- package/docs/contracts/file-ownership-matrix.json +0 -13941
- package/docs/contracts/file-ownership-matrix.md +0 -135
- package/docs/contracts/frontmatter-contract.md +0 -140
- package/docs/contracts/ghostwriter-schema.md +0 -337
- package/docs/contracts/governance-enforcement-projection.md +0 -159
- package/docs/contracts/gui-wizard.md +0 -350
- package/docs/contracts/harness-expectations.md +0 -128
- package/docs/contracts/hook-architecture-v1.md +0 -325
- package/docs/contracts/host-agent-protocol.md +0 -110
- package/docs/contracts/implement-ticket-flow.md +0 -625
- package/docs/contracts/init-telemetry.md +0 -132
- package/docs/contracts/injected-block-authenticity-model.md +0 -66
- package/docs/contracts/install-layout.md +0 -249
- package/docs/contracts/install-scopes.md +0 -82
- package/docs/contracts/installed-tools-lockfile.md +0 -144
- package/docs/contracts/installer-agent-mode.md +0 -137
- package/docs/contracts/iron-law-overrides.txt +0 -26
- package/docs/contracts/kernel-membership.md +0 -339
- package/docs/contracts/linear-ai-rules-inclusion.md +0 -143
- package/docs/contracts/linear-ai-three-layers.md +0 -130
- package/docs/contracts/linter-structural-model.md +0 -181
- package/docs/contracts/load-context-budget-model.md +0 -259
- package/docs/contracts/load-context-schema.md +0 -220
- package/docs/contracts/local-analytics.md +0 -160
- package/docs/contracts/local-knowledge-ingestion.md +0 -96
- package/docs/contracts/local-server-api.md +0 -134
- package/docs/contracts/low-impact-corpus-format.md +0 -95
- package/docs/contracts/mcp-beta-criteria.md +0 -130
- package/docs/contracts/mcp-cloud-scope.md +0 -355
- package/docs/contracts/mcp-discovery-phase-notice.md +0 -60
- package/docs/contracts/mcp-phase-1-scope.md +0 -272
- package/docs/contracts/mcp-registry-manifest.schema.json +0 -129
- package/docs/contracts/mcp-tool-inventory.md +0 -64
- package/docs/contracts/mcp-tool-stub-envelope.md +0 -78
- package/docs/contracts/measurement-baseline.md +0 -103
- package/docs/contracts/memory-visibility-v1.md +0 -160
- package/docs/contracts/mental-models.md +0 -336
- package/docs/contracts/migrate-command.md +0 -233
- package/docs/contracts/multi-tool-projection-fidelity.md +0 -134
- package/docs/contracts/namespace.md +0 -125
- package/docs/contracts/no-runtime-boundary.md +0 -61
- package/docs/contracts/one-off-script-lifecycle.md +0 -110
- package/docs/contracts/orchestration-dsl-v1.md +0 -153
- package/docs/contracts/package-self-orientation.md +0 -163
- package/docs/contracts/pilot/agent-authority.md +0 -24
- package/docs/contracts/pilot/direct-answers.md +0 -70
- package/docs/contracts/pilot/language-and-tone.md +0 -63
- package/docs/contracts/plain-language-surface.md +0 -117
- package/docs/contracts/prelaunch-diagnostics.md +0 -151
- package/docs/contracts/profile-system.md +0 -167
- package/docs/contracts/reasoning-discipline-protocol.md +0 -83
- package/docs/contracts/release-pr-gating.md +0 -151
- package/docs/contracts/release-sizing.md +0 -107
- package/docs/contracts/release-trunk-sync.md +0 -105
- package/docs/contracts/review-lens-schema.md +0 -64
- package/docs/contracts/roadmap-complexity-standard.md +0 -138
- package/docs/contracts/role-experience.md +0 -125
- package/docs/contracts/router-blending.md +0 -71
- package/docs/contracts/rule-classification.md +0 -171
- package/docs/contracts/rule-interactions.md +0 -132
- package/docs/contracts/rule-interactions.yml +0 -260
- package/docs/contracts/rule-priority-hierarchy.md +0 -88
- package/docs/contracts/rule-router.md +0 -287
- package/docs/contracts/safety-model.md +0 -129
- package/docs/contracts/session-profile-overlay.md +0 -157
- package/docs/contracts/settings-api.md +0 -264
- package/docs/contracts/settings-gui-agent-mode.schema.json +0 -128
- package/docs/contracts/settings-sync-yaml-subset.md +0 -139
- package/docs/contracts/skill-bundled-assets.md +0 -62
- package/docs/contracts/skill-discovery.md +0 -80
- package/docs/contracts/skill-distribution-channels.md +0 -66
- package/docs/contracts/skill-domains.md +0 -144
- package/docs/contracts/skill-dry-run.md +0 -47
- package/docs/contracts/skill-family-map.yml +0 -915
- package/docs/contracts/smoke-contracts.md +0 -144
- package/docs/contracts/subagent-boundary.md +0 -59
- package/docs/contracts/surface-agent-contracts.md +0 -153
- package/docs/contracts/surface-matrix.md +0 -108
- package/docs/contracts/surface-tiers.md +0 -81
- package/docs/contracts/telegraph-telemetry.md +0 -83
- package/docs/contracts/ticket-bundle-format.md +0 -233
- package/docs/contracts/tier-3-contrib-plugin.md +0 -137
- package/docs/contracts/trust-and-safety.md +0 -144
- package/docs/contracts/ui-stack-extension.md +0 -237
- package/docs/contracts/ui-track-flow.md +0 -329
- package/docs/contracts/universal-skills.md +0 -91
- package/docs/contracts/user-type-schema.md +0 -146
- package/docs/contracts/value-dashboard-spec.md +0 -378
- package/docs/contracts/value-report-schema.md +0 -168
- package/docs/contracts/workflow-packs.md +0 -121
- package/docs/contracts/workspace-boundary.md +0 -84
- package/docs/contracts/workspace-documents.md +0 -144
- package/docs/contracts/write-engine.md +0 -182
- package/docs/cookbook.md +0 -152
- package/docs/customization.md +0 -685
- package/docs/decisions/ADR-001-kernel-swap-deferred.md +0 -109
- package/docs/decisions/ADR-002-kernel-bucket-overrides.md +0 -135
- package/docs/decisions/ADR-003-flat-cluster-subs-and-colon-syntax.md +0 -137
- package/docs/decisions/ADR-004-rule-governance-pruning.md +0 -240
- package/docs/decisions/ADR-005-subagent-worktrees.md +0 -120
- package/docs/decisions/ADR-006-skill-tools-python-pilot.md +0 -114
- package/docs/decisions/ADR-007-agent-discovery-scopes.md +0 -371
- package/docs/decisions/ADR-008-installed-tools-manifest.md +0 -160
- package/docs/decisions/ADR-009-event4u-namespace.md +0 -188
- package/docs/decisions/ADR-010-profile-pack-preset-boundary.md +0 -168
- package/docs/decisions/ADR-011-domain-pack-readiness.md +0 -213
- package/docs/decisions/ADR-012-typescript-cli-shell.md +0 -162
- package/docs/decisions/ADR-013-discovery-frontmatter-contract.md +0 -342
- package/docs/decisions/ADR-014-gui-framework-choice.md +0 -136
- package/docs/decisions/ADR-015-discovery-manifest-contract.md +0 -146
- package/docs/decisions/ADR-016-installer-architecture.md +0 -189
- package/docs/decisions/ADR-017-monorepo-physical-layout.md +0 -261
- package/docs/decisions/ADR-018-trust-and-safety-layer.md +0 -159
- package/docs/decisions/ADR-019-router-json-dist-location.md +0 -124
- package/docs/decisions/ADR-020-global-only-consumer-scope.md +0 -213
- package/docs/decisions/ADR-021-deployment-shape.md +0 -153
- package/docs/decisions/ADR-022-daily-workspace-decomposition.md +0 -140
- package/docs/decisions/ADR-023-host-agent-protocol.md +0 -129
- package/docs/decisions/ADR-024-workspace-v0-feature-floor.md +0 -126
- package/docs/decisions/ADR-025-workspace-chrome.md +0 -119
- package/docs/decisions/ADR-026-explain-mode-translation.md +0 -117
- package/docs/decisions/ADR-027-changelog-machine-vs-manual.md +0 -129
- package/docs/decisions/ADR-028-root-layout.md +0 -147
- package/docs/decisions/ADR-029-multi-workspace-deferred.md +0 -122
- package/docs/decisions/ADR-030-claude-code-command-projection.md +0 -147
- package/docs/decisions/ADR-031-validation-severity-tiers-and-projection-roundtrip.md +0 -97
- package/docs/decisions/ADR-032-linked-projects-scope.md +0 -122
- package/docs/decisions/ADR-033-distribution-identity-npm-primary.md +0 -81
- package/docs/decisions/ADR-034-per-skill-model-recommendation-transport.md +0 -63
- package/docs/decisions/ADR-035-model-capability-tiers.md +0 -104
- package/docs/decisions/ADR-036-global-install-browser-wizard-handoff.md +0 -106
- package/docs/decisions/ADR-037-cost-profile-untangle.md +0 -117
- package/docs/decisions/ADR-038-canonical-settings-path.md +0 -96
- package/docs/decisions/ADR-039-claude-skills-untracked.md +0 -139
- package/docs/decisions/ADR-040-execution-model-projection-time-filtering.md +0 -244
- package/docs/decisions/ADR-041-controlled-command-verbs.md +0 -133
- package/docs/decisions/ADR-042-runtime-resolver-decision-gate.md +0 -113
- package/docs/decisions/ADR-043-monorepo-collapse-to-src-domains.md +0 -128
- package/docs/decisions/ADR-044-command-naming-scheme-hyphenated.md +0 -250
- package/docs/decisions/ADR-045-src-source-layout-and-profiles-as-views.md +0 -111
- package/docs/decisions/ADR-046-thin-command-principle.md +0 -93
- package/docs/decisions/ADR-047-framework-neutral-stack-adaptive-commands.md +0 -94
- package/docs/decisions/ADR-048-command-justification-rule.md +0 -106
- package/docs/decisions/ADR-049-configuration-trust-boundary.md +0 -132
- package/docs/decisions/ADR-050-workspace-vs-package-root-boundary.md +0 -121
- package/docs/decisions/ADR-051-uncondensed-source-container-relocation.md +0 -114
- package/docs/decisions/ADR-052-packages-removal-and-pack-home-migration.md +0 -86
- package/docs/decisions/ADR-053-agents-namespace-dual-role-resolution.md +0 -132
- package/docs/decisions/ADR-054-rule-adherence-decay-triggered-restate.md +0 -143
- package/docs/decisions/ADR-055-flow-layer-data-model.md +0 -235
- package/docs/decisions/ADR-056-unvalidated-video-adapters-disposition.md +0 -124
- package/docs/decisions/ADR-057-consolidation-evidence-gate-outcomes.md +0 -135
- package/docs/decisions/ADR-058-condensed-output-relocation-to-dist.md +0 -94
- package/docs/decisions/ADR-059-render-resume-filesystem-as-state.md +0 -161
- package/docs/decisions/ADR-060-comfyui-sandbox-model.md +0 -154
- package/docs/decisions/ADR-061-corpus-grounding-layer.md +0 -230
- package/docs/decisions/ADR-062-encrypt-at-rest-store-architecture.md +0 -121
- package/docs/decisions/ADR-063-append-jsonl-encryption-deferred.md +0 -83
- package/docs/decisions/ADR-064-append-jsonl-per-record-encryption.md +0 -113
- package/docs/decisions/ADR-065-tier3-inbox-handoff-v0.md +0 -86
- package/docs/decisions/ADR-066-skill-body-prerendering.md +0 -93
- package/docs/decisions/ADR-067-glama-registry-listing.md +0 -259
- package/docs/decisions/ADR-068-host-tier-detection.md +0 -90
- package/docs/decisions/ADR-069-prompt-renderer.md +0 -97
- package/docs/decisions/ADR-070-tier1-drive-loop.md +0 -94
- package/docs/decisions/ADR-071-launch-drive-integration.md +0 -95
- package/docs/decisions/ADR-072-codex-gemini-drive-configs.md +0 -90
- package/docs/decisions/ADR-073-drive-health-kill-switch.md +0 -81
- package/docs/decisions/ADR-074-drive-kill-switch-auto-recovery.md +0 -84
- package/docs/decisions/ADR-075-workspace-gui-drive.md +0 -83
- package/docs/decisions/ADR-076-workspace-multi-turn.md +0 -92
- package/docs/decisions/ADR-077-workspace-followup-gui.md +0 -70
- package/docs/decisions/ADR-078-drive-health-panel.md +0 -70
- package/docs/decisions/ADR-079-workspace-host-picker.md +0 -81
- package/docs/decisions/ADR-080-host-session-expired-410.md +0 -92
- package/docs/decisions/ADR-081-drive-health-reset-and-410-affordance.md +0 -71
- package/docs/decisions/ADR-082-410-one-click-relaunch.md +0 -58
- package/docs/decisions/ADR-083-session-thread-and-arbitrary-continuation.md +0 -85
- package/docs/decisions/ADR-084-drive-health-refresh-on-drive.md +0 -52
- package/docs/decisions/ADR-085-mcp-stdio-end-user-distribution-shape.md +0 -158
- package/docs/decisions/ADR-086-read-only-cross-agent-mcp-discovery-helper.md +0 -171
- package/docs/decisions/ADR-087-installer-e2e-test-strategy.md +0 -111
- package/docs/decisions/ADR-088-no-external-runtime-federation.md +0 -144
- package/docs/decisions/ADR-089-lean-local-plugin-install.md +0 -111
- package/docs/decisions/ADR-090-visibility-command-frontmatter-field.md +0 -95
- package/docs/decisions/ADR-091-split-meta-capability-packs.md +0 -113
- package/docs/decisions/ADR-092-defer-command-tier-alias-removal.md +0 -117
- package/docs/decisions/ADR-093-ai-council-config-user-global.md +0 -117
- package/docs/decisions/ADR-094-agent-memory-layer-removal.md +0 -94
- package/docs/decisions/ADR-095-workspace-boundary-contract.md +0 -108
- package/docs/decisions/ADR-096-analysis-workbench.md +0 -110
- package/docs/decisions/ADR-097-mission-recipe-privilege-boundary.md +0 -121
- package/docs/decisions/ADR-098-evidence-first-structure-discovery.md +0 -154
- package/docs/decisions/ADR-099-file-first-pattern-library.md +0 -87
- package/docs/decisions/ADR-100-global-knowledge-card-sharing.md +0 -140
- package/docs/decisions/ADR-101-ticket-bundle-emission.md +0 -109
- package/docs/decisions/ADR-102-ticket-handoff-paste-and-mcp.md +0 -72
- package/docs/decisions/ADR-103-global-knowledge-default-off-until-measured.md +0 -92
- package/docs/decisions/ADR-104-ai-council-config-global-only.md +0 -119
- package/docs/decisions/ADR-105-automatic-subagent-orchestration.md +0 -108
- package/docs/decisions/ADR-106-recursive-verification-benchmark-gate.md +0 -126
- package/docs/decisions/ADR-107-legal-domain-pack-adoption.md +0 -70
- package/docs/decisions/ADR-108-open-source-forever-no-commercial-tier.md +0 -46
- package/docs/decisions/ADR-109-subagent-v1-contract.md +0 -246
- package/docs/decisions/ADR-110-discipline-profile-resolution-locus.md +0 -110
- package/docs/decisions/ADR-111-canonical-glama-listing.md +0 -97
- package/docs/decisions/ADR-112-stdio-lite-stays-read-only.md +0 -92
- package/docs/decisions/ADR-113-ci-native-release-label-trigger.md +0 -201
- package/docs/decisions/ADR-114-commit-policy-iron-law-override.md +0 -85
- package/docs/decisions/ADR-115-command-cluster-consolidation-phase-4.md +0 -91
- package/docs/decisions/ADR-116-memory-tripwire-activation-path.md +0 -144
- package/docs/decisions/ADR-117-subagents-auto-default-on.md +0 -89
- package/docs/decisions/ADR-118-loop-engineering-boundaries.md +0 -162
- package/docs/decisions/ADR-119-global-knowledge-default-on.md +0 -104
- package/docs/decisions/ADR-120-council-chairman-mode.md +0 -70
- package/docs/decisions/ADR-121-knowledge-sensitivity-classes.md +0 -90
- package/docs/decisions/ADR-122-adversarial-verification-council.md +0 -166
- package/docs/decisions/ADR-123-runtime-security-scope-and-spawn-hardening.md +0 -142
- package/docs/decisions/ADR-200-python-to-typescript-migration.md +0 -203
- package/docs/decisions/ADR-rule-kernel-and-router.md +0 -133
- package/docs/decisions/INDEX.md +0 -136
- package/docs/deploy/connector-setup.md +0 -129
- package/docs/deploy/env-vars.md +0 -70
- package/docs/deploy/policy-cookbook.md +0 -130
- package/docs/deploy/quickstart.md +0 -112
- package/docs/deploy/small-team-recipe.md +0 -148
- package/docs/deploy/team-deployment-posture.md +0 -111
- package/docs/design/adversarial-council-eval.md +0 -106
- package/docs/design/council-vs-solo-baseline.md +0 -92
- package/docs/design/cross-model-parity-eval.md +0 -82
- package/docs/design/length-neutral-judge-rerun.md +0 -92
- package/docs/design/utilization-window-criteria.md +0 -51
- package/docs/development.md +0 -230
- package/docs/distribution/awesome-list-submission.md +0 -46
- package/docs/distribution/consumer-matrix.md +0 -96
- package/docs/distribution/launch-story-draft.md +0 -58
- package/docs/distribution/mcp-submission-checklist.md +0 -95
- package/docs/distribution/public-install-smoke.md +0 -68
- package/docs/distribution/registries.md +0 -117
- package/docs/distribution/registry-submissions.md +0 -85
- package/docs/distribution/telemetry-privacy.md +0 -128
- package/docs/distribution/telemetry-schema.md +0 -174
- package/docs/distribution/topics-equivalents-decay-policy.md +0 -51
- package/docs/end-to-end-walkthroughs.md +0 -165
- package/docs/enforcement-by-host.md +0 -44
- package/docs/examples/agent-user.example.md +0 -22
- package/docs/experiences/agency.md +0 -49
- package/docs/experiences/content_creator.md +0 -49
- package/docs/experiences/developer.md +0 -49
- package/docs/experiences/finance.md +0 -50
- package/docs/experiences/founder.md +0 -49
- package/docs/experiences/ops.md +0 -49
- package/docs/featured-commands.md +0 -27
- package/docs/featured-skills.md +0 -95
- package/docs/flows.md +0 -67
- package/docs/getting-started-by-role.md +0 -190
- package/docs/getting-started-laravel.md +0 -72
- package/docs/getting-started-local-stdio.md +0 -77
- package/docs/getting-started.md +0 -254
- package/docs/github-topics.md +0 -93
- package/docs/governance-advantage.md +0 -72
- package/docs/governance.md +0 -96
- package/docs/guides/cross-repo-linked-projects.md +0 -93
- package/docs/guides/cross-repo-retrieval.md +0 -61
- package/docs/guides/frontend-design-corpus-refresh.md +0 -83
- package/docs/guides/local-analytics.md +0 -125
- package/docs/guides/local-knowledge.md +0 -127
- package/docs/guides/skill-discovery.md +0 -71
- package/docs/guides/skill-preview.md +0 -71
- package/docs/hook-payload-capture.md +0 -221
- package/docs/install-friction-report.md +0 -66
- package/docs/installation.md +0 -959
- package/docs/maintainers/branch-protection.md +0 -105
- package/docs/maintainers/dev-mode.md +0 -106
- package/docs/maintainers/optional-media-deps.md +0 -50
- package/docs/maintainers/system-map.md +0 -85
- package/docs/mcp-registries.md +0 -94
- package/docs/mcp-server.md +0 -175
- package/docs/mcp.md +0 -147
- package/docs/media/proof-demo.cast +0 -14
- package/docs/media/proof-demo.gif +0 -0
- package/docs/migration/consumer-template-consumption-model.md +0 -145
- package/docs/migration/divergences/README.md +0 -55
- package/docs/migration/divergences/_template.md +0 -50
- package/docs/migration/divergences/bench-stats-float-precision.md +0 -72
- package/docs/migration/divergences/mcp-telemetry-node-sqlite.md +0 -61
- package/docs/migration/divergences/pack-mcp-content-gzip-body.md +0 -53
- package/docs/migration/divergences/src-scripts-build_cloud_bundle.md +0 -63
- package/docs/migration/divergences/src-scripts-check_memory.md +0 -91
- package/docs/migration/divergences/src-scripts-inventory_abstraction_budget.md +0 -65
- package/docs/migration/divergences/src-scripts-lint_marketplace.md +0 -57
- package/docs/migration/divergences/src-scripts-lint_mcp_registry_manifest.md +0 -70
- package/docs/migration/divergences/src-scripts-spotcheck_thin_root.md +0 -60
- package/docs/migration/divergences/src-scripts-validate_agent_settings.md +0 -58
- package/docs/migration/node-floor.md +0 -86
- package/docs/migration/v1-to-v2.md +0 -156
- package/docs/migration/yaml-roundtrip-spike.md +0 -163
- package/docs/migrations/commands-1.15.0.md +0 -117
- package/docs/parity/bench-external.json +0 -58
- package/docs/parity/bench.json +0 -41
- package/docs/parity/command-frontmatter.md +0 -60
- package/docs/parity/external-runtime.md +0 -46
- package/docs/personas.md +0 -178
- package/docs/positioning-evidence.md +0 -86
- package/docs/profiles.md +0 -108
- package/docs/proof.md +0 -176
- package/docs/quality.md +0 -98
- package/docs/readme-split-plan.md +0 -102
- package/docs/recruits/_template.md +0 -81
- package/docs/release-runbook.md +0 -141
- package/docs/role-experiences.md +0 -19
- package/docs/safety.md +0 -30
- package/docs/second-brain-scope.md +0 -116
- package/docs/self-review-gate.md +0 -65
- package/docs/setup/enterprise-and-offline.md +0 -201
- package/docs/setup/mcp-client-config.md +0 -358
- package/docs/setup/mcp-cloud-endpoints.md +0 -116
- package/docs/setup/mcp-cloud-registry-listing.md +0 -99
- package/docs/setup/mcp-cloud-setup.md +0 -183
- package/docs/setup/mcp-r2-bootstrap.md +0 -82
- package/docs/setup/mcp-server-docker.md +0 -101
- package/docs/setup/per-ide/aider.md +0 -48
- package/docs/setup/per-ide/antigravity.md +0 -68
- package/docs/setup/per-ide/augment.md +0 -89
- package/docs/setup/per-ide/claude-code.md +0 -97
- package/docs/setup/per-ide/claude-desktop.md +0 -207
- package/docs/setup/per-ide/cline.md +0 -43
- package/docs/setup/per-ide/codebuddy.md +0 -63
- package/docs/setup/per-ide/codex.md +0 -46
- package/docs/setup/per-ide/continue.md +0 -68
- package/docs/setup/per-ide/copilot.md +0 -80
- package/docs/setup/per-ide/cursor.md +0 -125
- package/docs/setup/per-ide/droid.md +0 -65
- package/docs/setup/per-ide/gemini-cli.md +0 -45
- package/docs/setup/per-ide/jetbrains.md +0 -76
- package/docs/setup/per-ide/kilocode.md +0 -66
- package/docs/setup/per-ide/kiro.md +0 -72
- package/docs/setup/per-ide/opencode.md +0 -62
- package/docs/setup/per-ide/qoder.md +0 -63
- package/docs/setup/per-ide/roocode.md +0 -68
- package/docs/setup/per-ide/trae.md +0 -63
- package/docs/setup/per-ide/warp.md +0 -63
- package/docs/setup/per-ide/windsurf.md +0 -109
- package/docs/setup/per-ide/zed.md +0 -73
- package/docs/showcase.md +0 -209
- package/docs/skill-duplication-findings.md +0 -91
- package/docs/skills-catalog.md +0 -265
- package/docs/skills-taxonomy.md +0 -90
- package/docs/spawn-site-policy.md +0 -72
- package/docs/succession.md +0 -80
- package/docs/threat-model.md +0 -29
- package/docs/troubleshooting.md +0 -155
- package/docs/ui-track-mental-model.md +0 -121
- package/docs/us-vs-the-category.md +0 -38
- package/docs/value.md +0 -86
- package/docs/walkthroughs/assets/workspace-role-grid.png +0 -0
- package/docs/walkthroughs/assets/workspace-session-started.png +0 -0
- package/docs/walkthroughs/assets/workspace-task-picker.png +0 -0
- package/docs/walkthroughs/daily-workspace-a11y.md +0 -87
- package/docs/walkthroughs/daily-workspace.md +0 -127
- package/docs/wedge/production-validator/README.md +0 -81
- package/docs/wedge/production-validator/first-run-check.sh +0 -42
- package/docs/wedge/production-validator/production-validator.md +0 -83
- package/docs/wizard.md +0 -173
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query tier — one engine, two sources (ADR-124 § 2). Runs identically over
|
|
3
|
+
* the native cache and a consumer-shipped `graph.json`; every answer names
|
|
4
|
+
* which source answered. BFS/DFS with a token budget; hybrid seed-matching
|
|
5
|
+
* (exact id / label → BM25 fallback via `_lib/lexical_index.ts`). All string
|
|
6
|
+
* fields pass the retrieved-content sanitizer before returning.
|
|
7
|
+
*/
|
|
8
|
+
import * as fs from 'node:fs';
|
|
9
|
+
|
|
10
|
+
import { LexicalIndex, tokenize } from '../_lib/lexical_index.js';
|
|
11
|
+
import { sanitizeLabel } from './sanitize.js';
|
|
12
|
+
import { emitSqliteTwin, loadSerializedFromTwin } from './sqlite_store.js';
|
|
13
|
+
import type { CodeEdge, CodeGraph } from './types.js';
|
|
14
|
+
import { validateGraph } from './validate.js';
|
|
15
|
+
|
|
16
|
+
const APPROX_CHARS_PER_TOKEN = 4;
|
|
17
|
+
|
|
18
|
+
export interface LoadedGraph {
|
|
19
|
+
graph: CodeGraph;
|
|
20
|
+
source: string; // attribution path
|
|
21
|
+
byId: Map<string, CodeGraph['nodes'][number]>;
|
|
22
|
+
out: Map<string, CodeEdge[]>;
|
|
23
|
+
in: Map<string, CodeEdge[]>;
|
|
24
|
+
lex: LexicalIndex;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function loadGraph(graphPath: string, source = graphPath): LoadedGraph {
|
|
28
|
+
// Prefer the derived SQLite twin (ADR-129): checksum/stat-verified against
|
|
29
|
+
// the canonical JSON, byte-identical content, ~1/90 the load cost at
|
|
30
|
+
// consumer scale. Fallback = parse the JSON — and best-effort re-emit the
|
|
31
|
+
// twin from it (zero-touch rebuild-on-drift, Phase 7).
|
|
32
|
+
const fromTwin = loadSerializedFromTwin(graphPath);
|
|
33
|
+
const raw = fromTwin ?? fs.readFileSync(graphPath, 'utf-8');
|
|
34
|
+
const parsed = JSON.parse(raw) as unknown;
|
|
35
|
+
const v = validateGraph(parsed);
|
|
36
|
+
if (!v.ok) throw new Error(`invalid graph at ${graphPath}: ${v.errors.slice(0, 3).join('; ')}`);
|
|
37
|
+
const graph = parsed as CodeGraph;
|
|
38
|
+
if (fromTwin === null) {
|
|
39
|
+
emitSqliteTwin(graph, raw, graphPath);
|
|
40
|
+
}
|
|
41
|
+
const byId = new Map(graph.nodes.map((n) => [n.id, n]));
|
|
42
|
+
const outM = new Map<string, CodeEdge[]>();
|
|
43
|
+
const inM = new Map<string, CodeEdge[]>();
|
|
44
|
+
const add = (m: Map<string, CodeEdge[]>, k: string, e: CodeEdge): void => {
|
|
45
|
+
const arr = m.get(k);
|
|
46
|
+
if (arr) arr.push(e);
|
|
47
|
+
else m.set(k, [e]);
|
|
48
|
+
};
|
|
49
|
+
for (const e of graph.edges) {
|
|
50
|
+
add(outM, e.source, e);
|
|
51
|
+
add(inM, e.target, e);
|
|
52
|
+
}
|
|
53
|
+
const lex = new LexicalIndex(graph.nodes.map((n) => ({ id: n.id, text: `${n.label} ${n.id}` })));
|
|
54
|
+
return { graph, source, byId, out: outM, in: inM, lex };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
interface SeedResolution {
|
|
58
|
+
ids: string[];
|
|
59
|
+
/** true when NEITHER an exact-id nor an exact-label match was found and
|
|
60
|
+
* resolution fell back to BM25 — a best-guess, not a confirmed hit. */
|
|
61
|
+
weak: boolean;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Resolve a free-text seed to node ids: exact id → exact label → BM25. */
|
|
65
|
+
function resolveSeedsTiered(g: LoadedGraph, seed: string, limit = 5): SeedResolution {
|
|
66
|
+
if (g.byId.has(seed)) return { ids: [seed], weak: false };
|
|
67
|
+
const exactLabel = g.graph.nodes.filter((n) => n.label === seed).map((n) => n.id);
|
|
68
|
+
if (exactLabel.length) return { ids: exactLabel.slice(0, limit), weak: false };
|
|
69
|
+
const ranked = g.lex.rank(tokenize(seed)).filter((r) => r.score > 0);
|
|
70
|
+
return { ids: ranked.slice(0, limit).map((r) => r.id), weak: true };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Resolve a free-text seed to node ids: exact id → exact label → BM25. */
|
|
74
|
+
export function resolveSeeds(g: LoadedGraph, seed: string, limit = 5): string[] {
|
|
75
|
+
return resolveSeedsTiered(g, seed, limit).ids;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function label(g: LoadedGraph, id: string): string {
|
|
79
|
+
return sanitizeLabel(g.byId.get(id)?.label ?? id);
|
|
80
|
+
}
|
|
81
|
+
function edgeLine(g: LoadedGraph, e: CodeEdge): string {
|
|
82
|
+
const cand = e.candidates?.length ? ` [${e.candidates.map((c) => sanitizeLabel(c)).join(', ')}]` : '';
|
|
83
|
+
return `${e.confidence} ${sanitizeLabel(e.source)} --${e.relation}--> ${sanitizeLabel(e.target)}${cand}`;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* A file + (when known) a 1-based inclusive line range worth reading directly
|
|
88
|
+
* — surfaced whenever the engine dropped or under-trusted something instead
|
|
89
|
+
* of silently truncating it (Phase 9 D4: "a read plan instead of silent
|
|
90
|
+
* truncation").
|
|
91
|
+
*/
|
|
92
|
+
export interface RecommendedRead {
|
|
93
|
+
path: string;
|
|
94
|
+
lines: [number, number] | null;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface QueryResult {
|
|
98
|
+
source: string;
|
|
99
|
+
seeds: string[];
|
|
100
|
+
lines: string[];
|
|
101
|
+
truncated: boolean;
|
|
102
|
+
recommended_reads: RecommendedRead[];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function readKey(r: RecommendedRead): string {
|
|
106
|
+
return r.lines ? `${r.path}:${r.lines[0]}-${r.lines[1]}` : r.path;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** A node's file + line range, or `null` for an unresolved `symbol:*`
|
|
110
|
+
* placeholder (nothing real to read) or a node with no location info. */
|
|
111
|
+
function recommendedReadFor(g: LoadedGraph, id: string): RecommendedRead | null {
|
|
112
|
+
const n = g.byId.get(id);
|
|
113
|
+
if (!n) return null;
|
|
114
|
+
const loc = n.source_location;
|
|
115
|
+
return { path: n.source_file, lines: loc.length >= 3 ? [loc[0] as number, loc[2] as number] : null };
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** One relation line plus the node id (if any) a reader should go inspect
|
|
119
|
+
* directly when this line gets dropped by the budget. */
|
|
120
|
+
interface LineEntry {
|
|
121
|
+
text: string;
|
|
122
|
+
focusId?: string;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Apply the token budget to `entries`, then translate BOTH failure classes
|
|
127
|
+
* this delta targets into a deterministic `recommended_reads` list: every
|
|
128
|
+
* entry the budget dropped, plus every read the caller already flagged as
|
|
129
|
+
* weak (an under-threshold/BM25-fallback seed match) — deduped by
|
|
130
|
+
* path+line-range, insertion-ordered for determinism.
|
|
131
|
+
*/
|
|
132
|
+
function budgetedLines(
|
|
133
|
+
g: LoadedGraph,
|
|
134
|
+
source: string,
|
|
135
|
+
seeds: string[],
|
|
136
|
+
entries: LineEntry[],
|
|
137
|
+
budget: number,
|
|
138
|
+
weakSeedReads: RecommendedRead[] = [],
|
|
139
|
+
): QueryResult {
|
|
140
|
+
const cap = budget * APPROX_CHARS_PER_TOKEN;
|
|
141
|
+
const kept: string[] = [];
|
|
142
|
+
const dropped: LineEntry[] = [];
|
|
143
|
+
let used = 0;
|
|
144
|
+
let truncated = false;
|
|
145
|
+
for (const entry of entries) {
|
|
146
|
+
if (!truncated && used + entry.text.length <= cap) {
|
|
147
|
+
kept.push(entry.text);
|
|
148
|
+
used += entry.text.length + 1;
|
|
149
|
+
} else {
|
|
150
|
+
truncated = true;
|
|
151
|
+
dropped.push(entry);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const recommended = new Map<string, RecommendedRead>();
|
|
155
|
+
for (const r of weakSeedReads) recommended.set(readKey(r), r);
|
|
156
|
+
for (const entry of dropped) {
|
|
157
|
+
if (!entry.focusId) continue;
|
|
158
|
+
const r = recommendedReadFor(g, entry.focusId);
|
|
159
|
+
if (r) recommended.set(readKey(r), r);
|
|
160
|
+
}
|
|
161
|
+
return { source, seeds, lines: kept, truncated, recommended_reads: [...recommended.values()] };
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function weakSeedReads(g: LoadedGraph, resolution: SeedResolution): RecommendedRead[] {
|
|
165
|
+
if (!resolution.weak) return [];
|
|
166
|
+
const out: RecommendedRead[] = [];
|
|
167
|
+
for (const id of resolution.ids) {
|
|
168
|
+
const r = recommendedReadFor(g, id);
|
|
169
|
+
if (r) out.push(r);
|
|
170
|
+
}
|
|
171
|
+
return out;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** `query <seed>` — the seed's direct (1-hop) outgoing relations. */
|
|
175
|
+
export function query(g: LoadedGraph, seed: string, budget = 1500): QueryResult {
|
|
176
|
+
const resolution = resolveSeedsTiered(g, seed);
|
|
177
|
+
const seeds = resolution.ids;
|
|
178
|
+
const entries: LineEntry[] = [];
|
|
179
|
+
for (const s of seeds) for (const e of g.out.get(s) ?? []) entries.push({ text: edgeLine(g, e), focusId: e.target });
|
|
180
|
+
return budgetedLines(g, g.source, seeds.map((s) => label(g, s)), entries, budget, weakSeedReads(g, resolution));
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/** `explain <seed>` — 2-hop neighbourhood (out-edges of seeds + their targets). */
|
|
184
|
+
export function explain(g: LoadedGraph, seed: string, budget = 1500): QueryResult {
|
|
185
|
+
const resolution = resolveSeedsTiered(g, seed);
|
|
186
|
+
const seeds = resolution.ids;
|
|
187
|
+
const seen = new Set<string>();
|
|
188
|
+
const entries: LineEntry[] = [];
|
|
189
|
+
const frontier = [...seeds];
|
|
190
|
+
for (let hop = 0; hop < 2 && frontier.length; hop += 1) {
|
|
191
|
+
const next: string[] = [];
|
|
192
|
+
for (const s of frontier.splice(0)) {
|
|
193
|
+
if (seen.has(s)) continue;
|
|
194
|
+
seen.add(s);
|
|
195
|
+
for (const e of g.out.get(s) ?? []) {
|
|
196
|
+
entries.push({ text: edgeLine(g, e), focusId: e.target });
|
|
197
|
+
next.push(e.target);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
frontier.push(...next);
|
|
201
|
+
}
|
|
202
|
+
return budgetedLines(g, g.source, seeds.map((s) => label(g, s)), entries, budget, weakSeedReads(g, resolution));
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** `affected <target>` — reverse BFS: who calls / references the target. */
|
|
206
|
+
export function affected(g: LoadedGraph, target: string, depth = 2, budget = 1500): QueryResult {
|
|
207
|
+
const resolution = resolveSeedsTiered(g, target);
|
|
208
|
+
const seeds = resolution.ids;
|
|
209
|
+
const seen = new Set<string>(seeds);
|
|
210
|
+
const entries: LineEntry[] = [];
|
|
211
|
+
let frontier = [...seeds];
|
|
212
|
+
for (let d = 0; d < depth && frontier.length; d += 1) {
|
|
213
|
+
const next: string[] = [];
|
|
214
|
+
for (const t of frontier) {
|
|
215
|
+
for (const e of g.in.get(t) ?? []) {
|
|
216
|
+
// the newly-discovered node here is the CALLER (e.source) —
|
|
217
|
+
// e.target is already a known seed, so that side carries no
|
|
218
|
+
// new read-plan information.
|
|
219
|
+
entries.push({ text: edgeLine(g, e), focusId: e.source });
|
|
220
|
+
if (!seen.has(e.source)) {
|
|
221
|
+
seen.add(e.source);
|
|
222
|
+
next.push(e.source);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
frontier = next;
|
|
227
|
+
}
|
|
228
|
+
return budgetedLines(g, g.source, seeds.map((s) => label(g, s)), entries, budget, weakSeedReads(g, resolution));
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/** `path <a> <b>` — shortest undirected path (direction preserved per edge). */
|
|
232
|
+
export function path(g: LoadedGraph, a: string, b: string, budget = 1500): QueryResult {
|
|
233
|
+
const startRes = resolveSeedsTiered(g, a, 1);
|
|
234
|
+
const goalRes = resolveSeedsTiered(g, b, 1);
|
|
235
|
+
const starts = startRes.ids;
|
|
236
|
+
const goals = new Set(goalRes.ids);
|
|
237
|
+
if (!starts.length || !goals.size) return { source: g.source, seeds: [], lines: [], truncated: false, recommended_reads: [] };
|
|
238
|
+
const start = starts[0] as string;
|
|
239
|
+
const prev = new Map<string, CodeEdge>();
|
|
240
|
+
const seen = new Set<string>([start]);
|
|
241
|
+
let frontier = [start];
|
|
242
|
+
let hit: string | null = goals.has(start) ? start : null;
|
|
243
|
+
while (frontier.length && !hit) {
|
|
244
|
+
const next: string[] = [];
|
|
245
|
+
for (const cur of frontier) {
|
|
246
|
+
const adj = [...(g.out.get(cur) ?? []), ...(g.in.get(cur) ?? [])];
|
|
247
|
+
for (const e of adj) {
|
|
248
|
+
const nb = e.source === cur ? e.target : e.source;
|
|
249
|
+
if (seen.has(nb)) continue;
|
|
250
|
+
seen.add(nb);
|
|
251
|
+
prev.set(nb, e);
|
|
252
|
+
if (goals.has(nb)) {
|
|
253
|
+
hit = nb;
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
next.push(nb);
|
|
257
|
+
}
|
|
258
|
+
if (hit) break;
|
|
259
|
+
}
|
|
260
|
+
frontier = next;
|
|
261
|
+
}
|
|
262
|
+
const seedReads = [...weakSeedReads(g, startRes), ...weakSeedReads(g, goalRes)];
|
|
263
|
+
if (!hit) {
|
|
264
|
+
return {
|
|
265
|
+
source: g.source,
|
|
266
|
+
seeds: [label(g, start)],
|
|
267
|
+
lines: ['(no path found)'],
|
|
268
|
+
truncated: false,
|
|
269
|
+
recommended_reads: [...new Map(seedReads.map((r) => [readKey(r), r])).values()],
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
const chain: CodeEdge[] = [];
|
|
273
|
+
let cur = hit;
|
|
274
|
+
while (prev.has(cur)) {
|
|
275
|
+
const e = prev.get(cur) as CodeEdge;
|
|
276
|
+
chain.unshift(e);
|
|
277
|
+
cur = e.source === cur ? e.target : e.source;
|
|
278
|
+
}
|
|
279
|
+
const entries = chain.map((e) => ({ text: edgeLine(g, e), focusId: e.target }));
|
|
280
|
+
return budgetedLines(g, g.source, [label(g, start), label(g, hit)], entries, budget, seedReads);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/** Merge several `QueryResult`s (e.g. one per `--since` seed) into one,
|
|
284
|
+
* de-duplicating `recommended_reads` by path+line-range so a read plan never
|
|
285
|
+
* repeats the same file twice across merged seeds. */
|
|
286
|
+
export function mergeRecommendedReads(results: readonly QueryResult[]): RecommendedRead[] {
|
|
287
|
+
const merged = new Map<string, RecommendedRead>();
|
|
288
|
+
for (const r of results) for (const rr of r.recommended_reads) merged.set(readKey(rr), rr);
|
|
289
|
+
return [...merged.values()];
|
|
290
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retrieved-content sanitizer. Graph node labels, file paths, and target ids
|
|
3
|
+
* are attacker-writable in a hostile repo; every string field passes through
|
|
4
|
+
* here before it re-enters the agent's context (hostile-repo injection row,
|
|
5
|
+
* ADR-124 risk register). Strips control + bidi/zero-width chars, collapses
|
|
6
|
+
* whitespace, caps length. Independent reimplementation — no coupling to any
|
|
7
|
+
* external label sanitizer.
|
|
8
|
+
*
|
|
9
|
+
* Filtering is done by codepoint (not a regex literal) so no control byte
|
|
10
|
+
* ever appears in this source file.
|
|
11
|
+
*/
|
|
12
|
+
const MAX_LABEL = 160;
|
|
13
|
+
|
|
14
|
+
/** True for C0/C1 controls, DEL, zero-width, bidi override/isolate, BOM. */
|
|
15
|
+
function isStrippable(cp: number): boolean {
|
|
16
|
+
if (cp <= 0x1f) return true; // C0 controls (incl. tab/newline → space)
|
|
17
|
+
if (cp >= 0x7f && cp <= 0x9f) return true; // DEL + C1 controls
|
|
18
|
+
if (cp >= 0x200b && cp <= 0x200f) return true; // zero-width + LRM/RLM
|
|
19
|
+
if (cp >= 0x202a && cp <= 0x202e) return true; // bidi embeds/overrides
|
|
20
|
+
if (cp >= 0x2066 && cp <= 0x2069) return true; // bidi isolates
|
|
21
|
+
if (cp === 0xfeff) return true; // BOM / ZWNBSP
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function sanitizeLabel(s: string, cap = MAX_LABEL): string {
|
|
26
|
+
let out = '';
|
|
27
|
+
for (const ch of s) out += isStrippable(ch.codePointAt(0) as number) ? ' ' : ch;
|
|
28
|
+
const cleaned = out.replace(/\s+/g, ' ').trim();
|
|
29
|
+
return cleaned.length > cap ? cleaned.slice(0, cap - 1) + '…' : cleaned;
|
|
30
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Derived SQLite twin of the code-graph JSON cache (ADR-129, Phase 6 of
|
|
3
|
+
* road-to-reachable-code-memory).
|
|
4
|
+
*
|
|
5
|
+
* `build` additionally emits `<cache>.sqlite3` beside the canonical JSON;
|
|
6
|
+
* the query path PREFERS the SQLite twin (cheap freshness check via the
|
|
7
|
+
* JSON's stat + stored source_checksum) and falls back to parsing the JSON
|
|
8
|
+
* when the twin is absent, stale, corrupt, version-mismatched, or the
|
|
9
|
+
* runtime has no `node:sqlite` (engines floor is Node >=20.11; the module
|
|
10
|
+
* needs >=22.5 — sqlite_guard's lazy import keeps old Nodes on the JSON
|
|
11
|
+
* path).
|
|
12
|
+
*
|
|
13
|
+
* INVARIANTS (ADR-129):
|
|
14
|
+
* - JSON stays canonical and byte-deterministic; the SQLite file is a
|
|
15
|
+
* derived, gitignored, disposable accelerator. Rollback = delete it.
|
|
16
|
+
* - Answers are byte-identical on both stores — the loader reconstructs the
|
|
17
|
+
* exact `CodeGraph` object (`serializeGraph` equality is the test).
|
|
18
|
+
* - Rollback triggers (recorded, not ship gates): query p95 <= 50 ms and
|
|
19
|
+
* heap <= 10 MB on the SQLite path — a miss reverts THAT store to the
|
|
20
|
+
* JSON fallback plus an incident note.
|
|
21
|
+
* - Zero-touch upgrades (Phase 7): `PRAGMA user_version` stamps the schema;
|
|
22
|
+
* a mismatch / corrupt / absent twin is silently rebuilt from the
|
|
23
|
+
* committed truth (the JSON) on the next load — never a user action.
|
|
24
|
+
*/
|
|
25
|
+
import * as fs from 'node:fs';
|
|
26
|
+
|
|
27
|
+
import {
|
|
28
|
+
isSqliteAvailableSync,
|
|
29
|
+
loadSqliteSync,
|
|
30
|
+
readUserVersion,
|
|
31
|
+
stampUserVersion,
|
|
32
|
+
} from '../_lib/sqlite_guard.js';
|
|
33
|
+
import type { CodeEdge, CodeGraph, CodeNode } from './types.js';
|
|
34
|
+
|
|
35
|
+
/** Bump on ANY table/column change — a mismatch sends readers to the JSON. */
|
|
36
|
+
export const GRAPH_STORE_VERSION = 1;
|
|
37
|
+
|
|
38
|
+
/** Derived twin path for a JSON cache path.
|
|
39
|
+
* cache-invalidation: versioned via PRAGMA user_version (GRAPH_STORE_VERSION), not the filename. */
|
|
40
|
+
export function sqliteTwinPath(jsonPath: string): string {
|
|
41
|
+
return jsonPath.endsWith('.json') ? `${jsonPath.slice(0, -5)}.sqlite3` : `${jsonPath}.sqlite3`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Emit the SQLite twin beside the JSON cache. Best-effort: returns false
|
|
46
|
+
* (never throws) when `node:sqlite` is unavailable or the write fails — the
|
|
47
|
+
* JSON path remains the source of truth either way.
|
|
48
|
+
*
|
|
49
|
+
* Storage model: nodes/edges land in real tables (queryable, and the FTS-free
|
|
50
|
+
* structure the rollback triggers measure), while `meta.graph_json` carries
|
|
51
|
+
* the byte-exact canonical serialization so the loader can guarantee
|
|
52
|
+
* byte-identical answers without re-deriving key order.
|
|
53
|
+
*/
|
|
54
|
+
export function emitSqliteTwin(graph: CodeGraph, serialized: string, jsonPath: string): boolean {
|
|
55
|
+
if (!isSqliteAvailableSync()) return false;
|
|
56
|
+
const twin = sqliteTwinPath(jsonPath);
|
|
57
|
+
const tmp = `${twin}.tmp-${process.pid}`;
|
|
58
|
+
try {
|
|
59
|
+
const { DatabaseSync } = loadSqliteSync('code_graph.sqlite_store');
|
|
60
|
+
let stat: fs.Stats;
|
|
61
|
+
try {
|
|
62
|
+
stat = fs.statSync(jsonPath);
|
|
63
|
+
} catch {
|
|
64
|
+
return false; // no canonical JSON — nothing to twin
|
|
65
|
+
}
|
|
66
|
+
fs.rmSync(tmp, { force: true });
|
|
67
|
+
const db = new DatabaseSync(tmp);
|
|
68
|
+
try {
|
|
69
|
+
db.exec('PRAGMA journal_mode = MEMORY');
|
|
70
|
+
db.exec(
|
|
71
|
+
'CREATE TABLE meta (key TEXT PRIMARY KEY, value TEXT NOT NULL);' +
|
|
72
|
+
'CREATE TABLE nodes (id TEXT PRIMARY KEY, label TEXT NOT NULL, kind TEXT, source_file TEXT, l0 INTEGER, l1 INTEGER, l2 INTEGER, l3 INTEGER);' +
|
|
73
|
+
'CREATE TABLE edges (source TEXT NOT NULL, target TEXT NOT NULL, relation TEXT NOT NULL, confidence TEXT NOT NULL, candidates TEXT);' +
|
|
74
|
+
'CREATE INDEX edges_source ON edges(source);' +
|
|
75
|
+
'CREATE INDEX edges_target ON edges(target);',
|
|
76
|
+
);
|
|
77
|
+
const meta = db.prepare('INSERT INTO meta (key, value) VALUES (?, ?)');
|
|
78
|
+
meta.run('source_checksum', graph.source_checksum);
|
|
79
|
+
meta.run('json_size', String(stat.size));
|
|
80
|
+
meta.run('json_mtime_ms', String(stat.mtimeMs));
|
|
81
|
+
meta.run('graph_json', serialized);
|
|
82
|
+
const insNode = db.prepare(
|
|
83
|
+
'INSERT INTO nodes (id, label, kind, source_file, l0, l1, l2, l3) VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
|
|
84
|
+
);
|
|
85
|
+
for (const n of graph.nodes) {
|
|
86
|
+
const loc = n.source_location ?? [];
|
|
87
|
+
insNode.run(
|
|
88
|
+
n.id,
|
|
89
|
+
n.label,
|
|
90
|
+
(n as { kind?: string }).kind ?? null,
|
|
91
|
+
n.source_file ?? null,
|
|
92
|
+
(loc[0] as number | undefined) ?? null,
|
|
93
|
+
(loc[1] as number | undefined) ?? null,
|
|
94
|
+
(loc[2] as number | undefined) ?? null,
|
|
95
|
+
(loc[3] as number | undefined) ?? null,
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
const insEdge = db.prepare(
|
|
99
|
+
'INSERT INTO edges (source, target, relation, confidence, candidates) VALUES (?, ?, ?, ?, ?)',
|
|
100
|
+
);
|
|
101
|
+
for (const e of graph.edges) {
|
|
102
|
+
insEdge.run(e.source, e.target, e.relation, e.confidence, e.candidates ? JSON.stringify(e.candidates) : null);
|
|
103
|
+
}
|
|
104
|
+
stampUserVersion(db, GRAPH_STORE_VERSION);
|
|
105
|
+
} finally {
|
|
106
|
+
db.close();
|
|
107
|
+
}
|
|
108
|
+
fs.renameSync(tmp, twin);
|
|
109
|
+
return true;
|
|
110
|
+
} catch {
|
|
111
|
+
fs.rmSync(tmp, { force: true });
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Load the canonical serialization from a FRESH SQLite twin, or null when the
|
|
118
|
+
* twin is absent / stale (JSON changed since emission) / corrupt /
|
|
119
|
+
* version-mismatched / unsupported runtime. Callers fall back to reading the
|
|
120
|
+
* JSON — and best-effort re-emit the twin from it (zero-touch rebuild).
|
|
121
|
+
*/
|
|
122
|
+
export function loadSerializedFromTwin(jsonPath: string): string | null {
|
|
123
|
+
if (!isSqliteAvailableSync()) return null;
|
|
124
|
+
const twin = sqliteTwinPath(jsonPath);
|
|
125
|
+
if (!fs.existsSync(twin)) return null;
|
|
126
|
+
let stat: fs.Stats;
|
|
127
|
+
try {
|
|
128
|
+
stat = fs.statSync(jsonPath);
|
|
129
|
+
} catch {
|
|
130
|
+
return null; // canonical JSON gone — the twin has no truth to mirror
|
|
131
|
+
}
|
|
132
|
+
try {
|
|
133
|
+
const { DatabaseSync } = loadSqliteSync('code_graph.sqlite_store');
|
|
134
|
+
const db = new DatabaseSync(twin, { readOnly: true });
|
|
135
|
+
try {
|
|
136
|
+
if (readUserVersion(db) !== GRAPH_STORE_VERSION) return null;
|
|
137
|
+
const rows = db.prepare('SELECT key, value FROM meta').all() as { key: string; value: string }[];
|
|
138
|
+
const meta = new Map(rows.map((r) => [r.key, r.value]));
|
|
139
|
+
if (meta.get('json_size') !== String(stat.size)) return null;
|
|
140
|
+
if (meta.get('json_mtime_ms') !== String(stat.mtimeMs)) return null;
|
|
141
|
+
const serialized = meta.get('graph_json');
|
|
142
|
+
return serialized && serialized.length > 0 ? serialized : null;
|
|
143
|
+
} finally {
|
|
144
|
+
db.close();
|
|
145
|
+
}
|
|
146
|
+
} catch {
|
|
147
|
+
// Corrupt twin is a non-event: drop it so the next build re-emits.
|
|
148
|
+
fs.rmSync(twin, { force: true });
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/** Structured node/edge access for future in-process consumers (kept minimal:
|
|
154
|
+
* the loader above guarantees byte-identical answers; these are for tooling). */
|
|
155
|
+
export function twinCounts(jsonPath: string): { nodes: number; edges: number } | null {
|
|
156
|
+
if (!isSqliteAvailableSync()) return null;
|
|
157
|
+
const twin = sqliteTwinPath(jsonPath);
|
|
158
|
+
if (!fs.existsSync(twin)) return null;
|
|
159
|
+
try {
|
|
160
|
+
const { DatabaseSync } = loadSqliteSync('code_graph.sqlite_store');
|
|
161
|
+
const db = new DatabaseSync(twin, { readOnly: true });
|
|
162
|
+
try {
|
|
163
|
+
const n = db.prepare('SELECT COUNT(*) AS c FROM nodes').get() as { c: number };
|
|
164
|
+
const e = db.prepare('SELECT COUNT(*) AS c FROM edges').get() as { c: number };
|
|
165
|
+
return { nodes: n.c, edges: e.c };
|
|
166
|
+
} finally {
|
|
167
|
+
db.close();
|
|
168
|
+
}
|
|
169
|
+
} catch {
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export type { CodeEdge, CodeGraph, CodeNode };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the native code-graph engine (Class-A, ADR-124).
|
|
3
|
+
*
|
|
4
|
+
* The graph shape is deliberately identical to what the interop tier consumes
|
|
5
|
+
* and to `discovery_graph.ts`'s edge-confidence scale — one code path serves
|
|
6
|
+
* the native cache, a consumer-shipped `graph.json`, and any future consumer
|
|
7
|
+
* of the shape. Deterministic + LLM-free + no network: identical source →
|
|
8
|
+
* identical graph bytes (enforced by the golden-checksum test).
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** Launch set — the stacks this suite's consumers actually run. */
|
|
12
|
+
export type Lang = 'php' | 'typescript' | 'javascript';
|
|
13
|
+
|
|
14
|
+
/** Same scale as `discovery_graph.ts::EdgeConfidence` (reused, not forked). */
|
|
15
|
+
export type EdgeConfidence = 'EXTRACTED' | 'INFERRED' | 'AMBIGUOUS';
|
|
16
|
+
|
|
17
|
+
/** Relations the extractor emits. */
|
|
18
|
+
export type Relation = 'calls' | 'imports' | 'uses' | 'inherits' | 'member';
|
|
19
|
+
|
|
20
|
+
export interface CodeNode {
|
|
21
|
+
/** Path-qualified from day one: `<relpath>#<symbol>` (collision-free). */
|
|
22
|
+
id: string;
|
|
23
|
+
label: string;
|
|
24
|
+
kind: 'file' | 'class' | 'interface' | 'trait' | 'function' | 'method' | 'skipped';
|
|
25
|
+
source_file: string;
|
|
26
|
+
/** 1-based [startLine, startCol, endLine, endCol]; [] for synthetic nodes. */
|
|
27
|
+
source_location: readonly number[];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface CodeEdge {
|
|
31
|
+
source: string;
|
|
32
|
+
target: string;
|
|
33
|
+
relation: Relation;
|
|
34
|
+
confidence: EdgeConfidence;
|
|
35
|
+
/**
|
|
36
|
+
* Present only on AMBIGUOUS / multi-candidate edges: the resolved-target
|
|
37
|
+
* candidates by id. An AMBIGUOUS edge is "correct" when the true target is
|
|
38
|
+
* among these (the honest-taxonomy acceptance rule).
|
|
39
|
+
*/
|
|
40
|
+
candidates?: string[];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface CodeGraph {
|
|
44
|
+
schema_version: number;
|
|
45
|
+
/** content-addressed to the file-manifest checksum (cache key). */
|
|
46
|
+
source_checksum: string;
|
|
47
|
+
/** launch-set languages actually seen in this build. */
|
|
48
|
+
languages: Lang[];
|
|
49
|
+
/** ABI version of the grammars used (pinned; asserted by the smoke test). */
|
|
50
|
+
grammar_abi: number;
|
|
51
|
+
/** per-confidence-class edge counts, so the honesty split is visible. */
|
|
52
|
+
edge_confidence_counts: Record<EdgeConfidence, number>;
|
|
53
|
+
nodes: CodeNode[];
|
|
54
|
+
edges: CodeEdge[];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export const SCHEMA_VERSION = 1;
|
|
58
|
+
|
|
59
|
+
/** Deterministic per-file byte cap — files above this become a SKIPPED node. */
|
|
60
|
+
export const MAX_FILE_BYTES = 1_000_000;
|
|
61
|
+
|
|
62
|
+
/** file-extension → language, launch set only. */
|
|
63
|
+
export const EXT_LANG: Readonly<Record<string, Lang>> = {
|
|
64
|
+
'.php': 'php',
|
|
65
|
+
'.ts': 'typescript',
|
|
66
|
+
'.tsx': 'typescript',
|
|
67
|
+
'.mts': 'typescript',
|
|
68
|
+
'.cts': 'typescript',
|
|
69
|
+
'.js': 'javascript',
|
|
70
|
+
'.jsx': 'javascript',
|
|
71
|
+
'.mjs': 'javascript',
|
|
72
|
+
'.cjs': 'javascript',
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/** Grammar wasm filename per language (in `tree-sitter-wasms/out/`). */
|
|
76
|
+
export const GRAMMAR_WASM: Readonly<Record<Lang, string>> = {
|
|
77
|
+
php: 'tree-sitter-php.wasm',
|
|
78
|
+
typescript: 'tree-sitter-typescript.wasm',
|
|
79
|
+
javascript: 'tree-sitter-javascript.wasm',
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/** The single ABI version the pinned grammar set is built against. */
|
|
83
|
+
export const EXPECTED_GRAMMAR_ABI = 14;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema gate — validate a graph.json (native cache or consumer-shipped)
|
|
3
|
+
* before any consumer trusts it. Pure, no IO.
|
|
4
|
+
*/
|
|
5
|
+
import type { CodeGraph } from './types.js';
|
|
6
|
+
|
|
7
|
+
const RELATIONS = new Set(['calls', 'imports', 'uses', 'inherits', 'member']);
|
|
8
|
+
const CONFIDENCES = new Set(['EXTRACTED', 'INFERRED', 'AMBIGUOUS']);
|
|
9
|
+
const KINDS = new Set(['file', 'class', 'interface', 'trait', 'function', 'method', 'skipped']);
|
|
10
|
+
|
|
11
|
+
export interface ValidateResult {
|
|
12
|
+
ok: boolean;
|
|
13
|
+
errors: string[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function validateGraph(g: unknown): ValidateResult {
|
|
17
|
+
const errors: string[] = [];
|
|
18
|
+
const push = (m: string): void => {
|
|
19
|
+
if (errors.length < 50) errors.push(m);
|
|
20
|
+
};
|
|
21
|
+
if (typeof g !== 'object' || g === null) return { ok: false, errors: ['graph is not an object'] };
|
|
22
|
+
const obj = g as Record<string, unknown>;
|
|
23
|
+
if (typeof obj['schema_version'] !== 'number') push('schema_version must be a number');
|
|
24
|
+
if (typeof obj['source_checksum'] !== 'string') push('source_checksum must be a string');
|
|
25
|
+
if (!Array.isArray(obj['nodes'])) push('nodes must be an array');
|
|
26
|
+
if (!Array.isArray(obj['edges'])) push('edges must be an array');
|
|
27
|
+
if (errors.length) return { ok: false, errors };
|
|
28
|
+
|
|
29
|
+
const nodes = obj['nodes'] as unknown[];
|
|
30
|
+
const ids = new Set<string>();
|
|
31
|
+
nodes.forEach((n, i) => {
|
|
32
|
+
if (typeof n !== 'object' || n === null) return push(`node[${i}] not an object`);
|
|
33
|
+
const nn = n as Record<string, unknown>;
|
|
34
|
+
if (typeof nn['id'] !== 'string') push(`node[${i}].id must be a string`);
|
|
35
|
+
else ids.add(nn['id']);
|
|
36
|
+
if (!KINDS.has(nn['kind'] as string)) push(`node[${i}].kind invalid: ${String(nn['kind'])}`);
|
|
37
|
+
if (typeof nn['source_file'] !== 'string') push(`node[${i}].source_file must be a string`);
|
|
38
|
+
if (!Array.isArray(nn['source_location'])) push(`node[${i}].source_location must be an array`);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
(obj['edges'] as unknown[]).forEach((e, i) => {
|
|
42
|
+
if (typeof e !== 'object' || e === null) return push(`edge[${i}] not an object`);
|
|
43
|
+
const ee = e as Record<string, unknown>;
|
|
44
|
+
if (typeof ee['source'] !== 'string') push(`edge[${i}].source must be a string`);
|
|
45
|
+
if (typeof ee['target'] !== 'string') push(`edge[${i}].target must be a string`);
|
|
46
|
+
if (!RELATIONS.has(ee['relation'] as string)) push(`edge[${i}].relation invalid: ${String(ee['relation'])}`);
|
|
47
|
+
if (!CONFIDENCES.has(ee['confidence'] as string))
|
|
48
|
+
push(`edge[${i}].confidence invalid: ${String(ee['confidence'])}`);
|
|
49
|
+
// a source must be a known node; targets may be unresolved `symbol:` refs
|
|
50
|
+
if (typeof ee['source'] === 'string' && !ids.has(ee['source'] as string))
|
|
51
|
+
push(`edge[${i}].source is not a known node: ${String(ee['source'])}`);
|
|
52
|
+
if (ee['candidates'] !== undefined && !Array.isArray(ee['candidates']))
|
|
53
|
+
push(`edge[${i}].candidates must be an array when present`);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
return { ok: errors.length === 0, errors };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Narrowing helper for callers that then treat the value as CodeGraph. */
|
|
60
|
+
export function assertGraph(g: unknown): asserts g is CodeGraph {
|
|
61
|
+
const r = validateGraph(g);
|
|
62
|
+
if (!r.ok) throw new Error(`invalid graph: ${r.errors.join('; ')}`);
|
|
63
|
+
}
|
package/src/scripts/condense.ts
CHANGED
|
@@ -965,17 +965,25 @@ function _read_rule_packs(): string[] | null {
|
|
|
965
965
|
}
|
|
966
966
|
|
|
967
967
|
/**
|
|
968
|
-
* Whether a rule source file projects under the given workspace + pack
|
|
969
|
-
* scopes.
|
|
970
|
-
* rule's frontmatter list must intersect
|
|
971
|
-
*
|
|
968
|
+
* Whether a rule source file projects under the given workspace + pack +
|
|
969
|
+
* role scopes. Each configured scope is an independent constraint: the
|
|
970
|
+
* rule's frontmatter list must intersect it. Kernel always projects;
|
|
971
|
+
* untagged axes fail safe.
|
|
972
|
+
*
|
|
973
|
+
* `role_scope` is the subagent-role axis (road-to-lean-agent-init Phase 4):
|
|
974
|
+
* a `roles:` frontmatter list, parallel to `workspaces:`/`packs:`, so a
|
|
975
|
+
* review-worker subagent's rule projection can be scoped to review-shaped
|
|
976
|
+
* rules instead of the full set. Additive — the new param defaults to
|
|
977
|
+
* `null` (no role filtering), so every existing 2- and 3-arg call site
|
|
978
|
+
* compiles and behaves unchanged.
|
|
972
979
|
*/
|
|
973
980
|
export function rule_in_scope(
|
|
974
981
|
source_path: string,
|
|
975
982
|
scope: readonly string[] | null,
|
|
976
983
|
pack_scope: readonly string[] | null = null,
|
|
984
|
+
role_scope: readonly string[] | null = null,
|
|
977
985
|
): boolean {
|
|
978
|
-
if (scope === null && pack_scope === null) {
|
|
986
|
+
if (scope === null && pack_scope === null && role_scope === null) {
|
|
979
987
|
return true;
|
|
980
988
|
}
|
|
981
989
|
const [meta] = _parse_frontmatter(_readText(source_path));
|
|
@@ -994,7 +1002,7 @@ export function rule_in_scope(
|
|
|
994
1002
|
}
|
|
995
1003
|
return values.some((v) => configured.includes(v));
|
|
996
1004
|
};
|
|
997
|
-
return axis('workspaces', scope) && axis('packs', pack_scope);
|
|
1005
|
+
return axis('workspaces', scope) && axis('packs', pack_scope) && axis('roles', role_scope);
|
|
998
1006
|
}
|
|
999
1007
|
|
|
1000
1008
|
/** List rule basenames under RULES_SOURCE, workspace/pack scope applied. */
|