Files
boshu2__agentops/docs/convergence/operationalized/scripts/validate-operators.py
Bo cfee2b078a docs(convergence): first-class Convergence section — The Reading + Ledger + Google SRE map (ag-4hf7 #google-sre-convergence) (#650)
## What

Establishes a first-class **`docs/convergence/`** section: the record of
the industry independently arriving at the structure AgentOps already
runs — kept distinct from the competitor map. Three surfaces:

1. **`the-reading.md`** — the *living thesis*. The argument (with
mechanism, firm-vs-forming consensus table, honest moat-risk, and a "how
to read a new signal" rubric) that the industry is converging and
**why**.
2. **`ledger.md`** — the dated *receipts* table (who/when/which
invariant). Seeded with Google SRE 2026.
3. **`google-sre.md`** — the per-party *encoding map*: 11 convergence
points → real AgentOps loci (8 encoded · 2 partial · 1 gap).
4. **`index.md`** — section hub framing the three.

## Why first-class, not under comparisons/

A vindication record is the *inverse* of a competitor grid — wrong to
parent it under "vs the competition." Radar = competitors in our lane;
Convergence = independents arriving from outside it. Promoted to its own
top-level nav section (`git mv`, history preserved; permalinks updated;
cross-links rewired both ways).

## Gaps surfaced (filed as beads)

| Bead | Point | Work |
|---|---|---|
| `ag-fjbu` | #3 | Adopt Bronze/Silver/Gold eval-tiering +
True-vs-Observed-Precision naming |
| `ag-wrom` | #8 | Formalize an L0–L4-style autonomy ladder for AgentOps
dispatch |
| `ag-7278` | #11 | Council: does coherent-arc need a fix-forward escape
hatch? (Google is ahead) |

## Verification

- All relative links across the convergence section + comparisons
pointers resolve.
- mkdocs nav + documentation-index updated; renames preserve history.

Closes-scenario: ag-4hf7#google-sre-convergence
Bounded-context: BC1-Corpus
Evidence: docs/convergence/the-reading.md
2026-05-31 18:48:45 +00:00

78 lines
2.6 KiB
Python
Executable File

#!/usr/bin/env python3
"""Validate operator cards have all required fields, valid anchors, and an enforcement verdict.
Exit non-zero on any failure. Pure stdlib.
"""
from __future__ import annotations
import re
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
LIB = ROOT / "corpus" / "specs" / "operator_library.md"
QB = ROOT / "corpus" / "quote_bank" / "quote_bank.md"
REQUIRED = [
"**Definition**",
"**When-to-Use Triggers**",
"**Failure Modes**",
"**Prompt Module**",
"**Canonical tag**",
"**Quote-bank anchors**",
"**AgentOps-Enforcement**", # local extension: the audit bridge
]
VALID_VERDICTS = ("ENFORCED", "PARTIAL", "GAP")
def main() -> int:
errs: list[str] = []
if not LIB.is_file():
print("FAIL: missing operator_library.md")
return 1
if not QB.is_file():
print("FAIL: missing quote_bank.md")
return 1
known_anchors = {int(n) for n in re.findall(r"^## §(\d+) —", QB.read_text(encoding="utf-8"), re.M)}
text = LIB.read_text(encoding="utf-8")
# Operator cards are '### Name' under the library (skip the doc's own H3 in preamble by requiring fields)
cards = re.findall(r"^### (.+?)\n(.*?)(?=^### |\Z)", text, re.M | re.S)
operators = [(name, body) for name, body in cards if "**Definition**" in body]
if not operators:
print("FAIL: no operator cards found")
return 1
for name, body in operators:
for field in REQUIRED:
if field not in body:
errs.append(f"{name}: missing field {field}")
# Prompt module fenced block present
if "~~~" not in body:
errs.append(f"{name}: Prompt Module fenced block (~~~) missing")
# Enforcement verdict valid
m = re.search(r"\*\*AgentOps-Enforcement\*\*:\s*(\w+)", body)
if m and m.group(1) not in VALID_VERDICTS:
errs.append(f"{name}: enforcement verdict '{m.group(1)}' not in {VALID_VERDICTS}")
# Anchors reference real quotes
am = re.search(r"\*\*Quote-bank anchors\*\*:\s*(.+)", body)
if am:
refs = {int(x) for x in re.findall(r"§(\d+)", am.group(1))}
missing = refs - known_anchors
if not refs:
errs.append(f"{name}: no §anchors cited")
if missing:
errs.append(f"{name}: anchors not in quote bank: {sorted(missing)}")
if errs:
print(f"FAIL operator validation ({len(errs)} error(s)):")
for e in errs:
print(f" - {e}")
return 1
print(f"OK operator validation ({len(operators)} operators)")
return 0
if __name__ == "__main__":
sys.exit(main())