@event4u/agent-config 16.3.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 +251 -0
- package/README.md +2 -2
- package/agents/templates/.ai-council.yml.example +26 -8
- package/dist/agent-src/commands/analyze/inbox.md +10 -7
- 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 +1 -1
- package/dist/agent-src/commands/fix/ci.md +17 -3
- 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 +3 -3
- 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/next.md +10 -1
- package/dist/agent-src/commands/roadmap/process-full.md +52 -38
- package/dist/agent-src/commands/roadmap/resolve-blockers.md +64 -14
- 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/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 +1 -1
- 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 +67 -52
- 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 +4 -10
- 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 +0 -1
- 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 +0 -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 +0 -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 +0 -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 +5 -5
- 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 +2 -3
- package/dist/agent-src/rules/delegation-policy.md +2 -3
- package/dist/agent-src/rules/design-fidelity.md +0 -1
- 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 +0 -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 +0 -1
- package/dist/agent-src/rules/domain-safety-pii.md +0 -1
- package/dist/agent-src/rules/domain-safety-retention.md +0 -1
- package/dist/agent-src/rules/downstream-changes.md +0 -1
- package/dist/agent-src/rules/engineering-safety-floor.md +0 -1
- 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 +1 -2
- package/dist/agent-src/rules/finance-safety-floor.md +0 -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 +1 -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 +0 -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 +0 -1
- package/dist/agent-src/rules/lethal-trifecta-guard.md +0 -1
- package/dist/agent-src/rules/linked-projects-onboarding-gate.md +0 -1
- package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +0 -1
- package/dist/agent-src/rules/markdown-safe-codeblocks.md +0 -1
- package/dist/agent-src/rules/media-governance-routing.md +1 -2
- 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 +2 -3
- 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 +2 -3
- package/dist/agent-src/rules/question-not-instruction.md +0 -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 +3 -6
- 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 +0 -1
- package/dist/agent-src/rules/scale-discipline.md +0 -1
- package/dist/agent-src/rules/secret-vcs-guard.md +0 -1
- package/dist/agent-src/rules/security-sensitive-stop.md +0 -1
- 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 +0 -1
- package/dist/agent-src/rules/settings-ask-protocol.md +5 -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 +0 -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 +0 -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 +0 -1
- package/dist/agent-src/rules/ui-audit-gate.md +1 -2
- package/dist/agent-src/rules/untrusted-input-defense.md +0 -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 +0 -1
- package/dist/agent-src/scripts/gate_budget.ts +47 -23
- package/dist/agent-src/scripts/gate_execute.ts +12 -4
- 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/bug-analyzer/SKILL.md +1 -1
- 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/estimate-ticket/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/jira-integration/SKILL.md +3 -3
- package/dist/agent-src/skills/merge-conflicts/SKILL.md +10 -4
- package/dist/agent-src/skills/po-discovery/SKILL.md +1 -1
- package/dist/agent-src/skills/refine-ticket/SKILL.md +4 -4
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +2 -2
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +4 -2
- package/dist/agent-src/skills/source-discovery/SKILL.md +1 -1
- package/dist/agent-src/skills/tailwind-engineer/SKILL.md +3 -1
- package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
- 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/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/skill.md +1 -1
- package/dist/cli/registry.js +1 -0
- package/dist/cli-delegate/check_update_banner.js +195 -119
- package/dist/cli-delegate/{chunk-TRI6DQZ6.js → chunk-5GPULQBE.js} +60 -42
- package/dist/cli-delegate/{chunk-JQVYKIZA.js → chunk-6SRJTYJS.js} +33 -177
- package/dist/cli-delegate/chunk-6V5FMA3P.js +186 -0
- 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-NQ7WT43P.js → chunk-AED2VQGM.js} +65 -11
- package/dist/cli-delegate/{chunk-7HQ52DHU.js → chunk-AL3RZ22D.js} +1 -1
- package/dist/cli-delegate/{chunk-DBH4AHDK.js → chunk-ED7KCMLB.js} +9 -11
- package/dist/cli-delegate/{chunk-NXEILF2K.js → chunk-F3QDG2GT.js} +481 -72
- package/dist/cli-delegate/{chunk-CQWX336L.js → chunk-G5VVIZRC.js} +3 -3
- package/dist/cli-delegate/{chunk-JY2I2DXV.js → chunk-H76PHZBI.js} +137 -60
- package/dist/cli-delegate/chunk-IAYTIIQW.js +67 -0
- package/dist/cli-delegate/{chunk-LIYTLH6O.js → chunk-KXXWJTDO.js} +5 -10
- package/dist/cli-delegate/{chunk-T7L2QK3K.js → chunk-LQOCRFWT.js} +1 -1
- package/dist/cli-delegate/{chunk-S4YWNRKO.js → chunk-MDPPKQCQ.js} +34 -1
- package/dist/cli-delegate/{chunk-S4UMZNES.js → chunk-MSUL5NYP.js} +5 -5
- package/dist/cli-delegate/chunk-OAFSJBHH.js +272 -0
- package/dist/cli-delegate/{chunk-GKE7ZVFA.js → chunk-PWX7CKMD.js} +1 -1
- package/dist/cli-delegate/{chunk-NDJLNC6Q.js → chunk-T6BP34WI.js} +1 -0
- package/dist/cli-delegate/{chunk-RQNNW7IF.js → chunk-T7XSJSUQ.js} +433 -632
- package/dist/cli-delegate/{chunk-EEHDXSYD.js → chunk-WQWXGIWB.js} +12 -273
- package/dist/cli-delegate/{chunk-QLDHIPWR.js → chunk-XQTPXKFA.js} +1 -1
- 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 +105 -35
- package/dist/cli-delegate/cmd_converge.js +3 -3
- package/dist/cli-delegate/cmd_doctor.js +15 -12
- package/dist/cli-delegate/cmd_doctor_neighbours.js +11 -4
- package/dist/cli-delegate/cmd_explain.js +43 -19
- package/dist/cli-delegate/cmd_export.js +10 -10
- package/dist/cli-delegate/cmd_git_convention.js +1851 -0
- package/dist/cli-delegate/cmd_handoff.js +40 -21
- package/dist/cli-delegate/cmd_mcp_available.js +3 -2
- package/dist/cli-delegate/cmd_migrate.js +3 -3
- package/dist/cli-delegate/cmd_packs_active.js +4 -3
- package/dist/cli-delegate/cmd_prune.js +10 -10
- package/dist/cli-delegate/cmd_route_audit.js +7 -7
- package/dist/cli-delegate/cmd_route_explain.js +5 -5
- package/dist/cli-delegate/cmd_session_recycle.js +9 -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 +10 -10
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +10 -10
- package/dist/cli-delegate/cmd_uninstall.js +10 -10
- package/dist/cli-delegate/cmd_update.js +7 -7
- package/dist/cli-delegate/cmd_upgrade.js +7 -7
- package/dist/cli-delegate/cmd_validate.js +10 -10
- package/dist/cli-delegate/cmd_versions.js +5 -5
- package/dist/cli-delegate/gate_budget.js +1 -1
- package/dist/cli-delegate/gate_execute.js +2 -2
- package/dist/cli-delegate/roadmap_gates.js +2 -2
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +129 -90
- 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 +24 -9
- package/dist/discovery/trust-report.md +3 -3
- package/dist/discovery/workspaces.json +5 -4
- package/dist/hooks/dispatch.js +2151 -1820
- package/dist/hooks/dispatch.sha256 +1 -1
- package/dist/install/install.mjs +462 -431
- package/dist/install/installThinLayer.js +40 -12
- package/dist/install/installedRuleLinks.js +105 -19
- 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 +2702 -1995
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/agent_settings.js +15 -120
- 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 +344 -18
- package/dist/scripts/_lib/package_root.js +68 -0
- package/dist/scripts/_lib/rule_law_section.js +1 -1
- package/dist/scripts/_lib/settings_removed_keys.js +168 -0
- package/dist/scripts/_lib/thin_rules.js +80 -3
- 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 +23 -81
- package/dist/shared/skillRanking.js +30 -4
- 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 +35 -65
- 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/gate_budget.ts +47 -23
- package/src/agent-src/scripts/gate_execute.ts +12 -4
- 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/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/config/agent-settings.template.yml +79 -312
- 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 +3 -3
- package/src/config/discovery/packs.yml +17 -1
- package/src/config/evaluator-budgets.json +19 -6
- package/src/config/gate-coverage.yml +65 -23
- package/src/config/gate-violation-baselines.json +53 -13
- package/src/config/gitignore-block.txt +19 -0
- package/src/config/hook-bundle-budget.json +1 -1
- package/src/config/release-gate-locality.yml +2 -1
- package/src/config/routing-coverage-seed.json +48 -6
- package/src/config/rule-law-ceilings.json +12 -6
- package/src/config/rule-obligations.json +833 -0
- package/src/install/installThinLayer.ts +76 -10
- package/src/install/installedRuleLinks.ts +105 -17
- 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 +10 -10
- package/src/scripts/_cli/cmd_doctor_neighbours.ts +133 -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 +37 -2
- package/src/scripts/_lib/agent_settings.ts +15 -124
- package/src/scripts/_lib/blocked_by_marker.ts +1 -1
- package/src/scripts/_lib/compile_time_toggles.ts +12 -21
- package/src/scripts/_lib/dispatch_import_closure.ts +163 -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/global_deploy_inventory.ts +74 -0
- package/src/scripts/_lib/graph_feeder_record.ts +236 -13
- package/src/scripts/_lib/installed_layer.ts +448 -23
- package/src/scripts/_lib/knowledge_global.ts +14 -1
- package/src/scripts/_lib/module_reach.ts +456 -0
- package/src/scripts/_lib/neighbour_contradictions.ts +236 -0
- package/src/scripts/_lib/neighbour_tool_use.ts +8 -10
- 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/rule_law_section.ts +1 -1
- 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/test_red_state.ts +5 -0
- package/src/scripts/_lib/thin_rules.ts +83 -3
- package/src/scripts/_lib/touched_file_quality.ts +142 -6
- package/src/scripts/_lib/worker_budget.ts +1 -1
- package/src/scripts/adr/regenerate_index.ts +16 -1
- package/src/scripts/ai_council/config.ts +7 -7
- 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_team/config.ts +11 -16
- package/src/scripts/audit_user_type_axis.ts +20 -8
- 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/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_evaluator_budgets.ts +4 -0
- package/src/scripts/check_finding_dispositions.ts +88 -25
- 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 +107 -0
- package/src/scripts/check_kernel_edit_ratified.ts +86 -6
- package/src/scripts/check_pack_size.ts +1 -1
- package/src/scripts/check_release_manifest_content.ts +189 -0
- package/src/scripts/check_standing_rule_delivery.ts +96 -0
- package/src/scripts/check_suppression_hygiene.ts +2 -5
- 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/command_suggester/settings.ts +8 -108
- package/src/scripts/command_suggester/types.ts +4 -5
- 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/explain_run.ts +8 -13
- package/src/scripts/generate_git_convention_grammar.ts +127 -0
- package/src/scripts/generate_host_cost_table.ts +20 -3
- package/src/scripts/handoff_context_hook.ts +86 -37
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +25 -6
- package/src/scripts/hooks/block_config_weakening.ts +48 -5
- package/src/scripts/hooks/block_plumbing_writes.ts +8 -4
- package/src/scripts/hooks/concern_registry.ts +2 -0
- package/src/scripts/hooks/delegation_nudge_hook.ts +2 -3
- package/src/scripts/hooks/evidence_independence.ts +12 -4
- package/src/scripts/hooks/mcp_usage_observation_hook.ts +121 -0
- package/src/scripts/hooks/push_settle_hook.ts +4 -3
- package/src/scripts/hooks/rule_inject_hook.ts +44 -3
- package/src/scripts/hooks/state_io.ts +8 -4
- package/src/scripts/hooks/telemetry_usage_hook.ts +7 -46
- package/src/scripts/hooks/turn_end_gate_hook.ts +1 -0
- package/src/scripts/install-hooks.sh +42 -14
- package/src/scripts/install.ts +7 -31
- 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_pack_boundaries.ts +406 -28
- 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 +151 -21
- 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 +12 -1
- package/src/scripts/measure_skill_ranker_baseline.ts +5 -0
- package/src/scripts/model_rule_injection.ts +3 -3
- 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/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_installed_rule_links.ts +118 -1
- package/src/scripts/report_module_reach.ts +212 -0
- package/src/scripts/report_obligation_mechanism.ts +16 -18
- package/src/scripts/report_parked_blockers.ts +222 -0
- package/src/scripts/report_required_checks_drift.ts +196 -0
- package/src/scripts/report_skill_ranker_confusion.ts +103 -2
- package/src/scripts/report_standing_payload_by_host.ts +1 -1
- package/src/scripts/routing_doctor.ts +2 -2
- package/src/scripts/schemas/agent-settings.schema.json +17 -31
- package/src/scripts/schemas/command.schema.json +1 -1
- package/src/scripts/schemas/skill.schema.json +1 -1
- package/src/scripts/self_review_gate.ts +39 -2
- package/src/scripts/skill_tools/score_skill_relevance.ts +28 -19
- package/src/scripts/sync_pr_branch.ts +403 -132
- package/src/scripts/trigger_eval_grandfather.json +0 -16
- package/src/server/schemas/settings.ts +33 -177
- package/src/shared/skillRanking.ts +53 -4
- package/dist/cli-delegate/chunk-NYX3L2PZ.js +0 -99
- 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
|
@@ -126,12 +126,13 @@ const _PATH_KEYS: readonly string[] = ['file_path', 'path', 'target_file', 'file
|
|
|
126
126
|
export type ConfigKind = 'allowlist' | 'advisory' | 'class-c' | null;
|
|
127
127
|
|
|
128
128
|
/**
|
|
129
|
-
* Project settings files
|
|
129
|
+
* Project settings files, and the committed git-convention carrier (ADR-283),
|
|
130
|
+
* whose keys this guard fences. User-global files are
|
|
130
131
|
* never in reach — the hook only sees a path a tool call named, and the writes
|
|
131
132
|
* that reach `~/.event4u/` go through `settings:set`, which applies its own
|
|
132
133
|
* per-key refusal.
|
|
133
134
|
*/
|
|
134
|
-
const CLASS_C_BASENAMES: readonly string[] = ['.agent-settings.yml', '.agent-settings.yaml', 'settings.json'];
|
|
135
|
+
const CLASS_C_BASENAMES: readonly string[] = ['.agent-settings.yml', '.agent-settings.yaml', '.git-convention.yml', 'settings.json'];
|
|
135
136
|
|
|
136
137
|
/** Where the class contract lives, relative to the package root. */
|
|
137
138
|
export const SETTINGS_CLASSES_RELATIVE = 'docs/contracts/settings-classes.md';
|
|
@@ -382,10 +383,25 @@ export interface Decision {
|
|
|
382
383
|
* unreadable for the length of one tool call, which is a bypass with no
|
|
383
384
|
* authorisation step in it.
|
|
384
385
|
*
|
|
386
|
+
* The edit forms it models: `Write` (`content`), `Edit` (`old_string` /
|
|
387
|
+
* `new_string`, with `replace_all`) and `MultiEdit` (an `edits` list of those
|
|
388
|
+
* pairs, applied in order).
|
|
389
|
+
*
|
|
385
390
|
* WHAT IT CANNOT SEE: an edit applied through a shell redirect rather than an
|
|
386
391
|
* edit tool — `EDIT_TOOLS` is the corpus, and the shell shapes are
|
|
387
392
|
* `block_plumbing_writes`' subject, not this one.
|
|
388
393
|
*/
|
|
394
|
+
/** The host writes `new_string` verbatim; `String.replace` would expand `$&`-style tokens. */
|
|
395
|
+
function _replaceFirstLiteral(text: string, from: string, to: string): string {
|
|
396
|
+
const at = text.indexOf(from);
|
|
397
|
+
return text.slice(0, at) + to + text.slice(at + from.length);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/** An empty `old_string` is the host's create form, which `split('')` does not model. */
|
|
401
|
+
function _applyEdit(text: string, from: string, to: string, all: unknown): string {
|
|
402
|
+
return all === true && from !== '' ? text.split(from).join(to) : _replaceFirstLiteral(text, from, to);
|
|
403
|
+
}
|
|
404
|
+
|
|
389
405
|
export function classCVerdict(
|
|
390
406
|
ti: JsonObject,
|
|
391
407
|
on_disk: string | null,
|
|
@@ -397,11 +413,22 @@ export function classCVerdict(
|
|
|
397
413
|
const content = ti['content'];
|
|
398
414
|
const oldStr = ti['old_string'];
|
|
399
415
|
const newStr = ti['new_string'];
|
|
416
|
+
const forms = [content !== undefined, oldStr !== undefined || newStr !== undefined, ti['edits'] !== undefined];
|
|
417
|
+
if (forms.filter(Boolean).length > 1) {
|
|
418
|
+
return (
|
|
419
|
+
`${rel_path}: this edit carries more than one edit form (content, old_string/new_string, edits), ` +
|
|
420
|
+
'so the guard cannot tell which one the host will run and no key can be cleared. ' +
|
|
421
|
+
'Re-send it as one form, or write the change through `agent-config settings:set`.'
|
|
422
|
+
);
|
|
423
|
+
}
|
|
424
|
+
// A file that does not exist yet is created by an edit with an empty
|
|
425
|
+
// `old_string`, so it is modelled as empty text rather than left unchecked.
|
|
426
|
+
const current = on_disk ?? '';
|
|
400
427
|
let afterText: string | null = null;
|
|
401
428
|
if (typeof content === 'string') {
|
|
402
429
|
afterText = content;
|
|
403
|
-
} else if (typeof oldStr === 'string' && typeof newStr === 'string'
|
|
404
|
-
if (!
|
|
430
|
+
} else if (typeof oldStr === 'string' && typeof newStr === 'string') {
|
|
431
|
+
if (!current.includes(oldStr)) return null; // the edit will not apply
|
|
405
432
|
// `replace_all` is the host's own flag and it changes WHICH text the
|
|
406
433
|
// edit produces. Modelling only the first occurrence let a
|
|
407
434
|
// `replace_all` edit whose SECOND occurrence is the Class C one pass
|
|
@@ -417,7 +444,23 @@ export function classCVerdict(
|
|
|
417
444
|
'`agent-config settings:set`.'
|
|
418
445
|
);
|
|
419
446
|
}
|
|
420
|
-
afterText =
|
|
447
|
+
afterText = _applyEdit(current, oldStr, newStr, all);
|
|
448
|
+
} else if (ti['edits'] !== undefined && !Array.isArray(ti['edits'])) {
|
|
449
|
+
return `${rel_path}: this MultiEdit carries an edit the guard cannot interpret, so the text it would produce is unknown and no key can be cleared. Re-send it as plain edits, or write the change through \`agent-config settings:set\`.`;
|
|
450
|
+
} else if (Array.isArray(ti['edits'])) {
|
|
451
|
+
// MultiEdit applies its pairs in order and applies none when one misses.
|
|
452
|
+
let text = current;
|
|
453
|
+
for (const e of ti['edits']) {
|
|
454
|
+
const o = _isObject(e) ? e['old_string'] : undefined;
|
|
455
|
+
const n = _isObject(e) ? e['new_string'] : undefined;
|
|
456
|
+
const a = _isObject(e) ? e['replace_all'] : undefined;
|
|
457
|
+
if (typeof o !== 'string' || typeof n !== 'string' || (a !== undefined && typeof a !== 'boolean')) {
|
|
458
|
+
return `${rel_path}: this MultiEdit carries an edit the guard cannot interpret, so the text it would produce is unknown and no key can be cleared. Re-send it as plain edits, or write the change through \`agent-config settings:set\`.`;
|
|
459
|
+
}
|
|
460
|
+
if (!text.includes(o)) return null;
|
|
461
|
+
text = _applyEdit(text, o, n, a);
|
|
462
|
+
}
|
|
463
|
+
afterText = text;
|
|
421
464
|
}
|
|
422
465
|
if (afterText === null) return null;
|
|
423
466
|
|
|
@@ -5,10 +5,14 @@
|
|
|
5
5
|
* road-to-a-kernel-that-guards-its-plumbing 1.2 — the other half of a
|
|
6
6
|
* deliberate split, and the split is the whole design:
|
|
7
7
|
*
|
|
8
|
-
* · plumbing SOURCES
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* · plumbing SOURCES are edited legitimately all the time. They carry a
|
|
9
|
+
* RECORD — the ADR-268 § 4 ratification gate — not a deny. Which files
|
|
10
|
+
* count is NOT listed here: it is `check_kernel_edit_ratified`'s
|
|
11
|
+
* `PLUMBING_SOURCE_RE` plus the verdict-deciding modules of the
|
|
12
|
+
* dispatcher's import closure (`derivedPlumbing`), computed at run time.
|
|
13
|
+
* A copy of that list here drifted once already — it named the pattern
|
|
14
|
+
* and missed the policy module a refactor moved out of the dispatcher —
|
|
15
|
+
* so this header points at the set instead of restating it.
|
|
12
16
|
* · plumbing BUILD OUTPUTS have no legitimate hand edit at all. They carry a
|
|
13
17
|
* DENY, which is this file.
|
|
14
18
|
*
|
|
@@ -65,6 +65,7 @@ import { main as suggestionCaptureMain } from './suggestion_capture_hook.js';
|
|
|
65
65
|
import { main as uiRouteNudgeMain } from './ui_route_nudge_hook.js';
|
|
66
66
|
import { main as orchestrationRecordMain } from './orchestration_record_hook.js';
|
|
67
67
|
import { main as telemetryUsageMain } from './telemetry_usage_hook.js';
|
|
68
|
+
import { main as mcpUsageObservationMain } from './mcp_usage_observation_hook.js';
|
|
68
69
|
import { main as telemetryFlushMain } from './telemetry_flush_hook.js';
|
|
69
70
|
import { main as delegationNudgeMain } from './delegation_nudge_hook.js';
|
|
70
71
|
import { main as skillRouteMain } from './skill_route_hook.js';
|
|
@@ -132,6 +133,7 @@ export const CONCERN_REGISTRY: Readonly<Record<string, ConcernMain>> = {
|
|
|
132
133
|
'src/scripts/hooks/ui_route_nudge_hook.ts': uiRouteNudgeMain as ConcernMain,
|
|
133
134
|
'src/scripts/hooks/orchestration_record_hook.ts': orchestrationRecordMain as ConcernMain,
|
|
134
135
|
'src/scripts/hooks/telemetry_usage_hook.ts': telemetryUsageMain as ConcernMain,
|
|
136
|
+
'src/scripts/hooks/mcp_usage_observation_hook.ts': mcpUsageObservationMain as ConcernMain,
|
|
135
137
|
'src/scripts/hooks/telemetry_flush_hook.ts': telemetryFlushMain as ConcernMain,
|
|
136
138
|
'src/scripts/hooks/delegation_nudge_hook.ts': delegationNudgeMain as ConcernMain,
|
|
137
139
|
'src/scripts/hooks/skill_route_hook.ts': skillRouteMain as ConcernMain,
|
|
@@ -320,11 +320,10 @@ export function resolveActivation(
|
|
|
320
320
|
const emergency = (settings["emergency"] ?? {}) as Record<string, unknown>;
|
|
321
321
|
const halted = emergency["orchestration_halt"] === true;
|
|
322
322
|
const host_manifest = probeHostCapabilities(hostId);
|
|
323
|
-
const sub = (settings["subagents"] ?? {}) as Record<string, unknown>;
|
|
324
|
-
const downshift = sub["downshift"] !== false;
|
|
325
323
|
return {
|
|
326
324
|
activation: { halted, subagent_spawn: host_manifest.subagent_spawn },
|
|
327
|
-
downshift
|
|
325
|
+
// Fixed on: the `subagents.downshift` key was retired with this default.
|
|
326
|
+
downshift: true,
|
|
328
327
|
separate_quota_pool: host_manifest.separate_quota_pool,
|
|
329
328
|
agentTeams: host_manifest.agent_teams,
|
|
330
329
|
};
|
|
@@ -53,6 +53,7 @@ import { atomic_write_json } from "./state_io.js";
|
|
|
53
53
|
import { readHookStdin } from "./hook_stdin.js";
|
|
54
54
|
import { isCodePath, isTestPath } from "../_lib/test_delta.js";
|
|
55
55
|
import { EXIT_ALLOW, EXIT_BLOCK } from './exit_codes.js';
|
|
56
|
+
import { ledgerFileFor } from "../git_authorization_hook.js";
|
|
56
57
|
|
|
57
58
|
// MUST equal dispatch_hook.EXIT_BLOCK. The dispatcher's internal ladder is
|
|
58
59
|
// 0 allow / 1 block / 2 warn — NOT the 2-means-block shape a PreToolUse guard
|
|
@@ -198,11 +199,18 @@ interface DispatchState extends JsonObject {
|
|
|
198
199
|
evaluations: JsonValue[];
|
|
199
200
|
}
|
|
200
201
|
|
|
201
|
-
/**
|
|
202
|
-
|
|
202
|
+
/**
|
|
203
|
+
* The current user turn's stamp, or "" when no ledger exists yet.
|
|
204
|
+
*
|
|
205
|
+
* Reads the ledger through the writer's own `ledgerFileFor(session_id)`
|
|
206
|
+
* rather than the legacy session-less path: with a session id the writer
|
|
207
|
+
* never touches that path, so reading it unconditionally found an empty or
|
|
208
|
+
* stale file and the stamp never changed per turn.
|
|
209
|
+
*/
|
|
210
|
+
function _ledgerStamp(consumer_root: string, session_id: string): string {
|
|
203
211
|
try {
|
|
204
212
|
const raw = fs.readFileSync(
|
|
205
|
-
path.join(consumer_root,
|
|
213
|
+
path.join(consumer_root, ledgerFileFor(session_id)),
|
|
206
214
|
"utf8",
|
|
207
215
|
);
|
|
208
216
|
const d = JSON.parse(raw) as Record<string, unknown>;
|
|
@@ -421,7 +429,7 @@ export function run(stdin_text: string, options: { consumer_root: string }): num
|
|
|
421
429
|
// in a session blocked every later one. The only per-user-turn stamp that
|
|
422
430
|
// actually exists is `detected_at` in the authorization ledger, which
|
|
423
431
|
// `git_authorization_hook` rewrites on every `user_prompt_submit`.
|
|
424
|
-
const turnMarker = `${session_id}:${_ledgerStamp(options.consumer_root)}`;
|
|
432
|
+
const turnMarker = `${session_id}:${_ledgerStamp(options.consumer_root, session_id)}`;
|
|
425
433
|
if (state.session_id !== turnMarker) {
|
|
426
434
|
state.session_id = turnMarker;
|
|
427
435
|
state.turn_started_at = new Date().toISOString();
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Foreign MCP tool names, observed on `post_tool_use`
|
|
4
|
+
* (road-to-neighbours-that-pull-their-weight step 3.3, decision D12).
|
|
5
|
+
*
|
|
6
|
+
* DEFAULT-ON LOCAL OBSERVATION, AND IT BYPASSES THE TELEMETRY OPT-IN. Stated
|
|
7
|
+
* here first because it is the one property a reader must not have to infer.
|
|
8
|
+
* This concern writes on every install, whether or not the org telemetry switch
|
|
9
|
+
* was ever enabled, because the file it writes feeds `doctor neighbours` — a
|
|
10
|
+
* report the consumer runs on their own tree — and gating it on an org switch
|
|
11
|
+
* would publish `0` on every install that never enabled one. Nothing here is
|
|
12
|
+
* telemetry: no transport reads the file, it is never spooled, and it lives
|
|
13
|
+
* under gitignored `agents/runtime/` (decision D9).
|
|
14
|
+
*
|
|
15
|
+
* WHAT IS RECORDED: the tool NAME, `mcp__<server>__<tool>`, and the UTC day it
|
|
16
|
+
* was last seen. Nothing else — no arguments, no response, no session id, no
|
|
17
|
+
* host. The dispatcher serves this concern a REDUCED payload: its manifest
|
|
18
|
+
* entry declares no `needs_payload_bodies`, so `tool_input` and `tool_response`
|
|
19
|
+
* arrive as size-only stubs and cannot be recorded even by mistake.
|
|
20
|
+
*
|
|
21
|
+
* RETENTION. A map keyed by tool name, rewritten in place at most once per day
|
|
22
|
+
* per name — bounded by the neighbour's tool surface, so it needs no TTL job.
|
|
23
|
+
* The reader applies a 30-day window; older entries stop counting. Deleting
|
|
24
|
+
* `agents/runtime/neighbour-tool-use.json` erases all of it.
|
|
25
|
+
*
|
|
26
|
+
* Why a concern of its own rather than a branch of `telemetry-usage`: that
|
|
27
|
+
* concern's dispatcher filter is `tools: [Skill]` and matches exactly, so a
|
|
28
|
+
* branch there was never called for an MCP tool; and a concern named for
|
|
29
|
+
* opt-in telemetry should not also carry default-on local collection. Both
|
|
30
|
+
* were the AI council's findings (2026-10-02); the owner chose this shape.
|
|
31
|
+
*
|
|
32
|
+
* No `tools:` filter on the manifest entry, deliberately: MCP tool names are
|
|
33
|
+
* not enumerable and matching is exact. The prefix test below is the filter.
|
|
34
|
+
*
|
|
35
|
+
* Exit code is ALWAYS 0 and nothing is printed — it observes, never gates.
|
|
36
|
+
*/
|
|
37
|
+
import * as path from 'node:path';
|
|
38
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
39
|
+
import * as fs from 'node:fs';
|
|
40
|
+
|
|
41
|
+
import { FOREIGN_TOOL_USE_REL, MCP_TOOL_PREFIX, resolveStoreRoot, usageDay } from '../_lib/neighbour_tool_use.js';
|
|
42
|
+
import { update_json_under_lock } from './state_io.js';
|
|
43
|
+
import { readHookStdin } from './hook_stdin.js';
|
|
44
|
+
import { EXIT_ALLOW } from './exit_codes.js';
|
|
45
|
+
|
|
46
|
+
type JsonObject = { [k: string]: unknown };
|
|
47
|
+
|
|
48
|
+
function isObject(v: unknown): v is JsonObject {
|
|
49
|
+
return typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** The MCP tool name off the envelope, or null for anything else. */
|
|
53
|
+
export function mcpToolName(envelope: unknown): string | null {
|
|
54
|
+
if (!isObject(envelope)) return null;
|
|
55
|
+
const payload = isObject(envelope['payload']) ? envelope['payload'] : envelope;
|
|
56
|
+
const v = payload['tool_name'] ?? payload['toolName'] ?? payload['tool'];
|
|
57
|
+
return typeof v === 'string' && v.startsWith(MCP_TOOL_PREFIX) && v.length > MCP_TOOL_PREFIX.length ? v : null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function record(envelope: unknown, consumer_root: string): number {
|
|
61
|
+
try {
|
|
62
|
+
const tool = mcpToolName(envelope);
|
|
63
|
+
if (tool === null) return EXIT_ALLOW;
|
|
64
|
+
const day = usageDay(new Date());
|
|
65
|
+
update_json_under_lock<Record<string, string>>(
|
|
66
|
+
path.join(resolveStoreRoot(consumer_root), FOREIGN_TOOL_USE_REL),
|
|
67
|
+
(seen) => (seen[tool] === day ? null : ({ ...seen, [tool]: day } as Record<string, string>)),
|
|
68
|
+
{ blocking: false },
|
|
69
|
+
);
|
|
70
|
+
} catch {
|
|
71
|
+
return EXIT_ALLOW;
|
|
72
|
+
}
|
|
73
|
+
return EXIT_ALLOW;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function run(stdin_text: string, options: { consumer_root: string }): number {
|
|
77
|
+
let envelope: unknown;
|
|
78
|
+
try {
|
|
79
|
+
const raw = stdin_text.trim();
|
|
80
|
+
if (!raw) return EXIT_ALLOW;
|
|
81
|
+
envelope = JSON.parse(raw);
|
|
82
|
+
} catch {
|
|
83
|
+
return EXIT_ALLOW;
|
|
84
|
+
}
|
|
85
|
+
return record(envelope, options.consumer_root);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function _root(envelope: unknown): string {
|
|
89
|
+
if (isObject(envelope)) {
|
|
90
|
+
const v = envelope['cwd'] ?? envelope['workspace_root'] ?? envelope['project_root'];
|
|
91
|
+
if (typeof v === 'string' && v) return v;
|
|
92
|
+
}
|
|
93
|
+
return process.cwd();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function main(): number {
|
|
97
|
+
const raw = readHookStdin();
|
|
98
|
+
let envelope: unknown = {};
|
|
99
|
+
try {
|
|
100
|
+
envelope = raw.trim() ? JSON.parse(raw) : {};
|
|
101
|
+
} catch {
|
|
102
|
+
return EXIT_ALLOW;
|
|
103
|
+
}
|
|
104
|
+
return record(envelope, _root(envelope));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Bundle-safety: guarded at the call site so esbuild drops the whole entry
|
|
108
|
+
// check inside the shared hook bundle (see telemetry_usage_hook.ts, D11).
|
|
109
|
+
declare const __AGENT_CONFIG_BUNDLE__: boolean | undefined;
|
|
110
|
+
function _isCliEntry(): boolean {
|
|
111
|
+
if (process.argv[1] === undefined) return false;
|
|
112
|
+
if (import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href) return true;
|
|
113
|
+
try {
|
|
114
|
+
return fs.realpathSync(fileURLToPath(import.meta.url)) === fs.realpathSync(path.resolve(process.argv[1]));
|
|
115
|
+
} catch {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (typeof __AGENT_CONFIG_BUNDLE__ === 'undefined' || !__AGENT_CONFIG_BUNDLE__) {
|
|
120
|
+
if (_isCliEntry()) process.exit(main());
|
|
121
|
+
}
|
|
@@ -195,9 +195,10 @@ export function buildReminder(branch: string, pr: number | null): { reason: stri
|
|
|
195
195
|
` 2. Red? Read only the failing part:\n` +
|
|
196
196
|
` gh run view --job <id> --log-failed | grep -E '×|FAIL|Error'\n` +
|
|
197
197
|
` then fix it and push again (fix-what-you-see: the author is irrelevant).\n` +
|
|
198
|
-
` 3.
|
|
199
|
-
`
|
|
200
|
-
`
|
|
198
|
+
` 3. 3 attempts on the same target triggers autonomous-execution's ` +
|
|
199
|
+
`execution.fix_loop_max strategy shift — change approach, never stop. ` +
|
|
200
|
+
`Blocked on something only the user can decide is the one branch that halts: ` +
|
|
201
|
+
`say so, with what was tried named.\n\n` +
|
|
201
202
|
`Handing the user a red PR with its cause named and unfixed is not a delivery ` +
|
|
202
203
|
`either. If you are deliberately leaving this WIP, say that in the reply — ` +
|
|
203
204
|
`silence is what this hook exists to stop.`;
|
|
@@ -147,7 +147,11 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
|
147
147
|
|
|
148
148
|
import { hookSectionEnabled } from '../_lib/hook_settings.js';
|
|
149
149
|
import * as user_global_paths from '../_lib/user_global_paths.js';
|
|
150
|
-
import {
|
|
150
|
+
import {
|
|
151
|
+
deliversBodies,
|
|
152
|
+
installerThinsHost,
|
|
153
|
+
resolveLeanProjection,
|
|
154
|
+
} from '../_lib/lean_projection_mode.js';
|
|
151
155
|
import { enforcement_class_from_frontmatter } from '../_lib/obligation_frequency.js';
|
|
152
156
|
import {
|
|
153
157
|
appendDelivered,
|
|
@@ -168,7 +172,8 @@ import {
|
|
|
168
172
|
} from '../_lib/rule_injection.js';
|
|
169
173
|
import { readConsequenceClass, stubLawIds } from '../_lib/rule_consequence_class.js';
|
|
170
174
|
import { lawText, ruleBody } from '../_lib/rule_law_section.js';
|
|
171
|
-
import { hostRuleLayerIds } from '../_lib/rule_layer_overlap.js';
|
|
175
|
+
import { hostRuleLayerDirs, hostRuleLayerIds } from '../_lib/rule_layer_overlap.js';
|
|
176
|
+
import { is_thin_entry } from '../_lib/thin_rules.js';
|
|
172
177
|
import { readHookStdin } from './hook_stdin.js';
|
|
173
178
|
import { EXIT_ALLOW, EXIT_WARN } from './exit_codes.js';
|
|
174
179
|
|
|
@@ -853,6 +858,9 @@ export function buildInjection(
|
|
|
853
858
|
openFiles: string[] | null,
|
|
854
859
|
command: string | null,
|
|
855
860
|
seen: Set<string>,
|
|
861
|
+
// `false` only for an offline measurement of WHAT the concern delivers,
|
|
862
|
+
// which must not read the measuring machine's installed rule files.
|
|
863
|
+
servedOnce = true,
|
|
856
864
|
): Injection | null {
|
|
857
865
|
let router;
|
|
858
866
|
try {
|
|
@@ -878,14 +886,47 @@ export function buildInjection(
|
|
|
878
886
|
// `hostRuleLayerIds`. No filter then, because scoping to an empty set would
|
|
879
887
|
// re-create the silence step 1.1 repaired.
|
|
880
888
|
const scope = hostRuleLayerIds(root);
|
|
881
|
-
|
|
889
|
+
let matches = matchTierRules(router, prompt, openFiles, command).filter(
|
|
882
890
|
(m) => !seen.has(m.id) && (scope === null || scope.has(m.id)),
|
|
883
891
|
);
|
|
884
892
|
if (matches.length === 0) return null;
|
|
893
|
+
// ONE COPY (`road-to-a-default-install-served-once` 1.1). The gate opens on
|
|
894
|
+
// the template's `delivery`, but the installer thins only on an explicit
|
|
895
|
+
// user-global choice, so a default install carries every routed body in
|
|
896
|
+
// its rule files already. A rule whose installed copy is a full body gets
|
|
897
|
+
// nothing; a stub still gets its body. Asked only off the consent path, so
|
|
898
|
+
// an opted-in install's delivery is unchanged byte for byte.
|
|
899
|
+
if (servedOnce && scope !== null && !installerThinsHost(DELIVERY_HOST, { packageRoot: ruleSources(root).pkg })) {
|
|
900
|
+
const full = installedFullIds(root, matches.map((m) => m.id));
|
|
901
|
+
matches = matches.filter((m) => !full.has(m.id));
|
|
902
|
+
if (matches.length === 0) return null;
|
|
903
|
+
}
|
|
885
904
|
const sel = selectForInjection(root, matches, CAP_BYTES);
|
|
886
905
|
return compose(root, sel, highConsequenceIds(root));
|
|
887
906
|
}
|
|
888
907
|
|
|
908
|
+
/**
|
|
909
|
+
* Ids among `ids` whose copy in EITHER host rule layer is a full body rather
|
|
910
|
+
* than a stub. Either, because the host loads both: one full copy is enough
|
|
911
|
+
* for the body to be standing in context already. Reads only matched ids,
|
|
912
|
+
* never the whole layer, because this runs on the per-prompt path.
|
|
913
|
+
*/
|
|
914
|
+
export function installedFullIds(root: string, ids: readonly string[]): Set<string> {
|
|
915
|
+
const out = new Set<string>();
|
|
916
|
+
for (const dir of hostRuleLayerDirs(root)) {
|
|
917
|
+
for (const id of ids) {
|
|
918
|
+
let text: string;
|
|
919
|
+
try {
|
|
920
|
+
text = fs.readFileSync(path.join(dir, `${id}.md`), 'utf-8');
|
|
921
|
+
} catch {
|
|
922
|
+
continue;
|
|
923
|
+
}
|
|
924
|
+
if (!is_thin_entry(text)) out.add(id);
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
return out;
|
|
928
|
+
}
|
|
929
|
+
|
|
889
930
|
// ── main ─────────────────────────────────────────────────────────────────
|
|
890
931
|
|
|
891
932
|
/**
|
|
@@ -6,10 +6,14 @@
|
|
|
6
6
|
* Python module exactly (snake_case kept deliberately — fidelity over
|
|
7
7
|
* TS idiom).
|
|
8
8
|
*
|
|
9
|
-
* Per `docs/contracts/hook-architecture-v1.md
|
|
10
|
-
* that writes under `agents
|
|
11
|
-
*
|
|
12
|
-
* 1. Acquire an exclusive lock on
|
|
9
|
+
* Per `docs/contracts/hook-architecture-v1.md`, Concurrency, every concern
|
|
10
|
+
* that writes a state file under `agents/` MUST:
|
|
11
|
+
*
|
|
12
|
+
* 1. Acquire an exclusive lock on `<state_dir>/.dispatcher.lock` — the SAME
|
|
13
|
+
* directory the target file lives in, derived from the target's own
|
|
14
|
+
* path (`path.dirname`), never a single fixed location: one concern's
|
|
15
|
+
* target under `agents/runtime/state/` locks there, another's target
|
|
16
|
+
* under `agents/state/` locks there instead.
|
|
13
17
|
* 2. Write to a sibling `<dest>.tmp.<pid>` file in the same directory.
|
|
14
18
|
* 3. Rename(2) (atomic on the same filesystem) tmp → dest.
|
|
15
19
|
* 4. Release the lock.
|
|
@@ -29,23 +29,11 @@
|
|
|
29
29
|
* settings file is how it learns it is off, the same as the artefact-
|
|
30
30
|
* engagement surface it mirrors.)
|
|
31
31
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* gating it on the org switch would print `0` everywhere (roadmap decision D9)
|
|
38
|
-
* — but it IS a file operation, so the guarantee now says which operations it
|
|
39
|
-
* covers. An unqualified claim this file's own code contradicts is worse than
|
|
40
|
-
* the narrower one it is replaced by.
|
|
41
|
-
*
|
|
42
|
-
* NOT REACHED YET, AND SAYING SO HERE BECAUSE THIS IS WHERE A READER LOOKS.
|
|
43
|
-
* The manifest entry for this concern carries `tools: [Skill]`, which the
|
|
44
|
-
* dispatcher matches exactly, so it is not invoked for an MCP call at all and
|
|
45
|
-
* the branch below is dead in production. Held as the
|
|
46
|
-
* `mcp-recorder-unreachable-behind-the-tools-filter` blocker on
|
|
47
|
-
* road-to-neighbours-that-pull-their-weight: the manifest is a gated
|
|
48
|
-
* governance surface and the council split on the edit rather than converging.
|
|
32
|
+
* The foreign-MCP tool-name recorder that once branched here lives in its own
|
|
33
|
+
* concern, `mcp-usage-observation` (road-to-neighbours-that-pull-their-weight
|
|
34
|
+
* D12): this concern's `tools: [Skill]` filter meant the dispatcher never
|
|
35
|
+
* called that branch, and default-on local collection does not belong under an
|
|
36
|
+
* opt-in telemetry name.
|
|
49
37
|
*
|
|
50
38
|
* NO OUTBOUND CALL EXISTS HERE, DELIBERATELY. Transport is Phase 2 and is
|
|
51
39
|
* blocked on `sink-choice`; org-wide enablement is Phase 3 and is blocked on
|
|
@@ -74,12 +62,7 @@ import {
|
|
|
74
62
|
FLUSH_SESSION_END,
|
|
75
63
|
spool_path_for,
|
|
76
64
|
} from '../../agent-src/templates/scripts/telemetry/transport.js';
|
|
77
|
-
import {
|
|
78
|
-
FOREIGN_TOOL_USE_REL,
|
|
79
|
-
MCP_TOOL_PREFIX,
|
|
80
|
-
usageDay,
|
|
81
|
-
} from '../_lib/neighbour_tool_use.js';
|
|
82
|
-
import { is_replay_mode, update_json_under_lock } from './state_io.js';
|
|
65
|
+
import { is_replay_mode } from './state_io.js';
|
|
83
66
|
import { readHookStdin } from './hook_stdin.js';
|
|
84
67
|
import { EXIT_ALLOW } from './exit_codes.js';
|
|
85
68
|
|
|
@@ -272,29 +255,7 @@ function processEnvelope(envelope: JsonValue, consumer_root: string): number {
|
|
|
272
255
|
|
|
273
256
|
const payload = unwrapPayload(envelope);
|
|
274
257
|
const tool = extractToolName(payload);
|
|
275
|
-
if (tool !== SKILL_TOOL_NAME)
|
|
276
|
-
// The other half of this slot's observation, and the only half a
|
|
277
|
-
// `post_tool_use` envelope can supply: the tool's NAME. The MCP
|
|
278
|
-
// fingerprint store wants a tool DEFINITION, which this envelope
|
|
279
|
-
// never carries (roadmap decision D2), so what is recorded here is
|
|
280
|
-
// what was actually seen. Rooted at the settings directory, not at
|
|
281
|
-
// the session cwd, for the same reason the Class-A log below is.
|
|
282
|
-
if (tool !== null && tool.startsWith(MCP_TOOL_PREFIX)) {
|
|
283
|
-
// The mutator's cast is safe at the only place that matters:
|
|
284
|
-
// the reader in `neighbour_tool_use` drops any value that is
|
|
285
|
-
// not a string, so a hand-edited store cannot widen this.
|
|
286
|
-
// Kept OUT of the argument list below — esbuild preserves a
|
|
287
|
-
// comment in that position and it would cost the shared
|
|
288
|
-
// bundle ~190 bytes of prose nothing executes.
|
|
289
|
-
const day = usageDay(new Date());
|
|
290
|
-
update_json_under_lock<Record<string, string>>(
|
|
291
|
-
path.join(readSettingsFor(consumer_root).root, FOREIGN_TOOL_USE_REL),
|
|
292
|
-
(seen) => (seen[tool] === day ? null : ({ ...seen, [tool]: day } as Record<string, string>)),
|
|
293
|
-
{ blocking: false },
|
|
294
|
-
);
|
|
295
|
-
}
|
|
296
|
-
return EXIT_ALLOW;
|
|
297
|
-
}
|
|
258
|
+
if (tool !== SKILL_TOOL_NAME) return EXIT_ALLOW;
|
|
298
259
|
|
|
299
260
|
const { settings, text, root } = readSettingsFor(consumer_root);
|
|
300
261
|
if (!settings.active) return EXIT_ALLOW;
|
|
@@ -70,9 +70,13 @@ cat > "$HOOKS_DIR/pre-push" << 'EOF'
|
|
|
70
70
|
# belongs here; resolution belongs to a step run with the result in front of
|
|
71
71
|
# you. When this hook refuses for staleness, the thing that fixes it is
|
|
72
72
|
#
|
|
73
|
-
# task push-ready # fetch -> integrate the base SET -> regenerate
|
|
74
|
-
#
|
|
75
|
-
# task push-ready DRY=1 # the same six steps, read-only
|
|
73
|
+
# task push-ready BASE=<base> # fetch -> integrate the base SET -> regenerate
|
|
74
|
+
# # -> verify -> re-check freshness -> push
|
|
75
|
+
# task push-ready DRY=1 BASE=<base> # the same six steps, read-only
|
|
76
|
+
#
|
|
77
|
+
# `<base>` is the base the refusal names. Without BASE the base comes from the
|
|
78
|
+
# open pull request (gh pr view), and is the default branch only when there is
|
|
79
|
+
# no open pull request or no gh.
|
|
76
80
|
#
|
|
77
81
|
# The base is a SET: a branch targeting a release line or a stacked parent may
|
|
78
82
|
# also have to integrate the default branch, per the branch-convergence policy
|
|
@@ -141,23 +145,47 @@ fail=0
|
|
|
141
145
|
# no useful second finding to collect from a tree that is about to move.
|
|
142
146
|
#
|
|
143
147
|
# It never merges. `check_branch_freshness` asks the REMOTE (one `ls-remote`,
|
|
144
|
-
# measured 4.5s) and returns 1
|
|
145
|
-
#
|
|
146
|
-
#
|
|
147
|
-
# cannot
|
|
148
|
+
# measured 4.5s) and returns 1 on a VERIFIED behind state, or when the remote
|
|
149
|
+
# answered without the base at all (a misspelled or deleted base); offline, in
|
|
150
|
+
# CI, on a detached HEAD, or standing on the base itself it returns 0 and says
|
|
151
|
+
# so. So an unreachable network cannot block a push, and a stale local tracking
|
|
152
|
+
# ref cannot fake a green. The refusal below names which of the two it was, read
|
|
153
|
+
# from the gate's own lines, so a typo is never reported as staleness.
|
|
148
154
|
echo "🔍 Base freshness — is this branch behind the base it will merge into?"
|
|
149
155
|
if [ "${AGENT_CONFIG_SKIP_PREPUSH_FRESHNESS:-}" = "1" ]; then
|
|
150
156
|
echo "⏭️ skipped via AGENT_CONFIG_SKIP_PREPUSH_FRESHNESS=1"
|
|
151
157
|
elif [ ! -x ./scripts-run ]; then
|
|
152
158
|
echo "⚠️ ./scripts-run not found — skipping the freshness check for this push."
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
159
|
+
else
|
|
160
|
+
fresh_rc=0
|
|
161
|
+
fresh_out=$(./scripts-run src/scripts/check_branch_freshness --quiet 2>&1) || fresh_rc=$?
|
|
162
|
+
[ -z "$fresh_out" ] || printf '%s\n' "$fresh_out"
|
|
163
|
+
fi
|
|
164
|
+
if [ "${fresh_rc:-0}" -ne 0 ]; then
|
|
165
|
+
# The gate prints the base in the spelling `task push-ready` accepts.
|
|
166
|
+
base=$(printf '%s\n' "$fresh_out" | sed -n 's/^ *task push-ready BASE=\([^ ]*\).*/\1/p' | head -n 1)
|
|
167
|
+
absent=$(printf '%s\n' "$fresh_out" | sed -n 's/.*base `\([^`]*\)` does not exist on \([^ ]*\) .*/\2\/\1/p' | head -n 1)
|
|
157
168
|
echo ""
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
169
|
+
if [ -n "$base" ]; then
|
|
170
|
+
echo " Push blocked — the branch is behind its base, and the gates you just"
|
|
171
|
+
echo " passed were answered against a base that no longer exists."
|
|
172
|
+
echo ""
|
|
173
|
+
echo " task push-ready BASE=$base # fetch → integrate the base SET"
|
|
174
|
+
echo " # → regenerate → verify → re-check"
|
|
175
|
+
echo " task push-ready DRY=1 BASE=$base # the same steps, read-only"
|
|
176
|
+
elif printf '%s\n' "$fresh_out" | grep -q 'branch is BEHIND'; then
|
|
177
|
+
# A strategy that does not merge gets no push-ready line; its remedy
|
|
178
|
+
# is printed by the gate itself.
|
|
179
|
+
echo " Push blocked — the branch is behind its base. The remedy for this"
|
|
180
|
+
echo " project's update strategy is printed above."
|
|
181
|
+
elif [ -n "$absent" ]; then
|
|
182
|
+
echo " Push blocked — the base $absent does not exist on the remote: a"
|
|
183
|
+
echo " misspelled or deleted base, not a stale branch. Name a branch the"
|
|
184
|
+
echo " remote has (--base main and --base origin/main are the same branch)."
|
|
185
|
+
else
|
|
186
|
+
echo " Push blocked — the freshness gate refused without a verdict line;"
|
|
187
|
+
echo " its output is above."
|
|
188
|
+
fi
|
|
161
189
|
echo ""
|
|
162
190
|
echo " This hook refuses; it never merges. Bypass a genuine WIP push with"
|
|
163
191
|
echo " AGENT_CONFIG_SKIP_PREPUSH_FRESHNESS=1."
|