Skip to content

ci(root): serve packed packages from a registry instead of file: specs - #839

Merged
mobeenabdullah merged 5 commits into
mainfrom
fix/pin-packed-peer-dependencies
Aug 16, 2026
Merged

mobeenabdullah merged 5 commits into
mainfrom
fix/pin-packed-peer-dependencies

Conversation

@mobeenabdullah

@mobeenabdullah mobeenabdullah commented Aug 15, 2026 •

Copy link
Copy Markdown
Collaborator

Scaffold blog-visual is red on main — the last remaining scaffold failure after #835 cleared the other one.

node_modules/.../@nextlyhq/plugin-form-builder/dist/admin/index.js
  Error: Module not found: Can't resolve '@nextlyhq/plugin-sdk/admin'   (x6)

It reads as a missing export. It is a missing install.

Two things combine

The pin loop only repoints names the manifest already declares. A packed package that is nothing but a peer of another packed package is named by neither the manifest nor the loop, so it never enters the tree.

The override makes that worse rather than better. pnpm applies overrides to peer ranges, not only to dependency specs. The range becomes file:/tmp/….tgz, and no resolved semver version can satisfy a file: specifier:

✕ unmet peer nextly@file:/tmp/.../nextly-0.0.2-alpha.57.tgz: found 0.0.2-alpha.57

That line is the proof, and it is the one reasoning cannot produce: the package is present at the exact version and the peer is still unmet. My first diagnosis was that the override failed to reach peers. It is the inverse — reaching them is the defect.

Measured, on a minimal fixture rather than through CI

manifest pnpm says linked into form-builder's scope?
peer only, override present ✕ missing peer no
peer also a direct dependency ✕ unmet peer (warning) yes

And the failing specifier resolves from the exact file that failed:

require.resolve('@nextlyhq/plugin-sdk/admin')
  -> @nextlyhq/plugin-sdk/dist/admin.mjs

This also explains why only ONE blog leg failed, which the mechanism alone does not: blog-code-first is npm, whose hoisted layout leaves the package reachable regardless of the peer range; blog-visual is pnpm, whose isolated layout declines to link it.

The fix

The peer set is derived from the tarballs already being opened for their names, not listed — the rule this file states about itself: "a list in this file would be a second answer to a question the manifests already answer".

optionalDependencies joins the pin loop as the third place a manifest can name a package; a spec left unpinned there resolves from the registry exactly as an unpinned dependency would. Flagged by a reviewer of #835, whose own first fix removed a hardcoded list and left a hardcoded expectation one level down.

Separating property

A green blank leg proves nothing here. Only the two blog legs declare core: workspace, so they are the only ones that mix registry and workspace packages and the only ones that can catch this. Judge this on Scaffold blog-visual.

No changeset: CI tooling, ships nothing.


A green run that the mechanism did not produce

Worth recording, because it is the reason the second fix here is ORDERING rather than
configuration.

The registry redirect was originally written to $HOME/.npmrc before npx fetched
verdaccio, so that fetch was aimed at a port nothing was listening on. Every run was green
anyway. The reason is that this step runs from the repository root, whose own .npmrc names
npmjs and project config outranks user config, while every other command in the step runs
cd /tmp and correctly resolved localhost. The ordering was wrong and the result was green,
because something other than the mechanism under test was supplying the answer.

It was found by accident: while verifying the unrelated dist-tag fix locally, the redirected
HOME was exported before starting verdaccio - the same ordering, without a repository .npmrc
to rescue it - and verdaccio never came up. With the start moved first it came up in 4 seconds.

AGENTS.md states the general form of this ("ask what ELSE would produce the same green"). The
fix is to start the registry first, so the fetch cannot depend on config precedence at all,
rather than to add configuration that makes the existing order work.

Scaffold blog-visual has been red on main. plugin-form-builder/dist/admin
cannot resolve @nextlyhq/plugin-sdk/admin, which reads as a missing export and
is a missing install.

Two things combine. The pin loop only repoints names the manifest ALREADY
declares, so a packed package that is nothing but a peer of another packed
package never enters the tree. And the override makes that worse rather than
better: pnpm applies overrides to peer RANGES, so the range becomes a file:
spec and no resolved semver version can satisfy one.

Measured on a minimal fixture. Without a direct dependency pnpm reports
missing peer and declines to link it; with one it reports unmet peer, a
warning, and links it anyway. That is why only the pnpm leg fails - npm's
hoisted layout leaves the package reachable either way.

