@arbiterforge/ca-pi 0.14.9 → 0.14.12

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 (40) hide show
  1. package/README.md +7 -2
  2. package/package.json +1 -1
  3. package/plugins/ca-pi/CHANGELOG.md +39 -0
  4. package/plugins/ca-pi/SKILLS.md +2 -2
  5. package/plugins/ca-pi/SPRINT.md +47 -0
  6. package/plugins/ca-pi/generated/command-catalog.json +2 -2
  7. package/plugins/ca-pi/helpers/artifacts/ca-artifact-darwin-amd64 +0 -0
  8. package/plugins/ca-pi/helpers/artifacts/ca-artifact-darwin-arm64 +0 -0
  9. package/plugins/ca-pi/helpers/artifacts/ca-artifact-linux-amd64 +0 -0
  10. package/plugins/ca-pi/helpers/artifacts/ca-artifact-linux-arm64 +0 -0
  11. package/plugins/ca-pi/helpers/artifacts/ca-artifact-windows-amd64.exe +0 -0
  12. package/plugins/ca-pi/helpers/artifacts/ca-artifact-windows-arm64.exe +0 -0
  13. package/plugins/ca-pi/helpers/artifacts/release.json +6 -6
  14. package/plugins/ca-pi/hooks/_approvallib.py +58 -22
  15. package/plugins/ca-pi/hooks/_artifactauthoritylib.py +1686 -0
  16. package/plugins/ca-pi/hooks/_artifactlib.py +14 -4
  17. package/plugins/ca-pi/hooks/_artifactpromptlib.py +177 -0
  18. package/plugins/ca-pi/hooks/_githooks.py +368 -39
  19. package/plugins/ca-pi/hooks/_host.py +1 -1
  20. package/plugins/ca-pi/hooks/_overrideappendlib.py +5 -1
  21. package/plugins/ca-pi/hooks/_prerequisitelib.py +44 -22
  22. package/plugins/ca-pi/hooks/_reconciliationlib.py +472 -0
  23. package/plugins/ca-pi/hooks/_sprintapprovallib.py +302 -0
  24. package/plugins/ca-pi/hooks/artifact-authority-hook.py +72 -0
  25. package/plugins/ca-pi/hooks/artifact-authority.py +80 -0
  26. package/plugins/ca-pi/hooks/artifact-reconcile.py +57 -0
  27. package/plugins/ca-pi/hooks/doctor.py +3 -1
  28. package/plugins/ca-pi/hooks/hostapi.py +1 -1
  29. package/plugins/ca-pi/hooks/prompt-submit.py +20 -3
  30. package/plugins/ca-pi/includes/artifacts.md +99 -12
  31. package/plugins/ca-pi/includes/sprint-authority.md +69 -0
  32. package/plugins/ca-pi/package.json +1 -1
  33. package/plugins/ca-pi/routines/INDEX.md +7 -4
  34. package/plugins/ca-pi/routines/brainstorming/SKILL.md +97 -29
  35. package/plugins/ca-pi/routines/commit-gate/SKILL.md +7 -1
  36. package/plugins/ca-pi/routines/executing-plans/SKILL.md +32 -15
  37. package/plugins/ca-pi/routines/skill-author/SKILL.md +26 -5
  38. package/plugins/ca-pi/routines/writing-plans/SKILL.md +22 -10
  39. package/plugins/ca-pi/skills/ca-commit/SKILL.md +170 -16
  40. package/plugins/ca-pi/skills/ca-new-skill/SKILL.md +116 -21
