Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
6936e97
feat: add health-driven automation decisions
Pigbibi Jul 6, 2026
8e66743
fix: harden automation execution control
Pigbibi Jul 6, 2026
f5fe332
fix: fail closed automation control policy
Pigbibi Jul 6, 2026
c1c1e7e
fix: fail closed automation policy loading
Pigbibi Jul 6, 2026
3f5fc85
fix: keep automation control default conservative
Pigbibi Jul 6, 2026
6ba9b3f
fix: include pending runs in automation decisions
Pigbibi Jul 6, 2026
0848dd8
fix: strengthen defer and pending-run guards
Pigbibi Jul 6, 2026
59e0ee3
fix: normalize execution policy decisions
Pigbibi Jul 6, 2026
0cc9ab9
fix: enforce repo-level trusted failure streaks
Pigbibi Jul 6, 2026
a0de099
fix: validate execution policy schema
Pigbibi Jul 6, 2026
acdd960
fix: preserve non-human defer control action
Pigbibi Jul 6, 2026
2afcb30
fix: keep automation control legacy actions compatible
Pigbibi Jul 6, 2026
9b84ef2
fix: align defer with legacy pause control
Pigbibi Jul 6, 2026
a349cf6
fix: validate control mode and failure streak gaps
Pigbibi Jul 6, 2026
aa3edc7
fix: distinguish review-only from human review
Pigbibi Jul 6, 2026
0d82924
fix: harden execution policy deployment
Pigbibi Jul 6, 2026
f3f6550
fix: accept legacy control modes
Pigbibi Jul 6, 2026
f79bf09
fix: normalize legacy execution modes
Pigbibi Jul 6, 2026
be0023c
fix: keep execution policy admin owned
Pigbibi Jul 6, 2026
dbb713a
fix: cap requested autonomy level
Pigbibi Jul 6, 2026
23ad527
fix: keep control default review only
Pigbibi Jul 6, 2026
e216952
fix: preserve manual as review only
Pigbibi Jul 6, 2026
2d8f795
fix: thread requested mode through triage
Pigbibi Jul 6, 2026
29d221e
fix: avoid enforcing truncated failure streaks
Pigbibi Jul 6, 2026
122be8b
fix: downgrade legacy action on autonomy cap
Pigbibi Jul 6, 2026
d5e1e27
fix: preserve auto pr execution on merge cap
Pigbibi Jul 6, 2026
10c2917
fix: enforce retained failure streaks
Pigbibi Jul 6, 2026
259cde8
fix: fail closed on truncated failure history
Pigbibi Jul 6, 2026
59b7dd1
fix: scope ledger truncation by repo
Pigbibi Jul 6, 2026
e381ee9
fix: mark legacy ledger history unknown
Pigbibi Jul 6, 2026
8a60650
fix: fail closed on unreadable automation ledger
Pigbibi Jul 6, 2026
689b1a5
fix: align automation triage fail-closed gates
Pigbibi Jul 6, 2026
b238d6d
fix: keep automation run modes fail closed
Pigbibi Jul 6, 2026
ef194a3
fix: recover ledger migration safety state
Pigbibi Jul 6, 2026
6818446
fix: align execution action with review-only mode
Pigbibi Jul 6, 2026
5f0ef55
fix: prevent stale ledger run resurrection
Pigbibi Jul 6, 2026
ef1f41e
docs: compress autonomy deployment notes
Pigbibi Jul 6, 2026
251e3a0
fix: preserve legacy control action contract
Pigbibi Jul 6, 2026
8133b00
fix: enforce strict automation control action
Pigbibi Jul 6, 2026
b12e407
fix: preserve pause semantics in automation control
Pigbibi Jul 6, 2026
9eaa83e
fix: bound automation history and policy trust checks
Pigbibi Jul 6, 2026
efe2791
fix: align automation control defaults
Pigbibi Jul 6, 2026
ce374ca
fix: preserve automation defaults with fresh run history
Pigbibi Jul 6, 2026
b7ce217
fix: keep human review legacy escalation
Pigbibi Jul 7, 2026
b800aff
fix: infer legacy ledger completeness
Pigbibi Jul 7, 2026
0d9ff1e
fix: fail closed on autonomy caps
Pigbibi Jul 7, 2026
86e3ac4
fix: keep legacy automation compatibility
Pigbibi Jul 7, 2026
1038fa9
fix: guard capped merges and stale ledger updates
Pigbibi Jul 7, 2026
af40391
fix: address automation review blockers
Pigbibi Jul 7, 2026
38e3576
fix: scope ledger history safety checks
Pigbibi Jul 7, 2026
97cb0a9
fix: align automation mode defaults
Pigbibi Jul 7, 2026
a56ad4e
fix: preserve legacy automation defaults
Pigbibi Jul 7, 2026
5f18c7d
fix: validate explicit automation modes
Pigbibi Jul 7, 2026
a2d559c
test: keep ledger coverage within review limits
Pigbibi Jul 7, 2026
b5680f1
fix: preserve historical run mode safety
Pigbibi Jul 7, 2026
b39be6d
fix: allow manual quota and recovery boundaries
Pigbibi Jul 7, 2026
bbc150c
fix: align failure recovery semantics
Pigbibi Jul 7, 2026
7f2f95f
fix: trust only service-owned failure boundaries
Pigbibi Jul 7, 2026
de0784d
fix: preserve low quota automation decisions
Pigbibi Jul 7, 2026
d9f0f7f
test: keep health decision review under gate
Pigbibi Jul 7, 2026
09ca009
fix: base automation control on recorded runs
Pigbibi Jul 7, 2026
be99788
fix: align retained failure boundaries
Pigbibi Jul 7, 2026
863956d
fix: count authenticated workflow failures
Pigbibi Jul 7, 2026
a82d700
fix: align trusted workflow boundaries
Pigbibi Jul 7, 2026
871a0fd
fix: allow only known success boundaries
Pigbibi Jul 7, 2026
47998f1
fix: preserve runtime action compatibility
Pigbibi Jul 7, 2026
b3730af
fix: tighten control action compatibility
Pigbibi Jul 7, 2026
5abdbd1
fix: trust only service-owned safety boundaries
Pigbibi Jul 7, 2026
dc47e3d
fix: validate explicit blank automation modes
Pigbibi Jul 7, 2026
e74113f
fix: preserve stricter automation action
Pigbibi Jul 7, 2026
55f95f5
fix: keep automation control fields consistent
Pigbibi Jul 7, 2026
531390f
fix: recover unknown automation history after boundary
Pigbibi Jul 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 122 additions & 1 deletion scripts/deploy_codex_audit_service.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ ALLOWED_REPOSITORY_VISIBILITIES="${CODEX_AUDIT_SERVICE_ALLOWED_REPOSITORY_VISIBI
ALLOWED_SOURCE_REPOSITORIES="${CODEX_AUDIT_SERVICE_ALLOWED_SOURCE_REPOSITORIES:-QuantStrategyLab/AIAuditBridge,QuantStrategyLab/CryptoLivePoolPipelines,QuantStrategyLab/HkEquitySnapshotPipelines,QuantStrategyLab/UsEquitySnapshotPipelines,QuantStrategyLab/ResearchSignalContextPipelines}"
JOB_DIR="${CODEX_AUDIT_SERVICE_JOB_DIR:-/var/lib/codex-audit-bridge/jobs}"
ADMIN_ENV_FILE="${CODEX_AUDIT_SERVICE_ADMIN_ENV_FILE:-/etc/codex-audit-bridge/admin.env}"
EXECUTION_POLICY_FILE="${CODEX_AUDIT_SERVICE_EXECUTION_POLICY_PATH:-/etc/codex-audit-bridge-policy/execution_policy.json}"
AUDIT_MODEL="${CODEX_AUDIT_SERVICE_MODEL:-}"
AUDIT_REASONING_EFFORT="${CODEX_AUDIT_SERVICE_REASONING_EFFORT:-}"
CODEX_ACCOUNT_USAGE="${CODEX_AUDIT_SERVICE_CODEX_ACCOUNT_USAGE:-1}"
Expand Down Expand Up @@ -60,7 +61,7 @@ systemctl_environment_brief() {
| sed 's/^Environment=//' \
| tr ' ' '\n' \
| sed -E "s/^[\"']//; s/[\"']$//" \
| grep -E '^CODEX_AUDIT_SERVICE_(ALLOWED_|AUDIENCE=|HOST=|PORT=|JOB_DIR=|QUOTA_STORE=|CODEX_ACCOUNT_USAGE=|OPENAI_USAGE_WINDOW_DAYS=|ANTHROPIC_USAGE_WINDOW_DAYS=|SANDBOX=|MODEL=|REASONING_EFFORT=)' \
| grep -E '^CODEX_AUDIT_SERVICE_(ALLOWED_|AUDIENCE=|HOST=|PORT=|JOB_DIR=|QUOTA_STORE=|EXECUTION_POLICY_PATH=|CODEX_ACCOUNT_USAGE=|OPENAI_USAGE_WINDOW_DAYS=|ANTHROPIC_USAGE_WINDOW_DAYS=|SANDBOX=|MODEL=|REASONING_EFFORT=)' \
| mask_infra || true
fi
}
Expand Down Expand Up @@ -214,6 +215,123 @@ write_admin_env_file_if_needed() {
trap - RETURN
}

