@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
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* source_digest — keyed digests for the source deny set
|
|
4
|
+
* (`road-to-source-silence` Phase 1.1).
|
|
5
|
+
*
|
|
6
|
+
* ## The problem
|
|
7
|
+
*
|
|
8
|
+
* `external_sources_denylist.json` publishes, in plaintext in a public
|
|
9
|
+
* repository, 65 names of the harvest sources it exists to hide. The list IS
|
|
10
|
+
* the disclosure. Phase 1's answer is to stop shipping the names: the tracked
|
|
11
|
+
* config carries **HMAC-SHA256 digests**, the readable master lives in a
|
|
12
|
+
* gitignored private file, and a build step derives one from the other.
|
|
13
|
+
*
|
|
14
|
+
* ## Why keyed and not a plain hash
|
|
15
|
+
*
|
|
16
|
+
* The candidate space is public repository slugs — a few million entries,
|
|
17
|
+
* enumerable in minutes. An unsalted SHA-256 of a slug is a lookup, not a
|
|
18
|
+
* secret. The construction is therefore keyed: without the key a digest is not
|
|
19
|
+
* reversible by dictionary attack, and with the key the gate matches exactly as
|
|
20
|
+
* a name list would.
|
|
21
|
+
*
|
|
22
|
+
* ## STATUS: DORMANT. This ships ALONGSIDE the plaintext gate, not instead of it.
|
|
23
|
+
*
|
|
24
|
+
* AI council 2026-08-28 (blocker `where-the-key-lives`), 2/2 convergent:
|
|
25
|
+
* shipping this as a REPLACEMENT is net-negative, because the half an agent can
|
|
26
|
+
* build is precisely the half that enforces nothing. Provisioning the CI
|
|
27
|
+
* secret, generating production digests, deleting the tracked plaintext deny
|
|
28
|
+
* array, and switching CI to strict mode are **one atomic maintainer change**;
|
|
29
|
+
* splitting them leaves the gate either failing every run for want of a key or
|
|
30
|
+
* silently degraded to warn mode, which is the exact failure the roadmap exists
|
|
31
|
+
* to remove.
|
|
32
|
+
*
|
|
33
|
+
* So: the plaintext `deny` array stays in force and is not deleted, and
|
|
34
|
+
* `deny_digests` ships EMPTY. When it is empty this module does no work at all.
|
|
35
|
+
* The cutover recipe is in `docs/maintainers/source-deny-digests.md`.
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
import * as crypto from 'node:crypto';
|
|
39
|
+
|
|
40
|
+
/** Environment variable carrying the HMAC key (CI secret / local `.env`). */
|
|
41
|
+
export const KEY_ENV = 'SOURCE_DENY_KEY';
|
|
42
|
+
|
|
43
|
+
/** Environment variable that makes a missing key fatal instead of dormant. */
|
|
44
|
+
export const STRICT_ENV = 'SOURCE_DENY_STRICT';
|
|
45
|
+
|
|
46
|
+
/** Exit code for "strict mode asked for, key absent". Never 0 — see Phase 1.2. */
|
|
47
|
+
export const EXIT_NO_KEY = 3;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Fold a candidate to its comparison form.
|
|
51
|
+
*
|
|
52
|
+
* Lowercase, every separator run (`-`, `_`, `.`, `/`, whitespace) collapsed to a
|
|
53
|
+
* single `-`, edges trimmed. `Foo_Bar`, `foo.bar`, `foo/bar` and `FOO - BAR` all
|
|
54
|
+
* reach the same digest, so a source cannot be smuggled past the set by
|
|
55
|
+
* re-punctuating its name.
|
|
56
|
+
*/
|
|
57
|
+
export function normalise(token: string): string {
|
|
58
|
+
return token
|
|
59
|
+
.toLowerCase()
|
|
60
|
+
.replace(/[\s._/\\-]+/g, '-')
|
|
61
|
+
.replace(/^-+|-+$/g, '');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** HMAC-SHA256 of the normalised token, lowercase hex. */
|
|
65
|
+
export function digest(token: string, key: string): string {
|
|
66
|
+
if (!key) throw new Error('empty digest key');
|
|
67
|
+
return crypto.createHmac('sha256', key).update(normalise(token), 'utf-8').digest('hex');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** A digest as it must appear in the config. */
|
|
71
|
+
export const DIGEST_RE = /^[0-9a-f]{64}$/;
|
|
72
|
+
|
|
73
|
+
/** Word-ish runs a source name could occupy. */
|
|
74
|
+
const WORD_RE = /[A-Za-z0-9][A-Za-z0-9._-]{2,80}/g;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* The candidate tokens on one line.
|
|
78
|
+
*
|
|
79
|
+
* A digest cannot be regex-matched, so the line is tokenised and each candidate
|
|
80
|
+
* hashed. Three shapes are produced per word run: the run itself, the run
|
|
81
|
+
* joined to its right-hand neighbour across a `/` (the `owner/repo` form), and
|
|
82
|
+
* the same across a `-`. That is a deliberate ceiling: an attribution spread
|
|
83
|
+
* over more than two adjacent tokens is not caught, and the module docstring of
|
|
84
|
+
* `source_shape.ts` says the same thing about its own classes — a floor, not a
|
|
85
|
+
* proof.
|
|
86
|
+
*/
|
|
87
|
+
export function candidateTokens(line: string): string[] {
|
|
88
|
+
const words: string[] = [];
|
|
89
|
+
WORD_RE.lastIndex = 0;
|
|
90
|
+
let m: RegExpExecArray | null;
|
|
91
|
+
const spans: Array<{ text: string; end: number; start: number }> = [];
|
|
92
|
+
while ((m = WORD_RE.exec(line)) !== null) {
|
|
93
|
+
spans.push({ text: m[0], start: m.index, end: m.index + m[0].length });
|
|
94
|
+
}
|
|
95
|
+
for (let i = 0; i < spans.length; i += 1) {
|
|
96
|
+
const cur = spans[i] as { text: string; end: number; start: number };
|
|
97
|
+
words.push(cur.text);
|
|
98
|
+
const next = spans[i + 1];
|
|
99
|
+
if (!next) continue;
|
|
100
|
+
const between = line.slice(cur.end, next.start);
|
|
101
|
+
if (between === '/' || between === '-') words.push(`${cur.text}${between}${next.text}`);
|
|
102
|
+
}
|
|
103
|
+
return words;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* A digest matcher over one deny set. Memoises per normalised token, so the
|
|
108
|
+
* per-line cost is a Map lookup once a token has been seen anywhere in the run.
|
|
109
|
+
*/
|
|
110
|
+
export class DigestMatcher {
|
|
111
|
+
private readonly set: ReadonlySet<string>;
|
|
112
|
+
private readonly key: string;
|
|
113
|
+
private readonly memo = new Map<string, boolean>();
|
|
114
|
+
|
|
115
|
+
constructor(digests: readonly string[], key: string) {
|
|
116
|
+
this.set = new Set(digests.map((d) => d.toLowerCase()));
|
|
117
|
+
this.key = key;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** Is this raw token in the deny set? */
|
|
121
|
+
has(token: string): boolean {
|
|
122
|
+
const norm = normalise(token);
|
|
123
|
+
if (norm.length < 3) return false;
|
|
124
|
+
const cached = this.memo.get(norm);
|
|
125
|
+
if (cached !== undefined) return cached;
|
|
126
|
+
const hit = this.set.has(digest(norm, this.key));
|
|
127
|
+
this.memo.set(norm, hit);
|
|
128
|
+
return hit;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** The denied tokens on one line, deduplicated, normalised form. */
|
|
132
|
+
hits(line: string): string[] {
|
|
133
|
+
const out = new Set<string>();
|
|
134
|
+
for (const t of candidateTokens(line)) if (this.has(t)) out.add(normalise(t));
|
|
135
|
+
return [...out];
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
get size(): number {
|
|
139
|
+
return this.set.size;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export interface DigestModeVerdict {
|
|
144
|
+
/** Digest matching is active this run. */
|
|
145
|
+
active: boolean;
|
|
146
|
+
/** Digests present in the config. */
|
|
147
|
+
digests: number;
|
|
148
|
+
/** Set, but the key is missing. */
|
|
149
|
+
keyMissing: boolean;
|
|
150
|
+
/** Strict mode was requested. */
|
|
151
|
+
strict: boolean;
|
|
152
|
+
/** One line for stdout/stderr. Empty when there is nothing to say. */
|
|
153
|
+
message: string;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Decide what digest matching does this run — the loud-when-keyless contract
|
|
158
|
+
* from Phase 1.2.
|
|
159
|
+
*
|
|
160
|
+
* | digests | key | strict | verdict |
|
|
161
|
+
* |---|---|---|---|
|
|
162
|
+
* | none | — | no | dormant, silent (today's shipped state) |
|
|
163
|
+
* | none | — | yes | **fatal**: strict asked for and there is nothing to enforce |
|
|
164
|
+
* | some | absent | no | **loud warning**, matching skipped — never silently green |
|
|
165
|
+
* | some | absent | yes | **fatal** (`EXIT_NO_KEY`) |
|
|
166
|
+
* | some | present | — | active |
|
|
167
|
+
*/
|
|
168
|
+
export function digestMode(opts: {
|
|
169
|
+
digests: readonly string[];
|
|
170
|
+
key: string | undefined;
|
|
171
|
+
strict: boolean;
|
|
172
|
+
}): DigestModeVerdict {
|
|
173
|
+
const n = opts.digests.length;
|
|
174
|
+
const key = opts.key ?? '';
|
|
175
|
+
if (n === 0) {
|
|
176
|
+
return {
|
|
177
|
+
active: false,
|
|
178
|
+
digests: 0,
|
|
179
|
+
keyMissing: false,
|
|
180
|
+
strict: opts.strict,
|
|
181
|
+
message: opts.strict
|
|
182
|
+
? `${STRICT_ENV} is set but the config carries no deny_digests — strict mode has ` +
|
|
183
|
+
'nothing to enforce. Run the digest build step before enabling strict mode.'
|
|
184
|
+
: '',
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
if (key === '') {
|
|
188
|
+
return {
|
|
189
|
+
active: false,
|
|
190
|
+
digests: n,
|
|
191
|
+
keyMissing: true,
|
|
192
|
+
strict: opts.strict,
|
|
193
|
+
message:
|
|
194
|
+
`⚠️ ${String(n)} deny digest(s) present but ${KEY_ENV} is unset — digest matching ` +
|
|
195
|
+
'is SKIPPED this run. This run did NOT check the hashed deny set. Set ' +
|
|
196
|
+
`${KEY_ENV} (CI secret / local .env) to enforce it.`,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
return { active: true, digests: n, keyMissing: false, strict: opts.strict, message: '' };
|
|
200
|
+
}
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* source_redact — write-time deny-set redaction for generated evidence
|
|
3
|
+
* snapshots (`road-to-source-silence` Phase 3.4).
|
|
4
|
+
*
|
|
5
|
+
* ## Why a redactor and not a skip_path
|
|
6
|
+
*
|
|
7
|
+
* The R2 reviewer input package (`<slug>.review-input/`) is a VERBATIM snapshot
|
|
8
|
+
* of a branch diff. A diff that happens to touch a line naming a harvest source
|
|
9
|
+
* carries that name into a tracked evidence file, which is why
|
|
10
|
+
* `agents/evidence/reviews/*.review-input/diff.patch` sat in the gate's
|
|
11
|
+
* `skip_paths` — a blanket exemption over a whole generated class.
|
|
12
|
+
*
|
|
13
|
+
* A blanket exemption is the wrong shape: it does not stop the leak, it stops
|
|
14
|
+
* the gate from seeing it. The generator is the one place that can fix the
|
|
15
|
+
* content instead, because it is the only writer. So the redaction happens at
|
|
16
|
+
* WRITE time and the snapshot stays readable and diffable.
|
|
17
|
+
*
|
|
18
|
+
* ## The exemption is still there, and this docstring will not pretend otherwise
|
|
19
|
+
*
|
|
20
|
+
* Step 3.4's second half — deleting the `skip_paths` entry — is NOT done, and
|
|
21
|
+
* the reason is a measurement that falsified the step's premise. Removing the
|
|
22
|
+
* entry exposed two populations, not one:
|
|
23
|
+
*
|
|
24
|
+
* - **120 exact deny hits**, all in a single snapshot. A backfill run of this
|
|
25
|
+
* module cleared every one of them (118 substitutions); those names are gone
|
|
26
|
+
* from the tracked tree permanently. This half worked exactly as designed.
|
|
27
|
+
* - **+26 attribution-SHAPE findings** at the block tier, taking the shrink-only
|
|
28
|
+
* ratchet from 275 to 301 and reddening CI. Write-time redaction of exact
|
|
29
|
+
* names cannot clear these, because they are heuristic matches, not names.
|
|
30
|
+
*
|
|
31
|
+
* The AI council (anthropic + openai, 2026-08-29) was asked what to do and
|
|
32
|
+
* **rejected the tempting answer**: tiering `*.review-input/` down to `warn`
|
|
33
|
+
* was refused by both seats as a gate weakening performed by the party that
|
|
34
|
+
* benefits from it, and — the sharper objection — because the claim that all 26
|
|
35
|
+
* findings are mere mirrors of already-counted tracked content was never
|
|
36
|
+
* verified. A diff can carry deleted lines, renamed paths and other preimage
|
|
37
|
+
* content that exists nowhere in the current tree.
|
|
38
|
+
*
|
|
39
|
+
* So the exemption stays, the roadmap step stays honestly open, and the path to
|
|
40
|
+
* closing it is recorded rather than improvised: provenance-aware deduplication
|
|
41
|
+
* that excludes a snapshot finding from the ratchet only when an identical
|
|
42
|
+
* class/value occurrence is independently block-counted in the corresponding
|
|
43
|
+
* current tracked file, with unique, deleted-only, malformed and unverifiable
|
|
44
|
+
* findings all remaining `block`.
|
|
45
|
+
*
|
|
46
|
+
* ## What it does NOT do
|
|
47
|
+
*
|
|
48
|
+
* - It does not touch the live tree. It only rewrites strings a generator is
|
|
49
|
+
* about to write into an evidence artefact.
|
|
50
|
+
* - It does not redact SHAPE findings (a speaking `**Source:**` header, a
|
|
51
|
+
* quoted `agents/tmp/<name>/` path). Those are heuristics with a measured
|
|
52
|
+
* false-positive tail, and redacting on a heuristic silently corrupts a diff
|
|
53
|
+
* a reviewer has to read. A deny entry names a source; a shape match guesses
|
|
54
|
+
* at one.
|
|
55
|
+
* - **The deny entries are REGEXES, not literals, and that is deliberate.** A
|
|
56
|
+
* cross-model review recommended escaping their metacharacters to make them
|
|
57
|
+
* exact-match. Measured before acting: 13 of the 65 shipped entries use `\b`
|
|
58
|
+
* word boundaries, so escaping would turn a working boundary assertion into a
|
|
59
|
+
* literal backslash-b and those 13 would stop matching entirely. More
|
|
60
|
+
* importantly the GATE compiles them as regexes too, so escaping here would
|
|
61
|
+
* make the redactor MISS tokens the gate still catches — a file that fails
|
|
62
|
+
* the gate and that this module declined to clean. Matching the gate exactly
|
|
63
|
+
* is the invariant; an earlier version of this docstring called the set
|
|
64
|
+
* "exact-match", which was simply wrong.
|
|
65
|
+
* - It does not preserve length or reversibility. The marker is deliberately
|
|
66
|
+
* fixed-width and opaque: a length-preserving redaction leaks the length.
|
|
67
|
+
*
|
|
68
|
+
* ## The evidence chain stays intact
|
|
69
|
+
*
|
|
70
|
+
* Redaction is **token-local**: it replaces matched spans and leaves every other
|
|
71
|
+
* byte alone, so a reviewer reading `diff.patch` sees the same hunks, the same
|
|
72
|
+
* paths and the same context. It is NOT *line*-local — an earlier docstring
|
|
73
|
+
* claimed that, and it was false: the matcher runs over the whole string, and a
|
|
74
|
+
* deny pattern permitting `\s` could span a newline. Nothing in the shipped set
|
|
75
|
+
* does today, but the guarantee is written to match the code rather than the
|
|
76
|
+
* intention. The count of redactions is returned so a caller can record it
|
|
77
|
+
* rather than silently changing what it wrote.
|
|
78
|
+
*/
|
|
79
|
+
|
|
80
|
+
import fs from 'node:fs';
|
|
81
|
+
import path from 'node:path';
|
|
82
|
+
import { fileURLToPath } from 'node:url';
|
|
83
|
+
|
|
84
|
+
import { isNonHarvestTmpDir, isOpaqueRoundId, legacySourceHeaderHits } from './source_shape.js';
|
|
85
|
+
|
|
86
|
+
const HERE = path.dirname(fileURLToPath(import.meta.url));
|
|
87
|
+
const ROOT = path.resolve(HERE, '..', '..', '..');
|
|
88
|
+
const CONFIG = path.join(ROOT, 'src', 'scripts', 'external_sources_denylist.json');
|
|
89
|
+
|
|
90
|
+
/** The marker written in place of a denied token. Fixed width, no length leak. */
|
|
91
|
+
export const REDACTION_MARKER = '[REDACTED:src-conf]';
|
|
92
|
+
|
|
93
|
+
interface DenyConfig {
|
|
94
|
+
deny: string[];
|
|
95
|
+
[k: string]: unknown;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Compile the deny patterns once. Same source of truth as the gate — a second
|
|
100
|
+
* hand-written copy of the list is exactly the drift this programme exists to
|
|
101
|
+
* remove.
|
|
102
|
+
*/
|
|
103
|
+
export function loadDenyPatterns(configPath: string = CONFIG): RegExp[] {
|
|
104
|
+
const data = JSON.parse(fs.readFileSync(configPath, 'utf-8')) as DenyConfig;
|
|
105
|
+
if (!data.deny || data.deny.length === 0) {
|
|
106
|
+
throw new Error('source_redact: empty deny list');
|
|
107
|
+
}
|
|
108
|
+
// Longest source first. Applying patterns SEQUENTIALLY lets a shorter one
|
|
109
|
+
// consume the head of a longer token and leave its tail in the clear: a
|
|
110
|
+
// `\b`-bounded entry can fire INSIDE a longer hyphenated entry, because a
|
|
111
|
+
// hyphen is a word boundary, so the naive order emits
|
|
112
|
+
// `[REDACTED:src-conf]-<tail>` — a partial disclosure that still names the
|
|
113
|
+
// source. **Two such pairs exist in the shipped set today** (verified by
|
|
114
|
+
// scanning the config; the pairs are deliberately not quoted here, because
|
|
115
|
+
// naming them is the disclosure this module exists to prevent). This is a
|
|
116
|
+
// live defect, not a hypothetical. Ordering feeds the alternation below,
|
|
117
|
+
// where
|
|
118
|
+
// JS picks the first alternative that matches at a position, so
|
|
119
|
+
// longest-first approximates longest-match.
|
|
120
|
+
//
|
|
121
|
+
// `g` so every occurrence is replaced, `i` to match the gate.
|
|
122
|
+
return [...data.deny]
|
|
123
|
+
.sort((a, b) => b.length - a.length)
|
|
124
|
+
.map((p) => new RegExp(p, 'gi'));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Combine the patterns into ONE alternation, preserving their order.
|
|
129
|
+
*
|
|
130
|
+
* Sequential application is what produces the partial-exposure defect above:
|
|
131
|
+
* each pass rewrites the output of the last, so an earlier pattern can destroy
|
|
132
|
+
* a later one's match. A single alternation makes every position decided once,
|
|
133
|
+
* against all patterns at the same time.
|
|
134
|
+
*
|
|
135
|
+
* Safe here because no shipped entry is anchored (`^`/`$`) — checked, 0 of 65 —
|
|
136
|
+
* and none carries a capturing group, so joining cannot change what any
|
|
137
|
+
* individual pattern means or shift a group index.
|
|
138
|
+
*/
|
|
139
|
+
function combine(patterns: RegExp[]): RegExp {
|
|
140
|
+
return new RegExp(patterns.map((rx) => `(?:${rx.source})`).join('|'), 'gi');
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export interface RedactionResult {
|
|
144
|
+
/** The redacted text. Identical to the input when nothing matched. */
|
|
145
|
+
text: string;
|
|
146
|
+
/** How many substitutions were made, across all patterns. */
|
|
147
|
+
count: number;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Replace every deny-set hit in `text` with {@link REDACTION_MARKER}.
|
|
152
|
+
*
|
|
153
|
+
* Pure: takes text, returns text. The caller decides what to do with the count.
|
|
154
|
+
*/
|
|
155
|
+
export function redactSourceTokens(text: string, patterns: RegExp[]): RedactionResult {
|
|
156
|
+
if (patterns.length === 0) {
|
|
157
|
+
return { text, count: 0 };
|
|
158
|
+
}
|
|
159
|
+
const rx = combine(patterns);
|
|
160
|
+
// A `g` RegExp carries lastIndex across calls; reset before use so the same
|
|
161
|
+
// compiled set can be reused across many files.
|
|
162
|
+
rx.lastIndex = 0;
|
|
163
|
+
let count = 0;
|
|
164
|
+
const out = text.replace(rx, () => {
|
|
165
|
+
count += 1;
|
|
166
|
+
return REDACTION_MARKER;
|
|
167
|
+
});
|
|
168
|
+
return { text: out, count };
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Neutralise attribution SHAPE in a derived snapshot — the half a deny set
|
|
173
|
+
* cannot reach.
|
|
174
|
+
*
|
|
175
|
+
* MEASURED, not anticipated. Committing the first review snapshot taken AFTER
|
|
176
|
+
* road-to-source-silence Phase 2.1 raised the shrink-only shape ratchet by 19,
|
|
177
|
+
* and the cause is structural rather than a bug in either mechanism: a change
|
|
178
|
+
* that REMOVES speaking references produces a diff whose PREIMAGE lines still
|
|
179
|
+
* carry them. Those lines have no counterpart in the current tree, so the
|
|
180
|
+
* provenance-aware dedup in `source_snapshot_dedup.ts` correctly refuses to
|
|
181
|
+
* exclude them — "deleted-only findings stay at block" is exactly what the AI
|
|
182
|
+
* council required of that rule, and it did its job.
|
|
183
|
+
*
|
|
184
|
+
* The fix therefore belongs HERE, at write time, not there. A snapshot is a
|
|
185
|
+
* DERIVED artefact: the evidence it must preserve is the shape of the change,
|
|
186
|
+
* never the identifier. Replacing a speaking round name inside it with the
|
|
187
|
+
* marker keeps the diff readable as a diff and removes the republication —
|
|
188
|
+
* which is the same trade Phase 2.1 makes for tracked content.
|
|
189
|
+
*
|
|
190
|
+
* Two classes, both narrowed to the value rather than the line:
|
|
191
|
+
*
|
|
192
|
+
* - a non-opaque `agents/tmp(.old)/<name>/` quote — the directory name only, so
|
|
193
|
+
* the path stays recognisable as an inbox path;
|
|
194
|
+
* - a speaking `> **Source:**` header value that is neither `ENC1:` nor an
|
|
195
|
+
* opaque round id.
|
|
196
|
+
*
|
|
197
|
+
* A name that is already opaque, an `ENC1:` token, and a named working set are
|
|
198
|
+
* all left alone — the predicates come from `_lib/source_shape.ts`, so this
|
|
199
|
+
* redactor and the gate cannot disagree about what counts as speaking.
|
|
200
|
+
*/
|
|
201
|
+
export function redactSourceShape(text: string): RedactionResult {
|
|
202
|
+
let count = 0;
|
|
203
|
+
const lines = text.split('\n');
|
|
204
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
205
|
+
let line = lines[i] as string;
|
|
206
|
+
|
|
207
|
+
// tmp-quote: rewrite the DIRECTORY NAME, keep the path shape.
|
|
208
|
+
line = line.replace(/(agents\/tmp(?:\.old)?\/)([A-Za-z0-9._-]+)(\/)/g, (whole, pre: string, name: string, post: string) => {
|
|
209
|
+
if (isOpaqueRoundId(name) || isNonHarvestTmpDir(name)) {
|
|
210
|
+
return whole as string;
|
|
211
|
+
}
|
|
212
|
+
count += 1;
|
|
213
|
+
return pre + REDACTION_MARKER + post;
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
// source-header: rewrite the VALUE, keep the header. The decision is
|
|
217
|
+
// DELEGATED to a predicate in `source_shape` — never re-implemented
|
|
218
|
+
// here. Two reasons, and the second was a real bug this test suite
|
|
219
|
+
// caught: agreement is then structural rather than maintained by hand,
|
|
220
|
+
// and re-deriving the "is this value acceptable" list independently
|
|
221
|
+
// made the redactor NON-IDEMPOTENT. It re-redacted its own marker,
|
|
222
|
+
// because the value normaliser strips `[` and `]` and a hand-written
|
|
223
|
+
// `value.includes(MARKER)` check therefore never matched. A redactor
|
|
224
|
+
// that does not converge rewrites the artefact on every dispatch.
|
|
225
|
+
//
|
|
226
|
+
// It delegates to `legacySourceHeaderHits`, the BROAD predicate, and
|
|
227
|
+
// that is the correction rather than a compromise. The two predicates
|
|
228
|
+
// answer different questions: the live one asks *does this value carry
|
|
229
|
+
// a readable identifier* (the gate's question, narrowed 2026-08-30),
|
|
230
|
+
// and the redactor asks *is this value SPEAKING* — which is the older,
|
|
231
|
+
// wider question and the one redaction is for. Narrowing the shared
|
|
232
|
+
// predicate silently narrowed the redactor with it, and this suite
|
|
233
|
+
// caught it: a speaking header naming no slug or domain stopped being
|
|
234
|
+
// redacted at all.
|
|
235
|
+
const hdr = /^(\s*(?:>\s*)?\*\*Source\*?\*?:?\*{0,2}\s*:?\s*)(\S.*)$/.exec(line);
|
|
236
|
+
if (hdr && legacySourceHeaderHits(line).length > 0) {
|
|
237
|
+
count += 1;
|
|
238
|
+
line = (hdr[1] as string) + REDACTION_MARKER;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
lines[i] = line;
|
|
242
|
+
}
|
|
243
|
+
return { text: lines.join('\n'), count };
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Write `text` to `dest`, redacted. Returns the number of substitutions so the
|
|
248
|
+
* caller can surface it; a silent redaction is a changed artefact nobody was
|
|
249
|
+
* told about.
|
|
250
|
+
*
|
|
251
|
+
* Both passes run: the deny set (names somebody listed) and the shape classes
|
|
252
|
+
* (form, independent of any list). Neither subsumes the other, which is the
|
|
253
|
+
* whole reason the gate carries both.
|
|
254
|
+
*/
|
|
255
|
+
export function writeRedacted(dest: string, text: string, patterns: RegExp[]): number {
|
|
256
|
+
const tokens = redactSourceTokens(text, patterns);
|
|
257
|
+
const shaped = redactSourceShape(tokens.text);
|
|
258
|
+
fs.writeFileSync(dest, shaped.text, 'utf-8');
|
|
259
|
+
return tokens.count + shaped.count;
|
|
260
|
+
}
|