"""Provenance footer (PRD forge-native-integration, chunk 5). Every orchestrator-posted comment ends with this footer — non-optional and not configurable off. It renders the run's audit trail (agent, bottle, timing, exit, gitleaks, done-signal source, egress) as a collapsed markdown block the reviewer sees at the moment of the merge decision. The function is pure: the orchestrator, which holds the run context, supplies the values. In particular `egress_routes` is the pre-rendered list of allowed-route lines the orchestrator computed from the run's resolved egress policy — this module does not parse backend-specific egress state. (The PRD sketch named an `egress_log_path`; passing the already-rendered lines keeps the footer builder pure and fully testable and leaves egress-state parsing where the data lives.) """ from __future__ import annotations from datetime import datetime def _parse(ts: str) -> datetime | None: try: return datetime.fromisoformat(ts) except (ValueError, TypeError): return None def _format_duration(started_at: str, finished_at: str) -> str: start = _parse(started_at) end = _parse(finished_at) if start is None or end is None: return "unknown" secs = int((end - start).total_seconds()) if secs < 0: return "unknown" if secs < 60: return f"{secs}s" return f"{secs // 60}m {secs % 60}s" def build_provenance_footer( slug: str, *, agent_name: str, bottle_names: tuple[str, ...], started_at: str, finished_at: str, exit_code: int, watchdog_fired: bool = False, gitleaks_clean: bool | None = None, egress_routes: list[str] | None = None, ) -> str: """Return a markdown string for appending to a Gitea comment body. `watchdog_fired=True` marks runs where the agent did not signal completion, so reviewers know the audit trail may be incomplete. `gitleaks_clean=None` renders the gitleaks row as "not run". `egress_routes` is omitted entirely when None/empty. """ bottle_label = ", ".join(f"`{b}`" for b in bottle_names) if bottle_names else "—" exit_cell = f"{exit_code} {'✓' if exit_code == 0 else '✗'}" if gitleaks_clean is None: gitleaks_cell = "— not run" elif gitleaks_clean: gitleaks_cell = "✓ no secrets detected" else: gitleaks_cell = "✗ secrets detected" if watchdog_fired: done_cell = "watchdog — agent did not signal" else: done_cell = "sidecar `signal_done`" lines = [ "
🔬 Run provenance", "", "| Field | Value |", "|---|---|", f"| agent | `{agent_name}` |", f"| bottle | {bottle_label} |", f"| slug | `{slug}` |", f"| started | {started_at} |", f"| duration | {_format_duration(started_at, finished_at)} |", f"| exit | {exit_cell} |", f"| gitleaks | {gitleaks_cell} |", f"| done signal | {done_cell} |", ] if egress_routes: lines.append("") lines.append( f"**Egress** (deny-by-default; {len(egress_routes)} " f"route{'s' if len(egress_routes) != 1 else ''} allowed)" ) for route in egress_routes: lines.append(f"- {route}") lines.append("") lines.append("
") return "\n".join(lines)