@miller-tech/uap 1.222.0 → 2.0.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.
Files changed (234) hide show
  1. package/README.md +19 -9
  2. package/config/exl3-profiles/qwen38-27b-exl3.env +68 -0
  3. package/config/llama-profiles/qwen38-27b-dflash2.env +6 -1
  4. package/dist/.tsbuildinfo +1 -1
  5. package/dist/benchmarks/paired/adapter.d.ts +15 -0
  6. package/dist/benchmarks/paired/adapter.d.ts.map +1 -1
  7. package/dist/benchmarks/paired/adapter.js +22 -1
  8. package/dist/benchmarks/paired/adapter.js.map +1 -1
  9. package/dist/bin/cli.js +20 -24
  10. package/dist/bin/cli.js.map +1 -1
  11. package/dist/cli/deliver.d.ts +34 -0
  12. package/dist/cli/deliver.d.ts.map +1 -1
  13. package/dist/cli/deliver.js +147 -20
  14. package/dist/cli/deliver.js.map +1 -1
  15. package/dist/cli/guided-setup.d.ts.map +1 -1
  16. package/dist/cli/guided-setup.js +15 -0
  17. package/dist/cli/guided-setup.js.map +1 -1
  18. package/dist/cli/init.d.ts.map +1 -1
  19. package/dist/cli/init.js +3 -0
  20. package/dist/cli/init.js.map +1 -1
  21. package/dist/cli/plan.d.ts.map +1 -1
  22. package/dist/cli/plan.js +8 -2
  23. package/dist/cli/plan.js.map +1 -1
  24. package/dist/cli/policy.d.ts.map +1 -1
  25. package/dist/cli/policy.js +104 -2
  26. package/dist/cli/policy.js.map +1 -1
  27. package/dist/cli/quality.d.ts +11 -0
  28. package/dist/cli/quality.d.ts.map +1 -0
  29. package/dist/cli/quality.js +213 -0
  30. package/dist/cli/quality.js.map +1 -0
  31. package/dist/cli/wizard-config.d.ts.map +1 -1
  32. package/dist/cli/wizard-config.js +19 -9
  33. package/dist/cli/wizard-config.js.map +1 -1
  34. package/dist/cli/worktree.d.ts.map +1 -1
  35. package/dist/cli/worktree.js +8 -1
  36. package/dist/cli/worktree.js.map +1 -1
  37. package/dist/dashboard/savings.d.ts +1 -4
  38. package/dist/dashboard/savings.d.ts.map +1 -1
  39. package/dist/dashboard/savings.js +2 -52
  40. package/dist/dashboard/savings.js.map +1 -1
  41. package/dist/delivery/acceptance-judge.d.ts +10 -0
  42. package/dist/delivery/acceptance-judge.d.ts.map +1 -1
  43. package/dist/delivery/acceptance-judge.js +45 -3
  44. package/dist/delivery/acceptance-judge.js.map +1 -1
  45. package/dist/delivery/agentic-executor.d.ts +12 -1
  46. package/dist/delivery/agentic-executor.d.ts.map +1 -1
  47. package/dist/delivery/agentic-executor.js +25 -5
  48. package/dist/delivery/agentic-executor.js.map +1 -1
  49. package/dist/delivery/bash-sweep.d.ts +12 -0
  50. package/dist/delivery/bash-sweep.d.ts.map +1 -1
  51. package/dist/delivery/bash-sweep.js +8 -1
  52. package/dist/delivery/bash-sweep.js.map +1 -1
  53. package/dist/delivery/convergence-loop.d.ts.map +1 -1
  54. package/dist/delivery/convergence-loop.js +6 -4
  55. package/dist/delivery/convergence-loop.js.map +1 -1
  56. package/dist/delivery/execution-gate.d.ts +1 -1
  57. package/dist/delivery/execution-gate.d.ts.map +1 -1
  58. package/dist/delivery/execution-gate.js +248 -5
  59. package/dist/delivery/execution-gate.js.map +1 -1
  60. package/dist/delivery/snapshot.d.ts +16 -0
  61. package/dist/delivery/snapshot.d.ts.map +1 -1
  62. package/dist/delivery/snapshot.js +113 -2
  63. package/dist/delivery/snapshot.js.map +1 -1
  64. package/dist/delivery/user-validation.d.ts.map +1 -1
  65. package/dist/delivery/user-validation.js +55 -10
  66. package/dist/delivery/user-validation.js.map +1 -1
  67. package/dist/delivery/verifier-ladder.d.ts +24 -0
  68. package/dist/delivery/verifier-ladder.d.ts.map +1 -1
  69. package/dist/delivery/verifier-ladder.js +119 -2
  70. package/dist/delivery/verifier-ladder.js.map +1 -1
  71. package/dist/generators/claude-md.js +17 -4
  72. package/dist/generators/claude-md.js.map +1 -1
  73. package/dist/policies/liveness.d.ts +105 -0
  74. package/dist/policies/liveness.d.ts.map +1 -0
  75. package/dist/policies/liveness.js +251 -0
  76. package/dist/policies/liveness.js.map +1 -0
  77. package/dist/policies/policy-memory.d.ts.map +1 -1
  78. package/dist/policies/policy-memory.js +3 -4
  79. package/dist/policies/policy-memory.js.map +1 -1
  80. package/dist/quality/baseline.d.ts +29 -0
  81. package/dist/quality/baseline.d.ts.map +1 -0
  82. package/dist/quality/baseline.js +79 -0
  83. package/dist/quality/baseline.js.map +1 -0
  84. package/dist/quality/complexity.d.ts +38 -0
  85. package/dist/quality/complexity.d.ts.map +1 -0
  86. package/dist/quality/complexity.js +239 -0
  87. package/dist/quality/complexity.js.map +1 -0
  88. package/dist/quality/config.d.ts +40 -0
  89. package/dist/quality/config.d.ts.map +1 -0
  90. package/dist/quality/config.js +77 -0
  91. package/dist/quality/config.js.map +1 -0
  92. package/dist/quality/crap.d.ts +11 -0
  93. package/dist/quality/crap.d.ts.map +1 -0
  94. package/dist/quality/crap.js +54 -0
  95. package/dist/quality/crap.js.map +1 -0
  96. package/dist/quality/languages.d.ts +25 -0
  97. package/dist/quality/languages.d.ts.map +1 -0
  98. package/dist/quality/languages.js +150 -0
  99. package/dist/quality/languages.js.map +1 -0
  100. package/dist/quality/report.d.ts +38 -0
  101. package/dist/quality/report.d.ts.map +1 -0
  102. package/dist/quality/report.js +251 -0
  103. package/dist/quality/report.js.map +1 -0
  104. package/dist/quality/scanner.d.ts +32 -0
  105. package/dist/quality/scanner.d.ts.map +1 -0
  106. package/dist/quality/scanner.js +127 -0
  107. package/dist/quality/scanner.js.map +1 -0
  108. package/dist/quality/tools.d.ts +28 -0
  109. package/dist/quality/tools.d.ts.map +1 -0
  110. package/dist/quality/tools.js +189 -0
  111. package/dist/quality/tools.js.map +1 -0
  112. package/dist/types/config.d.ts +148 -0
  113. package/dist/types/config.d.ts.map +1 -1
  114. package/dist/types/config.js +35 -0
  115. package/dist/types/config.js.map +1 -1
  116. package/docs/ATTRIBUTION.md +0 -1
  117. package/docs/INDEX.md +38 -4
  118. package/docs/analysis/MARKET_POSITION.md +179 -0
  119. package/docs/architecture/OVERVIEW.md +82 -18
  120. package/docs/architecture/PROTOCOL.md +1 -1
  121. package/docs/benchmarks/PAIRED_FINDINGS.md +106 -0
  122. package/docs/benchmarks/PAIRED_HARNESS.md +16 -0
  123. package/docs/benchmarks/README.md +59 -0
  124. package/docs/design/UAP_REACTOR.md +0 -1
  125. package/docs/getting-started/INSTALLATION.md +1 -1
  126. package/docs/guides/AUTOMATIC.md +0 -14
  127. package/docs/guides/AUTOMATIC_FEATURES.md +1 -9
  128. package/docs/guides/COORDINATION.md +1 -1
  129. package/docs/guides/DELIVERY_PIPELINE.md +5 -0
  130. package/docs/guides/DEPLOY_BATCHING.md +1 -1
  131. package/docs/guides/DROIDS_AND_SKILLS.md +1 -1
  132. package/docs/guides/LOCAL_MODELS.md +6 -1
  133. package/docs/guides/MCP_ROUTER.md +1 -1
  134. package/docs/guides/MEMORY.md +1 -1
  135. package/docs/guides/MULTI_MODEL.md +1 -1
  136. package/docs/guides/ORCHESTRATOR.md +1 -1
  137. package/docs/guides/POLICIES.md +19 -3
  138. package/docs/guides/QWEN38_EXL3.md +114 -0
  139. package/docs/guides/WORKTREE_WORKFLOW.md +45 -1
  140. package/docs/integrations/MCP_ROUTER.md +1 -4
  141. package/docs/plans/deliver-hardening-plan-2026-07-13.md +173 -0
  142. package/docs/plans/deliver-hardening-review-response-2026-07-13.md +180 -0
  143. package/docs/plans/k3-uap-uplift-validation.md +216 -0
  144. package/docs/plans/qwen38-uap-retest-plan.md +196 -0
  145. package/docs/reference/API.md +1 -1
  146. package/docs/reference/CLI.md +49 -14
  147. package/docs/reference/COMPARISON.md +248 -0
  148. package/docs/reference/CONFIGURATION.md +1 -3
  149. package/docs/reference/DATABASE_SCHEMA.md +1 -1
  150. package/docs/reference/FEATURES.md +3 -3
  151. package/docs/reference/PATTERNS.md +1 -1
  152. package/docs/reference/PLATFORMS.md +1 -1
  153. package/package.json +2 -2
  154. package/scripts/maintenance/update-skills.py +0 -22
  155. package/scripts/maintenance/verify-compliance.sh +3 -3
  156. package/src/policies/enforcers/__pycache__/_common.cpython-312.pyc +0 -0
  157. package/src/policies/enforcers/__pycache__/quality_metrics_gate.cpython-312.pyc +0 -0
  158. package/src/policies/enforcers/adr_guard.py +0 -0
  159. package/src/policies/enforcers/bearer_lockdown.py +0 -0
  160. package/src/policies/enforcers/branch_freshness.py +0 -0
  161. package/src/policies/enforcers/design_token_gate.py +0 -0
  162. package/src/policies/enforcers/enforcement_self_protect.py +70 -0
  163. package/src/policies/enforcers/expert_review_required.py +22 -0
  164. package/src/policies/enforcers/iac_plan_destruction_check.py +0 -0
  165. package/src/policies/enforcers/quality_metrics_gate.py +447 -0
  166. package/src/policies/enforcers/ship_loop_gate.py +0 -0
  167. package/src/policies/enforcers/validate_plan_on_change.py +0 -0
  168. package/src/policies/enforcers/visual_verification.py +0 -0
  169. package/src/policies/enforcers/workdir_scope.py +0 -0
  170. package/src/policies/schemas/policies/expert-review-required.md +9 -1
  171. package/src/policies/schemas/policies/quality-metrics-gate.md +74 -0
  172. package/templates/CLAUDE.template.md +1 -1
  173. package/templates/hooks/__pycache__/deliver_autoroute.cpython-312.pyc +0 -0
  174. package/templates/hooks/pre-tool-use-bash.sh +50 -3
  175. package/templates/hooks/pre-tool-use-edit-write.sh +31 -0
  176. package/templates/hooks/session-start.sh +15 -0
  177. package/templates/hooks/uap-policy-gate.sh +187 -5
  178. package/templates/stryker.config.json +14 -0
  179. package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-312.pyc +0 -0
  180. package/tools/agents/scripts/anthropic_proxy.py +254 -28
  181. package/tools/agents/tests/run_acceptance.py +0 -0
  182. package/tools/agents/tests/test_client_disconnect.py +0 -0
  183. package/tools/agents/tests/test_cycle_break_exploration.py +0 -0
  184. package/tools/agents/tests/test_deferral_break.py +0 -0
  185. package/tools/agents/tests/test_delivery_enforcement_all_langs.py +0 -0
  186. package/tools/agents/tests/test_delivery_enforcement_exemptions.py +0 -0
  187. package/tools/agents/tests/test_delivery_enforcement_filepath.py +0 -0
  188. package/tools/agents/tests/test_delivery_enforcement_web_and_bash.py +0 -0
  189. package/tools/agents/tests/test_delivery_enforcement_worktree.py +0 -0
  190. package/tools/agents/tests/test_delivery_enforcement_write_complexity.py +0 -0
  191. package/tools/agents/tests/test_disconnect_watcher.py +0 -0
  192. package/tools/agents/tests/test_doubling_break.py +0 -0
  193. package/tools/agents/tests/test_empty_maxtokens_recovery.py +0 -0
  194. package/tools/agents/tests/test_empty_tool_loop_break.py +0 -0
  195. package/tools/agents/tests/test_enforcement_self_protect.py +90 -0
  196. package/tools/agents/tests/test_enforcer_escape_hatches.py +0 -0
  197. package/tools/agents/tests/test_error_loop_break.py +0 -0
  198. package/tools/agents/tests/test_expert_review_pr_scope.py +13 -5
  199. package/tools/agents/tests/test_fastpath_config.py +0 -0
  200. package/tools/agents/tests/test_finalize_suppression.py +0 -0
  201. package/tools/agents/tests/test_gate_evidence.py +0 -0
  202. package/tools/agents/tests/test_gate_failclosed_indirection.py +0 -0
  203. package/tools/agents/tests/test_gate_integrity.py +0 -0
  204. package/tools/agents/tests/test_live_deliver_kill.py +0 -0
  205. package/tools/agents/tests/test_malformed_unclosed_think.py +0 -0
  206. package/tools/agents/tests/test_mandate_beats_recon.py +0 -0
  207. package/tools/agents/tests/test_mandate_deliver.py +0 -0
  208. package/tools/agents/tests/test_non_stream_resp_log.py +0 -0
  209. package/tools/agents/tests/test_output_token_ceilings.py +0 -0
  210. package/tools/agents/tests/test_overflow_truncate_count_tokens.py +0 -0
  211. package/tools/agents/tests/test_path_containment.py +0 -0
  212. package/tools/agents/tests/test_path_normalizer_hardened.py +0 -0
  213. package/tools/agents/tests/test_repeat_call_guard.py +0 -0
  214. package/tools/agents/tests/test_repeat_guard.py +0 -0
  215. package/tools/agents/tests/test_session_admission.py +0 -0
  216. package/tools/agents/tests/test_stream_heartbeat.py +0 -0
  217. package/tools/agents/tests/test_stream_thinking_deltas.py +405 -0
  218. package/tools/agents/tests/test_stuck_break_hard.py +0 -0
  219. package/tools/agents/tests/test_stuck_break_reattach.py +0 -0
  220. package/tools/agents/tests/test_turn_count_breaker_periodic.py +0 -0
  221. package/tools/agents/tests/test_upstream_chokepoint.py +0 -0
  222. package/tools/agents/tests/test_upstream_model_aliases.py +0 -0
  223. package/tools/agents/tests/test_validate_plan_gate.py +0 -0
  224. package/tools/agents/tests/test_vision_passthrough.py +0 -0
  225. package/tools/agents/tests/test_workdir_scope_enforcer.py +0 -0
  226. package/dist/cli/rtk.d.ts +0 -34
  227. package/dist/cli/rtk.d.ts.map +0 -1
  228. package/dist/cli/rtk.js +0 -401
  229. package/dist/cli/rtk.js.map +0 -1
  230. package/docs/integrations/RTK.md +0 -113
  231. package/scripts/setup/install-rtk.sh +0 -184
  232. package/src/policies/enforcers/rtk_wrap.py +0 -205
  233. package/src/policies/schemas/policies/rtk-wrap.md +0 -50
  234. package/tools/agents/tests/test_rtk_wrap.py +0 -151
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miller-tech/uap",
3
- "version": "1.222.0",
3
+ "version": "2.0.0",
4
4
  "description": "Autonomous AI agent memory system with CLAUDE.md protocol enforcement",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -21,7 +21,7 @@
