@miller-tech/uap 1.175.13 → 1.178.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 (95) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/benchmarks/harness-card.d.ts +86 -0
  3. package/dist/benchmarks/harness-card.d.ts.map +1 -0
  4. package/dist/benchmarks/harness-card.js +153 -0
  5. package/dist/benchmarks/harness-card.js.map +1 -0
  6. package/dist/benchmarks/paired/report.d.ts +15 -0
  7. package/dist/benchmarks/paired/report.d.ts.map +1 -1
  8. package/dist/benchmarks/paired/report.js +12 -0
  9. package/dist/benchmarks/paired/report.js.map +1 -1
  10. package/dist/benchmarks/paired/types.d.ts +1 -1
  11. package/dist/bin/cli.js +27 -0
  12. package/dist/bin/cli.js.map +1 -1
  13. package/dist/cli/bench.d.ts.map +1 -1
  14. package/dist/cli/bench.js +64 -3
  15. package/dist/cli/bench.js.map +1 -1
  16. package/dist/cli/harness.d.ts +3 -2
  17. package/dist/cli/harness.d.ts.map +1 -1
  18. package/dist/cli/harness.js +81 -0
  19. package/dist/cli/harness.js.map +1 -1
  20. package/dist/cli/memory.d.ts +7 -1
  21. package/dist/cli/memory.d.ts.map +1 -1
  22. package/dist/cli/memory.js +165 -0
  23. package/dist/cli/memory.js.map +1 -1
  24. package/dist/delivery/agentic-executor.d.ts +76 -2
  25. package/dist/delivery/agentic-executor.d.ts.map +1 -1
  26. package/dist/delivery/agentic-executor.js +231 -29
  27. package/dist/delivery/agentic-executor.js.map +1 -1
  28. package/dist/delivery/edit-match.d.ts +134 -0
  29. package/dist/delivery/edit-match.d.ts.map +1 -0
  30. package/dist/delivery/edit-match.js +331 -0
  31. package/dist/delivery/edit-match.js.map +1 -0
  32. package/dist/memory/dynamic-retrieval.d.ts.map +1 -1
  33. package/dist/memory/dynamic-retrieval.js +57 -0
  34. package/dist/memory/dynamic-retrieval.js.map +1 -1
  35. package/dist/memory/reconstruct-ingest.d.ts +88 -0
  36. package/dist/memory/reconstruct-ingest.d.ts.map +1 -0
  37. package/dist/memory/reconstruct-ingest.js +165 -0
  38. package/dist/memory/reconstruct-ingest.js.map +1 -0
  39. package/dist/memory/reconstruct-store.d.ts +143 -0
  40. package/dist/memory/reconstruct-store.d.ts.map +1 -0
  41. package/dist/memory/reconstruct-store.js +312 -0
  42. package/dist/memory/reconstruct-store.js.map +1 -0
  43. package/dist/memory/reconstruct.d.ts +272 -0
  44. package/dist/memory/reconstruct.d.ts.map +1 -0
  45. package/dist/memory/reconstruct.js +552 -0
  46. package/dist/memory/reconstruct.js.map +1 -0
  47. package/dist/policies/schemas/policy.d.ts +2 -2
  48. package/dist/self-harness/evidence-proposer.d.ts +58 -0
  49. package/dist/self-harness/evidence-proposer.d.ts.map +1 -0
  50. package/dist/self-harness/evidence-proposer.js +132 -0
  51. package/dist/self-harness/evidence-proposer.js.map +1 -0
  52. package/dist/self-harness/manifest.d.ts +130 -0
  53. package/dist/self-harness/manifest.d.ts.map +1 -0
  54. package/dist/self-harness/manifest.js +247 -0
  55. package/dist/self-harness/manifest.js.map +1 -0
  56. package/dist/self-harness/mods.d.ts +57 -3
  57. package/dist/self-harness/mods.d.ts.map +1 -1
  58. package/dist/self-harness/mods.js +72 -0
  59. package/dist/self-harness/mods.js.map +1 -1
  60. package/dist/self-harness/orchestrator.d.ts +27 -0
  61. package/dist/self-harness/orchestrator.d.ts.map +1 -1
  62. package/dist/self-harness/orchestrator.js +47 -4
  63. package/dist/self-harness/orchestrator.js.map +1 -1
  64. package/dist/self-harness/pending.d.ts +17 -3
  65. package/dist/self-harness/pending.d.ts.map +1 -1
  66. package/dist/self-harness/pending.js +26 -4
  67. package/dist/self-harness/pending.js.map +1 -1
  68. package/dist/self-harness/profile.d.ts +17 -1
  69. package/dist/self-harness/profile.d.ts.map +1 -1
  70. package/dist/self-harness/profile.js +11 -4
  71. package/dist/self-harness/profile.js.map +1 -1
  72. package/dist/self-harness/run.d.ts +19 -0
  73. package/dist/self-harness/run.d.ts.map +1 -1
  74. package/dist/self-harness/run.js +43 -4
  75. package/dist/self-harness/run.js.map +1 -1
  76. package/dist/self-harness/transfer.d.ts.map +1 -1
  77. package/dist/self-harness/transfer.js +2 -0
  78. package/dist/self-harness/transfer.js.map +1 -1
  79. package/dist/self-harness/validate.d.ts +17 -6
  80. package/dist/self-harness/validate.d.ts.map +1 -1
  81. package/dist/self-harness/validate.js +73 -8
  82. package/dist/self-harness/validate.js.map +1 -1
  83. package/dist/telemetry/tool-calls.d.ts +82 -0
  84. package/dist/telemetry/tool-calls.d.ts.map +1 -0
  85. package/dist/telemetry/tool-calls.js +280 -0
  86. package/dist/telemetry/tool-calls.js.map +1 -0
  87. package/dist/telemetry/tool-failure.d.ts +71 -0
  88. package/dist/telemetry/tool-failure.d.ts.map +1 -0
  89. package/dist/telemetry/tool-failure.js +123 -0
  90. package/dist/telemetry/tool-failure.js.map +1 -0
  91. package/docs/plans/harness-engineering-uplift-2026-07-31.md +280 -0
  92. package/package.json +1 -1
  93. package/src/policies/enforcers/__pycache__/_common.cpython-312.pyc +0 -0
  94. package/templates/hooks/__pycache__/deliver_autoroute.cpython-312.pyc +0 -0
  95. package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-312.pyc +0 -0
@@ -0,0 +1,280 @@
1
+ # Harness-engineering uplift — 2026-07-31
2
+
3
+ ## Motivation
4
+
5
+ Three 2026 papers converge on one claim: **the harness, not the model, is the
6
+ binding constraint on agent reliability** — and they disagree with the folklore
7
+ about *which parts* of the harness matter.
8
+
9
+ | Source | Claim | Number |
10
+ |---|---|---|
11
+ | [Stop Comparing LLM Agents Without Disclosing the Harness](https://arxiv.org/abs/2605.23950) | Controlled factorial: harness variance dominates model variance | HV 18.48 pp² vs MV 2.37 pp² = **7.8×**; 6 of 9 model rankings *reverse* across harnesses |
12
+ | Pi Research / Grok Code Fast (via the above) | Changing **only the edit-tool format** | SWE-bench **6.7% → 68.3%** |
13
+ | [Agentic Harness Engineering](https://arxiv.org/abs/2604.25850) | Observability-driven auto-evolution of a coding harness, base model fixed | Terminal-Bench 2 **69.7% → 77.0%** |
14
+ | [Memory is Reconstructed, Not Retrieved](https://arxiv.org/abs/2606.06036) | Active reconstruction over a Cue–Tag–Content graph beats retrieve-then-reason | **+23%** LoCoMo; **118k** tokens/query vs A-Mem 632k, LangMem 3.26M; 586s vs 1122s |
15
+ | [Agent Harness Engineering: A Survey](https://picrew.github.io/LLM-Harness/) | ETCLOVG seven-layer taxonomy; "the harness is becoming the binding constraint" | *(no comparative scores cited — see Provenance)* |
16
+
17
+ ### Provenance note
18
+
19
+ The widely-shared framing ("the ETCLOVG survey proves 6.7% → 68.3%") **conflates
20
+ two sources**. The survey cites no comparative scores at all. The 6.7% → 68.3%
21
+ figure is the Grok Code Fast edit-tool-format result, reported in the
22
+ harness-disclosure paper. The claim survives, but the *mechanism* is far more
23
+ specific than "optimize the harness": **the edit tool was the lever.** This plan
24
+ is built on the mechanism, not the slogan.
25
+
26
+ ### The ablation that drives this plan
27
+
28
+ Agentic Harness Engineering evolved each harness component in isolation:
29
+
30
+ | Component evolved alone | Δ pass@1 |
31
+ |---|---|
32
+ | Long-term memory | **+5.6pp** |
33
+ | Tools | **+3.3pp** |
34
+ | Middleware | **+2.2pp** |
35
+ | System prompt | **−2.3pp** |
36
+
37
+ Prompt-only edits are **negative**. Gains concentrate in tools, middleware, and
38
+ memory. Gains are **non-additive** — component deltas do not sum.
39
+
40
+ ---
41
+
42
+ ## UAP scored against ETCLOVG
43
+
44
+ | Layer | UAP today | Gap |
45
+ |---|---|---|
46
+ | **E** Execution | `src/cli/sandbox.ts`, `delivery/sanitized-env.ts`, `verifier-ladder.ts`, execution-gate (vm-dom / child-process) | No container/microVM isolation tier. Low benchmark yield; deferred |
47
+ | **T** Tool | `delivery/agentic-executor.ts` (6 tools), MCP router, `toolcall-path-normalizer` middleware | **`edit_file` is exact-match only**: miss → dead turn. No fuzzy fallback, no nearest-match hint, no line-anchored variant, no batch edit, **no per-call outcome telemetry** |
48
+ | **C** Context/Memory | Qdrant semantic store, `memory/dynamic-retrieval.ts`, `hierarchical-memory.ts`, `knowledge-graph.ts`, compressors | **Passive retrieve-then-reason.** KG exists but is not a traversal substrate |
49
+ | **L** Lifecycle | orchestrator, epics, hands-free, HALO, decompose | Mature |
50
+ | **O** Observability | telemetry.db (`sessions`, `routing_decisions`, `time_series`, …), dashboard, `self-harness/trace-mine.ts` | **No per-tool-call outcome table.** No component-attributed failure corpus. Mutation proposal is therefore blind search |
51
+ | **V** Verification | `uap verify`, acceptance judge, execution gate, expert-review, `bench paired` + held-out suite | Best-in-class — but underused *as a search signal* |
52
+ | **G** Governance | policies, enforcers, self-protect, workdir-scope | Mature |
53
+
54
+ ### The structural finding
55
+
56
+ `src/self-harness/validate.ts` auto-validates **`env` mods only** — inference
57
+ server launch knobs. `ScaffoldMod` and `MiddlewareMod` are explicitly routed to
58
+ a human-gated pending queue and return a null (no-lift) comparison so `decide`
59
+ rejects them.
60
+
61
+ > UAP's autonomous self-evolution loop searches the one surface the literature
62
+ > does not even list as a lever, while the three surfaces with measured
63
+ > +5.6 / +3.3 / +2.2pp are gated behind a human.
64
+
65
+ Inverting that is the largest structural gain available.
66
+
67
+ ---
68
+
69
+ ## Options
70
+
71
+ ### A. Edit-tool hardening (T) — highest evidence-to-effort
72
+
73
+ `edit_file` fails hard on exact-match miss. Every miss is a wasted turn, and on
74
+ small local models misses are the dominant tool failure.
75
+
76
+ - **A1 — Tolerant matching (recommended).** On exact-match miss, retry with a
77
+ whitespace/indentation-normalized match; if that resolves to exactly one span,
78
+ apply it and tell the model its `old_string` was whitespace-inexact.
79
+ - **A2 — Nearest-match diagnostics (recommended).** On genuine miss, return the
80
+ closest candidate span in the file as a diff instead of "not found". Turns a
81
+ dead turn into a corrective one.
82
+ - **A3 — `edit_range` line-anchored variant (recommended).** `{path, start_line,
83
+ end_line, new_text}`. Models that cannot reproduce exact whitespace *can*
84
+ count lines.
85
+ - **A4 — Batch multi-edit.** `edit_file` accepting an `edits[]` array, applied
86
+ atomically. Fewer round-trips, no interleaved-state hazards.
87
+ - **A5 — Edit-outcome telemetry (required for D).** Record every edit attempt:
88
+ tool, path, outcome class, bytes changed, turn index.
89
+
90
+ ### B. Invert the self-harness search space (V/O) — largest structural gain
91
+
92
+ - **B1 — Tool-schema mods first-class (recommended).** Add `ToolMod` to
93
+ `self-harness/mods.ts` with an allowlist of safe tool-surface knobs (edit-match
94
+ strategy, read window, error verbosity), routed through the same paired
95
+ validator `env` mods use.
96
+ - **B2 — Middleware mods auto-validated (recommended).** `MiddlewareMod` already
97
+ exists but returns a null comparison. Give it a real A/B: middleware is a
98
+ config change, so the arms differ by a flag, not a server restart.
99
+ - **B3 — Risk tiers, not category bans.** Keep the human gate as a *tier* for
100
+ high-blast-radius mods rather than a blanket category rejection.
101
+
102
+ ### C. Prediction manifests + file-granular rollback (O)
103
+
104
+ Each proposed mod declares which tasks it predicts it will fix and which it puts
105
+ at risk. The next round verifies prediction against actual per-task delta and
106
+ reverts at file granularity. "Each edit becomes a falsifiable contract."
107
+ UAP has propose → validate → decide but no manifest-attribution-rollback.
108
+
109
+ ### D. Evidence corpus / Agent Debugger (O) — prerequisite for B and C
110
+
111
+ - **D1 — `tool_calls` telemetry table (recommended).** run, task, component,
112
+ tool, outcome, error class, turn index, latency, bytes.
113
+ - **D2 — Failure taxonomy (recommended).** Classify every failed call into a
114
+ stable error class so classes can be counted, ranked, and targeted.
115
+ - **D3 — Layered evidence distillation.** Per-task failure analysis plus a
116
+ benchmark-level overview with per-component attribution, consumed by the
117
+ propose stage. Without it, mutation proposal is blind search.
118
+
119
+ ### E. Active memory reconstruction (C) — biggest headline number, biggest build
120
+
121
+ Port MRAgent's Cue–Tag–Content graph onto `knowledge-graph.ts` and make
122
+ retrieval an iterative traverse-and-prune loop rather than one-shot semantic
123
+ search. Directly attacks the recorded context-overflow failure on monolithic
124
+ epic builds.
125
+
126
+ Ablation warning: **the tag layer is the contribution.** Cue→Content without
127
+ tags scores ~65% recall vs ~90% for the full structure. A "graph memory" that
128
+ skips tags gets none of the benefit.
129
+
130
+ - **E1 — Cue/Tag/Content extraction + graph build.**
131
+ - **E2 — Active traversal loop** with action selection, semantic pruning, and a
132
+ sufficiency stop condition (papers converge at 3–4 turns).
133
+ - **E3 — Wire behind an opt-in flag**, off by default until paired bench shows lift.
134
+
135
+ ### F. Harness disclosure card (cross-cutting) — cheap, load-bearing
136
+
137
+ Emit an ETCSOVG card with every `bench paired` result: execution substrate, tool
138
+ list + schema style + error format, context caps and retrieval method,
139
+ scheduling/stop/retry rules, logged artifacts, verification rails, permission
140
+ model. Two payoffs: results become reproducible/comparable, **and the card
141
+ defines the search space that B mutates over.**
142
+
143
+ ### G. Execution isolation tier (E) — deferred
144
+
145
+ Container/microVM tier for untrusted runs. Blast-radius play, not a quality
146
+ play; low expected benchmark lift. Not in this plan.
147
+
148
+ ---
149
+
150
+ ## Sequencing
151
+
152
+ **F → D → A → C → B → E.**
153
+
154
+ F and D are cheap and load-bearing for everything after. A ships independently
155
+ and carries the strongest evidence. C + B together flip the self-evolution loop
156
+ onto the high-yield surfaces. E is sized like its own epic.
157
+
158
+ ## Constraints to respect
159
+
160
+ 1. **Harness coupling problem** (survey): optimizing a layer in isolation can
161
+ degrade the whole. Nothing here is accepted on reasoning alone.
162
+ 2. **Non-additivity** (AHE): component gains do not sum; aggregate lift is capped
163
+ below the sum of the ablations. Do not forecast stacked deltas.
164
+ 3. **Every mod validates through `uap bench paired`** with the existing held-out
165
+ disjoint suite for overfit detection — the machinery already exists.
166
+ 4. **Prompt-only edits measured negative.** Do not spend search budget there.
167
+
168
+ ## Validation review (recorded 2026-07-31)
169
+
170
+ - *Assumption*: edit-tool format is the dominant tool-layer lever. **Risk**: the
171
+ Grok case started from a *bad* format; UAP's `edit_file` is already exact-match
172
+ with corrective errors, so headroom is smaller. **Mitigation**: measure, do not
173
+ forecast a delta.
174
+ - *Risk*: tool-schema changes regress the strong-model path. **Mitigation**:
175
+ tolerant matching runs strictly *after* exact match; new tools are additive and
176
+ the tolerant path is a config knob defaulting to on only for the fallback.
177
+ - *Risk*: per-call telemetry write volume. **Mitigation**: WAL + bounded retention.
178
+ - *Gap*: E is epic-sized; phased and off by default.
179
+ - *Request match*: yes — analyze the cited posts, plan options, implement, ship.
180
+
181
+ ## Acceptance — 2026-07-31
182
+
183
+ Split honestly into **connected** (runs on a real code path) and **landed**
184
+ (implemented and tested, but nothing calls it yet). A plan that marks the second
185
+ as the first is the most expensive kind of debt in a self-modifying system.
186
+
187
+ ### Connected
188
+
189
+ - **A — edit-tool ladder.** `src/delivery/edit-match.ts`, wired into
190
+ `edit_file`/`edit_range` in the agentic executor. Exact → whitespace-tolerant
191
+ (indent-preserving on Python/YAML/Make) → nearest-region report; atomic
192
+ `edits[]` batches; line-anchored `edit_range`. On by default.
193
+ - **D — evidence corpus.** `tool_calls` written by every executor tool call,
194
+ classified by `src/telemetry/tool-failure.ts`, distilled by
195
+ `summarizeToolCalls`, readable via `uap harness evidence`.
196
+ - **D→B — evidence proposer.** `src/self-harness/evidence-proposer.ts` reads the
197
+ corpus and emits `ToolMod`s. Without it the corpus was written but unread and
198
+ `ToolMod` was defined but never proposed.
199
+ - **B — tool/middleware auto-validation.** `ToolMod` + `TOOL_KNOB_ALLOWLIST`;
200
+ `buildValidator` A/Bs both kinds through the paired validator; `promotionGate`
201
+ is a risk tier. The `toolcall-path-normalizer` is now gated on
202
+ `UAP_MW_TOOLCALL_PATH_NORMALIZER`, so its A/B varies something real.
203
+ - **F — disclosure card.** `uap bench paired` passes a `HarnessCardInput`, so
204
+ every paired report carries its ETCSOVG card. `uap harness card` prints the
205
+ live one.
206
+ - **C — change manifests.** `runSelfHarnessLoop` threads `manifests` /
207
+ `priorRecords` into the orchestrator, so stage 0 attribution and revert run on
208
+ the real loop, not only in tests.
209
+ - **E — active memory reconstruction.** `reconstruct-ingest.ts` turns UAP's
210
+ memory entries into cue–tag–content triples (deterministic extractor behind an
211
+ injectable seam, mirroring `ReconstructionPolicy`); `reconstruct-store.ts`
212
+ builds the derived graph from **both** memory tiers and exposes `recallActive`;
213
+ `uap memory graph build|status` and `uap memory query --active` are the
214
+ callers. Verified on the real store: 50 memories → 462 cues, 77 tags, **19
215
+ bridging tags**, and a five-hop traversal that reaches evidence the query never
216
+ names. Opt-in (`--active` / `UAP_MEMORY_ACTIVE=1`), refuses to route to an
217
+ empty graph, and **falls back to passive retrieval** when reconstruction finds
218
+ nothing or throws.
219
+
220
+ ### Not done (deliberately)
221
+
222
+ - **E, remaining.** The extractor is deterministic rather than the paper's LLM
223
+ extraction — a seam, not a rewrite. And no *agent* code path calls
224
+ `recallActive` yet: `dynamic-retrieval.ts` (what assembles model context) is
225
+ untouched, so today this changes what a **human** gets from `uap memory query`,
226
+ not what a **model** is given. The AHE memory ablation (+5.6pp) is about the
227
+ latter; claiming that number for this would be wrong.
228
+ - **G** (container/microVM execution tier) — blast-radius work, no measured
229
+ benchmark lift. Out of scope.
230
+ - No uplift figure is claimed. Every mechanism here is wired and tested; which of
231
+ them pays on OUR suite is what `uap bench paired` is for, and that run has not
232
+ happened yet. The literature's numbers are the literature's.
233
+
234
+ ## E-connection review (second pass)
235
+
236
+ Connecting E drew its own parallel review; the blockers it found:
237
+
238
+ | # | Defect | Fix |
239
+ |---|---|---|
240
+ | 1 | **`--active` silently dropped long-term memory.** The passive path queries short-term FTS *and* Qdrant; active replaced it with a graph built from the rolling ~50-entry short-term window only. A regression wearing a feature's clothes | `itemsFromLongTerm` ingests the semantic store; coverage reported per tier; falls back to passive when reconstruction is empty or throws |
241
+ | 2 | `--rebuild` duplicated the corpus instead of rebuilding — it reset the dedupe set without truncating, so two rebuilds meant every memory twice, permanently | `graph.clear()` truncates; test asserts `stats().contents` |
242
+ | 3 | Items skipped for "no cue" were marked ingested, dropping them forever — including after the extractor seam is upgraded | `seen.add` only after a successful store; `storedKeys` returned and marked |
243
+ | 4 | Ledger keyed on source id alone, so `uap memory correct` never reached the graph — it served pre-correction text forever | Key includes a content hash and the extractor id |
244
+ | 5 | The per-query refresh used `projectId: 'project'` and ignored the configured store path, so it indexed zero rows for any real project | `resolveStoreConfig` mirrors `uap memory query` |
245
+ | 6 | Default policy stopped after ONE hop (`sufficientAt: 3`) — every test had to override it, so the multi-hop mechanism was proven only under a policy the product did not ship | Default raised to 12 |
246
+ | 7 | `maxExpandPerStep` lived only inside the default policy, so the first LLM policy would reproduce the 453-cue full scan | Enforced in `reconstruct`, intersected with the active set |
247
+ | 8 | STOPWORDS were bypassed by the identifier regex — "The deploy failed" produced the cue `the` | Stopwords applied to identifiers |
248
+ | 9 | `type` and `when:YYYY-MM` derived tags are hubs, not bridges (a month links everything written that month), and inflated the `bridgingTags` health metric | Hubs only as a last-resort edge; bridging requires <60% corpus coverage |
249
+ | 10 | `bench paired` hardcoded `memoryMode`, so its card would state the wrong mode | One `describeMemoryMode`; `C.memory_mode` added to `MUTABLE_CARD_FIELDS` |
250
+ | 11 | Short-term handle leaked when the read threw — once per query, since recall refreshes every call | `close()` in `finally` |
251
+ | 12 | `--steps abc` produced NaN → zero iterations → "No evidence survived pruning", a false statement | `positiveInt` validation |
252
+ | 13 | `shouldUseActiveRecall` ran five aggregates on every query and card render | Cheap `isEmpty()` probe; added the missing `mg_triples(tag)` index |
253
+ | 14 | Context-budget overflow was reported as "pruned" and advised raising `--steps`, which cannot help | Separate `dropped` list and a `stopReason` |
254
+
255
+ ## Defects found and fixed during review
256
+
257
+ Parallel expert review (code-quality / security / architecture) found real
258
+ defects in the first cut. The ones that mattered:
259
+
260
+ | # | Defect | Fix |
261
+ |---|---|---|
262
+ | 1 | `edit_range`/`edit_file` bypassed the anti-gutting guard — `edit_range(1, N, "")` deleted a file and returned OK, while `write_file`'s refusal text names edit_file as the alternative. The escape route was the bypass. | `editGuttingRefusal` on both edit paths + regression tests |
263
+ | 2 | Tolerant matching dropped leading whitespace, so an anchor in one Python block bound to another, and the replacement landed at column 0 | Indent preserved for indent-sensitive languages; replacement re-indented onto the target |
264
+ | 3 | Tolerant rung left the original trailing newline, so the same (old,new) pair produced different files depending on which rung fired | One trailing newline stripped on the line-aligned path, matching `applyRangeEdit` |
265
+ | 4 | `occurrence` was re-indexed against the normalised candidate list — a different set — landing the edit at an unrelated site and reporting success | Multi-site tolerant matches are refused outright |
266
+ | 5 | `classifyToolResult` filed every failed `run_bash` as `ok` (results start `exit=`, not `ERROR:`), leaving `command-failed` dead code and the execution component permanently healthy | Classified by exit code; `refused` and `tamper-restored` classes added |
267
+ | 6 | The corpus was written under `projectRoot` — discarded temp dirs for bench cells, and `agents/data/` inside customer repos — while `uap harness evidence` read `process.cwd()` | Single per-user root under `~/.uap/telemetry`, overridable |
268
+ | 7 | Row cap keyed off a per-process counter that never reached it; handle cache unbounded across bench cells | Prune on open; LRU-capped handle cache |
269
+ | 8 | `detail` persisted the nearest-region report — user source excerpts — indefinitely | First line only |
270
+ | 9 | Middleware A/B was a null experiment: `middlewareEnvKey` was read by nothing, so both arms were identical and `decide` accepts on `netGain > 0` alone | Normalizer gated on that key |
271
+ | 10 | `validate.ts` restored env by the Mod's *claimed* `from`, leaking a wrong value into every later candidate; no allow-list check at the apply site | Observed prior captured; `validateMod` enforced |
272
+ | 11 | `run.ts` committed only `env` Mods but reported ALL accepted Mods as committed | Per-kind disposition; `unapplied` reported |
273
+ | 12 | `passingTasks` ignored `condition`, so on a real two-arm `records.jsonl` every predicted fix read as unrealised and `revertOnZeroRealised` would revert everything | Condition-scoped, majority-of-seeds pass ratio |
274
+ | 13 | A task absent from the later round scored as an undeclared regression → immediate revert | Intersection, not union |
275
+ | 14 | Stage 0 reverted into `profile` but stage 2 proposed from `opts.profile` | Propose from the post-revert profile |
276
+ | 15 | `edit_file` never ran the agent-internal guard `write_file` has, so `.uap/`, `.git/`, `node_modules` were editable through it | Guard added to both edit paths |
277
+ | 16 | `attributeWeakness` ran after the profile mutation, so it returned null and the transfer store lost attribution too | Computed once, before any mutation |
278
+ | 17 | Card read `process.env` at render time and hardcoded `read_window_bytes`; `UAP_STUB_GUARD` is not a real variable | All varying fields injected; correct guard names |
279
+ | 18 | Nearest-region report ignored its own line cap — a 200-line anchor echoed 200 lines into context | Bounded by `maxLines` |
280
+ | 19 | Batch edits had no size cap, no `new_string` requirement, and silently dropped the top-level pair when both forms were sent | Capped at 64; explicit errors |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miller-tech/uap",
3
- "version": "1.175.13",
3
+ "version": "1.178.0",
4
4
  "description": "Autonomous AI agent memory system with CLAUDE.md protocol enforcement",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",