omnilane 0.34.0 → 0.42.1

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 (42) hide show
  1. package/.claude-plugin/marketplace.json +4 -4
  2. package/.claude-plugin/plugin.json +2 -2
  3. package/CHANGELOG.md +71 -1
  4. package/README.ja.md +63 -33
  5. package/README.ko.md +63 -32
  6. package/README.md +147 -86
  7. package/README.zh-CN.md +61 -30
  8. package/README.zh-TW.md +124 -75
  9. package/VERSION +1 -1
  10. package/config/aa-model-policy.json +3046 -0
  11. package/docs/aa-model-coverage-2026-09-05.json +29204 -0
  12. package/docs/completion-wakeup.md +126 -0
  13. package/docs/model-capabilities-2026-09.md +380 -0
  14. package/docs/native-executor.md +264 -0
  15. package/docs/release-notes-0.42.1.md +32 -0
  16. package/hooks/routing-instruction.md +101 -40
  17. package/package.json +8 -2
  18. package/plugin.json +2 -2
  19. package/routing.local.yaml.example +8 -3
  20. package/routing.yaml +16 -16
  21. package/scripts/completion-wakeup.py +390 -0
  22. package/scripts/configure.sh +4 -4
  23. package/scripts/dispatch.sh +323 -32
  24. package/scripts/doctor.sh +55 -1
  25. package/scripts/jobs.sh +64 -17
  26. package/scripts/lib/aa_policy.py +473 -0
  27. package/scripts/lib/aa_retry.py +77 -0
  28. package/scripts/lib/common.sh +106 -1
  29. package/scripts/lib/job-worker.sh +314 -20
  30. package/scripts/lib/live-protocol.sh +147 -2
  31. package/scripts/lib/native.py +507 -0
  32. package/scripts/lib/normalize-claude-stream.py +72 -0
  33. package/scripts/lib/prepare-agy-mode.py +374 -0
  34. package/scripts/release-audit.sh +103 -0
  35. package/scripts/runners/run-claude.sh +81 -47
  36. package/scripts/runners/run-codex-live.py +462 -0
  37. package/scripts/runners/run-codex.sh +62 -3
  38. package/scripts/runners/run-gemini.sh +85 -10
  39. package/scripts/runners/run-grok-live.py +426 -0
  40. package/scripts/runners/run-grok.sh +117 -6
  41. package/scripts/runners/run-vote.sh +6 -3
  42. package/skills/omnilane/SKILL.md +217 -81
package/scripts/jobs.sh CHANGED
@@ -1,6 +1,8 @@
1
1
  #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
  # omnilane background-job helper.
4
+ # Native: jobs.sh [--json] complete-native JOB_ID COMPLETION.json
5
+ # Native pending cancellation records state only; the caller owns its agent.
4
6
  # Usage: jobs.sh [--json] list | status JOB_ID | result JOB_ID | stats [--last N]
5
7
  # jobs.sh [--json] recommend [--last N] [--lane L] [--min-samples N]
6
8
  # jobs.sh wait JOB_ID [--timeout N]
@@ -29,7 +31,7 @@ die() {
29
31
  exit "$rc"
30
32
  }
31
33
 
32
- USAGE_TEXT="usage: jobs.sh [--json] list [--lane L] [--vendor V] [--status running|done]|status ID|result ID|tail ID [--lines N]|send ID TEXT|watch ID|close ID|retry ID [--background]|stats [--last N] [--lane L] [--vendor V]|recommend [--last N] [--lane L] [--min-samples N]|wait ID [--timeout N]|cancel ID|rm ID|threads [list] [--json]|threads show NAME [--json]|threads rm NAME|audit [--last N]|prune [--keep N] [--older-than DAYS] [--apply]|help"
34
+ USAGE_TEXT="usage: jobs.sh [--json] list [--lane L] [--vendor V] [--status running|done|pending|cancelled]|status ID|result ID|complete-native ID FILE|tail ID [--lines N]|send ID TEXT|watch ID|close ID|retry ID [--background]|stats [--last N] [--lane L] [--vendor V]|recommend [--last N] [--lane L] [--min-samples N]|wait ID [--timeout N]|cancel ID|rm ID|threads [list] [--json]|threads show NAME [--json]|threads rm NAME|audit [--last N]|prune [--keep N] [--older-than DAYS] [--apply]|help"
33
35
 
