chore: strengthen agent onboarding, lint pinning and CI structure - #37
Merged
Conversation
Markdown lint ran through the GitHub action, which pins markdownlint-cli2 internally. Nothing told a contributor which version that was, so running `npx markdownlint-cli2` locally pulled the latest instead: 0.23 enforces MD060 (table-column-style) and reports ~46 violations on tables CI considers clean. That is a trap, and it already cost time in this repo. Move the version into package.json as an exact devDependency, matching what the action was already resolving, and put the globs in an npm script so local runs and CI cannot disagree: npm run lint:md markdownlint over *.md, docs/**, i18n/** npm run lint lint:md + typecheck npm run verify lint + build (mirrors CI end to end) Pinning to the version currently in effect keeps this a pure guardrail change with no new violations. Upgrading later means either fixing the MD060 tables or disabling that rule, and should be its own PR. Verified: `npm run verify` exits 0, linting 52 files with 0 errors. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The workflow had three problems beyond naming. `npm install` with a committed lockfile can resolve differently from what the lockfile pins, so CI was not reproducible. Switched to `npm ci`, and added setup-node's npm cache while there. The build ran inside the deploy job, so on a pull request the check that actually verified the build was reported as "Deploy to GitHub Pages" — misleading, since nothing was being deployed. Build is now its own job, scoped to pull requests; deploy is scoped to main pushes and still builds what it publishes. No status check was required by branch protection, so renaming is safe. That deploy job also checked out shallow, while docusaurus is configured with showLastUpdateAuthor and showLastUpdateTime. Those read git history, so with depth 1 every page reported the same last-updated date. Both jobs that build now use fetch-depth: 0. Also scope the push trigger to main so forks stop running the full workflow on every branch push, cancel superseded pull request runs (but never an in-flight deploy), and drop the default token down to contents: read except in deploy. Lint now runs `npm run lint`, the same command contributors run locally. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
AGENTS.md described the repository accurately enough but left out everything an agent actually needs to avoid breaking things, and a few details were wrong (typecheck is `tsc`, not `npx tsc --noEmit`). Add what was missing: - A single `npm run verify` as the definition of done, with the underlying commands spelled out - The four traps this repository has already produced: unpinned markdownlint reporting rules CI does not enforce, MD013's non-strict exemption making "max 200 characters" not literal, byte-vs-character counting inflating CJK line lengths, and mermaid being unverifiable from build output because it renders client-side - Content state: 13 of 24 pages are placeholders, with the command to list them, so an agent does not mistake a stub for a real page - The en/zh mirroring invariant and how to check it, since Docusaurus falls back to English and the build stays green when it is violated - The Chinese-prose-in-the-English-tree inconsistency, flagged as something not to copy - Which sidebar categories are autogenerated and which need editing - A do-not-stack-PRs rule, with the zncdatadev#33/zncdatadev#35/zncdatadev#36 breakage as the reason Also correct the "max 200 characters" rule, refresh the CI table for the new job layout, and point the PR template at `npm run verify`. CLAUDE.md is a symlink to AGENTS.md (git mode 120000, not a copy) so both conventions resolve to one file. Note for Windows contributors: with core.symlinks disabled git materialises it as a text file containing the target path. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Summary
Makes it easier for an AI agent (or a new human contributor) to pick up this repository and not break it. Three commits, reviewable independently.
Changes
chore: pin markdownlint and add lint/verify scriptsMarkdown lint ran through
markdownlint-cli2-action, which pinsmarkdownlint-cli2internally. Nothing told a contributor which version that was, so runningnpx markdownlint-cli2locally pulled the latest instead — 0.23 enforcesMD060(table-column-style) and reports ~46 violations on tables CI considers clean. That trap already cost time here.The version now lives in
package.jsonas an exact devDependency, matching what the action was already resolving, and the globs live in an npm script so local and CI cannot disagree:npm run lint:md*.md,docs/**,i18n/**npm run lintlint:md+typechecknpm run verifylint+build— mirrors CI end to endPinning to the version already in effect keeps this a pure guardrail change with no new violations. Upgrading later means either fixing the
MD060tables or disabling the rule, and should be its own PR.ci: split lint, build and deploy into separate jobsFour fixes:
npm install→npm ci. With a committed lockfile,npm installcan resolve differently from what is pinned. Added setup-node's npm cache while there.showLastUpdateAuthor/showLastUpdateTimeare enabled. Those read git history, so at depth 1 every page reported the same last-updated date. Both building jobs now usefetch-depth: 0.pushis limited tomainso forks stop running the whole workflow on every branch push; superseded PR runs cancel but an in-flight deploy never does; the default token drops tocontents: readexcept in deploy.No status check was required by branch protection (verified via the API — only
required_approving_review_count: 1), so renaming jobs is safe.docs: rewrite AGENTS.md for agent onboarding, symlink CLAUDE.mdAGENTS.mddescribed the repository but omitted most of what is needed to avoid breaking it, and a few details were wrong (typecheckistsc, notnpx tsc --noEmit). Added:npm run verifyas the definition of doneMD013'sstrict: falseexemption making "max 200 characters" not literal; byte-vs-character counting inflating CJK line lengths ~3x; mermaid being unverifiable from build output because it renders client-sideautogeneratedand which need hand-editingCLAUDE.mdis a symlink toAGENTS.md— git mode120000, not a copy — so both conventions resolve to one file.Testing
npm run verifyexits 0 — 52 files linted, 0 errors, both locales builtnpm cisucceeds from a cleannode_modulesLint(always),Build(PR only),Deploy to GitHub Pages(push only, needslint)CLAUDE.mdresolves toAGENTS.md(identical content, symlink preserved in the index)gh-pagesbranch exists,architectureis a manual sidebar entryNote for Windows contributors
With
core.symlinksdisabled, git materialisesCLAUDE.mdas a text file containing the pathAGENTS.mdrather than following it. Mentioned in the commit body.🤖 Generated with Claude Code