@event4u/agent-config 16.2.0 → 16.4.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/.augment-plugin/marketplace.json +3 -3
- package/.augment-plugin/plugin.json +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +337 -234
- package/README.md +15 -13
- package/agents/templates/.ai-council.yml.example +26 -8
- package/dist/agent-src/commands/analyze/inbox.md +11 -8
- package/dist/agent-src/commands/analyze/roadmap-repos.md +1 -1
- package/dist/agent-src/commands/bug/fix.md +17 -2
- package/dist/agent-src/commands/bug/investigate.md +1 -1
- package/dist/agent-src/commands/commit/in-chunks.md +40 -31
- package/dist/agent-src/commands/commit.md +72 -33
- package/dist/agent-src/commands/condense.md +2 -8
- package/dist/agent-src/commands/council/debate.md +11 -7
- package/dist/agent-src/commands/council/default.md +10 -9
- package/dist/agent-src/commands/council.md +1 -1
- package/dist/agent-src/commands/estimate-ticket.md +1 -1
- package/dist/agent-src/commands/feature/explore.md +3 -3
- package/dist/agent-src/commands/feature/plan.md +2 -2
- package/dist/agent-src/commands/feature/roadmap.md +1 -1
- package/dist/agent-src/commands/fix/ci.md +18 -4
- package/dist/agent-src/commands/fix/commit-messages.md +48 -23
- package/dist/agent-src/commands/fix/pr-comments.md +3 -6
- package/dist/agent-src/commands/implement-ticket.md +4 -4
- package/dist/agent-src/commands/jira-ticket.md +1 -1
- package/dist/agent-src/commands/memory/add.md +4 -16
- package/dist/agent-src/commands/memory/load.md +5 -6
- package/dist/agent-src/commands/memory/promote.md +3 -16
- package/dist/agent-src/commands/mission/upgrade.md +3 -2
- package/dist/agent-src/commands/optimize/agents-dir.md +2 -2
- package/dist/agent-src/commands/optimize/deep.md +4 -2
- package/dist/agent-src/commands/optimize/rtk.md +4 -26
- package/dist/agent-src/commands/pr/create/description-only.md +18 -15
- package/dist/agent-src/commands/pr/create.md +42 -34
- package/dist/agent-src/commands/pr/merge.md +136 -9
- package/dist/agent-src/commands/prepare-for-review.md +13 -11
- package/dist/agent-src/commands/project/analyze.md +7 -35
- package/dist/agent-src/commands/refine-ticket.md +1 -1
- package/dist/agent-src/commands/review/changes.md +14 -19
- package/dist/agent-src/commands/roadmap/create.md +1 -1
- package/dist/agent-src/commands/roadmap/materialize.md +1 -1
- package/dist/agent-src/commands/roadmap/next.md +10 -1
- package/dist/agent-src/commands/roadmap/process-full.md +56 -42
- package/dist/agent-src/commands/roadmap/resolve-blockers.md +411 -0
- package/dist/agent-src/commands/roadmap/triage-parked.md +325 -0
- package/dist/agent-src/commands/roadmap.md +18 -4
- package/dist/agent-src/commands/tests/create.md +17 -3
- package/dist/agent-src/commands/tests/execute.md +22 -5
- package/dist/agent-src/commands/worktree/create.md +7 -3
- package/dist/agent-src/commands/worktree/verify.md +2 -1
- package/dist/agent-src/contexts/authority/decision-revisit-gate-enforcement.md +43 -0
- package/dist/agent-src/contexts/communication/rules-auto/design-fidelity-enforcement.md +24 -0
- package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +5 -3
- package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +7 -9
- package/dist/agent-src/contexts/contracts/command-suggestion-flow.md +8 -6
- package/dist/agent-src/contexts/contracts/frugality-charter.md +8 -5
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +7 -7
- package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +0 -1
- package/dist/agent-src/contexts/execution/evidence-discipline.md +2 -2
- package/dist/agent-src/contexts/execution/non-interactive-contract.md +5 -8
- package/dist/agent-src/contexts/execution/rdp-gate.md +4 -4
- package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +9 -8
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +99 -54
- package/dist/agent-src/contexts/execution/session-canary-enforcement-history.md +67 -0
- package/dist/agent-src/contexts/execution/subagent-routing.md +8 -8
- package/dist/agent-src/contexts/execution/subagent-steering.md +6 -4
- package/dist/agent-src/contexts/execution/terminal-states.md +2 -2
- package/dist/agent-src/contexts/execution/toolchain-resolver.md +95 -7
- package/dist/agent-src/contexts/subagent-configuration.md +1 -1
- package/dist/agent-src/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
- package/dist/agent-src/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
- package/dist/agent-src/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
- package/dist/agent-src/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
- package/dist/agent-src/guidelines/agent-infra/layered-settings.md +13 -1
- package/dist/agent-src/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
- package/dist/agent-src/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
- package/dist/agent-src/guidelines/agent-infra/size-and-scope.md +36 -0
- package/dist/agent-src/guidelines/php/git.md +15 -2
- package/dist/agent-src/rules/active-remediation.md +1 -2
- package/dist/agent-src/rules/analysis-skill-routing.md +0 -1
- package/dist/agent-src/rules/architecture.md +0 -1
- package/dist/agent-src/rules/artifact-drafting-protocol.md +0 -1
- package/dist/agent-src/rules/artifact-engagement-recording.md +0 -1
- package/dist/agent-src/rules/augment-edit-discipline.md +0 -1
- package/dist/agent-src/rules/autonomous-execution.md +1 -1
- package/dist/agent-src/rules/brand-consistency.md +0 -1
- package/dist/agent-src/rules/brand-source-of-truth.md +0 -1
- package/dist/agent-src/rules/broken-access-control.md +1 -1
- package/dist/agent-src/rules/cli-output-handling.md +0 -1
- package/dist/agent-src/rules/code-comment-discipline.md +0 -1
- package/dist/agent-src/rules/code-provenance.md +0 -1
- package/dist/agent-src/rules/command-suggestion-policy.md +1 -1
- package/dist/agent-src/rules/commit-conventions.md +1 -2
- package/dist/agent-src/rules/communication-through-line.md +1 -2
- package/dist/agent-src/rules/content-quoting-floor.md +1 -2
- package/dist/agent-src/rules/context-hygiene.md +6 -6
- package/dist/agent-src/rules/copilot-routing.md +1 -2
- package/dist/agent-src/rules/council-availability.md +4 -4
- package/dist/agent-src/rules/cross-source-consistency.md +4 -6
- package/dist/agent-src/rules/decision-revisit-gate.md +17 -35
- package/dist/agent-src/rules/delegation-policy.md +2 -3
- package/dist/agent-src/rules/design-fidelity.md +12 -16
- package/dist/agent-src/rules/design-review-after-ui-write.md +3 -3
- package/dist/agent-src/rules/devcontainer-routing.md +1 -2
- package/dist/agent-src/rules/doc-screenshot-hygiene.md +1 -1
- package/dist/agent-src/rules/docker-commands.md +0 -1
- package/dist/agent-src/rules/domain-adoption-policy.md +0 -1
- package/dist/agent-src/rules/domain-safety-disclaimer.md +1 -1
- package/dist/agent-src/rules/domain-safety-pii.md +1 -1
- package/dist/agent-src/rules/domain-safety-retention.md +1 -1
- package/dist/agent-src/rules/downstream-changes.md +0 -1
- package/dist/agent-src/rules/engineering-safety-floor.md +1 -1
- package/dist/agent-src/rules/evaluator-independence.md +3 -2
- package/dist/agent-src/rules/external-code-graph-interop.md +0 -1
- package/dist/agent-src/rules/external-reference-deep-dive.md +0 -1
- package/dist/agent-src/rules/fast-path-marker-visibility.md +2 -2
- package/dist/agent-src/rules/finance-safety-floor.md +1 -1
- package/dist/agent-src/rules/fix-what-you-see.md +6 -32
- package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +0 -1
- package/dist/agent-src/rules/git-history-discipline.md +2 -2
- package/dist/agent-src/rules/guidelines.md +0 -1
- package/dist/agent-src/rules/history-discipline.md +0 -1
- package/dist/agent-src/rules/icon-consistency.md +0 -1
- package/dist/agent-src/rules/image-likeness-and-rights.md +1 -1
- package/dist/agent-src/rules/improve-before-implement.md +0 -1
- package/dist/agent-src/rules/invite-challenge.md +0 -1
- package/dist/agent-src/rules/laravel-routing.md +1 -2
- package/dist/agent-src/rules/laravel-translations.md +0 -1
- package/dist/agent-src/rules/legal-safety-floor.md +3 -3
- package/dist/agent-src/rules/lethal-trifecta-guard.md +1 -1
- package/dist/agent-src/rules/linked-projects-onboarding-gate.md +0 -1
- package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +1 -1
- package/dist/agent-src/rules/markdown-safe-codeblocks.md +0 -1
- package/dist/agent-src/rules/media-governance-routing.md +13 -17
- package/dist/agent-src/rules/media-sync-ground-truth.md +0 -1
- package/dist/agent-src/rules/minimal-safe-diff.md +0 -1
- package/dist/agent-src/rules/missing-skill-recovery.md +0 -1
- package/dist/agent-src/rules/missing-tool-handling.md +0 -1
- package/dist/agent-src/rules/model-recommendation.md +0 -1
- package/dist/agent-src/rules/neighbour-precedence.md +64 -0
- package/dist/agent-src/rules/no-attribution-footers.md +0 -1
- package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +0 -1
- package/dist/agent-src/rules/no-pr-progress-comments.md +0 -1
- package/dist/agent-src/rules/no-roadmap-references.md +0 -1
- package/dist/agent-src/rules/notes-first-reasoning.md +0 -1
- package/dist/agent-src/rules/onboarding-gate.md +0 -1
- package/dist/agent-src/rules/output-discipline.md +0 -1
- package/dist/agent-src/rules/package-ci-checks.md +0 -1
- package/dist/agent-src/rules/persona-governance.md +4 -5
- package/dist/agent-src/rules/php-coding.md +0 -1
- package/dist/agent-src/rules/prefer-enums-over-literals.md +0 -1
- package/dist/agent-src/rules/preservation-guard.md +0 -1
- package/dist/agent-src/rules/provider-lifecycle-discipline.md +3 -4
- package/dist/agent-src/rules/question-not-instruction.md +1 -1
- package/dist/agent-src/rules/reviewer-awareness.md +0 -1
- package/dist/agent-src/rules/roadmap-ci-steps-policy.md +0 -1
- package/dist/agent-src/rules/roadmap-progress-sync.md +4 -7
- package/dist/agent-src/rules/role-mode-adherence.md +0 -1
- package/dist/agent-src/rules/rule-type-governance.md +0 -1
- package/dist/agent-src/rules/runtime-safety.md +1 -1
- package/dist/agent-src/rules/scale-discipline.md +0 -1
- package/dist/agent-src/rules/secret-vcs-guard.md +1 -1
- package/dist/agent-src/rules/security-sensitive-stop.md +3 -3
- package/dist/agent-src/rules/self-repair-loop.md +0 -1
- package/dist/agent-src/rules/senior-engineering-discipline.md +0 -1
- package/dist/agent-src/rules/session-canary.md +7 -62
- package/dist/agent-src/rules/settings-ask-protocol.md +6 -6
- package/dist/agent-src/rules/size-enforcement.md +0 -1
- package/dist/agent-src/rules/skill-improvement-trigger.md +2 -3
- package/dist/agent-src/rules/skill-quality.md +0 -1
- package/dist/agent-src/rules/slash-command-routing-policy.md +0 -1
- package/dist/agent-src/rules/source-confidentiality.md +1 -1
- package/dist/agent-src/rules/source-discovery-gate.md +0 -1
- package/dist/agent-src/rules/source-of-truth.md +0 -1
- package/dist/agent-src/rules/spreadsheet-source-quality.md +1 -2
- package/dist/agent-src/rules/strategy-safety-floor.md +1 -1
- package/dist/agent-src/rules/symfony-routing.md +1 -2
- package/dist/agent-src/rules/think-before-action.md +0 -1
- package/dist/agent-src/rules/token-budget-discipline.md +12 -46
- package/dist/agent-src/rules/token-efficiency.md +0 -1
- package/dist/agent-src/rules/token-optimizer-maintenance.md +0 -1
- package/dist/agent-src/rules/tool-safety.md +1 -1
- package/dist/agent-src/rules/ui-audit-gate.md +1 -2
- package/dist/agent-src/rules/untrusted-input-defense.md +1 -1
- package/dist/agent-src/rules/upstream-proposal.md +0 -1
- package/dist/agent-src/rules/user-interaction.md +0 -1
- package/dist/agent-src/rules/user-interrupt-priority.md +1 -1
- package/dist/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
- package/dist/agent-src/scripts/deferral_carry.ts +339 -0
- package/dist/agent-src/scripts/gate_budget.ts +47 -23
- package/dist/agent-src/scripts/gate_execute.ts +12 -4
- package/dist/agent-src/scripts/update_roadmap_progress.ts +4 -1
- package/dist/agent-src/skills/ai-council/SKILL.md +7 -4
- package/dist/agent-src/skills/ai-council/references/cost-and-redaction.md +21 -11
- package/dist/agent-src/skills/ai-council/references/procedure.md +12 -6
- package/dist/agent-src/skills/analysis-autonomous-mode/SKILL.md +1 -1
- package/dist/agent-src/skills/api-design/data/manifest.json +2 -2
- package/dist/agent-src/skills/api-testing/SKILL.md +17 -0
- package/dist/agent-src/skills/bug-analyzer/SKILL.md +1 -1
- package/dist/agent-src/skills/code-intelligence/SKILL.md +14 -2
- package/dist/agent-src/skills/command-routing/SKILL.md +3 -4
- package/dist/agent-src/skills/conventional-commits-writing/SKILL.md +127 -139
- package/dist/agent-src/skills/corpus-grounding/ATTRIBUTION.md +39 -0
- package/dist/agent-src/skills/corpus-grounding/SKILL.md +8 -2
- package/dist/agent-src/skills/database/data/manifest.json +2 -2
- package/dist/agent-src/skills/database/data/query-tuning.csv +13 -13
- package/dist/agent-src/skills/design-system-capture/SKILL.md +0 -3
- package/dist/agent-src/skills/design-system-capture/references/import-procedure.md +1 -1
- package/dist/agent-src/skills/estimate-ticket/SKILL.md +1 -1
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +2 -2
- package/dist/agent-src/skills/fe-design/SKILL.md +1 -1
- package/dist/agent-src/skills/feature-planning/SKILL.md +1 -1
- package/dist/agent-src/skills/git-workflow/SKILL.md +44 -44
- package/dist/agent-src/skills/git-workflow/references/branch-update.md +312 -0
- package/dist/agent-src/skills/git-workflow/references/commit-subject.md +205 -0
- package/dist/agent-src/skills/iconography/SKILL.md +1 -1
- package/dist/agent-src/skills/jira-integration/SKILL.md +3 -3
- package/dist/agent-src/skills/js-library-packaging/SKILL.md +2 -2
- package/dist/agent-src/skills/merge-conflicts/SKILL.md +10 -4
- package/dist/agent-src/skills/monorepo-workspace/SKILL.md +1 -1
- package/dist/agent-src/skills/po-discovery/SKILL.md +1 -1
- package/dist/agent-src/skills/quality-tools/SKILL.md +11 -1
- package/dist/agent-src/skills/quality-tools/references/go-tools.md +76 -0
- package/dist/agent-src/skills/quality-tools/references/python-tools.md +104 -0
- package/dist/agent-src/skills/refine-ticket/SKILL.md +4 -4
- package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +2 -2
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +5 -3
- package/dist/agent-src/skills/source-discovery/SKILL.md +1 -1
- package/dist/agent-src/skills/storybook-workshop/SKILL.md +3 -3
- package/dist/agent-src/skills/tailwind-engineer/SKILL.md +4 -2
- package/dist/agent-src/skills/test-case-discovery/SKILL.md +7 -0
- package/dist/agent-src/skills/test-driven-development/SKILL.md +17 -0
- package/dist/agent-src/skills/test-performance/SKILL.md +19 -1
- package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/ui-component-architect/SKILL.md +2 -2
- package/dist/agent-src/skills/using-git-worktrees/SKILL.md +1 -1
- package/dist/agent-src/skills/verify-repair-loop/SKILL.md +2 -2
- package/dist/agent-src/templates/AGENTS.md +1 -1
- package/dist/agent-src/templates/agent-settings.md +46 -129
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +3 -3
- package/dist/agent-src/templates/command.md +2 -2
- package/dist/agent-src/templates/roadmaps.md +6 -1
- package/dist/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +48 -6
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
- package/dist/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
- package/dist/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
- package/dist/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
- package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
- package/dist/agent-src/templates/skill.md +1 -1
- package/dist/cli/registry.js +2 -1
- package/dist/cli-delegate/archive_completed_roadmaps.js +92 -12
- package/dist/cli-delegate/check_update_banner.js +207 -120
- package/dist/cli-delegate/chunk-523HCFYO.js +90 -0
- package/dist/cli-delegate/{chunk-FP36SWJD.js → chunk-5GPULQBE.js} +2797 -338
- package/dist/cli-delegate/{chunk-IGD6ERX6.js → chunk-6SRJTYJS.js} +42 -176
- package/dist/cli-delegate/chunk-6V5FMA3P.js +186 -0
- package/dist/cli-delegate/{chunk-M2DPGFZ4.js → chunk-6V6TA25H.js} +22 -152
- package/dist/cli-delegate/chunk-6YQC2HLF.js +415 -0
- package/dist/cli-delegate/{chunk-E4XIZDIB.js → chunk-7HKRE54K.js} +1 -64
- package/dist/cli-delegate/chunk-7IQE3D5S.js +191 -0
- package/dist/cli-delegate/{chunk-YJ72UIAK.js → chunk-AED2VQGM.js} +1245 -249
- package/dist/cli-delegate/{chunk-7HQ52DHU.js → chunk-AL3RZ22D.js} +1 -1
- package/dist/cli-delegate/chunk-DEIV7XP7.js +108 -0
- package/dist/cli-delegate/{chunk-DBH4AHDK.js → chunk-ED7KCMLB.js} +9 -11
- package/dist/cli-delegate/chunk-F3QDG2GT.js +2569 -0
- package/dist/cli-delegate/{chunk-6KFEC3G7.js → chunk-G5VVIZRC.js} +3 -3
- package/dist/cli-delegate/{chunk-FC75PGJE.js → chunk-H76PHZBI.js} +149 -61
- package/dist/cli-delegate/chunk-IAYTIIQW.js +67 -0
- package/dist/cli-delegate/chunk-JQOM7TTM.js +1201 -0
- package/dist/cli-delegate/chunk-KB5FZ655.js +208 -0
- package/dist/cli-delegate/{chunk-7RQP4UDH.js → chunk-KR6EM23A.js} +235 -1455
- package/dist/cli-delegate/{chunk-LTYVIY76.js → chunk-KXXWJTDO.js} +6 -11
- package/dist/cli-delegate/{chunk-T7L2QK3K.js → chunk-LQOCRFWT.js} +1 -1
- package/dist/cli-delegate/{chunk-6KM6ORRY.js → chunk-MDPPKQCQ.js} +58 -9
- package/dist/cli-delegate/{chunk-4XFP2Y3E.js → chunk-MSUL5NYP.js} +5 -5
- package/dist/cli-delegate/chunk-OAFSJBHH.js +272 -0
- package/dist/cli-delegate/{chunk-4E2W63DA.js → chunk-OKJUIAPS.js} +62 -1
- package/dist/cli-delegate/{chunk-QAJS5YWY.js → chunk-PHD7OOLE.js} +2 -1
- package/dist/cli-delegate/{chunk-P6ZHP5W2.js → chunk-PWX7CKMD.js} +4 -4
- package/dist/cli-delegate/{chunk-NDJLNC6Q.js → chunk-T6BP34WI.js} +1 -0
- package/dist/cli-delegate/{chunk-7XGBX6ZH.js → chunk-T7XSJSUQ.js} +1144 -589
- package/dist/cli-delegate/chunk-ULQRUR23.js +208 -0
- package/dist/cli-delegate/chunk-WQWXGIWB.js +1779 -0
- package/dist/cli-delegate/{chunk-RGNIWTEA.js → chunk-XQTPXKFA.js} +1 -1
- package/dist/cli-delegate/{chunk-NUHLI2RX.js → chunk-YCU3TIXH.js} +2 -0
- package/dist/cli-delegate/chunk-ZBZV2G5R.js +210 -0
- package/dist/cli-delegate/{chunk-WGXTVKCQ.js → chunk-ZUZKZYCN.js} +5 -3
- package/dist/cli-delegate/cmd_analyze_session.js +223 -43
- package/dist/cli-delegate/cmd_brand_status.js +3 -2
- package/dist/cli-delegate/cmd_conformance.js +1252 -249
- package/dist/cli-delegate/cmd_converge.js +3 -3
- package/dist/cli-delegate/cmd_doctor.js +19 -9
- package/dist/cli-delegate/cmd_doctor_neighbours.js +30 -0
- package/dist/cli-delegate/cmd_explain.js +45 -21
- package/dist/cli-delegate/cmd_export.js +13 -10
- package/dist/cli-delegate/cmd_fleet.js +3 -3
- package/dist/cli-delegate/cmd_git_convention.js +1851 -0
- package/dist/cli-delegate/cmd_handoff.js +44 -22
- package/dist/cli-delegate/cmd_mcp_available.js +3 -2
- package/dist/cli-delegate/cmd_memory_get.js +3 -1
- package/dist/cli-delegate/cmd_migrate.js +3 -3
- package/dist/cli-delegate/cmd_packs_active.js +5 -4
- package/dist/cli-delegate/cmd_preflight.js +6 -6
- package/dist/cli-delegate/cmd_prune.js +14 -11
- package/dist/cli-delegate/cmd_refresh.js +2 -1
- package/dist/cli-delegate/cmd_route_audit.js +10 -8
- package/dist/cli-delegate/cmd_route_explain.js +4 -4
- package/dist/cli-delegate/cmd_session_recycle.js +10 -7
- package/dist/cli-delegate/cmd_settings_check.js +54 -7
- package/dist/cli-delegate/cmd_settings_get.js +18 -8
- package/dist/cli-delegate/cmd_settings_migrate.js +13 -10
- package/dist/cli-delegate/cmd_settings_set.js +4 -4
- package/dist/cli-delegate/cmd_sync.js +14 -11
- package/dist/cli-delegate/cmd_uninstall.js +15 -12
- package/dist/cli-delegate/cmd_update.js +7 -7
- package/dist/cli-delegate/cmd_upgrade.js +9 -8
- package/dist/cli-delegate/cmd_validate.js +15 -12
- package/dist/cli-delegate/cmd_versions.js +5 -5
- package/dist/cli-delegate/deferral_carry.js +16 -0
- package/dist/cli-delegate/gate_budget.js +1 -1
- package/dist/cli-delegate/gate_execute.js +3 -3
- package/dist/cli-delegate/roadmap_gates.js +6 -6
- package/dist/cli-delegate/update_roadmap_progress.js +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +232 -141
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +3 -3
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +26 -9
- package/dist/discovery/trust-report.md +3 -3
- package/dist/discovery/workspaces.json +7 -4
- package/dist/hooks/dispatch.js +5655 -6623
- package/dist/hooks/dispatch.sha256 +1 -1
- package/dist/install/claudePathsPlan.js +47 -6
- package/dist/install/claudeRuleRewrite.js +7 -0
- package/dist/install/emit_host_rules_cli.js +39 -36
- package/dist/install/globalRuleScope.js +87 -0
- package/dist/install/host_rule_ownership.js +160 -0
- package/dist/install/install.mjs +2336 -1249
- package/dist/install/installThinLayer.js +289 -0
- package/dist/install/installedRuleLinks.js +262 -0
- package/dist/install/wizard-plan.js +24 -0
- package/dist/mcp/awesome-mcp-servers.row.md +1 -1
- package/dist/mcp/mcp-cloudflare-catalogue.json +2 -2
- package/dist/mcp/registry-manifest.json +5 -5
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +36504 -30986
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/agent_settings.js +26 -120
- package/dist/scripts/_lib/claude_settings_hooks.js +10 -8
- package/dist/scripts/_lib/compile_time_toggles.js +12 -21
- package/dist/scripts/_lib/git_convention.js +232 -0
- package/dist/scripts/_lib/global_deploy_inventory.js +730 -0
- package/dist/scripts/_lib/installed_layer.js +704 -0
- package/dist/scripts/_lib/lean_projection_mode.js +218 -15
- package/dist/scripts/_lib/package_root.js +68 -0
- package/dist/scripts/_lib/rule_consequence_class.js +45 -0
- package/dist/scripts/_lib/rule_injection.js +67 -10
- package/dist/scripts/_lib/rule_law_section.js +122 -0
- package/dist/scripts/_lib/settings_removed_keys.js +168 -0
- package/dist/scripts/_lib/thin_rules.js +535 -0
- package/dist/scripts/_lib/windsurf_render.js +60 -0
- package/dist/scripts/condense.js +14 -26
- package/dist/scripts/project_thin_rules.js +14 -294
- package/dist/server/app.js +2 -1
- package/dist/server/gitKeysGate.js +105 -0
- package/dist/server/routes/settings.js +67 -8
- package/dist/server/routes/wizard.js +4 -0
- package/dist/server/schemas/settings.js +29 -81
- package/dist/shared/skillRanking.js +103 -16
- package/dist/ui/assets/{index-Cwq4d0hX.js → index-C3djEJah.js} +2 -2
- package/dist/ui/index.html +1 -1
- package/docs/MIGRATION.md +72 -1
- package/docs/contracts/settings-classes.md +39 -67
- package/docs/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
- package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
- package/docs/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
- package/docs/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
- package/docs/guidelines/agent-infra/layered-settings.md +13 -1
- package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
- package/docs/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
- package/docs/guidelines/agent-infra/size-and-scope.md +36 -0
- package/docs/guidelines/php/git.md +15 -2
- package/package.json +1 -1
- package/src/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
- package/src/agent-src/scripts/deferral_carry.ts +339 -0
- package/src/agent-src/scripts/gate_budget.ts +47 -23
- package/src/agent-src/scripts/gate_execute.ts +12 -4
- package/src/agent-src/scripts/update_roadmap_progress.ts +4 -1
- package/src/agent-src/templates/AGENTS.md +1 -1
- package/src/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
- package/src/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
- package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +48 -6
- package/src/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
- package/src/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
- package/src/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
- package/src/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
- package/src/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
- package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
- package/src/config/agent-settings.template.yml +141 -334
- package/src/config/agents-paths.yml +16 -0
- package/src/config/assurance-capability-registry.json +7 -3
- package/src/config/ci-local-parity.yml +3 -0
- package/src/config/continuity-surface.json +10 -3
- package/src/config/discovery/packs.yml +17 -1
- package/src/config/evaluator-budgets.json +23 -10
- package/src/config/gate-coverage.yml +138 -3
- package/src/config/gate-violation-baselines.json +64 -16
- package/src/config/gitignore-block.txt +19 -0
- package/src/config/hook-bundle-budget.json +25 -0
- package/src/config/hook-token-budget.json +6 -1
- package/src/config/host-instruction-limits.json +33 -0
- package/src/config/release-gate-locality.yml +2 -1
- package/src/config/routing-coverage-seed.json +67 -4
- package/src/config/rule-activation-census.json +7 -3
- package/src/config/rule-consequence-class.json +161 -0
- package/src/config/rule-law-ceilings.json +105 -0
- package/src/config/rule-obligations.json +833 -0
- package/src/install/claudePathsPlan.ts +46 -4
- package/src/install/claudeRuleRewrite.ts +10 -1
- package/src/install/emit_host_rules_cli.ts +43 -34
- package/src/install/globalRuleScope.ts +109 -0
- package/src/install/host_rule_ownership.ts +170 -0
- package/src/install/installThinLayer.ts +378 -0
- package/src/install/installedRuleLinks.ts +308 -0
- package/src/install/wizard-plan.ts +24 -0
- package/src/scripts/_cli/cmd_analyze_session.ts +9 -15
- package/src/scripts/_cli/cmd_conformance.ts +13 -2
- package/src/scripts/_cli/cmd_doctor.ts +33 -81
- package/src/scripts/_cli/cmd_doctor_neighbours.ts +426 -0
- package/src/scripts/_cli/cmd_explain.ts +72 -14
- package/src/scripts/_cli/cmd_git_convention.ts +637 -0
- package/src/scripts/_cli/cmd_settings_check.ts +66 -8
- package/src/scripts/_cli/cmd_settings_get.ts +18 -3
- package/src/scripts/_cli/doctor_execution.ts +72 -1
- package/src/scripts/_dispatch.bash +53 -4
- package/src/scripts/_lib/agent_settings.ts +26 -124
- package/src/scripts/_lib/blocked_by_marker.ts +1 -1
- package/src/scripts/_lib/claude_settings_hooks.ts +10 -8
- package/src/scripts/_lib/compile_time_toggles.ts +12 -21
- package/src/scripts/_lib/dispatch_import_closure.ts +163 -0
- package/src/scripts/_lib/estate_offsets.ts +241 -0
- package/src/scripts/_lib/exemption_shape.ts +143 -0
- package/src/scripts/_lib/fnv.ts +23 -0
- package/src/scripts/_lib/foreign_scan.ts +106 -0
- package/src/scripts/_lib/git_base_ref.ts +92 -0
- package/src/scripts/_lib/git_convention.ts +291 -0
- package/src/scripts/_lib/git_convention_carrier.ts +389 -0
- package/src/scripts/_lib/git_convention_grammar.ts +246 -0
- package/src/scripts/_lib/git_convention_measure.ts +344 -0
- package/src/scripts/_lib/gitignore_block.ts +314 -0
- package/src/scripts/_lib/global_deploy_inventory.ts +106 -0
- package/src/scripts/_lib/graph_feeder_record.ts +437 -0
- package/src/scripts/_lib/hook_settings.ts +73 -0
- package/src/scripts/_lib/host_capability.ts +40 -19
- package/src/scripts/_lib/host_hook_merge.ts +165 -0
- package/src/scripts/_lib/installed_layer.ts +963 -0
- package/src/scripts/_lib/json_merge.ts +82 -0
- package/src/scripts/_lib/json_pointers.ts +93 -11
- package/src/scripts/_lib/knowledge_global.ts +14 -1
- package/src/scripts/_lib/lean_projection_mode.ts +275 -15
- package/src/scripts/_lib/machine_wake.ts +16 -3
- package/src/scripts/_lib/module_reach.ts +456 -0
- package/src/scripts/_lib/neighbour_census.ts +760 -0
- package/src/scripts/_lib/neighbour_contradictions.ts +236 -0
- package/src/scripts/_lib/neighbour_scan.ts +122 -0
- package/src/scripts/_lib/neighbour_tool_use.ts +187 -0
- package/src/scripts/_lib/prompt_shape.ts +46 -0
- package/src/scripts/_lib/ratification_artifact.ts +220 -1
- package/src/scripts/_lib/ratification_subject.ts +92 -0
- package/src/scripts/_lib/release_findings_ingest.ts +15 -7
- package/src/scripts/_lib/release_highlights.ts +5 -0
- package/src/scripts/_lib/release_migration_gate.ts +19 -3
- package/src/scripts/_lib/reserved_name_sweep.ts +73 -0
- package/src/scripts/_lib/review_coverage.ts +134 -0
- package/src/scripts/_lib/rule_consequence_class.ts +71 -0
- package/src/scripts/_lib/rule_injection.ts +130 -10
- package/src/scripts/_lib/rule_law_section.ts +147 -0
- package/src/scripts/_lib/rule_layer_overlap.ts +58 -0
- package/src/scripts/_lib/rule_obligations.ts +205 -0
- package/src/scripts/_lib/self_repair.ts +1 -1
- package/src/scripts/_lib/settings_removed_keys.ts +173 -0
- package/src/scripts/_lib/skill_origin.ts +254 -0
- package/src/scripts/_lib/structured_ask.ts +64 -21
- package/src/scripts/_lib/test_red_state.ts +5 -0
- package/src/scripts/_lib/thin_rules.ts +620 -0
- package/src/scripts/_lib/touched_file_quality.ts +570 -0
- package/src/scripts/_lib/turn_end_refusals.ts +77 -2
- package/src/scripts/_lib/windsurf_render.ts +63 -0
- package/src/scripts/_lib/worker_budget.ts +1 -1
- package/src/scripts/adr/regenerate_index.ts +16 -1
- package/src/scripts/ai_council/cli_call_budget.ts +13 -5
- package/src/scripts/ai_council/clients.ts +26 -57
- package/src/scripts/ai_council/config.ts +8 -8
- package/src/scripts/ai_council/modification_review.ts +100 -0
- package/src/scripts/ai_council/modification_review_questions.ts +90 -0
- package/src/scripts/ai_council/orchestrator.ts +5 -5
- package/src/scripts/ai_council/spend_gate.ts +18 -7
- package/src/scripts/ai_council/vendor_defaults.ts +45 -0
- package/src/scripts/ai_team/config.ts +11 -16
- package/src/scripts/audit_skill_overlap.ts +261 -0
- package/src/scripts/audit_user_type_axis.ts +20 -8
- package/src/scripts/before_complete_hook.ts +243 -12
- package/src/scripts/bench_ab_clone.ts +1 -2
- package/src/scripts/bench_concern_spawn_path.ts +129 -0
- package/src/scripts/bench_graph_feeder_latency.ts +584 -0
- package/src/scripts/bench_touched_file_quality.ts +238 -0
- package/src/scripts/check_agent_artifact_location.ts +36 -0
- package/src/scripts/check_branch_freshness.ts +147 -24
- package/src/scripts/check_enforcement_coverage.ts +130 -0
- package/src/scripts/check_enforcement_matrix.ts +377 -20
- package/src/scripts/check_estate_count.ts +130 -153
- package/src/scripts/check_evaluator_budgets.ts +4 -0
- package/src/scripts/check_finding_dispositions.ts +196 -21
- package/src/scripts/check_gate_coverage.ts +4 -3
- package/src/scripts/check_gate_reachability.ts +48 -1
- package/src/scripts/check_generator_sync.ts +48 -0
- package/src/scripts/check_hook_bundle_composition.ts +477 -0
- package/src/scripts/check_kernel_edit_ratified.ts +132 -14
- package/src/scripts/check_memory.ts +7 -1
- package/src/scripts/check_pack_size.ts +1 -1
- package/src/scripts/check_release_highlights.ts +10 -0
- package/src/scripts/check_release_manifest_content.ts +189 -0
- package/src/scripts/check_release_pr_shape.ts +38 -15
- package/src/scripts/check_standing_rule_delivery.ts +129 -13
- package/src/scripts/check_suppression_hygiene.ts +2 -5
- package/src/scripts/check_verify_expectation_delta.ts +521 -0
- package/src/scripts/ci_settle.ts +42 -5
- package/src/scripts/classify_merge_risk.ts +320 -0
- package/src/scripts/closure_scan.ts +91 -1
- package/src/scripts/code_graph/detect.ts +127 -7
- package/src/scripts/code_graph/foreign.ts +194 -0
- package/src/scripts/code_graph/query.ts +217 -4
- package/src/scripts/code_graph/types.ts +26 -2
- package/src/scripts/code_graph/validate.ts +3 -1
- package/src/scripts/code_graph/verbs.ts +103 -0
- package/src/scripts/command_suggester/settings.ts +8 -108
- package/src/scripts/command_suggester/types.ts +4 -5
- package/src/scripts/compile_hook_manifest.ts +33 -1
- package/src/scripts/condense.ts +14 -27
- package/src/scripts/consumer_matrix.ts +102 -0
- package/src/scripts/context_hygiene_hook.ts +13 -23
- package/src/scripts/cost/preflight.mjs +12 -1
- package/src/scripts/council_cli.ts +7 -7
- package/src/scripts/dispatch_r2_reviewer.ts +24 -11
- package/src/scripts/estate_exemption_shape.ts +202 -0
- package/src/scripts/explain_run.ts +8 -13
- package/src/scripts/generate_git_convention_grammar.ts +127 -0
- package/src/scripts/generate_host_cost_table.ts +21 -4
- package/src/scripts/handoff_context_hook.ts +86 -37
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +175 -15
- package/src/scripts/hooks/block_config_weakening.ts +115 -7
- package/src/scripts/hooks/block_plumbing_writes.ts +37 -5
- package/src/scripts/hooks/code_graph_context_hook.ts +252 -23
- package/src/scripts/hooks/concern_failure_policy.ts +280 -0
- package/src/scripts/hooks/concern_registry.ts +2 -0
- package/src/scripts/hooks/delegation_nudge_hook.ts +2 -3
- package/src/scripts/hooks/dispatch_hook.ts +52 -52
- package/src/scripts/hooks/evidence_independence.ts +12 -4
- package/src/scripts/hooks/exit_codes.ts +2 -1
- package/src/scripts/hooks/host_lowering.json +1 -1
- package/src/scripts/hooks/host_lowering.ts +19 -1
- package/src/scripts/hooks/mcp_usage_observation_hook.ts +121 -0
- package/src/scripts/hooks/one_question_per_ask_hook.ts +41 -25
- package/src/scripts/hooks/payload_stub.ts +10 -1
- package/src/scripts/hooks/push_settle_hook.ts +4 -3
- package/src/scripts/hooks/rule_inject_hook.ts +795 -60
- package/src/scripts/hooks/state_io.ts +8 -4
- package/src/scripts/hooks/table_fingerprint.ts +21 -0
- package/src/scripts/hooks/telemetry_usage_hook.ts +24 -7
- package/src/scripts/hooks/turn_end_gate_hook.ts +85 -0
- package/src/scripts/hooks_status.ts +112 -0
- package/src/scripts/injection_scan_hook.ts +7 -0
- package/src/scripts/install-hooks.sh +42 -14
- package/src/scripts/install.ts +78 -215
- package/src/scripts/installed_layer_report.ts +103 -0
- package/src/scripts/language_mirror_hook.ts +15 -6
- package/src/scripts/learning_sidecar.ts +119 -8
- package/src/scripts/lint_blocker_citations.ts +198 -0
- package/src/scripts/lint_evidence_artifacts.ts +9 -0
- package/src/scripts/lint_hook_concern_budget.ts +10 -21
- package/src/scripts/lint_hook_manifest.ts +53 -0
- package/src/scripts/lint_major_migration_sections.ts +156 -26
- package/src/scripts/lint_pack_boundaries.ts +465 -29
- package/src/scripts/lint_roadmap_blockers.ts +282 -29
- package/src/scripts/lint_roadmap_complexity.ts +4 -2
- package/src/scripts/lint_rule_law_section.ts +647 -0
- package/src/scripts/lint_rule_skill_pack_reach.ts +17 -0
- package/src/scripts/lint_settings_classes.ts +1 -1
- package/src/scripts/lint_ticked_unmet_criteria.ts +165 -0
- package/src/scripts/lint_workflow_security.ts +173 -6
- package/src/scripts/mcp_server/consumer_tool_catalog.json +53 -0
- package/src/scripts/mcp_server/graph_tools.ts +72 -3
- package/src/scripts/measure_routing_signal.ts +54 -16
- package/src/scripts/measure_skill_ranker_baseline.ts +221 -8
- package/src/scripts/memory_learn_hook.ts +91 -6
- package/src/scripts/model_rule_injection.ts +55 -8
- package/src/scripts/onboarding_gate_hook.ts +7 -6
- package/src/scripts/print_required_checks.ts +15 -3
- package/src/scripts/probe_host_compliance.ts +33 -5
- package/src/scripts/probe_turnaround.ts +183 -3
- package/src/scripts/project_thin_rules.ts +34 -327
- package/src/scripts/ratification_header.ts +77 -0
- package/src/scripts/refusal_envelope.ts +138 -0
- package/src/scripts/release_publication.ts +29 -3
- package/src/scripts/report_dispatch_import_closure.ts +76 -0
- package/src/scripts/report_evidence_temperature.ts +657 -0
- package/src/scripts/report_installed_rule_links.ts +274 -0
- package/src/scripts/report_label_agreement.ts +233 -0
- package/src/scripts/report_module_reach.ts +212 -0
- package/src/scripts/report_obligation_mechanism.ts +228 -0
- package/src/scripts/report_parked_blockers.ts +222 -0
- package/src/scripts/report_required_checks_drift.ts +196 -0
- package/src/scripts/report_single_token_triggers.ts +277 -0
- package/src/scripts/report_skill_ranker_confusion.ts +543 -0
- package/src/scripts/report_standing_payload_by_host.ts +188 -15
- package/src/scripts/report_verification_record_coverage.ts +306 -0
- package/src/scripts/routing_doctor.ts +2 -2
- package/src/scripts/rule_activation_census.ts +5 -2
- package/src/scripts/rule_trigger_eval.ts +9 -9
- package/src/scripts/schemas/agent-settings.schema.json +17 -31
- package/src/scripts/schemas/command.schema.json +1 -1
- package/src/scripts/schemas/review-findings.schema.json +3 -2
- package/src/scripts/schemas/rule.schema.json +5 -0
- package/src/scripts/schemas/skill.schema.json +1 -1
- package/src/scripts/self_review_gate.ts +101 -9
- package/src/scripts/skill_tools/score_skill_relevance.ts +314 -40
- package/src/scripts/sweep_skill_ranker_signals.ts +129 -0
- package/src/scripts/sync_gitignore.ts +29 -235
- package/src/scripts/sync_pr_branch.ts +403 -132
- package/src/scripts/trigger_eval_grandfather.json +0 -21
- package/src/server/schemas/settings.ts +42 -176
- package/src/shared/skillRanking.ts +169 -14
- package/dist/cli-delegate/chunk-5R7HOLAF.js +0 -99
- package/dist/cli-delegate/chunk-JNMVLWLR.js +0 -4457
- package/dist/cli-delegate/chunk-YDPILCOL.js +0 -152
- package/src/scripts/_lib/config_chain.ts +0 -477
- package/src/scripts/_lib/conformance_report.ts +0 -403
- package/src/scripts/_lib/eval_discrimination.ts +0 -95
- package/src/scripts/_lib/evaluator_promotion.ts +0 -225
- package/src/scripts/_lib/file_slicer.ts +0 -117
- package/src/scripts/_lib/legacy_boundary_map.ts +0 -228
- package/src/scripts/_lib/minimality_tiebreak.ts +0 -168
- package/src/scripts/_lib/overbuild_lens_contract.ts +0 -196
- package/src/scripts/_lib/role_split.ts +0 -338
|
@@ -71,6 +71,21 @@ function expanduser(p: string): string {
|
|
|
71
71
|
return p;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
/**
|
|
75
|
+
* `expanduser`, against a STATED home rather than the process's own.
|
|
76
|
+
*
|
|
77
|
+
* `home` omitted or empty falls back to {@link expanduser}, so every existing
|
|
78
|
+
* caller is unchanged.
|
|
79
|
+
*/
|
|
80
|
+
function expanduser_at(p: string, home?: string | null): string {
|
|
81
|
+
if (home === undefined || home === null || home === "") return expanduser(p);
|
|
82
|
+
if (p === "~") return home;
|
|
83
|
+
if (p.startsWith("~/") || (process.platform === "win32" && p.startsWith("~\\"))) {
|
|
84
|
+
return path.join(home, p.slice(2));
|
|
85
|
+
}
|
|
86
|
+
return p;
|
|
87
|
+
}
|
|
88
|
+
|
|
74
89
|
/**
|
|
75
90
|
* Resolve a path the way `Path.resolve()` does: expand-free `realpath`-style
|
|
76
91
|
* resolution that follows existing symlinks and normalises `..`, but does not
|
|
@@ -658,6 +673,97 @@ function difference(prev: unknown[], current: Set<string>): unknown[] {
|
|
|
658
673
|
return out;
|
|
659
674
|
}
|
|
660
675
|
|
|
676
|
+
/**
|
|
677
|
+
* The anchor-relative paths a previous deploy of `tool_id` recorded.
|
|
678
|
+
*
|
|
679
|
+
* Empty whenever the inventory has no entry, the recorded anchor differs from
|
|
680
|
+
* `anchor`, or the entry is malformed — the same "not provably ours anymore"
|
|
681
|
+
* discipline `reap_stale` applies before it deletes anything. Callers use it
|
|
682
|
+
* to answer "did this package write that file" for a file the CURRENT run did
|
|
683
|
+
* not write.
|
|
684
|
+
*/
|
|
685
|
+
export function recorded_rel_files(
|
|
686
|
+
tool_id: string,
|
|
687
|
+
anchor: string,
|
|
688
|
+
inventory?: Inventory | null,
|
|
689
|
+
): ReadonlySet<string> {
|
|
690
|
+
const inv = inventory ?? load_inventory();
|
|
691
|
+
const tools = (inv["tools"] as Record<string, unknown> | undefined) ?? {};
|
|
692
|
+
const entry = tools[tool_id];
|
|
693
|
+
if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
|
|
694
|
+
return new Set<string>();
|
|
695
|
+
}
|
|
696
|
+
const e = entry as Record<string, unknown>;
|
|
697
|
+
const recorded_anchor = e["anchor"];
|
|
698
|
+
const files = e["files"];
|
|
699
|
+
if (typeof recorded_anchor !== "string" || !Array.isArray(files)) {
|
|
700
|
+
return new Set<string>();
|
|
701
|
+
}
|
|
702
|
+
if (resolve_path(expanduser(recorded_anchor)) !== resolve_path(expanduser(anchor))) {
|
|
703
|
+
return new Set<string>();
|
|
704
|
+
}
|
|
705
|
+
return new Set(files.filter((f): f is string => typeof f === "string"));
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
/**
|
|
709
|
+
* Every file a previous deploy recorded, as ABSOLUTE paths, across all tools.
|
|
710
|
+
*
|
|
711
|
+
* `recorded_rel_files` answers "did this package write that file" for one tool
|
|
712
|
+
* whose anchor the caller already knows. This answers the ownership question a
|
|
713
|
+
* READER has — the installed-layer report and the install receipt both walk
|
|
714
|
+
* host rule directories and hold absolute paths, with no tool id and no anchor
|
|
715
|
+
* in hand — so asking the inventory per tool would mean the reader guessing
|
|
716
|
+
* anchors it never recorded.
|
|
717
|
+
*
|
|
718
|
+
* `home` IS A PARAMETER, AND NOT A CONVENIENCE. The installer records the
|
|
719
|
+
* anchor TILDE-RELATIVE — the real inventory reads `"anchor": "~/.claude/"` —
|
|
720
|
+
* so the recorded path is only meaningful against a stated home. Expanding it
|
|
721
|
+
* against `os.homedir()` makes the answer depend on which process is asking,
|
|
722
|
+
* which is exactly how a reader measuring a staged install under a temporary
|
|
723
|
+
* HOME gets back a set naming the maintainer's own machine and claims nothing.
|
|
724
|
+
* Omitted, it falls back to `os.homedir()`, which is right for a caller asking
|
|
725
|
+
* about the install it is itself running under.
|
|
726
|
+
*
|
|
727
|
+
* BOTH SPELLINGS OF EVERY PATH ARE EMITTED — the symlink-resolved one and the
|
|
728
|
+
* merely-normalised one. Callers compare by set membership against a path they
|
|
729
|
+
* built with `path.join(dir, name)` while walking a directory, which is
|
|
730
|
+
* lexical; the inventory's anchor is resolved with `realpath` the way
|
|
731
|
+
* `recorded_rel_files` resolves its anchor comparison. On macOS those two
|
|
732
|
+
* differ for anything under `/var`, which realpaths to `/private/var`, and a
|
|
733
|
+
* one-spelling set silently claimed nothing there — the reader asked about
|
|
734
|
+
* `/var/...`, the set held `/private/var/...`, and every file read foreign.
|
|
735
|
+
* Emitting both is the cheap direction: a set is a membership test, so a second
|
|
736
|
+
* spelling can only make a true answer reachable, never a false one.
|
|
737
|
+
*
|
|
738
|
+
* A malformed tool entry contributes nothing rather than throwing: a corrupt
|
|
739
|
+
* inventory is "no evidence", never a finding, which is the same discipline
|
|
740
|
+
* `reap_stale` applies before it deletes anything.
|
|
741
|
+
*/
|
|
742
|
+
export function recorded_absolute_files(
|
|
743
|
+
inventory?: Inventory | null,
|
|
744
|
+
home?: string | null,
|
|
745
|
+
): ReadonlySet<string> {
|
|
746
|
+
const inv = inventory ?? load_inventory();
|
|
747
|
+
const tools = (inv["tools"] as Record<string, unknown> | undefined) ?? {};
|
|
748
|
+
const out = new Set<string>();
|
|
749
|
+
if (typeof tools !== "object" || tools === null || Array.isArray(tools)) return out;
|
|
750
|
+
for (const entry of Object.values(tools)) {
|
|
751
|
+
if (typeof entry !== "object" || entry === null || Array.isArray(entry)) continue;
|
|
752
|
+
const e = entry as Record<string, unknown>;
|
|
753
|
+
const anchor = e["anchor"];
|
|
754
|
+
const files = e["files"];
|
|
755
|
+
if (typeof anchor !== "string" || !Array.isArray(files)) continue;
|
|
756
|
+
const expanded = expanduser_at(anchor, home);
|
|
757
|
+
for (const rel of files) {
|
|
758
|
+
if (typeof rel !== "string") continue;
|
|
759
|
+
const lexical = path.resolve(expanded, rel);
|
|
760
|
+
out.add(lexical);
|
|
761
|
+
out.add(resolve_path(lexical));
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
return out;
|
|
765
|
+
}
|
|
766
|
+
|
|
661
767
|
/** Sort string members ascending by codepoint (non-strings filtered out). */
|
|
662
768
|
function sorted_strings(items: unknown[]): string[] {
|
|
663
769
|
return items
|
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The graph feeder record — detector F's verdict and the code graph's, side by
|
|
3
|
+
* side, on every stop where a graph existed (`road-to-a-graph-that-feeds-the-gate`
|
|
4
|
+
* step 3.2).
|
|
5
|
+
*
|
|
6
|
+
* WHY A SEPARATE RECORD AND NOT `ShadowRecord` (D3). `ShadowRecord` is written
|
|
7
|
+
* only on the `stop_hook_active` and `refused_turn` layers and is the Q1
|
|
8
|
+
* instrument of `road-to-a-stop-that-holds` — a live measurement window with its
|
|
9
|
+
* own denominator. Folding a second signal into it would contaminate a reading
|
|
10
|
+
* somebody else is taking, which is a worse failure than a second file.
|
|
11
|
+
*
|
|
12
|
+
* WHY IT CHANGES NO VERDICT, AND WHAT THAT CLAIM DOES NOT COVER. Every function
|
|
13
|
+
* here is wrapped, every failure path returns silently, and no caller branches on
|
|
14
|
+
* the result, so no in-process path can move an exit code. It is NOT a claim
|
|
15
|
+
* about latency, and an earlier version of this paragraph said "costs the turn
|
|
16
|
+
* nothing", which a review correctly read as one: a stop in a repository with a
|
|
17
|
+
* graph pays a `git status` spawn, a graph open and an `untested` walk.
|
|
18
|
+
* `bench_graph_feeder_latency.ts` measures it, and over a large index the graph
|
|
19
|
+
* open dominates. A host that timed a stop
|
|
20
|
+
* hook out would drop the gate's refusal — a failure the comparative exit-code
|
|
21
|
+
* test cannot see, because both of its runs complete. Step 3.4 — promoting the
|
|
22
|
+
* graph verdict into F — is DEFERRED behind step 3.3's recall measurement and
|
|
23
|
+
* behind an owner amendment to ADR-277, and nothing here anticipates it.
|
|
24
|
+
*
|
|
25
|
+
* WHAT A ROW MAY CONTAIN. The fields are a closed set of enums, counts and
|
|
26
|
+
* source paths, repo-relative wherever the edit lay inside the workspace. There
|
|
27
|
+
* is no field able to hold a prompt, a file body, a reply or a command — the same
|
|
28
|
+
* PII-exclusion-by-construction discipline `domain-safety-pii` § Surface 2 asks
|
|
29
|
+
* of a log line, and the same shape `ToolCall` already has. Paths are in the set
|
|
30
|
+
* because they are the evidence a human labeller needs in step 3.3 and because
|
|
31
|
+
* the gate's own refusal text already quotes them; they are capped so one turn
|
|
32
|
+
* cannot write an unbounded row. An edit OUTSIDE the workspace root is the one
|
|
33
|
+
* shape that could carry identifying content, and {@link buildFeederRow}
|
|
34
|
+
* REDACTS it to {@link OUTSIDE_WORKSPACE} — it does not drop it, which was tried
|
|
35
|
+
* and rejected for the reason recorded at that call site.
|
|
36
|
+
*
|
|
37
|
+
* WHERE THAT PROPERTY ACTUALLY HOLDS, stated at its real width. The redaction
|
|
38
|
+
* lives in `buildFeederRow`, so it covers every row THIS module builds, which is
|
|
39
|
+
* every row anything writes today. It is not enforced by the TYPE:
|
|
40
|
+
* `GraphFeederRow.paths` is a plain `string[]` and {@link appendFeederRow} is
|
|
41
|
+
* exported and checks nothing, so a future second writer could persist an
|
|
42
|
+
* unredacted path with no compile error and no runtime guard. A completion
|
|
43
|
+
* review pointed out that the previous wording — "true by construction" without
|
|
44
|
+
* qualification — claimed exactly the convention it was disclaiming. The
|
|
45
|
+
* field-shape half of the header IS by construction: there is no field a prompt
|
|
46
|
+
* or a file body could occupy. The path-redaction half is by call site, and the
|
|
47
|
+
* two are worth not conflating.
|
|
48
|
+
*/
|
|
49
|
+
import * as fs from 'node:fs';
|
|
50
|
+
import * as path from 'node:path';
|
|
51
|
+
|
|
52
|
+
import { detectSources, type GraphState, NATIVE_CACHE_REL, pickSource } from '../code_graph/detect.js';
|
|
53
|
+
import { loadGraph } from '../code_graph/query.js';
|
|
54
|
+
import { untested } from '../code_graph/verbs.js';
|
|
55
|
+
|
|
56
|
+
/** At most this many edit paths per row. */
|
|
57
|
+
const MAX_PATHS = 5;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* What a row stores in place of an edit that lay outside the workspace root.
|
|
61
|
+
*
|
|
62
|
+
* Not a path, deliberately: it carries no directory, no user name and no
|
|
63
|
+
* project name, so it cannot be an egress surface when `paths` is handed to an
|
|
64
|
+
* external labeller. It still tells that labeller an edit happened out of tree,
|
|
65
|
+
* which is the difference between answering `cannot tell` and being misled.
|
|
66
|
+
*/
|
|
67
|
+
export const OUTSIDE_WORKSPACE = '<outside-workspace>';
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* At most this many rows per session file.
|
|
71
|
+
*
|
|
72
|
+
* `agents/state/` is local and gitignored, but "local" is not "free": a long
|
|
73
|
+
* session appends on every turn end, and an instrument that grows without a
|
|
74
|
+
* bound is the failure the gate's own refusal-state history already records.
|
|
75
|
+
* Past the cap the writer stops rather than rotating — a truncated tail is a
|
|
76
|
+
* readable sample, and a rotation would silently drop the earliest rows that a
|
|
77
|
+
* recall reading most wants.
|
|
78
|
+
*/
|
|
79
|
+
export const MAX_ROWS_PER_SESSION = 200;
|
|
80
|
+
|
|
81
|
+
/** The graph's half of the verdict. `null` means the graph did not contribute. */
|
|
82
|
+
export type GraphVerdict = 'untested' | 'tested' | 'no-seeds' | null;
|
|
83
|
+
|
|
84
|
+
/** One stop, as the feeder records it. */
|
|
85
|
+
/**
|
|
86
|
+
* The stop layer a row came from.
|
|
87
|
+
*
|
|
88
|
+
* A closed union rather than `string`. The header below calls these fields "a
|
|
89
|
+
* closed set of enums", and a review pointed out the types did not enforce it —
|
|
90
|
+
* the sets lived only in the call sites, so a later caller could widen either
|
|
91
|
+
* with no type error and the prose would quietly become false.
|
|
92
|
+
*/
|
|
93
|
+
export type FeederLayer = 'live' | 'stop_hook_active' | 'refused_turn';
|
|
94
|
+
|
|
95
|
+
/** Detector F's evidence class, from the same closed set the detector uses. */
|
|
96
|
+
export type FeederMode = 'transcript' | 'record';
|
|
97
|
+
|
|
98
|
+
export interface GraphFeederRow {
|
|
99
|
+
at: string;
|
|
100
|
+
/** The turn's ordinal — how many genuine user prompts preceded it. */
|
|
101
|
+
turn: number;
|
|
102
|
+
/** Which stop layer produced this row: the live verdict, or a retry. */
|
|
103
|
+
layer: FeederLayer;
|
|
104
|
+
graph_state: GraphState;
|
|
105
|
+
/** Did detector F fire on this turn? */
|
|
106
|
+
f: boolean;
|
|
107
|
+
/** F's evidence class when it fired — `transcript` or `record`. */
|
|
108
|
+
f_mode: FeederMode | null;
|
|
109
|
+
graph: GraphVerdict;
|
|
110
|
+
/** How many changed symbols the graph found no test edge for. */
|
|
111
|
+
graph_untested: number;
|
|
112
|
+
/** How many it did find one for — so the ratio is readable. */
|
|
113
|
+
graph_tested: number;
|
|
114
|
+
/** The turn's edit paths, capped at {@link MAX_PATHS}. */
|
|
115
|
+
paths: string[];
|
|
116
|
+
/** How many edit paths there were in total, when the list is capped. */
|
|
117
|
+
path_count: number;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function feederFile(workspaceRoot: string, sessionKey: string): string {
|
|
121
|
+
return path.join(workspaceRoot, 'agents', 'state', 'graph-feeder', `${sessionKey}.jsonl`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Put edit paths into the shape the graph indexes them in.
|
|
126
|
+
*
|
|
127
|
+
* THE DEFECT THIS REPAIRS, measured before it was fixed. `ToolCall.path` carries
|
|
128
|
+
* whatever the host wrote into `file_path`, and Claude Code writes an ABSOLUTE
|
|
129
|
+
* path. The graph keys its node ids on repo-relative paths, so `seedsForFiles`
|
|
130
|
+
* resolved nothing, `untested` returned an empty seed set, and the feeder wrote
|
|
131
|
+
* `no-seeds`. 19 accrued rows carried a path; the 18 that reached the graph at
|
|
132
|
+
* all recorded `no-seeds`, and the nineteenth was skipped on `behind:0`. Not one
|
|
133
|
+
* of them was a fact about the code: the graph arm was mute for its whole
|
|
134
|
+
* accrual window. Probed at `c58d7eae` against the real index —
|
|
135
|
+
* `src/scripts/check_memory.ts` resolves 60 seeds relative and 0 absolute.
|
|
136
|
+
*
|
|
137
|
+
* It survived review because every fixture fed a relative path. A test never run
|
|
138
|
+
* against the shape the host emits cannot see this, which is why the regression
|
|
139
|
+
* test added with this fix is written against the absolute form.
|
|
140
|
+
*
|
|
141
|
+
* Repaired HERE rather than at the one call site, because `graphUntestedVerdict`
|
|
142
|
+
* is exported and a second caller would meet the same silence.
|
|
143
|
+
*
|
|
144
|
+
* A path outside the workspace root is returned unchanged: it is not addressable
|
|
145
|
+
* in the graph under any spelling, and rewriting it to `../..` would turn an
|
|
146
|
+
* honest `no-seeds` into a relative-looking string that still indexes nothing.
|
|
147
|
+
*
|
|
148
|
+
* SEPARATORS ARE NORMALISED TO POSIX, and that is not cosmetic. The indexer
|
|
149
|
+
* writes `source_file` through its own `toPosixRel`, and the store matches it by
|
|
150
|
+
* exact string, so on a host whose `path.sep` is a backslash a raw
|
|
151
|
+
* `path.relative` would emit `src\service.ts`, resolve no seeds, and record
|
|
152
|
+
* `no-seeds` — reintroducing precisely the defect above as a platform-
|
|
153
|
+
* conditional one. Found by the completion review of the commit that first fixed
|
|
154
|
+
* it; neither regression test could have seen it, because both run on one
|
|
155
|
+
* platform.
|
|
156
|
+
*/
|
|
157
|
+
export function toRepoRelative(root: string, paths: readonly string[]): string[] {
|
|
158
|
+
let realRoot: string | null = null;
|
|
159
|
+
return paths.map((p) => {
|
|
160
|
+
if (!path.isAbsolute(p)) return p;
|
|
161
|
+
// RAW FIRST, RESOLVED ONLY AS A FALLBACK. The indexer keys `source_file`
|
|
162
|
+
// through a plain tree walk with NO realpath, so the raw spelling is the
|
|
163
|
+
// one it agrees with. Resolving unconditionally fixes a symlinked ROOT
|
|
164
|
+
// and breaks the opposite shape: an in-tree file reached through an
|
|
165
|
+
// in-repo symlink whose target leaves the workspace would relativise to
|
|
166
|
+
// a `..` segment and be redacted off the row — destroying the labelling
|
|
167
|
+
// evidence for a path that is in the tree, which is the harm the
|
|
168
|
+
// redact-rather-than-drop argument exists to prevent. Trying the raw
|
|
169
|
+
// comparison first keeps both: the common case matches the indexer, and
|
|
170
|
+
// the resolved walk is spent only when the raw answer says foreign.
|
|
171
|
+
const raw = _relativeInside(root, p);
|
|
172
|
+
if (raw !== null) return raw;
|
|
173
|
+
realRoot ??= _resolveReal(root);
|
|
174
|
+
return _relativeInside(realRoot, _resolveReal(p)) ?? p;
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* `from` -> `to` as a POSIX repo-relative path, or `null` when `to` is outside.
|
|
180
|
+
*
|
|
181
|
+
* `rel === ''` means `to` IS the root, which is emphatically not outside it —
|
|
182
|
+
* folding that into the escape branch made the row say the opposite of the
|
|
183
|
+
* truth. The `..` test is for a leading `..` SEGMENT, not a leading `..` string:
|
|
184
|
+
* `startsWith('..')` also matches an in-tree first segment that merely begins
|
|
185
|
+
* with two dots, such as `..cache/service.ts`.
|
|
186
|
+
*/
|
|
187
|
+
function _relativeInside(from: string, to: string): string | null {
|
|
188
|
+
let rel: string;
|
|
189
|
+
try {
|
|
190
|
+
rel = path.relative(from, to);
|
|
191
|
+
} catch {
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
if (rel === '') return '.';
|
|
195
|
+
if (rel === '..' || rel.startsWith(`..${path.sep}`) || path.isAbsolute(rel)) return null;
|
|
196
|
+
return rel.split(path.sep).join('/');
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* The real location of a path, for comparing one host-supplied string to
|
|
201
|
+
* another.
|
|
202
|
+
*
|
|
203
|
+
* WHY THIS IS NOT OPTIONAL. `workspace_root` and a tool call's `file_path` are
|
|
204
|
+
* two independently produced strings, and they routinely disagree about
|
|
205
|
+
* symlinks: macOS `/tmp` resolves to `/private/tmp`, and a worktree session's
|
|
206
|
+
* project dir can resolve to the parent checkout. Relativising them raw sends
|
|
207
|
+
* EVERY in-repo path down the foreign branch, which would return the graph to
|
|
208
|
+
* `no-seeds` and — now that the row redacts a foreign path — would also destroy
|
|
209
|
+
* the labelling evidence instead of merely failing to resolve it. That is
|
|
210
|
+
* strictly worse than the defect this module was repaired for, and it fails the
|
|
211
|
+
* same way: silently. A completion review found it; no fixture could, because
|
|
212
|
+
* every fixture builds its paths from the same realpathed root string.
|
|
213
|
+
*
|
|
214
|
+
* It walks up to the NEAREST EXISTING ancestor and rejoins the remainder, so a
|
|
215
|
+
* file the turn deleted — or a root that does not exist, as a pure unit test's
|
|
216
|
+
* does — still resolves through whatever part of the chain is real. The walk
|
|
217
|
+
* has to be symmetric or it introduces the very bug it fixes: resolving the root
|
|
218
|
+
* through an existing ancestor while leaving the path unresolved makes the two
|
|
219
|
+
* disagree by exactly the symlink prefix. That asymmetry was in the first
|
|
220
|
+
* version of this function and the suite's own POSIX test caught it.
|
|
221
|
+
*
|
|
222
|
+
* KNOWN REMAINING LIMIT: a case-insensitive filesystem can still present the
|
|
223
|
+
* same file under two spellings this does not reconcile. Named rather than
|
|
224
|
+
* silently assumed away.
|
|
225
|
+
*/
|
|
226
|
+
function _resolveReal(p: string): string {
|
|
227
|
+
const abs = path.resolve(p);
|
|
228
|
+
const tail: string[] = [];
|
|
229
|
+
let cur = abs;
|
|
230
|
+
for (;;) {
|
|
231
|
+
try {
|
|
232
|
+
const real = fs.realpathSync(cur);
|
|
233
|
+
return tail.length === 0 ? real : path.join(real, ...[...tail].reverse());
|
|
234
|
+
} catch {
|
|
235
|
+
const parent = path.dirname(cur);
|
|
236
|
+
// Reached the filesystem root with nothing resolvable — the absolute
|
|
237
|
+
// form is the best answer available, and it is still symmetric
|
|
238
|
+
// because the other side took the same walk.
|
|
239
|
+
if (parent === cur) return abs;
|
|
240
|
+
tail.push(path.basename(cur));
|
|
241
|
+
cur = parent;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Would storing this path put content from outside the workspace on the row?
|
|
248
|
+
*
|
|
249
|
+
* Broader than `path.isAbsolute` on purpose. Two shapes bypass that test while
|
|
250
|
+
* carrying exactly the identifying content the marker exists to withhold from
|
|
251
|
+
* the external labeller: an out-of-tree path already in relative form
|
|
252
|
+
* (`../other-project/x.ts`), and a foreign-platform absolute path, which POSIX
|
|
253
|
+
* `path.isAbsolute` reports as relative. Both were found by a completion review.
|
|
254
|
+
*/
|
|
255
|
+
function _escapesWorkspace(p: string): boolean {
|
|
256
|
+
return (
|
|
257
|
+
path.isAbsolute(p) ||
|
|
258
|
+
path.win32.isAbsolute(p) ||
|
|
259
|
+
p === '..' ||
|
|
260
|
+
p.startsWith('../') ||
|
|
261
|
+
p.startsWith(`..${path.sep}`)
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Run `untested` over the turn's edit paths.
|
|
267
|
+
*
|
|
268
|
+
* Returns `null` — the graph contributed nothing — for every reason there is:
|
|
269
|
+
* no usable source, a SCIP index with no owned reader, no edit paths, or any
|
|
270
|
+
* throw at all. A verdict this module cannot stand behind is not a verdict.
|
|
271
|
+
*/
|
|
272
|
+
export function graphUntestedVerdict(
|
|
273
|
+
root: string,
|
|
274
|
+
state: GraphState,
|
|
275
|
+
paths: readonly string[],
|
|
276
|
+
): { verdict: GraphVerdict; untested: number; tested: number } {
|
|
277
|
+
const none = { verdict: null, untested: 0, tested: 0 } as const;
|
|
278
|
+
// `behind:N` and `absent` contribute nothing, by the step's own terms: an
|
|
279
|
+
// answer from an index that predates the change is not evidence about the
|
|
280
|
+
// change.
|
|
281
|
+
if (state !== 'fresh' && state !== 'edited') return none;
|
|
282
|
+
if (paths.length === 0) return none;
|
|
283
|
+
// The graph indexes repo-relative paths; a host hands us absolute ones.
|
|
284
|
+
// NOT before the early returns below. Relativising walks the filesystem once
|
|
285
|
+
// per absolute path, and this runs inside a stop hook whose latency the
|
|
286
|
+
// module header names as a risk — a host that timed the hook out
|
|
287
|
+
// would drop the gate's refusal. Spending those syscalls only to discover
|
|
288
|
+
// there is no usable source is cost for nothing.
|
|
289
|
+
let picked;
|
|
290
|
+
try {
|
|
291
|
+
picked = pickSource(detectSources(root, path.join(root, NATIVE_CACHE_REL)));
|
|
292
|
+
} catch {
|
|
293
|
+
return none;
|
|
294
|
+
}
|
|
295
|
+
if (!picked || picked.kind === 'scip') return none;
|
|
296
|
+
let g;
|
|
297
|
+
try {
|
|
298
|
+
g = loadGraph(picked.path, `${picked.kind}:${path.relative(root, picked.path)}`);
|
|
299
|
+
} catch {
|
|
300
|
+
return none;
|
|
301
|
+
}
|
|
302
|
+
try {
|
|
303
|
+
const r = untested(g, toRepoRelative(root, paths), state);
|
|
304
|
+
if (r.seeds.length === 0) return { verdict: 'no-seeds', untested: 0, tested: 0 };
|
|
305
|
+
return {
|
|
306
|
+
verdict: r.untested.length > 0 ? 'untested' : 'tested',
|
|
307
|
+
untested: r.untested.length,
|
|
308
|
+
tested: r.tested.length,
|
|
309
|
+
};
|
|
310
|
+
} catch {
|
|
311
|
+
return none;
|
|
312
|
+
} finally {
|
|
313
|
+
// The handle owns an open database; a stop hook that leaked one per turn
|
|
314
|
+
// would hold a descriptor for the life of the session.
|
|
315
|
+
try {
|
|
316
|
+
g.close();
|
|
317
|
+
} catch {
|
|
318
|
+
/* nothing to do about a failed close */
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/** Append one row, or do nothing at all. Never throws, never returns a verdict. */
|
|
324
|
+
export function appendFeederRow(workspaceRoot: string, sessionKey: string, row: GraphFeederRow): void {
|
|
325
|
+
try {
|
|
326
|
+
const file = feederFile(workspaceRoot, sessionKey);
|
|
327
|
+
let existing = 0;
|
|
328
|
+
try {
|
|
329
|
+
existing = fs
|
|
330
|
+
.readFileSync(file, 'utf-8')
|
|
331
|
+
.split('\n')
|
|
332
|
+
.filter((l) => l.trim() !== '').length;
|
|
333
|
+
} catch {
|
|
334
|
+
/* absent is zero */
|
|
335
|
+
}
|
|
336
|
+
if (existing >= MAX_ROWS_PER_SESSION) return;
|
|
337
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
338
|
+
fs.appendFileSync(file, `${JSON.stringify(row)}\n`);
|
|
339
|
+
} catch {
|
|
340
|
+
// An instrument is never a reason to change what the gate does.
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/** Read a session's rows back, skipping anything unparseable. */
|
|
345
|
+
export function readFeederRows(workspaceRoot: string, sessionKey: string): GraphFeederRow[] {
|
|
346
|
+
try {
|
|
347
|
+
return fs
|
|
348
|
+
.readFileSync(feederFile(workspaceRoot, sessionKey), 'utf-8')
|
|
349
|
+
.split('\n')
|
|
350
|
+
.filter((l) => l.trim() !== '')
|
|
351
|
+
.map((l) => {
|
|
352
|
+
try {
|
|
353
|
+
return JSON.parse(l) as GraphFeederRow;
|
|
354
|
+
} catch {
|
|
355
|
+
return null;
|
|
356
|
+
}
|
|
357
|
+
})
|
|
358
|
+
.filter((r): r is GraphFeederRow => r !== null);
|
|
359
|
+
} catch {
|
|
360
|
+
return [];
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Build the row.
|
|
366
|
+
*
|
|
367
|
+
* NO LONGER PURE, and the previous line of this docstring still claimed it was.
|
|
368
|
+
* Relativising reads the filesystem — `toRepoRelative` falls back to
|
|
369
|
+
* `fs.realpathSync` when the raw comparison says foreign — so this touches disk
|
|
370
|
+
* for any absolute path outside the root, and the unit tests that pass a
|
|
371
|
+
* non-existent `/workspace` root walk real directories on the way to answering.
|
|
372
|
+
* It is still DETERMINISTIC given the tree, which is what the tests actually
|
|
373
|
+
* rely on. A completion review caught the stale claim; in a module whose header
|
|
374
|
+
* argues its guarantees hold by construction rather than by convention, a
|
|
375
|
+
* docstring that has quietly stopped being true is the same defect class as the
|
|
376
|
+
* rest of this change.
|
|
377
|
+
*
|
|
378
|
+
* `root` is required rather than optional, and relativising happens HERE rather
|
|
379
|
+
* than at the call site, for two reasons that point the same way. The caller is
|
|
380
|
+
* `turn_end_gate_hook.ts`, which sits against a shrink-only 1,500-line source
|
|
381
|
+
* budget it is exactly at — so the five lines this would cost there are five
|
|
382
|
+
* lines it does not have, and its own header already says such things belong in
|
|
383
|
+
* `_lib`. And a caller that can omit the root is a caller that can reintroduce
|
|
384
|
+
* the absolute-path defect {@link toRepoRelative} exists to close: the stored
|
|
385
|
+
* paths a step-3.3 labeller reads must be the paths the verdict was taken over.
|
|
386
|
+
*/
|
|
387
|
+
export function buildFeederRow(input: {
|
|
388
|
+
/** The workspace root the paths are made relative to. */
|
|
389
|
+
root: string;
|
|
390
|
+
turn: number;
|
|
391
|
+
layer: FeederLayer;
|
|
392
|
+
state: GraphState;
|
|
393
|
+
fFired: boolean;
|
|
394
|
+
fMode: FeederMode | null;
|
|
395
|
+
paths: readonly string[];
|
|
396
|
+
graph: { verdict: GraphVerdict; untested: number; tested: number };
|
|
397
|
+
at?: string;
|
|
398
|
+
}): GraphFeederRow {
|
|
399
|
+
return {
|
|
400
|
+
at: input.at ?? new Date().toISOString(),
|
|
401
|
+
turn: input.turn,
|
|
402
|
+
layer: input.layer,
|
|
403
|
+
graph_state: input.state,
|
|
404
|
+
f: input.fFired,
|
|
405
|
+
f_mode: input.fMode,
|
|
406
|
+
graph: input.graph.verdict,
|
|
407
|
+
graph_untested: input.graph.untested,
|
|
408
|
+
graph_tested: input.graph.tested,
|
|
409
|
+
// An out-of-workspace edit is REDACTED, not dropped and not stored
|
|
410
|
+
// verbatim. After relativising, a still-absolute path is exactly one
|
|
411
|
+
// that lay outside the root.
|
|
412
|
+
//
|
|
413
|
+
// Verbatim is an egress surface: `paths` is handed to external council
|
|
414
|
+
// seats at step 3.3's labelling, and a home-rooted path names a real
|
|
415
|
+
// user and an unrelated project.
|
|
416
|
+
//
|
|
417
|
+
// Dropping it looked right and was worse, which a completion review
|
|
418
|
+
// caught before it shipped. It would have shortened `paths` below
|
|
419
|
+
// `path_count` and so reused the protocol's truncation signal for a
|
|
420
|
+
// second, different cause — two meanings on one wire, with no field
|
|
421
|
+
// separating them. Worse, a turn editing one in-repo file and one file
|
|
422
|
+
// outside the root would then be excluded from labelling altogether,
|
|
423
|
+
// losing a perfectly labellable in-repo path from a corpus that is
|
|
424
|
+
// blocked precisely for want of rows.
|
|
425
|
+
//
|
|
426
|
+
// The marker keeps the lengths equal, so truncation stays the only
|
|
427
|
+
// cause of `path_count > paths.length`; keeps the row honest that an
|
|
428
|
+
// edit happened outside the tree, so a labeller can answer
|
|
429
|
+
// `cannot tell` rather than be silently misled; and carries nothing
|
|
430
|
+
// identifying. The graph's answer is unchanged either way — the probe
|
|
431
|
+
// sees the real path and resolves no seeds for it.
|
|
432
|
+
paths: toRepoRelative(input.root, input.paths.slice(0, MAX_PATHS)).map((p) =>
|
|
433
|
+
_escapesWorkspace(p) ? OUTSIDE_WORKSPACE : p,
|
|
434
|
+
),
|
|
435
|
+
path_count: input.paths.length,
|
|
436
|
+
};
|
|
437
|
+
}
|
|
@@ -78,6 +78,79 @@ export function hookSectionEnabled(root: string, section: string): boolean {
|
|
|
78
78
|
return false;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Raw scalar at `hooks.<section>.<key>` in `.agent-settings.yml`, or `''`.
|
|
83
|
+
*
|
|
84
|
+
* The `hookSectionEnabled` sibling above answers one boolean question and is
|
|
85
|
+
* the right shape for a default-OFF switch. This one exists because
|
|
86
|
+
* `hooks.verify_before_complete.touched_file_quality` is a three-valued mode
|
|
87
|
+
* (`off | shadow | warn`), and collapsing it into a boolean would lose exactly
|
|
88
|
+
* the distinction the roadmap's Phase 2 turns on — `shadow` records and says
|
|
89
|
+
* nothing, `warn` records and emits one line.
|
|
90
|
+
*
|
|
91
|
+
* It reuses the section scoping of `hookSectionEnabled` verbatim, including the
|
|
92
|
+
* ACTUAL-indent close that the 4-space-file defect produced: a reader that
|
|
93
|
+
* closed the section on a fixed depth would read a sibling section's value under
|
|
94
|
+
* this key's name, which for a mode string is worse than for a flag — the wrong
|
|
95
|
+
* value is a legal one.
|
|
96
|
+
*
|
|
97
|
+
* Interpretation is NOT done here. `''` means "nothing was written", and the
|
|
98
|
+
* caller decides what that defaults to — the same producer/consumer split
|
|
99
|
+
* `leanProjectionModeRaw` makes below, and for the same reason.
|
|
100
|
+
*/
|
|
101
|
+
export function hookSectionValue(root: string, section: string, key: string): string {
|
|
102
|
+
const file = path.join(root, SETTINGS_FILE);
|
|
103
|
+
let text: string;
|
|
104
|
+
try {
|
|
105
|
+
if (!fs.statSync(file).isFile()) return '';
|
|
106
|
+
text = fs.readFileSync(file, 'utf-8');
|
|
107
|
+
} catch {
|
|
108
|
+
return '';
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const esc = (s: string): string => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
112
|
+
const sectionPattern = new RegExp(`^(\\s+)${esc(section)}\\s*:\\s*$`);
|
|
113
|
+
const keyPattern = new RegExp(`^\\s+${esc(key)}\\s*:\\s*(.+)$`);
|
|
114
|
+
let inHooks = false;
|
|
115
|
+
let sectionIndent: number | null = null;
|
|
116
|
+
|
|
117
|
+
const indentOf = (line: string): number => line.length - line.replace(/^\s+/, '').length;
|
|
118
|
+
|
|
119
|
+
for (const raw of text.split(/\r\n|\r|\n/)) {
|
|
120
|
+
const line = raw.replace(/\s+$/, '');
|
|
121
|
+
if (!line || line.replace(/^\s+/, '').startsWith('#')) continue;
|
|
122
|
+
|
|
123
|
+
if (!(line.startsWith(' ') || line.startsWith('\t'))) {
|
|
124
|
+
inHooks = /^hooks\s*:\s*$/.test(line);
|
|
125
|
+
sectionIndent = null;
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (inHooks) {
|
|
130
|
+
const opened = sectionPattern.exec(line);
|
|
131
|
+
if (opened) {
|
|
132
|
+
sectionIndent = opened[1]!.length;
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
if (sectionIndent !== null && indentOf(line) <= sectionIndent) {
|
|
136
|
+
sectionIndent = null;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (sectionIndent !== null) {
|
|
141
|
+
const m = keyPattern.exec(line);
|
|
142
|
+
if (m) {
|
|
143
|
+
return (m[1] ?? '')
|
|
144
|
+
.replace(/\s+#.*$/, '')
|
|
145
|
+
.trim()
|
|
146
|
+
.replace(/^["']|["']$/g, '');
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return '';
|
|
152
|
+
}
|
|
153
|
+
|
|
81
154
|
/**
|
|
82
155
|
* Raw `lean_projection.mode` string out of `.agent-settings.yml`, or `''`.
|
|
83
156
|
*
|