@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
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* bench_touched_file_quality — what the shadow quality pass costs at stop.
|
|
4
|
+
*
|
|
5
|
+
* `road-to-touched-files-that-pass-their-own-tools` 1.4: record the `shadow`
|
|
6
|
+
* variant's p95 over a five-file TypeScript fixture BEFORE any default moves.
|
|
7
|
+
* Risk 1 of that roadmap is that a quality pass makes stop the slowest hook in
|
|
8
|
+
* the chain, and 2.3 defers the `shadow → warn` flip to the owner. Neither
|
|
9
|
+
* decision should be taken on an estimate.
|
|
10
|
+
*
|
|
11
|
+
* CORRECTED FROM REPRODUCTION — the step's premise was wrong, and the
|
|
12
|
+
* correction is why this is a file rather than a patch.
|
|
13
|
+
*
|
|
14
|
+
* The step reads "the per-concern bench already measures `verify-before-complete`
|
|
15
|
+
* at default". It does not. `bench_hook_latency.perConcernRows` is fed by
|
|
16
|
+
* `blockingConcerns()`, which filters `hook_manifest.yaml` to
|
|
17
|
+
* `severity: blocking`; `verify-before-complete` is declared `severity: advisory`
|
|
18
|
+
* (manifest line ~122), so it has never had a per-concern row and there was no
|
|
19
|
+
* `default` reading to add a `shadow` variant beside. Adding the concern to that
|
|
20
|
+
* filter would have changed what "blocking" means in a report whose consumer
|
|
21
|
+
* (step 3.3 of the kernel-plumbing roadmap) derives per-concern TIMEOUTS from it
|
|
22
|
+
* — a timeout for an advisory concern is a different decision, and smuggling it
|
|
23
|
+
* in through a measurement would have been the wrong place to take it.
|
|
24
|
+
*
|
|
25
|
+
* So this measures the pass directly, which is also the number the two open
|
|
26
|
+
* decisions actually need: the slot p95 in `docs/hook-latency.json` is dominated
|
|
27
|
+
* by spawn + bundle load, and what 1.4 asks about is the DELTA the pass adds.
|
|
28
|
+
*
|
|
29
|
+
* METHOD, pinned so the number reproduces:
|
|
30
|
+
* - A throwaway consumer-shaped project: `package.json` declaring `typescript`
|
|
31
|
+
* and `eslint`, five TypeScript files, a flat ESLint config, `git init`, and
|
|
32
|
+
* a `minimal-safe-diff.json` naming all five as this turn's touched files.
|
|
33
|
+
* - `node_modules` is SYMLINKED to this repository's, so `npx eslint` resolves
|
|
34
|
+
* a real, installed linter and runs offline. The measurement is therefore of
|
|
35
|
+
* a real tool over real files, not of a stub.
|
|
36
|
+
* - N iterations (default 20, `--runs N`) of `collectTouchedFileQuality` — the
|
|
37
|
+
* exact function the stop path calls — measured with `performance.now()`.
|
|
38
|
+
* That covers the recorder read, `git status`, `resolve_toolchain`, and every
|
|
39
|
+
* spawn the plan produced.
|
|
40
|
+
* - The `off` baseline is measured too, by the same loop with the pass skipped,
|
|
41
|
+
* so the row reports a DELTA rather than an absolute whose floor is unknown.
|
|
42
|
+
*
|
|
43
|
+
* WHAT THE NUMBER IS NOT. It is one machine's reading, and the dominant term is
|
|
44
|
+
* whichever tools the fixture's resolver happens to emit — a consumer whose
|
|
45
|
+
* toolchain resolves `phpstan` over a large tree will measure something else
|
|
46
|
+
* entirely. It bounds the decision for THIS shape; it is not a budget.
|
|
47
|
+
*
|
|
48
|
+
* Exit codes: 0 measured · 2 the fixture could not be built.
|
|
49
|
+
*/
|
|
50
|
+
import { spawnSync } from 'node:child_process';
|
|
51
|
+
import * as fs from 'node:fs';
|
|
52
|
+
import * as os from 'node:os';
|
|
53
|
+
import * as path from 'node:path';
|
|
54
|
+
import { fileURLToPath } from 'node:url';
|
|
55
|
+
|
|
56
|
+
import { collectTouchedFileQuality } from './before_complete_hook.js';
|
|
57
|
+
|
|
58
|
+
const REPO_ROOT = path.resolve(path.dirname(path.resolve(fileURLToPath(import.meta.url))), '..', '..');
|
|
59
|
+
|
|
60
|
+
/** Files in the fixture. Five, per the step. */
|
|
61
|
+
export const FIXTURE_FILE_COUNT = 5;
|
|
62
|
+
|
|
63
|
+
const SESSION = 'bench-touched-file-quality';
|
|
64
|
+
|
|
65
|
+
export function percentile(samples: readonly number[], p: number): number {
|
|
66
|
+
if (samples.length === 0) return 0;
|
|
67
|
+
const sorted = [...samples].sort((a, b) => a - b);
|
|
68
|
+
const idx = Math.min(sorted.length - 1, Math.ceil((p / 100) * sorted.length) - 1);
|
|
69
|
+
return sorted[Math.max(0, idx)] as number;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Build the throwaway consumer project and return its root.
|
|
74
|
+
*
|
|
75
|
+
* Deliberately NOT inside the repository: a fixture under `src/` or `agents/`
|
|
76
|
+
* would be picked up by the tree's own gates, and one that `git init`s inside an
|
|
77
|
+
* existing worktree would report the repository's status rather than its own.
|
|
78
|
+
*/
|
|
79
|
+
export function buildFixture(): string {
|
|
80
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'tfq-bench-'));
|
|
81
|
+
|
|
82
|
+
fs.writeFileSync(
|
|
83
|
+
path.join(root, 'package.json'),
|
|
84
|
+
JSON.stringify(
|
|
85
|
+
{ name: 'tfq-bench-fixture', private: true, devDependencies: { typescript: '*', eslint: '*' } },
|
|
86
|
+
null,
|
|
87
|
+
2,
|
|
88
|
+
),
|
|
89
|
+
'utf-8',
|
|
90
|
+
);
|
|
91
|
+
// A flat config with no rules: eslint still parses every file, which is the
|
|
92
|
+
// cost being measured, without a rule set that would make the number a
|
|
93
|
+
// statement about this repository's lint configuration.
|
|
94
|
+
fs.writeFileSync(path.join(root, 'eslint.config.mjs'), 'export default [];\n', 'utf-8');
|
|
95
|
+
|
|
96
|
+
for (let i = 0; i < FIXTURE_FILE_COUNT; i += 1) {
|
|
97
|
+
fs.writeFileSync(
|
|
98
|
+
path.join(root, `mod${String(i)}.ts`),
|
|
99
|
+
`export interface Row${String(i)} { id: number; name: string }\n` +
|
|
100
|
+
`export function build${String(i)}(n: number): Row${String(i)}[] {\n` +
|
|
101
|
+
` return Array.from({ length: n }, (_, j) => ({ id: j, name: 'r' + String(j) }));\n` +
|
|
102
|
+
`}\n`,
|
|
103
|
+
'utf-8',
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
fs.symlinkSync(path.join(REPO_ROOT, 'node_modules'), path.join(root, 'node_modules'), 'dir');
|
|
109
|
+
} catch {
|
|
110
|
+
// Left absent on a platform that refuses the link: `npx eslint` then
|
|
111
|
+
// resolves to nothing and the pass records `skipped: absent`, which the
|
|
112
|
+
// report states rather than hides.
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
spawnSync('git', ['init', '-q'], { cwd: root });
|
|
116
|
+
|
|
117
|
+
fs.mkdirSync(path.join(root, 'agents', 'state'), { recursive: true });
|
|
118
|
+
fs.writeFileSync(
|
|
119
|
+
path.join(root, 'agents', 'state', 'minimal-safe-diff.json'),
|
|
120
|
+
JSON.stringify({
|
|
121
|
+
session_id: SESSION,
|
|
122
|
+
files_touched_this_turn: Array.from(
|
|
123
|
+
{ length: FIXTURE_FILE_COUNT },
|
|
124
|
+
(_, i) => `mod${String(i)}.ts`,
|
|
125
|
+
),
|
|
126
|
+
}),
|
|
127
|
+
'utf-8',
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
return root;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export interface BenchRow {
|
|
134
|
+
readonly concern: string;
|
|
135
|
+
readonly mode: 'off' | 'shadow';
|
|
136
|
+
readonly runs: number;
|
|
137
|
+
readonly p50_ms: number;
|
|
138
|
+
readonly p95_ms: number;
|
|
139
|
+
readonly max_ms: number;
|
|
140
|
+
/** What the pass actually did, so a row of zeros is never mistaken for speed. */
|
|
141
|
+
readonly commands: readonly string[];
|
|
142
|
+
readonly skipped: readonly string[];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export function measure(root: string, iterations: number): { off: BenchRow; shadow: BenchRow } {
|
|
146
|
+
const offSamples: number[] = [];
|
|
147
|
+
const shadowSamples: number[] = [];
|
|
148
|
+
let commands: string[] = [];
|
|
149
|
+
let skipped: string[] = [];
|
|
150
|
+
|
|
151
|
+
// One warm-up outside the samples: the first `npx` resolution pays a cost no
|
|
152
|
+
// subsequent stop pays, and reporting it inside the p95 would describe a
|
|
153
|
+
// session's first stop as if it were every stop.
|
|
154
|
+
collectTouchedFileQuality(root, SESSION);
|
|
155
|
+
|
|
156
|
+
for (let i = 0; i < iterations; i += 1) {
|
|
157
|
+
const t0 = performance.now();
|
|
158
|
+
const result = collectTouchedFileQuality(root, SESSION);
|
|
159
|
+
shadowSamples.push(performance.now() - t0);
|
|
160
|
+
if (i === 0 && result !== null) {
|
|
161
|
+
commands = result.runs.filter((r) => r.skipped === null).map((r) => r.command);
|
|
162
|
+
skipped = result.runs
|
|
163
|
+
.filter((r) => r.skipped !== null)
|
|
164
|
+
.map((r) => `${r.source_command} → ${String(r.skipped)}`);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// `off` is not "the same loop with a flag" — on the off path the stop
|
|
168
|
+
// handler never reaches this function at all, so the baseline is the
|
|
169
|
+
// empty interval, measured to keep the harness's own overhead visible.
|
|
170
|
+
const t1 = performance.now();
|
|
171
|
+
offSamples.push(performance.now() - t1);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const row = (mode: 'off' | 'shadow', xs: number[]): BenchRow => ({
|
|
175
|
+
concern: 'verify-before-complete',
|
|
176
|
+
mode,
|
|
177
|
+
runs: xs.length,
|
|
178
|
+
p50_ms: Math.round(percentile(xs, 50) * 1000) / 1000,
|
|
179
|
+
p95_ms: Math.round(percentile(xs, 95) * 1000) / 1000,
|
|
180
|
+
max_ms: Math.round(Math.max(...xs, 0) * 1000) / 1000,
|
|
181
|
+
commands: mode === 'shadow' ? commands : [],
|
|
182
|
+
skipped: mode === 'shadow' ? skipped : [],
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
return { off: row('off', offSamples), shadow: row('shadow', shadowSamples) };
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export function render(rows: { off: BenchRow; shadow: BenchRow }): string {
|
|
189
|
+
const line = (r: BenchRow): string =>
|
|
190
|
+
`| ${r.concern} | ${r.mode} | ${String(r.runs)} | ${r.p50_ms.toFixed(3)} | ` +
|
|
191
|
+
`${r.p95_ms.toFixed(3)} | ${r.max_ms.toFixed(3)} |`;
|
|
192
|
+
const out: string[] = [
|
|
193
|
+
'',
|
|
194
|
+
`fixture: ${String(FIXTURE_FILE_COUNT)} TypeScript files, consumer-shaped project`,
|
|
195
|
+
'',
|
|
196
|
+
'| concern | mode | runs | p50_ms | p95_ms | max_ms |',
|
|
197
|
+
'|---|---|---|---|---|---|',
|
|
198
|
+
line(rows.off),
|
|
199
|
+
line(rows.shadow),
|
|
200
|
+
'',
|
|
201
|
+
`delta p95 (shadow − off): ${(rows.shadow.p95_ms - rows.off.p95_ms).toFixed(3)} ms`,
|
|
202
|
+
'',
|
|
203
|
+
`commands executed: ${rows.shadow.commands.length === 0 ? '(none)' : rows.shadow.commands.join(' · ')}`,
|
|
204
|
+
`skipped: ${rows.shadow.skipped.length === 0 ? '(none)' : rows.shadow.skipped.join(' · ')}`,
|
|
205
|
+
'',
|
|
206
|
+
];
|
|
207
|
+
return out.join('\n');
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export function main(argv: readonly string[]): number {
|
|
211
|
+
const runsIdx = argv.indexOf('--runs');
|
|
212
|
+
const parsed = runsIdx === -1 ? NaN : Number(argv[runsIdx + 1]);
|
|
213
|
+
const iterations = Number.isFinite(parsed) && parsed > 0 ? Math.trunc(parsed) : 20;
|
|
214
|
+
const asJson = argv.includes('--json');
|
|
215
|
+
|
|
216
|
+
let root: string;
|
|
217
|
+
try {
|
|
218
|
+
root = buildFixture();
|
|
219
|
+
} catch (err) {
|
|
220
|
+
process.stderr.write(`bench_touched_file_quality: could not build the fixture — ${String(err)}\n`);
|
|
221
|
+
return 2;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const rows = measure(root, iterations);
|
|
225
|
+
process.stdout.write(asJson ? `${JSON.stringify(rows, null, 2)}\n` : render(rows));
|
|
226
|
+
|
|
227
|
+
try {
|
|
228
|
+
fs.rmSync(root, { recursive: true, force: true });
|
|
229
|
+
} catch {
|
|
230
|
+
// A leftover temp directory is not a failed measurement.
|
|
231
|
+
}
|
|
232
|
+
return 0;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const _entry = process.argv[1];
|
|
236
|
+
if (_entry !== undefined && path.resolve(_entry) === path.resolve(fileURLToPath(import.meta.url))) {
|
|
237
|
+
process.exit(main(process.argv.slice(2)));
|
|
238
|
+
}
|
|
@@ -78,6 +78,23 @@ const SKIP_DIRS: ReadonlySet<string> = new Set([
|
|
|
78
78
|
|
|
79
79
|
/** Frontmatter keys that only a roadmap carries in this tree. */
|
|
80
80
|
const FM_ROADMAP_RE = /^complexity:[ \t]*(lightweight|structural)[ \t]*$/m;
|
|
81
|
+
/**
|
|
82
|
+
* Anchored at the absolute start of the string — `^` with no `m` flag — on
|
|
83
|
+
* purpose: this is a FRONTMATTER fence, which by the project's own convention
|
|
84
|
+
* only means something at byte offset 0 of the file. A `---` fence that
|
|
85
|
+
* begins three lines in is not frontmatter, it is a horizontal rule or a
|
|
86
|
+
* quoted example, so loosening this to `m` would create false positives of
|
|
87
|
+
* its own.
|
|
88
|
+
*
|
|
89
|
+
* The R2 review-input roadmap snapshots used to depend on that strictness as an
|
|
90
|
+
* INCIDENTAL exemption: their two-line HTML-comment header, written for a
|
|
91
|
+
* different gate, pushed this fence off offset 0. They are now exempt by path —
|
|
92
|
+
* see `isReviewInputRoadmapSnapshot` — so neither the header nor this regex's
|
|
93
|
+
* anchoring decides their fate any more.
|
|
94
|
+
*
|
|
95
|
+
* Tested in `check_agent_artifact_location.test.ts`
|
|
96
|
+
* (describe: "review-input snapshot convention").
|
|
97
|
+
*/
|
|
81
98
|
const FM_RE = /^---\n([\s\S]*?)\n---/;
|
|
82
99
|
const PHASE_RE = /^##[ \t]+Phase[ \t]/m;
|
|
83
100
|
const CHECKBOX_RE = /^[ \t]*- \[[ x~-]\][ \t]/m;
|
|
@@ -144,6 +161,24 @@ function walkMarkdown(root: string): string[] {
|
|
|
144
161
|
return out.sort();
|
|
145
162
|
}
|
|
146
163
|
|
|
164
|
+
/**
|
|
165
|
+
* The one declared exemption: an R2 review-input roadmap snapshot.
|
|
166
|
+
*
|
|
167
|
+
* `dispatch_r2_reviewer.ts` writes a verbatim roadmap copy to exactly this
|
|
168
|
+
* shape, and a file in it is non-authoritative evidence whoever wrote it —
|
|
169
|
+
* nothing reads it back as a roadmap. Decided by path, not by a marker an
|
|
170
|
+
* author could type anywhere (authority-routing roadmap 5.1, `## Decisions`):
|
|
171
|
+
* measured 2026-10-07, every roadmap-shaped file outside the root was one of
|
|
172
|
+
* these snapshots, so the path names the whole population and nothing else.
|
|
173
|
+
* Takes the repository-relative POSIX path the walker produces; the walker
|
|
174
|
+
* never follows a symlink, so a link cannot manufacture an exempt path.
|
|
175
|
+
*/
|
|
176
|
+
const REVIEW_INPUT_SNAPSHOT_PATH_RE = /^agents\/evidence\/(?:[^/]+\/)*[^/.][^/]*\.review-input\/roadmap\.md$/;
|
|
177
|
+
|
|
178
|
+
export function isReviewInputRoadmapSnapshot(rel: string): boolean {
|
|
179
|
+
return REVIEW_INPUT_SNAPSHOT_PATH_RE.test(rel) && !rel.split('/').some((s) => s === '..' || s === '.');
|
|
180
|
+
}
|
|
181
|
+
|
|
147
182
|
/** `true` when `child` is at or below `root`. */
|
|
148
183
|
function isUnder(child: string, root: string): boolean {
|
|
149
184
|
const rel = path.relative(root, child);
|
|
@@ -156,6 +191,7 @@ export function scan(root: string): ScanResult {
|
|
|
156
191
|
const findings: Finding[] = [];
|
|
157
192
|
for (const f of files) {
|
|
158
193
|
if (isUnder(f, roadmapRoot)) continue;
|
|
194
|
+
if (isReviewInputRoadmapSnapshot(path.relative(root, f).split(path.sep).join('/'))) continue;
|
|
159
195
|
// Cheap name pre-filter first — the SHARED definition, imported, so the
|
|
160
196
|
// roadmap corpus and this guard cannot drift apart.
|
|
161
197
|
if (!isRoadmapCandidate(f)) continue;
|
|
@@ -46,7 +46,9 @@
|
|
|
46
46
|
* branch AS THE SERVER REPORTS IT (`ls-remote --symref`), then the local
|
|
47
47
|
* `origin/HEAD`, then `main`. Every message names the base AND where it came
|
|
48
48
|
* from, because "I checked main because that is the PR's base" and "I checked
|
|
49
|
-
* main because I could not ask" must never print the same.
|
|
49
|
+
* main because I could not ask" must never print the same. An explicit
|
|
50
|
+
* `--base` given a blank value exits 2: an unset variable is not a request for
|
|
51
|
+
* the PR's base.
|
|
50
52
|
*
|
|
51
53
|
* The server symref matters for the same reason `remoteHead` exists: the local
|
|
52
54
|
* `refs/remotes/origin/HEAD` is written at clone time and never refreshed, so
|
|
@@ -67,6 +69,9 @@ import { fileURLToPath } from "node:url";
|
|
|
67
69
|
|
|
68
70
|
import { runGateCli, runSelfTest, type SelfTestCase } from "./_lib/gate_self_test.js";
|
|
69
71
|
import { workspaceIdentity } from "./_lib/git_common_dir.js";
|
|
72
|
+
import { describeRefusal, isRefusal, type GitConventionReading } from "./_lib/git_convention.js";
|
|
73
|
+
import { baseValueError, parseBaseRef } from "./_lib/git_base_ref.js";
|
|
74
|
+
import { makeTargetDeps, parseExactHeadSha, readCommittedConvention } from "./_lib/git_convention_carrier.js";
|
|
70
75
|
import { reportScanned } from "./_lib/scan_scope.js";
|
|
71
76
|
|
|
72
77
|
// ledger-exempt: single remote-ref probe — the entire scope is ONE ls-remote answer (0 or 1 refs) resolved to one aggregate ancestor verdict, and every empty path already publishes its reason via reportScanned allowEmpty; there is no per-target collection to account.
|
|
@@ -125,6 +130,8 @@ export type BaseSource =
|
|
|
125
130
|
export interface BaseResolution {
|
|
126
131
|
readonly base: string;
|
|
127
132
|
readonly source: BaseSource;
|
|
133
|
+
/** The remote `base` is a branch on; absent means origin. */
|
|
134
|
+
readonly remote?: string;
|
|
128
135
|
readonly pr?: number;
|
|
129
136
|
/** Present iff an open PR against a different base could not be ruled out. */
|
|
130
137
|
readonly unverified?: string;
|
|
@@ -270,6 +277,19 @@ export function explicitBase(argv: readonly string[]): string | null {
|
|
|
270
277
|
return explicit;
|
|
271
278
|
}
|
|
272
279
|
|
|
280
|
+
/**
|
|
281
|
+
* The usage error for a `--base` given a blank value, in either spelling, or
|
|
282
|
+
* null. A missing value or one that is another flag stays `explicitBase`'s
|
|
283
|
+
* typo case.
|
|
284
|
+
*/
|
|
285
|
+
export function blankExplicitBase(argv: readonly string[]): string | null {
|
|
286
|
+
const joined = argv.find((a) => a.startsWith("--base="));
|
|
287
|
+
if (joined !== undefined) return baseValueError(joined.slice("--base=".length));
|
|
288
|
+
const flag = argv.indexOf("--base");
|
|
289
|
+
const value = flag < 0 ? undefined : argv[flag + 1];
|
|
290
|
+
return value === undefined || value.startsWith("--") ? null : baseValueError(value);
|
|
291
|
+
}
|
|
292
|
+
|
|
273
293
|
/** `--base` wins, then the open PR's base, then the repo default. */
|
|
274
294
|
export function resolveBase(
|
|
275
295
|
argv: readonly string[],
|
|
@@ -277,8 +297,11 @@ export function resolveBase(
|
|
|
277
297
|
forge: (b: string) => ForgeAnswer = (b) => askForgeForBase(b),
|
|
278
298
|
): BaseResolution {
|
|
279
299
|
const explicit = explicitBase(argv);
|
|
280
|
-
|
|
281
|
-
|
|
300
|
+
const given = explicit === null ? null : parseBaseRef(explicit, configuredRemotes());
|
|
301
|
+
if (given !== null) {
|
|
302
|
+
return given.remote === "origin"
|
|
303
|
+
? { base: given.branch, source: "flag" }
|
|
304
|
+
: { base: given.branch, source: "flag", remote: given.remote };
|
|
282
305
|
}
|
|
283
306
|
// There is deliberately no cheap short-circuit for "the branch looks like the
|
|
284
307
|
// default". It was tried and reverted: it decided a VERDICT from
|
|
@@ -321,12 +344,25 @@ export function describeBase(r: BaseResolution): string {
|
|
|
321
344
|
|
|
322
345
|
/** The SHA the server reports for `<base>` right now — never a tracking ref. */
|
|
323
346
|
export function remoteHead(base: string, remote = "origin"): string | null {
|
|
324
|
-
const
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
347
|
+
const state = remoteHeadState(base, remote);
|
|
348
|
+
return state.kind === "sha" ? state.sha : null;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* `absent` is a remote that answered without the branch, which is a misspelled
|
|
353
|
+
* or deleted base; only a remote that did not answer is `unreachable`.
|
|
354
|
+
*/
|
|
355
|
+
export type RemoteHeadState = { kind: "sha"; sha: string } | { kind: "absent" } | { kind: "unreachable" };
|
|
356
|
+
|
|
357
|
+
export function remoteHeadState(base: string, remote = "origin"): RemoteHeadState {
|
|
358
|
+
const out = git(["ls-remote", remote, `refs/heads/${base}`]);
|
|
359
|
+
if (out === null) return { kind: "unreachable" };
|
|
360
|
+
const sha = parseExactHeadSha(out, base);
|
|
361
|
+
return sha === null ? { kind: "absent" } : { kind: "sha", sha };
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function configuredRemotes(): string[] {
|
|
365
|
+
return (git(["remote"]) ?? "").split("\n").map((r) => r.trim()).filter((r) => r !== "");
|
|
330
366
|
}
|
|
331
367
|
|
|
332
368
|
/**
|
|
@@ -525,6 +561,52 @@ function scanReport(scanned: number, allowEmpty?: string): void {
|
|
|
525
561
|
});
|
|
526
562
|
}
|
|
527
563
|
|
|
564
|
+
/** Whether this checkout's task runner defines `push-ready`, the remedy only this package ships. */
|
|
565
|
+
function definesPushReady(): boolean {
|
|
566
|
+
const root = git(["rev-parse", "--show-toplevel"]);
|
|
567
|
+
if (root === null || root === "") return false;
|
|
568
|
+
try {
|
|
569
|
+
return /^ {2}push-ready:/m.test(fs.readFileSync(path.join(root, "taskfiles", "dev.yml"), "utf8"));
|
|
570
|
+
} catch {
|
|
571
|
+
return false;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
/**
|
|
576
|
+
* What to do about a behind branch. A merge command is printed only under
|
|
577
|
+
* `merge`: under any other strategy, or one that cannot be read, a merge of the
|
|
578
|
+
* base is the commit the declaration excludes.
|
|
579
|
+
*/
|
|
580
|
+
export function behindRemedy(base: string, strategy: GitConventionReading | null, remote = "origin"): string[] {
|
|
581
|
+
if (strategy === null) {
|
|
582
|
+
return [
|
|
583
|
+
" git.update_strategy was not read — the base's commit is not in this checkout, and",
|
|
584
|
+
" this gate does not fetch to choose advice. Update the branch per the git-workflow",
|
|
585
|
+
" skill's references/branch-update.md, then regenerate (./agent-config roadmap:progress)",
|
|
586
|
+
" and re-run the gates before pushing.",
|
|
587
|
+
];
|
|
588
|
+
}
|
|
589
|
+
if (!isRefusal(strategy.state) && strategy.value === "merge") {
|
|
590
|
+
return [
|
|
591
|
+
` git fetch ${remote} && git merge ${remote}/${base}`,
|
|
592
|
+
" ./agent-config roadmap:progress # regenerate AFTER every merge, not only on conflict",
|
|
593
|
+
" then re-run the gates before pushing.",
|
|
594
|
+
"",
|
|
595
|
+
" The dashboard line is not optional housekeeping: the roadmap dashboard is a",
|
|
596
|
+
" GENERATED file, so a merge that lands cleanly still leaves it describing",
|
|
597
|
+
" neither side's roadmap set. A clean auto-merge of a generated file is still wrong.",
|
|
598
|
+
];
|
|
599
|
+
}
|
|
600
|
+
const why = isRefusal(strategy.state)
|
|
601
|
+
? ` git.update_strategy cannot be read — ${describeRefusal(strategy)}`
|
|
602
|
+
: ` git.update_strategy is \`${strategy.value ?? "?"}\` — the base is not merged in.`;
|
|
603
|
+
return [
|
|
604
|
+
why,
|
|
605
|
+
" Update the branch per the git-workflow skill's references/branch-update.md,",
|
|
606
|
+
" then regenerate (./agent-config roadmap:progress) and re-run the gates before pushing.",
|
|
607
|
+
];
|
|
608
|
+
}
|
|
609
|
+
|
|
528
610
|
/**
|
|
529
611
|
* @param forge Seam for the forge lookup. Production passes nothing and gets the
|
|
530
612
|
* real `gh`. Tests MUST pass a stub: without this parameter the only way to
|
|
@@ -542,6 +624,12 @@ export function main(
|
|
|
542
624
|
return selfTest(path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", ".."));
|
|
543
625
|
}
|
|
544
626
|
const quiet = argv.includes("--quiet");
|
|
627
|
+
const blank = blankExplicitBase(argv);
|
|
628
|
+
if (blank !== null) {
|
|
629
|
+
scanReport(0, "argument error");
|
|
630
|
+
console.error(`❌ check_branch_freshness: ${blank}`);
|
|
631
|
+
return 2;
|
|
632
|
+
}
|
|
545
633
|
|
|
546
634
|
// CI merges or refuses on the server; a second opinion here would be noise.
|
|
547
635
|
if (process.env["CI"] === "true" || process.env["GITHUB_ACTIONS"] === "true") {
|
|
@@ -565,8 +653,11 @@ export function main(
|
|
|
565
653
|
// positionally already selects the real `gh` — no branch needed here.
|
|
566
654
|
const resolved = resolveBase(argv, branch, forge);
|
|
567
655
|
const base = resolved.base;
|
|
656
|
+
const remote = resolved.remote ?? "origin";
|
|
657
|
+
const shown = `${remote}/${base}`;
|
|
568
658
|
|
|
569
|
-
|
|
659
|
+
// Remote and branch together: local `main` is not `upstream/main`, which can be ahead of it.
|
|
660
|
+
if (branch === base && remote === "origin") {
|
|
570
661
|
scanReport(0, `standing on ${base} itself — a branch cannot be behind itself`);
|
|
571
662
|
return 0;
|
|
572
663
|
}
|
|
@@ -577,49 +668,81 @@ export function main(
|
|
|
577
668
|
if (resolved.unverified !== undefined) {
|
|
578
669
|
process.stdout.write(
|
|
579
670
|
`⚠️ check_branch_freshness: could not ask the forge for this branch's PR base ` +
|
|
580
|
-
`(${resolved.unverified}) — checking
|
|
671
|
+
`(${resolved.unverified}) — checking ${shown}, the ${describeBase(resolved)}. ` +
|
|
581
672
|
"If an open PR targets a different base, THAT base is NOT verified here.\n",
|
|
582
673
|
);
|
|
583
674
|
}
|
|
584
675
|
|
|
585
|
-
const
|
|
586
|
-
if (
|
|
676
|
+
const head = remoteHeadState(base, remote);
|
|
677
|
+
if (head.kind === "absent") {
|
|
678
|
+
// The remote answered, so this is not the offline case: passing it as NOT
|
|
679
|
+
// VERIFIED let a misspelled base (`origin/origin/main`) skip the check.
|
|
680
|
+
scanReport(1);
|
|
681
|
+
console.error(
|
|
682
|
+
`❌ check_branch_freshness: base \`${base}\` does not exist on ${remote} — ${describeBase(resolved)}. ` +
|
|
683
|
+
"Name a branch on the remote: `--base main` and `--base origin/main` are the same branch.",
|
|
684
|
+
);
|
|
685
|
+
return 1;
|
|
686
|
+
}
|
|
687
|
+
if (head.kind === "unreachable") {
|
|
587
688
|
// Loud, not silent. An offline run has not verified the invariant, and a
|
|
588
689
|
// gate that passes on an invariant it never evaluated is the false green
|
|
589
690
|
// this repo keeps finding.
|
|
590
|
-
scanReport(0,
|
|
691
|
+
scanReport(0, `${shown} unreachable — reported NOT VERIFIED rather than green`);
|
|
591
692
|
process.stdout.write(
|
|
592
|
-
`check_branch_freshness: could not reach
|
|
693
|
+
`check_branch_freshness: could not reach ${shown} — NOT VERIFIED (offline?). ` +
|
|
593
694
|
"Re-run before pushing.\n",
|
|
594
695
|
);
|
|
595
696
|
return 0;
|
|
596
697
|
}
|
|
597
698
|
|
|
699
|
+
const sha = head.sha;
|
|
598
700
|
scanReport(1);
|
|
599
701
|
if (containsCommit(sha) === true) {
|
|
600
702
|
if (!quiet) {
|
|
601
703
|
process.stdout.write(
|
|
602
|
-
`✅ branch is current with
|
|
704
|
+
`✅ branch is current with ${shown} (${sha.slice(0, 9)}) — ${describeBase(resolved)}\n`,
|
|
603
705
|
);
|
|
604
706
|
}
|
|
605
707
|
return 0;
|
|
606
708
|
}
|
|
607
709
|
|
|
608
710
|
console.error(
|
|
609
|
-
`❌ branch is BEHIND
|
|
711
|
+
`❌ branch is BEHIND ${shown} — the remote is at ${sha.slice(0, 9)}. ` +
|
|
610
712
|
`(${describeBase(resolved)})`,
|
|
611
713
|
);
|
|
612
714
|
console.error("");
|
|
613
715
|
console.error(" Pushing now opens a PR that may conflict, and worse: another branch");
|
|
614
716
|
console.error(" may already have shipped what this one is implementing.");
|
|
615
717
|
console.error("");
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
718
|
+
// Advice text never pays for a fetch: the measured commit is new on a behind
|
|
719
|
+
// branch, so reading the strategy there would fetch inside the push budget.
|
|
720
|
+
// Read it at that commit only if it is already local, else at the cached
|
|
721
|
+
// remote-tracking commit; with neither, the remedy is the generic pointer.
|
|
722
|
+
const localAt = [sha, `refs/remotes/${remote}/${base}`]
|
|
723
|
+
.map((ref) => git(["rev-parse", "--verify", "-q", `${ref}^{commit}`]))
|
|
724
|
+
.find((found): found is string => found !== null && found !== "");
|
|
725
|
+
const strategy = localAt === undefined
|
|
726
|
+
? null
|
|
727
|
+
: (readCommittedConvention(process.cwd(), {
|
|
728
|
+
override: shown,
|
|
729
|
+
keys: ["update_strategy"],
|
|
730
|
+
fetch: false,
|
|
731
|
+
deps: { ...makeTargetDeps(process.cwd()), remoteSha: () => localAt },
|
|
732
|
+
}).readings.update_strategy as GitConventionReading);
|
|
733
|
+
// Read by the pre-push hook to print the exact BASE it refused for. Only a
|
|
734
|
+
// checkout that defines the task gets it: a consumer runs this script from
|
|
735
|
+
// node_modules, where the task does not exist and the line would not run.
|
|
736
|
+
// A strategy read as something other than merge would make the task refuse, so it
|
|
737
|
+
// is not offered then. An unread strategy keeps it: the task reads the strategy itself.
|
|
738
|
+
const mergeAllowed = strategy === null || (!isRefusal(strategy.state) && strategy.value === "merge");
|
|
739
|
+
if (definesPushReady() && mergeAllowed) {
|
|
740
|
+
console.error(` task push-ready BASE=${remote === "origin" ? base : shown} # integrate the base set, regenerate, verify, re-check`);
|
|
741
|
+
console.error("");
|
|
742
|
+
}
|
|
743
|
+
for (const line of behindRemedy(base, strategy, remote)) {
|
|
744
|
+
console.error(line);
|
|
745
|
+
}
|
|
623
746
|
console.error("");
|
|
624
747
|
console.error(
|
|
625
748
|
" This gate asks the REMOTE, not your tracking ref — a fetch from earlier in",
|