Skip to content

Normalize markdown heading levels and remove @module JSDoc tags - #1756

Merged
sergey-shandar merged 10 commits into
mainfrom
claude/review-todos-documentation-hrijwz
Aug 28, 2026
Merged

Normalize markdown heading levels and remove @module JSDoc tags#1756
sergey-shandar merged 10 commits into
mainfrom
claude/review-todos-documentation-hrijwz

Conversation

@sergey-shandar

@sergey-shandar sergey-shandar commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

A sweep over the ~600 markdown files and the JSDoc headers for broken links, stale citations, issue metadata that disagrees with todo/README.md, and one convention that had drifted repo-wide.

Broken links — 7 targets across 8 sites. fjs/cli/README.md and fjs/types/prime_field had never-existing or since-moved targets; patricia_trie moved under fjs/types/; the rtti README's #closed-containers anchor is now #structs-and-tuples-are-closed. Three citations pointed at todo files deleted when their work shipped — dispatch-help-rendering (renderHelp, e1f5e44) and name-entity-kind-discrimination-once (isBinFile/isJsModule/isDir, 0c21ef0) — and are rewritten in the retired form todo/README.md documents, naming the code that shipped. A rotted #L63 line anchor on reciprocal is dropped rather than re-pinned, per the tokenizer-line-citations issue. These last two are exactly the class todo/retired-issue-identifiers.md predicted but did not enumerate.

@modulefjs/AGENTS.md §2 reserves the tag for a package's entry point, "not to proof.f.mjs, types.ts, or any other file". 102 files carried it anyway: 89 types.ts, 11 proof files, plus fjs/bnf/testlib.f.mjs and fjs/emergent_testing/browser.mjs. All 137 real entry points already had it, so the rule was inverted almost everywhere it applied and enforced nowhere. This enforces a standing rule rather than fixing a tool — nothing consumes the tag today. The tag appeared in three block shapes and the adjacent blank comment line is removed with it, so each block keeps the spacing AGENTS.md shows. This also resolves fjs/todo/module-tag-on-types-ts.md, filed on main when #1750 stripped its own new private.ts files and recorded the rest as debt; that issue asked for a decision and its consistent application, and this takes the first of its two options.

