Skip to content

Commit e5b0bf9

Browse files
committed
fix(engine): remove self-grantable override from importable shipcheck.py + render panel
OVERRIDE_TOKEN, log_override, override_active param, override kwarg, and [OVERRIDE] suffix rendering are all gone. shipcheck.py is now a non-binding display heuristic only; skel/ship-check.py (oracle-backed) is the binding gate.
1 parent 3c7157e commit e5b0bf9

2 files changed

Lines changed: 26 additions & 71 deletions

File tree

prd_taskmaster/render.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ def shipcheck_panel(shipcheck: dict, *, ascii_mode: bool = False) -> str:
261261
lines.append(f"{sym} Gate {i} {name:<26} {word}")
262262
lines.append("")
263263
if shipcheck.get("passed"):
264-
token = "SHIP_CHECK_OK" + (" [OVERRIDE]" if shipcheck.get("override_active") else "")
264+
token = "SHIP_CHECK_OK"
265265
lines.append(f"{ok} {token}")
266266
else:
267267
lines.append(f"{blocked} not shippable — {len(shipcheck.get('failures', []))} gate(s) failed")

prd_taskmaster/shipcheck.py

Lines changed: 25 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
#!/usr/bin/env python3
2-
"""Deterministic ship-check for prd-taskmaster pipelines.
2+
"""NON-BINDING status-display heuristic for prd-taskmaster pipelines.
33
4-
Emits SHIP_CHECK_OK to stdout ONLY when all gates pass. Called by execute-task
5-
at termination AND by Step 9 (--dry-run) as a per-task predicate.
4+
This module is imported by status.py (dry_run=True) ONLY for display purposes.
5+
It is NOT the binding ship gate — the binding gate is skel/ship-check.py
6+
(oracle-backed, unfakable). Do not add an oracle call here.
67
78
Gate logic (grounded against actual pipeline.json / tasks.json schemas
89
observed 2026-06-04 in ai-human-tasker):
@@ -27,34 +28,30 @@
2728
skel checked .atlas-ai/ralph-loop-prompt.md — wrong path and irrelevant
2829
after /goal migration.
2930
30-
Gate 5 (HARD) — No non-zero "Exit status N" line in any .atlas-ai/evidence/
31-
file. This is the convergent must-do from the 2026-06-04 forensic audit
32-
(T12 marked DONE while pnpm test exited 1 with 11 failing tests).
33-
Override only via SHIP_CHECK_OVERRIDE_ADMIN token; overrides are logged
34-
to .atlas-ai/state/execute-log.jsonl as an audit record.
31+
Gate 5 (display only) — No non-zero "Exit status N" line in any
32+
.atlas-ai/evidence/ file. This is a heuristic display signal only;
33+
the binding oracle check is in skel/ship-check.py. There is no override
34+
path — the gate result cannot be bypassed.
3535
3636
Interface (standalone shim, created in a later step):
3737
python3 .atlas-ai/ship-check.py # standard gate
3838
python3 .atlas-ai/ship-check.py --dry-run # always exit 0; report on stderr
39-
python3 .atlas-ai/ship-check.py --override SHIP_CHECK_OVERRIDE_ADMIN # bypass Gate 5
4039
python3 .atlas-ai/ship-check.py --cwd /path/to/project # explicit project root
4140
4241
Exit codes:
43-
0 — SHIP_CHECK_OK (stdout: exactly "SHIP_CHECK_OK\n", with " [OVERRIDE]" suffix if applicable)
42+
0 — SHIP_CHECK_OK (stdout: exactly "SHIP_CHECK_OK\n")
4443
1 — gate failures (stderr only; nothing on stdout — log watchers must not see partial matches)
45-
2 — script error (IO, JSON parse, bad token)
44+
2 — script error (IO, JSON parse)
4645
"""
4746
from __future__ import annotations
4847

4948
import argparse
5049
import json
5150
import re
5251
import sys
53-
from datetime import datetime, timezone
5452
from pathlib import Path
5553
from typing import List, Optional, Tuple
5654

57-
OVERRIDE_TOKEN = "SHIP_CHECK_OVERRIDE_ADMIN"
5855
EXIT_STATUS_RE = re.compile(r"\bExit status\s+(\d+)\b", re.IGNORECASE)
5956

6057

@@ -163,21 +160,7 @@ def gate_exit_codes(atlas: Path) -> Tuple[bool, List[str]]:
163160
return len(failures) == 0, failures
164161

165162

166-
def log_override(atlas: Path, message: str) -> None:
167-
log = atlas / "state" / "execute-log.jsonl"
168-
log.parent.mkdir(parents=True, exist_ok=True)
169-
entry = {
170-
"iteration": "OVERRIDE",
171-
"timestamp": datetime.now(timezone.utc).isoformat(),
172-
"task_id": "SHIP_CHECK",
173-
"event": "override_invoked",
174-
"message": message,
175-
}
176-
with log.open("a") as fp:
177-
fp.write(json.dumps(entry) + "\n")
178-
179-
180-
def run_all_gates(repo_root: Path, override_active: bool) -> Tuple[bool, List[str]]:
163+
def run_all_gates(repo_root: Path) -> Tuple[bool, List[str]]:
181164
failures: List[str] = []
182165
atlas = repo_root / ".atlas-ai"
183166

@@ -194,60 +177,37 @@ def run_all_gates(repo_root: Path, override_active: bool) -> Tuple[bool, List[st
194177
_, f4 = gate_plan(repo_root)
195178
failures.extend(f4)
196179

197-
ok5, f5 = gate_exit_codes(atlas)
198-
if not ok5:
199-
if override_active:
200-
log_override(atlas, f"Gate 5 bypassed: {'; '.join(f5[:3])}{' ...' if len(f5) > 3 else ''}")
201-
# Override accepts the failures; no append to global failures list
202-
else:
203-
failures.extend(f5)
180+
_, f5 = gate_exit_codes(atlas)
181+
failures.extend(f5)
204182

205183
return len(failures) == 0, failures
206184

207185

208-
def run_ship_check(cwd: Optional[str] = None, dry_run: bool = False,
209-
override: Optional[str] = None) -> dict:
210-
"""Importable ship-check entry point. NEVER calls sys.exit.
186+
def run_ship_check(cwd: Optional[str] = None, dry_run: bool = False) -> dict:
187+
"""Importable ship-check entry point. NON-BINDING display heuristic only.
188+
NEVER calls sys.exit. There is no override path.
211189
212190
Args:
213191
cwd: project root (defaults to current working directory).
214192
dry_run: when True, the returned exit_code is forced to 0 regardless of
215193
gate outcome (gates still run and the report is preserved).
216-
override: if equal to OVERRIDE_TOKEN, Gate 5 (exit codes) is bypassed.
217194
218195
Returns a dict:
219-
passed: bool — True when all (non-overridden) gates pass.
220-
failures: list[str] — per-gate failure detail (empty when passed).
221-
override_active: bool — whether a valid override token was supplied.
222-
override_invalid: bool — an override value was supplied but did not match.
196+
passed: bool — True when all gates pass.
197+
failures: list[str] — per-gate failure detail (empty when passed).
223198
dry_run: bool
224-
exit_code: int — 0 / 1 / 2 mirroring the CLI contract.
225-
error: str | None — populated on a script error (exit_code 2).
226-
stdout: str | None — the exact stdout line the CLI would print, if any.
199+
exit_code: int — 0 / 1 / 2 mirroring the CLI contract.
200+
error: str | None — populated on a script error (exit_code 2).
201+
stdout: str | None — the exact stdout line the CLI would print, if any.
227202
"""
228-
if override is not None and override != OVERRIDE_TOKEN:
229-
return {
230-
"passed": False,
231-
"failures": [],
232-
"override_active": False,
233-
"override_invalid": True,
234-
"dry_run": dry_run,
235-
"exit_code": 2,
236-
"error": "--override value does not match expected token",
237-
"stdout": None,
238-
}
239-
240-
override_active = override == OVERRIDE_TOKEN
241203
repo_root = Path(cwd).resolve() if cwd else Path.cwd()
242204

