T08: .claude/rules/worker-protocol.md (imported by CLAUDE.md, pointed to from AGENTS.md) and tools/contract-tests/excerpt.py: name the rows, hand every worker one excerpt, one owner per step, check with the excerpt's tests. A test requires every table row to have details and a contract test (found O4). T06: bounded-executor/window_watch.py flags or closes the write role when no run Job is active or recent; stub tests; in the image. Built from the excerpt for O5, E1, C1, E8, E9, R2. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 943911@bnt-lap001 Assistant-Session: fc322940-1c8e-4bed-ab39-86cec99f23a0
62 lines
2.5 KiB
Python
62 lines
2.5 KiB
Python
#!/usr/bin/env python3
|
||
"""Contract excerpt for a worker on a cross-repo change (NK-WP-0058-T08). Read-only.
|
||
|
||
python3 tools/contract-tests/excerpt.py E1 C5 O1 # rows of docs/bounded-execution-contract-table.md
|
||
|
||
Prints, for each row: its line in the table (owner and source of truth, consumer, mark), its detail sections (names,
|
||
paths, roles, payloads, exit codes, and the one owning script or file per step), and the contract tests that cover
|
||
it. A worker gets this excerpt before starting and checks its result with those tests and `make contract-test`.
|
||
An unknown row fails: a new interface gets its row in the table first.
|
||
"""
|
||
import re
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
TABLE = Path(__file__).resolve().parents[2] / 'docs/bounded-execution-contract-table.md'
|
||
ROW = re.compile(r'^[EROCF]\d+$')
|
||
|
||
|
||
def ids_in(text):
|
||
"""Row ids named in a cell or heading, with ranges like O2–O4 expanded."""
|
||
found = set()
|
||
for first, last in re.findall(r'\b([EROCF]\d+)\s*[–-]\s*([EROCF]\d+)\b', text):
|
||
if first[0] == last[0]:
|
||
found |= {f'{first[0]}{n}' for n in range(int(first[1:]), int(last[1:]) + 1)}
|
||
return found | set(re.findall(r'\b[EROCF]\d+\b', text))
|
||
|
||
|
||
def sections(text):
|
||
"""(heading, body) for each ### section."""
|
||
parts = re.split(r'^(### .+)$', text, flags=re.M)
|
||
return [(parts[i], parts[i + 1].split('\n## ')[0]) for i in range(1, len(parts) - 1, 2)]
|
||
|
||
|
||
def excerpt(row_ids, text=None):
|
||
text = text if text is not None else TABLE.read_text()
|
||
out = []
|
||
for row in row_ids:
|
||
if not ROW.match(row):
|
||
raise SystemExit(f'not a row id: {row}')
|
||
line = next((l for l in text.splitlines() if l.startswith(f'| {row} |')), None)
|
||
if line is None:
|
||
raise SystemExit(f'{row}: no such row; add the interface to the table first')
|
||
out += [f'## {row}', '', line, '']
|
||
for heading, body in sections(text):
|
||
if row in ids_in(heading.split(':')[0]):
|
||
out += [heading, body.strip(), '']
|
||
coverage = [l for l in text[text.index('### Coverage by row'):].splitlines()
|
||
if l.startswith('| ') and not l.startswith('| Row') and row in ids_in(l.split('|')[1])]
|
||
out += ['**Contract tests:**', *(coverage or ['none recorded: add one with the change']), '']
|
||
return '\n'.join(out)
|
||
|
||
|
||
def main(argv=None):
|
||
rows = argv if argv is not None else sys.argv[1:]
|
||
if not rows:
|
||
raise SystemExit(__doc__)
|
||
print(excerpt(rows))
|
||
return 0
|
||
|
||
|
||
if __name__ == '__main__':
|
||
sys.exit(main())
|