@miller-tech/uap 1.157.0 → 1.159.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 (31) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/cli/deliver.js +56 -8
  3. package/dist/cli/deliver.js.map +1 -1
  4. package/dist/delivery/convergence-loop.d.ts.map +1 -1
  5. package/dist/delivery/convergence-loop.js +11 -1
  6. package/dist/delivery/convergence-loop.js.map +1 -1
  7. package/dist/delivery/epic-controller.d.ts.map +1 -1
  8. package/dist/delivery/epic-controller.js +25 -0
  9. package/dist/delivery/epic-controller.js.map +1 -1
  10. package/dist/delivery/orchestrated-mission.d.ts +15 -0
  11. package/dist/delivery/orchestrated-mission.d.ts.map +1 -1
  12. package/dist/delivery/orchestrated-mission.js +3 -0
  13. package/dist/delivery/orchestrated-mission.js.map +1 -1
  14. package/dist/delivery/run-state.d.ts +9 -0
  15. package/dist/delivery/run-state.d.ts.map +1 -1
  16. package/dist/delivery/run-state.js +20 -0
  17. package/dist/delivery/run-state.js.map +1 -1
  18. package/dist/delivery/task-orchestrator.d.ts +29 -0
  19. package/dist/delivery/task-orchestrator.d.ts.map +1 -1
  20. package/dist/delivery/task-orchestrator.js +51 -0
  21. package/dist/delivery/task-orchestrator.js.map +1 -1
  22. package/dist/delivery/user-validation.d.ts.map +1 -1
  23. package/dist/delivery/user-validation.js +14 -2
  24. package/dist/delivery/user-validation.js.map +1 -1
  25. package/package.json +1 -1
  26. package/src/policies/enforcers/__pycache__/_common.cpython-312.pyc +0 -0
  27. package/src/policies/enforcers/enforcement_infra_protect.py +33 -0
  28. package/templates/hooks/__pycache__/deliver_autoroute.cpython-312.pyc +0 -0
  29. package/templates/hooks/deliver_autoroute.py +234 -15
  30. package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-312.pyc +0 -0
  31. package/tools/agents/tests/test_deliver_autoroute.py +116 -1
@@ -30,9 +30,13 @@ class DecideTest(unittest.TestCase):
30
30
  def test_deliver_route_logs_intent_no_spawn_when_off(self):
31
31
  d = mod.decide(BLOCK_OUT, "Write", ARGS, False, set())
32
32
  self.assertFalse(d["spawn"])
33
+ self.assertFalse(d["replay"]) # no recorded content -> not replayable
33
34
  self.assertIsNotNone(d["intent"])
34
35
  self.assertEqual(d["intent"]["file_path"], "/repo/src/foo.ts")
35
- self.assertEqual(d["message"], BLOCK_OUT["reason"]) # unchanged
36
+ # autoroute off + no recorded content: message is annotated to tell the
37
+ # agent to run deliver itself; the block reason is preserved as prefix.
38
+ self.assertTrue(d["message"].startswith(BLOCK_OUT["reason"]))
39
+ self.assertIn("apply it yourself", d["message"])
36
40
 
37
41
  def test_deliver_route_spawns_when_on_and_unseen(self):
38
42
  d = mod.decide(BLOCK_OUT, "Write", ARGS, True, set())
@@ -117,5 +121,116 @@ class BashRoutedIntentTest(unittest.TestCase):
117
121
  self.assertFalse(d["spawn"])
118
122
 
119
123
 
