@event4u/agent-config 16.3.0 → 16.5.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 +178 -78
- 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/design.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/design-antipatterns.md +1 -1
- 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 +14 -48
- 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/accessibility-auditor/data/aria-patterns.csv +2 -0
- package/dist/agent-src/skills/accessibility-auditor/data/manifest.json +3 -3
- 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/canvas-design/SKILL.md +4 -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-intelligence/references/integration-mapping.md +13 -10
- 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/fe-design/references/design-patterns.md +49 -2
- package/dist/agent-src/skills/feature-planning/SKILL.md +1 -1
- package/dist/agent-src/skills/frontend-render-security/SKILL.md +9 -0
- 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 +4 -2
- package/dist/agent-src/skills/image-provider-routing/SKILL.md +16 -5
- package/dist/agent-src/skills/jira-integration/SKILL.md +3 -3
- package/dist/agent-src/skills/logo-generation/SKILL.md +12 -8
- 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/svg-authoring/SKILL.md +318 -0
- 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/skills/wireframe/SKILL.md +5 -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/commands/uiRender.js +201 -4
- package/dist/cli/commands/uiRenderAsset.js +1308 -0
- package/dist/cli/commands/uiRenderAssetCompare.js +752 -0
- package/dist/cli/commands/uiRenderAssetGrid.js +265 -0
- package/dist/cli/commands/uiRenderAssetGrounds.js +323 -0
- package/dist/cli/commands/uiRenderAssetIsolation.js +85 -0
- package/dist/cli/commands/uiRenderAssetTypes.js +145 -0
- package/dist/cli/main.js +47 -1
- package/dist/cli/registry.js +2 -1
- package/dist/cli-delegate/check_update_banner.js +195 -119
- package/dist/cli-delegate/{chunk-S4UMZNES.js → chunk-4DBG5K7M.js} +5 -5
- 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-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-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-NQ7WT43P.js → chunk-TMWYUOK4.js} +75 -12
- 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 +489 -238
- 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 +171 -107
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +7 -7
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +41 -22
- package/dist/discovery/trust-report.md +3 -3
- package/dist/discovery/workspaces.json +16 -11
- package/dist/hooks/dispatch.js +2520 -1924
- package/dist/hooks/dispatch.sha256 +1 -1
- package/dist/hooks/svg_rules.chunk.cjs +1626 -0
- package/dist/hooks/svg_rules.chunk.cjs.sha256 +1 -0
- 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 +3063 -2160
- 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/scan_scope.js +105 -0
- package/dist/scripts/_lib/settings_removed_keys.js +168 -0
- package/dist/scripts/_lib/svg_dom.js +284 -0
- package/dist/scripts/_lib/svg_geometry.js +477 -0
- package/dist/scripts/_lib/svg_motion.js +179 -0
- package/dist/scripts/_lib/svg_rules.js +1337 -0
- package/dist/scripts/_lib/svg_urls.js +67 -0
- package/dist/scripts/_lib/thin_rules.js +80 -3
- package/dist/scripts/lint_svg_asset.js +324 -0
- 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/design-antipatterns.md +1 -1
- package/docs/guidelines/php/git.md +15 -2
- package/package.json +4 -3
- 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 +56 -16
- 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 +55 -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/svg_dom.ts +318 -0
- package/src/scripts/_lib/svg_geometry.ts +480 -0
- package/src/scripts/_lib/svg_motion.ts +208 -0
- package/src/scripts/_lib/svg_rules.ts +1453 -0
- package/src/scripts/_lib/svg_urls.ts +72 -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/verification_command.ts +59 -0
- package/src/scripts/_lib/verify_clause.ts +27 -17
- 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/block_speaking_inbox_dir.ts +16 -1
- package/src/scripts/hooks/concern_registry.ts +2 -0
- package/src/scripts/hooks/delegation_nudge_hook.ts +2 -3
- package/src/scripts/hooks/design_pass_hook.ts +157 -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/svg_obligation.ts +497 -0
- package/src/scripts/hooks/svg_rules_loader.ts +133 -0
- package/src/scripts/hooks/telemetry_usage_hook.ts +7 -46
- package/src/scripts/hooks/turn_end_gate_hook.ts +6 -3
- 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_consolidation_lineage.ts +6 -3
- package/src/scripts/lint_design_quality.ts +60 -12
- package/src/scripts/lint_evidence_artifacts.ts +9 -0
- package/src/scripts/lint_hook_concern_budget.ts +10 -21
- package/src/scripts/lint_motion_authority_drift.ts +27 -0
- 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_svg_asset.ts +365 -0
- 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
|
@@ -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;
|
|
@@ -20,22 +20,19 @@ const profileId = z.enum(['developer', 'content_creator', 'founder', 'agency', '
|
|
|
20
20
|
const accessStyle = z.enum(['getters_setters', 'get_attribute', 'magic_properties']);
|
|
21
21
|
const chatFreq = z.enum(['per_turn', 'per_phase', 'per_tool']);
|
|
22
22
|
const qualityCadence = z.enum(['end_of_roadmap', 'per_phase', 'per_step']);
|
|
23
|
-
const regenCadence = z.enum(['per_step', 'every_5_steps', 'phase_boundary']);
|
|
24
23
|
const fidelityMode = z.enum(['strict', 'structural', 'hard-floor']);
|
|
25
|
-
const crossSourceMode = z.enum(['on', 'auto', 'off']);
|
|
26
|
-
const richSkillsMode = z.enum(['on', 'ask', 'off']);
|
|
27
24
|
const replyMethod = z.enum(['replies_endpoint', 'create_review_comment', 'auto']);
|
|
28
25
|
const confidenceBand = z.enum(['off', 'low', 'medium', 'high']);
|
|
29
26
|
const onBlock = z.enum(['stop', 'ask', 'warn']);
|
|
30
|
-
const onBlockFallback = z.enum(['stop', 'warn']);
|
|
31
27
|
const modelAutoSwitch = z.enum(['auto', 'suggest', 'off']);
|
|
32
28
|
const leanProjectionMode = z.enum(['eager-all', 'thin', 'delivery']);
|
|
33
29
|
const leanProjectionHost = z.enum(['claude-code', 'cursor', 'cline']);
|
|
34
30
|
const projectionMode = z.enum(['legacy-all', 'scoped']);
|
|
35
|
-
const memoryCadence = z.enum(['auto', 'always', 'never']);
|
|
36
31
|
const projectAudience = z.enum(['self', 'internal', 'client', 'public']);
|
|
37
32
|
const deliveryMerge = z.enum(['off', 'on-green']);
|
|
38
33
|
const prTopology = z.enum(['single', 'stacked']);
|
|
34
|
+
const gitCommitFormat = z.enum(['ticket-scope', 'ticket-conventional']);
|
|
35
|
+
const gitUpdateStrategy = z.enum(['merge', 'rebase']);
|
|
39
36
|
export const settingsSchema = z.object({
|
|
40
37
|
agent_config_version: z.string().default('').describe('Pin the package to an exact semver (e.g. "1.4.2") so all teammates load the same skill / rule set. Leave empty to track whatever is installed locally — useful for the maintainers of this package, risky for production projects.'),
|
|
41
38
|
profile: z.object({
|
|
@@ -79,20 +76,21 @@ export const settingsSchema = z.object({
|
|
|
79
76
|
ide: z.string().default('').describe('CLI binary your IDE registers (code, code-insiders, phpstorm, cursor, windsurf, idea, subl, …). Used by the file-editor skill to open edited files. Leave empty to disable IDE integration.'),
|
|
80
77
|
open_edited_files: z.boolean().default(false).describe('After the agent edits a file, run `<ide> <path>` to surface it in your editor immediately. Off by default to avoid window-stealing during long agent runs.'),
|
|
81
78
|
rtk_installed: z.boolean().default(false).describe('Does this machine have rtk (Rust Token Killer, a third-party Apache-2.0 tool: https://github.com/rtk-ai/rtk) on PATH — verified as the real Token Killer, not the unrelated Rust Type Kit that shares the binary name? When true the agent wraps verbose CLI output (git, tests, linters, docker, npm, composer) with rtk (upstream reports 60-90% token savings — their estimate). Leave false if rtk is missing — the agent falls back to tail / grep. The wizard overwrites this from a live two-stage probe (PATH presence + `rtk gain` identity check).'),
|
|
82
|
-
minimal_output: z.boolean().default(true).describe('Prefer short bullets and tables (true, default) vs verbose prose with rationale (false). Affects every chat reply; flip to false during debugging when you want the agent to think out loud.'),
|
|
83
79
|
canary_name: z.string().default('').describe('Session canary — the name the agent addresses you with at the start of every new task (e.g. "Alex"). When the greeting silently disappears, the context window is degrading: start a fresh conversation. Also keeps the reply-close markers (end-summary, PR URL as literal last line) alive. Empty = fall back to the user-global canary_name, then to identity.name from the setup wizard; no name anywhere = off. See rules/session-canary.md.'),
|
|
84
|
-
play_by_play: z.boolean().default(false).describe('Narrate intermediate findings between tool calls ("Found it.", "Let me check Y."). Off by default — most users find it noisy. Turn on when you want to follow the agent\'s reasoning step by step.'),
|
|
85
|
-
pr_comment_bot_icon: z.boolean().default(false).describe('Prefix every PR review-comment reply with 🤖 so humans can tell agent-authored comments apart from teammate comments at a glance. Cosmetic only; the comment body itself never changes.'),
|
|
86
80
|
pr_progress_comments: z.boolean().default(false).describe('Permit the agent to post unsolicited progress / status comments on an open PR (e.g. "CI fix iteration #2", "still blocked on workflow scope"). Default off — most teammates find them noisy. User-invoked flows (/fix:pr-comments, /create-pr, /code-review, explicit "post a comment that …") are NOT gated by this setting. See rules/no-pr-progress-comments.md.'),
|
|
87
81
|
autonomy: autonomyMode.default('auto').describe('How aggressively the agent suppresses trivial workflow questions ("commit now?", "open PR?"). on = silently pick the sensible default. off = always ask. auto (default) = decide per project, on for solo / off when collaborators are involved. The Hard Floor (prod, deploys, bulk deletes) ignores this setting and always asks.'),
|
|
88
82
|
user_type: userType.default('').describe('Optional persona axis used by the skill-suggester to surface the relevant subset (consultant / creator / developer / finance / founder / gtm / ops). Empty = no filter, all skills available. You can change this any time without re-running setup.'),
|
|
89
83
|
}),
|
|
90
84
|
project: z.object({
|
|
91
|
-
pr_template: z.string().default('.github/pull_request_template.md').describe('Path (relative to project root) to the PR-description template the agent fills in before opening a pull request. Override only if your repo keeps the template somewhere non-standard.'),
|
|
92
85
|
upstream_repo: z.string().default('').describe('GitHub slug (owner/repo) the upstream-contribute skill targets when you ask the agent to push a learning back to the shared agent-config package. Empty = improvement PRs are disabled.'),
|
|
93
86
|
improvement_pr_branch_prefix: z.string().default('improve/agent-').describe('Branch-name prefix for improvement PRs the agent opens against project.upstream_repo (e.g. "improve/agent-add-react-skill"). Pick a prefix your repo conventions allow.'),
|
|
94
87
|
audience: projectAudience.default('public').describe('Who this project is built for — read by the demand gate (§ 8-pre of docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md), whose L0-L4 ladder measures MARKET demand and is meaningless where no market is intended. self = a tool its maintainer builds for themselves; the gate is inert and work is classified L-self (build) instead of being deferred for lack of a user population nobody wants. internal = a team tool; only "what breaks without it?" survives. client = built for a named client, who is the requester rather than a market segment. public (default) = a product with an intended market; full three-question gate, behaviour unchanged from before this key existed.'),
|
|
95
88
|
}),
|
|
89
|
+
git: z.object({
|
|
90
|
+
commit_format: gitCommitFormat.default('ticket-scope').describe('Where a ticket id goes in a commit subject. ticket-scope (default) = the ticket is the Conventional-Commits scope, `feat(DEV-1234): add export filter` — the behaviour every install had before this key existed. ticket-conventional = the ticket leads the subject and the scope names the system area, `DEV-1234 feat(exporter): add export filter`; a ticket is then never a scope. Without a ticket both shapes are plain Conventional Commits. A commit-linting config in the repository (commitlint, a commit-msg hook) outranks this key.'),
|
|
91
|
+
branch_pattern: z.string().default('{type}/{slug}').describe('Shape of a branch name the agent creates. Placeholders: {type} (feat, fix, …), {ticket} (e.g. DEV-1234), {slug} (short kebab-case description). Default {type}/{slug}. {slug} is required, and characters outside the placeholders are limited to A-Z a-z 0-9 . _ / - so a rendered name is safe in a command; agent-config git:convention show reports anything else as invalid. A team that names branches after the ticket sets {ticket}-{slug}. A placeholder with no value is dropped together with the separator that follows it, or the one before it when it is last, so no name starts or ends with a separator ({type}/{ticket}-{slug} without a ticket gives feat/slug). Reading a ticket back out of an existing branch never depends on this pattern.'),
|
|
92
|
+
update_strategy: gitUpdateStrategy.default('merge').describe('How a feature branch is brought up to date with its base. merge (default) = merge the base into the branch, as before this key existed. rebase = rebase the branch onto origin/<base> and publish with --force-with-lease, never a merge of the base into the branch. Rebase rewrites history, so the agent still asks for it unless the git-history-discipline rule already authorises the rewrite (the user asked this turn, an unrevoked standing instruction, or a pull --rebase the user started); this key decides which operation is proposed, never whether one is authorised.'),
|
|
93
|
+
}).default({}),
|
|
96
94
|
github: z.object({
|
|
97
95
|
pr_reply_method: replyMethod.default('create_review_comment').describe('How the agent replies to PR review comments. create_review_comment = post a new review comment (works on every GitHub plan). replies_endpoint = thread the reply under the original comment (needs the newer REST endpoint). auto = detect at runtime, prefer threaded replies when available.'),
|
|
98
96
|
}),
|
|
@@ -140,18 +138,21 @@ export const settingsSchema = z.object({
|
|
|
140
138
|
phase: z.number().int().min(0).default(200).describe('Per-marker character cap for phase markers (Phase=Refine, Phase=Plan, …) in the chat-history log. Rarely needs tuning.'),
|
|
141
139
|
}),
|
|
142
140
|
}),
|
|
143
|
-
pipelines: z.object({
|
|
144
|
-
skill_improvement: z.boolean().default(true).describe('After a meaningful task the agent proposes a learning-capture turn (new skill, rule tweak, guideline). Turn off if you find the prompts noisy — you can still run /memory:promote manually.'),
|
|
145
|
-
}),
|
|
146
141
|
roadmap: z.object({
|
|
147
|
-
skip_pre_run_gate: z.boolean().default(true).describe('Skip the /roadmap:process-* pre-run confirmation gate. true (default) starts processing immediately and surfaces the resolved config inline; false shows the numbered-options gate and waits. A genuine "which roadmap?" ambiguity always prompts regardless.'),
|
|
148
142
|
quality_cadence: qualityCadence.default('per_phase').describe('When the agent runs the full quality / test suite during /roadmap:process-* runs. per_phase = after each phase boundary (default since 2026-09-13 — end_of_roadmap lets errors compound across phases, which is expensive in a multi-phase autonomous run nobody is watching). end_of_roadmap = once, after the last step (fastest). per_step = after every single step (slowest, highest confidence).'),
|
|
149
|
-
dashboard_regen_cadence: regenCadence.default('every_5_steps').describe('How often the agent regenerates agents/roadmaps/dashboard.md during a roadmap run. every_5_steps = batch the regen (default). per_step = after every step (freshest dashboard, highest subprocess overhead). phase_boundary = only at phase edges. A rename, phase add, or archive always regenerates immediately regardless.'),
|
|
150
143
|
horizon_weeks: z.number().int().min(0).default(0).describe('Optional planning horizon (weeks) the agent shows in roadmap framing ("next 4 weeks"). Set 0 to omit the horizon — most teams prefer to ship without a hardcoded window.'),
|
|
151
144
|
gate_budget: z.object({
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
145
|
+
// `.min(0)` is kept deliberately, at a known cost: the settings-
|
|
146
|
+
// reference generator renders a constrained nullable number as
|
|
147
|
+
// type `unknown` rather than `number,null` (it reads `node.type`,
|
|
148
|
+
// which a constrained nullable emits as an `anyOf` instead).
|
|
149
|
+
// Eight keys already render that way. Dropping the constraint
|
|
150
|
+
// would buy a nicer doc cell by letting a negative USD ceiling
|
|
151
|
+
// into the schema, and a cap that refuses everything is a worse
|
|
152
|
+
// outcome than an uninformative table cell.
|
|
153
|
+
max_cost_per_run_usd: z.number().min(0).nullable().default(null).describe('Per-run USD ceiling for a CLASS-1 roadmap blocker executed via `agent-config gates --execute`. A class-1 entry whose **Budget:** field states a larger figure renders its consent line instead of running. null (default) = no per-run ceiling, per ADR-279: a spend bound applies only where one was set, and the absence of a bound is not a refusal. Bounds the size of an authorised spend; never supplies the authorisation — `--confirm` is still required on every class-1 run, set or unset.'),
|
|
154
|
+
max_cost_per_rolling_7d_usd: z.number().min(0).nullable().default(null).describe('Rolling 7-day USD ceiling for class-1 gate execution, summed from the append-only receipt ledger at agents/runtime/state/gate-budget-ledger.jsonl. A run whose estimate would cross it renders instead of running. null (default) = no rolling ceiling, per ADR-279. A per-run cap alone bounds one mistake, not a week of them, which is why option (a) of b-gate-budget-preauth carries two numbers — but each cap now bounds on its own, so setting one and leaving the other null is supported.'),
|
|
155
|
+
}).default({ max_cost_per_run_usd: null, max_cost_per_rolling_7d_usd: null }),
|
|
155
156
|
}),
|
|
156
157
|
planning: z.object({
|
|
157
158
|
closure_pass: z.boolean().default(true).describe('Gate C — plan-closure pass. true (default) = a plan-artifact ask (/roadmap:create, roadmap-writing, /feature:plan, /feature:roadmap, /roadmap:materialize, /implement-ticket, /jira-ticket, /analyze:inbox, /analyze:roadmap-repos) ends in a closure pass (/challenge-me closure): every foreseeable decision is closed at the lowest rung that owns it and written into the roadmap\'s "## Decisions" table, so a long run never meets a question planning could have closed. false = inert, plan asks author directly. An explicit user bypass always wins for that turn and is counted as a bypass rather than as an absent closure.'),
|
|
@@ -193,53 +194,21 @@ export const settingsSchema = z.object({
|
|
|
193
194
|
code_graph: z.object({
|
|
194
195
|
consumer_index_paths: z.array(z.string()).default([]).describe("Extra project-relative paths where THIS project keeps a code-graph index another tool wrote. The built-in list is deliberately vendor-neutral (graph.json, code-graph.json, .code-graph/graph.json) and names no tool, so a tool that writes its index elsewhere is named here rather than waited for. A graph found this way LOADS and answers query and explain with every edge tagged read-from-elsewhere; the gate verbs (impact, untested, dead) refuse a graph made only of such edges and say so, because an empty answer from a gate must not read as 'nothing found' when it means 'nothing trusted'. Absolute paths and paths escaping the project root are ignored."),
|
|
195
196
|
}).default({}),
|
|
196
|
-
consistency: z.object({
|
|
197
|
-
cross_source: crossSourceMode.default('on').describe('Consumed by the cross-source-consistency rule. When the agent works from multiple sources (ticket text, an attached image/mockup, the spec, the codebase) it checks them against each other and asks before proceeding on a discrepancy — instead of silently guessing. on (default) = surface every real cross-source contradiction / silent-scope-expansion as one question; auto = surface only high-confidence contradictions, state low-confidence as an assumption; off = no cross-source checking.'),
|
|
198
|
-
}).default({ cross_source: 'on' }),
|
|
199
197
|
screenshots: z.object({
|
|
200
198
|
identity_allowlist: z.array(z.string()).default([]).describe("Consumed by the doc-screenshot-hygiene rule and screenshot-hygiene skill. Public identity tokens SAFE to show unredacted in a documentation screenshot — the maintainer's own public handles plus well-known fake-data tokens. Not a general fake-data dictionary and not identity-resolution: everything not listed is treated as sensitive by default, and a public handle co-located with a real name does not whitelist the real name. Default [] = nothing auto-allowed."),
|
|
201
199
|
forbid_terminal_capture: z.boolean().default(true).describe('Consumed by the doc-screenshot-hygiene rule. true (default) = terminal/CLI/IDE screenshots are forbidden (highest leak vector: absolute local paths, env tokens); use text code blocks with text redaction instead. false = allowed, still subject to the data-bearing human gate.'),
|
|
202
200
|
data_bearing_gate: z.enum(['on', 'off']).default('on').describe('Consumed by the doc-screenshot-hygiene rule. on (default) = a data-bearing screenshot embed is gated behind this-turn human confirmation; uncertain/unresolved regions redact-or-refuse, never ship-and-hope; illustrative/no-data screenshots may embed with a stated justification. off = no data-bearing gate (the anonymization taxonomy still applies).'),
|
|
203
201
|
}).default({ identity_allowlist: [], forbid_terminal_capture: true, data_bearing_gate: 'on' }),
|
|
204
|
-
telegraph: z.object({
|
|
205
|
-
speak: z.boolean().default(false).describe('Whether the telegraph-speak rule ships at all. false (default) = DORMANT: compile_router omits the rule from dist/router.json entirely, so its body never reaches a host. This is the only lever that stops the cost. Set true only after an output-side bench clears the kill-criterion bar (docs/adrs/telegraph/0002).'),
|
|
206
|
-
}).default({ speak: false }),
|
|
207
|
-
tokens: z.object({
|
|
208
|
-
rich_skills: richSkillsMode.default('on').describe('Whether skills marked token_budget_class: rich may load in full (exempt from telegraph-speak + thin-projector trimming), consumed by the token-budget-discipline rule. on = allowed (default); off = fall back to standard condensed behavior; ask = surface an estimated token delta (tokens, not dollars) and ask once per session before loading.'),
|
|
209
|
-
}).default({ rich_skills: 'on' }),
|
|
210
202
|
verbosity: z.object({
|
|
211
|
-
intent_announcements: z.boolean().default(false).describe('Intent narration before tool batches ("Let me check X…"). Only honored when personal.play_by_play is ALSO true (the direct-answers narration carve-out requires both). false (default) = act and emit the result.'),
|
|
212
|
-
preview_artifacts: z.boolean().default(false).describe('Show generated commit messages, PR titles/bodies, branch names before acting. false (default) = use generated content directly (/commit terse path).'),
|
|
213
|
-
routine_confirmations: z.boolean().default(false).describe('Confirmation prompts for routine workflow steps with one obvious answer. Iron-Law gates (commit-policy, scope-control git-ops, Hard Floor) ALWAYS ask regardless.'),
|
|
214
203
|
offer_council_in_delivery: z.boolean().default(false).describe('Offer "run AI Council on this?" inside delivery commands (/feature-plan, /review-changes, /roadmap-create). Council commands themselves are unaffected.'),
|
|
215
|
-
|
|
216
|
-
}).default({
|
|
217
|
-
intent_announcements: false,
|
|
218
|
-
preview_artifacts: false,
|
|
219
|
-
routine_confirmations: false,
|
|
220
|
-
offer_council_in_delivery: false,
|
|
221
|
-
post_action_reports: 'minimal',
|
|
222
|
-
}),
|
|
204
|
+
}).default({ offer_council_in_delivery: false }),
|
|
223
205
|
code_style: z.object({
|
|
224
206
|
docblocks: z.enum(['minimal', 'full']).default('minimal').describe('Consumed by the code-comment-discipline rule. minimal (default) = no signature-mirroring docblocks; docblocks only for machine-relevant precision (generics, array shapes) or genuine why-context. full = the exported public surface of a library package may carry one-line summary docblocks; the redundancy ban still holds.'),
|
|
225
207
|
}).default({ docblocks: 'minimal' }),
|
|
226
208
|
reasoning: z.object({
|
|
227
209
|
enabled: z.boolean().default(true).describe('Master switch for the Reasoning Discipline Protocol (RDP). false = the whole layer is inert (zero overhead).'),
|
|
228
|
-
auto_gate: z.boolean().default(true).describe('Engage the discipline only where it pays, using table-free signals (task triviality + agent-self-assessed host reasoning strength; no runtime model->band lookup, per ADR-035). false = gate on task-signal + the component toggles only.'),
|
|
229
|
-
components: z.object({
|
|
230
|
-
orchestrator: z.boolean().default(true).describe('Sequence the reasoning chain (ground->intent->notes->gather->audit->verify) as one system; the single coordination point.'),
|
|
231
|
-
notes_first: z.boolean().default(true).describe('Keep hypotheses/predictions/decisions in session notes; the response carries conclusions + evidence only.'),
|
|
232
|
-
grounding: z.boolean().default(true).describe('Explore the environment / close info-gaps before designing.'),
|
|
233
|
-
intent: z.boolean().default(true).describe('Infer the underlying goal before solving the literal ask (standard host only).'),
|
|
234
|
-
complexity_first: z.boolean().default(true).describe('Risk-first: resolve the load-bearing unknown before the easy parts (RDP derivation, not a Fable-documented behavior).'),
|
|
235
|
-
verifier_default: z.boolean().default(true).describe('Run a fresh-context verifier on the structural-complexity gate (branching/constraints/stateful/irreversible + token floor).'),
|
|
236
|
-
prediction_tracking: z.boolean().default(true).describe('Log prediction + confidence + outcome + lesson (calibration loop).'),
|
|
237
|
-
decision_ledger: z.boolean().default(true).describe('Log decision + alternatives + reason + revisit-if; escalates to decision-record/ADR when durable.'),
|
|
238
|
-
uncertainty_budget: z.boolean().default(true).describe('Per-dimension uncertainty score that feeds adaptive effort.'),
|
|
239
|
-
}).default({}),
|
|
240
210
|
}).default({}),
|
|
241
211
|
subagents: z.object({
|
|
242
|
-
downshift: z.boolean().default(true).describe('Route delegable sub-tasks to the lowest-capable model tier (cost + speed via model downshift). false = every subagent runs on the session tier.'),
|
|
243
212
|
quota_arbitrage: z.boolean().default(true).describe('Prefer a separate quota-pool model for delegable sub-tasks where the host manifest reports one. Optional bonus only — identical behaviour (minus the quota win) where unsupported. Never load-bearing.'),
|
|
244
213
|
model_map: z.object({
|
|
245
214
|
lite: z.string().default('').describe('Model alias for lite-tier sub-tasks. Empty = the tier runtime default.'),
|
|
@@ -249,7 +218,7 @@ export const settingsSchema = z.object({
|
|
|
249
218
|
implementer_model: z.string().default('').describe('Override the model the orchestrator dispatches to subagents that write code (e.g. claude-sonnet-4, gpt-5). Empty (default) = inherit the session\'s primary model — cheapest and usually right.'),
|
|
250
219
|
judge_model: z.string().default('').describe('Override the model used for review / judge subagents that critique implementer output. Empty (default) = one tier above the implementer model — picks up nuance the implementer missed.'),
|
|
251
220
|
model_ceiling: z.string().default('').describe('Session-wide model CEILING for subagents (spend cap). Empty (default) = no ceiling. When set, suite-owned CLI spawn wrappers export CLAUDE_CODE_SUBAGENT_MODEL to the sessions they launch. Class C: a human sets it; the agent never writes or infers one.'),
|
|
252
|
-
max_parallel: z.number().int().min(1).default(3).describe('
|
|
221
|
+
max_parallel: z.number().int().min(1).default(3).describe('Limit on subagents running in parallel during /do-in-parallel, /do-competitively, and /judge runs — a value the model reads from settings; no code counts spawns against it. Raise for faster fan-out, lower if you hit rate limits or want lower token spend.'),
|
|
253
222
|
adversarial_council: z.enum(['off', 'ask', 'on']).default('off').describe('Opt-in adversarial-verification-council mode (subagent-orchestration Mode 9, ADR-122). off (default) = never runs; ask = offer it on an explicit high-risk change; on = auto-run on high-risk changes. Advisory only — a panel of distinct-model skeptics red-teams a real change for defect FINDING coverage and NEVER auto-gates it (Hard Floor). Stays default-off until the adversarial-council-finding-coverage claim is backed.'),
|
|
254
223
|
}),
|
|
255
224
|
// `worktrees.mode` was DELETED (ADR-229). Worktree creation is
|
|
@@ -259,12 +228,11 @@ export const settingsSchema = z.object({
|
|
|
259
228
|
model: z.string().default('auto').describe("Model handed to the codex CLI. 'auto' (default) = pass no --model flag so the CLI's own default applies — tracks the subscription's current strongest model instead of pinning a stale ID. Any other value passes through verbatim as `--model <value>`."),
|
|
260
229
|
allow_delegate: z.boolean().default(false).describe('Second opt-in for the only wrapper that delegates write access (/team:delegate). false (default) = delegate refuses even when /team itself is available. Availability (codex CLI installed + authenticated) is necessary but not sufficient — this key must ALSO be true before delegation is reachable.'),
|
|
261
230
|
max_calls_per_day: z.number().int().min(0).default(50).describe('Per-day cap on team calls, read against the EXISTING cli_call_budget openai bucket (~/.event4u/agent-config/cli-calls.json, daily UTC reset) — one subscription, one counter, never a parallel count. 0 = block all team calls.'),
|
|
262
|
-
suppress_setup_hint: z.boolean().default(false).describe('Suppress the one-line wizard/init recommendation to set up the codex plugin on Claude-Code hosts. Cosmetic only — never changes behavior.'),
|
|
263
231
|
review_gate: z.object({
|
|
264
232
|
managed: z.boolean().default(false).describe("Managed governance of the codex plugin's Stop-hook Review Gate (road-to-team-mode Phase 4). false (default) = byte-identical pre-Phase-4 behavior: no counting, no circuit breaker. true = count consecutive BLOCK verdicts per session and trip the circuit breaker at max_consecutive_blocks."),
|
|
265
233
|
max_consecutive_blocks: z.number().int().min(1).default(3).describe('Circuit-breaker bound: after this many CONSECUTIVE BLOCK verdicts in one session, a visible notice is injected exactly once and the managed layer stops re-blocking — the user decides, never an infinite Claude↔Codex loop. An ALLOW verdict resets the counter. Positive integer.'),
|
|
266
234
|
}).default({ managed: false, max_consecutive_blocks: 3 }),
|
|
267
|
-
}).default({ model: 'auto', allow_delegate: false, max_calls_per_day: 50,
|
|
235
|
+
}).default({ model: 'auto', allow_delegate: false, max_calls_per_day: 50, review_gate: { managed: false, max_consecutive_blocks: 3 } }),
|
|
268
236
|
emergency: z.object({
|
|
269
237
|
orchestration_halt: z.boolean().default(false).describe('The one audited incident switch over the always-on orchestration stack (subagents, council, team). NOT an activation gate: false (default) = the stack runs normally. true = halted; arming requires no ceremony. Disarming (returning to false) requires orchestration_halt_justification to be a non-empty string. Both transitions emit one telemetry line.'),
|
|
270
238
|
orchestration_halt_justification: z.string().default('').describe('Required non-empty before orchestration_halt may return to false. Ignored while arming the halt.'),
|
|
@@ -273,21 +241,13 @@ export const settingsSchema = z.object({
|
|
|
273
241
|
onboarded: z.boolean().default(false).describe('Set to true once the developer has completed `agent-config setup`. The onboarding-gate rule blocks the first turn of every chat until this is true. Toggle back to false to re-trigger the wizard.'),
|
|
274
242
|
}),
|
|
275
243
|
commands: z.object({
|
|
276
|
-
auto_detect: z.enum(['enabled', 'warn', 'disabled']).default('enabled').describe('Global kill-switch for orchestrator auto-detection (6.1.0 non-interactive-contract). enabled (default) = /judge, /fix, /analytics, /tests, /override auto-detect their sub-command per a confidence-tiered table; warn = detect but always confirm before routing; disabled = never auto-detect (always show the menu interactively, require an explicit sub-command in CI). Per-orchestrator override: auto_detect:false in front-matter. Per-invocation: --no-auto-detect.'),
|
|
277
244
|
suggestion: z.object({
|
|
278
|
-
enabled: z.boolean().default(true).describe('Master switch for the slash-command suggestion layer. When on, the agent offers numbered options ("did you mean /commit?") instead of guessing. Turn off if you prefer to type every command yourself.'),
|
|
279
|
-
confidence_floor: z.number().min(0).max(1).default(0.6).describe('Minimum semantic-match score (0.0–1.0) before a command is offered as a suggestion. 0.6 (default) balances precision and recall. Raise toward 0.8 for fewer false positives, lower for broader hints.'),
|
|
280
|
-
cooldown_seconds: z.number().int().min(0).default(600).describe('How long (seconds) the suggester waits before offering the same command again after you ignored it. Default 600s (10 min) keeps the agent from nagging. Set 0 to disable the cooldown.'),
|
|
281
|
-
max_options: z.number().int().min(0).default(4).describe('Maximum number of command suggestions shown in a single numbered-options block, before the "Proceed as-is" escape. Lower for terser prompts, raise if you regularly want broader fan-out.'),
|
|
282
245
|
blocklist: z.array(z.string()).default([]).describe('Slash-command names that should never be suggested, one per line (e.g. "commit", "create-pr"). Useful if a command misfires on your common phrasing.'),
|
|
283
246
|
}),
|
|
284
247
|
create_pr: z.object({
|
|
285
248
|
preview_description: z.boolean().default(false).describe('When /create-pr runs, show the generated title and body and wait for confirmation before opening the PR. Off by default (zero-friction PR creation); turn on if you want a last-look gate.'),
|
|
286
249
|
detail_level: z.enum(['min', 'med', 'max']).default('min').describe('Verbosity tier for the generated PR description body. min (default) = title + 2-3 sentence what/why/impact + linked ticket (token-frugal); med = min + grouped changes + tests note; max = med + how-to-test + edge cases + reviewer guidance. Critical info (breaking changes, migrations, security, rollback) is ALWAYS included at every tier — the tier governs explanatory depth, never whether a critical callout appears.'),
|
|
287
|
-
api_examples: z.boolean().default(true).describe('JSON request/response examples for API-endpoint changes. true (default) = include a fenced example ONLY when grounded in a real source (response DTO/resource, OpenAPI/schema, test fixture, or an actual probe); no grounded source → a one-line pointer, never an invented example. false = never add API examples.'),
|
|
288
250
|
screenshots: z.boolean().default(false).describe('Screenshots for frontend changes. false (default) = never attempt. true = attempt when the host has browser/preview tooling and the diff touches a frontend surface; capability-gated (emits a one-line note and leaves the placeholder when tooling is absent, never fails or blocks the PR). Before/after + changed-region highlighting is best-effort.'),
|
|
289
|
-
ui_paths: z.array(z.string()).default([]).describe('Optional glob list that makes frontend detection explicit instead of heuristic (e.g. ["resources/views/**", "src/pages/**"]). Empty (default) = a light path/extension heuristic that fails open (no false enrichment when the surface is ambiguous).'),
|
|
290
|
-
api_paths: z.array(z.string()).default([]).describe('Optional glob list that makes API-endpoint detection explicit instead of heuristic (e.g. ["app/Http/Controllers/Api/**", "src/pages/api/**"]). Empty (default) = a light path/extension heuristic that fails open.'),
|
|
291
251
|
}),
|
|
292
252
|
}),
|
|
293
253
|
continuity: z.object({
|
|
@@ -295,8 +255,6 @@ export const settingsSchema = z.object({
|
|
|
295
255
|
run_checkpoints: z.enum(['on', 'off']).default('on').describe('Deterministic run-checkpoint production at session end (road-to-continuity-writer-activation Phase 1.4). on (default) = a session above the recycle threshold and inside a running roadmap contract leaves agents/runtime/state/checkpoints/<run>.json, so a killed run resumes from a derived checkpoint rather than from bookkeeping. off = no checkpoint; continuity writing, the recycle advisory and the context-fill surface are unaffected. Default ON because it is the behavior the tree already had — the switch exists to make the three session-end handlers independently disableable, not to change what ships.'),
|
|
296
256
|
}),
|
|
297
257
|
memory: z.object({
|
|
298
|
-
cadence: memoryCadence.default('always').describe('Cadence of the 🧠 memory-visibility line after a memory-consulting step. always (default) = show whenever a memory type was asked; auto = show only when 3+ types were consulted (less noise); never = suppress. Distinct from rule_loading_tier — owns its own key since the 2026-06-01 untangle.'),
|
|
299
|
-
review_threshold: z.number().int().min(0).default(10).describe('Maximum number of memory entries /memory:load surfaces inline before falling back to a summary view. Default 10 keeps the chat readable. Raise to see more candidates, lower to keep the context tight.'),
|
|
300
258
|
redact_patterns: z.array(z.string()).default([]).describe('Regex patterns (one per line) that scrub matches from chat-history transcripts and memory before they hit disk. Use for secrets, customer names, internal URLs. Patterns are anchored and case-insensitive.'),
|
|
301
259
|
session_index: z.enum(['on', 'off']).default('off').describe('Opt-in compact memory index at session start (road-to-memory-retrieval-economy P5). on = inject a compact id + title + ~tokens index of curated entries (hard cap 30 rows, bodies never included) through the hot-context hook; the agent fetches full entries via memory_get on demand. off (default) = no injection — the ship-criterion (measured hit-rate gain) is unproven, so off unless proven.'),
|
|
302
260
|
learn_on_session_end: z.boolean().default(false).describe('session_end learning-sidecar aggregation (road-to-reachable-code-memory P4). true = the session_end hook aggregates agents/memory/intake/*.jsonl through the learning sidecar into the gitignored .agent-learning.json + LESSONS.md (local-only, 2 s budget, fail-open; promotion stays human via /memory:propose). false (default, council 2026-07-27) = no-op; the flip is proposed only after the 30-day dogfood shows non-trivial signal AND session-end p95 < 2 s.'),
|
|
@@ -305,22 +263,11 @@ export const settingsSchema = z.object({
|
|
|
305
263
|
global_sharing: z.object({
|
|
306
264
|
enabled: z.boolean().default(true).describe('Master switch for the file-first global knowledge-card store (ADR-100; default-ON per ADR-119, the validated bounded-downside flip superseding ADR-103 — write-time redaction incl. hidden-unicode hardening, narrowest tier default, pre-registered demotion trigger). User-global setting — keep in ~/.event4u/agent-config/agent-settings.yml. false fully no-ops the layer (single-key revert); project-local cards (v1) are unaffected.'),
|
|
307
265
|
allowed_tiers: z.array(z.string()).default(['public']).describe('Origin tiers auto-eligible to cross a project boundary. proprietary is manual-only regardless (the gate hard-codes it), so an in-house schema never auto-shares.'),
|
|
308
|
-
redaction: z.object({
|
|
309
|
-
enabled: z.boolean().default(true).describe('Run the privacy-floor + source-confidentiality scan before any card goes global.'),
|
|
310
|
-
halt_on_trigger: z.boolean().default(true).describe('Halt-and-surface on a confidential-pattern hit; never silent-share, never auto-rewrite.'),
|
|
311
|
-
}).default({}),
|
|
312
|
-
auto_promote_threshold: z.number().int().min(1).default(2).describe('Distinct-repo count at which a public/vendor card triggers a promotion suggestion (never a silent write).'),
|
|
313
|
-
freshness: z.object({
|
|
314
|
-
hypothesis_after_days: z.number().int().min(0).default(90).describe('A global card older than this is lead-only (positive structure must be re-confirmed before use).'),
|
|
315
|
-
stale_after_days: z.number().int().min(0).default(180).describe('A global card older than this is skipped until re-verified.'),
|
|
316
|
-
}).default({}),
|
|
317
266
|
}).default({}),
|
|
318
267
|
}).default({}),
|
|
319
268
|
hooks: z.object({
|
|
320
269
|
concern_budget: z.object({
|
|
321
|
-
max_per_event: z.number().int().min(1).default(8).describe('Maximum number of concerns (issues / warnings) a single hook may raise per (platform, event) pair before the hook is rate-limited. Default 8 prevents noisy hooks from drowning out high-signal ones.'),
|
|
322
270
|
tier1_concerns: z.array(z.string()).default([]).describe('Concern IDs (one per line) that are allowed to block the run on failure rather than warn. Reserved for high-confidence guards — leave empty unless you maintain custom hooks.'),
|
|
323
|
-
hard_fail: z.boolean().default(false).describe('When a hook exceeds hooks.concern_budget.max_per_event, fail the run (true) instead of warning and continuing (false, default). Turn on in CI when you want hook quality to gate merges.'),
|
|
324
271
|
}),
|
|
325
272
|
verify_before_complete: z.object({
|
|
326
273
|
touched_file_quality: z.enum(['off', 'shadow', 'warn']).default('off').describe("Stop-slot pass that runs the project's OWN quality commands — the ones resolve_toolchain() already reports — over the files this turn edited. Default off. `shadow` records a per-run result and emits nothing; `warn` adds ONE advisory line of at most 200 bytes. Never blocks and never counts as verification: a command recorded here never reaches _lib/verification_command.ts, so a clean eslint run cannot let a turn claim it verified anything. A writing command runs only in its check form (pint --test) or not at all, and a command with no per-file form is skipped rather than run project-wide at every stop."),
|
|
@@ -354,23 +301,18 @@ export const settingsSchema = z.object({
|
|
|
354
301
|
// fires is decided by each detector's own trigger conditions, not by a
|
|
355
302
|
// flag. A leftover `hooks.turn_end_gate.*` block from an older install
|
|
356
303
|
// warns once on stderr and is ignored — see REMOVED_KEYS in
|
|
357
|
-
// `src/scripts/_lib/
|
|
304
|
+
// `src/scripts/_lib/settings_removed_keys.ts`.
|
|
358
305
|
}),
|
|
359
306
|
decision_engine: z.object({
|
|
360
|
-
surface_traces: z.boolean().default(false).describe('Emit DecisionTraceHook events that surface why the agent picked one option over another. Useful when debugging unexpected choices; off by default to keep chat noise low.'),
|
|
361
307
|
min_confidence: confidenceBand.default('off').describe('During Phase=Plan, refuse to advance to Phase=Implement if confidence is below this band. off (default) = no gate. low / medium / high = raise the floor; on miss, decision_engine.on_block decides what happens.'),
|
|
362
308
|
block_on_risk: confidenceBand.default('off').describe('During Phase=Implement, refuse to act when the risk class meets or exceeds this band. off (default) = no gate. low / medium / high = stricter ceilings; pairs with decision_engine.on_block.'),
|
|
363
309
|
require_memory_hits: z.boolean().default(false).describe('During Phase=Refine, require at least one relevant memory hit (skill, ADR, past decision) before the agent proceeds. Off by default; turn on for highly conventional codebases where memory should always inform decisions.'),
|
|
364
310
|
on_block: onBlock.default('stop').describe('What the decision engine does when a gate (min_confidence / block_on_risk / require_memory_hits) fires. stop (default) = halt and surface the reason. ask = present numbered options. warn = log and continue.'),
|
|
365
|
-
ask_timeout_seconds: z.number().int().min(0).default(30).describe('Non-TTY timeout (seconds) for decision_engine.on_block = ask. After this elapses without input,
|
|
366
|
-
on_block_fallback: onBlockFallback.default('stop').describe('Resolution when decision_engine.on_block = ask times out (see decision_engine.ask_timeout_seconds). stop (default) = halt the run. warn = log and continue with the agent\'s best guess.'),
|
|
311
|
+
ask_timeout_seconds: z.number().int().min(0).default(30).describe('Non-TTY timeout (seconds) for decision_engine.on_block = ask. After this elapses without input, the engine stops (fail-safe). Default 30s; raise for slow human review, 0 = wait forever.'),
|
|
367
312
|
}),
|
|
368
313
|
update_check: z.object({
|
|
369
314
|
enabled: z.boolean().default(true).describe('Once per day the agent checks the npm registry for a newer agent-config release and surfaces a one-line banner if one exists. Turn off in air-gapped environments or to silence the banner.'),
|
|
370
315
|
}),
|
|
371
|
-
explain: z.object({
|
|
372
|
-
enable_last: z.boolean().default(true).describe('Enable the `agent-config explain last` command, which prints the reasoning behind the agent\'s most recent decision (last tool call, last suggestion). Disable if you never use it and want a smaller CLI surface.'),
|
|
373
|
-
}),
|
|
374
316
|
legal_review_prep: z.object({
|
|
375
317
|
acknowledged: z.boolean().default(false).describe('I understand the legal-review-prep pack provides templates and general information ONLY — it is NOT legal advice, creates no attorney-client relationship, and never replaces a licensed lawyer. Individual cases require an attorney. The pack stays inactive until this is checked.'),
|
|
376
318
|
require_council: z.boolean().default(true).describe('Gate legal work-product behind a multi-model AI-council / deep-research pass (defense-in-depth: documented multi-stage review + audit trail; fail-closed when no council is configured). Leave on for the safest posture. Turning it off lets single-model legal output through — not recommended for a high-risk pack.'),
|
|
@@ -163,6 +163,13 @@ export function idf(term, stats) {
|
|
|
163
163
|
* absent or every flag off, the arithmetic is exactly the Python-parity one.
|
|
164
164
|
*/
|
|
165
165
|
export function scoreSkill(taskTerms, skill, terms, opts = {}, stats) {
|
|
166
|
+
return roundHalfToEven(rawSkillScore(taskTerms, skill, terms, opts, stats));
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* The score before `roundHalfToEven` — what {@link scoreSkill} rounds. Exposed
|
|
170
|
+
* only so `tieBreakUnrounded` can order a block of equal integers by it.
|
|
171
|
+
*/
|
|
172
|
+
export function rawSkillScore(taskTerms, skill, terms, opts = {}, stats) {
|
|
166
173
|
if (opts.idfWeighting && !stats) {
|
|
167
174
|
throw new Error('scoreSkill: idfWeighting is set but no TermStats was passed — scoring unweighted here ' +
|
|
168
175
|
'would publish a baseline number under the idf label. Build stats with buildTermStats.');
|
|
@@ -197,7 +204,7 @@ export function scoreSkill(taskTerms, skill, terms, opts = {}, stats) {
|
|
|
197
204
|
break;
|
|
198
205
|
}
|
|
199
206
|
}
|
|
200
|
-
return
|
|
207
|
+
return overlap * 70 + personaHit * 30;
|
|
201
208
|
}
|
|
202
209
|
/**
|
|
203
210
|
* Rank an in-memory skill set. Zero scores are dropped; ties break on name, so
|
|
@@ -208,13 +215,32 @@ export function rankSkills(task, skills, opts = {}) {
|
|
|
208
215
|
const termSets = skills.map((s) => skillTerms(s, opts));
|
|
209
216
|
const stats = opts.idfWeighting ? buildTermStats(skills, termSets) : undefined;
|
|
210
217
|
const rows = [];
|
|
218
|
+
const raw = new Map();
|
|
211
219
|
for (let i = 0; i < skills.length; i += 1) {
|
|
212
220
|
const skill = skills[i];
|
|
213
|
-
const
|
|
214
|
-
|
|
221
|
+
const unrounded = rawSkillScore(taskTerms, skill, termSets[i], opts, stats);
|
|
222
|
+
const score = roundHalfToEven(unrounded);
|
|
223
|
+
if (score > 0) {
|
|
215
224
|
rows.push({ name: skill.name, score, personas: [...(skill.personas ?? [])] });
|
|
225
|
+
raw.set(skill.name, unrounded);
|
|
226
|
+
}
|
|
216
227
|
}
|
|
217
|
-
rows.sort((a, b) => (
|
|
228
|
+
rows.sort((a, b) => compareRanked(a.name, a.score, b.name, b.score, opts, raw));
|
|
218
229
|
return rows;
|
|
219
230
|
}
|
|
231
|
+
/**
|
|
232
|
+
* The ranking order: score descending, then — only under `tieBreakUnrounded` —
|
|
233
|
+
* the unrounded score descending, then the name. One comparator for both
|
|
234
|
+
* rankers, so the flag cannot mean two orders in two places.
|
|
235
|
+
*/
|
|
236
|
+
export function compareRanked(aName, aScore, bName, bScore, opts, raw) {
|
|
237
|
+
if (bScore !== aScore)
|
|
238
|
+
return bScore - aScore;
|
|
239
|
+
if (opts.tieBreakUnrounded) {
|
|
240
|
+
const d = (raw.get(bName) ?? 0) - (raw.get(aName) ?? 0);
|
|
241
|
+
if (d !== 0)
|
|
242
|
+
return d;
|
|
243
|
+
}
|
|
244
|
+
return aName < bName ? -1 : aName > bName ? 1 : 0;
|
|
245
|
+
}
|
|
220
246
|
//# sourceMappingURL=skillRanking.js.map
|