write_default_execution_policy_if_missing() {
local policy_path="${EXECUTION_POLICY_FILE}"
local policy_dir
policy_dir="$(dirname "$policy_path")"
if [ -L "$policy_path" ]; then
echo "refusing to write execution policy through symlink: $policy_path" >&2
exit 1
fi
if [ -e "$policy_path" ]; then
return
fi
sudo python3 - "$policy_path" <<'PY'
import os
import stat
import sys

path = sys.argv[1]
if not os.path.isabs(path):
print(f"refusing to write execution policy to relative path: {path}", file=sys.stderr)
raise SystemExit(1)

policy_dir, policy_name = os.path.split(path)
if not policy_dir or not policy_name:
print(f"invalid execution policy path: {path}", file=sys.stderr)
raise SystemExit(1)

flags_dir = os.O_RDONLY | os.O_DIRECTORY
if hasattr(os, "O_NOFOLLOW"):
flags_dir |= os.O_NOFOLLOW


def fail(message: str) -> None:
print(message, file=sys.stderr)
raise SystemExit(1)


def ensure_trusted_dir(fd: int, label: str, *, created: bool) -> None:
info = os.fstat(fd)
if not stat.S_ISDIR(info.st_mode):
fail(f"execution policy parent path is not a directory: {label}")
if created:
os.fchown(fd, 0, 0)
os.fchmod(fd, 0o755)
info = os.fstat(fd)
if (info.st_uid, info.st_gid) != (0, 0):
fail(f"execution policy parent directory owner is invalid: {label}")
if info.st_mode & (stat.S_IWGRP | stat.S_IWOTH):
fail(f"execution policy parent directory permissions are too broad: {label}")


def open_admin_policy_dir(directory: str) -> int:
fd = os.open(os.sep, flags_dir)
ensure_trusted_dir(fd, os.sep, created=False)
for component in [part for part in directory.split(os.sep) if part]:
if component in {".", ".."}:
fail(f"invalid execution policy directory component: {component}")
created = False
try:
next_fd = os.open(component, flags_dir, dir_fd=fd)
except FileNotFoundError:
os.mkdir(component, 0o755, dir_fd=fd)
created = True
next_fd = os.open(component, flags_dir, dir_fd=fd)
except OSError as exc:
fail(f"refusing to write execution policy under unsafe directory component {component}: {exc}")
try:
ensure_trusted_dir(next_fd, component, created=created)
finally:
os.close(fd)
fd = next_fd
return fd


policy_dir_fd = open_admin_policy_dir(policy_dir)
flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL
if hasattr(os, "O_NOFOLLOW"):
flags |= os.O_NOFOLLOW
content = """{
"default": {
"max_autonomy": "auto_pr",
"max_consecutive_failures": 3,
"low_cost_model": "gpt-5.4-mini",
"low_cost_provider": "openai"
},
"repositories": {}
}
"""
try:
fd = os.open(policy_name, flags, 0o600, dir_fd=policy_dir_fd)
except FileExistsError:
if os.path.islink(path):
print(f"refusing to write execution policy through symlink: {path}", file=sys.stderr)
raise SystemExit(1)
raise SystemExit(0)
finally:
os.close(policy_dir_fd)
try:
with os.fdopen(fd, "w", encoding="utf-8") as handle:
fd = -1
handle.write(content)
handle.flush()
os.fchown(handle.fileno(), 0, 0)
os.fchmod(handle.fileno(), 0o644)
except Exception:
if fd >= 0:
try:
os.close(fd)
except OSError:
pass
try:
os.unlink(path)
except FileNotFoundError:
pass
raise
PY
}

