Add three rules to the shared blocks and cut 0.3.1 - #53
Merged
Conversation
The block says how to avoid writing to the wrong issue or pull request -- confirm the target with a read first, re-verify every write with a structured `--json` query -- and says nothing about what to do once a body has been overwritten anyway. That gap is worth a bullet because the recovery cannot be worked out in the moment. GitHub keeps every prior version of a body, but only `userContentEdits` in the GraphQL API exposes them, and nothing in the `gh` command line suggests it exists. An agent that does not know this reports the text as lost, or reconstructs it from what it remembers -- and a body that reads like the original and is not is harder to notice, and harder to undo, than an empty one. There is a path that reaches it in normal use. Refining an issue rewrites the issue body, which is an overwrite rather than a create, and the agent doing it reads the consuming repository's AGENTS.md. One bullet, because nothing has gone wrong yet. The prevention rules work -- a session doing dozens of `gh` writes clobbered nothing -- so this is for the case where they do not, and it earns its lines by being unguessable rather than by being common. Closes #50
The block says how to write an entry and nothing about the sections those entries sit in. One convention is missing, and this repository has been caught by it twice: 0.1.2 and 0.1.3 were both tagged with an empty `[Unreleased]` left behind, and the 0.1.4 entries were still sitting under that heading, which would have extracted an empty body and aborted the release after the tag was pushed. `release.yml` builds the notes by scanning for the heading that matches the tag, so this is not cosmetic tidying -- it is the difference between a release and a tag with no release behind it. The knowledge lives in one commit message here. All thirteen consuming repositories keep a CHANGELOG.md and none of them can see it. The no-references bullet is rewritten in the same change because its reasoning did not reach its rule. The rule is categorical -- no issue or pull request references -- while everything justifying it was about `Closes #N` and `Part of #N` being automation keywords. A plain (#123) is neither a keyword nor a command to a bot, so a reader holding one had nothing to weigh. The reason that does reach it is the reader: a release note names something in a tracker they may not be able to open, and the history behind it is git's to hold. The keyword argument survives as the sharper case rather than the whole of it, and the bullet loses the sentence that repeated the one before it. Closes #51
The block says a commit separates its title from its body with a blank line. It does not say that the usual way of getting that wrong produces a commit git accepts without complaint: passing the whole message as one `-m` argument with `\n` in it puts the escapes in the subject as two literal characters, leaves the body empty, and exits 0 with nothing on stderr. One mistake breaks three rules of that section at once -- the title runs past 50 characters, there is no blank line, and there is no body to explain why. Nothing downstream catches it. No lint reads commit subjects, and by the time a person reads the log the commit is history, needing a rebase to fix once it has been pushed. It is also a mistake only an agent makes, which is why it belongs in these blocks rather than in a contributing guide. A person running `git commit` gets an editor and never composes the message as a single shell argument. An agent assembling a command string is exactly who reaches for `\n`, and every commit an agent writes in these repositories goes through that path, including the ones an AgentCoop run makes. Closes #52
The three block changes on this branch each add a rule, which the grading in README.md makes MINOR and shifts down to PATCH below 1.0.0. They touch `blocks/`, so the surface guard has something to compare against 0.3.0 and the tag can be cut -- unlike the last two releases, which existed only because `repos.json` moved. The drift-warning entries were already sitting under `[Unreleased]`. They fold into this version rather than staying behind it. A released file carries no `[Unreleased]` section, and `release.yml` builds the notes by finding the heading that matches the tag, so an empty section left there fails the release after the tag has already been pushed -- which is one of the three rules this release adds. The reworded no-references bullet is `### Changed` rather than `### Added`. The rule itself does not move and only the reasoning under it does, but that bullet shipped in 0.3.0, so a consumer of that release sees the text in its own `AGENTS.md` change. That is the test an entry has to pass, and it is the same call 0.2.1 made for a wording-only rewrite of the `agentcoop` block.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three rule additions to the shared blocks, cut as 0.3.1 in the same branch.
What lands
workflow/ GitHub issues and PRs — how to recover an issue or pull request body that was overwritten. The block already said how to avoid writing to the wrong one and nothing about what to do once a body had gone anyway. That half is unguessable: GitHub keeps every prior version, but onlyuserContentEditsin the GraphQL API exposes them, and nothing in theghcommand line suggests it exists. The bullet names the query, names--body-fileas the restore, and says not to retype the body from memory.changelog— a released file carries no[Unreleased]section, plus a rewrite of the no-references bullet so its reasoning covers the rule it sits under. The categorical rule was justified entirely byCloses #NandPart of #Nbeing automation keywords, which left a plain reference resting on nothing; the reader argument reaches the whole rule, and the keyword case stays as the sharper one.workflow/ Commit messages — do not build a commit body out of literal\nescapes. They land in the subject as characters, the body comes out empty, and git exits 0, so one mistake breaks three rules of that section at once with no lint downstream that reads commit subjects.Release
Rule additions are MINOR, which shifts down to PATCH below
1.0.0, so 0.3.1. The cut is in this branch rather than a follow-up:## [Unreleased]became## [0.3.1] - 2026-08-12, folding in the drift-warning entries that were already sitting there, and the link reference became a compare range. No[Unreleased]heading or link reference is left behind — which is the rule this release adds.### Changed, not### Added. Its rule does not move and only the reasoning under it does, but the bullet shipped in 0.3.0, so a consumer of that release sees the text in its ownAGENTS.mdchange. Same call 0.2.1 made for theagentcoopwording rewrite.check_release_surface.shhas something to compare and the tag can be cut.Verification
Run on the final tree, all green:
python3 scripts/lint_blocks.py— blocks OK. TheuserContentEditsline is the tight one at 75 of 76 columns.render,apply_blocks,sync,release_surface,lint_blocks,pin_file,check_drift.markdownlint-cli2 "**/*.md"— 0 issues in 9 files.release.yml's notes extraction simulated against0.3.1: 50 lines, non-empty. This is the step that fails after the tag is pushed, so it was worth checking before the tag exists.After merge
Tag
0.3.1by hand, then the README's "Changing a block" step 5 — confirm the pin in all thirteen consumers.Closes #50
Closes #51
Closes #52