fix(ai-slop): fix ten audit-run defects, re-enable rule-em-dash, and purge the corpus - #3988
Open
kyle-sexton wants to merge 89 commits into
Open
fix(ai-slop): fix ten audit-run defects, re-enable rule-em-dash, and purge the corpus#3988kyle-sexton wants to merge 89 commits into
kyle-sexton wants to merge 89 commits into
Conversation
…t declined counts Refs #3987. Detector: the quotation exemption now carries an open double-quoted span across a soft line break; the bare noun "underscore" leaves the default vocabulary; every Summary row splits its declined count by cause (marker, quote, config). Emit script: --from is repeatable and per-rule counts are summed across chunks; the Surfaces section names files scanned, chunk count, whole files declined, and every config-disabled rule. Skill: the pre-computed config block no longer truncates disabled_rules; the rubric pass covers every file in scope and fans out per context/rubric-fanout.md with resumable per-batch result files; the persist doc says to create the guard file with the Write tool; the README says a bare /ai-slop is not a command. Tests cover the wrapped-quote exemption, the split counts, and multi-chunk aggregation. Repo config: em dashes are not this repository's house style, so rule-em-dash runs at its shipped zero-tolerance default and catalog.md leaves excluded_paths; the purge gate's header no longer claims the rule is disabled. Three "in order to" filler hits are fixed in claude-config, claude-ops (an in-place correction to the released 0.42.5 entry, named in 0.45.3), and review, each with its patch bump. The interview Brief that records these decisions is at docs/topics/ai-slop-plugin-scope/PLAN.md. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Refs #3987. Every em dash in the README, both skill bodies, the persist context file, the rewrite guide, and the changelog is rewritten per the rewrite guide, and reflexive uses of "load-bearing" are replaced by the concrete word. The rewrite guide's whole-file ignore marker is removed: its quoted examples are already exempt under the quotation exemption. In-place, wording-only corrections to released changelog entries 0.5.3, 0.5.0, 0.4.1, 0.4.0, 0.3.7, 0.3.4, 0.3.3, 0.3.2, 0.3.1, 0.3.0, 0.2.2, 0.2.1, 0.2.0, and 0.1.0 are named in the 0.6.0 entry. The catalog follows in the next commit. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
… tree purged Refs #3987. The catalog's whole-file ignore marker is removed and its 44 own-prose em dashes are rewritten per the rewrite guide; the one verbatim Wikipedia blockquote that carries the character sits in a block marker with a reason. The changelog's quoted retired step-6 wording moves from a line marker inside the quote to a block marker around it, so no bytes sit inside the quoted span. The persist doc names the disabled= field again beside the split declined counts. plugins/ai-slop is declared in scripts/em-dash-purged-paths.txt, and the purge gate passes with 103 declared paths. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
kyle-sexton
marked this pull request as ready for review
September 8, 2026 22:55
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a7962e6c96
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
4 tasks
Refs #3987, #2891. The maintainer reversed the per-plugin tranche decision after the pull request opened: the whole corpus purge lands in this branch. docs/adr and docs/upstream stay untouched per the purge list's header. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
…arks opening a quote span Review findings on the first push. A lone double quote now opens a carried span only where an opening quote sits (after the line start, whitespace, or an opening bracket, before a non-space character); an inch mark such as 6" or a stray closing quote is dropped so the prose around it stays scanned. A rubric batch result is complete on resume only when its recorded batch digest and file count match the current batch list and every path it names sits in that list, so a leftover result from an earlier scope is redone. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
…d declare the tree purged Every markdown surface under plugins/songwriting passes /ai-slop:audit. Em dashes in the plugin's own prose (README, changelog, agent, skill bodies, the Pat Pattison research and template files, the Suno context, reference, and templates) become a comma, a period, a colon, or a restructured sentence; headings that carried one take the colon form and every in-file link to a renamed anchor follows. Verbatim quotations from the four Pattison books, quoted retired wording inside correction notes, and the fenced worksheet and lyric specimens keep their em dashes inside ignore markers whose reason names the source. Reflexive load-bearing and seam become the concrete word they stood for. Each file was checked by a fresh-context semantic-diff verifier blind to the rewrite rationale, and every flag (semicolons standing in for the dash, markers splitting a list or a quotation, three paraphrased heading citations, one weakened claim, one edited inline-code literal) was fixed before this commit. songwriting 1.4.23 to 1.4.24. In-place wording corrections to 33 released changelog entries are named in the 1.4.24 entry. The purge list declares the whole plugin tree so the gate defends it. Refs #2891 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
… above main's current versions main released claude-config 0.40.41 and claude-ops 0.45.3 after this branch was cut, so the two entries this branch added under those numbers move to 0.40.42 and 0.45.4. Content unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Every released entry in plugins/source-control/CHANGELOG.md is rewritten so the file passes /ai-slop:audit: em dashes become a comma, a period, a colon, or a restructured sentence, and reflexive load-bearing and seam become the concrete thing each stood for (a config key, a gate, a hook contract, a helper). One verbatim quotation of the autonomy plugin's admission-policy wording keeps its em dash inside an ignore marker; backticked literals that carry one are exempt and untouched. Wording only; every entry's facts are unchanged. The version bump, the entry naming the edited sections, and the purge-list declaration follow in the plugin's wave commit. Refs #2891 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Keeps main's claude-config 0.40.41 and claude-ops 0.45.3 entries beside this branch's 0.40.42 and 0.45.4 entries; the manifests take the branch's higher versions. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
The Brief's durable outcomes live on #3987 (the ten plugin defects), on #2891 (the corpus decisions), and in the pull request body; the slice is Contract tier and is pruned per docs/conventions/topic-docs. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
main released claude-config 0.41.0 after the previous merge; this branch's filler-fix entry moves above it as 0.41.1 and the manifest follows. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
…e plugin trees playbooks: every markdown surface passes /ai-slop:audit; 0.9.9 to 0.9.10, with in-place wording corrections to 43 released changelog entries named in the 0.9.10 entry, and the purge list declares the tree. work-items and claude-config: the reference, skill, template, and adapter files rewritten so far (the changelogs and the remaining skill files follow in their area commits, with the version bumps). Refs #2891 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
….9.10 main released playbooks 0.9.10 after this branch's entry was written under that number. Content unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
…ed tree One heading took parentheses for the dash and takes the colon form; a Karpathy quotation's inline marker now names the quotation; a slate example that had lost its meaning reads as the original did; the ambiguity sort's second outcome is relabelled decisive; a released changelog entry's paraphrase is a verbatim quotation of the chapter's current wording again; and four sentences that read machine-written are restated. The babysit-prs contract test now asserts the current wording of the conflict-worker heading its source-control chapter renamed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
…references, the setup and worktree docs, and the audit references source-control: the babysit-prs and babysit-loop references, the commit, pull-request, setup, worktree, and resolve-conflicts docs and templates, and the generated guard contract (regenerated from its generator, whose preamble string is the edit). claude-config: the audit, audit-pass, audit-instructions, and permission-state references. Reflexive seam and load-bearing become the concrete word; defined terms such as the babysit trusted seam stay. Version bumps and the entries naming the edited sections follow in each area's closing commit. Refs #2891 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
…ker contract Every released entry in plugins/work-items/CHANGELOG.md and the work-item-tracker CONTRACT.md pass /ai-slop:audit. Reflexive seam and load-bearing become the concrete word; the tracker seam the contract defines keeps its name. Quoted heading references follow their targets' current wording. Wording only; every entry's facts are unchanged. The bump and the entry naming the edited sections follow in the area's closing commit. Refs #2891 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
main released playbooks 0.9.10 and work-items 0.40.6 after the previous merge; this branch's playbooks entry sits above main's as 0.9.11 and the manifests take the higher versions. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
…umps and purge-list declarations source-control 0.55.72 to 0.55.73 and work-items 0.40.6 to 0.40.7: every markdown surface in each plugin passes /ai-slop:audit, the new entries name the released changelog sections corrected in place (149 and 110), and the purge list declares both trees so the gate defends them. The remaining source-control references (config resolution, review discipline, pull-request create and monitor, setup apply, worktree cleanup, the worktree fixtures README) land here too. Refs #2891 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
…eria reference Refs #2891 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Keeps main's claude-ops 0.45.4 observability fix and renumbers this branch's changelog-correction entry to 0.45.5 above it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
… purges Finishes the em-dash purge for the claude-config plugin: every one of its 47 markdown files now passes the detector, the 0.41.1 entry names the 76 released changelog sections the rewrite touched, and the purge list declares the plugin tree so the gate defends it. Applies the fresh-context verifiers' semantic findings to work-items and claude-config: restores the tracker contract's defined terms `seam verb` and `seam's entry gates`, aligns the Jira adapter heading with its siblings, and repairs four claims a rewrite had weakened or inverted. Adds the one released section missing from the source-control 0.55.73 entry, and drops the last reflexive `load-bearing` from the ai-slop rewrite guide. Gates: purge list at 147 declared paths over 432 files with no em dashes; changelog parity clean in all three modes; markdownlint and typos clean. The affected-tests run is clean apart from a claude-ops process-budget probe that is byte-identical to origin/main and fails only in this sandbox, where the pid-stamped PS4 trace never reaches the traced shell. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Rewrites every em dash in 24 of the 25 files as a comma, a period, a colon where a definition or list follows, or a restructured sentence; the retired-conventions README was already clean. Sweeps reflexive load-bearing and seam for the concrete word each stood for, and keeps the term where the text defines it: the seam-phrasing convention that names it, the shell test helpers' documented public boundary, and the vault and tracker seams the topic-docs contract defines. One changelog entry quoted a heading a later version corrected. The quote is restated as what that entry actually said rather than retargeted to the current heading, which would falsify the record. No convention rule, threshold, key, or default changed. Convention changelog bodies edited for wording only. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Keeps main's claude-ops 0.47.0 (morning-brief REST fallback, changelog read marker) and renumbers this branch's changelog-correction entry to 0.47.1 above it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Rewrites every em dash as a comma, a period, a colon where a definition or list follows, or a restructured sentence, and sweeps reflexive load-bearing and seam for the concrete word each stood for. The extensibility contract's numbered seams, the commit-convention title that a registry row cites, and the seam-phrasing convention that defines the term keep it. Renamed headings drop the doubled anchor separator; no file links to any of the old anchors. No convention rule, threshold, key, or default changed. The standards README is the source that scripts/sync-standards-contract.sh copies into two plugins, so those copies now report drift. The sync, its contract semver bump, and the carrying plugins' bumps land once the units owning those plugins do, so the copies are written once rather than twice. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
…angelogs A de-slop pass rewrote the date separator in convention changelog version headings from an em dash to a comma, turning `## 1.3.0 — 2026-08-15` into `## 1.3.0, 2026-08-15`. That heading is parsed, not prose: check-changelog-parity.sh reads releases with `^##[[:space:]]+\[?<semver>\]?(\(|$|[[:space:]])`, so a comma right after the version stops the heading matching and the gate reports the release as deleted. Ten of these landed in 438e894; the rest were still unstaged. Every version heading now takes the Keep a Changelog form that gate's own header documents, `## [1.3.0] - 2026-08-15`. That parses, carries no em dash, and matches every plugin changelog in the repository. Headings with no version, such as the config-cascade implementers-table rows, keep the comma form because there is nothing to parse. No entry body changed, and no file links to any of these headings by anchor. check-changelog-parity.sh --check-preserved and --check-bump both pass, over 999 headings across 18 changed changelogs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Repairs what the fresh-context verifiers flagged in the earlier purge. The orchestrator, not the resolver, holds the merge decision; the platform gate is decisive rather than merely mattering; a "never say it, check GitHub" absolute that had become a conditional is an absolute again; and the promotion-evidence gate has one name across the changelog, the config-resolution reference, and the babysit-loop body. Splits a comma splice, a colon-spliced disposition line, two doubled connectors, and four repeated "meaning" appositives, and joins a list that dangled from its lead-in. The D-step checklist takes the label-period form in both the canonical review-discipline reference and the pull-request skill body that restates it, so the two no longer disagree. The fenced disposition templates keep the colon and bracket forms the earlier pass gave them, and the gate script, its tests, the classifier, and its tests now cite those forms in their comments; no matcher, regex, or fixture row changed, so the dash form the gate still accepts stays pinned by the rows that test it. Verified: readiness-gate suite 163 cases, babysit-prs suite 702 tests with 298 subtests, contract-clause coverage over 5 canonical surfaces and 16 tagged restatements, purge gate over 432 files, changelog parity across 1020 headings, markdownlint, typos, ruff, and shellcheck. The classifier's three reformatted signatures are the pinned ruff formatter bringing a file that was not format-clean at HEAD into compliance. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Detector-clean and markdownlint-clean at staging time; no shared-copy cluster drifted. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Completes unit 60 across 20 files: the audit skill's README and TODO, its
shared and per-OS references, the Windows check catalog, elevation matrix
and remediation policy, the setup skill body, and 18 released changelog
entries corrected in place and now named in the 0.12.15 entry.
Two things in this plugin are addresses rather than prose, and both were
handled as such:
- The fenced ```markdown block in `reference/shared/report-template.md` is
the live template. `Get-ReportTemplate` extracts it by regex and renders
the actual report from it, so it is the plugin's own output and was
rewritten with everything else. The fence markers and every
`{{placeholder}}` are unchanged, and I re-ran that regex against the
edited file to confirm it still matches and still yields the template.
- Every `## N.` heading in `reference/windows/check-catalog.md` is an anchor
that `catalog/checks.jsonc` `severity_rules` and the check scripts' header
comments point at. None carried an em dash, and none moved.
Declared in `scripts/em-dash-purged-paths.txt`, taking the gate to 250
declared paths over 899 files. `check-shell-portability.test.sh` passes at
345/0, and its baseline lists `check-catalog.md`.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Completes unit 54: the loop-lane prompt template and its claude-code-plugins profile, the cloud-bootstrap paste kit, SECURITY.md, the pull-request template's guidance comment, and one prose line in `.claude/source-control.md`. No config key, value, or literal token moved. The loop-lane files carry an inlined copy of the rate-limit operable floor, registered as `values`-mode consumers by `scripts/check-loop-lane-floor-drift.sh`. This is the fourth synced-content mechanism the campaign has met, after the standards contract, the statusline reference, and the claude-ops report template. Both inlined floor blocks were left byte-identical and only the prose around them changed; `--check` confirms 6 consumers still match the carrier in `plugins/rate-limit-guard/reference/reader-contract.md`, with no unregistered copy. The profile file declares its `3b` block a verbatim render of the template's, so the same rewrite was applied to both and the two blocks re-diffed afterwards: the only differences are the two filled variables, as before. Eight heading anchors changed across the two loop-lane files, each with its in-file table of contents updated in the same pass and no external linker. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Detector-clean and markdownlint-clean at staging time. Both drift gates clean: no cross-plugin cluster desynchronised, and all 6 loop-lane floor consumers still match their carrier. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Completes unit 52 across 23 files, with 21 released changelog entries corrected in place and now named in the 0.18.3 entry. `load-bearing` deliberately survives in three places. It is the name of the dissolve-comments class-C criterion, and `plugin.json` and the README carry that name verbatim, so rewriting it only here would have split one term across three surfaces. `seam` likewise stays where it names the extensibility contract that `docs/MIGRATION-PLAYBOOK.md` defines. The maintainer's decision was to drop reflexive uses, not defined ones, and the distinction is the whole of it. `reference/tidyings.md` moved its numbered headings to the colon form, and `reference/scope-budget.md`'s template line, which quotes one, was updated in the same pass to `"Beck #5: Reading Order"`. Declared in `scripts/em-dash-purged-paths.txt`, taking the gate to 255 declared paths over 927 files. `allowed-tools-pairing.test.sh` passes and changelog parity preserves all 3,522 headings. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Completes units 53, 55, and 56.
**claude-memory** (30 released entries): forty-seven `> — <source>`
attribution lines now render as their own blockquote paragraph after a
blank `>` rather than being rewritten, six of them at a list item's
continuation indent so the list does not end. The bloated-CLAUDE.md eval
fixture holds at 259 lines so eval 12's "more than 200 visible lines"
expectation still fires.
**overengineering** (5 released entries): roughly thirty headings took the
colon or comma form, each with its in-file Contents list updated. The
findings-artifact member-entry template keeps its em dashes on purpose:
there they are field delimiters, and the prose below the fence defines the
parse by counting them ("everything after the second em dash is prose").
Rewriting that would change the artifact's contract, not its wording.
**docs/specs**: five regions keep their em dashes inside markers, because
they quote the measured corpus at revision dff0942 that the committed
harness reproduces byte for byte. Rewriting a quoted corpus sentence would
desync the record from what it measured.
All three trees are declared in `scripts/em-dash-purged-paths.txt`, taking
the gate to 264 declared paths over 976 files, with the reason for each
kept-dash region recorded beside its entry.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Completes unit 58: the reader contract, the cloud and headless capture reference, the setup skill body, the legacy-statusline classification, and 33 released changelog entries corrected in place. The unit disclosed that its final line-rewrap of the changelog was done by a script writing the file directly rather than through Edit, so I checked for content loss rather than taking the self-report. A case-insensitive word-level diff against origin/main shows the only tokens that leave the file are `seam` (4), `load-bearing` (3), and `snapshot-seam` (1), which are exactly the jargon replacements the unit documented, plus a handful of function words from sentence restructuring. The first pass looked worse because it was case-sensitive: `— single-byte` becoming `. Single-byte` reads as a lost word until you account for the capital. `zones-inline-drift.test.sh` grep-pins eleven phrases in the reader contract, among them both token-band rows, the `2.1.132` floor, and the zone vocabulary. Every dash sat outside a pinned span, all eleven are byte-identical, and the suite reports PASS=11 FAIL=0. `rate-limit-guard`'s copy of the statusline reference is declared alongside the canonical one, so the gate now defends both halves of that synced pair rather than only the side a unit happened to own. Gate at 268 declared paths over 984 files. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Completes unit 51 and with it all ten units: the README, the setup skill body, and 88 released changelog entries corrected in place. Two spans keep their em dashes because live code emits or cites the exact text, and I verified both couplings rather than taking the report: - The `[0.28.1]` entry reproduces `_BYPASS_SCOPE_NOTE_BASH` verbatim. `hooks/block-hook-bypass.sh:1572` still emits that string with the dash in it, and `block-hook-bypass.test.sh:1350,1368` pin a substring. Rewriting the transcript would have made the changelog misquote the guard it documents. The suite passes at 642/0. - `## Consumer seams` keeps its name. `hooks/hardcoded-path-check.sh:17` and `hooks/secret-pattern-detection.sh:16` cite that section by name, and the README's own Contents links its anchor. Renaming it to satisfy a jargon finding would have stranded three references to fix one word. Four rubric findings on the README are skipped with reasons rather than half-applied: three ask for structural relocations (a 600-line measurement log, two guard-table cells carrying essays) and the fourth is the heading rename above. Declared in `scripts/em-dash-purged-paths.txt`, taking the gate to 271 declared paths over 989 files. Changelog parity clean in all three modes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Detector-clean and markdownlint-clean at staging time, across instruction-placement, mutation-testing, github, plugin-quality, repo-hygiene, provenance, architecture, testing, discipline, and implementation. All three sync gates clean: no cross-plugin cluster drifted, both standards-contract copies match their source, and `validate-plugin-contracts.mjs` passes over 3,549 plugin files, which covers the six byte-identical `artifact-protocol.md` copies. Plugin close-out lands when the wave reports. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Detector-clean and markdownlint-clean at staging time. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Detector-clean and markdownlint-clean at staging time. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Detector-clean and markdownlint-clean at staging time. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Detector-clean and markdownlint-clean at staging time. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Detector-clean and markdownlint-clean at staging time. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Detector-clean and markdownlint-clean at staging time. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Detector-clean and markdownlint-clean at staging time. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
…orrect Detector-clean and markdownlint-clean at staging time. The github unit flagged that `docs/specs/d1-model-already-knows-measurement.md` quotes the `change-routing.md` line it rewrote, and that the quotation no longer matches. Checked: that row belongs to the 185-row appendix recording the corpus verbatim at pinned revision dff0942, inside an ignore marker, which the committed harness reproduces byte for byte. It is a measurement record, not a live citation, so it must NOT track the source. Updating it would falsify what the measurement measured. Both sweeps agree it needs no action: 0 stale quotations, 0 broken cross-file anchors across 1,515 files. `github.test.sh` passes 36/0, which covers the six recipe headings, the checklist depth floor, and the area-key oracle the unit's rewrites ran through. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
main moved three commits under the branch and the merge came back dirty. Eight conflicts, resolved so both sides survive. **Manifests.** Three plugins conflicted on the description because the purge rewrote a line main also carried. main changed the description in only one of them: skill-quality added a check, twenty-five to twenty-six. Each manifest now takes main's version and main's content with the purge reapplied, so neither the new check nor the rewrite is lost. **Changelogs.** playbooks and skill-quality both gained a release entry on each side. Rather than keep two headings, each plugin's entry is merged under main's version number with both sides' bullets, since the version I had bumped to no longer exists once main published past it. **docs/CATALOG.md** is generated, so it was taken from main and regenerated from the resolved manifests rather than hand-merged. Its line-4 preamble sits above `<!-- catalog:start -->` and is therefore hand- maintained, not generated, so the em dash main reintroduced there was rewritten by hand; the generated block needed no edit. **tier-model.md** took main's side whole: main added the MCP tool-name forms with four-part verification records, and the branch had not touched that passage. **Version renumbering.** `--check-bump` then caught seven plugins: three collisions where the branch and main had claimed the same number, and four whose files this wave changed without a bump. All seven are renumbered strictly above main's current version, and the four gained release entries naming their corrected released sections. Gates after the merge: purge gate 271 paths over 991 files; changelog parity clean in all three modes, 3,647 headings preserved; catalog, cheat sheet, plugin options docs, standards contract and cross-plugin clusters all in sync; markdownlint clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
`changelog-parity-preserved` and `-bump` went red on the merge commit, and the gate named the mistake precisely: relabelling a published heading to a new version absorbs it. Resolving the playbooks and skill-quality changelog conflicts, I merged each pair of entries under one heading and renumbered it. That reads as a tidy resolution and is a deletion: main's published `## [0.10.0]` and `## [0.22.0]` stopped existing, and a released heading may never leave the file. Both are restored with their own notes, and this branch's entry now sits above them as `0.10.1` and `0.22.1`, which is what the manifests already carry. skill-quality's manifest bullet moves up into `0.22.1` rather than being duplicated into the restored `0.22.0`. My earlier local run passed only because it predated the merge commit, so it still compared against the old fork point. Post-merge the base is `18c85c25`, and all four parity modes now pass against it: 3,650 headings preserved, 93 changelogs newest-first with no duplicates. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
…ource Closes out units 65 and 70 and 72 through 80 of the #2891 corpus purge: ai-briefing, education, improvement, markdown-format, playwright, rate-limit-guard, repo-fleet-hygiene, repo-hygiene, skill-quality, toolchain, and verification. Each plugin's markdown is rewritten, its released changelog sections are corrected in place and named in its release entry, and its tree is declared in scripts/em-dash-purged-paths.txt, which now covers 307 paths across 1,078 files. The options-docs generator is the substantive fix. Every plugin README's Options block carried eleven em dashes emitted by scripts/sync-plugin-options-docs.py, and each README silenced them with an ignore marker naming the generator as the real source. That deferral was correct while the generator still emitted them: you fix a generator, not its output. The generator is fixed now, so all 35 READMEs are regenerated and the markers are gone. Those READMEs report zero findings and zero declines, rather than passing on a marker. Changing the block's BEGIN marker would have made split_block miss every README already carrying the old one and splice a second block in, so the script accepts either marker and rewrites in place. LEGACY_BEGIN quotes the old text and keeps its em dash on purpose: it is data the parser matches, not prose, and it is the file's only remaining one. Two surfaces stopped needing an exemption once the code that read them moved with the prose. repo-hygiene's `### git` heading and its report-only bullet separator are now colon-form, and cleanup-paths.test.sh, which passes that heading to extract_section_bullets and strips each bullet's note with an awk substitution, was updated in the same change; its drift contract still compares the same bullets (26 of 26 pass). repo-fleet-hygiene and improvement now say what a signal carries instead of calling it load-bearing, and repo-fleet-hygiene's matching eval moved with its document. Verification: check-purged-em-dashes 307 paths / 1,078 files clean; changelog parity clean in all four modes against 18c85c2 (3,650 headings preserved, 93 changelogs newest-first); sync-plugin-options-docs --check and generate-catalog --check in sync; validate-plugin-contracts clean across 3,563 plugin files; markdownlint clean on every edited file; ruff clean on the generator. Cross-file anchors resolve across all 1,517 tracked markdown files, and the stale-quotation sweep reports none. The only failing suite is cache-content-check.test.sh's process-budget probe, which measures -1 because the pid-stamped PS4 does not reach the traced shell in this sandbox; it fails identically on origin/main and passes in CI. Refs #2891 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Mid-wave snapshot of ten units still running: bugs, codebase-health, context7, coupling, evals, mcp-tools, naming, powershell-format, typos-format, and x. Only context7 has reported complete; the rest are partway through their files. None of these trees is declared in scripts/em-dash-purged-paths.txt yet, so a half-purged file cannot fail the gate. Each plugin is closed out in a later commit, once its agent reports: the version bump, the release entry naming the released sections corrected in place, and the allowlist globs all land together there. Verified on this snapshot: markdownlint clean across all 34 files, every release heading preserved against 18c85c2 (3,848 compared), and all 93 changelogs still newest-first with no duplicate versions. Refs #2891 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Completes the wave the previous commit checkpointed: bugs, codebase-health, context7, coupling, evals, mcp-tools, naming, powershell-format, typos-format, and x. Each plugin now carries its version bump, a release entry naming the released sections corrected in place, and its allowlist globs, so the gate defends 341 paths across 1,132 files. Two templates in codebase-health were cleared for rewrite rather than marked. The plugin ships no scripts at all and each em-dash-bearing template line appears nowhere else in the repository, so nothing parsed the separator; in config-template.md the dashes sat in the preamble's definition list, never in the field markers the config actually reads, which are byte-unchanged. The mcp-tools and bugs eval fixtures were cleared the same way: their dashes sit in descriptive headers, not in the fenced source the audit is graded on, and each evals.json refers to criteria by code rather than by name. One fenced line in bugs keeps its dash, because two expectations pin that string and the fence already exempts it. The seam sweep now distinguishes the two senses rather than applying one rule. coupling keeps the Feathers sense its own coupling-model.md defines, in the published-seam entry and in the list of architectural moves, and loses the reflexive one in the deletion test. guardrails, mcp-tools and bugs lose theirs. The HOOK_TELEMETRY_SINK sentence replicated across seven changelogs now reads "Consumer-side telemetry through HOOK_TELEMETRY_SINK is unaffected" in guardrails, which was already declared purged and so gets no later unit; the six siblings still carrying it have units of their own ahead and take the same wording there. Verification: purge gate 341 paths / 1,132 files clean; changelog parity clean in all four modes against 18c85c2 (3,883 headings preserved, 93 changelogs newest-first); catalog in sync; markdownlint clean on every edited file; 0 broken cross-file anchors across 1,517 files and no stale quotations. The full affected-tests fan-out ran 9,250 assertions with two failing suites, both already documented as pre-existing and both green in CI: cache-content-check.test.sh's process-budget probe, and test_save_point.py::test_new_origin_falls_back_to_directory_name. Refs #2891 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Mid-wave snapshot of ten units: actionlint, bash-format, context-budget, desktop-notification, firecrawl, go-format, kindle-dedrm, prototype, ruff-format, and visualization. bash-format and visualization have reported complete; the rest are partway through. None of these trees is declared in scripts/em-dash-purged-paths.txt yet, so a half-purged file cannot fail the gate. Each plugin is closed out in a later commit with its version bump, the release entry naming the released sections corrected in place, and its allowlist globs. bash-format is the first plugin to take the canonical HOOK_TELEMETRY_SINK wording, "Consumer-side telemetry through HOOK_TELEMETRY_SINK is unaffected", which guardrails already carries. The five siblings that replicate that sentence have units of their own in this wave and take the same wording there, so the fleet converges rather than splitting. Verified on this snapshot: markdownlint clean across all 19 files, every release heading preserved against 18c85c2 (3,883 compared), all 93 changelogs newest-first, and the purge gate still clean at 341 declared paths across 1,132 files. Refs #2891 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
…source Closes out the ten plugins of units 91 through 100: actionlint, bash-format, context-budget, desktop-notification, firecrawl, go-format, kindle-dedrm, prototype, ruff-format, and visualization. Each carries a version bump, a release entry naming the released sections corrected in place, and its tree declared in scripts/em-dash-purged-paths.txt, now at 366 paths across 1,167 files. Two more generators are fixed at the source rather than in their output, the same class as the options-docs fix. firecrawl's skills/update/scripts/update.sh writes UPSTREAM.md from a heredoc that still carried two em dashes, so the next --apply would have undone the purge of its own output; the heredoc now matches the committed file byte for byte, making a re-run a no-op. context-budget's measure.mjs emitted a caveats string calling the cli-parse rung load-bearing while reference/engine.md had already been rewritten; both now read "so this rung depends on unsanctioned behavior", so the record and the reference describe the evidence the same way. Every released-section list in these entries was recomputed from the diff against the base ref rather than copied from a worker's report. That caught one wrong version (go-format reported 0.3.4, the diff says 0.3.3) and supplied kindle-dedrm's list, whose worker did not survive to report. Verification: check-purged-em-dashes 366 paths / 1,167 files clean; changelog parity clean in --check, --check-preserved (3,908 headings against 18c85c2) and --check-order; markdownlint clean on all 13 changed markdown files; shellcheck clean on the firecrawl generator; measure.mjs parses and both context-budget suites pass (90 of 90, 3 of 3); cleanup-paths drift contract 26 of 26. --check-bump is red against origin/main, which moved three commits while this wave ran. That is the next commit's work, not a defect in this one. Refs #2891 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Main moved three commits (#4058, #4023, #4072) across 88 files while units 91 through 100 ran, producing 37 conflicts. Every one is resolved additively: no published `## [x.y.z]` heading is deleted, relabelled, or absorbed, and no content main added is dropped. Thirteen manifests conflicted on version alone, with every description identical on both sides, so each keeps this branch's purged description and takes a version one patch above main's: bugs 0.10.1, claude-config 0.42.1, claude-ops 0.48.1, code-tidying 0.19.1, context-budget 0.6.27, evals 0.2.4, improvement 0.1.12, playbooks 0.11.1, prototype 0.11.1, review 0.28.1, skill-quality 0.22.2, testing 0.8.1, visualization 0.6.1. guardrails 0.33.2 and claude-memory 0.12.2 collided without conflicting and were renumbered the same way. The changelogs took two shapes. Where both sides opened a new heading, the markers alone were stripped and this branch's heading renumbered, so main's entry survives untouched below it. Where both sides wrote under the SAME heading, main claimed that number first: main's bullets keep it and this branch's move to a new heading above. evals auto-merged into two `## [0.2.3]` entries and was renumbered the same way. Four content files took main's new material with its em dashes rewritten: PLUGIN-PHILOSOPHY's deliberation citation, plugin-data-report-keying's physical-working-directory clarification, the bugs scan lens's out-of-lane hop, and claude-ops's cache-diagnostics routing row. Three larger files were restored from one side and reconciled against the other rather than spliced by hand, which is what kept main's work intact: bugs findings-report took main's file and was re-purged (all 14 of its sections verified present), while decision-matrix and the native-references convention took this branch's purged file and had main's changes applied onto it (main's 10 adopter rows and every new section verified present). records.json keeps main's newer verification dates and added evidence with the dashes rewritten, and NATIVE-SURFACES.md was regenerated from it; its hand-maintained preamble, which regeneration does not touch, was re-purged by hand. Verification against the new base: check-purged-em-dashes 366 paths / 1,172 files clean; changelog parity clean in --check, --check-bump, --check-preserved (3,908 headings) and --check-order; catalog, plugin-options docs and the native-surfaces registry all in sync; validate-plugin-contracts clean across 3,573 files; markdownlint clean on every file touched here; no conflict marker survives anywhere in the tree. Refs #2891 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Units 101 through 109 are in flight; this captures what is complete and coherent so far, including units 106 through 109 in full (miro, wizard, debugging, domain-driven-design). Every file here is detector-clean and markdownlint-clean; the plugins are not closed out yet, so no version bump, release entry, or allowlist glob lands with this commit. docs/SKILL-CHEAT-SHEET.md is regenerated. domain-driven-design's `curate-language` summary renders into it, so rewriting that summary made the sheet stale by exactly one row; the worker reported the drift and left the sheet alone, and the regeneration happens here so source and generated output land together. The summary took the period form rather than a colon because `summary:` is an unquoted YAML scalar and a colon plus space would break the parse. The sheet now carries no em dash at all. Refs #2891 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
The nine plugins of the final wave are closed out: adhd, biome-format, computer-use, debugging, domain-driven-design, dometrain, eol-normalizer, miro, and wizard. Each carries a version bump, a release entry naming the released sections corrected in place, and its tree declared in scripts/em-dash-purged-paths.txt, now 383 paths across 1,194 files. This completes units 1 through 109, the whole partition built from the baseline detector run. Every released-section list here was recomputed from the diff against the base ref rather than copied from a worker's report; all nine matched. Three surfaces keep a word the sweep would otherwise have taken, each because the surrounding text makes it a name rather than a reflex. debugging's 0.7.4 entry keeps `load-bearing`: it identifies which paragraph that release removed, and the same name is still live in the plugin's evals and README, so rewriting it would leave a reader unable to tell what was removed. wizard's 0.2.5 entry keeps `seam`, which the same sentence defines as the single `exec 3</dev/tty` open its suite pins. dometrain keeps two published Dometrain titles byte-identical in a citation example, rewriting only the separator and the prose around them, because a citation that alters a title stops matching what it cites. computer-use also gained a mechanism where it had none: "The allowlist gate catches it safely every time" named no check and no observable, and now states that the gate refuses the action with the "not in the allowed applications" error instead of sending it to the wrong app. Verification: check-purged-em-dashes 383 paths / 1,194 files clean; changelog parity clean in all four modes against the new base 5cba274 (3,938 headings preserved, 93 changelogs newest-first); catalog, cheat sheet and plugin-options docs all in sync; validate-plugin-contracts clean across 3,573 files; markdownlint clean on every changed file; cross-file anchors resolve across all 1,529 tracked markdown files and the stale-quotation sweep reports none. Refs #2891 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
10 tasks
The lint lane failed on 360a7fe with 13 MD032 and 13 MD022 violations, one pair in each of the thirteen changelogs whose merge conflict I resolved by stripping the marker lines with sed. Removing `<<<<<<< HEAD`, `=======` and `>>>>>>> origin/main` also removed the only blank line between the end of this branch's bullet list and main's `## [x.y.z]` heading below it, so the list ran straight into the heading. This adds the blank line back: thirteen insertions, no other change, confirmed by a diff carrying no non-blank added or removed line. The miss was in how I verified the merge, not in the resolution. I ran markdownlint over a hand-picked list of the files I had resolved by hand and not over every conflicted file, so the thirteen resolved by sed were never linted. This commit was verified the other way: markdownlint over all 1,010 markdown files this branch changes against origin/main, which reports 0 issues. No heading moved. Changelog parity still preserves all 3,938 headings and reports 93 changelogs newest-first, and the purge gate is unchanged at 383 paths across 1,194 files. Refs #2891 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Second merge of main into the corpus purge. 38 conflicts, all additive-resolution: neither side's content is dropped. Manifests (21). Thirteen collided on version alone: keep this branch's purged description and bump one above main's current version. Seven that auto-merged still needed a bump, because main moved their version after this branch last set one. `architecture` was the exception: main changed its description to add real capability (committing the landscape record so later runs check for drift), so main's text is taken and re-purged rather than this branch's kept. Changelogs (21). Twenty are the same shape: both sides wrote under a heading main claimed first, so main's bullets keep that heading and this branch's move to a new heading above it. `architecture` is the other shape, both sides adding a distinct new heading. Every `## [x.y.z]` heading main carried at c41c642 is verified present after the merge. Content (2). `claude-ops` observability data-sources and plugins gotchas take main's substantive changes (the `slog_event_record_to` authority, the `hook::normalize_path_to` rename) re-purged, keeping this branch's punctuation. Generated (1). `docs/CATALOG.md` regenerated from main's version; its preamble sits above the marker and is hand-maintained, so its em dash was fixed by hand. Four purge-gate regressions from main's new prose inside already-declared paths are fixed: docs/conventions/hook-telemetry/README.md and the claude-ops observability data-sources context file. Validation: changelog parity (--check, --check-order, --check-bump, --check-preserved) plus an explicit check that no heading main carried was lost; catalog, cheat-sheet, plugin-options and native-surfaces --check gates; plugin contracts; the purge gate at 383 declared paths over 1194 files; and markdownlint over all 1010 changed markdown files, not a subset. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
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.
Closes #3987
Summary
Two pieces of work land together here, because the second is what the first
asked for.
The audit-run defects (#3987). A repo-wide
/ai-slop:auditrun surfaced tendefects in the
ai-slopplugin and a contradiction in this repository's ownconfig, which had disabled the em-dash rule as "house style". Em dashes are not
this repository's house style, so the rule is re-enabled and the plugin's own
tree becomes the first surface that passes the rule it ships. Decisions were
reached in an interview with the maintainer and recorded in
docs/topics/ai-slop-plugin-scope/PLAN.md.The corpus purge (#2891). Re-enabling the rule turned 25,558 findings across
1,003 files from a policy question into a backlog. The maintainer's call was that
the whole purge lands in this pull request rather than one per plugin, so it does.
The campaign runs surface by surface: each plugin's markdown is rewritten, its
manifest description cleaned, its released changelog entries corrected in place
and named in a new release entry, and its tree declared in
scripts/em-dash-purged-paths.txtso the gate defends it from that moment on.Every rewrite follows
plugins/ai-slop/skills/audit/reference/rewrite-guide.md:an em dash becomes a comma, a period, a colon where a definition or list follows,
or a restructured sentence. Never parentheses, never an en dash, never a spaced
hyphen, never a semicolon. Verbatim third-party quotations keep their dashes
inside an ignore marker naming what is quoted; the repository's own prose is
never fenced to silence a finding.
Fix
Plugin (ai-slop 0.5.13 to 0.6.0)
detect.sh: the quotation exemption carries an open double-quoted span across asoft line break (the plugin's own CHANGELOG produced two false
rule-challenges-conclusionfindings without this); the bare noununderscoreleaves the default vocabulary; every
Summaryrow splitsdeclined=intodeclined_marker,declined_quote,declined_config.emit-findings.sh:--fromis repeatable and per-rule counts are summed acrosschunks (the old script kept the last chunk's counts and called a rule "no
result" if any chunk had zero);
## Surfacesnow states files scanned, chunkcount, whole files declined, and every config-disabled rule.
SKILL.md: the pre-computed config block no longer truncatesdisabled_rulesand
rule_allowed_paths(head -8cut them off); the rubric pass covers everyfile in scope and fans out per the new
context/rubric-fanout.mdwith resumableper-batch result files.
persist-findings.md: the guard file is created with the Write tool (theguardrails hook blocks a shell redirect); the Surfaces description matches the
script.
/ai-slop:auditas the invocation; a bare/ai-slopis not acommand.
catalog.mdandrewrite-guide.mdare removed: the quotation exemption alreadycovers their examples.
Repository config and gates
.claude/ai-slop.json:rule-em-dashleavesdisabled_rules;catalog.mdleaves
excluded_paths(46 of its 47 em-dash lines were its own prose); thecomment states the current rule and its reason. Curly-quote and emoji rules stay
disabled on their owner rulings; vendor trees and eval fixtures stay excluded,
and those two exclusions are the only ones kept.
scripts/em-dash-purged-paths.txtgrows with the campaign, from 103 declaredpaths at the first commit to 383 covering 1,194 files. A glob
matching nothing fails the gate, so a declaration cannot outlive the surface it
names.
.claude/rules/vendor-docs-are-not-style.md: vendored upstream docs arereference material, not a style precedent for this repository's own instruction
surfaces.
Corpus surfaces purged, and what is left
The campaign is complete. All 77 plugins are declared, alongside the convention
documents under
docs/conventions/, the specifications underdocs/specs/, theroot-level instruction surfaces, and every plugin manifest in the marketplace.
docs/CATALOG.mdanddocs/SKILL-CHEAT-SHEET.mdboth report zero em-dashfindings, which is the proof that no manifest description and no skill summary
still carries one.
A repo-wide detector run over every tracked markdown file now reports 817
findings in 36 files, down from 25,558 in 1,003. Every one of the 36 sits in an
exclusion this repository recorded before the campaign began, and nothing is
unaccounted for:
docs/adr/**anddocs/upstream/**, whichscripts/em-dash-purged-paths.txthas declared out of scope since before thisbranch: decision records are a historical account rather than prose to
restyle, and the upstream tree is third-party text under the repository's own
vendor-docs-are-not-style rule.
standards-contract: the convention and itstwo byte-identical plugin copies, explained below.
Generated artifacts and the files that feed them
A file another artifact is generated from, or that a gate parses, is not just
prose. Four such surfaces were fixed at the source rather than in the output:
scripts/generate-catalog.mjs(the row separator) anddocs/CATALOG.mdregenerated.
plugins/claude-ops/skills/audit-native-overlap/scripts/overlap.py(the viewheader, the empty-verdict placeholder, and three row templates),
docs/native-surfaces/records.json, anddocs/NATIVE-SURFACES.mdregenerated.test_overlap.pyasserted the old header wording and was updated in the samepass.
userConfigdescriptions, with each plugin README's"Options reference" table regenerated by
scripts/sync-plugin-options-docs.py.extract-ssotcitation contract prescribed an em dash as its citationseparator. It now prescribes a colon, so the template no longer emits the
character this repository has purged.
docs/conventions/standards/README.mdis deliberately NOT purged and is excludedby name: it carries a
standards-contractsemver, and changing one character ofit forces a version bump that makes every consuming repository's index mismatch,
degrading skills to best-effort routing until each one re-runs setup. Thirty-nine
lines of punctuation are not worth that migration.
Anchors
Renaming a heading that carried an em dash changes its anchor. Every cross-file
anchor in the repository resolves:
check-anchors.pyreports 0 broken across all1,529 tracked markdown files, including three links to the
upstream-driftconvention's fetch-route heading that lost its doubled separator.
Verification
plugins/ai-slop/skills/audit/scripts/detect.test.sh: all 216 cases pass,including new cases for the wrapped-quote exemption, the noun
underscore, thesplit declined counts, and multi-chunk aggregation.
scripts/check-purged-em-dashes.sh: 383 declared paths, 1,194 files scanned, noem dashes.
scripts/check-changelog-parity.shin--check,--check-bump origin/main,and
--check-preserved origin/mainmodes: clean. All 88 changed changelogspreserve every version heading they carried at the base ref (3,938 headings
compared).
node scripts/generate-catalog.mjs --check,node scripts/generate-cheatsheet.mjs --check,overlap.py generate --check, andpython3 scripts/sync-plugin-options-docs.py --check: all in sync.scripts/affected-tests.sh --runon each shard of the work, and twice over thefull selection after the second
origin/mainmerge. Four suites fail in thiscontainer and none of them belongs to this branch: every hook, test, and harness
file involved is byte-identical to
origin/main. Two fail on every run,test_save_point.py::test_new_origin_falls_back_to_directory_nameandcache-content-check.test.sh's process-budget probe, which measures-1because the pid-stamped
PS4does not reach the traced shell in this sandbox.Two more rotate between runs, which is what marks them as container artifacts
rather than defects.
block-noncanonical-commit.test.shreported 43 failures onthe first run and none on the second; every one was a blocked case returning the
allow status while every allowed case passed, the signature of the guard's
documented fail-open posture, and the suite passes standalone at 239 of 239 over
four separate runs.
session-event-log.test.shreported 33 parallel fireswriting 32 lines on the second run and none on the first, a lost-write race in
the shared empty-guard heal that this branch does not touch. All four pass in
CI:
lint, all fourtest-linuxshards,test-windows,hook-utils, andci-statusare green on the merge head.markdownlint-cli2clean on every edited file; shellcheck, shfmt, and typosclean on the edited scripts.
rewrite rationale, and the flags it raised were fixed before the area landed.
Related
🤖 Generated with Claude Code
https://claude.ai/code/session_011o8Akf3vwDEHy5ATnB1RwF
Generated by Claude Code