Skip to content

The fumadocs-core patch header says a version bump drops the pin silently; pnpm 10.28.2 refuses the stale pin when the lockfile is regenerated #284

Closed

Description

@hotlong

Found while measuring #282's mechanism assumptions (session session_01FeA1nwBz1ohH65dvffUGKr). Observation only; nothing here is changed by #282's PR.

What the patch header says

patches/fumadocs-core@16.8.12.patch, section "ON A VERSION BUMP": the pin "is pinned to 16.8.12 by the key in package.json, so any other version simply does not receive it and the defect returns silently". #282's card table repeats it ("the version moves: the pin simply does not match, no patch is applied, install succeeds").

What pnpm 10.28.2 actually does, measured

On a detached tree at cb0c146 with #239's one-line change (apps/docs/package.json: fumadocs-core 16.8.12 to 16.15.2):

install exit what it printed
pnpm install --frozen-lockfile (lockfile not yet updated) 1 specifiers in the lockfile don't match
pnpm install --no-frozen-lockfile 1 ERR_PNPM_UNUSED_PATCH The following patches were not used: fumadocs-core@16.8.12
pnpm install --lockfile-only 1 same ERR_PNPM_UNUSED_PATCH
pin deleted from root package.json, then pnpm install --no-frozen-lockfile 0 nothing; 16.15.2 installed unpatched
lockfile regenerated with --config.allow-unused-patches=true (exit 0, one WARN), then pnpm install --frozen-lockfile 0 nothing: the frozen install does not check for an unused patch

So a bump is loud where the lockfile is regenerated, and the header's "silently" is wrong for that path. It is silent on two paths: deleting the pin, which is the first remedy pnpm's own error text offers ("Either remove them from patchedDependencies or update them"), and a lockfile produced with unused patches allowed, which CI's --frozen-lockfile then accepts. On the pin-deleted tree, a full build puts the defect back at 67 numeric character references and 4 of 661 malformed link targets in both llms consumers, and #282's gate reddens on it.

Why it matters beyond the comment

Suggested fix (not applied)

Correct the "ON A VERSION BUMP" paragraph of the patch header to say what is measured above. It sits under patches/, outside #282's file surface, so it is filed here rather than folded in.


Generated by Claude Code

Activity

  1. added theissue type on Sep 24, 2026
  2. hotlong commented on Sep 24, 2026

    @hotlong
    ContributorAuthor

    First-touch grading: promoted to pm:queue, Task, size S. Graded by the repo:objectos seat (objectstack#9831), session session_01FeA1nwBz1ohH65dvffUGKr.

    Why queue rather than close. The patch header is the first thing someone reads when a fumadocs-core bump goes red. Right now it tells them to expect silence, and the error they will actually get points them at deleting the pin. #285 (landed as c2d1181) now turns the delete-the-pin path red at Locale surface and says to regenerate the patch. Even so, the file that documents the pin should not contradict the measured behaviour. This restores declared = actual in the text a reader relies on at that moment, with no behaviour change.

    Scope, for whoever takes it:

    • Correct the "ON A VERSION BUMP" paragraph of patches/fumadocs-core@16.8.12.patch to match the measured table in this card's body. Only what was measured: the Dependabot-updater inference stays marked as an inference or is left out.
    • ⚠️ Premise to check first, not assume: pnpm keys the patch by a content hash, so editing the header may change pnpm-lock.yaml's patchedDependencies hash. If so, the lockfile update belongs in the same PR, done by the installed pnpm (10.28.2), never by hand. A clean pnpm install --frozen-lockfile must then exit 0, and the patch must still apply (the patch_hash= virtual-store path plus the peek line on disk, the same evidence fix(docs): pin the fumadocs-core peek omission that encodes markdown as entities #281 used).
    • ⚠️ pnpm-lock.yaml is a build input, so the merge publishes production. #285's gate must read 0 references and 0 malformed targets on the PR.

    Fold-or-serial. This shares patches/ with any PR that regenerates the patch for a newer fumadocs-core (Dependabot #239 is the live candidate). If such a PR is authored first, fold this paragraph into it. Every fold gate passes: same file, the same header rewritten, and one reviewable change. Otherwise this card runs on its own. It is currently serial behind #141 for a transport reason only: this session can push to one branch. The two share no files.


    Generated by Claude Code

  3. self-assigned this
    on Sep 24, 2026
  4. hotlong commented on Sep 24, 2026

    @hotlong
    ContributorAuthor

    Claim: PM loop, repo:objectos seat, R1 (third dispatch)
    Session: session_01FeA1nwBz1ohH65dvffUGKr
    Branch: claude/pm-dispatch-objectos-ju9td1. This is the session's one designated push branch. #141's work on it landed via PR #286 as 7004d3d, so the branch restarts from origin/main.
    Worktree: objectos-issue-284
    Domain: n/a (single-lane repo)
    File surface: patches/fumadocs-core@16.8.12.patch (header comment only; the diff hunks stay byte-identical) and pnpm-lock.yaml (only the patchedDependencies hash, written by pnpm). Stop on breach and explain in the report.
    Container & model: S, mode:subagent, model: opus. The edit is small, but it is a claim about tool behaviour, and it must say only what was measured. Its hazard is a lockfile change that publishes production.
    Clause-②: no
    Serial constraints cleared: patches/ and pnpm-lock.yaml are touched by no open PR except Dependabot #239. #239 is not being worked, so there is nothing to fold into; if it ever is, see the fold note in 5808353328. Nothing else is in flight: #141 was re-armed to pm:on-hold, and #282 is closed.

    Premise re-read on origin/main @ 7004d3d. The header at patches/fumadocs-core@16.8.12.patch:49 is headed "ON A VERSION BUMP, THIS PATCH IS EXPECTED TO FAIL LOUDLY". Two lines below, its body says "the defect returns silently", so the header contradicts itself before it contradicts pnpm. pnpm-lock.yaml:7-10 carries patchedDependencies → fumadocs-core@16.8.12 → hash: 042796c0…, the same hash as the patch_hash= store path PR #281 recorded. Editing the file is therefore expected to move that hash.


    Generated by Claude Code

  5. hotlong commented on Sep 24, 2026

    @hotlong
    ContributorAuthor

    Claim (os-dev, dispatched by the repo:objectos PM seat, objectstack#9831)
    Session: session_01FeA1nwBz1ohH65dvffUGKr
    Branch: claude/pm-dispatch-objectos-ju9td1 (restarted from origin/main @ 7004d3d; local name issue-284-local)
    Worktree: /home/user/objectos-issue-284
    File surface: patches/fumadocs-core@16.8.12.patch (the "ON A VERSION BUMP" header section only; diff hunks byte-identical) and pnpm-lock.yaml (only what pnpm 10.28.2 itself rewrites). Assignee untouched.


    Generated by Claude Code


    Generated by Claude Code

  6. hotlong commented on Sep 24, 2026

    @hotlong
    ContributorAuthor

    os-dev-report
    {
    "issue": 284,
    "status": "done",
    "branch": "claude/pm-dispatch-objectos-ju9td1",
    "pr": "#287",
    "premise_still_valid": true,
    "gates": {
    "final_commit": "2d9ffcb",
    "local": [
    { "cmd": "NEXT_PRIVATE_STANDALONE=true pnpm turbo run build --force (via os-verify-lock.sh)", "exit": 0, "verdict": "Tasks: 1 successful, 1 total / Cached: 0 cached, 1 total; os-verify-lock: VERDICT command-exit 0" },
    { "cmd": "node .github/scripts/check-locale-surface.mjs", "exit": 0, "verdict": "llms-full.txt | 1 | 1 | 0 | 661 | 0 ; llms.mdx | 79 | 79 | 0 | 661 | 0 ; fumadocs-core resolved by apps/docs: 16.8.12 · patch pinned to: 16.8.12 ; ✓ every advertised URL has a source file ... and neither llms consumer carries a numeric character reference or a malformed link target" },
    { "cmd": "pnpm turbo run test --force (via os-verify-lock.sh)", "exit": 0, "verdict": "✓ 7 self-test(s) passed; os-verify-lock: VERDICT command-exit 0" },
    { "cmd": "node .github/scripts/check-node-floor.mjs", "exit": 0, "verdict": "✅ Every declared floor clears what the dependency tree requires, and the declarations agree. (430 engines blocks scanned)" },
    { "cmd": "grep -naP control-byte scan on the patch file", "exit": 1, "verdict": "0 matches; header lines all ASCII, max 84 columns" }
    ],
    "ci": {
    "run": "https://github.com/objectstack-ai/objectos/actions/runs/35964962677",
    "head_sha": "2d9ffcba31e863dba1e1f6604a7149a7e04df0b9",
    "jobs": { "build": "success", "Node floor": "success", "Deploy docs": "skipped" },
    "build_steps": { "pnpm install --frozen-lockfile": "success", "Locale surface": "success", "pnpm turbo run test": "success", "Worker bundle fits the size budget": "success", "The docs site renders — smoke-check a local preview": "success", "Upload the Worker bundle": "skipped" },
    "locale_surface_lines": "llms-full.txt | 1 | 1 | 0 | 661 | 0 ; llms.mdx | 79 | 79 | 0 | 661 | 0 ; fumadocs-core resolved by apps/docs: 16.8.12 · patch pinned to: 16.8.12",
    "smoke_line": "✓ smoke: 4 page(s) rendered against http://127.0.0.1:8792, negative control demonstrated red",
    "size_line": "Total Upload: 58556.67 KiB / gzip: 8800.70 KiB; Worker bundle size — within budget; headroom to budget 2883.33 KiB"
    }
    },
    "measurements": {
    "hash_before": "042796c0fe0ae66ccc2f1eadd4df4b8399a43c39c49facd3a0d938b182ed8d79 (lockfile on origin/main 7004d3d; equals sha256sum of origin/main's whole patch file)",
    "hash_after": "a88318fc3b23c44ea3645ae68c43af3a905e0d00d6bc2fcefe3a7b625b3dfe57 (written by pnpm 10.28.2; equals sha256sum of the edited whole patch file)",
    "assumption_1_hash_moves": "confirmed: the pnpm patchedDependencies hash is the sha256 of the whole patch file, so a header-only edit moves it",
    "frozen_install_on_old_lockfile": "exit 1: ERR_PNPM_LOCKFILE_CONFIG_MISMATCH Cannot proceed with the frozen installation. The current "patchedDependencies" configuration doesn't match the value found in the lockfile",
    "regeneration": "pnpm install --lockfile-only, pnpm 10.28.2, exit 0",
    "lockfile_diff": "git diff --numstat: 9 9 pnpm-lock.yaml. The hash occurs 9 times: 1 patchedDependencies hash plus 8 patch_hash= segments in the dependency keys of fumadocs-core, fumadocs-mdx and fumadocs-ui. origin/main lockfile with sed s/OLD/NEW/g is byte-identical to the regenerated file (cmp exit 0); old-hash occurrences 9 before, 0 after; new-hash occurrences 9 after",
    "post_regeneration_install": "node_modules wiped (root and apps/docs; tools/ci-scripts had none), pnpm install --frozen-lockfile exit 0",
    "patch_applied_evidence": "resolved through apps/docs: node_modules/.pnpm/fumadocs-core@16.8.12_patch_hash=a88318fc3b23c44ea3645ae68c43af3a905e0d00d6bc2fcefe3a7b_96ea1a842d0433803cdfc29229a4f307/node_modules/fumadocs-core/dist/mdx-plugins/stringifier.js (only fumadocs-core dir in the store); line 81: if (handler.peek) wrapped.peek = handler.peek; count 1; pristine anchor count 0",
    "hunks_byte_identical": "first diff --git line to EOF: origin/main at byte 3407, branch at byte 4840; both 1357 bytes; both sha256 7501cfc05abd506d346be71b686133008a89a2af78d70d33eea33c4e9bfce8d3; cmp -l lists 0 differing bytes, cmp exit 0",
    "reformat_claim_remeasured": "npm pack fumadocs-core@16.8.12 and @16.15.2: diff of dist/mdx-plugins/stringifier.js shows only one if at line 28 going from 3 lines to 5; git apply --check of this patch on 16.15.2 exit 0 with Hunk #1 succeeded at 68 (offset 2 lines)"
    },
    "files_changed": ["patches/fumadocs-core@16.8.12.patch", "pnpm-lock.yaml"],
    "deviations": [
    "PM assumption 2 was partly wrong: the lockfile change is not one line but 9. The same hash substitution appears in 9 places, and the substitution proof shows nothing else changed.",
    "The header keeps the old sentence about 16.15.x reformatting an if, reworded to what this session measured. That measurement is not in #284's table. The header makes no claim about how pnpm's own patcher handles the 2-line offset.",
    "The header does not mention the Dependabot-updater inference.",
    "The header says the Locale surface gate was measured red only on the pin-deleted path. It makes no claim for the allow-unused-patches path, which #284's table does not show being built.",
    "A scratch hunk dump was briefly written into the worktree as patches/fumadocs-core@16.8.12.patch.hunks.bin by a path bug. It was removed before staging and never committed; git status showed only the two modified files at commit time.",
    "CI job logs were read through the GitHub MCP get_job_logs tool, because the curl log download got a proxy 403 on the blob host."
    ],
    "open_questions": [],
    "out_of_scope_findings": []
    }


    Generated by Claude Code

  7. hotlong commented on Sep 24, 2026

    @hotlong
    ContributorAuthor

    ACCEPT: PR #287. Driving to landing.

    Checklist, read on GitHub. The PR is a draft against main, and its first line is Fixes #284. It changes 2 files: the patch header (+35/−10) and pnpm-lock.yaml (9/9). Neither file is on the governed surface. Each check was read by its own conclusion on head 2d9ffcb: build succeeded and Node floor succeeded. Deploy docs was skipped, which is correct for a PR event. Ownership & freshness did not run, and that is also correct: its path filter is content/docs/**, which this PR does not touch. The check is absent, not failed.

    Every claim re-derived by the seat on the fetched branch:

    claim seat's own reading
    The diff hunks are byte-identical sha256 of everything from the first diff --git line to EOF is 7501cfc0… on both origin/main and the branch
    The lockfile hash is the patch file's sha256 sha256sum of the branch's patch file is a88318fc…3dfe57, and the branch lockfile contains that hash 9 times and the old hash 0 times
    The only lockfile change is the hash substitution substituting the old hash with the new one in origin/main's lockfile gives a file byte-identical to the branch's (cmp exit 0)

    The header now says only what was measured. It states that the lockfile regeneration is loud, names the two quiet paths, and says the Locale surface gate was measured red on the pin-deleted path only. It explicitly does not claim that for the allow-unused-patches path, and it leaves the unmeasured Dependabot inference out entirely. The old "two hunks up" was wrong, because the patch has one hunk. It was replaced with a measured git apply --check offset (2 lines on 16.15.2), which is the fact the next person to regenerate this patch needs.

    Deviation accepted: my assumption was that only one lockfile line would change. It was 9. The hash also appears inside the patch_hash= segments of the fumadocs-core / fumadocs-mdx / fumadocs-ui dependency keys. The substitution proof covers all nine.

    Path check before flipping ready: nothing governed. ⚠️ pnpm-lock.yaml is a build input, and merging publishes production. The pre-merge render gate and Locale surface (0/0, pinned = resolved = 16.8.12) were both green on this head.


    Generated by Claude Code

  8. added a commit that references this issue on Sep 24, 2026
    2e6f0e6
  9. hotlong commented on Sep 24, 2026

    @hotlong
    ContributorAuthor

    Landed and published. PR #287 was squash-merged as 2e6f0e6. Readings come from CI run 35966069203's own jobs:

    • build passed. pnpm install --frozen-lockfile passed on the regenerated lockfile, and Locale surface and the pre-merge render check both passed.
    • Deploy docs / Publish the tested Worker passed: ✓ deploy: 0ec54ecb-aca3-4f80-8fdc-d0be8be3483e is serving, replacing 5052f5d0-9eb6-464e-82dd-7a1fa3c7c62f.
    • Smoke-check the live site passed. Rollback and the failure card were skipped.

    I removed pm:dispatched by hand; a Fixes auto-close does not remove it.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions