@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,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The long-run continuity record — `road-to-adversarial-verification-and-long-runs`
|
|
3
|
+
* 9.1.
|
|
4
|
+
*
|
|
5
|
+
* `continuity_writer` already writes a session record. This is the MISSION
|
|
6
|
+
* record: the state a twelve-hour run must survive a restart with, and the two
|
|
7
|
+
* rules about reading it back — never re-ask a closed question, and never resume
|
|
8
|
+
* on an authority snapshot that has since been revoked.
|
|
9
|
+
*
|
|
10
|
+
* **Risk 5 is the reason `restore` is not just a deserialise.** The record
|
|
11
|
+
* carries the grant including `expires` and `revoked_by`. A restore that trusted
|
|
12
|
+
* the snapshot would resume with authority the owner withdrew after it was
|
|
13
|
+
* written — so the snapshot is revalidated against the LEDGER, which is the
|
|
14
|
+
* surface a revocation actually writes to. A record and a ledger that disagree
|
|
15
|
+
* are resolved in favour of the ledger, always.
|
|
16
|
+
*
|
|
17
|
+
* Pure. Reading the ledger and the forge belongs to the caller.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/** A decision the mission already settled. Re-asking one is the failure. */
|
|
21
|
+
export interface DecisionRef {
|
|
22
|
+
readonly id: string;
|
|
23
|
+
/** Where the reasoning lives, so a restore can read rather than redo it. */
|
|
24
|
+
readonly where: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** The authority the mission is running under. */
|
|
28
|
+
export interface AuthoritySnapshot {
|
|
29
|
+
readonly grant: string;
|
|
30
|
+
/** ISO instant, or `null` for a grant with no expiry. */
|
|
31
|
+
readonly expires: string | null;
|
|
32
|
+
/** Who revoked it, or `null` while it stands. */
|
|
33
|
+
readonly revoked_by: string | null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface MissionRecord {
|
|
37
|
+
readonly mission_id: string;
|
|
38
|
+
readonly roadmap: string;
|
|
39
|
+
readonly phase: string;
|
|
40
|
+
readonly completed_steps: readonly string[];
|
|
41
|
+
readonly decisions: readonly DecisionRef[];
|
|
42
|
+
readonly authority: AuthoritySnapshot;
|
|
43
|
+
readonly target_branch: string;
|
|
44
|
+
readonly pr: number | null;
|
|
45
|
+
readonly head_sha: string;
|
|
46
|
+
/** The last CI verdict observed, and the head it was about. */
|
|
47
|
+
readonly last_ci: { readonly verdict: string; readonly head: string } | null;
|
|
48
|
+
readonly recovery_epoch: number;
|
|
49
|
+
readonly attempt_count: number;
|
|
50
|
+
readonly pending_reviews: readonly string[];
|
|
51
|
+
readonly owner_owned_residue: readonly string[];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Every field a record must carry. Absent means the record is not one. */
|
|
55
|
+
export const REQUIRED_FIELDS: readonly (keyof MissionRecord)[] = [
|
|
56
|
+
'mission_id',
|
|
57
|
+
'roadmap',
|
|
58
|
+
'phase',
|
|
59
|
+
'completed_steps',
|
|
60
|
+
'decisions',
|
|
61
|
+
'authority',
|
|
62
|
+
'target_branch',
|
|
63
|
+
'pr',
|
|
64
|
+
'head_sha',
|
|
65
|
+
'last_ci',
|
|
66
|
+
'recovery_epoch',
|
|
67
|
+
'attempt_count',
|
|
68
|
+
'pending_reviews',
|
|
69
|
+
'owner_owned_residue',
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
/** When the record is written. A side task is NOT one of these. */
|
|
73
|
+
export const WRITE_BOUNDARIES = [
|
|
74
|
+
'phase-boundary',
|
|
75
|
+
'stop',
|
|
76
|
+
'pre-compact',
|
|
77
|
+
'session-end',
|
|
78
|
+
] as const;
|
|
79
|
+
export type WriteBoundary = (typeof WRITE_BOUNDARIES)[number];
|
|
80
|
+
|
|
81
|
+
/** Field names missing from a candidate record. Empty means complete. */
|
|
82
|
+
export function missingFields(candidate: Partial<MissionRecord>): string[] {
|
|
83
|
+
return REQUIRED_FIELDS.filter((f) => candidate[f] === undefined).map(String);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** What the LEDGER says about a grant right now. `null` = no ledger entry. */
|
|
87
|
+
export interface LedgerState {
|
|
88
|
+
readonly grant: string;
|
|
89
|
+
readonly revoked_by: string | null;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* `grant-mismatch` covers both ways the two sides can fail to be about one
|
|
94
|
+
* grant: they name different ones, or the record names none at all — which
|
|
95
|
+
* identifies nothing for the ledger to agree with.
|
|
96
|
+
*/
|
|
97
|
+
export type RestoreState =
|
|
98
|
+
| 'resume'
|
|
99
|
+
| 'authority-withdrawn'
|
|
100
|
+
| 'authority-expired'
|
|
101
|
+
| 'grant-mismatch';
|
|
102
|
+
|
|
103
|
+
export interface RestoreVerdict {
|
|
104
|
+
readonly state: RestoreState;
|
|
105
|
+
readonly reason: string;
|
|
106
|
+
/** Questions this record already answers. A restore re-asks none of them. */
|
|
107
|
+
readonly closed: readonly string[];
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Decide whether a restored mission may continue.
|
|
112
|
+
*
|
|
113
|
+
* The LEDGER wins over the snapshot, in one direction only: it can revoke a
|
|
114
|
+
* grant the record still shows as live, and it cannot revive one the record
|
|
115
|
+
* shows as revoked. A ledger that could un-revoke would make the record the
|
|
116
|
+
* weaker of two authorities and the revocation advisory.
|
|
117
|
+
*
|
|
118
|
+
* **Identity comes before precedence.** Asking which of the two wins is only
|
|
119
|
+
* meaningful once they are about the same grant. A restore that read
|
|
120
|
+
* `revoked_by` from a ledger describing a DIFFERENT grant would be using the
|
|
121
|
+
* ledger as an oracle for a question it was never asked — a mission authorised
|
|
122
|
+
* under a narrow grant would resume on a later, broader grant's silence. So the
|
|
123
|
+
* identity check runs first and refuses in both directions, which leaves the
|
|
124
|
+
* one-way revoke precedence below exactly as it was.
|
|
125
|
+
*/
|
|
126
|
+
export function restore(
|
|
127
|
+
record: MissionRecord,
|
|
128
|
+
ledger: LedgerState | null,
|
|
129
|
+
now: Date,
|
|
130
|
+
): RestoreVerdict {
|
|
131
|
+
const closed = record.decisions.map((d) => d.id);
|
|
132
|
+
|
|
133
|
+
if (record.authority.grant.trim().length === 0) {
|
|
134
|
+
return {
|
|
135
|
+
state: 'grant-mismatch',
|
|
136
|
+
reason: 'the snapshot names no grant, so there is nothing for the ledger to agree with',
|
|
137
|
+
closed,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
if (ledger !== null && ledger.grant !== record.authority.grant) {
|
|
141
|
+
return {
|
|
142
|
+
state: 'grant-mismatch',
|
|
143
|
+
reason: `the snapshot runs under ${record.authority.grant} and the ledger describes ${ledger.grant}; the two are not about the same grant`,
|
|
144
|
+
closed,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
if (record.authority.revoked_by !== null) {
|
|
148
|
+
return {
|
|
149
|
+
state: 'authority-withdrawn',
|
|
150
|
+
reason: `the record's own snapshot is revoked by ${record.authority.revoked_by}`,
|
|
151
|
+
closed,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
if (ledger !== null && ledger.revoked_by !== null) {
|
|
155
|
+
return {
|
|
156
|
+
state: 'authority-withdrawn',
|
|
157
|
+
reason: `the ledger reports the grant revoked by ${ledger.revoked_by} after the snapshot was written`,
|
|
158
|
+
closed,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
if (record.authority.expires !== null) {
|
|
162
|
+
const at = Date.parse(record.authority.expires);
|
|
163
|
+
// An UNPARSEABLE expiry is treated as expired. A grant whose lifetime
|
|
164
|
+
// cannot be read is not a grant with no lifetime.
|
|
165
|
+
if (!Number.isFinite(at) || at <= now.getTime()) {
|
|
166
|
+
return {
|
|
167
|
+
state: 'authority-expired',
|
|
168
|
+
reason: `the grant's expiry (${record.authority.expires}) is not a future instant`,
|
|
169
|
+
closed,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return { state: 'resume', reason: 'the grant stands in both the record and the ledger', closed };
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Has this question already been settled by the mission?
|
|
178
|
+
*
|
|
179
|
+
* The whole point of the record: a restore that re-asks a closed question has
|
|
180
|
+
* spent the owner's attention on something the mission already decided, which is
|
|
181
|
+
* the loop this roadmap exists to end.
|
|
182
|
+
*/
|
|
183
|
+
export function alreadyAnswered(record: MissionRecord, questionId: string): boolean {
|
|
184
|
+
return record.decisions.some((d) => d.id === questionId);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** A side task does not clear the record. */
|
|
188
|
+
export function clearedBy(boundary: string): boolean {
|
|
189
|
+
return boundary === 'mission-complete';
|
|
190
|
+
}
|
|
@@ -80,6 +80,223 @@ export function is_frequency(v: unknown): v is Frequency {
|
|
|
80
80
|
return typeof v === 'string' && (FREQUENCIES as readonly string[]).includes(v);
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
// ------------------------------------------------- declared enforcement class
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The CLOSED set of classes a rule may DECLARE in `enforced_by:`.
|
|
87
|
+
*
|
|
88
|
+
* It lives here, beside `Frequency`, because these are the two halves of one
|
|
89
|
+
* question and splitting them across files is how a third taxonomy gets born.
|
|
90
|
+
* `enforced_by` says *what kind of thing carries this*; `obligation_frequency`
|
|
91
|
+
* says *how often it comes due*. Neither answers the other, and
|
|
92
|
+
* `check_enforcement_coverage.ts` joins both.
|
|
93
|
+
*
|
|
94
|
+
* DECLARED IS NOT RESOLVED, and conflating them is the live trap.
|
|
95
|
+
* This set is what an AUTHOR may write. It is deliberately NARROWER than
|
|
96
|
+
* `Resolution` in `check_enforcement_coverage.ts:79-88`, which is what the
|
|
97
|
+
* RESOLVER may conclude. Four of the resolver's values — `validator-local`,
|
|
98
|
+
* `unwired`, `missing`, and resolved-`observer` — are findings about whether
|
|
99
|
+
* the declared carrier is actually reachable. No author can declare them,
|
|
100
|
+
* because they are not facts about intent.
|
|
101
|
+
*
|
|
102
|
+
* The asymmetry is load-bearing rather than accidental. A rule declaring
|
|
103
|
+
* `hook:design-pass` whose hook is `fail_closed: false` resolves to `observer`
|
|
104
|
+
* (`check_enforcement_coverage.ts:421-422`). Measured 2026-09-13: 11 declared
|
|
105
|
+
* hooks become 1 effective hook and 10 effective observers exactly this way.
|
|
106
|
+
* A reader who takes the resolved table for the declared one concludes the
|
|
107
|
+
* frontmatter is lying when it is merely being resolved.
|
|
108
|
+
*
|
|
109
|
+
* `observer` AND `none` ARE FIRST-CLASS HERE, and always were.
|
|
110
|
+
* Recorded because a proposed five-value taxonomy had no slot for `observer`,
|
|
111
|
+
* and adopting it would have silently remapped a value the schema already
|
|
112
|
+
* accepts and the census already counts. The falsifier is the schema pattern
|
|
113
|
+
* itself (`src/scripts/schemas/rule.schema.json`, `enforced_by.items.pattern`),
|
|
114
|
+
* which admits `observer:<reason>` and bare `none`. There was no decision to
|
|
115
|
+
* take: the set below is a transcription of a constraint the tree enforces,
|
|
116
|
+
* not a new vocabulary competing with it.
|
|
117
|
+
*
|
|
118
|
+
* Keep this in sync with that pattern. It is the same set written twice — once
|
|
119
|
+
* where JSON Schema can check authored frontmatter, once where TypeScript can
|
|
120
|
+
* check code — and `tests/scripts/obligation_frequency.test.ts` pins the
|
|
121
|
+
* two together so the pair cannot drift silently.
|
|
122
|
+
*/
|
|
123
|
+
export type EnforcementClass =
|
|
124
|
+
| 'hook'
|
|
125
|
+
| 'validator'
|
|
126
|
+
| 'test'
|
|
127
|
+
| 'observer'
|
|
128
|
+
| 'instruction-only'
|
|
129
|
+
| 'none';
|
|
130
|
+
|
|
131
|
+
export const ENFORCEMENT_CLASSES: readonly EnforcementClass[] = [
|
|
132
|
+
'hook',
|
|
133
|
+
'validator',
|
|
134
|
+
'test',
|
|
135
|
+
'observer',
|
|
136
|
+
'instruction-only',
|
|
137
|
+
'none',
|
|
138
|
+
] as const;
|
|
139
|
+
|
|
140
|
+
export function is_enforcement_class(v: unknown): v is EnforcementClass {
|
|
141
|
+
return typeof v === 'string' && (ENFORCEMENT_CLASSES as readonly string[]).includes(v);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* The class a single declared `enforced_by:` entry belongs to.
|
|
146
|
+
*
|
|
147
|
+
* `null` for anything outside the closed set — never a guess and never a
|
|
148
|
+
* silent `none`, because `none` is itself a meaningful declaration ("recorded
|
|
149
|
+
* gap") and returning it for an unparseable string would convert a schema
|
|
150
|
+
* violation into a legitimate-looking record.
|
|
151
|
+
*
|
|
152
|
+
* Bare `none` is matched exactly; every other class carries a `:` payload the
|
|
153
|
+
* schema requires to be non-empty.
|
|
154
|
+
*/
|
|
155
|
+
export function enforcement_class_of(declared: string): EnforcementClass | null {
|
|
156
|
+
const trimmed = declared.trim();
|
|
157
|
+
if (trimmed === 'none') return 'none';
|
|
158
|
+
const colon = trimmed.indexOf(':');
|
|
159
|
+
if (colon <= 0) return null;
|
|
160
|
+
const head = trimmed.slice(0, colon);
|
|
161
|
+
if (!is_enforcement_class(head) || head === 'none') return null;
|
|
162
|
+
// A prefix with an empty payload is a schema violation, not a declaration.
|
|
163
|
+
if (trimmed.slice(colon + 1).trim() === '') return null;
|
|
164
|
+
return head;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* The class for a whole rule's `enforced_by:` list.
|
|
169
|
+
*
|
|
170
|
+
* A rule may declare several carriers; the ledger row carries ONE class, so a
|
|
171
|
+
* choice is forced. It takes the STRONGEST by {@link ENFORCEMENT_CLASSES}
|
|
172
|
+
* order, which is the same direction `check_enforcement_coverage.ts`'s `RANK`
|
|
173
|
+
* runs, so the two never disagree about which of two declarations dominates.
|
|
174
|
+
*
|
|
175
|
+
* An empty list — a rule declaring nothing at all — is `none`. That is the
|
|
176
|
+
* honest reading: the roadmap step requiring this says the row carries `none`
|
|
177
|
+
* when the rule declares none, and a rule with no declaration has made no
|
|
178
|
+
* claim this could contradict.
|
|
179
|
+
*/
|
|
180
|
+
/**
|
|
181
|
+
* Classes whose discharge a machine could, in principle, observe.
|
|
182
|
+
*
|
|
183
|
+
* The discriminator is not severity — it is whether a mechanical discharge
|
|
184
|
+
* EXISTS to look for. `hook`, `validator` and `test` name a carrier that runs
|
|
185
|
+
* and leaves a trace. `observer`, `instruction-only` and `none` name,
|
|
186
|
+
* respectively, an instrument that cannot block, an honestly model-carried
|
|
187
|
+
* obligation, and no carrier at all — none of the three produces an artefact a
|
|
188
|
+
* detector could read, so a detector refusing on one would be demanding
|
|
189
|
+
* evidence nobody can produce.
|
|
190
|
+
*
|
|
191
|
+
* Measured 2026-09-13 over the frozen routing corpus: 69 of 97 delivered rules
|
|
192
|
+
* are class `none`. A detector without this filter would fire on the large
|
|
193
|
+
* majority of every turn, which is the "one false block and the operator
|
|
194
|
+
* disables the carrier for good" failure the risk register ranks first.
|
|
195
|
+
*
|
|
196
|
+
* The source set's proposed taxonomy also named a `judge` class that never
|
|
197
|
+
* refuses. It has no representation here because it is not in the declared
|
|
198
|
+
* vocabulary the schema admits, and adding a value to make a sentence
|
|
199
|
+
* transcribe literally would be inventing the second taxonomy this work exists
|
|
200
|
+
* to avoid. Its INTENT — a class whose discharge is a human judgement and so
|
|
201
|
+
* must never be refused on — is carried by `observer` and `instruction-only`,
|
|
202
|
+
* both excluded below.
|
|
203
|
+
*/
|
|
204
|
+
export const REFUSABLE_CLASSES: ReadonlySet<EnforcementClass> = new Set<EnforcementClass>([
|
|
205
|
+
'hook',
|
|
206
|
+
'validator',
|
|
207
|
+
'test',
|
|
208
|
+
]);
|
|
209
|
+
|
|
210
|
+
/** Whether a detector may ever refuse on this class. */
|
|
211
|
+
export function may_refuse_on(cls: EnforcementClass): boolean {
|
|
212
|
+
return REFUSABLE_CLASSES.has(cls);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* The class declared by a rule's frontmatter, read straight off the body text.
|
|
217
|
+
*
|
|
218
|
+
* Lives here rather than in the ledger that calls it, so every piece of
|
|
219
|
+
* reasoning about the class vocabulary sits in one module — the roadmap's
|
|
220
|
+
* second-ranked risk is this set drifting from the census that ratchets it,
|
|
221
|
+
* and two readers in two files is the first step of that drift.
|
|
222
|
+
*
|
|
223
|
+
* Deliberately NOT a general YAML parser and deliberately not the census's
|
|
224
|
+
* `read_frontmatter`: this runs inside a hook on the prompt path, where the
|
|
225
|
+
* cost of importing the coverage module's whole wiring corpus is paid on every
|
|
226
|
+
* fire, and the only key it needs is one list. The accepted shapes are exactly
|
|
227
|
+
* the two the rule schema permits — inline `enforced_by: [a, b]` and a block
|
|
228
|
+
* of `- ` items.
|
|
229
|
+
*
|
|
230
|
+
* A rule that declares nothing is `none`, which is the honest reading: it has
|
|
231
|
+
* made no claim, so there is none to contradict.
|
|
232
|
+
*/
|
|
233
|
+
export function enforcement_class_from_frontmatter(text: string): EnforcementClass {
|
|
234
|
+
if (!text.startsWith('---\n')) return 'none';
|
|
235
|
+
const end = text.indexOf('\n---\n', 4);
|
|
236
|
+
if (end === -1) return 'none';
|
|
237
|
+
const lines = text.slice(4, end).split('\n');
|
|
238
|
+
|
|
239
|
+
const entries: string[] = [];
|
|
240
|
+
let collecting = false;
|
|
241
|
+
for (const line of lines) {
|
|
242
|
+
if (collecting) {
|
|
243
|
+
const item = /^\s+-\s*(.+?)\s*$/.exec(line);
|
|
244
|
+
if (item !== null) {
|
|
245
|
+
entries.push(unquote(item[1] as string));
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
// Any non-item line ends the block. Checked before anything else so
|
|
249
|
+
// a following key can never be read as a carrier declaration.
|
|
250
|
+
if (/^\S/.test(line)) collecting = false;
|
|
251
|
+
if (!collecting && /^\s*$/.test(line)) continue;
|
|
252
|
+
if (!collecting) break;
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
const m = /^enforced_by:\s*(.*)$/.exec(line);
|
|
256
|
+
if (m === null) continue;
|
|
257
|
+
const rest = (m[1] ?? '').trim();
|
|
258
|
+
if (rest === '') {
|
|
259
|
+
collecting = true;
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
const inline = /^\[(.*)\]$/.exec(rest);
|
|
263
|
+
if (inline !== null) {
|
|
264
|
+
for (const part of (inline[1] as string).split(',')) {
|
|
265
|
+
const v = unquote(part.trim());
|
|
266
|
+
if (v !== '') entries.push(v);
|
|
267
|
+
}
|
|
268
|
+
} else {
|
|
269
|
+
entries.push(unquote(rest));
|
|
270
|
+
}
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
return enforcement_class_for(entries);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/** Strip one layer of matching quotes, which the schema permits on any entry. */
|
|
277
|
+
function unquote(raw: string): string {
|
|
278
|
+
const s = raw.trim();
|
|
279
|
+
if (s.length >= 2 && ((s[0] === '"' && s.endsWith('"')) || (s[0] === "'" && s.endsWith("'")))) {
|
|
280
|
+
return s.slice(1, -1);
|
|
281
|
+
}
|
|
282
|
+
return s;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export function enforcement_class_for(declared: readonly string[]): EnforcementClass {
|
|
286
|
+
let best: EnforcementClass = 'none';
|
|
287
|
+
let bestRank = ENFORCEMENT_CLASSES.length;
|
|
288
|
+
for (const entry of declared) {
|
|
289
|
+
const cls = enforcement_class_of(entry);
|
|
290
|
+
if (cls === null) continue;
|
|
291
|
+
const rank = ENFORCEMENT_CLASSES.indexOf(cls);
|
|
292
|
+
if (rank < bestRank) {
|
|
293
|
+
bestRank = rank;
|
|
294
|
+
best = cls;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return best;
|
|
298
|
+
}
|
|
299
|
+
|
|
83
300
|
export type Root = 'lifecycle' | 'tool-call' | 'repository' | 'external-event' | 'none';
|
|
84
301
|
|
|
85
302
|
const ROOT_OF: Record<Frequency, Root> = {
|