Fixes from the repo review (#1 to #47) - #49
Merged
Merged
Conversation
- Drop the push path filters. They left out stacks/**, so a stacks-only push was neither validated nor deployed until the Monday rebuild, and pages.yml also left out README.md, which the validator reads. The run takes seconds, so filtering saved nothing. - Pages calls the CI workflow (workflow_call) instead of repeating its steps, then builds and deploys. - Node 24 (current LTS) via .nvmrc for both; Node 20 is past end of life. - checkout v7, setup-node v7, upload-pages-artifact v5, deploy-pages v5. - ci.yml gets permissions: contents: read. - Dependabot keeps the action versions current, monthly. Fixes #1 Fixes #2 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
catalog/video/ has six entries, but the form's category dropdown stopped at tools. The validator now checks the dropdown against the catalog folders (next commit). The correction and new-source labels the forms apply now exist in the repo. Fixes #5 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
… loudly Parser (lib/frontmatter.mjs, used by build and validate): - build.mjs and validate.mjs each had a parser and they had drifted: validate kept \" escapes in ccmixter's attribution string, and its evidenceSection treated a following "## Extras" as Evidence. - Flow lists split on commas inside quotes and never unquoted items; block lists read as null; a repeated key won silently. Now: quoted commas stay in one item, block lists parse, and a repeated key or a line that is not key: value is an error with its line number. - A byte-order mark is ignored instead of hiding the entry. Build: - Summaries come from the page's own inline renderer with tags dropped, so underscores and # stay literal: "Rig_Medium", not "RigMedium", and "KHR_draco_mesh_compression". Five summaries change. - An entry that cannot be read, or a missing index.html marker, fails the build instead of printing a warning and publishing a site with the entry missing. The exitCode = 0 line did nothing and is gone. Checks: - V16: url must be http(s). javascript: and data: URLs passed and were rendered as the "Go to source" link. - verified, Evidence and walked dates must be real calendar dates; 2025-13-01 passed and 2026-02-30 rolled over to 2 March. - Evidence dates inside URLs no longer count, so a link to .../2026-09-20-notes cannot hide a bumped verified date. No entry's newest Evidence date changes. - "In the future" means after tomorrow in UTC, so a contributor east of UTC can write their own today. - V17: catalog folders, config.json categories and the new-source form must list the same categories. A folder missing from the config vanished from the homepage without a word. - V18: a link fragment into a Markdown file must name one of its headings. All 13 in the repo resolve. - The binary-file scan skips hidden folders and _scratch, which are not repo content (it failed on local git worktrees under .claude/). Markdown renderer: - Link hrefs keep one level of balanced parens (Foo_(bar)). - Italic that would cross a bold boundary stays literal instead of producing <strong><em></strong></em>. - Heading ids are unique on the page and avoid the template's own ids. Tests: 21 lib assertions and 19 check assertions added. Fixes #7 Fixes #8 Fixes #9 Fixes #10 Fixes #11 Fixes #12 Fixes #13 Fixes #14 Fixes #15 Fixes #30 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
- package.json (no dependencies) with test, validate, build, check (all of them in CI order), counts, new-entry and serve. The README's local checks now use it; before, they left out node site/lib/lib.test.mjs, which CI runs. - node site/new-entry.mjs <category> <id> copies the template with the id, category and date filled in, refuses an id used anywhere in the catalog, starts at needs-review, and prints the remaining steps. - node site/sync-counts.mjs rewrites both category count tables, the badge, "Browse N sources", "searches all N entries" and expectedEntryCount from the catalog. Adding an entry took about seven hand edits across three files; it now takes the entry, its README row and this command. - V6 also checks "searches all N entries", which nothing checked. - README layout lists stacks/, site/lib/, the two scripts and package.json; .gitignore ignores node_modules/. Fixes #6 Fixes #29 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
- TEMPLATE.md: license_spdx is a real line. Copied as it was, the template failed V3 (CC0 maps to CC0-1.0, license_spdx absent). - CONTRIBUTING: the steps use new-entry and sync-counts, and say what the validator enforces that was undocumented: attribution_string is required when attribution_required is true, verified may not be newer than the newest Evidence date (V8), deprecated entries need a "- Deprecated:" line (V9), url must be http(s), dates must be real, repeated keys and emoji are rejected. - PR template: the category README row, sync-counts, stacks, and npm run check. - The three design specs say implemented, not awaiting review. - SECURITY.md: private vulnerability reporting is enabled; say so. Fixes #27 Fixes #28 Fixes #31 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
r04 was a review-batch marker that leaked into the published tags of 15 entries. It is not a descriptive tag, so it is dropped. No other field changes. Fixes #35 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
Data half of the subcategory cleanup: - tiles -> tileset (the kept spelling in CONTRIBUTING) - pixel-art -> pixel - ir -> impulse-responses - base-mesh -> base-meshes (the spelling CONTRIBUTING uses as its example) - drop gui where ui is also set - drop the 2d subcategory inside the 2d category - drop public-domain as a subcategory: it is a licence, and each of the four entries already carries descriptive subcategories (archival, stock-footage, planetary, images, video, audio) No README or config referenced the old values. The alias table in the checks is left for a separate change. Refs #34 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
- game-ok -> games-ok - ps1 -> psx (psx is already in two entry names) - godot rule: every Godot-specific entry carries godot; an entry that targets Godot 4 also carries godot-4. So the 19 godot-4 entries gain godot, and a godot filter now finds all Godot entries. The nine godot-only entries are unchanged (several are Godot 3 or mixed). - drop cc0 from blenderkit and universal-lpc-generator (licence is varies) and public-domain from openclipart (licence is CC0), since those tags contradicted the licence field. No licence fields changed. The wider licence/publisher tag question in the issue is left open. Refs #36 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
- JPEG -> JPG (nasa-image-video-library), matching texture-ninja - godot-project -> Godot, the engine-target spelling CONTRIBUTING uses - glTF KHR_draco -> glTF on google-draco (Draco is a glTF extension; the body already names KHR_draco_mesh_compression) - GPL -> gpl-palette on lospec, so a GIMP palette no longer reads as a licence - add glTF beside GLB where the entry shows GLB is what is offered (quaternius-universal-animation-library 1 and 2, and 3dmodelscc0-melee-weapons, whose listing points at a GLB mirror). GLB is binary glTF. 3dmodelscc0-city and 3dmodelscc0-guns are left as they are: their bodies say the listing does not name a format. - ktx and ktx2 on ktx-software are kept: KTX 1 and KTX 2 are distinct container formats and the tool handles both. Refs #37 (the canonical format list and its check are still open) Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
Each pair shares a rights-holding publisher, so the entries now group: - pixabay-audio, pixabay-videos -> Pixabay - sky3d, terrain3d -> TokisanGames - ansimuz-sunnyland, ansimuz-industrial-parallax -> ansimuz None of these publishers was already spelled another way in the catalog. The license_spdx half of the issue is not touched here. Refs #39 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
The repo moved from GDQuest to gdquest-demos. Checked 2026-09-25: github.com/GDQuest/godot-3d-mannequin redirects to github.com/gdquest-demos/godot-3d-mannequin, and the GitHub API reports that full name (not archived). Only url changes; the Evidence section does not link the old URL. The versioned zip and http-only URLs in the issue are not touched here. Refs #32 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
- V13 folded only a trailing "s", so base-mesh and base-meshes (two entries each) passed as different values. It now joins an -es or -ies plural to its singular when that singular is in use, and only after a sibilant for -es, so "shades" never meets a "shad". - V19: site/value-aliases.json records the spellings the catalog metadata pass merged (tiles -> tileset, pixel-art -> pixel, ir -> impulse-responses, gui -> ui, base-mesh -> base-meshes, ps1 -> psx, game-ok -> games-ok, JPEG -> JPG, godot-project -> Godot), per field, and forbids public-domain as a subcategory. A tag shaped like an internal review marker (r04) is rejected. - CONTRIBUTING names the kept spellings and the alias file. Fixes #34 Fixes #35 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
site/check-links.mjs fetches every non-deprecated entry's url (8 at a time, 20 s timeout, one retry) and reports dead links, sources that moved to another domain or GitHub repository (the gdquest mannequin move stayed on github.com and would have been missed otherwise), and entries verified more than a year ago. 401/403/429 answers are listed for a manual look but never raise the issue alone: on 2026-09-25 seven sites refused the checker while serving people fine. links.yml runs it every Monday and opens or updates a single issue titled "Link check: N sources need a look", labelled correction. It edits no entry. Local: npm run links. Today's run: 317 checked, none dead, none moved, none stale. Fixes #4 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
robots.txt is only read at a host's root, so the Sitemap line in /Free-Game-Dev-Assets/robots.txt is never seen. The homepage now carries <link rel="sitemap">, and site/README.md says the step that actually gets it read: submitting it once in Search Console and Bing Webmaster Tools, which only the maintainer can do. Fixes #24 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
blender-ellie-poses and blender-human-base-meshes linked versioned zips (v2.0.0, v1.4.1) that 404 once Blender replaces them. Both now point at https://www.blender.org/download/demo-files/#assets, whose Asset Bundles section lists both (read 2026-09-25), and which both entries already cite. Only url changes. With the gdquest-3d-mannequin move (earlier commit), this closes the URL fixes. The http-only makehuman and cmu-mocap pass the new url check (V16), and the sites that refuse robots are listed by the weekly link check for a manual look. Fixes #32 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
Each query word now has to start a word in the entry's text, so "ui" no
longer finds "build" or "guide" and "art" no longer finds "earth"
(?q=ui drops from 106 to 52 entries). The plural fallback ("buttons"
finds the "button" tag) is kept.
Search text is split into three fields, normalised once at load: name
and tags, other metadata, summary. Under the default sort a search
ranks name and tag hits above metadata hits above summary-only hits,
then orders by name; the sort option now says so.
Fixes #16
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
Filtering used to compute every entry's search text twice per keystroke (once for the chip counts, once for the grid) and rebuild about 5,500 grid nodes through innerHTML. Now: - the search text is normalised once at load (previous commit) and each change makes one pass over the catalog, shared by the chip counts and the grid; - the grid adopts the prerendered rows and headings and keeps one node per entry and heading; deprecated entries, which the build leaves out, are rendered once. A change toggles `hidden` and moves nodes only when the order changes (another sort, or a ranked search); - typing waits 120 ms for a pause; every other control applies at once. A filter change now takes about 4 ms including layout in a desktop Chromium, down from about 124 ms reported in the issue. Fixes #17 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
Removing a filter chip, "Clear all" or the empty-state reset re-renders the button away, and focus fell back to the document body. Focus now moves to the chip that took the removed one's place, or, when none is left or everything was cleared, to the result count, which takes programmatic focus (tabindex="-1") and shows a focus ring for keyboard users. Fixes #18 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
Category headings and entry titles were both h3, so the catalog's outline was flat. Entry titles are now h4 under the h3 category headings, in the prerender (build.mjs, the title tag only) and in app.js alike. A flat list (another sort, or one category) has no category headings, so it gets a visually hidden h3, "Matching entries", and the outline never skips a level. The result count, which is the live region, now reads "52 of 319 entries shown" instead of "52 / 319". The prerendered no-script text still uses the short form; that string lives in build.mjs outside the heading markup and is left for a separate change. Fixes #19 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
The chip counts were faded with opacity (0.7, and 0.45 for an empty category), which took them to 2.92:1 in light and 4.25:1 in dark. They now use the chip's solid text colour, the muted token: 5.29:1 light, 7.52:1 dark, measured in the browser on every count. The count is set in the mono face so it still reads apart from the label, and an empty category is marked by a dashed outline and its 0 instead of by fading. Fixes #20 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
Under pointer: coarse, "Open source" and "Entry and evidence" were about 17px tall inside the card-wide title link, so a near miss opened the entry page. They now get 13px of padding cancelled by an equal negative margin: a 45px hit area with no change to the card's layout (checked with hit tests across the full height in a touch-emulated 360px Chromium). Chips, checkboxes, the selects and the legend toggle get the 44px minimum they already had on narrow screens on every touch screen. Fixes #21 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
readUrl() trusted the query string, so ?view=bogus or ?cat=nope showed 0 results with a blank select and ?sort=foo showed a blank sort and an unsorted list. cat, sort and view are now checked against the category keys, SORTS and the perspective list, and the boolean flags accept only 1 or 0. Anything else keeps its default, and the first apply() rewrites the URL without it. Fixes #22 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
data.js and app.js were parser-blocking at the end of the body. Both are now deferred: they still run in order before DOMContentLoaded, and the rows they hydrate are prerendered, so the page is complete before they run. The legacy #entry-<id> redirect and hash jumps still work. Google Fonts already loads with display=swap behind preconnect hints on every page, so nothing changes there. Self-hosting the two families, which the issue also suggests to drop the third-party request, is left for a separate pass. Fixes #23 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
"Commercial OK" deliberately keeps commercial: varies aggregators, but the only on-page explanation was a hover-only title, which touch and keyboard users never see. The title is gone. While the filter is on, a note under the filters says it keeps per-file review sources and asks the reader to check the licence of each file; the checkbox is described by that note (aria-describedby), and its active-filter chip now reads "commercial OK or per-file review". A separate "include per-file sources" toggle was the other option in the issue; the note keeps the filter's documented meaning unchanged. Fixes #25 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
At 360px the filter panel was about 530px of chips and checkboxes
between the search box and the first entry. At 640px and below the
category chips and the status, terms, view and sort controls now fold
behind a "Filters" button (aria-expanded, aria-controls), which shows
how many filters are set, e.g. "Filters (2)". The search box, the
result count (the live region), the commercial note and the
active-filter chips stay visible. The folded panel is 163px tall at
360px. app.js does the folding, so a page without the script keeps the
panel open; wider screens never show the button.
The jump link the issue asks for is already in the hero ("Browse
catalog"), next to "Catalog" in the top nav and the skip link.
Fixes #26
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
"Catalog" in an entry page's breadcrumb went to ../../#catalog, which dropped the reader's search and filters. The homepage now keeps its current query string in sessionStorage whenever it rewrites the URL (and clears it when nothing is set), and entry.js points the breadcrumb link, marked data-back-to-results, at ../../?<query>#catalog. Without the script or the storage the link stays the plain catalog link. entry.js now loads on every entry page, not only on those with a credit line to copy; the copy button still appears only where there is one. The lib tests say so, and credit() loses its now unused script flag. Fixes #44 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
A mistyped address such as /entry/kenny-ui/ now gets up to five
suggestions ("Kenney UI Pack" first for that one) and a link to search
the catalog for the same words (?q=kenny%20ui). The new
site/public/not-found.js reads the missing path, compares it by letter
pairs with each entry's id and name, prefers live entries over
deprecated ones, and builds the list with DOM calls, never innerHTML.
With no close match only the search link appears; without the script
the page is as before.
build.mjs changes only in the 404 template: an empty #suggestions slot
and deferred data.js and not-found.js, loaded from the site root like
the page's stylesheet.
Fixes #46
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
Before the script runs, the count said "317 / 319"; the script writes "317 of 319 entries shown". The prerender now says the same, so screen readers and no-script readers get the full sentence too. Refs #19 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
Three entries had attribution_required true although their licences only require a licence or notice to travel with redistributed copies. Each was re-read live on 2026-09-26; the vocabulary classes all three licence values as "notice", so no waiver marker is needed. - material-symbols (Apache-2.0): Google's README says "We'd love attribution in your app's *about* screen, but it's not required." Section 4(a) of LICENSE requires a copy of the licence with redistributed copies; the repository has no NOTICE file. Set false, dropped the credit string, added a Notes bullet on the notice duty. - ms-building-footprints (CDLA-Permissive-2.0): section 2.1 only asks that the agreement text travel with shared Data, and 3.1 puts no obligation on Results. The README asks for no credit or citation. Set false, dropped the credit string, added a Notes bullet. - microsoft-rocketbox (MIT): LICENSE.md requires the copyright and permission notice in all copies; the README's citation request is for research use only. Set false, dropped the credit string (it was a "keep LICENSE.md" instruction, now in Notes). Each entry gets dated Evidence lines and verified 2026-09-26. Fixes #33 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
Swept the 2D entries lacking camera_perspective or grid_dimensions and read each source page live on 2026-09-26. A value was set only where the page says it in words. - bondoki-rotating-gems: grid_dimensions 52x52. OpenGameArt page: "size per tile is 52x52 pixels". - lpc-revised-basics: camera_perspective isometric_3_4. The submission names the author's GitHub repository as the home of the collection; its README says "a 32-pixel style, with a three-quarters (top-down) perspective". Recorded in Notes. No grid set: "32-pixel style" is not a stated frame or tile size for this pack. Left unset because the page states no view or size: the Kenney card, board game, puzzle and pixel vehicle packs (Kenney asset pages list tags, file count and licence only), kenney-roguelike-characters and ansimuz-sunnyland grids, sylly-gem-match-3, glitch-archive and universal-lpc-generator. Left unset because no single value fits: publisher and aggregator entries (opengameart, craftpix, penzilla, pixel-frog, screaming-brain-studios grid, gameart2d-freebies), sparklin-superpowers (platformer and top-down packs in one repo), kenney-1-bit-pack (multi-perspective, per the review ledger), and the palette entries lospec and paleto-vol01. Refs #41 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
4 tasks
#48 fixed impossible dates (#10) independently. Keep its isRealDate, which also handles years 0000-0099 and non-strings, and its messages ("is not a real YYYY-MM-DD date"); drop this branch's copy. Keep this branch's evidenceDates (dates inside URLs ignored) and latestAllowedDate. Both test suites pass together: 101 check and 296 lib assertions. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ
This was referenced Sep 26, 2026
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.
Fixes from the 2026-09-25 repo review (issues #1 to #47). One commit per issue or per interlocked group; each commit body says what changed and why.
npm run check(tests, validate, build) passes.CI
.nvmrc, checkout/setup-node v7, pages artifact/deploy v5, Dependabot for actions; Pages callsci.ymlinstead of repeating it (ci: Node 20 is EOL; bump actions, add dependabot, dedupe the two workflows #2).links.yml,site/check-links.mjs) that opens or updates onecorrectionissue: dead links, sources moved to another domain or GitHub repo, entries verified over a year ago (ci: scheduled link-rot and licence-change check #4). First run: 317 checked, none dead, moved or stale.Build and checks
_and#("Rig_Medium", not "RigMedium"); five summaries change (site: entry summaries strip literal_and#(e.g. "RigMedium", "C#" -> "C") #7).urlscheme is never checked (javascript:/data: render as live links) #9), real calendar dates (validate: impossible dates pass (2025-13-01, 2026-02-30) #10), V17 folders/config/issue form list the same categories (validate: a catalog folder missing from config.categories silently vanishes from the site #11), Evidence dates inside URLs ignored (checks: evidence dates are matched anywhere, including inside URLs #13), a day of time-zone slack (validate: allow a day of slack forverifieddates east of UTC #15), V18 heading anchors resolve (validate: relative-link checker ignores #anchors #30), V19 retired spellings and internal tags, and -es/-ies plural folding (checks: normalize subcategory vocabulary; spelling check misses -es plurals #34, catalog: remove leaked internal tagr04from 15 entries #35).Tooling and docs
package.jsonscripts (npm run check),site/new-entry.mjs,site/sync-counts.mjs(dev: add package.json scripts and make local checks match CI #6, dev: adding one entry takes ~7 hand edits; derive counts or add a scaffold script #29).videoin the new-source form, and thecorrection/new-sourcelabels now exist (repo: issue-template labels don't exist and new-source form lacks the video category #5).Site
Word-start search ranked by name and tags (#16), rows toggled instead of rebuilt (#17), focus kept after removing a filter (#18),
h4card titles and a full-sentence count (#19), contrast (#20), touch targets (#21), URL params validated (#22), deferred scripts (#23), visible per-file note on Commercial OK (#25), folding filters on phones (#26), back-to-results breadcrumb (#44), 404 suggestions (#46), sitemap link (#24).Catalog
r04tag, merged subcategory synonyms, one spelling for duplicate tags and formats, publishers on six entries, three URLs moved to durable pages (catalog: fix URLs that moved, will break, or are http-only #32, checks: normalize subcategory vocabulary; spelling check misses -es plurals #34 to catalog: normalize format names #37, catalog: fill obvious publisher / license_spdx gaps #39).Not in this PR
#3 (branch protection, deferred), #36, #37 (canonical format list), #38, #40, #41 (remaining fields: sources do not state them), #42, #43, #45, #47. See the new section in
docs/review-ledger.md.After merge: submit
sitemap.xmlin Search Console and Bing Webmaster Tools.🤖 Generated with Claude Code
https://claude.ai/code/session_01Wc67NX9MM964uaVGn4bpZJ