@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
|
@@ -17,6 +17,16 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import type { LookupClass } from './auto_dispatch.js';
|
|
20
|
+
import type { EvidenceBasis } from './evidence_basis.js';
|
|
21
|
+
// TYPE-ONLY on purpose. `runtime_journal.ts` imports `node:sqlite` at runtime,
|
|
22
|
+
// and this module is loaded by a PreToolUse-adjacent CLI path where opening a
|
|
23
|
+
// database would be both wrong and slow. A `import type` is erased at compile
|
|
24
|
+
// time, so the guard costs nothing at runtime while still being one definition
|
|
25
|
+
// rather than a second copy of the key list -- the duplicate-enum failure step
|
|
26
|
+
// 9.1 exists to prevent.
|
|
27
|
+
import type { NoFreeForm } from './runtime_journal.js';
|
|
28
|
+
import { type PrivacyClass } from './privacy_class.js';
|
|
29
|
+
import type { PhaseOutcome } from './outcome_vocabularies.js';
|
|
20
30
|
|
|
21
31
|
export type DispatchOutcome = 'DONE' | 'DONE_WITH_CONCERNS' | 'NEEDS_CONTEXT' | 'BLOCKED' | 'killed';
|
|
22
32
|
/** Which route the rung took: deterministic primitive (lean-init L0),
|
|
@@ -24,12 +34,30 @@ export type DispatchOutcome = 'DONE' | 'DONE_WITH_CONCERNS' | 'NEEDS_CONTEXT' |
|
|
|
24
34
|
* subagent spawn. */
|
|
25
35
|
export type RouteTaken = 'primitive' | 'subagent' | 'ask';
|
|
26
36
|
export type VerifyMode = 'deterministic' | 'judge' | 'none';
|
|
27
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Migrated onto the shared evidence-basis vocabulary
|
|
39
|
+
* (`road-to-delivered-cost-truth` 4.1). The two literals are unchanged on the
|
|
40
|
+
* wire — `measured` and `estimated` mean here exactly what the contract says
|
|
41
|
+
* they mean — but they are no longer declared privately, so this surface and
|
|
42
|
+
* the census can no longer drift apart on what "measured" is.
|
|
43
|
+
*
|
|
44
|
+
* Narrowed to the two values this field can actually take: an orchestration
|
|
45
|
+
* record's floor is either read from the transcript ledger or arithmetic over
|
|
46
|
+
* it, and admitting `model-judged` here would be widening a type to match a
|
|
47
|
+
* vocabulary rather than a fact.
|
|
48
|
+
*/
|
|
49
|
+
export type Provenance = Extract<EvidenceBasis, 'measured' | 'estimated'>;
|
|
28
50
|
export type TierChosen = 'lite' | 'medium' | 'high';
|
|
29
51
|
export type TierSource = 'static' | 'inferred' | 'inherit';
|
|
30
52
|
export type Band = 'low' | 'medium' | 'high';
|
|
31
53
|
export type LinePhase = 'refine' | 'memory' | 'analyze' | 'plan' | 'implement' | 'test' | 'verify' | 'report';
|
|
32
|
-
|
|
54
|
+
/**
|
|
55
|
+
* Outcome of this audit-log line. Alias of the registry's `PhaseOutcome` —
|
|
56
|
+
* the name `LineOutcome` is kept because two modules import it, and the
|
|
57
|
+
* single definition now lives in `outcome_vocabularies.ts` so the contract
|
|
58
|
+
* table can be checked against it (`road-to-experience-loop-broadening` 1.3).
|
|
59
|
+
*/
|
|
60
|
+
export type LineOutcome = PhaseOutcome;
|
|
33
61
|
/** Which capsule-emission trigger arm fired first (Phase 1 shadow comparison). */
|
|
34
62
|
export type TriggerArm = 'watermark' | 'saturation' | 'tie';
|
|
35
63
|
/** The orchestration form the form-gate selected (road-to-opt-subagent-harvest P2). */
|
|
@@ -58,6 +86,45 @@ export interface RecordInput {
|
|
|
58
86
|
task_class?: string | null | undefined;
|
|
59
87
|
/** Form-gate outcome: which of the seven modes (or 'none') the gate selected. */
|
|
60
88
|
dispatch_mode?: DispatchModeId | null | undefined;
|
|
89
|
+
/**
|
|
90
|
+
* Stable skill ids that were APPLIED during this phase — the skills
|
|
91
|
+
* counterpart of `rules_applied`, which `audit-log-v1` has carried since v1
|
|
92
|
+
* while carrying no skills field at all.
|
|
93
|
+
*
|
|
94
|
+
* ABSENT and EMPTY mean different things, and the distinction is
|
|
95
|
+
* load-bearing rather than stylistic: the field OMITTED means *not
|
|
96
|
+
* recorded* (the producer had no skill observation to offer), while `[]`
|
|
97
|
+
* means *recorded, and none applied*. Folding the two together is what
|
|
98
|
+
* makes a per-asset report unable to tell "no signal" from "a negative
|
|
99
|
+
* signal", which is the failure `unknown != 0` exists to prevent
|
|
100
|
+
* downstream.
|
|
101
|
+
*
|
|
102
|
+
* Ids only, never bodies — privacy by construction, same as
|
|
103
|
+
* `rules_applied`. Bounded to <= 32; the remainder is dropped, mirroring
|
|
104
|
+
* the rules bound in the contract.
|
|
105
|
+
*/
|
|
106
|
+
skills_applied?: string[] | null | undefined;
|
|
107
|
+
/**
|
|
108
|
+
* What this dispatch was supposed to produce. Drives the anti-forgery gate
|
|
109
|
+
* in `envelopeOutcome`. Absent or `unknown` disables the gate for this
|
|
110
|
+
* line, which is the safe default: a producer that cannot say what it
|
|
111
|
+
* expected must not have its outcome downgraded on a guess.
|
|
112
|
+
*/
|
|
113
|
+
expected_output?: ExpectedOutput | null | undefined;
|
|
114
|
+
/**
|
|
115
|
+
* Measured lines changed by this dispatch. `null` means NOT MEASURED and is
|
|
116
|
+
* never read as zero — an unmeasured diff must not become a failure.
|
|
117
|
+
*/
|
|
118
|
+
diff_lines?: number | null | undefined;
|
|
119
|
+
/**
|
|
120
|
+
* Trigger fires suppressed as duplicates since the last outcome record.
|
|
121
|
+
*
|
|
122
|
+
* Reported as its own quantity, never folded into a success rate's
|
|
123
|
+
* numerator or denominator: a duplicate is not an outcome, and it is also
|
|
124
|
+
* not nothing — a rising count is what an idle loop looks like from
|
|
125
|
+
* outside. See `src/scripts/_lib/empty_cycles.ts`.
|
|
126
|
+
*/
|
|
127
|
+
empty_cycles?: number | null | undefined;
|
|
61
128
|
task_size_estimate?: number | undefined;
|
|
62
129
|
wall_clock_ms?: number | undefined;
|
|
63
130
|
/** Absolute measured tokens the dispatched slice consumed (feeds the modeled cost-%). */
|
|
@@ -178,12 +245,148 @@ const PAYLOAD_HASH_RE = /^[a-f0-9]{8,64}$/i;
|
|
|
178
245
|
/** Id-shaped origin tag — enum-ish, never free-form prose. */
|
|
179
246
|
const ORIGIN_RE = /^[a-z0-9][a-z0-9-]{0,63}$/;
|
|
180
247
|
|
|
248
|
+
/**
|
|
249
|
+
* Upper bound on an applied-id array, mirroring the `rules_applied` bound the
|
|
250
|
+
* contract has carried since v1 ("Bounded to <= 32; remainder dropped
|
|
251
|
+
* silently"). Stated as a named constant so the contract row and the code can
|
|
252
|
+
* be checked against one another instead of against a literal.
|
|
253
|
+
*/
|
|
254
|
+
const MAX_APPLIED_IDS = 32;
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* What THIS producer's lines carry. `ids-only` and not `counts-only` because
|
|
258
|
+
* every line carries `rules_applied`, and some carry `skills_applied`.
|
|
259
|
+
*/
|
|
260
|
+
const PRODUCER_PRIVACY_CLASS: PrivacyClass = 'ids-only';
|
|
261
|
+
|
|
262
|
+
type Assert<T extends true> = T;
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* PRIVACY BY CONSTRUCTION, enforced rather than asserted.
|
|
266
|
+
*
|
|
267
|
+
* Until 2026-08-30 the privacy floor on this module was a docstring, and
|
|
268
|
+
* `docs/contracts/audit-log-v1.md` said so in its own words: "No test enforces
|
|
269
|
+
* this floor". A docstring cannot stop the next author adding a `payload` or a
|
|
270
|
+
* `detail` field, and `audit-log-v1`'s forward-compat rule means readers would
|
|
271
|
+
* silently carry it.
|
|
272
|
+
*
|
|
273
|
+
* This assertion makes that a COMPILE error. If {@link RecordInput} ever grows
|
|
274
|
+
* a key from `FREE_FORM_KEYS` -- `prompt`, `body`, `file_path`, `stdout`,
|
|
275
|
+
* `reason`, `payload` and the rest of the set an author reaches for when they
|
|
276
|
+
* want to stash content -- `NoFreeForm` resolves to `never`, this becomes
|
|
277
|
+
* `Assert<false>`, and the build stops. The type cannot be widened back without
|
|
278
|
+
* deleting this line, which is a visible act in a diff.
|
|
279
|
+
*/
|
|
280
|
+
type _RecordInputCarriesNoFreeFormField = Assert<
|
|
281
|
+
[NoFreeForm<RecordInput>] extends [never] ? false : true
|
|
282
|
+
>;
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* The NEGATIVE fixture, and it is the half that is easy to leave out.
|
|
286
|
+
*
|
|
287
|
+
* The assertion above proves the guard ACCEPTS the current type. On its own
|
|
288
|
+
* that is satisfied just as well by a guard that accepts everything -- a
|
|
289
|
+
* `NoFreeForm` that had been broken into `type NoFreeForm<T> = T` would keep it
|
|
290
|
+
* green forever. This fixture proves the guard REJECTS, which is the direction
|
|
291
|
+
* that actually protects anything.
|
|
292
|
+
*
|
|
293
|
+
* The `@ts-expect-error` is itself the assertion: the line below is required to
|
|
294
|
+
* be a type error. If the guard ever stops rejecting a free-form key, the error
|
|
295
|
+
* disappears, the directive becomes unused, and `tsc` fails on the unused
|
|
296
|
+
* directive. Either way the build stops -- so `npm run typecheck` checks both
|
|
297
|
+
* directions, not only the flattering one.
|
|
298
|
+
*
|
|
299
|
+
* NOTE for whoever runs this by hand: `tsc -p tsconfig.json` does NOT cover
|
|
300
|
+
* this file. That config includes only `src/cli`, `src/server`, `src/shared`
|
|
301
|
+
* and `src/install`; `src/scripts/**` is reached solely by
|
|
302
|
+
* `tsconfig.scripts.json`. Use `npm run typecheck`, which runs both. A bare
|
|
303
|
+
* `tsc -p tsconfig.json` over this module is a gate that scans nothing and
|
|
304
|
+
* exits green.
|
|
305
|
+
*/
|
|
306
|
+
interface _RecordInputWithForbiddenField extends RecordInput {
|
|
307
|
+
prompt?: string | undefined;
|
|
308
|
+
}
|
|
309
|
+
type _Rejected = [NoFreeForm<_RecordInputWithForbiddenField>] extends [never] ? false : true;
|
|
310
|
+
// @ts-expect-error — a type carrying a free-form key must make this Assert<false>
|
|
311
|
+
type _ForbiddenFieldIsRejected = Assert<_Rejected>;
|
|
312
|
+
|
|
181
313
|
/** Map a dispatch outcome to the audit-log envelope outcome enum. */
|
|
182
|
-
|
|
314
|
+
/**
|
|
315
|
+
* What a dispatch was supposed to produce. The gate below reads THIS, never the
|
|
316
|
+
* diff alone.
|
|
317
|
+
*
|
|
318
|
+
* The unconditional rule -- claimed success x empty diff => never `success` --
|
|
319
|
+
* is the form this step deliberately does NOT ship. Analysis, review and
|
|
320
|
+
* read-only research dispatches are a large share of this repository's subagent
|
|
321
|
+
* traffic and legitimately produce no diff; marking them all as failures would
|
|
322
|
+
* poison the very aggregation the gate exists to protect, in the opposite
|
|
323
|
+
* direction. Zero diff may be valid, so "zero diff = failure" must not be
|
|
324
|
+
* global.
|
|
325
|
+
*/
|
|
326
|
+
export const EXPECTED_OUTPUTS = ['code-change', 'analysis', 'review', 'unknown'] as const;
|
|
327
|
+
export type ExpectedOutput = (typeof EXPECTED_OUTPUTS)[number];
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Version of the DispatchOutcome -> phase-outcome mapping that produced a line.
|
|
331
|
+
*
|
|
332
|
+
* Required by the AI council (2026-08-30, anthropic + openai, 2/2) as the
|
|
333
|
+
* condition on proceeding at all, and it addresses an asymmetry worth stating:
|
|
334
|
+
* a bad enforcement gate rolls back, a bad LABELLING change poisons historical
|
|
335
|
+
* analysis permanently, because audit-log-v1 lines are append-only and cannot
|
|
336
|
+
* be rewritten. A reader aggregating across the cutover must be able to see
|
|
337
|
+
* which semantics produced each line rather than infer it from a date.
|
|
338
|
+
*
|
|
339
|
+
* `1` -- unconditional: DONE / DONE_WITH_CONCERNS always mapped to `success`.
|
|
340
|
+
* Every line written before 2026-08-30 carries these semantics and
|
|
341
|
+
* carries NO `outcome_semantics` field, so an absent field reads as 1.
|
|
342
|
+
* `2` -- contract-gated: a `code-change` dispatch claiming success with a
|
|
343
|
+
* measured empty diff no longer maps to `success`.
|
|
344
|
+
*/
|
|
345
|
+
export const OUTCOME_SEMANTICS_VERSION = 2;
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Translate a dispatch outcome into an audit-log phase outcome.
|
|
349
|
+
*
|
|
350
|
+
* This is the tree's ONLY cross-domain outcome mapping
|
|
351
|
+
* (`src/scripts/_lib/outcome_vocabularies.ts` CROSS_DOMAIN_MAPPINGS), so a
|
|
352
|
+
* change here reaches every downstream aggregation. It was audited before
|
|
353
|
+
* changing: `envelopeOutcome` has no caller outside this module, the only
|
|
354
|
+
* reader of `outcome` is `src/scripts/extract_audit_patterns.ts` -- read-only,
|
|
355
|
+
* stdout, whose sole non-zero exit is argument validation -- and that script is
|
|
356
|
+
* wired into no Taskfile, no gate-coverage entry and no workflow. The label
|
|
357
|
+
* therefore enters no automated control path, which is the condition the
|
|
358
|
+
* council set for this being a labelling change rather than an enforcement one.
|
|
359
|
+
*
|
|
360
|
+
* The anti-forgery clause fires only when ALL THREE hold: the dispatch declared
|
|
361
|
+
* itself a `code-change`, it claimed success, and the diff was MEASURED at
|
|
362
|
+
* zero. `diff_lines == null` means not measured, and an unmeasured diff must
|
|
363
|
+
* never become a failure -- that would manufacture the forgery in the other
|
|
364
|
+
* direction, which is the same defect wearing the opposite sign.
|
|
365
|
+
*/
|
|
366
|
+
function envelopeOutcome(d: DispatchOutcome, ctx?: OutcomeContext): LineOutcome {
|
|
183
367
|
if (d === 'BLOCKED') return 'blocked';
|
|
184
368
|
if (d === 'NEEDS_CONTEXT') return 'skipped';
|
|
185
369
|
if (d === 'killed') return 'error';
|
|
186
|
-
|
|
370
|
+
|
|
371
|
+
const claimsSuccess = d === 'DONE' || d === 'DONE_WITH_CONCERNS';
|
|
372
|
+
if (
|
|
373
|
+
claimsSuccess &&
|
|
374
|
+
ctx?.expected_output === 'code-change' &&
|
|
375
|
+
typeof ctx.diff_lines === 'number' &&
|
|
376
|
+
ctx.diff_lines === 0
|
|
377
|
+
) {
|
|
378
|
+
// A code dispatch that claims success and demonstrably changed nothing
|
|
379
|
+
// is an unverified self-report, not a result. `error` rather than
|
|
380
|
+
// `blocked`: nothing prevented it from running, and `blocked` is
|
|
381
|
+
// already the value for a dispatch that never got to try.
|
|
382
|
+
return 'error';
|
|
383
|
+
}
|
|
384
|
+
return 'success';
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
interface OutcomeContext {
|
|
388
|
+
expected_output?: ExpectedOutput | null | undefined;
|
|
389
|
+
diff_lines?: number | null | undefined;
|
|
187
390
|
}
|
|
188
391
|
|
|
189
392
|
function isInt(n: unknown): n is number {
|
|
@@ -288,7 +491,23 @@ export function buildOrchestrationLine(input: RecordInput): BuiltLine {
|
|
|
288
491
|
if (input.origin != null && !ORIGIN_RE.test(input.origin)) {
|
|
289
492
|
errors.push("origin must be an id-shaped tag like 'lean-init-2026' (lowercase alnum + hyphens)");
|
|
290
493
|
}
|
|
494
|
+
if (input.expected_output != null && !EXPECTED_OUTPUTS.includes(input.expected_output)) {
|
|
495
|
+
errors.push(`expected_output must be one of ${EXPECTED_OUTPUTS.join(' | ')} (or omitted)`);
|
|
496
|
+
}
|
|
497
|
+
if (input.diff_lines != null && (!isInt(input.diff_lines) || input.diff_lines < 0)) {
|
|
498
|
+
errors.push('diff_lines must be a non-negative integer count, null for not-measured, or omitted');
|
|
499
|
+
}
|
|
500
|
+
if (input.skills_applied != null) {
|
|
501
|
+
if (!Array.isArray(input.skills_applied)) {
|
|
502
|
+
errors.push('skills_applied must be an array of skill ids, [] , or omitted');
|
|
503
|
+
} else if (!input.skills_applied.every((v) => typeof v === 'string' && ORIGIN_RE.test(v))) {
|
|
504
|
+
errors.push(
|
|
505
|
+
"skills_applied entries must be id-shaped skill names like 'code-review' (lowercase alnum + hyphens) — ids only, never bodies",
|
|
506
|
+
);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
291
509
|
for (const [key, v] of [
|
|
510
|
+
['empty_cycles', input.empty_cycles],
|
|
292
511
|
['rules_carried', input.rules_carried],
|
|
293
512
|
['rules_used', input.rules_used],
|
|
294
513
|
['work_tokens', input.work_tokens],
|
|
@@ -336,6 +555,9 @@ export function buildOrchestrationLine(input: RecordInput): BuiltLine {
|
|
|
336
555
|
const orchestration: Record<string, unknown> = {
|
|
337
556
|
task_size_estimate: input.task_size_estimate ?? 0,
|
|
338
557
|
spawn_count: input.spawn_count,
|
|
558
|
+
// Its OWN quantity, never folded into a rate. `null` = not tracked by
|
|
559
|
+
// this producer, which is not the same as zero duplicates observed.
|
|
560
|
+
empty_cycles: input.empty_cycles ?? null,
|
|
339
561
|
tiers: input.tiers ?? [],
|
|
340
562
|
token_delta: input.token_delta,
|
|
341
563
|
token_delta_provenance: prov,
|
|
@@ -388,12 +610,38 @@ export function buildOrchestrationLine(input: RecordInput): BuiltLine {
|
|
|
388
610
|
ts: input.ts,
|
|
389
611
|
work_id: input.work_id ?? `orchestration-${input.ts}`,
|
|
390
612
|
phase,
|
|
391
|
-
outcome:
|
|
613
|
+
outcome:
|
|
614
|
+
input.outcome ??
|
|
615
|
+
envelopeOutcome(dOutcome, {
|
|
616
|
+
expected_output: input.expected_output,
|
|
617
|
+
diff_lines: input.diff_lines,
|
|
618
|
+
}),
|
|
619
|
+
// The cutover marker. An ABSENT field means semantics 1 (unconditional),
|
|
620
|
+
// which is every line written before 2026-08-30 -- so a reader
|
|
621
|
+
// aggregating across the boundary can segment rather than infer from a
|
|
622
|
+
// date. Emitted unconditionally because this producer always applies
|
|
623
|
+
// the current mapping.
|
|
624
|
+
outcome_semantics: OUTCOME_SEMANTICS_VERSION,
|
|
392
625
|
confidence_band: band,
|
|
393
626
|
risk_class: risk,
|
|
394
627
|
memory: { asks: 0, hits: 0 },
|
|
395
628
|
verify: { claims: 0, first_try_passes: 0 },
|
|
396
629
|
rules_applied: ['delegation-policy'],
|
|
630
|
+
// MANDATORY, never optional and never derived by the reader. This line
|
|
631
|
+
// carries `rules_applied` and may carry `skills_applied`, both of which
|
|
632
|
+
// are stable artefact ids, so the class it declares is `ids-only`
|
|
633
|
+
// rather than `counts-only`. A consumer deciding whether this stream is
|
|
634
|
+
// safe to aggregate or export reads this field instead of re-deriving
|
|
635
|
+
// the answer from the producer's source.
|
|
636
|
+
privacy_class: PRODUCER_PRIVACY_CLASS,
|
|
637
|
+
// Emitted ONLY when the producer offered one. An omitted key means "not
|
|
638
|
+
// recorded"; `[]` means "recorded, none applied". Writing `null` or `[]`
|
|
639
|
+
// unconditionally would erase that distinction for every existing
|
|
640
|
+
// producer that has no skill observation to give, which is the whole
|
|
641
|
+
// reason the field is optional rather than defaulted.
|
|
642
|
+
...(input.skills_applied != null
|
|
643
|
+
? { skills_applied: input.skills_applied.slice(0, MAX_APPLIED_IDS) }
|
|
644
|
+
: {}),
|
|
397
645
|
persona: input.persona ?? null,
|
|
398
646
|
input_kind: 'orchestration',
|
|
399
647
|
type: 'phase',
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Machine-decidable outcomes: the terminal state, whether a retry can help, and
|
|
3
|
+
* whether a finding list is complete.
|
|
4
|
+
*
|
|
5
|
+
* `road-to-skill-ecosystem-runtime-enforcement` Phase 4, Steps 4-5. Two
|
|
6
|
+
* distinctions that an agent currently has to JUDGE from prose, and gets wrong
|
|
7
|
+
* in the same direction each time:
|
|
8
|
+
*
|
|
9
|
+
* 1. **Is this worth retrying?** A missing credential, a permission denial, a
|
|
10
|
+
* spend cap and an upstream 5xx are all "the command failed", and retrying
|
|
11
|
+
* any of them burns an iteration against a gap the loop cannot close. The
|
|
12
|
+
* rules already say so — `context-hygiene`'s hard-blocker classes — and
|
|
13
|
+
* nothing a script emits lets an agent decide it without reading English.
|
|
14
|
+
* 2. **Is this list complete?** A capped finding list reads as a complete one.
|
|
15
|
+
* A gate that reports "3 findings" after truncating at 3 has said something
|
|
16
|
+
* false, and the reader has no way to know.
|
|
17
|
+
*
|
|
18
|
+
* PER-CATEGORY caps rather than one global cap, because a single cap lets one
|
|
19
|
+
* high-volume check fill the budget and hide every other category behind it —
|
|
20
|
+
* which is the failure a cap is supposed to prevent, arriving through the cap.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import type { RunTerminalState } from './outcome_vocabularies.js';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The six terminal states. Contract: `contexts/execution/terminal-states.md`.
|
|
27
|
+
*
|
|
28
|
+
* Alias of the registry's `RunTerminalState`. This module stays the public
|
|
29
|
+
* surface — `runtime_journal.test.ts:212` pins the import path and `:215`
|
|
30
|
+
* asserts no second declaration — while the single definition moved to
|
|
31
|
+
* `outcome_vocabularies.ts` so the contract's table can be checked against it
|
|
32
|
+
* (`road-to-experience-loop-broadening` 1.3).
|
|
33
|
+
*/
|
|
34
|
+
export type TerminalState = RunTerminalState;
|
|
35
|
+
|
|
36
|
+
/** States that are NOT success. An error or an exhausted budget never reports as one. */
|
|
37
|
+
export const NON_SUCCESS_STATES: ReadonlySet<TerminalState> = new Set([
|
|
38
|
+
'blocked',
|
|
39
|
+
'approval-required',
|
|
40
|
+
'exhausted',
|
|
41
|
+
'stagnated',
|
|
42
|
+
]);
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Why a failure is or is not worth retrying.
|
|
46
|
+
*
|
|
47
|
+
* `hard-blocker` is the load-bearing value: it says *stop now and surface*,
|
|
48
|
+
* not *try twice more first*. `context-hygiene` names the classes — missing
|
|
49
|
+
* credential, permission denied, quota or rate limit reached, upstream 5xx —
|
|
50
|
+
* and a first occurrence of any of them skips the retry budget entirely.
|
|
51
|
+
*/
|
|
52
|
+
export type RetryClass = 'retryable' | 'hard-blocker' | 'not-applicable';
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* What the orchestrator did with a return — the acknowledgment half of the
|
|
56
|
+
* channel (`road-to-runtime-event-journal` Phase 3.1).
|
|
57
|
+
*
|
|
58
|
+
* The envelope already refuses to report a failure as a success. What it could
|
|
59
|
+
* not record is whether the *reader* did anything with that failure: a
|
|
60
|
+
* `blocked` return the orchestrator dropped on the floor is byte-identical to
|
|
61
|
+
* one it read, weighed, and deliberately set aside. Both are "a blocked return
|
|
62
|
+
* exists"; only one of them is a defect, and no field distinguished them.
|
|
63
|
+
*
|
|
64
|
+
* Three values, and the absent case is the fourth and the load-bearing one:
|
|
65
|
+
* ABSENT means nobody recorded a decision, which is exactly the ignored
|
|
66
|
+
* blocker `_lib/ignored_blocker.ts` reports.
|
|
67
|
+
*/
|
|
68
|
+
export type ConsumptionState = 'consumed' | 'partially-consumed' | 'rejected-with-reason';
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* The acknowledgment record. A discriminated union, so the reason that
|
|
72
|
+
* `rejected-with-reason` needs is enforced by the TYPE rather than by a
|
|
73
|
+
* runtime check the caller meets or does not: `{ consumption:
|
|
74
|
+
* 'rejected-with-reason' }` with no `reason` does not compile.
|
|
75
|
+
*
|
|
76
|
+
* The other two states may carry a reason and are not required to — a
|
|
77
|
+
* consumed return needs no justification, and demanding one would make the
|
|
78
|
+
* cheap path expensive, which is how a field stops being filled at all
|
|
79
|
+
* (Risk 5).
|
|
80
|
+
*/
|
|
81
|
+
export type Acknowledgment =
|
|
82
|
+
| { readonly consumption: 'consumed'; readonly reason?: string }
|
|
83
|
+
| { readonly consumption: 'partially-consumed'; readonly reason?: string }
|
|
84
|
+
| { readonly consumption: 'rejected-with-reason'; readonly reason: string };
|
|
85
|
+
|
|
86
|
+
export interface OutcomeEnvelope<T = unknown> {
|
|
87
|
+
state: TerminalState;
|
|
88
|
+
/** Whether a retry can plausibly change the outcome. */
|
|
89
|
+
retry: RetryClass;
|
|
90
|
+
/**
|
|
91
|
+
* What to do next, in the imperative, naming the thing to change. Required
|
|
92
|
+
* on every non-success state: a state without a next action is a report the
|
|
93
|
+
* reader must translate.
|
|
94
|
+
*/
|
|
95
|
+
suggestion: string;
|
|
96
|
+
/** True when the payload was capped. A capped list without this reads as complete. */
|
|
97
|
+
truncated: boolean;
|
|
98
|
+
/** Per-category counts BEFORE capping, so a reader sees what was dropped. */
|
|
99
|
+
totals: Record<string, number>;
|
|
100
|
+
payload: T;
|
|
101
|
+
/**
|
|
102
|
+
* What the orchestrator did with this return, when it recorded anything.
|
|
103
|
+
*
|
|
104
|
+
* OPTIONAL on purpose, and the optionality is the measurement surface: an
|
|
105
|
+
* absent acknowledgment on a non-success state is a detectable ignored
|
|
106
|
+
* blocker, not a defaulted-to-fine one. Never default it to `consumed` —
|
|
107
|
+
* that would make every unread return look read, which is the exact
|
|
108
|
+
* failure the field exists to expose.
|
|
109
|
+
*/
|
|
110
|
+
acknowledgment?: Acknowledgment;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Raised when an envelope is constructed in a state its own contract forbids. */
|
|
114
|
+
export class EnvelopeContractError extends Error {}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Build an envelope, refusing the two shapes that make one useless.
|
|
118
|
+
*
|
|
119
|
+
* A non-success state with no `suggestion` is refused, and so is `truncated`
|
|
120
|
+
* with empty `totals`: both are the "capped list reads as complete" failure in
|
|
121
|
+
* different clothes — one hides the next action, the other hides the drop.
|
|
122
|
+
*/
|
|
123
|
+
export function envelope<T>(init: {
|
|
124
|
+
state: TerminalState;
|
|
125
|
+
retry?: RetryClass;
|
|
126
|
+
suggestion?: string;
|
|
127
|
+
truncated?: boolean;
|
|
128
|
+
totals?: Record<string, number>;
|
|
129
|
+
payload: T;
|
|
130
|
+
/**
|
|
131
|
+
* Optional at construction. A producer almost never knows what its reader
|
|
132
|
+
* will do, so the normal path is {@link acknowledge} at the consuming end;
|
|
133
|
+
* this entry exists so a caller that IS both ends does not have to
|
|
134
|
+
* round-trip through a second call.
|
|
135
|
+
*/
|
|
136
|
+
acknowledgment?: Acknowledgment;
|
|
137
|
+
}): OutcomeEnvelope<T> {
|
|
138
|
+
const state = init.state;
|
|
139
|
+
const suggestion = init.suggestion ?? '';
|
|
140
|
+
if (NON_SUCCESS_STATES.has(state) && suggestion.trim() === '') {
|
|
141
|
+
throw new EnvelopeContractError(
|
|
142
|
+
`terminal state "${state}" requires a suggestion — a non-success outcome with no ` +
|
|
143
|
+
'named next action is a report the reader has to translate, which is the ' +
|
|
144
|
+
'judgement this envelope exists to remove.',
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
const truncated = init.truncated ?? false;
|
|
148
|
+
const totals = init.totals ?? {};
|
|
149
|
+
if (truncated && Object.keys(totals).length === 0) {
|
|
150
|
+
throw new EnvelopeContractError(
|
|
151
|
+
'truncated: true requires per-category totals — a capped list whose pre-cap counts ' +
|
|
152
|
+
'are unknown is indistinguishable from a complete one, which is the defect the ' +
|
|
153
|
+
'flag exists to remove.',
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
state,
|
|
158
|
+
retry: init.retry ?? (state === 'success' || state === 'clean-no-op' ? 'not-applicable' : 'retryable'),
|
|
159
|
+
suggestion,
|
|
160
|
+
truncated,
|
|
161
|
+
totals,
|
|
162
|
+
payload: init.payload,
|
|
163
|
+
// Spread rather than assigned: under `exactOptionalPropertyTypes` an
|
|
164
|
+
// explicit `undefined` is NOT the same as an absent key, and the whole
|
|
165
|
+
// detector rests on absence meaning "nobody decided".
|
|
166
|
+
...(init.acknowledgment === undefined ? {} : { acknowledgment: init.acknowledgment }),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Record what a reader did with a return, without mutating the original.
|
|
172
|
+
*
|
|
173
|
+
* Returns a NEW envelope. The producer's value stays as it was emitted, so an
|
|
174
|
+
* acknowledgment can never be mistaken for something the producer claimed
|
|
175
|
+
* about its own output — which is the same author-is-not-the-evaluator
|
|
176
|
+
* boundary the rest of this tree keeps.
|
|
177
|
+
*/
|
|
178
|
+
export function acknowledge<T>(env: OutcomeEnvelope<T>, ack: Acknowledgment): OutcomeEnvelope<T> {
|
|
179
|
+
return { ...env, acknowledgment: ack };
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Cap a finding list PER CATEGORY and report what was dropped.
|
|
184
|
+
*
|
|
185
|
+
* @returns the kept items, the pre-cap totals per category, and whether
|
|
186
|
+
* anything was dropped. The caller passes `totals` straight into
|
|
187
|
+
* {@link envelope}, so the flag and the counts cannot drift apart.
|
|
188
|
+
*/
|
|
189
|
+
export function capPerCategory<T>(
|
|
190
|
+
items: readonly T[],
|
|
191
|
+
categoryOf: (item: T) => string,
|
|
192
|
+
perCategoryCap: number,
|
|
193
|
+
): { kept: T[]; totals: Record<string, number>; truncated: boolean } {
|
|
194
|
+
const totals: Record<string, number> = {};
|
|
195
|
+
const seen: Record<string, number> = {};
|
|
196
|
+
const kept: T[] = [];
|
|
197
|
+
for (const item of items) {
|
|
198
|
+
const c = categoryOf(item);
|
|
199
|
+
totals[c] = (totals[c] ?? 0) + 1;
|
|
200
|
+
seen[c] = (seen[c] ?? 0) + 1;
|
|
201
|
+
if ((seen[c] ?? 0) <= perCategoryCap) kept.push(item);
|
|
202
|
+
}
|
|
203
|
+
return { kept, totals, truncated: kept.length < items.length };
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Classify a failure into a retry class from what a command actually produced.
|
|
208
|
+
*
|
|
209
|
+
* Deliberately a small, named list rather than a general heuristic: every entry
|
|
210
|
+
* corresponds to a hard-blocker class the rules already name, and a classifier
|
|
211
|
+
* that guessed beyond them would turn a transient failure into a permanent one.
|
|
212
|
+
* Anything unmatched is `retryable`, which is the safe direction — a wasted
|
|
213
|
+
* retry costs one iteration, a wrongly-permanent verdict costs the whole task.
|
|
214
|
+
*/
|
|
215
|
+
export function classifyFailure(text: string): RetryClass {
|
|
216
|
+
const t = text.toLowerCase();
|
|
217
|
+
const hard: readonly RegExp[] = [
|
|
218
|
+
/\b(permission denied|forbidden|403)\b/,
|
|
219
|
+
/\b(unauthorized|401|not authenticated|authentication (failed|required))\b/,
|
|
220
|
+
/\b(quota|rate limit|too many requests|429)\b/,
|
|
221
|
+
/\b(missing|unset|not set)\b[^\n]{0,40}\b(credential|token|api[_ -]?key|secret)\b/,
|
|
222
|
+
/\bcommand not found\b/,
|
|
223
|
+
/\bno such (file or directory|command)\b/,
|
|
224
|
+
/\bspend (cap|limit) reached\b/,
|
|
225
|
+
];
|
|
226
|
+
return hard.some((re) => re.test(t)) ? 'hard-blocker' : 'retryable';
|
|
227
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The three outcome vocabularies this repository actually produces, and the
|
|
3
|
+
* one crossing between them — in a single module, so a fourth cannot appear
|
|
4
|
+
* without a diff to this file.
|
|
5
|
+
*
|
|
6
|
+
* `road-to-experience-loop-broadening` step 1.3. That step was written on the
|
|
7
|
+
* premise that the tree holds **two** outcome enums and that one of them is
|
|
8
|
+
* documentation-only. Re-measured at `63d06b7eb`, both halves of that premise
|
|
9
|
+
* are wrong, and the corrected picture is why this module registers rather
|
|
10
|
+
* than unifies:
|
|
11
|
+
*
|
|
12
|
+
* | Vocabulary | Subject | Declared | Values |
|
|
13
|
+
* |---|---|---|---|
|
|
14
|
+
* | phase | one audit-log line — a `/work` PHASE | here, consumed by `orchestration_record` | 4 |
|
|
15
|
+
* | step | one work-engine STEP | `work_engine/delivery_state.ts` (template tree) | 3 |
|
|
16
|
+
* | run | one command or gate RUN | here, consumed by `outcome_envelope` | 6 |
|
|
17
|
+
*
|
|
18
|
+
* All three are declared in code AND emitted today. `skipped` and `error` are
|
|
19
|
+
* not aspirational: `envelopeOutcome` in `orchestration_record.ts` returns
|
|
20
|
+
* both, and `review_skipped_record.ts` writes `outcome: 'skipped'` onto a real
|
|
21
|
+
* audit line. An earlier reading of this tree concluded they "exist nowhere",
|
|
22
|
+
* because it grepped for enum MEMBER ASSIGNMENTS (`SKIPPED: 'skipped'`) and
|
|
23
|
+
* these are string-literal union members. The distinction cost a wrong premise
|
|
24
|
+
* once; it is written down here so it cannot cost it twice.
|
|
25
|
+
*
|
|
26
|
+
* **Why register and not unify.** AI council 2026-08-29 (anthropic + openai,
|
|
27
|
+
* 2 rounds, $0.00, both seats subscription-authed) split on the question and
|
|
28
|
+
* named the same discriminator: trace the producers before choosing. The trace
|
|
29
|
+
* settled it — the three subjects are genuinely different (a phase aggregates
|
|
30
|
+
* steps; a run is neither), all three are produced, and a cross-domain mapping
|
|
31
|
+
* already existed in the tree. A superset would admit states that are
|
|
32
|
+
* nonsense for their subject: a step ending `approval-required`, a run ending
|
|
33
|
+
* `partial`. So: separate vocabularies, one registry, mappings only where
|
|
34
|
+
* execution actually crosses.
|
|
35
|
+
*
|
|
36
|
+
* **Mappings are not written for symmetry.** Exactly one crossing exists
|
|
37
|
+
* (`DispatchOutcome` -> phase, in `orchestration_record.ts`). A total
|
|
38
|
+
* phase<->step<->run mapping would be nine relations of which one is real, and
|
|
39
|
+
* the eight invented ones would read as contract.
|
|
40
|
+
*
|
|
41
|
+
* `revisit-if`: a producer needs a value its vocabulary cannot express, or a
|
|
42
|
+
* second real crossing appears, or producer analysis shows two of the three
|
|
43
|
+
* subjects share identical terminal semantics with a lossless mapping — at
|
|
44
|
+
* which point unifying those two becomes the cheaper answer.
|
|
45
|
+
*
|
|
46
|
+
* Type-only + literal arrays. No `node:` import, so any surface may read it.
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Outcome of one audit-log line — a `/work` phase.
|
|
51
|
+
*
|
|
52
|
+
* Authoritative for `docs/contracts/audit-log-v1.md`'s `outcome` row. The
|
|
53
|
+
* binding is a test, not an import, because a markdown contract cannot import:
|
|
54
|
+
* `tests/contracts/outcome_vocabularies.test.ts`.
|
|
55
|
+
*/
|
|
56
|
+
export const PHASE_OUTCOMES = ['success', 'blocked', 'skipped', 'error'] as const;
|
|
57
|
+
export type PhaseOutcome = (typeof PHASE_OUTCOMES)[number];
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Outcome of one work-engine step.
|
|
61
|
+
*
|
|
62
|
+
* Declared in `src/agent-src/templates/scripts/work_engine/delivery_state.ts`,
|
|
63
|
+
* which is a TEMPLATE and self-contained by contract — no template file
|
|
64
|
+
* imports from `src/scripts/`. So this is the lint-checked mirror, not the
|
|
65
|
+
* declaration, and the same test asserts the two agree.
|
|
66
|
+
*/
|
|
67
|
+
export const STEP_OUTCOMES = ['success', 'blocked', 'partial'] as const;
|
|
68
|
+
export type StepOutcome = (typeof STEP_OUTCOMES)[number];
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Terminal state of one command or gate run.
|
|
72
|
+
*
|
|
73
|
+
* Authoritative for `contexts/execution/terminal-states.md`. Re-exported by
|
|
74
|
+
* `outcome_envelope.ts` as `TerminalState`, which stays the public surface —
|
|
75
|
+
* `runtime_journal.test.ts` pins that import path, and an anti-fork assertion
|
|
76
|
+
* there already prevents a second declaration.
|
|
77
|
+
*/
|
|
78
|
+
export const RUN_TERMINAL_STATES = [
|
|
79
|
+
'success',
|
|
80
|
+
'clean-no-op',
|
|
81
|
+
'blocked',
|
|
82
|
+
'approval-required',
|
|
83
|
+
'exhausted',
|
|
84
|
+
'stagnated',
|
|
85
|
+
] as const;
|
|
86
|
+
export type RunTerminalState = (typeof RUN_TERMINAL_STATES)[number];
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* The crossings that exist. One row, because one crossing is real.
|
|
90
|
+
*
|
|
91
|
+
* Read as: code at `from` translates a value of `source` into a value of
|
|
92
|
+
* `target`. A row is added when execution starts crossing, never in advance.
|
|
93
|
+
*/
|
|
94
|
+
export const CROSS_DOMAIN_MAPPINGS = [
|
|
95
|
+
{
|
|
96
|
+
source: 'DispatchOutcome',
|
|
97
|
+
target: 'phase',
|
|
98
|
+
at: 'src/scripts/_lib/orchestration_record.ts',
|
|
99
|
+
fn: 'envelopeOutcome',
|
|
100
|
+
/**
|
|
101
|
+
* The mapping is VERSIONED as of 2026-08-30
|
|
102
|
+
* (road-to-experience-loop-broadening 2.2). Version 1 was
|
|
103
|
+
* unconditional: DONE / DONE_WITH_CONCERNS always became `success`.
|
|
104
|
+
* Version 2 is contract-gated -- a `code-change` dispatch claiming
|
|
105
|
+
* success with a MEASURED empty diff no longer does.
|
|
106
|
+
*
|
|
107
|
+
* Recorded here rather than only at the call site because this registry
|
|
108
|
+
* is the one place a reader looks to learn that a crossing exists, and a
|
|
109
|
+
* crossing whose semantics changed silently is worse than one nobody
|
|
110
|
+
* documented. Lines carry `outcome_semantics`; an absent field is
|
|
111
|
+
* version 1.
|
|
112
|
+
*/
|
|
113
|
+
semantics_version: 2,
|
|
114
|
+
},
|
|
115
|
+
] as const;
|
|
116
|
+
|
|
117
|
+
/** Is this string a phase outcome? The guard the audit-log consumer was missing. */
|
|
118
|
+
export function isPhaseOutcome(v: unknown): v is PhaseOutcome {
|
|
119
|
+
return typeof v === 'string' && (PHASE_OUTCOMES as readonly string[]).includes(v);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** Is this string a run terminal state? */
|
|
123
|
+
export function isRunTerminalState(v: unknown): v is RunTerminalState {
|
|
124
|
+
return typeof v === 'string' && (RUN_TERMINAL_STATES as readonly string[]).includes(v);
|
|
125
|
+
}
|