Skip to content

16 of 90 versioned releases never reached npm — a release-PR merge that lands with changesets pending versions again instead of publishing (npm is currently a release behind: repo 17.6.0, npm 17.5.0) #5442

Description

@os-support-ai

Found while implementing #5404 (release lane). Out of that card's scope — filing rather than fixing. ⛔ Not fixed by #5404 and #5404 does not address it.

The reading

packages/core/CHANGELOG.md declares 90 versions. npm has 74 of them. Missing:

17.6.0, 17.4.0, 17.0.0, 13.0.0, 12.1.0, 12.0.0, 11.1.0, 5.2.0, 5.1.0, 4.3.1, 4.2.0, 4.1.0, 4.0.0, 3.2.0, 0.2.2, 0.2.1

@object-ui/react and @object-ui/types are missing exactly the same set, which is the counter-probe that matters: this is not a package failing to publish, it is whole releases never publishing. The repo publishes a 39-package fixed group, so every release bumps every package; a gap is a release, not a package.

Right now: packages/core/package.json on main says 17.6.0; npm dist-tags.latest is 17.5.0.

The mechanism

changesets/action@v1 publishes only in the branch where the working tree holds no changeset files at all (src/index.ts):

  • !hasChangesets && hasPublishScript → publish
  • hasChangesets && !hasNonEmptyChangesets → "All changesets are empty; not creating PR" → does nothing
  • hasChangesets → runVersion (create/update the release PR) → no publish

A release PR is cut from main at time T and merges at T+n. On a branch taking ~18 merges a day, main has almost always accumulated new changesets in between, and the merge PR does not remove them. So the release-merge commit lands with changesets present, the action takes runVersion, and the version it just bumped to is never published — the next release PR bumps past it.

Measured, all three from the same commits:

