Skip to content

Recast the banned constructions in README.md - #504

Merged
ptr727 merged 6 commits into
developfrom
feature/readme-prose-sweep
Aug 1, 2026
Merged

Recast the banned constructions in README.md#504
ptr727 merged 6 commits into
developfrom
feature/readme-prose-sweep

Conversation

@ptr727

@ptr727 ptr727 commented Aug 1, 2026

Copy link
Copy Markdown
Owner

The README.md entry from TODO.md. It was deferred rather than dropped because two edits to that file were in flight, and both have since landed, so it is now free to take.

Stacked on #503, which also edits the TODO.md entry this PR removes. Merge #503 first and GitHub retargets this to develop automatically. Branching from develop instead would have conflicted on that line for no gain.

Result

12 findings gone: 6 dash and 6 semicolon, both constructions GOVERNANCE bans in agent-authored prose.

before:  dash 6,  semicolon 6   (12)
after:   0

Each was recast the way the rule prescribes: a spaced hyphen becomes a comma, a preposition, or a subordinate clause, and a prose semicolon becomes a comma or two sentences. No content changed, only its construction.

Two worth naming

The Source Code and Versioned Releases bullets read - **Label**: [link] - explanation. That is not the - **Label** - explanation separator the dash rule exempts, because the label already ends in a colon, so the dash was a genuine clause break rather than structural punctuation. Both now read [link] for explanation.

The Python bullet carried both faults in a single line:

- Configure ruff and a type checker in `pyproject.toml` - pyright strict, or mypy in CI with pyright editor-only; whichever runs in CI is the gate.

It splits into two sentences, which resolves the dash and the semicolon together.

Verification

prose_lint README.md  (dash, semicolon, charset, charset-unknown, dupword, spelling, sentence-split)   clean
prose_lint TODO.md    (same set)                                                                       clean
prose_lint . --diff HEAD                        clean, all default rules
markdownlint-cli2 (docker, README + TODO)       0 issues
cspell (docker, README + TODO)                  0 issues
python3 scripts/test_prose_lint.py              144 tests, OK
python3 spec/validate.py                        OK, 21 cataloged

markdownlint and cspell were run because CI gates README.md with both, and this PR rewrites sentences rather than only comments.

🤖 Generated with Claude Code

ptr727 and others added 3 commits August 1, 2026 07:13
`.editorconfig` and `.gitattributes` are the first files an onboarding repo
carries, so until their comments follow the rules a new repo learns the shape
the rules forbid. Both are `intent` fidelity, so a downstream copy is adapted
rather than byte-matched and no re-vendor follows.

36 findings are gone, 22 in `.editorconfig` and 14 in `.gitattributes`.
`.gitignore` was already clean, so the 44 counted in `TODO.md` was stale.

Wrapped prose became one sentence per line. Two bare commands in
`.gitattributes` gained a label (`Inspect with: git ls-files --eol`) rather
than an exemption, since relabeling a command reads better where relabeling a
URI would corrupt it. Comments opening on `git` or `uv` were restructured, not
capitalized, per the tooling-casing rule.

A mid-sentence semicolon and several spaced hyphens went with them, both
banned in agent-authored prose and invisible here because those two rules are
markdown-only.

No setting or pattern changed: every non-comment line in both files is
byte-identical, and `repo_gate`'s eol check still cross-validates them.

`TODO.md` drops the two swept entries and records the fleet re-vendor that the
`configure.sh` sweep in #501 now obliges.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot found three comments where the rewrite satisfied the linter at the
cost of reading well, which is the failure a sweep is supposed to avoid. A
fourth had the same fault and was found by re-reading the rest.

- "keep it LF and a copied snippet runs, where a CRLF shebang breaks" splits
  into two sentences.
- "being the PreToolUse hook and its installer" becomes "namely".
- "reds on every `uv lock`" becomes "fails". That word was inherited rather
  than introduced, and rewriting the line was the moment to drop it.
- "There git stays passive" becomes "For those, git stays passive". The
  awkward fronting existed only to dodge a lowercase opening.

Also gates the class this work belongs to. GOVERNANCE puts verbatim content
on the hub, because a downstream copy is byte-matched and cannot be corrected
locally. Nothing enforced that, so the sweep could silently regress.

`TestCarriedContent` reads the `verbatim` entries live from spec/files.json
and asserts every one is comment-clean, with two guards so it cannot pass
vacuously: the manifest must still declare verbatim content, and every
declared file must exist. Confirmed to fail by reintroducing a wrapped
comment in configure.sh.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The `README.md` entry from `TODO.md`, 12 findings: 6 spaced hyphens and 6
prose semicolons, both banned in agent-authored prose. It was deferred
because two edits to the file were in flight, and both have since landed.

The spaced hyphens become a comma, a preposition, or a subordinate clause,
and the semicolons become a comma or two sentences, which is what GOVERNANCE
prescribes in each case.

Two are worth naming. The bullets under Source Code and Versioned Releases
used `[link] - explanation`, which is not the `- **Label** - explanation`
separator the rule exempts, so the dash was a real clause break and now reads
`[link] for explanation`. The Python bullet carried both faults in one line
and splits into two sentences.

Nothing about the content changed, only its construction.

`TODO.md` drops the entry.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 1, 2026 14:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the repository’s prose backlogs and README to comply with GOVERNANCE bans on specific prose constructions, while keeping the intended meaning unchanged.

Changes:

  • Removes the completed README prose-sweep entry from TODO.md.
  • Rewords multiple README.md bullets to eliminate the banned spaced-hyphen clause breaks and semicolon usage.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
TODO.md Drops the now-completed README prose-sweep backlog item.
README.md Recasts bullets/sentences to remove banned dash/semicolon constructions while preserving meaning.

ptr727 and others added 2 commits August 1, 2026 07:43
spec/secrets.json declares only the Actions and Dependabot stores, so a repo
that deploys somewhere has no declared way to state what it needs at runtime.
The required set is then discoverable only by reading the deploy.

Two shapes of the answer already run in the fleet. HomeAutomation-Config keeps
a gitignored secrets directory of env files and Docker secret files, and
ESPHome-Config keeps a gitignored secrets.yaml beside a committed
_secrets.yaml. The committed file carries the required names with dummy
values, which is the same split the GitHub side already gets from
requiredSecrets[].

Blog needs it immediately, since it deploys on the proxmox host through
HomeAutomation-Config's Docker Compose stack and carries the copy
destinations and the internal URI.

Recorded rather than designed: the hub carries neither the directory nor a
.gitignore entry for one today, so adopting it here comes before making it a
fleet standard.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Standing up a new repo pre-creates main and develop, which is right, and then
commits onto develop, which is not. The initial commits belong on a feature
branch that reaches develop by squash.

The two reasons do not carry equally, which is the part worth documenting.
A release repo's develop.json carries a pull_request rule, so a direct commit
is blocked and the agent learns the rule by hitting it. An operational repo's
payload carries only deletion, non_fast_forward and required_signatures, so a
direct commit succeeds and nothing corrects it.

The reason holding for both is that the squash collapses the exploratory
onboarding history, where PII, secrets and noise accumulate, and a public repo
gates on that history. There is no recovery afterwards: non_fast_forward is
set on both develop payloads, so what reaches develop cannot be rewritten.

Blog hit this during its standup and moved to a feature branch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ptr727
ptr727 deleted the branch develop August 1, 2026 14:50
@ptr727 ptr727 closed this Aug 1, 2026
Forward-merge to pick up the dotfile sweep and to trigger the validation
workflow, which never ran while this PR was based on a feature branch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

# Conflicts:
#	TODO.md
@ptr727 ptr727 reopened this Aug 1, 2026
@ptr727
ptr727 changed the base branch from feature/dotfile-comment-shape to develop August 1, 2026 14:52
@ptr727 ptr727 closed this Aug 1, 2026
@ptr727 ptr727 reopened this Aug 1, 2026
@ptr727
ptr727 requested a review from Copilot August 1, 2026 14:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