Todo issue files — 4 had no **Priority:**/**Status:** header, two of those spelling it as a list item; 56 were titled # Title where the documented format is ## Title. Where sections were already ### the title alone is demoted; where the whole document sat one level up, every heading is demoted together. Heading text is unchanged throughout, so no anchor moves. 38 files kept the bare number from the retired issues/ tracker (fjs/bnf/todo/32.md, fjs/djs/todo/157.md) and are renamed NNN-{slug}.md — the number is kept because most inbound links label them by it ([i157](./157.md)), and dropping it would break the correspondence between a citation's label and its target. spec/todo/ and todo/plan/ are excluded: they hold specification drafts and planning documents, not issues.

Four resolved issues retired, one kept. prefix-then-rest-tuple (closed) and data-tosequence-reuse / operator-test-operation-model (both irrelevant, superseded by unicode-rules and reuse-edag-operators) are deleted with their citations restated in the retired form; module-tag-on-types-ts (open) is deleted because this PR resolves it. fjs/effects/todo/io-effect-migration.md stays: it is done, but two live documents cite it for rationale nothing else states, and todo/README.md had no category for that — so the category is now written down, deliberately narrow.

EDAG constructor shape — review found the design documents specified flat ["[]", ...node] / ["{}", ...entries] while the shipped schema nests, so an implementation following them would emit nodes validation rejects. The disagreement predates this branch: fjs/edag/README.md already wrote ['[]', items[]] and the proofs construct ['[]', [1, 'a', true]]. Corrected in the normative places — the structural-operations table, subject 4's resolution and history, the object-constructor validation rule, and the three forms in compile-modules-to-edag.md — with the reason stated once in fjs/edag/README.md, where fjs/AGENTS.md §2 puts why this / why not that. fjs/edag/module.f.mjs is untouched by this PR. Roughly twenty illustrative examples elsewhere in todo/edag-stage1-discussion.md still use the flat spelling, several inside history paragraphs quoting superseded proposals; re-notating those needs a per-site judgement and is left open on the review thread.

Root README — the CLI table was missing fjs web and fjs help, both of which fjs/README.md and the dispatch table in fjs/module.f.mjs carry.

No behaviour or public-API change, so no changelog entry: markdown and JSDoc comments only. npx tsc clean, suite 3525/3525, and main's file-scope-typedef guard passes.

https://claude.ai/code/session_01T7vAocRuxfmWJDnujCoMup

claude added 4 commits August 28, 2026 15:41
A sweep over the ~600 markdown files in the tree for broken links,
missing issue metadata, and heading levels that disagree with
todo/README.md's format.

Broken links (7 targets, 8 sites). `fjs/cli` and `fjs/types/prime_field`
had never-existing or since-moved README targets; `patricia_trie` moved
under `fjs/types/`; the `rtti` README's `#closed-containers` anchor is
now `#structs-and-tuples-are-closed`. Three citations pointed at todo
files deleted when their work shipped — `dispatch-help-rendering`
(`renderHelp`, e1f5e44) and `name-entity-kind-discrimination-once`
(`isBinFile`/`isJsModule`/`isDir`, 0c21ef0) — and are rewritten in the
`retired` form todo/README.md documents, naming the code that shipped.
The rotted `#L63` line anchor on `reciprocal` is dropped rather than
re-pinned, per the tokenizer-line-citations issue.

Root README's CLI table was missing `fjs web` and `fjs help`, both of
which fjs/README.md and the dispatch table in fjs/module.f.mjs carry.
Reordered to match the command table itself, and `compile` now links
`fjs/fsc` alongside `fjs/djs` as fjs/README.md does.

Issue metadata. Four issue files carried no `**Priority:**`/`**Status:**`
header, and two of those spelled it as a list item; all four now use the
documented bare form. `abstract-write` is P4 as a pure DRY refactor, the
rest take the documented P3 default — adjust if that misreads them.

Heading levels. 56 issue files titled `# Title` where todo/README.md's
format is `## Title`. Where sections were already `###` the title alone
is demoted; where the whole document sat one level up, every heading is
demoted together so sections stay below the title. GitHub anchors are
level-independent, so no inbound link changes.

`spec/todo/` and `todo/plan/` are excluded throughout: they hold
specification drafts and planning documents, not issues, and their own
READMEs describe them that way.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T7vAocRuxfmWJDnujCoMup
fjs/AGENTS.md §2 states the tag "belongs only to a package's entry-point
file — `module.f.mjs` / `module.mjs` — not to `proof.f.mjs`, `types.ts`,
or any other file". 102 files carried it anyway: 89 `types.ts`, 11 proof
files, plus `fjs/bnf/testlib.f.mjs` and `fjs/emergent_testing/browser.mjs`.
Every one of the 137 real entry points already had it, so the rule was
being inverted almost everywhere it applied and enforced nowhere.

`@module` is what a documentation generator uses to decide that a file
*is* a module and to attach the block to it, so leaving it on type-only
stubs and proofs would list them beside the modules they describe once
`fjs/website/todo/publish-deno-doc-to-website.md` lands. That issue is
the reason to fix the files rather than relax the rule.

The tag appeared in three block shapes and the surrounding blank comment
line is removed with it, so each block keeps the spacing AGENTS.md shows:
a trailing `@module` takes the separator above it, a middle one takes one
of its two separators, and a leading one (a block that was only `@module`
plus `@import` tags) takes the separator below.

No runtime or type-level change: `npx tsc` is clean and the suite passes
3513/3513.

Nothing enforces this rule mechanically, which is how it drifted this
far; a check belongs in the `fjs ci` workflow, filed separately.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T7vAocRuxfmWJDnujCoMup
todo/README.md names issue files `{slug-kebab}.md`, but 38 kept the bare
number they carried in the retired `issues/` tracker — `fjs/bnf/todo/32.md`,
`fjs/djs/todo/157.md`, `nanvm-lib/todo/89.md`. A number tells a reader
nothing about what the issue is, which is the scannability the naming rule
exists for.

The number is kept as a prefix rather than dropped. These are exactly the
identifiers the tree cites as `iNNN`, and most inbound links label them
that way — `[i157](./157.md)`, `[i170-ci-tool-steps](./170.md)` — so
dropping it would break the correspondence between a citation's label and
its target, which is the rot todo/retired-issue-identifiers.md is open
about. `NNN-{slug}.md` also matches the retired tracker's own
`issues/NNN-{slug}.md` scheme and the files already named this way
(`todo/037-language-design-map.md`,
`fjs/emergent_testing/todo/028-unit-test-examples-api.md`).

Numbers are zero-padded to three digits, the majority form in the tree,
and the `NNN.` prefix in each heading is left alone: todo/README.md's own
worked example pairs file `037-language-design-map.md` with heading
`# 37.`, so the two need not agree digit for digit.

All 43 files holding inbound links are rewritten. No non-markdown file
referenced any of them. The link check reports no broken targets or
anchors, and the retired-identifier check in
todo/retired-issue-identifiers.md still reports its documented 18.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T7vAocRuxfmWJDnujCoMup
todo/README.md requires a done or won't-fix issue to be deleted once its
reasoning lives somewhere durable. Five files had a resolved status and
were still in the tree; three are retired here, and the rule grows the
category the other two actually need.

`prefix-then-rest-tuple` (won't fix) had nothing citing it, but its
decision was recorded nowhere else: that `edag`'s nested
`['[]', [elem, …]]` is the chosen representation rather than a workaround
for a shape rtti cannot spell, because an rtti `Tuple` pins one schema
per position and growing the `Type` ADT to match the spec's flat
spelling has no other consumer here. That now sits on `array`, where
someone comparing the code against the spec's structural-operations
table will hit it, with `object` pointing at it.

`data-tosequence-reuse` and `operator-test-operation-model` (both
irrelevant) were superseded by issues that already carry their content —
`unicode-rules` and `reuse-edag-operators`. Their seven citations are
restated in the `retired` form, and `unicode-rules`'s task to keep the
superseded file around goes with it.

`io-effect-migration` stays. It is done, but `fjs/effects/README.md` and
`spec/todo/io-effects.md` cite it for the staged rationale behind the
error channel, which no surviving file states. todo/README.md had no
category for that, so the file read as a rule violation while arguing in
its own text that it should stay — the gap was in the rule. The category
is now written down, deliberately narrow: it applies only where live
documents cite the issue for something nothing else says, and requires
the status to admit what the file is.

`todo/inline-type-casts.md` is untouched pending review — despite an
`implemented` status it is a live reference document with 84 open sites
and 20 inbound citations, not a resolved issue.

`npx tsc` is clean and the suite passes 3513/3513.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T7vAocRuxfmWJDnujCoMup
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
functionalscript f182a64 Commit Preview URL

Branch Preview URL
Aug 28 2026, 04:52 PM

@sergey-shandar
sergey-shandar marked this pull request as ready for review August 28, 2026 15:57
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

Two conflicts, and two follow-ups main's Stage 1 work left for this branch.

`fjs/emergent_testing/browser.mjs`: main widened the `@import` list while
this branch removed the `@module` tag beside it. Resolved to main's import
list without the tag — `browser.mjs` is not a `module.*` entry point, so
fjs/AGENTS.md §2 excludes it.

`todo/blocked/jsdoc-typedef-strip-internal.md`: deleted on main by the
Stage 1 private-type work, modified here only by the heading-level pass.
Deletion accepted. Main left both citations to it dangling in
`fjs/todo/separate-private-types.md` — the issue that asked for the
deletion — so they are rewritten here: the repository-policy bullet is
marked done and the `Related` entry takes the `retired` form.

`fjs/todo/module-tag-on-types-ts.md` is deleted. Main filed it when
`eebc007` stripped `@module` from the `private.ts` files that branch added
and recorded the pre-existing `types.ts` files as debt rather than widening.
It asked for a decision and its consistent application; `03a96e8` on this
branch made that decision the way the issue's first option reads — strip,
rather than narrow §2 — and applied it to all 102 files. After the merge no
non-entry-point file carries the tag and all 137 entry points do.

`npx tsc` is clean, the suite passes 3522/3522, and main's new
file-scope-typedef guard passes. `npm run update` reports no drift in the
generated workflow or `package-lock.json`; `deno.lock` and `bun.lock` could
not be refreshed here (neither runtime is installed) and nothing in this
merge declares a dependency change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T7vAocRuxfmWJDnujCoMup

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bb332ad332

ℹ️ 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".

Comment thread fjs/edag/module.f.mjs Outdated
Comment on lines +114 to +116
* The variadic part is nested one position deep — `['[]', [elem, elem, …]]`
* — where the spec's structural-operations table writes it flat,
* `['[]', ...elements]`. That is the decided representation, not a

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Update the canonical EDAG design to the nested shape

Declaring the nested form final while retiring its TODO leaves the canonical design contradictory: todo/edag-stage1-discussion.md still specifies flat array/object constructors at lines 220–221 and marks ['{}', ...entries] as decided at lines 764–767. A future compiler or Rust implementation following that document will therefore emit flat nodes that the shipped schema rejects; update the design document and its examples to the nested representation as part of this decision.

AGENTS.md reference: AGENTS.md:L47-L53

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Confirmed and partly fixed in f808280.

Worth noting the disagreement is older than this branch: fjs/edag/README.md already writes the form column as ['[]', items[]], and the proofs construct ['[]', [1, 'a', true]] / ['{}', [[':', 'a', 1]]]. So the code and the module documentation already agreed on nesting — only the working design documents were behind. This branch made it visible by recording the decision on array and retiring the todo that had been the sole written record of the gap.

Fixed here, being what an implementer reads as normative:

  • the structural-operations table rows for ["[]"] and ["{}"]
  • subject 4's resolution and its history paragraph
  • the object-constructor validation rule, whose "every ["{}", ...] operand" no longer described the shape (there is one operand now — the entry array)
  • the three constructor forms in fjs/djs/todo/compile-modules-to-edag.md

The reason is stated once under the table — an rtti Tuple pins one schema per position, so a tag followed by a homogeneous rest is not spellable inline, and growing the Type ADT has no other consumer here — with subject 4 carrying a *Revised:* note in the form that document already uses.

Not done, deliberately: roughly twenty illustrative examples elsewhere in the discussion still use the flat spelling — ["[]", x, x] in the sharing-is-observable passages, and ["{}"] for an empty object, which the schema writes ["{}", []]. Two reasons to keep that separate. It is a re-notation of a 1400-line working document rather than a correction, and several of those examples sit inside history paragraphs recording what an earlier proposal said, where rewriting the notation would falsify the record instead of fixing it. Those want a pass that decides per-site whether the example is describing today's shape or quoting a superseded one, which is a judgement for the document's author.


Generated by Claude Code

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Follow-up: the second finding on this file is fixed in a767b30, and it supersedes how I resolved the first one.

The JSDoc I had added described a schema/design conflict that the previous commit had just removed. fjs/AGENTS.md §2's documentation-home table decides where that text belongs rather than how to reword it — API shape and invariants in JSDoc, why this / why not that in the README — and the rationale is the second kind.

So fjs/edag/module.f.mjs is now byte-identical to main. The shape was already noted there by the pre-existing // Object — same nesting as array above, one position further in marker (from #1680), which makes the JSDoc addition redundant independently of having gone stale. The reason now extends the paragraph in fjs/edag/README.md that already explains the [] suffix, and todo/edag-stage1-discussion.md points at it rather than restating it.

That still does what retiring prefix-then-rest-tuple required — the decision is written down where a reader of this module meets it — with one home instead of three.

Remaining, unchanged from my earlier reply and still for the document's author: roughly twenty illustrative examples in the discussion use the flat spelling, several inside history paragraphs quoting superseded proposals.

npx tsc clean, suite 3521/3521, file-scope-typedef guard passes.


Generated by Claude Code

sergey-shandar and others added 2 commits August 28, 2026 09:29
Codex flagged that this branch declares the nested array/object form final
in `fjs/edag/module.f.mjs` while `todo/edag-stage1-discussion.md` still
specifies the flat, variadic `["[]", ...node]` / `["{}", ...entries]`, so
an implementation following the design document would emit nodes the
shipped schema rejects. The finding is right, and the disagreement is
older than this branch: `fjs/edag/README.md` writes `['[]', items[]]` and
the proofs construct `['[]', [1, 'a', true]]`, so the code and the module
documentation already agreed on nesting and only the working design
documents were behind.

Fixed here are the parts an implementer reads as normative: the
structural-operations table, subject 4's resolution and its history
paragraph, the object-constructor validation rule, and the three
constructor forms in `fjs/djs/todo/compile-modules-to-edag.md`. The reason
is stated once under the table — an rtti `Tuple` pins one schema per
position, so a tag followed by a homogeneous rest is not spellable inline
— with subject 4 carrying a `*Revised:*` note in the form that document
already uses for its other revisions.

Roughly twenty illustrative examples elsewhere in the discussion still use
the flat spelling (`["[]", x, x]`, and `["{}"]` for an empty object, which
the schema writes `["{}", []]`). Re-notating those is a separate pass, not
least because several sit inside history paragraphs recording what an
earlier proposal said — rewriting those would falsify the record rather
than correct it. Raised on the review thread rather than done here.

Markdown only. The link check reports no broken targets or anchors and
main's file-scope-typedef guard passes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T7vAocRuxfmWJDnujCoMup

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f8082809fe

ℹ️ 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".

Comment thread fjs/edag/module.f.mjs Outdated
claude and others added 3 commits August 28, 2026 16:40
Codex's second pass caught that the JSDoc added in 563ac09 now describes a
disagreement that no longer exists: it contrasted the nested schema against
a design document that writes the constructors flat, and f808280 changed
that document to write them nested. A reader would go looking for a
conflict that had just been resolved.

fjs/AGENTS.md §2's documentation-home table settles where the text belongs
rather than how to reword it — API shape and invariants in JSDoc,
"architectural choices, why this / why not that" in the README — and the
rationale is the second kind. `fjs/edag/module.f.mjs` is therefore restored
to exactly its state on main; the shape was already noted there by the
pre-existing `// Object — same nesting as `array` above` marker, so the
JSDoc addition was redundant even before it went stale.

The reason now sits in `fjs/edag/README.md`, extending the paragraph that
already explains the `[]` suffix — the nearest thing to a home it had. That
still satisfies what retiring `prefix-then-rest-tuple` required: the
decision is written down where a reader of this module will meet it, and
the design document points at it instead of restating it.

`npx tsc` is clean, the suite passes 3521/3521, main's file-scope-typedef
guard passes, and the link check reports no broken targets or anchors.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T7vAocRuxfmWJDnujCoMup

@o2alexanderfedin o2alexanderfedin 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.

Approved.

A 247-file sweep is where a substantive change hides, so I had the whole diff classified rather than sampled. It holds up: all 102 .ts/.mjs files are exactly 0 add / 2 del, the removed lines being only * @module and its blank comment line. Emitting declarations at both ends and diffing the trees, exactly those 102 .d.ts/.d.mts differ, and in every one the only changed lines are those same comments — no signature, export or type moved. Proof-leaf name sets are byte-identical in both directions, 3525 either side. Heading text sequences are unchanged in all 141 markdown files, so no anchor could have moved, and a repo-wide grep for the 4 deleted and 38 renamed basenames finds nothing left pointing at them. Gates: tsc 0, npm test 3525/3525.

Six hunks are real content rather than formatting, and all six check out — the fjs/edag/README.md paragraph on the array operand matches module.f.mjs:114 and types.ts:49 as shipped, the bracket-form corrections in the two todo docs agree with it, and the root README's new fjs web row names a genuinely registered command. The four deleted files were already irrelevant/closed before this PR.

Two things in the description, worth fixing since this repo squash-merges the body into history:

  • It says the EDAG clarification landed in fjs/edag/module.f.mjs comments. That file is untouched here; the clarification is in fjs/edag/README.md and the two todo docs.
  • It says @module was "causing documentation generation issues". Nothing consumes the tag today — the only candidate, deno doc via publish-deno-doc-to-website.md, is still an open todo and targets entry points only. The real justification is stronger and already exists: fjs/AGENTS.md §2 has said since #1568 that @module belongs only to entry-point files, and none of the 102 files here is one. The sweep enforces a standing rule rather than fixing a tool.

Copy link
Copy Markdown
Contributor Author

Thanks — both description corrections were right, and I've rewritten the body.

Verified each before editing rather than taking them on trust:

  • git diff origin/main…HEAD -- fjs/edag/ returns fjs/edag/README.md alone, so module.f.mjs is indeed untouched. It was changed earlier in the PR; Codex then pointed out that the JSDoc I had added asserted a design/schema conflict that the previous commit had just resolved, and fjs/AGENTS.md §2's documentation-home table puts why this / why not that in the README. Reverting it left the file byte-identical to main. The description still described the intermediate state.
  • Nothing consumes @module today — no deno doc, TypeDoc or JSDoc invocation anywhere in the repo. The body's "causing documentation generation issues" was my forward-looking argument about publish-deno-doc-to-website.md stated as present fact, which it isn't. The body now says the sweep enforces a standing rule rather than fixing a tool.

Two notes on the new text where I went slightly further than your summary:

  • The deleted files are four, but only three were irrelevant/closed beforehand. fjs/todo/module-tag-on-types-ts.md was open — filed on main when fjs: keep private types out of authored .mjs (Stage 1) #1750 stripped its own new private.ts files and recorded the pre-existing ones as debt. It asked for a decision between stripping the tag and narrowing §2, and this PR takes the first option, so it is deleted as resolved rather than as already-dead. The body now says so.
  • I cited the rule rather than the PR that introduced it: locally the text traces to ca49715, which I could not confirm is Split AGENTS.md into scoped documents by codebase #1568, so naming a number seemed worse than naming the rule.

Left alone: the PR title. It doesn't follow <topic>: <short description> from CONTRIBUTING.md and, like the body, becomes the squash commit — something such as docs: repair link rot and enforce the @module rule would fit. You didn't ask for it and it's the author's call, so say the word and I'll change it.


Generated by Claude Code

@sergey-shandar
sergey-shandar added this pull request to the merge queue Aug 28, 2026
Merged via the queue into main with commit 0233904 Aug 28, 2026
19 checks passed
sergey-shandar pushed a commit that referenced this pull request Aug 28, 2026
The merge queue dequeued this for MERGE_CONFLICT. One conflict, in the Related
section: both sides were additive, so both survive — my two ownership links,
and main's note recording that jsdoc-typedef-strip-internal is retired rather
than merely unlinked.

Main's heading normalization and todo renames (#1756) auto-merged; all links in
the three touched files still resolve and tsc is clean.

Re-measured everything the documents assert, since main moved a lot. The
invariants hold exactly: 16 private.ts, fjs/emergent_testing still has none
(so it remains a valid stand-in for a future module), 0 runtime imports among
the 226 in authored .ts, and bigfloat's divide is still unexported with
_BigFloatWithRemainder still private.

The absolute counts drifted for the third time, though: 675/659 is now 677/661
and 377 declarations is 378. The numbers were never the claim — "exactly 16
disappear, and they are exactly the private.d.ts" is — so the prose now says
that, with the totals marked as a re-measured snapshot. Future drift makes the
snapshot old rather than making the document wrong.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LqeS5t2ZKkSu3chRPMXR7n
@sergey-shandar
sergey-shandar deleted the claude/review-todos-documentation-hrijwz branch August 28, 2026 18:51
sergey-shandar pushed a commit that referenced this pull request Aug 28, 2026
Review caught a trap in this issue's own instructions. "Every `["{}"]` →
`["{}", []]`" reads as a blanket rewrite, but one of the seven occurrences
in `edag-stage1-discussion.md` is not an empty object: the validation rule
writes "every element of a `["{}"]` node's entry array must be a recognized
entry form", where the tag names *an object-constructor node*. Rewriting
that one with the examples makes the sentence contradict itself — an empty
entry array has no elements to check — so an implementer following this
issue literally would have introduced the defect.

It is also the occurrence #1756 introduced rather than inherited: the
previous wording said "every `["{}", ...]` operand", which stopped
describing the shape once the operands became one array.

Added as a fourth class with its own treatment. The shorthand only became
ambiguous when `["{}", []]` acquired a meaning, so it wants a nonempty
placeholder — `["{}", entries]` — rather than the empty form or a bare tag.
The counts in the problem statement, the class-1 blurb and the task list
are qualified to match: six genuine empty objects, one shorthand.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T7vAocRuxfmWJDnujCoMup
sergey-shandar pushed a commit that referenced this pull request Aug 28, 2026
Two issues asked the same question. #1756 answered it — strip the tag,
`fjs/AGENTS.md` §2 was right — and applied that to 102 files, then deleted
`fjs/todo/module-tag-on-types-ts.md` and missed this one.

Every premise in it is now false. "90 of the 94 `types.ts` files carry it
anyway" is 0 of 98. Its three tasks are done: the convention was decided,
applied to every `types.ts`, and `fjs/web/types.ts` — named as the minority
case — matches. Nothing cites it.

Nothing to move before deleting: the decision it asked for lives in
`fjs/AGENTS.md` §2, which never changed, and the CI-enforcement question it
did not ask about is settled the other way by §6.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T7vAocRuxfmWJDnujCoMup
sergey-shandar pushed a commit that referenced this pull request Aug 28, 2026
Three more review findings, all correct.

The module header lacked @module. fjs/AGENTS.md §2 requires it on every
module.* entry point, and all five sibling fjs/ci modules carry one; #1756
removed the tag from non-module files, not from these.

The proof lived in the parent. fjs/ci/deno, fjs/ci/nix and fjs/ci/node all have
co-located proofs, so the precedent is the opposite of what I assumed. The job's
own shape is now proved in fjs/ci/package/proof.f.mjs, and the parent keeps only
what the assembled workflow can show: that the job is wired in, and that the job
it waits for is really the one that uploads — an edge pointing at a job that
never produces the artifact would satisfy the ordering and still never run.

The compiler pin was the substantive one. Reading devDependencies.typescript
gives a dependency specification, not a resolved version: this repository pins
=7.0.2, but a project writing ^7.0.0 would have had npm choose, which is exactly
the determinism the checkout-less job exists to preserve. The script now
compares the installed version against the literal pin and refuses when they
differ.

That case is worse than it looks, and the test shows why: ^7.0.0 installs 7.0.2
today, so a range is indistinguishable from an exact pin until the day the
registry publishes 7.0.3 and the verdict moves with no change to the package.
Verified: ^7.0.0 exits non-zero, =7.0.2 exits 0 at 396 declarations, and a
second tarball named other-package still resolves and passes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LqeS5t2ZKkSu3chRPMXR7n
sergey-shandar pushed a commit that referenced this pull request Aug 28, 2026
§2 said the tag belongs only to `module.f.mjs` / `module.mjs`. That is the
rule #1756 enforced across 102 files, and it had the reason backwards.

`deno doc` reads the tag and nothing else. A file whose leading block
carries it gets that prose as `module_doc`; a file without it gets no
`module_doc` at all — the block is dropped, not demoted. Checked against
the Deno the repository pins, for `.mjs` and `.ts` alike, and the tag need
not be in the first block, only in some block. So the tag is what makes a
leading block *be* documentation, and it goes wherever a file has module
documentation to publish: `module.f.mjs`, `types.ts`, `private.ts`. A block
holding only `@import` tags has nothing to attach and wants none. Where the
documentation is never published the tag buys nothing, which is `proof.*`.

98 of the 102 stripped files had real prose, so their module documentation
is currently invisible to `deno doc` — the output
`fjs/website/todo/publish-deno-doc-to-website.md` plans to publish. §2 says
so plainly rather than describing a tree that does not exist, and points at
the restore.

`fjs/todo/module-tag-restore.md` (P3) carries the inventory, split by the
three decisions it actually contains: 89 `types.ts` with prose, mechanical;
11 proof files where the rule says leave them but that is worth confirming;
and two files that are neither — `browser.mjs` has real prose and reads
like the first group, `testlib.f.mjs` held only `@import` tags and wants no
tag at all.

`todo/jsdoc-verification.md` (P4) asks how any of this could be checked.
Three passes over one tag with no signal at any point is the argument for
looking; §6 ruling out text patterns is why the answer has to parse, and
"not worth it, leave it to review" is a legitimate outcome to record.

Documentation only. `npx tsc` clean, suite 3533/3533.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T7vAocRuxfmWJDnujCoMup
sergey-shandar pushed a commit that referenced this pull request Aug 28, 2026
…d claim

Three review findings, all against text I wrote in the previous commit.

§1.2 still showed a `proof.f.mjs` leading block carrying `@module`, while the
§2 I had just rewritten said a proof's documentation is never published so
the tag has nothing to attach to. Same file, opposite instructions for the
same shape. The example loses the tag and says why.

The restore issue omitted `private.ts`. All 16 have prose and none carry the
tag — stripped by #1750 rather than #1756, so they were not in the 102 I
counted, but it is the same reading and the same fix, and §2 names
`private.ts` explicitly. As written the issue could have been completed in
full while leaving 16 files violating the rule it exists to satisfy, and its
last task says to delete §2's non-compliance note.

And the publication rationale was overstated. The website issue plans
`deno doc --html **/module.f.mjs`, a glob excluding every `types.ts` and
`private.ts`, so restoring the tag alone puts nothing on the website. The
tag is necessary, not sufficient: it decides whether `deno doc` *can* see a
file's module documentation, and what the build is pointed at is a separate
question. Both §2 and the issue say that now, and widening the glob is named
as the other half.

Also added: a task to correct `todo/migrate-typescript-to-mjs.md`, which
restates the old rule verbatim under "Module header and import ordering"
rather than linking §2, so it did not move when §2 did.

Documentation only. `npx tsc` clean, suite 3533/3533.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T7vAocRuxfmWJDnujCoMup
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.

3 participants