@miller-tech/uap 2.48.1 → 2.48.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.
@@ -14,7 +14,6 @@
14
14
  "qwen38-gsq-rco-27b",
15
15
  "qwen3.8-flash-next-iq3_s",
16
16
  "swift-1.5-iq3_s",
17
- "Qwen3.8-27B",
18
17
  "Qwen3.8-27B-EXL3-3.5bpw"
19
18
  ],
20
19
  "models": {
@@ -306,3 +306,164 @@ Finding 1.
306
306
  "Opus 5.5 / Fable 5.2 levels" lever on this box today.
307
307
  - **R2-D — Re-measure after R2-A:** the post-client-update window is the
308
308
  honest post-fix read; era B's zeros become testable at population scale.
309
+
310
+ ---
311
+
312
+ ## Monitoring round 3 (2026-11-14 late) — the post-fix read at scale, and what the instrument was actually measuring
313
+
314
+ Post-state: client 2.48.2 global (O-C hints + readGate + turnpack live),
315
+ proxy 2.48.x with the O-D shim, baseModelId shipped (Droid treats the local
316
+ arm as the qwen3.8-max built-in class). The first window with BOTH layers
317
+ fixed: 916 calls, 09:50–11:15 UTC, 13 runs.
318
+
319
+ ### The fixes hold at scale — the first true post-fix read
320
+
321
+ | Class | Era A (pre, n=19,794) | Era C (post, n=916) |
322
+ |---|---:|---:|
323
+ | ok | 75.5% | **80.2%** |
324
+ | edit-miss | 3.2% | **0** |
325
+ | path-not-found | 2.6% | **0** |
326
+ | stub-refusal | 5.4% | 7.6% (all write_file) |
327
+ | refused | 2.2% | 3.3% (all run_bash) |
328
+
329
+ **edit-miss and path-not-found — the two classes O-C and turnpack were
330
+ built for — are zero at n=916**, including adversarial fixtures designed
331
+ to trigger them. ok-rate +4.7 points. The lever that remains un-shrunk is
332
+ stub-refusal.
333
+
334
+ ### The instrument finding: era B and era C are both mostly TEST traffic
335
+
336
+ The era-C stub-refusals all carry fixture paths (`src/big.ts`, `big.js`,
337
+ `js/player.js` — deliberate gutting attempts at turn=1 in deliver-gate
338
+ test tasks, i.e. the guard PASSING). Top era-C paths are fixtures
339
+ (`a.js` 380, `b.js`/`big.js` 70 each); the real-path remainder is small.
340
+ Era B's round-2 samples were the same fixtures. **The tool-calls DB pools
341
+ benchmark-harness traffic with live-client traffic**, so corpus-level
342
+ "class rates" blend a guard's self-tests with real client behavior —
343
+ future monitoring must segment first (the working recipe: filter on the
344
+ fixture path set + `.uap-deliver/verify.sh`, or segment by `task_id`).
345
+ Era-C's honest split: fixture traffic shows the fixed layer passing its
346
+ own adversarial tests; the live-client signal is thin (the kubectl
347
+ deliver contributed 24 kubectl/doctl-pathed calls).
348
+
349
+ ### The live client cost evidence
350
+
351
+ The kubectl deliver (the live interactive client, floor arm via
352
+ local-auto, `--max-turns 20`) is **2h29m in** on a credential-permission
353
+ ops task. The O-B reference: 6 gate-verified tasks in 4.7 min on glm-5.3.
354
+ Arm + arm-tier remains the dominant cost factor.
355
+
356
+ ### The levers now (R3)
357
+
358
+ - **R3-A — Frontier-class sessions route by tier (the literal ask):** the
359
+ Factory catalog now carries `claude-opus-5-5` (1.6x) and
360
+ `claude-fable-5.2` (3.2x) as built-ins — "Opus 5.5 / Fable 5.2 levels"
361
+ is a MODEL ROUTING choice, one flag per session. Measured reference
362
+ (glm-5.3 on the O-B suite): identical gates at 1/24 the tool volume and
363
+ 1/10 the wall time. Suggested split: glm-5.3 default (measured, cheap),
364
+ opus-5-5/fable-5.2 for the hardest tier, local arm for
365
+ cost-insensitive/background work.
366
+ - **R3-B — v31 arm switch (was O-A/R2-B, still unexecuted):** iq2_xs
367
+ still serves all client work; the strata unit additionally sits in the
368
+ panel-race latch state (failed+disabled with a live engine process
369
+ holding :8080). Recovery + switch is the documented one-liner
370
+ (`systemctl --user reset-failed` + `model-switch.sh strata`) — operator
371
+ action (infra-protect).
372
+ - **R3-C — baseModelId seam (shipped, unmeasured):** local-arm Droid
373
+ sessions now inherit qwen3.8-max-class prompts, tool conventions,
374
+ reasoning levels, and Script-mode eligibility. The first local-arm
375
+ Droid sessions post-change (a live three.js client was streaming
376
+ through the proxy at 22:31) are the watch window.
377
+ - **R3-D — telemetry run-kind tagging:** the era-B/C misread argues for a
378
+ `run_kind` tag (test vs live) at the classifier, or at minimum the
379
+ fixture-path segmentation recipe documented here. Small change, next
380
+ tools round.
381
+ - **R3-E — stub-refusal remains the top live class:** in live traffic it
382
+ is the gutting guard + readGate doing their jobs; the open question is
383
+ whether read-after-refusal recovery got FASTER (429 successful reads in
384
+ era C vs the era-A re-send loops). Needs a live-session segment large
385
+ enough to read.
386
+
387
+ ---
388
+
389
+ ## Monitoring round 4 (2026-11-15 early) — the per-turn budget is the wall-clock bottleneck the arm ladder alone can't fix
390
+
391
+ Post-state: client 2.48.2 global (O-C + turnpack live in every new
392
+ session), proxy 2.48.x with the O-D shim, baseModelId live, and the GPU
393
+ operating point shipped by the infra round (bf16 unlocked on the fleet
394
+ binaries, 370 W power limit, SM clock locked at 1800 MHz — idle-verified
395
+ 188 W/1800 MHz/65 °C; boot-default confirmation pending the next reboot).
396
+
397
+ ### Finding 1 — the live client's real-path calls went 34/34 ok (first clean live run)
398
+
399
+ The kubectl deliver (floor arm, `--max-turns 20`) ended at ~2h45m with
400
+ **every real-path tool call ok** — 34/34 kubectl/doctl-pathed calls, max
401
+ turn 12, and its final 14 calls (11:42–11:46 UTC) all ok (8 read_file,
402
+ 4 list_dir, 1 edit_file, 1 write_file). The fixed tool layer's first
403
+ complete live run shows zero failures on real paths; the failure classes
404
+ still visible in the corpus (round 3) are the guards' own fixtures. The
405
+ deliver exited without writing its `[deliver]` lesson (no memory entry, no
406
+ task record, no OOM, no reboot — cause unknown; the telemetry DB is its
407
+ only record).
408
+
409
+ ### Finding 2 — the per-turn generation budget, now measured
410
+
411
+ A live session on the floor arm was streaming with the engine capping
412
+ `thinking limited to 24576 of max_tokens 32768` — 21 capped generations
413
+ in ~17 minutes, i.e. routine thinking-heavy turns near the 32k budget.
414
+ At the measured deep-context decode rate (126 tok/s) a full-budget turn
415
+ is a ~4.3-minute floor **before tool volume even starts**. The O-B suite
416
+ hit the 480 s ceiling on 5/6 local tasks after the file work was done,
417
+ and the kubectl deliver had a 45-minute stretch with zero tool calls
418
+ (one long turn). Tool volume (O-B's ~24x) and per-turn budget multiply
419
+ into the ~10x wall gap.
420
+
421
+ ### Finding 3 — the GPU operating point is measurable on the serving arm
422
+
423
+ Inference health on the live arm post-operating-point: decode
424
+ 113 → 126 tok/s in the >30k-depth bucket (n=6/6), speculative drafts
425
+ accepted 67%, prompt-cache reuse 56% (~17,560 tok re-read per turn),
426
+ vram 3,046 MiB free. The arm tier (R3-B) and the operating point stack.
427
+ The box is otherwise loaded (100/121 GB used, load 13–22), so idle-window
428
+ reruns will read cleaner than this sample.
429
+
430
+ ### The levers now (R4)
431
+
432
+ - **R4-A — Thinking-budget discipline (new, the biggest untried
433
+ wall-clock lever):** routine tool turns do not need 24.5k thinking
434
+ tokens. The engine reserves 8k for the answer at max_tokens 32768
435
+ (the serve log names the knob: `"answer_room": false` turns the cap
436
+ off); a lower thinking budget — or a lower client max_tokens for
437
+ tool-heavy turns — cuts the per-turn floor from ~4.3 min toward
438
+ ~1.5–2 min (12k thinking ≈ 95 s at 126 tok/s). Verify gate parity on
439
+ the R4-B rerun. Knobs: the strata engine config (operator) or request
440
+ shaping at the proxy (UAP, a tools-round change).
441
+ - **R4-B — Arm tier + operating point, measured together (R3-B + the
442
+ GPU round):** rerun the archived O-B paired suite on v31 under the
443
+ new operating point against the archived iq2_xs baseline — one
444
+ repeatable run quantifies the stacked local-arm gain (tier + 11%
445
+ decode + bf16). Still gated on the operator arm switch (the strata
446
+ unit's latch-state recovery).
447
+ - **R4-C — Draft acceptance 67% → higher:** each acceptance point is
448
+ free decode; the speculative drafter's spec config (topK/epsilon) is
449
+ tunable on the strata engine.
450
+ - **R4-D — Cache reuse 56%:** 17.5k tok/turn re-read at depth; the
451
+ health tool found no prefill bucket with enough samples to split, so
452
+ measure prefill in the R4-B rerun (the Sharp template + turnpack
453
+ context discipline target this).
454
+ - **R4-E — Deliver-lesson gap:** abnormal deliver termination writes no
455
+ `[deliver]` lesson, so the kubectl run's outcome exists only in
456
+ telemetry. Write the lesson on every exit path — small harness change,
457
+ next tools round.
458
+
459
+ Routing unchanged from R3-A: frontier-class sessions route by tier
460
+ (glm-5.3 measured default; opus-5-5 / fable-5.2 for the hardest tier).
461
+ Outcome equivalence is already demonstrated (O-B gates TIED 13/13);
462
+ R4 is about closing the wall-clock gap on the local arm.
463
+
464
+ **Caveats (labeled):** the decode 113→126 comparison is bucket-vs-bucket
465
+ in the engine's ring log (no timestamps; `--since` could not be applied),
466
+ n=6/6 directional. The live-cadence count (21 caps/~17 min) is journal
467
+ grep on the serve log, one session. The 34/34 ok count covers real-path
468
+ calls only; the deliver's gate outcome is unknown (Finding 1's lesson
469
+ gap).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miller-tech/uap",
3
- "version": "2.48.1",
3
+ "version": "2.48.3",
4
4
  "description": "Autonomous AI agent memory system with CLAUDE.md protocol enforcement",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -66,6 +66,33 @@ _UAP_DROID_SYNC_CONTRACTS_LOADED=1
66
66
  # local model id — it must never carry a qwen id.
67
67
  : "${DROID_ANTHROPIC_BASE_MODEL:=claude-sonnet-4-6}"
68
68
 
69
+ # DROID_CHAT_BASE_MODEL — the Factory BUILT-IN catalog id written into
70
+ # `baseModelId` of the OpenAI-shaped local entries (the proxy chat /v1 route
71
+ # and the direct Responses :8080 route). qwen3.8-max is the choice because the
72
+ # served stack IS the Qwen3.8 family (Flash-Next 125B arms and its Edge0-145B
73
+ # latent-MoE derivative): the entry inherits the built-in's Qwen3.8-class
74
+ # prompts, tool-call conventions, reasoning levels, and Script-mode
75
+ # eligibility instead of tripping the "does not map to a built-in model"
76
+ # warning. Same family, same catalog — this is a BUILT-IN id, never a local
77
+ # wire id: it must never be the served alias, a retired arm, or anything the
78
+ # registry's advertises lists carry. (The prefix-era guard "never a qwen id"
79
+ # predates the Factory catalog gaining Qwen3.8 built-ins; the exact local-id
80
+ # check lives in the sandbox suite.)
81
+ : "${DROID_CHAT_BASE_MODEL:=qwen3.8-max}"
82
+
83
+ # DROID_LOCAL_27B_PIN / DROID_LOCAL_27B_DISPLAY — the SECOND local family the
84
+ # Droid pickers list alongside the live Flash-Next alias: the registry's
85
+ # qwen3.8-27b family (the llama.cpp / yskn / vLLM 27B arms — same :4000/:8080
86
+ # endpoints, the engine serves whichever arm is switched live, so the entry
87
+ # is a FAMILY LISTING, not a route switch; when placement turns on, the pin
88
+ # is registry-matchable). The pin must be an id that family advertises —
89
+ # checked against config/model-registry.json at sync time, fail-closed to
90
+ # skip-adding. A camelCase entry carrying the 27B marker id
91
+ # (custom:Qwen…-27B-UAP-local-N) is a DELIBERATE listing: the convergence
92
+ # loop never repoints or renames it, it only stamps baseModelId when absent.
93
+ : "${DROID_LOCAL_27B_PIN:=Qwen3.8-27B}"
94
+ : "${DROID_LOCAL_27B_DISPLAY:=Qwen3.8 27B (UAP local)}"
95
+
69
96
  # DROID_SYNC_LOCK — lock file serialising concurrent Droid config writes
70
97
  # (session-start hook + manual installer run + a second Droid window).
71
98
  # Without it two writers read-modify-write the same JSON and one set of
@@ -95,19 +122,37 @@ fi
95
122
  # in place or left alone. "0" = patch only when present.
96
123
  # Reads from the caller's scope: MODEL_ALIAS, PROXY_URL, DIRECT_URL,
97
124
  # CTX_SESSION, CTX_POOL, MAX_OUTPUT, DROID_ANTHROPIC_BASE_MODEL,
125
+ # DROID_CHAT_BASE_MODEL, DROID_LOCAL_27B_PIN, DROID_LOCAL_27B_DISPLAY,
98
126
  # PROXY_TOKEN (via UAP_SYNC_TOKEN env), DRY_RUN.
99
127
  # Migration rules (idempotent; no change => file left byte-identical):
100
- # * entries whose model is a RETIRED local id — or already the live
101
- # alias, or model-less but pointed at :4000/:8080 — converge onto
102
- # MODEL_ALIAS;
128
+ # * entries whose model is a RETIRED local id — already the live alias,
129
+ # a FLEET wire id (any registry advertises entry) pointed at this
130
+ # box's :4000/:8080, or model-less but pointed at :4000/:8080 —
131
+ # converge onto MODEL_ALIAS (fleet ids are gated on a local base:
132
+ # the compat names collide with real cloud ids, so a cloud-router
133
+ # entry carrying one survives untouched);
134
+ # * a camelCase entry whose id carries the 27B marker
135
+ # (custom:Qwen…-27B-UAP-local-N) is a DELIBERATE family listing:
136
+ # it is skipped by the convergence loop (only baseModelId is
137
+ # stamped when absent) and is preferred over non-marker members
138
+ # in its dedupe group;
103
139
  # * route by existing shape: baseUrl with :8080 -> direct strata route
104
140
  # (pool-sized); :4000 WITHOUT /v1 -> Anthropic Messages root (proxy
105
- # root + baseModelId + apiKey only if absent, session-sized); anything
106
- # else local -> proxy chat route ($PROXY_URL/v1 + token);
141
+ # root + baseModelId=DROID_ANTHROPIC_BASE_MODEL + apiKey only if
142
+ # absent, session-sized); anything else local -> proxy chat route
143
+ # ($PROXY_URL/v1 + token); every camelCase local route also gains
144
+ # baseModelId (anthropic shape -> DROID_ANTHROPIC_BASE_MODEL, OpenAI
145
+ # shapes -> DROID_CHAT_BASE_MODEL) when absent, so Droid inherits the
146
+ # built-in's prompts/tools/reasoning instead of warning the entry
147
+ # "does not map to a built-in model";
107
148
  # * cloud models (anything else, including the :8317 router entries) are
108
149
  # deliberate user choices and are never repointed;
109
150
  # * a settings.json with NO local entry after migration gains the
110
- # canonical proxy entry (add-if-missing);
151
+ # canonical proxy entry (add-if-missing), and gains the 27B family
152
+ # entry (model=DROID_LOCAL_27B_PIN on the proxy chat route, marker
153
+ # id, baseModelId) when the pin is an id the registry's qwen3.8-27b
154
+ # family advertises — the two-family listing: Flash-Next live alias
155
+ # + the 27B family, side by side in every picker;
111
156
  # * the 192.168.1.165:8317 split-brain host is fixed everywhere;
112
157
  # * writes are atomic (tmp file in the same directory + os.replace),
113
158
  # under the flock, with backups taken by the caller's backup().