Skip to content

Launch Phase 5, Increment 7b: remove captcha_verified and nsfw_mode_enabled from the model (the drop follows the next publish) - #845

Merged
TheAnswerManIsHere merged 12 commits into
mainfrom
claude/wizardly-gauss-t27yhk
Nov 3, 2026
Merged

TheAnswerManIsHere merged 12 commits into
mainfrom
claude/wizardly-gauss-t27yhk

Conversation

@TheAnswerManIsHere

@TheAnswerManIsHere TheAnswerManIsHere commented Nov 3, 2026 •

Copy link
Copy Markdown
Owner

Workstream: #795

What & why

The second-to-last step of Issue #795 — Launch Phase 5 — Account and identity: the expand-then-contract transition for two retired users columns. captcha_verified has been unused since Increment 3 (PR #801). nsfw_mode_enabled belongs to the NSFW opt-in that Increment 6b (PR #836) withdrew.

Round 1 changed the shape of this PR. It first carried migration 0122, which drops both columns. Codex found that the published release still declares both columns in its Drizzle model. Drizzle names every declared column in a full-row select(), an insert and a returning(), so dropping them while that release serves breaks password and OAuth sign-in, sign-up and Stripe webhooks, and a code rollback would not repair it. Both assessors recommended splitting the step. So this PR:

  • removes both fields from the Drizzle model (lib/db/src/schema/auth.ts) and from the legacy fixture allowlist (the loader inserts only allowlisted columns);
  • does not touch the database: no path under lib/db/migrations/ changes, and both columns stay, with their defaults;
  • exempts exactly those two columns from the schema-parity test (UNDECLARED_PENDING_DROP in lib/db/src/baseline.test.ts) until the drop lands;
  • reads the NSFW column by raw SQL in phase5.nsfwReadiness while it exists;
  • updates accounts-and-auth.md, and adds to migrations-and-backfills.md the rule that caught this: the ORM declaration is a use.

The drop (0122) is a follow-up PR, opened once David has published a release built from this one; its migration comment names that release's SHA.

Approved-plan oracle

Oracle source: docs/plans/PLAN_PHASE5_ACCOUNT_IDENTITY.md, sha256 52a059b6fccc0836d2c5293fdf0680e0376524bcc4d293113bffb73cdfa844af (as amended in PR #833); the 7a/7b split recorded on Issue #795.

Settled decisions this step enacts (verbatim):

  • S23. "The captcha column dies in two releases. Increment 3 stops every read and write of captcha_verified — the middleware, the session blob fallback, the OAuth and local-auth row reads, the bypass logic, which moves to onboarding_completed_at — while the column still exists; Increment 7 drops it (migrations-and-backfills.md, Expand, then contract; Astra, round 1, C10)."
  • S13. "The live NSFW opt-in is made unavailable. nsfwModeEnabled is removed from the profile PATCH body and the admin editor, and its consumers … pass false; the column stays until a contract step."
  • Increment 7 (plan): "Contract: 0119 once Increment 3's release is the published one." The migrations have since been renumbered, so this is 0122.
  • migrations-and-backfills.md: "Drop a table or column … only once the release currently published neither reads nor writes what is removed."

Must not change: no read or write of either column anywhere; the classifier's parameter, which every caller passes as false; every other users column.

Decisions taken on my recommendation

  • Resequenced on review, not amended: the plan's requirement (drop only once the published release does not use the columns) is unchanged; what changed is which release counts as compatible. Both assessors called this a technical fork, so it was settled in the loop. Undo: put 0122 back into this PR (commit beeb034).
  • A temporary, two-column exemption in the parity test rather than keeping the fields in the model: it is the only way the model can stop naming the columns while the database still holds them. It is removed in the drop PR. Undo: revert a1fe81f.
  • When it lands, 0122 reports the count of true rows it discards rather than copying them (for the follow-up).
  • /simplify not run: a field removal and its follow-on changes.

Latitude granted to me: none.

Verification (head a1fe81f)

  • The class sweep: the published release's full-row users queries (Fable's list, in the review-action comment) are all covered by removing the declaration. git grep -n -E "captchaVerified|nsfwModeEnabled" over lib/db/src and artifacts/*/src returns nothing outside tests and the classifier's own parameter.
  • Sign-in with the columns present AND dropped (Astra's acceptance): routes.localAuth 50/50, routes.google.callback 12/12, routes.apple.callback 6/6 and passwordHardening 10/10, in both states.
  • phase5.nsfwReadiness 5/5 · legacyFixtureAllowlist 19/19 · phase3.productionAdopt 19/19 · lib/db 50/50 (parity included) · check-migration-snapshots ✓ (122 entries) · pnpm run typecheck clean · check:docs ✓.

Post-merge verification (live environment)

  1. Dev, after the Repl sync (read-only): information_schema.columns still returns both captcha_verified and nsfw_mode_enabled for public.users (the interim state). The site loads, and /api/healthz answers ok.
  2. At David's next publish: Replit's generated migration should show no change to users from this PR. If it offers to drop either column, that means dev's schema drifted; cancel and tell me.

Checklist

  • Docs stay true — spec and migrations guide updated; check:docs passes.
  • Build gate reproduced when relevant n/a
  • General fix, not one example — every full-row query on users in the published release, covered at the declaration.
  • Ship the surface n/a (no behaviour)
  • Async shows status n/a
  • Human decisions preserved n/a
  • Migration safety — no migration in this PR; the drop waits for a compatible published release.
  • In scope — the planned contract step, split in two.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UMMrrtY1Cuk3a8j8vPnwGR

claude added 10 commits November 2, 2026 05:58
…tired rules

Bring the accounts-and-auth spec, the security model's auth section and
Manual chapter 9 up to date with launch Phase 5 (#795): the verify, onboard,
act gate; Turnstile; suspension; the account deletion engine and what it
keeps; the NSFW opt-in withdrawn; the soft delete and reinstatement retired.
Glossary, decisions, migrations and testing gotchas, two memory notes, and
the regenerated in-app help.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UMMrrtY1Cuk3a8j8vPnwGR
… the payload

Manual chapters 2, 10 and 11; membership-entitlements, admin-console,
community-and-engagement, the meme studio doc, the roadmap and the retention
matrix; glossary pointers; security-model cross-links; manual durations
restated as intent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UMMrrtY1Cuk3a8j8vPnwGR
…erified

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UMMrrtY1Cuk3a8j8vPnwGR
… inventory row updated

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UMMrrtY1Cuk3a8j8vPnwGR
…ne in Phase 5

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UMMrrtY1Cuk3a8j8vPnwGR
…dden, not all content; matrix payments; UI labels; inventory rows; Drizzle note measured

The one Documentation batch for PR #841's Astra and Fable assessments.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UMMrrtY1Cuk3a8j8vPnwGR
…bled (0122)

The contract step the plan held until Increment 3's release was published
(published 2026-11-03 from 61a2d8b). Migration 0122 drops the two users
columns nothing reads or writes: captcha_verified (retired by Increment 3)
and nsfw_mode_enabled (the opt-in withdrawn by Increment 6b). It reports how
many rows held true before each drop and is a no-op when the columns are
already gone. The schema, the legacy fixture allowlist, the snapshot
exemptions and the NSFW readiness test follow; the accounts spec now says the
columns are gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UMMrrtY1Cuk3a8j8vPnwGR
@github-actions

github-actions Bot commented Nov 3, 2026

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-03T01:07:12.561501Z a1fe81f Manual request
🔒 Security Review ✅ Completed 2026-11-03T00:49:49.389857Z beeb034 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

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

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

Copy link
Copy Markdown
Owner Author

Astra — round 1

Assessed at beeb0347e931a67b3147535d13800f74f4ae07ee · findings 4449549949 · requested gpt-6-astra at xhigh

Oracle met at this head: no

The cleanup is appropriate, but the published application still requests these columns when signing people in. Dropping them now would break sign-in on instances still serving that release, and reverting the code would not restore service. I recommend publishing the application’s remaining dependency removals first, then dropping the columns in a subsequent release. This completes the already agreed two-release approach.

Finding 4449549949 — recommend correction before the contract ships.

Direct inspection confirms that 61a2d8b declares both fields in usersTable, password login uses .select().from(usersTable), and OAuth includes full-row selection and .returning(). Those routes are unchanged at this head. The reviewer’s supplied Drizzle reproduction establishes that the selection explicitly names the removed columns; I have not independently rerun that reproduction.

The failure class is implicit database dependencies surviving the removal of explicit business-logic uses. Removing both fields from the shared ORM declaration addresses that class at its source. This head makes that removal alongside the destructive migration, so it protects the new application but leaves the published application incompatible.

The consequence follows the documented operating model: old instances serve while the shared database changes, and code rollback leaves those changes in place. Replit can also apply the deletions before the new server boots. See the migration policy. Idempotent drops and passing tests against the new code do not establish compatibility with the published code.

The additional release and bounded test/documentation adjustments are proportionate to preventing a sign-in outage that code rollback alone cannot repair. Although the general migration policy allows same-release contraction before Seed, S23 and this step’s oracle explicitly require prior published compatibility. That settled requirement governs here; no new product decision is needed.

I recommend this correction scope:

  1. Publish the compatibility change while retaining both database columns. Keep the shared ORM-field removals and necessary fixture changes; defer 0122 and its journal registration. Align the tests and documentation with this intermediate state.
  2. Account for the existing verification dependency. The schema-parity check rejects every undeclared database column. It needs narrowly scoped treatment of these two intentionally retained columns during the transition, while preserving checks for everything else. Remove that transition treatment with the later drop.
  3. Ship the contract after the compatible release is published. Name that actual release in the migration’s explanation and deployment instructions. Preserve the classifier parameter, callers’ false values, and every other users column.

Success should demonstrate that the compatibility release supports local and OAuth sign-in/account creation with the columns retained and after their removal. Include generated selections, returned rows and inserts in that verification; a search for explicit field references alone misses this mechanism. Existing focused checks can supply the evidence.

Remaining investigation and next action: Claude should confirm whether 0122 has reached Replit’s dev database. The PR reports a local test migration, which does not establish dev’s state. Because publishing copies dev’s schema changes, the compatibility publish must retain both columns there too. I have not inspected live deployment state.

Recommend preparing the compatibility release now, resolving that narrow deployment-state question before publication, and retaining the column drop as the subsequent contract step under the existing review and publish process.


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

Fable — round 1

Assessed at beeb0347e931a67b3147535d13800f74f4ae07ee · findings 4449549949 · expected claude-fable-5-1 · instructed alias fable · definition effort xhigh

Oracle met at this head: no
Running as: Claude Fable 5.1 (claude-fable-5-1) at unable to name.

David's readout

This change deletes the two retired account columns, and the deletion itself is written carefully. What is not met is the one condition the plan put on it: the drop may only run once the version of the site you have already published no longer touches those columns. The published version's code never mentions them, which is what everyone checked — but the database layer it uses still lists them, so every time that version loads an account row (signing in with a password, signing in with Google or Apple, creating an account, handling a Stripe event) it asks the database for those columns by name. Drop them while that version is still serving, and those requests fail until the new version has fully taken over; and if you ever went back to the older version, they would keep failing until another migration put the columns back. I reproduced the behaviour against the installed database library rather than taking the reviewer's word for it.

Nobody is downstream of that yet — Seed has not begun — and the rules do allow a drop in the same release before Seed. But the plan you approved chose to practise the safe order anyway, and the change says it did while in fact not doing so. The safe order costs little here: ship this change without the drop (the code stops listing the columns), and run the drop in a small follow-up after your next publish, whenever that is. No extra publish is needed for it, and nothing needs deciding by you. If you would rather spend the pre-launch latitude and drop in one go, that is your call to make, since the plan said otherwise; my recommendation is the two-step order.

Assessment and recommendations

4449549949 — correct it, by resequencing rather than by changing the migration

The failure class. A contract migration that drops a column the published release's ORM table still declares. The rule it violates is the one the oracle quotes (migrations-and-backfills.md, Expand, then contract: a drop runs "only once the release currently published neither reads nor writes what is removed"). The condition that produces it: Drizzle writes every declared column by name into any query that does not list its own columns. I measured this against the installed ORM (drizzle-orm 0.45.2, .toSQL() on a four-column users table carrying both fields):

select():           select "id", "email", "captcha_verified", "nsfw_mode_enabled" from "users" where ...
update.returning(): update "users" set ... returning "id", "email", "captcha_verified", "nsfw_mode_enabled"
insert.returning(): insert into "users" ("id", "email", "captcha_verified", "nsfw_mode_enabled") values ($1, default, default, default) returning ...

So the class is wider than the finding's example: a plain insert(usersTable).values(...) is in it as well, because the column list names the dropped columns even when no value is supplied.

What is actually wrong, from my own inspection. 61a2d8b (the #841 docs-sweep squash) is an ancestor of origin/main, and origin/main's lib/db/src/schema/auth.ts still declares captchaVerified (line 22) and nsfwModeEnabled (line 76); this PR is what removes them. That the published release is 61a2d8b is the builder's claim in the migration's own comment ("published by David on 2026-11-03") — I cannot check what Replit is serving — but it does not matter which commit is published: the fields leave the ORM only in this PR, so whatever release precedes it still declares them. At the published release (git grep on origin/main, production code only), the queries that would name the columns are:

  • full-row select() on usersTable: routes/localAuth.ts:271, 357, 585, 849; routes/auth.ts:178, 347; lib/webhookHandlers.ts:79, 88; lib/stripeStorage.ts:18; lib/dataLifecycle.ts:10; routes/admin.ts:672, 804
  • insert(usersTable): routes/localAuth.ts:186; routes/auth.ts:231; routes/admin.ts:773
  • update(usersTable) ... returning(): routes/admin.ts:309, 1995

That is password sign-in, OAuth sign-in and sign-up, local sign-up, Stripe webhook handling, and the admin user editor. The finding's cited lines (localAuth.ts:270–274) match what I read.

Why the window is real, not hypothetical. The repository's own rule says so and I read it rather than inferring it: migrations run at boot before listen() (artifacts/api-server/src/index.ts:323, await runMigrations()), the deployment is autoscale, "instances of the new release boot and migrate the one shared database while instances of the previous release are still serving", and on production "Replit's own publish migration changes the schema even earlier, when the publish is approved" (migrations-and-backfills.md, Why the previous release matters; replit-environment.md, Publish applies a schema migration of its own). Reverting code leaves the schema where it is (replit-platform.md, Republishing, history, rollback). Those are documented decisions and measurements by others, not mine.

Consequence and recoverability. Pre-Seed (launch-definition.md: the full build precedes Seed, and the plan itself says "no release is published to users yet"), so the people affected are David and test accounts; Stripe is in test mode and retries. The rollout window heals itself in minutes; a code revert does not — it needs a forward migration re-adding both columns (the plan already names this: "a contract step is reversible by re-adding the column null"). So this is recoverable, which is why the pre-Seed latitude exists. Three things still make the correction worth its cost:

  1. The plan chose the order on purpose: "Pre-Seed latitude applies ... but the expand/contract order is kept so the habit is in place when it binds" (plan, Data Model and Migration Impact). Shipping the drop in the same release as the field removal departs from that choice; the PR's text claims to honour it ("CONTRACT, NOT EXPAND ... its code neither reads nor writes either column") and does not. A false claim in a migration file is read by every later session as a precedent for what "stopped using" means.
  2. The habit being practised is exactly the one this PR gets wrong. S23 enumerated the reads Increment 3 was to stop ("the middleware, the session blob fallback, the OAuth and local-auth row reads, the bypass logic") and the ORM declaration was not on the list — so Increment 3 left the field believing every read was gone. That is the shared cause, and the correction below names it.
  3. The correct order is cheap here. It needs no publish of its own: the drop waits for whichever publish comes next, and launch work will publish again.

Correction scope.

  • This PR keeps the schema-field removals (lib/db/src/schema/auth.ts), the allowlist entries' removal (safe ahead of the drop: load.ts:117 selects only the columns the allowlist names, and the exporter checks table presence, not column presence, so the still-present column simply takes its default on load), and the test change reworked so it no longer asserts the column is absent (in the test database it still exists until 0122 runs; assert instead that the PATCH is accepted and, via raw SQL, that the column where present stays false). It sheds lib/db/migrations/0122_*.sql, the _journal.json entry and the SNAPSHOT_EXEMPT_TAGS line, and keeps accounts-and-auth.md in main's present-tense wording ("is dropped by 0122 ... once the release that stopped using it is the published one"), which is correct as it stands.
  • A follow-up PR carries 0122, the journal entry, the exempt tag and the past-tense doc edit, opened once a release whose auth.ts declares neither field is the published one; its migration comment names that release's SHA, and the comment's claim is then true at the SQL level.
  • Record the resequencing on Issue Launch Phase 5 — Account and identity #795 as the 7a/7b split was recorded. It changes how the plan's requirement is satisfied (which release is the compatible one) while keeping the property it proves — a technical fork settled in the loop, not a plan amendment.
  • Shared cause, one sentence (optional, builder's call): in migrations-and-backfills.md, the Contract bullet, say that for a column drop "neither reads nor writes" includes the ORM declaration — Drizzle names every declared column in select(), insert and returning(), measured with .toSQL() on 0.45.2 — so the release that stopped using a column is the one whose table definition no longer carries it. Without it the next contract step repeats this.

Observable acceptance.

  • git diff origin/main...HEAD --stat for this PR lists no path under lib/db/migrations/.
  • git grep -n -E "captchaVerified|nsfwModeEnabled" HEAD -- lib/db/src 'artifacts/*/src' returns nothing outside tests (at the current head it already returns nothing — I ran it).
  • For the follow-up: git show <published-sha>:lib/db/src/schema/auth.ts | grep -c -E "captcha_verified|nsfw_mode_enabled" prints 0, and the Repl's published SHA is confirmed through the connector before that PR merges.
  • phase5.nsfwReadiness passes with the column still present in the test database.

What remains possible if left as is. For the length of one rollout, every request on an old instance that loads, creates or updates an account row fails with an undefined-column error — sign-in, sign-up, OAuth and Stripe webhooks included — and a code revert afterwards keeps failing until a forward migration re-adds the columns. Pre-Seed, that reaches David and test accounts only. Choosing to accept it is a departure from the plan's stated order and so David's to make, not ours; I do not recommend it.

Oracle status, for the record. Everything else the oracle requires holds at this head by my inspection: the diff removes exactly the two fields and touches no other users column; no production code at HEAD references either field; the classifier's parameter is not in the diff (I did not re-audit its callers). The no is on the one precondition the oracle places on the drop, which this PR's structure cannot satisfy, not on the drop's own correctness.

Questions and next action

  • For Claude: none that changes the recommendation. Two things to verify while resequencing — that the reworked nsfwReadiness assertion passes with the column present, and that the fixture export/load tests pass with the allowlist entries gone and the column still in the test schema (my reading of load.ts:117 says they will; the run is the proof).
  • For Astra: if its recommendation is to ship the drop in this release under the pre-Seed latitude, the disagreement is not technical — the plan chose the order — and it goes to David's readout rather than to the tie-break. If it recommends a different mechanism (something the new release could do to protect the old one), I do not see one: nothing in the new release changes the queries the old release runs.
  • For David: nothing requires an answer. The plan's choice covers this; the line above is yours to reopen only if you want to.

Recommended next action: write — this is round 1, and the correction is a split, not new machinery. Supported now: remove 0122, its journal entry and exempt tag from this PR; rework the test; keep main's doc wording; note the resequencing on Issue #795; optionally add the one-sentence guide note. Dependent on an external event: the follow-up PR with 0122 waits for a publish of a field-less release, which only David can do and which launch work will bring in its own time. Nothing here authorises a merge.

Tie-break. None exercised; I have not read the other assessment. If one is needed and the disagreement is purely technical, my position is the resequencing above, for the three reasons under Constraint and recoverability.


Generated by Claude Code

Copy link
Copy Markdown
Owner Author
round: 1
head assessed: beeb034
decision: write — resequence. Both assessments said the oracle is not met and both recommended this split. No tie-break was needed and nothing goes to David.

Finding 4449549949 — class: a contract migration that drops a column the published release's ORM table still declares. Drizzle names every declared column in a full-row select(), an insert and a returning(); Fable measured this with .toSQL() on drizzle-orm 0.45.2.
Sweep of the class: the published release's full-row users queries, as listed in Fable's assessment — select() at localAuth.ts:271,357,585,849, auth.ts:178,347, webhookHandlers.ts:79,88, stripeStorage.ts:18, dataLifecycle.ts:10 and admin.ts:672,804; insert at localAuth.ts:186, auth.ts:231 and admin.ts:773; update…returning() at admin.ts:309,1995. Every one is covered by removing the fields from the model in this release and dropping the columns in the next.
Changes:
- removed lib/db/migrations/0122_drop_captcha_and_nsfw_opt_in.sql, and restored _journal.json and check-migration-snapshots.ts from main. This PR now touches no file under lib/db/migrations/.
- kept: the auth.ts field removals and the legacy fixture allowlist removals.
- lib/db/src/baseline.test.ts: UNDECLARED_PENDING_DROP exempts exactly users.captcha_verified and users.nsfw_mode_enabled from "built, not declared", until 0122 removes them (Astra item 2).
- phase5.nsfwReadiness: reads the column by raw SQL while it exists.
- accounts-and-auth.md: says the model dropped the fields in 7b and 0122 drops the columns after the next publish.
- migrations-and-backfills.md, Expand then contract: one rule — "The ORM declaration is a use" (the shared cause both assessors named).
Proof (Astra: sign-in and account creation with the columns retained AND removed): routes.localAuth 50/50, routes.google.callback 12/12, routes.apple.callback 6/6 and passwordHardening 10/10, run with the columns present, then again with them dropped from the test database (then restored). Also nsfwReadiness 5/5, legacyFixtureAllowlist 19/19, productionAdopt 19/19, lib/db 50/50 and check-migration-snapshots ✓ (122 entries). Typecheck clean.
Astra's deployment question: 0122 never reached the Repl's dev database, because PR #845 is unmerged and the Repl is at main. The interim release therefore publishes with both columns still present.
Follow-up: a new PR carries 0122 (migration, journal, exemption, removal of the UNDECLARED_PENDING_DROP entries, past-tense doc) after David publishes a release without the declarations. Its migration comment names that SHA, confirmed through the connector before merge.

