@event4u/agent-config 16.3.0 → 16.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.augment-plugin/marketplace.json +3 -3
- package/.augment-plugin/plugin.json +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +251 -0
- package/README.md +2 -2
- package/agents/templates/.ai-council.yml.example +26 -8
- package/dist/agent-src/commands/analyze/inbox.md +10 -7
- package/dist/agent-src/commands/bug/investigate.md +1 -1
- package/dist/agent-src/commands/commit/in-chunks.md +40 -31
- package/dist/agent-src/commands/commit.md +72 -33
- package/dist/agent-src/commands/condense.md +2 -8
- package/dist/agent-src/commands/council/debate.md +11 -7
- package/dist/agent-src/commands/council/default.md +10 -9
- package/dist/agent-src/commands/council.md +1 -1
- package/dist/agent-src/commands/estimate-ticket.md +1 -1
- package/dist/agent-src/commands/feature/explore.md +3 -3
- package/dist/agent-src/commands/feature/plan.md +1 -1
- package/dist/agent-src/commands/fix/ci.md +17 -3
- package/dist/agent-src/commands/fix/commit-messages.md +48 -23
- package/dist/agent-src/commands/fix/pr-comments.md +3 -6
- package/dist/agent-src/commands/implement-ticket.md +3 -3
- package/dist/agent-src/commands/memory/add.md +4 -16
- package/dist/agent-src/commands/memory/load.md +5 -6
- package/dist/agent-src/commands/memory/promote.md +3 -16
- package/dist/agent-src/commands/mission/upgrade.md +3 -2
- package/dist/agent-src/commands/optimize/agents-dir.md +2 -2
- package/dist/agent-src/commands/optimize/deep.md +4 -2
- package/dist/agent-src/commands/optimize/rtk.md +4 -26
- package/dist/agent-src/commands/pr/create/description-only.md +18 -15
- package/dist/agent-src/commands/pr/create.md +42 -34
- package/dist/agent-src/commands/pr/merge.md +136 -9
- package/dist/agent-src/commands/prepare-for-review.md +13 -11
- package/dist/agent-src/commands/project/analyze.md +7 -35
- package/dist/agent-src/commands/refine-ticket.md +1 -1
- package/dist/agent-src/commands/review/changes.md +14 -19
- package/dist/agent-src/commands/roadmap/next.md +10 -1
- package/dist/agent-src/commands/roadmap/process-full.md +52 -38
- package/dist/agent-src/commands/roadmap/resolve-blockers.md +64 -14
- package/dist/agent-src/commands/worktree/create.md +7 -3
- package/dist/agent-src/commands/worktree/verify.md +2 -1
- package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +5 -3
- package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +7 -9
- package/dist/agent-src/contexts/contracts/command-suggestion-flow.md +8 -6
- package/dist/agent-src/contexts/contracts/frugality-charter.md +8 -5
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +1 -1
- package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +0 -1
- package/dist/agent-src/contexts/execution/evidence-discipline.md +2 -2
- package/dist/agent-src/contexts/execution/non-interactive-contract.md +5 -8
- package/dist/agent-src/contexts/execution/rdp-gate.md +4 -4
- package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +9 -8
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +67 -52
- package/dist/agent-src/contexts/execution/subagent-routing.md +8 -8
- package/dist/agent-src/contexts/execution/subagent-steering.md +6 -4
- package/dist/agent-src/contexts/execution/terminal-states.md +2 -2
- package/dist/agent-src/contexts/execution/toolchain-resolver.md +4 -10
- package/dist/agent-src/contexts/subagent-configuration.md +1 -1
- package/dist/agent-src/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
- package/dist/agent-src/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
- package/dist/agent-src/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
- package/dist/agent-src/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
- package/dist/agent-src/guidelines/agent-infra/layered-settings.md +13 -1
- package/dist/agent-src/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
- package/dist/agent-src/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
- package/dist/agent-src/guidelines/agent-infra/size-and-scope.md +36 -0
- package/dist/agent-src/guidelines/php/git.md +15 -2
- package/dist/agent-src/rules/active-remediation.md +0 -1
- package/dist/agent-src/rules/analysis-skill-routing.md +0 -1
- package/dist/agent-src/rules/architecture.md +0 -1
- package/dist/agent-src/rules/artifact-drafting-protocol.md +0 -1
- package/dist/agent-src/rules/artifact-engagement-recording.md +0 -1
- package/dist/agent-src/rules/augment-edit-discipline.md +0 -1
- package/dist/agent-src/rules/autonomous-execution.md +0 -1
- package/dist/agent-src/rules/brand-consistency.md +0 -1
- package/dist/agent-src/rules/brand-source-of-truth.md +0 -1
- package/dist/agent-src/rules/broken-access-control.md +0 -1
- package/dist/agent-src/rules/cli-output-handling.md +0 -1
- package/dist/agent-src/rules/code-comment-discipline.md +0 -1
- package/dist/agent-src/rules/code-provenance.md +0 -1
- package/dist/agent-src/rules/command-suggestion-policy.md +0 -1
- package/dist/agent-src/rules/commit-conventions.md +1 -2
- package/dist/agent-src/rules/communication-through-line.md +1 -2
- package/dist/agent-src/rules/content-quoting-floor.md +1 -2
- package/dist/agent-src/rules/context-hygiene.md +5 -5
- package/dist/agent-src/rules/copilot-routing.md +1 -2
- package/dist/agent-src/rules/council-availability.md +4 -4
- package/dist/agent-src/rules/cross-source-consistency.md +4 -6
- package/dist/agent-src/rules/decision-revisit-gate.md +2 -3
- package/dist/agent-src/rules/delegation-policy.md +2 -3
- package/dist/agent-src/rules/design-fidelity.md +0 -1
- package/dist/agent-src/rules/design-review-after-ui-write.md +3 -3
- package/dist/agent-src/rules/devcontainer-routing.md +1 -2
- package/dist/agent-src/rules/doc-screenshot-hygiene.md +0 -1
- package/dist/agent-src/rules/docker-commands.md +0 -1
- package/dist/agent-src/rules/domain-adoption-policy.md +0 -1
- package/dist/agent-src/rules/domain-safety-disclaimer.md +0 -1
- package/dist/agent-src/rules/domain-safety-pii.md +0 -1
- package/dist/agent-src/rules/domain-safety-retention.md +0 -1
- package/dist/agent-src/rules/downstream-changes.md +0 -1
- package/dist/agent-src/rules/engineering-safety-floor.md +0 -1
- package/dist/agent-src/rules/external-code-graph-interop.md +0 -1
- package/dist/agent-src/rules/external-reference-deep-dive.md +0 -1
- package/dist/agent-src/rules/fast-path-marker-visibility.md +1 -2
- package/dist/agent-src/rules/finance-safety-floor.md +0 -1
- package/dist/agent-src/rules/fix-what-you-see.md +6 -32
- package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +0 -1
- package/dist/agent-src/rules/git-history-discipline.md +1 -2
- package/dist/agent-src/rules/guidelines.md +0 -1
- package/dist/agent-src/rules/history-discipline.md +0 -1
- package/dist/agent-src/rules/icon-consistency.md +0 -1
- package/dist/agent-src/rules/image-likeness-and-rights.md +0 -1
- package/dist/agent-src/rules/improve-before-implement.md +0 -1
- package/dist/agent-src/rules/invite-challenge.md +0 -1
- package/dist/agent-src/rules/laravel-routing.md +1 -2
- package/dist/agent-src/rules/laravel-translations.md +0 -1
- package/dist/agent-src/rules/legal-safety-floor.md +0 -1
- package/dist/agent-src/rules/lethal-trifecta-guard.md +0 -1
- package/dist/agent-src/rules/linked-projects-onboarding-gate.md +0 -1
- package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +0 -1
- package/dist/agent-src/rules/markdown-safe-codeblocks.md +0 -1
- package/dist/agent-src/rules/media-governance-routing.md +1 -2
- package/dist/agent-src/rules/media-sync-ground-truth.md +0 -1
- package/dist/agent-src/rules/minimal-safe-diff.md +0 -1
- package/dist/agent-src/rules/missing-skill-recovery.md +0 -1
- package/dist/agent-src/rules/missing-tool-handling.md +0 -1
- package/dist/agent-src/rules/model-recommendation.md +0 -1
- package/dist/agent-src/rules/neighbour-precedence.md +64 -0
- package/dist/agent-src/rules/no-attribution-footers.md +0 -1
- package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +0 -1
- package/dist/agent-src/rules/no-pr-progress-comments.md +0 -1
- package/dist/agent-src/rules/no-roadmap-references.md +0 -1
- package/dist/agent-src/rules/notes-first-reasoning.md +0 -1
- package/dist/agent-src/rules/onboarding-gate.md +0 -1
- package/dist/agent-src/rules/output-discipline.md +0 -1
- package/dist/agent-src/rules/package-ci-checks.md +0 -1
- package/dist/agent-src/rules/persona-governance.md +2 -3
- package/dist/agent-src/rules/php-coding.md +0 -1
- package/dist/agent-src/rules/prefer-enums-over-literals.md +0 -1
- package/dist/agent-src/rules/preservation-guard.md +0 -1
- package/dist/agent-src/rules/provider-lifecycle-discipline.md +2 -3
- package/dist/agent-src/rules/question-not-instruction.md +0 -1
- package/dist/agent-src/rules/reviewer-awareness.md +0 -1
- package/dist/agent-src/rules/roadmap-ci-steps-policy.md +0 -1
- package/dist/agent-src/rules/roadmap-progress-sync.md +3 -6
- package/dist/agent-src/rules/role-mode-adherence.md +0 -1
- package/dist/agent-src/rules/rule-type-governance.md +0 -1
- package/dist/agent-src/rules/runtime-safety.md +0 -1
- package/dist/agent-src/rules/scale-discipline.md +0 -1
- package/dist/agent-src/rules/secret-vcs-guard.md +0 -1
- package/dist/agent-src/rules/security-sensitive-stop.md +0 -1
- package/dist/agent-src/rules/self-repair-loop.md +0 -1
- package/dist/agent-src/rules/senior-engineering-discipline.md +0 -1
- package/dist/agent-src/rules/session-canary.md +0 -1
- package/dist/agent-src/rules/settings-ask-protocol.md +5 -6
- package/dist/agent-src/rules/size-enforcement.md +0 -1
- package/dist/agent-src/rules/skill-improvement-trigger.md +2 -3
- package/dist/agent-src/rules/skill-quality.md +0 -1
- package/dist/agent-src/rules/slash-command-routing-policy.md +0 -1
- package/dist/agent-src/rules/source-confidentiality.md +0 -1
- package/dist/agent-src/rules/source-discovery-gate.md +0 -1
- package/dist/agent-src/rules/source-of-truth.md +0 -1
- package/dist/agent-src/rules/spreadsheet-source-quality.md +1 -2
- package/dist/agent-src/rules/strategy-safety-floor.md +0 -1
- package/dist/agent-src/rules/symfony-routing.md +1 -2
- package/dist/agent-src/rules/think-before-action.md +0 -1
- package/dist/agent-src/rules/token-budget-discipline.md +12 -46
- package/dist/agent-src/rules/token-efficiency.md +0 -1
- package/dist/agent-src/rules/token-optimizer-maintenance.md +0 -1
- package/dist/agent-src/rules/tool-safety.md +0 -1
- package/dist/agent-src/rules/ui-audit-gate.md +1 -2
- package/dist/agent-src/rules/untrusted-input-defense.md +0 -1
- package/dist/agent-src/rules/upstream-proposal.md +0 -1
- package/dist/agent-src/rules/user-interaction.md +0 -1
- package/dist/agent-src/rules/user-interrupt-priority.md +0 -1
- package/dist/agent-src/scripts/gate_budget.ts +47 -23
- package/dist/agent-src/scripts/gate_execute.ts +12 -4
- package/dist/agent-src/skills/ai-council/SKILL.md +7 -4
- package/dist/agent-src/skills/ai-council/references/cost-and-redaction.md +21 -11
- package/dist/agent-src/skills/ai-council/references/procedure.md +12 -6
- package/dist/agent-src/skills/analysis-autonomous-mode/SKILL.md +1 -1
- package/dist/agent-src/skills/bug-analyzer/SKILL.md +1 -1
- package/dist/agent-src/skills/command-routing/SKILL.md +3 -4
- package/dist/agent-src/skills/conventional-commits-writing/SKILL.md +127 -139
- package/dist/agent-src/skills/corpus-grounding/ATTRIBUTION.md +39 -0
- package/dist/agent-src/skills/corpus-grounding/SKILL.md +8 -2
- package/dist/agent-src/skills/database/data/manifest.json +2 -2
- package/dist/agent-src/skills/database/data/query-tuning.csv +13 -13
- package/dist/agent-src/skills/design-system-capture/SKILL.md +0 -3
- package/dist/agent-src/skills/estimate-ticket/SKILL.md +1 -1
- package/dist/agent-src/skills/feature-planning/SKILL.md +1 -1
- package/dist/agent-src/skills/git-workflow/SKILL.md +44 -44
- package/dist/agent-src/skills/git-workflow/references/branch-update.md +312 -0
- package/dist/agent-src/skills/git-workflow/references/commit-subject.md +205 -0
- package/dist/agent-src/skills/jira-integration/SKILL.md +3 -3
- package/dist/agent-src/skills/merge-conflicts/SKILL.md +10 -4
- package/dist/agent-src/skills/po-discovery/SKILL.md +1 -1
- package/dist/agent-src/skills/refine-ticket/SKILL.md +4 -4
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +2 -2
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +4 -2
- package/dist/agent-src/skills/source-discovery/SKILL.md +1 -1
- package/dist/agent-src/skills/tailwind-engineer/SKILL.md +3 -1
- package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/using-git-worktrees/SKILL.md +1 -1
- package/dist/agent-src/skills/verify-repair-loop/SKILL.md +2 -2
- package/dist/agent-src/templates/AGENTS.md +1 -1
- package/dist/agent-src/templates/agent-settings.md +46 -129
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +3 -3
- package/dist/agent-src/templates/command.md +2 -2
- package/dist/agent-src/templates/roadmaps.md +6 -1
- package/dist/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
- package/dist/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
- package/dist/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
- package/dist/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
- package/dist/agent-src/templates/skill.md +1 -1
- package/dist/cli/registry.js +1 -0
- package/dist/cli-delegate/check_update_banner.js +195 -119
- package/dist/cli-delegate/{chunk-TRI6DQZ6.js → chunk-5GPULQBE.js} +60 -42
- package/dist/cli-delegate/{chunk-JQVYKIZA.js → chunk-6SRJTYJS.js} +33 -177
- package/dist/cli-delegate/chunk-6V5FMA3P.js +186 -0
- package/dist/cli-delegate/chunk-6YQC2HLF.js +415 -0
- package/dist/cli-delegate/{chunk-E4XIZDIB.js → chunk-7HKRE54K.js} +1 -64
- package/dist/cli-delegate/{chunk-NQ7WT43P.js → chunk-AED2VQGM.js} +65 -11
- package/dist/cli-delegate/{chunk-7HQ52DHU.js → chunk-AL3RZ22D.js} +1 -1
- package/dist/cli-delegate/{chunk-DBH4AHDK.js → chunk-ED7KCMLB.js} +9 -11
- package/dist/cli-delegate/{chunk-NXEILF2K.js → chunk-F3QDG2GT.js} +481 -72
- package/dist/cli-delegate/{chunk-CQWX336L.js → chunk-G5VVIZRC.js} +3 -3
- package/dist/cli-delegate/{chunk-JY2I2DXV.js → chunk-H76PHZBI.js} +137 -60
- package/dist/cli-delegate/chunk-IAYTIIQW.js +67 -0
- package/dist/cli-delegate/{chunk-LIYTLH6O.js → chunk-KXXWJTDO.js} +5 -10
- package/dist/cli-delegate/{chunk-T7L2QK3K.js → chunk-LQOCRFWT.js} +1 -1
- package/dist/cli-delegate/{chunk-S4YWNRKO.js → chunk-MDPPKQCQ.js} +34 -1
- package/dist/cli-delegate/{chunk-S4UMZNES.js → chunk-MSUL5NYP.js} +5 -5
- package/dist/cli-delegate/chunk-OAFSJBHH.js +272 -0
- package/dist/cli-delegate/{chunk-GKE7ZVFA.js → chunk-PWX7CKMD.js} +1 -1
- package/dist/cli-delegate/{chunk-NDJLNC6Q.js → chunk-T6BP34WI.js} +1 -0
- package/dist/cli-delegate/{chunk-RQNNW7IF.js → chunk-T7XSJSUQ.js} +433 -632
- package/dist/cli-delegate/{chunk-EEHDXSYD.js → chunk-WQWXGIWB.js} +12 -273
- package/dist/cli-delegate/{chunk-QLDHIPWR.js → chunk-XQTPXKFA.js} +1 -1
- package/dist/cli-delegate/cmd_analyze_session.js +223 -43
- package/dist/cli-delegate/cmd_brand_status.js +3 -2
- package/dist/cli-delegate/cmd_conformance.js +105 -35
- package/dist/cli-delegate/cmd_converge.js +3 -3
- package/dist/cli-delegate/cmd_doctor.js +15 -12
- package/dist/cli-delegate/cmd_doctor_neighbours.js +11 -4
- package/dist/cli-delegate/cmd_explain.js +43 -19
- package/dist/cli-delegate/cmd_export.js +10 -10
- package/dist/cli-delegate/cmd_git_convention.js +1851 -0
- package/dist/cli-delegate/cmd_handoff.js +40 -21
- package/dist/cli-delegate/cmd_mcp_available.js +3 -2
- package/dist/cli-delegate/cmd_migrate.js +3 -3
- package/dist/cli-delegate/cmd_packs_active.js +4 -3
- package/dist/cli-delegate/cmd_prune.js +10 -10
- package/dist/cli-delegate/cmd_route_audit.js +7 -7
- package/dist/cli-delegate/cmd_route_explain.js +5 -5
- package/dist/cli-delegate/cmd_session_recycle.js +9 -7
- package/dist/cli-delegate/cmd_settings_check.js +54 -7
- package/dist/cli-delegate/cmd_settings_get.js +18 -8
- package/dist/cli-delegate/cmd_settings_migrate.js +10 -10
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +10 -10
- package/dist/cli-delegate/cmd_uninstall.js +10 -10
- package/dist/cli-delegate/cmd_update.js +7 -7
- package/dist/cli-delegate/cmd_upgrade.js +7 -7
- package/dist/cli-delegate/cmd_validate.js +10 -10
- package/dist/cli-delegate/cmd_versions.js +5 -5
- package/dist/cli-delegate/gate_budget.js +1 -1
- package/dist/cli-delegate/gate_execute.js +2 -2
- package/dist/cli-delegate/roadmap_gates.js +2 -2
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +129 -90
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +3 -3
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +24 -9
- package/dist/discovery/trust-report.md +3 -3
- package/dist/discovery/workspaces.json +5 -4
- package/dist/hooks/dispatch.js +2151 -1820
- package/dist/hooks/dispatch.sha256 +1 -1
- package/dist/install/install.mjs +462 -431
- package/dist/install/installThinLayer.js +40 -12
- package/dist/install/installedRuleLinks.js +105 -19
- package/dist/mcp/awesome-mcp-servers.row.md +1 -1
- package/dist/mcp/mcp-cloudflare-catalogue.json +2 -2
- package/dist/mcp/registry-manifest.json +5 -5
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +2702 -1995
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/agent_settings.js +15 -120
- package/dist/scripts/_lib/compile_time_toggles.js +12 -21
- package/dist/scripts/_lib/git_convention.js +232 -0
- package/dist/scripts/_lib/global_deploy_inventory.js +730 -0
- package/dist/scripts/_lib/installed_layer.js +344 -18
- package/dist/scripts/_lib/package_root.js +68 -0
- package/dist/scripts/_lib/rule_law_section.js +1 -1
- package/dist/scripts/_lib/settings_removed_keys.js +168 -0
- package/dist/scripts/_lib/thin_rules.js +80 -3
- package/dist/server/app.js +2 -1
- package/dist/server/gitKeysGate.js +105 -0
- package/dist/server/routes/settings.js +67 -8
- package/dist/server/routes/wizard.js +4 -0
- package/dist/server/schemas/settings.js +23 -81
- package/dist/shared/skillRanking.js +30 -4
- package/dist/ui/assets/{index-Cwq4d0hX.js → index-C3djEJah.js} +2 -2
- package/dist/ui/index.html +1 -1
- package/docs/MIGRATION.md +72 -1
- package/docs/contracts/settings-classes.md +35 -65
- package/docs/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
- package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
- package/docs/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
- package/docs/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
- package/docs/guidelines/agent-infra/layered-settings.md +13 -1
- package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
- package/docs/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
- package/docs/guidelines/agent-infra/size-and-scope.md +36 -0
- package/docs/guidelines/php/git.md +15 -2
- package/package.json +1 -1
- package/src/agent-src/scripts/gate_budget.ts +47 -23
- package/src/agent-src/scripts/gate_execute.ts +12 -4
- package/src/agent-src/templates/AGENTS.md +1 -1
- package/src/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
- package/src/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
- package/src/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
- package/src/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
- package/src/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
- package/src/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
- package/src/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
- package/src/config/agent-settings.template.yml +79 -312
- package/src/config/agents-paths.yml +16 -0
- package/src/config/assurance-capability-registry.json +7 -3
- package/src/config/ci-local-parity.yml +3 -0
- package/src/config/continuity-surface.json +3 -3
- package/src/config/discovery/packs.yml +17 -1
- package/src/config/evaluator-budgets.json +19 -6
- package/src/config/gate-coverage.yml +65 -23
- package/src/config/gate-violation-baselines.json +53 -13
- package/src/config/gitignore-block.txt +19 -0
- package/src/config/hook-bundle-budget.json +1 -1
- package/src/config/release-gate-locality.yml +2 -1
- package/src/config/routing-coverage-seed.json +48 -6
- package/src/config/rule-law-ceilings.json +12 -6
- package/src/config/rule-obligations.json +833 -0
- package/src/install/installThinLayer.ts +76 -10
- package/src/install/installedRuleLinks.ts +105 -17
- package/src/scripts/_cli/cmd_analyze_session.ts +9 -15
- package/src/scripts/_cli/cmd_conformance.ts +13 -2
- package/src/scripts/_cli/cmd_doctor.ts +10 -10
- package/src/scripts/_cli/cmd_doctor_neighbours.ts +133 -0
- package/src/scripts/_cli/cmd_explain.ts +72 -14
- package/src/scripts/_cli/cmd_git_convention.ts +637 -0
- package/src/scripts/_cli/cmd_settings_check.ts +66 -8
- package/src/scripts/_cli/cmd_settings_get.ts +18 -3
- package/src/scripts/_cli/doctor_execution.ts +72 -1
- package/src/scripts/_dispatch.bash +37 -2
- package/src/scripts/_lib/agent_settings.ts +15 -124
- package/src/scripts/_lib/blocked_by_marker.ts +1 -1
- package/src/scripts/_lib/compile_time_toggles.ts +12 -21
- package/src/scripts/_lib/dispatch_import_closure.ts +163 -0
- package/src/scripts/_lib/git_base_ref.ts +92 -0
- package/src/scripts/_lib/git_convention.ts +291 -0
- package/src/scripts/_lib/git_convention_carrier.ts +389 -0
- package/src/scripts/_lib/git_convention_grammar.ts +246 -0
- package/src/scripts/_lib/git_convention_measure.ts +344 -0
- package/src/scripts/_lib/global_deploy_inventory.ts +74 -0
- package/src/scripts/_lib/graph_feeder_record.ts +236 -13
- package/src/scripts/_lib/installed_layer.ts +448 -23
- package/src/scripts/_lib/knowledge_global.ts +14 -1
- package/src/scripts/_lib/module_reach.ts +456 -0
- package/src/scripts/_lib/neighbour_contradictions.ts +236 -0
- package/src/scripts/_lib/neighbour_tool_use.ts +8 -10
- package/src/scripts/_lib/ratification_artifact.ts +220 -1
- package/src/scripts/_lib/ratification_subject.ts +92 -0
- package/src/scripts/_lib/release_findings_ingest.ts +15 -7
- package/src/scripts/_lib/release_highlights.ts +5 -0
- package/src/scripts/_lib/rule_law_section.ts +1 -1
- package/src/scripts/_lib/rule_obligations.ts +205 -0
- package/src/scripts/_lib/self_repair.ts +1 -1
- package/src/scripts/_lib/settings_removed_keys.ts +173 -0
- package/src/scripts/_lib/test_red_state.ts +5 -0
- package/src/scripts/_lib/thin_rules.ts +83 -3
- package/src/scripts/_lib/touched_file_quality.ts +142 -6
- package/src/scripts/_lib/worker_budget.ts +1 -1
- package/src/scripts/adr/regenerate_index.ts +16 -1
- package/src/scripts/ai_council/config.ts +7 -7
- package/src/scripts/ai_council/modification_review.ts +100 -0
- package/src/scripts/ai_council/modification_review_questions.ts +90 -0
- package/src/scripts/ai_council/orchestrator.ts +5 -5
- package/src/scripts/ai_council/spend_gate.ts +18 -7
- package/src/scripts/ai_team/config.ts +11 -16
- package/src/scripts/audit_user_type_axis.ts +20 -8
- package/src/scripts/bench_ab_clone.ts +1 -2
- package/src/scripts/bench_concern_spawn_path.ts +129 -0
- package/src/scripts/bench_graph_feeder_latency.ts +584 -0
- package/src/scripts/check_agent_artifact_location.ts +36 -0
- package/src/scripts/check_branch_freshness.ts +147 -24
- package/src/scripts/check_enforcement_coverage.ts +130 -0
- package/src/scripts/check_evaluator_budgets.ts +4 -0
- package/src/scripts/check_finding_dispositions.ts +88 -25
- package/src/scripts/check_gate_coverage.ts +4 -3
- package/src/scripts/check_gate_reachability.ts +48 -1
- package/src/scripts/check_generator_sync.ts +48 -0
- package/src/scripts/check_hook_bundle_composition.ts +107 -0
- package/src/scripts/check_kernel_edit_ratified.ts +86 -6
- package/src/scripts/check_pack_size.ts +1 -1
- package/src/scripts/check_release_manifest_content.ts +189 -0
- package/src/scripts/check_standing_rule_delivery.ts +96 -0
- package/src/scripts/check_suppression_hygiene.ts +2 -5
- package/src/scripts/ci_settle.ts +42 -5
- package/src/scripts/classify_merge_risk.ts +320 -0
- package/src/scripts/closure_scan.ts +91 -1
- package/src/scripts/command_suggester/settings.ts +8 -108
- package/src/scripts/command_suggester/types.ts +4 -5
- package/src/scripts/consumer_matrix.ts +102 -0
- package/src/scripts/context_hygiene_hook.ts +13 -23
- package/src/scripts/cost/preflight.mjs +12 -1
- package/src/scripts/council_cli.ts +7 -7
- package/src/scripts/dispatch_r2_reviewer.ts +24 -11
- package/src/scripts/explain_run.ts +8 -13
- package/src/scripts/generate_git_convention_grammar.ts +127 -0
- package/src/scripts/generate_host_cost_table.ts +20 -3
- package/src/scripts/handoff_context_hook.ts +86 -37
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +25 -6
- package/src/scripts/hooks/block_config_weakening.ts +48 -5
- package/src/scripts/hooks/block_plumbing_writes.ts +8 -4
- package/src/scripts/hooks/concern_registry.ts +2 -0
- package/src/scripts/hooks/delegation_nudge_hook.ts +2 -3
- package/src/scripts/hooks/evidence_independence.ts +12 -4
- package/src/scripts/hooks/mcp_usage_observation_hook.ts +121 -0
- package/src/scripts/hooks/push_settle_hook.ts +4 -3
- package/src/scripts/hooks/rule_inject_hook.ts +44 -3
- package/src/scripts/hooks/state_io.ts +8 -4
- package/src/scripts/hooks/telemetry_usage_hook.ts +7 -46
- package/src/scripts/hooks/turn_end_gate_hook.ts +1 -0
- package/src/scripts/install-hooks.sh +42 -14
- package/src/scripts/install.ts +7 -31
- package/src/scripts/lint_blocker_citations.ts +198 -0
- package/src/scripts/lint_evidence_artifacts.ts +9 -0
- package/src/scripts/lint_hook_concern_budget.ts +10 -21
- package/src/scripts/lint_pack_boundaries.ts +406 -28
- package/src/scripts/lint_roadmap_blockers.ts +282 -29
- package/src/scripts/lint_roadmap_complexity.ts +4 -2
- package/src/scripts/lint_rule_law_section.ts +151 -21
- package/src/scripts/lint_rule_skill_pack_reach.ts +17 -0
- package/src/scripts/lint_settings_classes.ts +1 -1
- package/src/scripts/lint_ticked_unmet_criteria.ts +165 -0
- package/src/scripts/lint_workflow_security.ts +12 -1
- package/src/scripts/measure_skill_ranker_baseline.ts +5 -0
- package/src/scripts/model_rule_injection.ts +3 -3
- package/src/scripts/onboarding_gate_hook.ts +7 -6
- package/src/scripts/print_required_checks.ts +15 -3
- package/src/scripts/probe_host_compliance.ts +33 -5
- package/src/scripts/probe_turnaround.ts +183 -3
- package/src/scripts/ratification_header.ts +77 -0
- package/src/scripts/refusal_envelope.ts +138 -0
- package/src/scripts/release_publication.ts +29 -3
- package/src/scripts/report_dispatch_import_closure.ts +76 -0
- package/src/scripts/report_installed_rule_links.ts +118 -1
- package/src/scripts/report_module_reach.ts +212 -0
- package/src/scripts/report_obligation_mechanism.ts +16 -18
- package/src/scripts/report_parked_blockers.ts +222 -0
- package/src/scripts/report_required_checks_drift.ts +196 -0
- package/src/scripts/report_skill_ranker_confusion.ts +103 -2
- package/src/scripts/report_standing_payload_by_host.ts +1 -1
- package/src/scripts/routing_doctor.ts +2 -2
- package/src/scripts/schemas/agent-settings.schema.json +17 -31
- package/src/scripts/schemas/command.schema.json +1 -1
- package/src/scripts/schemas/skill.schema.json +1 -1
- package/src/scripts/self_review_gate.ts +39 -2
- package/src/scripts/skill_tools/score_skill_relevance.ts +28 -19
- package/src/scripts/sync_pr_branch.ts +403 -132
- package/src/scripts/trigger_eval_grandfather.json +0 -16
- package/src/server/schemas/settings.ts +33 -177
- package/src/shared/skillRanking.ts +53 -4
- package/dist/cli-delegate/chunk-NYX3L2PZ.js +0 -99
- package/src/scripts/_lib/config_chain.ts +0 -477
- package/src/scripts/_lib/conformance_report.ts +0 -403
- package/src/scripts/_lib/eval_discrimination.ts +0 -95
- package/src/scripts/_lib/evaluator_promotion.ts +0 -225
- package/src/scripts/_lib/file_slicer.ts +0 -117
- package/src/scripts/_lib/legacy_boundary_map.ts +0 -228
- package/src/scripts/_lib/minimality_tiebreak.ts +0 -168
- package/src/scripts/_lib/overbuild_lens_contract.ts +0 -196
- package/src/scripts/_lib/role_split.ts +0 -338
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The registry of DELETED settings keys, and the once-per-run notice a leftover
|
|
3
|
+
* value gets. Extracted from `agent_settings.ts`, which sits at the 1500-line
|
|
4
|
+
* source ceiling — every retirement batch adds entries here, and here they cost
|
|
5
|
+
* no ratchet. `agent_settings.ts` re-exports `REMOVED_KEYS` so existing
|
|
6
|
+
* importers (the loader, `lint_settings_classes`) are unchanged.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
type SettingsDict = Record<string, unknown>;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Settings keys this package has DELETED. A leftover value from an older
|
|
13
|
+
* install is ignored — never applied by any reader — and surfaced with ONE
|
|
14
|
+
* deprecation line per key per process run (stderr; the exit code never
|
|
15
|
+
* changes).
|
|
16
|
+
*
|
|
17
|
+
* The map carries a per-key REASON rather than one shared sentence, because
|
|
18
|
+
* the list now spans more than one deletion doctrine and a single blanket
|
|
19
|
+
* phrase would mis-attribute every future entry. A reader who hits the line
|
|
20
|
+
* should learn why the key went, not just that it did.
|
|
21
|
+
*
|
|
22
|
+
* `subagents.*` — the always-on-orchestration doctrine
|
|
23
|
+
* (road-to-always-on-orchestration Phase 1): the layer has no per-layer
|
|
24
|
+
* on/off setting any more. `ai_team.enabled` joined in Step 1.3 — the
|
|
25
|
+
* `/team` family's availability is a codex-CLI/auth FACT
|
|
26
|
+
* (`src/scripts/ai_team/availability.ts`), not a flag; the `ai_team` config
|
|
27
|
+
* loader (`src/scripts/ai_team/config.ts`) separately accepts a leftover
|
|
28
|
+
* `enabled` key without failing closed, so this warning is the only surfaced
|
|
29
|
+
* signal of that deletion.
|
|
30
|
+
*
|
|
31
|
+
* `hooks.turn_end_gate.*` — the turn-end gate is always armed (2026-08-12).
|
|
32
|
+
* A default-off safety gate cannot soak, so the switch protecting the soak
|
|
33
|
+
* made the soak impossible; whether the gate fires is now decided by each
|
|
34
|
+
* detector's own trigger conditions. See `turn_end_gate_hook.ts` § "Always
|
|
35
|
+
* armed".
|
|
36
|
+
*
|
|
37
|
+
* The five `derivable` leaves below (2026-08-12, road-to-zero-settings Phase
|
|
38
|
+
* 2.1) are a different case from every entry above them, and the difference is
|
|
39
|
+
* the whole safety argument: no code path ever *consulted* them. Each appeared
|
|
40
|
+
* in the template, the schema and the reference page, and several in the setup
|
|
41
|
+
* wizard, while the decision they looked like they governed was taken
|
|
42
|
+
* elsewhere. A key nothing reads cannot change a default by leaving — so this
|
|
43
|
+
* is the one deletion batch that needs no replacement mechanism, only the
|
|
44
|
+
* per-key statement of what already decides.
|
|
45
|
+
*
|
|
46
|
+
* A sixth unread key, `screenshots.data_bearing_gate`, was found in the same
|
|
47
|
+
* pass and deliberately NOT deleted — it is `consent`, and the open question is
|
|
48
|
+
* whether the repair is to build its missing reader or to delete a promise a
|
|
49
|
+
* Hard Floor can never honour. See `settings-classes.md` § The six unread keys.
|
|
50
|
+
*
|
|
51
|
+
* `worktrees.mode` (2026-08-13, ADR-229) is a third doctrine again: not
|
|
52
|
+
* always-on, not unread. It WAS read, and the reader honoured all three values —
|
|
53
|
+
* the deletion says the decision was never the agent's to make. `ask` bought a
|
|
54
|
+
* round trip per spawn, `on` let the agent start parallel work unprompted, and
|
|
55
|
+
* `off` described the wanted behavior, so `off` became the hardcoded rule and
|
|
56
|
+
* the switch went. What decides instead is the user's own sentence in the chat.
|
|
57
|
+
*
|
|
58
|
+
* The 2026-10-09 batch (road-to-settings-classes-derivable-surface-stagnation
|
|
59
|
+
* Phase 2) is a fourth doctrine: `derivable` keys whose shipped default is the
|
|
60
|
+
* only behavior the package supports. Each WAS read — by code or by rule and
|
|
61
|
+
* command prose — and every reader was rewritten to state the old default as
|
|
62
|
+
* fixed behavior in the same change, so retiring the key changes no effective
|
|
63
|
+
* default; what a consumer who had set a non-default value loses is named by
|
|
64
|
+
* the reason.
|
|
65
|
+
*
|
|
66
|
+
* Every reason string must name what decides INSTEAD, never just "removed".
|
|
67
|
+
* Exported so `lint_settings_classes` can check the deletion side of the
|
|
68
|
+
* surface: a reason that names no replacement, or an entry whose key is live in
|
|
69
|
+
* the template again, is a contradiction the loader itself cannot notice.
|
|
70
|
+
*/
|
|
71
|
+
export const REMOVED_KEYS: ReadonlyMap<string, string> = new Map([
|
|
72
|
+
['subagents.enabled', 'always-on orchestration'],
|
|
73
|
+
['subagents.auto', 'always-on orchestration'],
|
|
74
|
+
['subagents.host_capabilities', 'always-on orchestration'],
|
|
75
|
+
['subagents.budget_routing', 'always-on orchestration'],
|
|
76
|
+
['ai_team.enabled', 'always-on orchestration'],
|
|
77
|
+
['hooks.turn_end_gate.enabled', 'the turn-end gate is always armed'],
|
|
78
|
+
['hooks.turn_end_gate.promissory', 'the turn-end gate is always armed'],
|
|
79
|
+
['hooks.turn_end_gate.language', 'the turn-end gate is always armed'],
|
|
80
|
+
['hooks.turn_end_gate.verification', 'the turn-end gate is always armed'],
|
|
81
|
+
['telegraph.speak_scope', 'the rule body states its own scope; compile_time_toggles decides whether the rule ships'],
|
|
82
|
+
['chat_history.max_size_kb', 'the rotate command takes --max-kb from argv; session-count pruning bounds the file'],
|
|
83
|
+
['chat_history.on_overflow', 'the overflow mode comes from the rotate command --mode argv'],
|
|
84
|
+
['quality.wait_for_remote_ci', 'whether to poll follows from the push plus a detectable remote pipeline'],
|
|
85
|
+
['legal_review_prep.consented_at', 'the provenance sidecar settings:set writes and consentVerdict reads'],
|
|
86
|
+
['worktrees.mode', 'the user asking for a worktree in the chat; creation is instruction-only and hardcoded'],
|
|
87
|
+
// 2026-10-09 — output and tone
|
|
88
|
+
['personal.minimal_output', 'direct-answers Iron Law 3 mandates terse replies; there is no verbose mode'],
|
|
89
|
+
['personal.play_by_play', 'direct-answers: no narration unless the user asks for it in the turn'],
|
|
90
|
+
['personal.pr_comment_bot_icon', 'no-decorative-emojis-in-git-surfaces forbids the 🤖 prefix'],
|
|
91
|
+
['verbosity.intent_announcements', 'direct-answers: act and emit the result, no "Let me…" openers'],
|
|
92
|
+
['verbosity.preview_artifacts', 'generated content is used directly; preview-on-error and the Iron-Law gates decide when a preview shows'],
|
|
93
|
+
['verbosity.routine_confirmations', 'the no-cheap-questions Pre-Send Self-Check; Iron-Law gates always ask'],
|
|
94
|
+
['verbosity.post_action_reports', 'direct-answers Iron Law 3: a one-line confirmation and one end-summary'],
|
|
95
|
+
['telegraph.speak', 'the telegraph-speak predicate in compile_time_toggles.ts; the bench verdict is package-level (ADR telegraph/0002)'],
|
|
96
|
+
['tokens.rich_skills', "the skill's own token_budget_class: rich plus the lint_token_budget_discipline ceiling"],
|
|
97
|
+
// 2026-10-09 — reasoning protocol switches
|
|
98
|
+
['reasoning.auto_gate', 'the RDP gate task signal plus the host self-assessment in rdp-gate.md'],
|
|
99
|
+
['reasoning.components.orchestrator', 'the RDP gate task and host signals decide per component; reasoning.enabled stays the hard off'],
|
|
100
|
+
['reasoning.components.notes_first', 'the RDP gate task and host signals decide per component; reasoning.enabled stays the hard off'],
|
|
101
|
+
['reasoning.components.grounding', 'the RDP gate task and host signals decide per component; reasoning.enabled stays the hard off'],
|
|
102
|
+
['reasoning.components.intent', 'the RDP gate task and host signals decide per component; reasoning.enabled stays the hard off'],
|
|
103
|
+
['reasoning.components.complexity_first', 'the RDP gate task and host signals decide per component; reasoning.enabled stays the hard off'],
|
|
104
|
+
['reasoning.components.verifier_default', 'the RDP gate task and host signals decide per component; reasoning.enabled stays the hard off'],
|
|
105
|
+
['reasoning.components.prediction_tracking', 'the RDP gate task and host signals decide per component; reasoning.enabled stays the hard off'],
|
|
106
|
+
['reasoning.components.decision_ledger', 'the RDP gate task and host signals decide per component; reasoning.enabled stays the hard off'],
|
|
107
|
+
['reasoning.components.uncertainty_budget', 'the RDP gate task and host signals decide per component; reasoning.enabled stays the hard off'],
|
|
108
|
+
// 2026-10-09 — roadmap cadence
|
|
109
|
+
['roadmap.skip_pre_run_gate', 'the command name names the scope; only an ambiguous roadmap or an unresolvable conflict shows the gate'],
|
|
110
|
+
['roadmap.dashboard_regen_cadence', 'a fixed cadence: every 5th closed step, every phase boundary, reply end and any file-shape touch'],
|
|
111
|
+
// 2026-10-09 — command suggestion and PR creation
|
|
112
|
+
['commands.auto_detect', "an orchestrator's own auto_detect front-matter and the --no-auto-detect flag"],
|
|
113
|
+
['commands.suggestion.enabled', 'the suggester match-score floor and cooldown; /command-suggestion-off silences one conversation'],
|
|
114
|
+
['commands.suggestion.confidence_floor', "the suggester's fixed 0.6 floor; a command's own suggestion frontmatter can tighten it"],
|
|
115
|
+
['commands.suggestion.cooldown_seconds', "the suggester's fixed 600-second cooldown; a command's own suggestion frontmatter can lengthen it"],
|
|
116
|
+
['commands.suggestion.max_options', 'the fixed cap of 4 suggestions plus the always-present as-is option'],
|
|
117
|
+
['commands.create_pr.api_examples', "/create-pr's grounding rule: an example only from a real source, otherwise a one-line pointer"],
|
|
118
|
+
['commands.create_pr.ui_paths', "/create-pr's light frontend heuristic, which fails open"],
|
|
119
|
+
['commands.create_pr.api_paths', "/create-pr's light API-endpoint heuristic, which fails open"],
|
|
120
|
+
// 2026-10-09 — memory and knowledge sharing
|
|
121
|
+
['memory.cadence', 'a fixed cadence: the memory line renders whenever a memory type was asked; memory.visibility: off still silences it'],
|
|
122
|
+
['memory.review_threshold', "/memory load's fixed preview threshold of 10 unreviewed intake signals"],
|
|
123
|
+
['knowledge.global_sharing.redaction.enabled', 'the write-time redaction scan, which always runs before a card goes global'],
|
|
124
|
+
['knowledge.global_sharing.redaction.halt_on_trigger', 'the redaction gate, which always halts on a confidential-pattern hit'],
|
|
125
|
+
['knowledge.global_sharing.auto_promote_threshold', 'the fixed two-repo sighting count that triggers a promotion suggestion'],
|
|
126
|
+
['knowledge.global_sharing.freshness.hypothesis_after_days', "the card's age over last_verified against the fixed 90-day lead-only window"],
|
|
127
|
+
['knowledge.global_sharing.freshness.stale_after_days', "the card's age over last_verified against the fixed 180-day skip window"],
|
|
128
|
+
// 2026-10-09 — hooks and engine
|
|
129
|
+
['hooks.concern_budget.max_per_event', "the concern-budget gate's own constant of 8 per (platform, event) cell"],
|
|
130
|
+
['hooks.concern_budget.hard_fail', "the concern-budget gate's --strict argv; without it the gate warns"],
|
|
131
|
+
['decision_engine.surface_traces', 'nothing: the per-phase decision trace stays off, the old default'],
|
|
132
|
+
['decision_engine.on_block_fallback', 'the fail-safe: an on_block ask that times out always stops'],
|
|
133
|
+
['explain.enable_last', 'the presence of a work-state trace; explain last always renders it'],
|
|
134
|
+
// 2026-10-09 — remaining
|
|
135
|
+
['project.pr_template', '/create-pr, which reads .github/pull_request_template.md'],
|
|
136
|
+
['pipelines.skill_improvement', 'the skill-improvement-trigger rule; the capture is a proposal the user confirms'],
|
|
137
|
+
['consistency.cross_source', 'the cross-source-consistency rule, always on; batching and the no-cheap-questions floor bound the noise'],
|
|
138
|
+
['subagents.downshift', 'the model_tier each sub-task declares; downshift is always on'],
|
|
139
|
+
['ai_team.suppress_setup_hint', 'nothing: the one-line team-mode setup hint is always shown'],
|
|
140
|
+
]);
|
|
141
|
+
|
|
142
|
+
/** Keys already warned about in THIS process — the "once per run" dedupe. */
|
|
143
|
+
const _warnedRemovedKeys = new Set<string>();
|
|
144
|
+
|
|
145
|
+
/** Read one dotted path out of a merged settings tree; `undefined` when absent. */
|
|
146
|
+
function _readDotted(root: SettingsDict, dotted: string): unknown {
|
|
147
|
+
let node: unknown = root;
|
|
148
|
+
for (const part of dotted.split('.')) {
|
|
149
|
+
if (typeof node !== 'object' || node === null || Array.isArray(node)) {
|
|
150
|
+
return undefined;
|
|
151
|
+
}
|
|
152
|
+
node = (node as SettingsDict)[part];
|
|
153
|
+
}
|
|
154
|
+
return node;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Warn once per process, on stderr, for every {@link REMOVED_KEYS} entry still
|
|
159
|
+
* present in a resolved settings tree. Never throws, never changes what the
|
|
160
|
+
* caller does with `merged` — a pure notification side effect.
|
|
161
|
+
*/
|
|
162
|
+
export function warnRemovedKeys(merged: SettingsDict): void {
|
|
163
|
+
for (const [key, reason] of REMOVED_KEYS) {
|
|
164
|
+
if (_warnedRemovedKeys.has(key)) {
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
if (_readDotted(merged, key) === undefined) {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
_warnedRemovedKeys.add(key);
|
|
171
|
+
process.stderr.write(`${key} was removed (${reason}); ignored.\n`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
@@ -10,6 +10,11 @@
|
|
|
10
10
|
* This module is that emission, so the registry entry moves in the same change
|
|
11
11
|
* rather than being left describing a gap that closed.
|
|
12
12
|
*
|
|
13
|
+
* DATED 2026-10-06. The emission exists and is tested, but nothing calls it:
|
|
14
|
+
* this writer has no production caller, so the registry row was corrected back
|
|
15
|
+
* to `degraded` the same day. The caller belongs to the stub that owns it —
|
|
16
|
+
* whoever lands it sets the row back to `available`.
|
|
17
|
+
*
|
|
13
18
|
* WHAT IT IS NOT. It is not a test runner, and it does not decide whether a
|
|
14
19
|
* failure is a legitimate RED. The failure CLASSES belong to the TDD skill
|
|
15
20
|
* (`src/skills/test-driven-development/SKILL.md`, Test-Red row) and this module
|
|
@@ -284,15 +284,95 @@ function _title(s: string): string {
|
|
|
284
284
|
* Exported so the WRITER and every DETECTOR share one definition. A gate that
|
|
285
285
|
* re-spelled this string would drift from the writer silently, and the failure
|
|
286
286
|
* would be invisible in exactly the direction that matters: a stub the gate
|
|
287
|
-
* fails to recognise reads as a complete rule body.
|
|
287
|
+
* fails to recognise reads as a complete rule body. Two gates had done exactly
|
|
288
|
+
* that until step 2.1 of `road-to-a-thinned-layer-measured-in-one-unit`; both
|
|
289
|
+
* import this now.
|
|
290
|
+
*
|
|
291
|
+
* SHORTENED 2026-10-06 from 47 characters to 27 (step 2.2). It is paid once per
|
|
292
|
+
* stub and there were 89 stubs on the measured layer, so the sentence cost
|
|
293
|
+
* 4,183 characters of a 97,496-character standing total; at 27 it costs 2,403,
|
|
294
|
+
* a saving of 1,780 = 20 x 89.
|
|
295
|
+
*
|
|
296
|
+
* WHAT THE SHORTENING WAS NOT ALLOWED TO DO: drop the instruction. This is the
|
|
297
|
+
* only standing text in the whole layer that says what a stub is FOR — "load
|
|
298
|
+
* the body" occurs in no kernel rule and in neither root instruction file — so
|
|
299
|
+
* a bare token like `> thin` would have saved more and left nothing that could
|
|
300
|
+
* be followed. The decision record (D2, K6) rejected that explicitly: nothing
|
|
301
|
+
* in this repository can check whether an instruction nobody states is still
|
|
302
|
+
* obeyed.
|
|
303
|
+
*
|
|
304
|
+
* WHY IT MUST STAY LONG ENOUGH TO BE UNIQUE: {@link is_thin_entry} is a
|
|
305
|
+
* substring test over the whole file, so a marker short or generic enough to
|
|
306
|
+
* occur inside ordinary rule prose would make that rule read as a stub — and
|
|
307
|
+
* nine rule files carry blockquote lines. `thin_marker_unique_in_corpus.test.ts`
|
|
308
|
+
* runs the constant against every rule body in `src/rules/` and against every
|
|
309
|
+
* entry `build_thin` emits, in both directions, which is the check that bounds
|
|
310
|
+
* any further shortening.
|
|
288
311
|
*/
|
|
289
|
-
export const THIN_ENTRY_MARKER = '>
|
|
312
|
+
export const THIN_ENTRY_MARKER = '> Load the body on a match.';
|
|
290
313
|
|
|
291
314
|
/** Is this projected entry a pointer stub rather than a rule body? */
|
|
292
315
|
export function is_thin_entry(text: string): boolean {
|
|
293
316
|
return text.includes(THIN_ENTRY_MARKER);
|
|
294
317
|
}
|
|
295
318
|
|
|
319
|
+
/**
|
|
320
|
+
* What introduces a stub's body pointer. One writer, one reader.
|
|
321
|
+
*
|
|
322
|
+
* A BARE PATH SINCE 2026-10-06 (step 2.3 of
|
|
323
|
+
* `road-to-a-thinned-layer-measured-in-one-unit`). The pointer used to be a
|
|
324
|
+
* markdown link, ``Body: [`<id>`](<prefix><id>.md)``, whose link TEXT repeated
|
|
325
|
+
* the rule id the target already ends in. That cost `6 + len(id)` per stub over
|
|
326
|
+
* the bare form — 2,359 characters across the 89 stubs of the measured layer,
|
|
327
|
+
* 534 of it pure syntax and the rest the id written a second time.
|
|
328
|
+
*
|
|
329
|
+
* Nothing followed the link as a link. Under `delivery` the hook loads the body
|
|
330
|
+
* and never reads the pointer at all; under `thin` an agent reads the path. A
|
|
331
|
+
* markdown link renders in neither case, so the syntax bought rendering nobody
|
|
332
|
+
* was doing.
|
|
333
|
+
*/
|
|
334
|
+
export const THIN_BODY_POINTER_PREFIX = 'Body: ';
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* The pointer, as the WRITER emits it — exported so a detector cannot re-spell
|
|
338
|
+
* it, which is the same drift {@link THIN_ENTRY_MARKER} documents one screen up
|
|
339
|
+
* and which two gates had already committed there.
|
|
340
|
+
*
|
|
341
|
+
* WHAT IT CAPTURES is the whole tail of the line from `Body: ` to its end, and
|
|
342
|
+
* that is the intended semantic rather than an accident of greediness: the
|
|
343
|
+
* writer emits the pointer LAST on its line, so the tail IS the path. A review
|
|
344
|
+
* round proposed a lazy `(.+?\.md)` to stop at the first `.md`; measured, it
|
|
345
|
+
* changes nothing, because `\s*$` forces the match to reach end of line either
|
|
346
|
+
* way and a lazy quantifier simply backtracks forward to the same place. The
|
|
347
|
+
* greedy form is kept and the property is pinned by a test, so the next reader
|
|
348
|
+
* meets the measurement instead of repeating the proposal.
|
|
349
|
+
*
|
|
350
|
+
* ANCHORED TO END OF LINE, NOT `\S+`. The pointer is the last thing on its
|
|
351
|
+
* line, and a package root may contain spaces; `\S+` would silently stop at the
|
|
352
|
+
* first one and report a well-formed pointer as missing.
|
|
353
|
+
*
|
|
354
|
+
* COMPOSED FROM {@link THIN_BODY_POINTER_PREFIX} rather than re-spelling it.
|
|
355
|
+
* The constant exists so a reader cannot hold its own copy, and a pattern six
|
|
356
|
+
* lines below it holding a literal `Body: ` would have broken that invariant in
|
|
357
|
+
* the file that states it.
|
|
358
|
+
*/
|
|
359
|
+
export const THIN_BODY_POINTER_RE = (() => {
|
|
360
|
+
const lit = THIN_BODY_POINTER_PREFIX.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
361
|
+
// THE LAST PREFIX ON THE LINE, NOT THE FIRST. `thin_entry` puts the rule's
|
|
362
|
+
// own `description` on the SAME line ahead of the pointer, so a description
|
|
363
|
+
// containing the literal `Body: ` used to start the match inside the
|
|
364
|
+
// description and capture it as part of the path — `has_body_pointer` stayed
|
|
365
|
+
// true while the extraction was wrong, which is a wrong assertion rather
|
|
366
|
+
// than a visible failure. Forbidding a second prefix inside the capture
|
|
367
|
+
// makes the first viable start the last occurrence, which is the pointer.
|
|
368
|
+
return new RegExp(`${lit}((?:(?!${lit}).)+\\.md)\\s*$`, 'm');
|
|
369
|
+
})();
|
|
370
|
+
|
|
371
|
+
/** Does this entry carry a body pointer the writer would recognise? */
|
|
372
|
+
export function has_body_pointer(text: string): boolean {
|
|
373
|
+
return THIN_BODY_POINTER_RE.test(text);
|
|
374
|
+
}
|
|
375
|
+
|
|
296
376
|
/**
|
|
297
377
|
* Where a stub tells a reader the body actually is.
|
|
298
378
|
*
|
|
@@ -356,7 +436,7 @@ export function thin_entry(
|
|
|
356
436
|
return (
|
|
357
437
|
`## ${title}\n` +
|
|
358
438
|
`${THIN_ENTRY_MARKER}${fires} ${desc} ` +
|
|
359
|
-
|
|
439
|
+
`${THIN_BODY_POINTER_PREFIX}${bodyLinkPrefix}${rule_id}.md\n`
|
|
360
440
|
);
|
|
361
441
|
}
|
|
362
442
|
|
|
@@ -89,6 +89,22 @@ export interface QualityRun {
|
|
|
89
89
|
readonly output_head: readonly string[];
|
|
90
90
|
readonly skipped: SkipReason | null;
|
|
91
91
|
readonly files: readonly string[];
|
|
92
|
+
/**
|
|
93
|
+
* Matched files the tool reported it declined to look at. A run where EVERY
|
|
94
|
+
* matched file is listed here and the tool exited 0 is a verdict about
|
|
95
|
+
* nothing, so `exit_code` is `null` for it — the readings page § 5(a) found
|
|
96
|
+
* that row recorded `0, skipped: null`, the exact shape of a pass. A field
|
|
97
|
+
* rather than a fifth `SkipReason` (D2): a partly-ignored run keeps its real
|
|
98
|
+
* exit code, and a skip reason cannot sit beside a verdict.
|
|
99
|
+
*/
|
|
100
|
+
readonly ignored_files: readonly string[];
|
|
101
|
+
/**
|
|
102
|
+
* Type-check commands the resolver emitted that produced no verdict on this
|
|
103
|
+
* turn — unscoped, absent or mutating. Identical on every record of the turn,
|
|
104
|
+
* so ANY single row says that a `0` beside it was a lint verdict and not a
|
|
105
|
+
* type verdict (§ 5(b): `tsc --noEmit` is unscoped on every stop).
|
|
106
|
+
*/
|
|
107
|
+
readonly typecheck_not_run: readonly string[];
|
|
92
108
|
readonly at: string;
|
|
93
109
|
}
|
|
94
110
|
|
|
@@ -112,8 +128,21 @@ interface ToolSpec {
|
|
|
112
128
|
* the resolver's by exactly the flag that makes it read-only.
|
|
113
129
|
*/
|
|
114
130
|
readonly check_form: boolean;
|
|
131
|
+
/**
|
|
132
|
+
* A line the tool prints, exit 0, for an input its own config ignores. Per
|
|
133
|
+
* row because the wording is the tool's (D1); a row without one reads no
|
|
134
|
+
* output as an ignore, which keeps the pre-existing behaviour rather than
|
|
135
|
+
* guessing at a message the tool might print.
|
|
136
|
+
*/
|
|
137
|
+
readonly ignored_signal?: RegExp;
|
|
115
138
|
}
|
|
116
139
|
|
|
140
|
+
/**
|
|
141
|
+
* ESLint 9's stylish report for an ignored input: the absolute path on its own
|
|
142
|
+
* line, then this indented warning. Pinned verbatim by the ignored-file fixture.
|
|
143
|
+
*/
|
|
144
|
+
const ESLINT_IGNORED = /^\s+\d+:\d+\s+warning\s+File ignored because of a matching ignore pattern\b/;
|
|
145
|
+
|
|
117
146
|
const JS_EXTENSIONS = ['.js', '.jsx', '.mjs', '.cjs', '.ts', '.tsx', '.mts', '.cts'] as const;
|
|
118
147
|
|
|
119
148
|
/**
|
|
@@ -124,7 +153,15 @@ const JS_EXTENSIONS = ['.js', '.jsx', '.mjs', '.cjs', '.ts', '.tsx', '.mts', '.c
|
|
|
124
153
|
* and absence is what produces `skipped: unscoped`.
|
|
125
154
|
*/
|
|
126
155
|
const SCOPED_FORMS: ReadonlyMap<string, ToolSpec> = new Map<string, ToolSpec>([
|
|
127
|
-
[
|
|
156
|
+
[
|
|
157
|
+
'npx eslint .',
|
|
158
|
+
{
|
|
159
|
+
argv: ['npx', 'eslint'],
|
|
160
|
+
extensions: JS_EXTENSIONS,
|
|
161
|
+
check_form: false,
|
|
162
|
+
ignored_signal: ESLINT_IGNORED,
|
|
163
|
+
},
|
|
164
|
+
],
|
|
128
165
|
[
|
|
129
166
|
'vendor/bin/phpstan analyse',
|
|
130
167
|
{ argv: ['vendor/bin/phpstan', 'analyse'], extensions: ['.php'], check_form: false },
|
|
@@ -153,6 +190,38 @@ const SCOPED_FORMS: ReadonlyMap<string, ToolSpec> = new Map<string, ToolSpec>([
|
|
|
153
190
|
*/
|
|
154
191
|
const MUTATING_WITHOUT_CHECK_FORM: ReadonlySet<string> = new Set<string>([]);
|
|
155
192
|
|
|
193
|
+
/**
|
|
194
|
+
* Resolver commands with no file-scoped form, unscoped ON PURPOSE (rule 3).
|
|
195
|
+
*
|
|
196
|
+
* Named so the parity test can tell a deliberate absence from `SCOPED_FORMS`
|
|
197
|
+
* apart from a resolver command nobody classified: every command the resolver
|
|
198
|
+
* emits is a scoped key, a mutating key, or on this list — or a test is red.
|
|
199
|
+
*/
|
|
200
|
+
export const UNSCOPED_ON_PURPOSE: readonly string[] = [
|
|
201
|
+
'npx tsc --noEmit',
|
|
202
|
+
'go vet ./...',
|
|
203
|
+
'cargo clippy',
|
|
204
|
+
];
|
|
205
|
+
|
|
206
|
+
/** The keys of `SCOPED_FORMS`, for the parity test. */
|
|
207
|
+
export const SCOPED_FORM_COMMANDS: readonly string[] = [...SCOPED_FORMS.keys()];
|
|
208
|
+
|
|
209
|
+
/** The keys of `MUTATING_WITHOUT_CHECK_FORM`, for the parity test. */
|
|
210
|
+
export const MUTATING_COMMANDS: readonly string[] = [...MUTATING_WITHOUT_CHECK_FORM];
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Resolver commands whose verdict is a type verdict. `go vet` and `cargo clippy`
|
|
214
|
+
* both compile the package, so a type error stops them; ESLint, ruff and pint do
|
|
215
|
+
* not type-check, which is the whole of § 5(b).
|
|
216
|
+
*/
|
|
217
|
+
export const TYPE_CHECK_COMMANDS: ReadonlySet<string> = new Set<string>([
|
|
218
|
+
'npx tsc --noEmit',
|
|
219
|
+
'vendor/bin/phpstan analyse',
|
|
220
|
+
'mypy .',
|
|
221
|
+
'go vet ./...',
|
|
222
|
+
'cargo clippy',
|
|
223
|
+
]);
|
|
224
|
+
|
|
156
225
|
function extensionOf(file: string): string {
|
|
157
226
|
const base = path.basename(file);
|
|
158
227
|
const dot = base.lastIndexOf('.');
|
|
@@ -253,7 +322,7 @@ function defaultSpawn(
|
|
|
253
322
|
export function runTouchedFileQuality(opts: RunOptions): QualityRun[] {
|
|
254
323
|
const timeout_ms = opts.timeout_ms ?? DEFAULT_TIMEOUT_MS;
|
|
255
324
|
const spawn = opts.spawn ?? defaultSpawn;
|
|
256
|
-
const out: QualityRun[] = [];
|
|
325
|
+
const out: Omit<QualityRun, 'typecheck_not_run'>[] = [];
|
|
257
326
|
for (const plan of planQualityRuns(opts.commands, opts.files)) {
|
|
258
327
|
if (plan.argv === null) {
|
|
259
328
|
out.push({
|
|
@@ -263,6 +332,7 @@ export function runTouchedFileQuality(opts: RunOptions): QualityRun[] {
|
|
|
263
332
|
output_head: [],
|
|
264
333
|
skipped: plan.skipped,
|
|
265
334
|
files: [],
|
|
335
|
+
ignored_files: [],
|
|
266
336
|
at: now(),
|
|
267
337
|
});
|
|
268
338
|
continue;
|
|
@@ -282,17 +352,69 @@ export function runTouchedFileQuality(opts: RunOptions): QualityRun[] {
|
|
|
282
352
|
// tool is a wrapper script whose own dependency is missing. Same meaning
|
|
283
353
|
// as ENOENT for this module's purposes, and the same bucket in 2.1.
|
|
284
354
|
const absent = enoent || status === 127;
|
|
355
|
+
const signal = SCOPED_FORMS.get(plan.source_command)?.ignored_signal;
|
|
356
|
+
const ignored =
|
|
357
|
+
absent || signal === undefined ? [] : ignoredFiles(output, signal, plan.files);
|
|
358
|
+
// Every matched file ignored AND exit 0: the tool looked at nothing, so
|
|
359
|
+
// there is no verdict to record. A non-zero exit over the same set stays,
|
|
360
|
+
// because a red the tool raised (a config crash, say) is real.
|
|
361
|
+
const nothingLooked = ignored.length === plan.files.length && status === 0;
|
|
285
362
|
out.push({
|
|
286
363
|
command: renderCommand(plan.argv),
|
|
287
364
|
source_command: plan.source_command,
|
|
288
|
-
exit_code: absent ? null : status,
|
|
365
|
+
exit_code: absent || nothingLooked ? null : status,
|
|
289
366
|
output_head: absent ? [] : headLines(output, OUTPUT_HEAD_LINES),
|
|
290
367
|
skipped: absent ? 'absent' : null,
|
|
291
368
|
files: plan.files,
|
|
369
|
+
ignored_files: ignored,
|
|
292
370
|
at: now(),
|
|
293
371
|
});
|
|
294
372
|
}
|
|
295
|
-
|
|
373
|
+
// `no_files` is excluded: no file the type checker reads was touched, so
|
|
374
|
+
// there was nothing on this turn for it to have caught.
|
|
375
|
+
const typecheck_not_run = out
|
|
376
|
+
.filter(
|
|
377
|
+
(r) =>
|
|
378
|
+
TYPE_CHECK_COMMANDS.has(r.source_command) &&
|
|
379
|
+
r.exit_code === null &&
|
|
380
|
+
r.skipped !== 'no_files' &&
|
|
381
|
+
r.skipped !== null,
|
|
382
|
+
)
|
|
383
|
+
.map((r) => r.source_command);
|
|
384
|
+
return out.map((r) => ({ ...r, typecheck_not_run: [...typecheck_not_run] }));
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* The matched files the tool's output reports as ignored.
|
|
389
|
+
*
|
|
390
|
+
* The stylish report names the file on an unindented line and the warning on
|
|
391
|
+
* the indented lines under it, so a signal line is attributed to the last path
|
|
392
|
+
* line above it. A signal that cannot be attributed is attributed to the one
|
|
393
|
+
* matched file only when there is exactly one; otherwise it is dropped, so an
|
|
394
|
+
* unreadable report keeps today's behaviour instead of inventing an ignore.
|
|
395
|
+
*/
|
|
396
|
+
export function ignoredFiles(
|
|
397
|
+
output: string,
|
|
398
|
+
signal: RegExp,
|
|
399
|
+
files: readonly string[],
|
|
400
|
+
): string[] {
|
|
401
|
+
const reported: string[] = [];
|
|
402
|
+
let unattributed = false;
|
|
403
|
+
let current: string | null = null;
|
|
404
|
+
for (const line of output.split(/\r\n|\r|\n/)) {
|
|
405
|
+
if (signal.test(line)) {
|
|
406
|
+
if (current === null) unattributed = true;
|
|
407
|
+
else reported.push(normalizePath(current));
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
if (line !== '' && !/^\s/.test(line)) current = line.trim();
|
|
411
|
+
}
|
|
412
|
+
const hit = files.filter((f) => {
|
|
413
|
+
const want = normalizePath(f);
|
|
414
|
+
return reported.some((r) => r === want || r.endsWith(`/${want}`));
|
|
415
|
+
});
|
|
416
|
+
if (hit.length === 0 && unattributed && files.length === 1) return [...files];
|
|
417
|
+
return hit;
|
|
296
418
|
}
|
|
297
419
|
|
|
298
420
|
/**
|
|
@@ -306,11 +428,25 @@ export function runTouchedFileQuality(opts: RunOptions): QualityRun[] {
|
|
|
306
428
|
export const WARN_LINE_MAX_BYTES = 200;
|
|
307
429
|
|
|
308
430
|
export function advisoryLine(runs: readonly QualityRun[]): string | null {
|
|
431
|
+
const ignored = [...new Set(runs.flatMap((r) => r.ignored_files))];
|
|
432
|
+
const ignoredPart =
|
|
433
|
+
ignored.length === 0
|
|
434
|
+
? ''
|
|
435
|
+
: `ignored ${ignored[0] ?? ''}${ignored.length > 1 ? ` (+${String(ignored.length - 1)} more)` : ''}`;
|
|
309
436
|
const failed = runs.find((r) => r.skipped === null && r.exit_code !== null && r.exit_code !== 0);
|
|
310
|
-
if (failed === undefined)
|
|
437
|
+
if (failed === undefined) {
|
|
438
|
+
// Nothing failed. Silence is right when every file was looked at; when a
|
|
439
|
+
// file was ignored, silence would read as clean, so say what was not seen.
|
|
440
|
+
if (ignored.length === 0) return null;
|
|
441
|
+
return truncateToBytes(
|
|
442
|
+
`touched-file quality: no verdict, ${ignoredPart}`,
|
|
443
|
+
WARN_LINE_MAX_BYTES,
|
|
444
|
+
);
|
|
445
|
+
}
|
|
311
446
|
const file = failed.files[0] ?? '(no file)';
|
|
312
447
|
const more = failed.files.length > 1 ? ` (+${String(failed.files.length - 1)} more)` : '';
|
|
313
|
-
const
|
|
448
|
+
const tail = ignoredPart === '' ? '' : `; ${ignoredPart}`;
|
|
449
|
+
const line = `touched-file quality: ${failed.source_command} exited ${String(failed.exit_code)} on ${file}${more}${tail}`;
|
|
314
450
|
return truncateToBytes(line, WARN_LINE_MAX_BYTES);
|
|
315
451
|
}
|
|
316
452
|
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* error on the wrong rung, not diligence.
|
|
10
10
|
*
|
|
11
11
|
* Composes with — replaces nothing:
|
|
12
|
-
* - the
|
|
12
|
+
* - the `execution.fix_loop_max` validation-loop budget (`autonomous-execution`),
|
|
13
13
|
* - the ADR-109 / `subagent-response-contract` body + 4-status envelope
|
|
14
14
|
* (`subagent-steering`): the partial result rides as the body of a
|
|
15
15
|
* `BLOCKED` envelope with `budget_hit: true` as the escalation flag.
|
|
@@ -187,11 +187,26 @@ export function scan(d: string): [Row[], Row[], string[]] {
|
|
|
187
187
|
* A scope with no refs renders as `—`: a qualifier on nothing is not a
|
|
188
188
|
* supersession, and printing the prose alone would read as one.
|
|
189
189
|
*/
|
|
190
|
+
/**
|
|
191
|
+
* Escape a `|` for safety inside a Markdown table cell. The free-text scope
|
|
192
|
+
* fields this feeds (`supersedes_scope` / `superseded_scope`) routinely quote
|
|
193
|
+
* a table row from the record they describe — and a quoted row has its own
|
|
194
|
+
* `|` column separators, verbatim, in the frontmatter prose. Unescaped, that
|
|
195
|
+
* splits the generated row into extra columns rather than rendering the quote
|
|
196
|
+
* (found live in ADR-230's and ADR-279's own rows, both quoting the same
|
|
197
|
+
* table cell from ADR-230 § Decision). `refs` itself is never escaped: it is
|
|
198
|
+
* always an `ADR-NNN` token list this generator produces or validates, never
|
|
199
|
+
* free text.
|
|
200
|
+
*/
|
|
201
|
+
function escapeCell(text: string): string {
|
|
202
|
+
return text.replaceAll('|', '\\|');
|
|
203
|
+
}
|
|
204
|
+
|
|
190
205
|
export function supersessionCell(refs: string | undefined, scope: string | undefined): string {
|
|
191
206
|
const r = (refs ?? '').trim();
|
|
192
207
|
if (r === '' || r === '—') return '—';
|
|
193
208
|
const s = (scope ?? '').trim();
|
|
194
|
-
return s === '' || s === '—' ? r : `${r} (${s})`;
|
|
209
|
+
return s === '' || s === '—' ? r : `${r} (${escapeCell(s)})`;
|
|
195
210
|
}
|
|
196
211
|
|
|
197
212
|
/** Mirror `row(r)`. */
|
|
@@ -291,8 +291,8 @@ export interface CostBudgetConfig {
|
|
|
291
291
|
readonly max_output_tokens: number;
|
|
292
292
|
readonly max_calls: number;
|
|
293
293
|
readonly max_total_usd: number;
|
|
294
|
-
/** Rolling 24h cap. 0 disables it
|
|
295
|
-
*
|
|
294
|
+
/** Rolling 24h cap. 0 disables it. The spend ledger is written either way
|
|
295
|
+
* (ADR-279); this value decides only whether the total is compared. */
|
|
296
296
|
readonly daily_limit_usd: number;
|
|
297
297
|
}
|
|
298
298
|
|
|
@@ -1020,7 +1020,7 @@ function _build_debate(d: Dict): DebateConfig {
|
|
|
1020
1020
|
if (!_isDict(d)) {
|
|
1021
1021
|
throw new CouncilConfigError('`debate` must be a mapping.');
|
|
1022
1022
|
}
|
|
1023
|
-
const cap = _pyFloat(_get(d, 'max_cost_usd',
|
|
1023
|
+
const cap = _pyFloat(_get(d, 'max_cost_usd', 0.0)); // 0 = no refusal cap (ADR-279)
|
|
1024
1024
|
if (cap < 0) {
|
|
1025
1025
|
throw new CouncilConfigError(
|
|
1026
1026
|
`debate.max_cost_usd must be >= 0 (got ${_pyRepr(_f(cap))}; ` +
|
|
@@ -1671,10 +1671,10 @@ function _build_cost_budget(d: Dict): CostBudgetConfig {
|
|
|
1671
1671
|
throw new CouncilConfigError('`cost_budget` must be a mapping.');
|
|
1672
1672
|
}
|
|
1673
1673
|
const cb: CostBudgetConfig = {
|
|
1674
|
-
max_input_tokens: _pyInt(_get(d, 'max_input_tokens',
|
|
1675
|
-
max_output_tokens: _pyInt(_get(d, 'max_output_tokens',
|
|
1676
|
-
max_calls: _pyInt(_get(d, 'max_calls', 50)),
|
|
1677
|
-
max_total_usd: _pyFloat(_get(d, 'max_total_usd',
|
|
1674
|
+
max_input_tokens: _pyInt(_get(d, 'max_input_tokens', 0)), // 0 = unbounded (ADR-279)
|
|
1675
|
+
max_output_tokens: _pyInt(_get(d, 'max_output_tokens', 0)), // 0 = unbounded (ADR-279)
|
|
1676
|
+
max_calls: _pyInt(_get(d, 'max_calls', 50)), // fan-out, not money — kept
|
|
1677
|
+
max_total_usd: _pyFloat(_get(d, 'max_total_usd', 0.0)), // 0 = unbounded (ADR-279)
|
|
1678
1678
|
daily_limit_usd: _pyFloat(_get(d, 'daily_limit_usd', 0.0)),
|
|
1679
1679
|
};
|
|
1680
1680
|
const fields: Array<[keyof CostBudgetConfig, boolean]> = [
|