@event4u/agent-config 16.2.0 → 16.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.augment-plugin/marketplace.json +3 -3
- package/.augment-plugin/plugin.json +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +337 -234
- package/README.md +15 -13
- package/agents/templates/.ai-council.yml.example +26 -8
- package/dist/agent-src/commands/analyze/inbox.md +11 -8
- package/dist/agent-src/commands/analyze/roadmap-repos.md +1 -1
- package/dist/agent-src/commands/bug/fix.md +17 -2
- package/dist/agent-src/commands/bug/investigate.md +1 -1
- package/dist/agent-src/commands/commit/in-chunks.md +40 -31
- package/dist/agent-src/commands/commit.md +72 -33
- package/dist/agent-src/commands/condense.md +2 -8
- package/dist/agent-src/commands/council/debate.md +11 -7
- package/dist/agent-src/commands/council/default.md +10 -9
- package/dist/agent-src/commands/council.md +1 -1
- package/dist/agent-src/commands/estimate-ticket.md +1 -1
- package/dist/agent-src/commands/feature/explore.md +3 -3
- package/dist/agent-src/commands/feature/plan.md +2 -2
- package/dist/agent-src/commands/feature/roadmap.md +1 -1
- package/dist/agent-src/commands/fix/ci.md +18 -4
- package/dist/agent-src/commands/fix/commit-messages.md +48 -23
- package/dist/agent-src/commands/fix/pr-comments.md +3 -6
- package/dist/agent-src/commands/implement-ticket.md +4 -4
- package/dist/agent-src/commands/jira-ticket.md +1 -1
- package/dist/agent-src/commands/memory/add.md +4 -16
- package/dist/agent-src/commands/memory/load.md +5 -6
- package/dist/agent-src/commands/memory/promote.md +3 -16
- package/dist/agent-src/commands/mission/upgrade.md +3 -2
- package/dist/agent-src/commands/optimize/agents-dir.md +2 -2
- package/dist/agent-src/commands/optimize/deep.md +4 -2
- package/dist/agent-src/commands/optimize/rtk.md +4 -26
- package/dist/agent-src/commands/pr/create/description-only.md +18 -15
- package/dist/agent-src/commands/pr/create.md +42 -34
- package/dist/agent-src/commands/pr/merge.md +136 -9
- package/dist/agent-src/commands/prepare-for-review.md +13 -11
- package/dist/agent-src/commands/project/analyze.md +7 -35
- package/dist/agent-src/commands/refine-ticket.md +1 -1
- package/dist/agent-src/commands/review/changes.md +14 -19
- package/dist/agent-src/commands/roadmap/create.md +1 -1
- package/dist/agent-src/commands/roadmap/materialize.md +1 -1
- package/dist/agent-src/commands/roadmap/next.md +10 -1
- package/dist/agent-src/commands/roadmap/process-full.md +56 -42
- package/dist/agent-src/commands/roadmap/resolve-blockers.md +411 -0
- package/dist/agent-src/commands/roadmap/triage-parked.md +325 -0
- package/dist/agent-src/commands/roadmap.md +18 -4
- package/dist/agent-src/commands/tests/create.md +17 -3
- package/dist/agent-src/commands/tests/execute.md +22 -5
- package/dist/agent-src/commands/worktree/create.md +7 -3
- package/dist/agent-src/commands/worktree/verify.md +2 -1
- package/dist/agent-src/contexts/authority/decision-revisit-gate-enforcement.md +43 -0
- package/dist/agent-src/contexts/communication/rules-auto/design-fidelity-enforcement.md +24 -0
- package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +5 -3
- package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +7 -9
- package/dist/agent-src/contexts/contracts/command-suggestion-flow.md +8 -6
- package/dist/agent-src/contexts/contracts/frugality-charter.md +8 -5
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +7 -7
- package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +0 -1
- package/dist/agent-src/contexts/execution/evidence-discipline.md +2 -2
- package/dist/agent-src/contexts/execution/non-interactive-contract.md +5 -8
- package/dist/agent-src/contexts/execution/rdp-gate.md +4 -4
- package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +9 -8
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +99 -54
- package/dist/agent-src/contexts/execution/session-canary-enforcement-history.md +67 -0
- package/dist/agent-src/contexts/execution/subagent-routing.md +8 -8
- package/dist/agent-src/contexts/execution/subagent-steering.md +6 -4
- package/dist/agent-src/contexts/execution/terminal-states.md +2 -2
- package/dist/agent-src/contexts/execution/toolchain-resolver.md +95 -7
- package/dist/agent-src/contexts/subagent-configuration.md +1 -1
- package/dist/agent-src/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
- package/dist/agent-src/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
- package/dist/agent-src/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
- package/dist/agent-src/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
- package/dist/agent-src/guidelines/agent-infra/layered-settings.md +13 -1
- package/dist/agent-src/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
- package/dist/agent-src/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
- package/dist/agent-src/guidelines/agent-infra/size-and-scope.md +36 -0
- package/dist/agent-src/guidelines/php/git.md +15 -2
- package/dist/agent-src/rules/active-remediation.md +1 -2
- package/dist/agent-src/rules/analysis-skill-routing.md +0 -1
- package/dist/agent-src/rules/architecture.md +0 -1
- package/dist/agent-src/rules/artifact-drafting-protocol.md +0 -1
- package/dist/agent-src/rules/artifact-engagement-recording.md +0 -1
- package/dist/agent-src/rules/augment-edit-discipline.md +0 -1
- package/dist/agent-src/rules/autonomous-execution.md +1 -1
- package/dist/agent-src/rules/brand-consistency.md +0 -1
- package/dist/agent-src/rules/brand-source-of-truth.md +0 -1
- package/dist/agent-src/rules/broken-access-control.md +1 -1
- package/dist/agent-src/rules/cli-output-handling.md +0 -1
- package/dist/agent-src/rules/code-comment-discipline.md +0 -1
- package/dist/agent-src/rules/code-provenance.md +0 -1
- package/dist/agent-src/rules/command-suggestion-policy.md +1 -1
- package/dist/agent-src/rules/commit-conventions.md +1 -2
- package/dist/agent-src/rules/communication-through-line.md +1 -2
- package/dist/agent-src/rules/content-quoting-floor.md +1 -2
- package/dist/agent-src/rules/context-hygiene.md +6 -6
- package/dist/agent-src/rules/copilot-routing.md +1 -2
- package/dist/agent-src/rules/council-availability.md +4 -4
- package/dist/agent-src/rules/cross-source-consistency.md +4 -6
- package/dist/agent-src/rules/decision-revisit-gate.md +17 -35
- package/dist/agent-src/rules/delegation-policy.md +2 -3
- package/dist/agent-src/rules/design-fidelity.md +12 -16
- package/dist/agent-src/rules/design-review-after-ui-write.md +3 -3
- package/dist/agent-src/rules/devcontainer-routing.md +1 -2
- package/dist/agent-src/rules/doc-screenshot-hygiene.md +1 -1
- package/dist/agent-src/rules/docker-commands.md +0 -1
- package/dist/agent-src/rules/domain-adoption-policy.md +0 -1
- package/dist/agent-src/rules/domain-safety-disclaimer.md +1 -1
- package/dist/agent-src/rules/domain-safety-pii.md +1 -1
- package/dist/agent-src/rules/domain-safety-retention.md +1 -1
- package/dist/agent-src/rules/downstream-changes.md +0 -1
- package/dist/agent-src/rules/engineering-safety-floor.md +1 -1
- package/dist/agent-src/rules/evaluator-independence.md +3 -2
- package/dist/agent-src/rules/external-code-graph-interop.md +0 -1
- package/dist/agent-src/rules/external-reference-deep-dive.md +0 -1
- package/dist/agent-src/rules/fast-path-marker-visibility.md +2 -2
- package/dist/agent-src/rules/finance-safety-floor.md +1 -1
- package/dist/agent-src/rules/fix-what-you-see.md +6 -32
- package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +0 -1
- package/dist/agent-src/rules/git-history-discipline.md +2 -2
- package/dist/agent-src/rules/guidelines.md +0 -1
- package/dist/agent-src/rules/history-discipline.md +0 -1
- package/dist/agent-src/rules/icon-consistency.md +0 -1
- package/dist/agent-src/rules/image-likeness-and-rights.md +1 -1
- package/dist/agent-src/rules/improve-before-implement.md +0 -1
- package/dist/agent-src/rules/invite-challenge.md +0 -1
- package/dist/agent-src/rules/laravel-routing.md +1 -2
- package/dist/agent-src/rules/laravel-translations.md +0 -1
- package/dist/agent-src/rules/legal-safety-floor.md +3 -3
- package/dist/agent-src/rules/lethal-trifecta-guard.md +1 -1
- package/dist/agent-src/rules/linked-projects-onboarding-gate.md +0 -1
- package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +1 -1
- package/dist/agent-src/rules/markdown-safe-codeblocks.md +0 -1
- package/dist/agent-src/rules/media-governance-routing.md +13 -17
- package/dist/agent-src/rules/media-sync-ground-truth.md +0 -1
- package/dist/agent-src/rules/minimal-safe-diff.md +0 -1
- package/dist/agent-src/rules/missing-skill-recovery.md +0 -1
- package/dist/agent-src/rules/missing-tool-handling.md +0 -1
- package/dist/agent-src/rules/model-recommendation.md +0 -1
- package/dist/agent-src/rules/neighbour-precedence.md +64 -0
- package/dist/agent-src/rules/no-attribution-footers.md +0 -1
- package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +0 -1
- package/dist/agent-src/rules/no-pr-progress-comments.md +0 -1
- package/dist/agent-src/rules/no-roadmap-references.md +0 -1
- package/dist/agent-src/rules/notes-first-reasoning.md +0 -1
- package/dist/agent-src/rules/onboarding-gate.md +0 -1
- package/dist/agent-src/rules/output-discipline.md +0 -1
- package/dist/agent-src/rules/package-ci-checks.md +0 -1
- package/dist/agent-src/rules/persona-governance.md +4 -5
- package/dist/agent-src/rules/php-coding.md +0 -1
- package/dist/agent-src/rules/prefer-enums-over-literals.md +0 -1
- package/dist/agent-src/rules/preservation-guard.md +0 -1
- package/dist/agent-src/rules/provider-lifecycle-discipline.md +3 -4
- package/dist/agent-src/rules/question-not-instruction.md +1 -1
- package/dist/agent-src/rules/reviewer-awareness.md +0 -1
- package/dist/agent-src/rules/roadmap-ci-steps-policy.md +0 -1
- package/dist/agent-src/rules/roadmap-progress-sync.md +4 -7
- package/dist/agent-src/rules/role-mode-adherence.md +0 -1
- package/dist/agent-src/rules/rule-type-governance.md +0 -1
- package/dist/agent-src/rules/runtime-safety.md +1 -1
- package/dist/agent-src/rules/scale-discipline.md +0 -1
- package/dist/agent-src/rules/secret-vcs-guard.md +1 -1
- package/dist/agent-src/rules/security-sensitive-stop.md +3 -3
- package/dist/agent-src/rules/self-repair-loop.md +0 -1
- package/dist/agent-src/rules/senior-engineering-discipline.md +0 -1
- package/dist/agent-src/rules/session-canary.md +7 -62
- package/dist/agent-src/rules/settings-ask-protocol.md +6 -6
- package/dist/agent-src/rules/size-enforcement.md +0 -1
- package/dist/agent-src/rules/skill-improvement-trigger.md +2 -3
- package/dist/agent-src/rules/skill-quality.md +0 -1
- package/dist/agent-src/rules/slash-command-routing-policy.md +0 -1
- package/dist/agent-src/rules/source-confidentiality.md +1 -1
- package/dist/agent-src/rules/source-discovery-gate.md +0 -1
- package/dist/agent-src/rules/source-of-truth.md +0 -1
- package/dist/agent-src/rules/spreadsheet-source-quality.md +1 -2
- package/dist/agent-src/rules/strategy-safety-floor.md +1 -1
- package/dist/agent-src/rules/symfony-routing.md +1 -2
- package/dist/agent-src/rules/think-before-action.md +0 -1
- package/dist/agent-src/rules/token-budget-discipline.md +12 -46
- package/dist/agent-src/rules/token-efficiency.md +0 -1
- package/dist/agent-src/rules/token-optimizer-maintenance.md +0 -1
- package/dist/agent-src/rules/tool-safety.md +1 -1
- package/dist/agent-src/rules/ui-audit-gate.md +1 -2
- package/dist/agent-src/rules/untrusted-input-defense.md +1 -1
- package/dist/agent-src/rules/upstream-proposal.md +0 -1
- package/dist/agent-src/rules/user-interaction.md +0 -1
- package/dist/agent-src/rules/user-interrupt-priority.md +1 -1
- package/dist/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
- package/dist/agent-src/scripts/deferral_carry.ts +339 -0
- package/dist/agent-src/scripts/gate_budget.ts +47 -23
- package/dist/agent-src/scripts/gate_execute.ts +12 -4
- package/dist/agent-src/scripts/update_roadmap_progress.ts +4 -1
- package/dist/agent-src/skills/ai-council/SKILL.md +7 -4
- package/dist/agent-src/skills/ai-council/references/cost-and-redaction.md +21 -11
- package/dist/agent-src/skills/ai-council/references/procedure.md +12 -6
- package/dist/agent-src/skills/analysis-autonomous-mode/SKILL.md +1 -1
- package/dist/agent-src/skills/api-design/data/manifest.json +2 -2
- package/dist/agent-src/skills/api-testing/SKILL.md +17 -0
- package/dist/agent-src/skills/bug-analyzer/SKILL.md +1 -1
- package/dist/agent-src/skills/code-intelligence/SKILL.md +14 -2
- package/dist/agent-src/skills/command-routing/SKILL.md +3 -4
- package/dist/agent-src/skills/conventional-commits-writing/SKILL.md +127 -139
- package/dist/agent-src/skills/corpus-grounding/ATTRIBUTION.md +39 -0
- package/dist/agent-src/skills/corpus-grounding/SKILL.md +8 -2
- package/dist/agent-src/skills/database/data/manifest.json +2 -2
- package/dist/agent-src/skills/database/data/query-tuning.csv +13 -13
- package/dist/agent-src/skills/design-system-capture/SKILL.md +0 -3
- package/dist/agent-src/skills/design-system-capture/references/import-procedure.md +1 -1
- package/dist/agent-src/skills/estimate-ticket/SKILL.md +1 -1
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +2 -2
- package/dist/agent-src/skills/fe-design/SKILL.md +1 -1
- package/dist/agent-src/skills/feature-planning/SKILL.md +1 -1
- package/dist/agent-src/skills/git-workflow/SKILL.md +44 -44
- package/dist/agent-src/skills/git-workflow/references/branch-update.md +312 -0
- package/dist/agent-src/skills/git-workflow/references/commit-subject.md +205 -0
- package/dist/agent-src/skills/iconography/SKILL.md +1 -1
- package/dist/agent-src/skills/jira-integration/SKILL.md +3 -3
- package/dist/agent-src/skills/js-library-packaging/SKILL.md +2 -2
- package/dist/agent-src/skills/merge-conflicts/SKILL.md +10 -4
- package/dist/agent-src/skills/monorepo-workspace/SKILL.md +1 -1
- package/dist/agent-src/skills/po-discovery/SKILL.md +1 -1
- package/dist/agent-src/skills/quality-tools/SKILL.md +11 -1
- package/dist/agent-src/skills/quality-tools/references/go-tools.md +76 -0
- package/dist/agent-src/skills/quality-tools/references/python-tools.md +104 -0
- package/dist/agent-src/skills/refine-ticket/SKILL.md +4 -4
- package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +2 -2
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +5 -3
- package/dist/agent-src/skills/source-discovery/SKILL.md +1 -1
- package/dist/agent-src/skills/storybook-workshop/SKILL.md +3 -3
- package/dist/agent-src/skills/tailwind-engineer/SKILL.md +4 -2
- package/dist/agent-src/skills/test-case-discovery/SKILL.md +7 -0
- package/dist/agent-src/skills/test-driven-development/SKILL.md +17 -0
- package/dist/agent-src/skills/test-performance/SKILL.md +19 -1
- package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/ui-component-architect/SKILL.md +2 -2
- package/dist/agent-src/skills/using-git-worktrees/SKILL.md +1 -1
- package/dist/agent-src/skills/verify-repair-loop/SKILL.md +2 -2
- package/dist/agent-src/templates/AGENTS.md +1 -1
- package/dist/agent-src/templates/agent-settings.md +46 -129
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +3 -3
- package/dist/agent-src/templates/command.md +2 -2
- package/dist/agent-src/templates/roadmaps.md +6 -1
- package/dist/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +48 -6
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
- package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
- package/dist/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
- package/dist/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
- package/dist/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
- package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
- package/dist/agent-src/templates/skill.md +1 -1
- package/dist/cli/registry.js +2 -1
- package/dist/cli-delegate/archive_completed_roadmaps.js +92 -12
- package/dist/cli-delegate/check_update_banner.js +207 -120
- package/dist/cli-delegate/chunk-523HCFYO.js +90 -0
- package/dist/cli-delegate/{chunk-FP36SWJD.js → chunk-5GPULQBE.js} +2797 -338
- package/dist/cli-delegate/{chunk-IGD6ERX6.js → chunk-6SRJTYJS.js} +42 -176
- package/dist/cli-delegate/chunk-6V5FMA3P.js +186 -0
- package/dist/cli-delegate/{chunk-M2DPGFZ4.js → chunk-6V6TA25H.js} +22 -152
- package/dist/cli-delegate/chunk-6YQC2HLF.js +415 -0
- package/dist/cli-delegate/{chunk-E4XIZDIB.js → chunk-7HKRE54K.js} +1 -64
- package/dist/cli-delegate/chunk-7IQE3D5S.js +191 -0
- package/dist/cli-delegate/{chunk-YJ72UIAK.js → chunk-AED2VQGM.js} +1245 -249
- package/dist/cli-delegate/{chunk-7HQ52DHU.js → chunk-AL3RZ22D.js} +1 -1
- package/dist/cli-delegate/chunk-DEIV7XP7.js +108 -0
- package/dist/cli-delegate/{chunk-DBH4AHDK.js → chunk-ED7KCMLB.js} +9 -11
- package/dist/cli-delegate/chunk-F3QDG2GT.js +2569 -0
- package/dist/cli-delegate/{chunk-6KFEC3G7.js → chunk-G5VVIZRC.js} +3 -3
- package/dist/cli-delegate/{chunk-FC75PGJE.js → chunk-H76PHZBI.js} +149 -61
- package/dist/cli-delegate/chunk-IAYTIIQW.js +67 -0
- package/dist/cli-delegate/chunk-JQOM7TTM.js +1201 -0
- package/dist/cli-delegate/chunk-KB5FZ655.js +208 -0
- package/dist/cli-delegate/{chunk-7RQP4UDH.js → chunk-KR6EM23A.js} +235 -1455
- package/dist/cli-delegate/{chunk-LTYVIY76.js → chunk-KXXWJTDO.js} +6 -11
- package/dist/cli-delegate/{chunk-T7L2QK3K.js → chunk-LQOCRFWT.js} +1 -1
- package/dist/cli-delegate/{chunk-6KM6ORRY.js → chunk-MDPPKQCQ.js} +58 -9
- package/dist/cli-delegate/{chunk-4XFP2Y3E.js → chunk-MSUL5NYP.js} +5 -5
- package/dist/cli-delegate/chunk-OAFSJBHH.js +272 -0
- package/dist/cli-delegate/{chunk-4E2W63DA.js → chunk-OKJUIAPS.js} +62 -1
- package/dist/cli-delegate/{chunk-QAJS5YWY.js → chunk-PHD7OOLE.js} +2 -1
- package/dist/cli-delegate/{chunk-P6ZHP5W2.js → chunk-PWX7CKMD.js} +4 -4
- package/dist/cli-delegate/{chunk-NDJLNC6Q.js → chunk-T6BP34WI.js} +1 -0
- package/dist/cli-delegate/{chunk-7XGBX6ZH.js → chunk-T7XSJSUQ.js} +1144 -589
- package/dist/cli-delegate/chunk-ULQRUR23.js +208 -0
- package/dist/cli-delegate/chunk-WQWXGIWB.js +1779 -0
- package/dist/cli-delegate/{chunk-RGNIWTEA.js → chunk-XQTPXKFA.js} +1 -1
- package/dist/cli-delegate/{chunk-NUHLI2RX.js → chunk-YCU3TIXH.js} +2 -0
- package/dist/cli-delegate/chunk-ZBZV2G5R.js +210 -0
- package/dist/cli-delegate/{chunk-WGXTVKCQ.js → chunk-ZUZKZYCN.js} +5 -3
- package/dist/cli-delegate/cmd_analyze_session.js +223 -43
- package/dist/cli-delegate/cmd_brand_status.js +3 -2
- package/dist/cli-delegate/cmd_conformance.js +1252 -249
- package/dist/cli-delegate/cmd_converge.js +3 -3
- package/dist/cli-delegate/cmd_doctor.js +19 -9
- package/dist/cli-delegate/cmd_doctor_neighbours.js +30 -0
- package/dist/cli-delegate/cmd_explain.js +45 -21
- package/dist/cli-delegate/cmd_export.js +13 -10
- package/dist/cli-delegate/cmd_fleet.js +3 -3
- package/dist/cli-delegate/cmd_git_convention.js +1851 -0
- package/dist/cli-delegate/cmd_handoff.js +44 -22
- package/dist/cli-delegate/cmd_mcp_available.js +3 -2
- package/dist/cli-delegate/cmd_memory_get.js +3 -1
- package/dist/cli-delegate/cmd_migrate.js +3 -3
- package/dist/cli-delegate/cmd_packs_active.js +5 -4
- package/dist/cli-delegate/cmd_preflight.js +6 -6
- package/dist/cli-delegate/cmd_prune.js +14 -11
- package/dist/cli-delegate/cmd_refresh.js +2 -1
- package/dist/cli-delegate/cmd_route_audit.js +10 -8
- package/dist/cli-delegate/cmd_route_explain.js +4 -4
- package/dist/cli-delegate/cmd_session_recycle.js +10 -7
- package/dist/cli-delegate/cmd_settings_check.js +54 -7
- package/dist/cli-delegate/cmd_settings_get.js +18 -8
- package/dist/cli-delegate/cmd_settings_migrate.js +13 -10
- package/dist/cli-delegate/cmd_settings_set.js +4 -4
- package/dist/cli-delegate/cmd_sync.js +14 -11
- package/dist/cli-delegate/cmd_uninstall.js +15 -12
- package/dist/cli-delegate/cmd_update.js +7 -7
- package/dist/cli-delegate/cmd_upgrade.js +9 -8
- package/dist/cli-delegate/cmd_validate.js +15 -12
- package/dist/cli-delegate/cmd_versions.js +5 -5
- package/dist/cli-delegate/deferral_carry.js +16 -0
- package/dist/cli-delegate/gate_budget.js +1 -1
- package/dist/cli-delegate/gate_execute.js +3 -3
- package/dist/cli-delegate/roadmap_gates.js +6 -6
- package/dist/cli-delegate/update_roadmap_progress.js +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +232 -141
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +3 -3
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +26 -9
- package/dist/discovery/trust-report.md +3 -3
- package/dist/discovery/workspaces.json +7 -4
- package/dist/hooks/dispatch.js +5655 -6623
- package/dist/hooks/dispatch.sha256 +1 -1
- package/dist/install/claudePathsPlan.js +47 -6
- package/dist/install/claudeRuleRewrite.js +7 -0
- package/dist/install/emit_host_rules_cli.js +39 -36
- package/dist/install/globalRuleScope.js +87 -0
- package/dist/install/host_rule_ownership.js +160 -0
- package/dist/install/install.mjs +2336 -1249
- package/dist/install/installThinLayer.js +289 -0
- package/dist/install/installedRuleLinks.js +262 -0
- package/dist/install/wizard-plan.js +24 -0
- package/dist/mcp/awesome-mcp-servers.row.md +1 -1
- package/dist/mcp/mcp-cloudflare-catalogue.json +2 -2
- package/dist/mcp/registry-manifest.json +5 -5
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +36504 -30986
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/agent_settings.js +26 -120
- package/dist/scripts/_lib/claude_settings_hooks.js +10 -8
- package/dist/scripts/_lib/compile_time_toggles.js +12 -21
- package/dist/scripts/_lib/git_convention.js +232 -0
- package/dist/scripts/_lib/global_deploy_inventory.js +730 -0
- package/dist/scripts/_lib/installed_layer.js +704 -0
- package/dist/scripts/_lib/lean_projection_mode.js +218 -15
- package/dist/scripts/_lib/package_root.js +68 -0
- package/dist/scripts/_lib/rule_consequence_class.js +45 -0
- package/dist/scripts/_lib/rule_injection.js +67 -10
- package/dist/scripts/_lib/rule_law_section.js +122 -0
- package/dist/scripts/_lib/settings_removed_keys.js +168 -0
- package/dist/scripts/_lib/thin_rules.js +535 -0
- package/dist/scripts/_lib/windsurf_render.js +60 -0
- package/dist/scripts/condense.js +14 -26
- package/dist/scripts/project_thin_rules.js +14 -294
- package/dist/server/app.js +2 -1
- package/dist/server/gitKeysGate.js +105 -0
- package/dist/server/routes/settings.js +67 -8
- package/dist/server/routes/wizard.js +4 -0
- package/dist/server/schemas/settings.js +29 -81
- package/dist/shared/skillRanking.js +103 -16
- package/dist/ui/assets/{index-Cwq4d0hX.js → index-C3djEJah.js} +2 -2
- package/dist/ui/index.html +1 -1
- package/docs/MIGRATION.md +72 -1
- package/docs/contracts/settings-classes.md +39 -67
- package/docs/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
- package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
- package/docs/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
- package/docs/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
- package/docs/guidelines/agent-infra/layered-settings.md +13 -1
- package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
- package/docs/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
- package/docs/guidelines/agent-infra/size-and-scope.md +36 -0
- package/docs/guidelines/php/git.md +15 -2
- package/package.json +1 -1
- package/src/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
- package/src/agent-src/scripts/deferral_carry.ts +339 -0
- package/src/agent-src/scripts/gate_budget.ts +47 -23
- package/src/agent-src/scripts/gate_execute.ts +12 -4
- package/src/agent-src/scripts/update_roadmap_progress.ts +4 -1
- package/src/agent-src/templates/AGENTS.md +1 -1
- package/src/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
- package/src/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
- package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +48 -6
- package/src/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
- package/src/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
- package/src/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
- package/src/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
- package/src/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
- package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
- package/src/config/agent-settings.template.yml +141 -334
- package/src/config/agents-paths.yml +16 -0
- package/src/config/assurance-capability-registry.json +7 -3
- package/src/config/ci-local-parity.yml +3 -0
- package/src/config/continuity-surface.json +10 -3
- package/src/config/discovery/packs.yml +17 -1
- package/src/config/evaluator-budgets.json +23 -10
- package/src/config/gate-coverage.yml +138 -3
- package/src/config/gate-violation-baselines.json +64 -16
- package/src/config/gitignore-block.txt +19 -0
- package/src/config/hook-bundle-budget.json +25 -0
- package/src/config/hook-token-budget.json +6 -1
- package/src/config/host-instruction-limits.json +33 -0
- package/src/config/release-gate-locality.yml +2 -1
- package/src/config/routing-coverage-seed.json +67 -4
- package/src/config/rule-activation-census.json +7 -3
- package/src/config/rule-consequence-class.json +161 -0
- package/src/config/rule-law-ceilings.json +105 -0
- package/src/config/rule-obligations.json +833 -0
- package/src/install/claudePathsPlan.ts +46 -4
- package/src/install/claudeRuleRewrite.ts +10 -1
- package/src/install/emit_host_rules_cli.ts +43 -34
- package/src/install/globalRuleScope.ts +109 -0
- package/src/install/host_rule_ownership.ts +170 -0
- package/src/install/installThinLayer.ts +378 -0
- package/src/install/installedRuleLinks.ts +308 -0
- package/src/install/wizard-plan.ts +24 -0
- package/src/scripts/_cli/cmd_analyze_session.ts +9 -15
- package/src/scripts/_cli/cmd_conformance.ts +13 -2
- package/src/scripts/_cli/cmd_doctor.ts +33 -81
- package/src/scripts/_cli/cmd_doctor_neighbours.ts +426 -0
- package/src/scripts/_cli/cmd_explain.ts +72 -14
- package/src/scripts/_cli/cmd_git_convention.ts +637 -0
- package/src/scripts/_cli/cmd_settings_check.ts +66 -8
- package/src/scripts/_cli/cmd_settings_get.ts +18 -3
- package/src/scripts/_cli/doctor_execution.ts +72 -1
- package/src/scripts/_dispatch.bash +53 -4
- package/src/scripts/_lib/agent_settings.ts +26 -124
- package/src/scripts/_lib/blocked_by_marker.ts +1 -1
- package/src/scripts/_lib/claude_settings_hooks.ts +10 -8
- package/src/scripts/_lib/compile_time_toggles.ts +12 -21
- package/src/scripts/_lib/dispatch_import_closure.ts +163 -0
- package/src/scripts/_lib/estate_offsets.ts +241 -0
- package/src/scripts/_lib/exemption_shape.ts +143 -0
- package/src/scripts/_lib/fnv.ts +23 -0
- package/src/scripts/_lib/foreign_scan.ts +106 -0
- package/src/scripts/_lib/git_base_ref.ts +92 -0
- package/src/scripts/_lib/git_convention.ts +291 -0
- package/src/scripts/_lib/git_convention_carrier.ts +389 -0
- package/src/scripts/_lib/git_convention_grammar.ts +246 -0
- package/src/scripts/_lib/git_convention_measure.ts +344 -0
- package/src/scripts/_lib/gitignore_block.ts +314 -0
- package/src/scripts/_lib/global_deploy_inventory.ts +106 -0
- package/src/scripts/_lib/graph_feeder_record.ts +437 -0
- package/src/scripts/_lib/hook_settings.ts +73 -0
- package/src/scripts/_lib/host_capability.ts +40 -19
- package/src/scripts/_lib/host_hook_merge.ts +165 -0
- package/src/scripts/_lib/installed_layer.ts +963 -0
- package/src/scripts/_lib/json_merge.ts +82 -0
- package/src/scripts/_lib/json_pointers.ts +93 -11
- package/src/scripts/_lib/knowledge_global.ts +14 -1
- package/src/scripts/_lib/lean_projection_mode.ts +275 -15
- package/src/scripts/_lib/machine_wake.ts +16 -3
- package/src/scripts/_lib/module_reach.ts +456 -0
- package/src/scripts/_lib/neighbour_census.ts +760 -0
- package/src/scripts/_lib/neighbour_contradictions.ts +236 -0
- package/src/scripts/_lib/neighbour_scan.ts +122 -0
- package/src/scripts/_lib/neighbour_tool_use.ts +187 -0
- package/src/scripts/_lib/prompt_shape.ts +46 -0
- package/src/scripts/_lib/ratification_artifact.ts +220 -1
- package/src/scripts/_lib/ratification_subject.ts +92 -0
- package/src/scripts/_lib/release_findings_ingest.ts +15 -7
- package/src/scripts/_lib/release_highlights.ts +5 -0
- package/src/scripts/_lib/release_migration_gate.ts +19 -3
- package/src/scripts/_lib/reserved_name_sweep.ts +73 -0
- package/src/scripts/_lib/review_coverage.ts +134 -0
- package/src/scripts/_lib/rule_consequence_class.ts +71 -0
- package/src/scripts/_lib/rule_injection.ts +130 -10
- package/src/scripts/_lib/rule_law_section.ts +147 -0
- package/src/scripts/_lib/rule_layer_overlap.ts +58 -0
- package/src/scripts/_lib/rule_obligations.ts +205 -0
- package/src/scripts/_lib/self_repair.ts +1 -1
- package/src/scripts/_lib/settings_removed_keys.ts +173 -0
- package/src/scripts/_lib/skill_origin.ts +254 -0
- package/src/scripts/_lib/structured_ask.ts +64 -21
- package/src/scripts/_lib/test_red_state.ts +5 -0
- package/src/scripts/_lib/thin_rules.ts +620 -0
- package/src/scripts/_lib/touched_file_quality.ts +570 -0
- package/src/scripts/_lib/turn_end_refusals.ts +77 -2
- package/src/scripts/_lib/windsurf_render.ts +63 -0
- package/src/scripts/_lib/worker_budget.ts +1 -1
- package/src/scripts/adr/regenerate_index.ts +16 -1
- package/src/scripts/ai_council/cli_call_budget.ts +13 -5
- package/src/scripts/ai_council/clients.ts +26 -57
- package/src/scripts/ai_council/config.ts +8 -8
- package/src/scripts/ai_council/modification_review.ts +100 -0
- package/src/scripts/ai_council/modification_review_questions.ts +90 -0
- package/src/scripts/ai_council/orchestrator.ts +5 -5
- package/src/scripts/ai_council/spend_gate.ts +18 -7
- package/src/scripts/ai_council/vendor_defaults.ts +45 -0
- package/src/scripts/ai_team/config.ts +11 -16
- package/src/scripts/audit_skill_overlap.ts +261 -0
- package/src/scripts/audit_user_type_axis.ts +20 -8
- package/src/scripts/before_complete_hook.ts +243 -12
- package/src/scripts/bench_ab_clone.ts +1 -2
- package/src/scripts/bench_concern_spawn_path.ts +129 -0
- package/src/scripts/bench_graph_feeder_latency.ts +584 -0
- package/src/scripts/bench_touched_file_quality.ts +238 -0
- package/src/scripts/check_agent_artifact_location.ts +36 -0
- package/src/scripts/check_branch_freshness.ts +147 -24
- package/src/scripts/check_enforcement_coverage.ts +130 -0
- package/src/scripts/check_enforcement_matrix.ts +377 -20
- package/src/scripts/check_estate_count.ts +130 -153
- package/src/scripts/check_evaluator_budgets.ts +4 -0
- package/src/scripts/check_finding_dispositions.ts +196 -21
- package/src/scripts/check_gate_coverage.ts +4 -3
- package/src/scripts/check_gate_reachability.ts +48 -1
- package/src/scripts/check_generator_sync.ts +48 -0
- package/src/scripts/check_hook_bundle_composition.ts +477 -0
- package/src/scripts/check_kernel_edit_ratified.ts +132 -14
- package/src/scripts/check_memory.ts +7 -1
- package/src/scripts/check_pack_size.ts +1 -1
- package/src/scripts/check_release_highlights.ts +10 -0
- package/src/scripts/check_release_manifest_content.ts +189 -0
- package/src/scripts/check_release_pr_shape.ts +38 -15
- package/src/scripts/check_standing_rule_delivery.ts +129 -13
- package/src/scripts/check_suppression_hygiene.ts +2 -5
- package/src/scripts/check_verify_expectation_delta.ts +521 -0
- package/src/scripts/ci_settle.ts +42 -5
- package/src/scripts/classify_merge_risk.ts +320 -0
- package/src/scripts/closure_scan.ts +91 -1
- package/src/scripts/code_graph/detect.ts +127 -7
- package/src/scripts/code_graph/foreign.ts +194 -0
- package/src/scripts/code_graph/query.ts +217 -4
- package/src/scripts/code_graph/types.ts +26 -2
- package/src/scripts/code_graph/validate.ts +3 -1
- package/src/scripts/code_graph/verbs.ts +103 -0
- package/src/scripts/command_suggester/settings.ts +8 -108
- package/src/scripts/command_suggester/types.ts +4 -5
- package/src/scripts/compile_hook_manifest.ts +33 -1
- package/src/scripts/condense.ts +14 -27
- package/src/scripts/consumer_matrix.ts +102 -0
- package/src/scripts/context_hygiene_hook.ts +13 -23
- package/src/scripts/cost/preflight.mjs +12 -1
- package/src/scripts/council_cli.ts +7 -7
- package/src/scripts/dispatch_r2_reviewer.ts +24 -11
- package/src/scripts/estate_exemption_shape.ts +202 -0
- package/src/scripts/explain_run.ts +8 -13
- package/src/scripts/generate_git_convention_grammar.ts +127 -0
- package/src/scripts/generate_host_cost_table.ts +21 -4
- package/src/scripts/handoff_context_hook.ts +86 -37
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +175 -15
- package/src/scripts/hooks/block_config_weakening.ts +115 -7
- package/src/scripts/hooks/block_plumbing_writes.ts +37 -5
- package/src/scripts/hooks/code_graph_context_hook.ts +252 -23
- package/src/scripts/hooks/concern_failure_policy.ts +280 -0
- package/src/scripts/hooks/concern_registry.ts +2 -0
- package/src/scripts/hooks/delegation_nudge_hook.ts +2 -3
- package/src/scripts/hooks/dispatch_hook.ts +52 -52
- package/src/scripts/hooks/evidence_independence.ts +12 -4
- package/src/scripts/hooks/exit_codes.ts +2 -1
- package/src/scripts/hooks/host_lowering.json +1 -1
- package/src/scripts/hooks/host_lowering.ts +19 -1
- package/src/scripts/hooks/mcp_usage_observation_hook.ts +121 -0
- package/src/scripts/hooks/one_question_per_ask_hook.ts +41 -25
- package/src/scripts/hooks/payload_stub.ts +10 -1
- package/src/scripts/hooks/push_settle_hook.ts +4 -3
- package/src/scripts/hooks/rule_inject_hook.ts +795 -60
- package/src/scripts/hooks/state_io.ts +8 -4
- package/src/scripts/hooks/table_fingerprint.ts +21 -0
- package/src/scripts/hooks/telemetry_usage_hook.ts +24 -7
- package/src/scripts/hooks/turn_end_gate_hook.ts +85 -0
- package/src/scripts/hooks_status.ts +112 -0
- package/src/scripts/injection_scan_hook.ts +7 -0
- package/src/scripts/install-hooks.sh +42 -14
- package/src/scripts/install.ts +78 -215
- package/src/scripts/installed_layer_report.ts +103 -0
- package/src/scripts/language_mirror_hook.ts +15 -6
- package/src/scripts/learning_sidecar.ts +119 -8
- package/src/scripts/lint_blocker_citations.ts +198 -0
- package/src/scripts/lint_evidence_artifacts.ts +9 -0
- package/src/scripts/lint_hook_concern_budget.ts +10 -21
- package/src/scripts/lint_hook_manifest.ts +53 -0
- package/src/scripts/lint_major_migration_sections.ts +156 -26
- package/src/scripts/lint_pack_boundaries.ts +465 -29
- package/src/scripts/lint_roadmap_blockers.ts +282 -29
- package/src/scripts/lint_roadmap_complexity.ts +4 -2
- package/src/scripts/lint_rule_law_section.ts +647 -0
- package/src/scripts/lint_rule_skill_pack_reach.ts +17 -0
- package/src/scripts/lint_settings_classes.ts +1 -1
- package/src/scripts/lint_ticked_unmet_criteria.ts +165 -0
- package/src/scripts/lint_workflow_security.ts +173 -6
- package/src/scripts/mcp_server/consumer_tool_catalog.json +53 -0
- package/src/scripts/mcp_server/graph_tools.ts +72 -3
- package/src/scripts/measure_routing_signal.ts +54 -16
- package/src/scripts/measure_skill_ranker_baseline.ts +221 -8
- package/src/scripts/memory_learn_hook.ts +91 -6
- package/src/scripts/model_rule_injection.ts +55 -8
- package/src/scripts/onboarding_gate_hook.ts +7 -6
- package/src/scripts/print_required_checks.ts +15 -3
- package/src/scripts/probe_host_compliance.ts +33 -5
- package/src/scripts/probe_turnaround.ts +183 -3
- package/src/scripts/project_thin_rules.ts +34 -327
- package/src/scripts/ratification_header.ts +77 -0
- package/src/scripts/refusal_envelope.ts +138 -0
- package/src/scripts/release_publication.ts +29 -3
- package/src/scripts/report_dispatch_import_closure.ts +76 -0
- package/src/scripts/report_evidence_temperature.ts +657 -0
- package/src/scripts/report_installed_rule_links.ts +274 -0
- package/src/scripts/report_label_agreement.ts +233 -0
- package/src/scripts/report_module_reach.ts +212 -0
- package/src/scripts/report_obligation_mechanism.ts +228 -0
- package/src/scripts/report_parked_blockers.ts +222 -0
- package/src/scripts/report_required_checks_drift.ts +196 -0
- package/src/scripts/report_single_token_triggers.ts +277 -0
- package/src/scripts/report_skill_ranker_confusion.ts +543 -0
- package/src/scripts/report_standing_payload_by_host.ts +188 -15
- package/src/scripts/report_verification_record_coverage.ts +306 -0
- package/src/scripts/routing_doctor.ts +2 -2
- package/src/scripts/rule_activation_census.ts +5 -2
- package/src/scripts/rule_trigger_eval.ts +9 -9
- package/src/scripts/schemas/agent-settings.schema.json +17 -31
- package/src/scripts/schemas/command.schema.json +1 -1
- package/src/scripts/schemas/review-findings.schema.json +3 -2
- package/src/scripts/schemas/rule.schema.json +5 -0
- package/src/scripts/schemas/skill.schema.json +1 -1
- package/src/scripts/self_review_gate.ts +101 -9
- package/src/scripts/skill_tools/score_skill_relevance.ts +314 -40
- package/src/scripts/sweep_skill_ranker_signals.ts +129 -0
- package/src/scripts/sync_gitignore.ts +29 -235
- package/src/scripts/sync_pr_branch.ts +403 -132
- package/src/scripts/trigger_eval_grandfather.json +0 -21
- package/src/server/schemas/settings.ts +42 -176
- package/src/shared/skillRanking.ts +169 -14
- package/dist/cli-delegate/chunk-5R7HOLAF.js +0 -99
- package/dist/cli-delegate/chunk-JNMVLWLR.js +0 -4457
- package/dist/cli-delegate/chunk-YDPILCOL.js +0 -152
- package/src/scripts/_lib/config_chain.ts +0 -477
- package/src/scripts/_lib/conformance_report.ts +0 -403
- package/src/scripts/_lib/eval_discrimination.ts +0 -95
- package/src/scripts/_lib/evaluator_promotion.ts +0 -225
- package/src/scripts/_lib/file_slicer.ts +0 -117
- package/src/scripts/_lib/legacy_boundary_map.ts +0 -228
- package/src/scripts/_lib/minimality_tiebreak.ts +0 -168
- package/src/scripts/_lib/overbuild_lens_contract.ts +0 -196
- package/src/scripts/_lib/role_split.ts +0 -338
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Required-check drift report — compares the live ruleset to the contract.
|
|
4
|
+
*
|
|
5
|
+
* `print_required_checks.ts` carries the list of status contexts the `main
|
|
6
|
+
* protection` ruleset requires, and it is contractually offline: it never calls
|
|
7
|
+
* `gh`. So nothing compared that list to the ruleset, and it drifted — it named
|
|
8
|
+
* one required context for a month after the ruleset gained a second. This
|
|
9
|
+
* report is the comparison: it reads the ruleset through `gh api`, extracts the
|
|
10
|
+
* required status contexts, and exits non-zero when they differ from
|
|
11
|
+
* `ENFORCED_CHECKS`.
|
|
12
|
+
*
|
|
13
|
+
* READ-ONLY. It writes nothing and changes nothing on the ruleset. It is run by
|
|
14
|
+
* hand or on a schedule and is NOT wired as a required check — a network read
|
|
15
|
+
* cannot sit on the path of every pull request, and the token it needs is a
|
|
16
|
+
* repository-read token, not something each PR should depend on.
|
|
17
|
+
*
|
|
18
|
+
* Usage:
|
|
19
|
+
* ./scripts-run src/scripts/report_required_checks_drift
|
|
20
|
+
* ./scripts-run src/scripts/report_required_checks_drift --repo <owner/name>
|
|
21
|
+
* ./scripts-run src/scripts/report_required_checks_drift --from-json <file>
|
|
22
|
+
*
|
|
23
|
+
* `--from-json` reads a ruleset object (the shape `gh api
|
|
24
|
+
* repos/{owner}/{repo}/rulesets/{id}` returns) from a file instead of the
|
|
25
|
+
* network, so the comparison itself is testable offline.
|
|
26
|
+
*
|
|
27
|
+
* Exit codes: 0 the lists agree · 1 they differ · 2 usage error, or the ruleset
|
|
28
|
+
* could not be read or carries no required-status-checks rule.
|
|
29
|
+
*/
|
|
30
|
+
import { spawnSync } from 'node:child_process';
|
|
31
|
+
import * as fs from 'node:fs';
|
|
32
|
+
import * as path from 'node:path';
|
|
33
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
34
|
+
|
|
35
|
+
import { ENFORCED_CHECKS } from './print_required_checks.js';
|
|
36
|
+
|
|
37
|
+
const _HERE = fileURLToPath(import.meta.url);
|
|
38
|
+
|
|
39
|
+
export const RULESET_NAME = 'main protection';
|
|
40
|
+
const DEFAULT_REPO = 'event4u-app/agent-config';
|
|
41
|
+
|
|
42
|
+
export interface Drift {
|
|
43
|
+
readonly missingFromContract: readonly string[];
|
|
44
|
+
readonly missingFromRuleset: readonly string[];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
class ReadError extends Error {}
|
|
48
|
+
|
|
49
|
+
/** The required status contexts of one ruleset object, sorted. */
|
|
50
|
+
export function requiredContexts(ruleset: unknown): string[] {
|
|
51
|
+
const rules = (ruleset as { rules?: unknown }).rules;
|
|
52
|
+
if (!Array.isArray(rules)) {
|
|
53
|
+
throw new ReadError('the ruleset object carries no `rules` array');
|
|
54
|
+
}
|
|
55
|
+
const lists = rules
|
|
56
|
+
.filter(
|
|
57
|
+
(r): r is { parameters?: { required_status_checks?: unknown } } =>
|
|
58
|
+
typeof r === 'object' && r !== null && (r as { type?: unknown }).type === 'required_status_checks',
|
|
59
|
+
)
|
|
60
|
+
.map((r) => r.parameters?.required_status_checks)
|
|
61
|
+
.filter((c): c is unknown[] => Array.isArray(c));
|
|
62
|
+
if (lists.length === 0) {
|
|
63
|
+
throw new ReadError('the ruleset has no `required_status_checks` rule');
|
|
64
|
+
}
|
|
65
|
+
// Every such rule counts: a context required by any of them blocks the merge.
|
|
66
|
+
const contexts = new Set(
|
|
67
|
+
lists
|
|
68
|
+
.flat()
|
|
69
|
+
.map((c) => (c as { context?: unknown }).context)
|
|
70
|
+
.filter((c): c is string => typeof c === 'string'),
|
|
71
|
+
);
|
|
72
|
+
return [...contexts].sort();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Set difference in both directions; empty both ways means agreement. */
|
|
76
|
+
export function compare(live: readonly string[], contract: readonly string[]): Drift {
|
|
77
|
+
const liveSet = new Set(live);
|
|
78
|
+
const contractSet = new Set(contract);
|
|
79
|
+
return {
|
|
80
|
+
missingFromContract: live.filter((c) => !contractSet.has(c)).sort(),
|
|
81
|
+
missingFromRuleset: contract.filter((c) => !liveSet.has(c)).sort(),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function ghJson(endpoint: string, paginate = false): unknown {
|
|
86
|
+
const args = paginate ? ['api', '--paginate', '--slurp', endpoint] : ['api', endpoint];
|
|
87
|
+
const r = spawnSync('gh', args, { encoding: 'utf-8', maxBuffer: 16 * 1024 * 1024 });
|
|
88
|
+
if (r.status !== 0) {
|
|
89
|
+
throw new ReadError(`gh api ${endpoint} failed: ${(r.stderr ?? '').trim() || `exit ${String(r.status)}`}`);
|
|
90
|
+
}
|
|
91
|
+
return JSON.parse(r.stdout) as unknown;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function readLiveRuleset(repo: string): unknown {
|
|
95
|
+
// --paginate --slurp: one array per page, so a ruleset past the first page
|
|
96
|
+
// of 30 is still found.
|
|
97
|
+
const pages = ghJson(`repos/${repo}/rulesets`, true);
|
|
98
|
+
if (!Array.isArray(pages) || !pages.every((p) => Array.isArray(p))) {
|
|
99
|
+
throw new ReadError('the rulesets listing is not an array of pages');
|
|
100
|
+
}
|
|
101
|
+
const list = (pages as unknown[][]).flat();
|
|
102
|
+
const hit = list.find((r) => (r as { name?: unknown }).name === RULESET_NAME) as { id?: unknown } | undefined;
|
|
103
|
+
if (hit === undefined || typeof hit.id !== 'number') {
|
|
104
|
+
throw new ReadError(`no ruleset named "${RULESET_NAME}" on ${repo}`);
|
|
105
|
+
}
|
|
106
|
+
return ghJson(`repos/${repo}/rulesets/${String(hit.id)}`);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
interface Options {
|
|
110
|
+
repo: string;
|
|
111
|
+
fromJson: string | null;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function parseArgs(argv: readonly string[]): Options | string {
|
|
115
|
+
let repo = DEFAULT_REPO;
|
|
116
|
+
let fromJson: string | null = null;
|
|
117
|
+
for (let i = 0; i < argv.length; i++) {
|
|
118
|
+
const a = argv[i] as string;
|
|
119
|
+
if (a === '--repo' || a === '--from-json') {
|
|
120
|
+
const v = argv[i + 1];
|
|
121
|
+
if (v === undefined || v.startsWith('--')) {
|
|
122
|
+
return `${a} needs a value`;
|
|
123
|
+
}
|
|
124
|
+
if (a === '--repo') {
|
|
125
|
+
repo = v;
|
|
126
|
+
} else {
|
|
127
|
+
fromJson = v;
|
|
128
|
+
}
|
|
129
|
+
i++;
|
|
130
|
+
} else {
|
|
131
|
+
return `unknown argument: ${a}`;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return { repo, fromJson };
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export function main(argv: readonly string[] = process.argv.slice(2)): number {
|
|
138
|
+
const opts = parseArgs(argv);
|
|
139
|
+
if (typeof opts === 'string') {
|
|
140
|
+
process.stderr.write(`❌ report_required_checks_drift: ${opts}\n`);
|
|
141
|
+
process.stderr.write('usage: report_required_checks_drift [--repo OWNER/NAME] [--from-json FILE]\n');
|
|
142
|
+
return 2;
|
|
143
|
+
}
|
|
144
|
+
let live: string[];
|
|
145
|
+
try {
|
|
146
|
+
const ruleset =
|
|
147
|
+
opts.fromJson === null
|
|
148
|
+
? readLiveRuleset(opts.repo)
|
|
149
|
+
: (JSON.parse(fs.readFileSync(opts.fromJson, 'utf-8')) as unknown);
|
|
150
|
+
live = requiredContexts(ruleset);
|
|
151
|
+
} catch (e) {
|
|
152
|
+
process.stderr.write(`❌ report_required_checks_drift: ${e instanceof Error ? e.message : String(e)}\n`);
|
|
153
|
+
return 2;
|
|
154
|
+
}
|
|
155
|
+
const drift = compare(live, ENFORCED_CHECKS);
|
|
156
|
+
const source = opts.fromJson === null ? `${opts.repo} ruleset "${RULESET_NAME}"` : opts.fromJson;
|
|
157
|
+
process.stdout.write(`required contexts read from ${source}: ${String(live.length)}\n`);
|
|
158
|
+
for (const c of live) {
|
|
159
|
+
process.stdout.write(` - ${c}\n`);
|
|
160
|
+
}
|
|
161
|
+
if (drift.missingFromContract.length === 0 && drift.missingFromRuleset.length === 0) {
|
|
162
|
+
process.stdout.write(
|
|
163
|
+
'✅ agrees with ENFORCED_CHECKS in src/scripts/print_required_checks.ts\n',
|
|
164
|
+
);
|
|
165
|
+
return 0;
|
|
166
|
+
}
|
|
167
|
+
for (const c of drift.missingFromContract) {
|
|
168
|
+
process.stdout.write(` ❌ required by the ruleset, absent from the contract: ${c}\n`);
|
|
169
|
+
}
|
|
170
|
+
for (const c of drift.missingFromRuleset) {
|
|
171
|
+
process.stdout.write(` ❌ named by the contract, not required by the ruleset: ${c}\n`);
|
|
172
|
+
}
|
|
173
|
+
process.stdout.write(
|
|
174
|
+
'❌ drift — update ENFORCED_CHECKS and docs/contracts/branch-protection-policy.md ' +
|
|
175
|
+
'together, with the date the ruleset was read.\n',
|
|
176
|
+
);
|
|
177
|
+
return 1;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function _isCliEntry(): boolean {
|
|
181
|
+
if (process.argv[1] === undefined) {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
if (pathToFileURL(path.resolve(process.argv[1])).href === import.meta.url) {
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
try {
|
|
188
|
+
return fs.realpathSync(path.resolve(process.argv[1])) === fs.realpathSync(_HERE);
|
|
189
|
+
} catch {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (_isCliEntry()) {
|
|
195
|
+
process.exitCode = main();
|
|
196
|
+
}
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Which one-token keyword triggers fire on prompts that belong to other rules.
|
|
4
|
+
*
|
|
5
|
+
* Step 1.3 of `road-to-rule-triggers-and-links-that-hold`. A single common word
|
|
6
|
+
* — `rename`, `delete` — is a legitimate trigger for the rule that owns the
|
|
7
|
+
* subject and a standing cost for every prompt that merely uses the word. This
|
|
8
|
+
* reports which words sit at which share of the corpus. **Report only.** A
|
|
9
|
+
* trigger change is a separate decision per rule, because a common word can be
|
|
10
|
+
* exactly right: `augment-edit-discipline` genuinely wants to fire on a rename.
|
|
11
|
+
*
|
|
12
|
+
* The corpus is `tests/eval/routing-matrix/*.yaml`, the frozen set this tree
|
|
13
|
+
* already evaluates routing against. Each `positives[].prompt` is labelled with
|
|
14
|
+
* its file's rule. For a one-token keyword `K` on rule `R`, the share is:
|
|
15
|
+
*
|
|
16
|
+
* |{ prompt : label(prompt) != R and K occurs as a word }|
|
|
17
|
+
* ---------------------------------------------------------
|
|
18
|
+
* |{ prompt : label(prompt) != R }|
|
|
19
|
+
*
|
|
20
|
+
* `near_misses` are deliberately NOT in the denominator. They carry a negative
|
|
21
|
+
* label against their own file's rule and no positive label against any other,
|
|
22
|
+
* so counting them would mix "belongs to another rule" with "belongs to no
|
|
23
|
+
* rule" — two different claims, and only the first is what a cross-firing
|
|
24
|
+
* trigger costs.
|
|
25
|
+
*
|
|
26
|
+
* The 5 % threshold is a stated default for a report, not a gate (D3). Nothing
|
|
27
|
+
* acts on the figure automatically.
|
|
28
|
+
*/
|
|
29
|
+
import * as fs from 'node:fs';
|
|
30
|
+
import * as path from 'node:path';
|
|
31
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
32
|
+
|
|
33
|
+
import { parse as parseYaml } from 'yaml';
|
|
34
|
+
|
|
35
|
+
// ledger-exempt: a REPORTER, not a gate. Its only non-zero exit says the
|
|
36
|
+
// corpus or the rule directory could not be read.
|
|
37
|
+
|
|
38
|
+
const _HERE = fileURLToPath(import.meta.url);
|
|
39
|
+
|
|
40
|
+
export const DEFAULT_THRESHOLD = 0.05;
|
|
41
|
+
|
|
42
|
+
export interface LabelledPrompt {
|
|
43
|
+
rule: string;
|
|
44
|
+
prompt: string;
|
|
45
|
+
/** `positive` — belongs to `rule`. `near_miss` — declared NOT to be `rule`. */
|
|
46
|
+
kind: 'positive' | 'near_miss';
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface TriggerRow {
|
|
50
|
+
rule: string;
|
|
51
|
+
keyword: string;
|
|
52
|
+
/** Foreign POSITIVE prompts the keyword occurs in. */
|
|
53
|
+
hits: number;
|
|
54
|
+
/** Prompts labelled positive against any other rule. */
|
|
55
|
+
foreign: number;
|
|
56
|
+
share: number;
|
|
57
|
+
/**
|
|
58
|
+
* Occurrences in a near-miss the rule ITSELF declares — the keyword fires
|
|
59
|
+
* on a prompt that rule's own fixture says it must not fire on. A declared
|
|
60
|
+
* false positive, and the sharpest row this report can produce.
|
|
61
|
+
*/
|
|
62
|
+
own_near_miss_hits: number;
|
|
63
|
+
own_near_misses: number;
|
|
64
|
+
/** Occurrences in another rule's near-miss list. */
|
|
65
|
+
foreign_near_miss_hits: number;
|
|
66
|
+
/** Which rules those foreign positives belong to, highest first. */
|
|
67
|
+
top_labels: { rule: string; count: number }[];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Every prompt in the matrix, labelled with its file's rule and its kind. */
|
|
71
|
+
export function loadCorpus(matrixDir: string): LabelledPrompt[] {
|
|
72
|
+
const out: LabelledPrompt[] = [];
|
|
73
|
+
const files = fs
|
|
74
|
+
.readdirSync(matrixDir)
|
|
75
|
+
.filter((n) => n.endsWith('.yaml'))
|
|
76
|
+
.sort();
|
|
77
|
+
for (const file of files) {
|
|
78
|
+
const doc = parseYaml(fs.readFileSync(path.join(matrixDir, file), 'utf-8')) as {
|
|
79
|
+
rule?: unknown;
|
|
80
|
+
positives?: { prompt?: unknown }[];
|
|
81
|
+
near_misses?: { prompt?: unknown }[];
|
|
82
|
+
} | null;
|
|
83
|
+
const rule = typeof doc?.rule === 'string' ? doc.rule : '';
|
|
84
|
+
if (!rule) continue;
|
|
85
|
+
for (const [items, kind] of [
|
|
86
|
+
[doc?.positives, 'positive'],
|
|
87
|
+
[doc?.near_misses, 'near_miss'],
|
|
88
|
+
] as const) {
|
|
89
|
+
if (!Array.isArray(items)) continue;
|
|
90
|
+
for (const item of items) {
|
|
91
|
+
if (typeof item?.prompt === 'string' && item.prompt.trim()) {
|
|
92
|
+
out.push({ rule, prompt: item.prompt, kind });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return out;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** One-token keyword triggers per rule, from `src/rules/*.md` frontmatter. */
|
|
101
|
+
export function singleTokenKeywords(rulesDir: string): { rule: string; keyword: string }[] {
|
|
102
|
+
const out: { rule: string; keyword: string }[] = [];
|
|
103
|
+
const files = fs
|
|
104
|
+
.readdirSync(rulesDir)
|
|
105
|
+
.filter((n) => n.endsWith('.md'))
|
|
106
|
+
.sort();
|
|
107
|
+
for (const file of files) {
|
|
108
|
+
const content = fs.readFileSync(path.join(rulesDir, file), 'utf-8');
|
|
109
|
+
if (!content.startsWith('---')) continue;
|
|
110
|
+
const end = content.indexOf('\n---', 3);
|
|
111
|
+
const block = end === -1 ? content : content.slice(0, end);
|
|
112
|
+
const rule = file.replace(/\.md$/, '');
|
|
113
|
+
for (const m of block.matchAll(/^\s*-\s*keyword:\s*["']?([^"'\n]+?)["']?\s*$/gm)) {
|
|
114
|
+
const kw = (m[1] as string).trim();
|
|
115
|
+
if (kw === '' || /\s/.test(kw)) continue;
|
|
116
|
+
out.push({ rule, keyword: kw });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return out;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** Word-boundary, case-insensitive, with the keyword's own characters escaped. */
|
|
123
|
+
function occursAsWord(prompt: string, keyword: string): boolean {
|
|
124
|
+
const esc = keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
125
|
+
return new RegExp(`(?:^|[^\\p{L}\\p{N}_])${esc}(?:$|[^\\p{L}\\p{N}_])`, 'iu').test(prompt);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export function rows(
|
|
129
|
+
corpus: readonly LabelledPrompt[],
|
|
130
|
+
keywords: readonly { rule: string; keyword: string }[],
|
|
131
|
+
): TriggerRow[] {
|
|
132
|
+
const out: TriggerRow[] = [];
|
|
133
|
+
for (const { rule, keyword } of keywords) {
|
|
134
|
+
const foreign = corpus.filter((c) => c.rule !== rule && c.kind === 'positive');
|
|
135
|
+
if (foreign.length === 0) continue;
|
|
136
|
+
const hitting = foreign.filter((c) => occursAsWord(c.prompt, keyword));
|
|
137
|
+
const ownNear = corpus.filter((c) => c.rule === rule && c.kind === 'near_miss');
|
|
138
|
+
const foreignNear = corpus.filter((c) => c.rule !== rule && c.kind === 'near_miss');
|
|
139
|
+
const labels = new Map<string, number>();
|
|
140
|
+
for (const h of hitting) labels.set(h.rule, (labels.get(h.rule) ?? 0) + 1);
|
|
141
|
+
out.push({
|
|
142
|
+
rule,
|
|
143
|
+
keyword,
|
|
144
|
+
hits: hitting.length,
|
|
145
|
+
foreign: foreign.length,
|
|
146
|
+
share: hitting.length / foreign.length,
|
|
147
|
+
own_near_miss_hits: ownNear.filter((c) => occursAsWord(c.prompt, keyword)).length,
|
|
148
|
+
own_near_misses: ownNear.length,
|
|
149
|
+
foreign_near_miss_hits: foreignNear.filter((c) => occursAsWord(c.prompt, keyword)).length,
|
|
150
|
+
top_labels: [...labels.entries()]
|
|
151
|
+
.map(([r, count]) => ({ rule: r, count }))
|
|
152
|
+
.sort((a, b) => b.count - a.count || a.rule.localeCompare(b.rule))
|
|
153
|
+
.slice(0, 5),
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
out.sort(
|
|
157
|
+
(a, b) =>
|
|
158
|
+
b.share - a.share ||
|
|
159
|
+
b.own_near_miss_hits - a.own_near_miss_hits ||
|
|
160
|
+
b.foreign_near_miss_hits - a.foreign_near_miss_hits ||
|
|
161
|
+
a.rule.localeCompare(b.rule) ||
|
|
162
|
+
a.keyword.localeCompare(b.keyword),
|
|
163
|
+
);
|
|
164
|
+
return out;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export function renderTable(data: readonly TriggerRow[]): string[] {
|
|
168
|
+
const L: string[] = [];
|
|
169
|
+
L.push(
|
|
170
|
+
'| Rule | Keyword | Foreign positives | Share | Own near-miss hits | Foreign near-miss hits | Mostly labelled against |',
|
|
171
|
+
);
|
|
172
|
+
L.push('|---|---|---:|---:|---:|---:|---|');
|
|
173
|
+
for (const r of data) {
|
|
174
|
+
const labels = r.top_labels.map((l) => `\`${l.rule}\` ${String(l.count)}`).join(', ') || '—';
|
|
175
|
+
L.push(
|
|
176
|
+
`| \`${r.rule}\` | \`${r.keyword}\` | ${String(r.hits)}/${String(r.foreign)} | ` +
|
|
177
|
+
`${(r.share * 100).toFixed(1)} % | ${String(r.own_near_miss_hits)}/${String(r.own_near_misses)} | ` +
|
|
178
|
+
`${String(r.foreign_near_miss_hits)} | ${labels} |`,
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
return L;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const USAGE =
|
|
185
|
+
'usage: report_single_token_triggers [--root DIR] [--threshold F] [--json | --table] [--all]\n' +
|
|
186
|
+
' --threshold share above which a row is reported (default 0.05)\n' +
|
|
187
|
+
' --all report every one-token keyword, not just those over the threshold\n';
|
|
188
|
+
|
|
189
|
+
export function main(): number {
|
|
190
|
+
const argv = process.argv.slice(2);
|
|
191
|
+
if (argv.includes('--help') || argv.includes('-h')) {
|
|
192
|
+
process.stdout.write(USAGE);
|
|
193
|
+
return 0;
|
|
194
|
+
}
|
|
195
|
+
const KNOWN = ['--root', '--threshold', '--json', '--table', '--all'];
|
|
196
|
+
// A silently-ignored `--treshold` would report against a threshold the
|
|
197
|
+
// operator did not ask for, while still printing the default in the header.
|
|
198
|
+
for (const a of argv) {
|
|
199
|
+
if (a.startsWith('-') && !KNOWN.includes(a)) {
|
|
200
|
+
process.stderr.write(`unknown argument: ${a}\n${USAGE}`);
|
|
201
|
+
return 2;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
const flagValue = (f: string): string | null => {
|
|
205
|
+
const i = argv.indexOf(f);
|
|
206
|
+
return i >= 0 && i + 1 < argv.length ? (argv[i + 1] as string) : null;
|
|
207
|
+
};
|
|
208
|
+
const root = flagValue('--root') ?? process.cwd();
|
|
209
|
+
const rawT = flagValue('--threshold');
|
|
210
|
+
const threshold = rawT === null ? DEFAULT_THRESHOLD : Number.parseFloat(rawT);
|
|
211
|
+
if (!Number.isFinite(threshold) || threshold < 0 || threshold > 1) {
|
|
212
|
+
process.stderr.write('--threshold must be a fraction between 0 and 1\n');
|
|
213
|
+
return 2;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const matrixDir = path.join(root, 'tests', 'eval', 'routing-matrix');
|
|
217
|
+
const rulesDir = path.join(root, 'src', 'rules');
|
|
218
|
+
if (!fs.existsSync(matrixDir) || !fs.existsSync(rulesDir)) {
|
|
219
|
+
process.stderr.write(`missing ${matrixDir} or ${rulesDir}\n`);
|
|
220
|
+
return 1;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const corpus = loadCorpus(matrixDir);
|
|
224
|
+
const keywords = singleTokenKeywords(rulesDir);
|
|
225
|
+
const all = rows(corpus, keywords);
|
|
226
|
+
// A keyword reaches the report by EITHER axis: the share the step names, or
|
|
227
|
+
// a hit on a near-miss. Filtering on the share alone would have hidden the
|
|
228
|
+
// only rows this corpus actually produces — see the report's own § on why
|
|
229
|
+
// the 5 % threshold finds nothing here.
|
|
230
|
+
const data = argv.includes('--all')
|
|
231
|
+
? all
|
|
232
|
+
: all.filter((r) => r.share > threshold || r.own_near_miss_hits > 0 || r.foreign_near_miss_hits > 0);
|
|
233
|
+
|
|
234
|
+
if (argv.includes('--json')) {
|
|
235
|
+
process.stdout.write(
|
|
236
|
+
`${JSON.stringify({ threshold, corpus: corpus.length, keywords: keywords.length, rows: data }, null, 2)}\n`,
|
|
237
|
+
);
|
|
238
|
+
return 0;
|
|
239
|
+
}
|
|
240
|
+
if (argv.includes('--table')) {
|
|
241
|
+
process.stdout.write(`${renderTable(data).join('\n')}\n`);
|
|
242
|
+
return 0;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const positives = corpus.filter((c) => c.kind === 'positive').length;
|
|
246
|
+
process.stdout.write(
|
|
247
|
+
`corpus ${String(corpus.length)} prompt(s) — ${String(positives)} positive, ` +
|
|
248
|
+
`${String(corpus.length - positives)} near-miss · ` +
|
|
249
|
+
`${String(keywords.length)} one-token keyword(s) over ` +
|
|
250
|
+
`${String(new Set(keywords.map((k) => k.rule)).size)} rule(s)\n` +
|
|
251
|
+
`${String(all.filter((r) => r.share > threshold).length)} row(s) above ` +
|
|
252
|
+
`${(threshold * 100).toFixed(1)} % of foreign positives · ` +
|
|
253
|
+
`${String(data.length)} reportable on either axis\n\n`,
|
|
254
|
+
);
|
|
255
|
+
for (const r of data) {
|
|
256
|
+
process.stdout.write(
|
|
257
|
+
` ${(r.share * 100).toFixed(1).padStart(5)} % ${r.keyword.padEnd(18)} ${r.rule.padEnd(32)} ` +
|
|
258
|
+
`pos ${String(r.hits)}/${String(r.foreign)} own-near ${String(r.own_near_miss_hits)}/${String(r.own_near_misses)} ` +
|
|
259
|
+
`foreign-near ${String(r.foreign_near_miss_hits)}\n`,
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
return 0;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function _isCliEntry(): boolean {
|
|
266
|
+
if (process.argv[1] === undefined) return false;
|
|
267
|
+
if (import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href) return true;
|
|
268
|
+
try {
|
|
269
|
+
return fs.realpathSync(_HERE) === fs.realpathSync(path.resolve(process.argv[1]));
|
|
270
|
+
} catch {
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (_isCliEntry()) {
|
|
276
|
+
process.exit(main());
|
|
277
|
+
}
|