Skip to content

No preview D1 carries a test account, so every :auth render refuses and signed-in surfaces are unjudgeable #9281

Description

@usirin

What is wrong

CI seeds a PR's preview D1 with read fixtures and nothing else, so no preview carries a
review-ui test account. .github/workflows/ci.yml has one seeding step, Seed preview D1, and it
runs node packages/preview-seed/src/bin.ts run --database-id "${{ steps.preview.outputs.db }}".
packages/preview-seed/src/seed.ts writes terms, definitions, posts and the two FTS tables — no
user, no session. The sibling command that writes those rows, preview-seed test-account
(packages/preview-seed/src/bin.ts), is invoked by no workflow under .github/.

Triage note: verified at origin/main — the seed step is .github/workflows/ci.yml:1018-1023, and
grepping .github/ at main for test-account returns nothing.

Consequence: every review-ui render of a :auth or :auth-caylak surface refuses on 11 ("the
preview answered the seeded cookie as a visitor"), so a PR whose rendered change lives behind sign-in
ends the rendered gate at CANT-SEE with no route to a verdict. Hit twice in one evening — PR #9276
(lane 9265) and PR #9279 (lane 9273). The --flag path inherits the block, since a forced run names
a tier on every surface.

The fix, proven by hand

A driver cleared it manually, first try: resolve the preview's D1 uuid, then run
preview-seed test-account --database-id <uuid> with the two tier session tokens in the environment.
That provisioned @onizleme-mod at yazar and @onizleme-caylak at çaylak with seven-day sessions,
and the re-fired gate authenticated. No Cloudflare permission beyond the token CI already holds.

So the change is an addition beside Seed preview D1, gated on the same
steps.preview.outputs.skipped != 'true', carrying the same steps.preview.outputs.db and the same
CLOUDFLARE_API_TOKEN / CLOUDFLARE_ACCOUNT_ID, plus the two tier token variables the verb reads:
PREVIEW_TEST_SESSION_TOKEN (yazar) and PREVIEW_TEST_CAYLAK_SESSION_TOKEN (çaylak).

Prerequisite a builder cannot supply

Those two repo secrets do not exist yet — the repo's secret list holds only ALCHEMY_PASSWORD,
BETTER_AUTH_SECRET, BETTER_AUTH_SECRET_TEST, CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_API_TOKEN. The
token value is the whole credential and must be the same string on both sides: the seeding side (CI)
and the capture side, which reads the same variable names from the driver's environment
(packages/fabrika-cli/src/capture/auth.ts). Creating the two repo secrets from the driver's
existing token values is an act for a person holding the repo's keys, not part of the diff. The
workflow change lands and reviews without them; the live proof needs them set.

Out of scope

Triage note: nothing on the board owns the "CI preview seeding" surface — the nearest tickets are the
four above, and each names a different artifact. Filed standalone.

Acceptance criteria

  • .github/workflows/ci.yml runs preview-seed test-account against the preview D1 in the same job as Seed preview D1, gated on steps.preview.outputs.skipped != 'true' and passing --database-id "${{ steps.preview.outputs.db }}".
  • That step's env carries CLOUDFLARE_API_TOKEN, CLOUDFLARE_ACCOUNT_ID, PREVIEW_TEST_SESSION_TOKEN and PREVIEW_TEST_CAYLAK_SESSION_TOKEN from repo secrets.
  • A skipped preview runs neither seeding step, so a PR with no preview is unaffected.
  • On this PR's own preview the step's log names both tiers provisioned — @onizleme-mod at yazar, @onizleme-caylak at çaylak — and the job stays green.
  • review-ui render of a :auth surface against this PR's preview no longer refuses on 11 with "answered the seeded cookie as a visitor": it captures signed in, or refuses for a reason other than a missing account.
  • A comment beside the new step says why the two seeding commands are separate and where the tier token secrets are read on the capture side.

Original report (verbatim)

Summary

A pull request's preview is seeded with the sözlük and pano fixtures and with nothing else, so the
two review-ui test accounts exist on no preview. Every review-ui render of a :auth or
:auth-caylak surface therefore refuses on 11, and a PR whose only rendered change lives behind
sign-in ends the rendered gate at CANT-SEE with no path to a verdict from inside the gate.

What I was doing

Running the review-ui gate on PR #9276 (issue #9265). The PR's added state — the profile stat
strip's loading placeholders — paints on /profile alone, which is signed-in only.

What I observed

review-ui render --pr 9276 --surface /profile:auth --surface /u/onizleme-mod:auth refused every
tier-naming surface on 11 with surface "/profile:auth" at desktop did not render signed in (the preview answered the seeded cookie as a visitor), at both viewports. The tier tokens and
BETTER_AUTH_SECRET were all present in the run's environment, so the missing half is the account
and its session row on the preview's own D1, not the credentials.

The bare /u/onizleme-mod surface captured cleanly and shows the "kullanıcı bulunamadı" not-found
composition, which is the same fact from the other side: that account is not on this preview's D1.

The seeding step in .github/workflows/ci.yml ("Seed preview D1") runs
node packages/preview-seed/src/bin.ts run --database-id … and nothing else;
packages/preview-seed/src/seed.ts inserts terms, definitions, posts and the two search tables, and
writes no user, session or user_profile rows. preview-seed test-account, the command the
review-ui contract names as what puts each tier's account and session on a preview's D1, is
invoked nowhere in the workflows.

Why it matters

The :auth axis exists precisely so a signed-in-only composition stops being disclosed as unseen,
and today it cannot succeed on any preview. So every PR whose rendered delta is behind sign-in parks
its lane at CANT-SEE and costs a human — and the failure mode is quiet in the other direction too: a
bare route beside an auth-gated one captures the sign-in wall as a valid PNG, which is a clean-looking
shot of a state the PR did not add. The --flag path inherits the same block, since a forced run must
name a tier on every surface.

Pointers

Suggested next step (non-binding)

Extend the same CI step to run preview-seed test-account for both tiers against the preview D1 uuid
the deploy comment already carries, so a preview is seeded with accounts the same way it is seeded
with fixtures. Whether the platform-admin grant the --flag path needs rides along is a separate
call.


Filed by an agent · session 94113692-2733-4534-9963-c7ae534247d0 · 2026-09-15T23:34:37Z

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    p1Medium priorityready-for:agentAn execution engine may pick this up.status:triagedTriage signed off; ready for write-code to picktype:bugBehavior diverges from intent

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions