@event4u/agent-config 14.12.0 → 14.14.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 +118 -155
- package/CONTRIBUTING.md +38 -0
- package/CREDITS.md +135 -0
- package/NOTICE +13 -0
- package/README.md +8 -6
- package/dist/agent-src/commands/analyze/inbox.md +145 -2
- package/dist/agent-src/commands/feature/dev.md +7 -2
- package/dist/agent-src/commands/ghostwriter/write.md +5 -1
- package/dist/agent-src/commands/implement-ticket.md +1 -1
- package/dist/agent-src/commands/mission/upgrade.md +1 -1
- package/dist/agent-src/commands/orchestrate.md +2 -2
- package/dist/agent-src/commands/post-as/me.md +5 -1
- package/dist/agent-src/commands/pr/merge.md +19 -6
- package/dist/agent-src/commands/roadmap/process-full.md +19 -5
- package/dist/agent-src/commands/tdd/red.md +12 -2
- package/dist/agent-src/commands/work.md +1 -1
- package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +40 -0
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +5 -2
- package/dist/agent-src/contexts/execution/autonomy-mechanics.md +21 -0
- package/dist/agent-src/contexts/execution/orchestration-telemetry.md +1 -0
- package/dist/agent-src/contexts/execution/subagent-response-contract.md +40 -0
- package/dist/agent-src/contexts/execution/subagent-steering.md +13 -1
- package/dist/agent-src/contexts/execution/terminal-states.md +96 -0
- package/dist/agent-src/rules/artifact-drafting-protocol.md +1 -1
- package/dist/agent-src/rules/broken-access-control.md +4 -0
- package/dist/agent-src/rules/code-comment-discipline.md +6 -0
- package/dist/agent-src/rules/code-provenance.md +4 -0
- package/dist/agent-src/rules/design-fidelity.md +1 -1
- package/dist/agent-src/rules/domain-safety-pii.md +4 -0
- package/dist/agent-src/rules/domain-safety-retention.md +4 -0
- package/dist/agent-src/rules/engineering-safety-floor.md +2 -0
- package/dist/agent-src/rules/external-code-graph-interop.md +14 -12
- package/dist/agent-src/rules/improve-before-implement.md +6 -8
- package/dist/agent-src/rules/laravel-routing.md +1 -1
- package/dist/agent-src/rules/lethal-trifecta-guard.md +4 -0
- package/dist/agent-src/rules/secret-vcs-guard.md +2 -0
- package/dist/agent-src/rules/security-sensitive-stop.md +2 -0
- package/dist/agent-src/rules/source-confidentiality.md +12 -34
- package/dist/agent-src/rules/symfony-routing.md +1 -1
- package/dist/agent-src/rules/token-efficiency.md +14 -0
- package/dist/agent-src/rules/tool-safety.md +4 -0
- package/dist/agent-src/rules/untrusted-input-defense.md +4 -0
- package/dist/agent-src/scripts/archive_completed_roadmaps.ts +252 -8
- package/dist/agent-src/scripts/guarded_baseline.ts +343 -0
- package/dist/agent-src/scripts/roadmap_set_step.ts +253 -0
- package/dist/agent-src/scripts/stub_queue.ts +82 -0
- package/dist/agent-src/scripts/stubs_due.ts +516 -0
- package/dist/agent-src/scripts/ticket_bundles.ts +84 -0
- package/dist/agent-src/scripts/update_roadmap_progress.ts +16 -12
- package/dist/agent-src/skills/brand-asset-generation/SKILL.md +17 -4
- package/dist/agent-src/skills/brand-audit/SKILL.md +33 -0
- package/dist/agent-src/skills/code-intelligence/SKILL.md +57 -0
- package/dist/agent-src/skills/database/SKILL.md +8 -0
- package/dist/agent-src/skills/dependency-upgrade/SKILL.md +27 -0
- package/dist/agent-src/skills/design-review/SKILL.md +1 -1
- package/dist/agent-src/skills/doc-coauthoring/SKILL.md +1 -1
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +17 -1
- package/dist/agent-src/skills/feature-planning/SKILL.md +9 -2
- package/dist/agent-src/skills/frontend-render-security/SKILL.md +44 -0
- package/dist/agent-src/skills/git-workflow/SKILL.md +1 -1
- package/dist/agent-src/skills/js-library-packaging/scripts/check_package_surface.ts +38 -4
- package/dist/agent-src/skills/judge-artifact-completeness/rubrics/ticket-quality-score.json +2 -2
- package/dist/agent-src/skills/laravel/SKILL.md +35 -0
- package/dist/agent-src/skills/laravel-migration/SKILL.md +57 -3
- package/dist/agent-src/skills/monorepo-workspace/SKILL.md +26 -0
- package/dist/agent-src/skills/playbook-authoring/SKILL.md +28 -1
- package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
- package/dist/agent-src/skills/skill-writing/references/procedure.md +5 -5
- package/dist/agent-src/skills/sql-writing/SKILL.md +7 -1
- package/dist/agent-src/skills/standards-from-config/SKILL.md +27 -4
- package/dist/agent-src/skills/supply-chain-intake/SKILL.md +11 -4
- package/dist/agent-src/skills/symfony-workflow/SKILL.md +35 -0
- package/dist/agent-src/skills/test-case-discovery/SKILL.md +85 -0
- package/dist/agent-src/skills/test-driven-development/SKILL.md +33 -9
- package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/testing-anti-patterns/process-anti-patterns.md +37 -0
- package/dist/agent-src/skills/ui-component-architect/SKILL.md +45 -2
- package/dist/agent-src/skills/upstream-contribute/SKILL.md +38 -1
- package/dist/agent-src/skills/verify-repair-loop/SKILL.md +9 -4
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +97 -3
- package/dist/agent-src/templates/scripts/check_memory.ts +258 -17
- package/dist/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
- package/dist/agent-src/templates/scripts/memory_lookup.ts +86 -0
- package/dist/agent-src/templates/scripts/memory_signal.ts +44 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
- package/dist/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
- package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
- package/dist/cli/commands/uiAudit.js +124 -5
- package/dist/cli/registry.js +2 -0
- package/dist/cli-delegate/{chunk-HYWSRNUX.js → chunk-2DK2VJWG.js} +3 -3
- package/dist/cli-delegate/{chunk-JCW7ZLHK.js → chunk-4FS4WRXP.js} +5 -0
- package/dist/cli-delegate/{chunk-OMIVVCG2.js → chunk-A4QJ6ENT.js} +24 -0
- package/dist/cli-delegate/{chunk-JJA2QEWA.js → chunk-AKJGUQNO.js} +466 -285
- package/dist/cli-delegate/{chunk-E46KPN6K.js → chunk-BTWUYDGN.js} +424 -363
- package/dist/cli-delegate/{chunk-K4FFODTS.js → chunk-ILMUPLGW.js} +1227 -316
- package/dist/cli-delegate/{chunk-FF7WAFMR.js → chunk-KPBWFOPZ.js} +5 -1
- package/dist/cli-delegate/cmd_adr_effective.js +102 -0
- package/dist/cli-delegate/cmd_conformance.js +80 -11
- package/dist/cli-delegate/cmd_doctor.js +3 -3
- package/dist/cli-delegate/cmd_export.js +3 -2
- package/dist/cli-delegate/cmd_fleet.js +2 -2
- 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 +3 -2
- package/dist/cli-delegate/cmd_settings_get.js +1 -1
- package/dist/cli-delegate/cmd_settings_migrate.js +3 -2
- package/dist/cli-delegate/cmd_settings_set.js +2 -2
- package/dist/cli-delegate/cmd_sync.js +3 -2
- package/dist/cli-delegate/cmd_uninstall.js +3 -2
- package/dist/cli-delegate/cmd_validate.js +3 -2
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +58 -58
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +1 -1
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +2 -2
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +2 -2
- package/dist/hooks/dispatch.js +2900 -1049
- package/dist/install/claudeRuleRewrite.js +254 -0
- package/dist/install/detect.js +29 -16
- package/dist/install/detect_php_shape.js +159 -0
- package/dist/install/install.mjs +634 -428
- package/dist/mcp/awesome-mcp-servers.row.md +1 -1
- package/dist/mcp/mcp-cloudflare-catalogue.json +1 -1
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +3 -3
- package/dist/mcp/server.mjs +4895 -2627
- package/dist/server/schemas/settings.js +3 -0
- package/dist/ui/assets/index-D0jaCRPM.js +29 -0
- package/dist/ui/index.html +1 -1
- package/docs/MIGRATION.md +1 -1
- package/docs/THIRD-PARTY-NOTICES.md +25 -0
- package/docs/contracts/provider-lifecycle.md +1 -1
- package/docs/contracts/settings-classes.md +10 -4
- package/docs/guidelines/agent-infra/5w2h-analysis.md +3 -3
- package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +1 -0
- package/docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +58 -3
- package/docs/guidelines/agent-infra/ask-when-uncertain-demos.md +2 -2
- package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +3 -3
- package/docs/guidelines/agent-infra/break-glass-usage.md +7 -7
- package/docs/guidelines/agent-infra/carve-out-predicates.md +3 -3
- package/docs/guidelines/agent-infra/comparison-matrix.md +1 -1
- package/docs/guidelines/agent-infra/critical-thinking.md +4 -4
- package/docs/guidelines/agent-infra/direct-answers-demos.md +2 -2
- package/docs/guidelines/agent-infra/domain-eval-anti-pattern.md +1 -1
- package/docs/guidelines/agent-infra/engineering-memory-data-format.md +3 -3
- package/docs/guidelines/agent-infra/existence-question-verdicts.md +80 -0
- package/docs/guidelines/agent-infra/first-principles.md +2 -2
- package/docs/guidelines/agent-infra/framework-neutrality-patterns.md +2 -2
- package/docs/guidelines/agent-infra/guarded-baseline.md +39 -0
- package/docs/guidelines/agent-infra/inversion-thinking.md +5 -5
- package/docs/guidelines/agent-infra/language-and-tone-examples.md +1 -1
- package/docs/guidelines/agent-infra/layered-settings.md +10 -10
- package/docs/guidelines/agent-infra/memory-access.md +1 -1
- package/docs/guidelines/agent-infra/mental-models.md +3 -3
- package/docs/guidelines/agent-infra/reuse-verdict-mechanics.md +71 -0
- package/docs/guidelines/agent-infra/review-routing-data-format.md +7 -7
- package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +13 -7
- package/docs/guidelines/agent-infra/role-contracts.md +2 -2
- package/docs/guidelines/agent-infra/role-mode-router.md +3 -3
- package/docs/guidelines/agent-infra/rule-type-governance.md +2 -2
- package/docs/guidelines/agent-infra/scqa-framework.md +5 -5
- package/docs/guidelines/agent-infra/self-improvement-pipeline.md +6 -6
- package/docs/guidelines/agent-infra/simplicity-and-goal-demos.md +2 -2
- package/docs/guidelines/agent-infra/six-hats.md +3 -3
- package/docs/guidelines/agent-infra/skill-quality-checklist.md +6 -6
- package/docs/guidelines/agent-infra/source-confidentiality-mechanics.md +109 -0
- package/docs/guidelines/agent-infra/systems-thinking.md +1 -1
- package/docs/guidelines/agent-infra/verify-before-complete-demos.md +2 -2
- package/docs/guidelines/augment-portability-patterns.md +6 -4
- package/docs/guidelines/code-clarity.md +18 -0
- package/docs/guidelines/component-oriented-and-oop-development.md +3 -2
- package/docs/guidelines/cross-role-handoff.md +2 -2
- package/docs/guidelines/design-fidelity-mechanics.md +1 -1
- package/docs/guidelines/docs/readme-size-and-splitting.md +3 -3
- package/docs/guidelines/php/database.md +90 -7
- package/docs/guidelines/prompt-templates.md +7 -7
- package/llms.txt +2 -2
- package/package.json +5 -2
- package/src/agent-src/scripts/archive_completed_roadmaps.ts +252 -8
- package/src/agent-src/scripts/guarded_baseline.ts +343 -0
- package/src/agent-src/scripts/roadmap_set_step.ts +253 -0
- package/src/agent-src/scripts/stub_queue.ts +82 -0
- package/src/agent-src/scripts/stubs_due.ts +516 -0
- package/src/agent-src/scripts/ticket_bundles.ts +84 -0
- package/src/agent-src/scripts/update_roadmap_progress.ts +16 -12
- package/src/agent-src/templates/scripts/check_memory.ts +258 -17
- package/src/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
- package/src/agent-src/templates/scripts/memory_lookup.ts +86 -0
- package/src/agent-src/templates/scripts/memory_signal.ts +44 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
- package/src/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
- package/src/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
- package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
- package/src/config/agent-settings.template.yml +32 -3
- package/src/config/assurance-capability-registry.json +21 -9
- package/src/config/canonical-terms.yml +119 -0
- package/src/config/capability-native-outcome-bars.json +81 -0
- package/src/config/ci-local-parity.yml +80 -0
- package/src/config/drafting-channels.yml +43 -0
- package/src/config/estate-count-budget.json +57 -36
- package/src/config/evaluator-budgets.json +14 -14
- package/src/config/gate-coverage.yml +729 -63
- package/src/config/gate-reachability-exemptions.json +21 -0
- package/src/config/gate-violation-baselines.json +42 -19
- package/src/config/harness-evolution-budget.json +25 -0
- package/src/config/lapsed-beta-baseline.json +96 -0
- package/src/config/memory-twin-verdicts.yml +129 -0
- package/src/config/metric-registry.yml +124 -0
- package/src/config/pack-size-budget.json +16 -15
- package/src/config/preamble-payload-budget.json +12 -4
- package/src/config/profiles/balanced.ini +27 -0
- package/src/config/profiles/full.ini +27 -0
- package/src/config/profiles/minimal.ini +27 -0
- package/src/config/publish-surface.json +9 -2
- package/src/config/routing-coverage-seed.json +16 -2
- package/src/config/rule-stub-ceilings.json +133 -112
- package/src/config/turnaround-budget.json +66 -0
- package/src/install/claudeRuleRewrite.ts +288 -0
- package/src/install/detect.ts +60 -17
- package/src/install/detect_php_shape.ts +191 -0
- package/src/scripts/_cli/cmd_doctor.ts +27 -112
- package/src/scripts/_dispatch.bash +23 -0
- package/src/scripts/_lib/activation_ladder.ts +255 -0
- package/src/scripts/_lib/activation_receipt_producer.ts +341 -0
- package/src/scripts/_lib/activation_states.ts +88 -0
- package/src/scripts/_lib/adherence_detectors.ts +143 -0
- package/src/scripts/_lib/adr_frontmatter.ts +26 -0
- package/src/scripts/_lib/arith_claims.ts +181 -0
- package/src/scripts/_lib/arm_ranking.ts +62 -0
- package/src/scripts/_lib/asset_delivery_ledger.ts +303 -0
- package/src/scripts/_lib/audit_field_provenance.ts +54 -0
- package/src/scripts/_lib/auto_dispatch.ts +32 -3
- package/src/scripts/_lib/bench_ab_size_claim.ts +98 -4
- package/src/scripts/_lib/benchmark_cache_fields.ts +158 -0
- package/src/scripts/_lib/candidate_pair_delta.ts +349 -0
- package/src/scripts/_lib/candidate_proposer.ts +402 -0
- package/src/scripts/_lib/candidate_record.ts +601 -0
- package/src/scripts/_lib/capture_rate.ts +319 -0
- package/src/scripts/_lib/carrier_status.ts +118 -0
- package/src/scripts/_lib/cascade_stage_enumeration.ts +92 -0
- package/src/scripts/_lib/collector_denominator.ts +771 -0
- package/src/scripts/_lib/collector_record.ts +340 -0
- package/src/scripts/_lib/collector_store.ts +664 -0
- package/src/scripts/_lib/collector_supervision.ts +827 -0
- package/src/scripts/_lib/concern_estate.ts +77 -0
- package/src/scripts/_lib/config_chain.ts +477 -0
- package/src/scripts/_lib/config_cost.ts +209 -0
- package/src/scripts/_lib/corpus_manifest.ts +726 -0
- package/src/scripts/_lib/council_settings_block.ts +6 -0
- package/src/scripts/_lib/curator_ops.ts +172 -0
- package/src/scripts/_lib/delivery_arm_experiment.ts +282 -0
- package/src/scripts/_lib/delivery_criticality.ts +126 -0
- package/src/scripts/_lib/doctor_runtime_checks.ts +70 -0
- package/src/scripts/_lib/empty_cycles.ts +88 -0
- package/src/scripts/_lib/estate_carrier_cases.ts +72 -0
- package/src/scripts/_lib/eval_publication.ts +354 -0
- package/src/scripts/_lib/evaluation_cascade.ts +452 -0
- package/src/scripts/_lib/evaluation_vector.ts +283 -0
- package/src/scripts/_lib/evaluator_promotion.ts +225 -0
- package/src/scripts/_lib/evidence_basis.ts +118 -0
- package/src/scripts/_lib/evolution_roi.ts +562 -0
- package/src/scripts/_lib/exec_evidence.ts +8 -0
- package/src/scripts/_lib/experience_card.ts +272 -0
- package/src/scripts/_lib/experience_report.ts +151 -0
- package/src/scripts/_lib/experiment_freeze.ts +112 -0
- package/src/scripts/_lib/generated_by.ts +66 -0
- package/src/scripts/_lib/harness_evolution_guards.ts +239 -0
- package/src/scripts/_lib/hook_effect_probe.ts +141 -0
- package/src/scripts/_lib/host_denominator.ts +687 -0
- package/src/scripts/_lib/host_projection_reach.ts +157 -0
- package/src/scripts/_lib/ignored_blocker.ts +148 -0
- package/src/scripts/_lib/install_reach_checks.ts +495 -0
- package/src/scripts/_lib/json_duplicate_keys.ts +150 -0
- package/src/scripts/_lib/judge_hygiene.ts +228 -0
- package/src/scripts/_lib/legacy_boundary_map.ts +228 -0
- package/src/scripts/_lib/lexical_shortlist.ts +215 -0
- package/src/scripts/_lib/llm_candidate_proposer.ts +461 -0
- package/src/scripts/_lib/llm_proposer_transport.ts +153 -0
- package/src/scripts/_lib/loop_guards.ts +299 -0
- package/src/scripts/_lib/loss_class.ts +129 -0
- package/src/scripts/_lib/machine_wake.ts +51 -0
- package/src/scripts/_lib/md_prose_lines.ts +177 -0
- package/src/scripts/_lib/minimality_tiebreak.ts +168 -0
- package/src/scripts/_lib/one_resolver_invariant.ts +449 -0
- package/src/scripts/_lib/orchestration_record.ts +253 -5
- package/src/scripts/_lib/outcome_envelope.ts +227 -0
- package/src/scripts/_lib/outcome_vocabularies.ts +125 -0
- package/src/scripts/_lib/paired_stats.ts +245 -0
- package/src/scripts/_lib/paired_verdict.ts +226 -0
- package/src/scripts/_lib/pathology_archive.ts +393 -0
- package/src/scripts/_lib/prefix_stable_surfaces.ts +123 -0
- package/src/scripts/_lib/privacy_class.ts +47 -0
- package/src/scripts/_lib/promotion_capability.ts +315 -0
- package/src/scripts/_lib/promotion_evidence.ts +414 -0
- package/src/scripts/_lib/promotion_review.ts +294 -0
- package/src/scripts/_lib/prompt_shape.ts +92 -0
- package/src/scripts/_lib/regression_neighbourhood.ts +259 -0
- package/src/scripts/_lib/release_highlights.ts +70 -1
- package/src/scripts/_lib/release_material.ts +125 -2
- package/src/scripts/_lib/repeated_failure.ts +105 -0
- package/src/scripts/_lib/repo_root.ts +111 -0
- package/src/scripts/_lib/review_skipped_record.ts +37 -0
- package/src/scripts/_lib/role_split.ts +338 -0
- package/src/scripts/_lib/routing_corpus.ts +307 -0
- package/src/scripts/_lib/routing_index_input.ts +104 -0
- package/src/scripts/_lib/rule_injection.ts +22 -1
- package/src/scripts/_lib/runtime_journal.ts +1499 -0
- package/src/scripts/_lib/runtime_wiring_checks.ts +430 -0
- package/src/scripts/_lib/semantic_noop.ts +167 -0
- package/src/scripts/_lib/skill_catalogue.ts +11 -1
- package/src/scripts/_lib/source_digest.ts +200 -0
- package/src/scripts/_lib/source_redact.ts +260 -0
- package/src/scripts/_lib/source_shape.ts +502 -0
- package/src/scripts/_lib/source_snapshot_dedup.ts +199 -0
- package/src/scripts/_lib/strip_comments.d.mts +8 -0
- package/src/scripts/_lib/strip_comments.mjs +65 -0
- package/src/scripts/_lib/test_red_state.ts +154 -0
- package/src/scripts/_lib/trigger_shift.ts +144 -0
- package/src/scripts/_lib/untrusted_content.ts +82 -7
- package/src/scripts/activation_receipt.ts +258 -0
- package/src/scripts/adoption_report.ts +1 -1
- package/src/scripts/adr/evidence_census.ts +1 -1
- package/src/scripts/adr/regenerate_index.ts +26 -2
- package/src/scripts/adr_cite_check.ts +164 -1
- package/src/scripts/ai_council/blind_review.ts +11 -1
- package/src/scripts/ai_council/clients.ts +4 -0
- package/src/scripts/ai_council/config.ts +3 -0
- package/src/scripts/ai_council/consensus.ts +28 -8
- package/src/scripts/ai_council/consensus_round.ts +226 -0
- package/src/scripts/ai_council/cross_exam.ts +128 -0
- package/src/scripts/ai_council/disagreement_signal.ts +338 -0
- package/src/scripts/ai_council/explain_route.ts +157 -0
- package/src/scripts/ai_council/information_gain.ts +293 -0
- package/src/scripts/ai_council/inline_findings.ts +340 -0
- package/src/scripts/ai_council/judge_position_bias.ts +197 -0
- package/src/scripts/ai_council/leakage_corpus.ts +385 -0
- package/src/scripts/ai_council/leakage_patterns.ts +453 -0
- package/src/scripts/ai_council/minority_retention.ts +171 -0
- package/src/scripts/ai_council/orchestrator.ts +16 -203
- package/src/scripts/ai_council/orchestrator_results.ts +23 -3
- package/src/scripts/ai_council/pricing.ts +106 -0
- package/src/scripts/ai_council/prompts.ts +74 -7
- package/src/scripts/ai_council/provider_leakage_bench.ts +327 -0
- package/src/scripts/ai_council/py_format.ts +14 -3
- package/src/scripts/ai_council/recouncil_guard.ts +293 -0
- package/src/scripts/ai_council/recouncil_savings.ts +299 -0
- package/src/scripts/ai_council/replay_route.ts +223 -0
- package/src/scripts/ai_council/response_record.ts +50 -0
- package/src/scripts/ai_council/reviewer_assignment.ts +279 -0
- package/src/scripts/ai_council/routing_training_row.ts +197 -0
- package/src/scripts/ai_council/synthesis_strategy.ts +159 -0
- package/src/scripts/ai_council/topology_bench_manifest.ts +860 -0
- package/src/scripts/ai_council/topology_vocabulary.ts +175 -0
- package/src/scripts/asset_delivery_ledger.ts +157 -0
- package/src/scripts/attest_artifact.ts +193 -0
- package/src/scripts/audit_auto_rules.ts +2 -1
- package/src/scripts/audit_command_surface.ts +1 -1
- package/src/scripts/audit_mcp_tools.ts +2 -2
- package/src/scripts/audit_skill_overlap_allowlist.json +6 -1
- package/src/scripts/audit_user_type_axis.ts +2 -1
- package/src/scripts/bench_ab_clone.ts +215 -10
- package/src/scripts/bench_ab_integrity.ts +119 -5
- package/src/scripts/bench_ab_v2_stats.ts +40 -213
- package/src/scripts/build_archive_index.ts +1 -1
- package/src/scripts/build_linear_digest.ts +1 -1
- package/src/scripts/build_proof.ts +11 -4
- package/src/scripts/build_rule_trigger_matrix.ts +1 -1
- package/src/scripts/build_source_digests.ts +157 -0
- package/src/scripts/cache_realization_report.ts +103 -0
- package/src/scripts/check_adr_frontmatter.ts +131 -10
- package/src/scripts/check_benchmark_report_fields.ts +207 -0
- package/src/scripts/check_beta_review_markers.ts +235 -6
- package/src/scripts/check_bundle_path_leakage.ts +34 -1
- package/src/scripts/check_claims.ts +576 -6
- package/src/scripts/check_composite_arming.ts +35 -0
- package/src/scripts/check_concern_admissions.ts +365 -0
- package/src/scripts/check_enforcement_coverage.ts +28 -0
- package/src/scripts/check_estate_count.ts +347 -25
- package/src/scripts/check_gate_reachability.ts +383 -0
- package/src/scripts/check_host_loadability.ts +104 -0
- package/src/scripts/check_loss_class_declared.ts +308 -0
- package/src/scripts/check_md_language.ts +15 -98
- package/src/scripts/check_memory_proposal.ts +18 -11
- package/src/scripts/check_no_currency_in_cost_surfaces.ts +225 -0
- package/src/scripts/check_no_external_sources.ts +281 -6
- package/src/scripts/check_pack_conformance_fixture.ts +11 -1
- package/src/scripts/check_pack_size.ts +59 -2
- package/src/scripts/check_preamble_payload_budget.ts +114 -3
- package/src/scripts/check_prefix_stable_mutation.ts +372 -0
- package/src/scripts/check_publish_surface.ts +10 -1
- package/src/scripts/check_references.ts +24 -1
- package/src/scripts/check_release_highlights.ts +96 -13
- package/src/scripts/check_roadmap_trackable.ts +17 -2
- package/src/scripts/check_rule_evidence_declaration.ts +316 -0
- package/src/scripts/check_rule_projection_integrity.ts +14 -4
- package/src/scripts/check_score_contract.ts +26 -3
- package/src/scripts/check_static_parity.ts +285 -0
- package/src/scripts/check_supervision_claim_atomicity.ts +498 -0
- package/src/scripts/check_suppression_hygiene.ts +15 -0
- package/src/scripts/ci_settle.ts +39 -2
- package/src/scripts/code_graph/build.ts +60 -3
- package/src/scripts/code_graph/extract.ts +44 -0
- package/src/scripts/code_graph/types.ts +24 -0
- package/src/scripts/collector_daemon.ts +714 -0
- package/src/scripts/config_cost_report.ts +302 -0
- package/src/scripts/consumer_matrix.ts +74 -1
- package/src/scripts/corpus_manifest.ts +235 -0
- package/src/scripts/cost/budget.mjs +10 -3
- package/src/scripts/cost/track.mjs +10 -3
- package/src/scripts/council_cli.ts +37 -54
- package/src/scripts/dispatch_r2_reviewer.ts +46 -5
- package/src/scripts/evolution_lab.ts +1153 -0
- package/src/scripts/external_sources_denylist.json +5 -18
- package/src/scripts/extract_audit_patterns.ts +21 -0
- package/src/scripts/fold_intake.ts +12 -1
- package/src/scripts/gen_discovery_baseline.ts +1 -1
- package/src/scripts/generate_capabilities_index.ts +12 -5
- package/src/scripts/generate_capability_matrix.ts +3 -3
- package/src/scripts/generate_command_flows.ts +2 -2
- package/src/scripts/generate_cookbook.ts +2 -2
- package/src/scripts/generate_index.ts +8 -1
- package/src/scripts/generate_knowledge_index.ts +2 -1
- package/src/scripts/generate_ownership_matrix.ts +2 -1
- package/src/scripts/generate_pack_manifests.ts +10 -2
- package/src/scripts/generate_role_experiences_catalog.ts +2 -2
- package/src/scripts/generate_settings_reference.ts +1 -1
- package/src/scripts/git_authorization_hook.ts +22 -1
- package/src/scripts/grade_target_readiness.ts +48 -5
- package/src/scripts/hook_effect_doctor.ts +261 -0
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +125 -16
- package/src/scripts/hooks/block_speaking_inbox_dir.ts +271 -0
- package/src/scripts/hooks/block_unauthorized_git.ts +18 -0
- package/src/scripts/hooks/comment_discipline_hook.ts +146 -0
- package/src/scripts/hooks/concern_registry.ts +6 -0
- package/src/scripts/hooks/dispatch_hook.ts +32 -0
- package/src/scripts/hooks/journal_record_hook.ts +345 -0
- package/src/scripts/hooks/prepush_metadata_sources.sh +110 -0
- package/src/scripts/hooks/run_continuation_hook.ts +44 -9
- package/src/scripts/hooks/shims/install.sh +61 -0
- package/src/scripts/hooks/shims/php +101 -0
- package/src/scripts/hooks/suggestion_capture_hook.ts +10 -0
- package/src/scripts/hooks/turn_end_gate_hook.ts +9 -1
- package/src/scripts/hot_context_hook.ts +16 -0
- package/src/scripts/install-hooks.sh +20 -5
- package/src/scripts/install.ts +17 -35
- package/src/scripts/inventory_frontmatter.ts +2 -1
- package/src/scripts/language_mirror_hook.ts +14 -2
- package/src/scripts/lint_adr_sweep_routing.ts +12 -0
- package/src/scripts/lint_canonical_terms.ts +604 -0
- package/src/scripts/lint_carrier_integrity.ts +820 -0
- package/src/scripts/lint_code_comments.ts +643 -0
- package/src/scripts/lint_composition_review.ts +619 -0
- package/src/scripts/lint_consolidation_lineage.ts +666 -0
- package/src/scripts/lint_eval_specs.ts +593 -0
- package/src/scripts/lint_hook_manifest.ts +19 -0
- package/src/scripts/lint_host_portability.ts +373 -0
- package/src/scripts/lint_judge_prompt_expectation.ts +27 -1
- package/src/scripts/lint_memory_twin_parity.ts +335 -0
- package/src/scripts/lint_metric_consumers.ts +355 -0
- package/src/scripts/lint_plan_risk_register.ts +39 -19
- package/src/scripts/lint_promotion_paths.ts +779 -0
- package/src/scripts/lint_skill_descriptions.ts +18 -1
- package/src/scripts/lint_skill_frontmatter_safety.ts +58 -0
- package/src/scripts/lint_skill_link_reach.ts +252 -0
- package/src/scripts/lint_skill_trigger_corpus.ts +426 -23
- package/src/scripts/lint_ticket_buildable.ts +17 -1
- package/src/scripts/llm_propose.ts +256 -0
- package/src/scripts/mcp_server/consumer_tool_catalog.json +1 -1
- package/src/scripts/mcp_server/tool_catalog_source.ts +1 -1
- package/src/scripts/measure_delivery_sets.ts +361 -0
- package/src/scripts/measure_docs_dead_links.ts +348 -0
- package/src/scripts/measure_host_capture.ts +461 -0
- package/src/scripts/measure_routing_signal.ts +307 -0
- package/src/scripts/migration_status.ts +3 -3
- package/src/scripts/model_rule_injection.ts +76 -0
- package/src/scripts/orchestration_record.ts +14 -0
- package/src/scripts/preamble_byte_census.ts +139 -10
- package/src/scripts/prepack-check.mjs +4 -1
- package/src/scripts/probe_council_retention.ts +495 -0
- package/src/scripts/probe_turnaround.ts +384 -0
- package/src/scripts/probe_unblocked_ask.ts +279 -0
- package/src/scripts/release.ts +21 -37
- package/src/scripts/release_drill.ts +143 -0
- package/src/scripts/release_env.ts +35 -0
- package/src/scripts/release_publication.ts +84 -0
- package/src/scripts/render_benchmark_md.ts +1 -1
- package/src/scripts/rule_activation_census.ts +70 -9
- package/src/scripts/rule_backlinks.ts +1 -1
- package/src/scripts/run_lifecycle_suite.ts +208 -0
- package/src/scripts/run_skill_evals.ts +40 -0
- package/src/scripts/schemas/delivery-manifest.schema.json +43 -0
- package/src/scripts/schemas/drafting-channels.schema.json +43 -0
- package/src/scripts/schemas/evals.schema.json +24 -1
- package/src/scripts/schemas/rule.schema.json +52 -1
- package/src/scripts/schemas/skill.schema.json +17 -2
- package/src/scripts/skill_overlap.ts +7 -1
- package/src/scripts/skill_tools/run_block_d_eval.ts +8 -1
- package/src/scripts/skill_tools/score_skill_relevance.ts +84 -3
- package/src/scripts/skill_tools/suggest_skill_for_task.ts +8 -1
- package/src/scripts/skill_usage_report.ts +2 -1
- package/src/scripts/stubs_due.ts +211 -0
- package/src/scripts/sweep_source_surfaces.ts +678 -0
- package/src/scripts/sync_pr_branch.ts +3 -3
- package/src/scripts/trigger_eval_grandfather.json +202 -222
- package/src/scripts/utilization_report.ts +22 -2
- package/src/server/schemas/settings.ts +5 -0
- package/src/templates/marketing-copy.yml +1 -1
- package/dist/ui/assets/index-Cxgy63kz.js +0 -26
|
@@ -123,8 +123,51 @@ Prop budget per component:
|
|
|
123
123
|
| Composite (Card, Dialog) | ≤ 8 props; prefer slots for variants |
|
|
124
124
|
| Page section / feature shell | ≤ 4 props; everything else via context |
|
|
125
125
|
|
|
126
|
-
Over-budget
|
|
127
|
-
state into context, or split into compound parts
|
|
126
|
+
Over-budget is a **prompt to look**, not a verdict. Extract a config object,
|
|
127
|
+
push state into context, or split into compound parts — **or record why the
|
|
128
|
+
count is right for this component.**
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
THE CAPS ABOVE ARE ADVISORY. THEY ARE NOT A GATE AND MUST NOT BECOME ONE
|
|
132
|
+
WITHOUT A NEW MEASUREMENT. NOTHING COMPUTES THE TIER, SO NOTHING CAN APPLY THEM
|
|
133
|
+
AUTOMATICALLY EVEN IF IT WANTED TO.
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Why advisory, measured rather than asserted** (2026-08-24, one production
|
|
137
|
+
component library: 55 atoms, 3 molecules, 2 organisms):
|
|
138
|
+
|
|
139
|
+
| component | its level | props | cap here | over |
|
|
140
|
+
|---|---|---:|---:|---:|
|
|
141
|
+
| `file-upload` | **atom** | 19 | 6 | **3.2×** |
|
|
142
|
+
| `date-navigator` | molecule | 18 | 8 | 2.25× |
|
|
143
|
+
| `picker-sheet` | organism | 14 | 4 | **3.5×** |
|
|
144
|
+
| `duration-input` | molecule | 13 | 8 | 1.6× |
|
|
145
|
+
| `stepper` | molecule | 4 | 8 | — |
|
|
146
|
+
|
|
147
|
+
**The budget is INVERTED, and that is the finding rather than a calibration
|
|
148
|
+
error.** This table tightens as granularity rises. Reality goes the other way:
|
|
149
|
+
a higher-level component legitimately surfaces every label, callback and test id
|
|
150
|
+
of the pattern it orchestrates, so a cap that shrinks with tier flags the
|
|
151
|
+
components that are **correctly built** and clears the one that is 3.2× over.
|
|
152
|
+
|
|
153
|
+
**And for most components the number does not exist.** Between **45 % and 72 %**
|
|
154
|
+
of that library declares no root prop interface at all, depending on how you
|
|
155
|
+
count — `React.ComponentProps<'div'> & VariantProps<cva>` is the dominant idiom.
|
|
156
|
+
A cap over an uncountable quantity is not a lenient rule; it is no rule.
|
|
157
|
+
|
|
158
|
+
**The tier itself is not computable.** Composition depth, state, sub-component
|
|
159
|
+
count and prop count were each tested as a discriminator between the three
|
|
160
|
+
levels. **Every one overlapped completely, and several inverted.** Sub-component
|
|
161
|
+
count is the tempting replacement and fails the same way: `atoms/combobox`
|
|
162
|
+
exports **16**, more than every molecule (1, 1, 2) and more than one of the two
|
|
163
|
+
organisms. So there is no measurement that could assign the tier a cap would be
|
|
164
|
+
applied to.
|
|
165
|
+
|
|
166
|
+
**Revisit-if:** a corpus of levelled libraries — plural, and not four days old —
|
|
167
|
+
yields a discriminator that separates the tiers without overlap, at which point
|
|
168
|
+
the caps can be re-derived against it rather than restated. Until then these
|
|
169
|
+
numbers are a conversation starter for a human reviewer, which is the only role
|
|
170
|
+
the evidence supports.
|
|
128
171
|
|
|
129
172
|
### 5. Name the slot contract
|
|
130
173
|
|
|
@@ -9,7 +9,7 @@ scope:
|
|
|
9
9
|
execution:
|
|
10
10
|
type: assisted
|
|
11
11
|
handler: internal
|
|
12
|
-
allowed_tools: ["
|
|
12
|
+
allowed_tools: ["Bash(gh:*)"]
|
|
13
13
|
workspaces:
|
|
14
14
|
- agent-config-maintainer
|
|
15
15
|
packs:
|
|
@@ -49,6 +49,43 @@ shared `agent-config` package — with correct file placement, quality gates, an
|
|
|
49
49
|
- **Quality verified** — must pass linter before PR creation
|
|
50
50
|
- **Local benefit immediately** — use override for instant project benefit while PR is pending
|
|
51
51
|
|
|
52
|
+
## A repeated override is a signal, and a signal is not evidence
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
THE SAME ARTIFACT OVERRIDDEN IN INDEPENDENT INSTALLS IS THE CHEAPEST AVAILABLE
|
|
56
|
+
HINT THAT A SHIPPED DEFAULT IS WRONG. IT IS A HINT.
|
|
57
|
+
NEVER CHANGE A SHIPPED DEFAULT ON OVERRIDES FROM ONE ORGANISATION.
|
|
58
|
+
INDEPENDENT MEANS DIFFERENT TEAMS, NOT DIFFERENT DIRECTORIES.
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`agent-config doctor --check override-set` reports which shipped artifacts a
|
|
62
|
+
tree overrides and in how many layers. Two same-culture installs overriding the
|
|
63
|
+
same artifact is **n=2 from one toolchain culture**, which is a discovery
|
|
64
|
+
channel and not a mandate — and the temptation to "just fix the default, we
|
|
65
|
+
already know" is exactly how a general package becomes one organisation's house
|
|
66
|
+
style.
|
|
67
|
+
|
|
68
|
+
**What makes an aggregate admissible**, matching the *Evidence-based* and
|
|
69
|
+
*Universality first* principles above:
|
|
70
|
+
|
|
71
|
+
- overrides from **independently operated** consumers, not several repositories
|
|
72
|
+
of one team;
|
|
73
|
+
- the overriding change **converging on the same substance**, not merely
|
|
74
|
+
touching the same filename — two teams deleting different halves of a rule
|
|
75
|
+
are not agreeing about anything;
|
|
76
|
+
- a **named public mechanism** that explains why the shipped default is wrong,
|
|
77
|
+
rather than "several people changed it".
|
|
78
|
+
|
|
79
|
+
Below that bar, the signal is one input to a future aggregate and nothing more.
|
|
80
|
+
Record it and leave the default alone.
|
|
81
|
+
|
|
82
|
+
**The signal carries no consumer content, by construction.** Artifact kind, name
|
|
83
|
+
and a layer count — the type has no field that can hold a path, a diff or
|
|
84
|
+
anything from the tree, so privacy is the schema's shape rather than a scrubbing
|
|
85
|
+
pass that could fail. Never widen it to make a proposal more persuasive; a
|
|
86
|
+
proposal that needs the consumer's diff is a proposal that has not cleared the
|
|
87
|
+
bar.
|
|
88
|
+
|
|
52
89
|
## Package repository
|
|
53
90
|
|
|
54
91
|
The shared agent-config package lives at:
|
|
@@ -15,7 +15,8 @@ packs:
|
|
|
15
15
|
> **executed verdict** — the project's real test/quality output, scored against a
|
|
16
16
|
> numeric threshold — escalated to a **judge** for qualitative confirmation only
|
|
17
17
|
> *after* the numeric gate passes (staged escalation). The loop is the
|
|
18
|
-
> conversation, not a process:
|
|
18
|
+
> conversation, not a process: this loop introduces no resident process of its
|
|
19
|
+
> own and no persistent cross-session state. Use
|
|
19
20
|
> it to drive a change to green when the verdict source is *runtime execution*,
|
|
20
21
|
> not a judge reading a diff.
|
|
21
22
|
|
|
@@ -126,7 +127,7 @@ iterating against a stale contract.
|
|
|
126
127
|
|
|
127
128
|
State lives in the conversation, optionally mirrored to a re-read working file —
|
|
128
129
|
**never** a daemon or persistent cross-session store (honors
|
|
129
|
-
[`
|
|
130
|
+
[`resident-process-governance`](../../../docs/contracts/resident-process-governance.md)).
|
|
130
131
|
|
|
131
132
|
## Validation
|
|
132
133
|
|
|
@@ -137,7 +138,11 @@ Before finalizing, confirm:
|
|
|
137
138
|
3. The loop stopped at `max_attempts`, a plateau, or a judge `apply` — never
|
|
138
139
|
ran unbounded.
|
|
139
140
|
4. The judge saw only the diff + results, dispatched in fresh context.
|
|
140
|
-
5. No
|
|
141
|
+
5. No **unsupervised** resident process introduced — and none of the four
|
|
142
|
+
governance conditions in `resident-process-governance.md` left unmet if a
|
|
143
|
+
supervised one is. (Amended 2026-08-27, ADR-249: this read "No daemon /
|
|
144
|
+
persistent runtime introduced" when a daemon was prohibited outright. The
|
|
145
|
+
check still fires; what it tests moved from existence to governance.)
|
|
141
146
|
|
|
142
147
|
## Output format
|
|
143
148
|
|
|
@@ -211,7 +216,7 @@ iter2 fixes A, breaks B, 92% → "PASS" ✗ regression ignored
|
|
|
211
216
|
* [`playwright-testing`](../playwright-testing/SKILL.md),
|
|
212
217
|
[`quality-tools`](../quality-tools/SKILL.md) — verdict sources.
|
|
213
218
|
* [`autonomous-execution`](../../rules/autonomous-execution.md) — the N=3 cap.
|
|
214
|
-
* [`
|
|
219
|
+
* [`resident-process-governance`](../../../docs/contracts/resident-process-governance.md) — the
|
|
215
220
|
runtime-free constraint this loop honors.
|
|
216
221
|
* Optional impact pre-step (when a code-graph is present, ADR-124): run
|
|
217
222
|
`agent-config code-graph affected --since <ref>` to scope which symbols a
|
|
@@ -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: "14.
|
|
42
|
+
agent_config_version: "14.14.0"
|
|
43
43
|
|
|
44
44
|
# --- Project identity ---
|
|
45
45
|
project:
|
|
@@ -78,6 +78,53 @@ that was never a judgement call.
|
|
|
78
78
|
`horizon_weeks` to a positive integer. Enforced by
|
|
79
79
|
`task lint-roadmap-complexity` (plate-token detection skipped when
|
|
80
80
|
`horizon_weeks > 0`).
|
|
81
|
+
17b. **A carried deferral is annotated, or it blocks archival forever.**
|
|
82
|
+
`archive_completed_roadmaps` used to refuse any roadmap with
|
|
83
|
+
`count_deferred > 0` unconditionally. Three of the four council-decidable
|
|
84
|
+
dispositions in the preservation test — carry to a follow-up, merge into
|
|
85
|
+
existing work, restore to open — leave the `[~]` glyph in place, so a
|
|
86
|
+
genuinely UNEXECUTABLE item (one needing elapsed time rather than effort)
|
|
87
|
+
had no council-reachable path to an archived roadmap. The only glyph that
|
|
88
|
+
cleared the gate was `[-]`, which is owner-reserved AND pinned to "won't
|
|
89
|
+
happen at all"; using it for a carried item makes cancellation and transfer
|
|
90
|
+
indistinguishable to every later reader.
|
|
91
|
+
Since 2026-08-27 (AI council, 2 seats, convergent) a `[~]` step may carry
|
|
92
|
+
a machine-readable resolution, inside the step's own block:
|
|
93
|
+
```markdown
|
|
94
|
+
- [~] **4.2 Measure the false-positive rate.**
|
|
95
|
+
<!-- deferred-resolution: carried-to=road-to-some-followup -->
|
|
96
|
+
```
|
|
97
|
+
`merged-into=<slug>` is the second accepted form, for a merge into
|
|
98
|
+
pre-existing work rather than a new follow-up. `[-]` stays cancellation-only.
|
|
99
|
+
**Validation fails closed at every step** — a bare `[~]`, a malformed
|
|
100
|
+
annotation, a destination that does not exist, a destination in `archive/`
|
|
101
|
+
or `skipped/`, and (for `carried-to`) a destination with no
|
|
102
|
+
`parent_roadmap: <source-slug>` back-link each refuse the archive and print
|
|
103
|
+
which door closed. `merged-into` needs no back-link but the destination must
|
|
104
|
+
still mention the source slug. An annotation is cheap to write, so it is
|
|
105
|
+
made expensive to satisfy.
|
|
106
|
+
Three further doors, each found by an independent review of the first
|
|
107
|
+
version rather than designed in: the destination may not be the **source
|
|
108
|
+
itself** (it passes every other check and then dies with it); it may not be
|
|
109
|
+
a roadmap **this same sweep will archive** (both complete in one run leaves
|
|
110
|
+
the carried item with no receiver — the loss the annotation exists to
|
|
111
|
+
prevent, produced by the mechanism); and `merged-into` needs a
|
|
112
|
+
**structured** link — a `relates:` row or a `parent_roadmap:` line — because
|
|
113
|
+
a substring match on the source slug is satisfied by a filename, an example
|
|
114
|
+
or a comment. The back-link slug is regex-escaped: interpolated raw, a slug
|
|
115
|
+
like `road.parent` matched `roadXparent` and one containing `[` threw and
|
|
116
|
+
aborted the sweep.
|
|
117
|
+
**Not checked, and stated rather than implied:** that the destination's copy
|
|
118
|
+
of the criterion is faithful. Both council seats asked for stable item
|
|
119
|
+
identity over verbatim text matching, and neither exists today — the
|
|
120
|
+
back-link plus the source mention is the strongest link the sweep can verify
|
|
121
|
+
without inventing an identity scheme, and the human reviewing the carry is
|
|
122
|
+
still the one reading it.
|
|
123
|
+
Eligibility differs from representation: an item that is merely
|
|
124
|
+
**unfinished** (needs effort nobody spent) stays `[ ]`. Carrying it would be
|
|
125
|
+
scope laundering. Only an item that **cannot** be executed now qualifies.
|
|
126
|
+
Contract: `agents/roadmaps/*` · `src/agent-src/scripts/archive_completed_roadmaps.ts`
|
|
127
|
+
§ `deferralProblems` · `tests/scripts/archive_deferral_resolution.test.ts`.
|
|
81
128
|
17. **Follow-up roadmaps from deferred items carry `parent_roadmap`.**
|
|
82
129
|
When a roadmap closes with `[~]` deferred items, the
|
|
83
130
|
[`roadmap-management`](../skills/roadmap-management/SKILL.md) skill
|
|
@@ -193,7 +240,7 @@ that was never a judgement call.
|
|
|
193
240
|
gap-table ritual. When it fires:
|
|
194
241
|
- **(a) Gap-table before drafting.** Audit each proposed item against
|
|
195
242
|
the existing skill / command / rule surface and keep only verified
|
|
196
|
-
gaps — `KEEP` (genuine gap) / `FOLD` (into an existing
|
|
243
|
+
gaps — `KEEP` (genuine gap) / `FOLD` (into an existing artifact) /
|
|
197
244
|
`CUT` (already covered). The plan integrates, it does not dump.
|
|
198
245
|
- **(b) `## Provenance` block** — source named by a **neutral
|
|
199
246
|
descriptor** (never the raw competitor / tool name, per
|
|
@@ -467,6 +514,46 @@ that was never a judgement call.
|
|
|
467
514
|
Register: the register ranks *known* risks with mitigations; the
|
|
468
515
|
pre-mortem imagines the *whole plan dead* and reconstructs why.
|
|
469
516
|
|
|
517
|
+
26. **A consolidating roadmap declares its parent set in `consolidates:`.**
|
|
518
|
+
When a roadmap claims to fold sibling proposals into one — a "master",
|
|
519
|
+
a consolidation, a document that supersedes others — it declares every
|
|
520
|
+
parent as a frontmatter list:
|
|
521
|
+
|
|
522
|
+
```yaml
|
|
523
|
+
consolidates:
|
|
524
|
+
- road-to-first-parent.md
|
|
525
|
+
- road-to-second-parent.md
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
The field is the *only* spelling a tracked roadmap may use. Five
|
|
529
|
+
legacy spellings exist in inbox artifacts and are read by
|
|
530
|
+
`lint_consolidation_lineage` so a legacy folder parses to the same
|
|
531
|
+
parent set rather than to an empty one — `supersedes_analysis:`, a
|
|
532
|
+
prose `**Inputs consolidated:**` list, a prose `**Ersetzt als
|
|
533
|
+
führendes Proposal:**` list, a `Master-Konsolidierung` heading with a
|
|
534
|
+
table, and a prose supersession sentence. They are **deprecated
|
|
535
|
+
spellings a reader may still encounter**, never shapes to author.
|
|
536
|
+
|
|
537
|
+
Why the field rather than prose: a consolidation presents its content
|
|
538
|
+
as adjudicated — parents named, conflicts resolved, a kill register
|
|
539
|
+
for what was rejected. A parent missing from that list is not
|
|
540
|
+
*killed*, it is *undiscussed*, and nothing in the artifact
|
|
541
|
+
distinguishes those two states. Measured
|
|
542
|
+
(`agents/evidence/analysis/consolidation-lineage-census-2026-08-26.md`):
|
|
543
|
+
four inbox folders carrying a declared consolidation, four with an
|
|
544
|
+
incomplete lineage.
|
|
545
|
+
|
|
546
|
+
An omission is discharged in exactly one of three ways, never by
|
|
547
|
+
silence: fold the parent in · record a kill ID for it · state that it
|
|
548
|
+
was read and adds nothing. `/analyze:inbox` carries the obligation at
|
|
549
|
+
the point the artifacts are produced.
|
|
550
|
+
|
|
551
|
+
Reported by `lint_consolidation_lineage` — report-mode, not blocking
|
|
552
|
+
(council 2026-08-27, 2/2 convergent: the four measured cases come from
|
|
553
|
+
a high-noise drafting context and do not establish precision on the
|
|
554
|
+
tracked estate; blocking is earned by tracked-scope evidence, not
|
|
555
|
+
assumed).
|
|
556
|
+
|
|
470
557
|
---
|
|
471
558
|
|
|
472
559
|
## Quality Gates (remote CI by default)
|
|
@@ -587,8 +674,15 @@ complexity: lightweight
|
|
|
587
674
|
<!-- ## Provenance — INCLUDE ONLY for source-derived / harvest / capability-adoption
|
|
588
675
|
roadmaps (rule 19). OMIT entirely for internally-originated roadmaps —
|
|
589
676
|
do NOT ship an empty Provenance section.
|
|
590
|
-
- Source:
|
|
591
|
-
|
|
677
|
+
- Source: `agents/tmp.old/<opaque-round-id>/` — an OPAQUE round identifier
|
|
678
|
+
(`inbox-2026-08-h`, `round-a91f3c`, `S17`), never a speaking directory name.
|
|
679
|
+
The `source-header` and `tmp-quote` shape classes BLOCK inside `agents/**`, so
|
|
680
|
+
a speaking value fails CI. Naming rule: `/analyze:inbox` Phase 1.
|
|
681
|
+
- Source class, if it needs saying: <neutral descriptor> (anonymized per
|
|
682
|
+
source-confidentiality) — describe the KIND, never the identity.
|
|
683
|
+
- Identity: recorded once, encrypted, in the round's intake note; the codename
|
|
684
|
+
map is `agents/evidence/reports/source-codename-map.md`. Decrypt via
|
|
685
|
+
`src/scripts/_lib/link_crypto.ts decrypt`: ENC1:<token>
|
|
592
686
|
- Council: <members>, <date>, <depth>; convergence inlined above. -->
|
|
593
687
|
```
|
|
594
688
|
|
|
@@ -1,17 +1,36 @@
|
|
|
1
1
|
#!/usr/bin/env tsx
|
|
2
|
+
/*
|
|
3
|
+
* TEMPLATE COPY — reconciled with `src/scripts/check_memory.ts` on 2026-08-26
|
|
4
|
+
* (`road-to-memory-twin-reconciliation` 2.2, verdict `dev-side-correct`).
|
|
5
|
+
*
|
|
6
|
+
* TWO differences remain, and both are `keep-duplicated` for the same
|
|
7
|
+
* STRUCTURAL reason rather than by preference: the installed consumer tree has
|
|
8
|
+
* no `scripts/_lib/`, so a template script may import node built-ins, `yaml`
|
|
9
|
+
* and its own installed siblings — nothing else.
|
|
10
|
+
*
|
|
11
|
+
* - `assertScanned` (`_lib/scan_scope.js`), the dead-scope guard. Not
|
|
12
|
+
* importable here, and its absence is safe in the direction that matters:
|
|
13
|
+
* a consumer with no `agents/memory/` scans zero and passes, which is the
|
|
14
|
+
* correct reading for a project that keeps no memory.
|
|
15
|
+
* - `asOf` (`_lib/as_of.js`), the reproducible-clock pin behind this
|
|
16
|
+
* repository's own `AC_AS_OF` discipline. A consumer has no such pin, so
|
|
17
|
+
* `new Date()` is the right substitute rather than a downgrade.
|
|
18
|
+
*
|
|
19
|
+
* Everything else is identical, INCLUDING the validations this copy used to
|
|
20
|
+
* lack entirely: the `priority` enum, the critical-stale SLA, the one-fact
|
|
21
|
+
* length limit, relative-date discipline, per-type caps, tier-0 inflation, and
|
|
22
|
+
* `status: superseded`.
|
|
23
|
+
*/
|
|
2
24
|
/**
|
|
3
25
|
* Engineering Memory validator.
|
|
4
26
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* `--base`), same exit codes, same stdout/stderr split, byte-identical finding
|
|
13
|
-
* messages, same scan scope and ordering. No behaviour changes — latent bugs
|
|
14
|
-
* are replicated and flagged in the porting report, not fixed.
|
|
27
|
+
* Ported from the retired Python `src/scripts/check_memory.py` (ADR-200, Phase 4 /
|
|
28
|
+
* Wave 4a). The CLI contract pins the historical contract exactly — same
|
|
29
|
+
* flags (`--path`, `--format`, `--append-only`, `--base`), same exit
|
|
30
|
+
* codes, same stdout/stderr split,
|
|
31
|
+
* byte-identical finding messages, same scan scope and ordering. No
|
|
32
|
+
* behaviour changes — latent bugs are replicated and flagged in the
|
|
33
|
+
* porting report, not fixed.
|
|
15
34
|
*
|
|
16
35
|
* Validates YAML files under `agents/memory/<type>/**\/*.yml` against the
|
|
17
36
|
* schema documented in `guidelines/agent-infra/engineering-memory-data-format`.
|
|
@@ -39,7 +58,7 @@
|
|
|
39
58
|
* check_memory --append-only # CI: diff vs origin/main
|
|
40
59
|
* check_memory --append-only --base HEAD~1
|
|
41
60
|
*
|
|
42
|
-
* Note on YAML date typing: the Python
|
|
61
|
+
* Note on YAML date typing: the retired Python implementation relies on PyYAML's
|
|
43
62
|
* `safe_load` converting unquoted `YYYY-MM-DD` scalars to `datetime.date`
|
|
44
63
|
* (and `YYYY-MM-DD HH:MM:SS` to `datetime.datetime`). The `yaml` npm
|
|
45
64
|
* package parses every scalar to a string, so this twin re-implements
|
|
@@ -56,6 +75,7 @@ import process from 'node:process';
|
|
|
56
75
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
57
76
|
import YAML, { parseDocument } from 'yaml';
|
|
58
77
|
|
|
78
|
+
|
|
59
79
|
type Severity = 'error' | 'warning' | 'info';
|
|
60
80
|
|
|
61
81
|
const REQUIRED_KEYS: ReadonlySet<string> = new Set([
|
|
@@ -67,14 +87,48 @@ const REQUIRED_KEYS: ReadonlySet<string> = new Set([
|
|
|
67
87
|
'last_validated',
|
|
68
88
|
'review_after_days',
|
|
69
89
|
]);
|
|
70
|
-
const VALID_STATUS: ReadonlySet<string> = new Set(['active', 'deprecated', 'archived']);
|
|
90
|
+
const VALID_STATUS: ReadonlySet<string> = new Set(['active', 'deprecated', 'archived', 'superseded']);
|
|
71
91
|
const VALID_CONFIDENCE: ReadonlySet<string> = new Set(['low', 'medium', 'high']);
|
|
92
|
+
// `priority` is optional (default `normal`); enum is the smallest set that
|
|
93
|
+
// solves the tier-0 surfacing use case. See the Phase 2 council brief for why
|
|
94
|
+
// the `high` tier was rejected.
|
|
95
|
+
const VALID_PRIORITY: ReadonlySet<string> = new Set(['critical', 'normal', 'low']);
|
|
96
|
+
// Soft-cap on `priority: critical` entries per memory type. Tier-0 inflation
|
|
97
|
+
// is the failure mode: when too many entries claim "always surface", the
|
|
98
|
+
// slice loses signal. Warn (not fail) when the cap is exceeded so curators
|
|
99
|
+
// notice without being blocked.
|
|
100
|
+
const CRITICAL_WARN_THRESHOLD = 10;
|
|
101
|
+
// Stale-critical guard: a `priority: critical` entry that hasn't been
|
|
102
|
+
// re-validated in this many days emits a warning. Surfaced separately
|
|
103
|
+
// from the generic `stale:` info so reviewers see it before merge.
|
|
104
|
+
const CRITICAL_STALE_DAYS = 90;
|
|
72
105
|
const KNOWN_TYPES: ReadonlySet<string> = new Set([
|
|
73
106
|
'domain-invariants',
|
|
107
|
+
'historical-patterns',
|
|
74
108
|
'incident-learnings',
|
|
109
|
+
'ownership',
|
|
75
110
|
'product-rules',
|
|
76
111
|
]);
|
|
77
112
|
|
|
113
|
+
// Per-type soft entry cap (size-bounding without a decay engine). Over-cap →
|
|
114
|
+
// warning, never a hard fail: the right answer to bloat is a consolidation pass
|
|
115
|
+
// (prune archived, merge duplicates), not CI failure. See
|
|
116
|
+
// road-to-memory-pipeline-consolidation.md Phase 7.
|
|
117
|
+
const PER_TYPE_CAPS: Readonly<Record<string, number>> = {
|
|
118
|
+
ownership: 50,
|
|
119
|
+
'domain-invariants': 150,
|
|
120
|
+
'product-rules': 100,
|
|
121
|
+
'incident-learnings': 150,
|
|
122
|
+
'historical-patterns': 150,
|
|
123
|
+
};
|
|
124
|
+
const DEFAULT_TYPE_CAP = 150;
|
|
125
|
+
// One-durable-fact-per-entry: a content field longer than this reads as a
|
|
126
|
+
// transcript / narrative blob, not a single durable fact → warning.
|
|
127
|
+
const ONE_FACT_MAX_CHARS = 600;
|
|
128
|
+
const ONE_FACT_FIELDS = ['rule', 'pattern', 'statement', 'observation', 'body', 'decision', 'note'] as const;
|
|
129
|
+
// Per-type entry tally, populated during validation, consumed by main().
|
|
130
|
+
const _TYPE_COUNTS: Record<string, number> = {};
|
|
131
|
+
|
|
78
132
|
// Redaction heuristics — plain-regex, deliberately conservative.
|
|
79
133
|
// False positives are fixed by quoting the line differently; false
|
|
80
134
|
// negatives are a curator responsibility.
|
|
@@ -90,6 +144,15 @@ const REDACTION_PATTERNS: ReadonlyArray<readonly [RegExp, string]> = [
|
|
|
90
144
|
[/\b192\.168\.\d{1,3}\.\d{1,3}\b/, 'internal ipv4 range'],
|
|
91
145
|
];
|
|
92
146
|
|
|
147
|
+
// Date-discipline — relative-date phrases without an ISO YYYY-MM-DD anchor
|
|
148
|
+
// within ±20 chars are rejected. Memory entries that say "yesterday" or
|
|
149
|
+
// "last week" rot the moment the file is re-read on another day; the
|
|
150
|
+
// anchor pins meaning.
|
|
151
|
+
const RELATIVE_DATE_PATTERN =
|
|
152
|
+
/\b(yesterday|today|tomorrow|last\s+(?:week|month|year)|next\s+(?:week|month|year)|this\s+(?:week|month|year))\b/gi;
|
|
153
|
+
const ISO_DATE_PATTERN = /\b\d{4}-\d{2}-\d{2}\b/;
|
|
154
|
+
const DATE_ANCHOR_WINDOW = 20;
|
|
155
|
+
|
|
93
156
|
// PyYAML timestamp implicit-resolver. A *plain* (unquoted) scalar matching
|
|
94
157
|
// this is constructed as datetime.date / datetime.datetime — both pass
|
|
95
158
|
// `isinstance(value, datetime.date)`. Source: yaml/resolver.py.
|
|
@@ -246,6 +309,15 @@ function _isInteger(v: unknown): v is number {
|
|
|
246
309
|
return typeof v === 'number' && Number.isInteger(v);
|
|
247
310
|
}
|
|
248
311
|
|
|
312
|
+
/** Mirror Python len(str) — code-point count, not UTF-16 unit count. */
|
|
313
|
+
function _pyLen(s: string): number {
|
|
314
|
+
let n = 0;
|
|
315
|
+
for (const _ of s) {
|
|
316
|
+
n += 1;
|
|
317
|
+
}
|
|
318
|
+
return n;
|
|
319
|
+
}
|
|
320
|
+
|
|
249
321
|
function _memoryType(p: string): string {
|
|
250
322
|
// Supports `memory/<type>.yml`, `memory/<type>/<hash>.yml`, and
|
|
251
323
|
// `memory/<type>.example.yml` template filenames.
|
|
@@ -270,7 +342,13 @@ function _stem(name: string): string {
|
|
|
270
342
|
return base.slice(0, dot);
|
|
271
343
|
}
|
|
272
344
|
|
|
273
|
-
function _validateEntry(
|
|
345
|
+
function _validateEntry(
|
|
346
|
+
entry: Entry,
|
|
347
|
+
p: string,
|
|
348
|
+
seenIds: Set<string>,
|
|
349
|
+
findings: Finding[],
|
|
350
|
+
criticalCounts: Record<string, number> | null,
|
|
351
|
+
): void {
|
|
274
352
|
const eid = typeof entry['id'] === 'string' ? (entry['id'] as string) : entry['id'] != null ? String(entry['id']) : '';
|
|
275
353
|
const eidStr = entry['id'] == null ? '' : eid;
|
|
276
354
|
const present = new Set(Object.keys(entry));
|
|
@@ -292,6 +370,22 @@ function _validateEntry(entry: Entry, p: string, seenIds: Set<string>, findings:
|
|
|
292
370
|
if (confidence && typeof confidence === 'string' && !VALID_CONFIDENCE.has(confidence)) {
|
|
293
371
|
findings.push(new Finding(p, 0, 'error', `invalid confidence '${confidence}'`, eidStr));
|
|
294
372
|
}
|
|
373
|
+
// Priority is optional (defaults to `normal` at read time). When present
|
|
374
|
+
// it MUST be one of the three-tier enum — see VALID_PRIORITY for the
|
|
375
|
+
// rationale on rejecting a fourth `high` tier.
|
|
376
|
+
const priority = entry['priority'];
|
|
377
|
+
if (priority !== undefined && priority !== null && !(typeof priority === 'string' && VALID_PRIORITY.has(priority))) {
|
|
378
|
+
const sortedPri = [...VALID_PRIORITY].sort();
|
|
379
|
+
findings.push(
|
|
380
|
+
new Finding(
|
|
381
|
+
p,
|
|
382
|
+
0,
|
|
383
|
+
'error',
|
|
384
|
+
`invalid priority '${_pyStr(priority)}' (expected one of [${sortedPri.map((x) => `'${x}'`).join(', ')}])`,
|
|
385
|
+
eidStr,
|
|
386
|
+
),
|
|
387
|
+
);
|
|
388
|
+
}
|
|
295
389
|
const sources = (entry['source'] ?? []) as unknown;
|
|
296
390
|
if (!Array.isArray(sources) || sources.length < 1) {
|
|
297
391
|
findings.push(new Finding(p, 0, 'error', 'source must be a list with ≥1 entry', eidStr));
|
|
@@ -309,6 +403,71 @@ function _validateEntry(entry: Entry, p: string, seenIds: Set<string>, findings:
|
|
|
309
403
|
findings.push(new Finding(p, 0, 'info', `stale: last_validated ${age} days ago (limit ${days})`, eidStr));
|
|
310
404
|
}
|
|
311
405
|
}
|
|
406
|
+
// Critical-stale guard: a `priority: critical` entry that has not been
|
|
407
|
+
// re-validated within CRITICAL_STALE_DAYS surfaces as a warning, even
|
|
408
|
+
// when the entry's own `review_after_days` is more lenient. Critical
|
|
409
|
+
// entries surface on every /memory:load — they have a tighter SLA.
|
|
410
|
+
if (priority === 'critical' && entry['status'] === 'active' && lv instanceof PyDate) {
|
|
411
|
+
const critAge = _dateDiffDays(_today(), lv);
|
|
412
|
+
if (critAge > CRITICAL_STALE_DAYS) {
|
|
413
|
+
findings.push(
|
|
414
|
+
new Finding(
|
|
415
|
+
p,
|
|
416
|
+
0,
|
|
417
|
+
'warning',
|
|
418
|
+
`critical-stale: last_validated ${critAge} days ago (critical SLA is ${CRITICAL_STALE_DAYS} days)`,
|
|
419
|
+
eidStr,
|
|
420
|
+
),
|
|
421
|
+
);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
// One-durable-fact-per-entry: reject transcript/narrative blobs. A single
|
|
425
|
+
// content field over ONE_FACT_MAX_CHARS is the bloat signal.
|
|
426
|
+
for (const fld of ONE_FACT_FIELDS) {
|
|
427
|
+
const val = entry[fld];
|
|
428
|
+
if (typeof val === 'string' && _pyLen(val) > ONE_FACT_MAX_CHARS) {
|
|
429
|
+
findings.push(
|
|
430
|
+
new Finding(
|
|
431
|
+
p,
|
|
432
|
+
0,
|
|
433
|
+
'warning',
|
|
434
|
+
`one-fact: \`${fld}\` is ${_pyLen(val)} chars (limit ${ONE_FACT_MAX_CHARS}) — split into separate durable facts, not a narrative blob`,
|
|
435
|
+
eidStr,
|
|
436
|
+
),
|
|
437
|
+
);
|
|
438
|
+
break;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
// Tier-0 inflation tracking — increment per memory type. The aggregate
|
|
442
|
+
// warning is emitted in main() after all files are validated.
|
|
443
|
+
if (criticalCounts !== null && priority === 'critical' && entry['status'] === 'active') {
|
|
444
|
+
const mtype = _memoryType(p);
|
|
445
|
+
criticalCounts[mtype] = (criticalCounts[mtype] ?? 0) + 1;
|
|
446
|
+
}
|
|
447
|
+
// Per-type entry-count tracking — aggregate cap warning in main().
|
|
448
|
+
if (criticalCounts !== null) {
|
|
449
|
+
const mt = _memoryType(p);
|
|
450
|
+
_TYPE_COUNTS[mt] = (_TYPE_COUNTS[mt] ?? 0) + 1;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/** Mirror Python's `str(value)` for the priority error message. */
|
|
455
|
+
function _pyStr(value: unknown): string {
|
|
456
|
+
if (value === null) {
|
|
457
|
+
return 'None';
|
|
458
|
+
}
|
|
459
|
+
if (value === true) {
|
|
460
|
+
return 'True';
|
|
461
|
+
}
|
|
462
|
+
if (value === false) {
|
|
463
|
+
return 'False';
|
|
464
|
+
}
|
|
465
|
+
if (value instanceof PyDate) {
|
|
466
|
+
const mm = String(value.month).padStart(2, '0');
|
|
467
|
+
const dd = String(value.day).padStart(2, '0');
|
|
468
|
+
return `${value.year}-${mm}-${dd}`;
|
|
469
|
+
}
|
|
470
|
+
return String(value);
|
|
312
471
|
}
|
|
313
472
|
|
|
314
473
|
function _checkRedaction(p: string, findings: Finding[]): void {
|
|
@@ -328,6 +487,38 @@ function _checkRedaction(p: string, findings: Finding[]): void {
|
|
|
328
487
|
});
|
|
329
488
|
}
|
|
330
489
|
|
|
490
|
+
function _checkDateDiscipline(p: string, findings: Finding[]): void {
|
|
491
|
+
// Reject relative-date phrases without an ISO YYYY-MM-DD anchor.
|
|
492
|
+
const text = fs.readFileSync(p, 'utf-8');
|
|
493
|
+
const lines = _splitlines(text);
|
|
494
|
+
lines.forEach((line, idx) => {
|
|
495
|
+
const lineNo = idx + 1;
|
|
496
|
+
const stripped = line.trimStart();
|
|
497
|
+
if (stripped.startsWith('#') || stripped.startsWith('last_validated')) {
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
RELATIVE_DATE_PATTERN.lastIndex = 0;
|
|
501
|
+
let match: RegExpExecArray | null;
|
|
502
|
+
while ((match = RELATIVE_DATE_PATTERN.exec(line)) !== null) {
|
|
503
|
+
const start = Math.max(0, match.index - DATE_ANCHOR_WINDOW);
|
|
504
|
+
const end = Math.min(line.length, match.index + match[0].length + DATE_ANCHOR_WINDOW);
|
|
505
|
+
const windowStr = line.slice(start, end);
|
|
506
|
+
if (ISO_DATE_PATTERN.test(windowStr)) {
|
|
507
|
+
continue;
|
|
508
|
+
}
|
|
509
|
+
const phrase = match[0];
|
|
510
|
+
findings.push(
|
|
511
|
+
new Finding(
|
|
512
|
+
p,
|
|
513
|
+
lineNo,
|
|
514
|
+
'error',
|
|
515
|
+
`relative date '${phrase}' without an ISO YYYY-MM-DD anchor within ±${DATE_ANCHOR_WINDOW} chars (re-anchor before commit)`,
|
|
516
|
+
),
|
|
517
|
+
);
|
|
518
|
+
}
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
|
|
331
522
|
/** Mirror Python str.splitlines() for the line-numbering used above. */
|
|
332
523
|
function _splitlines(text: string): string[] {
|
|
333
524
|
if (text === '') {
|
|
@@ -342,12 +533,17 @@ function _splitlines(text: string): string[] {
|
|
|
342
533
|
return lines;
|
|
343
534
|
}
|
|
344
535
|
|
|
345
|
-
function _validateFile(
|
|
536
|
+
function _validateFile(
|
|
537
|
+
p: string,
|
|
538
|
+
findings: Finding[],
|
|
539
|
+
criticalCounts: Record<string, number> | null,
|
|
540
|
+
): void {
|
|
346
541
|
const mtype = _memoryType(p);
|
|
347
542
|
if (!KNOWN_TYPES.has(mtype)) {
|
|
348
543
|
findings.push(new Finding(p, 0, 'warning', `unknown memory type '${mtype}'`));
|
|
349
544
|
}
|
|
350
545
|
_checkRedaction(p, findings);
|
|
546
|
+
_checkDateDiscipline(p, findings);
|
|
351
547
|
let data: unknown;
|
|
352
548
|
try {
|
|
353
549
|
data = pyYamlSafeLoad(fs.readFileSync(p, 'utf-8'));
|
|
@@ -369,7 +565,7 @@ function _validateFile(p: string, findings: Finding[]): void {
|
|
|
369
565
|
if (Array.isArray(entries)) {
|
|
370
566
|
for (const entry of entries) {
|
|
371
567
|
if (_isPlainObject(entry)) {
|
|
372
|
-
_validateEntry(entry as Entry, p, seenIds, findings);
|
|
568
|
+
_validateEntry(entry as Entry, p, seenIds, findings, criticalCounts);
|
|
373
569
|
}
|
|
374
570
|
}
|
|
375
571
|
}
|
|
@@ -549,8 +745,53 @@ function main(): number {
|
|
|
549
745
|
}
|
|
550
746
|
return 0;
|
|
551
747
|
}
|
|
552
|
-
|
|
553
|
-
|
|
748
|
+
// An ABSENT root stays a pinned exit-0 no-op (the branch above; the memory
|
|
749
|
+
// tree is an optional surface and `task check-memory` short-circuits it).
|
|
750
|
+
// A root that EXISTS but walks to zero `*.yml` is the case nothing covered:
|
|
751
|
+
// entries moved to a subtree this walk does not reach, and the validator
|
|
752
|
+
// reported "0 error(s)" over an empty read. No `allowEmpty` for that half —
|
|
753
|
+
// a present-but-unreadable corpus is blindness, not a clean bill of health.
|
|
754
|
+
// Exit 1 is this gate's only failure code (see `_emit`).
|
|
755
|
+
// No dead-scope guard: `_lib/scan_scope.js` is not installed with the
|
|
756
|
+
// template, and a consumer with no `agents/memory/` legitimately scans zero.
|
|
757
|
+
const ymls = _rglobYmlSorted(root);
|
|
758
|
+
|
|
759
|
+
const criticalCounts: Record<string, number> = {};
|
|
760
|
+
for (const key of Object.keys(_TYPE_COUNTS)) {
|
|
761
|
+
delete _TYPE_COUNTS[key];
|
|
762
|
+
}
|
|
763
|
+
for (const yml of ymls) {
|
|
764
|
+
_validateFile(yml, findings, criticalCounts);
|
|
765
|
+
}
|
|
766
|
+
// Tier-0 inflation warning — soft cap on `priority: critical` per type.
|
|
767
|
+
// Council convergence (Phase 2 B2): warn rather than block, because the
|
|
768
|
+
// right answer to "too many criticals" is curator review, not CI failure.
|
|
769
|
+
for (const [mtype, count] of Object.entries(criticalCounts).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))) {
|
|
770
|
+
if (count > CRITICAL_WARN_THRESHOLD) {
|
|
771
|
+
findings.push(
|
|
772
|
+
new Finding(
|
|
773
|
+
`agents/memory/${mtype}`,
|
|
774
|
+
0,
|
|
775
|
+
'warning',
|
|
776
|
+
`tier-0 inflation: ${count} active 'priority: critical' entries (threshold ${CRITICAL_WARN_THRESHOLD}) — review whether all still warrant always-surface treatment`,
|
|
777
|
+
),
|
|
778
|
+
);
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
// Per-type entry-count cap (size-bounding, Phase 7). Warn, never block —
|
|
782
|
+
// over-cap signals a consolidation pass is due (prune archived, merge dups).
|
|
783
|
+
for (const [mtype, count] of Object.entries(_TYPE_COUNTS).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))) {
|
|
784
|
+
const cap = PER_TYPE_CAPS[mtype] ?? DEFAULT_TYPE_CAP;
|
|
785
|
+
if (count > cap) {
|
|
786
|
+
findings.push(
|
|
787
|
+
new Finding(
|
|
788
|
+
`agents/memory/${mtype}`,
|
|
789
|
+
0,
|
|
790
|
+
'warning',
|
|
791
|
+
`entry-cap: ${count} entries (soft cap ${cap}) — run a consolidation pass (prune archived, merge duplicates)`,
|
|
792
|
+
),
|
|
793
|
+
);
|
|
794
|
+
}
|
|
554
795
|
}
|
|
555
796
|
return _emit(findings, args.format);
|
|
556
797
|
}
|