@event4u/agent-config 14.12.0 → 14.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.augment-plugin/marketplace.json +3 -3
- package/.augment-plugin/plugin.json +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +118 -155
- package/CONTRIBUTING.md +38 -0
- package/CREDITS.md +135 -0
- package/NOTICE +13 -0
- package/README.md +8 -6
- package/dist/agent-src/commands/analyze/inbox.md +145 -2
- package/dist/agent-src/commands/feature/dev.md +7 -2
- package/dist/agent-src/commands/ghostwriter/write.md +5 -1
- package/dist/agent-src/commands/implement-ticket.md +1 -1
- package/dist/agent-src/commands/mission/upgrade.md +1 -1
- package/dist/agent-src/commands/orchestrate.md +2 -2
- package/dist/agent-src/commands/post-as/me.md +5 -1
- package/dist/agent-src/commands/pr/merge.md +19 -6
- package/dist/agent-src/commands/roadmap/process-full.md +19 -5
- package/dist/agent-src/commands/tdd/red.md +12 -2
- package/dist/agent-src/commands/work.md +1 -1
- package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +40 -0
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +5 -2
- package/dist/agent-src/contexts/execution/autonomy-mechanics.md +21 -0
- package/dist/agent-src/contexts/execution/orchestration-telemetry.md +1 -0
- package/dist/agent-src/contexts/execution/subagent-response-contract.md +40 -0
- package/dist/agent-src/contexts/execution/subagent-steering.md +13 -1
- package/dist/agent-src/contexts/execution/terminal-states.md +96 -0
- package/dist/agent-src/rules/artifact-drafting-protocol.md +1 -1
- package/dist/agent-src/rules/broken-access-control.md +4 -0
- package/dist/agent-src/rules/code-comment-discipline.md +6 -0
- package/dist/agent-src/rules/code-provenance.md +4 -0
- package/dist/agent-src/rules/design-fidelity.md +1 -1
- package/dist/agent-src/rules/domain-safety-pii.md +4 -0
- package/dist/agent-src/rules/domain-safety-retention.md +4 -0
- package/dist/agent-src/rules/engineering-safety-floor.md +2 -0
- package/dist/agent-src/rules/external-code-graph-interop.md +14 -12
- package/dist/agent-src/rules/improve-before-implement.md +6 -8
- package/dist/agent-src/rules/laravel-routing.md +1 -1
- package/dist/agent-src/rules/lethal-trifecta-guard.md +4 -0
- package/dist/agent-src/rules/secret-vcs-guard.md +2 -0
- package/dist/agent-src/rules/security-sensitive-stop.md +2 -0
- package/dist/agent-src/rules/source-confidentiality.md +12 -34
- package/dist/agent-src/rules/symfony-routing.md +1 -1
- package/dist/agent-src/rules/token-efficiency.md +14 -0
- package/dist/agent-src/rules/tool-safety.md +4 -0
- package/dist/agent-src/rules/untrusted-input-defense.md +4 -0
- package/dist/agent-src/scripts/archive_completed_roadmaps.ts +252 -8
- package/dist/agent-src/scripts/guarded_baseline.ts +343 -0
- package/dist/agent-src/scripts/roadmap_set_step.ts +253 -0
- package/dist/agent-src/scripts/stub_queue.ts +82 -0
- package/dist/agent-src/scripts/stubs_due.ts +516 -0
- package/dist/agent-src/scripts/ticket_bundles.ts +84 -0
- package/dist/agent-src/scripts/update_roadmap_progress.ts +16 -12
- package/dist/agent-src/skills/brand-asset-generation/SKILL.md +17 -4
- package/dist/agent-src/skills/brand-audit/SKILL.md +33 -0
- package/dist/agent-src/skills/code-intelligence/SKILL.md +57 -0
- package/dist/agent-src/skills/database/SKILL.md +8 -0
- package/dist/agent-src/skills/dependency-upgrade/SKILL.md +27 -0
- package/dist/agent-src/skills/design-review/SKILL.md +1 -1
- package/dist/agent-src/skills/doc-coauthoring/SKILL.md +1 -1
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +17 -1
- package/dist/agent-src/skills/feature-planning/SKILL.md +9 -2
- package/dist/agent-src/skills/frontend-render-security/SKILL.md +44 -0
- package/dist/agent-src/skills/git-workflow/SKILL.md +1 -1
- package/dist/agent-src/skills/js-library-packaging/scripts/check_package_surface.ts +38 -4
- package/dist/agent-src/skills/judge-artifact-completeness/rubrics/ticket-quality-score.json +2 -2
- package/dist/agent-src/skills/laravel/SKILL.md +35 -0
- package/dist/agent-src/skills/laravel-migration/SKILL.md +57 -3
- package/dist/agent-src/skills/monorepo-workspace/SKILL.md +26 -0
- package/dist/agent-src/skills/playbook-authoring/SKILL.md +28 -1
- package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
- package/dist/agent-src/skills/skill-writing/references/procedure.md +5 -5
- package/dist/agent-src/skills/sql-writing/SKILL.md +7 -1
- package/dist/agent-src/skills/standards-from-config/SKILL.md +27 -4
- package/dist/agent-src/skills/supply-chain-intake/SKILL.md +11 -4
- package/dist/agent-src/skills/symfony-workflow/SKILL.md +35 -0
- package/dist/agent-src/skills/test-case-discovery/SKILL.md +85 -0
- package/dist/agent-src/skills/test-driven-development/SKILL.md +33 -9
- package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/testing-anti-patterns/process-anti-patterns.md +37 -0
- package/dist/agent-src/skills/ui-component-architect/SKILL.md +45 -2
- package/dist/agent-src/skills/upstream-contribute/SKILL.md +38 -1
- package/dist/agent-src/skills/verify-repair-loop/SKILL.md +9 -4
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +97 -3
- package/dist/agent-src/templates/scripts/check_memory.ts +258 -17
- package/dist/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
- package/dist/agent-src/templates/scripts/memory_lookup.ts +86 -0
- package/dist/agent-src/templates/scripts/memory_signal.ts +44 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
- package/dist/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
- package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
- package/dist/cli/commands/uiAudit.js +124 -5
- package/dist/cli/registry.js +2 -0
- package/dist/cli-delegate/{chunk-HYWSRNUX.js → chunk-2DK2VJWG.js} +3 -3
- package/dist/cli-delegate/{chunk-JCW7ZLHK.js → chunk-4FS4WRXP.js} +5 -0
- package/dist/cli-delegate/{chunk-OMIVVCG2.js → chunk-A4QJ6ENT.js} +24 -0
- package/dist/cli-delegate/{chunk-JJA2QEWA.js → chunk-AKJGUQNO.js} +466 -285
- package/dist/cli-delegate/{chunk-E46KPN6K.js → chunk-BTWUYDGN.js} +424 -363
- package/dist/cli-delegate/{chunk-K4FFODTS.js → chunk-ILMUPLGW.js} +1227 -316
- package/dist/cli-delegate/{chunk-FF7WAFMR.js → chunk-KPBWFOPZ.js} +5 -1
- package/dist/cli-delegate/cmd_adr_effective.js +102 -0
- package/dist/cli-delegate/cmd_conformance.js +80 -11
- package/dist/cli-delegate/cmd_doctor.js +3 -3
- package/dist/cli-delegate/cmd_export.js +3 -2
- package/dist/cli-delegate/cmd_fleet.js +2 -2
- package/dist/cli-delegate/cmd_handoff.js +1 -1
- package/dist/cli-delegate/cmd_preflight.js +2 -2
- package/dist/cli-delegate/cmd_prune.js +3 -2
- package/dist/cli-delegate/cmd_settings_get.js +1 -1
- package/dist/cli-delegate/cmd_settings_migrate.js +3 -2
- package/dist/cli-delegate/cmd_settings_set.js +2 -2
- package/dist/cli-delegate/cmd_sync.js +3 -2
- package/dist/cli-delegate/cmd_uninstall.js +3 -2
- package/dist/cli-delegate/cmd_validate.js +3 -2
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +58 -58
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +1 -1
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +2 -2
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +2 -2
- package/dist/hooks/dispatch.js +2900 -1049
- package/dist/install/claudeRuleRewrite.js +254 -0
- package/dist/install/detect.js +29 -16
- package/dist/install/detect_php_shape.js +159 -0
- package/dist/install/install.mjs +634 -428
- package/dist/mcp/awesome-mcp-servers.row.md +1 -1
- package/dist/mcp/mcp-cloudflare-catalogue.json +1 -1
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +3 -3
- package/dist/mcp/server.mjs +4895 -2627
- package/dist/server/schemas/settings.js +3 -0
- package/dist/ui/assets/index-D0jaCRPM.js +29 -0
- package/dist/ui/index.html +1 -1
- package/docs/MIGRATION.md +1 -1
- package/docs/THIRD-PARTY-NOTICES.md +25 -0
- package/docs/contracts/provider-lifecycle.md +1 -1
- package/docs/contracts/settings-classes.md +10 -4
- package/docs/guidelines/agent-infra/5w2h-analysis.md +3 -3
- package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +1 -0
- package/docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +58 -3
- package/docs/guidelines/agent-infra/ask-when-uncertain-demos.md +2 -2
- package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +3 -3
- package/docs/guidelines/agent-infra/break-glass-usage.md +7 -7
- package/docs/guidelines/agent-infra/carve-out-predicates.md +3 -3
- package/docs/guidelines/agent-infra/comparison-matrix.md +1 -1
- package/docs/guidelines/agent-infra/critical-thinking.md +4 -4
- package/docs/guidelines/agent-infra/direct-answers-demos.md +2 -2
- package/docs/guidelines/agent-infra/domain-eval-anti-pattern.md +1 -1
- package/docs/guidelines/agent-infra/engineering-memory-data-format.md +3 -3
- package/docs/guidelines/agent-infra/existence-question-verdicts.md +80 -0
- package/docs/guidelines/agent-infra/first-principles.md +2 -2
- package/docs/guidelines/agent-infra/framework-neutrality-patterns.md +2 -2
- package/docs/guidelines/agent-infra/guarded-baseline.md +39 -0
- package/docs/guidelines/agent-infra/inversion-thinking.md +5 -5
- package/docs/guidelines/agent-infra/language-and-tone-examples.md +1 -1
- package/docs/guidelines/agent-infra/layered-settings.md +10 -10
- package/docs/guidelines/agent-infra/memory-access.md +1 -1
- package/docs/guidelines/agent-infra/mental-models.md +3 -3
- package/docs/guidelines/agent-infra/reuse-verdict-mechanics.md +71 -0
- package/docs/guidelines/agent-infra/review-routing-data-format.md +7 -7
- package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +13 -7
- package/docs/guidelines/agent-infra/role-contracts.md +2 -2
- package/docs/guidelines/agent-infra/role-mode-router.md +3 -3
- package/docs/guidelines/agent-infra/rule-type-governance.md +2 -2
- package/docs/guidelines/agent-infra/scqa-framework.md +5 -5
- package/docs/guidelines/agent-infra/self-improvement-pipeline.md +6 -6
- package/docs/guidelines/agent-infra/simplicity-and-goal-demos.md +2 -2
- package/docs/guidelines/agent-infra/six-hats.md +3 -3
- package/docs/guidelines/agent-infra/skill-quality-checklist.md +6 -6
- package/docs/guidelines/agent-infra/source-confidentiality-mechanics.md +109 -0
- package/docs/guidelines/agent-infra/systems-thinking.md +1 -1
- package/docs/guidelines/agent-infra/verify-before-complete-demos.md +2 -2
- package/docs/guidelines/augment-portability-patterns.md +6 -4
- package/docs/guidelines/code-clarity.md +18 -0
- package/docs/guidelines/component-oriented-and-oop-development.md +3 -2
- package/docs/guidelines/cross-role-handoff.md +2 -2
- package/docs/guidelines/design-fidelity-mechanics.md +1 -1
- package/docs/guidelines/docs/readme-size-and-splitting.md +3 -3
- package/docs/guidelines/php/database.md +90 -7
- package/docs/guidelines/prompt-templates.md +7 -7
- package/llms.txt +2 -2
- package/package.json +5 -2
- package/src/agent-src/scripts/archive_completed_roadmaps.ts +252 -8
- package/src/agent-src/scripts/guarded_baseline.ts +343 -0
- package/src/agent-src/scripts/roadmap_set_step.ts +253 -0
- package/src/agent-src/scripts/stub_queue.ts +82 -0
- package/src/agent-src/scripts/stubs_due.ts +516 -0
- package/src/agent-src/scripts/ticket_bundles.ts +84 -0
- package/src/agent-src/scripts/update_roadmap_progress.ts +16 -12
- package/src/agent-src/templates/scripts/check_memory.ts +258 -17
- package/src/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
- package/src/agent-src/templates/scripts/memory_lookup.ts +86 -0
- package/src/agent-src/templates/scripts/memory_signal.ts +44 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
- package/src/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
- package/src/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
- package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
- package/src/config/agent-settings.template.yml +32 -3
- package/src/config/assurance-capability-registry.json +21 -9
- package/src/config/canonical-terms.yml +119 -0
- package/src/config/capability-native-outcome-bars.json +81 -0
- package/src/config/ci-local-parity.yml +80 -0
- package/src/config/drafting-channels.yml +43 -0
- package/src/config/estate-count-budget.json +57 -36
- package/src/config/evaluator-budgets.json +14 -14
- package/src/config/gate-coverage.yml +729 -63
- package/src/config/gate-reachability-exemptions.json +21 -0
- package/src/config/gate-violation-baselines.json +42 -19
- package/src/config/harness-evolution-budget.json +25 -0
- package/src/config/lapsed-beta-baseline.json +96 -0
- package/src/config/memory-twin-verdicts.yml +129 -0
- package/src/config/metric-registry.yml +124 -0
- package/src/config/pack-size-budget.json +16 -15
- package/src/config/preamble-payload-budget.json +12 -4
- package/src/config/profiles/balanced.ini +27 -0
- package/src/config/profiles/full.ini +27 -0
- package/src/config/profiles/minimal.ini +27 -0
- package/src/config/publish-surface.json +9 -2
- package/src/config/routing-coverage-seed.json +16 -2
- package/src/config/rule-stub-ceilings.json +133 -112
- package/src/config/turnaround-budget.json +66 -0
- package/src/install/claudeRuleRewrite.ts +288 -0
- package/src/install/detect.ts +60 -17
- package/src/install/detect_php_shape.ts +191 -0
- package/src/scripts/_cli/cmd_doctor.ts +27 -112
- package/src/scripts/_dispatch.bash +23 -0
- package/src/scripts/_lib/activation_ladder.ts +255 -0
- package/src/scripts/_lib/activation_receipt_producer.ts +341 -0
- package/src/scripts/_lib/activation_states.ts +88 -0
- package/src/scripts/_lib/adherence_detectors.ts +143 -0
- package/src/scripts/_lib/adr_frontmatter.ts +26 -0
- package/src/scripts/_lib/arith_claims.ts +181 -0
- package/src/scripts/_lib/arm_ranking.ts +62 -0
- package/src/scripts/_lib/asset_delivery_ledger.ts +303 -0
- package/src/scripts/_lib/audit_field_provenance.ts +54 -0
- package/src/scripts/_lib/auto_dispatch.ts +32 -3
- package/src/scripts/_lib/bench_ab_size_claim.ts +98 -4
- package/src/scripts/_lib/benchmark_cache_fields.ts +158 -0
- package/src/scripts/_lib/candidate_pair_delta.ts +349 -0
- package/src/scripts/_lib/candidate_proposer.ts +402 -0
- package/src/scripts/_lib/candidate_record.ts +601 -0
- package/src/scripts/_lib/capture_rate.ts +319 -0
- package/src/scripts/_lib/carrier_status.ts +118 -0
- package/src/scripts/_lib/cascade_stage_enumeration.ts +92 -0
- package/src/scripts/_lib/collector_denominator.ts +771 -0
- package/src/scripts/_lib/collector_record.ts +340 -0
- package/src/scripts/_lib/collector_store.ts +664 -0
- package/src/scripts/_lib/collector_supervision.ts +827 -0
- package/src/scripts/_lib/concern_estate.ts +77 -0
- package/src/scripts/_lib/config_chain.ts +477 -0
- package/src/scripts/_lib/config_cost.ts +209 -0
- package/src/scripts/_lib/corpus_manifest.ts +726 -0
- package/src/scripts/_lib/council_settings_block.ts +6 -0
- package/src/scripts/_lib/curator_ops.ts +172 -0
- package/src/scripts/_lib/delivery_arm_experiment.ts +282 -0
- package/src/scripts/_lib/delivery_criticality.ts +126 -0
- package/src/scripts/_lib/doctor_runtime_checks.ts +70 -0
- package/src/scripts/_lib/empty_cycles.ts +88 -0
- package/src/scripts/_lib/estate_carrier_cases.ts +72 -0
- package/src/scripts/_lib/eval_publication.ts +354 -0
- package/src/scripts/_lib/evaluation_cascade.ts +452 -0
- package/src/scripts/_lib/evaluation_vector.ts +283 -0
- package/src/scripts/_lib/evaluator_promotion.ts +225 -0
- package/src/scripts/_lib/evidence_basis.ts +118 -0
- package/src/scripts/_lib/evolution_roi.ts +562 -0
- package/src/scripts/_lib/exec_evidence.ts +8 -0
- package/src/scripts/_lib/experience_card.ts +272 -0
- package/src/scripts/_lib/experience_report.ts +151 -0
- package/src/scripts/_lib/experiment_freeze.ts +112 -0
- package/src/scripts/_lib/generated_by.ts +66 -0
- package/src/scripts/_lib/harness_evolution_guards.ts +239 -0
- package/src/scripts/_lib/hook_effect_probe.ts +141 -0
- package/src/scripts/_lib/host_denominator.ts +687 -0
- package/src/scripts/_lib/host_projection_reach.ts +157 -0
- package/src/scripts/_lib/ignored_blocker.ts +148 -0
- package/src/scripts/_lib/install_reach_checks.ts +495 -0
- package/src/scripts/_lib/json_duplicate_keys.ts +150 -0
- package/src/scripts/_lib/judge_hygiene.ts +228 -0
- package/src/scripts/_lib/legacy_boundary_map.ts +228 -0
- package/src/scripts/_lib/lexical_shortlist.ts +215 -0
- package/src/scripts/_lib/llm_candidate_proposer.ts +461 -0
- package/src/scripts/_lib/llm_proposer_transport.ts +153 -0
- package/src/scripts/_lib/loop_guards.ts +299 -0
- package/src/scripts/_lib/loss_class.ts +129 -0
- package/src/scripts/_lib/machine_wake.ts +51 -0
- package/src/scripts/_lib/md_prose_lines.ts +177 -0
- package/src/scripts/_lib/minimality_tiebreak.ts +168 -0
- package/src/scripts/_lib/one_resolver_invariant.ts +449 -0
- package/src/scripts/_lib/orchestration_record.ts +253 -5
- package/src/scripts/_lib/outcome_envelope.ts +227 -0
- package/src/scripts/_lib/outcome_vocabularies.ts +125 -0
- package/src/scripts/_lib/paired_stats.ts +245 -0
- package/src/scripts/_lib/paired_verdict.ts +226 -0
- package/src/scripts/_lib/pathology_archive.ts +393 -0
- package/src/scripts/_lib/prefix_stable_surfaces.ts +123 -0
- package/src/scripts/_lib/privacy_class.ts +47 -0
- package/src/scripts/_lib/promotion_capability.ts +315 -0
- package/src/scripts/_lib/promotion_evidence.ts +414 -0
- package/src/scripts/_lib/promotion_review.ts +294 -0
- package/src/scripts/_lib/prompt_shape.ts +92 -0
- package/src/scripts/_lib/regression_neighbourhood.ts +259 -0
- package/src/scripts/_lib/release_highlights.ts +70 -1
- package/src/scripts/_lib/release_material.ts +125 -2
- package/src/scripts/_lib/repeated_failure.ts +105 -0
- package/src/scripts/_lib/repo_root.ts +111 -0
- package/src/scripts/_lib/review_skipped_record.ts +37 -0
- package/src/scripts/_lib/role_split.ts +338 -0
- package/src/scripts/_lib/routing_corpus.ts +307 -0
- package/src/scripts/_lib/routing_index_input.ts +104 -0
- package/src/scripts/_lib/rule_injection.ts +22 -1
- package/src/scripts/_lib/runtime_journal.ts +1499 -0
- package/src/scripts/_lib/runtime_wiring_checks.ts +430 -0
- package/src/scripts/_lib/semantic_noop.ts +167 -0
- package/src/scripts/_lib/skill_catalogue.ts +11 -1
- package/src/scripts/_lib/source_digest.ts +200 -0
- package/src/scripts/_lib/source_redact.ts +260 -0
- package/src/scripts/_lib/source_shape.ts +502 -0
- package/src/scripts/_lib/source_snapshot_dedup.ts +199 -0
- package/src/scripts/_lib/strip_comments.d.mts +8 -0
- package/src/scripts/_lib/strip_comments.mjs +65 -0
- package/src/scripts/_lib/test_red_state.ts +154 -0
- package/src/scripts/_lib/trigger_shift.ts +144 -0
- package/src/scripts/_lib/untrusted_content.ts +82 -7
- package/src/scripts/activation_receipt.ts +258 -0
- package/src/scripts/adoption_report.ts +1 -1
- package/src/scripts/adr/evidence_census.ts +1 -1
- package/src/scripts/adr/regenerate_index.ts +26 -2
- package/src/scripts/adr_cite_check.ts +164 -1
- package/src/scripts/ai_council/blind_review.ts +11 -1
- package/src/scripts/ai_council/clients.ts +4 -0
- package/src/scripts/ai_council/config.ts +3 -0
- package/src/scripts/ai_council/consensus.ts +28 -8
- package/src/scripts/ai_council/consensus_round.ts +226 -0
- package/src/scripts/ai_council/cross_exam.ts +128 -0
- package/src/scripts/ai_council/disagreement_signal.ts +338 -0
- package/src/scripts/ai_council/explain_route.ts +157 -0
- package/src/scripts/ai_council/information_gain.ts +293 -0
- package/src/scripts/ai_council/inline_findings.ts +340 -0
- package/src/scripts/ai_council/judge_position_bias.ts +197 -0
- package/src/scripts/ai_council/leakage_corpus.ts +385 -0
- package/src/scripts/ai_council/leakage_patterns.ts +453 -0
- package/src/scripts/ai_council/minority_retention.ts +171 -0
- package/src/scripts/ai_council/orchestrator.ts +16 -203
- package/src/scripts/ai_council/orchestrator_results.ts +23 -3
- package/src/scripts/ai_council/pricing.ts +106 -0
- package/src/scripts/ai_council/prompts.ts +74 -7
- package/src/scripts/ai_council/provider_leakage_bench.ts +327 -0
- package/src/scripts/ai_council/py_format.ts +14 -3
- package/src/scripts/ai_council/recouncil_guard.ts +293 -0
- package/src/scripts/ai_council/recouncil_savings.ts +299 -0
- package/src/scripts/ai_council/replay_route.ts +223 -0
- package/src/scripts/ai_council/response_record.ts +50 -0
- package/src/scripts/ai_council/reviewer_assignment.ts +279 -0
- package/src/scripts/ai_council/routing_training_row.ts +197 -0
- package/src/scripts/ai_council/synthesis_strategy.ts +159 -0
- package/src/scripts/ai_council/topology_bench_manifest.ts +860 -0
- package/src/scripts/ai_council/topology_vocabulary.ts +175 -0
- package/src/scripts/asset_delivery_ledger.ts +157 -0
- package/src/scripts/attest_artifact.ts +193 -0
- package/src/scripts/audit_auto_rules.ts +2 -1
- package/src/scripts/audit_command_surface.ts +1 -1
- package/src/scripts/audit_mcp_tools.ts +2 -2
- package/src/scripts/audit_skill_overlap_allowlist.json +6 -1
- package/src/scripts/audit_user_type_axis.ts +2 -1
- package/src/scripts/bench_ab_clone.ts +215 -10
- package/src/scripts/bench_ab_integrity.ts +119 -5
- package/src/scripts/bench_ab_v2_stats.ts +40 -213
- package/src/scripts/build_archive_index.ts +1 -1
- package/src/scripts/build_linear_digest.ts +1 -1
- package/src/scripts/build_proof.ts +11 -4
- package/src/scripts/build_rule_trigger_matrix.ts +1 -1
- package/src/scripts/build_source_digests.ts +157 -0
- package/src/scripts/cache_realization_report.ts +103 -0
- package/src/scripts/check_adr_frontmatter.ts +131 -10
- package/src/scripts/check_benchmark_report_fields.ts +207 -0
- package/src/scripts/check_beta_review_markers.ts +235 -6
- package/src/scripts/check_bundle_path_leakage.ts +34 -1
- package/src/scripts/check_claims.ts +576 -6
- package/src/scripts/check_composite_arming.ts +35 -0
- package/src/scripts/check_concern_admissions.ts +365 -0
- package/src/scripts/check_enforcement_coverage.ts +28 -0
- package/src/scripts/check_estate_count.ts +347 -25
- package/src/scripts/check_gate_reachability.ts +383 -0
- package/src/scripts/check_host_loadability.ts +104 -0
- package/src/scripts/check_loss_class_declared.ts +308 -0
- package/src/scripts/check_md_language.ts +15 -98
- package/src/scripts/check_memory_proposal.ts +18 -11
- package/src/scripts/check_no_currency_in_cost_surfaces.ts +225 -0
- package/src/scripts/check_no_external_sources.ts +281 -6
- package/src/scripts/check_pack_conformance_fixture.ts +11 -1
- package/src/scripts/check_pack_size.ts +59 -2
- package/src/scripts/check_preamble_payload_budget.ts +114 -3
- package/src/scripts/check_prefix_stable_mutation.ts +372 -0
- package/src/scripts/check_publish_surface.ts +10 -1
- package/src/scripts/check_references.ts +24 -1
- package/src/scripts/check_release_highlights.ts +96 -13
- package/src/scripts/check_roadmap_trackable.ts +17 -2
- package/src/scripts/check_rule_evidence_declaration.ts +316 -0
- package/src/scripts/check_rule_projection_integrity.ts +14 -4
- package/src/scripts/check_score_contract.ts +26 -3
- package/src/scripts/check_static_parity.ts +285 -0
- package/src/scripts/check_supervision_claim_atomicity.ts +498 -0
- package/src/scripts/check_suppression_hygiene.ts +15 -0
- package/src/scripts/ci_settle.ts +39 -2
- package/src/scripts/code_graph/build.ts +60 -3
- package/src/scripts/code_graph/extract.ts +44 -0
- package/src/scripts/code_graph/types.ts +24 -0
- package/src/scripts/collector_daemon.ts +714 -0
- package/src/scripts/config_cost_report.ts +302 -0
- package/src/scripts/consumer_matrix.ts +74 -1
- package/src/scripts/corpus_manifest.ts +235 -0
- package/src/scripts/cost/budget.mjs +10 -3
- package/src/scripts/cost/track.mjs +10 -3
- package/src/scripts/council_cli.ts +37 -54
- package/src/scripts/dispatch_r2_reviewer.ts +46 -5
- package/src/scripts/evolution_lab.ts +1153 -0
- package/src/scripts/external_sources_denylist.json +5 -18
- package/src/scripts/extract_audit_patterns.ts +21 -0
- package/src/scripts/fold_intake.ts +12 -1
- package/src/scripts/gen_discovery_baseline.ts +1 -1
- package/src/scripts/generate_capabilities_index.ts +12 -5
- package/src/scripts/generate_capability_matrix.ts +3 -3
- package/src/scripts/generate_command_flows.ts +2 -2
- package/src/scripts/generate_cookbook.ts +2 -2
- package/src/scripts/generate_index.ts +8 -1
- package/src/scripts/generate_knowledge_index.ts +2 -1
- package/src/scripts/generate_ownership_matrix.ts +2 -1
- package/src/scripts/generate_pack_manifests.ts +10 -2
- package/src/scripts/generate_role_experiences_catalog.ts +2 -2
- package/src/scripts/generate_settings_reference.ts +1 -1
- package/src/scripts/git_authorization_hook.ts +22 -1
- package/src/scripts/grade_target_readiness.ts +48 -5
- package/src/scripts/hook_effect_doctor.ts +261 -0
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +125 -16
- package/src/scripts/hooks/block_speaking_inbox_dir.ts +271 -0
- package/src/scripts/hooks/block_unauthorized_git.ts +18 -0
- package/src/scripts/hooks/comment_discipline_hook.ts +146 -0
- package/src/scripts/hooks/concern_registry.ts +6 -0
- package/src/scripts/hooks/dispatch_hook.ts +32 -0
- package/src/scripts/hooks/journal_record_hook.ts +345 -0
- package/src/scripts/hooks/prepush_metadata_sources.sh +110 -0
- package/src/scripts/hooks/run_continuation_hook.ts +44 -9
- package/src/scripts/hooks/shims/install.sh +61 -0
- package/src/scripts/hooks/shims/php +101 -0
- package/src/scripts/hooks/suggestion_capture_hook.ts +10 -0
- package/src/scripts/hooks/turn_end_gate_hook.ts +9 -1
- package/src/scripts/hot_context_hook.ts +16 -0
- package/src/scripts/install-hooks.sh +20 -5
- package/src/scripts/install.ts +17 -35
- package/src/scripts/inventory_frontmatter.ts +2 -1
- package/src/scripts/language_mirror_hook.ts +14 -2
- package/src/scripts/lint_adr_sweep_routing.ts +12 -0
- package/src/scripts/lint_canonical_terms.ts +604 -0
- package/src/scripts/lint_carrier_integrity.ts +820 -0
- package/src/scripts/lint_code_comments.ts +643 -0
- package/src/scripts/lint_composition_review.ts +619 -0
- package/src/scripts/lint_consolidation_lineage.ts +666 -0
- package/src/scripts/lint_eval_specs.ts +593 -0
- package/src/scripts/lint_hook_manifest.ts +19 -0
- package/src/scripts/lint_host_portability.ts +373 -0
- package/src/scripts/lint_judge_prompt_expectation.ts +27 -1
- package/src/scripts/lint_memory_twin_parity.ts +335 -0
- package/src/scripts/lint_metric_consumers.ts +355 -0
- package/src/scripts/lint_plan_risk_register.ts +39 -19
- package/src/scripts/lint_promotion_paths.ts +779 -0
- package/src/scripts/lint_skill_descriptions.ts +18 -1
- package/src/scripts/lint_skill_frontmatter_safety.ts +58 -0
- package/src/scripts/lint_skill_link_reach.ts +252 -0
- package/src/scripts/lint_skill_trigger_corpus.ts +426 -23
- package/src/scripts/lint_ticket_buildable.ts +17 -1
- package/src/scripts/llm_propose.ts +256 -0
- package/src/scripts/mcp_server/consumer_tool_catalog.json +1 -1
- package/src/scripts/mcp_server/tool_catalog_source.ts +1 -1
- package/src/scripts/measure_delivery_sets.ts +361 -0
- package/src/scripts/measure_docs_dead_links.ts +348 -0
- package/src/scripts/measure_host_capture.ts +461 -0
- package/src/scripts/measure_routing_signal.ts +307 -0
- package/src/scripts/migration_status.ts +3 -3
- package/src/scripts/model_rule_injection.ts +76 -0
- package/src/scripts/orchestration_record.ts +14 -0
- package/src/scripts/preamble_byte_census.ts +139 -10
- package/src/scripts/prepack-check.mjs +4 -1
- package/src/scripts/probe_council_retention.ts +495 -0
- package/src/scripts/probe_turnaround.ts +384 -0
- package/src/scripts/probe_unblocked_ask.ts +279 -0
- package/src/scripts/release.ts +21 -37
- package/src/scripts/release_drill.ts +143 -0
- package/src/scripts/release_env.ts +35 -0
- package/src/scripts/release_publication.ts +84 -0
- package/src/scripts/render_benchmark_md.ts +1 -1
- package/src/scripts/rule_activation_census.ts +70 -9
- package/src/scripts/rule_backlinks.ts +1 -1
- package/src/scripts/run_lifecycle_suite.ts +208 -0
- package/src/scripts/run_skill_evals.ts +40 -0
- package/src/scripts/schemas/delivery-manifest.schema.json +43 -0
- package/src/scripts/schemas/drafting-channels.schema.json +43 -0
- package/src/scripts/schemas/evals.schema.json +24 -1
- package/src/scripts/schemas/rule.schema.json +52 -1
- package/src/scripts/schemas/skill.schema.json +17 -2
- package/src/scripts/skill_overlap.ts +7 -1
- package/src/scripts/skill_tools/run_block_d_eval.ts +8 -1
- package/src/scripts/skill_tools/score_skill_relevance.ts +84 -3
- package/src/scripts/skill_tools/suggest_skill_for_task.ts +8 -1
- package/src/scripts/skill_usage_report.ts +2 -1
- package/src/scripts/stubs_due.ts +211 -0
- package/src/scripts/sweep_source_surfaces.ts +678 -0
- package/src/scripts/sync_pr_branch.ts +3 -3
- package/src/scripts/trigger_eval_grandfather.json +202 -222
- package/src/scripts/utilization_report.ts +22 -2
- package/src/server/schemas/settings.ts +5 -0
- package/src/templates/marketing-copy.yml +1 -1
- package/dist/ui/assets/index-Cxgy63kz.js +0 -26
|
@@ -94,6 +94,12 @@ export function synthesizeAiCouncilBlock(cfg: CouncilConfig): Dict {
|
|
|
94
94
|
strong_threshold: cfg.consensus_scoring.strong_threshold,
|
|
95
95
|
minority_threshold: cfg.consensus_scoring.minority_threshold,
|
|
96
96
|
lenses: [...cfg.consensus_scoring.lenses],
|
|
97
|
+
// Phase 1B. Omitting it here is not a missing default — it is the key
|
|
98
|
+
// becoming UNREADABLE: `inlineFindingsActive` reads this projected
|
|
99
|
+
// dict, not the typed config, so an absent key resolves to `false` and
|
|
100
|
+
// the feature is silently off no matter what the YAML says. A live
|
|
101
|
+
// analysis run on 2026-08-30 is what found it, after the tests passed.
|
|
102
|
+
inline_findings: cfg.consensus_scoring.inline_findings,
|
|
97
103
|
},
|
|
98
104
|
cli_call_budget: {
|
|
99
105
|
max_calls_per_day: _mapToObject(cfg.cli_call_budget.max_calls_per_day),
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The curator's operation set — SEVEN ops per decision E6 — and the
|
|
3
|
+
* deterministic near-duplicate pre-stage that runs before any model judgment.
|
|
4
|
+
*
|
|
5
|
+
* `road-to-governed-harness-evolution` Phase 5, step 5.5.
|
|
6
|
+
*
|
|
7
|
+
* > *Curator operation set per E6. Candidates only, never promotions. Run
|
|
8
|
+
* > `src/scripts/_lib/shingle_similarity.ts` as a deterministic pre-stage
|
|
9
|
+
* > before any model judgment.*
|
|
10
|
+
* > verify: **a near-duplicate candidate is caught by the similarity stage with
|
|
11
|
+
* > zero model calls.**
|
|
12
|
+
*
|
|
13
|
+
* ## Seven, and why the middle answer was rejected
|
|
14
|
+
*
|
|
15
|
+
* E6 (decided 2026-08-30, AI council, anthropic + openai, 2/2) settled this on
|
|
16
|
+
* a contradiction rather than a preference: step 7.6 of the same roadmap
|
|
17
|
+
* already specifies the verdict set `KEEP / REVISE / MERGE / SPLIT / RETIRE`,
|
|
18
|
+
* so a four-op curator would emit verdicts it cannot execute. The six-op middle
|
|
19
|
+
* — deferring `SPLIT` — was rejected explicitly: it still contradicts 7.6, so
|
|
20
|
+
* it buys nothing the four-op answer does not also cost. The algebra argument
|
|
21
|
+
* is the one worth carrying: `MERGE` is n→1 and `SPLIT` is 1→n, and without
|
|
22
|
+
* `SPLIT` an overgrown rule becoming two must be written as
|
|
23
|
+
* `RETIRE + 2 x ADD`, which loses the semantic link and makes the intent
|
|
24
|
+
* unreadable in the audit log. {@link validateOp} encodes exactly that arity.
|
|
25
|
+
*
|
|
26
|
+
* ## Candidates only — carried by the type, not by a promise
|
|
27
|
+
*
|
|
28
|
+
* Every screened proposal carries `lifecycle: 'candidate'` as a LITERAL type,
|
|
29
|
+
* so there is no value a curator can construct that names any other lifecycle.
|
|
30
|
+
* Phase 7 is gated on the OPEN `merge-authority` blocker; a curator that could
|
|
31
|
+
* express a promotion would be one edit from performing one.
|
|
32
|
+
*
|
|
33
|
+
* ## Zero model calls, and how that is established rather than asserted
|
|
34
|
+
*
|
|
35
|
+
* {@link screenNearDuplicates} is synchronous, imports only
|
|
36
|
+
* `shingle_similarity`, and returns `model_calls: 0` as a literal-typed field.
|
|
37
|
+
* `tests/scripts/curator_ops.test.ts` proves the property two ways: it scans
|
|
38
|
+
* this module and its one dependency for network and model-client constructs in
|
|
39
|
+
* both polarities, and it runs the screen with `globalThis.fetch` replaced by a
|
|
40
|
+
* throwing stub, so a call would surface as a thrown error rather than as an
|
|
41
|
+
* unchecked assumption. An assertion by inspection would be worth nothing here
|
|
42
|
+
* — the whole point of a deterministic pre-stage is that it is cheaper than the
|
|
43
|
+
* judgment it precedes.
|
|
44
|
+
*/
|
|
45
|
+
import { shingleOverlap } from './shingle_similarity.js';
|
|
46
|
+
|
|
47
|
+
/** E6, option B. The exact set — arity and membership are both pinned by the test. */
|
|
48
|
+
export const CURATOR_OPS = [
|
|
49
|
+
'KEEP',
|
|
50
|
+
'ADD',
|
|
51
|
+
'MERGE',
|
|
52
|
+
'REPLACE',
|
|
53
|
+
'SPLIT',
|
|
54
|
+
'RETIRE',
|
|
55
|
+
'SKIP',
|
|
56
|
+
] as const;
|
|
57
|
+
|
|
58
|
+
export type CuratorOp = (typeof CURATOR_OPS)[number];
|
|
59
|
+
|
|
60
|
+
export interface CuratorProposal {
|
|
61
|
+
id: string;
|
|
62
|
+
op: CuratorOp;
|
|
63
|
+
/** Existing artifact ids the op reads or consumes. */
|
|
64
|
+
targets: readonly string[];
|
|
65
|
+
/** Artifact ids the op would produce. Empty for read-only ops. */
|
|
66
|
+
produces: readonly string[];
|
|
67
|
+
/** The proposed text, which is what the similarity stage compares. */
|
|
68
|
+
text: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Arity per op. `null` means the op places no constraint on that side. */
|
|
72
|
+
const OP_ARITY: Record<CuratorOp, { targets: [number, number | null]; produces: [number, number | null] }> = {
|
|
73
|
+
KEEP: { targets: [1, 1], produces: [0, 0] },
|
|
74
|
+
ADD: { targets: [0, 0], produces: [1, 1] },
|
|
75
|
+
MERGE: { targets: [2, null], produces: [1, 1] },
|
|
76
|
+
REPLACE: { targets: [1, 1], produces: [1, 1] },
|
|
77
|
+
SPLIT: { targets: [1, 1], produces: [2, null] },
|
|
78
|
+
RETIRE: { targets: [1, 1], produces: [0, 0] },
|
|
79
|
+
SKIP: { targets: [0, null], produces: [0, 0] },
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
function arityError(label: string, n: number, [lo, hi]: [number, number | null]): string | null {
|
|
83
|
+
if (n < lo) return `${label}: expected at least ${String(lo)}, got ${String(n)}`;
|
|
84
|
+
if (hi !== null && n > hi) return `${label}: expected at most ${String(hi)}, got ${String(n)}`;
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** `null` when the proposal's arity matches its op, otherwise the reason it does not. */
|
|
89
|
+
export function validateOp(p: CuratorProposal): string | null {
|
|
90
|
+
const spec = OP_ARITY[p.op];
|
|
91
|
+
return (
|
|
92
|
+
arityError(`${p.op} targets`, p.targets.length, spec.targets) ??
|
|
93
|
+
arityError(`${p.op} produces`, p.produces.length, spec.produces)
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Containment-overlap percent at which a proposal is a near-duplicate.
|
|
99
|
+
*
|
|
100
|
+
* A STATED default, not a measured optimum: `lint_originality`'s own gate uses
|
|
101
|
+
* shingle containment on the same primitive, and 70 % is the conservative end
|
|
102
|
+
* of the range a reskin scores there. `revisit-if` a screening run rejects a
|
|
103
|
+
* proposal a curator then has to re-add by hand, or admits one a human calls a
|
|
104
|
+
* duplicate.
|
|
105
|
+
*/
|
|
106
|
+
export const NEAR_DUPLICATE_THRESHOLD = 70;
|
|
107
|
+
|
|
108
|
+
export interface CorpusEntry {
|
|
109
|
+
id: string;
|
|
110
|
+
text: string;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export interface NearDuplicateFinding {
|
|
114
|
+
proposal_id: string;
|
|
115
|
+
/** The corpus entry it duplicates. */
|
|
116
|
+
against: string;
|
|
117
|
+
overlap_percent: number;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface ScreenedProposal {
|
|
121
|
+
proposal: CuratorProposal;
|
|
122
|
+
/** Literal. There is no other value this field can hold. */
|
|
123
|
+
lifecycle: 'candidate';
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface ScreenResult {
|
|
127
|
+
admitted: readonly ScreenedProposal[];
|
|
128
|
+
near_duplicates: readonly NearDuplicateFinding[];
|
|
129
|
+
malformed: readonly { proposal_id: string; reason: string }[];
|
|
130
|
+
/** Literal 0. The stage is deterministic; a model call here would be a defect. */
|
|
131
|
+
model_calls: 0;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* The deterministic pre-stage: reject malformed ops and near-duplicates before
|
|
136
|
+
* anything expensive runs.
|
|
137
|
+
*
|
|
138
|
+
* Synchronous on purpose — a synchronous function cannot await a network call,
|
|
139
|
+
* so the zero-model-call property is a consequence of the signature rather than
|
|
140
|
+
* a claim the body has to keep.
|
|
141
|
+
*/
|
|
142
|
+
export function screenNearDuplicates(
|
|
143
|
+
proposals: readonly CuratorProposal[],
|
|
144
|
+
corpus: readonly CorpusEntry[],
|
|
145
|
+
threshold: number = NEAR_DUPLICATE_THRESHOLD,
|
|
146
|
+
): ScreenResult {
|
|
147
|
+
const admitted: ScreenedProposal[] = [];
|
|
148
|
+
const nearDuplicates: NearDuplicateFinding[] = [];
|
|
149
|
+
const malformed: { proposal_id: string; reason: string }[] = [];
|
|
150
|
+
|
|
151
|
+
for (const p of proposals) {
|
|
152
|
+
const shapeError = validateOp(p);
|
|
153
|
+
if (shapeError !== null) {
|
|
154
|
+
malformed.push({ proposal_id: p.id, reason: shapeError });
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
let worst: NearDuplicateFinding | null = null;
|
|
158
|
+
for (const entry of corpus) {
|
|
159
|
+
const overlap = shingleOverlap(p.text, entry.text);
|
|
160
|
+
if (overlap >= threshold && (worst === null || overlap > worst.overlap_percent)) {
|
|
161
|
+
worst = { proposal_id: p.id, against: entry.id, overlap_percent: overlap };
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (worst !== null) {
|
|
165
|
+
nearDuplicates.push(worst);
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
admitted.push({ proposal: p, lifecycle: 'candidate' });
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return { admitted, near_duplicates: nearDuplicates, malformed, model_calls: 0 };
|
|
172
|
+
}
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The three-arm delivery experiment — `road-to-governed-harness-evolution` 6.1.
|
|
3
|
+
*
|
|
4
|
+
* WHAT 6.1 ASKS, AND WHY IT IS NOT THE PRICE GRID. Step 6.1 says: measure
|
|
5
|
+
* `eager-all` against `thin` against `delivery` — the three values
|
|
6
|
+
* `_lib/lean_projection_mode.ts:19` already declares — BEFORE any new retrieval
|
|
7
|
+
* component is written. `model_rule_injection.ts` already prices those three
|
|
8
|
+
* shapes, and a price grid is a cost model rather than a delivery measurement:
|
|
9
|
+
* it reports what each shape COSTS and never what each shape DELIVERS. The
|
|
10
|
+
* three arms differ on exactly one observable, and it is not cost:
|
|
11
|
+
*
|
|
12
|
+
* for a given prompt, is the labelled rule's BODY in the model's context?
|
|
13
|
+
*
|
|
14
|
+
* That question is decidable from the tree, so this module answers it for all
|
|
15
|
+
* three arms over one corpus with one matcher, and reports the cost figures
|
|
16
|
+
* beside it so the arms are commensurable on one table.
|
|
17
|
+
*
|
|
18
|
+
* WHAT EACH ARM PUTS IN CONTEXT, read off the two consumers of the mode rather
|
|
19
|
+
* than assumed. `condense.ts:1124` calls `writesThinFiles(mode)`, so `thin` and
|
|
20
|
+
* `delivery` project pointer stubs where `eager-all` projects bodies;
|
|
21
|
+
* `hooks/rule_inject_hook.ts:230` calls `deliversBodies(mode)`, so only
|
|
22
|
+
* `delivery` binds the concern that injects matched bodies back at prompt time.
|
|
23
|
+
* Hence:
|
|
24
|
+
*
|
|
25
|
+
* eager-all every projected body is standing.
|
|
26
|
+
* thin kernel bodies + no-trigger residue bodies are standing; every
|
|
27
|
+
* other body is a pointer and is NOT in context. Nothing is
|
|
28
|
+
* injected, because the concern is not bound.
|
|
29
|
+
* delivery thin's standing set, PLUS the bodies `selectForInjection`
|
|
30
|
+
* returns for this prompt under the concern's byte cap.
|
|
31
|
+
*
|
|
32
|
+
* The `thin` standing set mirrors `standingCorpora` in `model_rule_injection.ts`
|
|
33
|
+
* — kernel or triggerless keeps a body, anything else becomes a pointer — so the
|
|
34
|
+
* delivery half and the cost half classify each rule the same way. Two
|
|
35
|
+
* classifications would be the "measures nothing" defect `_lib/rule_injection.ts`
|
|
36
|
+
* names in its own header.
|
|
37
|
+
*
|
|
38
|
+
* NO SECOND MATCHER, WHICH IS 6.2'S CONSTRAINT AND THIS MODULE'S TOO. Every
|
|
39
|
+
* match here comes from `matchTierRules`, and every selection from
|
|
40
|
+
* `selectForInjection` — both in `_lib/rule_injection.ts`, which owns no matcher
|
|
41
|
+
* of its own and wraps `_lib/router_match.ts`. This module imports nothing else
|
|
42
|
+
* that could answer "which rules fire on this prompt?", and
|
|
43
|
+
* `tests/scripts/single_matcher_preserved.test.ts` fails if it ever does.
|
|
44
|
+
*
|
|
45
|
+
* ZERO MODEL CALLS, and the property follows from the imports rather than from
|
|
46
|
+
* good behaviour: the only import is `_lib/rule_injection.js`, which reads files.
|
|
47
|
+
* Token counting and the standing-corpus sizes are PARAMETERS, not imports, so
|
|
48
|
+
* this module carries no tokenizer and no network surface at all.
|
|
49
|
+
*
|
|
50
|
+
* WHAT IT DOES NOT MEASURE, stated because the gap is the interesting half.
|
|
51
|
+
* It does not measure whether a session that RECEIVES a body behaves like a
|
|
52
|
+
* session that HAD it standing. That is not an expense this run declined to pay
|
|
53
|
+
* — the instrument is closed by ADR-202 (`docs/decisions/ADR-202-anchor-scoring-as-thin-quality-instrument.md`),
|
|
54
|
+
* whose status reads "instrument not achievable with available evaluators" at an
|
|
55
|
+
* inter-evaluator kappa of 0.472 against a registered floor of 0.800, with no
|
|
56
|
+
* third attempt licensed. Nothing printed here is evidence about quality.
|
|
57
|
+
*/
|
|
58
|
+
import {
|
|
59
|
+
kernelIds,
|
|
60
|
+
loadRuleBody,
|
|
61
|
+
matchTierRules,
|
|
62
|
+
selectForInjection,
|
|
63
|
+
triggerlessRuleIds,
|
|
64
|
+
type Router,
|
|
65
|
+
} from './rule_injection.js';
|
|
66
|
+
|
|
67
|
+
/** The three arms, named exactly as `LeanProjectionMode` declares them. */
|
|
68
|
+
export const ARMS = ['eager-all', 'thin', 'delivery'] as const;
|
|
69
|
+
export type ArmName = (typeof ARMS)[number];
|
|
70
|
+
|
|
71
|
+
/** The corpus fields this experiment reads. Structurally a `CorpusCase`. */
|
|
72
|
+
export interface LabelledCase {
|
|
73
|
+
readonly rule: string;
|
|
74
|
+
readonly prompt: string;
|
|
75
|
+
readonly openFiles: string[] | null;
|
|
76
|
+
readonly label: 'positive' | 'near_miss';
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface ArmRow {
|
|
80
|
+
readonly arm: ArmName;
|
|
81
|
+
/** Positives whose labelled rule body is in context under this arm. */
|
|
82
|
+
readonly delivered: number;
|
|
83
|
+
readonly positives: number;
|
|
84
|
+
/** Near-miss prompts whose labelled rule body is nevertheless in context. */
|
|
85
|
+
readonly falseContext: number;
|
|
86
|
+
readonly nearMisses: number;
|
|
87
|
+
/** Positives the matcher fired on but the byte cap then dropped. */
|
|
88
|
+
readonly capDropped: number;
|
|
89
|
+
/** Exact-BPE tokens standing in context before the first prompt. */
|
|
90
|
+
readonly standingTokens: number;
|
|
91
|
+
/** Mean exact-BPE tokens injected per positive prompt. */
|
|
92
|
+
readonly injectedMeanTokens: number;
|
|
93
|
+
/** Same, at the 90th percentile. */
|
|
94
|
+
readonly injectedP90Tokens: number;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface ArmExperimentInput {
|
|
98
|
+
readonly repoRoot: string;
|
|
99
|
+
readonly router: Router;
|
|
100
|
+
readonly cases: readonly LabelledCase[];
|
|
101
|
+
/** The concern's per-prompt byte cap. The sensitivity handle. */
|
|
102
|
+
readonly capBytes: number;
|
|
103
|
+
/** Standing exact-BPE tokens per arm, supplied by the caller. */
|
|
104
|
+
readonly standing: Readonly<Record<ArmName, number>>;
|
|
105
|
+
/** Exact-BPE tokenizer, injected so this module imports none. */
|
|
106
|
+
readonly tokensOf: (text: string) => number;
|
|
107
|
+
/**
|
|
108
|
+
* STEP 6.3 — optional per-prompt lexical shortlist, injected so this module
|
|
109
|
+
* builds no index of its own.
|
|
110
|
+
*
|
|
111
|
+
* Absent (the default) the delivery arm is byte-for-byte the arm 6.1
|
|
112
|
+
* measured, which is why its recorded figures stay reproducible. Present,
|
|
113
|
+
* it reaches `selectForInjection` as a TIE-BREAK under the matcher's score —
|
|
114
|
+
* it can change which matched bodies survive a binding cap and can change
|
|
115
|
+
* nothing else, so `delivered` can only move through `capDropped`.
|
|
116
|
+
*/
|
|
117
|
+
readonly shortlist?: ((prompt: string) => readonly string[]) | null;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Ids whose FULL body is standing under `thin` and `delivery`.
|
|
122
|
+
*
|
|
123
|
+
* Kernel is standing by definition; a rule with no trigger cannot be delivered,
|
|
124
|
+
* so the projector keeps it eager under the thin shapes too.
|
|
125
|
+
*/
|
|
126
|
+
export function thinStandingIds(router: Router): Set<string> {
|
|
127
|
+
const ids = new Set<string>(kernelIds(router));
|
|
128
|
+
for (const id of triggerlessRuleIds(router)) ids.add(id);
|
|
129
|
+
return ids;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** Nearest-rank quantile over a copy. Deterministic. */
|
|
133
|
+
function quantile(values: readonly number[], q: number): number {
|
|
134
|
+
if (values.length === 0) return 0;
|
|
135
|
+
const s = [...values].sort((a, b) => a - b);
|
|
136
|
+
const idx = Math.min(s.length - 1, Math.max(0, Math.ceil(q * s.length) - 1));
|
|
137
|
+
return s[idx] as number;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function mean(values: readonly number[]): number {
|
|
141
|
+
if (values.length === 0) return 0;
|
|
142
|
+
return values.reduce((a, b) => a + b, 0) / values.length;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** Ids projected with a real body file — the `eager-all` standing set. */
|
|
146
|
+
function hasBody(repoRoot: string, id: string): boolean {
|
|
147
|
+
return loadRuleBody(repoRoot, id) !== null;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Run the experiment. Pure over its inputs; two runs are byte-identical.
|
|
152
|
+
*
|
|
153
|
+
* One walk over the corpus computes all three arms, so no arm can be scored on
|
|
154
|
+
* a different case set than another.
|
|
155
|
+
*/
|
|
156
|
+
export function runArmExperiment(input: ArmExperimentInput): ArmRow[] {
|
|
157
|
+
const { repoRoot, router, cases, capBytes, standing, tokensOf, shortlist } = input;
|
|
158
|
+
const thinStanding = thinStandingIds(router);
|
|
159
|
+
|
|
160
|
+
const delivered: Record<ArmName, number> = { 'eager-all': 0, thin: 0, delivery: 0 };
|
|
161
|
+
const falseContext: Record<ArmName, number> = { 'eager-all': 0, thin: 0, delivery: 0 };
|
|
162
|
+
let positives = 0;
|
|
163
|
+
let nearMisses = 0;
|
|
164
|
+
let capDropped = 0;
|
|
165
|
+
const injectedTokens: number[] = [];
|
|
166
|
+
|
|
167
|
+
for (const c of cases) {
|
|
168
|
+
const inEager = hasBody(repoRoot, c.rule);
|
|
169
|
+
const inThin = thinStanding.has(c.rule) && inEager;
|
|
170
|
+
|
|
171
|
+
const matches = matchTierRules(router, c.prompt, c.openFiles);
|
|
172
|
+
const sel = selectForInjection(
|
|
173
|
+
repoRoot,
|
|
174
|
+
matches,
|
|
175
|
+
capBytes,
|
|
176
|
+
shortlist ? shortlist(c.prompt) : null,
|
|
177
|
+
);
|
|
178
|
+
const injectedIds = new Set(sel.selected.map((m) => m.id));
|
|
179
|
+
const inDelivery = inThin || injectedIds.has(c.rule);
|
|
180
|
+
|
|
181
|
+
if (c.label === 'positive') {
|
|
182
|
+
positives += 1;
|
|
183
|
+
if (inEager) delivered['eager-all'] += 1;
|
|
184
|
+
if (inThin) delivered.thin += 1;
|
|
185
|
+
if (inDelivery) delivered.delivery += 1;
|
|
186
|
+
if (sel.dropped.some((m) => m.id === c.rule)) capDropped += 1;
|
|
187
|
+
let tokens = 0;
|
|
188
|
+
for (const m of sel.selected) tokens += tokensOf(loadRuleBody(repoRoot, m.id) ?? '');
|
|
189
|
+
injectedTokens.push(tokens);
|
|
190
|
+
} else {
|
|
191
|
+
nearMisses += 1;
|
|
192
|
+
if (inEager) falseContext['eager-all'] += 1;
|
|
193
|
+
if (inThin) falseContext.thin += 1;
|
|
194
|
+
if (inDelivery) falseContext.delivery += 1;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const injMean = Math.round(mean(injectedTokens));
|
|
199
|
+
const injP90 = quantile(injectedTokens, 0.9);
|
|
200
|
+
return ARMS.map((arm) => ({
|
|
201
|
+
arm,
|
|
202
|
+
delivered: delivered[arm],
|
|
203
|
+
positives,
|
|
204
|
+
falseContext: falseContext[arm],
|
|
205
|
+
nearMisses,
|
|
206
|
+
capDropped: arm === 'delivery' ? capDropped : 0,
|
|
207
|
+
standingTokens: standing[arm],
|
|
208
|
+
injectedMeanTokens: arm === 'delivery' ? injMean : 0,
|
|
209
|
+
injectedP90Tokens: arm === 'delivery' ? injP90 : 0,
|
|
210
|
+
}));
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function ratio(hits: number, total: number): string {
|
|
214
|
+
return total === 0 ? '—' : (hits / total).toFixed(3);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function signed(n: number): string {
|
|
218
|
+
return n > 0 ? `+${n}` : String(n);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Render the report. The pairwise deltas are printed, not left to the reader:
|
|
223
|
+
* "measured against one another" is a comparison, and a table of three
|
|
224
|
+
* independent rows is three measurements rather than one comparison.
|
|
225
|
+
*/
|
|
226
|
+
export function renderArmExperiment(rows: readonly ArmRow[], capBytes: number): string[] {
|
|
227
|
+
const by = new Map<ArmName, ArmRow>(rows.map((r) => [r.arm, r]));
|
|
228
|
+
const eager = by.get('eager-all') as ArmRow;
|
|
229
|
+
const thin = by.get('thin') as ArmRow;
|
|
230
|
+
const delivery = by.get('delivery') as ArmRow;
|
|
231
|
+
|
|
232
|
+
const out: string[] = [];
|
|
233
|
+
const push = (s: string): void => {
|
|
234
|
+
out.push(s);
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
push('── three-arm delivery experiment (road-to-governed-harness-evolution 6.1) ──');
|
|
238
|
+
push(
|
|
239
|
+
`arms = LeanProjectionMode (_lib/lean_projection_mode.ts:19) · ` +
|
|
240
|
+
`one corpus · one matcher (_lib/router_match.ts) · cap ${capBytes} B`,
|
|
241
|
+
);
|
|
242
|
+
push('');
|
|
243
|
+
push(' arm delivery(pos) false-context(near-miss) standing tok injected tok/prompt');
|
|
244
|
+
for (const r of rows) {
|
|
245
|
+
const inj =
|
|
246
|
+
r.arm === 'delivery'
|
|
247
|
+
? `mean ${r.injectedMeanTokens} p90 ${r.injectedP90Tokens}`
|
|
248
|
+
: '0';
|
|
249
|
+
push(
|
|
250
|
+
` ${r.arm.padEnd(12)} ${ratio(r.delivered, r.positives)} (${r.delivered}/${r.positives})`.padEnd(
|
|
251
|
+
33,
|
|
252
|
+
) +
|
|
253
|
+
`${ratio(r.falseContext, r.nearMisses)} (${r.falseContext}/${r.nearMisses})`.padEnd(27) +
|
|
254
|
+
`${r.standingTokens}`.padEnd(15) +
|
|
255
|
+
inj,
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
push('');
|
|
259
|
+
push('── pairwise deltas ──');
|
|
260
|
+
push(
|
|
261
|
+
` thin vs eager-all: delivery ${signed(thin.delivered - eager.delivered)} positives · ` +
|
|
262
|
+
`standing ${signed(thin.standingTokens - eager.standingTokens)} tok`,
|
|
263
|
+
);
|
|
264
|
+
push(
|
|
265
|
+
` delivery vs eager-all: delivery ${signed(delivery.delivered - eager.delivered)} positives · ` +
|
|
266
|
+
`standing ${signed(delivery.standingTokens - eager.standingTokens)} tok`,
|
|
267
|
+
);
|
|
268
|
+
push(
|
|
269
|
+
` delivery vs thin: delivery ${signed(delivery.delivered - thin.delivered)} positives · ` +
|
|
270
|
+
`standing ${signed(delivery.standingTokens - thin.standingTokens)} tok`,
|
|
271
|
+
);
|
|
272
|
+
push(` cap-dropped under delivery: ${delivery.capDropped} of ${delivery.positives} positives`);
|
|
273
|
+
push('');
|
|
274
|
+
push(
|
|
275
|
+
'This measures WHICH BODIES REACH CONTEXT and what they cost. It does not',
|
|
276
|
+
);
|
|
277
|
+
push(
|
|
278
|
+
'measure whether a delivered body behaves like a standing one — that instrument',
|
|
279
|
+
);
|
|
280
|
+
push('is closed by ADR-202 and this run does not reopen it.');
|
|
281
|
+
return out;
|
|
282
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The fail-closed delivery ladder (`road-to-runtime-context-floors` step 2.3).
|
|
3
|
+
*
|
|
4
|
+
* An obligation moved out of the always-loaded prefix onto a runtime carrier is
|
|
5
|
+
* cheaper and can be MISSING. This module is the single encoding of what happens
|
|
6
|
+
* then; the prose lives in `docs/contracts/resident-process-floors.md` § 3 and
|
|
7
|
+
* the wire shape in `src/scripts/schemas/delivery-manifest.schema.json`.
|
|
8
|
+
*
|
|
9
|
+
* Three values, not a boolean, because "may this migrate" and "what if the
|
|
10
|
+
* carrier is down" are different questions and collapsing them loses the middle
|
|
11
|
+
* case that matters:
|
|
12
|
+
*
|
|
13
|
+
* critical-A never migrates; stays in standing context
|
|
14
|
+
* critical-B may migrate; carrier down ⇒ delivered EAGERLY, never dropped
|
|
15
|
+
* standard may migrate; carrier down ⇒ may fail open
|
|
16
|
+
*
|
|
17
|
+
* THE DEFAULT IS `critical-B`. An obligation whose class nobody declared is one
|
|
18
|
+
* nobody classified, and the cheap reading of an unclassified obligation must not
|
|
19
|
+
* be "droppable" — that is the same fail-closed choice
|
|
20
|
+
* `check_prefix_stable_mutation` makes for an undecidable write target.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
export const DELIVERY_CRITICALITY = ['critical-A', 'critical-B', 'standard'] as const;
|
|
24
|
+
export type DeliveryCriticality = (typeof DELIVERY_CRITICALITY)[number];
|
|
25
|
+
|
|
26
|
+
/** What nobody declared. Deliberately the middle rung, never the cheap one. */
|
|
27
|
+
export const DEFAULT_CRITICALITY: DeliveryCriticality = 'critical-B';
|
|
28
|
+
|
|
29
|
+
export interface DeliveryEntry {
|
|
30
|
+
/** Logical obligation id — the rule, gate or floor being delivered. */
|
|
31
|
+
id: string;
|
|
32
|
+
/** Omitted ⇒ {@link DEFAULT_CRITICALITY}. */
|
|
33
|
+
criticality?: DeliveryCriticality;
|
|
34
|
+
/** The runtime carrier that would deliver it. */
|
|
35
|
+
carrier?: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type DeliveryOutcome =
|
|
39
|
+
/** Never left standing context; the carrier is irrelevant to it. */
|
|
40
|
+
| 'standing'
|
|
41
|
+
/** The carrier delivered it. */
|
|
42
|
+
| 'carrier'
|
|
43
|
+
/** The carrier is unavailable and the obligation was delivered the expensive way. */
|
|
44
|
+
| 'eager-fallback'
|
|
45
|
+
/** The carrier is unavailable and the obligation may be omitted. */
|
|
46
|
+
| 'fail-open';
|
|
47
|
+
|
|
48
|
+
export interface DeliveryDecision {
|
|
49
|
+
id: string;
|
|
50
|
+
criticality: DeliveryCriticality;
|
|
51
|
+
/** True when the value was defaulted rather than declared. */
|
|
52
|
+
defaulted: boolean;
|
|
53
|
+
outcome: DeliveryOutcome;
|
|
54
|
+
reason: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function isDeliveryCriticality(v: unknown): v is DeliveryCriticality {
|
|
58
|
+
return typeof v === 'string' && (DELIVERY_CRITICALITY as readonly string[]).includes(v);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Resolve one obligation against carrier availability.
|
|
63
|
+
*
|
|
64
|
+
* An UNRECOGNISED declared value is not honoured and does not throw: it
|
|
65
|
+
* defaults, exactly as an omitted one does. A typo must not be able to buy a
|
|
66
|
+
* weaker rung than the default — which is the direction a throw would also
|
|
67
|
+
* prevent, but a throw would take the whole delivery down with it, and losing
|
|
68
|
+
* every obligation to protect one is the wrong trade.
|
|
69
|
+
*/
|
|
70
|
+
export function resolveDelivery(entry: DeliveryEntry, carrierAvailable: boolean): DeliveryDecision {
|
|
71
|
+
const declared = entry.criticality;
|
|
72
|
+
const known = isDeliveryCriticality(declared);
|
|
73
|
+
const criticality: DeliveryCriticality = known ? declared : DEFAULT_CRITICALITY;
|
|
74
|
+
const defaulted = !known;
|
|
75
|
+
|
|
76
|
+
if (criticality === 'critical-A') {
|
|
77
|
+
return {
|
|
78
|
+
id: entry.id,
|
|
79
|
+
criticality,
|
|
80
|
+
defaulted,
|
|
81
|
+
outcome: 'standing',
|
|
82
|
+
reason: 'critical-A never migrates off standing context, so carrier availability cannot reach it',
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
if (carrierAvailable) {
|
|
86
|
+
return {
|
|
87
|
+
id: entry.id,
|
|
88
|
+
criticality,
|
|
89
|
+
defaulted,
|
|
90
|
+
outcome: 'carrier',
|
|
91
|
+
reason: `delivered by carrier ${entry.carrier ?? '(unnamed)'}`,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
if (criticality === 'critical-B') {
|
|
95
|
+
return {
|
|
96
|
+
id: entry.id,
|
|
97
|
+
criticality,
|
|
98
|
+
defaulted,
|
|
99
|
+
outcome: 'eager-fallback',
|
|
100
|
+
reason:
|
|
101
|
+
`carrier ${entry.carrier ?? '(unnamed)'} is unavailable and this obligation is critical-B` +
|
|
102
|
+
(defaulted ? ' by default (its class was not declared)' : '') +
|
|
103
|
+
' — delivered eagerly rather than dropped',
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
id: entry.id,
|
|
108
|
+
criticality,
|
|
109
|
+
defaulted,
|
|
110
|
+
outcome: 'fail-open',
|
|
111
|
+
reason: `carrier ${entry.carrier ?? '(unnamed)'} is unavailable and this obligation is standard — may fail open`,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Resolve a whole manifest. Order is preserved so a report reads deterministically. */
|
|
116
|
+
export function resolveDeliveryManifest(
|
|
117
|
+
entries: readonly DeliveryEntry[],
|
|
118
|
+
carrierAvailable: boolean,
|
|
119
|
+
): DeliveryDecision[] {
|
|
120
|
+
return entries.map((e) => resolveDelivery(e, carrierAvailable));
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** The obligations a carrier failure must NOT silently drop. */
|
|
124
|
+
export function droppedObligations(decisions: readonly DeliveryDecision[]): DeliveryDecision[] {
|
|
125
|
+
return decisions.filter((d) => d.outcome === 'fail-open');
|
|
126
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two runtime-presence checks of `agent-config doctor`.
|
|
3
|
+
*
|
|
4
|
+
* PURE MOVE out of `cmd_doctor.ts`, made under the extraction discipline that
|
|
5
|
+
* file's own `_lib` siblings follow: it is ~3,700 lines and
|
|
6
|
+
* `check_source_size_budget` counts every line above 1,500, so a change that
|
|
7
|
+
* adds lines there must pay for them by taking lines away. Wiring the Phase-1
|
|
8
|
+
* install-reach checks in (`road-to-consumer-repo-reality` 1.1) charged five
|
|
9
|
+
* lines; this move returns more than that.
|
|
10
|
+
*
|
|
11
|
+
* Both checks are cohesive with each other and with nothing else in that file:
|
|
12
|
+
* each answers "is a runtime present, and what does the package do when it is
|
|
13
|
+
* not", and neither reads the manifest, the drift sets, or the project root.
|
|
14
|
+
* Their one dependency is a `which` lookup, and it is passed IN rather than
|
|
15
|
+
* imported: `shutilWhich` lives in `cmd_doctor.ts` and importing it back would
|
|
16
|
+
* make the two modules circular. A parameter is cheaper than moving a shared
|
|
17
|
+
* utility that four other call sites already resolve from there.
|
|
18
|
+
*
|
|
19
|
+
* Behaviour is unchanged — same ids, same statuses, same message strings.
|
|
20
|
+
*/
|
|
21
|
+
/** The doctor's structured check row. Mirrors `cmd_doctor`'s internal `Dict`. */
|
|
22
|
+
export interface RuntimeCheck {
|
|
23
|
+
id: string;
|
|
24
|
+
status: 'ok' | 'warn' | 'fail' | 'skipped';
|
|
25
|
+
message: string;
|
|
26
|
+
remedy: string;
|
|
27
|
+
/** Structural compatibility with `cmd_doctor`'s `Dict` row type. */
|
|
28
|
+
[k: string]: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function checkPythonRuntime(): RuntimeCheck {
|
|
32
|
+
// Post-teardown: the package runtime is TypeScript-on-`tsx`. python3 is no
|
|
33
|
+
// longer a runtime dependency, so this check no longer probes for an
|
|
34
|
+
// interpreter (spawning python3 here would be misleading in a python-free
|
|
35
|
+
// package). The check id is retained for the doctor's stable report shape;
|
|
36
|
+
// it always reports `ok`.
|
|
37
|
+
return {
|
|
38
|
+
id: 'python-runtime',
|
|
39
|
+
status: 'ok',
|
|
40
|
+
message: 'python3 is not a runtime dependency (TS runtime via tsx)',
|
|
41
|
+
remedy: '',
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function checkHumanizerRuntime(which: (name: string) => string | null): RuntimeCheck {
|
|
46
|
+
// Write-engine step 4b (humanize audit) runs `detect_ai_tells.ts` via a
|
|
47
|
+
// Node/tsx runtime "when available", degrading to a prose-only audit
|
|
48
|
+
// otherwise. This check surfaces which path a consumer install gets so the
|
|
49
|
+
// default-on behavior is not a silent surprise. Either state is healthy —
|
|
50
|
+
// the fallback is graceful by design — so it never fails the run.
|
|
51
|
+
const node = which('node');
|
|
52
|
+
if (node === null) {
|
|
53
|
+
return {
|
|
54
|
+
id: 'humanizer-runtime',
|
|
55
|
+
status: 'ok',
|
|
56
|
+
message:
|
|
57
|
+
'no Node runtime on PATH — write-engine step 4b uses the ' +
|
|
58
|
+
'prose-only humanize audit (graceful fallback)',
|
|
59
|
+
remedy:
|
|
60
|
+
'install Node to enable the mechanical detect_ai_tells.ts pass; ' +
|
|
61
|
+
'the prose audit runs regardless',
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
id: 'humanizer-runtime',
|
|
66
|
+
status: 'ok',
|
|
67
|
+
message: `Node runtime present (${node}) — step 4b runs the mechanical detect_ai_tells.ts pass`,
|
|
68
|
+
remedy: '',
|
|
69
|
+
};
|
|
70
|
+
}
|