@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,212 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Report — which `_lib` modules does nothing in production call?
|
|
4
|
+
*
|
|
5
|
+
* A REPORT, not a gate: it always exits 0. Phase 3 of
|
|
6
|
+
* `road-to-modules-that-something-calls.md` wires its counts into
|
|
7
|
+
* `check_gate_reachability`'s own output, reported and not gated, the way
|
|
8
|
+
* the estate gate already prints its draft-roadmap count.
|
|
9
|
+
*
|
|
10
|
+
* ```bash
|
|
11
|
+
* report_module_reach # human-readable, one line per module
|
|
12
|
+
* report_module_reach --markdown # the four tables, for the evidence page
|
|
13
|
+
* report_module_reach --json
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
import * as path from 'node:path';
|
|
17
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
18
|
+
import * as fs from 'node:fs';
|
|
19
|
+
|
|
20
|
+
import { analyseModuleReach, groupCounts, type ModuleFact, type ReachGroup } from './_lib/module_reach.js';
|
|
21
|
+
import { assertScanned, reportScanned } from './_lib/scan_scope.js';
|
|
22
|
+
|
|
23
|
+
const _FILE = fileURLToPath(import.meta.url);
|
|
24
|
+
const REPO = path.resolve(path.dirname(_FILE), '..', '..');
|
|
25
|
+
|
|
26
|
+
const GROUP_LABEL: Record<ReachGroup, string> = {
|
|
27
|
+
'contract-test': 'imported by a test under tests/contracts/',
|
|
28
|
+
'open-or-deferred-step': 'named in an open or deferred step',
|
|
29
|
+
'named-outside-open-step': 'named in such a roadmap outside any open step',
|
|
30
|
+
'named-in-none': 'named in no live roadmap',
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
function humanLine(m: ModuleFact): string {
|
|
34
|
+
const bits = [
|
|
35
|
+
`${m.lines}L`,
|
|
36
|
+
m.namedByProduction ? 'named-by-production' : 'UNREFERENCED',
|
|
37
|
+
m.reachedByImportOrPath ? 'reached' : 'REACHED-BY-NOTHING',
|
|
38
|
+
m.hasOwnEntryPoint ? 'has-entry-point' : null,
|
|
39
|
+
m.registryDeclared.length > 0 ? `registry:[${m.registryDeclared.join(',')}]` : null,
|
|
40
|
+
m.importingTests.length > 0 ? `tests:${String(m.importingTests.length)}` : 'tests:0',
|
|
41
|
+
m.group !== null ? `group:${m.group}` : null,
|
|
42
|
+
].filter((b): b is string => b !== null);
|
|
43
|
+
return ` ${m.relPath} — ${bits.join(' · ')}`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function human(modules: readonly ModuleFact[]): string {
|
|
47
|
+
const unreferenced = modules.filter((m) => !m.namedByProduction);
|
|
48
|
+
const unreached = modules.filter((m) => !m.reachedByImportOrPath);
|
|
49
|
+
const counts = groupCounts(unreferenced);
|
|
50
|
+
const lines: string[] = [];
|
|
51
|
+
lines.push(
|
|
52
|
+
`module reach: ${String(modules.length)} module(s) under src/scripts/_lib — ` +
|
|
53
|
+
`${String(unreferenced.length)} unreferenced by name, ${String(unreached.length)} reached by nothing`,
|
|
54
|
+
);
|
|
55
|
+
for (const m of modules) lines.push(humanLine(m));
|
|
56
|
+
lines.push('');
|
|
57
|
+
lines.push('unreferenced-by-name groups:');
|
|
58
|
+
for (const g of Object.keys(GROUP_LABEL) as ReachGroup[]) {
|
|
59
|
+
lines.push(` ${GROUP_LABEL[g]}: ${String(counts[g])}`);
|
|
60
|
+
}
|
|
61
|
+
return lines.join('\n');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function table(modules: readonly ModuleFact[], header: readonly string[], row: (m: ModuleFact) => string[]): string {
|
|
65
|
+
const lines = [`| ${header.join(' | ')} |`, `|${header.map(() => '---').join('|')}|`];
|
|
66
|
+
for (const m of modules) lines.push(`| ${row(m).join(' | ')} |`);
|
|
67
|
+
return lines.join('\n');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function markdown(modules: readonly ModuleFact[], roadmapsAvailable: boolean): string {
|
|
71
|
+
const unreferenced = modules.filter((m) => !m.namedByProduction);
|
|
72
|
+
const unreached = modules.filter((m) => !m.reachedByImportOrPath);
|
|
73
|
+
const byGroup = (g: ReachGroup): ModuleFact[] => unreferenced.filter((m) => m.group === g);
|
|
74
|
+
|
|
75
|
+
const lines: string[] = [];
|
|
76
|
+
lines.push('<!-- evidence-type: analysis -->');
|
|
77
|
+
lines.push('# Module reach — 2026-10');
|
|
78
|
+
lines.push('');
|
|
79
|
+
lines.push(
|
|
80
|
+
`Command: \`npx tsx src/scripts/report_module_reach.ts --markdown\`. ` +
|
|
81
|
+
`${String(modules.length)} module(s) directly under \`src/scripts/_lib/\`, ` +
|
|
82
|
+
`${String(unreferenced.length)} named in no file outside themselves and their own tests, ` +
|
|
83
|
+
`${String(unreached.length)} reached by nothing via import edges or run-by-path.`,
|
|
84
|
+
);
|
|
85
|
+
lines.push('');
|
|
86
|
+
if (!roadmapsAvailable) {
|
|
87
|
+
lines.push('> No `agents/roadmaps/` directory in this checkout — the two roadmap-based groups below are skipped.');
|
|
88
|
+
lines.push('');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
lines.push('## Group 1 — imported by a contract test');
|
|
92
|
+
lines.push('');
|
|
93
|
+
lines.push(table(byGroup('contract-test'), ['module', 'lines', 'evidence'], (m) => [m.relPath, String(m.lines), m.groupEvidence ?? '']));
|
|
94
|
+
lines.push('');
|
|
95
|
+
|
|
96
|
+
lines.push('## Group 2 — named in an open or deferred step');
|
|
97
|
+
lines.push('');
|
|
98
|
+
lines.push(
|
|
99
|
+
table(byGroup('open-or-deferred-step'), ['module', 'lines', 'evidence'], (m) => [
|
|
100
|
+
m.relPath,
|
|
101
|
+
String(m.lines),
|
|
102
|
+
m.groupEvidence ?? '',
|
|
103
|
+
]),
|
|
104
|
+
);
|
|
105
|
+
lines.push('');
|
|
106
|
+
|
|
107
|
+
lines.push('## Group 3 — named in such a roadmap outside any open step');
|
|
108
|
+
lines.push('');
|
|
109
|
+
lines.push(
|
|
110
|
+
table(byGroup('named-outside-open-step'), ['module', 'lines', 'evidence'], (m) => [
|
|
111
|
+
m.relPath,
|
|
112
|
+
String(m.lines),
|
|
113
|
+
m.groupEvidence ?? '',
|
|
114
|
+
]),
|
|
115
|
+
);
|
|
116
|
+
lines.push('');
|
|
117
|
+
|
|
118
|
+
lines.push('## Group 4 — named in no live roadmap');
|
|
119
|
+
lines.push('');
|
|
120
|
+
lines.push(
|
|
121
|
+
table(byGroup('named-in-none'), ['module', 'lines', 'importing tests'], (m) => [
|
|
122
|
+
m.relPath,
|
|
123
|
+
String(m.lines),
|
|
124
|
+
String(m.importingTests.length),
|
|
125
|
+
]),
|
|
126
|
+
);
|
|
127
|
+
lines.push('');
|
|
128
|
+
|
|
129
|
+
lines.push('## Every module under `_lib` — full facts');
|
|
130
|
+
lines.push('');
|
|
131
|
+
lines.push(
|
|
132
|
+
table(
|
|
133
|
+
modules,
|
|
134
|
+
['module', 'lines', 'importing tests', 'named by production', 'has entry point', 'registry', 'reached'],
|
|
135
|
+
(m) => [
|
|
136
|
+
m.relPath,
|
|
137
|
+
String(m.lines),
|
|
138
|
+
String(m.importingTests.length),
|
|
139
|
+
m.namedByProduction ? 'yes' : 'no',
|
|
140
|
+
m.hasOwnEntryPoint ? 'yes' : 'no',
|
|
141
|
+
m.registryDeclared.length > 0 ? m.registryDeclared.join(', ') : '—',
|
|
142
|
+
m.reachedByImportOrPath ? 'yes' : 'no',
|
|
143
|
+
],
|
|
144
|
+
),
|
|
145
|
+
);
|
|
146
|
+
lines.push('');
|
|
147
|
+
|
|
148
|
+
// Phase 2.1: one `reading:` line per fourth-group module — never the
|
|
149
|
+
// whole unreferenced set, which also holds groups 1-3 that Phase 2
|
|
150
|
+
// explicitly leaves untouched. The content here is a placeholder; the
|
|
151
|
+
// real verdict (test-carried / helper-never-connected / only-caller-is-
|
|
152
|
+
// its-own-test) is a judgement call a re-run of this script cannot make,
|
|
153
|
+
// and is filled in by hand after reading each module and its test.
|
|
154
|
+
for (const m of byGroup('named-in-none')) {
|
|
155
|
+
lines.push(`reading: ${m.relPath} — TODO: read the module and its test, then state the verdict`);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return lines.join('\n');
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export function main(argv: readonly string[] = process.argv.slice(2), root = REPO): number {
|
|
162
|
+
const { modules, roadmapsAvailable } = analyseModuleReach(root);
|
|
163
|
+
// One options literal, not three (a second R2 review found it triplicated
|
|
164
|
+
// across the --json, --markdown and default branches).
|
|
165
|
+
const scanOpts = {
|
|
166
|
+
gate: 'report_module_reach',
|
|
167
|
+
scanned: modules.length,
|
|
168
|
+
units: 'module(s) under src/scripts/_lib',
|
|
169
|
+
roots: ['src/scripts/_lib'],
|
|
170
|
+
};
|
|
171
|
+
if (argv.includes('--json')) {
|
|
172
|
+
// No trailing `scanned:` line here — an R2 review found that
|
|
173
|
+
// `reportScanned` (which PRINTS) made this invalid as a single JSON
|
|
174
|
+
// document; `check_gate_reachability.ts`'s own `--json` branch already
|
|
175
|
+
// returns immediately after writing JSON for the same reason. The
|
|
176
|
+
// scope is still ASSERTED (never silently printed clean from an empty
|
|
177
|
+
// corpus).
|
|
178
|
+
assertScanned(scanOpts);
|
|
179
|
+
process.stdout.write(`${JSON.stringify({ modules, roadmapsAvailable }, null, 2)}\n`);
|
|
180
|
+
} else if (argv.includes('--markdown')) {
|
|
181
|
+
// The page is the artifact — no trailing `scanned:` line inside it,
|
|
182
|
+
// but the scope is still asserted (never silently printed clean from
|
|
183
|
+
// an empty corpus). The default human mode below is the only one that
|
|
184
|
+
// still publishes the count per this family's convention.
|
|
185
|
+
assertScanned(scanOpts);
|
|
186
|
+
process.stdout.write(`${markdown(modules, roadmapsAvailable)}\n`);
|
|
187
|
+
} else {
|
|
188
|
+
// Asserted BEFORE writing, matching the other two branches (an R2
|
|
189
|
+
// review found the prior "assert after" order here was the one case
|
|
190
|
+
// that would have printed a human report before a DeadScopeError on
|
|
191
|
+
// an empty corpus, while --json/--markdown print nothing in that
|
|
192
|
+
// case) — then printed, since the default mode is the one that still
|
|
193
|
+
// publishes the count per this family's convention.
|
|
194
|
+
reportScanned(scanOpts);
|
|
195
|
+
process.stdout.write(`${human(modules)}\n`);
|
|
196
|
+
}
|
|
197
|
+
return 0;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function _isCliEntry(): boolean {
|
|
201
|
+
const a = process.argv[1];
|
|
202
|
+
if (!a) return false;
|
|
203
|
+
if (a === _FILE || pathToFileURL(path.resolve(a)).href === import.meta.url) return true;
|
|
204
|
+
try {
|
|
205
|
+
return fs.realpathSync(a) === fs.realpathSync(_FILE);
|
|
206
|
+
} catch {
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
if (_isCliEntry()) process.exit(main());
|
|
211
|
+
|
|
212
|
+
export { REPO };
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Per rule: is the obligation already carried by a mechanism, and is there a
|
|
4
|
+
* slot that could carry it?
|
|
5
|
+
*
|
|
6
|
+
* Step 1.5 of `road-to-rule-triggers-and-links-that-hold`. It joins three
|
|
7
|
+
* instruments that already exist and had never been read together:
|
|
8
|
+
*
|
|
9
|
+
* · `check_enforcement_coverage --json` — the only place `enforced_by` and
|
|
10
|
+
* `obligation_frequency` are already resolved per rule, including what the
|
|
11
|
+
* declaration resolves TO (a wired validator, a bound hook, nothing).
|
|
12
|
+
* · `report_obligation_carriers` — how many artifacts restate the same
|
|
13
|
+
* obligation, which is a different question from whether one enforces it.
|
|
14
|
+
* · `src/config/rule-obligations.json` — the stable obligation ids per rule
|
|
15
|
+
* (road-to-enforcement-per-obligation). It replaced the hand-kept
|
|
16
|
+
* `# obligation: line N` frontmatter marker this report was the only
|
|
17
|
+
* reader of, and whose line numbers had drifted out of the law section on
|
|
18
|
+
* half the rules that carried one.
|
|
19
|
+
*
|
|
20
|
+
* **Two columns, and conflating them would be the error worth avoiding.**
|
|
21
|
+
* `carried` is measured: a gate either refuses or it does not.
|
|
22
|
+
* `slot_exists` is NECESSARY, NEVER SUFFICIENT — it says a host event fires at
|
|
23
|
+
* the obligation's own frequency, so a carrier could at least be bound. It
|
|
24
|
+
* does not say the obligation is decidable from what that event sees, which is
|
|
25
|
+
* the actual question and is not answerable by a join. A rule whose body says
|
|
26
|
+
* `instruction-only` has usually already answered it in the other direction,
|
|
27
|
+
* and that answer is reproduced rather than overridden.
|
|
28
|
+
*
|
|
29
|
+
* Report only. Moving an obligation out of prose is a per-rule change with its
|
|
30
|
+
* own review, which this roadmap's scope section says in as many words.
|
|
31
|
+
*/
|
|
32
|
+
import { execFileSync } from 'node:child_process';
|
|
33
|
+
import * as fs from 'node:fs';
|
|
34
|
+
import * as path from 'node:path';
|
|
35
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
36
|
+
|
|
37
|
+
import { loadRuleObligations, RULE_OBLIGATIONS_PATH } from './_lib/rule_obligations.js';
|
|
38
|
+
|
|
39
|
+
// ledger-exempt: a REPORTER, not a gate. Its only non-zero exit says an input
|
|
40
|
+
// instrument could not be run, which is a statement about the walk.
|
|
41
|
+
|
|
42
|
+
const _HERE = fileURLToPath(import.meta.url);
|
|
43
|
+
|
|
44
|
+
/** Frequencies a host event is known to fire at — the `slot_exists` test. */
|
|
45
|
+
const EVENT_BOUND_FREQUENCIES: ReadonlySet<string> = new Set([
|
|
46
|
+
'per-edit',
|
|
47
|
+
'per-file-write',
|
|
48
|
+
'per-commit',
|
|
49
|
+
'per-turn',
|
|
50
|
+
'per-session',
|
|
51
|
+
'per-event',
|
|
52
|
+
'per-task',
|
|
53
|
+
]);
|
|
54
|
+
|
|
55
|
+
/** Resolutions where something can actually refuse. */
|
|
56
|
+
const REFUSING: ReadonlySet<string> = new Set(['validator', 'validator-local', 'test', 'hook']);
|
|
57
|
+
|
|
58
|
+
export interface MechanismRow {
|
|
59
|
+
rule: string;
|
|
60
|
+
tier: string;
|
|
61
|
+
/** Obligation ids this rule declares, `null` when it declares none (the kernel). */
|
|
62
|
+
obligations: number | null;
|
|
63
|
+
frequency: string;
|
|
64
|
+
declared: number;
|
|
65
|
+
effective: string;
|
|
66
|
+
/** `gate` · `observer` · `declared-gap` · `undeclared`. */
|
|
67
|
+
carried: string;
|
|
68
|
+
/** A host event is known to fire at this frequency. Necessary, not sufficient. */
|
|
69
|
+
slot_exists: boolean;
|
|
70
|
+
/** Artifacts restating this rule's obligations, per the carrier census. */
|
|
71
|
+
restatements: number;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function run(root: string, script: string, args: readonly string[]): string {
|
|
75
|
+
return execFileSync(path.join(root, 'scripts-run'), [script, ...args], {
|
|
76
|
+
cwd: root,
|
|
77
|
+
encoding: 'utf8',
|
|
78
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
79
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
interface CoverageRule {
|
|
84
|
+
id: string;
|
|
85
|
+
tier?: string;
|
|
86
|
+
declared?: string[];
|
|
87
|
+
effective?: string;
|
|
88
|
+
obligation_frequency?: string | null;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function rows(root: string): MechanismRow[] {
|
|
92
|
+
const coverage = JSON.parse(run(root, 'src/scripts/check_enforcement_coverage', ['--json'])) as {
|
|
93
|
+
rules: CoverageRule[];
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
run(root, 'src/scripts/report_obligation_carriers', ['--top', '1']);
|
|
97
|
+
const carriersPath = path.join(root, 'agents', 'runtime', 'reports', 'obligation-carriers.json');
|
|
98
|
+
const restatements = new Map<string, number>();
|
|
99
|
+
if (!fs.existsSync(carriersPath)) {
|
|
100
|
+
// Not a degradation to absorb: `agents/runtime/` is gitignored, so a
|
|
101
|
+
// fresh checkout reaches this, and a silent fallback would publish a
|
|
102
|
+
// uniformly-zero Restatements column with nothing saying it is empty.
|
|
103
|
+
// Every other input failure in this script exits 1; so does this one.
|
|
104
|
+
throw new Error(
|
|
105
|
+
`report_obligation_carriers wrote no census at ${carriersPath} — the ` +
|
|
106
|
+
'Restatements column would read 0 for every rule without saying so',
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
{
|
|
110
|
+
const census = JSON.parse(fs.readFileSync(carriersPath, 'utf8')) as {
|
|
111
|
+
rows: { carriers: { path: string; cls: string }[] }[];
|
|
112
|
+
};
|
|
113
|
+
for (const r of census.rows) {
|
|
114
|
+
// A row is one obligation; it counts for every RULE that carries it.
|
|
115
|
+
for (const c of r.carriers) {
|
|
116
|
+
if (c.cls !== 'rule') continue;
|
|
117
|
+
const id = path.basename(c.path, '.md');
|
|
118
|
+
restatements.set(id, (restatements.get(id) ?? 0) + r.carriers.length - 1);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const inventory = fs.existsSync(path.join(root, RULE_OBLIGATIONS_PATH))
|
|
124
|
+
? loadRuleObligations(root).rules
|
|
125
|
+
: {};
|
|
126
|
+
const out: MechanismRow[] = [];
|
|
127
|
+
for (const r of coverage.rules) {
|
|
128
|
+
const declared = r.declared ?? [];
|
|
129
|
+
const effective = r.effective ?? 'none';
|
|
130
|
+
const frequency = r.obligation_frequency ?? '—';
|
|
131
|
+
|
|
132
|
+
let carried: string;
|
|
133
|
+
if (REFUSING.has(effective)) carried = 'gate';
|
|
134
|
+
else if (effective === 'observer') carried = 'observer';
|
|
135
|
+
else if (declared.length > 0) carried = 'declared-gap';
|
|
136
|
+
else carried = 'undeclared';
|
|
137
|
+
|
|
138
|
+
out.push({
|
|
139
|
+
rule: r.id,
|
|
140
|
+
tier: r.tier ?? '—',
|
|
141
|
+
obligations: inventory[r.id]?.obligations.length ?? null,
|
|
142
|
+
frequency,
|
|
143
|
+
declared: declared.length,
|
|
144
|
+
effective,
|
|
145
|
+
carried,
|
|
146
|
+
slot_exists: EVENT_BOUND_FREQUENCIES.has(frequency),
|
|
147
|
+
restatements: restatements.get(r.id) ?? 0,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
out.sort((a, b) => a.rule.localeCompare(b.rule));
|
|
151
|
+
return out;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export function renderTable(data: readonly MechanismRow[]): string[] {
|
|
155
|
+
const L: string[] = [];
|
|
156
|
+
L.push('| Rule | Tier | Obligations | Frequency | `enforced_by` | Resolves to | Carried | Slot exists | Restatements |');
|
|
157
|
+
L.push('|---|---|---:|---|---:|---|---|---|---:|');
|
|
158
|
+
for (const r of data) {
|
|
159
|
+
L.push(
|
|
160
|
+
`| \`${r.rule}\` | ${r.tier} | ${r.obligations === null ? '—' : String(r.obligations)} | ` +
|
|
161
|
+
`${r.frequency} | ${String(r.declared)} | \`${r.effective}\` | ${r.carried} | ` +
|
|
162
|
+
`${r.slot_exists ? 'yes' : 'no'} | ${String(r.restatements)} |`,
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
return L;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const USAGE = 'usage: report_obligation_mechanism [--root DIR] [--json | --table]\n';
|
|
169
|
+
|
|
170
|
+
export function main(): number {
|
|
171
|
+
const argv = process.argv.slice(2);
|
|
172
|
+
if (argv.includes('--help') || argv.includes('-h')) {
|
|
173
|
+
process.stdout.write(USAGE);
|
|
174
|
+
return 0;
|
|
175
|
+
}
|
|
176
|
+
for (const a of argv) {
|
|
177
|
+
if (a.startsWith('-') && !['--root', '--json', '--table'].includes(a)) {
|
|
178
|
+
process.stderr.write(`unknown argument: ${a}\n${USAGE}`);
|
|
179
|
+
return 2;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
const i = argv.indexOf('--root');
|
|
183
|
+
const root = i >= 0 && i + 1 < argv.length ? (argv[i + 1] as string) : process.cwd();
|
|
184
|
+
|
|
185
|
+
let data: MechanismRow[];
|
|
186
|
+
try {
|
|
187
|
+
data = rows(root);
|
|
188
|
+
} catch (e) {
|
|
189
|
+
process.stderr.write(`could not read an input instrument: ${String(e)}\n`);
|
|
190
|
+
return 1;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (argv.includes('--json')) {
|
|
194
|
+
process.stdout.write(`${JSON.stringify(data, null, 2)}\n`);
|
|
195
|
+
return 0;
|
|
196
|
+
}
|
|
197
|
+
if (argv.includes('--table')) {
|
|
198
|
+
process.stdout.write(`${renderTable(data).join('\n')}\n`);
|
|
199
|
+
return 0;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const by = (k: string): number => data.filter((r) => r.carried === k).length;
|
|
203
|
+
const slotNoGate = data.filter((r) => r.carried !== 'gate' && r.slot_exists).length;
|
|
204
|
+
process.stdout.write(
|
|
205
|
+
`${String(data.length)} rule(s)\n` +
|
|
206
|
+
` carried by a gate that can refuse: ${String(by('gate'))}\n` +
|
|
207
|
+
` carried by an observer (fires, never refuses): ${String(by('observer'))}\n` +
|
|
208
|
+
` declared gap (the rule says instruction-only / none): ${String(by('declared-gap'))}\n` +
|
|
209
|
+
` no enforcement declaration at all: ${String(by('undeclared'))}\n` +
|
|
210
|
+
` not gated, but a host event fires at the obligation's frequency: ${String(slotNoGate)}\n` +
|
|
211
|
+
` declare no obligation ids: ${String(data.filter((r) => r.obligations === null).length)}\n`,
|
|
212
|
+
);
|
|
213
|
+
return 0;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function _isCliEntry(): boolean {
|
|
217
|
+
if (process.argv[1] === undefined) return false;
|
|
218
|
+
if (import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href) return true;
|
|
219
|
+
try {
|
|
220
|
+
return fs.realpathSync(_HERE) === fs.realpathSync(path.resolve(process.argv[1]));
|
|
221
|
+
} catch {
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (_isCliEntry()) {
|
|
227
|
+
process.exit(main());
|
|
228
|
+
}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Census of open blockers in parked roadmaps — measures, never gates.
|
|
4
|
+
*
|
|
5
|
+
* `lint_roadmap_blockers` and `/roadmap:resolve-blockers` both exclude
|
|
6
|
+
* the parked directory (`later/`) by a recorded decision ("history rather than
|
|
7
|
+
* debt"). This report reads exactly that directory so the decision can be
|
|
8
|
+
* revisited on a number rather than a guess: every `### blocker:` entry whose
|
|
9
|
+
* `Status:` is not `resolved`, with its file, its raw `Owner:` value and
|
|
10
|
+
* whether that owner is the owner (maintainer / user / owner — the same set
|
|
11
|
+
* `lint_roadmap_blockers` treats as a user decision) or a condition an agent
|
|
12
|
+
* can reach. Separately it lists every blockquote that names an owner
|
|
13
|
+
* question or owner decision, because such a question is invisible to any
|
|
14
|
+
* blocker reader even when its directory is in scope.
|
|
15
|
+
*
|
|
16
|
+
* The raw `Owner:` value is printed beside its classification: the field is
|
|
17
|
+
* free text, and a misread must be visible to whoever reads the report.
|
|
18
|
+
*
|
|
19
|
+
* Usage:
|
|
20
|
+
* ./scripts-run src/scripts/report_parked_blockers
|
|
21
|
+
* ./scripts-run src/scripts/report_parked_blockers --format json
|
|
22
|
+
* ./scripts-run src/scripts/report_parked_blockers --dir <path>
|
|
23
|
+
*
|
|
24
|
+
* Exit codes: 0 report emitted · 2 usage error.
|
|
25
|
+
*/
|
|
26
|
+
import * as fs from 'node:fs';
|
|
27
|
+
import * as path from 'node:path';
|
|
28
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
29
|
+
|
|
30
|
+
import { REPO_ROOT, _stripFencedCode } from './lint_roadmap_blockers.js';
|
|
31
|
+
|
|
32
|
+
type OwnerWait = 'owner' | 'agent';
|
|
33
|
+
|
|
34
|
+
interface ParkedBlocker {
|
|
35
|
+
file: string;
|
|
36
|
+
id: string;
|
|
37
|
+
status: string;
|
|
38
|
+
owner: string;
|
|
39
|
+
wait: OwnerWait;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface OwnerQuestion {
|
|
43
|
+
file: string;
|
|
44
|
+
line: number;
|
|
45
|
+
text: string;
|
|
46
|
+
blocker_entries_in_file: number;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
interface Census {
|
|
50
|
+
dir: string;
|
|
51
|
+
files_scanned: number;
|
|
52
|
+
files_with_open_blockers: number;
|
|
53
|
+
blockers: ParkedBlocker[];
|
|
54
|
+
owner_questions: OwnerQuestion[];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const BLOCKERS_SECTION_RE = /^##[ \t]+Blockers[ \t]*$/im;
|
|
58
|
+
const NEXT_H2_RE = /^##[ \t]+\S/m;
|
|
59
|
+
const BLOCKER_HEADING_RE = /^###[ \t]+blocker:[ \t]*(.+?)[ \t]*$/gim;
|
|
60
|
+
const STATUS_RE = /^-[ \t]*\*\*Status:\*\*[ \t]*(.*)$/im;
|
|
61
|
+
const OWNER_RE = /^-[ \t]*\*\*Owner:\*\*[ \t]*(.*)$/im;
|
|
62
|
+
const OWNER_WAIT_RE = /^(maintainer|user|owner)\b/i;
|
|
63
|
+
const OWNER_QUESTION_RE = /owner[ \t]+(question|decision)/i;
|
|
64
|
+
|
|
65
|
+
function _classifyOwner(raw: string): OwnerWait {
|
|
66
|
+
return OWNER_WAIT_RE.test(raw.trim()) ? 'owner' : 'agent';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Every blocker entry in one file's `## Blockers` section, open or not. */
|
|
70
|
+
function _blockerEntries(text: string): Array<{ id: string; status: string; owner: string }> {
|
|
71
|
+
const stripped = _stripFencedCode(text);
|
|
72
|
+
const sectionMatch = BLOCKERS_SECTION_RE.exec(stripped);
|
|
73
|
+
if (!sectionMatch) {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
const start = sectionMatch.index + sectionMatch[0].length;
|
|
77
|
+
const rest = stripped.slice(start);
|
|
78
|
+
const h2 = NEXT_H2_RE.exec(rest);
|
|
79
|
+
const section = h2 ? rest.slice(0, h2.index) : rest;
|
|
80
|
+
|
|
81
|
+
const heads: Array<{ start: number; end: number; id: string }> = [];
|
|
82
|
+
BLOCKER_HEADING_RE.lastIndex = 0;
|
|
83
|
+
let hm: RegExpExecArray | null;
|
|
84
|
+
while ((hm = BLOCKER_HEADING_RE.exec(section)) !== null) {
|
|
85
|
+
heads.push({ start: hm.index, end: hm.index + hm[0].length, id: (hm[1] as string).trim() });
|
|
86
|
+
if (hm.index === BLOCKER_HEADING_RE.lastIndex) {
|
|
87
|
+
BLOCKER_HEADING_RE.lastIndex++;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return heads.map((cur, i) => {
|
|
91
|
+
const next = heads[i + 1];
|
|
92
|
+
const body = section.slice(cur.end, next ? next.start : section.length);
|
|
93
|
+
return {
|
|
94
|
+
id: cur.id,
|
|
95
|
+
status: (STATUS_RE.exec(body)?.[1] ?? '').trim(),
|
|
96
|
+
owner: (OWNER_RE.exec(body)?.[1] ?? '').trim(),
|
|
97
|
+
};
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Blockquote lines that name an owner question or owner decision. */
|
|
102
|
+
function _ownerQuestionLines(text: string): Array<{ line: number; text: string }> {
|
|
103
|
+
const out: Array<{ line: number; text: string }> = [];
|
|
104
|
+
let inFence = false;
|
|
105
|
+
text.split('\n').forEach((raw, i) => {
|
|
106
|
+
if (/^[ \t]*```/.test(raw)) {
|
|
107
|
+
inFence = !inFence;
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (!inFence && /^[ \t]*>/.test(raw) && OWNER_QUESTION_RE.test(raw)) {
|
|
111
|
+
out.push({ line: i + 1, text: raw.trim() });
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
return out;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function collect(dir: string, root: string = REPO_ROOT): Census {
|
|
118
|
+
const files = fs.existsSync(dir)
|
|
119
|
+
? fs
|
|
120
|
+
.readdirSync(dir, { withFileTypes: true })
|
|
121
|
+
.filter((e) => e.isFile() && e.name.endsWith('.md'))
|
|
122
|
+
.map((e) => path.join(dir, e.name))
|
|
123
|
+
.sort()
|
|
124
|
+
: [];
|
|
125
|
+
const blockers: ParkedBlocker[] = [];
|
|
126
|
+
const ownerQuestions: OwnerQuestion[] = [];
|
|
127
|
+
const filesWithOpen = new Set<string>();
|
|
128
|
+
for (const abs of files) {
|
|
129
|
+
const rel = path.relative(root, abs).split(path.sep).join('/');
|
|
130
|
+
const text = fs.readFileSync(abs, 'utf8');
|
|
131
|
+
const entries = _blockerEntries(text);
|
|
132
|
+
for (const e of entries) {
|
|
133
|
+
if (/^resolved\b/i.test(e.status)) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
filesWithOpen.add(rel);
|
|
137
|
+
blockers.push({ file: rel, id: e.id, status: e.status, owner: e.owner, wait: _classifyOwner(e.owner) });
|
|
138
|
+
}
|
|
139
|
+
for (const q of _ownerQuestionLines(text)) {
|
|
140
|
+
ownerQuestions.push({ file: rel, line: q.line, text: q.text, blocker_entries_in_file: entries.length });
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
dir: path.relative(root, dir).split(path.sep).join('/'),
|
|
145
|
+
files_scanned: files.length,
|
|
146
|
+
files_with_open_blockers: filesWithOpen.size,
|
|
147
|
+
blockers,
|
|
148
|
+
owner_questions: ownerQuestions,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function format(c: Census): string {
|
|
153
|
+
const owner = c.blockers.filter((b) => b.wait === 'owner');
|
|
154
|
+
const agent = c.blockers.filter((b) => b.wait === 'agent');
|
|
155
|
+
const lines: string[] = [];
|
|
156
|
+
lines.push(`Parked blockers under ${c.dir}/`);
|
|
157
|
+
lines.push(
|
|
158
|
+
`files scanned: ${c.files_scanned} · files with an open blocker: ${c.files_with_open_blockers} · open blockers: ${c.blockers.length} (owner-wait ${owner.length}, agent-wait ${agent.length})`,
|
|
159
|
+
);
|
|
160
|
+
for (const [label, group] of [
|
|
161
|
+
['owner-wait', owner],
|
|
162
|
+
['agent-wait', agent],
|
|
163
|
+
] as const) {
|
|
164
|
+
lines.push('');
|
|
165
|
+
lines.push(`## ${label} (${group.length})`);
|
|
166
|
+
for (const b of group) {
|
|
167
|
+
lines.push(`- ${b.file} · ${b.id} · Owner: ${b.owner || '(none)'} · Status: ${b.status || '(none)'}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
lines.push('');
|
|
171
|
+
lines.push(`## owner questions in blockquotes (${c.owner_questions.length})`);
|
|
172
|
+
for (const q of c.owner_questions) {
|
|
173
|
+
lines.push(`- ${q.file}:${q.line} · blocker entries in file: ${q.blocker_entries_in_file} · ${q.text.slice(0, 120)}`);
|
|
174
|
+
}
|
|
175
|
+
return `${lines.join('\n')}\n`;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function fail(message: string): never {
|
|
179
|
+
process.stderr.write(`report_parked_blockers: ${message}\n`);
|
|
180
|
+
process.exit(2);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function main(argv: string[] = process.argv.slice(2)): number {
|
|
184
|
+
let fmt: 'text' | 'json' = 'text';
|
|
185
|
+
let dir = path.join(REPO_ROOT, 'agents', 'roadmaps', 'later');
|
|
186
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
187
|
+
const arg = argv[i];
|
|
188
|
+
if (arg === '--format') {
|
|
189
|
+
const v = argv[i + 1];
|
|
190
|
+
if (v !== 'text' && v !== 'json') fail(`--format must be 'text' or 'json'`);
|
|
191
|
+
fmt = v;
|
|
192
|
+
i += 1;
|
|
193
|
+
} else if (arg === '--dir') {
|
|
194
|
+
const v = argv[i + 1];
|
|
195
|
+
if (v === undefined) fail('--dir requires a value');
|
|
196
|
+
dir = path.resolve(v);
|
|
197
|
+
i += 1;
|
|
198
|
+
} else {
|
|
199
|
+
fail(`unknown argument: ${arg}`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
const census = collect(dir);
|
|
203
|
+
process.stdout.write(fmt === 'json' ? `${JSON.stringify(census, null, 2)}\n` : format(census));
|
|
204
|
+
return 0;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (process.argv[1] !== undefined) {
|
|
208
|
+
try {
|
|
209
|
+
const here = fs.realpathSync(fileURLToPath(import.meta.url));
|
|
210
|
+
const argv1 = fs.realpathSync(path.resolve(process.argv[1]));
|
|
211
|
+
if (here === argv1) {
|
|
212
|
+
process.exit(main());
|
|
213
|
+
}
|
|
214
|
+
} catch {
|
|
215
|
+
if (import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href) {
|
|
216
|
+
process.exit(main());
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export { _classifyOwner, _blockerEntries, _ownerQuestionLines, collect, format, main };
|
|
222
|
+
export type { Census, ParkedBlocker, OwnerQuestion };
|