@miller-tech/uap 1.189.1 → 1.189.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miller-tech/uap",
3
- "version": "1.189.1",
3
+ "version": "1.189.2",
4
4
  "description": "Autonomous AI agent memory system with CLAUDE.md protocol enforcement",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -161,6 +161,22 @@ PROTECTED_TARGETS = (
161
161
  # stopped with the STOP file, which leaves the checkpoint intact.
162
162
  ".uap/deliver.lock",
163
163
  ".uap/deliver-runs",
164
+ # The heartbeat is part of the SAME guard, and leaving it out left the
165
+ # bypass open one file over. `isDeliverLockAbandoned` treats a MISSING
166
+ # heartbeat plus a lock older than the wedge timeout as abandoned, so
167
+ # deleting it makes a live holder look dead and the next launch reclaims
168
+ # its lock. Verified: with the heartbeat present a two-hour-old lock held
169
+ # by a live pid is abandoned=False; delete it and the same lock is
170
+ # abandoned=True.
171
+ ".uap/deliver.heartbeat",
172
+ # NOT `.uap/pending-deliver.jsonl`, though the delivery-enforcement policy
173
+ # names it alongside these. It is an APPEND-ONLY queue the tooling writes
174
+ # constantly, and the destructive check treats every redirect alike, so
175
+ # protecting it here refuses `echo x >> .uap/pending-deliver.jsonl` — the
176
+ # ordinary way the queue is filled. Caught by the Python enforcer suite
177
+ # (test_gate_evidence), which asserts that exact append stays allowed.
178
+ # Guarding it needs a rule that tells `>>` from `>`; blocking the queue's
179
+ # own writes to protect it is not that rule.
164
180
  ".uap.json",
165
181
  "anthropic-proxy.env",
166
182
  )
@@ -322,7 +338,11 @@ def _destructive_intent(command: str) -> bool:
322
338
  return bool(toks & set(DESTRUCTIVE_VERBS)) or bool(_REDIRECT.search(command))
323
339
 
324
340
 
325
- _DELIVER_COORD = (".uap/deliver.lock", ".uap/deliver-runs")
341
+ _DELIVER_COORD = (
342
+ ".uap/deliver.lock",
343
+ ".uap/deliver-runs",
344
+ ".uap/deliver.heartbeat",
345
+ )
326
346
 
327
347
 
328
348
  def _mentions_deliver_coord(command: str) -> bool:
@@ -512,7 +532,9 @@ def main() -> None:
512
532
  "does not free anything, it puts a SECOND mission on the same "
513
533
  "tree, and two of them overwrite each other's edits. "
514
534
  "`.uap/deliver-runs/` holds every run's checkpoint, which is "
515
- "the work itself. "
535
+ "the work itself. `.uap/deliver.heartbeat` is how a live run is "
536
+ "told apart from an abandoned one - remove it and the next launch "
537
+ "reclaims a RUNNING mission's lock. "
516
538
  "You never need to remove either: a lock whose holder is dead "
517
539
  "or wedged is reclaimed automatically by the next launch. "
518
540
  "To STOP a run instead of forcing past it, request the "