@miller-tech/uap 2.21.0 → 2.21.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/config/model-profiles/qwen38.json +3 -3
- package/package.json +1 -1
- package/src/policies/enforcers/__pycache__/_common.cpython-312.pyc +0 -0
- package/src/policies/enforcers/__pycache__/expert_review_required.cpython-312.pyc +0 -0
- package/src/policies/enforcers/__pycache__/quality_metrics_gate.cpython-312.pyc +0 -0
- package/src/policies/enforcers/enforcement_self_protect.py +9 -1
- package/templates/hooks/__pycache__/deliver_autoroute.cpython-312.pyc +0 -0
- package/templates/hooks/uap-policy-gate.sh +8 -1
- package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-312.pyc +0 -0
- package/tools/agents/tests/test_enforcement_self_protect.py +19 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_profile": "qwen38",
|
|
3
3
|
"_description": "Qwen3.8 Flash-Next — local Strata serve-layer deployment for agentic tool-calling workloads. Successor to qwen36 and to the 2026-09-20 GSQ-RCO llama.cpp deployment; the default local executor in UAP routing. Routes through the anthropic-proxy for the tool/finalize guardrails, NOT the inference server directly.",
|
|
4
|
-
"_engine": "strata serve layer 0.1.
|
|
4
|
+
"_engine": "strata serve layer 0.1.40.1 (python server 0.1.40.1 + engine binary 0.1.40, compiled locally with a user-space CUDA 13.4 toolkit after the Debian 12.4 headers proved too old for 0.1.40) on :8080, launched by the systemd user unit uap-strata-server.service with /home/cogtek/dev/strata/strata-iq3_s.json. Serves llama.cpp-shaped /props, /slots and /v1, plus a JSON /metrics (engine/live/requests — NOT Prometheus text; `uap inference health` auto-detects it). Weights: strata-data pack iq3_s (Qwen3.8-Flash-Next-GSQ-RCO-IQ3_S since the 2026-10-07 swap per the IQ3_S speed≈IQ3_XXS reports; predecessors Swift 1.5 IQ3_XXS 2026-10-06, Qwen3.8-Flash-Next-GSQ-RCO-IQ3_XXS, native experts + PLE shard) with MTP speculative drafts (spec 8, spec-min-p 0.8 since the 2026-10-06 tuning; previously spec 4, spec-min-p 0.5, mtp_max 4) and an auto-sized expert cache. Model id advertised at /v1/models: qwen3.8-flash-next-iq3_s; the server ignores requested model ids entirely, which is why stale client pins (e.g. a resumed session still naming qwen36 ids) keep working.",
|
|
5
5
|
"_engine_history": "SUPERSEDED 2026-10-04: this profile described buun-llama-cpp behind uap-gsq-rco-server.service (2 rails sharing a 229376-cell VBR pool, DFlash2 draft). That unit is now INACTIVE — the box serves the Strata layer on :8080 instead (tuned 2026-10-03: +15% over the llama.cpp fork on agent workloads). The old description was itself a 2026-09-20 correction of a ninfer-serve description. Verify against /metrics before trusting engine claims here; the dead unit's ExecStart still reports -c 229376 to systemctl, and on 2026-10-04 `uap inference health` printed that stale pool size for the live (131072) backend.",
|
|
6
|
-
"model": "
|
|
6
|
+
"model": "qwen3.8-flash-next-iq3_s",
|
|
7
7
|
"max_tokens": 57344,
|
|
8
8
|
"_max_tokens_comment": "Deliberately generous: 50% of the 114688 window, the same ratio the previous 65536/131072 pairing used. The engine returns chain-of-thought in a SEPARATE reasoning_content field, so reasoning spends completion budget without ever appearing in content. A tight cap therefore does not produce a short answer, it produces an EMPTY one with finish_reason=length — measured previously as ~90% first-turn decode failure that read as bad output format and was really budget truncation. Do not lower this without re-measuring decode compliance. (The proxy additionally clamps tool turns to PROXY_TOOL_TURN_MAX_TOKENS=32768 regardless.)",
|
|
9
9
|
"temperature": 0.3,
|
|
@@ -74,4 +74,4 @@
|
|
|
74
74
|
"endpoint": "http://127.0.0.1:4000/v1",
|
|
75
75
|
"_comment": "Route through the anthropic-proxy, NOT the strata port directly — the proxy applies the tool/finalize guardrails and, via this profile, the per-session context window that clients size their history to. Clients select this profile with the header 'x-uap-model-profile: qwen38' (or a uap_model_profile body param)."
|
|
76
76
|
}
|
|
77
|
-
}
|
|
77
|
+
}
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -734,7 +734,15 @@ def main() -> None:
|
|
|
734
734
|
op, args = parse_cli()
|
|
735
735
|
|
|
736
736
|
if op in EDIT_OPS:
|
|
737
|
-
|
|
737
|
+
# Key list widened for opencode, which sends camelCase `filePath`.
|
|
738
|
+
# It previously landed on the fail-open "no file path in args" branch,
|
|
739
|
+
# so agent edits to protected files (.uap.json, enforcers, hooks) were
|
|
740
|
+
# allowed whenever the caller used a different key convention — the
|
|
741
|
+
# gate armed its fail-closed net, then this enforcer blinked first and
|
|
742
|
+
# allowed. Widening only ever BLOCKS: every added key names a file the
|
|
743
|
+
# agent is editing, not one it is merely reading.
|
|
744
|
+
target = (args.get("file_path") or args.get("filePath") or args.get("path")
|
|
745
|
+
or args.get("target") or args.get("filename") or args.get("file") or "")
|
|
738
746
|
if not target:
|
|
739
747
|
emit(True, "no file path in args")
|
|
740
748
|
rp = Path(target).resolve()
|
|
Binary file
|
|
@@ -252,7 +252,14 @@ except Exception: a = {}
|
|
|
252
252
|
markers = ("/.policy-tools/", "/src/policies/", "/policies/", "/.uap.json",
|
|
253
253
|
".uap.json", "/.uap/", "anthropic-proxy.env", "uap-policy-gate.sh",
|
|
254
254
|
"uap-reactor-prompt.sh", "pre-tool-use")
|
|
255
|
-
|
|
255
|
+
# Key list matches the one at the top of this script (worktree resolution):
|
|
256
|
+
# harnesses disagree on the arg name (file_path vs filePath vs target/…), and
|
|
257
|
+
# an op whose path key this list misses scores SEC_SENSITIVE=0 — arming
|
|
258
|
+
# neither the fail-closed net nor the fastpath skip. Observed live: opencode
|
|
259
|
+
# sends filePath (camelCase), so a trivial agent edit to .uap.json was
|
|
260
|
+
# fast-pathed around the self-protect enforcer. Widening only TIGHTENS.
|
|
261
|
+
target = (a.get("file_path") or a.get("filePath") or a.get("path")
|
|
262
|
+
or a.get("target") or a.get("filename") or a.get("file") or "")
|
|
256
263
|
cmd = a.get("command") or ""
|
|
257
264
|
# Scan the COMMAND as well as file_path. Only file_path was checked, so for
|
|
258
265
|
# every Bash call SEC_SENSITIVE was 0 unless the command set a bypass var --
|
|
Binary file
|
|
@@ -37,6 +37,25 @@ class SelfProtectTest(unittest.TestCase):
|
|
|
37
37
|
rc, out = run("Edit", {"file_path": str(REPO / ".uap.json")})
|
|
38
38
|
self.assertEqual(rc, 2)
|
|
39
39
|
|
|
40
|
+
def test_blocks_edit_to_uap_json_camel_case(self):
|
|
41
|
+
# opencode sends camelCase `filePath`. The extraction previously read
|
|
42
|
+
# only file_path/path/target, so this shape landed on the fail-open
|
|
43
|
+
# "no file path in args" branch and the edit was ALLOWED — observed
|
|
44
|
+
# live: a looping client repeatedly tried to strip a policy flag from
|
|
45
|
+
# .uap.json and every attempt sailed past this enforcer.
|
|
46
|
+
rc, out = run("Edit", {"filePath": str(REPO / ".uap.json"), "oldString": "x", "newString": "y"})
|
|
47
|
+
self.assertEqual(rc, 2)
|
|
48
|
+
self.assertFalse(out["allowed"])
|
|
49
|
+
self.assertIn("BLOCKED", out["reason"])
|
|
50
|
+
|
|
51
|
+
def test_allows_normal_file_edit_camel_case(self):
|
|
52
|
+
# The widened key list must not over-block: an ordinary file named with
|
|
53
|
+
# the same convention still allows, with the same reason as before.
|
|
54
|
+
rc, out = run("Edit", {"filePath": str(REPO / "README.md"), "oldString": "x", "newString": "y"})
|
|
55
|
+
self.assertEqual(rc, 0)
|
|
56
|
+
self.assertTrue(out["allowed"])
|
|
57
|
+
self.assertEqual(out["reason"], "not an enforcement-control file")
|
|
58
|
+
|
|
40
59
|
def test_blocks_edit_to_policy_tools(self):
|
|
41
60
|
rc, out = run("Write", {"file_path": str(REPO / ".policy-tools/abc_delivery_enforcement.py")})
|
|
42
61
|
self.assertEqual(rc, 2)
|