@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,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Paired binary statistics — the exact test and its effect size.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from `bench_ab_v2_stats.ts` and re-exported there, so every existing
|
|
5
|
+
* importer is unchanged. The move is not cosmetic: that file sits above the
|
|
6
|
+
* 1500-line ceiling `check_source_size_budget` charges, so lines added to it are
|
|
7
|
+
* paid back by extraction rather than by raising a baseline.
|
|
8
|
+
*
|
|
9
|
+
* `mcnemar_exact` is the shape `_lib/paired_verdict.ts` generalises — a binomial
|
|
10
|
+
* over DISCORDANT pairs only, which is the whole point: a concordant pair
|
|
11
|
+
* carries no information about direction and must not dilute the count. This one
|
|
12
|
+
* is two-sided (its callers ask whether the arms differ); `paired_verdict`'s is
|
|
13
|
+
* one-sided (it asks whether the treatment is better). They are kept apart for
|
|
14
|
+
* that reason rather than merged into a flag.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/** Exact binomial coefficient via BigInt, so a large n cannot drift. */
|
|
18
|
+
function comb(n: number, k: number): number {
|
|
19
|
+
if (k < 0 || k > n) return 0;
|
|
20
|
+
let num = 1n;
|
|
21
|
+
let den = 1n;
|
|
22
|
+
const kk = BigInt(Math.min(k, n - k));
|
|
23
|
+
for (let i = 0n; i < kk; i += 1n) {
|
|
24
|
+
num *= BigInt(n) - i;
|
|
25
|
+
den *= i + 1n;
|
|
26
|
+
}
|
|
27
|
+
return Number(num / den);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function mcnemar_exact(b: number, c: number): number {
|
|
31
|
+
// Two-sided exact McNemar p-value (binomial on discordant pairs).
|
|
32
|
+
const n = b + c;
|
|
33
|
+
if (n === 0) {
|
|
34
|
+
return 1.0;
|
|
35
|
+
}
|
|
36
|
+
const k = Math.min(b, c);
|
|
37
|
+
let tail = 0;
|
|
38
|
+
for (let i = 0; i <= k; i += 1) {
|
|
39
|
+
tail += comb(n, i);
|
|
40
|
+
}
|
|
41
|
+
tail = tail * 0.5 ** n;
|
|
42
|
+
return Math.min(1.0, 2.0 * tail);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function cohens_h(p1: number, p2: number): number {
|
|
46
|
+
return (
|
|
47
|
+
2 * Math.asin(Math.sqrt(Math.max(0, Math.min(1, p1)))) -
|
|
48
|
+
2 * Math.asin(Math.sqrt(Math.max(0, Math.min(1, p2))))
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Python `round(x)` (no ndigits) → int, round-half-to-even. */
|
|
53
|
+
export function _pyRoundNoArg(x: number): number {
|
|
54
|
+
if (!Number.isFinite(x)) return x;
|
|
55
|
+
const floor = Math.floor(x);
|
|
56
|
+
const frac = x - floor;
|
|
57
|
+
if (frac < 0.5) return floor;
|
|
58
|
+
if (frac > 0.5) return floor + 1;
|
|
59
|
+
return floor % 2 === 0 ? floor : floor + 1;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Python `round(x, ndigits)` — round-half-to-even on the exact double. */
|
|
63
|
+
export function _pyRound(value: number, ndigits: number): number {
|
|
64
|
+
if (!Number.isFinite(value) || value === 0) {
|
|
65
|
+
return value;
|
|
66
|
+
}
|
|
67
|
+
const neg = value < 0;
|
|
68
|
+
const abs = Math.abs(value);
|
|
69
|
+
const exact = abs.toFixed(40);
|
|
70
|
+
const dot = exact.indexOf('.');
|
|
71
|
+
const intPart = dot === -1 ? exact : exact.slice(0, dot);
|
|
72
|
+
const fracPart = dot === -1 ? '' : exact.slice(dot + 1);
|
|
73
|
+
const keepFrac = fracPart.slice(0, ndigits).padEnd(ndigits, '0');
|
|
74
|
+
const rest = fracPart.slice(ndigits);
|
|
75
|
+
const scaledStr = (intPart + keepFrac).replace(/^0+(?=\d)/, '');
|
|
76
|
+
let scaled = BigInt(scaledStr === '' ? '0' : scaledStr);
|
|
77
|
+
if (rest.length > 0) {
|
|
78
|
+
const firstRest = rest.charCodeAt(0) - 48;
|
|
79
|
+
const hasMore = /[1-9]/.test(rest.slice(1));
|
|
80
|
+
if (firstRest > 5 || (firstRest === 5 && hasMore)) {
|
|
81
|
+
scaled += 1n;
|
|
82
|
+
} else if (firstRest === 5 && !hasMore) {
|
|
83
|
+
if (scaled % 2n === 1n) {
|
|
84
|
+
scaled += 1n;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
const factor = 10 ** ndigits;
|
|
89
|
+
const result = Number(scaled) / factor;
|
|
90
|
+
return neg ? -result : result;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// CPython's `m_erf` (Modules/mathmodule.c): a Maclaurin series for |x| < 1.5
|
|
94
|
+
// and 1 - erfc for larger |x|; `m_erfc` uses a continued-fraction expansion.
|
|
95
|
+
// Ported verbatim so `_phi(z)` matches python3 to full double precision.
|
|
96
|
+
|
|
97
|
+
const _ERF_SERIES_CUTOFF = 1.5;
|
|
98
|
+
const _ERF_SERIES_TERMS = 25;
|
|
99
|
+
const _ERFC_CONTFRAC_CUTOFF = 30.0;
|
|
100
|
+
const _ERFC_CONTFRAC_TERMS = 50;
|
|
101
|
+
const _SQRTPI = 1.772453850905516027298167483341145182798;
|
|
102
|
+
|
|
103
|
+
function _m_erf_series(x: number): number {
|
|
104
|
+
// erf(x) = 2/sqrt(pi) * x * sum_{k>=0} (-x^2)^k / (k! (2k+1))
|
|
105
|
+
let x2 = x * x;
|
|
106
|
+
let acc = 0.0;
|
|
107
|
+
let fk = _ERF_SERIES_TERMS + 0.5;
|
|
108
|
+
for (let i = 0; i < _ERF_SERIES_TERMS; i += 1) {
|
|
109
|
+
acc = 2.0 + (x2 * acc) / fk;
|
|
110
|
+
fk -= 1.0;
|
|
111
|
+
}
|
|
112
|
+
return (acc * x * Math.exp(-x2)) / _SQRTPI;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function _m_erfc_contfrac(x: number): number {
|
|
116
|
+
if (x >= _ERFC_CONTFRAC_CUTOFF) {
|
|
117
|
+
return 0.0;
|
|
118
|
+
}
|
|
119
|
+
const x2 = x * x;
|
|
120
|
+
let a = 0.0;
|
|
121
|
+
let da = 0.5;
|
|
122
|
+
let p = 1.0;
|
|
123
|
+
let p_last = 0.0;
|
|
124
|
+
let q = da + x2;
|
|
125
|
+
let q_last = 1.0;
|
|
126
|
+
for (let i = 0; i < _ERFC_CONTFRAC_TERMS; i += 1) {
|
|
127
|
+
a += da;
|
|
128
|
+
da += 2.0;
|
|
129
|
+
const b = da + x2;
|
|
130
|
+
const temp_p = b * p - a * p_last;
|
|
131
|
+
p_last = p;
|
|
132
|
+
p = temp_p;
|
|
133
|
+
const temp_q = b * q - a * q_last;
|
|
134
|
+
q_last = q;
|
|
135
|
+
q = temp_q;
|
|
136
|
+
}
|
|
137
|
+
return (((p / q) * x) * Math.exp(-x2)) / _SQRTPI;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function _erf(x: number): number {
|
|
141
|
+
if (Number.isNaN(x)) {
|
|
142
|
+
return x;
|
|
143
|
+
}
|
|
144
|
+
const absx = Math.abs(x);
|
|
145
|
+
if (absx < _ERF_SERIES_CUTOFF) {
|
|
146
|
+
return _m_erf_series(x);
|
|
147
|
+
}
|
|
148
|
+
const cf = _m_erfc_contfrac(absx);
|
|
149
|
+
return x > 0.0 ? 1.0 - cf : cf - 1.0;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** Python `math.comb(n, k)` — exact non-negative integer (BigInt → Number). */
|
|
153
|
+
function _comb(n: number, k: number): number {
|
|
154
|
+
if (k < 0 || k > n) {
|
|
155
|
+
return 0;
|
|
156
|
+
}
|
|
157
|
+
let kk = BigInt(Math.min(k, n - k));
|
|
158
|
+
if (kk === 0n) {
|
|
159
|
+
return 1;
|
|
160
|
+
}
|
|
161
|
+
const N = BigInt(n);
|
|
162
|
+
let result = 1n;
|
|
163
|
+
let i = 0n;
|
|
164
|
+
while (i < kk) {
|
|
165
|
+
result = (result * (N - i)) / (i + 1n);
|
|
166
|
+
i += 1n;
|
|
167
|
+
}
|
|
168
|
+
return Number(result);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function _phi(z: number): number {
|
|
172
|
+
// Standard-normal CDF via erf.
|
|
173
|
+
return 0.5 * (1.0 + _erf(z / Math.sqrt(2.0)));
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
interface WilcoxonResult {
|
|
178
|
+
n: number;
|
|
179
|
+
W_plus: number; // PyFloat-flagged at dump for the rounded case
|
|
180
|
+
W_minus: number;
|
|
181
|
+
p: number;
|
|
182
|
+
rank_biserial: number;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export function wilcoxon(diffs: number[]): WilcoxonResult {
|
|
186
|
+
// Wilcoxon signed-rank on paired differences (treatment - baseline).
|
|
187
|
+
// Returns W+, W-, normal-approx two-sided p (continuity-corrected), and
|
|
188
|
+
// rank-biserial effect size. Zeros are dropped.
|
|
189
|
+
const nz = diffs.filter((d) => Math.abs(d) > 1e-9);
|
|
190
|
+
const n = nz.length;
|
|
191
|
+
if (n === 0) {
|
|
192
|
+
return { n: 0, W_plus: 0, W_minus: 0, p: 1.0, rank_biserial: 0.0 };
|
|
193
|
+
}
|
|
194
|
+
// order = sorted(range(n), key=lambda i: abs(nz[i])) — stable sort.
|
|
195
|
+
const order = Array.from({ length: n }, (_, i) => i).sort((x, y) => {
|
|
196
|
+
const ax = Math.abs(nz[x] as number);
|
|
197
|
+
const ay = Math.abs(nz[y] as number);
|
|
198
|
+
return ax < ay ? -1 : ax > ay ? 1 : x - y; // stable on tie
|
|
199
|
+
});
|
|
200
|
+
const ranks: number[] = new Array(n).fill(0.0);
|
|
201
|
+
let i = 0;
|
|
202
|
+
while (i < n) {
|
|
203
|
+
let j = i;
|
|
204
|
+
while (j + 1 < n && Math.abs(nz[order[j + 1] as number] as number) === Math.abs(nz[order[i] as number] as number)) {
|
|
205
|
+
j += 1;
|
|
206
|
+
}
|
|
207
|
+
const avg = (i + 1 + j + 1) / 2.0; // average rank for ties (1-based)
|
|
208
|
+
for (let k = i; k <= j; k += 1) {
|
|
209
|
+
ranks[order[k] as number] = avg;
|
|
210
|
+
}
|
|
211
|
+
i = j + 1;
|
|
212
|
+
}
|
|
213
|
+
let w_plus = 0.0;
|
|
214
|
+
let w_minus = 0.0;
|
|
215
|
+
for (let idx = 0; idx < n; idx += 1) {
|
|
216
|
+
if ((nz[idx] as number) > 0) {
|
|
217
|
+
w_plus += ranks[idx] as number;
|
|
218
|
+
} else if ((nz[idx] as number) < 0) {
|
|
219
|
+
w_minus += ranks[idx] as number;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
const total = w_plus + w_minus;
|
|
223
|
+
const rb = total ? (w_plus - w_minus) / total : 0.0;
|
|
224
|
+
// Normal approximation (ok-ish for n>=10; for small n it's conservative —
|
|
225
|
+
// we surface n so the reader can weight it).
|
|
226
|
+
const mean = (n * (n + 1)) / 4.0;
|
|
227
|
+
const sd = Math.sqrt((n * (n + 1) * (2 * n + 1)) / 24.0);
|
|
228
|
+
const w = Math.min(w_plus, w_minus);
|
|
229
|
+
let p: number;
|
|
230
|
+
if (sd === 0) {
|
|
231
|
+
p = 1.0;
|
|
232
|
+
} else {
|
|
233
|
+
const z = (w - mean + 0.5) / sd;
|
|
234
|
+
p = Math.min(1.0, 2.0 * _phi(z));
|
|
235
|
+
}
|
|
236
|
+
return {
|
|
237
|
+
n,
|
|
238
|
+
// W_plus / W_minus are not surfaced in JSON/markdown (compare() drops
|
|
239
|
+
// them), so plain numbers suffice; p / rank_biserial are floats.
|
|
240
|
+
W_plus: _pyRound(w_plus, 1),
|
|
241
|
+
W_minus: _pyRound(w_minus, 1),
|
|
242
|
+
p: _pyRound(p, 4),
|
|
243
|
+
rank_biserial: _pyRound(rb, 4),
|
|
244
|
+
};
|
|
245
|
+
}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Paired verdicts decided by DIRECTION, never by magnitude.
|
|
3
|
+
*
|
|
4
|
+
* `road-to-skill-ecosystem-eval-integrity` Phase 2. The defect this replaces was
|
|
5
|
+
* proved by exhaustive comparison rather than argued: weighting a paired
|
|
6
|
+
* confidence interval by per-trial magnitude disagrees with the exact test on
|
|
7
|
+
* twelve records up to ten trials, and it is the PERMISSIVE side in every one of
|
|
8
|
+
* them. The visible symptom is the opposite of what "permissive" suggests, which
|
|
9
|
+
* is why it went unnoticed — an artifact that won every trial still failed five
|
|
10
|
+
* consecutive runs, because a handful of large opposite-direction deltas
|
|
11
|
+
* outweighed a clean sweep of small ones.
|
|
12
|
+
*
|
|
13
|
+
* The fix is not a better interval. It is to stop asking the question magnitude
|
|
14
|
+
* answers. A paired comparison asks *did this help more often than it hurt*, and
|
|
15
|
+
* the exact test for that reads the DISCORDANT trials only: a pair where both
|
|
16
|
+
* arms tie carries no information about direction and must not dilute the count.
|
|
17
|
+
*
|
|
18
|
+
* ── What magnitude is still for ─────────────────────────────────────────────
|
|
19
|
+
* Triage, and nothing else. {@link PairedVerdict.magnitude_mean} is retained and
|
|
20
|
+
* reported so a human can see whether a directional win is worth anything, and
|
|
21
|
+
* every renderer that prints it must say it decides nothing. A number in a
|
|
22
|
+
* report with no stated role gets read as a criterion by the next person.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/** The four outcomes. `underpowered` is deliberately not a kind of pass. */
|
|
26
|
+
export type PairedVerdictKind = 'pass' | 'regression' | 'no-change' | 'underpowered';
|
|
27
|
+
|
|
28
|
+
export interface PairedVerdict {
|
|
29
|
+
kind: PairedVerdictKind;
|
|
30
|
+
/** Trials where the arms differed. Concordant pairs are excluded by design. */
|
|
31
|
+
discordant: number;
|
|
32
|
+
/** Discordant trials favouring the treatment. */
|
|
33
|
+
wins: number;
|
|
34
|
+
/** Discordant trials favouring the control. */
|
|
35
|
+
losses: number;
|
|
36
|
+
/** One-sided exact p in the observed direction. */
|
|
37
|
+
p: number;
|
|
38
|
+
/** Mean signed delta over ALL trials. Triage only — decides nothing. */
|
|
39
|
+
magnitude_mean: number | null;
|
|
40
|
+
/** True when `discordant` sits exactly on the derived floor. */
|
|
41
|
+
at_floor: boolean;
|
|
42
|
+
/** Why this verdict, in one sentence a report can print verbatim. */
|
|
43
|
+
reason: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Significance level. 0.05 is the convention every sibling gate in this tree
|
|
48
|
+
* already applies (`bench_ab_size_claim.ALPHA`), and changing it here would make
|
|
49
|
+
* two verdicts in one report answer to different bars.
|
|
50
|
+
*/
|
|
51
|
+
export const ALPHA = 0.05;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Minimum discordant trials, DERIVED from the test rather than chosen.
|
|
55
|
+
*
|
|
56
|
+
* The one-sided exact sign test over `n` discordant trials has a smallest
|
|
57
|
+
* attainable p of `0.5 ** n` — the probability of a perfect sweep. A pass at
|
|
58
|
+
* `ALPHA` is therefore arithmetically impossible until `0.5 ** n <= ALPHA`:
|
|
59
|
+
*
|
|
60
|
+
* n=1 → 0.5 n=2 → 0.25 n=3 → 0.125
|
|
61
|
+
* n=4 → 0.0625 n=5 → 0.03125 ← first n that can clear 0.05
|
|
62
|
+
*
|
|
63
|
+
* So the floor is **5**, and it is a fact about the test, not a preference. A
|
|
64
|
+
* specification with fewer discordant trials cannot pass however good the
|
|
65
|
+
* artifact is, which is why {@link decidePairedVerdict} returns `underpowered`
|
|
66
|
+
* there instead of `no-change`: the two look identical in a table and have
|
|
67
|
+
* opposite remedies — one says run more trials, the other says stop.
|
|
68
|
+
*
|
|
69
|
+
* Recomputed by {@link deriveMinDiscordant} rather than hardcoded, so a future
|
|
70
|
+
* change to ALPHA moves the floor with it instead of leaving a stale constant.
|
|
71
|
+
*/
|
|
72
|
+
export function deriveMinDiscordant(alpha: number = ALPHA): number {
|
|
73
|
+
let n = 1;
|
|
74
|
+
while (0.5 ** n > alpha && n < 64) n += 1;
|
|
75
|
+
return n;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export const MIN_DISCORDANT = deriveMinDiscordant();
|
|
79
|
+
|
|
80
|
+
/** Binomial coefficient, exact via BigInt so large n cannot drift. */
|
|
81
|
+
function comb(n: number, k: number): number {
|
|
82
|
+
if (k < 0 || k > n) return 0;
|
|
83
|
+
let num = 1n;
|
|
84
|
+
let den = 1n;
|
|
85
|
+
const kk = BigInt(Math.min(k, n - k));
|
|
86
|
+
for (let i = 0n; i < kk; i += 1n) {
|
|
87
|
+
num *= BigInt(n) - i;
|
|
88
|
+
den *= i + 1n;
|
|
89
|
+
}
|
|
90
|
+
return Number(num / den);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* One-sided exact sign test over discordant trials.
|
|
95
|
+
*
|
|
96
|
+
* `P(X >= wins)` under a fair coin on `discordant` trials — the probability of
|
|
97
|
+
* seeing at least this many wins if direction were noise. One-sided because the
|
|
98
|
+
* question a verdict asks is directional: *is the treatment better*, not *do the
|
|
99
|
+
* arms differ*. A two-sided p answers the second and is twice as hard to clear
|
|
100
|
+
* for the first, which is a bar nobody chose.
|
|
101
|
+
*/
|
|
102
|
+
export function exactOneSidedP(wins: number, discordant: number): number {
|
|
103
|
+
if (discordant <= 0) return 1;
|
|
104
|
+
let tail = 0;
|
|
105
|
+
for (let i = wins; i <= discordant; i += 1) tail += comb(discordant, i);
|
|
106
|
+
return Math.min(1, tail * 0.5 ** discordant);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export interface PairedInput {
|
|
110
|
+
/** One signed delta per trial. Positive favours the treatment. */
|
|
111
|
+
deltas: readonly number[];
|
|
112
|
+
/** Deltas within this of zero are ties and are excluded as concordant. */
|
|
113
|
+
tieEpsilon?: number;
|
|
114
|
+
alpha?: number;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Decide a paired comparison from direction alone.
|
|
119
|
+
*
|
|
120
|
+
* Ties are dropped BEFORE anything is counted, which is the half a
|
|
121
|
+
* magnitude-weighted interval gets wrong: a tie has zero magnitude, so it
|
|
122
|
+
* contributes nothing to the mean while still inflating `n` and narrowing the
|
|
123
|
+
* interval. Dropping it makes the sample honest about how much evidence there
|
|
124
|
+
* actually is.
|
|
125
|
+
*/
|
|
126
|
+
export function decidePairedVerdict(input: PairedInput): PairedVerdict {
|
|
127
|
+
const alpha = input.alpha ?? ALPHA;
|
|
128
|
+
const eps = input.tieEpsilon ?? 0;
|
|
129
|
+
const floor = deriveMinDiscordant(alpha);
|
|
130
|
+
const wins = input.deltas.filter((d) => d > eps).length;
|
|
131
|
+
const losses = input.deltas.filter((d) => d < -eps).length;
|
|
132
|
+
const discordant = wins + losses;
|
|
133
|
+
const magnitude_mean =
|
|
134
|
+
input.deltas.length === 0
|
|
135
|
+
? null
|
|
136
|
+
: input.deltas.reduce((a, b) => a + b, 0) / input.deltas.length;
|
|
137
|
+
const at_floor = discordant === floor;
|
|
138
|
+
|
|
139
|
+
if (discordant < floor) {
|
|
140
|
+
return {
|
|
141
|
+
kind: 'underpowered',
|
|
142
|
+
discordant,
|
|
143
|
+
wins,
|
|
144
|
+
losses,
|
|
145
|
+
p: 1,
|
|
146
|
+
magnitude_mean,
|
|
147
|
+
at_floor: false,
|
|
148
|
+
reason:
|
|
149
|
+
`${String(discordant)} discordant trial(s) is below the derived floor of ` +
|
|
150
|
+
`${String(floor)}: the smallest attainable one-sided p is ${(0.5 ** discordant).toFixed(4)}, ` +
|
|
151
|
+
`so no result here can clear ${String(alpha)}. This is NOT a null result — it is an ` +
|
|
152
|
+
'absent measurement, and it belongs in no pass-rate denominator.',
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const favoured = wins >= losses ? wins : losses;
|
|
157
|
+
const p = exactOneSidedP(favoured, discordant);
|
|
158
|
+
if (p > alpha) {
|
|
159
|
+
return {
|
|
160
|
+
kind: 'no-change',
|
|
161
|
+
discordant,
|
|
162
|
+
wins,
|
|
163
|
+
losses,
|
|
164
|
+
p,
|
|
165
|
+
magnitude_mean,
|
|
166
|
+
at_floor,
|
|
167
|
+
reason:
|
|
168
|
+
`${String(wins)}/${String(discordant)} discordant trials favour the treatment ` +
|
|
169
|
+
`(one-sided exact p=${p.toFixed(4)}); the direction is not distinguishable from noise at ${String(alpha)}.`,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
return {
|
|
173
|
+
kind: wins >= losses ? 'pass' : 'regression',
|
|
174
|
+
discordant,
|
|
175
|
+
wins,
|
|
176
|
+
losses,
|
|
177
|
+
p,
|
|
178
|
+
magnitude_mean,
|
|
179
|
+
at_floor,
|
|
180
|
+
reason:
|
|
181
|
+
`${String(wins)}/${String(discordant)} discordant trials favour the ` +
|
|
182
|
+
`${wins >= losses ? 'treatment' : 'control'} (one-sided exact p=${p.toFixed(4)}).`,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* The warning a specification earns by sitting EXACTLY on the derived floor.
|
|
188
|
+
*
|
|
189
|
+
* At the floor, `0.5 ** n` equals or barely clears alpha, so a pass requires a
|
|
190
|
+
* PERFECT sweep — one trial going the other way makes the result arithmetically
|
|
191
|
+
* unreachable before the run starts. That is a specification defect rather than
|
|
192
|
+
* a result, and it is invisible in the output: the run simply fails. Observed as
|
|
193
|
+
* five specifications raised to exactly the floor all failing, four of them
|
|
194
|
+
* decided before the run began.
|
|
195
|
+
*
|
|
196
|
+
* Returns `null` when there is nothing to warn about, so a caller can print it
|
|
197
|
+
* unconditionally.
|
|
198
|
+
*/
|
|
199
|
+
export function floorWarning(v: PairedVerdict, alpha: number = ALPHA): string | null {
|
|
200
|
+
if (!v.at_floor) return null;
|
|
201
|
+
return (
|
|
202
|
+
`specification sits exactly on the derived discordant floor (${String(v.discordant)}): ` +
|
|
203
|
+
`a pass needs every trial to agree, because one dissent moves p to ` +
|
|
204
|
+
`${exactOneSidedP(v.discordant - 1, v.discordant).toFixed(4)} against a bar of ${String(alpha)}. ` +
|
|
205
|
+
'Raise the trial count rather than the expectation.'
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Pass rate over a set of verdicts, with `underpowered` excluded.
|
|
211
|
+
*
|
|
212
|
+
* Exported as the ONLY sanctioned way to compute one, because the exclusion is
|
|
213
|
+
* the whole point and an inline `filter(v => v.kind === 'pass').length / all.length`
|
|
214
|
+
* silently reinstates the defect. Returns `null` when nothing is decidable —
|
|
215
|
+
* a rate over an empty denominator is a fabricated number, not a zero.
|
|
216
|
+
*/
|
|
217
|
+
export function passRate(verdicts: readonly PairedVerdict[]): { rate: number; decided: number; excluded: number } | null {
|
|
218
|
+
const decidable = verdicts.filter((v) => v.kind !== 'underpowered');
|
|
219
|
+
const excluded = verdicts.length - decidable.length;
|
|
220
|
+
if (decidable.length === 0) return null;
|
|
221
|
+
return {
|
|
222
|
+
rate: decidable.filter((v) => v.kind === 'pass').length / decidable.length,
|
|
223
|
+
decided: decidable.length,
|
|
224
|
+
excluded,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The canonical prefix-stable surface set — one list, loaded by every gate
|
|
3
|
+
* that needs it, restated by none.
|
|
4
|
+
*
|
|
5
|
+
* WHAT A PREFIX-STABLE SURFACE IS
|
|
6
|
+
* -------------------------------
|
|
7
|
+
* Bytes that sit in the cached prompt prefix of every dispatch. Rewriting them
|
|
8
|
+
* mid-session invalidates the cache for the remainder of that session, so the
|
|
9
|
+
* next call pays the cache-WRITE rate over the whole prefix instead of the
|
|
10
|
+
* cache-READ rate. That is the cost this list exists to bound; it is not a
|
|
11
|
+
* correctness claim about the content.
|
|
12
|
+
*
|
|
13
|
+
* WHY THE LIST LIVES HERE AND NOT IN A GATE
|
|
14
|
+
* -----------------------------------------
|
|
15
|
+
* `check_preamble_payload_budget` measured these three buckets first and stated
|
|
16
|
+
* their roots twice inside its own file — once to drive the census, once as the
|
|
17
|
+
* `roots:` argument to the dead-scope guard. A second gate restating them a
|
|
18
|
+
* third time is the recorded drift shape this repository already pays for
|
|
19
|
+
* elsewhere: two lists describing one boundary diverge, and each gate then
|
|
20
|
+
* guards a set the other no longer measures. So the roots move here and both
|
|
21
|
+
* gates import them.
|
|
22
|
+
*
|
|
23
|
+
* SCOPE — decided, with the reopen condition recorded
|
|
24
|
+
* ---------------------------------------------------
|
|
25
|
+
* Council 2026-08-28 (2/2 convergent, anthropic + openai, 2 rounds) resolved
|
|
26
|
+
* `road-to-runtime-context-floors`'s `which-surfaces-are-prefix-stable` blocker
|
|
27
|
+
* as option (c): the declared set is the three buckets the payload budget
|
|
28
|
+
* already measures, and the widening to "every surface a hook can write that
|
|
29
|
+
* reaches standing context" is recorded as an explicit reopen condition rather
|
|
30
|
+
* than enumerated now. Enumerating carriers that do not exist would be
|
|
31
|
+
* enumerating a plan.
|
|
32
|
+
*
|
|
33
|
+
* REOPEN — see `docs/contracts/prefix-stable-surfaces.md` § Reopen condition.
|
|
34
|
+
* A change that lands a hook or resident-process carrier able to write standing
|
|
35
|
+
* context outside these three roots must add it here in the same change.
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
export interface PrefixStableSurface {
|
|
39
|
+
/** Stable identifier; the mutation gate names it in its findings. */
|
|
40
|
+
id: string;
|
|
41
|
+
/** Repo-relative root. A directory root covers everything beneath it. */
|
|
42
|
+
root: string;
|
|
43
|
+
kind: 'dir' | 'file';
|
|
44
|
+
/** Human-readable bucket name, as the payload budget reports it. */
|
|
45
|
+
bucket: string;
|
|
46
|
+
/** Why these bytes are in the cached prefix. */
|
|
47
|
+
why: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* The declared set. Order is the order the payload budget reports its buckets,
|
|
52
|
+
* so a reader comparing the two outputs sees the same sequence.
|
|
53
|
+
*/
|
|
54
|
+
export const PREFIX_STABLE_SURFACES: readonly PrefixStableSurface[] = [
|
|
55
|
+
{
|
|
56
|
+
id: 'project-scope-rules',
|
|
57
|
+
root: 'dist/agent-src/rules',
|
|
58
|
+
kind: 'dir',
|
|
59
|
+
bucket: 'project-scope rules',
|
|
60
|
+
why: 'Every always-loaded rule body is re-written into the preamble on every spawn.',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
id: 'preloaded-skills-catalog',
|
|
64
|
+
root: 'dist/agent-src/skills',
|
|
65
|
+
kind: 'dir',
|
|
66
|
+
bucket: 'preloaded skills catalog',
|
|
67
|
+
why: 'Skill names and descriptions are catalogued into the preamble on every spawn.',
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
id: 'project-claude-md',
|
|
71
|
+
root: 'CLAUDE.md',
|
|
72
|
+
kind: 'file',
|
|
73
|
+
bucket: 'CLAUDE.md hierarchy (project only)',
|
|
74
|
+
why: 'The project half of the CLAUDE.md hierarchy is injected ahead of the first user turn.',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
id: 'project-claude-local-md',
|
|
78
|
+
root: 'CLAUDE.local.md',
|
|
79
|
+
kind: 'file',
|
|
80
|
+
bucket: 'CLAUDE.md hierarchy (project only)',
|
|
81
|
+
why: 'The gitignored project-local override is injected on the same path as CLAUDE.md.',
|
|
82
|
+
},
|
|
83
|
+
] as const;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The re-arm events. A rebuilt prefix is expected and paid for once at each of
|
|
87
|
+
* these boundaries, so a write declared against one is not a mid-session
|
|
88
|
+
* mutation. Anything not listed here fires mid-session.
|
|
89
|
+
*/
|
|
90
|
+
export const RE_ARM_EVENTS: readonly string[] = ['session_start', 'pre_compact'] as const;
|
|
91
|
+
|
|
92
|
+
/** Roots only, in declaration order — the shape `assertScanned` wants. */
|
|
93
|
+
export function prefixStableRoots(): string[] {
|
|
94
|
+
return PREFIX_STABLE_SURFACES.map((s) => s.root);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Directory roots only — the shape the payload census walks. */
|
|
98
|
+
export function prefixStableDirRoots(): string[] {
|
|
99
|
+
return PREFIX_STABLE_SURFACES.filter((s) => s.kind === 'dir').map((s) => s.root);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function normalise(p: string): string {
|
|
103
|
+
return p.replace(/\\/g, '/').replace(/^\.\//, '').replace(/\/+$/, '');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Does `target` (a repo-relative path, or a path literal lifted out of source)
|
|
108
|
+
* resolve inside a declared surface? Returns the surface, or `null`.
|
|
109
|
+
*
|
|
110
|
+
* Deliberately substring-free: a literal must match a root exactly, or sit
|
|
111
|
+
* beneath a directory root at a path separator. `dist/agent-src/rules-backup`
|
|
112
|
+
* is NOT inside `dist/agent-src/rules`.
|
|
113
|
+
*/
|
|
114
|
+
export function surfaceFor(target: string): PrefixStableSurface | null {
|
|
115
|
+
const t = normalise(target);
|
|
116
|
+
if (t === '') return null;
|
|
117
|
+
for (const s of PREFIX_STABLE_SURFACES) {
|
|
118
|
+
const root = normalise(s.root);
|
|
119
|
+
if (t === root) return s;
|
|
120
|
+
if (s.kind === 'dir' && t.startsWith(root + '/')) return s;
|
|
121
|
+
}
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The privacy class an audit-log-v1 line declares about ITSELF.
|
|
3
|
+
*
|
|
4
|
+
* `docs/contracts/audit-log-v1.md` states a privacy floor in prose and, until
|
|
5
|
+
* 2026-08-30, named a test file that exists in no tree — so the floor was
|
|
6
|
+
* asserted and not enforced. Two things close that gap, and they are different
|
|
7
|
+
* mechanisms rather than one restated twice:
|
|
8
|
+
*
|
|
9
|
+
* 1. A COMPILE-TIME guard (`NoFreeForm`, applied to each producer's input type)
|
|
10
|
+
* makes a field that *could* hold a body a build error. That is what stops
|
|
11
|
+
* the leak.
|
|
12
|
+
* 2. This enum makes each line SAY what it carries. That is what lets a reader
|
|
13
|
+
* decide whether a stream is safe to aggregate, export, or ship without
|
|
14
|
+
* re-deriving the answer from the producer's source.
|
|
15
|
+
*
|
|
16
|
+
* The first without the second leaves every consumer inferring the class; the
|
|
17
|
+
* second without the first is a label with nothing behind it.
|
|
18
|
+
*
|
|
19
|
+
* One module rather than a literal per producer, per step 9.1's rule that an
|
|
20
|
+
* enum family appearing in more than one place gets exactly one definition —
|
|
21
|
+
* the duplicate-enum failure that gave this tree two outcome vocabularies.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Ordered from least to most permissive. A reader may treat a lower class as
|
|
26
|
+
* satisfying any assertion made about a higher one; the reverse is never true.
|
|
27
|
+
*/
|
|
28
|
+
export const PRIVACY_CLASSES = [
|
|
29
|
+
/**
|
|
30
|
+
* Counts, enums, timestamps and opaque ids the package itself minted. No
|
|
31
|
+
* artefact names at all. The strictest class a line can declare.
|
|
32
|
+
*/
|
|
33
|
+
'counts-only',
|
|
34
|
+
/**
|
|
35
|
+
* Everything `counts-only` allows, plus STABLE ARTEFACT IDS the package
|
|
36
|
+
* governs — rule ids, skill ids, task-class ids. Still no bodies, no paths,
|
|
37
|
+
* no user content, and no third-party identifiers. This is what both
|
|
38
|
+
* shipped producers emit, because both carry `rules_applied`.
|
|
39
|
+
*/
|
|
40
|
+
'ids-only',
|
|
41
|
+
] as const;
|
|
42
|
+
|
|
43
|
+
export type PrivacyClass = (typeof PRIVACY_CLASSES)[number];
|
|
44
|
+
|
|
45
|
+
export function isPrivacyClass(v: unknown): v is PrivacyClass {
|
|
46
|
+
return typeof v === 'string' && (PRIVACY_CLASSES as readonly string[]).includes(v);
|
|
47
|
+
}
|