omnilane 0.42.4 → 0.42.6

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": "omnilane",
3
- "version": "0.42.4",
3
+ "version": "0.42.6",
4
4
  "description": "One routing table, every harness — classify subtasks into lanes and delegate each lane through a compatible caller-owned native agent or vendor CLI.",
5
5
  "bin": {
6
6
  "omnilane": "bin/omnilane"
@@ -29,7 +29,7 @@
29
29
  "docs/model-capabilities-2026-09.md",
30
30
  "docs/native-executor.md",
31
31
  "docs/completion-wakeup.md",
32
- "docs/release-notes-0.42.4.md",
32
+ "docs/release-notes-0.42.5.md",
33
33
  "hooks/",
34
34
  "skills/",
35
35
  ".claude-plugin/",
package/plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://antigravity.google/schemas/v1/plugin.json",
3
3
  "name": "omnilane",
4
- "version": "0.42.4",
4
+ "version": "0.42.6",
5
5
  "description": "One routing table, every harness: classify subtasks into lanes and delegate through compatible caller-owned native agents or vendor CLIs with exact-AA downward policy and supervised jobs."
6
6
  }
package/scripts/doctor.sh CHANGED
@@ -33,6 +33,7 @@ REPO="${OMNILANE_DOCTOR_REPO:-$SCRIPT_ROOT}"
33
33
  OMNILANE_HOME="${OMNILANE_HOME:-$HOME/.omnilane}"
34
34
  PROBE_SCRIPT="${OMNILANE_PROVIDER_PROBE_SCRIPT:-$REPO/scripts/provider-probe.sh}"
35
35
  GOAL_LOOP="${OMNILANE_DOCTOR_GOAL_LOOP:-$REPO/scripts/lib/goal-loop.sh}"
36
+ OVERLAY_HEALTH="${OMNILANE_DOCTOR_OVERLAY_HEALTH:-$REPO/scripts/lib/overlay_health.py}"
36
37
  # shellcheck disable=SC1091
37
38
  source "$SCRIPT_ROOT/scripts/lib/live-protocol.sh"
38
39
  PASS_COUNT=0
@@ -409,6 +410,31 @@ else
409
410
  report PASS live-unavailable "none"
410
411
  fi
411
412
 
413
+ # live-capable above answers "does this CLI support a live session", which stays
414
+ # true while the AA gate refuses every dispatch. Nothing else loads the overlay,
415
+ # so one drifted evidence hash used to go unreported by an all-green doctor.
416
+ overlay_path="$(
417
+ set +u
418
+ [[ -f "$OMNILANE_HOME/local.sh" ]] && . "$OMNILANE_HOME/local.sh" 2>/dev/null
419
+ printf '%s' "${OMNILANE_AA_TRANSPORT_OVERLAY:-}"
420
+ )"
421
+ if [[ -z "$overlay_path" ]]; then
422
+ report PASS transport-overlay "no overlay configured; every runtime mapping stays unverified"
423
+ elif ! command -v python3 >/dev/null 2>&1; then
424
+ report WARN transport-overlay "python3 is absent; cannot load the AA transport overlay"
425
+ elif [[ ! -r "$OVERLAY_HEALTH" ]]; then
426
+ report WARN transport-overlay "$OVERLAY_HEALTH is missing"
427
+ else
428
+ overlay_line="$(OMNILANE_AA_TRANSPORT_OVERLAY="$overlay_path" \
429
+ python3 "$OVERLAY_HEALTH" "$REPO" 2>&1)"
430
+ overlay_level="${overlay_line%% *}"
431
+ overlay_message="${overlay_line#* }"
432
+ case "$overlay_level" in
433
+ PASS|WARN|FAIL) report "$overlay_level" transport-overlay "$overlay_message" ;;
434
+ *) report WARN transport-overlay "unreadable overlay health output: $overlay_line" ;;
435
+ esac
436
+ fi
437
+
412
438
  if [[ -n "$PROBE_VENDOR" ]]; then
413
439
  if [[ ! -x "$PROBE_SCRIPT" ]]; then
