Generate a convergence issue from a repo's audit (audit.py --issue) - #399
Conversation
Scripts the issue content instead of composing it by hand each time, so it never drifts from what the audit actually found and regenerates as the repo changes - the idempotent-artifact model applied to issues. - audit.py: render_issue formats one repo's audit findings into a ready-to-file title and body, grouped by what the maintainer does with them - must-fix (defect/letter), converge (drift: re-vendor a verbatim file or section, honor an interface contract, or judge a stale/intent copy), and could-not-verify (error). `--issue <repo>` runs the audit for one repo and emits only the issue on stdout (title on the first line), so it can be captured and filed. - selftest covers the grouping, the finding count in the title, and the clean case. - AUDIT.md section 8 documents it. Verified live: `--issue Financial-Modeling` produces its four real divergences (the three verbatim AGENTS.md sections + the stale configure.sh) with no invented prose. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds an --issue output mode to the fleet audit runner so it can deterministically generate a ready-to-file convergence issue (title + body) from the live audit findings, reducing drift between reported findings and tracking issues.
Changes:
- Extend
spec/audit.pywith--issue <repo>to emit a convergence issue derived fromaudit_repo()findings. - Add
render_issue()to group findings into “Must fix”, “Converge”, and “Could not verify”, and extend--selftestto cover this rendering. - Update
AUDIT.mdto document the new issue generator and reiterate the “point-in-time snapshot” requirement.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| spec/audit.py | Implements issue generation (--issue) and adds selftest coverage for grouping/title/empty-case output. |
| AUDIT.md | Documents generating convergence issues from audit output to avoid hand-written drift. |
Comments suppressed due to low confidence (2)
spec/audit.py:817
- In
--issuemode the script claims to emit "title on the first line, then the body", but the current output adds aTITLE:prefix and an extra blank line. That makes the stdout harder to capture and file as-is (and doesn't match the documented contract).
print(f"TITLE: {title}")
print()
print(body, end="")
return 0
spec/audit.py:740
- The generated issue intro sentence ends with "The full letter and intent verdict is AUDIT.md's.", which reads ungrammatical and is likely to confuse readers of the issue. Rephrase to a clear directive to consult AUDIT.md for the full verdicts.
w(f"Generated from the hub audit of `{name}` ({types}) at `{stamp}`, hub `{hub_sha}`, {run_utc}. "
f"Regenerate with `spec/audit.py --issue {name}`. Findings are a point-in-time snapshot - re-run the "
f"audit before acting (AUDIT.md section 8). This lists what the audit mechanically detects. The full "
f"letter and intent verdict is AUDIT.md's.")
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (2)
spec/audit.py:816
--issuemode is documented as emitting a ready-to-file issue with the title on the first line, but the code prefixes the title withTITLE:. That makes the output not directly pasteable/consumable as a GitHub issue title and contradicts the nearby comment/docstrings describing the format.
title, body = render_issue(entry, findings, entry.get("groundTruthBranch", "main"),
audited_sha, run_utc, hub_sha)
print(f"TITLE: {title}")
print()
print(body, end="")
spec/audit.py:802
- This new
--issueheader comment is 3 lines and mostly restates what the code does. AGENTS.md asks to keep comments terse (one line by default) and focus on the non-obvious why (AGENTS.md:145-149). Consider condensing this to a single line.
# --issue <repo>: emit a ready-to-file convergence issue for one repo (title on the first line, then the
# body) - stdout carries only the issue so it can be captured and filed. The body is generated from the
# audit, so it never drifts from reality.
…ed issue "The full letter and intent verdict is AUDIT.md's." reads as a truncated possessive; reword to "lives in AUDIT.md." Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
spec/audit.py:816
--issuemode printsTITLE: ...plus a blank line before the body. The PR description/AUDIT.md describe a ready-to-file issue with the title on the first line, then the body; theTITLE:prefix makes the output not directly copy/pasteable as an issue title.
print(f"TITLE: {title}")
print()
print(body, end="")
…comment - render_issue: the issue intro now quotes the run stamp in the canonical AUDIT.md section 8 format (`audit run <UTC> | hub <sha>` and `@ <branch>@<sha>`), instead of the same data in an ad-hoc shape, so it is the recognizable stamp a reader is told to check. - Condense the --issue block comment to one line (the why lives in render_issue's docstring). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The --issue output now puts the title on the first line and the body from the second, matching the documented "title on the first line, then the body" - a consumer takes line 1 as the title and the rest as the body with no blank to skip. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
spec/audit.py:812
--issueis documented (and commented) as emitting the title on the first line and the body from the second, so consumers can take line 1 as the issue title. Prefixing the first line withTITLE:makes the output not "ready-to-file" and can break simple capture tooling.
print(f"TITLE: {title}")
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (2)
spec/audit.py:813
--issueoutput is documented as "title on the first line, then the body" for clean capture/filing, but it currently prefixes the first line withTITLE:. That makes simple "first line is the issue title" tooling harder and doesn't match the PR description/AUDIT.md wording.
print(f"TITLE: {title}")
print(body, end="") # body begins on the next line - title first line, body from the second
spec/audit.py:730
- When
audited_shais empty (e.g. earlyghfailure),stampbecomes just the branch name, so the issue intro claims it read@ maininstead of quoting the documented@ <branch>@<sha>stamp format. Consider emitting an explicit@ <branch>@unknownso derived artifacts still follow the contract while staying honest about missing data.
name = entry["name"]
types = ", ".join(entry.get("types", [])) or "untyped"
stamp = f"{ground}@{audited_sha[:7]}" if audited_sha else ground
blocking = [(k, t) for k, t in findings if k in ("DEFECT", "LETTER")]
drift = [t for k, t in findings if k == "DRIFT"]
…rated issue "read `@ ...`" overclaimed in an error case where no commit SHA resolved (the stamp is then just the branch). Use "against `@ ...`", which is accurate whether or not a SHA was read. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
spec/audit.py:813
--issueoutput contract is documented as "title on the first line, then the body" for easy capture/filing, but the code prefixes the first line withTITLE:. That breaks simple consumers that treat line 1 as the issue title verbatim (and it also diverges from the PR description/AUDIT.md text). Print the raw title as line 1 instead.
title, body = render_issue(entry, findings, entry.get("groundTruthBranch", "main"),
audited_sha, run_utc, hub_sha)
print(f"TITLE: {title}")
print(body, end="") # body begins on the next line - title first line, body from the second
Scripts the convergence-issue content so it's derived from the audit, never composed on the fly — the idempotent-artifact model applied to issues. Filing a hand-written issue is exactly the "content drifts from reality" problem the fidelity model exists to kill.
What
spec/audit.py --issue <repo>— runs the per-repo audit and emits a ready-to-file issue (title on the first line, then the body) on stdout, so it can be captured and filed.render_issuegroups the findings by what the maintainer does with them:DEFECT/LETTER(a missing carried file, a broken workflow contract).DRIFT(re-vendor averbatim:file or section, honor aninterface:contract, or judge a stale/intent copy per AUDIT.md).ERROR.--selftestcovers grouping, the finding count in the title, and the clean case.Verified live
--issue Financial-Modeling→ its four real divergences (the three verbatimAGENTS.mdsections + the staleconfigure.sh), no invented prose.Next
Use it to file finmod's convergence issue — the first catalog-driven issue.
🤖 Generated with Claude Code