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
78Gate logic (grounded against actual pipeline.json / tasks.json schemas
89observed 2026-06-04 in ai-human-tasker):
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
3636Interface (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
4241Exit 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"""
4746from __future__ import annotations
4847
4948import argparse
5049import json
5150import re
5251import sys
53- from datetime import datetime , timezone
5452from pathlib import Path
5553from typing import List , Optional , Tuple
5654
57- OVERRIDE_TOKEN = "SHIP_CHECK_OVERRIDE_ADMIN"
5855EXIT_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
280237def 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