414
440
  report FAIL provider-probe "probe runner is unavailable"
@@ -28,6 +28,11 @@ MAX_BYTES = 1_048_576
28
28
  APPROVED_REGISTRY_SHA256 = "0782c87de123c02738c3ff60e4bc3c1cc10d110113e872b8f8627212861cdaab"
29
29
 
30
30
  IDENTITY_FIELDS = ("vendor", "model", "effort", "reasoning", "fallback")
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"))
31
36
  IDENTIFIER = re.compile(r"[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}\Z")
32
37
 
33
38
 
@@ -147,15 +152,37 @@ def apply_transport_overlay(registry: dict[str, Any]) -> None:
147
152
  _check(overlay.get("schema_version") == 1, "unsupported transport overlay")
148
153
  _check(overlay.get("snapshot_id") == registry["snapshot"]["id"], "transport overlay snapshot mismatch")
149
154
  _check(overlay.get("host") == socket.gethostname(), "transport overlay host mismatch")
155
+ stale_vendors: set[str] = set()
150
156
  for evidence in overlay.get("evidence", []):
151
- fd = os.open(evidence["path"], os.O_RDONLY | os.O_NOFOLLOW | os.O_NONBLOCK)
157
+ _check(isinstance(evidence, dict), "invalid transport evidence")
158
+ vendor = evidence.get("vendor")
159
+ _check(
160
+ "vendor" not in evidence
161
+ or type(vendor) is str and vendor in TRANSPORT_EVIDENCE_VENDORS,
162
+ "invalid transport evidence vendor",
163
+ )
164
+ evidence_path = evidence["path"]
165
+ evidence_sha256 = evidence["sha256"]
166
+ _check(type(evidence_path) is str, "invalid transport evidence path")
167
+ _check(type(evidence_sha256) is str, "invalid transport evidence digest")
168
+ try:
169
+ fd = os.open(evidence_path, os.O_RDONLY | os.O_NOFOLLOW | os.O_NONBLOCK)
170
+ except FileNotFoundError:
171
+ if vendor is None:
172
+ raise
173
+ stale_vendors.add(vendor)
174
+ continue
152
175
  with os.fdopen(fd, "rb") as stream:
153
176
  _check(stat.S_ISREG(os.fstat(stream.fileno()).st_mode), "invalid transport evidence file")
154
177
  digest_file = hashlib.sha256()
155
178
  for block in iter(lambda: stream.read(1024 * 1024), b""):
156
179
  digest_file.update(block)
157
- _check(digest_file.hexdigest() == evidence["sha256"], "transport contract evidence changed")
180
+ if digest_file.hexdigest() != evidence_sha256:
181
+ if vendor is None:
182
+ _check(False, "transport contract evidence changed")
183
+ stale_vendors.add(vendor)
158
184
  _check(bool(overlay.get("evidence")), "transport overlay requires local evidence")
185
+ tiers: dict[str, str] = {}
159
186
  for mapping in overlay.get("mappings", []):
160
187
  rows = [row for row in registry["scored_configs"] if row["id"] == mapping.get("config_id")]
161
188
  _check(len(rows) == 1, "unknown overlay config")
@@ -175,6 +202,11 @@ def apply_transport_overlay(registry: dict[str, Any]) -> None:
175
202
  _check(mapping["runtime_model"].endswith("-" + row["effort"]), "encoded effort does not match exact tuple")
176
203
  else:
177
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")
207
+ if row["vendor"] in stale_vendors:
208
+ continue
209
+ tiers[row["id"]] = tier
178
210
  row["transport_mapping"].update(
179
211
  status="verified", runtime_verified=True,
180
212
  runtime_model=mapping["runtime_model"], runtime_effort=mapping["runtime_effort"],
@@ -183,6 +215,8 @@ def apply_transport_overlay(registry: dict[str, Any]) -> None:
183
215
  verification="request-selector-contract", upstream_identity_verified=False,
184
216
  overlay_sha256=digest, overlay_host=overlay["host"],
185
217
  )