write_audit_service_unit() {
local runner_user runner_home
runner_user="$(id -un)"
Expand Down Expand Up @@ -252,6 +370,7 @@ Environment=CODEX_AUDIT_SERVICE_ALLOWED_REPOSITORY_VISIBILITIES=${ALLOWED_REPOSI
Environment=CODEX_AUDIT_SERVICE_ALLOWED_SOURCE_REPOSITORIES=${ALLOWED_SOURCE_REPOSITORIES}
Environment=CODEX_AUDIT_SERVICE_JOB_DIR=${JOB_DIR}
Environment=CODEX_AUDIT_SERVICE_QUOTA_STORE=${JOB_DIR}/quota.json
Environment=CODEX_AUDIT_SERVICE_EXECUTION_POLICY_PATH=${EXECUTION_POLICY_FILE}
Environment=CODEX_AUDIT_SERVICE_CODEX_ACCOUNT_USAGE=${CODEX_ACCOUNT_USAGE}
Environment=CODEX_AUDIT_SERVICE_OPENAI_USAGE_WINDOW_DAYS=${OPENAI_USAGE_WINDOW_DAYS}
Environment=CODEX_AUDIT_SERVICE_ANTHROPIC_USAGE_WINDOW_DAYS=${ANTHROPIC_USAGE_WINDOW_DAYS}
Expand Down Expand Up @@ -281,6 +400,7 @@ Environment="CODEX_AUDIT_SERVICE_ALLOWED_WORKFLOW_REFS=${ALLOWED_WORKFLOW_REFS}"
Environment="CODEX_AUDIT_SERVICE_ALLOWED_REFS=${ALLOWED_REFS}"
Environment="CODEX_AUDIT_SERVICE_ALLOWED_REPOSITORY_VISIBILITIES=${ALLOWED_REPOSITORY_VISIBILITIES}"
Environment="CODEX_AUDIT_SERVICE_ALLOWED_SOURCE_REPOSITORIES=${ALLOWED_SOURCE_REPOSITORIES}"
Environment="CODEX_AUDIT_SERVICE_EXECUTION_POLICY_PATH=${EXECUTION_POLICY_FILE}"
EOF_DROPIN
}

Expand Down Expand Up @@ -508,6 +628,7 @@ deploy() {
install_file "scripts/codex_audit_service.py" "${DEPLOY_DIR}/scripts/codex_audit_service.py" "0755"
install_service_package
sudo install -d -m 0700 -o "$runner_user" -g "$runner_user" "$JOB_DIR"
write_default_execution_policy_if_missing
write_admin_env_file_if_needed
write_audit_service_unit
write_managed_audit_service_dropin
Expand Down
Loading
Loading