@ptr727
ptr727 merged commit d1c682d into develop Aug 1, 2026
11 checks passed
@ptr727
ptr727 deleted the feature/readme-prose-sweep branch August 1, 2026 14:56
ptr727 added a commit that referenced this pull request Aug 1, 2026
…anup (#506)

Replaces the onboarding-branch entry added in #504 with the sequence
Pieter proposed after watching `Blog` hit the problem.

## What changed and why

The #504 entry said the initial commits belong on a feature branch and
reach `develop` by squash. That is correct, but it still treats `main`
and `develop` as branches an agent might commit onto and then have to
clean up. `Blog` tried to squash its standup work back onto the `main`
and `develop` it had already committed to, and **was blocked**, which is
the ruleset doing its job.

The proposed sequence removes the problem rather than managing it:

1. Create `main`, carrying nothing.
2. Create `develop` from `main`, carrying nothing.
3. Create the first feature branch from `develop` and do the **whole**
standup there.
4. Add the repo to GitHub and apply the repo config while still on that
branch.
5. Open a normal pull request to `develop` when the repo is ready.

Nothing ever has to be cleaned off `main` or `develop`, because nothing
ever reached them without review.

## Two details the write-up would otherwise get wrong

**A git branch cannot exist without a commit.** "Carrying nothing"
therefore means exactly one signed empty root commit (`git commit
--allow-empty`), not a literally empty ref. Section 0's signing window
applies to that commit like any other, so it has to be signed before it
is made.

**Squashing afterwards is not an escape hatch.** `non_fast_forward` is
set on **both** `develop` payloads, so once history reaches `develop` it
cannot be rewritten without disabling the ruleset. That is why `Blog`
was blocked rather than merely inconvenienced.

## The gap this fills

`STANDUP.md` says nothing about how `main` and `develop` come into
being. Section 0 covers signing before the first commit, section 0A
covers the human-gated prerequisites, and section 2 covers carrying the
baseline files, but the branch bootstrap between them is undocumented.
An agent with no instruction commits onto whichever branch it finds
itself on.

Worth noting the protection is **uneven**, which the entry records:

| Payload | Rules | Direct commit to `develop` |
| --- | --- | --- |
| `repo-config/develop.json` (release) | adds `pull_request`,
`required_linear_history`, `required_status_checks`,
`copilot_code_review` | blocked |
| `repo-config/operational/develop.json` | `deletion`,
`non_fast_forward`, `required_signatures` only | **succeeds** |

On an operational repo the ruleset alone would not stop a direct commit,
so only the instruction stands between it and an unfixable history. That
is the argument for documenting the sequence rather than relying on the
gate.

**Correction, after this PR was opened:** `Blog` is `release`, not
`operational`. I had classified it wrongly, and Pieter corrected it. The
test is where the config lives, since `operational` is for config that
sits on the actual server, and Blog builds and pushes releases out
instead. So Blog's own `develop` *is* PR-gated and the ruleset does
block it. That strengthens the entry rather than weakening it: the
uneven-protection point stands for every genuinely operational repo, and
the bootstrap sequence is what keeps `main` and `develop` clean in both
models.

The reason it matters on a public repo: the exploratory standup history
is where PII, secrets and noise commits accumulate, and squashing a
feature branch is the one chance to leave them out.

## Verification

```
prose_lint TODO.md  (dash, semicolon, charset, charset-unknown, dupword, spelling, sentence-split)   clean
prose_lint . --check charset --check dupword --check spelling                                        clean
markdownlint-cli2 (docker)    0 issues
cspell (docker)               0 issues
```

`cspell` rejected "unreviewed" on the first pass. Rephrased rather than
adding a word to `cspell.json`, since one entry's worth of dictionary
growth is not worth a phrasing that had an ordinary alternative.

Backlog only. The `STANDUP.md` change itself is the work this entry
describes, not this PR.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
ptr727 added a commit that referenced this pull request Aug 1, 2026
… the carried-file corrections to main (#517)

Promotes twelve commits to `main`. Three of them change **carried**
files, so downstream repos read the stale text until this lands, which
is what makes the promotion the delivery step rather than bookkeeping.

## What this delivers to the fleet

**Carried-file corrections**, picked up by every repo on its next
re-vendor:

| PR | File | Correction |
| --- | --- | --- |
| #514 | `.github/copilot-instructions.md` | Described the pre-split
`AGENTS.md`, wrong in both halves. `GOVERNANCE.md` holds the rule
sections and the two `intent` ones; `AGENTS.md` carries two verbatim
sections and none repo-specific |
| #514 | `CODESTYLE.md` | Said MD033 flags HTML elements while the
config allows `details` and `summary`; also gains the `HISTORY.md`
mirror rule, moved from a hub-only spec file so a repo can read the rule
it is graded against |
| #514 | `WORKFLOW.md` | D2.2 "skipped on smoke" read as the job rather
than the validation, and a review acting on it proposed a change that
would have coupled the release to smoke |
| #503 | `.editorconfig`, `.gitattributes` | 36 comment findings in the
files a new repo copies first |
| #501 (earlier) | `repo-config/configure.sh` | Already on `main` |

**Spec and requirement changes**:

- **#507** makes `OPERATIONS.md` `appliesTo: "*"`, keyed to the need
rather than to `workflowModel`. Measured: 3 of 21 repos carry it, so
**17 will report a new `LETTER file:` finding**. Intended, and a headed
stub satisfies it.
- **#512** declares `.github/workflows/merge-bot-pull-request.yml` at
`interface` fidelity, closing a graded contract (`WORKFLOW.md` D8.1)
that no spec required. 15 of 21 already carry it, so this ratifies a de
facto standard; the other **6 report a new `DRIFT`**, and those six have
Dependabot pull requests piling up with nothing to merge them.
- **#505** stops the audit flagging the hub against itself and drops a
premise that was false since this repo went public.
- **#511** fixes the README shape across repository visibility.
- **#515** puts audit-report authorship with the hub and names the base
branch, after a downstream conformance PR targeted `main` and I merged
it without checking.
- **#513** forward-ports that PR's content, restoring the forward-only
invariant.

**Backlog and reports**: #504, #506, #510, #516 record the README shape
rework, the branch-bootstrap step, the declared-description design, and
why the audit is on demand.

## Fleet consequence, stated before it lands

Two owed follow-ups this promotion creates or carries:

1. **Re-vendor `repo-config/configure.sh`**, already owed from #501,
since it is `verbatim` with `appliesTo: "*"` and every repo holding a
copy is byte-mismatched.
2. **The next fleet audit reads noisier**, by 17 `OPERATIONS.md` letters
and 6 merge-bot drifts. Both are new requirements rather than repo
regressions.

## Verification

Run on `develop` at `e4c76bc`:

```
python3 scripts/test_prose_lint.py     144 tests, OK
python3 scripts/test_repo_gate.py       23 tests, OK
python3 scripts/test_pr_review.py       27 tests, OK
python3 spec/audit.py --selftest        SELFTEST PASS
python3 scripts/repo_gate.py            eol 0, sha-pin 0
python3 spec/validate.py                OK, 21 cataloged
prose_lint --check charset --check dupword --check spelling    clean
editorconfig-checker (docker, canonical)                       clean
```

Every one of the twelve was merged green with a Copilot review covering
its head SHA.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants