Skip to content

docs: correct CLAUDE.md statements the tree contradicts - #301

Merged
OmarAlJarrah merged 2 commits into
mainfrom
docs/claude-md-corrections
Aug 9, 2026
Merged

docs: correct CLAUDE.md statements the tree contradicts#301
OmarAlJarrah merged 2 commits into
mainfrom
docs/claude-md-corrections

Conversation

@OmarAlJarrah

@OmarAlJarrahOmarAlJarrah commented Aug 9, 2026

Copy link
Copy Markdown
Member

Summary

CLAUDE.md is binding on every contributor and is read before the code, so a false statement in it
is worse than a stale comment: it is followed. Eight of them had accumulated, all in the same shape
— a hand-maintained enumeration or count that the tree moved out from under, which is the failure
mode the file's own "Derive counts; never maintain them" rule exists to prevent.

Where a count could be replaced by the command that derives it, it was. Where a fact had to stay
written down, it now names the site it can be re-derived from.

  1. The JSON codec rule was wrong in both of its clauses (closesdocs: CLAUDE.md says BigVal has a custom JSON codec; it has none #277). It said "custom
    MarshalJSON/UnmarshalJSON for special forms (the IR's sum types and BigVal do this)".
    BigVal has no codec at all — it is type BigVal string with one method, String(), and needs
    none, because being a string type is what preserves precision. And the sum is asymmetric: all
    eleven TypeDef kinds have MarshalJSON, none has UnmarshalJSON; the module's only
    UnmarshalJSON is (*TypeRegistry)'s, which peeks the adjacent kind tag and dispatches.
    Dropping BigVal alone would have left the second falsehood standing, so the sentence now
    describes the asymmetry and gives the grep that lists the codecs.
  2. The switch-completeness test was called "generated". Nothing in this module is generated —
    there is no go:generate directive anywhere. The kind lists are hand-written, and
    TestTypeDef_HandWrittenKindListsAreComplete is what holds them to the kinds the ir sources
    declare. Calling it generated invites a contributor to look for a generator to re-run instead of
    editing the list.
  3. "openapi has thirteen" internal packages. There are fourteen (overlay/ is the one the
    count predates). Deleted rather than corrected: the paragraph below the diagram already says the
    diagram deliberately does not name them and gives the command that lists them, so the count was
    the one part of that sentence able to rot.
  4. The oracle list named five oracles; harness.Check applies six. Order-invariance was
    missing. That omission was doing active harm two paragraphs later, where the two-order-diff rule
    read as though no oracle implemented it — so contributors were being told to hand-roll, per new
    construct, a diff that already runs across the corpus under testdata/. Both are corrected, and
    the reworded paragraph says when a targeted case is still worth writing: the oracle proves
    order-independence only for constructs its inputs contain.
  5. cmd/morphic/ was documented as importing engine; internal/archtest's rules map — the
    stated source of truth — says {ir, engine}.
  6. cmd/morphic-harness/ was absent from the layout block entirely, which was the one part of
    docs: CLAUDE.md still describes the pre-implementation repository #63's acceptance ("every package in the tree appears in the documented layout") still unmet.
  7. The normative-docs list named four of eight documents.docs/emitter-design.md was missing
    despite declaring itself normative for the emitter half, as were reference-learnings.md and the
    two micro-compiler-*.md records. All are now listed, with the two micro-compiler documents
    marked as records of landed work so they are not mistaken for a proposal or a backlog.
  8. Invariant 1 read "a emitter's only input" — article left behind by the generator → emitter
    rename.

Items 1 and 7 are #277 and the last open bullet of #63. Items 2-6 are not in either issue text;
they surfaced while checking the sections around them and are the same defect, so they are fixed
here rather than left to be re-derived by the next reader.

Deliberately out of scope, so it is not lost:docs/architecture.md §3 lists the same thirteen
internal packages and also omits overlay/, and README/architecture carry the cmd/morphic import
row — those belong to #64 and are being fixed there. Two further sites found while verifying are
filed rather than fixed here: #299 (docs/micro-compiler-design.md repeats the thirteen) and #300
(the "a emitter" rename residue, 22 occurrences across five files in docs/).

Test plan

No test guards prose, so every corrected claim was re-derived from the tree by command rather than
by reading, and the whole set was then run against the pre-change file to confirm each correction
was load-bearing — 11 assertions fail against origin/main's CLAUDE.md, 0 against this branch.

ClaimCommandResult
BigVal has no codecgrep -n 'type BigVal|func (v BigVal)' ir/bigval.gotype BigVal string, String() — nothing else
the sum marshals but does not unmarshalgrep -rnE 'func .*(Unm|M)arshalJSON' ir/11 MarshalJSON (one per typeDef() implementer), 1 UnmarshalJSON, on TypeRegistry
nothing is generatedgrep -rn 'go:generate' --include='*.go' .no output, exit 1
the test is hand-writtengrep -rn 'func TestTypeDef.*Complete' ir/TestTypeDef_KindDispatchIsComplete, TestTypeDef_HandWrittenKindListsAreComplete
fourteen internal packagesls -d compilers/openapi/internal/*/ | wc -l14; the same 14 as keys in archtest's rules
six oraclesinternal/harness/harness.go:50-88ends at orderInvariantOutcomeOrderDependent
cmd/morphic importsgrep -n '"cmd/morphic"' internal/archtest/arch_test.go{module + "/ir", module + "/engine"}
every package is documentedgit ls-files '*/*.go' | xargs -n1 dirname | sort -uall 27 covered, compilers/openapi/internal/* as a class by design
every doc is listedls docs/*.md8 files, 8 named

Each command the file now instructs a reader to run was executed as written from the repo root,
including go run ./cmd/morphic-harness <file> and <dir> — both report ok.

Full gate (gofmt, go vet, golangci-lint, go build, scripts/check-coverage.sh) passes; the
change is documentation only, so no goldens move and coverage is unaffected.

Closes#63
Closes#277

Closes#339

Two follow-ups on the same file, both instances of the rule the rest of
the change set out to apply.
The reference-learnings entry hard-coded "seven shipped generators" — a
maintained count, sitting one paragraph below the line that had just
stopped counting the documents. It now points at that document's own
header, which names the generators it surveys, so the fact is
re-derivable rather than restated in a second place that can rot.
The oracle bullet said the harness CLI "runs them all" two sentences
after saying Check stops at the first oracle that fires, which invites
reading it as "every oracle runs on every spec". It now says what the
CLI actually varies — the input — instead of making a claim about
exhaustiveness that the preceding sentence contradicts.
@OmarAlJarrah
OmarAlJarrah merged commit 1afeaae into mainAug 9, 2026
1 check passed
@OmarAlJarrah
OmarAlJarrah deleted the docs/claude-md-corrections branch August 9, 2026 06:17
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant

@OmarAlJarrah