Cut the comments back, rebuild docs/, and make both checkable - #69
Merged
Conversation
Docblocks carried long explanations of why the code is the way it is: what core does and why that forced a choice, what was tried before, which decision a rule came from. That reasoning belongs in the docs, which already hold it; in the source it was 26% of every non-blank line and it went stale silently. Every docblock is now its short description plus @param/@return/@var. Inline comments are gone. Comment lines: 10,395 -> 6,495. Left alone, because something reads them: the plugin header and the theme patterns' own headers, which WordPress parses (reducing one deregisters the plugin or the pattern); phpcs:ignore annotations; translators: notes that WPCS requires; eslint directives; and one warning in the cloud porter -- "Never trust the wire, even our own service" -- which guards a re-sanitize somebody could otherwise read as redundant. Comments were located with PHP's own tokenizer and with Babel rather than by pattern-matching, so a "//" inside a string or a regex was never mistaken for one. To confirm nothing else moved, every changed file had all comments stripped from both its old and new version and the remaining code compared. Four differ, all of them the repo's own formatters run afterwards: eslint's curly rule adding braces, prettier unwrapping two method chains whose parentheses only existed because comments split them, one empty catch block collapsing to catch {}, and two CSS comments inside an inline <style> removed by hand, which the PHP tokenizer does not see. Safe_Css is vendored byte-for-byte into patternbuilderwp.com; both copies got the same treatment and their bodies remain identical line for line. phpcs is down to the one pre-existing i18n error, lint:js from 41 errors to the 7 pre-existing no-unused-vars, lint:css clean, 104 JS unit tests green, and 425/426 PHP tests -- the one failure being the media-pipeline test that already fails in this sandbox. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KtSTgGTH5hSBWVLPCJohhi
Nine one-line comments where the code looks arbitrary or redundant and getting it wrong fails silently: the theme root without which WP_Theme_JSON_Resolver hands back a theme with every preset emptied; the `$post` global core/post-content reads instead of its context; the mirror rows that are the only ID -> slug map, read before anything deletes them; the array wp_handle_sideload() takes by reference; the variable-font weight whose space would be escaped in every URL naming the file; the theme.json cache that is stale after a write; `late_route_registration`; the annotations that select an ability's HTTP method; and why constrain() is passed a mime type rather than sniffing one. Each is guarded by a test, so the bug never ships; what the comment buys back is the diagnosis. docs/ is rebuilt around what exists now: - The 1.x deep dive, self-labelled HISTORICAL and describing the DB mirror and REST hijacking that 2.0 removed, is deleted. - architecture-2.0.md is promoted to architecture.md and brought current. It had gone stale in two places: the browse grid draws its tiles on the server now, and the Site Editor's canvas is never used, not even for the user patterns it could host. - abilities.md and cloud.md are new, and are where most of CLAUDE.md's bulk now lives. - collections.md and dependencies.md lose their "Order of work" and "Acceptance" sections, which planned work that shipped, and their before-and-after framing. dependencies.md named an `export_tree()` that was never built; the walk is `local_tree()` + `rewrite_references()`. CLAUDE.md goes from 10,987 words to 942: what this is, where the detail lives, the commands, the invariants that bite, the standards. readme.md drops the marketing copy and the use cases for what the plugin is, how to run it, and where to read. Every code identifier the docs name was checked against the source. phpcs is at the one pre-existing i18n error, lint:js at the 7 pre-existing no-unused-vars, lint:css clean, 104 JS tests green, and 425/426 PHP -- the failure being the media-pipeline test that already fails here. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KtSTgGTH5hSBWVLPCJohhi
Both repositories already said "docs/ is living", and both had drifted anyway: a Cloud_Client class that never existed, an export_tree() that was never built, a taxonomy renamed two releases ago, and "seventeen abilities" in four places when there are twenty-six. Prose alone did not hold, so this adds the instruction and something that enforces part of it. CLAUDE.md gains a "Keeping the documentation true" section: a change is not finished until the documents describing it are right, corrected in place and in the same commit. It says which documents to re-read, when the README and CLAUDE.md themselves need touching, and to run the check. scripts/check-docs.mjs reads every backticked token in CLAUDE.md, the README and docs/, and verifies it: a path has to exist, a directory has to have something tracked under it, a symbol has to appear somewhere in the source. That is exactly how these documents rot -- a class renamed, a file moved, a method never built -- and it is the part a person cannot do by reading. It is `npm run check:docs`, and `--list` prints what it saw. What it cannot do is stated where people will read it: a sentence can be wrong with every identifier in it spelled correctly, so green means the names are real, not that the document is true. The re-reading is the step that matters; this is the backstop. Names the repository only talks about -- core, the other repository, an illustrative path, gitignored build output -- are in an ALLOW list with a comment saying which is which, and a line carrying `check-docs:ignore` is skipped. Writing a removed symbol in backticks to say it was removed defeats the check, so the guidance says not to, and one sentence in the service's CLAUDE.md was rewritten accordingly. Both checks pass. Verified by mutation: renaming a class, moving a file and inventing a method are each caught in both repositories. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KtSTgGTH5hSBWVLPCJohhi
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 commits, each reviewable on its own.
1. Comments cut back to a summary line and its tags
Docblocks carried long explanations of why the code is the way it is — what core does and why that forced a choice, what was tried before, which decision a rule came from. That belongs in the docs; in the source it was 26% of every non-blank line and went stale silently.
/* *///Left alone, because something reads them: the plugin header and every theme pattern's own header (
Plugin Name:,Title:,Slug:,Synced:— reducing one deregisters the plugin, or the pattern, and this was the single most dangerous case),phpcs:ignore,/* translators: */, andeslint-disable.Comments were located with PHP's own
token_get_all()and with Babel, never by pattern-matching://inside'https://…'or a regex literal is everywhere here, and a regex pass would have eaten code. To prove the edit reached nothing else, every changed file had all comments stripped from both its old and new version and the remaining code compared. Four differ, each the repo's own formatters run afterwards — eslint'scurlyadding braces, prettier unwrapping two method chains whose parens only existed because comments split them, an emptycatch { /* … */ }collapsing tocatch {}, and two CSS comments inside an inline<style>that the PHP tokenizer sees as HTML.2. The notes the code cannot carry, and a rebuilt docs/
Nine one-line comments went back, only where the code looks arbitrary or redundant and getting it wrong fails silently — the theme root without which
WP_Theme_JSON_Resolverhands back a theme with every preset emptied; the$postglobalcore/post-contentreads instead of its context; the mirror rows read before anything deletes them; the arraywp_handle_sideload()takes by reference; the variable-font weight whose space would be escaped in every URL; the theme.json cache that is stale after a write;late_route_registration; the annotations that select an ability's HTTP method; and whyconstrain()is passed a mime type rather than sniffing one. Each is guarded by a test, so the bug never ships; the comment buys back the diagnosis.docs/is rebuilt around what exists now:architecture-2.0.mdis promoted toarchitecture.mdand brought current. It had gone stale in two places: the browse grid draws its tiles on the server now, and the Site Editor's canvas is never used, not even for the user patterns it could host.abilities.mdandcloud.mdare new, and are where most of CLAUDE.md's bulk now lives.collections.mdanddependencies.mdlose their "Order of work" and "Acceptance" sections, which planned work that shipped.dependencies.mdnamed anexport_tree()that was never built; the walk islocal_tree()+rewrite_references().CLAUDE.md: 10,987 words → 942. readme.md drops the marketing copy and the use cases for what the plugin is, how to run it, and where to read.
3. Keeping it true, and checkable
Both repos already said "
docs/is living" and both had drifted anyway. So CLAUDE.md gains a Keeping the documentation true section — a change is not finished until the documents describing it are right, corrected in place and in the same commit — backed bynpm run check:docs.The check reads every backticked token in
CLAUDE.md,readme.mdanddocs/and verifies it: a path must exist, a directory must have something tracked under it, a symbol must appear in the source. That is exactly how these rot — a class renamed, a file moved, a method never built — and it is the part a person cannot do by reading. Mutation-tested: all three are caught.What it cannot do is stated where people will read it: a sentence can be wrong with every identifier in it spelled correctly, so green means the names are real, not that the document is true.
Verification
phpcslint:jsno-unused-varslint:csscheck:docstest:unit@param $tileondocument_around(), since CLAUDE.md asks for pre-existing violations to be fixed in files you touch and a missing doc comment is squarely this PR's subject. The remainingphpcserror isMissingSingularPlaceholder; fixing it edits a translatable string, so I left it.lint:jserrors are dead imports inPatternDetailsPanel.js, identical at the base.test_convert_theme_image_pattern_exports_assets, which fails identically at the base — the media pipeline this sandbox lacks, as CLAUDE.md documents.Safe_Cssis vendored byte-for-byte into patternbuilderwp.com apart from its namespace. Both copies got the identical transform and their bodies still match line for line — checked, not assumed. The sharedtests/php/fixtures/safe-css-cases.jsonis untouched and still has the same md5 in both.Companion PR: Twenty-Bellows/patternbuilderwp.com#57.
🤖 Generated with Claude Code
https://claude.ai/code/session_01KtSTgGTH5hSBWVLPCJohhi