The peer set is derived from the tarballs already being opened for their names,
rather than listed, which is the rule this file states about itself.

optionalDependencies joins the pin loop as the third place a manifest can name
a package; a spec left unpinned there resolves from the registry exactly as an
unpinned dependency would.
@coderabbitai

coderabbitai Bot commented Aug 15, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

@mobeenabdullah, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 55 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: d2bf8a4e-2644-4177-8e84-141ce9df4558

📥 Commits

Reviewing files that changed from the base of the PR and between 682cc31 and 3907484.

📒 Files selected for processing (2)
  • .github/workflows/scaffold-build.yml
  • scripts/pin-workspace-packages.mjs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@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: 03a4f7de10

ℹ️ 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 scripts/pin-workspace-packages.mjs Outdated
@pkg-pr-new

pkg-pr-new Bot commented Aug 15, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

@nextlyhq/adapter-drizzle

npm i https://pkg.pr.new/@nextlyhq/adapter-drizzle@3907484

@nextlyhq/adapter-mysql

npm i https://pkg.pr.new/@nextlyhq/adapter-mysql@3907484

@nextlyhq/adapter-postgres

npm i https://pkg.pr.new/@nextlyhq/adapter-postgres@3907484

@nextlyhq/adapter-sqlite

npm i https://pkg.pr.new/@nextlyhq/adapter-sqlite@3907484

@nextlyhq/admin

npm i https://pkg.pr.new/@nextlyhq/admin@3907484

@nextlyhq/admin-css

npm i https://pkg.pr.new/@nextlyhq/admin-css@3907484

@nextlyhq/blocks-engine

npm i https://pkg.pr.new/@nextlyhq/blocks-engine@3907484

@nextlyhq/blocks-react

npm i https://pkg.pr.new/@nextlyhq/blocks-react@3907484

@nextlyhq/builder

npm i https://pkg.pr.new/@nextlyhq/builder@3907484

create-nextly-app

npm i https://pkg.pr.new/create-nextly-app@3907484

nextly

npm i https://pkg.pr.new/nextly@3907484

@nextlyhq/plugin-form-builder

npm i https://pkg.pr.new/@nextlyhq/plugin-form-builder@3907484

@nextlyhq/plugin-page-builder

npm i https://pkg.pr.new/@nextlyhq/plugin-page-builder@3907484

@nextlyhq/plugin-sdk

npm i https://pkg.pr.new/@nextlyhq/plugin-sdk@3907484

@nextlyhq/plugin-seo

npm i https://pkg.pr.new/@nextlyhq/plugin-seo@3907484

@nextlyhq/storage-s3

npm i https://pkg.pr.new/@nextlyhq/storage-s3@3907484

@nextlyhq/storage-uploadthing

npm i https://pkg.pr.new/@nextlyhq/storage-uploadthing@3907484

@nextlyhq/storage-vercel-blob

npm i https://pkg.pr.new/@nextlyhq/storage-vercel-blob@3907484

@nextlyhq/ui

npm i https://pkg.pr.new/@nextlyhq/ui@3907484

commit: 3907484

nextly declares all three database adapters as optional peers, and a scaffolded
app installs exactly the one it was generated for. Adding the other two would
not merely bloat the install: it would let an accidental import of an adapter
the app never declared COMPILE, so the leg would pass on code a real user's
install cannot run - the check weakened by the change meant to repair it.

peerDependenciesMeta is read from the same tarball manifest already being
opened, so the optional flag is derived rather than assumed.

Measured with all three adapter tarballs packed and a manifest declaring only
sqlite: sqlite is added, mysql and postgres are not.
@mobeenabdullah

Copy link
Copy Markdown
Collaborator Author

@codex please review this PR

@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: 6822138168

ℹ️ 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 scripts/pin-workspace-packages.mjs Outdated
A union over all packed tarballs adds a peer because SOME packed package wants
it. Reproduced: a blank-like manifest gained @nextlyhq/plugin-sdk purely
because plugin-form-builder declares it, and that scaffold installs no plugin.

That is the same failure as adding an optional adapter - it lets an accidental
import compile in a project whose real install would reject it, so the leg
passes on code a user cannot run. The change meant to repair the check weakens
it, twice over, in the same derivation.

The set is now the reachability closure from the packages the manifest actually
declares, followed through required peers only. Transitive, because a peer that
gets added brings its own required peers and stopping at one level leaves the
second unresolvable for the reason the first was.

