@event4u/agent-config 14.10.0 → 14.11.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 +335 -0
- package/README.md +1 -1
- package/dist/agent-src/commands/design.md +88 -0
- package/dist/agent-src/commands/project/analyze.md +47 -0
- package/dist/agent-src/commands/review/changes.md +67 -6
- package/dist/agent-src/commands/roadmap/create.md +49 -0
- package/dist/agent-src/commands/roadmap/next.md +27 -11
- package/dist/agent-src/commands/roadmap/process-full.md +14 -0
- package/dist/agent-src/commands/video/from-script.md +60 -3
- package/dist/agent-src/commands/video/stitch.md +14 -0
- package/dist/agent-src/contexts/communication/rules-auto/guidelines-mechanics.md +1 -0
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +154 -2
- package/dist/agent-src/rules/active-remediation.md +3 -3
- package/dist/agent-src/rules/code-provenance.md +2 -2
- package/dist/agent-src/rules/context-hygiene.md +13 -33
- package/dist/agent-src/rules/council-availability.md +2 -2
- package/dist/agent-src/rules/decision-revisit-gate.md +3 -1
- package/dist/agent-src/rules/design-fidelity.md +18 -0
- package/dist/agent-src/rules/design-review-after-ui-write.md +2 -2
- package/dist/agent-src/rules/evaluator-independence.md +56 -44
- package/dist/agent-src/rules/fix-what-you-see.md +9 -1
- package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +1 -1
- package/dist/agent-src/rules/minimal-safe-diff.md +14 -20
- package/dist/agent-src/rules/missing-skill-recovery.md +13 -1
- package/dist/agent-src/rules/playbook-precedence.md +105 -0
- package/dist/agent-src/rules/recurring-criticism.md +3 -1
- package/dist/agent-src/rules/roadmap-progress-sync.md +14 -13
- package/dist/agent-src/rules/scale-discipline.md +24 -0
- package/dist/agent-src/rules/security-sensitive-stop.md +2 -2
- package/dist/agent-src/rules/settings-ask-protocol.md +2 -2
- package/dist/agent-src/rules/ui-audit-gate.md +27 -15
- package/dist/agent-src/rules/untrusted-input-defense.md +2 -2
- package/dist/agent-src/skills/accessibility-auditor/SKILL.md +19 -0
- package/dist/agent-src/skills/adr-create/SKILL.md +7 -0
- package/dist/agent-src/skills/agents-md-thin-root/SKILL.md +33 -0
- package/dist/agent-src/skills/ai-council/references/advanced-modes.md +17 -3
- package/dist/agent-src/skills/ai-council/references/output-and-synthesis.md +31 -0
- package/dist/agent-src/skills/ai-council/references/procedure.md +19 -0
- package/dist/agent-src/skills/alerting-doctrine/SKILL.md +225 -0
- package/dist/agent-src/skills/alerting-doctrine/evals/triggers.json +17 -0
- package/dist/agent-src/skills/authz-review/SKILL.md +0 -1
- package/dist/agent-src/skills/blast-radius-analyzer/SKILL.md +32 -0
- package/dist/agent-src/skills/brand/SKILL.md +3 -0
- package/dist/agent-src/skills/brand-asset-generation/SKILL.md +3 -0
- package/dist/agent-src/skills/brand-audit/SKILL.md +3 -0
- package/dist/agent-src/skills/brand-identity/SKILL.md +3 -0
- package/dist/agent-src/skills/brand-strategy/SKILL.md +3 -0
- package/dist/agent-src/skills/brand-to-tokens/SKILL.md +3 -0
- package/dist/agent-src/skills/check-refs/SKILL.md +3 -0
- package/dist/agent-src/skills/code-review/SKILL.md +11 -0
- package/dist/agent-src/skills/command-routing/SKILL.md +6 -0
- package/dist/agent-src/skills/condense-memory/SKILL.md +3 -0
- package/dist/agent-src/skills/context-authoring/SKILL.md +1 -1
- package/dist/agent-src/skills/conventional-commits-writing/SKILL.md +3 -0
- package/dist/agent-src/skills/copilot-agents-optimization/SKILL.md +10 -0
- package/dist/agent-src/skills/corpus-grounding/SKILL.md +3 -0
- package/dist/agent-src/skills/design-intelligence/SKILL.md +3 -0
- package/dist/agent-src/skills/design-intelligence/data/landing.csv +36 -35
- package/dist/agent-src/skills/design-intelligence/data/stacks/threejs.csv +1 -0
- package/dist/agent-src/skills/design-review/SKILL.md +79 -1
- package/dist/agent-src/skills/design-review/references/verification-automation.md +41 -0
- package/dist/agent-src/skills/design-system-capture/SKILL.md +35 -40
- package/dist/agent-src/skills/design-system-capture/references/import-procedure.md +50 -0
- package/dist/agent-src/skills/design-tokens/SKILL.md +3 -0
- package/dist/agent-src/skills/design-variations/SKILL.md +3 -0
- package/dist/agent-src/skills/developer-like-execution/SKILL.md +3 -0
- package/dist/agent-src/skills/estimate-ticket/SKILL.md +3 -0
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +20 -3
- package/dist/agent-src/skills/fe-design/SKILL.md +74 -41
- package/dist/agent-src/skills/fe-design/evals/triggers.json +65 -53
- package/dist/agent-src/skills/fe-design/references/craft-floor.md +52 -0
- package/dist/agent-src/skills/fe-design/references/source-led-port.md +36 -0
- package/dist/agent-src/skills/file-editor/SKILL.md +5 -0
- package/dist/agent-src/skills/finishing-a-development-branch/SKILL.md +2 -2
- package/dist/agent-src/skills/git-workflow/SKILL.md +3 -0
- package/dist/agent-src/skills/html-deck/SKILL.md +3 -0
- package/dist/agent-src/skills/iconography/SKILL.md +3 -0
- package/dist/agent-src/skills/image-editing/SKILL.md +3 -0
- package/dist/agent-src/skills/image-generation/SKILL.md +3 -0
- package/dist/agent-src/skills/image-provider-routing/SKILL.md +3 -0
- package/dist/agent-src/skills/incident-commander/SKILL.md +10 -0
- package/dist/agent-src/skills/js-library-packaging/SKILL.md +173 -0
- package/dist/agent-src/skills/js-library-packaging/evals/triggers.json +17 -0
- package/dist/agent-src/skills/js-library-packaging/scripts/check_package_surface.ts +270 -0
- package/dist/agent-src/skills/laravel-migration/SKILL.md +3 -0
- package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +3 -0
- package/dist/agent-src/skills/lint-skills/SKILL.md +3 -0
- package/dist/agent-src/skills/llm-provider-knowledge/SKILL.md +3 -0
- package/dist/agent-src/skills/logging-monitoring/SKILL.md +234 -51
- package/dist/agent-src/skills/logo-generation/SKILL.md +3 -0
- package/dist/agent-src/skills/md-language-check/SKILL.md +3 -0
- package/dist/agent-src/skills/monorepo-workspace/SKILL.md +149 -0
- package/dist/agent-src/skills/monorepo-workspace/evals/triggers.json +17 -0
- package/dist/agent-src/skills/motion-choreographer/SKILL.md +6 -0
- package/dist/agent-src/skills/multi-tenancy/SKILL.md +4 -0
- package/dist/agent-src/skills/operational-readiness/SKILL.md +184 -0
- package/dist/agent-src/skills/operational-readiness/evals/triggers.json +17 -0
- package/dist/agent-src/skills/override-management/SKILL.md +3 -0
- package/dist/agent-src/skills/persona-improvement/SKILL.md +3 -0
- package/dist/agent-src/skills/pest-testing/SKILL.md +3 -0
- package/dist/agent-src/skills/playbook-authoring/SKILL.md +162 -0
- package/dist/agent-src/skills/playwright-testing/SKILL.md +3 -0
- package/dist/agent-src/skills/privacy-review/SKILL.md +3 -0
- package/dist/agent-src/skills/prompt-engineering-image/SKILL.md +3 -0
- package/dist/agent-src/skills/quality-tools/SKILL.md +5 -0
- package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +52 -21
- package/dist/agent-src/skills/readme-reviewer/SKILL.md +3 -0
- package/dist/agent-src/skills/readme-writing/SKILL.md +3 -0
- package/dist/agent-src/skills/readme-writing-package/SKILL.md +3 -0
- package/dist/agent-src/skills/receiving-code-review/SKILL.md +2 -2
- package/dist/agent-src/skills/refine-prompt/SKILL.md +3 -0
- package/dist/agent-src/skills/refine-ticket/SKILL.md +3 -0
- package/dist/agent-src/skills/requesting-code-review/SKILL.md +2 -2
- package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +23 -41
- package/dist/agent-src/skills/roadmap-writing/references/follow-up-roadmap-shape.md +47 -0
- package/dist/agent-src/skills/rtk-output-filtering/SKILL.md +22 -6
- package/dist/agent-src/skills/runway-cognition/SKILL.md +3 -0
- package/dist/agent-src/skills/scene-expander/scene-blueprint.schema.yaml +26 -0
- package/dist/agent-src/skills/secrets-management/SKILL.md +4 -0
- package/dist/agent-src/skills/server-hardening/SKILL.md +159 -0
- package/dist/agent-src/skills/server-hardening/evals/triggers.json +17 -0
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +3 -0
- package/dist/agent-src/skills/skill-management/SKILL.md +3 -0
- package/dist/agent-src/skills/skill-reviewer/SKILL.md +3 -0
- package/dist/agent-src/skills/skill-writing/SKILL.md +6 -0
- package/dist/agent-src/skills/spreadsheet-authoring/SKILL.md +3 -0
- package/dist/agent-src/skills/storybook-workshop/SKILL.md +194 -0
- package/dist/agent-src/skills/storybook-workshop/evals/triggers.json +17 -0
- package/dist/agent-src/skills/storybook-workshop/scripts/story_contrast_floor.ts +134 -0
- package/dist/agent-src/skills/subagent-orchestration/SKILL.md +1 -1
- package/dist/agent-src/skills/subagent-orchestration/prompts/README.md +25 -0
- package/dist/agent-src/skills/supply-chain-intake/SKILL.md +12 -0
- package/dist/agent-src/skills/systematic-debugging/SKILL.md +1 -1
- package/dist/agent-src/skills/terraform/SKILL.md +3 -0
- package/dist/agent-src/skills/test-driven-development/SKILL.md +1 -1
- package/dist/agent-src/skills/threat-modeling/SKILL.md +0 -3
- package/dist/agent-src/skills/token-optimizer/SKILL.md +3 -0
- package/dist/agent-src/skills/typography-system/SKILL.md +3 -0
- package/dist/agent-src/skills/ui-component-architect/SKILL.md +9 -1
- package/dist/agent-src/skills/upstream-contribute/SKILL.md +3 -0
- package/dist/agent-src/skills/validate-feature-fit/SKILL.md +3 -0
- package/dist/agent-src/skills/verify-completion-evidence/SKILL.md +2 -2
- package/dist/agent-src/skills/wireframe/SKILL.md +3 -0
- package/dist/agent-src/skills/wireframe/references/story-beat-ledger.schema.json +115 -0
- package/dist/agent-src/skills/workspace-link/SKILL.md +131 -0
- package/dist/agent-src/skills/workspace-link/evals/triggers.json +17 -0
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/playbook.md +75 -0
- package/dist/agent-src/templates/roadmaps.md +37 -0
- package/dist/agent-src/templates/scripts/check_playbook_invokes.ts +231 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +24 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +2 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/review.ts +216 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +159 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +73 -4
- package/dist/agent-src/templates/scripts/work_engine/stack/detect.ts +325 -40
- package/dist/cli/commands/uiAudit.js +221 -0
- package/dist/cli/commands/uiAudit.js.map +1 -0
- package/dist/cli/commands/uiRender.js +206 -0
- package/dist/cli/commands/uiRender.js.map +1 -0
- package/dist/cli/main.js +22 -1
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/mcp/content.js +64 -1
- package/dist/cli/mcp/content.js.map +1 -1
- package/dist/cli/mcp/dispatch.js +175 -10
- package/dist/cli/mcp/dispatch.js.map +1 -1
- package/dist/cli/registry.js +3 -0
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli-delegate/{chunk-H4VIVD4C.js → chunk-236PNQZK.js} +413 -391
- package/dist/cli-delegate/{chunk-G23AT6GD.js → chunk-DMSZHXZS.js} +57 -1
- package/dist/cli-delegate/{chunk-77GR3VD4.js → chunk-FF7WAFMR.js} +58 -3
- package/dist/cli-delegate/{chunk-PLSG6UL5.js → chunk-K4FFODTS.js} +341 -204
- package/dist/cli-delegate/{chunk-YM4GZDJG.js → chunk-L43NCYPB.js} +5 -0
- package/dist/cli-delegate/{chunk-B2ERU2VA.js → chunk-WOKWX5PL.js} +1 -1
- package/dist/cli-delegate/cmd_brand_status.js +8 -6
- package/dist/cli-delegate/cmd_conformance.js +3 -3
- package/dist/cli-delegate/cmd_doctor.js +3 -3
- package/dist/cli-delegate/cmd_export.js +4 -4
- package/dist/cli-delegate/cmd_handoff.js +1 -1
- package/dist/cli-delegate/cmd_preflight.js +2 -2
- package/dist/cli-delegate/cmd_prune.js +4 -4
- package/dist/cli-delegate/cmd_session_recycle.js +70 -9
- package/dist/cli-delegate/cmd_settings_migrate.js +4 -4
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +4 -4
- package/dist/cli-delegate/cmd_uninstall.js +4 -4
- package/dist/cli-delegate/cmd_validate.js +4 -4
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +359 -124
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +4 -4
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +18 -8
- package/dist/discovery/trust-report.md +3 -3
- package/dist/discovery/workspaces.json +16 -6
- package/dist/hooks/dispatch.js +2337 -1436
- package/dist/install/install.mjs +795 -708
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +1685 -1250
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/lean_projection_mode.js +40 -0
- package/dist/scripts/_lib/lean_projection_mode.js.map +1 -0
- package/dist/scripts/_lib/scoped_projection.js +84 -0
- package/dist/scripts/_lib/scoped_projection.js.map +1 -1
- package/dist/scripts/_lib/ui_surface.js +89 -0
- package/dist/scripts/_lib/ui_surface.js.map +1 -0
- package/dist/scripts/condense.js +6 -10
- package/dist/scripts/condense.js.map +1 -1
- package/dist/scripts/project_thin_rules.js +40 -2
- package/dist/scripts/project_thin_rules.js.map +1 -1
- package/dist/server/schemas/settings.js +3 -0
- package/dist/server/schemas/settings.js.map +1 -1
- package/dist/shared/skillRanking.js +159 -0
- package/dist/shared/skillRanking.js.map +1 -0
- package/docs/contracts/provider-lifecycle.md +47 -18
- package/docs/contracts/settings-classes.md +14 -4
- package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +49 -0
- package/docs/guidelines/agent-infra/evaluator-independence-mechanics.md +92 -0
- package/docs/guidelines/agent-infra/minimal-safe-diff-mechanics.md +45 -1
- package/docs/guidelines/agent-infra/roadmap-deferred-resolution-provenance.md +54 -0
- package/docs/guidelines/design-antipatterns.md +4 -2
- package/docs/guidelines/design-asset-discipline.md +38 -0
- package/docs/guidelines/design-fidelity-mechanics.md +45 -29
- package/docs/guidelines/design-handover-extraction.md +35 -5
- package/docs/guidelines/design-modes.md +41 -1
- package/docs/guidelines/monorepo-antipatterns.md +141 -0
- package/llms.txt +50 -39
- package/package.json +1 -1
- package/src/agent-src/templates/scripts/check_playbook_invokes.ts +231 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +24 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +2 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/review.ts +216 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +159 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +73 -4
- package/src/agent-src/templates/scripts/work_engine/stack/detect.ts +325 -40
- package/src/config/agent-settings.template.yml +28 -0
- package/src/config/assurance-capability-registry.json +223 -0
- package/src/config/assurance-threshold-budget.json +65 -0
- package/src/config/ci-local-parity.yml +14 -0
- package/src/config/discovery/unassigned-artefacts.yml +2 -0
- package/src/config/dispatch-economy-metrics.json +4 -2
- package/src/config/evaluator-budgets.json +14 -14
- package/src/config/gate-coverage.yml +207 -8
- package/src/config/gate-violation-baselines.json +76 -72
- package/src/config/hook-latency-budget.json +1 -0
- package/src/config/hook-token-budget.json +137 -125
- package/src/config/pack-size-budget.json +4 -2
- package/src/config/quorum-attendance-budget.json +12 -4
- package/src/config/rule-activation-census.json +7 -3
- package/src/config/rule-enforcement-baseline.json +0 -1
- package/src/config/rule-stub-ceilings.json +112 -91
- package/src/scripts/_cli/cmd_doctor.ts +15 -16
- package/src/scripts/_cli/doctor_install_mode.ts +49 -0
- package/src/scripts/_cli/doctor_overrides.ts +154 -0
- package/src/scripts/_dispatch.bash +17 -0
- package/src/scripts/_lib/as_of.ts +412 -0
- package/src/scripts/_lib/exec_evidence.ts +7 -0
- package/src/scripts/_lib/hook_settings.ts +33 -0
- package/src/scripts/_lib/host_listing_model.ts +192 -0
- package/src/scripts/_lib/lean_projection_mode.ts +44 -0
- package/src/scripts/_lib/mcp_bridge.ts +199 -0
- package/src/scripts/_lib/review_independence.ts +62 -10
- package/src/scripts/_lib/rule_injection.ts +239 -0
- package/src/scripts/_lib/run_checkpoint.ts +54 -1
- package/src/scripts/_lib/scoped_projection.ts +96 -0
- package/src/scripts/_lib/session_register.ts +44 -2
- package/src/scripts/_lib/skill_catalogue.ts +38 -2
- package/src/scripts/_lib/transcript_reads.ts +207 -0
- package/src/scripts/_lib/ui_authority.test.ts +251 -0
- package/src/scripts/_lib/ui_authority.ts +343 -0
- package/src/scripts/ai-video/adapters/fal.sh +8 -3
- package/src/scripts/ai-video/adapters/gemini-veo.sh +10 -0
- package/src/scripts/ai-video/adapters/higgsfield.sh +10 -2
- package/src/scripts/ai-video/adapters/kling.sh +10 -0
- package/src/scripts/ai-video/adapters/sora.sh +10 -0
- package/src/scripts/ai-video/lib/calibrate-cost.sh +145 -0
- package/src/scripts/ai-video/lib/model-capabilities/README.md +53 -7
- package/src/scripts/ai-video/lib/model-capabilities/comfyui.json +15 -3
- package/src/scripts/ai-video/lib/model-capabilities/fal.json +36 -6
- package/src/scripts/ai-video/lib/model-capabilities/gemini-veo.json +23 -0
- package/src/scripts/ai-video/lib/model-capabilities/higgsfield.json +23 -0
- package/src/scripts/ai-video/lib/model-capabilities/kling.json +23 -0
- package/src/scripts/ai-video/lib/model-capabilities/musetalk.json +8 -2
- package/src/scripts/ai-video/lib/model-capabilities/replicate.json +36 -6
- package/src/scripts/ai-video/lib/model-capabilities/sora.json +45 -0
- package/src/scripts/ai-video/lib/model-capabilities/syncso.json +8 -2
- package/src/scripts/ai-video/lib/parse-blueprint.sh +52 -5
- package/src/scripts/ai-video/lib/resume-scan.sh +92 -3
- package/src/scripts/ai-video/lib/seam-plan.sh +212 -0
- package/src/scripts/ai-video/smoke-trace.sh +450 -2
- package/src/scripts/ai-video/stitch.sh +191 -10
- package/src/scripts/ai-video/test-pipeline.sh +84 -6
- package/src/scripts/ai_council/cli_agency_bounds.ts +139 -0
- package/src/scripts/ai_council/cli_least_agency_canary.ts +347 -0
- package/src/scripts/ai_council/clients.ts +3 -2
- package/src/scripts/ai_council/consensus.ts +63 -6
- package/src/scripts/ai_council/events_log.ts +46 -1
- package/src/scripts/ai_council/orchestrator.ts +103 -108
- package/src/scripts/ai_council/orchestrator_results.ts +166 -0
- package/src/scripts/ai_council/prompts.ts +12 -5
- package/src/scripts/ai_council/quorum.ts +82 -1
- package/src/scripts/ai_council/quorum_wiring.ts +82 -5
- package/src/scripts/ai_council/stance_tally.ts +22 -0
- package/src/scripts/bench_hook_latency.ts +62 -0
- package/src/scripts/build_proof.ts +12 -1
- package/src/scripts/capture_skill_catalogue.ts +21 -0
- package/src/scripts/check_always_budget.ts +2 -1
- package/src/scripts/check_augmentignore.ts +2 -1
- package/src/scripts/check_beta_review_markers.ts +2 -1
- package/src/scripts/check_composite_arming.ts +364 -0
- package/src/scripts/check_corpus_staleness.ts +2 -1
- package/src/scripts/check_council_pin_staleness.ts +3 -1
- package/src/scripts/check_enforcement_coverage.ts +116 -3
- package/src/scripts/check_enforcement_denominator.ts +365 -0
- package/src/scripts/check_gate_coverage.ts +2 -1
- package/src/scripts/check_hook_bundle_freshness.ts +13 -1
- package/src/scripts/check_knowledge_cards.ts +2 -1
- package/src/scripts/check_knowledge_pages.ts +3 -2
- package/src/scripts/check_memory.ts +2 -1
- package/src/scripts/check_no_automerge_key.ts +287 -0
- package/src/scripts/check_pack_conformance_fixture.ts +565 -0
- package/src/scripts/check_proposal.ts +2 -1
- package/src/scripts/check_reach_staleness.ts +2 -1
- package/src/scripts/check_release_adjacent_health.ts +2 -1
- package/src/scripts/check_release_pr_shape.ts +5 -0
- package/src/scripts/check_review_schema.ts +34 -1
- package/src/scripts/check_roadmap_trackable.ts +48 -3
- package/src/scripts/check_source_size_budget.ts +2 -1
- package/src/scripts/check_standing_payload_delta.ts +505 -0
- package/src/scripts/check_trigger_evals.ts +2 -1
- package/src/scripts/classify_change_risk.ts +281 -0
- package/src/scripts/compute_skill_tiers.ts +186 -0
- package/src/scripts/condense.ts +8 -13
- package/src/scripts/council_attendance_metrics.ts +183 -0
- package/src/scripts/council_cli.ts +10 -8
- package/src/scripts/council_parse_rate.ts +116 -0
- package/src/scripts/derive_playbooks.ts +406 -0
- package/src/scripts/design_slop_rules.test.ts +7 -0
- package/src/scripts/design_slop_rules.ts +56 -2
- package/src/scripts/dispatch_r2_reviewer.ts +16 -0
- package/src/scripts/frontend_corpus_hash.ts +116 -0
- package/src/scripts/grade_target_readiness.ts +478 -0
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +97 -16
- package/src/scripts/hooks/concern_registry.ts +4 -0
- package/src/scripts/hooks/design_pass_hook.ts +356 -0
- package/src/scripts/hooks/rtk_wrap_hook.ts +30 -7
- package/src/scripts/hooks/rule_inject_hook.ts +318 -0
- package/src/scripts/hot_context_hook.ts +74 -7
- package/src/scripts/install.ts +40 -89
- package/src/scripts/lint_adapter_tier.ts +663 -0
- package/src/scripts/lint_archived_skills.ts +93 -0
- package/src/scripts/lint_budget_ownership.ts +2 -1
- package/src/scripts/lint_deterministic_time.ts +470 -0
- package/src/scripts/lint_framework_leakage.ts +5 -0
- package/src/scripts/lint_handoffs.ts +525 -1
- package/src/scripts/lint_judge_prompt_expectation.ts +155 -0
- package/src/scripts/lint_marketplace.ts +88 -0
- package/src/scripts/lint_media_policy_linkage.ts +140 -1
- package/src/scripts/lint_one_off_age.ts +6 -1
- package/src/scripts/lint_override_kernel_guard.ts +87 -5
- package/src/scripts/lint_roadmap_complexity.ts +56 -0
- package/src/scripts/lint_rule_enforcement_declaration.ts +24 -7
- package/src/scripts/lint_rule_norm_pin.ts +321 -0
- package/src/scripts/lint_spawn_payload.ts +42 -5
- package/src/scripts/lint_symptom_intake.ts +2 -1
- package/src/scripts/mcp_parity_smoke.ts +30 -4
- package/src/scripts/mcp_render.ts +66 -1
- package/src/scripts/mcp_tool_fingerprint.ts +241 -0
- package/src/scripts/measure_risk_class_drift.ts +140 -0
- package/src/scripts/measure_skill_ranker_baseline.ts +212 -0
- package/src/scripts/media/lib/adapter-common.sh +211 -1
- package/src/scripts/media/lib/adapter-contract.md +74 -6
- package/src/scripts/model_rule_injection.ts +907 -0
- package/src/scripts/project_thin_rules.ts +45 -2
- package/src/scripts/release.ts +66 -860
- package/src/scripts/release_drill.ts +59 -3
- package/src/scripts/release_env.ts +298 -0
- package/src/scripts/release_publication.ts +720 -0
- package/src/scripts/roadmap_context.ts +778 -0
- package/src/scripts/schemas/fidelity-measurement-sheet.schema.json +169 -0
- package/src/scripts/schemas/rule.schema.json +24 -2
- package/src/scripts/schemas/skill.schema.json +39 -0
- package/src/scripts/schemas/ui-authority.schema.json +114 -0
- package/src/scripts/session_register_hook.ts +29 -3
- package/src/scripts/sessions_cli.ts +67 -3
- package/src/scripts/skill_tools/score_skill_relevance.ts +36 -53
- package/src/scripts/token_sink_report.ts +239 -0
- package/src/scripts/trigger_coverage.ts +122 -3
- package/src/scripts/update_counts.ts +7 -3
- package/src/scripts/validate_frontmatter.ts +66 -0
- package/src/server/schemas/settings.ts +5 -0
- package/src/shared/skillRanking.ts +183 -0
|
@@ -40,15 +40,52 @@
|
|
|
40
40
|
# visible, or it repeats the sin it exists to catch.
|
|
41
41
|
# canary optional mutation recipe (Phase 7) — see CANARY below
|
|
42
42
|
#
|
|
43
|
-
# COVERAGE — THE HONEST DENOMINATOR (re-measured 2026-08-
|
|
43
|
+
# COVERAGE — THE HONEST DENOMINATOR (re-measured 2026-08-23)
|
|
44
44
|
# ----------------------------------------------------------
|
|
45
|
-
#
|
|
45
|
+
# 283 `lint_*` / `check_*` / `audit_*` scripts live under `src/scripts/`
|
|
46
46
|
# (the count is computed, not asserted — `check_gate_coverage.count_gate_scripts`,
|
|
47
|
-
# re-run 2026-08-
|
|
48
|
-
# **
|
|
49
|
-
# CI-identical argv, and
|
|
47
|
+
# re-run 2026-08-23 and it returns 283).
|
|
48
|
+
# **58 of them emit the machine-readable `scanned: <N>` line under their
|
|
49
|
+
# CI-identical argv, and 55 of those 58 are listed below.** The manifest is
|
|
50
50
|
# therefore complete with respect to its own contract for every gate that can
|
|
51
|
-
# carry a floor, and covers ~
|
|
51
|
+
# carry a floor, and covers ~19 % of the population.
|
|
52
|
+
#
|
|
53
|
+
# RECOUNTED on 2026-08-23 while adding `lint_deterministic_time` and
|
|
54
|
+
# `check_enforcement_denominator` (two rows, and the figures above are the
|
|
55
|
+
# function's answer AFTER both — not the previous reading plus two), and — the sixth
|
|
56
|
+
# time in a row, which is the whole point of this section — the prose was already
|
|
57
|
+
# stale before the row landed. It said 279 / 56 / 53 while `count_gate_scripts()`
|
|
58
|
+
# already returned **281**, so two scripts had arrived since the previous
|
|
59
|
+
# recount without touching this text. Incrementing 279 by one would have written
|
|
60
|
+
# 280 and been wrong by two; the figures above are the function's answer and a
|
|
61
|
+
# fresh `grep`, not arithmetic on the previous sentence. Derivation, so the next
|
|
62
|
+
# reader checks rather than trusts: `grep -c '^ - id:' src/config/gate-coverage.yml`
|
|
63
|
+
# returns 55; every listed row is an emitter, because a row that did not emit
|
|
64
|
+
# could carry no floor; the same THREE emitters remain deliberately unlisted
|
|
65
|
+
# (`lint_evidence_artifacts`, `adr_cite_check`, `check_new_adr_evidence`, each
|
|
66
|
+
# with its reason at the place its row would have sat); 55 + 3 = 58.
|
|
67
|
+
#
|
|
68
|
+
# RECOUNTED on 2026-08-23 while adding `check_no_automerge_key`, and BOTH numbers
|
|
69
|
+
# were stale before the recount by more than the one row this change adds — which
|
|
70
|
+
# is the fifth time, and the reason this paragraph keeps asking to be computed
|
|
71
|
+
# rather than adjusted. The previous prose said 272 / 47 / 44 while the file
|
|
72
|
+
# already carried 51 rows and the population function already returned 277: six
|
|
73
|
+
# scripts and seven rows had landed since 2026-08-22 without touching this text.
|
|
74
|
+
# Derivation, so the next reader checks rather than trusts:
|
|
75
|
+
# `grep -c '^ - id:' src/config/gate-coverage.yml` returns 53; every listed row
|
|
76
|
+
# is an emitter, because a row that did not emit could carry no floor; the same
|
|
77
|
+
# THREE emitters remain deliberately unlisted (`lint_evidence_artifacts`,
|
|
78
|
+
# `adr_cite_check`, `check_new_adr_evidence`, each with its reason at the place
|
|
79
|
+
# its row would have sat); 53 + 3 = 56. The population comes from the function.
|
|
80
|
+
#
|
|
81
|
+
# RE-RECOUNTED on the same day, after a rebase, and the re-count is the point:
|
|
82
|
+
# `check_no_automerge_key` and `check_pack_conformance_fixture` landed in two
|
|
83
|
+
# separate changes hours apart, and the first change's prose (52 / 55 / 278) was
|
|
84
|
+
# CORRECT when written and stale by one on each axis the moment the second
|
|
85
|
+
# rebased onto it. Adding one to each figure would have been right here by
|
|
86
|
+
# accident; it was recomputed anyway, because "right by accident" is
|
|
87
|
+
# indistinguishable in a diff from the arithmetic-on-prose this paragraph
|
|
88
|
+
# forbids.
|
|
52
89
|
#
|
|
53
90
|
# RECOUNTED on 2026-08-22, and it was wrong on every figure before the recount —
|
|
54
91
|
# which is the fourth time, and the reason this paragraph keeps asking to be
|
|
@@ -491,8 +528,8 @@ gates:
|
|
|
491
528
|
|
|
492
529
|
- id: check_requirements_trace
|
|
493
530
|
argv: []
|
|
494
|
-
min_scanned:
|
|
495
|
-
corpus: "roadmap files at the top level of agents/roadmaps/ (25 at registration, 2026-08-22)"
|
|
531
|
+
min_scanned: 2
|
|
532
|
+
corpus: "roadmap files at the top level of agents/roadmaps/ (25 at registration, 2026-08-22; 9 live on 2026-08-23, mid-drain). The floor tracks a corpus that shrinks by design, so completing and archiving a roadmap lowers it — it is never satisfied by un-archiving finished work. LOWERED 10 -> 2 on 2026-08-23. The 15 -> 10 move earlier the same day already recorded this shape and under-shot it: eight further PRs were open at that moment, each one titled `roadmap: complete <slug>` and each archiving exactly one top-level file, so the estate this floor tracks was already committed to landing at one or two. A floor of 10 against a corpus heading for 2 does not detect anything — it reds on every remaining merge in the drain, which is the gate firing on the drain WORKING, and the note directly above says so in its own words. 2 is chosen as one above the only reading this floor exists to catch: a scan whose root moved reports 0, never 2, so the collapse signal survives the move intact. What is given up is the middle band, and it was never load-bearing here — this gate is a LISTING (see no_canary_reason: `main()` returns 0 on every path), so the floor is its only failure mode and a partial-corpus read is not something it could act on anyway. Revisit-if: the drain ends and the estate stabilises above 2 — re-derive the floor from what the estate is then expected to hold, and never from the live count, which reds on the next archive by construction."
|
|
496
533
|
status: enforced
|
|
497
534
|
no_canary_reason: >-
|
|
498
535
|
this gate is a LISTING, not an enforcement: `main()` returns 0 on every
|
|
@@ -511,6 +548,30 @@ gates:
|
|
|
511
548
|
registration: the active estate is being drained deliberately and is
|
|
512
549
|
expected to shrink, so a tight floor would red on the drain working.
|
|
513
550
|
|
|
551
|
+
LOWERED 15 -> 10 on 2026-08-23, and the reason is the sentence directly
|
|
552
|
+
above coming true. Archiving `road-to-role-scoped-spawn-profiles` took the
|
|
553
|
+
live top-level count from 15 to 14, so the floor red on the drain working
|
|
554
|
+
— exactly the failure mode the registration note predicted, one drain
|
|
555
|
+
after it was written. Measured at this commit: `find agents/roadmaps
|
|
556
|
+
-maxdepth 1 -name '*.md' -type f | wc -l` = 14, and the gate's own
|
|
557
|
+
`scanned:` line agrees at 14.
|
|
558
|
+
|
|
559
|
+
Why 10 and not 14. A floor set at the live count reds again on the very
|
|
560
|
+
next archive, which turns a collapse detector into per-drain friction with
|
|
561
|
+
no safety gain. The floor's only job is stated in its own note above: catch
|
|
562
|
+
a scan that stopped seeing `agents/roadmaps/` at all, and such a scan
|
|
563
|
+
reports **0**. 10 leaves four further drains of headroom while still
|
|
564
|
+
sitting an order of magnitude above the collapse signal it exists to
|
|
565
|
+
distinguish.
|
|
566
|
+
|
|
567
|
+
What did NOT move, checked rather than assumed: all four
|
|
568
|
+
`requirements-trace-budget.json` counters (`unlinked`, `unresolved`,
|
|
569
|
+
`dangling_ac`, `malformed`) remain at their registered baseline of 0. The
|
|
570
|
+
`0 declaring` reading is likewise NOT from this change — no top-level
|
|
571
|
+
roadmap at `origin/main` (2a7a8e221) declares `requirement_id` either, and
|
|
572
|
+
the archived roadmap never carried the trace fields. Only the scan count
|
|
573
|
+
moved.
|
|
574
|
+
|
|
514
575
|
- id: check_council_pin_staleness
|
|
515
576
|
argv: []
|
|
516
577
|
min_scanned: 3
|
|
@@ -1421,3 +1482,141 @@ gates:
|
|
|
1421
1482
|
# so a future change that silently narrowed its corpus to zero would pass. The
|
|
1422
1483
|
# honest close is the rename, in its own change, where 26 files of churn are
|
|
1423
1484
|
# the subject rather than a side effect.
|
|
1485
|
+
|
|
1486
|
+
- id: check_no_automerge_key
|
|
1487
|
+
argv: ["--quiet"]
|
|
1488
|
+
min_scanned: 200
|
|
1489
|
+
corpus: "every declared key in the two settings files — `src/config/agent-settings.template.yml` plus `src/scripts/schemas/agent-settings.schema.json` (304 on 2026-08-23, so the floor sits well below the live count and far above a collapse)"
|
|
1490
|
+
status: enforced
|
|
1491
|
+
no_canary_reason: >-
|
|
1492
|
+
Create-only canary cannot reach this corpus: both settings files are
|
|
1493
|
+
tracked and always exist, so a planted file lands outside the corpus and
|
|
1494
|
+
the gate correctly stays green. Measured on a previous attempt, where the
|
|
1495
|
+
gate was then mis-reported as dead. Same class as `check_condensation` and
|
|
1496
|
+
`check_ci_local_parity` — the only possible violation is a modification of
|
|
1497
|
+
an existing tracked artefact. The red is proven instead by the committed
|
|
1498
|
+
violating fixture `tests/fixtures/automerge-key/` plus two recorded
|
|
1499
|
+
sabotage probes in `tests/scripts/check_no_automerge_key.test.ts`.
|
|
1500
|
+
note: >
|
|
1501
|
+
The no-canary reason above is the create-only contract rather than an
|
|
1502
|
+
omission. Both corpus files are tracked and always exist, so a planted file
|
|
1503
|
+
lands OUTSIDE the corpus and the gate correctly stays green — measured on a
|
|
1504
|
+
previous attempt at this gate, where it was then mis-reported as dead. The
|
|
1505
|
+
only violation this gate can have is a modification of an existing tracked
|
|
1506
|
+
artefact, which is the same class as `check_condensation` and
|
|
1507
|
+
`check_ci_local_parity`, and the CANARY section above already states that
|
|
1508
|
+
such a gate carries no recipe and is reported UNPROVEN rather than green.
|
|
1509
|
+
|
|
1510
|
+
The red is proven elsewhere instead, deliberately and committed:
|
|
1511
|
+
`tests/fixtures/automerge-key/` is a violating settings pair the gate must
|
|
1512
|
+
refuse, and `tests/scripts/check_no_automerge_key.test.ts` asserts exit 1
|
|
1513
|
+
against it, exit 2 on a missing corpus, and records the two sabotage probes
|
|
1514
|
+
(emptying the forbidden set → 4 of 9 red; widening the matcher from a key
|
|
1515
|
+
to a bare word → 6 of 9 red).
|
|
1516
|
+
|
|
1517
|
+
The floor is a KEY count, not a file count. Two files is a constant, and a
|
|
1518
|
+
floor under a constant can never trip — the false-count shape this manifest
|
|
1519
|
+
rejects. 304 keys collapses to 0 if either root moves, which is what the
|
|
1520
|
+
floor is for.
|
|
1521
|
+
- id: check_pack_conformance_fixture
|
|
1522
|
+
argv: ["--quiet"]
|
|
1523
|
+
min_scanned: 12
|
|
1524
|
+
corpus: "(fixture, gate) assertions over `tests/fixtures/pack-conformance/` — 3 fixture-provable gates × (1 conformant fixture + 3 seeded twins) = 12 on 2026-08-23"
|
|
1525
|
+
status: enforced
|
|
1526
|
+
no_canary_reason: >-
|
|
1527
|
+
The corpus is a committed fixture and every violation this gate can have IS
|
|
1528
|
+
a seeded violation — the three twins under
|
|
1529
|
+
`tests/fixtures/pack-conformance/twins/` are the negative control, already
|
|
1530
|
+
committed and already asserted. A create-only plant would have to add a
|
|
1531
|
+
FOURTH twin, which the harness would not know about and would therefore
|
|
1532
|
+
ignore. Discrimination is proven instead by the gate's own `--self-test`
|
|
1533
|
+
(5 cases, 2 rejecting, including a missing-fixture probe that must exit 2)
|
|
1534
|
+
and by three recorded sabotage probes in
|
|
1535
|
+
`tests/scripts/check_pack_conformance_fixture.test.ts` — a conformant-fixture
|
|
1536
|
+
break, an orthogonality break (a twin reddening two gates), and a neutered
|
|
1537
|
+
twin that reds none. Real exit codes captured directly, never through a
|
|
1538
|
+
pipe.
|
|
1539
|
+
note: >
|
|
1540
|
+
The floor is an ASSERTION count, not a file count. It is exactly
|
|
1541
|
+
`provable_gates × (1 + twins)`, so adding a twin without wiring it — or
|
|
1542
|
+
losing one of the three injection seams — moves the number and the floor
|
|
1543
|
+
catches it. A file count would not: the fixture directory can grow while
|
|
1544
|
+
the harness quietly stops driving a gate.
|
|
1545
|
+
|
|
1546
|
+
This gate is deliberately PARTIAL and says so in its own success line
|
|
1547
|
+
("PARTIAL as designed: 3 of 6"). Three of the six pack-fitness gates cannot
|
|
1548
|
+
be driven from a fixture — `lint_pack_first_win` pins argv-ignoring as an
|
|
1549
|
+
ADR-200 port-fidelity guarantee, `lint_pack_dependencies` derives its pack
|
|
1550
|
+
home from `import.meta.url`, and `prove_pack_extractable` resolves a pack
|
|
1551
|
+
by name under the real `src/packs/`. Raising this gate's coverage by
|
|
1552
|
+
pretending otherwise is the manufactured green this file exists to prevent.
|
|
1553
|
+
|
|
1554
|
+
- id: lint_deterministic_time
|
|
1555
|
+
argv: ["--quiet"]
|
|
1556
|
+
min_scanned: 200
|
|
1557
|
+
corpus: "gate scripts under `src/scripts/` carrying a `check_` or `lint_` prefix, excluding `*.test.ts` (261 at baseline)"
|
|
1558
|
+
status: enforced
|
|
1559
|
+
canary:
|
|
1560
|
+
class: contract-violation
|
|
1561
|
+
path: src/scripts/check_zz_canary_wall_clock.ts
|
|
1562
|
+
content: |
|
|
1563
|
+
// zz canary probe: a gate script reading the wall clock inline, which is
|
|
1564
|
+
// exactly the construct `lint_deterministic_time` refuses. The plant is
|
|
1565
|
+
// create-only and therefore expressible as a canary, unlike the
|
|
1566
|
+
// MODIFICATION shape most ratchets in this file detect.
|
|
1567
|
+
const planted = Date.now();
|
|
1568
|
+
export { planted };
|
|
1569
|
+
note: >
|
|
1570
|
+
The floor is 200 against a live corpus of 261, which is the usual
|
|
1571
|
+
"comfortably below, far above a collapse" shape — a prefix regex that
|
|
1572
|
+
stopped matching, or the flat-`src/` scan root moving again, collapses this
|
|
1573
|
+
to single digits long before it reaches 200.
|
|
1574
|
+
|
|
1575
|
+
`argv` carries `--quiet` because that is what the preflight task and the
|
|
1576
|
+
workflow step both pass. `reportScanned` is not quiet-gated, so the count
|
|
1577
|
+
is published either way; the flag is registered anyway because rule 2 of
|
|
1578
|
+
this manifest is argv PARITY, not "an argv that happens to work".
|
|
1579
|
+
|
|
1580
|
+
The canary is a genuine create-only plant rather than a
|
|
1581
|
+
`no_canary_reason`, and that is unusual enough here to be worth stating:
|
|
1582
|
+
this gate's violation shape is a NEW file carrying the construct, so a
|
|
1583
|
+
single planted script expresses it completely. Discrimination is
|
|
1584
|
+
additionally proven by the gate's own `--self-test` (7 cases, 4 rejecting)
|
|
1585
|
+
— including the two cases the canary cannot express: a mention inside a
|
|
1586
|
+
comment or a string literal that must NOT be a finding (the gate's own
|
|
1587
|
+
docstring names the construct it bans, so a raw-text matcher would refuse
|
|
1588
|
+
itself), and a dead scan root that must exit 2 rather than green.
|
|
1589
|
+
|
|
1590
|
+
- id: check_enforcement_denominator
|
|
1591
|
+
argv: ["--quiet"]
|
|
1592
|
+
min_scanned: 350
|
|
1593
|
+
corpus: "published markdown under `docs/` plus `README.md`, excluding `docs/decisions/` and `docs/archive/` (464 at baseline)"
|
|
1594
|
+
status: enforced
|
|
1595
|
+
canary:
|
|
1596
|
+
class: contract-violation
|
|
1597
|
+
path: docs/zz-canary-enforcement-count.md
|
|
1598
|
+
content: |
|
|
1599
|
+
# ZZ canary probe
|
|
1600
|
+
|
|
1601
|
+
15 of 120 governed rules carry a backstop that fails a CI build.
|
|
1602
|
+
|
|
1603
|
+
A hand-written enforcement denominator in a published doc, which is the
|
|
1604
|
+
sixth-number defect this gate exists to prevent. Create-only, so it is
|
|
1605
|
+
expressible as a canary.
|
|
1606
|
+
note: >
|
|
1607
|
+
The floor is 350 against a live corpus of 464. The collapse case is real
|
|
1608
|
+
rather than theoretical here: `docs/` was flattened once already
|
|
1609
|
+
(ADR-051), and a walk rooted at a moved directory reads zero files and
|
|
1610
|
+
prints "no published doc restates it" — a green over nothing.
|
|
1611
|
+
|
|
1612
|
+
The gate deliberately does NOT compare values against the resolver. A
|
|
1613
|
+
hand-written figure that happens to be right today is precisely how the
|
|
1614
|
+
plurality returned each of the previous times, so the finding is the
|
|
1615
|
+
restatement, not the disagreement. That is why the canary body carries a
|
|
1616
|
+
CORRECT figure: a value-comparing gate would pass this plant.
|
|
1617
|
+
|
|
1618
|
+
Discrimination is additionally proven by the gate's own `--self-test`
|
|
1619
|
+
(9 cases, 5 rejecting) — including the three cases the canary cannot
|
|
1620
|
+
express: the generated projection which must stay green, a `docs/decisions/`
|
|
1621
|
+
ADR whose dated record must not be rewritten, and a bare rule count with no
|
|
1622
|
+
enforcement sense ("2 rules" in a concepts page) which must not be a finding.
|
|
@@ -1,76 +1,80 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
},
|
|
9
|
-
"check_depth_budget": {
|
|
10
|
-
"count": 4,
|
|
11
|
-
"landed": "2026-08-06",
|
|
12
|
-
"note": "Four depth files exceed the 16,000-char per-file ceiling: rule-body-migration-inventory.md (23,782), design-antipatterns.md (20,707), roadmap-process-loop.md (20,360), orchestration-telemetry.md (16,155). Recorded rather than fixed because splitting four large reference documents is unrelated to the change that introduced the ceiling, and a gate that lands as four instant blockers is the shape this repository has already recorded as a failure. Shrink-only from here: a FIFTH over-ceiling file reds. roadmap-process-loop.md is the file that motivated the gate \u2014 it states 'Size budget: <= 4,000 chars' in its own header and is 5x over it, which is what a declared budget with nothing measuring it decays into. The ceiling is a GROWTH RATCHET, not a measured quality threshold: the 7,308-trajectory study behind the 3,500-token skill ceiling (ADR-217) was taken on procedural always-co-loaded skills, and this layer is declarative and loaded one or two files at a time. Replace the number when someone measures comprehension on THIS layer."
|
|
13
|
-
},
|
|
14
|
-
"check_gate_completeness": {
|
|
15
|
-
"count": 215,
|
|
16
|
-
"landed": "2026-08-17",
|
|
17
|
-
"note": "Ledger adoption ratchet. Gates registered under the CI task roots that carry neither per-target completeness accounting (`_lib/gate_ledger.ts`) nor a `// ledger-exempt:` marker. This is deliberately NOT a sweep: road-to-skill-ecosystem-gate-integrity Phase 1 adopts exactly three gates (lint_framework_leakage, check_references, lint_roadmap_complexity) plus the checker itself to prove the interface, and the remainder migrates as gates are touched. Shrink-only from here \u2014 the number may not grow, so a NEW gate must adopt or exempt. Lowered 216 -> 215 on 2026-08-17 by discharging the obligation three NEW arrivals had incurred, which is the standing rule being enforced rather than a drain: the registered population grew 244 -> 258 and three of the fourteen arrivals adopted nothing \u2014 `build_archive_index`, `check_gate_coverage`, `check_pr_ci_current`. The reading was 218 against this baseline of 216, and the missing arithmetic is that one PRE-existing gate (`lint_rule_skill_pack_reach`) had adopted in the meantime: 216 + 3 - 1 = 218. All three adopted a real ledger. `check_pr_ci_current` first took a reasoned exemption claiming no target population; the completion review refuted it from the file itself \u2014 the check rows ARE a population, and rows whose `state` is not a string were being dropped before any verdict ran, so a dropped row could be the failing one. The exemption was withdrawn and the ledger adopted, counting kept rows as read, dropped rows as skips, and rows a pre-row verdict never reached as out of scope. The denominator in this note was 14 stale (it said 244) and is now expressed without one, because a count pinned to a population that grows weekly rots faster than the count itself. Note what this lowering does NOT buy: headroom is zero either way, so the next un-adopted arrival reds this gate immediately \u2014 which is the intended behaviour and the reason the number is not padded. The refreshed `landed` is load-bearing rather than bookkeeping: `checkRatchet` returns `improved` BEFORE it evaluates staleness, so an entry left at 216 while the tree measures 215 would never expire at any age (pinned by tests/lib/gate_baseline.test.ts, which asserts `improved` at landed + STALE_AFTER_DAYS + 400 days) \u2014 the greenest available state and the worst, since it switches off the anti-fossilization clause exactly when someone has done real work.",
|
|
18
|
-
"falsifier": "./scripts-run src/scripts/check_gate_completeness"
|
|
19
|
-
},
|
|
20
|
-
"check_no_new_legacy_path:hardcoded-scan-roots": {
|
|
21
|
-
"count": 47,
|
|
22
|
-
"landed": "2026-08-13",
|
|
23
|
-
"note": "Lines under src/scripts/**/*.{ts,mts,mjs} that pass the retired `.agent-src.uncondensed` directory into `path.join(...)` \u2014 a filesystem path CONSTRUCTED against the tree ADR-051 abandoned, which is the exact shape of all 14 dead gates. Deliberately narrow so the number is signal, not noise: 236 raw mentions under src/scripts \u2192 147 string-literal lines \u2192 67 path-constructing lines when the pass was written, after exempting src/scripts/_lib/agent_src.ts (the shared resolver, whose job IS owning the constant \u2014 gates that route through it survived the move). Detectors holding the literal as data to match, strip, or print are not counted, and no prose, docs, tests or fixtures are read: that full-tree shape was measured at 44 files / 213 hits and rejected as the wrong lint (see the note in check_no_new_legacy_path.ts::find_offenders). Recorded at 58 rather than 67 because Phase 1's scan-root repairs were landing on this branch while the pass was being written and had already removed 9 \u2014 a baseline above the truth silently permits new violations. This count goes to ZERO as the remaining repairs land; every repair is a lowering commit. Lowered 56\u219251 by the road-to-renewal-foundation Phase 1 dead-root sweep (check_always_budget, check_portability, check_references, lint_framework_leakage, lint_agents_md). Lowered 51\u219249 by the gate-hardening adoption PR: skill_collision_clusters and skill_overlap were repointed at the live skills tree via the shared resolver \u2014 two gates that had been reading the retired container and scoring 0 of 288 skills. Lowered 49\u219248 by road-to-rule-delivery-integrity P2.2: score_skill_selection was repointed at the live skills tree via the shared resolver. It is the same shape as the two gates lowered before it \u2014 a scorer reading the retired container and scoring 0 of 288 skills \u2014 and here the consequence was sharper than a dead gate: the roadmap's pre-registered selection-accuracy criteria would have been compared against a baseline of silent zeros. Lowered 48\u219247 on 2026-08-13, and this one is a catch-up rather than a repair: the pass reported 47 against a baseline of 48, so a gain had already landed without the ratchet following it. Attributed to 455160160 (fix(evals): resolve the eval orchestrator against the live skills tree), the most recent repair in this branch's base that removes a path-constructing line \u2014 SKILLS_ROOT repointed through _lib/agent_src.ts::SRC_SKILLS(). A loose ratchet is not harmless: it silently permits one new violation to be added back without any gate noticing, which is the shape this entry exists to prevent."
|
|
24
|
-
},
|
|
25
|
-
"check_source_size_budget": {
|
|
26
|
-
"count": 19363,
|
|
27
|
-
"landed": "2026-08-22",
|
|
28
|
-
"note": "Lowered 19,395 -> 19,363 on 2026-08-22 by road-to-council-seat-selection, and the -32 is the residue of a LOWERING THROUGH EXTRACTION that had to pay for its own feature first. The branch adds the verified_at member stamp and the check_council_pin_staleness gate, whose 74 new lines landed in two files already far above the ceiling -- ai_council/config.ts (+63, at 2,272) and ai_council/clients.ts (+11, at 2,862). This gate refused it, correctly, and the debt could not be paid out of the additions themselves: of the 63 only a ~48-line validation block is a movable unit, and the 11 are a comment on a one-line constant. So the payment came from the cleanest pre-existing unit in the same file -- the already-labelled, already-self-contained 'Python-format helpers' section (114 lines) moved whole to ai_council/py_format.ts, which config.ts now imports. Net -32 past zero rather than exactly to it, because the section is a section and splitting it to hit a number would leave a worse file than moving it.",
|
|
29
|
-
"falsifier": "./scripts-run src/scripts/check_source_size_budget --quiet"
|
|
30
|
-
},
|
|
31
|
-
"ci-parity:local-only": {
|
|
32
|
-
"count": 165,
|
|
33
|
-
"landed": "2026-08-13",
|
|
34
|
-
"note": "Gates that `task ci` runs and no workflow does \u2014 the direction this manifest's own header calls the one that let real defects merge (16 stale index rows reached the trunk behind a local-only check-index). Revealed, not created, by repairing the checker's extraction: check_ci_local_parity built its CI-side set by regexing RAW workflow text for `task <name>` and expanding each closure, comments included. Several workflow comments contain the literal string `task ci` while stating that no workflow invokes it, so `ci` was read as an invocation and its full 247-gate closure entered the 'runs in CI' set. The count was therefore 0 BY CONSTRUCTION, and the prose documenting the gap was what suppressed it. Measured at the repair: CI-side 273 \u2192 106, undeclared_local_only 0 \u2192 167 of 247 local gates (68%). Baselined rather than hard-failed because 167 findings nobody can clear in the change that reveals them is the gate-that-lands-as-N-instant-blockers failure this repository has refused before; shrink-only keeps the property that matters, namely that a NEW gate registered in `task ci` with no workflow reds immediately. Lowering happens by wiring gates into workflows or declaring them under `local_only:` with a reason. Note the punchline, because it bounds the risk of this entry: check_ci_local_parity ITSELF runs in no workflow, so it is its own finding and this ratchet has no remote reach either \u2014 clearing the backlog is what gives it teeth. DRAINED BY ONE, 2026-08-13: check_ci_local_parity itself was wired into consistency.yml, so it left the set it exists to report. That is the whole shape of a legitimate drain here \u2014 the gate stops being local-only because a workflow now runs it, not because the declaration list grew. The floor in gate-coverage.yml moved in the same change and for the same reason: wiring two gates raised the parsed population 357 -> 360 (109 CI + 251 local). The intermediate 359 was the reading after the CI-side wiring alone and before check_gate_coverage joined the local `ci` chain; it was committed here by mistake and is corrected rather than left as a second number for the same measurement. WALKED DOWN 166 -> 165 on 2026-08-20 (road-to-session-closeout 5.2): check_ci_local_parity reported `ci-parity:local-only: 165 violation(s), baseline 166 - ratchet is loose` and asked for exactly this, so the gain cannot be silently given back. The measurement is the gate's own output on the merged tree, not a branch. What is NOT done here is the classification the same step asks for: 165 gates each need a recorded class (belongs-in-CI / developer-aid / dead), which is per-gate judgement, and migrating them would red the trunk on the landing day - the step forbids it for that reason.",
|
|
35
|
-
"falsifier": "./scripts-run src/scripts/check_ci_local_parity"
|
|
36
|
-
},
|
|
37
|
-
"gate-self-test:registered-non-adopters": {
|
|
38
|
-
"count": 24,
|
|
39
|
-
"landed": "2026-08-06",
|
|
40
|
-
"note": "Self-test adoption ratchet, expressed as a shrink-only NON-adopter count. 24 of the 32 gates registered enforced in gate-coverage.yml carry neither a `--self-test` (`_lib/gate_self_test.ts`) nor a `// self-test-exempt: <reason>` marker, so nothing proves they DISCRIMINATE \u2014 an enforced `scanned:` floor proves a gate read something, only a self-test proves the reading changes the verdict. Deliberately NOT an adoption column ratcheted upward: check_gate_coverage.ts's own report_hardening_ratchet rejects that shape in this same file (\"grades the solution instead of the problem\"), and the sibling adoption ratchet (check_gate_completeness) is already a non-adopter count. Population is the manifest, not every script under src/scripts: padding the manifest to move this number would mean adding a floor per row. Shrink-only from here \u2014 a NEW registered gate must adopt or exempt. Migration mechanism, same as the ledger ratchet above: gates adopt as they are touched, not in a sweep \u2014 the eight current adopters were each added alongside a real change to that gate. The 56-day non-stagnation clause applies unchanged, so a count parked here fails on its own.",
|
|
41
|
-
"falsifier": "./scripts-run src/scripts/check_gate_coverage"
|
|
42
|
-
},
|
|
43
|
-
"lint_handoffs": {
|
|
44
|
-
"count": 18,
|
|
45
|
-
"landed": "2026-08-02",
|
|
46
|
-
"note": "All 18 are `handoff_tier_mismatch`: a senior-tier skill links to a peer whose frontmatter carries no `tier` (reported as tier='unset') \u2014 e.g. build-buy-partner \u2192 adr-create, customer-research \u2192 po-discovery, gated-reach \u2192 threat-modeling. This is a tier-metadata backfill backlog on the LINKED-TO skills, not a broken link. The one genuinely dangling link revealed by the same repair (competitive-positioning \u2192 a non-existent ../analyze-reference-repo/SKILL.md; it is a command, not a skill) was FIXED in the repairing commit rather than baselined. Clearing this entry means backfilling `tier` on the linked-to skills, or deciding that `tier: unset` on a link target is not a violation and narrowing the rule."
|
|
47
|
-
},
|
|
48
|
-
"lint_pack_boundaries": {
|
|
49
|
-
"count": 337,
|
|
50
|
-
"landed": "2026-08-02",
|
|
51
|
-
"note": "Markdown links between source artefacts that cross a pack boundary the source pack's `requires` graph does not reach \u2014 revealed when the scan root moved off the deleted packages/ tree to the live corpus (0 -> 753 artefacts scanned). 82 distinct pack pairs across 131 source files; largest single class is engineering-base -> meta (73), skills in a consumer-installable pack citing this package's own maintenance skills. Each is a link that dangles for a consumer who installs the source pack without the target's. Judged real drift rather than an over-strict gate because it is long-tailed \u2014 top bucket 22%, no single systematic cause \u2014 unlike the lint_artefact_frontmatter case, where one required shape had 0-of-288 adoption. Fix per finding: add the edge to packs.yml requires, retarget the link, or move the artefact."
|
|
52
|
-
},
|
|
53
|
-
"lint_provenance_vocabulary:permanence-language": {
|
|
54
|
-
"count": 5,
|
|
55
|
-
"landed": "2026-08-22",
|
|
56
|
-
"note": "Permanence language in an ADR record's load-bearing positions -- its `# ` title, its `decision:` frontmatter slug, its `## Decision` section, or an `Addendum` heading. Revealed by adding rule 4 to lint_provenance_vocabulary, not created by it: ADR-240 section 6 states the doctrine (`forever`, `permanently`, `never revisit`, `never reconsider` and their kin do not belong in a mechanism decision's title, slug or Decision section) and the corpus had five records violating it on the day the rule landed. Baselined rather than hard-failed because a gate that lands as five instant blockers is the shape this repository has already refused (see ci-parity:local-only and lint_roadmap_blockers:decidability above), and every one of the five is a content decision rather than a copy edit: ADR-208 (slug `dist-agent-src-keep-forever`, title \"kept forever\", Decision \"KEEP -- permanently\") is the standing self-contradiction ADR-240 cites, since lines 10-11 of its own frontmatter carry the conditions under which it should be reopened; ADR-107:37 and ADR-108:5/12/24/29 are owner PURPOSE statements (\"open-source forever\", \"now or in the future\", \"liability disclaimer is permanent\") whose fix is the escape ADR-240 names -- record `authority_basis: owner_intent` -- which is an owner ruling, not an agent edit; ADR-122:77/154 and ADR-124:229 assert a permanently-off default whose honest form is a default-off setting plus a reopen condition. The rule is deliberately SCOPED and the scoping is the gate: the same word list applied to whole files matches many more, and the large majority are legitimate. The comparison figure is given with its method because 'unscoped' has two readings and an earlier version of this note picked one without saying which, giving 41 lines across 30 records which reproduces neither way: the bare word list over both ADR surfaces matches 45 lines in 26 records, and the word list PLUS the lint's own line filters (code fences, quoted spans, table rows, in-sentence negation, attributive `permanent`, hyphen compounds) but WITHOUT position scoping matches 29 in 17. Scoping to the four load-bearing positions takes it to 11 in 5. The 29-to-11 step is what the scoping buys; the 45 is what a naive grep would report -- an `## Alternatives considered` entry rejecting a permanence option (ADR-105:97, ADR-137:148-151, ADR-212:133), a `## Consequences` line reporting one (ADR-136:90, ADR-208:73, ADR-216:278/298), a `## Context` recounting one (ADR-042:36, ADR-232:34), a quoted open question (ADR-201:342/343) and a table rationale cell bounding a failure mode (ADR-074:41, ADR-225:64) are all describing a permanence claim rather than making one. Shrink-only from here, which is the property that matters: a NEW record asserting permanence in any of the four positions reds this gate immediately, and headroom is zero. Lowering happens one record at a time -- convert an owner purpose statement to `authority_basis: owner_intent`, or restate a mechanism decision with the reopen condition it already carries. The 56-day expiry is the point rather than a hazard: if this number has not moved in two months, the doctrine is not being applied and the gate should fail until someone decides whether it is real.\n\nWALKED 11 -> 5 on 2026-08-22 by road-to-evidence-based-adr-governance 4.3, and the split is exactly the one this note predicted: the six AGENT-EXECUTABLE hits are fixed and the five OWNER-RESERVED ones are untouched. ADR-208's slug is now `dist-agent-src-is-the-shipped-projection-tree`, its title says \"until its `review_trigger` fires\", and its Decision reads \"KEEP, until `review_trigger` (a), (b) or (c) fires\" -- the escape ADR-240 section 6 names, taken against reopen conditions the record's own frontmatter already carried, which is why it needed no new judgement. ADR-122:77/154 and ADR-124:229 asserted a permanently-off default; each now states default-off plus the reopen condition its own measurement supplies (for ADR-122, a re-run clearing both locked thresholds with the FP control held; for ADR-124, the category limit behind the null being shown not to hold). Those two carry no `review_trigger` at all -- both predate the 2026-07-25 requirement -- so the condition was derived from the measurement in the record rather than restated from frontmatter, and that difference is recorded because it is the weaker of the two moves. The FILE NAME of ADR-208 is deliberately unchanged: no gate couples the `decision:` slug to the filename (regenerate_index reads the slug only as a fallback when `decision:` is absent), and renaming would rewrite eight inbound references, two of them inside frozen review-input diffs and one inside an archived roadmap whose path was correct when written -- rewriting history to fix a name, which is the trade this tree already refused for out-of-directory decision records. The remaining five are ADR-107:37 and ADR-108:5/12/24/29, owner PURPOSE statements whose fix is `authority_basis: owner_intent`; they are routed to stubs/road-to-owner-authority-decisions.md and are not agent-editable. Zero headroom still holds for the four load-bearing positions.",
|
|
57
|
-
"falsifier": "./scripts-run src/scripts/lint_provenance_vocabulary"
|
|
58
|
-
},
|
|
59
|
-
"lint_settings_classes:derivable-surface": {
|
|
60
|
-
"count": 83,
|
|
61
|
-
"landed": "2026-08-12",
|
|
62
|
-
"note": "Anti-regrowth ratchet for the settings disposition axis. 83 of 134 template leaves are classified `derivable` \u2014 the mechanism can decide from the situation, so the key should not exist \u2014 and each names the replacement that would decide instead (`lint_settings_classes` rejects the bare label, which is what keeps the class from becoming a synonym for \"inconvenient to keep\"). This is a DELETION QUEUE, not 83 deletions: a row stays until the mechanism it names actually exists, and deleting a key ahead of its mechanism is a silently-changed default rather than a simplification. Shrink-only from here, which is the anti-regrowth half \u2014 a NEW key classified `derivable` raises the number and reds, so a key whose answer the situation already carries cannot be added at all. The 56-day non-stagnation clause is the other half and is wanted here rather than tolerated: a queue that never drains is a stated direction nobody is walking. The queue opened at 88 of 140 on 2026-08-12 and drained to 83 of 134 the same day: six keys had no reader whatsoever (telegraph.speak_scope, chat_history.max_size_kb, chat_history.on_overflow, quality.wait_for_remote_ci, screenshots.data_bearing_gate, legal_review_prep.consented_at), five of them `derivable` and one a `consent` row reclassified because a published-egress confirmation is a Hard Floor no setting may lift. An unread key is the only deletion that cannot silently change a default, which is why that batch went first. The classification itself is docs/contracts/settings-classes.md.",
|
|
63
|
-
"falsifier": "./scripts-run src/scripts/lint_settings_classes"
|
|
64
|
-
}
|
|
2
|
+
"$comment": "Violation ratchet for gates whose dead scan root was repaired. A repair REVEALS pre-existing debt; it does not create it. Each entry records the count revealed at repair time \u2014 the gate fails only when its count RISES. Lowering a count is a normal commit; raising one is a defect. Entries expire: a baseline that has not dropped within 56 days of `landed` (or of `reaffirmed.date`) fails its gate, because a number that never moves is suppression with extra steps. Mechanism + rationale: src/scripts/_lib/gate_baseline.ts. Decision: AI council 2026-08-02, roadmap road-to-gates-that-can-fail blocker `dead-gate-finding-triage`.",
|
|
3
|
+
"gates": {
|
|
4
|
+
"audit_user_type_axis": {
|
|
5
|
+
"count": 1,
|
|
6
|
+
"landed": "2026-08-02",
|
|
7
|
+
"note": "One orphan user-type value: `legal`. Five legal-review-prep skills (contract-review, dpa-review, nda-triage, legal-intake-triage, legal-practice-profile) declare `recommended_for_user_types: [legal]`, but there is no `user-types/legal.yml` \u2014 the pack shipped an axis value with no user-type definition behind it, and the dead scan root hid it (the audit reported used=0 orphans=0 while reading zero skills; it now reads 288 and reports used=8). Clearing this entry is a product call, not a copy edit: either author `user-types/legal.yml` (tagline, recommended packs, install-path hint) or drop `legal` from those five skills. Not decided here because both options change shipped pack behaviour."
|
|
65
8
|
},
|
|
66
|
-
"
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
"note": "Open blocker entries that are not yet DECIDABLE by the person who owns them \u2014 missing `Recommendation:` (which option and why), missing `If you do nothing:` (the cost of the non-decision), or a `What to do:` carrying no command, path or enumerated option set. Revealed by adding the decidability half to lint_roadmap_blockers, not created by it: the five original fields describe a situation and never made it actionable, so a blocker could pass the contract while handing the analysis back to the person least equipped to redo it. Measured at introduction: 36 open entries, ALL 36 undecidable, and 14 of the 46 total entries carry no command/path/option at all in `What to do`. Baselined rather than hard-failed because 36 findings nobody can clear in the change that reveals them is the gate-that-lands-as-N-instant-blockers failure this repository has refused before \u2014 the same reasoning as ci-parity:local-only above. First measured at 34 rather than 36 because the two blockers on the branch that introduced this (`ac3-false-positive-reading`, `publish-side-marker-invariant`) were rewritten to the new standard and then closed in the same change; a baseline above the truth silently permits new violations. Re-measured at 38 when the branch was re-pointed at current main, and the +4 is population growth rather than a loosening: main gained the four `road-to-inbox-harvest-2026-08-d-*` roadmaps (context-ledger, runtime-skill-routing, scheduled-deprecation, top-band-model-economy), each carrying one open blocker authored before this requirement existed. That is the honest number for the population this gate now scans \u2014 recording 34 against a 38-entry tree would have failed the gate on its own introducing commit and taught the next reader to distrust it. Lowering happens one blocker at a time, and every roadmap touched for other reasons is a chance to lower it. Lowered 38\u219237 by the scheduled-deprecation PR, which is exactly that shape: code-graph-removal-authorisation was rewritten to the new standard because the roadmap was being touched anyway. Its `If you do nothing:` was one of the few that was not the common no-cost answer \u2014 the release gate that PR ships would have refused the next major cut while the blocker stayed open. Recorded in the past tense because the maintainer then RESOLVED that blocker on the trunk by withdrawing the commitment, so nothing refuses a cut today. The lowering stands on the rewrite, not on the consequence, and the sentence is corrected rather than deleted because a baseline note arguing from a retracted state is how a ratchet's rationale rots. The 56-day expiry is the point, not a hazard: if this number has not moved in two months, the fields are not being written and the gate should fail until someone decides whether the requirement is real. Lowered 37\u219234 when the scheduled-deprecation branch merged current main: three blockers were resolved or rewritten on the trunk in the meantime, so the drop is a genuine drain plus a merge, not a loosening. Re-tightened here rather than left loose because a ratchet that lags its own tree permits violations back in silently. Lowered 34\u219229 on 2026-08-16 by rewriting six entries to the new standard (raw-capture-needs-host-env, telemetry-sample-size, repo-admin-and-usage, benchmark-spend, measurement-a-no-per-arm-builder-tier, measurement-b-no-renderable-lane-pair) in a PR whose only purpose was the drain \u2014 the first lowering not taken on the back of another change, which the note above says is the usual shape. Two findings from that pass are worth keeping. The tree measured 35 against a baseline of 34 BEFORE the drain, i.e. the ratchet was already red on main and nobody knew: this gate runs in `task ci`, no workflow invokes `task ci`, and the local run that would have shown it was read through a `tail`, which hid every row above the last six. And four of the six `If you do nothing:` answers are honestly that nothing degrades \u2014 that is the true answer for a held measurement, and writing it is what makes the entry decidable, so the field earns its place by being cheap to answer truthfully rather than by always carrying a cost. Lowered 29 \u2192 27 on 2026-08-16 by the merge of this branch and the trunk drain above, and the arithmetic matters more than the delta: both sides rewrote entries from the same tree of 35 independently \u2014 the trunk six (recorded above), this branch two (deferred-finding-decision-reopen, spent-inbox-artifacts-await-deletion, rewritten because road-to-inbox-harvest-residuals was being touched anyway). The sets are disjoint, so the merged tree measures 27 and the gate itself reported the slack. Tightened rather than banked: 29 against a 27-entry tree would absorb the next two undecidable blockers without anything noticing, which is the lag this note has now corrected twice. Lowered 27 \u2192 26 on 2026-08-16 by rewriting `picktier-wire-or-archive` (road-to-inbox-harvest-2026-08-d-top-band-model-economy), and this one is the usual shape the note describes rather than the dedicated-drain shape: the roadmap was being worked for its own Step 4.1 and the entry was rewritten because it was open on the desk. Worth recording for what writing the two fields SURFACED, which is the argument for the requirement: `Recommendation:` forced the question 'which option, and why' and the honest answer turned out not to be one of the three options at all \u2014 the entry defers to a converged council verdict, and the council cannot reach quorum (re-measured 0 of 2 the same day), so the actionable next step is a one-line fix to a user-global config file outside this repository. Five fields had described that situation accurately for two weeks without anyone noticing that the named blocker was infrastructure rather than judgement. Lowered 26 \u2192 22 on 2026-08-18 by road-to-estate-drawdown Step 0.1, which needed the two fields for a different reason and therefore drained six entries as a by-product: the consolidated decision sheet renders a DEFAULT plus that default's provenance per user-owned decision, and 7 of the 21 live entries recorded no `Recommendation:` to derive one from. Six were rewritten to the new standard (skill-activation-window, b-convergence-machine, maintainer-blind-ratings, real-orchestration-usage, human-gated-live-trigger-eval, manual-rubric-rater), each marked `agent-drafted` in the field itself so the sheet can label the provenance rather than presenting a drafted default beside a maintainer-recorded one as the same kind of statement. The seventh, `road-to-gated-reach-followup`'s legacy `> Blocked until \u2026` note, is NOT counted here and was not rewritten: it is a blocked-until note rather than a `### blocker:` entry, so it has no field to carry, and converting it is a roadmap restructure this change did not take. **The tree was RED at 28 against this baseline of 26 before the drain, and again nobody knew** \u2014 the same failure the 34\u219229 paragraph above records, one gate cycle later: two entries had been added on the trunk without the fields, and this gate runs in `task ci`, which no workflow invokes. That is the second recorded instance of this ratchet being red on main undetected, which is an argument about where it runs rather than about its number. `human-gated-live-trigger-eval` also gained a command in `What to do:` (`rule_trigger_eval`, verified to exist at src/scripts/) because the field carried a path-less instruction; the other five needed only the two decidability fields. Lowered 22 -> 20 on 2026-08-19 by road-to-estate-drawdown Phase 2 triage batch 1, and RE-MEASURED after two merges of origin/main rather than carried over: the trunk gained roadmaps in between (the long-horizon pair and the council-fallback set), and the live count over the merged tree is still 20 across 39 roadmaps. Six roadmaps moved to later/, and two of them carried an undecidable open blocker each. The gain is a side effect of parking rather than of drafting a recommendation, so it is recorded as such \u2014 the two entries are unchanged and still undecidable where they sit; they are simply outside the active tree this ratchet scans. Walked down because the gate reported itself loose, and a baseline above the measurement is headroom a later change can spend with nothing objecting. Lowered 20 -> 17 on 2026-08-20 by the road-to-frontend-skill-application closeout, and the shape is the usual one this note describes: the roadmap was being closed for its own reasons and its three open blockers were on the desk anyway. Two (ui-corpus-has-no-ui, enforcement-evidence) left the population by being RESOLVED rather than rewritten, which is the cleanest way to lower this number and the only one that does not add prose; the third (ui-session-capture-window) was rewritten to the new standard. Worth recording what writing the two fields surfaced, since that is the standing argument for the requirement: on ui-corpus-has-no-ui, `Recommendation:` forced the question \"which option, and why\" and the honest answer was that the entry's own premise was false \u2014 it asserted the question could not be answered without a human naming a consumer store, and the stores were already on the machine, readable by the command the entry itself printed. Five fields had described that situation accurately for a week without anyone noticing the blocker was a measurement nobody had run. Tightened rather than banked because 20 against a 17-entry tree is headroom the next three undecidable blockers would spend with nothing objecting, which is the lag the paragraphs above have now corrected three times. Walked 17 -> 12 at the drain/road-to-frontend-skill-application merge, 2026-08-21, on the gate's own loose-ratchet report. Re-measured against the merged tree rather than attributed: sibling drain PRs made entries decidable in parallel, so this branch's share is not separable here and is not claimed. Banked at the measurement rather than left as headroom a later change could spend.\n\nWALKED 12 -> 1 on 2026-08-22 by resolving the two `road-to-evidence-based-adr-governance` blockers (`owner-autonomy-batch`, `authority-coupling-decision`), which were undecidable in exactly the way this ratchet names: each handed a Hard-Floor question to the reader without a landed outcome. Both now carry one. The single remaining violation is `road-to-drain-commands:395` (`merge-authority`), which PR #1517 resolves and archives \u2014 so the honest count for THIS tree is 1 and it is expected to reach 0 once that lands. It is not lowered to 0 here, because a baseline must describe the tree it ships with rather than the tree someone expects next. Lowered 1 -> 0 on 2026-08-22, and the prediction the previous entry made is what closed it: the single remaining violation was `road-to-drain-commands:395` (`merge-authority`), and PR #1517 archived that roadmap, taking the entry out of the scanned population. Nothing was rewritten to reach zero -- the record left the active tree with its blocker RESOLVED, which is the cleanest of the two ways this number goes down and the only one that adds no prose. Zero is now the ceiling: any new open blocker missing `Recommendation:`, `If you do nothing:` or an actionable `What to do:` reds this gate immediately, with no headroom at all.",
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
9
|
+
"check_depth_budget": {
|
|
10
|
+
"count": 4,
|
|
11
|
+
"landed": "2026-08-06",
|
|
12
|
+
"note": "Four depth files exceed the 16,000-char per-file ceiling: rule-body-migration-inventory.md (23,782), design-antipatterns.md (20,707), roadmap-process-loop.md (20,360), orchestration-telemetry.md (16,155). Recorded rather than fixed because splitting four large reference documents is unrelated to the change that introduced the ceiling, and a gate that lands as four instant blockers is the shape this repository has already recorded as a failure. Shrink-only from here: a FIFTH over-ceiling file reds. roadmap-process-loop.md is the file that motivated the gate \u2014 it states 'Size budget: <= 4,000 chars' in its own header and is 5x over it, which is what a declared budget with nothing measuring it decays into. The ceiling is a GROWTH RATCHET, not a measured quality threshold: the 7,308-trajectory study behind the 3,500-token skill ceiling (ADR-217) was taken on procedural always-co-loaded skills, and this layer is declarative and loaded one or two files at a time. Replace the number when someone measures comprehension on THIS layer."
|
|
13
|
+
},
|
|
14
|
+
"check_gate_completeness": {
|
|
15
|
+
"count": 215,
|
|
16
|
+
"landed": "2026-08-17",
|
|
17
|
+
"note": "Ledger adoption ratchet. Gates registered under the CI task roots that carry neither per-target completeness accounting (`_lib/gate_ledger.ts`) nor a `// ledger-exempt:` marker. This is deliberately NOT a sweep: road-to-skill-ecosystem-gate-integrity Phase 1 adopts exactly three gates (lint_framework_leakage, check_references, lint_roadmap_complexity) plus the checker itself to prove the interface, and the remainder migrates as gates are touched. Shrink-only from here \u2014 the number may not grow, so a NEW gate must adopt or exempt. Lowered 216 -> 215 on 2026-08-17 by discharging the obligation three NEW arrivals had incurred, which is the standing rule being enforced rather than a drain: the registered population grew 244 -> 258 and three of the fourteen arrivals adopted nothing \u2014 `build_archive_index`, `check_gate_coverage`, `check_pr_ci_current`. The reading was 218 against this baseline of 216, and the missing arithmetic is that one PRE-existing gate (`lint_rule_skill_pack_reach`) had adopted in the meantime: 216 + 3 - 1 = 218. All three adopted a real ledger. `check_pr_ci_current` first took a reasoned exemption claiming no target population; the completion review refuted it from the file itself \u2014 the check rows ARE a population, and rows whose `state` is not a string were being dropped before any verdict ran, so a dropped row could be the failing one. The exemption was withdrawn and the ledger adopted, counting kept rows as read, dropped rows as skips, and rows a pre-row verdict never reached as out of scope. The denominator in this note was 14 stale (it said 244) and is now expressed without one, because a count pinned to a population that grows weekly rots faster than the count itself. Note what this lowering does NOT buy: headroom is zero either way, so the next un-adopted arrival reds this gate immediately \u2014 which is the intended behaviour and the reason the number is not padded. The refreshed `landed` is load-bearing rather than bookkeeping: `checkRatchet` returns `improved` BEFORE it evaluates staleness, so an entry left at 216 while the tree measures 215 would never expire at any age (pinned by tests/lib/gate_baseline.test.ts, which asserts `improved` at landed + STALE_AFTER_DAYS + 400 days) \u2014 the greenest available state and the worst, since it switches off the anti-fossilization clause exactly when someone has done real work.",
|
|
18
|
+
"falsifier": "./scripts-run src/scripts/check_gate_completeness"
|
|
19
|
+
},
|
|
20
|
+
"check_no_new_legacy_path:hardcoded-scan-roots": {
|
|
21
|
+
"count": 47,
|
|
22
|
+
"landed": "2026-08-13",
|
|
23
|
+
"note": "Lines under src/scripts/**/*.{ts,mts,mjs} that pass the retired `.agent-src.uncondensed` directory into `path.join(...)` \u2014 a filesystem path CONSTRUCTED against the tree ADR-051 abandoned, which is the exact shape of all 14 dead gates. Deliberately narrow so the number is signal, not noise: 236 raw mentions under src/scripts \u2192 147 string-literal lines \u2192 67 path-constructing lines when the pass was written, after exempting src/scripts/_lib/agent_src.ts (the shared resolver, whose job IS owning the constant \u2014 gates that route through it survived the move). Detectors holding the literal as data to match, strip, or print are not counted, and no prose, docs, tests or fixtures are read: that full-tree shape was measured at 44 files / 213 hits and rejected as the wrong lint (see the note in check_no_new_legacy_path.ts::find_offenders). Recorded at 58 rather than 67 because Phase 1's scan-root repairs were landing on this branch while the pass was being written and had already removed 9 \u2014 a baseline above the truth silently permits new violations. This count goes to ZERO as the remaining repairs land; every repair is a lowering commit. Lowered 56\u219251 by the road-to-renewal-foundation Phase 1 dead-root sweep (check_always_budget, check_portability, check_references, lint_framework_leakage, lint_agents_md). Lowered 51\u219249 by the gate-hardening adoption PR: skill_collision_clusters and skill_overlap were repointed at the live skills tree via the shared resolver \u2014 two gates that had been reading the retired container and scoring 0 of 288 skills. Lowered 49\u219248 by road-to-rule-delivery-integrity P2.2: score_skill_selection was repointed at the live skills tree via the shared resolver. It is the same shape as the two gates lowered before it \u2014 a scorer reading the retired container and scoring 0 of 288 skills \u2014 and here the consequence was sharper than a dead gate: the roadmap's pre-registered selection-accuracy criteria would have been compared against a baseline of silent zeros. Lowered 48\u219247 on 2026-08-13, and this one is a catch-up rather than a repair: the pass reported 47 against a baseline of 48, so a gain had already landed without the ratchet following it. Attributed to 455160160 (fix(evals): resolve the eval orchestrator against the live skills tree), the most recent repair in this branch's base that removes a path-constructing line \u2014 SKILLS_ROOT repointed through _lib/agent_src.ts::SRC_SKILLS(). A loose ratchet is not harmless: it silently permits one new violation to be added back without any gate noticing, which is the shape this entry exists to prevent."
|
|
24
|
+
},
|
|
25
|
+
"check_roadmap_trackable:relates": {
|
|
26
|
+
"count": 9,
|
|
27
|
+
"landed": "2026-08-23",
|
|
28
|
+
"note": "The nine active non-draft roadmaps that predate the `relates:` requirement (road-to-agentic-engineering-assurance, road-to-component-library-lifecycle, road-to-council-evidence-integrity, road-to-frontend-fidelity-calibration, road-to-monorepo-scope-and-detection, road-to-observability-plate, road-to-role-scoped-spawn-profiles, road-to-skill-delivery-over-mcp, road-to-standing-payload-diet). This is a NEW obligation rather than a repaired scan root, and the ratchet is the point: `depends:` shipped in the template with nothing requiring it and measured 0 adoption, so requiring `relates:` retroactively across the estate would be an owner-reserved write with no analysis behind the edges it would have to invent (held as step 4.3, deferred). Clearing an entry here is one roadmap at a time: run `agent-config roadmap:context` on it, write the rows the probe surfaces, and lower the count."
|
|
29
|
+
},
|
|
30
|
+
"check_source_size_budget": {
|
|
31
|
+
"count": 18512,
|
|
32
|
+
"landed": "2026-08-24",
|
|
33
|
+
"note": "Lowered 18,561 -> 18,512 on 2026-08-24 by the same method every prior entry here prescribes — the merged tree MEASURED, never a side picked. main had reached 18,561; this branch (road-to-skill-delivery-over-mcp) carries its own extractions, and the merged total reads 18,512, a -49 gain that would have been silently given back by keeping main's number. Set to the EXACT live total, because check_source_size_budget.test.ts asserts baseline == tree total; a baseline loose by one line is a red test, and that is how this surfaced. Prior entry: lowered 18,566 -> 18,561 on 2026-08-24 by the method the two prior entries prescribe, for the same reason: independent gains met in a merge, so the merged tree was MEASURED rather than a side picked. main had reached 18,566 via road-to-skill-link-integrity-and-manifest-sync Phase 2; this branch had already paid its own extraction under road-to-trigger-delivered-rule-bodies 1.6 (condense.ts's inline mode literal moved whole to _lib/lean_projection_mode.ts, -5; the new module is 45 lines and therefore free). check_source_size_budget reports 18,561 on the merged tree, exactly 18,566 - 5, so picking either side's number would have given back the other's gain. Set to the EXACT live total: check_source_size_budget.test.ts asserts baseline == tree total, so a baseline loose by one line is a red test — which is how this lowering surfaced rather than by inspection. `landed` refreshed deliberately, not as bookkeeping: checkRatchet returns `improved` BEFORE it evaluates staleness, so an entry left at the old number while the tree measures lower would never expire at any age. Prior entry: lowered 18,574 -> 18,571 on 2026-08-23, and the -3 is the SUM of two independent lowerings-through-extraction that met in a merge, not a new reduction. main had already reached 18,573 via road-to-override-efficacy-proof (-1: _check_overrides moved whole to _cli/doctor_overrides.ts, -119, and the install-mode detector plus its marker constant to _cli/doctor_install_mode.ts, -14, both names forwarded with `export ... from`; net -1 past zero rather than exactly to it, because the unit that paid is a unit). This branch had reached 18,572 via road-to-council-evidence-integrity Phases 1-2 (-2: the two result bundles PeerReviewResult and ConsensusResult, -98, the two options interfaces, -19, and CouncilQuestion, -11, all PURE MOVES into ai_council/orchestrator_results.ts, with orchestrator.ts re-exporting every name; the options interfaces required a TYPE-ONLY back-import of OnOverrunCallback, legal and runtime-free since both directions are erased). The merge conflict was resolved by MEASURING the merged tree rather than picking a side: check_source_size_budget reports 18571 on it, which is exactly 18,574 - 1 - 2. Picking either branch's number would have silently given back the other branch's gain -- the failure main's own entry names one line above. Set to the EXACT live total: check_source_size_budget.test.ts asserts baseline == tree total, so a baseline left loose by even one line is a red test. Lowered 18,571 -> 18,566 on 2026-08-23 by road-to-skill-link-integrity-and-manifest-sync Phase 2, which had to pay its own way before it could pass: adding set_augment_manifest_version to release.ts charged +35 lines, because release.ts is 564 lines PAST the 1500-line threshold and every line above it counts. The fix was extraction, never a bump. Both manifest-version writers -- the new set_augment_manifest_version and its pre-existing twin set_marketplace_version -- moved whole into release_env.ts, the leaf that already owns both manifest paths AND jsonDumpsIndent, so neither function needed anything it did not already have there. release_env.ts is 298 lines, far under the threshold, so those lines are now free. release.ts re-exports set_marketplace_version so its existing test import keeps resolving; the new function is imported from release_env directly. Net -5 past zero rather than exactly to it, for the same reason main's entry gives: the unit that pays is a unit."
|
|
34
|
+
},
|
|
35
|
+
"ci-parity:local-only": {
|
|
36
|
+
"count": 165,
|
|
37
|
+
"landed": "2026-08-13",
|
|
38
|
+
"note": "Gates that `task ci` runs and no workflow does \u2014 the direction this manifest's own header calls the one that let real defects merge (16 stale index rows reached the trunk behind a local-only check-index). Revealed, not created, by repairing the checker's extraction: check_ci_local_parity built its CI-side set by regexing RAW workflow text for `task <name>` and expanding each closure, comments included. Several workflow comments contain the literal string `task ci` while stating that no workflow invokes it, so `ci` was read as an invocation and its full 247-gate closure entered the 'runs in CI' set. The count was therefore 0 BY CONSTRUCTION, and the prose documenting the gap was what suppressed it. Measured at the repair: CI-side 273 \u2192 106, undeclared_local_only 0 \u2192 167 of 247 local gates (68%). Baselined rather than hard-failed because 167 findings nobody can clear in the change that reveals them is the gate-that-lands-as-N-instant-blockers failure this repository has refused before; shrink-only keeps the property that matters, namely that a NEW gate registered in `task ci` with no workflow reds immediately. Lowering happens by wiring gates into workflows or declaring them under `local_only:` with a reason. Note the punchline, because it bounds the risk of this entry: check_ci_local_parity ITSELF runs in no workflow, so it is its own finding and this ratchet has no remote reach either \u2014 clearing the backlog is what gives it teeth. DRAINED BY ONE, 2026-08-13: check_ci_local_parity itself was wired into consistency.yml, so it left the set it exists to report. That is the whole shape of a legitimate drain here \u2014 the gate stops being local-only because a workflow now runs it, not because the declaration list grew. The floor in gate-coverage.yml moved in the same change and for the same reason: wiring two gates raised the parsed population 357 -> 360 (109 CI + 251 local). The intermediate 359 was the reading after the CI-side wiring alone and before check_gate_coverage joined the local `ci` chain; it was committed here by mistake and is corrected rather than left as a second number for the same measurement. WALKED DOWN 166 -> 165 on 2026-08-20 (road-to-session-closeout 5.2): check_ci_local_parity reported `ci-parity:local-only: 165 violation(s), baseline 166 - ratchet is loose` and asked for exactly this, so the gain cannot be silently given back. The measurement is the gate's own output on the merged tree, not a branch. What is NOT done here is the classification the same step asks for: 165 gates each need a recorded class (belongs-in-CI / developer-aid / dead), which is per-gate judgement, and migrating them would red the trunk on the landing day - the step forbids it for that reason.",
|
|
39
|
+
"falsifier": "./scripts-run src/scripts/check_ci_local_parity"
|
|
40
|
+
},
|
|
41
|
+
"gate-self-test:registered-non-adopters": {
|
|
42
|
+
"count": 24,
|
|
43
|
+
"landed": "2026-08-06",
|
|
44
|
+
"note": "Self-test adoption ratchet, expressed as a shrink-only NON-adopter count. 24 of the 32 gates registered enforced in gate-coverage.yml carry neither a `--self-test` (`_lib/gate_self_test.ts`) nor a `// self-test-exempt: <reason>` marker, so nothing proves they DISCRIMINATE \u2014 an enforced `scanned:` floor proves a gate read something, only a self-test proves the reading changes the verdict. Deliberately NOT an adoption column ratcheted upward: check_gate_coverage.ts's own report_hardening_ratchet rejects that shape in this same file (\"grades the solution instead of the problem\"), and the sibling adoption ratchet (check_gate_completeness) is already a non-adopter count. Population is the manifest, not every script under src/scripts: padding the manifest to move this number would mean adding a floor per row. Shrink-only from here \u2014 a NEW registered gate must adopt or exempt. Migration mechanism, same as the ledger ratchet above: gates adopt as they are touched, not in a sweep \u2014 the eight current adopters were each added alongside a real change to that gate. The 56-day non-stagnation clause applies unchanged, so a count parked here fails on its own.",
|
|
45
|
+
"falsifier": "./scripts-run src/scripts/check_gate_coverage"
|
|
46
|
+
},
|
|
47
|
+
"lint_handoffs": {
|
|
48
|
+
"count": 18,
|
|
49
|
+
"landed": "2026-08-02",
|
|
50
|
+
"note": "All 18 are `handoff_tier_mismatch`: a senior-tier skill links to a peer whose frontmatter carries no `tier` (reported as tier='unset') \u2014 e.g. build-buy-partner \u2192 adr-create, customer-research \u2192 po-discovery, gated-reach \u2192 threat-modeling. This is a tier-metadata backfill backlog on the LINKED-TO skills, not a broken link. The one genuinely dangling link revealed by the same repair (competitive-positioning \u2192 a non-existent ../analyze-reference-repo/SKILL.md; it is a command, not a skill) was FIXED in the repairing commit rather than baselined. Clearing this entry means backfilling `tier` on the linked-to skills, or deciding that `tier: unset` on a link target is not a violation and narrowing the rule."
|
|
51
|
+
},
|
|
52
|
+
"lint_pack_boundaries": {
|
|
53
|
+
"count": 337,
|
|
54
|
+
"landed": "2026-08-02",
|
|
55
|
+
"note": "Markdown links between source artefacts that cross a pack boundary the source pack's `requires` graph does not reach \u2014 revealed when the scan root moved off the deleted packages/ tree to the live corpus (0 -> 753 artefacts scanned). 82 distinct pack pairs across 131 source files; largest single class is engineering-base -> meta (73), skills in a consumer-installable pack citing this package's own maintenance skills. Each is a link that dangles for a consumer who installs the source pack without the target's. Judged real drift rather than an over-strict gate because it is long-tailed \u2014 top bucket 22%, no single systematic cause \u2014 unlike the lint_artefact_frontmatter case, where one required shape had 0-of-288 adoption. Fix per finding: add the edge to packs.yml requires, retarget the link, or move the artefact."
|
|
56
|
+
},
|
|
57
|
+
"lint_provenance_vocabulary:permanence-language": {
|
|
58
|
+
"count": 5,
|
|
59
|
+
"landed": "2026-08-22",
|
|
60
|
+
"note": "Permanence language in an ADR record's load-bearing positions -- its `# ` title, its `decision:` frontmatter slug, its `## Decision` section, or an `Addendum` heading. Revealed by adding rule 4 to lint_provenance_vocabulary, not created by it: ADR-240 section 6 states the doctrine (`forever`, `permanently`, `never revisit`, `never reconsider` and their kin do not belong in a mechanism decision's title, slug or Decision section) and the corpus had five records violating it on the day the rule landed. Baselined rather than hard-failed because a gate that lands as five instant blockers is the shape this repository has already refused (see ci-parity:local-only and lint_roadmap_blockers:decidability above), and every one of the five is a content decision rather than a copy edit: ADR-208 (slug `dist-agent-src-keep-forever`, title \"kept forever\", Decision \"KEEP -- permanently\") is the standing self-contradiction ADR-240 cites, since lines 10-11 of its own frontmatter carry the conditions under which it should be reopened; ADR-107:37 and ADR-108:5/12/24/29 are owner PURPOSE statements (\"open-source forever\", \"now or in the future\", \"liability disclaimer is permanent\") whose fix is the escape ADR-240 names -- record `authority_basis: owner_intent` -- which is an owner ruling, not an agent edit; ADR-122:77/154 and ADR-124:229 assert a permanently-off default whose honest form is a default-off setting plus a reopen condition. The rule is deliberately SCOPED and the scoping is the gate: the same word list applied to whole files matches many more, and the large majority are legitimate. The comparison figure is given with its method because 'unscoped' has two readings and an earlier version of this note picked one without saying which, giving 41 lines across 30 records which reproduces neither way: the bare word list over both ADR surfaces matches 45 lines in 26 records, and the word list PLUS the lint's own line filters (code fences, quoted spans, table rows, in-sentence negation, attributive `permanent`, hyphen compounds) but WITHOUT position scoping matches 29 in 17. Scoping to the four load-bearing positions takes it to 11 in 5. The 29-to-11 step is what the scoping buys; the 45 is what a naive grep would report -- an `## Alternatives considered` entry rejecting a permanence option (ADR-105:97, ADR-137:148-151, ADR-212:133), a `## Consequences` line reporting one (ADR-136:90, ADR-208:73, ADR-216:278/298), a `## Context` recounting one (ADR-042:36, ADR-232:34), a quoted open question (ADR-201:342/343) and a table rationale cell bounding a failure mode (ADR-074:41, ADR-225:64) are all describing a permanence claim rather than making one. Shrink-only from here, which is the property that matters: a NEW record asserting permanence in any of the four positions reds this gate immediately, and headroom is zero. Lowering happens one record at a time -- convert an owner purpose statement to `authority_basis: owner_intent`, or restate a mechanism decision with the reopen condition it already carries. The 56-day expiry is the point rather than a hazard: if this number has not moved in two months, the doctrine is not being applied and the gate should fail until someone decides whether it is real.\n\nWALKED 11 -> 5 on 2026-08-22 by road-to-evidence-based-adr-governance 4.3, and the split is exactly the one this note predicted: the six AGENT-EXECUTABLE hits are fixed and the five OWNER-RESERVED ones are untouched. ADR-208's slug is now `dist-agent-src-is-the-shipped-projection-tree`, its title says \"until its `review_trigger` fires\", and its Decision reads \"KEEP, until `review_trigger` (a), (b) or (c) fires\" -- the escape ADR-240 section 6 names, taken against reopen conditions the record's own frontmatter already carried, which is why it needed no new judgement. ADR-122:77/154 and ADR-124:229 asserted a permanently-off default; each now states default-off plus the reopen condition its own measurement supplies (for ADR-122, a re-run clearing both locked thresholds with the FP control held; for ADR-124, the category limit behind the null being shown not to hold). Those two carry no `review_trigger` at all -- both predate the 2026-07-25 requirement -- so the condition was derived from the measurement in the record rather than restated from frontmatter, and that difference is recorded because it is the weaker of the two moves. The FILE NAME of ADR-208 is deliberately unchanged: no gate couples the `decision:` slug to the filename (regenerate_index reads the slug only as a fallback when `decision:` is absent), and renaming would rewrite eight inbound references, two of them inside frozen review-input diffs and one inside an archived roadmap whose path was correct when written -- rewriting history to fix a name, which is the trade this tree already refused for out-of-directory decision records. The remaining five are ADR-107:37 and ADR-108:5/12/24/29, owner PURPOSE statements whose fix is `authority_basis: owner_intent`; they are routed to stubs/road-to-owner-authority-decisions.md and are not agent-editable. Zero headroom still holds for the four load-bearing positions.",
|
|
61
|
+
"falsifier": "./scripts-run src/scripts/lint_provenance_vocabulary"
|
|
62
|
+
},
|
|
63
|
+
"lint_settings_classes:derivable-surface": {
|
|
64
|
+
"count": 83,
|
|
65
|
+
"landed": "2026-08-12",
|
|
66
|
+
"note": "Anti-regrowth ratchet for the settings disposition axis. 83 of 134 template leaves are classified `derivable` \u2014 the mechanism can decide from the situation, so the key should not exist \u2014 and each names the replacement that would decide instead (`lint_settings_classes` rejects the bare label, which is what keeps the class from becoming a synonym for \"inconvenient to keep\"). This is a DELETION QUEUE, not 83 deletions: a row stays until the mechanism it names actually exists, and deleting a key ahead of its mechanism is a silently-changed default rather than a simplification. Shrink-only from here, which is the anti-regrowth half \u2014 a NEW key classified `derivable` raises the number and reds, so a key whose answer the situation already carries cannot be added at all. The 56-day non-stagnation clause is the other half and is wanted here rather than tolerated: a queue that never drains is a stated direction nobody is walking. The queue opened at 88 of 140 on 2026-08-12 and drained to 83 of 134 the same day: six keys had no reader whatsoever (telegraph.speak_scope, chat_history.max_size_kb, chat_history.on_overflow, quality.wait_for_remote_ci, screenshots.data_bearing_gate, legal_review_prep.consented_at), five of them `derivable` and one a `consent` row reclassified because a published-egress confirmation is a Hard Floor no setting may lift. An unread key is the only deletion that cannot silently change a default, which is why that batch went first. The classification itself is docs/contracts/settings-classes.md.",
|
|
67
|
+
"falsifier": "./scripts-run src/scripts/lint_settings_classes"
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"retired": {
|
|
71
|
+
"lint_roadmap_blockers:decidability": {
|
|
72
|
+
"count": 0,
|
|
73
|
+
"landed": "2026-08-22",
|
|
74
|
+
"note": "Open blocker entries that are not yet DECIDABLE by the person who owns them \u2014 missing `Recommendation:` (which option and why), missing `If you do nothing:` (the cost of the non-decision), or a `What to do:` carrying no command, path or enumerated option set. Revealed by adding the decidability half to lint_roadmap_blockers, not created by it: the five original fields describe a situation and never made it actionable, so a blocker could pass the contract while handing the analysis back to the person least equipped to redo it. Measured at introduction: 36 open entries, ALL 36 undecidable, and 14 of the 46 total entries carry no command/path/option at all in `What to do`. Baselined rather than hard-failed because 36 findings nobody can clear in the change that reveals them is the gate-that-lands-as-N-instant-blockers failure this repository has refused before \u2014 the same reasoning as ci-parity:local-only above. First measured at 34 rather than 36 because the two blockers on the branch that introduced this (`ac3-false-positive-reading`, `publish-side-marker-invariant`) were rewritten to the new standard and then closed in the same change; a baseline above the truth silently permits new violations. Re-measured at 38 when the branch was re-pointed at current main, and the +4 is population growth rather than a loosening: main gained the four `road-to-inbox-harvest-2026-08-d-*` roadmaps (context-ledger, runtime-skill-routing, scheduled-deprecation, top-band-model-economy), each carrying one open blocker authored before this requirement existed. That is the honest number for the population this gate now scans \u2014 recording 34 against a 38-entry tree would have failed the gate on its own introducing commit and taught the next reader to distrust it. Lowering happens one blocker at a time, and every roadmap touched for other reasons is a chance to lower it. Lowered 38\u219237 by the scheduled-deprecation PR, which is exactly that shape: code-graph-removal-authorisation was rewritten to the new standard because the roadmap was being touched anyway. Its `If you do nothing:` was one of the few that was not the common no-cost answer \u2014 the release gate that PR ships would have refused the next major cut while the blocker stayed open. Recorded in the past tense because the maintainer then RESOLVED that blocker on the trunk by withdrawing the commitment, so nothing refuses a cut today. The lowering stands on the rewrite, not on the consequence, and the sentence is corrected rather than deleted because a baseline note arguing from a retracted state is how a ratchet's rationale rots. The 56-day expiry is the point, not a hazard: if this number has not moved in two months, the fields are not being written and the gate should fail until someone decides whether the requirement is real. Lowered 37\u219234 when the scheduled-deprecation branch merged current main: three blockers were resolved or rewritten on the trunk in the meantime, so the drop is a genuine drain plus a merge, not a loosening. Re-tightened here rather than left loose because a ratchet that lags its own tree permits violations back in silently. Lowered 34\u219229 on 2026-08-16 by rewriting six entries to the new standard (raw-capture-needs-host-env, telemetry-sample-size, repo-admin-and-usage, benchmark-spend, measurement-a-no-per-arm-builder-tier, measurement-b-no-renderable-lane-pair) in a PR whose only purpose was the drain \u2014 the first lowering not taken on the back of another change, which the note above says is the usual shape. Two findings from that pass are worth keeping. The tree measured 35 against a baseline of 34 BEFORE the drain, i.e. the ratchet was already red on main and nobody knew: this gate runs in `task ci`, no workflow invokes `task ci`, and the local run that would have shown it was read through a `tail`, which hid every row above the last six. And four of the six `If you do nothing:` answers are honestly that nothing degrades \u2014 that is the true answer for a held measurement, and writing it is what makes the entry decidable, so the field earns its place by being cheap to answer truthfully rather than by always carrying a cost. Lowered 29 \u2192 27 on 2026-08-16 by the merge of this branch and the trunk drain above, and the arithmetic matters more than the delta: both sides rewrote entries from the same tree of 35 independently \u2014 the trunk six (recorded above), this branch two (deferred-finding-decision-reopen, spent-inbox-artifacts-await-deletion, rewritten because road-to-inbox-harvest-residuals was being touched anyway). The sets are disjoint, so the merged tree measures 27 and the gate itself reported the slack. Tightened rather than banked: 29 against a 27-entry tree would absorb the next two undecidable blockers without anything noticing, which is the lag this note has now corrected twice. Lowered 27 \u2192 26 on 2026-08-16 by rewriting `picktier-wire-or-archive` (road-to-inbox-harvest-2026-08-d-top-band-model-economy), and this one is the usual shape the note describes rather than the dedicated-drain shape: the roadmap was being worked for its own Step 4.1 and the entry was rewritten because it was open on the desk. Worth recording for what writing the two fields SURFACED, which is the argument for the requirement: `Recommendation:` forced the question 'which option, and why' and the honest answer turned out not to be one of the three options at all \u2014 the entry defers to a converged council verdict, and the council cannot reach quorum (re-measured 0 of 2 the same day), so the actionable next step is a one-line fix to a user-global config file outside this repository. Five fields had described that situation accurately for two weeks without anyone noticing that the named blocker was infrastructure rather than judgement. Lowered 26 \u2192 22 on 2026-08-18 by road-to-estate-drawdown Step 0.1, which needed the two fields for a different reason and therefore drained six entries as a by-product: the consolidated decision sheet renders a DEFAULT plus that default's provenance per user-owned decision, and 7 of the 21 live entries recorded no `Recommendation:` to derive one from. Six were rewritten to the new standard (skill-activation-window, b-convergence-machine, maintainer-blind-ratings, real-orchestration-usage, human-gated-live-trigger-eval, manual-rubric-rater), each marked `agent-drafted` in the field itself so the sheet can label the provenance rather than presenting a drafted default beside a maintainer-recorded one as the same kind of statement. The seventh, `road-to-gated-reach-followup`'s legacy `> Blocked until \u2026` note, is NOT counted here and was not rewritten: it is a blocked-until note rather than a `### blocker:` entry, so it has no field to carry, and converting it is a roadmap restructure this change did not take. **The tree was RED at 28 against this baseline of 26 before the drain, and again nobody knew** \u2014 the same failure the 34\u219229 paragraph above records, one gate cycle later: two entries had been added on the trunk without the fields, and this gate runs in `task ci`, which no workflow invokes. That is the second recorded instance of this ratchet being red on main undetected, which is an argument about where it runs rather than about its number. `human-gated-live-trigger-eval` also gained a command in `What to do:` (`rule_trigger_eval`, verified to exist at src/scripts/) because the field carried a path-less instruction; the other five needed only the two decidability fields. Lowered 22 -> 20 on 2026-08-19 by road-to-estate-drawdown Phase 2 triage batch 1, and RE-MEASURED after two merges of origin/main rather than carried over: the trunk gained roadmaps in between (the long-horizon pair and the council-fallback set), and the live count over the merged tree is still 20 across 39 roadmaps. Six roadmaps moved to later/, and two of them carried an undecidable open blocker each. The gain is a side effect of parking rather than of drafting a recommendation, so it is recorded as such \u2014 the two entries are unchanged and still undecidable where they sit; they are simply outside the active tree this ratchet scans. Walked down because the gate reported itself loose, and a baseline above the measurement is headroom a later change can spend with nothing objecting. Lowered 20 -> 17 on 2026-08-20 by the road-to-frontend-skill-application closeout, and the shape is the usual one this note describes: the roadmap was being closed for its own reasons and its three open blockers were on the desk anyway. Two (ui-corpus-has-no-ui, enforcement-evidence) left the population by being RESOLVED rather than rewritten, which is the cleanest way to lower this number and the only one that does not add prose; the third (ui-session-capture-window) was rewritten to the new standard. Worth recording what writing the two fields surfaced, since that is the standing argument for the requirement: on ui-corpus-has-no-ui, `Recommendation:` forced the question \"which option, and why\" and the honest answer was that the entry's own premise was false \u2014 it asserted the question could not be answered without a human naming a consumer store, and the stores were already on the machine, readable by the command the entry itself printed. Five fields had described that situation accurately for a week without anyone noticing the blocker was a measurement nobody had run. Tightened rather than banked because 20 against a 17-entry tree is headroom the next three undecidable blockers would spend with nothing objecting, which is the lag the paragraphs above have now corrected three times. Walked 17 -> 12 at the drain/road-to-frontend-skill-application merge, 2026-08-21, on the gate's own loose-ratchet report. Re-measured against the merged tree rather than attributed: sibling drain PRs made entries decidable in parallel, so this branch's share is not separable here and is not claimed. Banked at the measurement rather than left as headroom a later change could spend.\n\nWALKED 12 -> 1 on 2026-08-22 by resolving the two `road-to-evidence-based-adr-governance` blockers (`owner-autonomy-batch`, `authority-coupling-decision`), which were undecidable in exactly the way this ratchet names: each handed a Hard-Floor question to the reader without a landed outcome. Both now carry one. The single remaining violation is `road-to-drain-commands:395` (`merge-authority`), which PR #1517 resolves and archives \u2014 so the honest count for THIS tree is 1 and it is expected to reach 0 once that lands. It is not lowered to 0 here, because a baseline must describe the tree it ships with rather than the tree someone expects next. Lowered 1 -> 0 on 2026-08-22, and the prediction the previous entry made is what closed it: the single remaining violation was `road-to-drain-commands:395` (`merge-authority`), and PR #1517 archived that roadmap, taking the entry out of the scanned population. Nothing was rewritten to reach zero -- the record left the active tree with its blocker RESOLVED, which is the cleanest of the two ways this number goes down and the only one that adds no prose. Zero is now the ceiling: any new open blocker missing `Recommendation:`, `If you do nothing:` or an actionable `What to do:` reds this gate immediately, with no headroom at all.",
|
|
75
|
+
"falsifier": "./scripts-run src/scripts/lint_roadmap_blockers --quiet",
|
|
76
|
+
"retired_on": "2026-08-22",
|
|
77
|
+
"retired_because": "Walked to 0 and therefore removed from `gates`: an entry recording no debt is what gate_baseline.test.ts refuses, and a missing entry is not weaker \u2014 evaluateGate treats an absent baseline as ok only when the live count is 0, which is the same ceiling the note below asked for. Kept here because the note is dated history, not commentary; nothing reads this key at runtime."
|
|
75
78
|
}
|
|
79
|
+
}
|
|
76
80
|
}
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"p50_ci": null,
|
|
52
52
|
"observe_only_decision": "b-per-turn-composite-bar option (b) — council 2026-08-20, 2/2 quorum, both seats convergent: \"mark (pre + post) x 10 + ups + stop observe-only for one release, then derive an absolute ceiling and a pathology net from that distribution.\" Option (a), adopting the source draft's p50 <= 1.5 s, was refused because no run in this tree produced that number and an invented bar on a summed metric is the flappiest gate available. Option (c), declining the composite, was refused because it leaves D-1 permanently unmeasurable, which is the defect itself.",
|
|
53
53
|
"observe_only_since_version": "14.6.0",
|
|
54
|
+
"observe_only_extended": "EXTENDED 2026-08-23 - b-composite-ceiling-value option (c), AI council 2026-08-23, 2/2 quorum (anthropic/claude-sonnet-4-5 + openai/codex-default), convergent across two passes. Option (b) (a p50-derived cap plus a separate pathology threshold) was chosen first and then found NOT EXECUTABLE: its own Resolved-when requires the row to carry \"the number with the n and session count it was derived from\", and check_composite_arming reports n = 0 - no store at agents/evidence/hook-composite-readings.jsonl at all. Arming from local bench runs was considered and refused: the predicate would have accepted them, because composeReadingRecord gives each local invocation its own session id by design, but every local session is ONE machine and that is exactly the under-sampling MIN_SESSIONS = 2 was written to exclude. Satisfying a counter while defeating its purpose is the silent-green the arming procedure exists to prevent. So p50_ci stays null and observe_only stays true. REOPENS when check_composite_arming reports armable (>= 10 readings from >= 2 distinct CI runner sessions), at which point the blocker is answered again with a number in hand. Nothing about arming_procedure, arming_precondition or the 2026-08-20 decision is weakened here - only the date at which a number is chosen moves.",
|
|
54
55
|
"arming_procedure": "1. Collect the printed composite from every CI gate run across one release cycle — the bench prints it on every run, gated or not. 2. Set p50_ci to an ABSOLUTE cap derived from that distribution, never a creep window: shared CI runners flap, which is why regression_gate.max_regression_pct is already 200. 3. Keep the pathology net separate from the cap, so one spike is caught as a pathology rather than by lowering the cap. 4. Set observe_only to false — no code change is needed to arm it.",
|
|
55
56
|
"arming_precondition": "At least 10 CI gate readings of the composite, from at least 2 distinct runner sessions. Below that the estimator cannot separate code cost from runner load: the transport-isolation cell added for b-payload-read-parse-dominates read 44-157% at n=12 and 69-74% at n=50 on ONE machine, and a bar set from single-digit readings would carry that same instability.",
|
|
56
57
|
"_arming_precondition_honesty": "The 10-readings / 2-sessions floor is a STATED MINIMUM, not a derived one — it is the point below which the n=12 instability above was directly observed on a sibling metric in this same roadmap. Revisit-if: a release cycle produces the readings and their spread demands a wider floor, or the composite turns out to be dominated by one slot, in which case that slot's own cap is the better gate and this row stays observe-only permanently with that recorded.",
|