Generated by Claude Code

…after the next publish

Codex (PR #845, round 1) found that the published release still declares
both columns in the Drizzle model, which names every declared column in a
full-row select, an insert and a returning(); dropping them now would break
sign-in, sign-up and Stripe webhooks on instances still serving it. Both
assessors recommended the split. This release removes the fields from the
model only. Migration 0122 moves to a follow-up PR after the next publish.

The parity test exempts exactly the two columns until 0122 drops them; the
NSFW readiness test reads the column by raw SQL while it exists; the
migrations guide now says the ORM declaration counts as a use.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UMMrrtY1Cuk3a8j8vPnwGR
@TheAnswerManIsHere TheAnswerManIsHere changed the title Launch Phase 5, Increment 7b: drop captcha_verified and nsfw_mode_enabled (0122) Launch Phase 5, Increment 7b: remove captcha_verified and nsfw_mode_enabled from the model (the drop follows the next publish) Nov 3, 2026

Copy link
Copy Markdown
Owner Author

Round 2 context. Head a1fe81f resequences 7b after round 1: the model no longer declares either column, and no migration is in the diff. What would end the loop: a clean pass, or findings only on the parity exemption's scope or the test rework. A finding that the interim state (fields out of the model, columns still in the database) breaks a read, insert or returning on users would reopen the design.


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

@codex review


Generated by Claude Code

@chatgpt-codex-connector

Copy link
Copy Markdown

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

Reviewed commit: a1fe81fe75

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

@TheAnswerManIsHere
TheAnswerManIsHere merged commit 1231526 into main Nov 3, 2026
21 of 29 checks passed
@TheAnswerManIsHere
TheAnswerManIsHere deleted the claude/wizardly-gauss-t27yhk branch November 3, 2026 01:15
TheAnswerManIsHere added a commit that referenced this pull request Nov 3, 2026
…nd nsfw_mode_enabled (#847)

The contract step of the expand-then-contract pair begun in PR #845. That
release (main at 1231526), the first whose Drizzle model declares neither
column, is now the published one, so 0122 drops both users columns. It
reports how many rows held true in each before dropping, and is idempotent.
The parity test's pending-drop exemption and the column-present branch of the
NSFW test go with it; the accounts spec and decisions log move to past tense.


Claude-Session: https://claude.ai/code/session_01UMMrrtY1Cuk3a8j8vPnwGR

Co-authored-by: Claude <noreply@anthropic.com>
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.

2 participants