124
+ class BashHeredocReplayTest(unittest.TestCase):
125
+ """A model whose Write tool is gated reaches for `cat > FILE << EOF ... EOF`.
126
+ That heredoc carries the path AND body in the command, so autoroute recovers
127
+ both and the write becomes REPLAYABLE — else the model's `cat >` rewrites are
128
+ blocked forever (octopus_invaders_v3, 2026-07-16: 35 min, 0 landed)."""
129
+
130
+ HEREDOC = 'cat > src/app.js <<EOF\nconsole.log(1)\nEOF'
131
+
132
+ def test_parse_bash_write_extracts_path_and_body(self):
133
+ p, b = mod._parse_bash_write(self.HEREDOC)
134
+ self.assertEqual(p, 'src/app.js')
135
+ self.assertEqual(b, 'console.log(1)')
136
+
137
+ def test_parse_handles_wrapper_and_quoted_delim(self):
138
+ cmd = "UAP_DELIVER_BYPASS=1 bash -c 'cat > /a/game.js << \"GAMEJS\"\nX=1\nGAMEJS'"
139
+ p, b = mod._parse_bash_write(cmd)
140
+ self.assertEqual(p, '/a/game.js')
141
+ self.assertEqual(b, 'X=1')
142
+
143
+ def test_parse_returns_none_for_non_heredoc(self):
144
+ self.assertEqual(mod._parse_bash_write('cat > a.js'), (None, None))
145
+ self.assertEqual(mod._parse_bash_write('echo hi > a.js'), (None, None))
146
+
147
+ def test_bash_heredoc_is_replayable(self):
148
+ d = mod.decide(BLOCK_OUT, "Bash", {"command": self.HEREDOC}, True, set())
149
+ self.assertTrue(d["replay"]) # recovered content -> deterministic replay
150
+ self.assertFalse(d["spawn"])
151
+ self.assertEqual(d["file_path"], 'src/app.js') # path recovered from the command
152
+ self.assertEqual(d["intent"]["edit"]["content"], 'console.log(1)')
153
+
154
+ def test_bash_without_body_still_model_spawns(self):
155
+ # No heredoc body to recover -> not replayable -> model-spawn on the hint.
156
+ d = mod.decide(BLOCK_OUT, "Bash", {"command": "cat > a.js <<EOF"}, True, set())
157
+ self.assertFalse(d["replay"])
158
+ self.assertTrue(d["spawn"])
159
+ self.assertEqual(d["file_path"], "")
160
+
161
+
162
+ class ReplayIntentTest(unittest.TestCase):
163
+ """A REPLAYABLE intent (the blocked edit's exact content was recorded) must
164
+ be applied DETERMINISTICALLY via `uap deliver --pending` — not re-routed
165
+ through a fresh model deliver that just re-blocks. Without this the blocked
166
+ write is recorded but never lands: the model re-emits it forever and 0 files
167
+ change (octopus_invaders_v3, 2026-07-16 — every run frozen at phase 0)."""
168
+
169
+ REPLAY_ARGS = {"file_path": "/repo/src/foo.ts", "content": "const X = 1;\n"}
170
+
171
+ def test_content_intent_is_replayable_not_model_spawn(self):
172
+ d = mod.decide(BLOCK_OUT, "Write", self.REPLAY_ARGS, True, set())
173
+ self.assertTrue(d["replay"])
174
+ self.assertFalse(d["spawn"]) # deterministic replay, not a model run
175
+ self.assertIn("--pending", d["message"])
176
+ self.assertEqual(d["intent"]["edit"]["content"], "const X = 1;\n")
177
+
178
+ def test_replay_not_gated_on_autoroute(self):
179
+ d = mod.decide(BLOCK_OUT, "Write", self.REPLAY_ARGS, False, set())
180
+ self.assertTrue(d["replay"]) # safe deterministic path runs even when autoroute is off
181
+ self.assertFalse(d["spawn"])
182
+
183
+ def test_enforcer_editIntent_old_new_is_replayable(self):
184
+ out = dict(BLOCK_OUT); out["editIntent"] = {"old_string": "a", "new_string": "b"}
185
+ d = mod.decide(out, "Edit", {"file_path": "/repo/src/foo.ts"}, True, set())
186
+ self.assertTrue(d["replay"])
187
+ self.assertFalse(d["spawn"])
188
+
189
+ def test_non_replayable_still_model_spawns(self):
190
+ d = mod.decide(BLOCK_OUT, "Write", ARGS, True, set()) # no content recorded
191
+ self.assertFalse(d["replay"])
192
+ self.assertTrue(d["spawn"])
193
+
194
+
195
+ class CoherentMissionRouteTest(unittest.TestCase):
196
+ """Phase 1: route the whole mission to ONE agentic `uap deliver --epics` run
197
+ instead of landing files one at a time via the per-file replay/model-spawn
198
+ side-channel — which produced syntactically-valid but NON-integrating output
199
+ (octopus_invaders_v3, 2026-07-16). Opt-in: UAP_DELIVER_COHERENT_MISSION."""
200
+
201
+ def test_off_by_default(self):
202
+ self.assertEqual(mod.coherent_route(False, "deliver", True, "build X", False), "")
203
+
204
+ def test_spawn_when_on_mission_and_free(self):
205
+ self.assertEqual(mod.coherent_route(True, "deliver", True, "build X", False), "spawn")
206
+
207
+ def test_wait_when_run_already_inflight(self):
208
+ self.assertEqual(mod.coherent_route(True, "deliver", True, "build X", True), "wait")
209
+
210
+ def test_no_route_without_mission(self):
211
+ self.assertEqual(mod.coherent_route(True, "deliver", True, "", False), "")
212
+
213
+ def test_no_route_without_write_intent(self):
214
+ self.assertEqual(mod.coherent_route(True, "deliver", False, "build X", False), "")
215
+
216
+ def test_no_route_for_non_deliver(self):
217
+ self.assertEqual(mod.coherent_route(True, "worktree", True, "build X", False), "")
218
+
219
+ def test_recover_mission_from_ledger(self):
220
+ import tempfile, os, json as _j
221
+ from pathlib import Path
222
+ with tempfile.TemporaryDirectory() as td:
223
+ os.makedirs(os.path.join(td, ".uap"))
224
+ _j.dump({"mission": "Build the thing"},
225
+ open(os.path.join(td, ".uap", "completion-ledger.json"), "w"))
226
+ self.assertEqual(mod._recover_mission(Path(td)), "Build the thing")
227
+
228
+ def test_recover_mission_empty_when_absent(self):
229
+ import tempfile
230
+ from pathlib import Path
231
+ with tempfile.TemporaryDirectory() as td:
232
+ self.assertEqual(mod._recover_mission(Path(td)), "")
233
+
234
+
120
235
  if __name__ == "__main__":
121
236
  unittest.main()