@miller-tech/uap 1.220.2 → 1.220.3

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.220.2",
3
+ "version": "1.220.3",
4
4
  "description": "Autonomous AI agent memory system with CLAUDE.md protocol enforcement",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -386,6 +386,7 @@ def _record_escalation_edit(root: Path, rel: str) -> None:
386
386
  edits = st.get("edits_since_green") if isinstance(st.get("edits_since_green"), dict) else {}
387
387
  edits[rel] = int(edits.get(rel, 0)) + 1
388
388
  st["edits_since_green"] = edits
389
+ st["edits_total"] = int(st.get("edits_total") or 0) + 1 # attempt counter (tracker reads it)
389
390
  st.setdefault("failures", 0)
390
391
  st["updated"] = int(_time.time())
391
392
  try:
@@ -169,9 +169,19 @@ def record_fail(source: str, detail: str, root: Path | None = None) -> dict:
169
169
  sig = failure_signature(detail)
170
170
  prev = st.get("last_failure") if isinstance(st.get("last_failure"), dict) else None
171
171
  prev_sig = (prev or {}).get("sig")
172
+ edits_total = int(st.get("edits_total") or 0)
173
+ _ep = (prev or {}).get("edits_total")
174
+ edits_at_prev = int(_ep) if isinstance(_ep, (int, float)) else -1 # 0 is a real value
172
175
  if prev_sig and sig and sig != prev_sig:
173
176
  st["failures"] = 1
174
177
  st["streak_reset"] = {"ts": int(time.time()), "from": prev_sig[:120], "to": sig[:120]}
178
+ elif prev_sig and sig == prev_sig and edits_total == edits_at_prev:
179
+ # The SAME failure observed again with no edit in between (idle/stop
180
+ # verify hooks re-run the gates every time the session pauses). That is
181
+ # a re-observation, not another failed attempt — the streak must not
182
+ # grow while the agent has not tried anything. Observed live: 4 "failures"
183
+ # from one red user-path test across four idle pauses.
184
+ st["reobserved"] = int(st.get("reobserved") or 0) + 1
175
185
  else:
176
186
  st["failures"] = int(st.get("failures") or 0) + 1
177
187
  st["last_failure"] = {
@@ -179,6 +189,7 @@ def record_fail(source: str, detail: str, root: Path | None = None) -> dict:
179
189
  "source": source or "unknown",
180
190
  "detail": (detail or "")[-DETAIL_MAX:],
181
191
  "sig": sig,
192
+ "edits_total": edits_total,
182
193
  }
183
194
  save_state(st, root)
184
195
  return st
@@ -199,6 +210,7 @@ def record_edit(rel: str, root: Path | None = None) -> dict:
199
210
  edits = st.get("edits_since_green") or {}
200
211
  edits[rel] = int(edits.get(rel, 0)) + 1
201
212
  st["edits_since_green"] = edits
213
+ st["edits_total"] = int(st.get("edits_total") or 0) + 1 # monotonic: "an attempt happened"
202
214
  save_state(st, root)
203
215
  return st
204
216