omnilane 0.42.5 → 0.42.7
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +98 -1
- package/README.ja.md +29 -5
- package/README.ko.md +29 -5
- package/README.md +60 -6
- package/README.zh-CN.md +52 -6
- package/README.zh-TW.md +52 -6
- package/VERSION +1 -1
- package/bin/omnilane +8 -0
- package/completions/_omnilane +1 -1
- package/completions/omnilane.bash +1 -1
- package/completions/omnilane.fish +1 -0
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/scripts/dispatch.sh +11 -0
- package/scripts/lib/aa_policy.py +13 -1
- package/scripts/lib/aa_retry.py +3 -1
- package/scripts/lib/build_overlay.py +42 -17
- package/scripts/lib/caller_identity.py +238 -0
- package/scripts/lib/overlay_health.py +8 -2
- package/scripts/lib/probe.py +261 -37
- package/skills/omnilane/SKILL.md +69 -17
package/scripts/lib/aa_policy.py
CHANGED
|
@@ -29,6 +29,10 @@ APPROVED_REGISTRY_SHA256 = "0782c87de123c02738c3ff60e4bc3c1cc10d110113e872b8f862
|
|
|
29
29
|
|
|
30
30
|
IDENTITY_FIELDS = ("vendor", "model", "effort", "reasoning", "fallback")
|
|
31
31
|
TRANSPORT_EVIDENCE_VENDORS = frozenset(("codex", "claude", "grok", "gemini"))
|
|
32
|
+
# How strongly a mapping's probe identified the responder. Reported, never
|
|
33
|
+
# enforced: dispatch turns on runtime_verified alone, as it did before the field
|
|
34
|
+
# existed, so a weaker tier can never refuse a lane that used to run.
|
|
35
|
+
TRANSPORT_EVIDENCE_TIERS = frozenset(("billed-model", "client-echo", "selector-only"))
|
|
32
36
|
IDENTIFIER = re.compile(r"[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}\Z")
|
|
33
37
|
|
|
34
38
|
|
|
@@ -178,6 +182,7 @@ def apply_transport_overlay(registry: dict[str, Any]) -> None:
|
|
|
178
182
|
_check(False, "transport contract evidence changed")
|
|
179
183
|
stale_vendors.add(vendor)
|
|
180
184
|
_check(bool(overlay.get("evidence")), "transport overlay requires local evidence")
|
|
185
|
+
tiers: dict[str, str] = {}
|
|
181
186
|
for mapping in overlay.get("mappings", []):
|
|
182
187
|
rows = [row for row in registry["scored_configs"] if row["id"] == mapping.get("config_id")]
|
|
183
188
|
_check(len(rows) == 1, "unknown overlay config")
|
|
@@ -197,8 +202,11 @@ def apply_transport_overlay(registry: dict[str, Any]) -> None:
|
|
|
197
202
|
_check(mapping["runtime_model"].endswith("-" + row["effort"]), "encoded effort does not match exact tuple")
|
|
198
203
|
else:
|
|
199
204
|
_check(mapping.get("runtime_model") == row["model"], "overlay model mismatch")
|
|
205
|
+
tier = mapping.get("evidence_tier", "selector-only")
|
|
206
|
+
_check(tier in TRANSPORT_EVIDENCE_TIERS, "unknown transport evidence tier")
|
|
200
207
|
if row["vendor"] in stale_vendors:
|
|
201
208
|
continue
|
|
209
|
+
tiers[row["id"]] = tier
|
|
202
210
|
row["transport_mapping"].update(
|
|
203
211
|
status="verified", runtime_verified=True,
|
|
204
212
|
runtime_model=mapping["runtime_model"], runtime_effort=mapping["runtime_effort"],
|
|
@@ -208,6 +216,7 @@ def apply_transport_overlay(registry: dict[str, Any]) -> None:
|
|
|
208
216
|
overlay_sha256=digest, overlay_host=overlay["host"],
|
|
209
217
|
)
|
|
210
218
|
registry["_stale_transport_vendors"] = sorted(stale_vendors)
|
|
219
|
+
registry["_transport_evidence_tiers"] = tiers
|
|
211
220
|
|
|
212
221
|
|
|
213
222
|
def load_registry(path: str | Path, expected_sha256: str | None = None) -> tuple[dict[str, Any], str]:
|
|
@@ -332,7 +341,10 @@ def decide(registry: dict[str, Any], registry_sha256: str, *,
|
|
|
332
341
|
if caller is None:
|
|
333
342
|
base.update(
|
|
334
343
|
code="missing-caller-context",
|
|
335
|
-
message="
|
|
344
|
+
message=("no caller identity: a model caller runs `omnilane whoami` and passes the "
|
|
345
|
+
"file it prints as --caller-context, which dispatch does itself when the "
|
|
346
|
+
"launching CLI names its model and effort; a human operator passes "
|
|
347
|
+
"--operator-asserted-human"),
|
|
336
348
|
)
|
|
337
349
|
return base
|
|
338
350
|
base["caller_context_sha256"] = caller_sha256
|
package/scripts/lib/aa_retry.py
CHANGED
|
@@ -27,7 +27,9 @@ def retry_args(directory):
|
|
|
27
27
|
original_limit = min(rows[0]["score"], original["inherited_ceiling"])
|
|
28
28
|
current_path = os.environ.get("OMNILANE_AA_CALLER_CONTEXT")
|
|
29
29
|
current_human = os.environ.get("OMNILANE_AA_OPERATOR_ASSERTED_HUMAN") == "1"
|
|
30
|
-
aa_policy._check(bool(current_path) != current_human,
|
|
30
|
+
aa_policy._check(bool(current_path) != current_human,
|
|
31
|
+
"retry requires one current caller context or explicit current human "
|
|
32
|
+
"assertion; a model caller gets one from `omnilane whoami`")
|
|
31
33
|
if current_path:
|
|
32
34
|
current, _ = aa_policy.load_caller(current_path, registry)
|
|
33
35
|
rows = aa_policy._matching_rows(registry, current["caller"])
|
|
@@ -10,7 +10,9 @@ import argparse
|
|
|
10
10
|
import hashlib
|
|
11
11
|
import json
|
|
12
12
|
import os
|
|
13
|
+
import shutil
|
|
13
14
|
import socket
|
|
15
|
+
from collections import Counter
|
|
14
16
|
from datetime import datetime, timezone
|
|
15
17
|
from pathlib import Path
|
|
16
18
|
|
|
@@ -37,13 +39,13 @@ for effort in ["xhigh", "medium"]:
|
|
|
37
39
|
PROVEN[f"codex/gpt-5-4-mini" + ("" if effort == "xhigh" else f"-{effort}")] = (
|
|
38
40
|
"model_and_effort", "gpt-5.4-mini", f"cx-gpt-5_4-mini-{effort}")
|
|
39
41
|
|
|
40
|
-
PROVEN["grok/grok-4-6"] = ("cli_reasoning_effort", "grok-4.6", "
|
|
42
|
+
PROVEN["grok/grok-4-6"] = ("cli_reasoning_effort", "grok-4.6", "gk-grok-4_6-high")
|
|
41
43
|
for effort in ["xhigh", "medium", "low"]:
|
|
42
44
|
PROVEN[f"grok/grok-4-6-{effort}"] = ("cli_reasoning_effort", "grok-4.6", f"gk-grok-4_6-{effort}")
|
|
43
45
|
PROVEN["grok/grok-4-5"] = ("cli_reasoning_effort", "grok-4.5", "gk-grok-4_5-high")
|
|
44
46
|
|
|
45
47
|
for cid, rid, ev in [
|
|
46
|
-
("gemini/gemini-3-8-flash", "gemini-3.8-flash-high", "
|
|
48
|
+
("gemini/gemini-3-8-flash", "gemini-3.8-flash-high", "agy-gemini-3_8-flash-high"),
|
|
47
49
|
("gemini/gemini-3-8-flash-medium", "gemini-3.8-flash-medium", "agy-gemini-3_8-flash-medium"),
|
|
48
50
|
("gemini/gemini-3-8-flash-low", "gemini-3.8-flash-low", "agy-gemini-3_8-flash-low"),
|
|
49
51
|
("gemini/gemini-3-7-flash", "gemini-3.7-flash-high", "agy-gemini-3_7-flash-high"),
|
|
@@ -83,16 +85,32 @@ for effort in ["max", "xhigh", "high", "medium", "low"]:
|
|
|
83
85
|
PROVEN["claude/claude-fable-5"] = (
|
|
84
86
|
"model_and_effort", "claude-fable-5", "cl-claude-fable-5-max")
|
|
85
87
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
88
|
+
def cli_path(name: str) -> Path:
|
|
89
|
+
"""Anchor the executable the runners resolve, not a version pinned here.
|
|
90
|
+
|
|
91
|
+
The runners invoke bare names, so a pinned path can name a binary that has
|
|
92
|
+
not run since the last self-update; the overlay must hash what answers.
|
|
93
|
+
aa_policy opens evidence with O_NOFOLLOW, so this resolves past the symlink.
|
|
94
|
+
"""
|
|
95
|
+
found = shutil.which(name)
|
|
96
|
+
if not found:
|
|
97
|
+
raise SystemExit(f"cannot resolve the {name} CLI to anchor its evidence")
|
|
98
|
+
return Path(found).resolve()
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def core_evidence() -> list[tuple[Path, str]]:
|
|
102
|
+
"""Resolved when a build runs, not at import: a host missing one CLI can
|
|
103
|
+
still load this module to read PROVEN."""
|
|
104
|
+
return [
|
|
105
|
+
(cli_path("grok"), "grok"),
|
|
106
|
+
(REPO / "scripts/runners/run-grok.sh", "grok"),
|
|
107
|
+
(cli_path("codex"), "codex"),
|
|
108
|
+
(REPO / "scripts/runners/run-codex.sh", "codex"),
|
|
109
|
+
(cli_path("claude"), "claude"),
|
|
110
|
+
(REPO / "scripts/runners/run-claude.sh", "claude"),
|
|
111
|
+
(cli_path("agy"), "gemini"),
|
|
112
|
+
(REPO / "scripts/runners/run-gemini.sh", "gemini"),
|
|
113
|
+
]
|
|
96
114
|
|
|
97
115
|
|
|
98
116
|
def sha256(path: Path) -> str:
|
|
@@ -116,12 +134,12 @@ def main(argv: list[str] | None = None) -> None:
|
|
|
116
134
|
|
|
117
135
|
manifest = {"probe_runs": {}}
|
|
118
136
|
unproven = []
|
|
137
|
+
# Evidence written before 0.42.6 carries no tier; it proved the selector and
|
|
138
|
+
# nothing about who answered, which is exactly what selector-only records.
|
|
139
|
+
tiers: dict[str, str] = {}
|
|
119
140
|
for cid, (_, _, ev) in sorted(PROVEN.items()):
|
|
120
|
-
if ev.startswith("PRIOR:"):
|
|
121
|
-
manifest["probe_runs"][cid] = {"source": ev, "note": "verified in the 2026-09-07 Codex run"}
|
|
122
|
-
continue
|
|
123
141
|
entry = {}
|
|
124
|
-
for suffix in ("json", "stdout", "stderr"):
|
|
142
|
+
for suffix in ("json", "stdout", "stderr", "rollout", "cli_log"):
|
|
125
143
|
path = root / "evidence" / f"{ev}.{suffix}"
|
|
126
144
|
if path.exists():
|
|
127
145
|
entry[suffix] = {"path": str(path), "sha256": sha256(path)}
|
|
@@ -143,6 +161,10 @@ def main(argv: list[str] | None = None) -> None:
|
|
|
143
161
|
})
|
|
144
162
|
# Visibility only: failed evidence must not enter the signed manifest.
|
|
145
163
|
continue
|
|
164
|
+
tier = descriptor.get("evidence_tier", "selector-only")
|
|
165
|
+
if tier not in ("billed-model", "client-echo", "selector-only"):
|
|
166
|
+
raise SystemExit(f"unknown evidence tier for {cid}: {tier}")
|
|
167
|
+
tiers[cid] = tier
|
|
146
168
|
manifest["probe_runs"][cid] = entry
|
|
147
169
|
manifest_path = root / "probe-manifest.json"
|
|
148
170
|
manifest_path.write_text(json.dumps(manifest, indent=2, sort_keys=True) + "\n")
|
|
@@ -159,6 +181,7 @@ def main(argv: list[str] | None = None) -> None:
|
|
|
159
181
|
"runtime_effort": row["effort"],
|
|
160
182
|
"selector_type": selector,
|
|
161
183
|
"verification": "request-selector-contract",
|
|
184
|
+
"evidence_tier": tiers.get(cid, "selector-only"),
|
|
162
185
|
}
|
|
163
186
|
if selector == "cli_reasoning_effort":
|
|
164
187
|
mapping["cli_flag"] = "--reasoning-effort"
|
|
@@ -166,7 +189,7 @@ def main(argv: list[str] | None = None) -> None:
|
|
|
166
189
|
|
|
167
190
|
evidence = [
|
|
168
191
|
{"path": str(path), "sha256": sha256(path), "vendor": vendor}
|
|
169
|
-
for path, vendor in
|
|
192
|
+
for path, vendor in core_evidence()
|
|
170
193
|
]
|
|
171
194
|
evidence.append({"path": str(manifest_path), "sha256": sha256(manifest_path)})
|
|
172
195
|
|
|
@@ -182,7 +205,9 @@ def main(argv: list[str] | None = None) -> None:
|
|
|
182
205
|
}
|
|
183
206
|
out = root / "transport-contracts.local.json"
|
|
184
207
|
out.write_text(json.dumps(overlay, indent=2, ensure_ascii=False) + "\n")
|
|
208
|
+
spread = Counter(m["evidence_tier"] for m in mappings)
|
|
185
209
|
print(f"wrote {out} with {len(mappings)} mappings and {len(evidence)} evidence anchors")
|
|
210
|
+
print(" evidence tiers: " + ", ".join(f"{tier} {count}" for tier, count in sorted(spread.items())))
|
|
186
211
|
|
|
187
212
|
|
|
188
213
|
if __name__ == "__main__":
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Read the exact AA caller identity of the CLI this process runs under.
|
|
3
|
+
|
|
4
|
+
Walks up the process tree to the nearest vendor CLI, reads the model and effort
|
|
5
|
+
it was launched with, and maps them onto the one scored configuration they
|
|
6
|
+
select. Launch flags are the harness's request selector: the same class of
|
|
7
|
+
evidence the transport overlay carries, and unlike a hand-written caller-context
|
|
8
|
+
file, not something the model can edit.
|
|
9
|
+
|
|
10
|
+
Prints the path of a caller-context file for that identity. Exits 3 with the
|
|
11
|
+
reason on stderr when it cannot decide. It never guesses: a missing flag, an
|
|
12
|
+
alias, or an identity the frozen registry does not score exactly once is a
|
|
13
|
+
refusal, not a fallback.
|
|
14
|
+
"""
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import argparse
|
|
18
|
+
import json
|
|
19
|
+
import os
|
|
20
|
+
import subprocess
|
|
21
|
+
import sys
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
from typing import Callable, Optional
|
|
24
|
+
|
|
25
|
+
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
26
|
+
import aa_policy # noqa: E402
|
|
27
|
+
|
|
28
|
+
REPO = Path(__file__).resolve().parents[2]
|
|
29
|
+
MAX_DEPTH = 64
|
|
30
|
+
ENCODED_EFFORTS = ("xhigh", "high", "medium", "low")
|
|
31
|
+
Selector = tuple[str, Optional[str], Optional[str]]
|
|
32
|
+
Lookup = Callable[[int], Optional[tuple[int, list[str]]]]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def _vendor(executable: str) -> str | None:
|
|
36
|
+
path = Path(executable)
|
|
37
|
+
name = path.name
|
|
38
|
+
if name == "claude" or (path.parent.name == "versions" and path.parent.parent.name == "claude"):
|
|
39
|
+
return "claude"
|
|
40
|
+
if name == "codex":
|
|
41
|
+
return "codex"
|
|
42
|
+
if name == "grok" or (name.startswith("grok-") and path.parent.name == "downloads"):
|
|
43
|
+
return "grok"
|
|
44
|
+
if name == "agy":
|
|
45
|
+
return "gemini"
|
|
46
|
+
return None
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _flag(argv: list[str], *names: str) -> str | None:
|
|
50
|
+
"""The last value given for any of names, as `--name value` or `--name=value`."""
|
|
51
|
+
value = None
|
|
52
|
+
for index, token in enumerate(argv):
|
|
53
|
+
for name in names:
|
|
54
|
+
if token == name and index + 1 < len(argv):
|
|
55
|
+
value = argv[index + 1]
|
|
56
|
+
elif token.startswith(name + "="):
|
|
57
|
+
value = token.split("=", 1)[1]
|
|
58
|
+
return value
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _codex_effort(argv: list[str]) -> str | None:
|
|
62
|
+
effort = None
|
|
63
|
+
for index, token in enumerate(argv[:-1]):
|
|
64
|
+
if token in ("-c", "--config"):
|
|
65
|
+
key, _, value = argv[index + 1].partition("=")
|
|
66
|
+
if key.strip() == "model_reasoning_effort":
|
|
67
|
+
effort = value.strip().strip("'\"")
|
|
68
|
+
return effort
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def read_selector(argv: list[str]) -> Selector | None:
|
|
72
|
+
"""(vendor, model, effort) when argv launches a vendor CLI, otherwise None."""
|
|
73
|
+
if not argv:
|
|
74
|
+
return None
|
|
75
|
+
vendor = _vendor(argv[0])
|
|
76
|
+
rest = argv[1:]
|
|
77
|
+
if vendor == "claude":
|
|
78
|
+
return vendor, _flag(rest, "--model"), _flag(rest, "--effort")
|
|
79
|
+
if vendor == "codex":
|
|
80
|
+
return vendor, _flag(rest, "-m", "--model"), _codex_effort(rest)
|
|
81
|
+
if vendor == "grok":
|
|
82
|
+
return vendor, _flag(rest, "-m", "--model"), _flag(rest, "--reasoning-effort")
|
|
83
|
+
if vendor == "gemini":
|
|
84
|
+
return vendor, _flag(rest, "--model", "-m"), None
|
|
85
|
+
return None
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def resolve(registry: dict, vendor: str, model: str | None,
|
|
89
|
+
effort: str | None) -> tuple[dict | None, str]:
|
|
90
|
+
"""The one scored row a launch selector lands on, or None and the reason."""
|
|
91
|
+
if not model:
|
|
92
|
+
return None, f"{vendor} was launched without a model flag"
|
|
93
|
+
if vendor == "gemini" and effort is None:
|
|
94
|
+
base, _, suffix = model.rpartition("-")
|
|
95
|
+
if suffix in ENCODED_EFFORTS:
|
|
96
|
+
model, effort = base, suffix
|
|
97
|
+
if vendor == "codex":
|
|
98
|
+
if effort is None:
|
|
99
|
+
return None, (f"codex was launched without model_reasoning_effort; its configured "
|
|
100
|
+
f"default is not read, so the effort of {model} is unknown")
|
|
101
|
+
if effort == "none":
|
|
102
|
+
effort = None
|
|
103
|
+
rows = [row for row in registry["scored_configs"]
|
|
104
|
+
if row["vendor"] == vendor and row["model"] == model and row["effort"] == effort]
|
|
105
|
+
excluded = []
|
|
106
|
+
if vendor == "claude":
|
|
107
|
+
# ADR-0046: --effort has no reasoning-off value, so a non-reasoning row
|
|
108
|
+
# can never be what a Claude launch selected.
|
|
109
|
+
excluded = [row for row in rows if row["reasoning"] == "non-reasoning"]
|
|
110
|
+
rows = [row for row in rows if row["reasoning"] != "non-reasoning"]
|
|
111
|
+
if len(rows) == 1:
|
|
112
|
+
return rows[0], ""
|
|
113
|
+
if rows:
|
|
114
|
+
return None, f"{vendor} {model} at effort {effort} matches {len(rows)} scored configurations"
|
|
115
|
+
if excluded:
|
|
116
|
+
return None, (f"the only scored {model} row at effort {effort} is non-reasoning, which a "
|
|
117
|
+
f"Claude launch cannot select")
|
|
118
|
+
if vendor == "claude" and effort is None:
|
|
119
|
+
return None, f"{model} was launched without --effort and no default is scored for it"
|
|
120
|
+
return None, f"no scored configuration for {vendor} {model} at effort {effort}"
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def _process(pid: int) -> tuple[int, list[str]] | None:
|
|
124
|
+
"""(ppid, argv) for pid. /proc keeps argv exact; ps joins it with spaces, so
|
|
125
|
+
argv[0] comes from `comm`, which keeps a path like `Application Support` whole."""
|
|
126
|
+
proc = Path(f"/proc/{pid}")
|
|
127
|
+
if proc.is_dir():
|
|
128
|
+
try:
|
|
129
|
+
argv = [part.decode(errors="replace")
|
|
130
|
+
for part in (proc / "cmdline").read_bytes().split(b"\0") if part]
|
|
131
|
+
ppid = int((proc / "stat").read_text().rsplit(")", 1)[1].split()[1])
|
|
132
|
+
except (OSError, ValueError, IndexError):
|
|
133
|
+
return None
|
|
134
|
+
return ppid, argv
|
|
135
|
+
try:
|
|
136
|
+
head = subprocess.run(["ps", "-o", "ppid=", "-o", "comm=", "-p", str(pid)],
|
|
137
|
+
capture_output=True, text=True, timeout=5).stdout.strip()
|
|
138
|
+
args = subprocess.run(["ps", "-o", "args=", "-p", str(pid)],
|
|
139
|
+
capture_output=True, text=True, timeout=5).stdout.strip()
|
|
140
|
+
except (OSError, subprocess.SubprocessError):
|
|
141
|
+
return None
|
|
142
|
+
parts = head.split(None, 1)
|
|
143
|
+
if len(parts) != 2 or not parts[0].isdigit():
|
|
144
|
+
return None
|
|
145
|
+
comm = parts[1].strip()
|
|
146
|
+
rest = args[len(comm):] if args.startswith(comm) else args.partition(" ")[2]
|
|
147
|
+
return int(parts[0]), [comm, *rest.split()]
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def find_launcher(pid: int, lookup: Lookup = _process) -> tuple[int, Selector] | None:
|
|
151
|
+
"""The nearest process at or above pid that is a vendor CLI, with its selector.
|
|
152
|
+
|
|
153
|
+
Nearest wins: a codex worker started by a Claude session is a codex caller.
|
|
154
|
+
"""
|
|
155
|
+
seen: set[int] = set()
|
|
156
|
+
for _ in range(MAX_DEPTH):
|
|
157
|
+
if pid <= 0 or pid in seen:
|
|
158
|
+
return None
|
|
159
|
+
seen.add(pid)
|
|
160
|
+
entry = lookup(pid)
|
|
161
|
+
if entry is None:
|
|
162
|
+
return None
|
|
163
|
+
ppid, argv = entry
|
|
164
|
+
selector = read_selector(argv)
|
|
165
|
+
if selector is not None:
|
|
166
|
+
return pid, selector
|
|
167
|
+
pid = ppid
|
|
168
|
+
return None
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def load_registry(path: str | Path) -> tuple[dict, str]:
|
|
172
|
+
"""The approved registry without the transport overlay, which says nothing
|
|
173
|
+
about the caller and must not stop one from learning who it is."""
|
|
174
|
+
saved = {key: os.environ.pop(key)
|
|
175
|
+
for key in ("OMNILANE_AA_TRANSPORT_OVERLAY", "OMNILANE_AA_OVERLAY_SHA256")
|
|
176
|
+
if key in os.environ}
|
|
177
|
+
try:
|
|
178
|
+
return aa_policy.load_registry(path)
|
|
179
|
+
finally:
|
|
180
|
+
os.environ.update(saved)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def write_context(row: dict, registry: dict, home: Path) -> Path:
|
|
184
|
+
"""One file per identity: every session launched the same way is the same caller."""
|
|
185
|
+
directory = Path(home) / "caller-context"
|
|
186
|
+
directory.mkdir(parents=True, exist_ok=True)
|
|
187
|
+
path = directory / (row["id"].replace("/", "--") + ".json")
|
|
188
|
+
text = json.dumps({
|
|
189
|
+
"schema_version": 1,
|
|
190
|
+
"snapshot_id": registry["snapshot"]["id"],
|
|
191
|
+
"kind": "model",
|
|
192
|
+
"caller": {key: row[key] for key in aa_policy.IDENTITY_FIELDS},
|
|
193
|
+
"inherited_ceiling": row["score"],
|
|
194
|
+
}, indent=2, sort_keys=True) + "\n"
|
|
195
|
+
try:
|
|
196
|
+
if path.read_text() == text:
|
|
197
|
+
return path
|
|
198
|
+
except OSError:
|
|
199
|
+
pass
|
|
200
|
+
staging = path.with_name(f".{path.name}.{os.getpid()}.tmp")
|
|
201
|
+
staging.write_text(text)
|
|
202
|
+
os.replace(staging, path)
|
|
203
|
+
return path
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def main(argv: list[str] | None = None) -> int:
|
|
207
|
+
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
|
208
|
+
parser.add_argument("--registry",
|
|
209
|
+
default=os.environ.get("OMNILANE_AA_POLICY_FILE")
|
|
210
|
+
or str(REPO / "config" / "aa-model-policy.json"),
|
|
211
|
+
help="frozen AA registry (default: the repository copy)")
|
|
212
|
+
args = parser.parse_args(argv)
|
|
213
|
+
try:
|
|
214
|
+
registry, _ = load_registry(args.registry)
|
|
215
|
+
except (aa_policy.PolicyError, OSError, ValueError) as error:
|
|
216
|
+
print(f"omnilane: cannot read the AA registry: {error}", file=sys.stderr)
|
|
217
|
+
return 3
|
|
218
|
+
found = find_launcher(os.getpid())
|
|
219
|
+
if found is None:
|
|
220
|
+
print("omnilane: no vendor CLI among this process's ancestors; a model caller passes "
|
|
221
|
+
"--caller-context FILE and a human operator --operator-asserted-human",
|
|
222
|
+
file=sys.stderr)
|
|
223
|
+
return 3
|
|
224
|
+
pid, (vendor, model, effort) = found
|
|
225
|
+
row, reason = resolve(registry, vendor, model, effort)
|
|
226
|
+
if row is None:
|
|
227
|
+
print(f"omnilane: cannot read the caller identity from pid {pid}: {reason}", file=sys.stderr)
|
|
228
|
+
return 3
|
|
229
|
+
home = Path(os.environ.get("OMNILANE_HOME") or Path.home() / ".omnilane")
|
|
230
|
+
path = write_context(row, registry, home)
|
|
231
|
+
print(f"omnilane: caller is {row['id']} (score {row['score']}), read from pid {pid}",
|
|
232
|
+
file=sys.stderr)
|
|
233
|
+
print(path)
|
|
234
|
+
return 0
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
if __name__ == "__main__":
|
|
238
|
+
raise SystemExit(main())
|
|
@@ -68,17 +68,23 @@ def main() -> None:
|
|
|
68
68
|
detail = "; ".join(offenders(Path(overlay_path))) or str(error)
|
|
69
69
|
emit("FAIL", f"overlay rejected, every dispatch is refused: {error} ({detail})")
|
|
70
70
|
|
|
71
|
+
tiers = registry.get("_transport_evidence_tiers", {})
|
|
71
72
|
verified = Counter()
|
|
72
73
|
for row in registry["scored_configs"]:
|
|
73
74
|
if row["transport_mapping"].get("runtime_verified") is True:
|
|
74
|
-
verified[row["vendor"]] += 1
|
|
75
|
-
summary = ", ".join(f"{
|
|
75
|
+
verified[row["vendor"], tiers.get(row["id"], "selector-only")] += 1
|
|
76
|
+
summary = ", ".join(f"{vendor} {count} {tier}"
|
|
77
|
+
for (vendor, tier), count in sorted(verified.items())) or "none"
|
|
76
78
|
|
|
77
79
|
import json
|
|
78
80
|
|
|
79
81
|
overlay = json.loads(Path(overlay_path).read_text())
|
|
80
82
|
unproven = overlay.get("unproven", [])
|
|
81
83
|
extra = f"; {len(unproven)} config(s) recorded unproven" if unproven else ""
|
|
84
|
+
weak = sorted({vendor for (vendor, tier) in verified if tier == "selector-only"})
|
|
85
|
+
if weak:
|
|
86
|
+
extra += (f"; {', '.join(weak)} prove only the request selector, re-probe to "
|
|
87
|
+
"record who answered")
|
|
82
88
|
|
|
83
89
|
stale = registry.get("_stale_transport_vendors", [])
|
|
84
90
|
if stale:
|