@@ -0,0 +1,1686 @@
1
+ #!/usr/bin/env python3
2
+ # codeArbiter — durable closed authority producers for structured artifacts.
3
+ """Supervise verification and correlate independent Codex review evidence.
4
+
5
+ arm_request(...) -> dict
6
+ run_verification(...) -> dict
7
+ observe_codex_hook(...) -> dict
8
+ publish_request(...) -> dict
9
+
10
+ The artifact engine owns every target binding. Callers select only an activity
11
+ and record; they cannot supply an authority kind, verdict, evidence payload, or
12
+ reviewer identity. External work is journaled before launch, observations are
13
+ immutable and content-addressed, and replay never silently reruns a completed
14
+ attempt. Codex review correlation uses stable hook fields and deliberately
15
+ ignores transcript bytes whose format is not a public contract.
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ import hashlib
21
+ import json
22
+ import os
23
+ from pathlib import Path
24
+ import re
25
+ import secrets
26
+ import shlex
27
+ import shutil
28
+ import stat
29
+ import subprocess
30
+ import tempfile
31
+ import threading
32
+ import time
33
+ from typing import Any
34
+
35
+ from _gitexec import git_executable, root_bound_git_env
36
+
37
+
38
+ OBSERVATION_DIR = Path(".codearbiter/.artifacts/observations")
39
+ SOURCE_DIR = Path(".codearbiter/.artifacts/authority-sources")
40
+ STATE_FORMAT = "codearbiter.authority-run/0.1.0"
41
+ OBSERVATION_FORMAT = "codearbiter.observation/0.2.0"
42
+ EVENT_FORMAT = "codearbiter.workflow-event/0.2.0"
43
+ DECISION_FORMAT = "codearbiter.review-decision/0.1.0"
44
+ ACTIVITIES = frozenset({"verification", "spec_review", "quality_review"})
45
+ REVIEW_ACTIVITIES = frozenset({"spec_review", "quality_review"})
46
+ STATES = frozenset({
47
+ "ARMED", "LAUNCHING", "LAUNCHED", "RUNNING", "COMPLETED", "REJECTED",
48
+ "FAILED", "ABANDONED", "CAPTURED",
49
+ })
50
+ TERMINAL_STATES = frozenset({"REJECTED", "FAILED", "ABANDONED", "CAPTURED"})
51
+ SHA256_RE = re.compile(r"[0-9a-f]{64}")
52
+ ID_RE = re.compile(r"[A-Z][A-Z0-9_-]{0,127}")
53
+ REQUEST_RE = re.compile(r"[0-9a-f]{64}")
54
+ TOKEN_RE = re.compile(r"[A-Za-z0-9_-]{12,128}")
55
+ HOST_ID_RE = re.compile(r"[A-Za-z0-9][A-Za-z0-9_.:-]{0,255}")
56
+ MAX_STATE = 1 << 20
57
+ MAX_OUTPUT = 8 << 20
58
+ MAX_DECISION = 65536
59
+ REGISTRY_PARENT = Path(tempfile.gettempdir())
60
+
61
+
62
+ class AuthorityError(RuntimeError):
63
+ def __init__(self, code: str, message: str):
64
+ self.code = code
65
+ super().__init__(f"{code}: {message}")
66
+
67
+
68
+ def _canonical(value: Any) -> bytes:
69
+ try:
70
+ return json.dumps(
71
+ value, ensure_ascii=True, allow_nan=False, sort_keys=True,
72
+ separators=(",", ":"),
73
+ ).encode("utf-8")
74
+ except (TypeError, ValueError) as exc:
75
+ raise AuthorityError("INVALID_AUTHORITY_STATE", "state is not finite JSON") from exc
76
+
77
+
78
+ def _digest(data: bytes) -> str:
79
+ return hashlib.sha256(data).hexdigest()
80
+
81
+
82
+ def _integrity(value: dict[str, Any]) -> str:
83
+ unsigned = dict(value)
84
+ unsigned.pop("integrity_sha256", None)
85
+ return _digest(_canonical(unsigned))
86
+
87
+
88
+ def _real_root(root: str | Path) -> Path:
89
+ try:
90
+ resolved = Path(root).resolve(strict=True)
91
+ info = resolved.lstat()
92
+ except OSError as exc:
93
+ raise AuthorityError("UNSAFE_REPOSITORY", "repository root is unavailable") from exc
94
+ reparse = getattr(info, "st_file_attributes", 0) & 0x400
95
+ if stat.S_ISLNK(info.st_mode) or reparse or not stat.S_ISDIR(info.st_mode):
96
+ raise AuthorityError("UNSAFE_REPOSITORY", "repository root must be a real directory")
97
+ return resolved
98
+
99
+
100
+ def _safe_directory(root: Path, relative: Path, *, create: bool) -> Path:
101
+ current = root
102
+ for part in relative.parts:
103
+ current = current / part
104
+ try:
105
+ info = current.lstat()
106
+ except FileNotFoundError:
107
+ if not create:
108
+ raise
109
+ current.mkdir()
110
+ info = current.lstat()
111
+ reparse = getattr(info, "st_file_attributes", 0) & 0x400
112
+ if stat.S_ISLNK(info.st_mode) or reparse or not stat.S_ISDIR(info.st_mode):
113
+ raise AuthorityError("UNSAFE_AUTHORITY_PATH", "authority directories must be real")
114
+ return current
115
+
116
+
117
+ def _atomic_replace(root: Path, relative: Path, data: bytes) -> None:
118
+ parent = _safe_directory(root, relative.parent, create=True)
119
+ temporary = parent / f".{relative.name}.{secrets.token_hex(8)}.tmp"
120
+ flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL
121
+ if hasattr(os, "O_BINARY"):
122
+ flags |= os.O_BINARY
123
+ fd = os.open(temporary, flags, 0o600)
124
+ try:
125
+ view = memoryview(data)
126
+ while view:
127
+ written = os.write(fd, view)
128
+ if written <= 0:
129
+ raise OSError("short authority-state write")
130
+ view = view[written:]
131
+ os.fsync(fd)
132
+ finally:
133
+ os.close(fd)
134
+ try:
135
+ os.replace(temporary, root / relative)
136
+ finally:
137
+ try:
138
+ temporary.unlink()
139
+ except FileNotFoundError:
140
+ pass
141
+
142
+
143
+ def _publish_immutable(root: Path, relative: Path, data: bytes) -> None:
144
+ parent = _safe_directory(root, relative.parent, create=True)
145
+ target = parent / relative.name
146
+ temporary = parent / f".{relative.name}.{secrets.token_hex(8)}.tmp"
147
+ try:
148
+ flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL
149
+ if hasattr(os, "O_BINARY"):
150
+ flags |= os.O_BINARY
151
+ fd = os.open(temporary, flags, 0o600)
152
+ view = memoryview(data)
153
+ while view:
154
+ written = os.write(fd, view)
155
+ if written <= 0:
156
+ raise OSError("short immutable observation write")
157
+ view = view[written:]
158
+ os.fsync(fd)
159
+ finally:
160
+ if 'fd' in locals():
161
+ os.close(fd)
162
+ try:
163
+ try:
164
+ os.link(temporary, target)
165
+ except FileExistsError:
166
+ try:
167
+ info = target.lstat()
168
+ reparse = getattr(info, "st_file_attributes", 0) & 0x400
169
+ if stat.S_ISLNK(info.st_mode) or reparse or not stat.S_ISREG(info.st_mode) or info.st_size != len(data):
170
+ raise OSError("unsafe immutable authority target")
171
+ flags = os.O_RDONLY | getattr(os, "O_BINARY", 0) | getattr(os, "O_NOFOLLOW", 0)
172
+ with os.fdopen(os.open(target, flags), "rb") as existing_file:
173
+ opened = os.fstat(existing_file.fileno())
174
+ if (
175
+ not stat.S_ISREG(opened.st_mode) or opened.st_size != len(data)
176
+ or (opened.st_dev, opened.st_ino) != (info.st_dev, info.st_ino)
177
+ ):
178
+ raise OSError("immutable authority target changed during read")
179
+ existing = existing_file.read(len(data) + 1)
180
+ after = target.lstat()
181
+ if (after.st_dev, after.st_ino) != (info.st_dev, info.st_ino):
182
+ raise OSError("immutable authority target changed during read")
183
+ except OSError as exc:
184
+ raise AuthorityError("UNSAFE_AUTHORITY_PATH", "immutable authority target is unsafe") from exc
185
+ if existing != data:
186
+ raise AuthorityError("AUTHORITY_COLLISION", "content-addressed bytes differ")
187
+ finally:
188
+ try:
189
+ temporary.unlink()
190
+ except FileNotFoundError:
191
+ pass
192
+
193
+
194
+ def _request_path(request_id: str) -> Path:
195
+ if not isinstance(request_id, str) or REQUEST_RE.fullmatch(request_id) is None:
196
+ raise AuthorityError("INVALID_REQUEST_ID", "request identity is malformed")
197
+ return Path(f"{request_id}.json")
198
+
199
+
200
+ def _spool_root(root: Path) -> Path:
201
+ try:
202
+ # Callers may supply an alias for the same repository (notably /var on
203
+ # macOS). Use the canonical root for both Git and the spool identity.
204
+ root = _real_root(root)
205
+ result = subprocess.run(
206
+ [git_executable(), "-C", str(root), "rev-parse", "--path-format=absolute", "--git-common-dir"],
207
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, encoding="utf-8",
208
+ errors="replace", timeout=5, check=False, env=root_bound_git_env(),
209
+ )
210
+ if result.returncode != 0 or not result.stdout.strip():
211
+ raise OSError("git common directory unavailable")
212
+ common = Path(result.stdout.strip()).resolve(strict=True)
213
+ info = common.lstat()
214
+ reparse = getattr(info, "st_file_attributes", 0) & 0x400
215
+ if stat.S_ISLNK(info.st_mode) or reparse or not stat.S_ISDIR(info.st_mode):
216
+ raise OSError("git common directory is unsafe")
217
+ worktree_id = _digest(_canonical(_repository_identity(root)))[:32]
218
+ spool = _safe_directory(
219
+ common, Path("codearbiter") / "authority-runs" / worktree_id, create=True
220
+ )
221
+ spool_info = spool.lstat()
222
+ spool_reparse = getattr(spool_info, "st_file_attributes", 0) & 0x400
223
+ if stat.S_ISLNK(spool_info.st_mode) or spool_reparse or not stat.S_ISDIR(spool_info.st_mode):
224
+ raise OSError("authority spool is unsafe")
225
+ return spool
226
+ except (OSError, subprocess.SubprocessError) as exc:
227
+ raise AuthorityError("AUTHORITY_BUSY", "resolved git-common authority spool is unavailable") from exc
228
+
229
+
230
+ def _save(root: Path, value: dict[str, Any]) -> None:
231
+ value = dict(value)
232
+ value["integrity_sha256"] = _integrity(value)
233
+ _atomic_replace(_spool_root(root), _request_path(value["request_id"]), _canonical(value))
234
+ if value["state"] in TERMINAL_STATES:
235
+ (_registry_root() / f"{value['request_id']}.json").unlink(missing_ok=True)
236
+
237
+
238
+ def _load(root: Path, request_id: str) -> dict[str, Any]:
239
+ path = _spool_root(root) / _request_path(request_id)
240
+ try:
241
+ info = path.lstat()
242
+ reparse = getattr(info, "st_file_attributes", 0) & 0x400
243
+ if stat.S_ISLNK(info.st_mode) or reparse or not stat.S_ISREG(info.st_mode):
244
+ raise OSError("not regular")
245
+ if info.st_size > MAX_STATE:
246
+ raise OSError("oversized")
247
+ value = json.loads(path.read_text(encoding="utf-8"))
248
+ except (OSError, UnicodeError, ValueError) as exc:
249
+ raise AuthorityError("INVALID_AUTHORITY_STATE", "request state is unreadable") from exc
250
+ allowed = {
251
+ "format", "request_id", "state", "activity", "repository", "context",
252
+ "context_ref", "context_sha256", "attempt", "launch", "observation_ref",
253
+ "observation_sha256", "receipt", "integrity_sha256", "payload",
254
+ "authority_source", "dispatch_prompt", "review_contract_sha256",
255
+ "required_coverage", "wrapper", "command_bindings", "recovery",
256
+ "launch_envelope", "workspace_roots",
257
+ }
258
+ if (
259
+ not isinstance(value, dict)
260
+ or set(value) - allowed
261
+ or value.get("format") != STATE_FORMAT
262
+ or value.get("request_id") != request_id
263
+ or value.get("activity") not in ACTIVITIES
264
+ or value.get("state") not in STATES
265
+ or not isinstance(value.get("context"), dict)
266
+ or not isinstance(value.get("repository"), dict)
267
+ or not isinstance(value.get("command_bindings", []), list)
268
+ or not isinstance(value.get("workspace_roots", {}), dict)
269
+ or any(not isinstance(key, str) or not isinstance(path, str)
270
+ for key, path in value.get("workspace_roots", {}).items())
271
+ or value.get("integrity_sha256") != _integrity(value)
272
+ or not isinstance(value.get("context_ref"), str)
273
+ or SHA256_RE.fullmatch(value.get("context_sha256", "")) is None
274
+ ):
275
+ raise AuthorityError("INVALID_AUTHORITY_STATE", "request state failed validation")
276
+ return value
277
+
278
+
279
+ def _validate_hash(value: Any, field: str) -> str:
280
+ if not isinstance(value, str) or SHA256_RE.fullmatch(value) is None:
281
+ raise AuthorityError("INVALID_EVIDENCE_CONTEXT", f"{field} is malformed")
282
+ return value
283
+
284
+
285
+ def _context(
286
+ root: Path, client: Any, artifact_id: str, record_id: str, activity: str
287
+ ) -> tuple[dict[str, Any], str, str]:
288
+ result = client.call("evidence-context", {
289
+ "artifact_id": artifact_id, "record_id": record_id, "activity": activity,
290
+ })
291
+ if not isinstance(result, dict):
292
+ raise AuthorityError("INVALID_EVIDENCE_CONTEXT", "engine context result is malformed")
293
+ context_hash = _validate_hash(result.get("context_sha256"), "context_sha256")
294
+ context_ref = result.get("context_ref")
295
+ expected_ref = f".codearbiter/.artifacts/evidence-contexts/{context_hash}.json"
296
+ if context_ref != expected_ref:
297
+ raise AuthorityError("INVALID_EVIDENCE_CONTEXT", "context locator is not content addressed")
298
+ try:
299
+ raw = (root / expected_ref).read_bytes()
300
+ context = json.loads(raw.decode("utf-8"))
301
+ except (OSError, UnicodeError, ValueError) as exc:
302
+ raise AuthorityError("INVALID_EVIDENCE_CONTEXT", "context bytes are unavailable") from exc
303
+ if _digest(raw) != context_hash or raw != _canonical(context):
304
+ raise AuthorityError("INVALID_EVIDENCE_CONTEXT", "context bytes changed or are not canonical")
305
+ subject = context.get("subject") if isinstance(context, dict) else None
306
+ if (
307
+ not isinstance(context, dict)
308
+ or context.get("format") != "codearbiter.evidence-context/0.1.0"
309
+ or not isinstance(subject, dict)
310
+ or subject.get("artifact_id") != artifact_id
311
+ or subject.get("record_id") != record_id
312
+ or context["activity"] != activity
313
+ or not ID_RE.fullmatch(artifact_id)
314
+ or not ID_RE.fullmatch(record_id)
315
+ ):
316
+ raise AuthorityError("INVALID_EVIDENCE_CONTEXT", "engine context changed selection")
317
+ for field in ("input_sha256", "spec_sha256", "plan_sha256"):
318
+ _validate_hash(context.get(field), field)
319
+ _validate_hash(subject.get("normative_sha256"), "normative_sha256")
320
+ if activity in {"verification", "spec_review"}:
321
+ _validate_hash(context.get("task_sha256"), "task_sha256")
322
+ if activity == "verification":
323
+ commands = context.get("commands")
324
+ if not isinstance(commands, list) or not commands:
325
+ raise AuthorityError("INVALID_EVIDENCE_CONTEXT", "verification has no commands")
326
+ for command in commands:
327
+ definition = command.get("definition") if isinstance(command, dict) else None
328
+ if (
329
+ not isinstance(command, dict)
330
+ or set(command) != {"definition_sha256", "definition"}
331
+ or not isinstance(definition, dict)
332
+ or not {"argv", "cwd", "expected_exit", "required_tests"} <= set(definition)
333
+ or not isinstance(definition.get("argv"), list)
334
+ or not definition.get("argv")
335
+ or any(not isinstance(item, str) or not item for item in definition.get("argv", []))
336
+ or not isinstance(definition.get("cwd"), str)
337
+ or not definition.get("cwd")
338
+ or type(definition.get("expected_exit")) is not int
339
+ or not 0 <= definition.get("expected_exit", -1) <= 255
340
+ or not isinstance(definition.get("required_tests"), list)
341
+ or any(not isinstance(item, str) or not item for item in definition.get("required_tests", []))
342
+ or len(set(definition.get("required_tests", []))) != len(definition.get("required_tests", []))
343
+ ):
344
+ raise AuthorityError("INVALID_EVIDENCE_CONTEXT", "command definition is malformed")
345
+ _validate_hash(command["definition_sha256"], "definition_sha256")
346
+ elif activity == "spec_review":
347
+ if not isinstance(context.get("task"), dict):
348
+ raise AuthorityError("INVALID_EVIDENCE_CONTEXT", "review task is absent")
349
+ else:
350
+ _validate_hash(context.get("base_input_sha256"), "base_input_sha256")
351
+ if not isinstance(context.get("task_hashes"), dict) or not isinstance(context.get("tasks"), list):
352
+ raise AuthorityError("INVALID_EVIDENCE_CONTEXT", "quality-review scope is incomplete")
353
+ return context, context_ref, context_hash
354
+
355
+
356
+ def _review_binding(context: dict[str, Any]) -> tuple[str, list[str]]:
357
+ contract = {
358
+ "format": DECISION_FORMAT,
359
+ "decision": ["pass", "changes_requested"],
360
+ "finding_severity": ["BLOCK", "WARN", "INFO"],
361
+ "required_fields": [
362
+ "format", "request_id", "target_sha256", "contract_sha256",
363
+ "decision", "coverage", "findings", "assessment",
364
+ ],
365
+ }
366
+ records = [context["task"]] if context["activity"] == "spec_review" else context["tasks"]
367
+ coverage = sorted({
368
+ ref for record in records for ref in record.get("criterion_refs", [])
369
+ if isinstance(ref, str) and ref
370
+ })
371
+ if not coverage:
372
+ raise AuthorityError("INVALID_EVIDENCE_CONTEXT", "review target has no criterion coverage")
373
+ return _digest(_canonical(contract)), coverage
374
+
375
+
376
+ def _repository_identity(root: Path) -> dict[str, str]:
377
+ info = os.stat(root)
378
+ return {
379
+ "path": str(root),
380
+ "filesystem_id": f"{int(getattr(info, 'st_dev', 0))}:{int(getattr(info, 'st_ino', 0))}",
381
+ }
382
+
383
+
384
+ def _registry_root() -> Path:
385
+ namespace = f"uid-{os.getuid()}" if hasattr(os, "getuid") else "current-user"
386
+ root = REGISTRY_PARENT.resolve(strict=True) / f"codearbiter-authority-{namespace}"
387
+ try:
388
+ root.mkdir(mode=0o700, exist_ok=True)
389
+ info = root.lstat()
390
+ reparse = getattr(info, "st_file_attributes", 0) & 0x400
391
+ if stat.S_ISLNK(info.st_mode) or reparse or not stat.S_ISDIR(info.st_mode):
392
+ raise OSError("unsafe registry")
393
+ if hasattr(os, "getuid"):
394
+ if info.st_uid != os.getuid():
395
+ raise OSError("foreign registry")
396
+ os.chmod(root, 0o700)
397
+ except OSError as exc:
398
+ raise AuthorityError("AUTHORITY_BUSY", "authority registry is unavailable") from exc
399
+ return root
400
+
401
+
402
+ def _register_request(root: Path, request: dict[str, Any]) -> None:
403
+ pointer = {
404
+ "format": "codearbiter.authority-pointer/0.1.0",
405
+ "request_id": request["request_id"],
406
+ "repository": request["repository"],
407
+ }
408
+ pointer["integrity_sha256"] = _integrity(pointer)
409
+ registry = _registry_root()
410
+ target = registry / f"{request['request_id']}.json"
411
+ data = _canonical(pointer)
412
+ try:
413
+ existing = target.read_bytes()
414
+ except FileNotFoundError:
415
+ flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL
416
+ if hasattr(os, "O_BINARY"):
417
+ flags |= os.O_BINARY
418
+ fd = os.open(target, flags, 0o600)
419
+ try:
420
+ view = memoryview(data)
421
+ while view:
422
+ written = os.write(fd, view)
423
+ if written <= 0:
424
+ raise OSError("short authority-pointer write")
425
+ view = view[written:]
426
+ os.fsync(fd)
427
+ finally:
428
+ os.close(fd)
429
+ else:
430
+ if existing != data:
431
+ raise AuthorityError("AUTHORITY_COLLISION", "request registry entry differs")
432
+
433
+
434
+ def _registered_requests() -> list[tuple[Path, dict[str, Any]]]:
435
+ results = []
436
+ for path in _registry_root().glob("*.json"):
437
+ try:
438
+ raw = path.read_bytes()
439
+ if len(raw) > 16384:
440
+ continue
441
+ pointer = json.loads(raw.decode("utf-8"))
442
+ repository = pointer.get("repository") if isinstance(pointer, dict) else None
443
+ if (
444
+ not isinstance(pointer, dict)
445
+ or pointer.get("format") != "codearbiter.authority-pointer/0.1.0"
446
+ or pointer.get("request_id") != path.stem
447
+ or pointer.get("integrity_sha256") != _integrity(pointer)
448
+ or not isinstance(repository, dict)
449
+ ):
450
+ continue
451
+ root = _real_root(repository.get("path"))
452
+ if _repository_identity(root) != repository:
453
+ continue
454
+ request = _load(root, path.stem)
455
+ if request["state"] in TERMINAL_STATES:
456
+ path.unlink(missing_ok=True)
457
+ continue
458
+ results.append((root, request))
459
+ except (AuthorityError, OSError, UnicodeError, ValueError):
460
+ continue
461
+ return results
462
+
463
+
464
+ def _registered_request(request_id: str) -> tuple[Path, dict[str, Any]]:
465
+ matches = [item for item in _registered_requests() if item[1]["request_id"] == request_id]
466
+ if len(matches) != 1:
467
+ raise AuthorityError("UNSUPPORTED_HOST_SEAM", "authority request routing is ambiguous")
468
+ return matches[0]
469
+
470
+
471
+ def _ordinary_spawn_marker(session_id: str, turn_id: str) -> Path:
472
+ key = _digest(_canonical({"session_id": session_id, "turn_id": turn_id}))
473
+ return _registry_root() / f"ordinary-spawn-{key}.marker"
474
+
475
+
476
+ def _record_ordinary_spawn(session_id: str, turn_id: str) -> None:
477
+ marker = _ordinary_spawn_marker(session_id, turn_id)
478
+ try:
479
+ fd = os.open(marker, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
480
+ except FileExistsError:
481
+ return
482
+ try:
483
+ os.write(fd, b"ordinary spawn observed\n")
484
+ os.fsync(fd)
485
+ finally:
486
+ os.close(fd)
487
+
488
+
489
+ def _reject_overlapping_authority(session_id: str, turn_id: str) -> None:
490
+ for root, request in _registered_requests():
491
+ launch = request.get("launch") or {}
492
+ if (
493
+ request["state"] in {"LAUNCHING", "RUNNING"}
494
+ and launch.get("parent_session_id") == session_id
495
+ and launch.get("parent_turn_id") == turn_id
496
+ ):
497
+ request["state"] = "REJECTED"
498
+ request["recovery"] = {
499
+ "mode": "overlapping-subagent-launch",
500
+ "rerun_permitted": False,
501
+ }
502
+ _save(root, request)
503
+
504
+
505
+ def _git_text(directory: Path, *args: str) -> str:
506
+ try:
507
+ result = subprocess.run(
508
+ [git_executable(), "-C", str(directory), *args],
509
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=False,
510
+ timeout=15, env=root_bound_git_env(),
511
+ )
512
+ except (OSError, subprocess.SubprocessError) as exc:
513
+ raise AuthorityError("UNSUPPORTED_WORKSPACE", "git workspace identity is unavailable") from exc
514
+ if result.returncode != 0:
515
+ raise AuthorityError("UNSUPPORTED_WORKSPACE", "git workspace identity is unavailable")
516
+ decoded = result.stdout.decode("utf-8", "strict")
517
+ return decoded if "-z" in args else decoded.strip()
518
+
519
+
520
+ def _path_identity(path: Path) -> str:
521
+ info = path.lstat()
522
+ reparse = getattr(info, "st_file_attributes", 0) & 0x400
523
+ if stat.S_ISLNK(info.st_mode) or reparse:
524
+ raise AuthorityError("UNSUPPORTED_WORKSPACE", "workspace path is replaceable indirection")
525
+ return f"{int(getattr(info, 'st_dev', 0))}:{int(getattr(info, 'st_ino', 0))}"
526
+
527
+
528
+ def _file_sha256(path: Path) -> str:
529
+ digest = hashlib.sha256()
530
+ try:
531
+ with path.open("rb") as stream:
532
+ while True:
533
+ block = stream.read(1 << 20)
534
+ if not block:
535
+ break
536
+ digest.update(block)
537
+ except OSError as exc:
538
+ raise AuthorityError("UNSUPPORTED_EXECUTABLE", "declared executable is unreadable") from exc
539
+ return digest.hexdigest()
540
+
541
+
542
+ def _workspace_for(
543
+ root: Path, label: str, workspace_roots: dict[str, str]
544
+ ) -> tuple[Path, Path, Path]:
545
+ if label in workspace_roots:
546
+ cwd = _real_root(workspace_roots[label])
547
+ declared_top = _real_root(_git_text(cwd, "rev-parse", "--show-toplevel"))
548
+ if declared_top != cwd:
549
+ raise AuthorityError("UNSUPPORTED_WORKSPACE", "mapped workspace is not an exact Git worktree root")
550
+ elif label in {".", "current worktree", "candidate worktree"}:
551
+ cwd = root
552
+ else:
553
+ candidate = Path(label)
554
+ if candidate.is_absolute() or ".." in candidate.parts:
555
+ raise AuthorityError("UNSUPPORTED_WORKSPACE", "declared cwd escapes the artifact worktree")
556
+ cwd = _resolved_directory(root / candidate)
557
+ worktree = _real_root(_git_text(cwd, "rev-parse", "--show-toplevel"))
558
+ if label not in workspace_roots and worktree != root:
559
+ raise AuthorityError("UNSUPPORTED_WORKSPACE", "declared cwd is not in the artifact worktree")
560
+ common = _real_root(_git_text(worktree, "rev-parse", "--path-format=absolute", "--git-common-dir"))
561
+ artifact_common = _real_root(_git_text(root, "rev-parse", "--path-format=absolute", "--git-common-dir"))
562
+ if common != artifact_common:
563
+ raise AuthorityError("UNSUPPORTED_WORKSPACE", "workspace does not share the artifact git-common-dir")
564
+ return cwd, worktree, common
565
+
566
+
567
+ def _resolve_executable(name: str, cwd: Path) -> Path:
568
+ candidate = Path(name)
569
+ if candidate.is_absolute() or candidate.parent != Path("."):
570
+ path = (cwd / candidate).resolve(strict=True) if not candidate.is_absolute() else candidate.resolve(strict=True)
571
+ else:
572
+ located = shutil.which(name, path=os.environ.get("PATH", ""))
573
+ if not located:
574
+ raise AuthorityError("UNSUPPORTED_EXECUTABLE", "declared executable is not resolvable")
575
+ path = Path(located).resolve(strict=True)
576
+ if not path.is_file():
577
+ raise AuthorityError("UNSUPPORTED_EXECUTABLE", "declared executable is not a regular file")
578
+ _path_identity(path)
579
+ return path
580
+
581
+
582
+ def _bind_commands(
583
+ root: Path, context: dict[str, Any], workspace_roots: dict[str, str]
584
+ ) -> list[dict[str, Any]]:
585
+ bindings = []
586
+ for command in context["commands"]:
587
+ definition = command["definition"]
588
+ cwd, worktree, common = _workspace_for(root, definition["cwd"], workspace_roots)
589
+ executable = _resolve_executable(definition["argv"][0], cwd)
590
+ bindings.append({
591
+ "definition_sha256": command["definition_sha256"],
592
+ "argv": [str(executable), *definition["argv"][1:]],
593
+ "cwd": str(cwd),
594
+ "cwd_filesystem_id": _path_identity(cwd),
595
+ "workspace_root": str(worktree),
596
+ "workspace_filesystem_id": _path_identity(worktree),
597
+ "git_common_dir": str(common),
598
+ "git_common_filesystem_id": _path_identity(common),
599
+ "executable_sha256": _file_sha256(executable),
600
+ })
601
+ return bindings
602
+
603
+
604
+ def _workspace_snapshots(bindings: list[dict[str, Any]]) -> list[dict[str, str]]:
605
+ unique: dict[str, dict[str, str]] = {}
606
+ for binding in bindings:
607
+ cwd = _resolved_directory(binding["cwd"])
608
+ root = _real_root(binding["workspace_root"])
609
+ common = _real_root(binding["git_common_dir"])
610
+ if (
611
+ _path_identity(cwd) != binding["cwd_filesystem_id"]
612
+ or _path_identity(root) != binding["workspace_filesystem_id"]
613
+ or _path_identity(common) != binding["git_common_filesystem_id"]
614
+ or _file_sha256(Path(binding["argv"][0])) != binding["executable_sha256"]
615
+ ):
616
+ raise AuthorityError("WORKSPACE_DRIFT", "workspace or executable identity changed")
617
+ status = _git_text(root, "status", "--porcelain=v2", "-z", "--untracked-files=all")
618
+ index = _git_text(root, "ls-files", "--stage", "-z")
619
+ untracked = _git_text(root, "ls-files", "--others", "--exclude-standard", "-z")
620
+ entries: dict[str, str] = {}
621
+ for record in (part for part in index.split("\0") if part):
622
+ try:
623
+ metadata, relative = record.split("\t", 1)
624
+ mode, _object_id, stage = metadata.split(" ")
625
+ except ValueError as exc:
626
+ raise AuthorityError("WORKSPACE_DRIFT", "git index entry cannot be frozen") from exc
627
+ if stage != "0" or mode not in {"100644", "100755", "120000", "160000"} or relative in entries:
628
+ raise AuthorityError("WORKSPACE_DRIFT", "git index entry cannot be frozen")
629
+ entries[relative] = mode
630
+ for relative in (part for part in untracked.split("\0") if part):
631
+ if relative in entries:
632
+ raise AuthorityError("WORKSPACE_DRIFT", "git workspace entry cannot be frozen")
633
+ entries[relative] = "untracked"
634
+ content = hashlib.sha256()
635
+ for relative in sorted(entries):
636
+ encoded = relative.encode("utf-8")
637
+ candidate = root / relative
638
+ try:
639
+ if not candidate.parent.resolve(strict=False).is_relative_to(root):
640
+ raise OSError("workspace member escapes the worktree")
641
+ mode = entries[relative]
642
+ try:
643
+ info = candidate.lstat()
644
+ except FileNotFoundError:
645
+ if mode == "untracked":
646
+ raise
647
+ kind, data = "deleted", b""
648
+ else:
649
+ reparse = getattr(info, "st_file_attributes", 0) & 0x400
650
+ if stat.S_ISLNK(info.st_mode):
651
+ if mode not in {"120000", "untracked"}:
652
+ raise OSError("regular workspace member became a symlink")
653
+ resolved = candidate.resolve(strict=False)
654
+ if not resolved.is_relative_to(root):
655
+ raise OSError("workspace symlink escapes the worktree")
656
+ target = os.fsencode(os.readlink(candidate))
657
+ resolved_path = resolved.relative_to(root).as_posix().encode("utf-8")
658
+ try:
659
+ target_info = resolved.lstat()
660
+ except FileNotFoundError:
661
+ kind, data = "dangling-symlink", target + b"\0" + resolved_path
662
+ else:
663
+ target_reparse = getattr(target_info, "st_file_attributes", 0) & 0x400
664
+ if target_reparse or not stat.S_ISREG(target_info.st_mode):
665
+ raise OSError("workspace symlink target has unsupported type")
666
+ kind, data = "symlink", target + b"\0" + resolved_path + b"\0" + resolved.read_bytes()
667
+ elif reparse:
668
+ raise OSError("workspace member is replaceable indirection")
669
+ elif stat.S_ISREG(info.st_mode) and mode != "160000":
670
+ kind = "materialized-symlink" if mode == "120000" else "file"
671
+ data = candidate.read_bytes()
672
+ elif stat.S_ISDIR(info.st_mode) and mode == "160000":
673
+ nested_top = _git_text(candidate, "rev-parse", "--show-toplevel")
674
+ if _real_root(nested_top) != candidate:
675
+ if any(candidate.iterdir()):
676
+ raise OSError("uninitialized gitlink has unexpected content")
677
+ kind, data = "uninitialized-gitlink", b""
678
+ else:
679
+ if _git_text(candidate, "status", "--porcelain", "--untracked-files=all"):
680
+ raise OSError("dirty gitlink cannot be frozen")
681
+ kind, data = "gitlink", _git_text(candidate, "rev-parse", "HEAD").encode("ascii")
682
+ else:
683
+ raise OSError("workspace member has unsupported type")
684
+ except (OSError, RuntimeError, AuthorityError) as exc:
685
+ raise AuthorityError("WORKSPACE_DRIFT", "workspace content cannot be frozen") from exc
686
+ content.update(len(encoded).to_bytes(8, "big"))
687
+ content.update(encoded)
688
+ typed = f"{mode}:{kind}".encode("ascii")
689
+ content.update(len(typed).to_bytes(8, "big"))
690
+ content.update(typed)
691
+ content.update(len(data).to_bytes(8, "big"))
692
+ content.update(data)
693
+ unique[str(root)] = {
694
+ "root": str(root),
695
+ "filesystem_id": binding["workspace_filesystem_id"],
696
+ "git_common_dir": str(common),
697
+ "git_common_filesystem_id": binding["git_common_filesystem_id"],
698
+ "head": _git_text(root, "rev-parse", "HEAD"),
699
+ "status_sha256": _digest(status.encode("utf-8")),
700
+ "content_sha256": content.hexdigest(),
701
+ }
702
+ return [unique[key] for key in sorted(unique)]
703
+
704
+
705
+ def _dispatch_prompt(request: dict[str, Any]) -> str:
706
+ context = request["context"]
707
+ return (
708
+ f"[CODEARBITER_AUTHORITY_REQUEST:{request['request_id']}]\n"
709
+ f"Target repository: {request['repository']['path']}\n"
710
+ f"Frozen context: {request['context_ref']} sha256={request['context_sha256']}\n"
711
+ "Frozen target data follows as canonical JSON:\n"
712
+ + _canonical(context).decode("ascii") + "\n"
713
+ "Act as a fresh read-only independent codeArbiter reviewer. Do not edit files or "
714
+ "delegate. Review only the frozen target and return exactly one JSON object using "
715
+ f"format {DECISION_FORMAT}. Bind request_id={request['request_id']}, "
716
+ f"target_sha256={context['input_sha256']}, "
717
+ f"contract_sha256={request['review_contract_sha256']}. Required coverage: "
718
+ + json.dumps(request["required_coverage"], ensure_ascii=True)
719
+ + ". Fields: format, request_id, target_sha256, contract_sha256, decision "
720
+ "(pass or changes_requested), coverage (unique strings), findings (objects with "
721
+ "severity, code, message), assessment (non-empty string)."
722
+ )
723
+
724
+
725
+ def arm_request(
726
+ root: str | Path,
727
+ client: Any,
728
+ artifact_id: str,
729
+ record_id: str,
730
+ activity: str,
731
+ *,
732
+ request_nonce: str | None = None,
733
+ workspace_roots: dict[str, str | Path] | None = None,
734
+ **unexpected: Any,
735
+ ) -> dict[str, Any]:
736
+ if unexpected:
737
+ raise AuthorityError(
738
+ "INVALID_AUTHORITY_REQUEST",
739
+ "authority, verdict, payload, and observations are not caller inputs",
740
+ )
741
+ if activity not in ACTIVITIES:
742
+ raise AuthorityError("INVALID_AUTHORITY_REQUEST", "activity is unsupported")
743
+ root = _real_root(root)
744
+ nonce = request_nonce or secrets.token_urlsafe(24)
745
+ if not isinstance(nonce, str) or TOKEN_RE.fullmatch(nonce) is None:
746
+ raise AuthorityError("INVALID_AUTHORITY_REQUEST", "request nonce is malformed")
747
+ context, context_ref, context_sha256 = _context(
748
+ root, client, artifact_id, record_id, activity
749
+ )
750
+ frozen_workspaces: dict[str, str] = {}
751
+ if workspace_roots is not None:
752
+ if activity != "verification" or not isinstance(workspace_roots, dict):
753
+ raise AuthorityError("INVALID_AUTHORITY_REQUEST", "workspace roots apply only to verification")
754
+ labels = {command["definition"]["cwd"] for command in context["commands"]}
755
+ if set(workspace_roots) != labels:
756
+ raise AuthorityError("UNSUPPORTED_WORKSPACE", "workspace map must exactly cover declared cwd labels")
757
+ frozen_workspaces = {label: str(_real_root(path)) for label, path in workspace_roots.items()}
758
+ command_bindings = _bind_commands(root, context, frozen_workspaces) if activity == "verification" else []
759
+ seed = _canonical({
760
+ "repository": _repository_identity(root), "context": context, "nonce": nonce,
761
+ "command_bindings": command_bindings,
762
+ "workspace_roots": frozen_workspaces,
763
+ })
764
+ request_id = _digest(seed)
765
+ request = {
766
+ "format": STATE_FORMAT,
767
+ "request_id": request_id,
768
+ "state": "ARMED",
769
+ "activity": activity,
770
+ "repository": _repository_identity(root),
771
+ "context": context,
772
+ "context_ref": context_ref,
773
+ "context_sha256": context_sha256,
774
+ "attempt": None,
775
+ "launch": None,
776
+ "observation_ref": None,
777
+ "observation_sha256": None,
778
+ "receipt": None,
779
+ "wrapper": None,
780
+ "recovery": None,
781
+ "command_bindings": command_bindings,
782
+ "workspace_roots": frozen_workspaces,
783
+ }
784
+ if activity in REVIEW_ACTIVITIES:
785
+ request["review_contract_sha256"], request["required_coverage"] = _review_binding(context)
786
+ request["dispatch_prompt"] = _dispatch_prompt(request)
787
+ request["launch_envelope"] = {
788
+ "message": request["dispatch_prompt"],
789
+ "task_name": f"authority_{request_id[:12]}",
790
+ "fork_turns": "none",
791
+ }
792
+ _save(root, request)
793
+ _register_request(root, request)
794
+ result = {
795
+ "request_id": request_id,
796
+ "request_path": str(_spool_root(root) / _request_path(request_id)),
797
+ "activity": activity,
798
+ }
799
+ if activity in REVIEW_ACTIVITIES:
800
+ result["dispatch_prompt"] = request["dispatch_prompt"]
801
+ result["review_contract_sha256"] = request["review_contract_sha256"]
802
+ result["required_coverage"] = request["required_coverage"]
803
+ result["launch_envelope"] = request["launch_envelope"]
804
+ return result
805
+
806
+
807
+ def _bounded_output(value: Any) -> bytes:
808
+ if not isinstance(value, (bytes, bytearray)):
809
+ raise AuthorityError("INVALID_PROCESS_RESULT", "process output must be bytes")
810
+ if len(value) > MAX_OUTPUT:
811
+ raise AuthorityError("PROCESS_OUTPUT_TOO_LARGE", "process output exceeds 8 MiB")
812
+ return bytes(value)
813
+
814
+
815
+ def _unittest_collector(stdout: bytes, stderr: bytes, required: list[str]) -> list[dict[str, str]]:
816
+ text = (stdout + b"\n" + stderr).decode("utf-8", "replace")
817
+ results = []
818
+ for name in required:
819
+ pattern = re.compile(r"(?m)^" + re.escape(name) + r"(?:\s+\([^\r\n]*\))?\s+\.\.\.\s+ok\s*$")
820
+ matches = pattern.findall(text)
821
+ if not matches:
822
+ raise AuthorityError("MISSING_TEST_RESULT", f"required test did not pass: {name}")
823
+ if len(matches) != 1:
824
+ raise AuthorityError("DUPLICATE_TEST_RESULT", f"required test appeared more than once: {name}")
825
+ results.append({"name": name, "status": "pass"})
826
+ return results
827
+
828
+
829
+ def _named_line_collector(stdout: bytes, stderr: bytes, required: list[str]) -> list[dict[str, str]]:
830
+ # Intentional producer gap: current SingedTerra movement, walls, and
831
+ # fall-damage harnesses emit umbrella summaries for some plan aggregates.
832
+ # Those summaries are not semantic evidence; only exact PASS names qualify.
833
+ text = (stdout + b"\n" + stderr).decode("utf-8", "replace")
834
+ passed: dict[str, int] = {}
835
+ for line in text.splitlines():
836
+ stripped = line.strip()
837
+ if stripped.startswith("PASS: "):
838
+ name = stripped[6:].rstrip(".")
839
+ passed[name] = passed.get(name, 0) + 1
840
+ duplicates = [name for name in required if passed.get(name, 0) > 1]
841
+ if duplicates:
842
+ raise AuthorityError("DUPLICATE_TEST_RESULT", "required PASS lines are duplicated: " + ", ".join(duplicates))
843
+ missing = [name for name in required if passed.get(name, 0) != 1]
844
+ if missing:
845
+ raise AuthorityError(
846
+ "MISSING_TEST_RESULT", "required explicit PASS lines are absent: " + ", ".join(missing)
847
+ )
848
+ return [{"name": name, "status": "pass"} for name in required]
849
+
850
+
851
+ def _vitest_verbose_collector(stdout: bytes, stderr: bytes, required: list[str]) -> list[dict[str, str]]:
852
+ text = (stdout + b"\n" + stderr).decode("utf-8", "replace")
853
+ passed: dict[str, int] = {}
854
+ for line in text.splitlines():
855
+ stripped = line.strip()
856
+ if stripped.startswith(("✓ ", "√ ")):
857
+ name = stripped[2:].rsplit(" > ", 1)[-1]
858
+ name = re.sub(r"\s+\d+(?:\.\d+)?m?s$", "", name)
859
+ passed[name] = passed.get(name, 0) + 1
860
+ duplicates = [name for name in required if passed.get(name, 0) > 1]
861
+ if duplicates:
862
+ raise AuthorityError("DUPLICATE_TEST_RESULT", "required Vitest cases are duplicated: " + ", ".join(duplicates))
863
+ missing = [name for name in required if passed.get(name, 0) != 1]
864
+ if missing:
865
+ raise AuthorityError(
866
+ "MISSING_TEST_RESULT", "required exact Vitest case names are absent: " + ", ".join(missing)
867
+ )
868
+ return [{"name": name, "status": "pass"} for name in required]
869
+
870
+
871
+ def _exit_only_collector(_stdout: bytes, _stderr: bytes, required: list[str]) -> list[dict[str, str]]:
872
+ if required:
873
+ raise AuthorityError("UNSUPPORTED_COLLECTOR", "exit-only profile cannot attest named tests")
874
+ return []
875
+
876
+
877
+ COLLECTORS: dict[str, Callable[[bytes, bytes, list[str]], list[dict[str, str]]]] = {
878
+ "python-unittest-text/0.1.0": _unittest_collector,
879
+ "codearbiter-named-lines/0.1.0": _named_line_collector,
880
+ "vitest-verbose/0.1.0": _vitest_verbose_collector,
881
+ "exit-only/0.1.0": _exit_only_collector,
882
+ }
883
+
884
+
885
+ def _collector_profile(argv: list[str], required: list[str]) -> str:
886
+ if not required:
887
+ return "exit-only/0.1.0"
888
+ lowered = [part.casefold() for part in argv]
889
+ if len(lowered) >= 3 and lowered[1:3] == ["-m", "unittest"]:
890
+ return "python-unittest-text/0.1.0"
891
+ if "vitest" in lowered and "--reporter=verbose" in lowered:
892
+ return "vitest-verbose/0.1.0"
893
+ if "tsx" in lowered or lowered[:3] == ["npm", "run", "test:client"] or lowered[:3] == ["npm", "run", "check"]:
894
+ return "codearbiter-named-lines/0.1.0"
895
+ raise AuthorityError("UNSUPPORTED_COLLECTOR", "declared runner has no qualified collector")
896
+
897
+
898
+ def _minimal_environment() -> tuple[dict[str, str], str]:
899
+ names = (
900
+ "PATH", "PATHEXT", "SystemRoot", "WINDIR", "COMSPEC", "TEMP", "TMP",
901
+ "HOME", "USERPROFILE", "APPDATA", "LOCALAPPDATA", "LANG", "LC_ALL",
902
+ )
903
+ environment = {name: os.environ[name] for name in names if name in os.environ}
904
+ return environment, _digest(_canonical(environment))
905
+
906
+
907
+ def _resolved_directory(value: Any) -> Path:
908
+ if not isinstance(value, (str, Path)):
909
+ raise AuthorityError("UNSUPPORTED_WORKSPACE", "workspace resolver returned no directory")
910
+ try:
911
+ path = Path(value).resolve(strict=True)
912
+ info = path.lstat()
913
+ except OSError as exc:
914
+ raise AuthorityError("UNSUPPORTED_WORKSPACE", "workspace directory is unavailable") from exc
915
+ reparse = getattr(info, "st_file_attributes", 0) & 0x400
916
+ if stat.S_ISLNK(info.st_mode) or reparse or not stat.S_ISDIR(info.st_mode):
917
+ raise AuthorityError("UNSUPPORTED_WORKSPACE", "workspace must be a real directory")
918
+ return path
919
+
920
+
921
+ def _run_contained(
922
+ argv: list[str], *, cwd: str, env: dict[str, str], timeout_seconds: float = 1800.0
923
+ ) -> subprocess.CompletedProcess:
924
+ """Bound output and descendants with POSIX sessions or a Windows Job Object."""
925
+ if not isinstance(timeout_seconds, (int, float)) or timeout_seconds <= 0:
926
+ raise AuthorityError("INVALID_PROCESS_TIMEOUT", "process timeout must be positive")
927
+ job = None
928
+ if os.name == "nt":
929
+ import ctypes
930
+ from ctypes import wintypes
931
+
932
+ class BasicLimits(ctypes.Structure):
933
+ _fields_ = [
934
+ ("PerProcessUserTimeLimit", ctypes.c_longlong),
935
+ ("PerJobUserTimeLimit", ctypes.c_longlong),
936
+ ("LimitFlags", wintypes.DWORD),
937
+ ("MinimumWorkingSetSize", ctypes.c_size_t),
938
+ ("MaximumWorkingSetSize", ctypes.c_size_t),
939
+ ("ActiveProcessLimit", wintypes.DWORD),
940
+ ("Affinity", ctypes.c_size_t),
941
+ ("PriorityClass", wintypes.DWORD),
942
+ ("SchedulingClass", wintypes.DWORD),
943
+ ]
944
+
945
+ class IoCounters(ctypes.Structure):
946
+ _fields_ = [(name, ctypes.c_ulonglong) for name in (
947
+ "ReadOperationCount", "WriteOperationCount", "OtherOperationCount",
948
+ "ReadTransferCount", "WriteTransferCount", "OtherTransferCount",
949
+ )]
950
+
951
+ class ExtendedLimits(ctypes.Structure):
952
+ _fields_ = [
953
+ ("BasicLimitInformation", BasicLimits), ("IoInfo", IoCounters),
954
+ ("ProcessMemoryLimit", ctypes.c_size_t), ("JobMemoryLimit", ctypes.c_size_t),
955
+ ("PeakProcessMemoryUsed", ctypes.c_size_t), ("PeakJobMemoryUsed", ctypes.c_size_t),
956
+ ]
957
+
958
+ kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
959
+ ntdll = ctypes.WinDLL("ntdll")
960
+ kernel32.CreateJobObjectW.restype = wintypes.HANDLE
961
+ kernel32.CreateJobObjectW.argtypes = [ctypes.c_void_p, wintypes.LPCWSTR]
962
+ kernel32.SetInformationJobObject.argtypes = [wintypes.HANDLE, ctypes.c_int, ctypes.c_void_p, wintypes.DWORD]
963
+ kernel32.AssignProcessToJobObject.argtypes = [wintypes.HANDLE, wintypes.HANDLE]
964
+ kernel32.TerminateJobObject.argtypes = [wintypes.HANDLE, wintypes.UINT]
965
+ kernel32.CloseHandle.argtypes = [wintypes.HANDLE]
966
+ ntdll.NtResumeProcess.argtypes = [wintypes.HANDLE]
967
+ job = kernel32.CreateJobObjectW(None, None)
968
+ if not job:
969
+ raise AuthorityError("UNSUPPORTED_PROCESS_CONTAINMENT", "CreateJobObjectW failed")
970
+ limits = ExtendedLimits()
971
+ limits.BasicLimitInformation.LimitFlags = 0x00002000 # KILL_ON_JOB_CLOSE
972
+ if not kernel32.SetInformationJobObject(job, 9, ctypes.byref(limits), ctypes.sizeof(limits)):
973
+ kernel32.CloseHandle(job)
974
+ raise AuthorityError("UNSUPPORTED_PROCESS_CONTAINMENT", "job limits could not be installed")
975
+ try:
976
+ process = subprocess.Popen(
977
+ argv, cwd=cwd, env=env, stdin=subprocess.DEVNULL,
978
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False,
979
+ creationflags=0x00000200 | 0x00000004, # NEW_PROCESS_GROUP | SUSPENDED
980
+ )
981
+ if not kernel32.AssignProcessToJobObject(job, wintypes.HANDLE(int(process._handle))):
982
+ process.kill()
983
+ process.wait()
984
+ raise AuthorityError("UNSUPPORTED_PROCESS_CONTAINMENT", "child could not enter Job Object")
985
+ if ntdll.NtResumeProcess(wintypes.HANDLE(int(process._handle))) != 0:
986
+ kernel32.TerminateJobObject(job, 1)
987
+ process.wait()
988
+ raise AuthorityError("UNSUPPORTED_PROCESS_CONTAINMENT", "suspended child could not resume")
989
+ except Exception:
990
+ kernel32.CloseHandle(job)
991
+ raise
992
+ else:
993
+ process = subprocess.Popen(
994
+ argv, cwd=cwd, env=env, stdin=subprocess.DEVNULL,
995
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False,
996
+ start_new_session=True,
997
+ )
998
+ buffers = {"stdout": bytearray(), "stderr": bytearray()}
999
+ overflow = threading.Event()
1000
+
1001
+ def drain(name: str, stream: Any) -> None:
1002
+ while True:
1003
+ chunk = stream.read(65536)
1004
+ if not chunk:
1005
+ return
1006
+ if len(buffers[name]) + len(chunk) > MAX_OUTPUT:
1007
+ overflow.set()
1008
+ else:
1009
+ buffers[name].extend(chunk)
1010
+
1011
+ threads = [
1012
+ threading.Thread(target=drain, args=("stdout", process.stdout), daemon=True),
1013
+ threading.Thread(target=drain, args=("stderr", process.stderr), daemon=True),
1014
+ ]
1015
+ for thread in threads:
1016
+ thread.start()
1017
+ deadline = time.monotonic() + timeout_seconds
1018
+ try:
1019
+ while process.poll() is None:
1020
+ if overflow.is_set() or time.monotonic() >= deadline:
1021
+ if os.name == "nt":
1022
+ kernel32.TerminateJobObject(job, 1)
1023
+ else:
1024
+ import signal
1025
+ os.killpg(process.pid, signal.SIGKILL)
1026
+ process.wait(timeout=10)
1027
+ if overflow.is_set():
1028
+ raise AuthorityError("PROCESS_OUTPUT_TOO_LARGE", "process output exceeds 8 MiB")
1029
+ raise AuthorityError("VERIFICATION_PROCESS_FAILED", "verification process timed out")
1030
+ time.sleep(0.02)
1031
+ finally:
1032
+ if job is not None:
1033
+ kernel32.CloseHandle(job) # KILL_ON_JOB_CLOSE ends surviving descendants.
1034
+ job = None
1035
+ elif process.poll() is not None:
1036
+ try:
1037
+ import signal
1038
+ os.killpg(process.pid, signal.SIGKILL)
1039
+ except (OSError, ProcessLookupError):
1040
+ pass
1041
+ for thread in threads:
1042
+ thread.join(timeout=10)
1043
+ process.stdout.close()
1044
+ process.stderr.close()
1045
+ if overflow.is_set():
1046
+ raise AuthorityError("PROCESS_OUTPUT_TOO_LARGE", "process output exceeds 8 MiB")
1047
+ return subprocess.CompletedProcess(argv, process.returncode, bytes(buffers["stdout"]), bytes(buffers["stderr"]))
1048
+
1049
+
1050
+ def _observation(root: Path, request: dict[str, Any], value: dict[str, Any]) -> None:
1051
+ raw = _canonical(value)
1052
+ digest = _digest(raw)
1053
+ relative = OBSERVATION_DIR / f"{digest}.json"
1054
+ _publish_immutable(root, relative, raw)
1055
+ request["observation_ref"] = relative.as_posix()
1056
+ request["observation_sha256"] = digest
1057
+
1058
+
1059
+ def _closed_observation(
1060
+ request: dict[str, Any], payload: dict[str, Any], producer_profile: str,
1061
+ producer_run_id: str, producer_result: dict[str, Any],
1062
+ ) -> dict[str, Any]:
1063
+ return {
1064
+ "format": OBSERVATION_FORMAT,
1065
+ "kind": request["activity"],
1066
+ "subject": request["context"]["subject"],
1067
+ "context_ref": request["context_ref"],
1068
+ "context_sha256": request["context_sha256"],
1069
+ "payload_sha256": _digest(_canonical(payload)),
1070
+ "producer_profile": producer_profile,
1071
+ "producer_run_id": producer_run_id,
1072
+ "producer_result": producer_result,
1073
+ "producer_result_sha256": _digest(_canonical(producer_result)),
1074
+ }
1075
+
1076
+
1077
+ def capture_user_prompt(
1078
+ root: str | Path, client: Any, event: dict[str, Any], *, host: str, session_id: str
1079
+ ) -> dict[str, Any]:
1080
+ """Capture one exact host UserPromptSubmit event through a closed observation."""
1081
+ root = _real_root(root)
1082
+ if (
1083
+ not isinstance(event, dict)
1084
+ or event.get("kind") not in {"approval", "prerequisite", "reconciliation", "farm_authorization"}
1085
+ or event.get("authority_kind") != "user_workflow"
1086
+ or not isinstance(event.get("subject"), dict)
1087
+ or not isinstance(event.get("source_text"), str)
1088
+ or not event["source_text"]
1089
+ ):
1090
+ raise AuthorityError("INVALID_PROMPT_EVENT", "user prompt event is malformed")
1091
+ producer_run_id = f"{_host_id(host, 'host')}:{_host_id(session_id, 'session_id')}"
1092
+ prompt_sha256 = _digest(event["source_text"].encode("utf-8"))
1093
+ subject = event["subject"]
1094
+ result = client.call("evidence-context", {
1095
+ "artifact_id": subject.get("artifact_id"),
1096
+ "record_id": subject.get("record_id"),
1097
+ "activity": event["kind"],
1098
+ "prompt_sha256": prompt_sha256,
1099
+ })
1100
+ if not isinstance(result, dict):
1101
+ raise AuthorityError("INVALID_EVIDENCE_CONTEXT", "prompt context result is malformed")
1102
+ context_ref = result.get("context_ref")
1103
+ context_sha256 = _validate_hash(result.get("context_sha256"), "context_sha256")
1104
+ if context_ref != f".codearbiter/.artifacts/evidence-contexts/{context_sha256}.json":
1105
+ raise AuthorityError("INVALID_EVIDENCE_CONTEXT", "prompt context is not content addressed")
1106
+ try:
1107
+ context_raw = (root / context_ref).read_bytes()
1108
+ context = json.loads(context_raw.decode("utf-8"))
1109
+ except (OSError, UnicodeError, ValueError) as exc:
1110
+ raise AuthorityError("INVALID_EVIDENCE_CONTEXT", "prompt context is unavailable") from exc
1111
+ if (
1112
+ _digest(context_raw) != context_sha256
1113
+ or context_raw != _canonical(context)
1114
+ or context.get("activity") != event["kind"]
1115
+ or context.get("subject") != subject
1116
+ or context.get("prompt_sha256") != prompt_sha256
1117
+ ):
1118
+ raise AuthorityError("INVALID_EVIDENCE_CONTEXT", "prompt context changed its authority binding")
1119
+ producer_result = {"host": host, "session_id": session_id, "prompt_sha256": prompt_sha256}
1120
+ observation = {
1121
+ "format": OBSERVATION_FORMAT,
1122
+ "kind": event["kind"],
1123
+ "subject": subject,
1124
+ "context_ref": context_ref,
1125
+ "context_sha256": context_sha256,
1126
+ "payload_sha256": _digest(_canonical(event.get("payload"))),
1127
+ "producer_profile": "host-user-prompt/0.1.0",
1128
+ "producer_run_id": producer_run_id,
1129
+ "producer_result": producer_result,
1130
+ "producer_result_sha256": _digest(_canonical(producer_result)),
1131
+ }
1132
+ observation_raw = _canonical(observation)
1133
+ observation_sha256 = _digest(observation_raw)
1134
+ observation_ref = OBSERVATION_DIR / f"{observation_sha256}.json"
1135
+ _publish_immutable(root, observation_ref, observation_raw)
1136
+ current_event = dict(event)
1137
+ current_event["format"] = EVENT_FORMAT
1138
+ current_event["observation_ref"] = observation_ref.as_posix()
1139
+ current_event["observation_sha256"] = observation_sha256
1140
+ event_raw = _canonical(current_event)
1141
+ event_sha256 = _digest(event_raw)
1142
+ source_ref = SOURCE_DIR / f"{event_sha256}.json"
1143
+ _publish_immutable(root, source_ref, event_raw)
1144
+ captured = client.call("capture-observation", {
1145
+ "source_ref": source_ref.as_posix(), "source_sha256": event_sha256,
1146
+ })
1147
+ if not isinstance(captured, dict) or not isinstance(captured.get("receipt"), str):
1148
+ raise AuthorityError("INVALID_RECEIPT", "observed prompt capture returned no receipt")
1149
+ return {
1150
+ **captured, "authority_source": source_ref.as_posix(),
1151
+ "observation_ref": observation_ref.as_posix(),
1152
+ }
1153
+
1154
+
1155
+ def run_verification(
1156
+ root: str | Path,
1157
+ client: Any,
1158
+ request_id: str,
1159
+ ) -> dict[str, Any]:
1160
+ root = _real_root(root)
1161
+ request = _load(root, request_id)
1162
+ if request["activity"] != "verification":
1163
+ raise AuthorityError("INVALID_AUTHORITY_REQUEST", "request is not verification")
1164
+ if request["state"] == "COMPLETED":
1165
+ return {
1166
+ "request_id": request_id, "state": "COMPLETED",
1167
+ "commands": request["payload"]["commands"],
1168
+ }
1169
+ if request["state"] != "ARMED":
1170
+ raise AuthorityError("INTERRUPTED_ATTEMPT", "verification attempt cannot be rerun")
1171
+ wrapper = request.get("wrapper")
1172
+ if not isinstance(wrapper, dict) or wrapper.get("state") != "AUTHORIZED":
1173
+ raise AuthorityError(
1174
+ "UNAUTHORIZED_VERIFIER",
1175
+ "verification requires a correlated PreToolUse authorization",
1176
+ )
1177
+ if _bind_commands(root, request["context"], request["workspace_roots"]) != request["command_bindings"]:
1178
+ raise AuthorityError("WORKSPACE_DRIFT", "effective argv or workspace changed after arm")
1179
+ fresh_context, fresh_ref, fresh_hash = _context(
1180
+ root, client, request["context"]["subject"]["artifact_id"],
1181
+ request["context"]["subject"]["record_id"], "verification",
1182
+ )
1183
+ if (fresh_context, fresh_ref, fresh_hash) != (
1184
+ request["context"], request["context_ref"], request["context_sha256"],
1185
+ ):
1186
+ raise AuthorityError("WORKSPACE_DRIFT", "repository content changed after arm")
1187
+ workspace_before = _workspace_snapshots(request["command_bindings"])
1188
+ if workspace_before != wrapper.get("workspace_before"):
1189
+ raise AuthorityError("WORKSPACE_DRIFT", "workspace changed after wrapper authorization")
1190
+
1191
+ environment, environment_sha256 = _minimal_environment()
1192
+ request["state"] = "RUNNING"
1193
+ request["attempt"] = secrets.token_hex(16)
1194
+ _save(root, request)
1195
+ commands = []
1196
+ for command, binding in zip(request["context"]["commands"], request["command_bindings"]):
1197
+ definition = command["definition"]
1198
+ collector = COLLECTORS[_collector_profile(definition["argv"], definition["required_tests"])]
1199
+ cwd = _resolved_directory(binding["cwd"])
1200
+ try:
1201
+ completed = _run_contained(list(binding["argv"]), cwd=str(cwd), env=environment)
1202
+ except (OSError, subprocess.SubprocessError) as exc:
1203
+ raise AuthorityError("VERIFICATION_PROCESS_FAILED", "verification process did not complete") from exc
1204
+ stdout = _bounded_output(completed.stdout)
1205
+ stderr = _bounded_output(completed.stderr)
1206
+ if type(completed.returncode) is not int or not 0 <= completed.returncode <= 255:
1207
+ raise AuthorityError("INVALID_PROCESS_RESULT", "process exit is invalid")
1208
+ if completed.returncode != definition["expected_exit"]:
1209
+ raise AuthorityError("FAILED_VERIFICATION", "process exit differs from approved definition")
1210
+ tests = collector(stdout, stderr, list(definition["required_tests"]))
1211
+ commands.append({
1212
+ "definition_sha256": command["definition_sha256"],
1213
+ "exit": completed.returncode,
1214
+ "tests": tests,
1215
+ "stdout_sha256": _digest(stdout),
1216
+ "stderr_sha256": _digest(stderr),
1217
+ })
1218
+ workspace_after = _workspace_snapshots(request["command_bindings"])
1219
+ if workspace_after != workspace_before:
1220
+ raise AuthorityError("WORKSPACE_DRIFT", "verification changed the frozen workspace")
1221
+ final_context, final_ref, final_hash = _context(
1222
+ root, client, request["context"]["subject"]["artifact_id"],
1223
+ request["context"]["subject"]["record_id"], "verification",
1224
+ )
1225
+ if (final_context, final_ref, final_hash) != (
1226
+ request["context"], request["context_ref"], request["context_sha256"],
1227
+ ):
1228
+ raise AuthorityError("WORKSPACE_DRIFT", "verification changed repository content")
1229
+ producer_result = {
1230
+ "environment_sha256": environment_sha256,
1231
+ "command_bindings": request["command_bindings"],
1232
+ "workspace_before": workspace_before,
1233
+ "workspace_after": workspace_after,
1234
+ "commands": commands,
1235
+ }
1236
+ payload = {
1237
+ "input_sha256": request["context"]["input_sha256"],
1238
+ "spec_sha256": request["context"]["spec_sha256"],
1239
+ "task_sha256": request["context"]["task_sha256"],
1240
+ "commands": commands,
1241
+ }
1242
+ observation = _closed_observation(
1243
+ request, payload, "declared-command/0.1.0", request["attempt"],
1244
+ producer_result,
1245
+ )
1246
+ _observation(root, request, observation)
1247
+ request["payload"] = payload
1248
+ request["state"] = "COMPLETED"
1249
+ _save(root, request)
1250
+ return {"request_id": request_id, "state": "COMPLETED", "commands": commands}
1251
+
1252
+
1253
+ def _request_id_from_prompt(message: Any) -> str:
1254
+ if not isinstance(message, str):
1255
+ raise AuthorityError("UNSUPPORTED_HOST_SEAM", "spawn message is absent")
1256
+ match = re.match(r"\[CODEARBITER_AUTHORITY_REQUEST:([0-9a-f]{64})\]\n", message)
1257
+ if match is None:
1258
+ raise AuthorityError("UNSUPPORTED_HOST_SEAM", "spawn message has no authority request")
1259
+ return match.group(1)
1260
+
1261
+
1262
+ def _host_id(value: Any, field: str) -> str:
1263
+ if not isinstance(value, str) or HOST_ID_RE.fullmatch(value) is None:
1264
+ raise AuthorityError("UNSUPPORTED_HOST_SEAM", f"{field} is malformed")
1265
+ return value
1266
+
1267
+
1268
+ def _verification_selector(event: dict[str, Any]) -> tuple[str, Path] | None:
1269
+ """Recognize only the closed wrapper selector, never caller-authored child argv."""
1270
+ if event.get("tool_name") not in {
1271
+ "Bash", "shell_command", "exec_command", "unified_exec",
1272
+ }:
1273
+ return None
1274
+ tool_input = event.get("tool_input")
1275
+ if not isinstance(tool_input, dict):
1276
+ raise AuthorityError("UNSUPPORTED_HOST_SEAM", "exec input is malformed")
1277
+ command = tool_input.get("command", tool_input.get("cmd"))
1278
+ if not isinstance(command, str):
1279
+ raise AuthorityError("UNSUPPORTED_HOST_SEAM", "exec command is absent")
1280
+ compound = any(marker in command for marker in ("\n", "\r", ";", "&&", "||", "|", ">", "<", "`"))
1281
+ try:
1282
+ tokens = [token.strip('"') for token in shlex.split(command, posix=False)]
1283
+ except ValueError as exc:
1284
+ raise AuthorityError("UNSUPPORTED_HOST_SEAM", "verifier wrapper command is malformed") from exc
1285
+ wrapper_start = (
1286
+ len(tokens) >= 3
1287
+ and Path(tokens[0]).name.lower() in {
1288
+ "python", "python.exe", "python3", "python3.exe", "py", "py.exe",
1289
+ }
1290
+ and Path(tokens[1]).name.lower() == "artifact-authority.py"
1291
+ and tokens[2] == "verify"
1292
+ )
1293
+ if compound:
1294
+ if wrapper_start:
1295
+ raise AuthorityError("UNSUPPORTED_HOST_SEAM", "verifier wrapper command is compound")
1296
+ return None
1297
+ if len(tokens) != 7:
1298
+ return None
1299
+ if (
1300
+ Path(tokens[0]).name.lower() not in {
1301
+ "python", "python.exe", "python3", "python3.exe", "py", "py.exe",
1302
+ }
1303
+ or Path(tokens[1]).name.lower() != "artifact-authority.py"
1304
+ or tokens[2] != "verify"
1305
+ or tokens[3] != "--root"
1306
+ or tokens[5] != "--request-id"
1307
+ or REQUEST_RE.fullmatch(tokens[6]) is None
1308
+ ):
1309
+ return None
1310
+ return tokens[6], _real_root(tokens[4])
1311
+
1312
+
1313
+ def observe_verifier_hook(
1314
+ invocation_root: str | Path, event: dict[str, Any]
1315
+ ) -> dict[str, Any] | None:
1316
+ """Authorize/corroborate the wrapper; native exit/output remain result evidence."""
1317
+ _real_root(invocation_root)
1318
+ if not isinstance(event, dict) or event.get("hook_event_name") not in {"PreToolUse", "PostToolUse"}:
1319
+ raise AuthorityError("UNSUPPORTED_HOST_SEAM", "verifier hook event is unsupported")
1320
+ selected = _verification_selector(event)
1321
+ if selected is None:
1322
+ return None
1323
+ request_id, selected_root = selected
1324
+ root, request = _registered_request(request_id)
1325
+ if root != selected_root or request["activity"] != "verification":
1326
+ raise AuthorityError("UNSUPPORTED_HOST_SEAM", "verifier target does not match its request")
1327
+ session_id = _host_id(event.get("session_id"), "session_id")
1328
+ turn_id = _host_id(event.get("turn_id"), "turn_id")
1329
+ tool_use_id = _host_id(event.get("tool_use_id"), "tool_use_id")
1330
+ if event["hook_event_name"] == "PreToolUse":
1331
+ if request["state"] != "ARMED" or request.get("wrapper") is not None:
1332
+ raise AuthorityError("INTERRUPTED_ATTEMPT", "verifier wrapper is not armable")
1333
+ current_bindings = _bind_commands(root, request["context"], request["workspace_roots"])
1334
+ if current_bindings != request["command_bindings"]:
1335
+ raise AuthorityError("WORKSPACE_DRIFT", "effective child argv or cwd changed")
1336
+ for command in request["context"]["commands"]:
1337
+ definition = command["definition"]
1338
+ _collector_profile(definition["argv"], definition["required_tests"])
1339
+ workspace_before = _workspace_snapshots(current_bindings)
1340
+ request["wrapper"] = {
1341
+ "state": "AUTHORIZED", "session_id": session_id,
1342
+ "turn_id": turn_id, "tool_use_id": tool_use_id,
1343
+ "command_bindings": current_bindings,
1344
+ "workspace_before": workspace_before,
1345
+ }
1346
+ _save(root, request)
1347
+ return {
1348
+ "request_id": request_id, "state": "AUTHORIZED",
1349
+ "command_bindings": current_bindings, "workspace_before": workspace_before,
1350
+ }
1351
+ wrapper = request.get("wrapper")
1352
+ if (
1353
+ not isinstance(wrapper, dict)
1354
+ or wrapper.get("session_id") != session_id
1355
+ or wrapper.get("turn_id") != turn_id
1356
+ or wrapper.get("tool_use_id") != tool_use_id
1357
+ or request["state"] != "COMPLETED"
1358
+ ):
1359
+ raise AuthorityError("UNSUPPORTED_HOST_SEAM", "verifier completion is not correlated")
1360
+ response = event.get("tool_response")
1361
+ if isinstance(response, dict):
1362
+ if response.get("exit_code") != 0:
1363
+ raise AuthorityError("FAILED_VERIFICATION", "verifier wrapper did not report exit 0")
1364
+ elif isinstance(response, str):
1365
+ try:
1366
+ completed = json.loads(response) if len(response.encode("utf-8")) <= MAX_OUTPUT else None
1367
+ except ValueError:
1368
+ completed = None
1369
+ if (
1370
+ not isinstance(completed, dict)
1371
+ or completed.get("request_id") != request_id
1372
+ or completed.get("state") != "COMPLETED"
1373
+ ):
1374
+ raise AuthorityError("FAILED_VERIFICATION", "verifier wrapper output did not corroborate completion")
1375
+ else:
1376
+ raise AuthorityError("FAILED_VERIFICATION", "verifier wrapper result is unavailable")
1377
+ wrapper["state"] = "CORROBORATED"
1378
+ _save(root, request)
1379
+ return {"request_id": request_id, "state": "CORROBORATED"}
1380
+
1381
+
1382
+ def _parse_decision(raw: Any, request: dict[str, Any]) -> dict[str, Any]:
1383
+ if not isinstance(raw, str) or len(raw.encode("utf-8")) > MAX_DECISION:
1384
+ raise AuthorityError("INVALID_REVIEW_DECISION", "review decision is absent or oversized")
1385
+ try:
1386
+ value = json.loads(raw)
1387
+ except ValueError as exc:
1388
+ raise AuthorityError("INVALID_REVIEW_DECISION", "review decision is not JSON") from exc
1389
+ expected = {
1390
+ "format", "request_id", "target_sha256", "contract_sha256", "decision",
1391
+ "coverage", "findings", "assessment",
1392
+ }
1393
+ context = request["context"]
1394
+ if (
1395
+ not isinstance(value, dict)
1396
+ or set(value) != expected
1397
+ or value.get("format") != DECISION_FORMAT
1398
+ or value.get("request_id") != request["request_id"]
1399
+ or value.get("target_sha256") != context["input_sha256"]
1400
+ or value.get("contract_sha256") != request["review_contract_sha256"]
1401
+ or value.get("decision") not in {"pass", "changes_requested"}
1402
+ or not isinstance(value.get("assessment"), str)
1403
+ or not value["assessment"].strip()
1404
+ or not isinstance(value.get("coverage"), list)
1405
+ or len(set(value["coverage"])) != len(value["coverage"])
1406
+ or not isinstance(value.get("findings"), list)
1407
+ ):
1408
+ raise AuthorityError("INVALID_REVIEW_DECISION", "review decision failed its closed schema")
1409
+ if set(value["coverage"]) != set(request["required_coverage"]):
1410
+ raise AuthorityError("INCOMPLETE_REVIEW", "review coverage is incomplete")
1411
+ for finding in value["findings"]:
1412
+ if (
1413
+ not isinstance(finding, dict)
1414
+ or set(finding) != {"severity", "code", "message"}
1415
+ or finding["severity"] not in {"BLOCK", "WARN", "INFO"}
1416
+ or not all(isinstance(finding[key], str) and finding[key] for key in ("code", "message"))
1417
+ ):
1418
+ raise AuthorityError("INVALID_REVIEW_DECISION", "review finding is malformed")
1419
+ if value["decision"] != "pass" or any(
1420
+ finding["severity"] == "BLOCK" for finding in value["findings"]
1421
+ ):
1422
+ raise AuthorityError("REVIEW_REJECTED", "independent reviewer did not pass the target")
1423
+ return value
1424
+
1425
+
1426
+ def observe_codex_hook(root: str | Path, event: dict[str, Any]) -> dict[str, Any]:
1427
+ _real_root(root) # Invocation repository is observed but cannot select authority.
1428
+ if not isinstance(event, dict):
1429
+ raise AuthorityError("UNSUPPORTED_HOST_SEAM", "hook event is malformed")
1430
+ name = event.get("hook_event_name")
1431
+ session_id = _host_id(event.get("session_id"), "session_id")
1432
+
1433
+ if name == "PreToolUse":
1434
+ if event.get("tool_name") != "spawn_agent":
1435
+ raise AuthorityError("UNSUPPORTED_HOST_SEAM", "only spawn_agent can launch a reviewer")
1436
+ tool_use_id = _host_id(event.get("tool_use_id"), "tool_use_id")
1437
+ turn_id = _host_id(event.get("turn_id"), "turn_id")
1438
+ tool_input = event.get("tool_input")
1439
+ if not isinstance(tool_input, dict):
1440
+ raise AuthorityError("UNSUPPORTED_HOST_SEAM", "spawn input is malformed")
1441
+ message = tool_input.get("message")
1442
+ if not isinstance(message, str) or not message.startswith("[CODEARBITER_AUTHORITY_REQUEST:"):
1443
+ _record_ordinary_spawn(session_id, turn_id)
1444
+ _reject_overlapping_authority(session_id, turn_id)
1445
+ return None
1446
+ request_id = _request_id_from_prompt(message)
1447
+ root, request = _registered_request(request_id)
1448
+ if request["activity"] not in REVIEW_ACTIVITIES or request["state"] != "ARMED":
1449
+ raise AuthorityError("UNSUPPORTED_HOST_SEAM", "review request is not launchable")
1450
+ if tool_input != request.get("launch_envelope"):
1451
+ raise AuthorityError("UNSUPPORTED_HOST_SEAM", "review launch envelope was changed")
1452
+ if _ordinary_spawn_marker(session_id, turn_id).exists():
1453
+ request["state"] = "REJECTED"
1454
+ request["recovery"] = {
1455
+ "mode": "overlapping-subagent-launch",
1456
+ "rerun_permitted": False,
1457
+ }
1458
+ _save(root, request)
1459
+ raise AuthorityError(
1460
+ "UNSUPPORTED_HOST_SEAM",
1461
+ "authority review cannot share a parent turn with another subagent launch",
1462
+ )
1463
+ request["launch"] = {
1464
+ "parent_session_id": session_id, "parent_turn_id": turn_id,
1465
+ "tool_use_id": tool_use_id, "post_confirmed": False,
1466
+ "agent_id": None, "agent_type": None,
1467
+ "task_name": tool_input["task_name"],
1468
+ "fork_turns": tool_input["fork_turns"],
1469
+ }
1470
+ request["state"] = "LAUNCHING"
1471
+ _save(root, request)
1472
+ return {"request_id": request_id, "state": "LAUNCHING"}
1473
+
1474
+ if name == "PostToolUse":
1475
+ if event.get("tool_name") != "spawn_agent":
1476
+ raise AuthorityError("UNSUPPORTED_HOST_SEAM", "post-tool event is not reviewer launch")
1477
+ tool_use_id = _host_id(event.get("tool_use_id"), "tool_use_id")
1478
+ turn_id = _host_id(event.get("turn_id"), "turn_id")
1479
+ response = event.get("tool_response")
1480
+ if not isinstance(response, dict):
1481
+ raise AuthorityError("UNSUPPORTED_HOST_SEAM", "spawn result is malformed")
1482
+ task_name = _host_id(response.get("task_name"), "task_name")
1483
+ matches = []
1484
+ for candidate_root, candidate in _registered_requests():
1485
+ launch = candidate.get("launch") or {}
1486
+ if (
1487
+ candidate["state"] in {"LAUNCHING", "RUNNING"}
1488
+ and launch.get("parent_session_id") == session_id
1489
+ and launch.get("parent_turn_id") == turn_id
1490
+ and launch.get("tool_use_id") == tool_use_id
1491
+ ):
1492
+ matches.append((candidate_root, candidate))
1493
+ if not matches:
1494
+ return None
1495
+ if len(matches) != 1:
1496
+ raise AuthorityError("UNSUPPORTED_HOST_SEAM", "review launch correlation is ambiguous")
1497
+ root, request = matches[0]
1498
+ if task_name != request["launch"].get("task_name"):
1499
+ raise AuthorityError("UNSUPPORTED_HOST_SEAM", "spawn result task_name differs")
1500
+ request["launch"]["post_confirmed"] = True
1501
+ _save(root, request)
1502
+ return {"request_id": request["request_id"], "state": request["state"]}
1503
+
1504
+ if name in {"SubagentStart", "SubagentStop"}:
1505
+ agent_id = _host_id(event.get("agent_id"), "agent_id")
1506
+ turn_id = _host_id(event.get("turn_id"), "turn_id")
1507
+ matches = []
1508
+ same_turn = []
1509
+ for candidate_root, candidate in _registered_requests():
1510
+ launch = candidate.get("launch") or {}
1511
+ if (
1512
+ launch.get("parent_session_id") == session_id
1513
+ and launch.get("parent_turn_id") == turn_id
1514
+ and candidate["state"] in {"LAUNCHING", "RUNNING"}
1515
+ ):
1516
+ same_turn.append((candidate_root, candidate))
1517
+ if name == "SubagentStart" and (
1518
+ candidate["state"] == "LAUNCHING"
1519
+ and launch.get("parent_session_id") == session_id
1520
+ and launch.get("parent_turn_id") == turn_id
1521
+ ):
1522
+ matches.append((candidate_root, candidate))
1523
+ elif name == "SubagentStop" and (
1524
+ launch.get("parent_session_id") == session_id
1525
+ and launch.get("parent_turn_id") == turn_id
1526
+ and launch.get("agent_id") == agent_id
1527
+ ):
1528
+ matches.append((candidate_root, candidate))
1529
+ if not matches and not same_turn:
1530
+ return None
1531
+ if not matches and same_turn:
1532
+ raise AuthorityError("UNSUPPORTED_HOST_SEAM", "subagent does not match the active authority launch")
1533
+ if len(matches) != 1:
1534
+ raise AuthorityError("UNSUPPORTED_HOST_SEAM", "subagent correlation is ambiguous")
1535
+ root, request = matches[0]
1536
+ agent_type = _host_id(event.get("agent_type"), "agent_type")
1537
+ if name == "SubagentStart":
1538
+ request["launch"]["agent_id"] = agent_id
1539
+ request["launch"]["agent_type"] = agent_type
1540
+ request["state"] = "RUNNING"
1541
+ _save(root, request)
1542
+ return {"request_id": request["request_id"], "state": "RUNNING"}
1543
+ if (
1544
+ request["state"] != "RUNNING"
1545
+ or request["launch"].get("agent_type") != agent_type
1546
+ or request["launch"].get("post_confirmed") is not True
1547
+ ):
1548
+ raise AuthorityError("UNSUPPORTED_HOST_SEAM", "subagent stop is out of order")
1549
+ try:
1550
+ decision = _parse_decision(event.get("last_assistant_message"), request)
1551
+ except AuthorityError:
1552
+ request["state"] = "REJECTED"
1553
+ _save(root, request)
1554
+ raise
1555
+ payload = {
1556
+ "input_sha256": request["context"]["input_sha256"],
1557
+ "spec_sha256": request["context"]["spec_sha256"],
1558
+ "assessment": decision["assessment"],
1559
+ }
1560
+ if request["activity"] == "spec_review":
1561
+ payload["task_sha256"] = request["context"]["task_sha256"]
1562
+ else:
1563
+ payload["base_input_sha256"] = request["context"]["base_input_sha256"]
1564
+ payload["task_hashes"] = request["context"]["task_hashes"]
1565
+ producer_result = {"launch": request["launch"], "decision": decision}
1566
+ observation = _closed_observation(
1567
+ request, payload, "codex-review/0.1.0", agent_id,
1568
+ producer_result,
1569
+ )
1570
+ _observation(root, request, observation)
1571
+ request["payload"] = payload
1572
+ request["state"] = "COMPLETED"
1573
+ _save(root, request)
1574
+ return {"request_id": request["request_id"], "state": "COMPLETED"}
1575
+
1576
+ raise AuthorityError("UNSUPPORTED_HOST_SEAM", "hook event is not supported")
1577
+
1578
+
1579
+ def _event(request: dict[str, Any]) -> dict[str, Any]:
1580
+ context = request["context"]
1581
+ activity = request["activity"]
1582
+ if activity == "verification":
1583
+ authority_kind = "verification_runner"
1584
+ actor = "codeArbiter supervised verifier"
1585
+ origin = f"codex:verification-run:{request['request_id']}"
1586
+ source_text = "Observed exact declared-command completion and qualified named-test results."
1587
+ else:
1588
+ authority_kind = "review_workflow"
1589
+ actor = "independent codex reviewer"
1590
+ origin = f"codex:subagent:{request['launch']['agent_id']}"
1591
+ source_text = "Observed a correlated fresh Codex reviewer completion with a closed passing decision."
1592
+ return {
1593
+ "format": EVENT_FORMAT,
1594
+ "kind": activity,
1595
+ "authority_kind": authority_kind,
1596
+ "subject": context["subject"],
1597
+ "actor": actor,
1598
+ "origin": origin,
1599
+ "verdict": "passed",
1600
+ "payload": request["payload"],
1601
+ "source_text": source_text,
1602
+ "observation_ref": request["observation_ref"],
1603
+ "observation_sha256": request["observation_sha256"],
1604
+ }
1605
+
1606
+
1607
+ def publish_request(
1608
+ root: str | Path, client: Any, request_id: str
1609
+ ) -> dict[str, Any]:
1610
+ root = _real_root(root)
1611
+ request = _load(root, request_id)
1612
+ if request["state"] == "CAPTURED":
1613
+ return {
1614
+ "request_id": request_id, "receipt": request["receipt"],
1615
+ "authority_source": request["authority_source"],
1616
+ }
1617
+ if request["state"] != "COMPLETED":
1618
+ raise AuthorityError("AUTHORITY_NOT_COMPLETE", "successful observation is absent")
1619
+ if request["activity"] == "verification":
1620
+ wrapper = request.get("wrapper")
1621
+ if not isinstance(wrapper, dict) or wrapper.get("state") != "CORROBORATED":
1622
+ raise AuthorityError("AUTHORITY_NOT_COMPLETE", "verifier wrapper completion is uncorroborated")
1623
+ current, current_ref, current_hash = _context(
1624
+ root, client, request["context"]["subject"]["artifact_id"],
1625
+ request["context"]["subject"]["record_id"],
1626
+ request["activity"],
1627
+ )
1628
+ if (
1629
+ current != request["context"]
1630
+ or current_ref != request["context_ref"]
1631
+ or current_hash != request["context_sha256"]
1632
+ ):
1633
+ raise AuthorityError("STALE_AUTHORITY_REQUEST", "engine evidence context changed")
1634
+ observation_path = root / request["observation_ref"]
1635
+ try:
1636
+ observation = observation_path.read_bytes()
1637
+ except OSError as exc:
1638
+ raise AuthorityError("INVALID_OBSERVATION", "observation is unavailable") from exc
1639
+ if _digest(observation) != request["observation_sha256"]:
1640
+ raise AuthorityError("INVALID_OBSERVATION", "observation digest differs")
1641
+ event = _event(request)
1642
+ raw = _canonical(event)
1643
+ digest = _digest(raw)
1644
+ relative = SOURCE_DIR / f"{digest}.json"
1645
+ _publish_immutable(root, relative, raw)
1646
+ captured = client.call("capture-observation", {
1647
+ "source_ref": relative.as_posix(), "source_sha256": digest,
1648
+ })
1649
+ receipt = captured.get("receipt")
1650
+ if not isinstance(receipt, str) or not receipt:
1651
+ raise AuthorityError("INVALID_RECEIPT", "capture returned no receipt")
1652
+ request["state"] = "CAPTURED"
1653
+ request["receipt"] = receipt
1654
+ request["authority_source"] = relative.as_posix()
1655
+ _save(root, request)
1656
+ return {"request_id": request_id, "receipt": receipt, "authority_source": relative.as_posix()}
1657
+
1658
+
1659
+ def recover_request(root: str | Path, request_id: str, disposition: str) -> dict[str, Any]:
1660
+ """Retain an uncertain attempt and close it without ever rerunning commands."""
1661
+ root = _real_root(root)
1662
+ if disposition not in {"failed", "abandoned"}:
1663
+ raise AuthorityError("INVALID_RECOVERY", "recovery disposition must be failed or abandoned")
1664
+ request = _load(root, request_id)
1665
+ recoverable_completed = (
1666
+ request["state"] == "COMPLETED"
1667
+ and request["activity"] == "verification"
1668
+ and isinstance(request.get("wrapper"), dict)
1669
+ and request["wrapper"].get("state") != "CORROBORATED"
1670
+ )
1671
+ recoverable_authorized = (
1672
+ request["state"] == "ARMED"
1673
+ and request["activity"] == "verification"
1674
+ and isinstance(request.get("wrapper"), dict)
1675
+ and request["wrapper"].get("state") == "AUTHORIZED"
1676
+ )
1677
+ if request["state"] not in {"RUNNING", "LAUNCHING"} and not recoverable_completed and not recoverable_authorized:
1678
+ raise AuthorityError("INVALID_RECOVERY", "only an interrupted active attempt can be recovered")
1679
+ request["state"] = disposition.upper()
1680
+ request["recovery"] = {
1681
+ "disposition": disposition,
1682
+ "previous_attempt": request.get("attempt"),
1683
+ "rerun_permitted": False,
1684
+ }
1685
+ _save(root, request)
1686
+ return {"request_id": request_id, "state": request["state"], "rerun_permitted": False}