@event4u/agent-config 14.12.0 → 14.13.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 +234 -0
- 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 +109 -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-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 +247 -3
- package/dist/agent-src/scripts/guarded_baseline.ts +328 -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 +400 -0
- package/dist/agent-src/scripts/ticket_bundles.ts +84 -0
- package/dist/agent-src/scripts/update_roadmap_progress.ts +8 -4
- 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 +42 -10
- 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 +57 -57
- 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 +1836 -712
- 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 +4818 -2645
- 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/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 +247 -3
- package/src/agent-src/scripts/guarded_baseline.ts +328 -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 +400 -0
- package/src/agent-src/scripts/ticket_bundles.ts +84 -0
- package/src/agent-src/scripts/update_roadmap_progress.ts +8 -4
- 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 +38 -36
- package/src/config/evaluator-budgets.json +14 -14
- package/src/config/gate-coverage.yml +579 -63
- package/src/config/gate-reachability-exemptions.json +21 -0
- package/src/config/gate-violation-baselines.json +37 -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 +8 -8
- 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 +126 -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 +27 -0
- package/src/scripts/_lib/activation_ladder.ts +211 -0
- package/src/scripts/_lib/activation_states.ts +88 -0
- package/src/scripts/_lib/adherence_detectors.ts +143 -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_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/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/council_settings_block.ts +6 -0
- package/src/scripts/_lib/curator_ops.ts +172 -0
- package/src/scripts/_lib/delivery_arm_experiment.ts +266 -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/eval_publication.ts +354 -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/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 +229 -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/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/prefix_stable_surfaces.ts +123 -0
- package/src/scripts/_lib/privacy_class.ts +47 -0
- package/src/scripts/_lib/regression_neighbourhood.ts +259 -0
- 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/runtime_journal.ts +1499 -0
- package/src/scripts/_lib/runtime_wiring_checks.ts +430 -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/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/disagreement_signal.ts +338 -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/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/response_record.ts +50 -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 +126 -0
- 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 +142 -1
- 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_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/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 +980 -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 +98 -11
- 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/concern_registry.ts +4 -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/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/lint_adr_sweep_routing.ts +12 -0
- package/src/scripts/lint_canonical_terms.ts +604 -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_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/mcp_server/consumer_tool_catalog.json +1 -1
- package/src/scripts/mcp_server/tool_catalog_source.ts +1 -1
- package/src/scripts/measure_docs_dead_links.ts +348 -0
- package/src/scripts/measure_host_capture.ts +461 -0
- package/src/scripts/migration_status.ts +3 -3
- package/src/scripts/model_rule_injection.ts +60 -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_turnaround.ts +384 -0
- package/src/scripts/probe_unblocked_ask.ts +279 -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,259 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression selection from the affected neighbourhood.
|
|
3
|
+
*
|
|
4
|
+
* `road-to-governed-harness-evolution` Phase 4, step 4.6.
|
|
5
|
+
*
|
|
6
|
+
* > *Use the code graph to choose which regressions to run for a given
|
|
7
|
+
* > candidate. The master adopted the attack "local improvement, global
|
|
8
|
+
* > regression" as a risk with no mechanism behind it. This is distinct from
|
|
9
|
+
* > the killed curriculum generator — it selects existing regressions, it does
|
|
10
|
+
* > not author tasks.*
|
|
11
|
+
* > verify: **a candidate touching one surface runs the regressions its
|
|
12
|
+
* > neighbourhood names, and a fixture proves a neighbour regression is
|
|
13
|
+
* > caught.**
|
|
14
|
+
*
|
|
15
|
+
* ## Which graph, and why it is not the one the step names
|
|
16
|
+
*
|
|
17
|
+
* The step says "the code graph". This tree has two graph surfaces and only one
|
|
18
|
+
* of them resolves here, so the substitution is STATED rather than hidden.
|
|
19
|
+
*
|
|
20
|
+
* · `agent-config code-graph` — the native code-graph engine (ADR-124). It
|
|
21
|
+
* ships `hooks.code_graph.enabled: false`
|
|
22
|
+
* (`src/config/agent-settings.template.yml:1373-1374`), and
|
|
23
|
+
* `agent-config code-graph detect` in this checkout answers
|
|
24
|
+
* `no code-graph source detected`. There is no index to select against.
|
|
25
|
+
* · `src/scripts/discovery_graph.ts` — this suite's OWN artefact relation
|
|
26
|
+
* graph, five typed edges extracted from the discovery manifest's
|
|
27
|
+
* structured fields, with an `affected` BFS already implemented and
|
|
28
|
+
* answering. That is the surface this module builds on.
|
|
29
|
+
*
|
|
30
|
+
* The substitution changes what a "neighbourhood" means, and the difference is
|
|
31
|
+
* worth naming: the native engine would neighbour a candidate by SYMBOL
|
|
32
|
+
* relations, while `discovery_graph` neighbours it by ARTEFACT relations
|
|
33
|
+
* (`supersedes`, `routes_to`, `references_adr`, pack and workspace membership).
|
|
34
|
+
* For this roadmap's candidates — rules, skills, guidelines — the artefact
|
|
35
|
+
* graph is the one that carries the coupling a rewrite can break. For a
|
|
36
|
+
* candidate that edits a `.ts` symbol, it is the weaker surface, and this
|
|
37
|
+
* module says so through {@link selectionVerdict}: a touched surface absent
|
|
38
|
+
* from the graph is REFUSED, never silently neighboured with the empty set.
|
|
39
|
+
*
|
|
40
|
+
* ## Why an unresolved surface refuses instead of selecting nothing
|
|
41
|
+
*
|
|
42
|
+
* A selector whose neighbourhood lookup fails and then runs zero regressions
|
|
43
|
+
* reports a clean sheet, which is indistinguishable from a candidate that
|
|
44
|
+
* genuinely touches nothing coupled. That is exactly the "local improvement,
|
|
45
|
+
* global regression" hole the step exists to close, arriving through the
|
|
46
|
+
* selector rather than around it. So an unresolved touched surface is a
|
|
47
|
+
* refusal reason, and there is no option flag that relaxes it.
|
|
48
|
+
*
|
|
49
|
+
* ## Selects, never authors — carried by object identity (K9)
|
|
50
|
+
*
|
|
51
|
+
* K9 killed the curriculum generator. This module has no code path that
|
|
52
|
+
* constructs a {@link RegressionSpec}: every selected entry is an element of
|
|
53
|
+
* the registry the caller supplied, returned by reference, so
|
|
54
|
+
* `registry.includes(selected.spec)` holds by identity for every selection.
|
|
55
|
+
* A test asserts that identity rather than an id match, because an id match
|
|
56
|
+
* would also be satisfied by a synthesized spec carrying a copied id.
|
|
57
|
+
*/
|
|
58
|
+
import { affected, isSyntheticNode, type Graph } from '../discovery_graph.js';
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* An EXISTING regression, as the registry holds it. `guards` names the artefact
|
|
62
|
+
* ids whose breakage this regression would detect.
|
|
63
|
+
*
|
|
64
|
+
* Nothing in this module builds one of these. It is the caller's registry entry,
|
|
65
|
+
* passed through by reference.
|
|
66
|
+
*/
|
|
67
|
+
export interface RegressionSpec {
|
|
68
|
+
id: string;
|
|
69
|
+
guards: readonly string[];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** A candidate under evaluation, reduced to the surfaces it touches. */
|
|
73
|
+
export interface Candidate {
|
|
74
|
+
id: string;
|
|
75
|
+
/** Artefact ids the candidate's diff touches. */
|
|
76
|
+
touches: readonly string[];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Why a node is in the neighbourhood: the candidate touched it, or a relation reached it. */
|
|
80
|
+
export type NeighbourReason = 'touched' | 'neighbour';
|
|
81
|
+
|
|
82
|
+
export interface NeighbourhoodNode {
|
|
83
|
+
node: string;
|
|
84
|
+
reason: NeighbourReason;
|
|
85
|
+
/** Hop distance from the nearest touched surface. `0` for a touched surface. */
|
|
86
|
+
depth: number;
|
|
87
|
+
/** The relation that reached it, or `''` for a touched surface. */
|
|
88
|
+
via: string;
|
|
89
|
+
/** True for `pack:` / `workspace:` container nodes the graph invents. */
|
|
90
|
+
synthetic: boolean;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface Selection {
|
|
94
|
+
spec: RegressionSpec;
|
|
95
|
+
/** The neighbourhood nodes this regression guards, sorted. */
|
|
96
|
+
matched: readonly string[];
|
|
97
|
+
/** `touched` when it guards a surface the candidate edited, else `neighbour`. */
|
|
98
|
+
reason: NeighbourReason;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface NeighbourhoodReport {
|
|
102
|
+
candidate_id: string;
|
|
103
|
+
neighbourhood: readonly NeighbourhoodNode[];
|
|
104
|
+
/** Touched surfaces that are not nodes in the graph. A refusal reason, not a warning. */
|
|
105
|
+
unresolved: readonly string[];
|
|
106
|
+
selected: readonly Selection[];
|
|
107
|
+
/** Registry entries whose guards intersect nothing in the neighbourhood. */
|
|
108
|
+
skipped: readonly string[];
|
|
109
|
+
/**
|
|
110
|
+
* Literal 0. This module selects from a registry; a non-zero value here
|
|
111
|
+
* would mean it authored a task, which is K9.
|
|
112
|
+
*/
|
|
113
|
+
authored: 0;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Hops walked out from each touched surface.
|
|
118
|
+
*
|
|
119
|
+
* A STATED default, not a measured optimum. Two is the smallest depth that
|
|
120
|
+
* reaches a `routes_to` target AND that target's own container membership, so a
|
|
121
|
+
* rule edit neighbours the skill it routes to and the pack that skill sits in.
|
|
122
|
+
* `revisit-if` a run selects a regression nobody can explain from the diff, or
|
|
123
|
+
* a real breakage lands outside the two-hop set.
|
|
124
|
+
*/
|
|
125
|
+
export const DEFAULT_NEIGHBOURHOOD_DEPTH = 2;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* The neighbourhood of a candidate: every touched surface, plus everything the
|
|
129
|
+
* relation graph reaches from it within `depth` hops.
|
|
130
|
+
*
|
|
131
|
+
* Deterministic — nodes are emitted at their shallowest depth and sorted by
|
|
132
|
+
* `(depth, node)`, so two runs over the same graph produce byte-identical
|
|
133
|
+
* reports.
|
|
134
|
+
*/
|
|
135
|
+
export function neighbourhood(
|
|
136
|
+
graph: Graph,
|
|
137
|
+
candidate: Candidate,
|
|
138
|
+
depth: number = DEFAULT_NEIGHBOURHOOD_DEPTH,
|
|
139
|
+
): NeighbourhoodNode[] {
|
|
140
|
+
const best = new Map<string, NeighbourhoodNode>();
|
|
141
|
+
for (const t of candidate.touches) {
|
|
142
|
+
best.set(t, { node: t, reason: 'touched', depth: 0, via: '', synthetic: isSyntheticNode(t) });
|
|
143
|
+
}
|
|
144
|
+
for (const t of candidate.touches) {
|
|
145
|
+
for (const hit of affected(graph, t, depth)) {
|
|
146
|
+
const prior = best.get(hit.node);
|
|
147
|
+
if (prior !== undefined && prior.depth <= hit.depth) continue;
|
|
148
|
+
best.set(hit.node, {
|
|
149
|
+
node: hit.node,
|
|
150
|
+
reason: 'neighbour',
|
|
151
|
+
depth: hit.depth,
|
|
152
|
+
via: hit.via,
|
|
153
|
+
synthetic: isSyntheticNode(hit.node),
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return [...best.values()].sort((a, b) => a.depth - b.depth || a.node.localeCompare(b.node));
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** Touched surfaces the graph does not know about. */
|
|
161
|
+
export function unresolvedSurfaces(graph: Graph, candidate: Candidate): string[] {
|
|
162
|
+
const known = new Set(graph.nodes);
|
|
163
|
+
return candidate.touches.filter((t) => !known.has(t)).sort((a, b) => a.localeCompare(b));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Select the registry entries whose guards intersect the candidate's
|
|
168
|
+
* neighbourhood.
|
|
169
|
+
*
|
|
170
|
+
* The returned `spec` values are the caller's registry objects, by reference.
|
|
171
|
+
*/
|
|
172
|
+
export function selectRegressions(
|
|
173
|
+
graph: Graph,
|
|
174
|
+
candidate: Candidate,
|
|
175
|
+
registry: readonly RegressionSpec[],
|
|
176
|
+
depth: number = DEFAULT_NEIGHBOURHOOD_DEPTH,
|
|
177
|
+
): NeighbourhoodReport {
|
|
178
|
+
const hood = neighbourhood(graph, candidate, depth);
|
|
179
|
+
const reasonOf = new Map<string, NeighbourReason>(hood.map((n) => [n.node, n.reason]));
|
|
180
|
+
const selected: Selection[] = [];
|
|
181
|
+
const skipped: string[] = [];
|
|
182
|
+
for (const spec of registry) {
|
|
183
|
+
const matched = spec.guards.filter((g) => reasonOf.has(g)).sort((a, b) => a.localeCompare(b));
|
|
184
|
+
if (matched.length === 0) {
|
|
185
|
+
skipped.push(spec.id);
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
const reason: NeighbourReason = matched.some((m) => reasonOf.get(m) === 'touched')
|
|
189
|
+
? 'touched'
|
|
190
|
+
: 'neighbour';
|
|
191
|
+
selected.push({ spec, matched, reason });
|
|
192
|
+
}
|
|
193
|
+
return {
|
|
194
|
+
candidate_id: candidate.id,
|
|
195
|
+
neighbourhood: hood,
|
|
196
|
+
unresolved: unresolvedSurfaces(graph, candidate),
|
|
197
|
+
selected: selected.sort((a, b) => a.spec.id.localeCompare(b.spec.id)),
|
|
198
|
+
skipped: skipped.sort((a, b) => a.localeCompare(b)),
|
|
199
|
+
authored: 0,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* `null` when the selection may be trusted, otherwise every reason it may not.
|
|
205
|
+
*
|
|
206
|
+
* Fail-closed by construction: no option object relaxes a reason, so a caller
|
|
207
|
+
* who wants to proceed on an unresolved surface has to delete this call — which
|
|
208
|
+
* is visible in a diff — rather than pass a flag, which is not.
|
|
209
|
+
*/
|
|
210
|
+
export function selectionVerdict(report: NeighbourhoodReport): readonly string[] | null {
|
|
211
|
+
const reasons: string[] = [];
|
|
212
|
+
if (report.unresolved.length > 0) {
|
|
213
|
+
reasons.push(
|
|
214
|
+
`touched surfaces absent from the relation graph: ${report.unresolved.join(', ')} — ` +
|
|
215
|
+
'their neighbourhood is unknown, and an unknown neighbourhood is not an empty one',
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
if (report.neighbourhood.length === 0) {
|
|
219
|
+
reasons.push('empty neighbourhood — the candidate touches nothing the graph knows');
|
|
220
|
+
}
|
|
221
|
+
return reasons.length === 0 ? null : reasons;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/** One regression's observed result on a candidate. */
|
|
225
|
+
export interface RegressionOutcome {
|
|
226
|
+
regression_id: string;
|
|
227
|
+
passed: boolean;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export interface CatchReport {
|
|
231
|
+
/** Selected regressions that FAILED — the breakages this selection caught. */
|
|
232
|
+
caught: readonly string[];
|
|
233
|
+
/**
|
|
234
|
+
* Regressions that failed but were never selected, so their failure was
|
|
235
|
+
* never observed. Present so a miss is countable rather than invisible.
|
|
236
|
+
*/
|
|
237
|
+
missed: readonly string[];
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Split observed regression outcomes by whether the selection actually ran them.
|
|
242
|
+
*
|
|
243
|
+
* `outcomes` is the full registry's result — what WOULD have been observed had
|
|
244
|
+
* everything run. `caught` is the part the neighbourhood selection reached;
|
|
245
|
+
* `missed` is the part it did not. A selector that narrows too far shows up
|
|
246
|
+
* here as a non-empty `missed`, which is what makes the fixture in
|
|
247
|
+
* `tests/scripts/regression_neighbourhood.test.ts` falsifiable.
|
|
248
|
+
*/
|
|
249
|
+
export function catchReport(
|
|
250
|
+
report: NeighbourhoodReport,
|
|
251
|
+
outcomes: readonly RegressionOutcome[],
|
|
252
|
+
): CatchReport {
|
|
253
|
+
const ran = new Set(report.selected.map((s) => s.spec.id));
|
|
254
|
+
const failed = outcomes.filter((o) => !o.passed).map((o) => o.regression_id);
|
|
255
|
+
return {
|
|
256
|
+
caught: failed.filter((id) => ran.has(id)).sort((a, b) => a.localeCompare(b)),
|
|
257
|
+
missed: failed.filter((id) => !ran.has(id)).sort((a, b) => a.localeCompare(b)),
|
|
258
|
+
};
|
|
259
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The repeated-failure rate — computed over the AMENDED view, by construction.
|
|
3
|
+
*
|
|
4
|
+
* This is the roadmap's single pre-registered core metric, and the reason it
|
|
5
|
+
* needed the amendment path first is arithmetic rather than aesthetic. A repeat
|
|
6
|
+
* is precisely the signal that surfaces AFTER an episode's terminal record is
|
|
7
|
+
* written: rework lands, a regression is found, a review comes back. A rate
|
|
8
|
+
* computed over unamended rows therefore undercounts the exact thing it exists
|
|
9
|
+
* to measure, and undercounts it in the flattering direction.
|
|
10
|
+
*
|
|
11
|
+
* The guarantee here is structural, not documentary: this module's input type
|
|
12
|
+
* is {@link EpisodeReconstruction}, which is the folded projection. It has no
|
|
13
|
+
* overload taking raw `JournalEvent[]`, so a caller CANNOT accidentally compute
|
|
14
|
+
* the rate over unamended rows — there is nothing to pass.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type { BasisTag } from './evidence_basis.js';
|
|
18
|
+
import type { EpisodeReconstruction } from './runtime_journal.js';
|
|
19
|
+
import { RUN_TERMINAL_STATES, type RunTerminalState } from './outcome_vocabularies.js';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Terminal states that count as a failure for this metric.
|
|
23
|
+
*
|
|
24
|
+
* `clean-no-op` is deliberately NOT a failure: an episode that correctly
|
|
25
|
+
* determined there was nothing to do succeeded at the thing it was asked. And
|
|
26
|
+
* `approval-required` is not one either — it is the safety floor working, and
|
|
27
|
+
* counting a floor doing its job as a failure would make the metric fall every
|
|
28
|
+
* time governance fires.
|
|
29
|
+
*/
|
|
30
|
+
export const FAILURE_TERMINALS: ReadonlySet<RunTerminalState> = new Set([
|
|
31
|
+
'blocked',
|
|
32
|
+
'exhausted',
|
|
33
|
+
'stagnated',
|
|
34
|
+
]);
|
|
35
|
+
|
|
36
|
+
/** States that count as a success for the metric. */
|
|
37
|
+
export const SUCCESS_TERMINALS: ReadonlySet<RunTerminalState> = new Set([
|
|
38
|
+
'success',
|
|
39
|
+
'clean-no-op',
|
|
40
|
+
]);
|
|
41
|
+
|
|
42
|
+
// Every terminal state is classified or deliberately excluded -- silence about
|
|
43
|
+
// one is how a metric quietly changes meaning when the vocabulary grows.
|
|
44
|
+
const CLASSIFIED = new Set<string>([...FAILURE_TERMINALS, ...SUCCESS_TERMINALS, 'approval-required']);
|
|
45
|
+
const _unclassified = RUN_TERMINAL_STATES.filter((t) => !CLASSIFIED.has(t));
|
|
46
|
+
if (_unclassified.length > 0) {
|
|
47
|
+
throw new Error(
|
|
48
|
+
`repeated_failure: terminal state(s) ${_unclassified.join(', ')} are neither a failure, ` +
|
|
49
|
+
'a success, nor explicitly excluded. Classify them or the rate silently changes meaning.',
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface RepeatedFailureRate {
|
|
54
|
+
/** Episodes whose EFFECTIVE terminal state is a failure. */
|
|
55
|
+
failed: number;
|
|
56
|
+
/** Episodes with any classifiable effective terminal state. */
|
|
57
|
+
classified: number;
|
|
58
|
+
/** Episodes whose terminal state is absent or excluded. Its own share. */
|
|
59
|
+
unknown: number;
|
|
60
|
+
/** `failed / classified`, or `null` when nothing was classifiable. */
|
|
61
|
+
rate: number | null;
|
|
62
|
+
/** How many of the counted episodes carried at least one amendment. */
|
|
63
|
+
amended_episodes: number;
|
|
64
|
+
basis: BasisTag;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Compute the rate.
|
|
69
|
+
*
|
|
70
|
+
* `rate` is `null`, never `0`, when nothing classifiable was seen — the same
|
|
71
|
+
* rule the per-asset report follows, for the same reason: zero is a measurement
|
|
72
|
+
* and null is an absence, and a reader acts on the first while asking about the
|
|
73
|
+
* second.
|
|
74
|
+
*/
|
|
75
|
+
export function repeatedFailureRate(
|
|
76
|
+
episodes: readonly EpisodeReconstruction[],
|
|
77
|
+
): RepeatedFailureRate {
|
|
78
|
+
let failed = 0;
|
|
79
|
+
let classified = 0;
|
|
80
|
+
let unknown = 0;
|
|
81
|
+
let amended_episodes = 0;
|
|
82
|
+
|
|
83
|
+
for (const ep of episodes) {
|
|
84
|
+
if (ep.amendment_count > 0) amended_episodes += 1;
|
|
85
|
+
|
|
86
|
+
// `ep.terminal_state` is already the AMENDED verdict: reconstructEpisode
|
|
87
|
+
// drops superseded rows and takes the LAST effective terminal state.
|
|
88
|
+
const t = ep.terminal_state;
|
|
89
|
+
if (t === null || !CLASSIFIED.has(t) || t === 'approval-required') {
|
|
90
|
+
unknown += 1;
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
classified += 1;
|
|
94
|
+
if (FAILURE_TERMINALS.has(t)) failed += 1;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
failed,
|
|
99
|
+
classified,
|
|
100
|
+
unknown,
|
|
101
|
+
rate: classified === 0 ? null : failed / classified,
|
|
102
|
+
amended_episodes,
|
|
103
|
+
basis: 'estimated:ratio-over-amended-episode-terminals',
|
|
104
|
+
};
|
|
105
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repository-root resolution that REFUSES rather than guesses.
|
|
3
|
+
*
|
|
4
|
+
* `road-to-skill-ecosystem-runtime-enforcement` Phase 2 Step 6. The trap class
|
|
5
|
+
* this closes is small to describe and has cost multiple sessions:
|
|
6
|
+
*
|
|
7
|
+
* 1. **An inherited `GIT_DIR`.** A git hook exports `GIT_DIR` (often `.git`,
|
|
8
|
+
* relative) into every child process. A gate that resolves its root with
|
|
9
|
+
* `git rev-parse --show-toplevel` then answers for whatever repository the
|
|
10
|
+
* inherited variable points at — which inside a worktree hook is the parent
|
|
11
|
+
* checkout, not the tree being committed. The gate runs, reads the wrong
|
|
12
|
+
* files, and passes.
|
|
13
|
+
* 2. **A path walked one directory too far.** `path.resolve(__dirname, '..',
|
|
14
|
+
* '..')` is correct until a file moves, and then it silently addresses a
|
|
15
|
+
* parent directory that also exists. Nothing fails; the scan is simply
|
|
16
|
+
* empty, which several gates report as a clean pass.
|
|
17
|
+
*
|
|
18
|
+
* Both are the same failure in the end: a resolver that always SUCCEEDS. So the
|
|
19
|
+
* contract here is the opposite — a root is returned only when the directory
|
|
20
|
+
* carries a **sentinel** proving it is the repository, and otherwise the call
|
|
21
|
+
* throws. A caller that cannot locate its own repository should stop, not scan
|
|
22
|
+
* an arbitrary directory.
|
|
23
|
+
*
|
|
24
|
+
* The sentinel is `package.json` carrying this package's `name`, not a bare
|
|
25
|
+
* `package.json`: every node_modules entry and every sibling project has one of
|
|
26
|
+
* those, and a resolver that accepts any of them has not narrowed anything.
|
|
27
|
+
*/
|
|
28
|
+
import * as fs from 'node:fs';
|
|
29
|
+
import * as path from 'node:path';
|
|
30
|
+
|
|
31
|
+
/** The package name that identifies THIS repository. */
|
|
32
|
+
export const SENTINEL_PACKAGE_NAME = '@event4u/agent-config';
|
|
33
|
+
|
|
34
|
+
/** Raised when no directory on the walk carries the sentinel. */
|
|
35
|
+
export class RepoRootUnresolvedError extends Error {
|
|
36
|
+
readonly startedAt: string;
|
|
37
|
+
|
|
38
|
+
constructor(startedAt: string, message: string) {
|
|
39
|
+
super(message);
|
|
40
|
+
this.name = 'RepoRootUnresolvedError';
|
|
41
|
+
this.startedAt = startedAt;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* True when `dir` is this repository's root.
|
|
47
|
+
*
|
|
48
|
+
* Reads `package.json` and compares `name`. A parse failure is `false`, never a
|
|
49
|
+
* throw: a malformed `package.json` somewhere up the walk must not stop the walk
|
|
50
|
+
* from reaching a valid root above it.
|
|
51
|
+
*/
|
|
52
|
+
export function hasSentinel(dir: string): boolean {
|
|
53
|
+
try {
|
|
54
|
+
const raw = fs.readFileSync(path.join(dir, 'package.json'), 'utf8');
|
|
55
|
+
return (JSON.parse(raw) as { name?: unknown }).name === SENTINEL_PACKAGE_NAME;
|
|
56
|
+
} catch {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Walk upward from `from` and return the first directory carrying the sentinel.
|
|
63
|
+
*
|
|
64
|
+
* @throws {RepoRootUnresolvedError} when the walk reaches the filesystem root
|
|
65
|
+
* without finding one. Deliberately not a `null` return: an optional type
|
|
66
|
+
* invites `?? process.cwd()`, which is the guess this module exists to prevent.
|
|
67
|
+
*/
|
|
68
|
+
export function resolveRepoRoot(from: string = process.cwd()): string {
|
|
69
|
+
let dir = path.resolve(from);
|
|
70
|
+
const seen: string[] = [];
|
|
71
|
+
for (;;) {
|
|
72
|
+
seen.push(dir);
|
|
73
|
+
if (hasSentinel(dir)) return dir;
|
|
74
|
+
const parent = path.dirname(dir);
|
|
75
|
+
if (parent === dir) break;
|
|
76
|
+
dir = parent;
|
|
77
|
+
}
|
|
78
|
+
throw new RepoRootUnresolvedError(
|
|
79
|
+
path.resolve(from),
|
|
80
|
+
`no repository root above ${path.resolve(from)} — no directory on the walk carries a ` +
|
|
81
|
+
`package.json named "${SENTINEL_PACKAGE_NAME}". Checked ${String(seen.length)} directory(ies). ` +
|
|
82
|
+
'This is a refusal, not a fallback: resolving to the working directory here is how a gate ' +
|
|
83
|
+
'ends up scanning an arbitrary tree and reporting a clean pass over it.',
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* The environment variables that override git's own discovery.
|
|
89
|
+
*
|
|
90
|
+
* `GIT_DIR` is the one that has actually bitten; the other three are listed
|
|
91
|
+
* because they fail the same way and a reader checking for one should see all
|
|
92
|
+
* four rather than believe the list is complete at one entry.
|
|
93
|
+
*/
|
|
94
|
+
export const GIT_DISCOVERY_OVERRIDES = [
|
|
95
|
+
'GIT_DIR',
|
|
96
|
+
'GIT_WORK_TREE',
|
|
97
|
+
'GIT_INDEX_FILE',
|
|
98
|
+
'GIT_COMMON_DIR',
|
|
99
|
+
] as const;
|
|
100
|
+
|
|
101
|
+
/** Any git discovery override present in `env`, with its value. */
|
|
102
|
+
export function inheritedGitOverrides(
|
|
103
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
104
|
+
): { name: string; value: string }[] {
|
|
105
|
+
const out: { name: string; value: string }[] = [];
|
|
106
|
+
for (const name of GIT_DISCOVERY_OVERRIDES) {
|
|
107
|
+
const value = env[name];
|
|
108
|
+
if (typeof value === 'string' && value !== '') out.push({ name, value });
|
|
109
|
+
}
|
|
110
|
+
return out;
|
|
111
|
+
}
|
|
@@ -34,6 +34,17 @@
|
|
|
34
34
|
*/
|
|
35
35
|
export type MutationMeasure = 'exact' | 'capped_approximation';
|
|
36
36
|
|
|
37
|
+
import type { NoFreeForm } from './runtime_journal.js';
|
|
38
|
+
import { type PrivacyClass } from './privacy_class.js';
|
|
39
|
+
|
|
40
|
+
type Assert<T extends true> = T;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* What THIS producer's lines carry: counts (`diff_lines`), enums, and the
|
|
44
|
+
* `rules_applied` id array. `ids-only`, same as the orchestration producer.
|
|
45
|
+
*/
|
|
46
|
+
const PRODUCER_PRIVACY_CLASS: PrivacyClass = 'ids-only';
|
|
47
|
+
|
|
37
48
|
export interface ReviewSkippedInput {
|
|
38
49
|
/** Non-doc tracked-file mutation size that triggered the nudge (count only). */
|
|
39
50
|
diff_lines: number;
|
|
@@ -92,6 +103,15 @@ export function buildReviewSkippedLine(input: ReviewSkippedInput): BuiltReviewSk
|
|
|
92
103
|
memory: { asks: 0, hits: 0 },
|
|
93
104
|
verify: { claims: 0, first_try_passes: 0 },
|
|
94
105
|
rules_applied: ['delegation-policy'],
|
|
106
|
+
// MANDATORY on every audit line, same as the orchestration producer.
|
|
107
|
+
privacy_class: PRODUCER_PRIVACY_CLASS,
|
|
108
|
+
// `skills_applied` is OMITTED here, deliberately and not by oversight.
|
|
109
|
+
// audit-log-v1 distinguishes an absent key ("not recorded") from `[]`
|
|
110
|
+
// ("recorded, none applied"), and this writer observes a review that
|
|
111
|
+
// did not happen -- it has no skill observation to offer in either
|
|
112
|
+
// direction. Emitting `[]` would assert "no skills applied" on evidence
|
|
113
|
+
// this producer never gathered, which is the exact fabrication the
|
|
114
|
+
// absent/empty split exists to make impossible.
|
|
95
115
|
persona: null,
|
|
96
116
|
input_kind: 'prompt',
|
|
97
117
|
type: 'note',
|
|
@@ -100,3 +120,20 @@ export function buildReviewSkippedLine(input: ReviewSkippedInput): BuiltReviewSk
|
|
|
100
120
|
|
|
101
121
|
return { line, errors: [] };
|
|
102
122
|
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* The SECOND producer's half of the compile-time privacy floor.
|
|
126
|
+
*
|
|
127
|
+
* `docs/contracts/audit-log-v1.md` states that the floor holds by construction
|
|
128
|
+
* "on two paths"; guarding only the first would leave that sentence half true
|
|
129
|
+
* while reading as fully true. Same mechanism as
|
|
130
|
+
* `orchestration_record.ts`: a free-form key on the input type makes this
|
|
131
|
+
* `Assert<false>` and stops the build.
|
|
132
|
+
*
|
|
133
|
+
* The negative direction is fixtured there rather than duplicated here — one
|
|
134
|
+
* proof that `NoFreeForm` still rejects is enough for both call sites, since
|
|
135
|
+
* they share the type.
|
|
136
|
+
*/
|
|
137
|
+
type _ReviewSkippedInputCarriesNoFreeFormField = Assert<
|
|
138
|
+
[NoFreeForm<ReviewSkippedInput>] extends [never] ? false : true
|
|
139
|
+
>;
|