Paired controls: a blank-like manifest does NOT gain plugin-sdk, a manifest
that installs plugin-form-builder DOES, and both keep ui, which admin requires.
@mobeenabdullah

Copy link
Copy Markdown
Collaborator Author

@codex please review this PR

@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: 2106e55003

ℹ️ 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 scripts/pin-workspace-packages.mjs Outdated
@mobeenabdullah

Copy link
Copy Markdown
Collaborator Author

My own change has now demonstrated the defect its reviewer predicted, empirically rather than by argument. I recommend closing this unmerged.

Latest run (2106e5500, run 31868835902):

success   Scaffold blog-visual      <- the target leg, FIXED
failure   Scaffold blog-code-first  <- was passing on main, broken by this PR
success   blank, blank-bundled, blank-pnpm9, blank-pnpm11

The failure:

the build ran the Google font loader, which needs the network

Mechanism, measured. On a code-first blog manifest, this change adds exactly one package: @nextlyhq/ui, as a root dependency. The generator declares it only conditionally (template.ts:554), and templates/blog/src/app/layout.tsx uses next/font/google. Widening the root graph changed what the build resolves, and the hermetic-build assertion caught it.

So the objection in the open thread is no longer hypothetical. Adding a root dependency to satisfy a peer cannot avoid changing the dependency boundary, and the scaffold legs exist to test that boundary. Four rounds, and rounds 2, 3 and 4 were all the same defect in different clothes:

round added consequence
2 optional adapter peers an undeclared adapter import would compile
3 peers of packages the app never installs an undeclared SDK import would compile in blank
4 plugin-sdk as a root dependency an undeclared SDK import would compile in blog
now @nextlyhq/ui as a root dependency an actual leg broke

I measured the cheap alternative before concluding this: pnpm.peerDependencyRules.allowedVersions set to * for every packed name leaves the peer still missing and still unlinked. It does not help.

What I believe is correct. Stop using file: overrides. Publish the packed tarballs to a local registry (verdaccio) and pin by VERSION. Peer ranges stay semver and resolve naturally, the scaffolded manifest keeps exactly the dependencies the generator wrote, and the class disappears rather than being narrowed a fifth time. It touches .github/workflows/scaffold-build.yml, which belongs to another lane, so it needs coordination.

Leaving this open for the founder to decide rather than closing it myself. Scaffold blog-visual stays red on main meanwhile — which it already was, and a fix that trades away what the leg checks is worse than a visible failure.

@mobeenabdullah

Copy link
Copy Markdown
Collaborator Author

Correcting my own diagnosis. The mechanism I posted earlier was wrong, and I stated it as measured.

I claimed this PR adds @nextlyhq/ui as a root dependency and that this unlocked next/font/google. Both halves are false:

  1. @nextlyhq/ui is already unconditional for the blog — packages/create-nextly-app/src/utils/template.ts:554, inside the if (!useYalc) block alongside nextly, admin and the adapters. My fixture omitted it, so my "added by this change" measurement was against a manifest the generator never produces.

  2. Against the REAL blog dependency set this PR adds exactly one package: @nextlyhq/plugin-sdk. Measured with all 8 tarballs and a manifest matching the generator (nextly, admin, ui, adapter-drizzle, adapter-sqlite, plugin-form-builder).

  3. No installed package actually uses next/font/google. I grepped every packed tarball. The single hit is in @nextlyhq/admin's dist/index.d.ts line 107 — a doc comment in a type declaration, never executed. And the blog layout deliberately imports @fontsource-variable/inter and @fontsource-variable/geist-mono as bare packages specifically to avoid the Google loader; the comment in that file says so. My earlier grep matched that comment.

So the story I told — widened graph unlocks the font loader — is not supported. I am withdrawing it.

What I actually know:

  • blog-code-first passes on main and fails at this tip, so the change is implicated.
  • It fails on the assertion grep -rq "internal/font/google" .next, not on the build.
  • The only manifest difference is @nextlyhq/plugin-sdk as a root dependency, and that package contains zero references to the font loader.

Leading hypothesis, explicitly NOT yet verified: the assertion greps .next for a STRING that also occurs in a shipped type declaration. If adding a package changes what Next traces into .next, the grep can match admin's doc comment rather than the loader having run. That would make the check fire on a build that never touched the network — a false positive in the assertion, not a defect in the install.

Next diagnostic, and I will not post another mechanism before running it: reproduce the code-first scaffold locally with and without plugin-sdk pinned, and inspect what in .next matches — a real internal/font/google module, or the traced declaration file.

