@event4u/agent-config 16.0.0 → 16.2.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 +289 -140
- package/CONTRIBUTING.md +9 -0
- package/README.md +2 -2
- package/dist/agent-src/commands/analyze/inbox.md +26 -0
- package/dist/agent-src/commands/analyze/roadmap-repos.md +27 -0
- package/dist/agent-src/commands/challenge-me/closure.md +178 -0
- package/dist/agent-src/commands/challenge-me.md +9 -2
- package/dist/agent-src/commands/council/default.md +25 -5
- package/dist/agent-src/commands/feature/plan.md +28 -1
- package/dist/agent-src/commands/feature/roadmap.md +28 -1
- package/dist/agent-src/commands/implement-ticket.md +27 -0
- package/dist/agent-src/commands/jira-ticket.md +27 -0
- package/dist/agent-src/commands/pr/create.md +29 -0
- package/dist/agent-src/commands/pr/merge.md +60 -9
- package/dist/agent-src/commands/roadmap/ai-council.md +7 -1
- package/dist/agent-src/commands/roadmap/create.md +74 -27
- package/dist/agent-src/commands/roadmap/materialize.md +27 -0
- package/dist/agent-src/commands/roadmap/process-full.md +123 -18
- package/dist/agent-src/commands/team.md +22 -0
- package/dist/agent-src/commands/work.md +4 -0
- package/dist/agent-src/contexts/authority/scope-growth-ownership.md +80 -0
- package/dist/agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +47 -0
- package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +44 -3
- package/dist/agent-src/contexts/execution/autonomy-mechanics.md +19 -23
- package/dist/agent-src/contexts/execution/decision-closure-execution.md +93 -0
- package/dist/agent-src/contexts/execution/fix-loop-ladder.md +108 -0
- package/dist/agent-src/contexts/execution/plan-confidence-gate.md +4 -2
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +75 -6
- package/dist/agent-src/guidelines/agent-infra/active-remediation-mechanics.md +57 -0
- package/dist/agent-src/guidelines/agent-infra/evaluator-independence-mechanics.md +102 -0
- package/dist/agent-src/guidelines/design-fidelity-routing.md +29 -0
- package/dist/agent-src/rules/autonomous-execution.md +15 -8
- package/dist/agent-src/rules/delegation-policy.md +23 -45
- package/dist/agent-src/rules/design-fidelity.md +32 -37
- package/dist/agent-src/rules/evaluator-independence.md +43 -49
- package/dist/agent-src/rules/test-first.md +41 -0
- package/dist/agent-src/rules/ui-audit-gate.md +1 -2
- package/dist/agent-src/skills/accessibility-auditor/data/aria-patterns.csv +1 -1
- package/dist/agent-src/skills/accessibility-auditor/data/manifest.json +3 -3
- package/dist/agent-src/skills/ai-council/SKILL.md +11 -3
- package/dist/agent-src/skills/api-design/data/manifest.json +3 -3
- package/dist/agent-src/skills/database/data/manifest.json +4 -4
- package/dist/agent-src/skills/database/data/query-tuning.csv +3 -3
- package/dist/agent-src/skills/design-review/SKILL.md +80 -4
- package/dist/agent-src/skills/design-review/references/verification-automation.md +32 -0
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +30 -5
- package/dist/agent-src/skills/existing-ui-audit/references/component-taxonomy-detection.md +56 -0
- package/dist/agent-src/skills/experiment-loop/SKILL.md +31 -1
- package/dist/agent-src/skills/markitdown/SKILL.md +4 -0
- package/dist/agent-src/skills/playwright-testing/SKILL.md +30 -6
- package/dist/agent-src/skills/roadmap-writing/SKILL.md +1 -1
- package/dist/agent-src/skills/storybook-workshop/SKILL.md +42 -3
- package/dist/agent-src/skills/threat-modeling/SKILL.md +9 -4
- package/dist/agent-src/skills/threat-modeling/data/manifest.json +4 -4
- package/dist/agent-src/skills/ui-component-architect/SKILL.md +23 -0
- package/dist/agent-src/skills/verify-repair-loop/SKILL.md +37 -3
- package/dist/agent-src/templates/agent-settings.md +1 -1
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +218 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +62 -2
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.ts +1 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +1 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/app_spec.ts +10 -4
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +260 -21
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/audit.ts +22 -3
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +6 -1
- package/dist/agent-src/templates/scripts/work_engine/state.ts +57 -7
- package/dist/agent-src/templates/scripts/work_engine/taxonomy/detect.ts +500 -0
- package/dist/agent-src/templates/scripts/work_engine/taxonomy/place.ts +183 -0
- package/dist/cli/python/knowledge_ingest.js +1 -1
- package/dist/cli/python/workspace_drive.js +1 -1
- package/dist/cli-delegate/check_update_banner.js +40 -2
- package/dist/cli-delegate/chunk-4E2W63DA.js +335 -0
- package/dist/cli-delegate/{chunk-S3VFXMTM.js → chunk-4XFP2Y3E.js} +1 -1
- package/dist/cli-delegate/chunk-5R7HOLAF.js +99 -0
- package/dist/cli-delegate/{chunk-IVBPRCQO.js → chunk-6KFEC3G7.js} +1 -1
- package/dist/cli-delegate/{chunk-2TAQ2K4V.js → chunk-6KM6ORRY.js} +55 -386
- package/dist/cli-delegate/{chunk-AK6HODNQ.js → chunk-7XGBX6ZH.js} +973 -555
- package/dist/cli-delegate/{chunk-2XY7ILBT.js → chunk-FC75PGJE.js} +42 -2
- package/dist/cli-delegate/{chunk-55ACLDUE.js → chunk-FP36SWJD.js} +587 -141
- package/dist/cli-delegate/{chunk-3FKR64R5.js → chunk-IGD6ERX6.js} +62 -7
- package/dist/cli-delegate/{chunk-GYC3VRYN.js → chunk-JNMVLWLR.js} +99 -14
- package/dist/cli-delegate/{chunk-H32DGUJH.js → chunk-P6ZHP5W2.js} +1 -1
- package/dist/cli-delegate/{chunk-57PN4GYJ.js → chunk-RGNIWTEA.js} +1 -1
- package/dist/cli-delegate/chunk-ROYYTEZU.js +39 -0
- package/dist/cli-delegate/{chunk-2DK2VJWG.js → chunk-WGXTVKCQ.js} +20 -6
- package/dist/cli-delegate/chunk-YDPILCOL.js +152 -0
- package/dist/cli-delegate/{chunk-QJWAUMJW.js → chunk-YJ72UIAK.js} +730 -15
- package/dist/cli-delegate/cmd_analyze_session.js +1 -1
- package/dist/cli-delegate/cmd_brand_status.js +1 -1
- package/dist/cli-delegate/cmd_conformance.js +985 -831
- package/dist/cli-delegate/cmd_doctor.js +7 -5
- package/dist/cli-delegate/cmd_explain.js +2 -2
- package/dist/cli-delegate/cmd_export.js +9 -7
- package/dist/cli-delegate/cmd_fleet.js +4 -2
- package/dist/cli-delegate/cmd_handoff.js +7 -7
- package/dist/cli-delegate/cmd_mcp_available.js +1 -1
- package/dist/cli-delegate/cmd_memory_get.js +1 -1
- package/dist/cli-delegate/cmd_migrate.js +2 -2
- package/dist/cli-delegate/cmd_packs_active.js +2 -2
- package/dist/cli-delegate/cmd_preflight.js +4 -2
- package/dist/cli-delegate/cmd_prune.js +10 -8
- package/dist/cli-delegate/cmd_route_audit.js +3 -3
- package/dist/cli-delegate/cmd_route_explain.js +1 -1
- package/dist/cli-delegate/cmd_session_recycle.js +4 -4
- package/dist/cli-delegate/cmd_settings_get.js +28 -2
- package/dist/cli-delegate/cmd_settings_migrate.js +9 -7
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +10 -8
- package/dist/cli-delegate/cmd_uninstall.js +16 -13
- package/dist/cli-delegate/cmd_update.js +1 -1
- package/dist/cli-delegate/cmd_upgrade.js +1 -1
- package/dist/cli-delegate/cmd_validate.js +12 -10
- package/dist/cli-delegate/cmd_versions.js +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +90 -43
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +4 -4
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +10 -8
- package/dist/discovery/trust-report.md +3 -3
- package/dist/discovery/workspaces.json +8 -6
- package/dist/hooks/dispatch.js +7682 -2772
- package/dist/hooks/dispatch.sha256 +1 -0
- package/dist/install/claudeRuleRewrite.js +14 -3
- package/dist/install/conflict.js +60 -10
- package/dist/install/conflictTracker.js +218 -0
- package/dist/install/fsPrimitives.js +54 -0
- package/dist/install/install.mjs +2200 -1559
- package/dist/install/manifestFiles.js +259 -0
- package/dist/install/preflight.js +14 -2
- package/dist/install/preserve.js +157 -0
- package/dist/install/recordedOwnership.js +132 -0
- package/dist/install/txlog.js +11 -2
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +3066 -1470
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/agent_settings.js +3 -2
- package/dist/scripts/_lib/fs_atomic.js +167 -0
- package/dist/scripts/_lib/installed_tools.js +460 -0
- package/dist/scripts/_lib/lean_projection_mode.js +3 -2
- package/dist/scripts/_lib/settings_renamed_keys.js +78 -0
- package/dist/server/routes/install.js +8 -0
- package/dist/server/routes/wizard.js +9 -3
- package/dist/server/schemas/settings.js +40 -5
- package/dist/shared/missionExecution.js +97 -0
- package/dist/ui/assets/index-Cwq4d0hX.js +23 -0
- package/dist/ui/assets/index-Cyjy8bWO.css +1 -0
- package/dist/ui/index.html +2 -2
- package/docs/MIGRATION.md +103 -0
- package/docs/contracts/settings-classes.md +28 -7
- package/docs/guidelines/agent-infra/active-remediation-mechanics.md +57 -0
- package/docs/guidelines/agent-infra/evaluator-independence-mechanics.md +102 -0
- package/docs/guidelines/design-fidelity-routing.md +29 -0
- package/package.json +4 -4
- package/src/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +62 -2
- package/src/agent-src/templates/scripts/work_engine/directives/backend/test.ts +1 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +1 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/app_spec.ts +10 -4
- package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +260 -21
- package/src/agent-src/templates/scripts/work_engine/directives/ui/audit.ts +22 -3
- package/src/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +6 -1
- package/src/agent-src/templates/scripts/work_engine/state.ts +57 -7
- package/src/agent-src/templates/scripts/work_engine/taxonomy/detect.ts +500 -0
- package/src/agent-src/templates/scripts/work_engine/taxonomy/place.ts +183 -0
- package/src/config/agent-settings.template.yml +168 -27
- package/src/config/auto-rule-budget.json +16 -0
- package/src/config/ci-local-parity.yml +36 -5
- package/src/config/continuity-surface.json +23 -2
- package/src/config/gate-coverage.yml +377 -13
- package/src/config/gate-violation-baselines.json +10 -6
- package/src/config/hook-latency-budget.json +21 -0
- package/src/config/hook-token-budget.json +4 -2
- package/src/config/loop-surfaces.yaml +215 -0
- package/src/config/metric-registry.yml +114 -0
- package/src/config/placeholder-drift-budget.json +10 -0
- package/src/config/platform-anchor.json +3 -2
- package/src/config/release-gate-locality.yml +11 -0
- package/src/config/routing-coverage-seed.json +33 -5
- package/src/config/rule-enforcement-baseline.json +0 -1
- package/src/install/claudeRuleRewrite.ts +16 -2
- package/src/install/conflict.ts +65 -9
- package/src/install/conflictTracker.ts +299 -0
- package/src/install/fsPrimitives.ts +54 -0
- package/src/install/manifestFiles.ts +312 -0
- package/src/install/preflight.ts +16 -2
- package/src/install/preserve.ts +205 -0
- package/src/install/recordedOwnership.ts +149 -0
- package/src/install/txlog.ts +11 -2
- package/src/install/types.ts +19 -4
- package/src/scripts/_cli/cmd_conformance.ts +88 -15
- package/src/scripts/_cli/cmd_doctor.ts +7 -20
- package/src/scripts/_cli/cmd_route_explain.ts +9 -2
- package/src/scripts/_cli/cmd_settings_get.ts +44 -0
- package/src/scripts/_cli/doctor_execution.ts +173 -0
- package/src/scripts/_cli/doctor_network_posture.ts +226 -0
- package/src/scripts/_lib/activation_payload.ts +247 -0
- package/src/scripts/_lib/agent_settings.ts +4 -2
- package/src/scripts/_lib/authority_path.ts +102 -0
- package/src/scripts/_lib/body_portable.ts +102 -0
- package/src/scripts/_lib/cascade_base.ts +94 -0
- package/src/scripts/_lib/cc_transcript.ts +132 -1
- package/src/scripts/_lib/changelog_eras.ts +7 -2
- package/src/scripts/_lib/concern_sla_window.ts +200 -0
- package/src/scripts/_lib/continuation_ladder.ts +149 -2
- package/src/scripts/_lib/council_transport.ts +129 -0
- package/src/scripts/_lib/delivery_ready.ts +112 -0
- package/src/scripts/_lib/forge_protection.ts +381 -0
- package/src/scripts/_lib/forge_reader.ts +558 -0
- package/src/scripts/_lib/hook_platform_keys.ts +27 -0
- package/src/scripts/_lib/host_env_write.ts +111 -0
- package/src/scripts/_lib/json_python_parity.ts +127 -0
- package/src/scripts/_lib/lean_projection_mode.ts +14 -3
- package/src/scripts/_lib/llm_proposer_transport.ts +14 -4
- package/src/scripts/_lib/loop_surfaces.ts +382 -0
- package/src/scripts/_lib/mission_record.ts +190 -0
- package/src/scripts/_lib/obligation_frequency.ts +217 -0
- package/src/scripts/_lib/obligations.ts +513 -0
- package/src/scripts/_lib/orchestration_record.ts +11 -20
- package/src/scripts/_lib/probe_inputs.ts +271 -0
- package/src/scripts/_lib/read_surface_scan.ts +322 -0
- package/src/scripts/_lib/release_highlights.ts +201 -11
- package/src/scripts/_lib/release_holds.ts +493 -0
- package/src/scripts/_lib/release_migration_gate.ts +184 -0
- package/src/scripts/_lib/retrieval_sanitize.ts +77 -16
- package/src/scripts/_lib/rides_along.ts +102 -0
- package/src/scripts/_lib/settings_renamed_keys.ts +82 -0
- package/src/scripts/_lib/shell_write_shapes.ts +108 -0
- package/src/scripts/_lib/structural_hiding.ts +622 -0
- package/src/scripts/_lib/test_delta.ts +166 -0
- package/src/scripts/_lib/test_provenance.ts +171 -0
- package/src/scripts/_lib/turn_end_refusals.ts +525 -4
- package/src/scripts/_lib/turn_end_transcript.ts +216 -0
- package/src/scripts/_lib/typed_op_grant.ts +246 -0
- package/src/scripts/_lib/typed_op_watch.ts +185 -0
- package/src/scripts/_lib/verification_command.ts +324 -0
- package/src/scripts/_lib/verification_evidence.ts +647 -0
- package/src/scripts/_lib/verify_clause.ts +280 -0
- package/src/scripts/ai_council/config.ts +8 -11
- package/src/scripts/ai_council/fallback_config.ts +5 -3
- package/src/scripts/ai_council/ownership_classes.ts +118 -0
- package/src/scripts/ai_team/team_dispatch.ts +4 -0
- package/src/scripts/ask_block_census.ts +285 -15
- package/src/scripts/before_complete_hook.ts +340 -23
- package/src/scripts/bench_hook_latency.ts +412 -5
- package/src/scripts/cache_realization_report.ts +61 -1
- package/src/scripts/check_argument_hint.ts +287 -0
- package/src/scripts/check_claims.ts +125 -1
- package/src/scripts/check_enforcement_coverage.ts +38 -9
- package/src/scripts/check_enforcement_matrix.ts +866 -0
- package/src/scripts/check_finding_dispositions.ts +22 -3
- package/src/scripts/check_gate_reachability.ts +173 -10
- package/src/scripts/check_generator_sync.ts +1025 -0
- package/src/scripts/check_host_docs_digest.ts +786 -0
- package/src/scripts/check_host_format_column.ts +559 -0
- package/src/scripts/check_input_references.ts +228 -0
- package/src/scripts/check_inputs_parity.ts +235 -0
- package/src/scripts/check_kernel_edit_ratified.ts +47 -5
- package/src/scripts/check_kill_switch_table.ts +294 -0
- package/src/scripts/check_placeholder_drift.ts +221 -0
- package/src/scripts/check_preamble_payload_budget.ts +75 -2
- package/src/scripts/check_read_surface_coverage.ts +515 -0
- package/src/scripts/check_release_highlights.ts +33 -1
- package/src/scripts/check_release_holds.ts +568 -0
- package/src/scripts/check_routing_coverage.ts +378 -11
- package/src/scripts/check_rule_projection_integrity.ts +22 -12
- package/src/scripts/check_static_parity.ts +17 -0
- package/src/scripts/check_test_delta.ts +294 -0
- package/src/scripts/check_test_weakening.ts +299 -0
- package/src/scripts/ci_settle.ts +145 -19
- package/src/scripts/closure_scan.ts +447 -0
- package/src/scripts/compile_hook_manifest.ts +102 -18
- package/src/scripts/council_record_shape.ts +209 -0
- package/src/scripts/external_sources_denylist.json +29 -4
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +127 -11
- package/src/scripts/hooks/block_config_weakening.ts +229 -4
- package/src/scripts/hooks/block_kernel_rule_writes.ts +9 -78
- package/src/scripts/hooks/block_plumbing_writes.ts +314 -0
- package/src/scripts/hooks/bundle_integrity.ts +291 -0
- package/src/scripts/hooks/chain_nudge_hook.ts +1 -2
- package/src/scripts/hooks/code_graph_context_hook.ts +1 -2
- package/src/scripts/hooks/comment_discipline_hook.ts +1 -3
- package/src/scripts/hooks/concern_registry.ts +6 -0
- package/src/scripts/hooks/concern_timings.ts +94 -0
- package/src/scripts/hooks/delegation_nudge_hook.ts +1 -2
- package/src/scripts/hooks/design_pass_hook.ts +221 -5
- package/src/scripts/hooks/design_slop_hook.ts +1 -2
- package/src/scripts/hooks/dispatch_hook.ts +25 -19
- package/src/scripts/hooks/edit_shape_hook.ts +1 -2
- package/src/scripts/hooks/end_review_nudge_hook.ts +1 -1
- package/src/scripts/hooks/evidence_independence.ts +97 -2
- package/src/scripts/hooks/exit_codes.ts +128 -0
- package/src/scripts/hooks/host_lowering.json +1 -0
- package/src/scripts/hooks/host_lowering.ts +128 -3
- package/src/scripts/hooks/host_lowering.yaml +262 -46
- package/src/scripts/hooks/host_semantics.ts +30 -2
- package/src/scripts/hooks/injection_budget.ts +9 -2
- package/src/scripts/hooks/interruption_ledger_hook.ts +1 -2
- package/src/scripts/hooks/journal_record_hook.ts +1 -2
- package/src/scripts/hooks/memory_recall_hook.ts +539 -0
- package/src/scripts/hooks/obligation_settle_hook.ts +328 -0
- package/src/scripts/hooks/one_question_per_ask_hook.ts +25 -4
- package/src/scripts/hooks/orchestration_record_hook.ts +1 -2
- package/src/scripts/hooks/permission_gate.ts +1 -2
- package/src/scripts/hooks/push_settle_hook.ts +1 -3
- package/src/scripts/hooks/replay_hook.ts +2 -1
- package/src/scripts/hooks/reread_guard_hook.ts +1 -2
- package/src/scripts/hooks/review_baseline_hook.ts +1 -2
- package/src/scripts/hooks/rtk_wrap_hook.ts +1 -2
- package/src/scripts/hooks/rule_inject_hook.ts +55 -4
- package/src/scripts/hooks/run_continuation_hook.ts +30 -35
- package/src/scripts/hooks/skill_route_hook.ts +1 -2
- package/src/scripts/hooks/source_first_gate_hook.ts +1 -2
- package/src/scripts/hooks/spawn_guard_shadow_hook.ts +1 -2
- package/src/scripts/hooks/subagent_ledger_hook.ts +1 -2
- package/src/scripts/hooks/suggestion_capture_hook.ts +1 -1
- package/src/scripts/hooks/table_fingerprint.ts +49 -0
- package/src/scripts/hooks/telemetry_flush_hook.ts +1 -2
- package/src/scripts/hooks/telemetry_usage_hook.ts +1 -2
- package/src/scripts/hooks/tool_result_bytes_hook.ts +93 -9
- package/src/scripts/hooks/turn_end_gate_hook.ts +337 -324
- package/src/scripts/hooks/ui_route_nudge_hook.ts +1 -2
- package/src/scripts/hooks_doctor.ts +85 -0
- package/src/scripts/hooks_status.ts +19 -0
- package/src/scripts/install.ts +109 -210
- package/src/scripts/janitor.ts +7 -0
- package/src/scripts/lint_decision_classes.ts +464 -0
- package/src/scripts/lint_deny_text.ts +419 -0
- package/src/scripts/lint_exit_codes.ts +262 -0
- package/src/scripts/lint_hook_manifest.ts +66 -0
- package/src/scripts/lint_major_migration_sections.ts +450 -0
- package/src/scripts/lint_plan_risk_register.ts +47 -3
- package/src/scripts/lint_roadmap_blockers.ts +139 -12
- package/src/scripts/lint_roadmap_producers.ts +202 -0
- package/src/scripts/lint_skill_descriptions.ts +1 -1
- package/src/scripts/lint_skill_scripts_readonly.ts +1 -1
- package/src/scripts/mcp_server/prompts.ts +142 -1
- package/src/scripts/measure_rule_budget.ts +101 -5
- package/src/scripts/measure_skill_ranker_baseline.ts +305 -51
- package/src/scripts/measure_turn_end_gate.ts +193 -0
- package/src/scripts/memory_lookup.ts +1 -1
- package/src/scripts/new_roadmap.ts +37 -0
- package/src/scripts/orchestration_record.ts +0 -5
- package/src/scripts/prepack-check.mjs +53 -0
- package/src/scripts/release.ts +14 -98
- package/src/scripts/release_drill.ts +267 -1
- package/src/scripts/release_publication.ts +64 -1
- package/src/scripts/report_enforcement_drift.ts +566 -0
- package/src/scripts/report_host_injection_effect.ts +3 -11
- package/src/scripts/report_invocation_surface.ts +383 -0
- package/src/scripts/report_obligation_carriers.ts +699 -0
- package/src/scripts/report_obligation_writer_split.ts +236 -0
- package/src/scripts/report_skill_menu_census.ts +208 -0
- package/src/scripts/report_standing_payload_by_host.ts +26 -152
- package/src/scripts/roadmap_verify_share.ts +213 -0
- package/src/scripts/schemas/agent-settings.schema.json +23 -0
- package/src/scripts/schemas/command.schema.json +48 -0
- package/src/scripts/schemas/review-findings.schema.json +4 -0
- package/src/scripts/schemas/skill.schema.json +44 -0
- package/src/scripts/scope_growth.ts +219 -0
- package/src/scripts/self_review_gate.ts +359 -10
- package/src/scripts/semantic_parity_census.ts +314 -0
- package/src/scripts/session_eol_report.ts +54 -1
- package/src/scripts/sweep_dead_scan_roots.ts +1 -1
- package/src/scripts/trigger_eval_grandfather.json +0 -3
- package/src/scripts/trigger_eval_rotation.ts +122 -27
- package/src/scripts/ui_conformance_probe.ts +774 -0
- package/src/scripts/update_prices.ts +85 -3
- package/src/scripts/write_bundle_digest.mjs +74 -0
- package/src/server/schemas/settings.ts +62 -7
- package/src/shared/missionExecution.ts +126 -0
- package/src/templates/consumer-settings/ONBOARDING.md +1 -0
- package/dist/cli-delegate/chunk-523HCFYO.js +0 -90
- package/dist/ui/assets/index-D0jaCRPM.js +0 -29
- package/dist/ui/assets/index-jSfMW8_t.css +0 -1
- /package/dist/cli-delegate/{chunk-YUM5KURG.js → chunk-7RQP4UDH.js} +0 -0
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* obligation-settle — the reader the delivered-obligation record never had.
|
|
4
|
+
*
|
|
5
|
+
* The injector has always known which rules it delivered into a session. Until
|
|
6
|
+
* this concern, nothing asked whether the turn that received them discharged
|
|
7
|
+
* any. This is that question, asked at turn-end, and — for now — asked out
|
|
8
|
+
* loud and answered with nothing.
|
|
9
|
+
*
|
|
10
|
+
* SHADOW ONLY. IT REFUSES NOTHING, AND THAT IS NOT A PLACEHOLDER.
|
|
11
|
+
* It computes the verdict a future armed detector would reach, records it, and
|
|
12
|
+
* returns allow on every path. Arming is gated on a bar pre-registered in
|
|
13
|
+
* `docs/CLAIMS.md` BEFORE any code able to refuse exists, so that the bar
|
|
14
|
+
* cannot be chosen to fit the numbers the shadow window happened to produce.
|
|
15
|
+
* The estate already has one blocking turn-end concern and the first-ranked
|
|
16
|
+
* risk against this work is that a second one refuses a clean turn and an
|
|
17
|
+
* operator disables the carrier for good.
|
|
18
|
+
*
|
|
19
|
+
* THE TOUCHED SET COMES FROM THE DIFF, NOT FROM TOOL EVENTS.
|
|
20
|
+
* A tool event carries the path the tool was given. A shell heredoc writing
|
|
21
|
+
* three files reports one Bash call and no paths at all, so a detector reading
|
|
22
|
+
* tool events is blind to exactly the turns that wrote the most. `git diff
|
|
23
|
+
* --numstat HEAD` plus `git ls-files --others` sees the tree as it actually
|
|
24
|
+
* is, which is the only description that cannot be evaded by how the write was
|
|
25
|
+
* spelled. The helpers are the end-review concern's own, imported rather than
|
|
26
|
+
* re-derived.
|
|
27
|
+
*
|
|
28
|
+
* IT REFUSES ONLY ON CLASSES THAT COULD HAVE A DISCHARGE.
|
|
29
|
+
* `hook`, `validator` and `test` name carriers that run and leave traces.
|
|
30
|
+
* `observer`, `instruction-only` and `none` do not, so demanding a discharge
|
|
31
|
+
* for one would demand evidence nobody can produce — and 69 of 97 delivered
|
|
32
|
+
* rules on the frozen corpus are class `none`.
|
|
33
|
+
*
|
|
34
|
+
* IT IS SILENT WHILE A SUBAGENT DISPATCH IS OPEN.
|
|
35
|
+
* Three of the turn-end gate's six detectors are gated this way and three are
|
|
36
|
+
* not; the difference is whether the finding could be about work a dispatch is
|
|
37
|
+
* still doing. This one could — a subagent writing UI files is the canonical
|
|
38
|
+
* case — so it takes the gated side.
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
import path from 'node:path';
|
|
42
|
+
import process from 'node:process';
|
|
43
|
+
|
|
44
|
+
import { readHookStdin } from './hook_stdin.js';
|
|
45
|
+
// The WRITER's own root resolver, imported rather than re-derived. A second
|
|
46
|
+
// spelling of "which tree is this" is how a reader comes to address a ledger
|
|
47
|
+
// the writer never wrote — which is the defect this whole file is repairing,
|
|
48
|
+
// one field over.
|
|
49
|
+
import { workspaceRoot as writerWorkspaceRoot } from './rule_inject_hook.js';
|
|
50
|
+
|
|
51
|
+
import { may_refuse_on } from '../_lib/obligation_frequency.js';
|
|
52
|
+
import { appendShadow, readDelivered, readDischarged, stamp } from '../_lib/obligations.js';
|
|
53
|
+
import { loadRouter, matchTierRules } from '../_lib/rule_injection.js';
|
|
54
|
+
import { gitNumstatRows, isDocPath, untrackedNonDocFiles } from './end_review_nudge_hook.js';
|
|
55
|
+
import { openRecordStats } from './subagent_ledger_hook.js';
|
|
56
|
+
import { EXIT_ALLOW } from './exit_codes.js';
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Every non-doc path this turn wrote, tracked or not.
|
|
60
|
+
*
|
|
61
|
+
* Doc paths are excluded on the same grounds the end-review concern excludes
|
|
62
|
+
* them: a markdown edit is not the kind of change whose obligations this
|
|
63
|
+
* detector can speak to, and including them would make almost every turn a
|
|
64
|
+
* candidate.
|
|
65
|
+
*/
|
|
66
|
+
export function touchedPaths(cwd: string): string[] {
|
|
67
|
+
const tracked = gitNumstatRows(cwd)
|
|
68
|
+
.map((r) => r.path)
|
|
69
|
+
.filter((p) => p !== '' && !isDocPath(p));
|
|
70
|
+
const untracked = untrackedNonDocFiles(cwd);
|
|
71
|
+
return [...new Set([...tracked, ...untracked])];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface SettleVerdict {
|
|
75
|
+
/** Non-doc paths this turn wrote. */
|
|
76
|
+
readonly touched: string[];
|
|
77
|
+
/** Delivered rules whose path triggers match something touched. */
|
|
78
|
+
readonly candidates: string[];
|
|
79
|
+
/** Candidates with no recorded discharge, and a class that could have one. */
|
|
80
|
+
readonly missing: string[];
|
|
81
|
+
/** True when a subagent dispatch is open — every other field is then advisory only. */
|
|
82
|
+
readonly dispatchOpen: boolean;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* What an armed detector would conclude, computed without refusing anything.
|
|
87
|
+
*
|
|
88
|
+
* Exported whole rather than as a boolean so the shadow row, the tests and any
|
|
89
|
+
* later armed path all read the SAME computation. A detector whose shadow
|
|
90
|
+
* measurement and live behaviour come from different code measures nothing.
|
|
91
|
+
*/
|
|
92
|
+
export function computeVerdict(root: string, session: string): SettleVerdict {
|
|
93
|
+
const dispatchOpen = (() => {
|
|
94
|
+
try {
|
|
95
|
+
return openRecordStats(root).open_count > 0;
|
|
96
|
+
} catch {
|
|
97
|
+
// An unreadable ledger is not a reason to change the verdict.
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
})();
|
|
101
|
+
|
|
102
|
+
const touched = touchedPaths(root);
|
|
103
|
+
if (touched.length === 0) {
|
|
104
|
+
return { touched, candidates: [], missing: [], dispatchOpen };
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const delivered = readDelivered(root, session);
|
|
108
|
+
if (delivered.length === 0) {
|
|
109
|
+
return { touched, candidates: [], missing: [], dispatchOpen };
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
let pathMatched = new Set<string>();
|
|
113
|
+
try {
|
|
114
|
+
const router = loadRouter(root);
|
|
115
|
+
// Empty prompt, so only PATH triggers can fire. A turn's file writes
|
|
116
|
+
// are not a restatement of the user's request and must not re-fire
|
|
117
|
+
// keyword rules — the same reasoning the injector applies on its own
|
|
118
|
+
// tool slot.
|
|
119
|
+
pathMatched = new Set(matchTierRules(router, '', touched, null).map((m) => m.id));
|
|
120
|
+
} catch {
|
|
121
|
+
return { touched, candidates: [], missing: [], dispatchOpen };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const candidates = delivered
|
|
125
|
+
.filter((r) => pathMatched.has(r.rule) && may_refuse_on(r.cls))
|
|
126
|
+
.map((r) => r.rule);
|
|
127
|
+
|
|
128
|
+
const discharged = new Set(readDischarged(root, session).map((r) => r.rule));
|
|
129
|
+
const missing = candidates.filter((id) => !discharged.has(id));
|
|
130
|
+
return { touched, candidates: [...new Set(candidates)], missing: [...new Set(missing)] , dispatchOpen };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Whether this reading should force a continuation, were anything armed.
|
|
135
|
+
*
|
|
136
|
+
* An UNCHANGED missing set on a second reading means the previous nudge moved
|
|
137
|
+
* nothing, so nudging again would loop rather than progress. The obligations
|
|
138
|
+
* stay OPEN — that is the whole point, and it is the side of the source set's
|
|
139
|
+
* self-contradiction this ships. A budget running out is a fact about the
|
|
140
|
+
* budget; letting it write a policy verdict is how an unmet obligation becomes
|
|
141
|
+
* a satisfied one with nobody deciding, and an exhausted budget is exactly the
|
|
142
|
+
* moment the obligation is least likely to have been met.
|
|
143
|
+
*
|
|
144
|
+
* There is therefore no `waived` state anywhere in this file, and no code path
|
|
145
|
+
* that writes one.
|
|
146
|
+
*/
|
|
147
|
+
export function shouldContinue(attempt: number): boolean {
|
|
148
|
+
return attempt <= 1;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* The session and root this reading is about, resolved the way the WRITER does.
|
|
153
|
+
*
|
|
154
|
+
* THE DEFECT THIS EXISTS TO CLOSE. This hook used to read
|
|
155
|
+
* `CLAUDE_CODE_SESSION_ID` out of the process environment and return allow when
|
|
156
|
+
* it was empty. The dispatcher sets no such variable — it hands each concern
|
|
157
|
+
* the envelope on stdin and `AGENT_CONFIG_PACKAGE_ROOT` in the environment,
|
|
158
|
+
* nothing else — so on every dispatched stop event the reader looked for a
|
|
159
|
+
* ledger under a key the writer never used. Measured 2026-09-29 on this
|
|
160
|
+
* machine's own ledgers: 187 delivered rows, 0 shadow rows, across 8 sessions.
|
|
161
|
+
*
|
|
162
|
+
* WHY THE ORDER IS ENVELOPE-THEN-ENVIRONMENT AND NOT THE REVERSE. The envelope
|
|
163
|
+
* id is the key `rule_inject_hook.ts` wrote the delivered rows under, so it is
|
|
164
|
+
* not merely the better source — it is the ONLY one that can find them. The
|
|
165
|
+
* environment fallback survives for a raw invocation that carries no envelope
|
|
166
|
+
* at all (a maintainer piping nothing, a host shim that skips the dispatcher),
|
|
167
|
+
* which is a case where guessing wrong costs a missing reading rather than a
|
|
168
|
+
* wrong one.
|
|
169
|
+
*
|
|
170
|
+
* THE ROOT IS PART OF THE SAME JOIN, not a second change riding along. A ledger
|
|
171
|
+
* is addressed by root AND session; reading the session from the envelope while
|
|
172
|
+
* taking the root from `process.cwd()` would leave the pair half-joined, and the
|
|
173
|
+
* two disagree exactly on the hosts whose shim does not chdir. `cwd` stays the
|
|
174
|
+
* fallback because that is what the dispatcher sets it to.
|
|
175
|
+
*
|
|
176
|
+
* Both spellings of each key are accepted because the injector accepts both.
|
|
177
|
+
*/
|
|
178
|
+
export function resolveSettleContext(
|
|
179
|
+
envelope: Record<string, unknown>,
|
|
180
|
+
payload: Record<string, unknown>,
|
|
181
|
+
env: Record<string, string | undefined>,
|
|
182
|
+
): { root: string; session: string } {
|
|
183
|
+
const str = (...values: unknown[]): string => {
|
|
184
|
+
for (const v of values) {
|
|
185
|
+
if (typeof v === 'string' && v.trim() !== '') return v.trim();
|
|
186
|
+
}
|
|
187
|
+
return '';
|
|
188
|
+
};
|
|
189
|
+
return {
|
|
190
|
+
// `workspaceRoot` is the INJECTOR's function, not a copy of it. It reads
|
|
191
|
+
// `workspace` / `cwd` / `project_dir`; this file used to read
|
|
192
|
+
// `workspace_root` / `workspace` / `cwd`, so the two key sets overlapped
|
|
193
|
+
// without matching and the pair was joined on the session only. It
|
|
194
|
+
// happened to agree on both real envelope shapes — the dispatcher sets
|
|
195
|
+
// `workspace_root` and chdirs concerns to it, a native wiring passes
|
|
196
|
+
// `cwd` — which made the asymmetry a property of today's envelopes
|
|
197
|
+
// rather than of the code. `workspace_root` is appended ahead of the
|
|
198
|
+
// shared resolver because the dispatcher is the only producer that sets
|
|
199
|
+
// it and nothing else reads it.
|
|
200
|
+
root:
|
|
201
|
+
str(envelope['workspace_root'])
|
|
202
|
+
|| writerWorkspaceRoot(envelope as Parameters<typeof writerWorkspaceRoot>[0]),
|
|
203
|
+
session: str(
|
|
204
|
+
envelope['session_id'],
|
|
205
|
+
envelope['sessionId'],
|
|
206
|
+
payload['session_id'],
|
|
207
|
+
payload['sessionId'],
|
|
208
|
+
// The one pre-existing source, kept as the last resort and NOT
|
|
209
|
+
// joined by siblings: adding a name the writer never keys on
|
|
210
|
+
// would address a ledger that cannot exist.
|
|
211
|
+
env['CLAUDE_CODE_SESSION_ID'],
|
|
212
|
+
),
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* The session id the WRITER would have used, for the ledger nobody reads.
|
|
218
|
+
*
|
|
219
|
+
* `rule_inject_hook.ts` defaults an unnamed session to the literal `unknown`
|
|
220
|
+
* and writes delivered rows there; this reader used to return `''` and allow, so
|
|
221
|
+
* that population was invisible to every reading of the bar. Reported rather
|
|
222
|
+
* than silently joined: a shared `unknown` bucket aggregates unrelated sessions,
|
|
223
|
+
* so reading it as one session's turn would be worse than not reading it. The
|
|
224
|
+
* constant is exported so a future census can count what is sitting there.
|
|
225
|
+
*/
|
|
226
|
+
export const WRITER_UNNAMED_SESSION = 'unknown';
|
|
227
|
+
|
|
228
|
+
/** The envelope on stdin, or an empty object when there is none to read. */
|
|
229
|
+
function readEnvelope(): { envelope: Record<string, unknown>; payload: Record<string, unknown> } {
|
|
230
|
+
let envelope: Record<string, unknown> = {};
|
|
231
|
+
try {
|
|
232
|
+
const raw = readHookStdin();
|
|
233
|
+
const parsed: unknown = raw.trim() === '' ? {} : JSON.parse(raw);
|
|
234
|
+
if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
|
|
235
|
+
envelope = parsed as Record<string, unknown>;
|
|
236
|
+
}
|
|
237
|
+
} catch {
|
|
238
|
+
// A malformed envelope is not a reason to refuse, and this concern
|
|
239
|
+
// refuses nothing anyway. It is a reason to read nothing from it.
|
|
240
|
+
}
|
|
241
|
+
const nested = envelope['payload'];
|
|
242
|
+
const payload =
|
|
243
|
+
typeof nested === 'object' && nested !== null && !Array.isArray(nested)
|
|
244
|
+
? (nested as Record<string, unknown>)
|
|
245
|
+
: envelope;
|
|
246
|
+
return { envelope, payload };
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* The resolver as it stood BEFORE the join fix, kept reachable for one test.
|
|
251
|
+
*
|
|
252
|
+
* A reproduction that cannot run the old code is not a reproduction — it is an
|
|
253
|
+
* assertion about the new function's behavior on inputs nobody sends, and
|
|
254
|
+
* `tests/hooks/obligation_settle.test.ts` carried exactly that until an
|
|
255
|
+
* independent review named it. This function is dead on every production path
|
|
256
|
+
* (nothing but the fixture calls it) and exists so the defect stays executable:
|
|
257
|
+
* environment-only resolution, allow when empty, root from the cwd.
|
|
258
|
+
*/
|
|
259
|
+
export function resolveSettleContextPreFix(
|
|
260
|
+
_envelope: Record<string, unknown>,
|
|
261
|
+
_payload: Record<string, unknown>,
|
|
262
|
+
env: Record<string, string | undefined>,
|
|
263
|
+
): { root: string; session: string } {
|
|
264
|
+
// Same arity as the live resolver ON PURPOSE. A narrower signature would let
|
|
265
|
+
// the fixture pass the envelope in as `env`, where the lookup misses for the
|
|
266
|
+
// wrong reason and the test goes green without exercising the defect.
|
|
267
|
+
return { root: process.cwd(), session: (env['CLAUDE_CODE_SESSION_ID'] ?? '').trim() };
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Which context resolver this reading uses — the seam the pre-fix fixture needs.
|
|
272
|
+
*
|
|
273
|
+
* It is NOT a parameter of `main()`, and that is a contract rather than a
|
|
274
|
+
* preference: `concern_main_signature` requires every concern's `main()` to take
|
|
275
|
+
* argv first or nothing, because the dispatcher calls `main(argv)` — so a
|
|
276
|
+
* resolver in first position would receive an argv array at runtime and resolve
|
|
277
|
+
* a session from it. Caught by that test, which is the reason this indirection
|
|
278
|
+
* exists instead of the obvious default parameter.
|
|
279
|
+
*/
|
|
280
|
+
export type SettleResolver = (
|
|
281
|
+
envelope: Record<string, unknown>,
|
|
282
|
+
payload: Record<string, unknown>,
|
|
283
|
+
env: Record<string, string | undefined>,
|
|
284
|
+
) => { root: string; session: string };
|
|
285
|
+
|
|
286
|
+
export function runSettle(resolve: SettleResolver = resolveSettleContext): number {
|
|
287
|
+
const { envelope, payload } = readEnvelope();
|
|
288
|
+
const { root, session } = resolve(envelope, payload, process.env);
|
|
289
|
+
if (session === '') return EXIT_ALLOW;
|
|
290
|
+
|
|
291
|
+
let verdict: SettleVerdict;
|
|
292
|
+
try {
|
|
293
|
+
verdict = computeVerdict(root, session);
|
|
294
|
+
} catch {
|
|
295
|
+
// A detector that cannot compute has nothing to say. It never has a
|
|
296
|
+
// refusal to withhold, so there is no safe-vs-unsafe choice here.
|
|
297
|
+
return EXIT_ALLOW;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Silent while a dispatch is open: the files may be a subagent's, still
|
|
301
|
+
// being written, and a shadow row claiming otherwise would poison the very
|
|
302
|
+
// corpus the arming decision is measured against.
|
|
303
|
+
if (verdict.dispatchOpen) return EXIT_ALLOW;
|
|
304
|
+
if (verdict.missing.length === 0) return EXIT_ALLOW;
|
|
305
|
+
|
|
306
|
+
const attempt = appendShadow(root, session, verdict.missing, stamp());
|
|
307
|
+
if (attempt === 0) return EXIT_ALLOW;
|
|
308
|
+
|
|
309
|
+
// ONE line for the whole missing set, never one per obligation — the same
|
|
310
|
+
// aggregation the row itself uses, for the same reason.
|
|
311
|
+
process.stderr.write(
|
|
312
|
+
`obligation-settle (shadow, refusing nothing): ${verdict.missing.length} `
|
|
313
|
+
+ `obligation(s) with no recorded discharge after writing `
|
|
314
|
+
+ `${verdict.touched.length} file(s): ${verdict.missing.join(', ')}`
|
|
315
|
+
+ `${shouldContinue(attempt) ? '' : ' — unchanged since the last reading; still open'}\n`,
|
|
316
|
+
);
|
|
317
|
+
return EXIT_ALLOW;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/** The dispatcher entry point. Argv-shaped, per `concern_main_signature`. */
|
|
321
|
+
export function main(_argv: readonly string[] = process.argv.slice(2)): number {
|
|
322
|
+
return runSettle();
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Bundle-safety: never auto-run when inlined into an esbuild bundle.
|
|
326
|
+
if (process.argv[1] !== undefined && path.basename(process.argv[1]).startsWith('obligation_settle')) {
|
|
327
|
+
process.exit(main());
|
|
328
|
+
}
|
|
@@ -16,10 +16,31 @@
|
|
|
16
16
|
*
|
|
17
17
|
* WHAT IT SEES, honestly. `_lib/structured_ask.ts` carries no observed
|
|
18
18
|
* per-host tool, so this guard matches on a name SHAPE and is filtered by the
|
|
19
|
-
* manifest's per-concern `tools:` key to the same candidate names.
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
19
|
+
* manifest's per-concern `tools:` key to the same candidate names. No host's
|
|
20
|
+
* delivered surface has been OBSERVED in this tree carrying a question-picker
|
|
21
|
+
* tool, which is why `STRUCTURED_ASK_SHAPES` is empty and no per-host shape row
|
|
22
|
+
* exists — the same sentence `_lib/structured_ask.ts` already uses about itself.
|
|
23
|
+
*
|
|
24
|
+
* That is NARROWER than the claim this header used to make. The earlier
|
|
25
|
+
* sentence asserted that on every host measured today the concern therefore
|
|
26
|
+
* matches nothing at all, and the two are different claims with only the first
|
|
27
|
+
* supported. The old wording is described here rather than quoted, because
|
|
28
|
+
* 1.1's drift check is a grep and a grep cannot tell a refuted quotation from
|
|
29
|
+
* a live assertion. The measurement base is ONE row:
|
|
30
|
+
* `_lib/host_capability.ts`'s registry records `structured_ask: false` for
|
|
31
|
+
* `claude` alone, observed-absent on Claude Code 2.1.263 on 2026-09-07, and the
|
|
32
|
+
* other eight hosts in `docs/enforcement-by-host.md` have no row at all — never
|
|
33
|
+
* looked, not measured. "Every host measured" read against that table therefore
|
|
34
|
+
* describes one host, and a present-tense claim about what the concern matches
|
|
35
|
+
* turns one dated single-version reading into a standing property, which the registry's own
|
|
36
|
+
* comment refuses in the same breath: the observation "is not a claim that the
|
|
37
|
+
* vendor ships no such tool anywhere, and a later session observing one writes
|
|
38
|
+
* the `true` row over it".
|
|
39
|
+
*
|
|
40
|
+
* So the honest statement is about what has been looked at, not about what
|
|
41
|
+
* fires. The concern exists so the first host whose delivered surface carries a
|
|
42
|
+
* picker meets the rule already in force, not because a violation has been
|
|
43
|
+
* observed.
|
|
23
44
|
*
|
|
24
45
|
* ENFORCEMENT REACH, also honestly. `fail_closed: false` and the exit-1 deny
|
|
25
46
|
* are only a deny where the host both binds `pre_tool_use` AND honours the
|
|
@@ -72,8 +72,7 @@ import { buildOrchestrationLine, type RecordInput } from '../_lib/orchestration_
|
|
|
72
72
|
import { DEFAULT_DIR } from '../orchestration_record.js';
|
|
73
73
|
import { is_replay_mode } from './state_io.js';
|
|
74
74
|
import { readHookStdin } from './hook_stdin.js';
|
|
75
|
-
|
|
76
|
-
const EXIT_ALLOW = 0;
|
|
75
|
+
import { EXIT_ALLOW } from './exit_codes.js';
|
|
77
76
|
|
|
78
77
|
type JsonValue = string | number | boolean | null | JsonValue[] | { [k: string]: JsonValue };
|
|
79
78
|
type JsonObject = { [k: string]: JsonValue };
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
type PermissionDecision,
|
|
21
21
|
type PermissionEmission,
|
|
22
22
|
} from "./host_semantics.js";
|
|
23
|
+
import { EXIT_ALLOW, EXIT_BLOCK } from './exit_codes.js';
|
|
23
24
|
|
|
24
25
|
type JsonValue = string | number | boolean | null | JsonValue[] | { [k: string]: JsonValue };
|
|
25
26
|
type JsonObject = { [k: string]: JsonValue };
|
|
@@ -29,8 +30,6 @@ function _isObject(v: unknown): v is JsonObject {
|
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
/** Mirrors `dispatch_hook.EXIT_ALLOW` / `EXIT_BLOCK`; imported would be a cycle. */
|
|
32
|
-
const EXIT_ALLOW = 0;
|
|
33
|
-
const EXIT_BLOCK = 1;
|
|
34
33
|
|
|
35
34
|
/** The host's `tool_name`, or `""` when the event carries none. */
|
|
36
35
|
export function _payload_tool_name(envelope: JsonObject): string {
|
|
@@ -54,9 +54,7 @@ import path from "node:path";
|
|
|
54
54
|
import { execFileSync } from "node:child_process";
|
|
55
55
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
56
56
|
import { readHookStdin } from "./hook_stdin.js";
|
|
57
|
-
|
|
58
|
-
const EXIT_ALLOW = 0;
|
|
59
|
-
const EXIT_WARN = 2;
|
|
57
|
+
import { EXIT_ALLOW, EXIT_WARN } from './exit_codes.js';
|
|
60
58
|
|
|
61
59
|
type JsonValue = string | number | boolean | null | JsonValue[] | { [k: string]: JsonValue };
|
|
62
60
|
type JsonObject = { [k: string]: JsonValue };
|
|
@@ -36,6 +36,7 @@ import { spawnSync } from "node:child_process";
|
|
|
36
36
|
import fs from "node:fs";
|
|
37
37
|
import path from "node:path";
|
|
38
38
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
39
|
+
import { EXIT_USAGE } from './exit_codes.js';
|
|
39
40
|
|
|
40
41
|
// src/scripts/hooks/replay_hook.ts → parents[3] is the repo root.
|
|
41
42
|
const REPO_ROOT = path.resolve(
|
|
@@ -175,7 +176,7 @@ function _parse_args(argv: string[]): ReplayArgs {
|
|
|
175
176
|
process.stderr.write(
|
|
176
177
|
`replay_hook: the following arguments are required: ${missing.join(", ")}\n`,
|
|
177
178
|
);
|
|
178
|
-
process.exit(
|
|
179
|
+
process.exit(EXIT_USAGE);
|
|
179
180
|
}
|
|
180
181
|
return args;
|
|
181
182
|
}
|
|
@@ -69,12 +69,11 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
|
69
69
|
import { unwrap, type JsonObject, type JsonValue } from './envelope.js';
|
|
70
70
|
import { readHookStdin } from './hook_stdin.js';
|
|
71
71
|
import { atomic_write_json } from './state_io.js';
|
|
72
|
+
import { EXIT_ALLOW, EXIT_WARN } from './exit_codes.js';
|
|
72
73
|
|
|
73
|
-
const EXIT_ALLOW = 0;
|
|
74
74
|
// Severity is taken from the EXIT CODE, not from the `decision` field — see
|
|
75
75
|
// the file header for why this never blocks on `claude`. This concern never
|
|
76
76
|
// returns exit 1 on any path.
|
|
77
|
-
const EXIT_WARN = 2;
|
|
78
77
|
|
|
79
78
|
/**
|
|
80
79
|
* Committed exemption list — deliberately duplicated from
|
|
@@ -49,8 +49,7 @@ import { deriveSessionKey, totalNonDocMutatedLinesWithMeasure } from './end_revi
|
|
|
49
49
|
import { unwrap, type JsonObject, type JsonValue } from './envelope.js';
|
|
50
50
|
import { readHookStdin } from './hook_stdin.js';
|
|
51
51
|
import { atomic_write_json } from './state_io.js';
|
|
52
|
-
|
|
53
|
-
const EXIT_OK = 0;
|
|
52
|
+
import { EXIT_ALLOW as EXIT_OK } from './exit_codes.js';
|
|
54
53
|
|
|
55
54
|
export function buildBaseline(workspaceRoot: string, now: Date = new Date()): ReviewBaseline {
|
|
56
55
|
const measured = totalNonDocMutatedLinesWithMeasure(workspaceRoot);
|
|
@@ -63,10 +63,9 @@ import {
|
|
|
63
63
|
} from "./block_no_verify.js";
|
|
64
64
|
import { readHookStdin } from "./hook_stdin.js";
|
|
65
65
|
import { detectRtkCached } from "../../install/rtkDetection.js";
|
|
66
|
+
import { EXIT_ALLOW, EXIT_WARN } from './exit_codes.js';
|
|
66
67
|
|
|
67
68
|
const SETTINGS_FILE = ".agent-settings.yml";
|
|
68
|
-
const EXIT_ALLOW = 0;
|
|
69
|
-
const EXIT_WARN = 2;
|
|
70
69
|
|
|
71
70
|
type JsonValue = string | number | boolean | null | JsonValue[] | { [k: string]: JsonValue };
|
|
72
71
|
type JsonObject = { [k: string]: JsonValue };
|
|
@@ -11,7 +11,14 @@
|
|
|
11
11
|
* the 36.2 %-against-48 % run at `docs/CLAIMS.md:188-189`. Whatever that
|
|
12
12
|
* instrument's flaws — and ADR-202 closed it — it points one way.
|
|
13
13
|
*
|
|
14
|
-
* SHIPPED ON FOR CLAUDE CODE SINCE ADR-
|
|
14
|
+
* SHIPPED ON FOR CLAUDE CODE SINCE ADR-267 — the delivery-default record, and
|
|
15
|
+
* the citation is corrected here (2026-09-13) from ADR-265, which decides
|
|
16
|
+
* something else entirely: whether the iron-law reserve is activated, answered
|
|
17
|
+
* no, with the verifier kept inside the change. Nothing in it ships a
|
|
18
|
+
* projection mode. ADR-267 `delivery-default-for-claude-code` is the record
|
|
19
|
+
* that turns this concern on for this host, and it is the one whose
|
|
20
|
+
* `review_trigger` fires if a rule stops arriving. Previously corrected
|
|
21
|
+
* 2026-09-08 (R2 finding
|
|
15
22
|
* 4), because this paragraph read "DEFAULT OFF, AND OFF MEANS ZERO BYTES …
|
|
16
23
|
* under every shipped default it emits nothing … there is no measured emission
|
|
17
24
|
* to register yet" and all four clauses became false in the same change that
|
|
@@ -94,6 +101,13 @@ import {
|
|
|
94
101
|
normalizeLeanProjectionMode,
|
|
95
102
|
resolveLeanProjectionHosts,
|
|
96
103
|
} from '../_lib/lean_projection_mode.js';
|
|
104
|
+
import { enforcement_class_from_frontmatter } from '../_lib/obligation_frequency.js';
|
|
105
|
+
import {
|
|
106
|
+
appendDelivered,
|
|
107
|
+
stamp,
|
|
108
|
+
type DeliveredRow,
|
|
109
|
+
type WriterInput,
|
|
110
|
+
} from '../_lib/obligations.js';
|
|
97
111
|
import {
|
|
98
112
|
loadRuleBody,
|
|
99
113
|
loadRouter,
|
|
@@ -101,9 +115,7 @@ import {
|
|
|
101
115
|
selectForInjection,
|
|
102
116
|
} from '../_lib/rule_injection.js';
|
|
103
117
|
import { readHookStdin } from './hook_stdin.js';
|
|
104
|
-
|
|
105
|
-
const EXIT_ALLOW = 0;
|
|
106
|
-
const EXIT_WARN = 2;
|
|
118
|
+
import { EXIT_ALLOW, EXIT_WARN } from './exit_codes.js';
|
|
107
119
|
|
|
108
120
|
/**
|
|
109
121
|
* Per-prompt injection ceiling, in UTF-8 BYTES.
|
|
@@ -237,6 +249,44 @@ export interface Injection {
|
|
|
237
249
|
body: string;
|
|
238
250
|
}
|
|
239
251
|
|
|
252
|
+
/**
|
|
253
|
+
* Record what this fire delivered, so something can later ask whether the turn
|
|
254
|
+
* discharged it.
|
|
255
|
+
*
|
|
256
|
+
* The write happens HERE and not in a later slot because this is the only
|
|
257
|
+
* place that knows the answer. By the time a turn ends, the selection that
|
|
258
|
+
* produced these ids is gone — the router would have to be re-run against a
|
|
259
|
+
* prompt nobody kept, which is a different computation that could disagree.
|
|
260
|
+
*
|
|
261
|
+
* EMITTER RECORD, NEVER A COMPLIANCE ONE. A row says a body was emitted into
|
|
262
|
+
* this slot. It does not say the model read it, and the ledger's own header
|
|
263
|
+
* carries the council lock that forbids reading it that way.
|
|
264
|
+
*
|
|
265
|
+
* Best-effort by construction: every failure path inside `appendDelivered`
|
|
266
|
+
* returns rather than throws, and this wrapper adds one more guard so a
|
|
267
|
+
* ledger problem can never turn a successful injection into a failed hook.
|
|
268
|
+
* A missed reading is cheaper than a refused turn, and this concern has no
|
|
269
|
+
* refusal to offer anyway.
|
|
270
|
+
*/
|
|
271
|
+
export function recordDelivered(root: string, session: string, ruleIds: string[]): number {
|
|
272
|
+
try {
|
|
273
|
+
const now = stamp();
|
|
274
|
+
const rows: WriterInput<DeliveredRow>[] = ruleIds.map((id) => {
|
|
275
|
+
const body = loadRuleBody(root, id);
|
|
276
|
+
return {
|
|
277
|
+
rule: id,
|
|
278
|
+
// A rule with no projected body declares nothing this can read,
|
|
279
|
+
// which is `none` — the same answer as a body declaring none.
|
|
280
|
+
cls: body === null ? 'none' : enforcement_class_from_frontmatter(body),
|
|
281
|
+
at: now,
|
|
282
|
+
};
|
|
283
|
+
});
|
|
284
|
+
return appendDelivered(root, session, rows);
|
|
285
|
+
} catch {
|
|
286
|
+
return 0;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
240
290
|
/**
|
|
241
291
|
* Build the injection for one event, or `null` for silence.
|
|
242
292
|
*
|
|
@@ -371,6 +421,7 @@ export function main(argv: readonly string[] = process.argv.slice(2)): number {
|
|
|
371
421
|
|
|
372
422
|
for (const id of injection.rules) seen.add(id);
|
|
373
423
|
writeSeen(root, session, seen);
|
|
424
|
+
recordDelivered(root, session, injection.rules);
|
|
374
425
|
|
|
375
426
|
process.stdout.write(
|
|
376
427
|
`${JSON.stringify({
|