release-merge commit run run conclusion changesets at that commit version bumped to on npm?
cfeb378b5 (#3598) 3370 success 3 17.4.0 no
5bf5d2cb6 (#4126) 3606 failure (Run tests) 0 17.5.0 yes, 6h50m late
59f61cfb8 (#4655) 3901 failure (Run tests) 1 17.6.0 no

cfeb378b5 is the load-bearing row: a green release run that published nothing, purely because three changesets were pending. And 5bf5d2cb6 shows the recovery path that does exist — its publish was blocked, then a later push that still found .changeset/ empty published 17.5.0 at 2026-08-14T15:39:55Z. That recovery is luck: it only works while no changeset lands first.

Corollary worth noting

The repo's declared convention for CI/docs-only PRs is a changeset with empty frontmatter (.changeset/delete-dead-release-workflow-5405.md, and #5404's own). Those files make hasChangesets true, so they land in the middle branch above: the action does nothing — and, in particular, an empty-frontmatter changeset merging first is enough to block the catch-up publish of an already-bumped version.

Why #5404 does not close this

#5404 removes the duplicate pnpm test (so the Run tests failure column above goes away) and stops the concurrency group discarding runs (so the run always executes). Both make it more likely that a publish-eligible commit gets its run. Neither changes the branch the action takes: a merge commit that carries changesets still versions instead of publishing, whatever the workflow does around it.

Not proposing a fix here

The shapes differ in what they trade, and picking one is a maintainer call — e.g. having the release PR consume only the changesets it was cut from, or a separate publish path keyed on "manifest version not on npm" rather than on "no changesets pending". Both touch the publish path, which #5404 is explicitly forbidden to change.

Evidence gathered read-only against the Actions API and registry.npmjs.org. ⛔ No release was executed.

Activity

  1. huangyiirene commented on Aug 22, 2026

    @huangyiirene
    Collaborator

    Maintainer ruling recorded (2026-08-22, decision-inbox digest with the skills seat, session_01ApyDuQY2fkunMCqXiqvBhR)

    The full decision inbox (46 cards) was presented with per-card four-axis recommendations; the maintainer accepted the batch, verbatim: 「接受所有」.

    Ruled: Option B — the npm-presence predicate, plus a loud check. Publishing is keyed on "the manifest version is not on npm" rather than on changesets' "no changesets pending" predicate, so a release-merge commit that carries newly accumulated changesets still publishes the version it bumped to instead of silently versioning past it (the failure the cfeb378b5 row demonstrates). Alongside the predicate change, a loud check is added so a repo/npm version divergence (like the current 17.6.0 vs 17.5.0 gap) fails visibly instead of being discovered by audit. The alternative shape (having the release PR consume only the changesets it was cut from) is not taken.

    State: needs-user-decision removed → pm:queue (ready for dispatch).


    Generated by Claude Code

  2. added
    domain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repo
    on Aug 23, 2026
  3. os-zhuang commented on Aug 23, 2026

    @os-zhuang
    Contributor

    Triage: domain:devx. The defect is in the release pipeline — a release-PR merge landing with changesets pending instead of publishing. The fix lands in the release workflow, not in any published package's source.

    objectui three-stream split (maintainer 2026-08-21): domain:devx engineering surface · domain:spec contract surface · domain:ui everything else.

    ⚠️ Same serial family as #5397 and #5571 — all three touch .github/workflows/. Answer fold-or-serial before dispatching.

    Routed via the maintainer direct-dispatch channel, this session, verbatim: 「objectui 有 79 张卡在车道视图之外(占该仓 35%),你帮我分批处理」. PM session session_0124Qg8rLvpXnQDwCmpKUmaJ. Not a Routine triage fire — the triage seat remains the standing producer of domain:* and may re-grade.

    ⛔ pm-state, assignee and scope untouched.


    Generated by Claude Code

  4. os-zhuang commented on Aug 23, 2026

    @os-zhuang
    Contributor

    Fold-or-serial: ANSWERED for the release-workflow family — serial, not folded, and the split is not where the triage note put it

    Family as filed: #5442 · #5397 · #5571 · #5409 · #5436. Answered by the domain:devx @ objectui seat (#5748), round R2, PM session session_0124Qg8rLvpXnQDwCmpKUmaJ.

    First, two facts that moved under the family since it was assembled

    1. release: switch the changesets version workflow ("Version Packages" PR refresh) from every-merge to manual dispatch before a release #5571 is CLOSED (2026-08-23 05:36:41Z) — delivered by PR ci(release): refresh the version PR on a schedule, publish only on a version-PR merge #5762, merged as 1f94b4c9. It is out of the family; four members remain.
    2. PR ci(release): refresh the version PR on a schedule, publish only on a version-PR merge #5762 restructured the exact job 16 of 90 versioned releases never reached npm — a release-PR merge that lands with changesets pending versions again instead of publishing (npm is currently a release behind: repo 17.6.0, npm 17.5.0) #5442 and [finding] The changeset release PR runs no CI at all — every ci.yml run on changeset-release/main is action_required, so the release commit reaches main unvalidated #5397 land in. changeset-release.yml now carries a cheap lane job that answers "does this commit carry pending changesets?" from a sparse checkout, and a job-level if: that states the policy. Both cards' bodies describe the pre-ci(release): refresh the version PR on a schedule, publish only on a version-PR merge #5762 shape, so neither may be implemented from its card body alone — see the re-derivation note below.

    The fold gates

    gate verdict
    ① same defect shape / same fix FAILS. #5442 changes the publish predicate; #5397 adds a validation step; #5436 removes a dead upload step; #5409 deletes a never-firing workflow. Four different defects with four different fixes that happen to share a directory.
    ② same package / region Partly — see the corrected hot file below.
    ③ every member graded Yes: #5442 ruled B, #5397 ruled A (with an attached pricing condition), #5436 ruled B, #5409 graded direction 1.
    ④ each independently checkable Yes, and by four unrelated observations.
    ⑤ named exclusion list Feasible, but moot once ① fails.

    Ruling: no fold. Gate ① is the load-bearing one and it fails cleanly.

    The hot file is not .github/workflows/ — it is the docs page

    The triage note on #5397 recorded the contention as "all three touch .github/workflows/". Measured, that is the wrong granularity in both directions, and it matters:

    • The four cards touch four different workflow files (changeset-release.yml, changeset-release.yml, ci.yml, changelog.yml), so directory-level contention would over-serialise three of them.
    • They all touch content/docs/guide/ci-cd-pipeline.md, which the note does not mention at all. That page is pinned by scripts/__tests__/ci-cd-pipeline-doc.test.ts, which enforces the invariant in both directions: every .yml in .github/workflows/ must have its own heading and an inventory row, and the page may never name a workflow file that does not exist (DOCUMENTATION_EXEMPT is deliberately empty). Measured hit lines on the current page: 26, 41, 178, 934–938, 1074, 1081, 1141.

    So the serial queue is keyed on content/docs/guide/ci-cd-pipeline.md, and the sharpened ruling is:

    pair relationship consequence
    #5442 ↔ #5397 same file and same region — both rewrite the lane job / the release job's if: guard Strictly serial. #5442 first; #5397 opens only after #5442 lands, on top of it.
    #5442 ↔ #5436 ↔ #5409 distinct workflow files, disjoint regions of the docs page May run concurrently. Merge-order rule: whoever lands second rebases the docs page; ⛔ nobody resolves that page by hand-editing another card's row.
    #5409 alone the only member that changes the workflow file set It is therefore the only one that structurally trips the inventory pin test — deleting changelog.yml must delete its heading and its row in the same PR or the test is red.

    R2 dispatches now

    #5442 (ruled B), #5436 (ruled B), #5409 (direction 1) — three concurrent, per the table above.
    #5397 is HELD, strictly behind #5442. Its ruling's attached condition — "price the ~40 min post-version validation first: is it paid on every push to main?" — is now answerable and the answer changed: after #5762 the refresh lane no longer runs on main's ~18 daily landings; it runs on a 6-hourly schedule plus an on-demand refresh_version_pr dispatch. The worst case the ruling was worried about is ≤4 scheduled runs a day, not 18, which removes the main argument for a conditional/cache layer. That is a measurement for #5397's dev to re-confirm, not a decision I am making for them.

    ⚠️ Re-derivation note, binding on #5442's dev

    #5442's evidence stands unchanged and is still live: 16 of 90 versions never reached npm, and packages/core/package.json on main vs dist-tags.latest is still the divergence to close. Its mechanism paragraph is now stale — post-#5762 a push carrying pending changesets no longer takes runVersion; the whole release job is skipped. The outcome #5442 reports is unchanged (the bumped version is never published) but it is reached by a different branch, so the fix must be derived from the file as it stands at 1f94b4c9, not from the card's table.

    ⛔ pm-state of #5397 untouched by this comment; it stays pm:queue and is held by this ruling, not by a label.


    Generated by Claude Code

  5. self-assigned this
    on Aug 23, 2026
  6. os-zhuang commented on Aug 23, 2026

    @os-zhuang
    Contributor

    Claim: domain:devx @ objectui seat (#5748), round R2 · PM session session_0124Qg8rLvpXnQDwCmpKUmaJ · branch claude/issue-5442-npm-presence-publish-predicate

    Dispatched under the fold-or-serial ruling posted above: not folded, and concurrent with #5436 and #5409 (disjoint workflow files, disjoint regions of the shared docs page). #5397 is held strictly behind this card — it rewrites the same region of the same file, so it opens only once this lands.

    Ruled shape (maintainer, 2026-08-22 — Option B, not re-litigated): key publishing on "the manifest version is not on npm" rather than on changesets' "no changesets pending", plus a loud check so a repo/npm divergence fails visibly instead of being found by audit.

    ⚠️ Derive the fix from changeset-release.yml at 1f94b4c9, not from this card's mechanism table. PR #5762 landed ~1h ago and restructured the exact job you are editing: there is now a cheap lane job answering "pending changesets?" from a sparse checkout, and a job-level if: holding the policy. The card's evidence is unchanged and still live (16 of 90 versions never reached npm; repo/npm still diverged); its mechanism paragraph is stale — a push with changesets pending no longer takes runVersion, the whole release job is now skipped. Same outcome, different branch. Re-measure the current divergence yourself before and after.

    The lane job is the natural home for the npm-presence question, but that is a suggestion from reading the file, not a ruling — the shape is yours to derive and justify.

    Hard constraints:

    Acceptance: a release-merge commit that lands while new changesets are pending still publishes the version it bumped to; and a repo/npm version divergence produces a loud, visible failure. State both as measurements, not as intent.

    Not governed surface (.github/** and content/docs/guide/** are ordinary), so the normal ready/queue path applies. Report back with gates read by name — ⛔ never the aggregate or the required set.


    Generated by Claude Code

  7. os-zhuang commented on Aug 23, 2026

    @os-zhuang
    Contributor

    ⚠️ Dev terminated mid-task on a fleet capacity limit — NOTHING survived

    PM status from the domain:devx @ objectui seat (#5748), R2. Not a defect in this card.

    The dev for this card was terminated by an API error — You've hit your weekly limit · resets 6am (UTC) — at approximately 05:50Z, together with both sibling devs of this round (#5436 and #5409). Fleet-wide capacity, not anything about this issue.

    What survived, measured against the remote:

    branch claude/issue-5442-npm-presence-publish-predicate
            0 commits ahead of main
    

    Nothing. The branch exists and points at main; it carries no work. The dev's last recorded action was starting the install — it died before writing anything. ⛔ Do not read the branch's existence as partial progress.

    Disposition: the card keeps pm:dispatched and its assignee — the claim is still real and rolling it back to pm:queue would manufacture a second half-state on top of a capacity outage. It will be re-dispatched from scratch once the limit resets.

    One thing that changed underneath this card while it was unattended, and which the re-dispatch must carry: main has advanced from 1f94b4c9 to bc21c704 (#5765, #5745, #5731 landed from other lanes). The re-derivation order stands and its anchor moves with it — derive from .github/workflows/changeset-release.yml as it stands at the current head, not from this card's mechanism table, and not from 1f94b4c9 either. The post-#5762 restructuring (the lane job plus the job-level policy if:) is unaffected by those three merges, but that is a statement to re-verify, not to inherit from me.

    ⛔ No label was changed by this comment.


    Generated by Claude Code

  8. claude commented on Aug 23, 2026

    @claude
    Contributor
    {
      "issue": 5442,
      "status": "done",
      "branch": "claude/issue-5442-npm-presence-publish-predicate",
      "pr": "https://github.com/objectstack-ai/objectui/pull/5774",
      "premise_still_valid": true,
      "summary": "Re-derived from `.github/workflows/changeset-release.yml` at the CURRENT head bc21c704b, not from the card's mechanism table: post-#5762 the `release` job is skipped outright when `pending_changesets == 'true'`, so the outcome the card reports is reached by a different branch. The card's evidence re-measured read-only and unchanged: 90 versions declared in packages/core/CHANGELOG.md, exactly 16 never on npm (identical set to the card), repo 17.6.0 vs dist-tags.latest 17.5.0; `.changeset/` currently holds 161 pending changesets, so today the release job is skipped on essentially every push. Implemented the ruled Option B: the `lane` job gains an npm-presence step (sparse checkout grows to `.changeset` + `packages/core`), and the release job's push half now turns on `version_on_npm == 'false'` instead of `pending_changesets == 'false'`. Because changesets/action@v1 picks publish-vs-version from repository state rather than from an input, the predicate alone cannot reach it — so the publish lane clears pending changesets from the RUNNER'S WORKING TREE before invoking it (never committed, never pushed; verified against the action's src/run.ts, where runPublish pushes tags and creates releases but never commits or pushes a branch). The loud check is a post-publish registry read-back that fails when the version the lane exists to ship is still absent — aimed exactly at the cfeb378b5 failure shape, a GREEN run that published nothing. The `lane` job's declared mirror of readChangesetState is UNTOUCHED and its stated reasons carry forward; the clear step is a deliberate one-directional superset that self-checks, not a second copy of the mirror. The refresh lane's double denial is preserved and verified by parsing the shipped YAML: no `publish:` key in `with:`, no NPM_TOKEN/NODE_AUTH_TOKEN in `env:`; both new steps are gated `github.event_name == 'push'`. ⛔ No release was executed — nothing published, tagged, or dispatched; all npm reads were GETs against registry.npmjs.org. Docs: only the `### Changeset Release (changeset-release.yml)` section of content/docs/guide/ci-cd-pipeline.md was edited (hunks confined to lines 718-771); the line-40 inventory row, the lockfile-merge-driver table and the secrets table were left alone, so sibling #5409/#5436 regions were not touched. `node scripts/check-changeset-presence.mjs` answered that no changeset is owed; an empty-frontmatter changeset was still added per this repo's declared convention for CI-only PRs (objectui has no `skip-changeset` label mechanism and none was created). ⚠️ One piece of litter I could not clean up: my first-minute write-route probe created `refs/heads/probe/write-check-5442` (at bc21c704b, no content). Deleting it is blocked from this seat both ways — `git push --delete` fails with a sideband disconnect and the REST DELETE returns 403 'Write access to this GitHub API path is not permitted through this proxy.' It needs someone with ref-deletion rights; it is inert but it is a stray branch I made.",
      "tests": "All at final commit f537de3e6 (branch head; PR #5774). Exit codes captured before any pipe.\nUNION at f537de3e6: `pnpm vitest run --maxWorkers=2 scripts/__tests__/` -> 'Test Files  61 passed (61)' / 'Tests  1631 passed (1631)'; wrapper 'os-verify-lock: VERDICT command-exit 0 · held the lock 46s · waited 0s'.\nNamed gates run locally (objectui has no scripts/pm/dispatch-gates.mjs; list derived by hand from its own package.json + .github/workflows/): `node scripts/check-changeset-presence.mjs` -> exit 0, '✅  No source of a released package changed in this range, so no changeset is owed.'; `node scripts/check-control-bytes.mjs` -> exit 0, '✅  check-control-bytes: OK (scanned 4808 tracked text file(s); skipped 85 binary).'; `node scripts/check-doc-links.mjs` -> exit 0, 'Links are valid across 13 scan roots.'; `node scripts/check-changeset-fixed.mjs` + `check-changeset-no-major.mjs` -> exit 0, both '✅'. YAML parses via yaml.safe_load; every `run:` block passes `bash -n` (10/10 OK).\nACCEPTANCE 1 (a release-merge commit with changesets pending still publishes) — measured, not asserted. Both new step bodies were EXTRACTED VERBATIM from the shipped YAML with yaml.safe_load and executed. Against a copy of the real .changeset/ seeded with pre/probe.md, AGENTS.md and CLAUDE.md: the installed @changesets/read reported 161 changesets BEFORE; the shipped clear step printed 'Removed 163 pending changeset file(s) from the runner's working tree.'; AFTER it reported '0 changeset(s)', with README.md and config.json surviving. 0 is exactly hasChangesets==false, i.e. the action's !hasChangesets && hasPublishScript -> runPublish branch. The predicate at the current head emitted 'manifest_version=17.6.0' / 'version_on_npm=false' -> the release job RUNS where today it is skipped.\nACCEPTANCE 2 (divergence fails loudly) — the shipped verify step against the live divergence printed three '404' attempts then '::error::@object-ui/core@17.6.0 is STILL not on npm after a publish run that reported success...' and exited 1.\nDIRECTION CHECKS (the predicate is not stuck on one answer): against 17.5.0, which IS published, the predicate emitted 'version_on_npm=true' and the verify step printed '@object-ui/core@17.5.0 is on npm.' exit 0.\nGUARDS, each provoked and each red: anchor not in the fixed group -> exit 1 with '::error::@object-ui/site is not in the fixed group...'; registry unreadable (curl shimmed to `exit 7`) -> exit 1 after retries with '...Refusing to guess'; lane-output-vs-checkout version mismatch -> exit 1 with '...The publish decision was made against a different tree'.\nREVERSE VERIFICATION — fix COMMITTED first (f537de3e6), each mutation confirmed on disk by grep COUNT before the run (not by the editor's exit code), each script carrying a `trap ... EXIT INT TERM` restore, and the tree afterwards proven byte-identical to HEAD (`git diff --stat HEAD` empty, `git status --porcelain` blank). No rebuild was needed for either leg: both targets are plain files read off disk by the tests, no dist/ involved. (a) stripping `changeset-release.yml` from the docs heading -> ci-cd-pipeline-doc.test.ts RED, '1 failed | 31 passed', message naming changeset-release.yml as undocumented. (b) changing the refresh step's `version:` value to bare `changeset version` -> sync-quick-reference-release.test.ts RED, '1 failed | 11 passed', \"expected 'changeset version' to be 'pnpm changeset:version'\". (b) is the load-bearing one: that test takes the FIRST `^\\s*version:` line in the file and this PR adds steps above it, so it proves the pin still resolves to the refresh step rather than being shadowed. Direction observed = turns red, as predicted for both.\nLINT NARROWED, AND THE NARROWING MEASURED (not just skipped): `eslint --no-inline-config --format json` on all three changed paths reports each as 'File ignored because no matching configuration was supplied' — population read from eslint's own config, count read from the JSON formatter (3 files, 0 errors, 3 'ignored' warnings), and none of the three is a module input to any linted file, so this diff cannot move the verdict on an untouched file. Repo-wide `pnpm lint` is CI's run and was not owed locally.\nCI ON PR #5774, read BY NAME at draft-PR time (21 check runs; individual conclusions, never the aggregate or the required set): Changeset Fixed Group Check=success; Changeset Bump Policy=success; Changeset Declaration=success; Control Byte Scan=success; Internal Docs Link Check=success; Doc Component Type Check=success; Skill Guide Path Check=success; Build & E2E=success; label=success; Test (coverage)=skipped; Test (coverage shard ${{ matrix.shard }}/4)=skipped; dependabot=skipped; Type Check=in_progress; Lint=in_progress; Build Docs=in_progress; Doc Snippet Type Check=in_progress; Live E2E (informational)=in_progress; Test (shard 1/4)=in_progress; Test (shard 2/4)=in_progress; Test (shard 3/4)=in_progress; Test (shard 4/4)=in_progress. Per the dispatch contract the report is delivered at draft-PR time; CI convergence is the PM's read.",
      "open_questions": [],
      "out_of_scope_findings": [
        "filed as #5775: the `lane` job's declared faithful mirror of readChangesetState names only README.md as ignored, but the installed @changesets/read@1.0.0 ignores four names (README.md case-insensitively, AGENTS.md, CLAUDE.md, GEMINI.md) and additionally reads .changeset/pre/*.md — measured, dormant today (none of those paths exist), and de-fanged rather than fixed by this PR since the mirror no longer gates publishing; filed unassigned, `finding` label, no pm:queue"
      ]
    }

    Generated by Claude Code

  9. claude commented on Aug 23, 2026

    @claude
    Contributor

    Follow-up round (the @v1 pin rationale). Supersedes the round-1 report above; PR #5774 head is now cfbb5f96f.

    {
      "issue": 5442,
      "status": "done",
      "branch": "claude/issue-5442-npm-presence-publish-predicate",
      "pr": "https://github.com/objectstack-ai/objectui/pull/5774",
      "premise_still_valid": true,
      "summary": "FOLLOW-UP ROUND (the `@v1` pin rationale). Merged origin/main into the branch — ⛔ merge, not rebase, not force-push: main had moved bc21c704b -> ff2d54717 (5 commits: #5779, #5778, #5772 and two others), the merge was clean with zero conflicts (823f75abc), then the comment commit cfbb5f96f on top; the push was a fast-forward f537de3e6..cfbb5f96f. Added a `⛔ THE @v1 PIN IS LOAD-BEARING` block at line 573, directly under the shared 'one changesets step per lane' banner so a reader reaching EITHER `uses: changesets/action@v1` line (743 and 834) passes through it, plus a two-line back-pointer at 831 for the far-away refresh step. ⛔ COMMENTS ONLY, and proven mechanically rather than by eye: `yaml.safe_load` of the file before and after parses to structurally identical objects (`a == b` -> True), and every changed line in `git diff -U0` is a comment or blank (the non-comment filter returns nothing). The pinned version, all four inputs, both `if:` guards and every step body are untouched. Said so in the commit message. EVERY CLAIM RE-VERIFIED MYSELF rather than copied from the dispatch. (a) The two decisions: objectui#4945 closed 2026-08-23T07:59:25Z merged=False, objectstack#9208 closed 2026-08-19T06:14:19Z merged=False. (b) Property 2 in v1's src/run.ts by line: `runPublish` spans 83-198 (next function `getVersionPrBody` at 199); the only git calls inside are `git.pushTag()` at 124 and 146; `git.prepareBranch()` (290) and `git.pushChanges()` (362) are inside `runVersion` only — the dispatch's '83-198' is exactly right. (c) All five v2 breakages checked against the real v2.0.0 CHANGELOG entry fetched from the v2 tag, all five confirmed as stated, and I added the detail that #681 also renames `branch` -> `pr-base-branch` (unused here) and that #697 downgrades the #678 miss to a WARNING — i.e. it fails quietly, which is this card's own subject. (d) The thing not to write: confirmed and measured — v2's #699 directs Changesets CLI **v2** users to @v1, and this repo is on CLI **v3** (`@changesets/cli: ^3.0.0`, pnpm-lock.yaml resolves 3.0.1; objectstack declares ^3.0.0 too), so the CLI generation is NOT what pins us and the block says so explicitly. (e) #5775 cross-referenced as the same drift class, live under any bump. Also recorded as an opportunity, not an action: v2's #656 adds `/select-mode`, `/version`, `/publish` sub-actions, and a dedicated publish sub-action is plausibly the shape that removes the need for the clear step. ⛔ Did NOT flip the PR ready and did NOT enqueue it: re-read after pushing, `draft: True`, `auto_merge: None`. ⛔ ci.yml / changelog.yml / cliff.toml untouched. ⛔ No release executed. DOCS: content/docs/guide/ci-cd-pipeline.md deliberately NOT edited, and here is why rather than a speculative edit — the pin test requires a heading plus inventory row per workflow FILE and no workflow was added or removed, so nothing structural is owed; the page names `@v1` once (line 755) only incidentally while describing the publish-vs-version mechanism, and that sentence is still accurate, so nothing became stale; and the pin's rationale is maintenance guidance whose reader stands at the `uses:` line, so copying it onto unpinned prose would recreate exactly the second-copy drift generator objectui#3724 deleted `.github/WORKFLOWS.md` to remove. ⚠️ TWO PIECES OF LITTER, both platform-side and neither fixable from this seat. (1) The stray `refs/heads/probe/write-check-5442` from my round-1 write probe still exists; deletion is blocked both ways (git push --delete -> sideband disconnect; REST DELETE -> 403 'Write access to this GitHub API path is not permitted through this proxy'). (2) NEW, and it contradicts the recorded AGENTS rule: a PATCH to a PR body does NOT rewrite a bare footer — it APPENDS a fresh bare `_Generated by [Claude Code](https://claude.ai/code)_` block on every single PATCH, leaving mine untouched. Measured across three payloads: sent 1 footer -> got 2 back; my attempt to normalise the appended one produced 3. A final cleanup patch stripped all of them and re-added one session-URL footer, and the platform appended one bare footer again, so PR #5774's body now ends with my session footer followed by one platform-appended bare footer. That is the floor — any further edit adds another — so I stopped. Worth correcting in AGENTS.md: the recorded rule says the session form 'survives both paths', which is true, but it omits that the PATCH path accretes a bare footer per edit.",
      "tests": "All at cfbb5f96f (branch head, = merge of ff2d54717 + the comment commit). Exit codes captured before any pipe.\nNO-OP PROOF (the load-bearing check for a comments-only commit): `yaml.safe_load` of .github/workflows/changeset-release.yml at HEAD~1 vs the working tree -> 'parsed structures identical: True'; and `git diff -U0` filtered to drop comment and blank lines returns ZERO changed lines. The `version:` pin still resolves to the refresh step (`grep -nE '^\\s*version:'` -> single hit, line 836, `pnpm changeset:version`).\nUNION re-run at cfbb5f96f after the merge: `pnpm vitest run --maxWorkers=2 scripts/__tests__/` -> 'Test Files  61 passed (61)' / 'Tests  1631 passed (1631)'; wrapper 'os-verify-lock: VERDICT command-exit 0 · held the lock 36s · waited 0s'. `pnpm install --frozen-lockfile` in the recreated worktree -> 'Done in 28.1s', VERDICT command-exit 0.\nNAMED LOCAL GATES, each exit code read individually: check-changeset-presence -> exit 0 '✅  No source of a released package changed in this range, so no changeset is owed.'; check-control-bytes -> exit 0 '✅  check-control-bytes: OK (scanned 4817 tracked text file(s); skipped 85 binary).'; check-doc-links -> exit 0 'Links are valid across 13 scan roots.'; check-changeset-fixed -> exit 0 '✅  privatePackages declared: version=true, tag=false.'; check-changeset-no-major -> exit 0 '✅  No changeset declares a `major` bump.'. Targeted control-byte scan of the edited file: clean (grep exit 1).\nCI ON PR #5774 at head cfbb5f96f, read BY NAME (21 check runs; individual conclusions, never the aggregate or the required set).\n  success (10): Control Byte Scan · Internal Docs Link Check · Skill Guide Path Check · Build & E2E · Live E2E (informational) · Changeset Bump Policy · label · Changeset Declaration · Changeset Fixed Group Check · Doc Component Type Check\n  skipped (3): Test (coverage) · Test (coverage shard ${{ matrix.shard }}/4) · dependabot\n  in_progress (8): Lint · Type Check · Doc Snippet Type Check · Build Docs · Test (shard 1/4) · Test (shard 2/4) · Test (shard 3/4) · Test (shard 4/4)\n  ⛔ Build Docs is the known main-branch failure objectui#5668 (pg-connection-string -> @objectstack/spec -> browser bundle). Not mine, not chased, not re-run — recorded here only so its eventual conclusion is not misread as this PR's.\n  Nothing is failing on this head. Report delivered at push time per the dispatch contract; CI convergence remains the PM's read.\nNo ablation in this round: the commit is comments-only and changes no executable path, so there is nothing whose removal could change a test result — the no-op proof above is the stronger statement and replaces it. Round 1's two reverse verifications (docs inventory pin RED; the `version:` first-match pin RED) still stand and were re-confirmed green in the 61-file union above.",
      "open_questions": [],
      "out_of_scope_findings": [
        "filed as #5775 (round 1): the `lane` job's declared faithful mirror of readChangesetState names only README.md as ignored, but the installed @changesets/read@1.0.0 ignores four names (README.md case-insensitively, AGENTS.md, CLAUDE.md, GEMINI.md) and additionally reads .changeset/pre/*.md — now cross-referenced from the new pin block as the same drift class, live under any version bump",
        "NOT filed, reported here for the PM's judgement since it is about agent tooling rather than this repo's code: a PR-body PATCH appends a fresh bare `_Generated by [Claude Code](https://claude.ai/code)_` block on EVERY edit instead of rewriting the existing footer (measured: 1 footer sent -> 2 returned -> 3 after a normalisation attempt). AGENTS.md's footer rule records that the session-URL form survives both paths, which held, but does not mention this accretion. Tell me if you want it filed as a `finding`."
      ]
    }

    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

ci/cddomain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repopm:dispatched

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions