Review/optimize checklist, executive-summary format, build executor (T02-T04)
docs/review-optimize-checklist.md: six checks (naming, TTL/scoping,
redundancy, compaction, ease of use, posture), applied for real to the
rein-openweights plan's section 4 -- including a genuinely useful
finding (credentials.py already expects this exact path/delivery shape,
zero code changes needed to consume it).
docs/executive-summary-format.md: six fixed fields, no bao syntax, no
restating earlier sections, explicit approve/reject/revise decision.
Rendered for real into the plan's section 5 -- ready for an actual
decision.
src/ops_mason/{plan,executor,audit}.py: the phase-4 build executor for
credential_type openbao-approle-kv. Refuses to run against anything but
an approved plan -- verified the refusal never even calls subprocess.run.
role_id/secret_id (the AppRole's own access credential, not the
downstream secret) land as 0600 files, never logged; the HCL policy
goes over stdin, never argv; the audit trail is metadata-only. 12 tests,
all mocked at the bao boundary (no live OpenBao access from this
session).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
123ccfe20c
commit
0d62ac501d
12 changed files with 645 additions and 12 deletions
48
src/ops_mason/audit.py
Normal file
48
src/ops_mason/audit.py
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
"""Metadata-only audit trail for what ops-mason built.
|
||||
|
||||
Same invariant as ops-warden's own audit trail (`warden activity`):
|
||||
object names and plan references only, never secret material.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from dataclasses import asdict, dataclass
|
||||
from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
|
||||
_DEFAULT_LOG = Path(__file__).resolve().parents[2] / "audit" / "build-log.jsonl"
|
||||
|
||||
|
||||
@dataclass
|
||||
class BuildRecord:
|
||||
plan_id: str
|
||||
plan_path: str
|
||||
approved_by: str
|
||||
approved_at: str
|
||||
objects: dict[str, str]
|
||||
built_at: str
|
||||
|
||||
|
||||
def record_build(
|
||||
*,
|
||||
plan_id: str,
|
||||
plan_path: str,
|
||||
approved_by: str,
|
||||
approved_at: str,
|
||||
objects: dict[str, str],
|
||||
log_path: Path | None = None,
|
||||
) -> BuildRecord:
|
||||
record = BuildRecord(
|
||||
plan_id=plan_id,
|
||||
plan_path=plan_path,
|
||||
approved_by=approved_by,
|
||||
approved_at=approved_at,
|
||||
objects=objects,
|
||||
built_at=datetime.now(UTC).isoformat(),
|
||||
)
|
||||
path = log_path or _DEFAULT_LOG
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
with path.open("a") as fh:
|
||||
fh.write(json.dumps(asdict(record)) + "\n")
|
||||
return record
|
||||
Loading…
Add table
Add a link
Reference in a new issue