218
+ registry["_stale_transport_vendors"] = sorted(stale_vendors)
219
+ registry["_transport_evidence_tiers"] = tiers
186
220
 
187
221
 
188
222
  def load_registry(path: str | Path, expected_sha256: str | None = None) -> tuple[dict[str, Any], str]:
@@ -233,6 +267,8 @@ def _runtime_target(registry: dict[str, Any], vendor: str, model: str,
233
267
  exact_id = [row for row in registry["scored_configs"] if row["id"] == target_config] if target_config else registry["scored_configs"]
234
268
  if target_config and not exact_id:
235
269
  return None, "unknown-target-config", {"target_config": target_config}
270
+ if vendor in registry.get("_stale_transport_vendors", []):
271
+ return None, "unknown-target-runtime", {"vendor": vendor, "model": model, "effort": effort}
236
272
  vendor_rows = [row for row in exact_id if row["vendor"] == vendor]
237
273
  candidates: list[dict[str, Any]] = []
238
274
  unresolved: list[str] = []
@@ -0,0 +1,214 @@
1
+ #!/usr/bin/env python3
2
+ """Build the merged omnilane AA transport overlay from verified probe evidence.
3
+
4
+ Only (config_id, selector) pairs listed in PROVEN are written. Every entry here
5
+ corresponds to a probe run under the selected evidence root whose raw
6
+ stdout/stderr is hashed into the manifest, so the overlay's evidence[] anchors
7
+ the whole set.
8
+ """
9
+ import argparse
10
+ import hashlib
11
+ import json
12
+ import os
13
+ import shutil
14
+ import socket
15
+ from collections import Counter
16
+ from datetime import datetime, timezone
17
+ from pathlib import Path
18
+
19
+ REPO = Path(os.environ.get("OMNILANE_REPO", "/Users/vincentw/dev/omnilane"))
20
+ HOME = Path.home()
21
+ SWEEP_ID = os.environ.get("OMNILANE_TRANSPORT_SWEEP_ID", "overlay-reprobe-20260909")
22
+ DEFAULT_ROOT = HOME / ".omnilane" / "transport-evidence" / SWEEP_ID
23
+ REGISTRY = json.loads((REPO / "config/aa-model-policy.json").read_text())
24
+ ROWS = {r["id"]: r for r in REGISTRY["scored_configs"]}
25
+ IDENTITY_FIELDS = ("vendor", "model", "effort", "reasoning", "fallback")
26
+
27
+ # config_id -> (selector_type, runtime_model, probe evidence basename)
28
+ PROVEN: dict[str, tuple[str, str, str]] = {}
29
+
30
+ for model, slug in [("gpt-6-astra", "gpt-6-astra"), ("gpt-5.6-sol", "gpt-5_6-sol"),
31
+ ("gpt-5.6-luna", "gpt-5_6-luna"), ("gpt-5.6-terra", "gpt-5_6-terra")]:
32
+ base = model.replace(".", "-").replace("gpt-", "gpt-")
33
+ for effort in ["max", "xhigh", "high", "medium", "low"]:
34
+ cid = f"codex/{model.replace('.', '-')}" + ("" if effort == "max" else f"-{effort}")
35
+ ev = f"cx-avail-{model.replace('.', '_')}" if effort == "high" else f"cx-{model.replace('.', '_')}-{effort}"
36
+ PROVEN[cid] = ("model_and_effort", model, ev)
37
+
38
+ for effort in ["xhigh", "medium"]:
39
+ PROVEN[f"codex/gpt-5-4-mini" + ("" if effort == "xhigh" else f"-{effort}")] = (
40
+ "model_and_effort", "gpt-5.4-mini", f"cx-gpt-5_4-mini-{effort}")
41
+
42
+ PROVEN["grok/grok-4-6"] = ("cli_reasoning_effort", "grok-4.6", "gk-grok-4_6-high")
43
+ for effort in ["xhigh", "medium", "low"]:
44
+ PROVEN[f"grok/grok-4-6-{effort}"] = ("cli_reasoning_effort", "grok-4.6", f"gk-grok-4_6-{effort}")
45
+ PROVEN["grok/grok-4-5"] = ("cli_reasoning_effort", "grok-4.5", "gk-grok-4_5-high")
46
+
47
+ for cid, rid, ev in [
48
+ ("gemini/gemini-3-8-flash", "gemini-3.8-flash-high", "agy-gemini-3_8-flash-high"),
49
+ ("gemini/gemini-3-8-flash-medium", "gemini-3.8-flash-medium", "agy-gemini-3_8-flash-medium"),
50
+ ("gemini/gemini-3-8-flash-low", "gemini-3.8-flash-low", "agy-gemini-3_8-flash-low"),
51
+ ("gemini/gemini-3-7-flash", "gemini-3.7-flash-high", "agy-gemini-3_7-flash-high"),
52
+ ("gemini/gemini-3-7-flash-medium", "gemini-3.7-flash-medium", "agy-gemini-3_7-flash-medium"),
53
+ ("gemini/gemini-3-7-flash-low", "gemini-3.7-flash-low", "agy-gemini-3_7-flash-low"),
54
+ ("gemini/gemini-3-6-flash", "gemini-3.6-flash-high", "agy-gemini-3_6-flash-high"),
55
+ ]:
56
+ PROVEN[cid] = ("model_id_encoded_effort", rid, ev)
57
+
58
+ for effort in ["max", "xhigh", "high", "medium", "low"]:
59
+ cid = "claude/claude-opus-5" + ("" if effort == "max" else f"-{effort}")
60
+ PROVEN[cid] = ("model_and_effort", "claude-opus-5", f"cl-claude-opus-5-{effort}")
61
+ # gpt-6-astra rejects effort "none" upstream ("Unsupported value: 'none' is not
62
+ # supported with the 'gpt-6-astra' model"), so it has no non-reasoning selector.
63
+ for model in ["gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna", "gpt-5.4-mini"]:
64
+ PROVEN[f"codex/{model.replace('.', '-')}-non-reasoning"] = (
65
+ "model_and_effort", model, f"cx-{model.replace('.', '_')}-none")
66
+
67
+ # Default (no --effort) Haiku 4.5 spent 124 thinking tokens, so the selector
68
+ # lands on the reasoning row rather than its non-reasoning sibling.
69
+ PROVEN["claude/claude-4-5-haiku-reasoning"] = (
70
+ "model_and_effort", "claude-haiku-4-5", "cl-rmode-claude-haiku-4-5-noeffort")
71
+
72
+ for cid, model in [("claude/claude-sonnet-5", "claude-sonnet-5"),
73
+ ("claude/claude-opus-4-8", "claude-opus-4-8"),
74
+ ("claude/claude-opus-4-7", "claude-opus-4-7"),
75
+ ("claude/claude-opus-4-6-adaptive", "claude-opus-4-6"),
76
+ ("claude/claude-sonnet-4-6-adaptive", "claude-sonnet-4-6")]:
77
+ PROVEN[cid] = ("model_and_effort", model, f"cl-{model}-max")
78
+
79
+ # Fable is listed so its failures reach unproven[] rather than vanishing. Its
80
+ # probes were refused for quota on 2026-09-07 and again on 2026-09-09; the
81
+ # verdict decides whether these rows become mappings or stay visible failures.
82
+ for effort in ["max", "xhigh", "high", "medium", "low"]:
83
+ cid = "claude/claude-fable-5-1" + ("" if effort == "max" else f"-{effort}")
84
+ PROVEN[cid] = ("model_and_effort", "claude-fable-5-1", f"cl-claude-fable-5-1-{effort}")
85
+ PROVEN["claude/claude-fable-5"] = (
86
+ "model_and_effort", "claude-fable-5", "cl-claude-fable-5-max")
87
+
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
+ ]
114
+
115
+
116
+ def sha256(path: Path) -> str:
117
+ digest = hashlib.sha256()
118
+ with open(path, "rb") as stream:
119
+ for block in iter(lambda: stream.read(1 << 20), b""):
120
+ digest.update(block)
121
+ return digest.hexdigest()
122
+
123
+
124
+ def main(argv: list[str] | None = None) -> None:
125
+ parser = argparse.ArgumentParser(description=__doc__)
126
+ parser.add_argument(
127
+ "--root",
128
+ type=Path,
129
+ default=DEFAULT_ROOT,
130
+ help=f"probe sweep root (default: {DEFAULT_ROOT})",
131
+ )
132
+ args = parser.parse_args(argv)
133
+ root = args.root.expanduser()
134
+
135
+ manifest = {"probe_runs": {}}
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] = {}
140
+ for cid, (_, _, ev) in sorted(PROVEN.items()):
141
+ entry = {}
142
+ for suffix in ("json", "stdout", "stderr", "rollout", "cli_log"):
143
+ path = root / "evidence" / f"{ev}.{suffix}"
144
+ if path.exists():
145
+ entry[suffix] = {"path": str(path), "sha256": sha256(path)}
146
+ if "json" not in entry:
147
+ raise SystemExit(f"missing probe evidence for {cid}: {ev}")
148
+ descriptor_path = Path(entry["json"]["path"])
149
+ descriptor = json.loads(descriptor_path.read_text())
150
+ if not isinstance(descriptor, dict):
151
+ raise SystemExit(f"invalid probe descriptor for {cid}: {ev}")
152
+ if "verdict" not in descriptor:
153
+ print(f"warning: legacy evidence (verdict=unknown): {cid}: {ev}")
154
+ elif descriptor["verdict"] != "pass":
155
+ unproven.append({
156
+ "config_id": cid,
157
+ "verdict_reason": descriptor.get("verdict_reason") or f"verdict: {descriptor['verdict']}",
158
+ "observed_model": descriptor.get("observed_model"),
159
+ "probed_at": descriptor.get("probed_at") or datetime.fromtimestamp(
160
+ descriptor_path.stat().st_mtime, timezone.utc).isoformat(),
161
+ })
162
+ # Visibility only: failed evidence must not enter the signed manifest.
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
168
+ manifest["probe_runs"][cid] = entry
169
+ manifest_path = root / "probe-manifest.json"
170
+ manifest_path.write_text(json.dumps(manifest, indent=2, sort_keys=True) + "\n")
171
+
172
+ mappings = []
173
+ for cid, (selector, runtime_model, _) in sorted(PROVEN.items()):
174
+ if cid not in manifest["probe_runs"]:
175
+ continue
176
+ row = ROWS[cid]
177
+ mapping = {
178
+ "config_id": cid,
179
+ "identity": {key: row[key] for key in IDENTITY_FIELDS},
180
+ "runtime_model": runtime_model,
181
+ "runtime_effort": row["effort"],
182
+ "selector_type": selector,
183
+ "verification": "request-selector-contract",
184
+ "evidence_tier": tiers.get(cid, "selector-only"),
185
+ }
186
+ if selector == "cli_reasoning_effort":
187
+ mapping["cli_flag"] = "--reasoning-effort"
188
+ mappings.append(mapping)
189
+
190
+ evidence = [
191
+ {"path": str(path), "sha256": sha256(path), "vendor": vendor}
192
+ for path, vendor in core_evidence()
193
+ ]
194
+ evidence.append({"path": str(manifest_path), "sha256": sha256(manifest_path)})
195
+
196
+ overlay = {
197
+ "schema_version": 1,
198
+ "snapshot_id": REGISTRY["snapshot"]["id"],
199
+ "host": socket.gethostname(),
200
+ "source": ("claude-code / MacStudio / operator-directed full sweep 2026-09-07; "
201
+ "gemini selectors re-probed 2026-09-09 after agy 1.1.27 -> 1.1.28"),
202
+ "evidence": evidence,
203
+ "mappings": mappings,
204
+ "unproven": unproven,
205
+ }
206
+ out = root / "transport-contracts.local.json"
207
+ out.write_text(json.dumps(overlay, indent=2, ensure_ascii=False) + "\n")
208
+ spread = Counter(m["evidence_tier"] for m in mappings)
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())))
211
+
212
+
213
+ if __name__ == "__main__":
214
+ main()
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env python3
2
+ """Report whether the configured AA transport overlay still loads.
3
+
4
+ Prints one `LEVEL<TAB>message` line for `omnilane doctor`. Always exits 0; the
5
+ caller decides how to grade the level. Nothing here contacts a provider.
6
+
7
+ Exists because no other doctor check observes the AA gate: every vendor CLI can
8
+ be reachable and every lane resolvable while `load_registry` refuses the whole
9
+ registry over one drifted evidence hash.
10
+ """
11
+ import hashlib
12
+ import os
13
+ import sys
14
+ from collections import Counter
15
+ from pathlib import Path
16
+
17
+ REPO = Path(sys.argv[1]) if len(sys.argv) > 1 else Path(__file__).resolve().parents[1]
18
+ sys.path.insert(0, str(REPO / "scripts" / "lib"))
19
+
20
+
21
+ def emit(level: str, message: str) -> None:
22
+ print(f"{level}\t{message}")
23
+ raise SystemExit(0)
24
+
25
+
26
+ def digest(path: Path) -> str:
27
+ value = hashlib.sha256()
28
+ with open(path, "rb") as stream:
29
+ for block in iter(lambda: stream.read(1024 * 1024), b""):
30
+ value.update(block)
31
+ return value.hexdigest()
32
+
33
+
34
+ def offenders(overlay_path: Path) -> list[str]:
35
+ """Name the evidence entries that no longer match, for an actionable report."""
36
+ import json
37
+
38
+ try:
39
+ overlay = json.loads(overlay_path.read_text())
40
+ except (OSError, ValueError):
41
+ return []
42
+ found = []
43
+ for entry in overlay.get("evidence", []):
44
+ path = Path(entry.get("path", ""))
45
+ tag = entry.get("vendor") or "untagged"
46
+ if not path.exists():
47
+ found.append(f"{tag}:missing {path}")
48
+ elif digest(path) != entry.get("sha256"):
49
+ found.append(f"{tag}:hash drift {path}")
50
+ return found
51
+
52
+
53
+ def main() -> None:
54
+ overlay_path = os.environ.get("OMNILANE_AA_TRANSPORT_OVERLAY", "")
55
+ if not overlay_path:
56
+ emit("PASS", "no overlay configured; every runtime mapping stays unverified")
57
+ if not Path(overlay_path).exists():
58
+ emit("FAIL", f"configured overlay is missing: {overlay_path}")
59
+
60
+ try:
61
+ import aa_policy
62
+ except ImportError as error:
63
+ emit("WARN", f"cannot import aa_policy: {error}")
64
+
65
+ try:
66
+ registry, _ = aa_policy.load_registry(str(REPO / "config" / "aa-model-policy.json"))
67
+ except Exception as error: # PolicyError, OSError, and anything else fails the gate
68
+ detail = "; ".join(offenders(Path(overlay_path))) or str(error)
69
+ emit("FAIL", f"overlay rejected, every dispatch is refused: {error} ({detail})")
70
+
71
+ tiers = registry.get("_transport_evidence_tiers", {})
72
+ verified = Counter()
73
+ for row in registry["scored_configs"]:
74
+ if row["transport_mapping"].get("runtime_verified") is True:
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"
78
+
79
+ import json
80
+
81
+ overlay = json.loads(Path(overlay_path).read_text())
82
+ unproven = overlay.get("unproven", [])
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")
88
+
89
+ stale = registry.get("_stale_transport_vendors", [])
90
+ if stale:
91
+ detail = "; ".join(o for o in offenders(Path(overlay_path))) or "unknown cause"
92
+ emit("WARN", f"stale vendor(s) {', '.join(stale)} degraded to unverified "
93
+ f"({detail}); still verified: {summary}{extra}")
94
+ emit("PASS", f"verified mappings: {summary}{extra}")
95
+
96
+
97
+ main()