34
36
  usage() {
35
37
  die 2 "$USAGE_TEXT"
@@ -137,11 +139,15 @@ load_job_vendor() {
137
139
  }
138
140
 
139
141
  require_live_job() {
142
+ local action="${1:-}"
140
143
  load_job_vendor
141
144
  live_vendor_capable "$JOB_VENDOR" ||
142
145
  die 1 "job vendor '$JOB_VENDOR' is not live-capable (live vendors: $(live_capable_vendors)); it runs in single-shot mode"
143
146
  [[ "$JOB_SESSION_MODE" == "live" ]] ||
144
147
  die 1 "job vendor '$JOB_VENDOR' was dispatched in single-shot mode"
148
+ if [[ "$action" == "send" && "$JOB_VENDOR" == "grok" ]]; then
149
+ echo "note: Grok send cancels an active turn before starting the new prompt; conversation context survives, but in-progress work is lost"
150
+ fi
145
151
  }
146
152
 
147
153
  wait_for_live_ready() {
@@ -194,7 +200,7 @@ parse_stats_metadata() {
194
200
  parse_audit_metadata() {
195
201
  local value="$1" current_re legacy_re
196
202
  local json_string='([^"\\]|\\["\\/bfnrt]|\\u[0-9a-fA-F]{4})*'
197
- current_re="^\\{\"lane\":\"[a-z][a-z0-9-]*\",\"vendor\":\"(${OMNILANE_VENDOR_ALT})\",\"session_mode\":\"(live|single-shot)\",\"idle_timeout\":(0|[1-9][0-9]*),\"model\":\"${json_string}\",\"effort\":\"${json_string}\",\"timeout\":(0|[1-9][0-9]*),\"job_timeout\":(null|0|[1-9][0-9]*),\"mode\":\"(advise|work|sysops)\",\"workdir\":\"${json_string}\",\"foreman_session\":\"${json_string}\",\"candidate\":\"[1-9][0-9]*/[1-9][0-9]*\",\"started\":\"[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z\"\\}$"
203
+ current_re="^\\{\"lane\":\"[a-z][a-z0-9-]*\",\"vendor\":\"(${OMNILANE_VENDOR_ALT})\",\"session_mode\":\"(live|single-shot)\",\"idle_timeout\":(0|[1-9][0-9]*),\"model\":\"${json_string}\",\"effort\":\"${json_string}\",\"timeout\":(0|[1-9][0-9]*),\"job_timeout\":(null|0|[1-9][0-9]*),\"mode\":\"(advise|work|sysops)\",\"workdir\":\"${json_string}\",\"foreman_session\":\"${json_string}\",(\"thread\":\"${json_string}\",\"thread_turn\":[1-9][0-9]*,)?\"candidate\":\"[1-9][0-9]*/[1-9][0-9]*\",\"started\":\"[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z\"(,\"worker_interpreter_path\":\"${json_string}\",\"worker_interpreter_version\":\"${json_string}\",\"job_worker_sha256\":\"[0-9a-f]{64}\")?\\}$"
198
204
  legacy_re="^\\{\"lane\":\"[a-z][a-z0-9-]*\",\"vendor\":\"(${OMNILANE_VENDOR_ALT})\",\"model\":\"${json_string}\",\"effort\":\"${json_string}\",\"timeout\":(0|[1-9][0-9]*),\"job_timeout\":(null|0|[1-9][0-9]*),\"mode\":\"(advise|work|sysops)\",\"workdir\":\"${json_string}\",(\"foreman_session\":\"${json_string}\",)?\"candidate\":\"[1-9][0-9]*/[1-9][0-9]*\",\"started\":\"[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z\"\\}$"
199
205
  [[ "$value" =~ $current_re || "$value" =~ $legacy_re ]]
200
206
  }
@@ -318,6 +324,23 @@ done
318
324
  # set -u on Bash 3.2; a bare `jobs.sh` must reach usage, not crash.
319
325
  set -- ${args[@]+"${args[@]}"}
320
326
  COMMAND="${1:-unknown}"
327
+
328
+ # Native jobs have no shell worker PID. Intercept before any CLI lifecycle
329
+ # operation, including cancellation, retry, wait and rm. Python validates the
330
+ # store, job ID, lock and record before accepting or publishing a transition.
331
+ if [[ "$COMMAND" == "complete-native" ]] ||
332
+ { [[ "${2:-}" =~ $JOB_ID_PATTERN ]] &&
333
+ { [[ -e "$JOBS/${2}/native.json" || -L "$JOBS/${2}/native.json" ||
334
+ -e "$JOBS/${2}/native.lock" || -L "$JOBS/${2}/native.lock" ]]; }; }; then
335
+ case "$COMMAND" in
336
+ complete-native) [[ $# -eq 3 ]] || usage ;;
337
+ status|result|cancel) [[ $# -eq 2 ]] || usage ;;
338
+ *) die 2 "native job supports status, result, cancel and complete-native; caller owns agent lifecycle" ;;
339
+ esac
340
+ native_args=(job --home "$OMNILANE_HOME")
341
+ [[ "$JSON_MODE" -eq 0 ]] || native_args+=(--json)
342
+ exec python3 "$OMNILANE_REPO/scripts/lib/native.py" "${native_args[@]}" "$@"
343
+ fi
321
344
  if [[ "$JSON_MODE" -eq 1 ]]; then
322
345
  case "$COMMAND" in
323
346
  list|status|result|stats|recommend|audit|threads) ;;
@@ -405,7 +428,7 @@ case "${1:-}" in
405
428
  send)
406
429
  [[ "$JSON_MODE" -eq 0 && $# -eq 3 ]] || usage
407
430
  select_job "$2"
408
- require_live_job
431
+ require_live_job send
409
432
  wait_for_live_ready
410
433
  if [[ "${FOREMAN_SESSION+x}" == "x" ]]; then
411
434
  foreman_value="$FOREMAN_SESSION"
@@ -507,6 +530,15 @@ case "${1:-}" in
507
530
  while [[ $# -gt 0 ]]; do
508
531
  case "$1" in
509
532
  --background) retry_background=1; shift ;;
533
+ --caller-context)
534
+ [[ "$#" -ge 2 ]] || die 2 "retry --caller-context requires a file"
535
+ export OMNILANE_AA_CALLER_CONTEXT="$2"
536
+ unset OMNILANE_AA_OPERATOR_ASSERTED_HUMAN
537
+ shift 2 ;;
538
+ --operator-asserted-human)
539
+ export OMNILANE_AA_OPERATOR_ASSERTED_HUMAN=1
540
+ unset OMNILANE_AA_CALLER_CONTEXT
541
+ shift ;;
510
542
  *) usage ;;
511
543
  esac
512
544
  done
@@ -517,18 +549,14 @@ case "${1:-}" in
517
549
  read_public_metadata "$JOB_DIR/meta.json" || {
518
550
  die 1 "cannot retry: unreadable job metadata"
519
551
  }
520
- retry_re='^\{"lane":"([a-z][a-z0-9-]*)","vendor":"('"$OMNILANE_VENDOR_ALT"')","model":"([^"\\]*)","effort":"([^"\\]*)","timeout":([1-9][0-9]*),"job_timeout":([1-9][0-9]*|null),"mode":"(advise|work)","workdir":"([^"\\]*)",'
521
- [[ "$PUBLIC_METADATA" =~ $retry_re ]] || {
522
- die 1 "cannot retry: job metadata is not safely parseable"
523
- }
524
- retry_lane="${BASH_REMATCH[1]}"
525
- retry_vendor="${BASH_REMATCH[2]}"
526
- retry_model="${BASH_REMATCH[3]}"
527
- retry_effort="${BASH_REMATCH[4]}"
528
- retry_timeout="${BASH_REMATCH[5]}"
529
- retry_job_timeout="${BASH_REMATCH[6]}"
530
- retry_mode="${BASH_REMATCH[7]}"
531
- retry_workdir="${BASH_REMATCH[8]}"
552
+ retry_fields_text="$(python3 "$OMNILANE_REPO/scripts/lib/aa_retry.py" --metadata "$JOB_DIR")" || exit $?
553
+ retry_fields=()
554
+ while IFS= read -r retry_field; do retry_fields+=("$retry_field"); done <<< "$retry_fields_text"
555
+ [[ "${#retry_fields[@]}" -eq 8 ]] || die 1 "invalid retry metadata fields"
556
+ retry_lane="${retry_fields[0]}"; retry_vendor="${retry_fields[1]}"
557
+ retry_model="${retry_fields[2]}"; retry_effort="${retry_fields[3]}"
558
+ retry_timeout="${retry_fields[4]}"; retry_job_timeout="${retry_fields[5]}"
559
+ retry_mode="${retry_fields[6]}"; retry_workdir="${retry_fields[7]}"
532
560
  task_path="$JOB_DIR/task.txt"
533
561
  [[ -f "$task_path" && ! -L "$task_path" ]] || {
534
562
  die 1 "cannot retry: original task text is missing"
@@ -537,6 +565,13 @@ case "${1:-}" in
537
565
  die 1 "cannot retry: original workdir no longer exists: $retry_workdir"
538
566
  }
539
567
  retry_args=(--mode "$retry_mode" --workdir "$retry_workdir" --timeout "$retry_timeout")
568
+ policy_retry_args="$(python3 "$OMNILANE_REPO/scripts/lib/aa_retry.py" "$JOB_DIR")" || exit $?
569
+ while IFS= read -r policy_arg; do
570
+ retry_args+=("$policy_arg")
571
+ done <<< "$policy_retry_args"
572
+ # Retry reauthorizes under the original job, not the current shell identity.
573
+ unset OMNILANE_AA_CALLER_CONTEXT OMNILANE_AA_OPERATOR_ASSERTED_HUMAN OMNILANE_AA_TRANSPORT_OVERLAY OMNILANE_AA_OVERLAY_SHA256
574
+
540
575
  [[ "$retry_job_timeout" == "null" ]] || retry_args+=(--job-timeout "$retry_job_timeout")
541
576
  # dispatch --vendor only accepts real CLI vendors; an exec gate is re-run
542
577
  # through normal lane resolution plus the recorded --model script path.
@@ -888,8 +923,8 @@ case "${1:-}" in
888
923
  [[ -z "$filter_lane" || "$filter_lane" =~ ^[a-z][a-z0-9-]*$ ]] || die 2 "invalid --lane value"
889
924
  [[ -z "$filter_vendor" ]] || omnilane_known_vendor "$filter_vendor" || die 2 "invalid --vendor value"
890
925
  case "$filter_status" in
891
- ""|running|done) ;;
892
- *) die 2 "invalid --status value (want running or done)" ;;
926
+ ""|running|done|pending|cancelled) ;;
927
+ *) die 2 "invalid --status value (want running, done, pending or cancelled)" ;;
893
928
  esac
894
929
  if [[ ! -d "$JOBS" ]]; then
895
930
  [[ "$JSON_MODE" -eq 0 ]] || printf '{"schema_version":1,"command":"list","ok":true,"jobs":[]}\n'
@@ -925,6 +960,16 @@ case "${1:-}" in
925
960
  else
926
961
  json_state="running"
927
962
  fi
963
+ if [[ -e "$JOBS/$id/native.json" || -L "$JOBS/$id/native.json" || -e "$JOBS/$id/native.lock" ]]; then
964
+ json_state="$(python3 "$OMNILANE_REPO/scripts/lib/native.py" job --home "$OMNILANE_HOME" list-state "$id")" || die 1 "invalid native state"
965
+ state="$json_state"
966
+ # Native completion lives in native.json, not a PID/exit pair.
967
+ exit_json="null"
968
+ if [[ "$json_state" != "pending" ]]; then
969
+ native_status="$(python3 "$OMNILANE_REPO/scripts/lib/native.py" job --home "$OMNILANE_HOME" --json status "$id")" || die 1 "invalid native state"
970
+ exit_json="$(python3 -c 'import json,sys; print(json.loads(sys.argv[1])["job"]["exit_code"])' "$native_status")"
971
+ fi
972
+ fi
928
973
  metadata=""
929
974
  metadata_json="null"
930
975
  metadata_status="missing"
@@ -949,6 +994,7 @@ case "${1:-}" in
949
994
  case "$json_state" in
950
995
  done) [[ "$filter_status" == "done" ]] || continue ;;
951
996
  running) [[ "$filter_status" == "running" ]] || continue ;;
997
+ pending|cancelled) [[ "$filter_status" == "$json_state" ]] || continue ;;
952
998
  *) continue ;;
953
999
  esac
954
1000
  fi
@@ -1225,6 +1271,7 @@ case "${1:-}" in
1225
1271
  [[ -d "$job_dir" && ! -L "$job_dir" ]] || continue
1226
1272
  id="${job_dir##*/}"
1227
1273
  [[ "$id" =~ $JOB_ID_PATTERN ]] || continue
1274
+ [[ ! -e "$job_dir/native.lock" && ! -e "$job_dir/native.json" ]] || continue
1228
1275
  read_exit_code "$job_dir/exit" || continue
1229
1276
  completed+=("$id")
1230
1277
  done
@@ -0,0 +1,473 @@
1
+ #!/usr/bin/env python3
2
+ """Frozen exact-AA downward-delegation decision engine.
3
+
4
+ This module is intentionally provider-free. It validates one explicit caller
5
+ assertion against the frozen registry, resolves only runtime-verified target
6
+ mappings, and emits a structured allow/deny decision. The JSON context is
7
+ cooperative workflow metadata, not operating-system authentication.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import argparse
13
+ import hashlib
14
+ import json
15
+ import os
16
+ from pathlib import Path
17
+ import re
18
+ import stat
19
+ import tempfile
20
+ import socket
21
+ import sys
22
+ from typing import Any
23
+
24
+
25
+ MAX_BYTES = 1_048_576
26
+ # Approval anchor for the frozen AA v4.2 2026-09-07 source bytes. Updating this
27
+ # constant is a governance change, never a caller argument/environment override.
28
+ APPROVED_REGISTRY_SHA256 = "0782c87de123c02738c3ff60e4bc3c1cc10d110113e872b8f8627212861cdaab"
29
+
30
+ IDENTITY_FIELDS = ("vendor", "model", "effort", "reasoning", "fallback")
31
+ IDENTIFIER = re.compile(r"[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}\Z")
32
+
33
+
34
+ class PolicyError(ValueError):
35
+ """A public, non-sensitive policy validation error."""
36
+
37
+
38
+ def _check(condition: bool, message: str) -> None:
39
+ if not condition:
40
+ raise PolicyError(message)
41
+
42
+
43
+ def _unique_object(pairs: list[tuple[str, Any]]) -> dict[str, Any]:
44
+ result: dict[str, Any] = {}
45
+ for key, value in pairs:
46
+ _check(key not in result, "duplicate JSON key")
47
+ result[key] = value
48
+ return result
49
+
50
+
51
+ def _read_bytes(path: str | Path) -> bytes:
52
+ fd = os.open(path, os.O_RDONLY | os.O_NOFOLLOW | os.O_NONBLOCK)
53
+ with os.fdopen(fd, "rb") as stream:
54
+ info = os.fstat(stream.fileno())
55
+ _check(stat.S_ISREG(info.st_mode), "policy input must be a regular file")
56
+ _check(info.st_size <= MAX_BYTES, "policy input is too large")
57
+ data = stream.read(MAX_BYTES + 1)
58
+ _check(len(data) <= MAX_BYTES, "policy input is too large")
59
+ return data
60
+
61
+
62
+ def _read_json(path: str | Path) -> tuple[dict[str, Any], str]:
63
+ data = _read_bytes(path)
64
+ try:
65
+ value = json.loads(
66
+ data.decode("utf-8"),
67
+ object_pairs_hook=_unique_object,
68
+ parse_constant=lambda _: (_ for _ in ()).throw(PolicyError("invalid JSON number")),
69
+ )
70
+ except (UnicodeError, json.JSONDecodeError) as error:
71
+ raise PolicyError("invalid JSON input") from error
72
+ _check(isinstance(value, dict), "policy input must be a JSON object")
73
+ return value, hashlib.sha256(data).hexdigest()
74
+
75
+
76
+ def _exact_fields(value: dict[str, Any], required: set[str]) -> None:
77
+ _check(set(value) == required, "missing or unknown caller-context fields")
78
+
79
+
80
+ def _identity(value: Any, label: str) -> dict[str, Any]:
81
+ _check(isinstance(value, dict), f"{label} must be a JSON object")
82
+ _exact_fields(value, set(IDENTITY_FIELDS))
83
+ for key in ("vendor", "model", "reasoning"):
84
+ field = value[key]
85
+ _check(isinstance(field, str) and bool(IDENTIFIER.fullmatch(field)),
86
+ f"invalid {label}.{key}")
87
+ for key in ("effort", "fallback"):
88
+ field = value[key]
89
+ _check(field is None or (isinstance(field, str) and bool(IDENTIFIER.fullmatch(field))),
90
+ f"invalid {label}.{key}")
91
+ return {key: value[key] for key in IDENTITY_FIELDS}
92
+
93
+
94
+ def _validate_registry(value: dict[str, Any]) -> dict[str, Any]:
95
+ required = {
96
+ "schema_version", "snapshot", "policy", "scored_configs",
97
+ "unknown_configs", "reference_configs", "aliases", "coverage",
98
+ }
99
+ _check(required <= set(value) <= required | {"schema_notes"},
100
+ "unsupported AA registry schema")
101
+ _check(type(value["schema_version"]) is int and value["schema_version"] == 1,
102
+ "unsupported AA registry version")
103
+ snapshot = value["snapshot"]
104
+ _check(isinstance(snapshot, dict), "invalid AA registry snapshot")
105
+ for key in ("id", "benchmark_version", "as_of", "frozen"):
106
+ _check(key in snapshot, "incomplete AA registry snapshot")
107
+ _check(snapshot["benchmark_version"] == "4.2"
108
+ and snapshot["as_of"] == "2026-09-07"
109
+ and snapshot["frozen"] is True,
110
+ "AA registry is not frozen v4.2 dated 2026-09-07")
111
+ policy = value["policy"]
112
+ _check(isinstance(policy, dict)
113
+ and policy.get("decision") == "target_score <= min(caller_score, inherited_ceiling)"
114
+ and policy.get("same_score_allowed") is True
115
+ and policy.get("unknown") == "deny"
116
+ and policy.get("transport_mapping_requires_runtime_verification") is True,
117
+ "AA registry policy contract mismatch")
118
+ rows = value["scored_configs"]
119
+ _check(isinstance(rows, list) and rows, "AA registry has no scored configurations")
120
+ seen: set[str] = set()
121
+ for row in rows:
122
+ _check(isinstance(row, dict), "invalid AA scored configuration")
123
+ for key in (*IDENTITY_FIELDS, "id", "score", "estimated", "benchmark_version",
124
+ "as_of", "transport_mapping"):
125
+ _check(key in row, "incomplete AA scored configuration")
126
+ _check(isinstance(row["id"], str) and row["id"] not in seen,
127
+ "duplicate AA scored configuration")
128
+ seen.add(row["id"])
129
+ _identity({key: row[key] for key in IDENTITY_FIELDS}, "registry identity")
130
+ _check(type(row["score"]) is int and 0 <= row["score"] <= 100,
131
+ "invalid AA score")
132
+ _check(type(row["estimated"]) is bool, "invalid AA estimated flag")
133
+ _check(row["benchmark_version"] == "4.2" and row["as_of"] == "2026-09-07",
134
+ "mixed AA registry snapshot")
135
+ _check(isinstance(row["transport_mapping"], dict), "invalid transport mapping")
136
+ return value
137
+
138
+
139
+ def apply_transport_overlay(registry: dict[str, Any]) -> None:
140
+ """Host-local request selector proof, independent of frozen AA scores."""
141
+ path = os.environ.get("OMNILANE_AA_TRANSPORT_OVERLAY")
142
+ if not path:
143
+ return
144
+ overlay, digest = _read_json(path)
145
+ expected = os.environ.get("OMNILANE_AA_OVERLAY_SHA256")
146
+ _check(not expected or expected == digest, "transport overlay changed after initial decision")
147
+ _check(overlay.get("schema_version") == 1, "unsupported transport overlay")
148
+ _check(overlay.get("snapshot_id") == registry["snapshot"]["id"], "transport overlay snapshot mismatch")
149
+ _check(overlay.get("host") == socket.gethostname(), "transport overlay host mismatch")
150
+ for evidence in overlay.get("evidence", []):
151
+ fd = os.open(evidence["path"], os.O_RDONLY | os.O_NOFOLLOW | os.O_NONBLOCK)
152
+ with os.fdopen(fd, "rb") as stream:
153
+ _check(stat.S_ISREG(os.fstat(stream.fileno()).st_mode), "invalid transport evidence file")
154
+ digest_file = hashlib.sha256()
155
+ for block in iter(lambda: stream.read(1024 * 1024), b""):
156
+ digest_file.update(block)
157
+ _check(digest_file.hexdigest() == evidence["sha256"], "transport contract evidence changed")
158
+ _check(bool(overlay.get("evidence")), "transport overlay requires local evidence")
159
+ for mapping in overlay.get("mappings", []):
160
+ rows = [row for row in registry["scored_configs"] if row["id"] == mapping.get("config_id")]
161
+ _check(len(rows) == 1, "unknown overlay config")
162
+ row = rows[0]
163
+ _check(mapping.get("identity") == _row_identity(row), "overlay exact identity mismatch")
164
+ _check(mapping.get("verification") == "request-selector-contract", "unsupported overlay verification")
165
+ _check(mapping.get("runtime_effort") == row["effort"], "overlay effort mismatch")
166
+ selector_type = mapping.get("selector_type", "model_and_effort")
167
+ _check(selector_type in ("model_and_effort", "model_id_encoded_effort"), "unknown selector type")
168
+ if selector_type == "model_id_encoded_effort":
169
+ _check(row["vendor"] == "gemini", "unsupported encoded-effort vendor")
170
+ _check(mapping.get("runtime_model") in row["transport_mapping"].get("candidate_model_ids", []), "unproven encoded model selector")
171
+ _check(mapping["runtime_model"].endswith("-" + row["effort"]), "encoded effort does not match exact tuple")
172
+ else:
173
+ _check(mapping.get("runtime_model") == row["model"], "overlay model mismatch")
174
+ row["transport_mapping"].update(
175
+ status="verified", runtime_verified=True,
176
+ runtime_model=mapping["runtime_model"], runtime_effort=mapping["runtime_effort"],
177
+ selector_type=selector_type,
178
+ verification="request-selector-contract", upstream_identity_verified=False,
179
+ overlay_sha256=digest, overlay_host=overlay["host"],
180
+ )
181
+
182
+
183
+ def load_registry(path: str | Path, expected_sha256: str | None = None) -> tuple[dict[str, Any], str]:
184
+ value, digest = _read_json(path)
185
+ _check(digest == APPROVED_REGISTRY_SHA256, "unapproved AA registry; use the approved frozen snapshot byte-for-byte")
186
+ if expected_sha256:
187
+ _check(digest == expected_sha256, "AA registry changed after initial decision")
188
+ registry = _validate_registry(value)
189
+ apply_transport_overlay(registry)
190
+ return registry, digest
191
+
192
+
193
+ def load_caller(path: str | Path, registry: dict[str, Any],
194
+ expected_sha256: str | None = None) -> tuple[dict[str, Any], str]:
195
+ value, digest = _read_json(path)
196
+ if expected_sha256:
197
+ _check(digest == expected_sha256, "caller context changed after initial decision")
198
+ _check(type(value.get("schema_version")) is int and value["schema_version"] == 1,
199
+ "unsupported caller-context version")
200
+ _check(value.get("snapshot_id") == registry["snapshot"]["id"],
201
+ "caller-context snapshot does not match frozen registry")
202
+ _check(value.get("kind") == "model", "unsupported caller-context kind")
203
+ _exact_fields(value, {"schema_version", "snapshot_id", "kind", "caller", "inherited_ceiling"})
204
+ value["caller"] = _identity(value["caller"], "caller")
205
+ ceiling = value["inherited_ceiling"]
206
+ _check(type(ceiling) is int and 0 <= ceiling <= 100,
207
+ "invalid inherited caller ceiling")
208
+ return value, digest
209
+
210
+
211
+ def _row_identity(row: dict[str, Any]) -> dict[str, Any]:
212
+ return {key: row[key] for key in IDENTITY_FIELDS}
213
+
214
+
215
+ def _matching_rows(registry: dict[str, Any], identity: dict[str, Any]) -> list[dict[str, Any]]:
216
+ return [row for row in registry["scored_configs"] if _row_identity(row) == identity]
217
+
218
+
219
+ def _unknown_reason(registry: dict[str, Any], identity: dict[str, Any]) -> str | None:
220
+ for row in registry["unknown_configs"]:
221
+ if all(row.get(key) == identity[key] for key in IDENTITY_FIELDS):
222
+ return row.get("reason")
223
+ return None
224
+
225
+
226
+ def _runtime_target(registry: dict[str, Any], vendor: str, model: str,
227
+ effort: str | None, target_config: str | None) -> tuple[dict[str, Any] | None, str, dict[str, Any]]:
228
+ exact_id = [row for row in registry["scored_configs"] if row["id"] == target_config] if target_config else registry["scored_configs"]
229
+ if target_config and not exact_id:
230
+ return None, "unknown-target-config", {"target_config": target_config}
231
+ vendor_rows = [row for row in exact_id if row["vendor"] == vendor]
232
+ candidates: list[dict[str, Any]] = []
233
+ unresolved: list[str] = []
234
+ for row in vendor_rows:
235
+ mapping = row["transport_mapping"]
236
+ model_ids = mapping.get("candidate_model_ids", [])
237
+ runtime_model = mapping.get("runtime_model")
238
+ runtime_effort = mapping.get("runtime_effort", row["effort"])
239
+ model_match = model == runtime_model if runtime_model is not None else model in model_ids
240
+ encoded_effort = mapping.get("selector_type") == "model_id_encoded_effort"
241
+ if not model_match:
242
+ continue
243
+ if encoded_effort and effort not in (None, runtime_effort):
244
+ return None, "encoded-effort-conflict", {"model": model, "effort": effort, "encoded_effort": runtime_effort}
245
+ if not encoded_effort and effort != runtime_effort:
246
+ continue
247
+ if mapping.get("runtime_verified") is True and mapping.get("status") in ("verified", "resolved"):
248
+ candidates.append(row)
249
+ else:
250
+ unresolved.append(row["id"])
251
+ if vendor == "grok" and candidates:
252
+ # The checked-in Grok runner accepts EFFORT for interface parity but
253
+ # discards it. A scored reasoning/effort row therefore cannot be
254
+ # proven by that runtime surface.
255
+ return None, "runtime-effort-discarded", {"vendor": vendor, "model": model, "effort": effort}
256
+ if len(candidates) == 1:
257
+ return candidates[0], "runtime-mapping-verified", {}
258
+ if len(candidates) > 1:
259
+ return None, "ambiguous-runtime-mapping", {"candidate_config_ids": [row["id"] for row in candidates]}
260
+ if unresolved:
261
+ return None, "runtime-mapping-unverified", {"candidate_config_ids": unresolved}
262
+ return None, "unknown-target-runtime", {"vendor": vendor, "model": model, "effort": effort}
263
+
264
+
265
+ def decide(registry: dict[str, Any], registry_sha256: str, *,
266
+ vendor: str, model: str, effort: str | None,
267
+ caller: dict[str, Any] | None, caller_sha256: str | None,
268
+ operator_asserted_human: bool = False,
269
+ target_config: str | None = None) -> dict[str, Any]:
270
+ base: dict[str, Any] = {
271
+ "schema_version": 1,
272
+ "snapshot_id": registry["snapshot"]["id"],
273
+ "registry_sha256": registry_sha256,
274
+ "allowed": False,
275
+ "code": "deny",
276
+ "message": "AA policy denied dispatch",
277
+ "caller_kind": "operator-asserted-human" if operator_asserted_human else "model",
278
+ "target_request": {"vendor": vendor, "model": model, "effort": effort},
279
+ "target_config_id": target_config,
280
+ "caller_score": None,
281
+ "inherited_ceiling": None,
282
+ "effective_ceiling": None,
283
+ "target_score": None,
284
+ "target_estimated": None,
285
+ "child_context": None,
286
+ "evidence_limit": "workflow metadata and selected model arguments do not prove actual provider identity",
287
+ }
288
+ if operator_asserted_human:
289
+ base.update(
290
+ allowed=True,
291
+ code="operator-asserted-human-exemption",
292
+ message="explicit operator assertion bypassed model-level AA ceiling",
293
+ evidence_limit="operator assertion is cooperative metadata, not authentication or provider-identity proof",
294
+ )
295
+ return base
296
+ if caller is None:
297
+ base.update(
298
+ code="missing-caller-context",
299
+ message="provide --caller-context FILE or explicitly assert --operator-asserted-human",
300
+ )
301
+ return base
302
+ base["caller_context_sha256"] = caller_sha256
303
+ caller_identity = caller["caller"]
304
+ caller_rows = _matching_rows(registry, caller_identity)
305
+ if len(caller_rows) != 1:
306
+ detail = _unknown_reason(registry, caller_identity)
307
+ base.update(
308
+ code="unknown-caller-config" if not caller_rows else "ambiguous-caller-config",
309
+ message=detail or "caller exact vendor/model/effort/reasoning/fallback is not uniquely scored",
310
+ caller=caller_identity,
311
+ )
312
+ return base
313
+ caller_row = caller_rows[0]
314
+ effective = min(caller_row["score"], caller["inherited_ceiling"])
315
+ base.update(
316
+ caller=caller_identity,
317
+ caller_score=caller_row["score"],
318
+ inherited_ceiling=caller["inherited_ceiling"],
319
+ effective_ceiling=effective,
320
+ )
321
+ target_row, mapping_code, detail = _runtime_target(
322
+ registry, vendor, model, effort, target_config
323
+ )
324
+ if target_row is None:
325
+ base.update(code=mapping_code, message="target runtime cannot be mapped to one verified exact AA configuration", **detail)
326
+ return base
327
+ target_score = target_row["score"]
328
+ target_identity = _row_identity(target_row)
329
+ base.update(
330
+ target_config_id=target_row["id"],
331
+ target=target_identity,
332
+ target_score=target_score,
333
+ target_estimated=target_row["estimated"],
334
+ )
335
+ if target_score > effective:
336
+ base.update(
337
+ code="target-above-effective-ceiling",
338
+ message=f"target score {target_score} exceeds effective caller ceiling {effective}",
339
+ )
340
+ return base
341
+ child_context = {
342
+ "schema_version": 1,
343
+ "snapshot_id": registry["snapshot"]["id"],
344
+ "kind": "model",
345
+ "caller": target_identity,
346
+ "inherited_ceiling": effective,
347
+ }
348
+ base.update(
349
+ allowed=True,
350
+ code="same-score-allowed" if target_score == effective else "downward-allowed",
351
+ message="target exact AA score is at or below effective caller ceiling",
352
+ child_context=child_context,
353
+ )
354
+ return base
355
+
356
+
357
+ def _normalized_effort(value: str) -> str | None:
358
+ return None if value in ("", "-") else value
359
+
360
+
361
+ def _json_line(value: dict[str, Any]) -> str:
362
+ return json.dumps(value, ensure_ascii=False, separators=(",", ":")) + "\n"
363
+
364
+
365
+ def atomic_bytes(path: Path, content: bytes) -> None:
366
+ """Publish private metadata without exposing a partial file."""
367
+ fd, name = tempfile.mkstemp(prefix=".aa-", dir=path.parent)
368
+ try:
369
+ with os.fdopen(fd, "wb") as stream:
370
+ stream.write(content)
371
+ stream.flush()
372
+ os.fsync(stream.fileno())
373
+ os.replace(name, path)
374
+ finally:
375
+ if os.path.exists(name):
376
+ os.unlink(name)
377
+
378
+
379
+ def atomic_json(path: Path, value: dict[str, Any]) -> None:
380
+ atomic_bytes(path, _json_line(value).encode("utf-8"))
381
+
382
+
383
+ def publish_context(directory: str | Path, registry: dict[str, Any],
384
+ caller: dict[str, Any] | None, decision: dict[str, Any],
385
+ registry_source: str | Path | None = None) -> dict[str, Any]:
386
+ """Keep immutable-by-convention authorizer and a distinct narrowed child identity.
387
+
388
+ This is lineage metadata, not authentication. The frozen registry content is
389
+ copied so later retries cannot silently select a different score snapshot.
390
+ """
391
+ root = Path(directory)
392
+ _check(root.is_dir() and not root.is_symlink(), "invalid context publication directory")
393
+ _check(decision.get("allowed") is True, "cannot publish a denied decision")
394
+ source = Path(registry_source) if registry_source else Path(__file__).resolve().parents[2] / "config/aa-model-policy.json"
395
+ source_bytes = _read_bytes(source)
396
+ _check(hashlib.sha256(source_bytes).hexdigest() == APPROVED_REGISTRY_SHA256, "unapproved AA registry snapshot publication")
397
+ atomic_bytes(root / "aa-registry.json", source_bytes)
398
+ registry_sha = hashlib.sha256((root / "aa-registry.json").read_bytes()).hexdigest()
399
+ if caller is not None:
400
+ atomic_json(root / "aa-authorizer.json", caller)
401
+ child = decision.get("child_context")
402
+ if child is not None:
403
+ atomic_json(root / "aa-child-context.json", child)
404
+ lineage = {
405
+ "schema_version": 1,
406
+ "registry_sha256": registry_sha,
407
+ "authorizer_sha256": hashlib.sha256((root / "aa-authorizer.json").read_bytes()).hexdigest() if caller else None,
408
+ "operator_asserted_human": decision["caller_kind"] == "operator-asserted-human",
409
+ "target_config_id": decision["target_config_id"],
410
+ "target_request": decision["target_request"],
411
+ "effective_ceiling": decision["effective_ceiling"],
412
+ "child_context": child,
413
+ }
414
+ overlay_path = os.environ.get("OMNILANE_AA_TRANSPORT_OVERLAY")
415
+ if overlay_path:
416
+ overlay, _ = _read_json(overlay_path)
417
+ atomic_json(root / "aa-transport-overlay.json", overlay)
418
+ lineage["transport_overlay_sha256"] = hashlib.sha256((root / "aa-transport-overlay.json").read_bytes()).hexdigest()
419
+ atomic_json(root / "aa-lineage.json", lineage)
420
+ atomic_json(root / "aa-decision.json", decision)
421
+ return lineage
422
+
423
+
424
+ def main(argv: list[str] | None = None) -> int:
425
+ parser = argparse.ArgumentParser(description=__doc__)
426
+ parser.add_argument("--registry", required=True)
427
+ parser.add_argument("--expected-registry-sha256")
428
+ source = parser.add_mutually_exclusive_group()
429
+ source.add_argument("--caller-context")
430
+ source.add_argument("--operator-asserted-human", action="store_true")
431
+ parser.add_argument("--expected-caller-sha256")
432
+ parser.add_argument("--vendor", required=True)
433
+ parser.add_argument("--model", required=True)
434
+ parser.add_argument("--effort", required=True)
435
+ parser.add_argument("--target-config")
436
+ parser.add_argument("--publish-dir")
437
+ args = parser.parse_args(argv)
438
+ try:
439
+ registry, registry_sha = load_registry(args.registry, args.expected_registry_sha256)
440
+ caller = None
441
+ caller_sha = None
442
+ if args.caller_context:
443
+ caller, caller_sha = load_caller(
444
+ args.caller_context, registry, args.expected_caller_sha256
445
+ )
446
+ result = decide(
447
+ registry,
448
+ registry_sha,
449
+ vendor=args.vendor,
450
+ model=args.model,
451
+ effort=_normalized_effort(args.effort),
452
+ caller=caller,
453
+ caller_sha256=caller_sha,
454
+ operator_asserted_human=args.operator_asserted_human,
455
+ target_config=args.target_config,
456
+ )
457
+ if args.publish_dir and result["allowed"]:
458
+ publish_context(args.publish_dir, registry, caller, result, args.registry)
459
+ print(_json_line(result), end="")
460
+ return 0 if result["allowed"] else 3
461
+ except (PolicyError, OSError, RecursionError, TypeError, KeyError) as error:
462
+ message = str(error) if isinstance(error, PolicyError) else "invalid or inaccessible AA policy input"
463
+ print(_json_line({
464
+ "schema_version": 1,
465
+ "allowed": False,
466
+ "code": "invalid-policy-input",
467
+ "message": message,
468
+ }), end="")
469
+ return 2
470
+
471
+
472
+ if __name__ == "__main__":
473
+ sys.exit(main())