243205
try:
244-
ok, failures = run_all_gates(repo_root, override_active=override_active)
206+
ok, failures = run_all_gates(repo_root)
245207
except Exception as exc: # noqa: BLE001 — top-level guard
246208
return {
247209
"passed": False,
248210
"failures": [],
249-
"override_active": override_active,
250-
"override_invalid": False,
251211
"dry_run": dry_run,
252212
"exit_code": 2,
253213
"error": f"ship-check script error: {exc!r}",
@@ -259,17 +219,14 @@ def run_ship_check(cwd: Optional[str] = None, dry_run: bool = False,
259219
stdout = None
260220
elif ok:
261221
exit_code = 0
262-
suffix = " [OVERRIDE]" if override_active else ""
263-
stdout = f"SHIP_CHECK_OK{suffix}"
222+
stdout = "SHIP_CHECK_OK"
264223
else:
265224
exit_code = 1
266225
stdout = None
267226

268227
return {
269228
"passed": ok,
270229
"failures": failures,
271-
"override_active": override_active,
272-
"override_invalid": False,
273230
"dry_run": dry_run,
274231
"exit_code": exit_code,
275232
"error": None,
@@ -278,16 +235,14 @@ def run_ship_check(cwd: Optional[str] = None, dry_run: bool = False,
278235

279236

280237
def main(argv: Optional[List[str]] = None) -> int:
281-
parser = argparse.ArgumentParser(description="Deterministic ship-check for prd-taskmaster pipelines.")
238+
parser = argparse.ArgumentParser(description="NON-BINDING status-display ship-check for prd-taskmaster pipelines.")
282239
parser.add_argument("--dry-run", action="store_true",
283240
help="Run all gates but always exit 0. Report goes to stderr. Used by execute-task Step 9 as a per-task predicate.")
284-
parser.add_argument("--override", type=str, default=None,
285-
help=f"Bypass Gate 5 (exit codes) if value equals {OVERRIDE_TOKEN}. Logged to execute-log.jsonl.")
286241
parser.add_argument("--cwd", type=str, default=None,
287242
help="Project root (defaults to current working directory).")
288243
args = parser.parse_args(argv)
289244

290-
result = run_ship_check(cwd=args.cwd, dry_run=args.dry_run, override=args.override)
245+
result = run_ship_check(cwd=args.cwd, dry_run=args.dry_run)
291246

292247
# Script error (bad token or IO/JSON failure) — exit 2, message on stderr.
293248
if result["exit_code"] == 2:

0 commit comments

Comments
 (0)