Two lanes have now relayed my unverified mechanism onward. That is on me: I presented an inference in the same register as a measurement, and it travelled. The measurements above are re-runnable; the earlier story was not.

The pin rewrote the generated manifest to `file:` specifiers, and pnpm applies
that rewrite to peer RANGES as well as to dependency specs. No resolved semver
version satisfies a `file:` range, so pnpm reported an unmet peer with a correct
copy installed, never linked it, and the build failed on
`Can't resolve '@nextlyhq/plugin-sdk/admin'`. npm's hoisted layout hid it.

Publishing the tarballs to a registry inside the job and installing them by
version removes that: peer ranges stay semver and the manifest is not modified,
so the legs still test the dependency boundary the generator writes rather than
one CI invented. A new assertion requires the manifest to carry no `file:` spec
and no `pnpm.overrides`.

Publishing needs both `--registry` and an `@nextlyhq:registry` config entry, and
neither is sufficient alone: the flag overrides each package's own
`publishConfig.registry`, and the config entry wins for a scoped name where the
flag does not. A guard refuses to publish unless both resolve to localhost,
because these packages name the real registry in `publishConfig`.
@mobeenabdullah mobeenabdullah changed the title fix(ci): give a packed peer a place in the scaffolded tree ci(root): serve packed packages from a registry instead of file: specs Aug 15, 2026
@mobeenabdullah

Copy link
Copy Markdown
Collaborator Author

Mechanism REPLACED rather than narrowed a fifth time. The pin script is deleted.

Why the previous approach could not work

file: specifiers were the defect class, not the tuning. pnpm applies an override to peer RANGES as well as to dependency specs, and no resolved semver version can satisfy a file: range - so pnpm reported unmet peer nextly@file:...: found 0.0.2-alpha.57 with a correct copy installed, never linked the peer, and the build failed on Can't resolve '@nextlyhq/plugin-sdk/admin'. npm's hoisted layout hid the same defect, which is why the two blog legs kept trading places.

Every repair so far satisfied the peer by ADDING a root dependency, which necessarily widens the app's dependency graph - the exact boundary these legs exist to test.

What replaces it

The packed tarballs are published to a registry running inside the job and installed BY VERSION. The generator already writes ^0.0.2-alpha.<current>, which the packed version satisfies, so the generated manifest is not modified at all.

A new assertion makes the old regression unrepresentable rather than merely absent: the manifest must carry no file: specifier and no pnpm.overrides.

Measured locally, both legs, before pushing

blog-code-first (npm) blog-visual (pnpm)
scaffold exit 0 exit 0
build exit 0 exit 0
plugin-sdk as root dep false false
any file: spec / pnpm.overrides none none
installed nextly matches packed build YES YES
internal/font/google matches in .next 0 0

Under pnpm, @nextlyhq/plugin-sdk is correctly symlinked into plugin-form-builder's own node_modules - the linkage that was missing before - with zero Can't resolve errors in the build log.

Two findings worth carrying

Publishing needs BOTH --registry and an @nextlyhq:registry config entry. Neither is sufficient: the flag overrides each package's publishConfig.registry, and the config entry wins for a scoped name where the flag does not. Measured - with only the config entry, the unscoped nextly publish was aimed at npmjs while the other 17 went local.

Every package carries publishConfig.registry: https://registry.npmjs.org/, so a naive version of this step publishes to the REAL registry. The step therefore refuses to publish unless both registry and @nextlyhq:registry resolve to localhost, and fails if the publish log ever mentions npmjs. This was demonstrated locally, where only the absence of a credential stopped it.

Withdrawn

I posted a next/font/google mechanism for the blog-code-first failure and it was wrong. next/font/google appears in exactly one place across all 18 packed tarballs and in the published alpha.42: a DOC COMMENT in admin/dist/index.d.ts. No package runs the loader. The failure also does not reproduce locally, including with CI's exact sequence. I do not know that mechanism and am not proposing another; it is moot here because nothing is added to the manifest.

Staying in DRAFT until both blog legs are green at one commit in CI.

@mobeenabdullah

Copy link
Copy Markdown
Collaborator Author

@codex please review this PR

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: d4dbe4e5b9

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

@mobeenabdullah
mobeenabdullah marked this pull request as ready for review August 15, 2026 22:17

@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: d4dbe4e5b9

ℹ️ 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 .github/workflows/scaffold-build.yml Outdated
Comment thread .github/workflows/scaffold-build.yml
@mobeenabdullah

