@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
|
@@ -18,11 +18,10 @@
|
|
|
18
18
|
* target dir of your choosing — it never overwrites the live `.claude/` /
|
|
19
19
|
* `.augment/` projections.
|
|
20
20
|
*
|
|
21
|
-
* NOTE
|
|
22
|
-
* `
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* file by twin-parity.
|
|
21
|
+
* NOTE: the thin-entry pointer literal moved with the mechanism — it is
|
|
22
|
+
* `BODY_LINK_PREFIX` in `_lib/thin_rules.ts` now, so the twin-parity argument
|
|
23
|
+
* that exempted it from the ADR-051 legacy-path guard belongs to THAT file and
|
|
24
|
+
* no longer describes this one, which holds the string nowhere.
|
|
26
25
|
*
|
|
27
26
|
* Historical quirks are preserved deliberately — tests and downstream consumers pin the exact behaviour.
|
|
28
27
|
*
|
|
@@ -34,299 +33,20 @@ import * as fs from 'node:fs';
|
|
|
34
33
|
import * as path from 'node:path';
|
|
35
34
|
import process from 'node:process';
|
|
36
35
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
37
|
-
import { pathOnlyRuleIds, triggerlessRuleIds, } from './_lib/rule_injection.js';
|
|
38
36
|
import * as token_count from './_lib/token_count.js';
|
|
39
|
-
const _HERE = fileURLToPath(import.meta.url);
|
|
40
|
-
// REPO_ROOT = Path(__file__).resolve().parent.parent.parent — three dirs up
|
|
41
|
-
// from src/scripts/<file>.
|
|
42
|
-
export const REPO_ROOT = path.resolve(path.dirname(_HERE), '..', '..');
|
|
43
|
-
export const RULES_SOURCE = path.join(REPO_ROOT, 'dist/agent-src', 'rules');
|
|
44
|
-
export const ROUTER = path.join(REPO_ROOT, 'dist', 'router.json');
|
|
45
|
-
/** `sorted(dir.glob("*.md"))` — non-recursive, lexically sorted abs paths. */
|
|
46
|
-
function _globSortedMd(dir) {
|
|
47
|
-
let names;
|
|
48
|
-
try {
|
|
49
|
-
names = fs.readdirSync(dir);
|
|
50
|
-
}
|
|
51
|
-
catch {
|
|
52
|
-
return [];
|
|
53
|
-
}
|
|
54
|
-
const out = names.filter((n) => n.endsWith('.md')).map((n) => path.join(dir, n));
|
|
55
|
-
out.sort();
|
|
56
|
-
return out;
|
|
57
|
-
}
|
|
58
|
-
/** The always-full-bodied set — authoritative kernel list from the router. */
|
|
59
|
-
export function kernel_ids() {
|
|
60
|
-
const data = JSON.parse(fs.readFileSync(ROUTER, 'utf-8'));
|
|
61
|
-
const kernel = data.kernel;
|
|
62
|
-
if (Array.isArray(kernel)) {
|
|
63
|
-
return new Set(kernel.map((x) => String(x)));
|
|
64
|
-
}
|
|
65
|
-
return new Set();
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Tier rules the router gives NO trigger at all.
|
|
69
|
-
*
|
|
70
|
-
* These cannot be delivered on a match, so thinning them would remove a body
|
|
71
|
-
* that nothing can ever put back — a silent hole rather than a saving. They
|
|
72
|
-
* project full-bodied, and `measure` reports them by name so the residue is
|
|
73
|
-
* visible instead of being absorbed into the pointer count
|
|
74
|
-
* (road-to-trigger-delivered-rule-bodies 1.3).
|
|
75
|
-
*/
|
|
76
|
-
/**
|
|
77
|
-
* Rules whose ONLY triggers are path-shaped — reachable from `pre_tool_use`
|
|
78
|
-
* and from no other slot (road-to-delivery-for-every-host 3.2).
|
|
79
|
-
*
|
|
80
|
-
* They must never be thinned while the delivery concern is NOT bound on
|
|
81
|
-
* `pre_tool_use`, because a stub plus a slot nobody listens on is a rule that
|
|
82
|
-
* reaches the model at no scope at all. This is the same failure the
|
|
83
|
-
* `no_trigger_ids` exemption prevents, one step out: there the rule has nothing
|
|
84
|
-
* to match on, here it has nothing to match ON.
|
|
85
|
-
*
|
|
86
|
-
* Stated as a PROPERTY rather than a list of ids. If the concern is ever bound
|
|
87
|
-
* on `pre_tool_use` again, this exemption is what should be reconsidered — not
|
|
88
|
-
* three names someone has to remember.
|
|
89
|
-
*
|
|
90
|
-
* WHAT THIS EXEMPTION DOES **NOT** COVER — recorded 2026-09-08, R2 finding 1,
|
|
91
|
-
* because the silence read as coverage. The predicate is `every` trigger
|
|
92
|
-
* path-shaped. A rule with BOTH path and non-path triggers is therefore THINNED,
|
|
93
|
-
* and its path-shaped half then has no carrier at all: the stub carries no
|
|
94
|
-
* frontmatter (`condense.ts` writes it with `_writeText`, bypassing
|
|
95
|
-
* `_emit_claude_rule`'s host-native `paths:` key), `pre_tool_use` lost the
|
|
96
|
-
* binding under owner ruling E2, and `user_prompt_submit` never populates
|
|
97
|
-
* `openFiles`. Measured over the current `dist/router.json`: **18 such rules**,
|
|
98
|
-
* all non-kernel and all thinned — augment-edit-discipline, design-fidelity,
|
|
99
|
-
* doc-screenshot-hygiene, domain-adoption-policy,
|
|
100
|
-
* framework-neutrality-in-generic-skills, image-likeness-and-rights,
|
|
101
|
-
* laravel-translations, lethal-trifecta-guard, linked-projects-onboarding-gate,
|
|
102
|
-
* low-impact-corpus-privacy-floor, markdown-safe-codeblocks, onboarding-gate,
|
|
103
|
-
* persona-governance, php-coding, provider-lifecycle-discipline,
|
|
104
|
-
* roadmap-ci-steps-policy, roadmap-progress-sync, settings-ask-protocol.
|
|
105
|
-
*
|
|
106
|
-
* They do NOT reach the model at no scope: every non-path route
|
|
107
|
-
* (keyword / phrase / command) still delivers the body through the concern, and
|
|
108
|
-
* on `claude-code` they never had a separate host-native path route to lose —
|
|
109
|
-
* `_claude_paths_plan` emits no `paths:` for a mixed-trigger rule on purpose, so
|
|
110
|
-
* under `eager-all` they loaded UNCONDITIONALLY. What is lost is the difference
|
|
111
|
-
* between unconditional and prompt-triggered: a session that touches a matching
|
|
112
|
-
* file and says nothing that matches gets nothing.
|
|
113
|
-
*
|
|
114
|
-
* The labelled corpus cannot see this and the endpoint says so rather than
|
|
115
|
-
* implying otherwise — `model_rule_injection --endpoints` (b) now publishes the
|
|
116
|
-
* shipped `user_prompt_submit` reach beside the pre-registered reading, and
|
|
117
|
-
* every one of these 18 has at least one prompt-matching positive, so none
|
|
118
|
-
* appears in its "reachable only via a path trigger" column.
|
|
119
|
-
*
|
|
120
|
-
* WHY THIS IS NOT WIDENED TO `some` HERE. Measured: exempting all 18 moves the
|
|
121
|
-
* thin rule layer 23,592 -> 39,921 GPT tok (+16,329, +69 %), which is a budget
|
|
122
|
-
* move of a magnitude no agent may take, and it would erase most of the saving
|
|
123
|
-
* the flip is licensed on. Restoring a path route needs either that exemption
|
|
124
|
-
* under a re-anchored baseline or a `pre_tool_use` binding under a raised slot
|
|
125
|
-
* cap — both owner-reserved, so the closure is tracked rather than taken here.
|
|
126
|
-
* ADR-267's Consequences section names the receiver.
|
|
127
|
-
*/
|
|
128
|
-
/**
|
|
129
|
-
* ONE spelling of the router-derived sets, shared with the injector (R2
|
|
130
|
-
* finding 11).
|
|
131
|
-
*
|
|
132
|
-
* `path_only_ids` and `no_trigger_ids` were each a second, hand-rolled
|
|
133
|
-
* implementation of `_lib/rule_injection.ts::pathOnlyRuleIds` /
|
|
134
|
-
* `triggerlessRuleIds` — verified identical over the current router at the time
|
|
135
|
-
* (symmetric difference empty), so drift risk rather than a live defect. It is
|
|
136
|
-
* exactly the hazard `THIN_ENTRY_MARKER`'s own comment argues against one
|
|
137
|
-
* screen below ("a gate that re-spelled this string would drift from the writer
|
|
138
|
-
* silently"), and the two consumers here are the PROJECTOR's exemption set and
|
|
139
|
-
* the INJECTOR's reachability set: they must not be able to disagree about which
|
|
140
|
-
* rules the delivery path can reach.
|
|
141
|
-
*
|
|
142
|
-
* The finding named `path_only_ids`. The defect-pattern sweep found the SECOND
|
|
143
|
-
* instance one function down — `no_trigger_ids` against `triggerlessRuleIds` —
|
|
144
|
-
* and it is delegated in the same change. Count: 2 of 2 duplicated
|
|
145
|
-
* router-derived sets in this file, 0 remaining.
|
|
146
|
-
*/
|
|
147
|
-
function _router() {
|
|
148
|
-
return JSON.parse(fs.readFileSync(ROUTER, 'utf-8'));
|
|
149
|
-
}
|
|
150
|
-
export function path_only_ids() {
|
|
151
|
-
return pathOnlyRuleIds(_router());
|
|
152
|
-
}
|
|
153
|
-
export function no_trigger_ids() {
|
|
154
|
-
return new Set(triggerlessRuleIds(_router()));
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* id → workspaces for every non-kernel router entry (router.json schema v2,
|
|
158
|
-
* road-to-request-scoped-rule-load Phase 1). Rules absent from the map (or
|
|
159
|
-
* with an empty list) fail safe: they stay in scope.
|
|
160
|
-
*/
|
|
161
|
-
export function rule_workspaces_map() {
|
|
162
|
-
const data = JSON.parse(fs.readFileSync(ROUTER, 'utf-8'));
|
|
163
|
-
const map = new Map();
|
|
164
|
-
for (const tier of ['tier_1', 'tier_2']) {
|
|
165
|
-
const entries = data[tier];
|
|
166
|
-
if (!Array.isArray(entries))
|
|
167
|
-
continue;
|
|
168
|
-
for (const e of entries) {
|
|
169
|
-
const obj = e;
|
|
170
|
-
const ws = Array.isArray(obj.workspaces) ? obj.workspaces.map((w) => String(w)) : [];
|
|
171
|
-
map.set(String(obj.id), ws);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
return map;
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Whether a rule id survives a workspace scope. Kernel always survives;
|
|
178
|
-
* `scope === null` = legacy-all. An out-of-scope non-kernel rule is dropped
|
|
179
|
-
* entirely — neither body nor pointer line (the pointer floor shrinks with
|
|
180
|
-
* consumer scoping).
|
|
181
|
-
*/
|
|
182
|
-
export function id_in_scope(rule_id, scope, kernel, wsMap, fallback_ws = []) {
|
|
183
|
-
if (scope === null || kernel.has(rule_id)) {
|
|
184
|
-
return true;
|
|
185
|
-
}
|
|
186
|
-
// Router map first (schema v2); `type: manual` rules are reference-only
|
|
187
|
-
// and never emitted to the router — their frontmatter is the fallback.
|
|
188
|
-
const ws = wsMap.get(rule_id) ?? fallback_ws;
|
|
189
|
-
if (ws.length === 0) {
|
|
190
|
-
return true; // untagged / unknown → fail safe
|
|
191
|
-
}
|
|
192
|
-
return ws.some((w) => scope.includes(w));
|
|
193
|
-
}
|
|
194
|
-
/** `workspaces:` list parsed straight from a rule file's frontmatter. */
|
|
195
|
-
export function fm_workspaces(text) {
|
|
196
|
-
const [fm] = split_frontmatter(text);
|
|
197
|
-
// Flow style: `workspaces: [a, b, c]`
|
|
198
|
-
const flow = /^workspaces:[ \t]*\[([^\]]*)\]/m.exec(fm);
|
|
199
|
-
if (flow) {
|
|
200
|
-
return flow[1]
|
|
201
|
-
.split(',')
|
|
202
|
-
.map((s) => s.trim().replace(/^["']|["']$/g, ''))
|
|
203
|
-
.filter((s) => s.length > 0);
|
|
204
|
-
}
|
|
205
|
-
// Block style; tolerate the list being the LAST frontmatter key.
|
|
206
|
-
const m = /^workspaces:[ \t]*\n((?:[ \t]+-[ \t]+.*(?:\n|$))+)/m.exec(fm);
|
|
207
|
-
if (!m) {
|
|
208
|
-
return [];
|
|
209
|
-
}
|
|
210
|
-
return [...m[1].matchAll(/-[ \t]+(\S+)/g)].map((x) => x[1]);
|
|
211
|
-
}
|
|
212
|
-
/** Return [frontmatter_including_fences, body]. Empty fm if none. */
|
|
213
|
-
export function split_frontmatter(text) {
|
|
214
|
-
if (text.startsWith('---\n')) {
|
|
215
|
-
const end = text.indexOf('\n---\n', 4);
|
|
216
|
-
if (end !== -1) {
|
|
217
|
-
return [text.slice(0, end + 5), text.slice(end + 5)];
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
return ['', text];
|
|
221
|
-
}
|
|
222
|
-
function _description(fm) {
|
|
223
|
-
// re.search(r'^description:\s*"?(.+?)"?\s*$', fm, re.MULTILINE)
|
|
224
|
-
const m = /^description:\s*"?(.+?)"?\s*$/m.exec(fm);
|
|
225
|
-
return m ? m[1].trim() : '';
|
|
226
|
-
}
|
|
227
|
-
// How many trigger keywords/phrases to surface as the always-on match hint.
|
|
228
|
-
const _TRIGGER_HINT_LIMIT = 6;
|
|
229
|
-
/** A short, comma-joined sample of the rule's trigger keywords/phrases. */
|
|
230
|
-
function _trigger_hint(fm) {
|
|
231
|
-
const hits = [];
|
|
232
|
-
// re.finditer(r'^\s*-\s*(?:keyword|phrase):\s*"?(.+?)"?\s*$', fm, re.MULTILINE)
|
|
233
|
-
const re = /^\s*-\s*(?:keyword|phrase):\s*"?(.+?)"?\s*$/gm;
|
|
234
|
-
let m;
|
|
235
|
-
while ((m = re.exec(fm)) !== null) {
|
|
236
|
-
hits.push(m[1].trim());
|
|
237
|
-
if (hits.length >= _TRIGGER_HINT_LIMIT) {
|
|
238
|
-
break;
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
return hits.join(', ');
|
|
242
|
-
}
|
|
243
|
-
/** Python `str.title()` — uppercase first alpha of each run, rest lowercase. */
|
|
244
|
-
function _title(s) {
|
|
245
|
-
return s.replace(/[A-Za-z]+/g, (w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase());
|
|
246
|
-
}
|
|
247
|
-
/**
|
|
248
|
-
* The marker that makes a projected entry recognisable as a stub.
|
|
249
|
-
*
|
|
250
|
-
* Exported so the WRITER and every DETECTOR share one definition. A gate that
|
|
251
|
-
* re-spelled this string would drift from the writer silently, and the failure
|
|
252
|
-
* would be invisible in exactly the direction that matters: a stub the gate
|
|
253
|
-
* fails to recognise reads as a complete rule body.
|
|
254
|
-
*/
|
|
255
|
-
export const THIN_ENTRY_MARKER = '> Routed rule — load the body on trigger-match.';
|
|
256
|
-
/** Is this projected entry a pointer stub rather than a rule body? */
|
|
257
|
-
export function is_thin_entry(text) {
|
|
258
|
-
return text.includes(THIN_ENTRY_MARKER);
|
|
259
|
-
}
|
|
260
37
|
/**
|
|
261
|
-
*
|
|
262
|
-
*
|
|
263
|
-
* FIXED 2026-09-07: this pointed into the uncondensed source tree ADR-051
|
|
264
|
-
* retired — the literal path is deliberately NOT reproduced here, because
|
|
265
|
-
* `check_no_uncondensed_refs` matches the string and cannot tell a repair
|
|
266
|
-
* record from a live reference; `git log -S` on this file finds the old value.
|
|
267
|
-
* It exists in no checkout, so EVERY stub's fallback pointer
|
|
268
|
-
* resolved to nothing — invisible under `delivery`, where the hook loads the
|
|
269
|
-
* body from `dist/agent-src/rules` and never follows this link, and total under
|
|
270
|
-
* `thin`, where the pointer is the only path to the body there is.
|
|
38
|
+
* The mechanism lives in `_lib/thin_rules.ts`; this file is its CLI.
|
|
271
39
|
*
|
|
272
|
-
*
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
* needs an operator to have added `cline` to that list, and its pointer is off
|
|
278
|
-
* by one level. That is strictly better than the previous state, where the
|
|
279
|
-
* pointer was dead in all three, and it is recorded here so the remaining case
|
|
280
|
-
* is a known limit rather than a surprise.
|
|
40
|
+
* Re-exported wholesale so every existing importer of
|
|
41
|
+
* `project_thin_rules.{build_thin,thin_entry,is_thin_entry,RULES_SOURCE,…}`
|
|
42
|
+
* keeps working unchanged. The split exists because `src/scripts/install.ts` is
|
|
43
|
+
* a bundle entry and `check_installer_import_purity` forbids it reaching a
|
|
44
|
+
* module-level `process.exit()` — which this file has, at its foot, by design.
|
|
281
45
|
*/
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
const desc = _description(fm);
|
|
287
|
-
const hint = _trigger_hint(fm);
|
|
288
|
-
const title = _title(rule_id.replace(/-/g, ' '));
|
|
289
|
-
const fires = hint ? ` Fires on: ${hint}.` : '';
|
|
290
|
-
return (`## ${title}\n` +
|
|
291
|
-
`${THIN_ENTRY_MARKER}${fires} ${desc} ` +
|
|
292
|
-
`Body: [\`${rule_id}\`](${BODY_LINK_PREFIX}${rule_id}.md)\n`);
|
|
293
|
-
}
|
|
294
|
-
/** Map {filename: thin_or_full_text} for every rule. Kernel stays full. */
|
|
295
|
-
export function build_thin(rules_dir = RULES_SOURCE, scope = null,
|
|
296
|
-
/**
|
|
297
|
-
* Optional sink for the D3 diagnostic
|
|
298
|
-
* (road-to-delivery-for-every-host 2.2).
|
|
299
|
-
*
|
|
300
|
-
* An `auto` rule the router gives NO trigger is already kept full-bodied by
|
|
301
|
-
* `noTrigger` below, which is the substantive protection and predates this
|
|
302
|
-
* roadmap. What did not exist is any way to SEE it happen: the rule is
|
|
303
|
-
* silently exempted, so an author who removes a rule's last trigger gets a
|
|
304
|
-
* silently eager rule and no signal. The line makes the exemption audible.
|
|
305
|
-
*/
|
|
306
|
-
announce = null) {
|
|
307
|
-
const kernel = kernel_ids();
|
|
308
|
-
const noTrigger = no_trigger_ids();
|
|
309
|
-
const pathOnly = path_only_ids();
|
|
310
|
-
const wsMap = scope !== null ? rule_workspaces_map() : new Map();
|
|
311
|
-
const out = new Map();
|
|
312
|
-
for (const p of _globSortedMd(rules_dir)) {
|
|
313
|
-
const text = fs.readFileSync(p, 'utf-8');
|
|
314
|
-
const stem = path.basename(p).replace(/\.md$/, '');
|
|
315
|
-
if (!id_in_scope(stem, scope, kernel, wsMap, fm_workspaces(text))) {
|
|
316
|
-
continue; // out of workspace scope — no body, no pointer line
|
|
317
|
-
}
|
|
318
|
-
const full = kernel.has(stem) || noTrigger.has(stem) || pathOnly.has(stem);
|
|
319
|
-
if (announce !== null && noTrigger.has(stem) && !kernel.has(stem)) {
|
|
320
|
-
announce(`D3: trigger-less auto rule ${path.basename(p)} — kept full-bodied, never thinned`);
|
|
321
|
-
}
|
|
322
|
-
if (announce !== null && pathOnly.has(stem) && !kernel.has(stem) && !noTrigger.has(stem)) {
|
|
323
|
-
announce(`E2: path-only auto rule ${path.basename(p)} — kept full-bodied; its only triggers ` +
|
|
324
|
-
`are path-shaped and the delivery concern is not bound on pre_tool_use`);
|
|
325
|
-
}
|
|
326
|
-
out.set(path.basename(p), full ? text : thin_entry(stem, text));
|
|
327
|
-
}
|
|
328
|
-
return out;
|
|
329
|
-
}
|
|
46
|
+
export * from './_lib/thin_rules.js';
|
|
47
|
+
import { _globSortedMd, build_thin, fm_workspaces, id_in_scope, kernel_ids, no_trigger_ids, REPO_ROOT, RULES_SOURCE, rule_workspaces_map, } from './_lib/thin_rules.js';
|
|
48
|
+
void REPO_ROOT;
|
|
49
|
+
const _HERE = fileURLToPath(import.meta.url);
|
|
330
50
|
/** Python `round(x, 1)` — round-half-to-even at one decimal. */
|
|
331
51
|
function _python_round1(x) {
|
|
332
52
|
const scaled = x * 10;
|
package/dist/server/app.js
CHANGED
|
@@ -155,7 +155,7 @@ export async function createApp(opts) {
|
|
|
155
155
|
await app.register(pingRoute({ writeRoot, projectScopeRoot, mode, dryRun, projectSurface: opts.projectSurface === true }));
|
|
156
156
|
await app.register(discoveryRoute(opts.discoveryManifestPath ? { manifestPath: opts.discoveryManifestPath } : {}));
|
|
157
157
|
await app.register(schemaRoute());
|
|
158
|
-
await app.register(settingsRoute({ writeRoot, legacyReadRoot, packageRoot, dryRun, userGlobalReadRoot: userGlobalRead }));
|
|
158
|
+
await app.register(settingsRoute({ writeRoot, legacyReadRoot, packageRoot, dryRun, userGlobalReadRoot: userGlobalRead, userGlobalWrite: mode === 'global' }));
|
|
159
159
|
await app.register(settingsChangesRoute({ writeRoot, userGlobalReadRoot: userGlobalRead, dryRun }));
|
|
160
160
|
await app.register(userMdRoute({ writeRoot, legacyReadRoot, dryRun, userGlobalReadRoot: userGlobalRead }));
|
|
161
161
|
await app.register(installRoute(opts.installRouteOptions ?? {}));
|
|
@@ -167,6 +167,7 @@ export async function createApp(opts) {
|
|
|
167
167
|
dryRun,
|
|
168
168
|
userGlobalReadRoot: userGlobalRead,
|
|
169
169
|
extendedSteps: opts.extendedSteps === true,
|
|
170
|
+
userGlobalWrite: mode === 'global',
|
|
170
171
|
...(opts.initialStep !== undefined ? { initialStep: opts.initialStep } : {}),
|
|
171
172
|
...(opts.wizardMode !== undefined ? { wizardMode: opts.wizardMode } : {}),
|
|
172
173
|
}));
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The settings route's handling of the three `git.*` keys.
|
|
3
|
+
*
|
|
4
|
+
* In global mode the route writes the user-global file, and `load_agent_settings`
|
|
5
|
+
* discards `git.*` keys from that file, so a value saved there has no effect in
|
|
6
|
+
* any repository. The form is not offered those keys, and a non-default value is
|
|
7
|
+
* refused with the place a team declares them instead (ADR-283). A template
|
|
8
|
+
* default is accepted: the form round-trips it, and `upgrade` inserts it too.
|
|
9
|
+
*
|
|
10
|
+
* In every mode a value goes through the same check `git:convention show` and
|
|
11
|
+
* `settings:check` run, so a pattern that would reach a shell is refused here as
|
|
12
|
+
* well.
|
|
13
|
+
*/
|
|
14
|
+
import { promises as fs } from 'node:fs';
|
|
15
|
+
import { join } from 'node:path';
|
|
16
|
+
import { parseYaml } from './io/yamlIO.js';
|
|
17
|
+
import { GIT_CONVENTION_KEYS, invalidReason } from '../scripts/_lib/git_convention.js';
|
|
18
|
+
export const WITHHELD_GIT_KEYS = GIT_CONVENTION_KEYS.map((k) => `git.${k}`);
|
|
19
|
+
export const WITHHELD_REASON = 'This form writes your user-global settings file, which does not carry git.* keys. ' +
|
|
20
|
+
'A team declares them in .git-convention.yml at the repository root; one checkout can set them in its project settings file.';
|
|
21
|
+
function _gitSection(values) {
|
|
22
|
+
const git = values['git'];
|
|
23
|
+
return git !== null && typeof git === 'object' && !Array.isArray(git) ? git : null;
|
|
24
|
+
}
|
|
25
|
+
/** The values and the JSON schema with the `git` section removed. */
|
|
26
|
+
export function withholdGitKeys(values, schema) {
|
|
27
|
+
const { git: _git, ...rest } = values;
|
|
28
|
+
const properties = { ...(schema.properties ?? {}) };
|
|
29
|
+
delete properties['git'];
|
|
30
|
+
const next = { ...schema, properties };
|
|
31
|
+
if (Array.isArray(schema.required))
|
|
32
|
+
next.required = schema.required.filter((k) => k !== 'git');
|
|
33
|
+
return { values: rest, schema: next };
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Field issues for the `git.*` values of a write. `defaults` is the template's
|
|
37
|
+
* `git` section; `userGlobal` is true when the write lands in the user-global file.
|
|
38
|
+
*/
|
|
39
|
+
export function gitKeyWriteIssues(values, defaults, userGlobal) {
|
|
40
|
+
const git = _gitSection(values);
|
|
41
|
+
if (git === null)
|
|
42
|
+
return [];
|
|
43
|
+
const fallback = _gitSection(defaults) ?? {};
|
|
44
|
+
const issues = [];
|
|
45
|
+
for (const key of GIT_CONVENTION_KEYS) {
|
|
46
|
+
const value = git[key];
|
|
47
|
+
if (typeof value !== 'string')
|
|
48
|
+
continue;
|
|
49
|
+
const why = invalidReason(key, value);
|
|
50
|
+
if (why !== null) {
|
|
51
|
+
issues.push({ path: `git.${key}`, message: why });
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
const def = fallback[key];
|
|
55
|
+
if (userGlobal && !(typeof def === 'string' && def === value)) {
|
|
56
|
+
issues.push({ path: `git.${key}`, message: WITHHELD_REASON });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return issues;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The write candidate with the `git` section the file already holds. In global
|
|
63
|
+
* mode the form never showed that section, and the schema's `.default({})`
|
|
64
|
+
* fills template defaults into whatever arrives, so a value the user-global
|
|
65
|
+
* file carries would otherwise read as a change the user made: a guarded-key
|
|
66
|
+
* confirmation for a field they never saw, then a silent reset.
|
|
67
|
+
*
|
|
68
|
+
* `fileValues` is that file alone, never the merged view: the merge carries
|
|
69
|
+
* the template defaults and any project layer, and copying a project value
|
|
70
|
+
* here would write it into the user-global file without passing the gate.
|
|
71
|
+
*/
|
|
72
|
+
export function keepWithheldGit(candidate, fileValues) {
|
|
73
|
+
const { git: _sent, ...rest } = candidate;
|
|
74
|
+
return 'git' in fileValues ? { ...rest, git: fileValues['git'] } : rest;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The before-side of a global-mode diff: the merged view with its `git` section
|
|
78
|
+
* swapped for the file's own, or dropped when the file has none. The candidate
|
|
79
|
+
* from `keepWithheldGit` carries exactly that section, so comparing it against
|
|
80
|
+
* the merged view would report template defaults and project values as edits
|
|
81
|
+
* to a section the form never showed.
|
|
82
|
+
*/
|
|
83
|
+
export function gitDiffBase(merged, fileValues) {
|
|
84
|
+
return keepWithheldGit(merged, fileValues);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* The wizard's finish write through the same gate: a 422 is sent and true
|
|
88
|
+
* returned when a `git.*` value is refused. The template's `git` section holds
|
|
89
|
+
* no install placeholder, so it is parsed without substitution.
|
|
90
|
+
*/
|
|
91
|
+
export async function refuseGitKeys(reply, values, packageRoot, userGlobal) {
|
|
92
|
+
let defaults = {};
|
|
93
|
+
try {
|
|
94
|
+
defaults = parseYaml(await fs.readFile(join(packageRoot, 'src', 'config', 'agent-settings.template.yml'), 'utf8'));
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
defaults = {};
|
|
98
|
+
}
|
|
99
|
+
const issues = gitKeyWriteIssues(values, defaults, userGlobal);
|
|
100
|
+
if (issues.length === 0)
|
|
101
|
+
return false;
|
|
102
|
+
await reply.code(422).send({ error: { code: 'VALIDATION', message: 'invalid settings', fields: issues } });
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=gitKeysGate.js.map
|
|
@@ -1,12 +1,36 @@
|
|
|
1
1
|
import { promises as fs } from 'node:fs';
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
|
+
import { isDeepStrictEqual } from 'node:util';
|
|
3
4
|
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
4
5
|
import { settingsSchema } from '../schemas/settings.js';
|
|
5
|
-
import { parseYaml, mergeIntoTemplate, diffValues, deepMerge, TEMPLATE_PLACEHOLDER_DEFAULTS } from '../io/yamlIO.js';
|
|
6
|
+
import { parseYaml, mergeIntoTemplate, diffValues, deepMerge, renderSparseSettings, substituteTemplatePlaceholders, TEMPLATE_PLACEHOLDER_DEFAULTS } from '../io/yamlIO.js';
|
|
7
|
+
import { sparseSettingsValues } from './wizard.js';
|
|
6
8
|
import { writeAtomic } from '../io/atomicWrite.js';
|
|
9
|
+
import { WITHHELD_GIT_KEYS, WITHHELD_REASON, gitDiffBase, gitKeyWriteIssues, keepWithheldGit, withholdGitKeys } from '../gitKeysGate.js';
|
|
7
10
|
import { sharedWriteTarget, resolveThroughSymlinks } from '../io/sharedWriteCheck.js';
|
|
8
11
|
import { PACKAGE_ROOT } from '../../cli/paths.js';
|
|
9
12
|
import { buildSettingsClassIndex, guardedChangedKeys, parseSettingsClassRows } from '../../shared/settingsClasses.js';
|
|
13
|
+
/**
|
|
14
|
+
* A fresh user-global file records decisions, not the defaults: the form posts
|
|
15
|
+
* every value, and a copy of the template's would freeze each default at today's
|
|
16
|
+
* value. Only leaves that differ from the template are kept, over the carve-outs.
|
|
17
|
+
*/
|
|
18
|
+
async function freshUserGlobalValues(packageRoot, candidate) {
|
|
19
|
+
const templateBody = await fs.readFile(join(packageRoot, 'src', 'config', 'agent-settings.template.yml'), 'utf8');
|
|
20
|
+
const template = parseYaml(substituteTemplatePlaceholders(templateBody));
|
|
21
|
+
const decided = (value, dflt) => {
|
|
22
|
+
if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
|
|
23
|
+
const base = dflt !== null && typeof dflt === 'object' && !Array.isArray(dflt) ? dflt : {};
|
|
24
|
+
const kept = Object.entries(value)
|
|
25
|
+
.map(([k, v]) => [k, decided(v, base[k])])
|
|
26
|
+
.filter(([, v]) => v !== undefined);
|
|
27
|
+
return kept.length === 0 ? undefined : Object.fromEntries(kept);
|
|
28
|
+
}
|
|
29
|
+
return isDeepStrictEqual(value, dflt) ? undefined : value;
|
|
30
|
+
};
|
|
31
|
+
const own = (decided(candidate, template) ?? {});
|
|
32
|
+
return deepMerge(sparseSettingsValues(templateBody, {}), own);
|
|
33
|
+
}
|
|
10
34
|
/** Sidecar written by `settings:set`, keyed by dotted path. */
|
|
11
35
|
const PROVENANCE_RELATIVE = join('settings', '.agent-settings.provenance.json');
|
|
12
36
|
/**
|
|
@@ -217,6 +241,8 @@ async function readLayeredSettings(packageRoot, writeRoot, legacyReadRoot, userG
|
|
|
217
241
|
])],
|
|
218
242
|
project: projectLayer !== null ? dottedLeafPaths(projectLayer.values) : [],
|
|
219
243
|
},
|
|
244
|
+
writeLayer: globalLayer?.values ?? null,
|
|
245
|
+
writeLayerRaw: globalLayer?.raw ?? null,
|
|
220
246
|
};
|
|
221
247
|
}
|
|
222
248
|
function zodIssuesToFields(issues) {
|
|
@@ -234,6 +260,10 @@ export function settingsRoute(opts) {
|
|
|
234
260
|
app.get('/api/v1/settings', async (_request, reply) => {
|
|
235
261
|
try {
|
|
236
262
|
const state = await readLayeredSettings(packageRoot, opts.writeRoot, opts.legacyReadRoot, opts.userGlobalReadRoot);
|
|
263
|
+
const offered = opts.userGlobalWrite === true
|
|
264
|
+
? withholdGitKeys(state.values, SETTINGS_JSON_SCHEMA)
|
|
265
|
+
: { values: state.values, schema: SETTINGS_JSON_SCHEMA };
|
|
266
|
+
const withheld = opts.userGlobalWrite === true ? { withheld: { keys: WITHHELD_GIT_KEYS, reason: WITHHELD_REASON } } : {};
|
|
237
267
|
if (!state.hasRealFile) {
|
|
238
268
|
// No on-disk file yet — the wizard creates it. Surface the
|
|
239
269
|
// template-defaults values + schema + path in the body so
|
|
@@ -242,19 +272,21 @@ export function settingsRoute(opts) {
|
|
|
242
272
|
// `{}` and the user's first save fails schema validation).
|
|
243
273
|
await reply.code(404).send({
|
|
244
274
|
error: { code: 'NOT_FOUND', message: 'settings file missing' },
|
|
245
|
-
defaults:
|
|
275
|
+
defaults: offered.values,
|
|
246
276
|
lastModified: 0,
|
|
247
277
|
path: SETTINGS_RELATIVE,
|
|
248
|
-
schema:
|
|
278
|
+
schema: offered.schema,
|
|
279
|
+
...withheld,
|
|
249
280
|
});
|
|
250
281
|
return reply;
|
|
251
282
|
}
|
|
252
283
|
const legacyHints = extractLegacyHints(state.values);
|
|
253
284
|
return {
|
|
254
|
-
values:
|
|
285
|
+
values: offered.values,
|
|
255
286
|
lastModified: state.mtimeMs,
|
|
256
287
|
path: SETTINGS_RELATIVE,
|
|
257
|
-
schema:
|
|
288
|
+
schema: offered.schema,
|
|
289
|
+
...withheld,
|
|
258
290
|
legacyHints,
|
|
259
291
|
// Phase 5.4 — per-layer provenance for the settings hub's
|
|
260
292
|
// "set globally / in this project" source badges.
|
|
@@ -293,7 +325,13 @@ export function settingsRoute(opts) {
|
|
|
293
325
|
});
|
|
294
326
|
return reply;
|
|
295
327
|
}
|
|
296
|
-
const
|
|
328
|
+
const candidate = opts.userGlobalWrite === true
|
|
329
|
+
? keepWithheldGit(parsed.data, current.writeLayer ?? {})
|
|
330
|
+
: parsed.data;
|
|
331
|
+
const before = opts.userGlobalWrite === true
|
|
332
|
+
? gitDiffBase(current.values, current.writeLayer ?? {})
|
|
333
|
+
: current.values;
|
|
334
|
+
const changes = diffValues(before, candidate);
|
|
297
335
|
return { changes };
|
|
298
336
|
});
|
|
299
337
|
app.put('/api/v1/settings', async (request, reply) => {
|
|
@@ -310,6 +348,11 @@ export function settingsRoute(opts) {
|
|
|
310
348
|
});
|
|
311
349
|
return reply;
|
|
312
350
|
}
|
|
351
|
+
const gitIssues = gitKeyWriteIssues(parsed.data, await loadDefaultSettings(packageRoot), opts.userGlobalWrite === true);
|
|
352
|
+
if (gitIssues.length > 0) {
|
|
353
|
+
await reply.code(422).send({ error: { code: 'VALIDATION', message: 'invalid settings', fields: gitIssues } });
|
|
354
|
+
return reply;
|
|
355
|
+
}
|
|
313
356
|
const current = await readLayeredSettings(packageRoot, opts.writeRoot, opts.legacyReadRoot, opts.userGlobalReadRoot);
|
|
314
357
|
if (!current.hasRealFile) {
|
|
315
358
|
await reply.code(404).send({ error: { code: 'NOT_FOUND', message: 'settings file missing' } });
|
|
@@ -322,8 +365,22 @@ export function settingsRoute(opts) {
|
|
|
322
365
|
});
|
|
323
366
|
return reply;
|
|
324
367
|
}
|
|
368
|
+
const candidate = opts.userGlobalWrite === true
|
|
369
|
+
? keepWithheldGit(parsed.data, current.writeLayer ?? {})
|
|
370
|
+
: parsed.data;
|
|
325
371
|
try {
|
|
326
|
-
|
|
372
|
+
// In global mode the scaffold may be the project file, whose
|
|
373
|
+
// git section the candidate does not overwrite; the file being
|
|
374
|
+
// written is the base, so a section it lacks stays absent. An
|
|
375
|
+
// absent user-global file is rendered the way the wizard renders
|
|
376
|
+
// a fresh one: merging into an empty body appends flat dotted
|
|
377
|
+
// keys, which no reader resolves.
|
|
378
|
+
const ownRaw = current.writeLayerRaw;
|
|
379
|
+
const merged = opts.userGlobalWrite !== true
|
|
380
|
+
? mergeIntoTemplate(current.raw, candidate)
|
|
381
|
+
: ownRaw !== null
|
|
382
|
+
? mergeIntoTemplate(ownRaw, candidate)
|
|
383
|
+
: renderSparseSettings(await freshUserGlobalValues(packageRoot, candidate));
|
|
327
384
|
if (opts.dryRun === true) {
|
|
328
385
|
// No disk write, no Last-Modified bump — surface the
|
|
329
386
|
// rendered body so the maintainer sees what a real
|
|
@@ -352,7 +409,9 @@ export function settingsRoute(opts) {
|
|
|
352
409
|
// this point and is not gated — it writes nothing.
|
|
353
410
|
if (body.confirmGuarded !== true) {
|
|
354
411
|
const classes = await readClassIndex(packageRoot);
|
|
355
|
-
const guarded = guardedChangedKeys(classes, diffValues(
|
|
412
|
+
const guarded = guardedChangedKeys(classes, diffValues(opts.userGlobalWrite === true
|
|
413
|
+
? gitDiffBase(current.values, current.writeLayer ?? {})
|
|
414
|
+
: current.values, candidate));
|
|
356
415
|
if (guarded.length > 0) {
|
|
357
416
|
await reply.code(409).send({
|
|
358
417
|
error: 'guarded-keys',
|
|
@@ -19,6 +19,7 @@ import { detectAgentSwitch, AGENT_SWITCH_INSTALL_COMMAND, AGENT_SWITCH_REPO } fr
|
|
|
19
19
|
import { readDismissedRecommendations, dismissRecommendation } from '../../install/wizardDismissals.js';
|
|
20
20
|
import { installCompleted, installDoneSummary } from '../../install/preserve.js';
|
|
21
21
|
import { apiOnQuotaView } from '../../scripts/ai_council/transport_resolver.js';
|
|
22
|
+
import { refuseGitKeys } from '../gitKeysGate.js';
|
|
22
23
|
const STATE_REL = join('state', 'wizard-state.json');
|
|
23
24
|
const SETTINGS_REL = join('settings', '.agent-settings.yml');
|
|
24
25
|
const USER_IDENTITY_REL = join('settings', '.agent-user.yml');
|
|
@@ -1198,6 +1199,9 @@ export function wizardRoute(opts) {
|
|
|
1198
1199
|
const effectiveWriteRoot = scope === 'project' && projectScopeRoot !== null
|
|
1199
1200
|
? projectScopeRoot
|
|
1200
1201
|
: opts.writeRoot;
|
|
1202
|
+
const userGlobalTarget = opts.userGlobalWrite === true && effectiveWriteRoot === opts.writeRoot;
|
|
1203
|
+
if (await refuseGitKeys(reply, settingsParsed.data, opts.packageRoot, userGlobalTarget))
|
|
1204
|
+
return reply;
|
|
1201
1205
|
try {
|
|
1202
1206
|
const template = await readTemplate(opts.packageRoot);
|
|
1203
1207
|
const answers = settingsParsed.data;
|