21
21
  "start": "node dist/bin/cli.js",
22
22
  "test": "vitest",
23
23
  "test:ci": "vitest run",
24
- "test:enforcers": "UAP_PROXY_ENV_AUTOLOAD=0 python3 -m unittest tools.agents.tests.test_enforcement_self_protect tools.agents.tests.test_conditional_destructive_verbs tools.agents.tests.test_live_deliver_kill tools.agents.tests.test_schema_diff_gate tools.agents.tests.test_schema_diff_inline tools.agents.tests.test_stream_telemetry tools.agents.tests.test_project_telemetry_events tools.agents.tests.test_workdir_scope_enforcer tools.agents.tests.test_gate_evidence tools.agents.tests.test_repeat_call_guard tools.agents.tests.test_repeat_guard tools.agents.tests.test_gate_integrity tools.agents.tests.test_gate_failclosed_indirection tools.agents.tests.test_gate_failclosed_schema_diff tools.agents.tests.test_rtk_wrap tools.agents.tests.test_expert_review_pr_scope tools.agents.tests.test_path_containment tools.agents.tests.test_path_normalizer_hardened tools.agents.tests.test_sandbox_tool_strip tools.agents.tests.test_proxy_env_loader tools.agents.tests.test_stream_required_tool tools.agents.tests.test_tool_call_wrapper_profiles tools.agents.tests.test_tool_convert_cache tools.agents.tests.test_doubling_break tools.agents.tests.test_error_loop_ignores_correctives tools.agents.tests.test_attractor_detection tools.agents.tests.test_client_disconnect tools.agents.tests.test_confidence_escalation tools.agents.tests.test_coordination_ban tools.agents.tests.test_coordination_early_ban tools.agents.tests.test_cycle_break_exploration tools.agents.tests.test_deferral_break tools.agents.tests.test_deliver_autoroute tools.agents.tests.test_delivery_enforcement_all_langs tools.agents.tests.test_delivery_enforcement_exemptions tools.agents.tests.test_delivery_enforcement_filepath tools.agents.tests.test_delivery_enforcement_write_complexity tools.agents.tests.test_fastpath_config tools.agents.tests.test_delivery_enforcement_web_and_bash tools.agents.tests.test_disconnect_watcher tools.agents.tests.test_empty_maxtokens_recovery tools.agents.tests.test_empty_tool_loop_break tools.agents.tests.test_enforcer_escape_hatches tools.agents.tests.test_error_loop_break tools.agents.tests.test_finalize_suppression tools.agents.tests.test_malformed_unclosed_think tools.agents.tests.test_mandate_beats_recon tools.agents.tests.test_mandate_deliver tools.agents.tests.test_overflow_truncate_count_tokens tools.agents.tests.test_passthrough_oauth tools.agents.tests.test_project_telemetry tools.agents.tests.test_proxy_auth_headers tools.agents.tests.test_prune_preserve_force_write tools.agents.tests.test_recon_deliver_gate tools.agents.tests.test_session_admission tools.agents.tests.test_stream_heartbeat tools.agents.tests.test_stuck_break_reattach tools.agents.tests.test_stuck_break_hard tools.agents.tests.test_turn_count_breaker_periodic tools.agents.tests.test_upstream_chokepoint tools.agents.tests.test_vision_passthrough tools.agents.tests.test_worktree_required tools.agents.tests.test_enforcer_suite_coverage tools.agents.tests.test_validate_plan_gate tools.agents.tests.test_validate_plan_inside_project tools.agents.tests.test_anthropic_proxy_streaming tools.agents.tests.test_non_stream_resp_log tools.agents.tests.test_delivery_enforcement_worktree tools.agents.tests.test_output_token_ceilings tools.agents.tests.test_tool_narrowing_core tools.agents.tests.test_models_context_window tools.agents.tests.test_thinking_template_kwargs tools.agents.tests.test_cycle_break_wait_poll tools.agents.tests.test_upstream_model_aliases",
24
+ "test:enforcers": "UAP_PROXY_ENV_AUTOLOAD=0 python3 -m unittest tools.agents.tests.test_enforcement_self_protect tools.agents.tests.test_conditional_destructive_verbs tools.agents.tests.test_live_deliver_kill tools.agents.tests.test_schema_diff_gate tools.agents.tests.test_schema_diff_inline tools.agents.tests.test_stream_telemetry tools.agents.tests.test_project_telemetry_events tools.agents.tests.test_workdir_scope_enforcer tools.agents.tests.test_gate_evidence tools.agents.tests.test_repeat_call_guard tools.agents.tests.test_repeat_guard tools.agents.tests.test_gate_integrity tools.agents.tests.test_gate_failclosed_indirection tools.agents.tests.test_gate_failclosed_schema_diff tools.agents.tests.test_expert_review_pr_scope tools.agents.tests.test_path_containment tools.agents.tests.test_path_normalizer_hardened tools.agents.tests.test_sandbox_tool_strip tools.agents.tests.test_proxy_env_loader tools.agents.tests.test_stream_required_tool tools.agents.tests.test_tool_call_wrapper_profiles tools.agents.tests.test_tool_convert_cache tools.agents.tests.test_doubling_break tools.agents.tests.test_error_loop_ignores_correctives tools.agents.tests.test_attractor_detection tools.agents.tests.test_client_disconnect tools.agents.tests.test_confidence_escalation tools.agents.tests.test_coordination_ban tools.agents.tests.test_coordination_early_ban tools.agents.tests.test_cycle_break_exploration tools.agents.tests.test_deferral_break tools.agents.tests.test_deliver_autoroute tools.agents.tests.test_delivery_enforcement_all_langs tools.agents.tests.test_delivery_enforcement_exemptions tools.agents.tests.test_delivery_enforcement_filepath tools.agents.tests.test_delivery_enforcement_write_complexity tools.agents.tests.test_fastpath_config tools.agents.tests.test_delivery_enforcement_web_and_bash tools.agents.tests.test_disconnect_watcher tools.agents.tests.test_empty_maxtokens_recovery tools.agents.tests.test_empty_tool_loop_break tools.agents.tests.test_enforcer_escape_hatches tools.agents.tests.test_error_loop_break tools.agents.tests.test_finalize_suppression tools.agents.tests.test_malformed_unclosed_think tools.agents.tests.test_mandate_beats_recon tools.agents.tests.test_mandate_deliver tools.agents.tests.test_overflow_truncate_count_tokens tools.agents.tests.test_passthrough_oauth tools.agents.tests.test_project_telemetry tools.agents.tests.test_proxy_auth_headers tools.agents.tests.test_prune_preserve_force_write tools.agents.tests.test_recon_deliver_gate tools.agents.tests.test_session_admission tools.agents.tests.test_stream_heartbeat tools.agents.tests.test_stuck_break_reattach tools.agents.tests.test_stuck_break_hard tools.agents.tests.test_turn_count_breaker_periodic tools.agents.tests.test_upstream_chokepoint tools.agents.tests.test_vision_passthrough tools.agents.tests.test_worktree_required tools.agents.tests.test_enforcer_suite_coverage tools.agents.tests.test_validate_plan_gate tools.agents.tests.test_validate_plan_inside_project tools.agents.tests.test_anthropic_proxy_streaming tools.agents.tests.test_non_stream_resp_log tools.agents.tests.test_delivery_enforcement_worktree tools.agents.tests.test_output_token_ceilings tools.agents.tests.test_tool_narrowing_core tools.agents.tests.test_models_context_window tools.agents.tests.test_thinking_template_kwargs tools.agents.tests.test_cycle_break_wait_poll tools.agents.tests.test_upstream_model_aliases tools.agents.tests.test_stream_thinking_deltas",
25
25
  "test:coverage": "vitest --coverage",
