feat(devkit): add resumable workspace automation and UI review tooling
Dependency Audit / dependency-audit (push) Successful in 1m45s
Deployment Installer / deployment-installer (push) Successful in 6s
Security Audit / security-audit (push) Successful in 11m30s

Verified with the coordinated workspace changes by devkit full run
2026-09-08T225814-186389-0000-3e3ed7cd (all seven phases passed).
This shared UI pass does not mark the individual module reviews complete.
This commit is contained in:
2026-09-09 02:03:17 +02:00
parent 14b19fbead
commit 2ffdb23f69
67 changed files with 17306 additions and 94 deletions
+251
View File
@@ -0,0 +1,251 @@
"""Read-only run discovery and bounded provisional output, never passing evidence."""
from __future__ import annotations
from datetime import datetime
import os
from pathlib import Path
import re
import time
from .common import (
atomic_json,
identifier,
now,
read_json,
redact,
reject_symlinks,
state_root,
)
MAX_LIVE_BYTES = 65536
MAX_HISTORY_ENTRIES = 10000
MAX_HISTORY_SCAN = 500
ANSI = re.compile(r"\x1b(?:\[[0-?]*[ -/]*[@-~]|\][^\x07\x1b]*(?:\x07|\x1b\\))")
CONTROLS = re.compile(r"[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x9f]")
def display_text(value: str) -> str:
return redact(CONTROLS.sub("", ANSI.sub("", value)))
def _closed_lines(value: bytes) -> bytes:
boundary = value.rfind(b"\n")
return value[: boundary + 1] if boundary >= 0 else b""
def capture_text(snapshot, *, provisional: bool = False) -> str:
"""Do not expose partial secret/context fragments at live or retention boundaries."""
data = snapshot.stdout
omitted = snapshot.omitted_stdout_bytes
if omitted:
head = _closed_lines(data[: snapshot.stdout_head_bytes])
tail = data[snapshot.stdout_head_bytes :]
# A rolling tail can start inside Authorization or a secret: drop that fragment.
tail = tail.partition(b"\n")[2]
if provisional:
tail = _closed_lines(tail)
return (
display_text(head.decode("utf-8", errors="replace"))
+ f"\n[Output truncated: {omitted} bytes omitted between retained head and tail; cut boundary lines are withheld.]\n"
+ display_text(tail.decode("utf-8", errors="replace"))
)
if provisional:
data = _closed_lines(data)
return display_text(data.decode("utf-8", errors="replace"))
def bounded_display(value: str, maximum: int, *, tail_only: bool = False) -> str:
if type(maximum) is not int or maximum < 1:
raise ValueError("Display bound must be a positive integer")
encoded = value.encode("utf-8")
if len(encoded) <= maximum:
return value
if tail_only:
return encoded[-maximum:].decode("utf-8", errors="ignore")
marker = b"\n[Display bound: middle omitted; retained beginning and final output follow.]\n"
if maximum <= len(marker):
return encoded[-maximum:].decode("utf-8", errors="ignore")
available = max(0, maximum - len(marker))
head = available // 2
return (
encoded[:head].decode("utf-8", errors="ignore")
+ marker.decode()
+ encoded[-(available - head) :].decode("utf-8", errors="ignore")
)
def write_live(log_path: Path, stage_id: str, snapshot, started: float) -> None:
# Complete lines only, even at final callback: the separately finalized log
# may include an unterminated final line after normal redaction.
excerpt = bounded_display(
capture_text(snapshot, provisional=True), MAX_LIVE_BYTES, tail_only=True
)
atomic_json(
log_path.with_suffix(".live.json"),
{
"schema_version": 1,
"run_id": log_path.parent.name,
"stage_id": stage_id,
"provisional": True,
"updated_at": now(),
"elapsed_seconds": round(time.monotonic() - started, 3),
"output_truncated": snapshot.truncated,
"omitted_bytes": snapshot.omitted_stdout_bytes,
"excerpt": excerpt,
},
)
def read_live(
workspace_root: Path, state_dir: Path | None, run_id: str, stage_id: str
) -> dict:
identifier(run_id)
identifier(stage_id)
path = (
state_root(workspace_root, state_dir)
/ "runs"
/ run_id
/ (stage_id + ".live.json")
)
if not path.exists() and not path.is_symlink():
return {"provisional": True, "excerpt": "", "live_available": False}
payload = read_json(path, max_bytes=MAX_LIVE_BYTES * 6 + 8192)
if (
not isinstance(payload, dict)
or payload.get("schema_version") != 1
or payload.get("run_id") != run_id
or payload.get("stage_id") != stage_id
or payload.get("provisional") is not True
or not isinstance(payload.get("excerpt"), str)
or len(payload["excerpt"].encode("utf-8")) > MAX_LIVE_BYTES
or not isinstance(payload.get("updated_at"), str)
or type(payload.get("elapsed_seconds")) not in {int, float}
or payload["elapsed_seconds"] < 0
or type(payload.get("output_truncated")) is not bool
):
raise ValueError("Invalid provisional log snapshot")
return {
"provisional": True,
"live_available": True,
"excerpt": display_text(payload["excerpt"]),
"updated_at": payload.get("updated_at"),
"elapsed_seconds": payload.get("elapsed_seconds"),
"output_truncated": payload.get("output_truncated"),
}
def elapsed_seconds(receipt: dict) -> float | None:
try:
started = datetime.fromisoformat(receipt["generated_at"])
finished = datetime.fromisoformat(receipt.get("finished_at") or now())
return max(0, round((finished - started).total_seconds(), 3))
except (KeyError, TypeError, ValueError):
return None
def list_runs(args) -> dict:
from .runner import read_receipt
limit = getattr(args, "limit", 10)
before = getattr(args, "before", None)
if type(limit) is not int or not 1 <= limit <= 100:
raise ValueError("Run history limit must be between 1 and 100")
if before:
identifier(before)
base = state_root(args.workspace_root, args.state_dir) / "runs"
reject_symlinks(base)
names = []
if base.exists():
with os.scandir(base) as entries:
for index, entry in enumerate(entries):
if index >= MAX_HISTORY_ENTRIES:
raise ValueError(
"Run history exceeds its directory bound; archive old evidence explicitly before listing"
)
if not entry.name.startswith("."):
identifier(entry.name)
names.append(entry.name)
names = sorted(
(name for name in names if before is None or name < before), reverse=True
)
rows, examined, cursor = [], 0, None
wanted_project = (
str(args.project.resolve()) if getattr(args, "project", None) else None
)
for identity in names:
examined += 1
cursor = identity
try:
record = read_receipt(args.workspace_root, args.state_dir, identity)
if wanted_project and record.get("project_file") != wanted_project:
if examined >= MAX_HISTORY_SCAN:
break
continue
rows.append(
{
"run_id": identity,
"status": record["status"],
"phase": record.get("phase"),
"profile": record.get("profile"),
"generated_at": record.get("generated_at"),
"elapsed_seconds": elapsed_seconds(record),
"snapshot_verified": record["snapshot_verified"],
"passed_stages": sum(
item["status"] == "passed" for item in record["stages"]
),
"total_stages": len(record["stages"]),
}
)
except (OSError, ValueError) as exc:
# Corrupt/newest evidence is visible, never silently replaced with an older pass.
rows.append(
{
"run_id": display_text(identity),
"status": "invalid",
"error": display_text(str(exc)),
}
)
if len(rows) >= limit or examined >= MAX_HISTORY_SCAN:
break
next_cursor = cursor if examined < len(names) else None
lines = [
f"{item['run_id']}: {item['status']}"
+ (
f" ({item.get('profile')}; {item.get('elapsed_seconds')}s)"
if item["status"] != "invalid"
else "" + item["error"]
)
for item in rows
]
if not lines:
lines = ["No matching check runs found; no verification is implied."]
if next_cursor:
lines.append("More history: use --before " + display_text(next_cursor))
return {
"runs": rows,
"next_cursor": next_cursor,
"examined": examined,
"summary": lines,
"_exit_code": 1 if any(item["status"] == "invalid" for item in rows) else 0,
}
def latest_run(args) -> dict:
from argparse import Namespace
from .runner import read_receipt, summarize
selected = list_runs(Namespace(**{**vars(args), "limit": 1}))
if not selected["runs"]:
return {
"status": "not_found",
"summary": selected["summary"],
"next_cursor": selected["next_cursor"],
"_exit_code": 1,
}
row = selected["runs"][0]
if row["status"] == "invalid":
raise ValueError(
"Latest run is invalid; inspect run history instead of assuming an older pass"
)
return summarize(read_receipt(args.workspace_root, args.state_dir, row["run_id"]))