@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
|
@@ -96,10 +96,227 @@ export interface RatificationProblem {
|
|
|
96
96
|
| 'no-providers'
|
|
97
97
|
| 'diversity-required'
|
|
98
98
|
| 'diversity-unverifiable'
|
|
99
|
-
| 'bad-effective-after'
|
|
99
|
+
| 'bad-effective-after'
|
|
100
|
+
| 'no-seats'
|
|
101
|
+
| 'malformed-seats'
|
|
102
|
+
| 'bad-seat-provider'
|
|
103
|
+
| 'unknown-seat-verdict'
|
|
104
|
+
| 'seat-dissent'
|
|
105
|
+
| 'providers-exceed-seats'
|
|
106
|
+
| 'header-not-derived';
|
|
100
107
|
message: string;
|
|
101
108
|
}
|
|
102
109
|
|
|
110
|
+
/** A seat that closed, timed out or was absent at the last round gave no final verdict. */
|
|
111
|
+
export const SEAT_NO_FINAL_VERDICT = 'no-final-verdict';
|
|
112
|
+
export type SeatVerdict = RatificationVerdict | typeof SEAT_NO_FINAL_VERDICT;
|
|
113
|
+
/** Every value a seat's final verdict may take — shared by the writer and the reader. */
|
|
114
|
+
export const SEAT_VERDICTS: readonly string[] = [...RATIFICATION_VERDICTS, SEAT_NO_FINAL_VERDICT];
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* A provider id as a seat key: lower-case, no whitespace and no YAML
|
|
118
|
+
* metacharacter, so a rendered header cannot be split or extended by a name
|
|
119
|
+
* and two spellings of one provider cannot collide after normalisation.
|
|
120
|
+
*/
|
|
121
|
+
export const SEAT_PROVIDER_RE = /^[a-z0-9][a-z0-9._-]*$/u;
|
|
122
|
+
|
|
123
|
+
export type SeatsReading =
|
|
124
|
+
| { kind: 'absent' }
|
|
125
|
+
| { kind: 'invalid'; problems: RatificationProblem[] }
|
|
126
|
+
| { kind: 'present'; seats: Map<string, SeatVerdict> };
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* The `seats:` map — provider id to that seat's FINAL verdict — in source
|
|
130
|
+
* order, which is the order `providers` is derived in.
|
|
131
|
+
*
|
|
132
|
+
* Absent and present-but-unusable are reported apart: a missing key and a
|
|
133
|
+
* `seats:` key that is empty, a scalar, a list, or carries a bad id or verdict
|
|
134
|
+
* are both refusals, with different codes.
|
|
135
|
+
*/
|
|
136
|
+
export function readSeats(fm: AdrFrontmatter, text = ''): SeatsReading {
|
|
137
|
+
const duplicates = duplicateSeatKeys(text);
|
|
138
|
+
if (duplicates.length > 0) {
|
|
139
|
+
return {
|
|
140
|
+
kind: 'invalid',
|
|
141
|
+
problems: [
|
|
142
|
+
{
|
|
143
|
+
code: 'bad-seat-provider',
|
|
144
|
+
message: `seat \`${duplicates.join('`, `')}\` is recorded more than once — the parser keeps only the last`,
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
const hasScalar = Object.prototype.hasOwnProperty.call(fm.scalars, 'seats');
|
|
150
|
+
const node = fm.nested['seats'];
|
|
151
|
+
if (node === undefined && !hasScalar) {
|
|
152
|
+
return { kind: 'absent' };
|
|
153
|
+
}
|
|
154
|
+
if (node === undefined || typeof node === 'string' || Array.isArray(node)) {
|
|
155
|
+
return {
|
|
156
|
+
kind: 'invalid',
|
|
157
|
+
problems: [{ code: 'malformed-seats', message: '`seats:` is present but is not a provider-to-verdict map' }],
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
const problems: RatificationProblem[] = [];
|
|
161
|
+
const seats = new Map<string, SeatVerdict>();
|
|
162
|
+
for (const [provider, verdict] of Object.entries(node)) {
|
|
163
|
+
if (!SEAT_PROVIDER_RE.test(provider)) {
|
|
164
|
+
problems.push({
|
|
165
|
+
code: 'bad-seat-provider',
|
|
166
|
+
message: `seat key \`${provider}\` is not a provider id (${String(SEAT_PROVIDER_RE)})`,
|
|
167
|
+
});
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if (typeof verdict !== 'string' || !SEAT_VERDICTS.includes(verdict.trim())) {
|
|
171
|
+
problems.push({
|
|
172
|
+
code: 'unknown-seat-verdict',
|
|
173
|
+
message: `seat \`${provider}\` records \`${String(verdict)}\`, not one of ${SEAT_VERDICTS.join(', ')}`,
|
|
174
|
+
});
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
seats.set(provider, verdict.trim() as SeatVerdict);
|
|
178
|
+
}
|
|
179
|
+
if (problems.length === 0 && seats.size === 0) {
|
|
180
|
+
problems.push({ code: 'malformed-seats', message: '`seats:` is present and empty' });
|
|
181
|
+
}
|
|
182
|
+
return problems.length > 0 ? { kind: 'invalid', problems } : { kind: 'present', seats };
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/** Keys repeated inside the frontmatter `seats:` block, read from the raw text. */
|
|
186
|
+
function duplicateSeatKeys(text: string): string[] {
|
|
187
|
+
if (!text.startsWith('---\n')) return [];
|
|
188
|
+
const end = text.indexOf('\n---\n', 4);
|
|
189
|
+
const lines = text.slice(4, end === -1 ? undefined : end).split('\n');
|
|
190
|
+
const start = lines.findIndex((l) => /^seats:\s*$/u.test(l));
|
|
191
|
+
if (start === -1) return [];
|
|
192
|
+
const seen = new Set<string>();
|
|
193
|
+
const dup = new Set<string>();
|
|
194
|
+
for (const line of lines.slice(start + 1)) {
|
|
195
|
+
if (!/^\s/u.test(line)) break;
|
|
196
|
+
// Compared by the identity a YAML parser would give the key, so a quoted
|
|
197
|
+
// spelling cannot hide a second entry for the same seat.
|
|
198
|
+
const key = line
|
|
199
|
+
.slice(0, line.indexOf(':') === -1 ? undefined : line.indexOf(':'))
|
|
200
|
+
.trim()
|
|
201
|
+
.replace(/^(["'])(.*)\1$/u, '$2')
|
|
202
|
+
.trim();
|
|
203
|
+
if (key === '' || key.startsWith('#')) continue;
|
|
204
|
+
if (seen.has(key)) dup.add(key);
|
|
205
|
+
seen.add(key);
|
|
206
|
+
}
|
|
207
|
+
return [...dup];
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* The header a set of seat verdicts supports, and no more.
|
|
212
|
+
*
|
|
213
|
+
* `providers` is every seat that gave a final verdict — a closed seat is not a
|
|
214
|
+
* provider the verdict came from. Any refusing seat makes the verdict `refused`,
|
|
215
|
+
* any non-convergent one `non-convergent`; only when every final seat passed is
|
|
216
|
+
* the verdict passing, and then `ratified` if any seat said so. No final seat at
|
|
217
|
+
* all is `non-convergent`: a review that ended without a verdict did not pass.
|
|
218
|
+
*/
|
|
219
|
+
export function deriveRatificationHeader(
|
|
220
|
+
seats: ReadonlyMap<string, SeatVerdict> | Readonly<Record<string, SeatVerdict>>,
|
|
221
|
+
): { providers: string[]; verdict: RatificationVerdict } {
|
|
222
|
+
const entries = seats instanceof Map ? [...seats.entries()] : Object.entries(seats);
|
|
223
|
+
const final = entries.filter(([, v]) => v !== SEAT_NO_FINAL_VERDICT) as [string, RatificationVerdict][];
|
|
224
|
+
const verdicts = final.map(([, v]) => v);
|
|
225
|
+
let verdict: RatificationVerdict;
|
|
226
|
+
if (verdicts.includes('refused')) {
|
|
227
|
+
verdict = 'refused';
|
|
228
|
+
} else if (final.length === 0 || verdicts.includes('non-convergent')) {
|
|
229
|
+
verdict = 'non-convergent';
|
|
230
|
+
} else {
|
|
231
|
+
verdict = verdicts.includes('ratified') ? 'ratified' : 'confirmed-non-expanding';
|
|
232
|
+
}
|
|
233
|
+
return { providers: final.map(([p]) => p), verdict };
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* The `providers:`, `verdict:` and `seats:` frontmatter lines, derived — never
|
|
238
|
+
* typed. Throws on a provider id outside {@link SEAT_PROVIDER_RE}: a name that
|
|
239
|
+
* could carry YAML syntax is refused rather than escaped.
|
|
240
|
+
*/
|
|
241
|
+
export function renderRatificationHeader(
|
|
242
|
+
seats: ReadonlyMap<string, SeatVerdict> | Readonly<Record<string, SeatVerdict>>,
|
|
243
|
+
): string {
|
|
244
|
+
const entries = seats instanceof Map ? [...seats.entries()] : Object.entries(seats);
|
|
245
|
+
for (const [p, v] of entries) {
|
|
246
|
+
if (!SEAT_PROVIDER_RE.test(p)) throw new Error(`not a provider id: ${JSON.stringify(p)}`);
|
|
247
|
+
if (!SEAT_VERDICTS.includes(v)) throw new Error(`not a seat verdict: ${JSON.stringify(v)}`);
|
|
248
|
+
}
|
|
249
|
+
const { providers, verdict } = deriveRatificationHeader(seats);
|
|
250
|
+
return [
|
|
251
|
+
`providers: [${providers.join(', ')}]`,
|
|
252
|
+
`verdict: ${verdict}`,
|
|
253
|
+
'seats:',
|
|
254
|
+
...entries.map(([p, v]) => ` ${p}: ${v}`),
|
|
255
|
+
].join('\n');
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* The header claims the seats do not support.
|
|
260
|
+
*
|
|
261
|
+
* `seats:` is required. Optional, it left `providers` and `verdict` free-written
|
|
262
|
+
* for every author who omitted it, which is the defect it exists to close; the
|
|
263
|
+
* round-2 ratification review refused that shape. The gate reads only the
|
|
264
|
+
* artifacts in the diff under review, so an artifact merged before the field
|
|
265
|
+
* existed is never re-read and needs no migration to stay valid.
|
|
266
|
+
*
|
|
267
|
+
* The recorded header must EQUAL the derived one; the two named overclaims get
|
|
268
|
+
* their own codes so a reader sees which one it was.
|
|
269
|
+
*/
|
|
270
|
+
function seatProblems(reading: SeatsReading, providers: readonly string[], verdict: string | null): RatificationProblem[] {
|
|
271
|
+
if (reading.kind === 'absent') {
|
|
272
|
+
return [
|
|
273
|
+
{
|
|
274
|
+
code: 'no-seats',
|
|
275
|
+
message:
|
|
276
|
+
'missing `seats:` — `providers` and `verdict` are derived from the per-seat final ' +
|
|
277
|
+
'verdicts, never typed (print all three with `ratification_header`)',
|
|
278
|
+
},
|
|
279
|
+
];
|
|
280
|
+
}
|
|
281
|
+
if (reading.kind === 'invalid') return reading.problems;
|
|
282
|
+
const seats = reading.seats;
|
|
283
|
+
const problems: RatificationProblem[] = [];
|
|
284
|
+
if (verdict !== null && PASSING_VERDICTS.has(verdict)) {
|
|
285
|
+
const dissent = [...seats].filter(([, v]) => v === 'refused' || v === 'non-convergent');
|
|
286
|
+
if (dissent.length > 0) {
|
|
287
|
+
problems.push({
|
|
288
|
+
code: 'seat-dissent',
|
|
289
|
+
message:
|
|
290
|
+
`verdict \`${verdict}\` while ${dissent.map(([p, v]) => `${p} was \`${v}\``).join(', ')} ` +
|
|
291
|
+
'at the final round — a header cannot say more than its seats said',
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
const derived = deriveRatificationHeader(seats);
|
|
296
|
+
const extra = providers.filter((p) => !derived.providers.includes(p));
|
|
297
|
+
if (extra.length > 0) {
|
|
298
|
+
problems.push({
|
|
299
|
+
code: 'providers-exceed-seats',
|
|
300
|
+
message:
|
|
301
|
+
`providers names ${extra.join(', ')}, which gave no final verdict ` +
|
|
302
|
+
`(${String(derived.providers.length)} seat(s) did) — diversity is counted over seats that answered`,
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
if (
|
|
306
|
+
problems.length === 0 &&
|
|
307
|
+
(verdict !== derived.verdict || providers.join('\u0000') !== derived.providers.join('\u0000'))
|
|
308
|
+
) {
|
|
309
|
+
problems.push({
|
|
310
|
+
code: 'header-not-derived',
|
|
311
|
+
message:
|
|
312
|
+
`recorded providers [${providers.join(', ')}] / verdict \`${String(verdict)}\` differ from the ` +
|
|
313
|
+
`header the seats derive: [${derived.providers.join(', ')}] / \`${derived.verdict}\` ` +
|
|
314
|
+
'(print it with `ratification_header`)',
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
return problems;
|
|
318
|
+
}
|
|
319
|
+
|
|
103
320
|
export interface RatificationReading {
|
|
104
321
|
artifact: RatificationArtifact | null;
|
|
105
322
|
problems: RatificationProblem[];
|
|
@@ -208,6 +425,8 @@ export function readRatification(
|
|
|
208
425
|
}
|
|
209
426
|
}
|
|
210
427
|
|
|
428
|
+
problems.push(...seatProblems(readSeats(fm, text), providers, verdict));
|
|
429
|
+
|
|
211
430
|
// Diversity, against the REQUIRED count.
|
|
212
431
|
//
|
|
213
432
|
// Round 1 refused the previous shape: the count came from the user-global
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ratification_subject — the digest a ratification record carries over the
|
|
3
|
+
* gated content it reviewed.
|
|
4
|
+
*
|
|
5
|
+
* `road-to-self-modification-that-a-council-must-pass` step 2.1, the half that
|
|
6
|
+
* does not touch the gate. The record says WHO reviewed; without a digest it
|
|
7
|
+
* does not say WHAT, so a gated file edited after its review still ships under
|
|
8
|
+
* a record that approved something else.
|
|
9
|
+
*
|
|
10
|
+
* WHY IT RE-ASSEMBLES THE LIST RATHER THAN RE-DECIDING IT. The gate's
|
|
11
|
+
* `classifyPaths` returns the kernel rules, hooks and plumbing by name but
|
|
12
|
+
* reports the self surface as a BOOLEAN, so the gated list cannot be read back
|
|
13
|
+
* out of it. This module therefore imports the gate's own path constants and
|
|
14
|
+
* re-assembles — it never restates the membership rule, because a second
|
|
15
|
+
* definition of "gated" is a second thing to keep in step, and the first time
|
|
16
|
+
* the two diverged a file would be reviewed by one and digested by the other.
|
|
17
|
+
*
|
|
18
|
+
* NO BASE DIFF. The digest is over the tree as it stands, so it is the same on
|
|
19
|
+
* a branch and on the merged checkout CI judges — unless the base changed a
|
|
20
|
+
* gated file the change also touches, and then the content that would land is
|
|
21
|
+
* not the content that was reviewed, which is precisely what should move it.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { createHash } from 'node:crypto';
|
|
25
|
+
import * as fs from 'node:fs';
|
|
26
|
+
import * as path from 'node:path';
|
|
27
|
+
|
|
28
|
+
import {
|
|
29
|
+
ANCHOR_PATHS,
|
|
30
|
+
CLOSURE_READER_PATH,
|
|
31
|
+
POLICY_PATH,
|
|
32
|
+
READER_PATH,
|
|
33
|
+
SELF_PATH,
|
|
34
|
+
WORKFLOW_PATH,
|
|
35
|
+
classifyPaths,
|
|
36
|
+
} from '../check_kernel_edit_ratified.js';
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Stands in for the content of a gated file the change deletes. A deleted file
|
|
40
|
+
* is ENTERED, never skipped: skipping would make "this file was removed"
|
|
41
|
+
* digest-identical to "this file was never gated", and removing a governance
|
|
42
|
+
* hook is exactly the change the record most needs to be bound to.
|
|
43
|
+
*/
|
|
44
|
+
export const DELETED_MARKER = '\u0000deleted\u0000';
|
|
45
|
+
|
|
46
|
+
/** The self surface, by the gate's own constants rather than a copy of them. */
|
|
47
|
+
const SELF_SET: ReadonlySet<string> = new Set<string>([
|
|
48
|
+
SELF_PATH,
|
|
49
|
+
READER_PATH,
|
|
50
|
+
CLOSURE_READER_PATH,
|
|
51
|
+
POLICY_PATH,
|
|
52
|
+
WORKFLOW_PATH,
|
|
53
|
+
...ANCHOR_PATHS,
|
|
54
|
+
]);
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The gated subset of a changed-file list: sorted, deduplicated, and stable
|
|
58
|
+
* against the order the caller happened to collect the paths in.
|
|
59
|
+
*/
|
|
60
|
+
export function gatedFilesOf(
|
|
61
|
+
files: readonly string[],
|
|
62
|
+
derived?: readonly string[],
|
|
63
|
+
): readonly string[] {
|
|
64
|
+
const normalized = files.map((f) => f.replace(/\\/g, '/').trim()).filter((f) => f !== '');
|
|
65
|
+
const g = derived === undefined ? classifyPaths(normalized) : classifyPaths(normalized, derived);
|
|
66
|
+
const out = new Set<string>([...g.kernelRules, ...g.governanceHooks, ...g.plumbing]);
|
|
67
|
+
for (const f of normalized) {
|
|
68
|
+
if (SELF_SET.has(f)) out.add(f);
|
|
69
|
+
}
|
|
70
|
+
return [...out].sort();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* One digest over the sorted paths AND contents of the gated files, read from
|
|
75
|
+
* `root`.
|
|
76
|
+
*
|
|
77
|
+
* The path is hashed alongside its content, so two files with identical bytes
|
|
78
|
+
* do not collide and a rename moves the digest — a gated file moved to another
|
|
79
|
+
* gated path is a different change, not the same one.
|
|
80
|
+
*/
|
|
81
|
+
export function subjectDigest(root: string, files: readonly string[]): string {
|
|
82
|
+
const h = createHash('sha256');
|
|
83
|
+
for (const rel of gatedFilesOf(files)) {
|
|
84
|
+
const abs = path.join(root, rel);
|
|
85
|
+
const content = fs.existsSync(abs) ? fs.readFileSync(abs) : Buffer.from(DELETED_MARKER);
|
|
86
|
+
h.update(rel);
|
|
87
|
+
h.update('\u0000');
|
|
88
|
+
h.update(createHash('sha256').update(content).digest('hex'));
|
|
89
|
+
h.update('\n');
|
|
90
|
+
}
|
|
91
|
+
return h.digest('hex');
|
|
92
|
+
}
|
|
@@ -160,7 +160,9 @@ export function dispositionStopMessage(
|
|
|
160
160
|
resumeCmd: string,
|
|
161
161
|
): string {
|
|
162
162
|
const count =
|
|
163
|
-
blocking > 0
|
|
163
|
+
blocking > 0
|
|
164
|
+
? ` ${blocking} of them are blocking findings with no disposition yet (no status, or still_open).\n`
|
|
165
|
+
: '';
|
|
164
166
|
return (
|
|
165
167
|
`the disposition gate refuses ${version}. Its own report:\n` +
|
|
166
168
|
`${gateOutput.trim() || ' (the gate printed nothing — run it directly to see why)'}\n` +
|
|
@@ -296,7 +298,7 @@ export function settleFindingsLedger(
|
|
|
296
298
|
// the operator `scanned: N` and discarded the entire reason the
|
|
297
299
|
// release stopped.
|
|
298
300
|
[verdict.stdout, verdict.stderr].map((s) => s.trim()).filter(Boolean).join('\n'),
|
|
299
|
-
blockingWithoutDisposition(path.join(deps.repoRoot, rel)),
|
|
301
|
+
blockingWithoutDisposition(path.join(deps.repoRoot, rel), version),
|
|
300
302
|
'task release -- --resume --yes',
|
|
301
303
|
),
|
|
302
304
|
);
|
|
@@ -304,20 +306,26 @@ export function settleFindingsLedger(
|
|
|
304
306
|
}
|
|
305
307
|
|
|
306
308
|
/**
|
|
307
|
-
* How many blocking findings carry no
|
|
308
|
-
*
|
|
309
|
+
* How many blocking findings carry no disposition — no status, or `still_open`,
|
|
310
|
+
* which a blocking row may not rest on — a figure for the stop message, never
|
|
311
|
+
* the reason for it.
|
|
309
312
|
*
|
|
310
313
|
* The gate refuses for more shapes than this counts (an unknown status, an
|
|
311
314
|
* empty rationale or verifier, a `fixed` with no commit, a malformed ledger),
|
|
312
|
-
* which is why the gate's own output is what the operator is shown.
|
|
315
|
+
* which is why the gate's own output is what the operator is shown. It
|
|
316
|
+
* classifies against the version being released, the same input the gate
|
|
317
|
+
* reads from `--release`, not the ledger file's own `release` field.
|
|
313
318
|
*/
|
|
314
|
-
function blockingWithoutDisposition(ledgerAbs: string): number {
|
|
319
|
+
export function blockingWithoutDisposition(ledgerAbs: string, version: string): number {
|
|
315
320
|
if (!fs.existsSync(ledgerAbs)) {
|
|
316
321
|
return 0;
|
|
317
322
|
}
|
|
318
323
|
try {
|
|
319
324
|
const ledger = parse_ledger(fs.readFileSync(ledgerAbs, 'utf-8'), ledgerAbs);
|
|
320
|
-
return ledger.findings.filter((f) =>
|
|
325
|
+
return ledger.findings.filter((f) => {
|
|
326
|
+
const status = (f.status ?? '').trim();
|
|
327
|
+
return isBlocking(f, version) && (status === '' || status === 'still_open');
|
|
328
|
+
}).length;
|
|
321
329
|
} catch {
|
|
322
330
|
return 0;
|
|
323
331
|
}
|
|
@@ -610,6 +610,11 @@ const TEST_FOOTER_RE = /^Tests: \d+/mu;
|
|
|
610
610
|
*/
|
|
611
611
|
export interface MixObligation {
|
|
612
612
|
level: string;
|
|
613
|
+
/** The resolved ends the counts were read on; the rendered level names both. */
|
|
614
|
+
from_sha?: string;
|
|
615
|
+
to_sha?: string;
|
|
616
|
+
governance_only?: number;
|
|
617
|
+
consumer_only?: number;
|
|
613
618
|
}
|
|
614
619
|
|
|
615
620
|
/** Labels whose curated value is still the generator's unedited draft. */
|
|
@@ -24,6 +24,7 @@ import * as path from 'node:path';
|
|
|
24
24
|
import { REPO_ROOT } from '../release_env.js';
|
|
25
25
|
import { die, run, type RunResult } from '../release_publication.js';
|
|
26
26
|
import {
|
|
27
|
+
BREAKING_INDEX_PATH,
|
|
27
28
|
MIGRATION_PATH as MAJOR_MIGRATION_PATH,
|
|
28
29
|
pendingMajorFinding,
|
|
29
30
|
} from '../lint_major_migration_sections.js';
|
|
@@ -148,8 +149,15 @@ export function assert_scheduled_deprecations_clear(
|
|
|
148
149
|
* real run will refuse and returns, because `--dry-run exits 0` is a contract
|
|
149
150
|
* this file's own tests assert.
|
|
150
151
|
*
|
|
152
|
+
* A major owes TWO records and this seam reads both: the migration section and
|
|
153
|
+
* the by-major row in `BREAKING_CHANGES.md`. Checking only the first at cut
|
|
154
|
+
* time while the lint checks both would let a cut create the exact state the
|
|
155
|
+
* lint then reds `main` over — the gate arriving one merge too late, which is
|
|
156
|
+
* the shape `pendingMajorFinding` exists to avoid in the first place.
|
|
157
|
+
*
|
|
151
158
|
* @param migrationReader Seam for the file read, so a test can drive the
|
|
152
159
|
* refusal without mutating a tracked file.
|
|
160
|
+
* @param indexReader The same seam for the breaking-changes index.
|
|
153
161
|
*/
|
|
154
162
|
export function assert_major_migration_section(
|
|
155
163
|
target: string,
|
|
@@ -157,18 +165,23 @@ export function assert_major_migration_section(
|
|
|
157
165
|
opts: { previewOnly?: boolean } = {},
|
|
158
166
|
migrationReader: () => string = () =>
|
|
159
167
|
fs.readFileSync(path.join(REPO_ROOT, MAJOR_MIGRATION_PATH), 'utf-8'),
|
|
168
|
+
indexReader: () => string = () =>
|
|
169
|
+
fs.readFileSync(path.join(REPO_ROOT, BREAKING_INDEX_PATH), 'utf-8'),
|
|
160
170
|
): void {
|
|
161
171
|
let migration: string;
|
|
172
|
+
let index: string;
|
|
162
173
|
try {
|
|
163
174
|
migration = migrationReader();
|
|
175
|
+
index = indexReader();
|
|
164
176
|
} catch (exc) {
|
|
165
177
|
die(
|
|
166
|
-
`refusing the ${target} cut: cannot read ${MAJOR_MIGRATION_PATH} ` +
|
|
178
|
+
`refusing the ${target} cut: cannot read ${MAJOR_MIGRATION_PATH} or ` +
|
|
179
|
+
`${BREAKING_INDEX_PATH} ` +
|
|
167
180
|
`(${exc instanceof Error ? exc.message : String(exc)}). That is an environment ` +
|
|
168
181
|
'failure, not a finding — fix the checkout, then re-run.',
|
|
169
182
|
);
|
|
170
183
|
}
|
|
171
|
-
const finding = pendingMajorFinding(target, changelog_entry, migration);
|
|
184
|
+
const finding = pendingMajorFinding(target, changelog_entry, migration, index);
|
|
172
185
|
if (finding === null) {
|
|
173
186
|
return;
|
|
174
187
|
}
|
|
@@ -180,5 +193,8 @@ export function assert_major_migration_section(
|
|
|
180
193
|
);
|
|
181
194
|
return;
|
|
182
195
|
}
|
|
183
|
-
die(
|
|
196
|
+
die(
|
|
197
|
+
`refusing the ${target} cut: ${MAJOR_MIGRATION_PATH} or ${BREAKING_INDEX_PATH} ` +
|
|
198
|
+
`does not name ${target}.`,
|
|
199
|
+
);
|
|
184
200
|
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The reserved-name sweep over flat Claude Code command files.
|
|
3
|
+
*
|
|
4
|
+
* A flat command whose slug shadows a Claude Code built-in never ships on the
|
|
5
|
+
* claude-code anchor — the suite complements the host, it does not overlay its
|
|
6
|
+
* built-ins. The sweep that enforces this used to delete EVERY builtin-named
|
|
7
|
+
* `.md` in the anchor's `commands/` directory, including one another agent
|
|
8
|
+
* package or the consumer had put there. The consumer's own `/review` command
|
|
9
|
+
* disappeared at install time with no message, because the sweep's only
|
|
10
|
+
* question was the filename.
|
|
11
|
+
*
|
|
12
|
+
* The question it asks now is ownership: a file is removed when this package
|
|
13
|
+
* wrote it — the current deploy's own written set, or a path a previous
|
|
14
|
+
* install recorded in the installed-tools manifest. Anything else is FOREIGN:
|
|
15
|
+
* it stays on disk and is reported, so the consumer learns that a built-in
|
|
16
|
+
* name is shadowed by someone and can decide, rather than finding their file
|
|
17
|
+
* gone.
|
|
18
|
+
*
|
|
19
|
+
* Both halves of the sweep's original purpose survive: ours never ships under
|
|
20
|
+
* a reserved name, and the suite still never overlays a built-in with its own
|
|
21
|
+
* file. What it no longer does is enforce that on a file that is not its own.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import * as fs from 'node:fs';
|
|
25
|
+
import * as path from 'node:path';
|
|
26
|
+
|
|
27
|
+
export interface ReservedSweepResult {
|
|
28
|
+
/** Slugs of OUR files removed because the name is a host built-in. */
|
|
29
|
+
reserved: string[];
|
|
30
|
+
/** Slugs left in place because nothing proves this package wrote them. */
|
|
31
|
+
foreign: string[];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Remove our builtin-named flat commands from `commandsDir`; keep foreign ones.
|
|
36
|
+
*
|
|
37
|
+
* Both ownership sets are anchor-relative, exactly as the deploy inventory
|
|
38
|
+
* records them. `currentFiles` is this deploy's written set — the live half,
|
|
39
|
+
* and the only one that exists on a first install. `recordedFiles` is what a
|
|
40
|
+
* previous deploy recorded under the same anchor, so a builtin-named file of
|
|
41
|
+
* ours left behind by an older version is still reaped rather than becoming
|
|
42
|
+
* permanently unprovable. A removed entry is dropped from `currentFiles` so
|
|
43
|
+
* the inventory record stays consistent with the tree, exactly as before.
|
|
44
|
+
*/
|
|
45
|
+
export function sweepReservedNames(
|
|
46
|
+
commandsDir: string,
|
|
47
|
+
currentFiles: Set<string>,
|
|
48
|
+
isBuiltinName: (slug: string) => boolean,
|
|
49
|
+
recordedFiles: ReadonlySet<string>,
|
|
50
|
+
): ReservedSweepResult {
|
|
51
|
+
const reserved: string[] = [];
|
|
52
|
+
const foreign: string[] = [];
|
|
53
|
+
let entries: string[] = [];
|
|
54
|
+
try {
|
|
55
|
+
entries = fs.readdirSync(commandsDir).filter((f) => f.endsWith('.md'));
|
|
56
|
+
} catch {
|
|
57
|
+
return { reserved, foreign };
|
|
58
|
+
}
|
|
59
|
+
for (const fname of entries.sort()) {
|
|
60
|
+
const slug = fname.slice(0, -'.md'.length);
|
|
61
|
+
if (!isBuiltinName(slug)) continue;
|
|
62
|
+
const rel = `commands/${fname}`;
|
|
63
|
+
const ours = currentFiles.has(rel) || recordedFiles.has(rel);
|
|
64
|
+
if (!ours) {
|
|
65
|
+
foreign.push(slug);
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
fs.rmSync(path.join(commandsDir, fname), { force: true });
|
|
69
|
+
currentFiles.delete(rel);
|
|
70
|
+
reserved.push(slug);
|
|
71
|
+
}
|
|
72
|
+
return { reserved, foreign };
|
|
73
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How much of a release the self-review actually read, stated where the record
|
|
3
|
+
* is read.
|
|
4
|
+
*
|
|
5
|
+
* `self_review_gate` writes a `coverage` block — `{chunks, filesReviewed,
|
|
6
|
+
* filesTotal, unreviewed[]}` — into the findings artifact, `--ingest` carries it
|
|
7
|
+
* into the per-release ledger named by {@link LEDGER_DIR}, and from there NOBODY
|
|
8
|
+
* reads `filesReviewed` back. The 16.2.0 ledger records `filesReviewed: 65,
|
|
9
|
+
* filesTotal: 678`: the review saw under a tenth of the change. Every consumer
|
|
10
|
+
* of that record — the disposition gate's success line, the release-highlights
|
|
11
|
+
* gate, a human opening the file — saw output that said nothing about it.
|
|
12
|
+
*
|
|
13
|
+
* A finding count over 9.6 % of a diff and the same count over all of it are
|
|
14
|
+
* different claims, and the record spelled them identically.
|
|
15
|
+
*
|
|
16
|
+
* A LABEL, NEVER A FLOOR, and the distinction is the decision.
|
|
17
|
+
*
|
|
18
|
+
* Nothing here refuses. `coverageLabel` returns a string or `null`; no caller
|
|
19
|
+
* turns it into an exit code, and none may. Raising what a review reads costs
|
|
20
|
+
* one more paid model request per chunk per cut, which is a spend decision
|
|
21
|
+
* belonging to the owner. A gate that failed a cut on partial coverage would
|
|
22
|
+
* force that decision through the back door — the operator would either pay or
|
|
23
|
+
* be unable to release — which is exactly the move the roadmap's decision D1
|
|
24
|
+
* records as rejected.
|
|
25
|
+
*
|
|
26
|
+
* The honest cost of that choice, stated rather than left to be discovered: a
|
|
27
|
+
* release can ship with 9.6 % coverage and this module will only have said so.
|
|
28
|
+
* Saying so is the whole claim.
|
|
29
|
+
*
|
|
30
|
+
* It lives in its own module because two consumers read it — `check_finding_dispositions` on the ledger and
|
|
31
|
+
* `check_release_highlights` beside the Known-limitations field — and a label
|
|
32
|
+
* the two spell differently is a label a reader cannot compare across the two
|
|
33
|
+
* places they meet it. One definition is also the seam the unit tests use, so
|
|
34
|
+
* the arithmetic is checked without either CLI in the loop.
|
|
35
|
+
*/
|
|
36
|
+
import * as fs from 'node:fs';
|
|
37
|
+
import * as path from 'node:path';
|
|
38
|
+
|
|
39
|
+
/** Where the per-release ledgers live, relative to the repository root. */
|
|
40
|
+
export const LEDGER_DIR = path.join('agents', 'evidence', 'release-findings');
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The coverage block as the gate writes it. Every field optional: this type
|
|
44
|
+
* describes an artifact read back off disk, which may be from an older writer
|
|
45
|
+
* or hand-edited, so the reader's job is to decide whether it can answer rather
|
|
46
|
+
* than to assume it can.
|
|
47
|
+
*/
|
|
48
|
+
export interface ReviewCoverage {
|
|
49
|
+
readonly chunks?: unknown;
|
|
50
|
+
readonly filesReviewed?: unknown;
|
|
51
|
+
readonly filesTotal?: unknown;
|
|
52
|
+
readonly unreviewed?: unknown;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function _finite(v: unknown): number | null {
|
|
56
|
+
return typeof v === 'number' && Number.isFinite(v) ? v : null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The one sentence both gates print, or `null` when there is nothing to say.
|
|
61
|
+
*
|
|
62
|
+
* `null` covers three cases deliberately collapsed into one, because they lead
|
|
63
|
+
* to the same output: full coverage (nothing to warn about), an absent block (an
|
|
64
|
+
* older ledger, written before the gate recorded coverage), and a malformed one
|
|
65
|
+
* (a string where a number belongs, a zero total). A reader who sees no label
|
|
66
|
+
* learns "this record makes no partial-coverage claim" — which is true of all
|
|
67
|
+
* three — and never a fabricated percentage derived from a field that was not
|
|
68
|
+
* a number.
|
|
69
|
+
*
|
|
70
|
+
* `filesTotal === 0` is `null` rather than `0 of 0 (partial)`: a change set with
|
|
71
|
+
* no files was fully read by any definition, and dividing by it says nothing.
|
|
72
|
+
*/
|
|
73
|
+
export function coverageLabel(coverage: unknown): string | null {
|
|
74
|
+
if (coverage === null || typeof coverage !== 'object') {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
const c = coverage as ReviewCoverage;
|
|
78
|
+
const reviewed = _finite(c.filesReviewed);
|
|
79
|
+
const total = _finite(c.filesTotal);
|
|
80
|
+
if (reviewed === null || total === null || total <= 0 || reviewed >= total) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
return `self-review read ${String(reviewed)} of ${String(total)} changed files (partial)`;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* The `coverage` block of a committed ledger, or `undefined`.
|
|
88
|
+
*
|
|
89
|
+
* Never throws. A missing ledger is the normal state of an in-flight release and
|
|
90
|
+
* a corrupt one is already the business of the gate that parses it properly —
|
|
91
|
+
* a label is not the place to discover either, and a reader that threw here
|
|
92
|
+
* would turn an informational line into a crash on a release branch.
|
|
93
|
+
*/
|
|
94
|
+
export function readLedgerCoverage(root: string, release: string): unknown {
|
|
95
|
+
const file = path.join(root, LEDGER_DIR, `${release}.json`);
|
|
96
|
+
try {
|
|
97
|
+
const parsed: unknown = JSON.parse(fs.readFileSync(file, 'utf-8'));
|
|
98
|
+
if (parsed === null || typeof parsed !== 'object') {
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
return (parsed as Record<string, unknown>)['coverage'];
|
|
102
|
+
} catch {
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** `coverageLabel` over the committed ledger for `release`. */
|
|
108
|
+
export function ledgerCoverageLabel(root: string, release: string): string | null {
|
|
109
|
+
return coverageLabel(readLedgerCoverage(root, release));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* The same label as a Known-limitations line, for the release-highlights gate.
|
|
114
|
+
*
|
|
115
|
+
* It carries the label plus the sentence that keeps a reader from mistaking it
|
|
116
|
+
* for a refusal, because the field it prints beside is one the gate CAN refuse
|
|
117
|
+
* on. Without that sentence the next person to read the output reasonably
|
|
118
|
+
* concludes the gate is about to start failing cuts on coverage, and the cheapest
|
|
119
|
+
* way to make the message go away becomes raising the ceiling — which is the
|
|
120
|
+
* owner's spend decision, taken by whoever happened to read the line.
|
|
121
|
+
*
|
|
122
|
+
* Returns `null` when there is nothing to say, so the caller prints nothing
|
|
123
|
+
* rather than a reassuring sentence about a number it does not have.
|
|
124
|
+
*/
|
|
125
|
+
export function coverageLimitationNote(label: string | null): string | null {
|
|
126
|
+
if (label === null) {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
return (
|
|
130
|
+
`ℹ️ ${label} — a limitation of the RECORD, not a verdict on the release. ` +
|
|
131
|
+
'Stated, never enforced:\n what the review reads is a spend decision and this ' +
|
|
132
|
+
'gate does not take it.'
|
|
133
|
+
);
|
|
134
|
+
}
|