@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
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a browser reads the URLs and names in an SVG, for the safety rules in
|
|
3
|
+
* `svg_rules.ts`: references decoded, controls stripped, CSS escapes resolved,
|
|
4
|
+
* and an element prefix stripped only where it is bound to the SVG namespace.
|
|
5
|
+
* Its own module so `svg_rules.ts` stays under the source-size ceiling.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/** Prefixes the document binds to the SVG namespace (`xmlns:svg="…/2000/svg"`). */
|
|
9
|
+
export function svgPrefixes(content: string): Set<string> {
|
|
10
|
+
const out = new Set<string>();
|
|
11
|
+
const re = /xmlns:([\w.-]+)\s*=\s*["']http:\/\/www\.w3\.org\/2000\/svg["']/gi;
|
|
12
|
+
let m: RegExpExecArray | null;
|
|
13
|
+
while ((m = re.exec(content)) !== null) out.add((m[1] ?? '').toLowerCase());
|
|
14
|
+
return out;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** The SVG local name: `svg:script` is a `script` where `svg` is bound to SVG; `foo:script` is not. */
|
|
18
|
+
export function localName(name: string, prefixes: ReadonlySet<string>): string {
|
|
19
|
+
const colon = name.indexOf(':');
|
|
20
|
+
return colon !== -1 && prefixes.has(name.slice(0, colon)) ? name.slice(colon + 1) : name;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Attributes read from the raw tag, unquoted values included — HTML parses those. */
|
|
24
|
+
export function rawAttrs(raw: string): Record<string, string> {
|
|
25
|
+
const out: Record<string, string> = {};
|
|
26
|
+
const re = /([\w:.-]+)\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>"'`=]+))/g;
|
|
27
|
+
let m: RegExpExecArray | null;
|
|
28
|
+
while ((m = re.exec(raw)) !== null) out[(m[1] ?? '').toLowerCase()] = m[2] ?? m[3] ?? m[4] ?? '';
|
|
29
|
+
return out;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Attributes whose value is followed as a URL. */
|
|
33
|
+
export const URL_ATTRS = new Set(['href', 'xlink:href', 'src']);
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
/** A URL that executes or opens a document when followed. */
|
|
37
|
+
export const isActiveUrl = (raw: string): boolean => /^(javascript:|data:text\/html)/i.test(resolvedUrl(raw));
|
|
38
|
+
|
|
39
|
+
const NAMED_URL_ENTITIES: Record<string, string> = {
|
|
40
|
+
colon: ':', sol: '/', tab: '\t', newline: '\n', period: '.', lpar: '(', rpar: ')', amp: '&',
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The URL a browser would actually resolve from an attribute value: character
|
|
45
|
+
* references decoded, leading/trailing C0 controls and spaces stripped, tab and
|
|
46
|
+
* newline removed anywhere. The trailing `;` of a reference is optional on
|
|
47
|
+
* purpose: an `.svg` parsed as XML needs it, but the same graphic inlined in an
|
|
48
|
+
* HTML host is parsed by the HTML tokenizer, which decodes `javascript:`
|
|
49
|
+
* too — over-reading XML here costs precision, under-reading HTML costs a miss.
|
|
50
|
+
* The raw value is attacker-chosen, so a scheme test
|
|
51
|
+
* against it is a test of one spelling — ` https:`, `ht\ttps:`, `javascript:`
|
|
52
|
+
* all load, and all passed.
|
|
53
|
+
*/
|
|
54
|
+
export function resolvedUrl(raw: string): string {
|
|
55
|
+
const decoded = raw.replace(/&(?:#x([0-9a-f]+)|#(\d+)|([a-z]+));?/gi, (m, hex, dec, name) => {
|
|
56
|
+
const cp = hex ? parseInt(hex, 16) : dec ? parseInt(dec, 10) : NaN;
|
|
57
|
+
if (!Number.isNaN(cp)) return cp <= 0x10ffff ? String.fromCodePoint(cp) : m;
|
|
58
|
+
return NAMED_URL_ENTITIES[(name as string).toLowerCase()] ?? m;
|
|
59
|
+
});
|
|
60
|
+
return decoded.replace(/^[\u0000- ]+|[\u0000- ]+$/g, '').replace(/[\t\n\r]/g, '');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** CSS escapes decoded: `\\68 ` and `\\h` both read `h`. */
|
|
64
|
+
export function cssUnescape(raw: string): string {
|
|
65
|
+
return raw.replace(/\\([0-9a-f]{1,6})\s?|\\(.)/gi, (m, hex, ch) => {
|
|
66
|
+
if (hex) {
|
|
67
|
+
const cp = parseInt(hex, 16);
|
|
68
|
+
return cp <= 0x10ffff ? String.fromCodePoint(cp) : m;
|
|
69
|
+
}
|
|
70
|
+
return ch as string;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
@@ -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
|
|
|
@@ -271,6 +271,28 @@ function segmentVerifies(rawWords: readonly string[]): boolean {
|
|
|
271
271
|
// the old token-anywhere regex accepted it by accident and neither
|
|
272
272
|
// explicit list named it, so the union seeding missed it too.
|
|
273
273
|
return rest.some((a) => a === 'test' || a.startsWith('--test'));
|
|
274
|
+
case 'agent-config':
|
|
275
|
+
// NEITHER `ui:render` NOR `xmllint` verifies here, and the first
|
|
276
|
+
// half of that was true, then false, and is true again.
|
|
277
|
+
//
|
|
278
|
+
// Step 3.5 of `road-to-svg-with-a-witness` taught this predicate
|
|
279
|
+
// `ui:render --profile asset`, reasoning that it is the one
|
|
280
|
+
// subcommand which opens the delivered file in a real engine. Step
|
|
281
|
+
// 2.1(b) of `road-to-svg-review-followups` removed it again on
|
|
282
|
+
// review claim C2, which is narrower than the first argument and
|
|
283
|
+
// refutes it: the turn-end gate's TRANSCRIPT path matches a command
|
|
284
|
+
// and never sees an exit code, so a call that rendered nothing —
|
|
285
|
+
// the ordinary case on a machine with no Playwright, where the
|
|
286
|
+
// command also exited 0 until the same day — discharged the
|
|
287
|
+
// obligation from its text alone.
|
|
288
|
+
//
|
|
289
|
+
// What replaces it reads the RENDER instead of the call:
|
|
290
|
+
// `hooks/svg_obligation.ts` matches a manifest to the file's own
|
|
291
|
+
// digest, and accepts a renderer-absent manifest only together with
|
|
292
|
+
// a clean static witness on those same bytes. `xmllint --noout`
|
|
293
|
+
// stays out for its original reason (S6): a file can parse and
|
|
294
|
+
// still be the wrong picture.
|
|
295
|
+
return false;
|
|
274
296
|
case 'scripts-run': {
|
|
275
297
|
// `./scripts-run src/scripts/lint_x` verifies; `…/rule_activation_census`
|
|
276
298
|
// writes a report and asserts nothing, which is why this keys on the
|
|
@@ -322,3 +344,40 @@ const _WIDE_CANDIDATE_RE =
|
|
|
322
344
|
export function mightBeVerification(command: string): boolean {
|
|
323
345
|
return _WIDE_CANDIDATE_RE.test(command);
|
|
324
346
|
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* `agent-config ui:render … --profile asset`, by shape.
|
|
350
|
+
*
|
|
351
|
+
* Moved here from `hooks/svg_obligation.ts` by finding 3 of this change's
|
|
352
|
+
* SECOND completion review: two detectors need it and one of them is in
|
|
353
|
+
* `_lib`, so a hook module was the wrong home. Re-exported there, so no
|
|
354
|
+
* caller moved.
|
|
355
|
+
*/
|
|
356
|
+
export function isAssetRenderCommand(command: string): boolean {
|
|
357
|
+
return /\bui:render\b/.test(command) && /--profile[= ]\s*asset\b/.test(command);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Did this command ATTEMPT to verify something — as opposed to: did it produce
|
|
362
|
+
* a verdict this gate may read?
|
|
363
|
+
*
|
|
364
|
+
* The distinction is the whole point, and the first review round and the
|
|
365
|
+
* second each saw one half of it. Round one (claim C2) was right that
|
|
366
|
+
* `isVerificationCommand` must NOT learn the asset render: the transcript path
|
|
367
|
+
* never sees an exit code, so the command's TEXT would have discharged the SVG
|
|
368
|
+
* obligation on a machine where the render produced nothing. Round two
|
|
369
|
+
* (finding 3) was right that removing it left detector C — "did any
|
|
370
|
+
* verification command follow the last edit" — unable to see the one command
|
|
371
|
+
* this package PRESCRIBES for an `.svg`, so the prescribed turn was refused.
|
|
372
|
+
*
|
|
373
|
+
* Both hold because they are about different detectors. Detector C asks
|
|
374
|
+
* whether the author tried; it is satisfied by `eslint` and must be satisfied
|
|
375
|
+
* by a render too. The SVG obligation asks what the render FOUND, and still
|
|
376
|
+
* reads the manifest and the file's digest — an attempt that produced nothing
|
|
377
|
+
* discharges nothing there, with a far better reason than detector C's.
|
|
378
|
+
*
|
|
379
|
+
* So: one predicate per question, and `isVerificationCommand` is unchanged.
|
|
380
|
+
*/
|
|
381
|
+
export function isVerificationAttempt(command: string): boolean {
|
|
382
|
+
return isVerificationCommand(command) || isAssetRenderCommand(command);
|
|
383
|
+
}
|
|
@@ -126,25 +126,35 @@ function lastMatch(re: RegExp, text: string): RegExpExecArray | null {
|
|
|
126
126
|
* carries `(?!`)`: a label followed by a backtick is the delimited form, which
|
|
127
127
|
* branch one already owns.
|
|
128
128
|
*
|
|
129
|
-
* The tail is
|
|
130
|
-
* this parser a whole step BLOCK already joined
|
|
131
|
-
* the line" can mean "the rest of the step"
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
129
|
+
* The tail is bounded by the EXPECTATION'S OWN DELIMITERS, not by the end of
|
|
130
|
+
* the line. A caller may hand this parser a whole step BLOCK already joined
|
|
131
|
+
* into one line, so "the rest of the line" can mean "the rest of the step": an
|
|
132
|
+
* end-anchored tail would lose the expectation of any step that carries prose
|
|
133
|
+
* after its clause. A slash-delimited regex therefore runs to the first
|
|
134
|
+
* UNESCAPED closing `/` — one not preceded by an odd number of backslashes —
|
|
135
|
+
* that is followed by whitespace or the end of the text, and an exit code is
|
|
136
|
+
* one non-space token; both self-terminating, so the step may continue and
|
|
137
|
+
* `-> /[1-9]/ and then note the result` still yields `[1-9]`.
|
|
137
138
|
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
* the
|
|
144
|
-
*
|
|
145
|
-
*
|
|
139
|
+
* The word UNESCAPED is load-bearing and was added on 2026-10-11 (step 1.1 of
|
|
140
|
+
* `road-to-svg-review-followups`, review claim C4). The tail used to be a lazy
|
|
141
|
+
* `\/.*?\/(?=\s|$)`, which stops at ANY `/` followed by a space — so a clause
|
|
142
|
+
* ending in ``-> /a\/ b/`` was cut at the escaped slash and parsed to the
|
|
143
|
+
* regex source `a\`. A pattern that deliberately matches a path separator is
|
|
144
|
+
* exactly the case that spells it `\/`, and the truncation was silent: a
|
|
145
|
+
* shorter regex is still a regex, so nothing reported the loss.
|
|
146
|
+
*
|
|
147
|
+
* It was capped at a single non-space token until 2026-10-11, which cost this
|
|
148
|
+
* form every expectation containing a space: `-> /Icon-only button/` parsed as
|
|
149
|
+
* a clause with NO expectation, and nothing reported the loss — the step simply
|
|
150
|
+
* read as unfalsifiable. The two forms now agree on every expectation rather
|
|
151
|
+
* than only the space-free ones; {@link VERIFY_ARROW_SOURCE} stays the single
|
|
152
|
+
* `$`-anchored decision about what an expectation IS, and this regex decides
|
|
153
|
+
* only where the tail ENDS. A bare word stays refused by the constant, so
|
|
154
|
+
* widening the boundary widened no grammar.
|
|
146
155
|
*/
|
|
147
|
-
const BACKTICKED_RE =
|
|
156
|
+
const BACKTICKED_RE =
|
|
157
|
+
/(?:`verify:`|verify:(?!`))\s*`([^`]+)`[ \t]*((?:->|→)[ \t]*(?:\/(?:[^\\/]|\\.)*\/(?=\s|$)|\S+))?/g;
|
|
148
158
|
|
|
149
159
|
/** Prose after the label. The MANUAL form; the body is bounded separately. */
|
|
150
160
|
const PROSE_RE = /(?:`verify:`|verify:(?!`))[ \t]*/g;
|
|
@@ -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]> = [
|