Copy link
Copy Markdown
Collaborator Author

CI verification at d4dbe4e5b9d32df6821c84508267958b4c5b59f1, asserted per job rather than inferred from the absence of failures.

24 completed/success, 6 completed/skipped, 0 failing, 0 pending. The six skips are the nextly-bot-mention and nextly-review-bot jobs, which correctly skip when nothing mentions them.

Both blog legs are green AT ONE COMMIT, which is the bar this PR was held to:

leg result
Scaffold blog-code-first completed/success
Scaffold blog-visual completed/success
Scaffold blank, blank-pnpm9, blank-pnpm11, blank-bundled completed/success
Integration (postgres/mysql/sqlite) completed/success
Lint / Typecheck / Test / Build completed/success
Browser tests, Dev script ..., Scaffold smoke (3 OS) completed/success

Scaffold blog-visual is the leg the left-tasks claims board records as red REPO-WIDE since 2026-08-14, on mains own code, with the fix deliberately deferred. That warning is now stale.

Two notes for whoever updates the claims board:

  1. Cite PR ci(root): serve packed packages from a registry instead of file: specs #839 at d4dbe4e5b, not "fixed on main". scaffold-build.yml has no push trigger, so these legs never run on main and a green is not observable there — which is exactly why this sat red for two days, visible only from whichever PR happened to touch a template.
  2. The board lists the plugin-sdk peer omission as a SEPARATE deferred cause. It is not: it was a CONSEQUENCE of the broken resolution. Publishing all 18 packed packages to the in-job registry lets pnpm resolve and link that peer normally, and one fix closes both. Confirmed by symlink inspection locally and by this run.

Still outstanding: no reviewer has looked at this head. Codex last reviewed 2106e5500, which carried the mechanism this PR deletes, so that verdict says nothing about what is now proposed.

@codex please review this PR

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

Reviewed commit: d4dbe4e5b9

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

…version alpha

Two defects that a green run does not reveal.

The registry redirect was written to `$HOME/.npmrc` BEFORE `npx` fetched
verdaccio, so that fetch was aimed at a port nothing was listening on. It
survived only because the step runs from the repository root, whose own `.npmrc`
names npmjs and outranks the user-level file — a working directory away from
hanging. Reproduced by moving the redirect ahead of the start locally: verdaccio
never came up. Starting it first removes the dependency on config precedence.

Every published version now also carries the `alpha` tag. The generator resolves
a version by asking npmjs for dist-tags, and a package whose only published
artifact is its `0.0.0` name-claiming placeholder has no `alpha` tag to find, so
it writes the literal string `alpha` as the spec rather than a range. A registry
carrying only `latest` cannot satisfy that, and the leg would fail on an
unavailable tag instead of testing the new package.
@mobeenabdullah

Copy link
Copy Markdown
Collaborator Author

@codex please review this PR

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

Reviewed commit: 3907484861

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

@mobeenabdullah

Copy link
Copy Markdown
Collaborator Author

Browser tests is RED at 390748486, and it is not this PR. Recording the reasoning rather than re-running until it goes green.

Failure: e2e/tests/canvas/acceptance.spec.ts:410 — "a canvas any Nextly editor could ship › never turns a click into a drag", failing its own positive control at line 442 (the press must be live, or 'not dragging' proves nothing).

This PR changes exactly two paths:

.github/workflows/scaffold-build.yml
scripts/pin-workspace-packages.mjs   (deleted)

Neither is reachable from the e2e canvas suite. That suite boots the playground and exercises page-builder drag behaviour; a scaffold-build workflow and a deleted CI script cannot participate in it. Unreachability is what exonerates a PR here, not a green re-run — and that argument holds whether or not a second run passes, which is why I am not simply re-running it.

The failing assertion is a positive control on press liveness, which belongs to the canvas/page-builder lane's settle-allowance and drag-threshold work (#825, and #854 recovering the settle-guard commit stranded by it). Flagging it there rather than adopting it here.

Everything this PR is responsible for is green at 390748486: both blog legs, all four blank legs, all three Integration legs, Lint / Typecheck / Test / Build, Scaffold smoke on three OS, and Dev script starts every watcher. 22 success, 4 legitimately skipped (the bot workflows), 1 failure that the diff cannot reach.

@mobeenabdullah
mobeenabdullah merged commit 29dc898 into main Aug 16, 2026
29 of 30 checks passed
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.

1 participant