@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,502 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* source_shape — name-list-independent detection of *attribution shape*.
|
|
3
|
+
*
|
|
4
|
+
* The deny list in `external_sources_denylist.json` can only catch a source
|
|
5
|
+
* somebody already wrote down. Every family it misses is invisible until a
|
|
6
|
+
* human notices, which is the gap `road-to-source-silence` Phase 3.2 exists to
|
|
7
|
+
* close: attribution has a recognisable FORM, and the form is checkable without
|
|
8
|
+
* knowing the name.
|
|
9
|
+
*
|
|
10
|
+
* Three classes, deliberately narrow (AI council 2026-08-28, blocker
|
|
11
|
+
* `how-loud-the-slug-heuristic-is`: "the heuristic must be narrowly defined and
|
|
12
|
+
* tested against its likely false positives"):
|
|
13
|
+
*
|
|
14
|
+
* 1. `source-header` — a `> **Source:** …` header whose value is neither an
|
|
15
|
+
* `ENC1:` token nor an opaque round identifier.
|
|
16
|
+
* 2. `tmp-quote` — a quoted `agents/tmp(.old)?/<name>/` path whose `<name>` is
|
|
17
|
+
* not an opaque round identifier. The inbox directory name is the root of
|
|
18
|
+
* the whole leak chain; quoting it republishes it.
|
|
19
|
+
* 3. `repo-slug` — a `github.com/<owner>/<repo>` URL whose owner is not
|
|
20
|
+
* allowlisted (own org, GitHub's own reserved paths, documentation
|
|
21
|
+
* placeholders, and the vendors whose tools this suite integrates or
|
|
22
|
+
* recommends — naming an integrated tool is explicitly allowed by the rule).
|
|
23
|
+
*
|
|
24
|
+
* ## What this is NOT — a floor, not a proof
|
|
25
|
+
*
|
|
26
|
+
* Line-based patterns cannot see a wrapped sentence, an attribution spread over
|
|
27
|
+
* two lines, or a source named without any of the three forms.
|
|
28
|
+
*
|
|
29
|
+
* **A bare `<owner>/<repo>` slug class was built, measured and REMOVED.** The
|
|
30
|
+
* council's requirement was that the heuristic be "narrowly defined and tested
|
|
31
|
+
* against its likely false positives"; the measurement is the answer. Even
|
|
32
|
+
* gated on an attribution cue (`inspired by`, `ported from`, `based on`, …) the
|
|
33
|
+
* bare form produced **3,109 hits across the tracked tree, against 202 for the
|
|
34
|
+
* URL form** — and the top values were `text/markdown` (278), `origin/main`
|
|
35
|
+
* (29), `JS/TS`, `before/after`, `CI/CD`, `request/response`, `403/404`. Those
|
|
36
|
+
* are precisely the filesystem-path, ratio and enumeration shapes the council
|
|
37
|
+
* named, and a class whose signal is 6 % of its output would drive exactly the
|
|
38
|
+
* broad allowlisting the council said is "worse than the gap it closes".
|
|
39
|
+
*
|
|
40
|
+
* The stated recall limit that follows: **a source named as a bare slug, with
|
|
41
|
+
* no `github.com` URL and no deny-list entry, is not detected.** That is a real
|
|
42
|
+
* hole, it is written down rather than papered over with a wider regex, and the
|
|
43
|
+
* deny set plus the Phase 0 census sweep are what cover it.
|
|
44
|
+
*
|
|
45
|
+
* Every predicate is pure and takes a bare string, so it answers for a file
|
|
46
|
+
* that does not exist yet (a diff, a plan, a fixture).
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
/** The classes, in the order they are reported. */
|
|
50
|
+
export const SHAPE_CLASSES = ['source-header', 'tmp-quote', 'repo-slug'] as const;
|
|
51
|
+
export type ShapeClass = (typeof SHAPE_CLASSES)[number];
|
|
52
|
+
|
|
53
|
+
/** One shape finding on one line. */
|
|
54
|
+
export interface ShapeHit {
|
|
55
|
+
/** Which class fired. */
|
|
56
|
+
cls: ShapeClass;
|
|
57
|
+
/** The offending value, already truncated for reporting. NEVER logged by the gate. */
|
|
58
|
+
value: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* An opaque round identifier — the form Phase 4 mandates for inbox directories.
|
|
63
|
+
*
|
|
64
|
+
* Accepts exactly three shapes, all of which carry no information about the
|
|
65
|
+
* source: `inbox-2026-08-g` (round-dated, optional 1-3 char disambiguator),
|
|
66
|
+
* `round-<hex>` / `set-<hex>` (content-free), and `S17` (a set number). Anything
|
|
67
|
+
* else is speaking by construction — a name that reads is a name that leaks.
|
|
68
|
+
*/
|
|
69
|
+
const OPAQUE_ROUND_RE =
|
|
70
|
+
/^(?:(?:inbox|round|src-set|source-set)-\d{4}-\d{2}(?:-[a-z0-9]{1,3})?|(?:round|set|src-set|source-set)-[0-9a-f]{6,}|s\d{1,4})$/i;
|
|
71
|
+
|
|
72
|
+
/** Is `name` an opaque round identifier? */
|
|
73
|
+
export function isOpaqueRoundId(name: string): boolean {
|
|
74
|
+
return OPAQUE_ROUND_RE.test(name.trim());
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** An `ENC1:` ciphertext token (see `_lib/link_crypto.ts`). */
|
|
78
|
+
const ENC_TOKEN_RE = /^ENC1:[A-Za-z0-9+/=]+$/;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The write-time redaction marker from `_lib/source_redact.ts`, matched WITHOUT
|
|
82
|
+
* its brackets because the value normaliser below strips `[` and `]`.
|
|
83
|
+
*
|
|
84
|
+
* A redacted header is the compliant END STATE, not a violation: the marker
|
|
85
|
+
* carries no information about any source, which is its entire purpose. Without
|
|
86
|
+
* this the gate flagged its own marker — measured on the first review snapshot
|
|
87
|
+
* taken after shape redaction shipped, where `> **Source:** [REDACTED:src-conf]`
|
|
88
|
+
* counted as a speaking value.
|
|
89
|
+
*/
|
|
90
|
+
const REDACTION_VALUE_RE = /^REDACTED:src-conf$/;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* A `> **Source:**` header line. The `>` and the bold markers are both optional
|
|
94
|
+
* because the convention drifted across the roadmap corpus; matching only the
|
|
95
|
+
* blockquoted form would miss the plain one for no reason.
|
|
96
|
+
*
|
|
97
|
+
* `\b` does not match inside `**bold**`, which is exactly the formatting the
|
|
98
|
+
* lines that matter use — so the markers are consumed explicitly rather than
|
|
99
|
+
* relied upon as boundaries.
|
|
100
|
+
*/
|
|
101
|
+
const SOURCE_HEADER_RE = /^\s*(?:>\s*)?\*\*Source\*?\*?:?\*{0,2}\s*:?\s*(\S.*)$/;
|
|
102
|
+
|
|
103
|
+
/** A quoted inbox directory. Terminated by `/`, so a bare mention of the parent is not a hit. */
|
|
104
|
+
const TMP_QUOTE_RE = /agents\/tmp(?:\.old)?\/([A-Za-z0-9._-]+)\//g;
|
|
105
|
+
|
|
106
|
+
/** A GitHub repository URL, scheme-optional. */
|
|
107
|
+
const GITHUB_URL_RE = /(?:https?:\/\/)?(?:www\.)?github\.com\/([A-Za-z0-9][A-Za-z0-9-]{0,38})\/([A-Za-z0-9][A-Za-z0-9._-]{0,99})/g;
|
|
108
|
+
|
|
109
|
+
export interface SlugAllowlist {
|
|
110
|
+
/** GitHub owners whose repos may be named openly (own org, integrated tools). */
|
|
111
|
+
owners: readonly string[];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* The allowlist, deliberately small and deliberately IN CODE rather than in a
|
|
116
|
+
* `*allowlist.json`.
|
|
117
|
+
*
|
|
118
|
+
* It is a **precision guard for a URL-host pattern**, not a set of exempted
|
|
119
|
+
* sources: three of its four groups (GitHub's own reserved first path segments,
|
|
120
|
+
* documentation placeholders, this suite's own org) name nothing external at
|
|
121
|
+
* all. The fourth — vendors whose tools this suite integrates or recommends —
|
|
122
|
+
* is legitimate by the rule's own carve-out: "Recommending / integrating a tool
|
|
123
|
+
* or registry … Naming the tool is fine."
|
|
124
|
+
*
|
|
125
|
+
* Kept in code so growth is a reviewed code change with a group comment beside
|
|
126
|
+
* it, which is the control the council asked for when it warned that a loud
|
|
127
|
+
* heuristic "would generate enough noise to drive broad allowlisting". A JSON
|
|
128
|
+
* allowlist would be ratcheted by `check_suppression_hygiene` instead; that is
|
|
129
|
+
* the alternative, and it was not chosen because this list must not read as a
|
|
130
|
+
* register of permitted sources.
|
|
131
|
+
*/
|
|
132
|
+
const ALLOWED_OWNERS: readonly string[] = [
|
|
133
|
+
// This suite's own organisation.
|
|
134
|
+
'event4u-app',
|
|
135
|
+
// GitHub's own reserved first path segments — not owners at all.
|
|
136
|
+
'sponsors', 'features', 'apps', 'marketplace', 'orgs', 'settings', 'topics',
|
|
137
|
+
'login', 'about', 'pricing', 'security', 'readme', 'collections', 'trending',
|
|
138
|
+
'explore', 'notifications', 'enterprise', 'customer-stories', 'contact',
|
|
139
|
+
// Documentation placeholders.
|
|
140
|
+
'example', 'acme', 'org', 'owner', 'user', 'username', 'myorg', 'your-org',
|
|
141
|
+
'yourorg', 'my-org', 'youruser', 'your-username', 'some-org',
|
|
142
|
+
// Two further placeholders, added on a MEASURED false positive rather than
|
|
143
|
+
// on taste (road-to-source-silence Phase 3.4). `someone/other` in
|
|
144
|
+
// tests/scripts/envelope_grounding.test.ts and `o/r.git` in
|
|
145
|
+
// tests/scripts/unattended_guard.test.ts are literal fixture URLs naming
|
|
146
|
+
// nothing external. They were the only two of 26 review-snapshot findings
|
|
147
|
+
// that survived provenance-aware deduplication — and surviving is what
|
|
148
|
+
// identified them: the AI council's requirement was that unique and
|
|
149
|
+
// unverifiable findings stay at block so a human looks at them. A human
|
|
150
|
+
// looked; this is the answer. Fixing them here rather than by widening the
|
|
151
|
+
// dedup rule is what keeps that rule strict.
|
|
152
|
+
'someone', 'o',
|
|
153
|
+
// Vendors whose tools this suite integrates or recommends (rule carve-out).
|
|
154
|
+
'anthropics', 'anthropic', 'microsoft', 'github', 'modelcontextprotocol',
|
|
155
|
+
'cloudflare', 'openai', 'nodejs', 'vitest-dev', 'vercel', 'tailwindlabs',
|
|
156
|
+
'laravel', 'symfony', 'shadcn-ui', 'playwright-community', 'actions',
|
|
157
|
+
'denoland', 'pnpm', 'npm', 'astral-sh', 'go-task', 'charmbracelet',
|
|
158
|
+
];
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* `agents/tmp(.old)/<name>/` directories whose `<name>` names a WORKING SET, not
|
|
162
|
+
* a harvest round.
|
|
163
|
+
*
|
|
164
|
+
* The `tmp-quote` class exists because a harvest round lands in a directory
|
|
165
|
+
* named after its source, so quoting that path republishes the name the deny
|
|
166
|
+
* list hides. A directory named after the *work* leaks nothing — and the
|
|
167
|
+
* distinction is not decorative: `bench-local` was added on a MEASURED false
|
|
168
|
+
* positive, four hits in
|
|
169
|
+
* `agents/evidence/analysis/code-graph-rerun-irrecoverability-2026-08-28.md`,
|
|
170
|
+
* whose probe table quotes the four pinned benchmark input files by path
|
|
171
|
+
* BECAUSE THE PATH IS THE EVIDENCE. The filenames it quotes are already
|
|
172
|
+
* anonymised (`repo-a`, `repo-b`, `repo-c`), so there is no name to protect,
|
|
173
|
+
* and rewriting the table would have destroyed the reading it records.
|
|
174
|
+
*
|
|
175
|
+
* Kept as small as `ALLOWED_OWNERS` and for the same reason: an entry here is a
|
|
176
|
+
* reviewed code change with its evidence beside it. Anything that names a
|
|
177
|
+
* ROUND, a source, or an external project does NOT belong in this list — the
|
|
178
|
+
* fix for those is an opaque round id, per `isOpaqueRoundId`.
|
|
179
|
+
*/
|
|
180
|
+
const NON_HARVEST_TMP_DIRS: ReadonlySet<string> = new Set([
|
|
181
|
+
// Benchmark inputs. Pinned by SHA-256, filenames already anonymised.
|
|
182
|
+
'bench-local',
|
|
183
|
+
]);
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Is `name` a named WORKING SET rather than a harvest round?
|
|
187
|
+
*
|
|
188
|
+
* Exported so the Phase 4.2 write-time guard
|
|
189
|
+
* (`hooks/block_speaking_inbox_dir.ts`) decides from the same set this module
|
|
190
|
+
* uses. Two copies of "which names are acceptable" is how a guard and its gate
|
|
191
|
+
* drift into disagreeing about the thing they both exist to enforce.
|
|
192
|
+
*/
|
|
193
|
+
export function isNonHarvestTmpDir(name: string): boolean {
|
|
194
|
+
return NON_HARVEST_TMP_DIRS.has(name.trim().toLowerCase());
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const DEFAULT_ALLOWLIST: SlugAllowlist = { owners: ALLOWED_OWNERS };
|
|
198
|
+
|
|
199
|
+
/** Normalise for allowlist comparison. */
|
|
200
|
+
function fold(s: string): string {
|
|
201
|
+
return s.trim().toLowerCase();
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Repo-relative prefixes that make a token an INTERNAL reference.
|
|
206
|
+
*
|
|
207
|
+
* A `**Source:**` value pointing at this repository's own tree names nothing
|
|
208
|
+
* external, whatever shape it has. Listed rather than pattern-matched because
|
|
209
|
+
* the set is small, closed, and a reviewer should be able to read it — which is
|
|
210
|
+
* why two INERT entries were removed rather than left in place (R2 finding 13):
|
|
211
|
+
* `'pr #'` could never match, since the tokens tested here come from a path or
|
|
212
|
+
* slug scan and contain no space, and it made a reader believe PR references
|
|
213
|
+
* were handled here when they are handled by carrying no identifier at all.
|
|
214
|
+
* `.agent-src` stays because the token now carries its whole path.
|
|
215
|
+
*/
|
|
216
|
+
const INTERNAL_PATH_PREFIXES: readonly string[] = [
|
|
217
|
+
'agents/', 'docs/', 'src/', 'tests/', 'scripts/', 'internal/', 'evals/',
|
|
218
|
+
'dist/', 'provenance/', 'templates/', 'packages/', 'node_modules/',
|
|
219
|
+
'.agent-src', '.augment/', '.claude/', '.github/', 'road-to-', 'adr-',
|
|
220
|
+
];
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Hosts a value may name openly — the same carve-out `ALLOWED_OWNERS` encodes.
|
|
224
|
+
*
|
|
225
|
+
* Matched by SUFFIX, so a documentation subdomain of a permitted vendor is
|
|
226
|
+
* permitted too. See {@link firstDomainIn} for why exact matching was wrong.
|
|
227
|
+
*/
|
|
228
|
+
const ALLOWED_HOSTS: readonly string[] = [
|
|
229
|
+
'example.com', 'example.org', 'example.net', 'localhost',
|
|
230
|
+
'github.com', 'githubusercontent.com', 'anthropic.com', 'openai.com',
|
|
231
|
+
'nodejs.org', 'npmjs.com',
|
|
232
|
+
];
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* npm SCOPES a value may name openly.
|
|
236
|
+
*
|
|
237
|
+
* Separate from `ALLOWED_OWNERS` because they are different namespaces (R2
|
|
238
|
+
* finding 6). That list is a GitHub-owner list — its own docstring calls it "a
|
|
239
|
+
* precision guard for a URL-host pattern" — and reusing it meant an integrated
|
|
240
|
+
* vendor whose npm scope differs from its GitHub org was flagged:
|
|
241
|
+
* `@anthropic-ai/claude-code` and `@types/node` both did, though
|
|
242
|
+
* `source-confidentiality` explicitly permits naming an integrated tool.
|
|
243
|
+
* Reusing one list avoided a second allowlist at the cost of applying it to a
|
|
244
|
+
* namespace nobody measured it against.
|
|
245
|
+
*/
|
|
246
|
+
const ALLOWED_NPM_SCOPES: readonly string[] = [
|
|
247
|
+
'event4u', 'anthropic-ai', 'openai', 'types', 'modelcontextprotocol',
|
|
248
|
+
'preact', 'eslint', 'typescript-eslint', 'vitest',
|
|
249
|
+
];
|
|
250
|
+
|
|
251
|
+
const BARE_SLUG_RE = /\b([A-Za-z][A-Za-z0-9-]{1,38})\/([A-Za-z][A-Za-z0-9._-]{1,99})\b/g;
|
|
252
|
+
const DOMAIN_RE = /\b([a-z0-9-]+(?:\.[a-z0-9-]+)*\.(?:com|io|dev|ai|org|net|sh|app|co))\b/gi;
|
|
253
|
+
const SCOPED_PKG_RE = /(^|\s)@([a-z0-9-]+)\/([a-z0-9._-]+)/gi;
|
|
254
|
+
|
|
255
|
+
function isInternalToken(token: string): boolean {
|
|
256
|
+
const t = fold(token);
|
|
257
|
+
return INTERNAL_PATH_PREFIXES.some((prefix) => t.startsWith(prefix));
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Does this `**Source:**` value carry a READABLE identifier?
|
|
262
|
+
*
|
|
263
|
+
* This is the operational grammar the narrowing rests on, and it is written out
|
|
264
|
+
* rather than left to a reviewer's judgement because a council seat named
|
|
265
|
+
* exactly that risk: *"'readable slug' is still an open question disguised as a
|
|
266
|
+
* decision … without that specification, option (a) merely moves subjective
|
|
267
|
+
* classification into code."*
|
|
268
|
+
*
|
|
269
|
+
* An identifier is one of three shapes, none of which prose produces by
|
|
270
|
+
* accident: an `owner/repo` slug, a domain name, or an `@scope/package`. A
|
|
271
|
+
* value carrying none of them names nothing a reader could look up — it is a
|
|
272
|
+
* description, and a description is what `source-confidentiality` ASKS authors
|
|
273
|
+
* to write.
|
|
274
|
+
*
|
|
275
|
+
* Internal tokens are excluded first: this repository's own paths, its roadmap
|
|
276
|
+
* slugs, ADR ids and PR references are `owner/repo`-shaped and name nothing
|
|
277
|
+
* external.
|
|
278
|
+
*/
|
|
279
|
+
export function readableIdentifierIn(value: string): string | null {
|
|
280
|
+
const hosts = ALLOWED_HOSTS.map(fold);
|
|
281
|
+
const owners = new Set(ALLOWED_OWNERS.map(fold));
|
|
282
|
+
const scopes = new Set(ALLOWED_NPM_SCOPES.map(fold));
|
|
283
|
+
|
|
284
|
+
for (const token of pathLikeTokens(value)) {
|
|
285
|
+
// INTERNAL FIRST, for every branch (R2 finding 4). The domain branch
|
|
286
|
+
// used to run before this check and no branch but the slug one applied
|
|
287
|
+
// it, so any internal path whose extension collides with a TLD was
|
|
288
|
+
// reported as a leak: `agents/tooling/setup.sh` produced `setup.sh`, at
|
|
289
|
+
// block tier, contradicting this function's own docstring.
|
|
290
|
+
if (isInternalToken(token)) continue;
|
|
291
|
+
|
|
292
|
+
const domain = firstDomainIn(token, hosts);
|
|
293
|
+
if (domain !== null) return domain;
|
|
294
|
+
|
|
295
|
+
const scoped = SCOPED_PKG_RE.exec(token);
|
|
296
|
+
SCOPED_PKG_RE.lastIndex = 0;
|
|
297
|
+
if (scoped !== null && !scopes.has(fold(scoped[2] as string))) {
|
|
298
|
+
return `@${fold(scoped[2] as string)}/${scoped[3] as string}`;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
const slug = firstSlugIn(token, owners);
|
|
302
|
+
if (slug !== null) return slug;
|
|
303
|
+
}
|
|
304
|
+
return null;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Split a header value into whitespace-delimited tokens, stripped of the
|
|
309
|
+
* punctuation a sentence wraps them in.
|
|
310
|
+
*
|
|
311
|
+
* Tokenising is what closed the recall hole (R2 finding 2). The first version
|
|
312
|
+
* scanned the WHOLE value with a slug regex and then tried to tell a repository
|
|
313
|
+
* from a path by looking at the characters either side of the match — which
|
|
314
|
+
* dropped every slug followed by a further segment. Measured: `somevendor/
|
|
315
|
+
* some-suite/skills/foo.md`, `ported from somevendor/some-suite/README.md` and
|
|
316
|
+
* `./somevendor/some-suite` all returned nothing, and citing a FILE inside an
|
|
317
|
+
* external repository is the most natural Source-header shape there is.
|
|
318
|
+
*
|
|
319
|
+
* With the whole token in hand the question answers itself: an internal path
|
|
320
|
+
* starts with an internal prefix, and anything else that carries an
|
|
321
|
+
* `owner/repo` head is a citation into somewhere else.
|
|
322
|
+
*/
|
|
323
|
+
export function pathLikeTokens(value: string): string[] {
|
|
324
|
+
return value
|
|
325
|
+
.split(/\s+/)
|
|
326
|
+
.map((t) => t.replace(/^[`*_[(<"'.,;:]+/, '').replace(/[`*_\])>"'.,;:]+$/, ''))
|
|
327
|
+
// Leading path noise AFTER the punctuation strip, not before: the
|
|
328
|
+
// punctuation pass already removes the `.` of `./`, so checking for
|
|
329
|
+
// `./` first never fires — which is how `./somevendor/some-suite`
|
|
330
|
+
// survived the first version of this fix.
|
|
331
|
+
.map((t) => t.replace(/^[/]+/, ''))
|
|
332
|
+
.filter((t) => t.length > 0);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/** The first non-allowlisted domain in a token, or null. */
|
|
336
|
+
function firstDomainIn(token: string, hosts: readonly string[]): string | null {
|
|
337
|
+
DOMAIN_RE.lastIndex = 0;
|
|
338
|
+
let m: RegExpExecArray | null;
|
|
339
|
+
while ((m = DOMAIN_RE.exec(token)) !== null) {
|
|
340
|
+
const host = fold(m[1] as string);
|
|
341
|
+
// SUFFIX match, not exact (R2 finding 5). The first version carved out
|
|
342
|
+
// `.example.com` alone, so `docs.anthropic.com` and
|
|
343
|
+
// `platform.openai.com` — vendors the rule explicitly permits naming —
|
|
344
|
+
// were reported as leaks. A subdomain of an allowed host is the same
|
|
345
|
+
// host's documentation, not a different source.
|
|
346
|
+
if (hosts.some((h) => host === h || host.endsWith(`.${h}`))) continue;
|
|
347
|
+
return host;
|
|
348
|
+
}
|
|
349
|
+
return null;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/** The first non-allowlisted `owner/repo` head in a token, or null. */
|
|
353
|
+
function firstSlugIn(token: string, owners: ReadonlySet<string>): string | null {
|
|
354
|
+
BARE_SLUG_RE.lastIndex = 0;
|
|
355
|
+
const m = BARE_SLUG_RE.exec(token);
|
|
356
|
+
BARE_SLUG_RE.lastIndex = 0;
|
|
357
|
+
if (m === null) return null;
|
|
358
|
+
// Only the HEAD of the token counts: `owner/repo/path/to/file.md` names one
|
|
359
|
+
// repository, and reporting `path/to` from the same token would report a
|
|
360
|
+
// directory as a source.
|
|
361
|
+
if (m.index !== 0) return null;
|
|
362
|
+
const owner = m[1] as string;
|
|
363
|
+
if (owners.has(fold(owner))) return null;
|
|
364
|
+
const repo = m[2] as string;
|
|
365
|
+
// A two-segment token ending in a file extension is a path, not a repo:
|
|
366
|
+
// `results/2026-04-21T08.json`, `road-to-x.md`.
|
|
367
|
+
if (token === `${owner}/${repo}` && /\.(md|json|ts|tsx|js|mjs|yml|yaml|txt|jsonl|patch|png|svg|sh|lock)$/i.test(repo)) {
|
|
368
|
+
return null;
|
|
369
|
+
}
|
|
370
|
+
return `${owner}/${repo}`;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* `source-header` hits on one line.
|
|
375
|
+
*
|
|
376
|
+
* **NARROWED 2026-08-30 by AI-council verdict (2/2 seats present), and the
|
|
377
|
+
* reason is that the previous form measured the opposite of what it was
|
|
378
|
+
* baselined for.** It flagged the VALUE of every `**Source:**` header that was
|
|
379
|
+
* not an `ENC1:` token or an opaque round id — so a correctly anonymised header
|
|
380
|
+
* scored exactly like a leaking one. All 95 findings in the tracked tree were
|
|
381
|
+
* read: not one named an external source in readable form, and six of them were
|
|
382
|
+
* flagging the *anonymisation notice itself* (`**Source:** anonymisation
|
|
383
|
+
* (source-confidentiality). External harvest sources …`). One seat put it
|
|
384
|
+
* plainly: the detector penalised correct behaviour.
|
|
385
|
+
*
|
|
386
|
+
* The class is NARROWED, never deleted — both seats refused (c), removing it,
|
|
387
|
+
* on the grounds that a `**Source:**` header is the location policy directs
|
|
388
|
+
* authors to record attribution and is therefore the highest-value place to
|
|
389
|
+
* keep looking. What it now flags is a value carrying a readable identifier
|
|
390
|
+
* (see {@link readableIdentifierIn}); the reported `value` is that identifier
|
|
391
|
+
* rather than the whole header, so a finding names the thing that leaked.
|
|
392
|
+
*/
|
|
393
|
+
export function sourceHeaderHits(line: string): ShapeHit[] {
|
|
394
|
+
const value = normalisedHeaderValue(line);
|
|
395
|
+
if (value === null) return [];
|
|
396
|
+
const identifier = readableIdentifierIn(value);
|
|
397
|
+
if (identifier === null) return [];
|
|
398
|
+
return [{ cls: 'source-header', value: identifier.slice(0, 120) }];
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* The value of a `**Source:**` header, normalised — or null when the line is
|
|
403
|
+
* not a header, or carries a form that is already opaque.
|
|
404
|
+
*
|
|
405
|
+
* EXTRACTED (R2 finding 9). Both predicates below used to carry this eight-line
|
|
406
|
+
* prefilter as a verbatim copy, so any future edit to it — a new `ENC` form, a
|
|
407
|
+
* different redaction marker, a change to what counts as an opaque round id —
|
|
408
|
+
* would silently change what the "pre-2026-08-30" baseline MEANS, in one copy
|
|
409
|
+
* or in both. A shadow metric whose definition can drift away from the live one
|
|
410
|
+
* measures nothing about the live one.
|
|
411
|
+
*/
|
|
412
|
+
export function normalisedHeaderValue(line: string): string | null {
|
|
413
|
+
const m = SOURCE_HEADER_RE.exec(line);
|
|
414
|
+
if (!m) return null;
|
|
415
|
+
const raw = (m[1] as string).trim();
|
|
416
|
+
// Strip markdown emphasis, backticks and trailing punctuation before judging.
|
|
417
|
+
const value = raw.replace(/^[`*_[(<"']+/, '').replace(/[`*_\])>"'.,;]+$/, '').trim();
|
|
418
|
+
if (value === '') return null;
|
|
419
|
+
if (ENC_TOKEN_RE.test(value)) return null;
|
|
420
|
+
if (REDACTION_VALUE_RE.test(value)) return null;
|
|
421
|
+
if (isOpaqueRoundId(value)) return null;
|
|
422
|
+
// A header pointing at an inbox directory is judged on the directory NAME,
|
|
423
|
+
// so the tmp-quote class owns it and this class stays silent — otherwise one
|
|
424
|
+
// line would be counted twice and the two ratchets would move together.
|
|
425
|
+
if (/agents\/tmp(?:\.old)?\//.test(value)) return null;
|
|
426
|
+
return value;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* The PRE-narrowing `source-header` predicate, kept as a shadow metric.
|
|
431
|
+
*
|
|
432
|
+
* A council condition, and its purpose is auditability rather than enforcement:
|
|
433
|
+
* *"keep the old detector shadow-reporting until at least one subsequent
|
|
434
|
+
* corpus-changing release passes both detectors"*. It is exported so
|
|
435
|
+
* `check_no_external_sources` can report the legacy count beside the live one,
|
|
436
|
+
* and it gates nothing.
|
|
437
|
+
*
|
|
438
|
+
* It shares {@link normalisedHeaderValue} with the live predicate deliberately:
|
|
439
|
+
* the only difference between the two is the readable-identifier test, and
|
|
440
|
+
* making that the ONLY difference is what keeps the comparison meaningful.
|
|
441
|
+
*/
|
|
442
|
+
export function legacySourceHeaderHits(line: string): ShapeHit[] {
|
|
443
|
+
const value = normalisedHeaderValue(line);
|
|
444
|
+
if (value === null) return [];
|
|
445
|
+
return [{ cls: 'source-header', value: value.slice(0, 120) }];
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/** `tmp-quote` hits on one line. */
|
|
449
|
+
export function tmpQuoteHits(line: string): ShapeHit[] {
|
|
450
|
+
const out: ShapeHit[] = [];
|
|
451
|
+
TMP_QUOTE_RE.lastIndex = 0;
|
|
452
|
+
let m: RegExpExecArray | null;
|
|
453
|
+
while ((m = TMP_QUOTE_RE.exec(line)) !== null) {
|
|
454
|
+
const name = m[1] as string;
|
|
455
|
+
if (isOpaqueRoundId(name)) continue;
|
|
456
|
+
if (NON_HARVEST_TMP_DIRS.has(name.toLowerCase())) continue;
|
|
457
|
+
out.push({ cls: 'tmp-quote', value: name.slice(0, 120) });
|
|
458
|
+
}
|
|
459
|
+
return out;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* `repo-slug` hits on one line — the `github.com/<owner>/<repo>` URL form only.
|
|
464
|
+
* See the module docstring for the measured reason the bare-slug form is absent.
|
|
465
|
+
*/
|
|
466
|
+
export function repoSlugHits(line: string, allow: SlugAllowlist = DEFAULT_ALLOWLIST): ShapeHit[] {
|
|
467
|
+
const out: ShapeHit[] = [];
|
|
468
|
+
const owners = new Set(allow.owners.map(fold));
|
|
469
|
+
GITHUB_URL_RE.lastIndex = 0;
|
|
470
|
+
let m: RegExpExecArray | null;
|
|
471
|
+
while ((m = GITHUB_URL_RE.exec(line)) !== null) {
|
|
472
|
+
const owner = m[1] as string;
|
|
473
|
+
if (owners.has(fold(owner))) continue;
|
|
474
|
+
out.push({ cls: 'repo-slug', value: `${owner}/${m[2] as string}`.slice(0, 120) });
|
|
475
|
+
}
|
|
476
|
+
return out;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/** Every shape hit on one line. */
|
|
480
|
+
export function shapeHits(line: string, allow: SlugAllowlist = DEFAULT_ALLOWLIST): ShapeHit[] {
|
|
481
|
+
return [...sourceHeaderHits(line), ...tmpQuoteHits(line), ...repoSlugHits(line, allow)];
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* `tmp-quote` and `repo-slug` also apply to a tracked PATH — a filename can
|
|
486
|
+
* carry a round name (`agents/evidence/reviews/<round>.review-input/`) with no
|
|
487
|
+
* content line to match. Path scanning against the deny set is Phase 3.1; this
|
|
488
|
+
* is its shape half.
|
|
489
|
+
*/
|
|
490
|
+
export function shapePathHits(rel: string, allow: SlugAllowlist = DEFAULT_ALLOWLIST): ShapeHit[] {
|
|
491
|
+
return [...tmpQuoteHits(rel), ...repoSlugHits(rel, allow)];
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* The enforcement tier for a hit, per the resolved
|
|
496
|
+
* `how-loud-the-slug-heuristic-is` blocker: block inside `agents/**`, warn
|
|
497
|
+
* everywhere else. Attribution is concentrated in `agents/**`; repository slugs
|
|
498
|
+
* are ordinary content in integration code and docs.
|
|
499
|
+
*/
|
|
500
|
+
export function tierFor(rel: string): 'block' | 'warn' {
|
|
501
|
+
return rel.startsWith('agents/') ? 'block' : 'warn';
|
|
502
|
+
}
|