@event4u/agent-config 9.20.0 → 9.21.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/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +51 -0
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/cli-delegate/{chunk-XGA2NTU4.js → chunk-3EWYC3YK.js} +40 -0
- package/dist/cli-delegate/cmd_handoff.js +1 -1
- package/dist/cli-delegate/cmd_memory_get.js +1 -1
- package/dist/cli-delegate/cmd_route_audit.js +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +1 -1
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +1 -1
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +1 -1
- package/dist/hooks/dispatch.js +58 -2
- package/dist/mcp/registry-manifest.json +2 -2
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +47 -29
- package/package.json +1 -1
- package/src/config/gate-coverage.yml +22 -4
- package/src/config/gate-violation-baselines.json +3 -8
- package/src/scripts/_lib/gate_population.ts +70 -0
- package/src/scripts/_lib/roadmap_granularity.ts +157 -0
- package/src/scripts/_lib/scan_scope.ts +44 -0
- package/src/scripts/_lib/stdin.ts +82 -0
- package/src/scripts/audit_adr_coverage.ts +38 -0
- package/src/scripts/audit_auto_rules.ts +17 -3
- package/src/scripts/audit_command_surface.ts +51 -0
- package/src/scripts/audit_initial_context.ts +39 -3
- package/src/scripts/audit_mcp_tools.ts +25 -0
- package/src/scripts/audit_overlap.ts +24 -1
- package/src/scripts/audit_skill_descriptions.ts +19 -0
- package/src/scripts/{verify_before_complete_hook.ts → before_complete_hook.ts} +16 -3
- package/src/scripts/check_adr_frontmatter.ts +23 -3
- package/src/scripts/check_always_budget.ts +24 -0
- package/src/scripts/check_artefact_checksums.ts +24 -1
- package/src/scripts/check_artefact_count_messaging.ts +20 -0
- package/src/scripts/check_augmentignore.ts +22 -15
- package/src/scripts/check_backstop_debt.ts +22 -0
- package/src/scripts/check_beta_review_markers.ts +22 -1
- package/src/scripts/check_bridge_derivation.ts +22 -1
- package/src/scripts/check_bundle_path_leakage.ts +26 -0
- package/src/scripts/check_ci_strict_superset.ts +21 -3
- package/src/scripts/check_claims.ts +22 -0
- package/src/scripts/check_cli_registry_budget_sync.ts +33 -4
- package/src/scripts/check_cluster_patterns.ts +26 -4
- package/src/scripts/check_command_count_messaging.ts +20 -4
- package/src/scripts/check_comparison.ts +18 -0
- package/src/scripts/check_condensed_paths.ts +23 -2
- package/src/scripts/check_consumer_scope_flip.ts +21 -2
- package/src/scripts/check_council_config_location.ts +20 -0
- package/src/scripts/check_council_layout.ts +22 -2
- package/src/scripts/check_council_references.ts +23 -1
- package/src/scripts/check_dependency_floors.ts +19 -3
- package/src/scripts/check_discovery_determinism.ts +26 -0
- package/src/scripts/check_enforcement_coverage.ts +20 -0
- package/src/scripts/check_evaluator_budgets.ts +23 -0
- package/src/scripts/check_finding_dispositions.ts +29 -0
- package/src/scripts/check_gate_coverage.ts +63 -22
- package/src/scripts/check_gate_paths.ts +30 -5
- package/src/scripts/check_generated_artefact_headers.ts +21 -0
- package/src/scripts/check_generator_output_coverage.ts +23 -0
- package/src/scripts/check_gitignore_freshness.ts +23 -0
- package/src/scripts/check_host_loadability.ts +34 -8
- package/src/scripts/check_installer_import_purity.ts +22 -8
- package/src/scripts/check_kernel_prefix_stability.ts +19 -1
- package/src/scripts/check_kernel_rule_bundle.ts +23 -0
- package/src/scripts/check_knowledge_cards.ts +13 -0
- package/src/scripts/check_knowledge_pages.ts +23 -0
- package/src/scripts/check_knowledge_sharing.ts +27 -0
- package/src/scripts/check_md_language.ts +24 -0
- package/src/scripts/check_media_deps.ts +23 -0
- package/src/scripts/check_memory.ts +26 -1
- package/src/scripts/check_memory_contradiction.ts +16 -1
- package/src/scripts/check_memory_proposal.ts +15 -0
- package/src/scripts/check_memory_similarity.ts +16 -0
- package/src/scripts/check_module_management_neutral.ts +19 -11
- package/src/scripts/check_no_conflict_markers.ts +22 -1
- package/src/scripts/check_no_external_sources.ts +26 -1
- package/src/scripts/check_no_local_settings_committed.ts +37 -10
- package/src/scripts/check_no_new_legacy_path.ts +30 -1
- package/src/scripts/check_one_off_location.ts +43 -0
- package/src/scripts/check_originality_freshness.ts +25 -1
- package/src/scripts/check_overlay_cascade_subdirs.ts +21 -0
- package/src/scripts/check_pack_size.ts +22 -0
- package/src/scripts/check_preamble_payload_budget.ts +35 -5
- package/src/scripts/check_proposal.ts +24 -1
- package/src/scripts/check_public_catalog_links.ts +27 -0
- package/src/scripts/check_public_links.ts +19 -0
- package/src/scripts/check_quality_regression.ts +19 -0
- package/src/scripts/check_reach_channels.ts +44 -0
- package/src/scripts/check_reach_staleness.ts +27 -0
- package/src/scripts/check_release_adjacent_health.ts +28 -0
- package/src/scripts/check_release_highlights.ts +34 -0
- package/src/scripts/check_release_includes_discovery.ts +25 -6
- package/src/scripts/check_release_pr_shape.ts +18 -1
- package/src/scripts/check_release_published.ts +21 -0
- package/src/scripts/check_release_surface_equality.ts +22 -0
- package/src/scripts/check_release_trunk_sync.ts +19 -0
- package/src/scripts/check_reply_consistency.ts +22 -0
- package/src/scripts/check_roadmap_trackable.ts +20 -0
- package/src/scripts/check_role_doc_links.ts +23 -0
- package/src/scripts/check_rule_invariants.ts +14 -0
- package/src/scripts/check_secret_leak.ts +47 -0
- package/src/scripts/check_skill_gaps.ts +32 -0
- package/src/scripts/check_skill_requires.ts +19 -0
- package/src/scripts/check_source_pointer_freshness.ts +20 -0
- package/src/scripts/check_structural_breaking.ts +29 -2
- package/src/scripts/check_surface_tiers.ts +34 -0
- package/src/scripts/check_template_pin_drift.ts +23 -1
- package/src/scripts/check_test_coverage_diff.ts +17 -1
- package/src/scripts/check_token_optimizer_freshness.ts +18 -3
- package/src/scripts/check_token_quality_golden.ts +21 -0
- package/src/scripts/check_token_regression.ts +25 -0
- package/src/scripts/check_tracked_but_ignored.ts +26 -0
- package/src/scripts/check_trigger_eval_presence.ts +23 -1
- package/src/scripts/check_trigger_evals.ts +36 -0
- package/src/scripts/check_trunk_drift.ts +23 -0
- package/src/scripts/check_update_banner.ts +24 -0
- package/src/scripts/gate_scope_classify.ts +513 -0
- package/src/scripts/hook_manifest.yaml +1 -1
- package/src/scripts/hooks/block_kernel_rule_writes.ts +1 -1
- package/src/scripts/hooks/concern_registry.ts +2 -2
- package/src/scripts/lint_agent_security.ts +19 -0
- package/src/scripts/lint_agent_skill_names.ts +30 -0
- package/src/scripts/lint_agents_layout.ts +20 -0
- package/src/scripts/lint_agents_md.ts +20 -0
- package/src/scripts/lint_archived_skills.ts +24 -3
- package/src/scripts/lint_behavioural_eval_freshness.ts +29 -3
- package/src/scripts/lint_bench_ab.ts +25 -0
- package/src/scripts/lint_bench_corpus.ts +20 -4
- package/src/scripts/lint_breaking_changes_index.ts +24 -0
- package/src/scripts/lint_budget_ownership.ts +20 -3
- package/src/scripts/lint_changelog_rollback.ts +24 -0
- package/src/scripts/lint_command_flow_coverage.ts +22 -0
- package/src/scripts/lint_command_tiers.ts +29 -5
- package/src/scripts/lint_commit_subjects.ts +15 -0
- package/src/scripts/lint_confusables.ts +24 -0
- package/src/scripts/lint_consumer_internal_refs.ts +24 -0
- package/src/scripts/lint_design_quality.ts +22 -0
- package/src/scripts/lint_design_slop.ts +23 -0
- package/src/scripts/lint_discovery_manifest.ts +23 -0
- package/src/scripts/lint_discovery_vocabulary.ts +19 -0
- package/src/scripts/lint_documented_commands.ts +23 -0
- package/src/scripts/lint_empty_roadmaps.ts +23 -0
- package/src/scripts/lint_eval_fixture_citations.ts +19 -0
- package/src/scripts/lint_eval_freshness.ts +35 -0
- package/src/scripts/lint_examples.ts +18 -3
- package/src/scripts/lint_explain_trace.ts +23 -0
- package/src/scripts/lint_featured_skills.ts +26 -1
- package/src/scripts/lint_flows.ts +19 -0
- package/src/scripts/lint_frontmatter_boilerplate.ts +20 -0
- package/src/scripts/lint_ghostwriter_source.ts +26 -6
- package/src/scripts/lint_glama_drift.ts +24 -0
- package/src/scripts/lint_global_paths.ts +24 -0
- package/src/scripts/lint_governed_writes.ts +20 -0
- package/src/scripts/lint_hidden_unicode.ts +25 -0
- package/src/scripts/lint_hook_concern_budget.ts +39 -6
- package/src/scripts/lint_hook_manifest.ts +22 -0
- package/src/scripts/lint_instruction_smuggling.ts +23 -0
- package/src/scripts/lint_knowledge_scale.ts +32 -2
- package/src/scripts/lint_legal_pack.ts +31 -0
- package/src/scripts/lint_marketplace.ts +26 -0
- package/src/scripts/lint_marketplace_install_completeness.ts +23 -0
- package/src/scripts/lint_mcp_config_security.ts +24 -0
- package/src/scripts/lint_mcp_registry_manifest.ts +22 -1
- package/src/scripts/lint_memory_tripwire.ts +35 -0
- package/src/scripts/lint_missions.ts +23 -7
- package/src/scripts/lint_model_tier_coverage.ts +18 -0
- package/src/scripts/lint_namespace_collisions.ts +19 -0
- package/src/scripts/lint_no_new_atomic_commands.ts +33 -0
- package/src/scripts/lint_no_python_twin_rationale.ts +18 -0
- package/src/scripts/lint_one_off_age.ts +38 -2
- package/src/scripts/lint_orchestration_dsl.ts +23 -3
- package/src/scripts/lint_orchestrator_auto_detect.ts +19 -12
- package/src/scripts/lint_originality.ts +22 -4
- package/src/scripts/lint_originality_shingles.ts +28 -3
- package/src/scripts/lint_output_slop.ts +19 -0
- package/src/scripts/lint_override_kernel_guard.ts +30 -0
- package/src/scripts/lint_pack_first_win.ts +23 -0
- package/src/scripts/lint_pack_risk_class.ts +19 -3
- package/src/scripts/lint_persistence.ts +19 -0
- package/src/scripts/lint_persona_governance.ts +18 -3
- package/src/scripts/lint_positioning.ts +23 -0
- package/src/scripts/lint_pre_migration_refs.ts +24 -0
- package/src/scripts/lint_profile_overlay_set_only.ts +24 -0
- package/src/scripts/lint_provenance.ts +21 -0
- package/src/scripts/lint_provenance_vocabulary.ts +24 -1
- package/src/scripts/lint_readme_jargon.ts +21 -3
- package/src/scripts/lint_readme_serial_comma.ts +21 -3
- package/src/scripts/lint_readme_size.ts +21 -3
- package/src/scripts/lint_regression.ts +28 -0
- package/src/scripts/lint_roadmap_blockers.ts +43 -0
- package/src/scripts/lint_roadmap_ci_steps.ts +45 -0
- package/src/scripts/lint_roadmap_complexity.ts +47 -0
- package/src/scripts/lint_roadmap_later_disposition.ts +23 -0
- package/src/scripts/lint_rule_interactions.ts +16 -2
- package/src/scripts/lint_rule_tiers.ts +19 -6
- package/src/scripts/lint_showcase_sessions.ts +19 -3
- package/src/scripts/lint_skill_descriptions.ts +19 -0
- package/src/scripts/lint_skill_frontmatter_safety.ts +24 -0
- package/src/scripts/lint_skill_originality.ts +18 -3
- package/src/scripts/lint_skill_scripts_readonly.ts +20 -0
- package/src/scripts/lint_skill_tools.ts +84 -145
- package/src/scripts/lint_spawn_payload.ts +27 -1
- package/src/scripts/lint_store_boundary.ts +19 -0
- package/src/scripts/lint_subagent_determinism.ts +23 -1
- package/src/scripts/lint_supported_tools_matrix.ts +18 -0
- package/src/scripts/lint_surface_matrix.ts +19 -3
- package/src/scripts/lint_ticket_buildable.ts +23 -0
- package/src/scripts/lint_topics_yaml.ts +19 -12
- package/src/scripts/lint_trigger_precision.ts +27 -0
- package/src/scripts/lint_trust_coherence.ts +21 -0
- package/src/scripts/lint_ui_stack_bundles.ts +17 -3
- package/src/scripts/lint_value_dashboard.ts +19 -3
- package/src/scripts/lint_versioned_cache.ts +19 -1
- package/src/scripts/lint_workflow_security.ts +22 -14
- package/src/scripts/pr_url_reminder_hook.ts +1 -1
- package/src/scripts/skill_collision_clusters.ts +37 -3
- package/src/scripts/skill_discovery.ts +20 -0
- package/src/scripts/skill_eval_coverage.ts +22 -0
- package/src/scripts/skill_overlap.ts +32 -6
- package/src/scripts/skill_preview.ts +31 -0
- package/src/scripts/skill_trigger_eval.ts +18 -0
- package/src/scripts/skill_usage_collect.ts +21 -0
- package/src/scripts/skill_usage_report.ts +21 -0
- package/src/scripts/sweep_dead_scan_roots.ts +11 -3
- package/src/scripts/verify_physical_move.ts +24 -0
- package/src/scripts/check_bite_sized_granularity.ts +0 -116
- package/src/scripts/lint_workspace_boundary.ts +0 -267
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Bootstrap shim for the event4u agent-config suite. This plugin ships ONLY the dispatcher hooks plus one install-pointer skill — ALL content (skills, rules, commands) is installed via `npx -y @event4u/agent-config init`, which writes the file projection AND registers the same hooks in ~/.claude/settings.json. DEPRECATED as a content channel; kept so the marketplace listing stays discoverable and existing installs keep working hooks.",
|
|
9
|
-
"version": "9.
|
|
9
|
+
"version": "9.21.0",
|
|
10
10
|
"keywords": [
|
|
11
11
|
"agent-config",
|
|
12
12
|
"skills",
|
package/CHANGELOG.md
CHANGED
|
@@ -294,6 +294,57 @@ Entry-shape contract: [`docs/contracts/CHANGELOG-conventions.md`](docs/contracts
|
|
|
294
294
|
> that forces a new era split (`# Era: 9.19.x`, etc.) — see
|
|
295
295
|
> [`docs/contracts/CHANGELOG-conventions.md § Era splits`](docs/contracts/CHANGELOG-conventions.md).
|
|
296
296
|
|
|
297
|
+
## [9.21.0](https://github.com/event4u-app/agent-config/compare/9.20.0...9.21.0) (2026-08-05)
|
|
298
|
+
|
|
299
|
+
### Release highlights
|
|
300
|
+
|
|
301
|
+
<!-- Curated head: fill before merge, keep it under 10 lines, and leave `_none_` where it is genuinely the answer. The generated log below is unchanged. -->
|
|
302
|
+
- **Behaviour changes:** _none_
|
|
303
|
+
- **Default changes + migration:** _none_
|
|
304
|
+
- **Security and correctness:** _none_
|
|
305
|
+
- **Honest nulls:** _none_
|
|
306
|
+
- **Known limitations:** _none_
|
|
307
|
+
|
|
308
|
+
### Features
|
|
309
|
+
|
|
310
|
+
* **gates:** take the unhardened-gate count to 0 and delete the ratchet entry ([e31690c](https://github.com/event4u-app/agent-config/commit/e31690c7330bb90ed813cc25ead2268da2971ea1))
|
|
311
|
+
* **gates:** repoint lint_skill_tools at the .ts corpus and harden it ([694a729](https://github.com/event4u-app/agent-config/commit/694a729359e674953881a996af6079123e91a98d))
|
|
312
|
+
* **gates:** fold bite-sized granularity into lint_roadmap_complexity ([08d9075](https://github.com/event4u-app/agent-config/commit/08d9075c978a6a76a250a74fe6377ad3b2c2d8a2))
|
|
313
|
+
* **gates:** assert the scan scope of the last 57 gates — 61 → 4 ([5244b21](https://github.com/event4u-app/agent-config/commit/5244b21ea664db73a3a07c8ce717a2b43c4ba157))
|
|
314
|
+
* **gates:** assert the scan scope of 54 more gates — 115 → 61 ([835fd54](https://github.com/event4u-app/agent-config/commit/835fd545649287574c9d74e3280302ca429b8d20))
|
|
315
|
+
* **gates:** assert the scan scope of 48 tree-walking gates ([9cc51a2](https://github.com/event4u-app/agent-config/commit/9cc51a20c8d3d3c9f133d0bb8a94a322b90ee235))
|
|
316
|
+
* **gates:** assert the scan scope of 28 more corpus gates ([f4e79e4](https://github.com/event4u-app/agent-config/commit/f4e79e4a8f7c90e27353693f42d27c1a70bbdac4))
|
|
317
|
+
* **gates:** classify the corpusless gates by what they read ([c7a851b](https://github.com/event4u-app/agent-config/commit/c7a851becd7a77ff85c7c443c59ca45b91bc7ef3))
|
|
318
|
+
* **gates:** assert the scan scope of five corpus gates ([7433f72](https://github.com/event4u-app/agent-config/commit/7433f72482c639bf88d01e58e093d7c57a608960))
|
|
319
|
+
* **gates:** derive the conversion work-list instead of reading 189 gates ([b845e4d](https://github.com/event4u-app/agent-config/commit/b845e4df66e90b1d43a42f9fa55bb41457b4a1b5))
|
|
320
|
+
* **scan-scope:** pair the scope assertion with the published count ([b8b2840](https://github.com/event4u-app/agent-config/commit/b8b2840d17466f0be5047fbaa98ed67751a93a70))
|
|
321
|
+
|
|
322
|
+
### Bug Fixes
|
|
323
|
+
|
|
324
|
+
* **gates:** read piped stdin whole — a gate that only broke on big diffs ([0e3e9cd](https://github.com/event4u-app/agent-config/commit/0e3e9cd4ca91c01c00d8c611a96db72b936952d8))
|
|
325
|
+
* **gates:** clear the two preflight blockers the repairs introduced ([2683395](https://github.com/event4u-app/agent-config/commit/268339595ca2dd34b14a1a63abd6362fde7868fb))
|
|
326
|
+
* **gates:** repair two dead scan roots the widened population revealed ([5b41c55](https://github.com/event4u-app/agent-config/commit/5b41c556bc245c4eb9da7506b4de449a3cde07b0))
|
|
327
|
+
* **gates:** one definition of "a gate", and an honest denominator ([9f65efe](https://github.com/event4u-app/agent-config/commit/9f65efea7882d4c79f2e5f4c8fcefb0b521bcdde))
|
|
328
|
+
* **gate-coverage:** an unenforced `scanned:` line hardens nothing ([2873c91](https://github.com/event4u-app/agent-config/commit/2873c919d0245ca76a18f2315c768b9a9cb1e1ca))
|
|
329
|
+
|
|
330
|
+
### Documentation
|
|
331
|
+
|
|
332
|
+
* **roadmap:** close and archive road-to-gate-hardening-adoption ([d1497c5](https://github.com/event4u-app/agent-config/commit/d1497c5fc12f5475b683f27b42953cf2f448def8))
|
|
333
|
+
* **roadmap:** file the four-gate blocker where the dashboard reads it ([7e0c8e9](https://github.com/event4u-app/agent-config/commit/7e0c8e9e369c29a7574c99f1ec453835e1ae44e9))
|
|
334
|
+
* **roadmap:** close Phase 1 — the mechanically-safe conversions ([877859a](https://github.com/event4u-app/agent-config/commit/877859ac99e70a79630b201a025a474df156fe55))
|
|
335
|
+
* **roadmap:** record the assert-first conversion contract ([613d478](https://github.com/event4u-app/agent-config/commit/613d47878252edfe8c5d225d73c1bed3fe6fb753))
|
|
336
|
+
|
|
337
|
+
### Refactoring
|
|
338
|
+
|
|
339
|
+
* **gates:** re-home the ADR-095 workspace boundary to ESLint ([2bc2483](https://github.com/event4u-app/agent-config/commit/2bc24833149cff33573a84c9dfbc973b5b3b5fe3))
|
|
340
|
+
* **hooks:** rename verify_before_complete_hook off the gate prefix ([f57d969](https://github.com/event4u-app/agent-config/commit/f57d969c6c54e591060054f217a12d816d121116))
|
|
341
|
+
|
|
342
|
+
### Chores
|
|
343
|
+
|
|
344
|
+
* **tests:** drop a dead helper the lint scope only now reaches ([9b49d24](https://github.com/event4u-app/agent-config/commit/9b49d240140c9b6af28969c752f4757bf5580d98))
|
|
345
|
+
|
|
346
|
+
Tests: 11034 (+39 since 9.20.0)
|
|
347
|
+
|
|
297
348
|
## [9.20.0](https://github.com/event4u-app/agent-config/compare/9.19.0...9.20.0) (2026-08-04)
|
|
298
349
|
|
|
299
350
|
### Release highlights
|
|
@@ -39,7 +39,7 @@ schema_version: 1
|
|
|
39
39
|
# CI guard: a release bump of `package.json` must update this value
|
|
40
40
|
# in lockstep — see scripts/check_template_pin_drift.ts (road-to-
|
|
41
41
|
# portable-runtime-and-update-check P3.3).
|
|
42
|
-
agent_config_version: "9.
|
|
42
|
+
agent_config_version: "9.21.0"
|
|
43
43
|
|
|
44
44
|
# --- Project identity ---
|
|
45
45
|
project:
|
|
@@ -457,6 +457,29 @@ function _pyJsonScalarAscii(value) {
|
|
|
457
457
|
return _pyJsonScalar(value);
|
|
458
458
|
}
|
|
459
459
|
|
|
460
|
+
// src/scripts/_lib/scan_scope.ts
|
|
461
|
+
var DeadScopeError = class extends Error {
|
|
462
|
+
gate;
|
|
463
|
+
constructor(gate, message) {
|
|
464
|
+
super(message);
|
|
465
|
+
this.name = "DeadScopeError";
|
|
466
|
+
this.gate = gate;
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
function assertScanned(opts) {
|
|
470
|
+
if (opts.scanned > 0) {
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
if (opts.allowEmpty !== void 0 && opts.allowEmpty.trim() !== "") {
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
const roots = opts.roots.length > 0 ? opts.roots.join(", ") : "(no root declared)";
|
|
477
|
+
throw new DeadScopeError(
|
|
478
|
+
opts.gate,
|
|
479
|
+
`${opts.gate}: scanned 0 ${opts.units} under ${roots} \u2014 the scan scope is dead or the root moved. A gate that read nothing has not passed. Repoint the root (prefer the shared resolver in _lib/agent_src.ts), or declare a justified \`allowEmpty\` reason if an empty corpus is genuinely expected.`
|
|
480
|
+
);
|
|
481
|
+
}
|
|
482
|
+
|
|
460
483
|
// src/scripts/lint_hidden_unicode.ts
|
|
461
484
|
var CHECK = "hidden-unicode";
|
|
462
485
|
var _BIDI = /* @__PURE__ */ new Set([
|
|
@@ -872,7 +895,9 @@ function main(argv = null) {
|
|
|
872
895
|
const args = parse_args(argv ?? process.argv.slice(2));
|
|
873
896
|
const findings = [];
|
|
874
897
|
const flagged = /* @__PURE__ */ new Set();
|
|
898
|
+
let corpusFiles = 0;
|
|
875
899
|
for (const sf of iter_corpus()) {
|
|
900
|
+
corpusFiles += 1;
|
|
876
901
|
const hits = _scan(sf);
|
|
877
902
|
for (const h of hits) {
|
|
878
903
|
findings.push(h);
|
|
@@ -881,6 +906,21 @@ function main(argv = null) {
|
|
|
881
906
|
flagged.add(sf.path);
|
|
882
907
|
}
|
|
883
908
|
}
|
|
909
|
+
try {
|
|
910
|
+
assertScanned({
|
|
911
|
+
gate: "lint_hidden_unicode",
|
|
912
|
+
scanned: corpusFiles,
|
|
913
|
+
units: "corpus file(s)",
|
|
914
|
+
roots: DEFAULT_SCAN_ROOTS
|
|
915
|
+
});
|
|
916
|
+
} catch (exc) {
|
|
917
|
+
if (exc instanceof DeadScopeError) {
|
|
918
|
+
process.stderr.write(`\u274C ${exc.message}
|
|
919
|
+
`);
|
|
920
|
+
return 1;
|
|
921
|
+
}
|
|
922
|
+
throw exc;
|
|
923
|
+
}
|
|
884
924
|
const sourceFiles = _eligibleSourceFiles();
|
|
885
925
|
for (const h of _scanSourceControlBytes(sourceFiles)) {
|
|
886
926
|
findings.push(h);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
4
|
memory_get_v1
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-3EWYC3YK.js";
|
|
6
6
|
import "./chunk-OY53J6II.js";
|
|
7
7
|
import "./chunk-J55WI3RR.js";
|
|
8
8
|
|
|
@@ -14402,7 +14402,7 @@
|
|
|
14402
14402
|
"reason": "scaffold template for ticket-bundle tickets (ADR-101); carries no runtime frontmatter — emit-tickets fills it in per ticket"
|
|
14403
14403
|
}
|
|
14404
14404
|
],
|
|
14405
|
-
"generated_at": "2026-08-
|
|
14405
|
+
"generated_at": "2026-08-05T03:10:28Z",
|
|
14406
14406
|
"packs": [
|
|
14407
14407
|
{
|
|
14408
14408
|
"artefact_count": 117,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
4b795a51a6574b400b90053e476daf9aac787dd71aa03ca8be86ad3f2913ea3e discovery-manifest.json
|
package/dist/hooks/dispatch.js
CHANGED
|
@@ -8170,6 +8170,29 @@ function _pyJsonScalarAscii(value) {
|
|
|
8170
8170
|
return _pyJsonScalar(value);
|
|
8171
8171
|
}
|
|
8172
8172
|
|
|
8173
|
+
// src/scripts/_lib/scan_scope.ts
|
|
8174
|
+
var DeadScopeError = class extends Error {
|
|
8175
|
+
gate;
|
|
8176
|
+
constructor(gate, message) {
|
|
8177
|
+
super(message);
|
|
8178
|
+
this.name = "DeadScopeError";
|
|
8179
|
+
this.gate = gate;
|
|
8180
|
+
}
|
|
8181
|
+
};
|
|
8182
|
+
function assertScanned(opts) {
|
|
8183
|
+
if (opts.scanned > 0) {
|
|
8184
|
+
return;
|
|
8185
|
+
}
|
|
8186
|
+
if (opts.allowEmpty !== void 0 && opts.allowEmpty.trim() !== "") {
|
|
8187
|
+
return;
|
|
8188
|
+
}
|
|
8189
|
+
const roots = opts.roots.length > 0 ? opts.roots.join(", ") : "(no root declared)";
|
|
8190
|
+
throw new DeadScopeError(
|
|
8191
|
+
opts.gate,
|
|
8192
|
+
`${opts.gate}: scanned 0 ${opts.units} under ${roots} \u2014 the scan scope is dead or the root moved. A gate that read nothing has not passed. Repoint the root (prefer the shared resolver in _lib/agent_src.ts), or declare a justified \`allowEmpty\` reason if an empty corpus is genuinely expected.`
|
|
8193
|
+
);
|
|
8194
|
+
}
|
|
8195
|
+
|
|
8173
8196
|
// src/scripts/lint_hidden_unicode.ts
|
|
8174
8197
|
var CHECK = "hidden-unicode";
|
|
8175
8198
|
var _BIDI = /* @__PURE__ */ new Set([
|
|
@@ -8585,7 +8608,9 @@ function main(argv = null) {
|
|
|
8585
8608
|
const args = parse_args(argv ?? process.argv.slice(2));
|
|
8586
8609
|
const findings = [];
|
|
8587
8610
|
const flagged = /* @__PURE__ */ new Set();
|
|
8611
|
+
let corpusFiles = 0;
|
|
8588
8612
|
for (const sf of iter_corpus()) {
|
|
8613
|
+
corpusFiles += 1;
|
|
8589
8614
|
const hits = _scan(sf);
|
|
8590
8615
|
for (const h of hits) {
|
|
8591
8616
|
findings.push(h);
|
|
@@ -8594,6 +8619,21 @@ function main(argv = null) {
|
|
|
8594
8619
|
flagged.add(sf.path);
|
|
8595
8620
|
}
|
|
8596
8621
|
}
|
|
8622
|
+
try {
|
|
8623
|
+
assertScanned({
|
|
8624
|
+
gate: "lint_hidden_unicode",
|
|
8625
|
+
scanned: corpusFiles,
|
|
8626
|
+
units: "corpus file(s)",
|
|
8627
|
+
roots: DEFAULT_SCAN_ROOTS
|
|
8628
|
+
});
|
|
8629
|
+
} catch (exc) {
|
|
8630
|
+
if (exc instanceof DeadScopeError) {
|
|
8631
|
+
process.stderr.write(`\u274C ${exc.message}
|
|
8632
|
+
`);
|
|
8633
|
+
return 1;
|
|
8634
|
+
}
|
|
8635
|
+
throw exc;
|
|
8636
|
+
}
|
|
8597
8637
|
const sourceFiles = _eligibleSourceFiles();
|
|
8598
8638
|
for (const h of _scanSourceControlBytes(sourceFiles)) {
|
|
8599
8639
|
findings.push(h);
|
|
@@ -14983,7 +15023,7 @@ if (isCliEntry3) {
|
|
|
14983
15023
|
process.exit(main11(process.argv.slice(2)));
|
|
14984
15024
|
}
|
|
14985
15025
|
|
|
14986
|
-
// src/scripts/
|
|
15026
|
+
// src/scripts/before_complete_hook.ts
|
|
14987
15027
|
import fs19 from "node:fs";
|
|
14988
15028
|
import path18 from "node:path";
|
|
14989
15029
|
import { fileURLToPath as fileURLToPath13, pathToFileURL as pathToFileURL9 } from "node:url";
|
|
@@ -19005,6 +19045,22 @@ function main27() {
|
|
|
19005
19045
|
for (const f of walkDir(scanDir, /\.(html|htm|css|scss|sass|less|vue|svelte|astro|jsx|tsx|md|mdx)$/i)) {
|
|
19006
19046
|
if (!ignoreGlobs.some((g) => f.includes(g.replace("**", "")))) files.push(f);
|
|
19007
19047
|
}
|
|
19048
|
+
try {
|
|
19049
|
+
assertScanned({
|
|
19050
|
+
gate: "lint_design_slop",
|
|
19051
|
+
scanned: files.length,
|
|
19052
|
+
units: "design source file(s)",
|
|
19053
|
+
// Absolute: --dir may point outside the cwd (or outside any repo).
|
|
19054
|
+
roots: [scanDir]
|
|
19055
|
+
});
|
|
19056
|
+
} catch (exc) {
|
|
19057
|
+
if (exc instanceof DeadScopeError) {
|
|
19058
|
+
process.stderr.write(`\u274C ${exc.message}
|
|
19059
|
+
`);
|
|
19060
|
+
process.exit(1);
|
|
19061
|
+
}
|
|
19062
|
+
throw exc;
|
|
19063
|
+
}
|
|
19008
19064
|
const findings = [];
|
|
19009
19065
|
for (const fp of files) {
|
|
19010
19066
|
const rel = path37.relative(process.cwd(), fp);
|
|
@@ -19461,7 +19517,7 @@ var CONCERN_REGISTRY = {
|
|
|
19461
19517
|
"src/scripts/roadmap_progress_hook.ts": main9,
|
|
19462
19518
|
"src/scripts/onboarding_gate_hook.ts": main10,
|
|
19463
19519
|
"src/scripts/context_hygiene_hook.ts": main11,
|
|
19464
|
-
"src/scripts/
|
|
19520
|
+
"src/scripts/before_complete_hook.ts": main12,
|
|
19465
19521
|
"src/scripts/minimal_safe_diff_hook.ts": main13,
|
|
19466
19522
|
"src/scripts/injection_scan_hook.ts": main14,
|
|
19467
19523
|
"src/scripts/memory_learn_hook.ts": main15,
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
"artefact_count": 594,
|
|
4
4
|
"scanner_version": "c24312e116f8"
|
|
5
5
|
},
|
|
6
|
-
"generated_at": "2026-08-
|
|
6
|
+
"generated_at": "2026-08-05",
|
|
7
7
|
"package": {
|
|
8
8
|
"description": "Governed skills, rules and commands for AI coding tools (Claude Code, Cursor, Windsurf, Copilot) \u2014 every claim machine-checked, including \"zero runtime daemon\".",
|
|
9
9
|
"homepage": "https://event4u-app.github.io/agent-config",
|
|
10
10
|
"name": "@event4u/agent-config",
|
|
11
11
|
"repository": "https://github.com/event4u-app/agent-config",
|
|
12
|
-
"version": "9.
|
|
12
|
+
"version": "9.21.0"
|
|
13
13
|
},
|
|
14
14
|
"registries": [
|
|
15
15
|
{
|
package/dist/mcp/server.json
CHANGED
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
"transport": {
|
|
10
10
|
"type": "stdio"
|
|
11
11
|
},
|
|
12
|
-
"version": "9.
|
|
12
|
+
"version": "9.21.0"
|
|
13
13
|
}
|
|
14
14
|
],
|
|
15
15
|
"repository": {
|
|
16
16
|
"source": "github",
|
|
17
17
|
"url": "https://github.com/event4u-app/agent-config"
|
|
18
18
|
},
|
|
19
|
-
"version": "9.
|
|
19
|
+
"version": "9.21.0"
|
|
20
20
|
}
|
package/dist/mcp/server.mjs
CHANGED
|
@@ -9362,6 +9362,35 @@ var init_security_lint = __esm({
|
|
|
9362
9362
|
}
|
|
9363
9363
|
});
|
|
9364
9364
|
|
|
9365
|
+
// src/scripts/_lib/scan_scope.ts
|
|
9366
|
+
function assertScanned(opts) {
|
|
9367
|
+
if (opts.scanned > 0) {
|
|
9368
|
+
return;
|
|
9369
|
+
}
|
|
9370
|
+
if (opts.allowEmpty !== void 0 && opts.allowEmpty.trim() !== "") {
|
|
9371
|
+
return;
|
|
9372
|
+
}
|
|
9373
|
+
const roots = opts.roots.length > 0 ? opts.roots.join(", ") : "(no root declared)";
|
|
9374
|
+
throw new DeadScopeError(
|
|
9375
|
+
opts.gate,
|
|
9376
|
+
`${opts.gate}: scanned 0 ${opts.units} under ${roots} \u2014 the scan scope is dead or the root moved. A gate that read nothing has not passed. Repoint the root (prefer the shared resolver in _lib/agent_src.ts), or declare a justified \`allowEmpty\` reason if an empty corpus is genuinely expected.`
|
|
9377
|
+
);
|
|
9378
|
+
}
|
|
9379
|
+
var DeadScopeError;
|
|
9380
|
+
var init_scan_scope = __esm({
|
|
9381
|
+
"src/scripts/_lib/scan_scope.ts"() {
|
|
9382
|
+
"use strict";
|
|
9383
|
+
DeadScopeError = class extends Error {
|
|
9384
|
+
gate;
|
|
9385
|
+
constructor(gate, message) {
|
|
9386
|
+
super(message);
|
|
9387
|
+
this.name = "DeadScopeError";
|
|
9388
|
+
this.gate = gate;
|
|
9389
|
+
}
|
|
9390
|
+
};
|
|
9391
|
+
}
|
|
9392
|
+
});
|
|
9393
|
+
|
|
9365
9394
|
// src/scripts/lint_hidden_unicode.ts
|
|
9366
9395
|
import * as fs7 from "node:fs";
|
|
9367
9396
|
import * as path7 from "node:path";
|
|
@@ -9549,7 +9578,9 @@ function main(argv = null) {
|
|
|
9549
9578
|
const args = parse_args(argv ?? process.argv.slice(2));
|
|
9550
9579
|
const findings = [];
|
|
9551
9580
|
const flagged = /* @__PURE__ */ new Set();
|
|
9581
|
+
let corpusFiles = 0;
|
|
9552
9582
|
for (const sf of iter_corpus()) {
|
|
9583
|
+
corpusFiles += 1;
|
|
9553
9584
|
const hits = _scan(sf);
|
|
9554
9585
|
for (const h of hits) {
|
|
9555
9586
|
findings.push(h);
|
|
@@ -9558,6 +9589,21 @@ function main(argv = null) {
|
|
|
9558
9589
|
flagged.add(sf.path);
|
|
9559
9590
|
}
|
|
9560
9591
|
}
|
|
9592
|
+
try {
|
|
9593
|
+
assertScanned({
|
|
9594
|
+
gate: "lint_hidden_unicode",
|
|
9595
|
+
scanned: corpusFiles,
|
|
9596
|
+
units: "corpus file(s)",
|
|
9597
|
+
roots: DEFAULT_SCAN_ROOTS
|
|
9598
|
+
});
|
|
9599
|
+
} catch (exc) {
|
|
9600
|
+
if (exc instanceof DeadScopeError) {
|
|
9601
|
+
process.stderr.write(`\u274C ${exc.message}
|
|
9602
|
+
`);
|
|
9603
|
+
return 1;
|
|
9604
|
+
}
|
|
9605
|
+
throw exc;
|
|
9606
|
+
}
|
|
9561
9607
|
const sourceFiles = _eligibleSourceFiles();
|
|
9562
9608
|
for (const h of _scanSourceControlBytes(sourceFiles)) {
|
|
9563
9609
|
findings.push(h);
|
|
@@ -9608,6 +9654,7 @@ var init_lint_hidden_unicode = __esm({
|
|
|
9608
9654
|
"src/scripts/lint_hidden_unicode.ts"() {
|
|
9609
9655
|
"use strict";
|
|
9610
9656
|
init_security_lint();
|
|
9657
|
+
init_scan_scope();
|
|
9611
9658
|
CHECK = "hidden-unicode";
|
|
9612
9659
|
_BIDI = /* @__PURE__ */ new Set([
|
|
9613
9660
|
8234,
|
|
@@ -14000,35 +14047,6 @@ var init_release_scope = __esm({
|
|
|
14000
14047
|
}
|
|
14001
14048
|
});
|
|
14002
14049
|
|
|
14003
|
-
// src/scripts/_lib/scan_scope.ts
|
|
14004
|
-
function assertScanned(opts) {
|
|
14005
|
-
if (opts.scanned > 0) {
|
|
14006
|
-
return;
|
|
14007
|
-
}
|
|
14008
|
-
if (opts.allowEmpty !== void 0 && opts.allowEmpty.trim() !== "") {
|
|
14009
|
-
return;
|
|
14010
|
-
}
|
|
14011
|
-
const roots = opts.roots.length > 0 ? opts.roots.join(", ") : "(no root declared)";
|
|
14012
|
-
throw new DeadScopeError(
|
|
14013
|
-
opts.gate,
|
|
14014
|
-
`${opts.gate}: scanned 0 ${opts.units} under ${roots} \u2014 the scan scope is dead or the root moved. A gate that read nothing has not passed. Repoint the root (prefer the shared resolver in _lib/agent_src.ts), or declare a justified \`allowEmpty\` reason if an empty corpus is genuinely expected.`
|
|
14015
|
-
);
|
|
14016
|
-
}
|
|
14017
|
-
var DeadScopeError;
|
|
14018
|
-
var init_scan_scope = __esm({
|
|
14019
|
-
"src/scripts/_lib/scan_scope.ts"() {
|
|
14020
|
-
"use strict";
|
|
14021
|
-
DeadScopeError = class extends Error {
|
|
14022
|
-
gate;
|
|
14023
|
-
constructor(gate, message) {
|
|
14024
|
-
super(message);
|
|
14025
|
-
this.name = "DeadScopeError";
|
|
14026
|
-
this.gate = gate;
|
|
14027
|
-
}
|
|
14028
|
-
};
|
|
14029
|
-
}
|
|
14030
|
-
});
|
|
14031
|
-
|
|
14032
14050
|
// src/scripts/skill_linter.ts
|
|
14033
14051
|
var skill_linter_exports = {};
|
|
14034
14052
|
__export(skill_linter_exports, {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@event4u/agent-config",
|
|
3
3
|
"mcpName": "io.github.event4u-app/agent-config",
|
|
4
|
-
"version": "9.
|
|
4
|
+
"version": "9.21.0",
|
|
5
5
|
"description": "Governed skills, rules and commands for AI coding tools (Claude Code, Cursor, Windsurf, Copilot) — every claim machine-checked, including \"zero runtime daemon\".",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"private": false,
|
|
@@ -72,10 +72,15 @@
|
|
|
72
72
|
#
|
|
73
73
|
# What remains is NOT one line per gate. For the ~201 the count would have to be
|
|
74
74
|
# INVENTED (what is this gate's unit?) rather than published, and that judgement
|
|
75
|
-
# is per-gate. It
|
|
76
|
-
# unhardened-scan-scope` in src/config/gate-violation-baselines.json, which
|
|
77
|
-
# on a RISE and
|
|
78
|
-
#
|
|
75
|
+
# is per-gate. It was tracked as a vulnerability ratchet — `gate-hardening:
|
|
76
|
+
# unhardened-scan-scope` in src/config/gate-violation-baselines.json, which
|
|
77
|
+
# failed on a RISE and targeted 0 — under the road-to-gate-hardening-adoption
|
|
78
|
+
# charter. That charter closed 2026-08-05: the count reached 0 and the baseline
|
|
79
|
+
# entry was DELETED rather than zeroed, so `checkRatchet` now returns
|
|
80
|
+
# `unbaselined` with `ok = (actual === 0)`. Zero is mandatory, not a floor — any
|
|
81
|
+
# new gate written without a scope assertion reds immediately, and
|
|
82
|
+
# `tests/scripts/check_gate_coverage.test.ts` pins both the empty population and
|
|
83
|
+
# the entry's continued absence.
|
|
79
84
|
#
|
|
80
85
|
# `tests/scripts/check_gate_coverage.test.ts` fails the build the moment a gate
|
|
81
86
|
# starts emitting the line without being registered here, so the list cannot
|
|
@@ -441,3 +446,16 @@ gates:
|
|
|
441
446
|
note: >
|
|
442
447
|
Emits on stderr, not stdout: `--format json` owns this gate's stdout and a
|
|
443
448
|
count written there would corrupt the payload. The guard reads both streams.
|
|
449
|
+
|
|
450
|
+
- id: check_cli_registry_budget_sync
|
|
451
|
+
argv: []
|
|
452
|
+
min_scanned: 3
|
|
453
|
+
corpus: "the three named inputs it cross-checks — src/cli/registry.ts, src/config/evaluator-budgets.json, internal/bench/reports/evaluator-measurements.json"
|
|
454
|
+
status: enforced
|
|
455
|
+
note: >
|
|
456
|
+
Registered because its count became REAL, not to pad the manifest. The
|
|
457
|
+
gate always printed a hardcoded `scanned: 3`; hardening derived it from
|
|
458
|
+
the watch list that actually resolved, which is what makes a floor of 3
|
|
459
|
+
meaningful — it now falls when one of the three inputs is renamed away.
|
|
460
|
+
`argv: []` is the CI-identical invocation: both `taskfiles/ci-fast.yml`
|
|
461
|
+
and `.github/workflows/tests.yml` call it bare.
|
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
{
|
|
2
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 — 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
3
|
"gates": {
|
|
4
|
-
"gate-hardening:unhardened-scan-scope": {
|
|
5
|
-
"count": 189,
|
|
6
|
-
"landed": "2026-08-04",
|
|
7
|
-
"note": "Gate scripts under src/scripts (population 223, the lint_/check_/audit_ prefix set) that neither route through _lib/scan_scope nor emit the machine-readable 'scanned:' line — the gates that can still report success over a moved or empty root without saying so. This is a VULNERABILITY count, not a coverage percentage: it measures how much of the original defect class is still reachable, it RISES whenever a new gate is written without a scope assertion, and its target is 0. That direction is the whole point — an adoption-reach metric ('hardened gates must increase') can never regress and would be threshold-lowering wearing a ratchet's clothes (AI council 2026-08-04, anthropic/claude-sonnet-4-5 + openai/gpt-4o, convergent on scope decomposition plus this discriminator). Clearing it is the charter of road-to-gate-hardening-adoption; the 56-day non-stagnation clause applies unchanged, so a number that never drops fails this gate rather than hardening into configuration. NEW ENTRY, not a raised threshold: this records newly-measured pre-existing exposure at first measurement — nothing was loosened."
|
|
8
|
-
},
|
|
9
4
|
"check_no_new_legacy_path:hardcoded-scan-roots": {
|
|
10
|
-
"count":
|
|
11
|
-
"landed": "2026-08-
|
|
12
|
-
"note": "Lines under src/scripts/**/*.{ts,mts,mjs} that pass the retired `.agent-src.uncondensed` directory into `path.join(...)` — 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 → 147 string-literal lines → 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 — 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 — 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→51 by the road-to-renewal-foundation Phase 1 dead-root sweep (check_always_budget, check_portability, check_references, lint_framework_leakage, lint_agents_md)."
|
|
5
|
+
"count": 49,
|
|
6
|
+
"landed": "2026-08-04",
|
|
7
|
+
"note": "Lines under src/scripts/**/*.{ts,mts,mjs} that pass the retired `.agent-src.uncondensed` directory into `path.join(...)` — 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 → 147 string-literal lines → 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 — 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 — 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→51 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→49 by the gate-hardening adoption PR: skill_collision_clusters and skill_overlap were repointed at the live skills tree via the shared resolver — two gates that had been reading the retired container and scoring 0 of 288 skills."
|
|
13
8
|
},
|
|
14
9
|
"audit_user_type_axis": {
|
|
15
10
|
"count": 1,
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "What is a gate?" — asserted once, read by everything that needs the answer.
|
|
3
|
+
*
|
|
4
|
+
* Three call sites each carried their own regex and each got a different number
|
|
5
|
+
* (measured 2026-08-04):
|
|
6
|
+
*
|
|
7
|
+
* | Site | Pattern | Population |
|
|
8
|
+
* |---|---|---:|
|
|
9
|
+
* | `check_gate_coverage` (the ratchet) | `(lint\|check\|audit)_` minus `.d.ts` | 223 |
|
|
10
|
+
* | `sweep_dead_scan_roots` | `(lint\|audit\|check\|verify)_` | 225 |
|
|
11
|
+
* | the manifest-registration test | `(lint\|check\|audit\|skill)_` | 232 |
|
|
12
|
+
*
|
|
13
|
+
* Harmless while the numbers were only reported. Load-bearing the moment the
|
|
14
|
+
* ratchet read one of them, which it now does — and it read the narrowest:
|
|
15
|
+
*
|
|
16
|
+
* - it counted `check_secret_leak.test.ts`, a **test file**, which can never be
|
|
17
|
+
* hardened, so its target of 0 was unreachable by construction;
|
|
18
|
+
* - it missed 10 real gates the other two definitions caught — 8 × `skill_*`
|
|
19
|
+
* (including `skill_linter`, which already carries an enforced floor of 380 in
|
|
20
|
+
* the coverage manifest, so the manifest and the ratchet openly disagreed
|
|
21
|
+
* about whether it is a gate) and 2 × `verify_*`.
|
|
22
|
+
*
|
|
23
|
+
* ## Why a prefix filter and not manifest membership
|
|
24
|
+
*
|
|
25
|
+
* AI council 2026-08-04 (anthropic/claude-sonnet-4-5 + openai/gpt-4o, 3 rounds):
|
|
26
|
+
* making manifest registration the classifier inverts a dependency that runs the
|
|
27
|
+
* other way in practice. A new gate script lands BEFORE anyone registers it —
|
|
28
|
+
* that is precisely how the registration test found the drift — so a
|
|
29
|
+
* manifest-driven population would ignore every gate during the window when it
|
|
30
|
+
* is least proven. Classification is structural (this filter); registration is
|
|
31
|
+
* operational and layered on top (`enforced_manifest_ids`).
|
|
32
|
+
*
|
|
33
|
+
* The prefix set is a proxy for "this script certifies something and can lie
|
|
34
|
+
* about it", and an imperfect one: `skill_usage_report` reports rather than
|
|
35
|
+
* validates. It is kept because it is mechanical and over-inclusive in the safe
|
|
36
|
+
* direction — a reporting script that asserts its scan scope loses nothing,
|
|
37
|
+
* while a validator missing from the population is invisible exposure.
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
/** Prefixes that mark a script as gate-shaped. */
|
|
41
|
+
const GATE_PREFIX = /^(lint|check|audit|skill|verify)_/;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Is this filename a gate script?
|
|
45
|
+
*
|
|
46
|
+
* Structural only — takes a bare filename, never touches disk, so it answers
|
|
47
|
+
* for a file that does not exist yet (a diff, a plan, a test fixture).
|
|
48
|
+
*/
|
|
49
|
+
export function matchesGatePattern(filename: string): boolean {
|
|
50
|
+
if (!filename.endsWith('.ts')) return false;
|
|
51
|
+
// A type declaration has no runtime behaviour to harden; a test file cannot
|
|
52
|
+
// be hardened at all, and counting one made the ratchet's own target
|
|
53
|
+
// unreachable.
|
|
54
|
+
if (filename.endsWith('.d.ts') || filename.endsWith('.test.ts')) return false;
|
|
55
|
+
return GATE_PREFIX.test(filename);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** The gate scripts in `dir`, as bare ids (no `.ts`), sorted. Missing dir → `[]`. */
|
|
59
|
+
export function listGateScripts(dir: string, readdir: (d: string) => string[]): string[] {
|
|
60
|
+
let entries: string[];
|
|
61
|
+
try {
|
|
62
|
+
entries = readdir(dir);
|
|
63
|
+
} catch {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
return entries
|
|
67
|
+
.filter(matchesGatePattern)
|
|
68
|
+
.map((f) => f.replace(/\.ts$/, ''))
|
|
69
|
+
.sort();
|
|
70
|
+
}
|