26
26
  "bench": "vitest --config vitest.bench.config.ts",
27
27
  "lint": "eslint src --ext .ts",
@@ -28,27 +28,6 @@ skills_to_update = {
28
28
  }
29
29
 
30
30
 
31
- def add_rtk_header(content, skill_name):
32
- rtk_addition = f"""---
33
- name: {skill_name}
34
- version: "2.0.0"
35
- compatibility: CLAUDE.md v2.3.0+
36
- ---
37
-
38
- > **RTK Integration**: Supports `@hooks-session-start.md`, `@PreCompact.md`
39
-
40
- """
41
- if content.startswith("---"):
42
- end_frontmatter = content.find("---", 3)
43
- if end_frontmatter > 0:
44
- return (
45
- content[: end_frontmatter + 3]
46
- + rtk_addition
47
- + content[end_frontmatter + 3 :]
48
- )
49
- return rtk_addition + content
50
-
51
-
52
31
  def add_decision_loop_ref(content, skill_name):
53
32
  decision_loop = f"""
54
33
  ## Protocol Integration
@@ -117,7 +96,6 @@ def update_skill_file(skill_dir, skill_name):
117
96
  content = f.read()
118
97
 
119
98
  original_content = content
120
- content = add_rtk_header(content, skill_name)
121
99
  content = add_decision_loop_ref(content, skill_name)
122
100
  content = add_uam_compliance(content)
123
101
 
@@ -79,12 +79,12 @@ else
79
79
  echo "✗ Pattern Router MISSING"
80
80
  fi
81
81
 
82
- # 10. RTK includes
82
+ # 10. Session-hook includes
83
83
  if grep -q "@hooks-session-start.md\|@PreCompact.md" CLAUDE.md; then
84
84
  score=$((score + 1))
85
- echo "✓ RTK includes (@hooks-session-start, @PreCompact)"
85
+ echo "✓ Session-hook includes (@hooks-session-start, @PreCompact)"
86
86
  else
87
- echo "✗ RTK includes MISSING"
87
+ echo "✗ Session-hook includes MISSING"
88
88
  fi
89
89
 
90
90
  # 11. Verifier loop enforcement (min 3 runs)
File without changes
File without changes
File without changes
File without changes
@@ -39,6 +39,11 @@ PROTECTED_MARKERS = (
39
39
  "/.policy-tools/",
40
40
  "/src/policies/",
41
41
  "/policies/", # the policy-definition markdown dir
42
+ # The policies DB the gates read. Compliance artifact paths are carved out
43
+ # below, so without this the enforcement registry itself was the soft spot:
44
+ # rewrite the DB and every downstream gate grades a forgery (the pay2u
45
+ # inversion the operator patch fixed out-of-tree).
46
+ "/agents/data/memory/policies.db",
42
47
  "/.uap.json",
43
48
  "/.uap/",
44
49
  "anthropic-proxy.env",
@@ -62,6 +67,10 @@ BYPASS_PATTERNS = (
62
67
  # agent writes its own command strings, so an inline form waives its own
63
68
  # review. Refuse it here so the attempt is visible rather than silent.
64
69
  re.compile(r"UAP_NO_REVIEW\s*=\s*['\"]?1", re.I),
70
+ # quality-metrics gate hatch, same operator-only shape: the enforcer reads
71
+ # the launch env, so the only agent-reachable move is PERSISTING the flag
72
+ # (rc files, proxy env) — which is exactly what this pattern refuses.
73
+ re.compile(r"UAP_QUALITY_GATE_OFF\s*=\s*['\"]?1", re.I),
65
74
  re.compile(r"UAP_USER_VALIDATION\s*=\s*['\"]?0", re.I),
66
75
  # Single-flight is a DATA-SAFETY control, not a policy preference: deliver
67
76
  # runs each candidate in a git worktree, and two runs against one repo are
@@ -246,8 +255,33 @@ PROTECTED_TARGETS = (
246
255
  # (test_gate_evidence), which asserts that exact append stays allowed.
247
256
  # Guarding it needs a rule that tells `>>` from `>`; blocking the queue's
248
257
  # own writes to protect it is not that rule.
258
+ #
259
+ # The policies DB the gates READ. The inversion this closes: compliance
260
+ # artifact paths (.uap/reviews/) were agent-locked while the DB that
261
+ # decides what is enforced sat unprotected — an agent could delete or
262
+ # rewrite the policy registry instead of complying with it (pay2u operator
263
+ # patch uap-policy-fix-APPLY.sh, upstreamed here). The CLI's own writes go
264
+ # through the `uap policy` process, not agent Edit/Write tools, so policy
265
+ # management is unaffected; what this refuses is the agent deleting or
266
+ # editing the DB directly.
267
+ "agents/data/memory/policies.db",
249
268
  ".uap.json",
250
269
  "anthropic-proxy.env",
270
+ # F3 (deliver-hardening 2026-07-13): the signed operator-override file.
271
+ # Edit/Write to it is already refused via the "/.uap/" marker, but the
272
+ # destructive check treats every redirect alike and this directory is
273
+ # otherwise permissive — `echo '{deliverBypass:true…}' >
274
+ # .uap/operator-overrides.json` would self-mint the bypass the file exists
275
+ # to restrict to the operator. Only an out-of-band operator writes it; the
276
+ # hook additionally verifies uid/mode/expiresAt before honoring it.
277
+ ".uap/operator-overrides.json",
278
+ # F1: the liveness cache the gate's degrade consult trusts. A forged entry
279
+ # ({healthy:false, degradable:true}) would downgrade a BLOCKING policy to
280
+ # advisory — exactly the sabotage the degrade guard exists to refuse — so
281
+ # the cache must be as unwritable as the verdicts it carries. Legitimate
282
+ # writes go through `uap policy liveness`/`status`, whose command text
283
+ # never names the file (same shape as the policies.db guard).
284
+ ".uap/policy-liveness.json",
251
285
  )
252
286
 
253
287
  _SEGMENT_SPLIT = re.compile(r"(?:\|\||&&|[;\n|&])")
@@ -525,6 +559,37 @@ def _kills_live_deliver_run(command: str, root) -> str:
525
559
  return ""
526
560
 
527
561
 
562
+ # The two files the gate's TRUST decisions rest on: the signed operator
563
+ # override and the liveness cache the degrade consult reads. They get a rule
564
+ # the rest of the protected surface does not (deliver-hardening security
565
+ # review, 2026-07-13): an INTERPRETER-MEDIATED write —
566
+ # python3 -c 'import json; json.dump({...}, open(".uap/operator-overrides.json","w"))'
567
+ # carries no destructive verb, no shell redirect and no UAP_* bypass text, so
568
+ # every other scan here walks straight past it — yet a successful write used
569
+ # to mint a full bypass. The hook now also requires these files ROOT-owned
570
+ # before trusting them, which is the load-bearing fix; this rule is the
571
+ # defense-in-depth that stops the write from landing at all. Root ownership
572
+ # is what makes this narrow list sufficient — anything else the agent writes
573
+ # is distrusted on READ, so it need not be write-blocked here.
574
+ _TRUST_ANCHORS = (".uap/operator-overrides.json", ".uap/policy-liveness.json")
575
+ _INTERPRETER_RE = re.compile(r"(?:^|[\s;|&('\"`])(?:python\d*(?:\.\d+)?|perl|ruby|node)(?:\s|$)")
576
+ # A write primitive in interpreter code: open(…, "w"/"a"/"x"/"+"), or a
577
+ # mutating method call. Reads (open without a mode, json.load, print) match
578
+ # neither and stay allowed.
579
+ _INTERPRETER_WRITE_RE = re.compile(
580
+ r"open\s*\([^)]*[\"'][wax+]|"
581
+ r"\.\s*(?:write\w*|writelines|dump|rename|replace|unlink|remove|removedirs|"
582
+ r"chmod|chown|rmtree|move|copy\w*)\s*\(")
583
+
584
+
585
+ def _interpreter_write_to_anchor(command: str) -> bool:
586
+ """True when an interpreter command names a trust anchor with write intent."""
587
+ lowered = command.lower()
588
+ if not any(anchor in lowered for anchor in _TRUST_ANCHORS):
589
+ return False
590
+ return bool(_INTERPRETER_RE.search(command) and _INTERPRETER_WRITE_RE.search(command))
591
+
592
+
528
593
  def _direct_destructive(command: str) -> bool:
529
594
  """Destructive op naming a protected path, judged per command segment."""
530
595
  cd_into_protected = False
@@ -586,6 +651,11 @@ def _bash_destructive(command: str, _depth: int = 0) -> bool:
586
651
  return False
587
652
  if _direct_destructive(command):
588
653
  return True
654
+ # Checked at EVERY depth (an interpreter write inside `bash -c "..."` is
655
+ # still one) and BEFORE the intent gate below — that gate reads shell
656
+ # verbs, and an interpreter-mediated write to a trust anchor carries none.
657
+ if _interpreter_write_to_anchor(command):
658
+ return True
589
659
  if _depth < 2: # bounded: `bash -c "bash -c ..."`
590
660
  for inner in _inner_commands(command):
591
661
  if _bash_destructive(inner, _depth + 1):
@@ -63,6 +63,9 @@ GH_API_SHIP_RE = re.compile(
63
63
  )
64
64
  GIT_VALUE_OPTIONS = frozenset({"-C", "-c", "--git-dir", "--work-tree", "--namespace"})
65
65
  WRAPPER_VERBS = frozenset({
66
+ # "rtk" stays even though UAP no longer integrates the rtk CLI: the binary
67
+ # can still exist on operator machines, and without the unwrap, forms like
68
+ # `rtk git -C /repo push` would slip past the ship gate (fail-open).
66
69
  "rtk", "env", "nohup", "sudo", "time", "command", "timeout", "stdbuf",
67
70
  })
68
71
  _SEGMENT_SPLIT = re.compile(r"(?:\|\||&&|[;\n|&])")
@@ -481,6 +484,25 @@ def main() -> None:
481
484
  "Override: UAP_NO_REVIEW=1.",
482
485
  )
483
486
 
487
+ # Quality-metrics fusion: when the review artifact carries a `quality`
488
+ # block (written from `uap quality check --json` by the
489
+ # parallel-expert-review flow), a failing machine report vetoes the
490
+ # approval — reviewers adjudicate the numbers, they cannot outvote them.
491
+ # Absent block -> fail-open (repos without .uap/quality-metrics.json and
492
+ # pre-existing artifacts keep working).
493
+ quality = data.get("quality") if isinstance(data, dict) else None
494
+ if isinstance(quality, dict) and quality.get("pass") is False:
495
+ blocking = quality.get("blocking")
496
+ detail = f" ({blocking} blocking violation(s))" if isinstance(blocking, int) else ""
497
+ emit(
498
+ False,
499
+ f"expert-review-required: the review's quality gate FAILED{detail}. "
500
+ "Run `uap quality check`, fix the blocking violations (or regenerate the "
501
+ "baseline deliberately with `uap quality baseline --update`), refresh the "
502
+ "artifact's quality block, and re-record the review. "
503
+ "Override: UAP_NO_REVIEW=1.",
504
+ )
505
+
484
506
  emit(
485
507
  True,
486
508
  f"expert-review satisfied (.uap/reviews/{slug}.json"