Skip to content

Launch Phase 5 — Account and identity #795

Open
1 of 1 issue completed
Open

Description

@TheAnswerManIsHere

State of Play

Phases

Parent: #628

Activity

  1. TheAnswerManIsHere commented on Oct 30, 2026

    @TheAnswerManIsHere
    OwnerAuthor

    Handoff — 2026-10-30

    Handing off because: Phase 3 (#770) is closed, and Phase 5 is a different workstream. The Phase 3 session's context would be dead weight here.

    What just finished: Launch Phase 3 — Data and environments (#770, closed 2026-10-30).

    Settled this session — do not re-open:

    • Production holds exactly one account: David's, signed up with the bootstrap admin address overhypeme+admin@gmail.com, which grants admin by email (lib/auth.ts, BOOTSTRAP_ADMIN_EMAIL), not through a stored is_admin flag. Every pre-reset account, session and fact is gone, by design.
    • Dev keeps its content: 26 users, 53 facts, 58 settings, on database heliumdb.
    • Approve Replit's generated migration at publish (David, 2026-10-28). Replit's publish copies dev's tables into production but not functions or triggers (measured 2026-10-30). A new trigger therefore reaches production only through our own migration runner at boot, never through Replit's copy, so a Phase 5 migration that adds a trigger must ship as a runner migration.
    • Settings into code is Phase 13's work (plan v9), not Phase 5's. Its item-by-item lists, the entitlement grid's move included, are proposed scope that Phase 13's own plan approval confirms. Phase 5's "beta-overlay row in the grid" therefore goes into the grid as it stands today, the tier_feature_permissions table edited at /admin/features.
    • The dev-admin-login backdoor stays through Phase 4; Phase 15 redesigns it (David, 2026-10-21; decisions.md).

    Ruled out:

    • Seeding production by CSV import (David: every fact must be attributable to a real user who isn't him; launch-feature-inventory.md).

    Live state that does not cross: none.

    Still open (not Phase 5's to settle, but in its neighbourhood):

    Durable learnings: the Replit gotchas are in #770's harvest-notes comment, for the next /document or /maintenance harvest.


    Generated by Claude Code

  2. TheAnswerManIsHere commented on Oct 31, 2026

    @TheAnswerManIsHere
    OwnerAuthor

    Planning record — plan approved 2026-10-31

    Exchanges run: 3 with Astra (gpt-6-astra, xhigh, read-only): scope (round 0), assessment rounds 1 and 2. A third round was not run: the last changes were Astra's own suggested passages, then David's answers, which removed mechanism rather than adding it.

    Ledger at approval: 12 concerns; 10 addressed, 2 accepted by David (paid access after a cancelled deletion; under-13 handling). None settled over dissent.

    What Astra changed in the plan, in one line each: verify before onboard before act; 18+ enforced at photo upload, not just computed; a mutating-GET inventory beside the method rule; one deletion engine for admin and self-service, with the admin population lock at accept and suspend; owner-hiding derived from the deletion request so in-flight uploads stay hidden; destructive claims serialized per owner; pre-existing retired tombstones stay permanent; the captcha column retired over two releases; the share-by-email widget that sends no token today; tests that drive real paths instead of counting rows.

    David's overrides and design calls: no Terms text in Phase 5 (over Astra's and Claude's recommendation; Phase 14 does it once); everything in My content undoable, photos included; memes baked at save after research (Imgflip stores files; Cloudinary persists derived images; design tools export flattened files for sharing; the existing renderer-version ETag shows recipe memes change look when the renderer changes).

    👀 FYI — the container's scratch area was reclaimed during planning, taking the Astra sign-in with it; nothing in the plan was affected, and a further Astra exchange would start with a fresh sign-in code.


    Generated by Claude Code

  3. 97 remaining items

  4. TheAnswerManIsHere commented on Nov 2, 2026

    @TheAnswerManIsHere
    OwnerAuthor

    👀 FYI — Retiring reinstatement in PR #837 also removed the only manual way to correct a Stripe cancellation or refund that never reached us. Before, an admin could deactivate and then reinstate the account to force a re-check against Stripe. Now nothing on the admin surface can do that, and suspension touches no billing. The gap was already recorded as accepted ("Stripe↔local membership reconciliation", docs/engineering/deferred-work.md). The docs sweep now states that the workaround is gone (membership-entitlements.md, Manual chapter 10). No code change has been made. Separately, a source comment in membershipRefresh.ts still names "admin soft-delete, reinstatement" as callers. That is product code, so it is out of scope for this Documentation PR and is recorded as next.


    Generated by Claude Code

  5. TheAnswerManIsHere commented on Nov 2, 2026

    @TheAnswerManIsHere
    OwnerAuthor

    David, 2026-11-02 ~23:45 UTC: not yet published. Increment 7b (0122) stays held until he publishes. Before that publish: TURNSTILE_SECRET_KEY and VITE_TURNSTILE_SITE_KEY go into Replit's secrets. After it: his own set-up on the live site, passing one real challenge. Then 7b starts from this issue's To resume line.


    Generated by Claude Code

  6. TheAnswerManIsHere commented on Nov 3, 2026

    @TheAnswerManIsHere
    OwnerAuthor

    Published. David published production on 2026-11-03 ~00:20 UTC, from main at 61a2d8b with the Turnstile secrets set (both confirmed present in the Repl by name). get_publish_status reads success, and https://overhype.me/api/healthz answers 200 {"status":"ok"}. Next: David's own set-up on the live site, passing a real challenge, plus one Google and one Apple sign-in. Then Increment 7b (0122) starts.


    Generated by Claude Code

  7. TheAnswerManIsHere commented on Nov 3, 2026

    @TheAnswerManIsHere
    OwnerAuthor

    Live check (David, 2026-11-03): the Turnstile challenge passes on overhype.me ("Success!"). Google and Apple sign-in both work, but each created a new account, because they send david@davidcarlos.net and the admin account is overhypeme+admin@gmail.com. Accounts are matched by email only: no provider subject is stored, and linking refuses a mismatched email (link_error=email_mismatch). Now, no code: David makes the david@ account his everyday account and grants it admin from the bootstrap admin account; the bootstrap account stays as break-glass. Next to plan, with the "Last used" badge: linked sign-in methods. That means a provider identity stored by the provider's permanent ID; connecting from Profile whatever the provider's email, after a fresh password check; and a prompt to "sign in and connect" before a provider sign-in silently creates a second account. This also covers Apple's Hide My Email. The 7b precondition is met (the publish is live), so Increment 7b starts now.


    Generated by Claude Code

  8. TheAnswerManIsHere commented on Nov 3, 2026

    @TheAnswerManIsHere
    OwnerAuthor

    👀 FYI — Increment 7b is open as PR #845 — Launch Phase 5, Increment 7b: drop captcha_verified and nsfw_mode_enabled (0122). Decision taken on my recommendation: the migration reports the count of true rows it discards rather than copying them anywhere. Neither value is needed: onboarding replaced the captcha flag, and the NSFW opt-in was withdrawn. Undo: a forward migration re-adding the columns. Production loses the columns only at David's next publish, when he approves Replit's two DROP COLUMN statements.


    Generated by Claude Code

  9. TheAnswerManIsHere commented on Nov 3, 2026

    @TheAnswerManIsHere
    OwnerAuthor

    👀 FYI — Increment 7b is resequenced: the two columns leave the code's database model now, and the drop (0122) waits for one more publish. Codex found, and both assessors confirmed, that the published release still declares the columns in its model, so dropping them now would break sign-in while it serves. PR #845 — Launch Phase 5, Increment 7b: remove captcha_verified and nsfw_mode_enabled from the model (the drop follows the next publish) now holds only the model change. A follow-up PR carries 0122 after David's next publish. The rule that caught it is now in migrations-and-backfills.md: the ORM declaration is a use. Undo: put 0122 back into PR #845 (beeb034).


    Generated by Claude Code

  10. TheAnswerManIsHere commented on Nov 3, 2026

    @TheAnswerManIsHere
    OwnerAuthor

    Harvest notes — PR #845 — Launch Phase 5, Increment 7b: remove captcha_verified and nsfw_mode_enabled from the model (the drop follows the next publish) (squash 1231526; round 1 had one Codex finding, both assessors wrote for it; round 2 was clean)

    Decisions and why

    • A column drop takes two releases, because the ORM declaration is a use. 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. So a release whose usersTable still declares a column reads it on every sign-in, sign-up and Stripe webhook, even though no code mentions the field. 7b removes the fields from the model; 0122 drops the columns only once a release without them is the published one. Recorded in migrations-and-backfills.md, Expand, then contract.
    • Parity-test transition set: UNDECLARED_PENDING_DROP in lib/db/src/baseline.test.ts exempts exactly users.captcha_verified and users.nsfw_mode_enabled from "built, not declared". The drop PR removes them from that set.
    • The legacy fixture needs no transition state: the loader inserts only allowlisted columns, so a column in the database but not in the allowlist simply takes its default.

    Alternatives rejected

    • Same-release drop under pre-Seed latitude: the plan chose to practise the order ("the expand/contract order is kept so the habit is in place when it binds").
    • Keeping the fields in the model until the drop: then the release that drops them would still be the first one without the declaration, and nothing would be gained.

    Gotcha candidates

    • A & at the end of an && chain backgrounds the whole chain in a subshell. Variables assigned inside it don't exist in the next commands of the same shell line, so a later $S/... path expanded to /.... Detach only the one command (setsid … & on its own line).
    • Sign-in suites can run against both schema states in one session: run with the columns present, drop them in the public schema, run-test.sh --setup (which re-clones), run again, then restore them.

    The follow-up: a new PR carries 0122, its journal entry, the snapshot exemption, the UNDECLARED_PENDING_DROP removal and the past-tense doc, after David publishes a release containing 1231526. Its migration comment names the published SHA, confirmed through the connector first.


    Generated by Claude Code

  11. TheAnswerManIsHere commented on Nov 3, 2026

    @TheAnswerManIsHere
    OwnerAuthor

    Build report — PR #845 — Launch Phase 5, Increment 7b: remove captcha_verified and nsfw_mode_enabled from the model (the drop follows the next publish) · differs on 2 points; 3 decisions questioned; partial — something could not be assessed

    The first half of Increment 7b of Launch Phase 5: the code's description of the account table stops listing the two retired columns (the old 'passed a captcha' flag and the withdrawn per-account NSFW switch) so a later release can drop them without breaking sign-in; the drop itself was pulled out of this PR after review and now waits for your next publish.

    Evidence: workstream Issue #795 — Launch Phase 5 — Account and identity · PR #845 — Launch Phase 5, Increment 7b: remove captcha_verified and nsfw_mode_enabled from the model (the drop follows the next publish)

    Needs you: Nothing now; at your next publish, if Replit's schema step offers to drop captcha_verified or nsfw_mode_enabled from users, cancel and tell the builder (the PR's own post-merge instruction, and the one check only you can make).

    What was built

    Read from the twelve commits and the merged six-file diff (47 lines added, 16 removed, no migration). The code's model of the account table no longer declares two columns: captcha_verified, unused since Increment 3, and nsfw_mode_enabled, the opt-in Increment 6b withdrew. That matters because the database library writes every declared column by name into every 'load this account', 'create this account' and 'update and return' query, so the published site (61a2d8b) still asks for both columns on every password, Google or Apple sign-in, sign-up and Stripe event even though no code mentions them; only a release whose model omits them can safely survive their removal. Around that one change: the test that keeps the code's table model and the real database in step is told to tolerate exactly these two columns being in the database but not in the code, with a comment naming the migration that ends the exemption; the old-data test fixture stops carrying them; one test reads the NSFW column by raw SQL while it still exists and returns nothing once it is gone; the accounts spec describes the interim state; and the migrations guide gains the rule that caught this ('the ORM declaration is a use'). The database is untouched everywhere: dev, test and production keep both columns with their defaults. The PR opened with the drop migration (0122), its journal entry and a snapshot-check exemption; the second commit removed all three after Codex's finding.

    Decisions taken on my recommendation

    • The drop was pulled out of this PR and resequenced into a follow-up after your next publish, treated as a technical fork settled in the review loop rather than a plan amendment: the plan's rule (drop only once the published release does not use the columns) is unchanged; what changed is which release counts as not using them. — undo: Put migration 0122 back into this PR (its content is commit beeb034) and merge the drop in one go, accepting a one-rollout sign-in outage on the current published release. · Concern: None with the call itself. It does mean Phase 5 cannot close until you publish once more and the follow-up merges; and the plan's own S23 wording ('dies in two releases') is now out of date (see Disagreements).
    • A temporary two-column exemption in the schema-parity test, rather than keeping the two fields in the code's model until the drop. — undo: Recorded as 'revert a1fe81f'. · Concern: That undo reverts the whole resequencing commit, not just the exemption; the exemption cannot be removed on its own without either putting the fields back or dropping the columns, so this and the first decision stand or fall together. The alternative (keeping the fields) would have gained nothing, as the harvest notes say.
    • When migration 0122 lands in the follow-up, it will report how many rows held 'true' for each column and discard the values rather than copying them anywhere. — undo: Have the follow-up copy the two columns into a side table before dropping them (nothing in the product would read it). · Concern: This decides a file that is no longer in this PR; it needs re-recording on the follow-up or it will be lost. The values themselves are worthless by your own rulings: onboarding replaced the captcha flag and the NSFW opt-in is withdrawn.
    • The pre-PR simplification pass was not run, since the change is a field removal and its follow-ons. — undo: Run it on the follow-up.

    Ramifications

    For you: one more publish stands between here and the end of Phase 5. The drop needs a release containing this change (squash 1231526) to be the published one, and at that publish Replit should show no change to the users table; if it offers to drop either column, that is the outage this PR was reshaped to avoid, and cancelling is the remedy. After this publish nothing visible changes. For users: nothing, now or after the publish; sign-in, sign-up and every screen behave the same. For the next unit: a follow-up PR carries 0122, its journal entry, the snapshot exemption, the removal of the parity exemption and the past-tense docs, and must confirm through the connector which release is live before it merges. More durably, every future column removal in this product now takes two releases by written rule (remove the field, then drop the column), a small standing cost on each contract step and the right one. The 'two releases' count the plan's S23 gives is now three in practice.

    Shipping unfixed

    • Reasonable: Both columns stay in every database, production included, holding whatever values they have, invisible to the code, until a follow-up that waits on a publish with no date. — Dead data costs nothing, and the parity test now names the two columns and the migration they wait for, so they cannot be forgotten silently.
    • Reasonable: The sign-in outage Codex found is still possible if the drop PR is ever merged while a release that declares the columns is the published one; what prevents it is a procedure (confirm the live release's SHA through the connector first), not a check that fails. — The procedure is written in three places (the review-action, the harvest notes, the migrations guide), the follow-up's migration comment is to name the SHA, and before Seed the blast radius is you and test accounts for the length of one rollout.

    Where it disagrees with the builder (2)

    • The builder's record of this unit lives in the FYI comments, the PR body and the harvest notes. At the cutoff the issue's State of Play, the block /status and a fresh session read as current, still says 'Everything but Increment 7b is done', '7b waits for David's next publish', 'Last movement: 2026-11-02 06:45 UTC', and its Phases checklist shows 7b 'not yet opened'; it carries no line for PR Launch Phase 5, Increment 7b: remove captcha_verified and nsfw_mode_enabled from the model (the drop follows the next publish) #845 — Launch Phase 5, Increment 7b: remove captcha_verified and nsfw_mode_enabled from the model (the drop follows the next publish), none for the resequencing, and its Spend so far line has nothing for this PR's Astra and Fable round-1 runs, both of which ran and are posted on the PR. — A fresh session or /status would read that 7b has not started and that your publish of 61a2d8b was the last thing it waited for, when in fact it is half done and needs another publish; and the spend line is the one you set caps from. Earlier reports flagged the same pattern and it was corrected after the fact each time.
    • The PR body says the plan is 'unchanged' and the change is 'resequenced, not amended'. The requirement is indeed intact. But S23, quoted verbatim in the same body, says 'The captcha column dies in two releases' and lists the reads Increment 3 was to stop; the model declaration was not on that list, which is why it now takes three releases. Nothing in this PR touches the plan file on main. — Small. The rule that matters now lives in the migrations guide, which every future contract step reads; the plan becomes history when Phase 5 closes. Worth knowing only so the 'two releases' count in the plan is not taken at face value.

    Spend

    Where we are

    • Planned: Launch Phase 5 — Account and identity: an account becomes a verified, consenting, age-known identity that can leave cleanly, with the data model ready for beta and adult content without shipping either, in seven increments plus the 3b, 4a/4b, 5a/5b, 6a/6b and 7a/7b splits. Increment 7b is the contract step: drop the old captcha column and the withdrawn NSFW column (migration 0122) once the release that stopped using them is the published one.
    • Done: Everything but the drop itself. PR Launch Phase 5, Increment 7b: remove captcha_verified and nsfw_mode_enabled from the model (the drop follows the next publish) #845 — Launch Phase 5, Increment 7b: remove captcha_verified and nsfw_mode_enabled from the model (the drop follows the next publish) — merged 3 November at 01:15:30 UTC as squash 1231526 on main (read; the same six files as the PR), with Build, Test, Frontend Test and all four E2E Smoke shards green on its final commit a1fe81f (read), Codex's round 2 clean on that commit (read) and the one round-1 thread resolved with its fix. Your publish of 61a2d8b at about 00:20 UTC met 7b's original precondition; the review then showed that release still declares the columns, so the drop waits for a publish containing 1231526. At the cutoff, 45 seconds after the merge, the Repl sync and the post-merge dev check were not yet reported.
    • Next: A follow-up PR carrying migration 0122, its journal entry, the snapshot exemption, the removal of the parity exemption and the past-tense docs, opened after you publish a release containing this change, with the live release's SHA confirmed through the connector before it merges; that completes the Phase 5 plan. Beside the plan: linked sign-in methods and the 'Last used' badge are next to plan (your 00:43 live check found Google and Apple sign-in each created a second account, because the admin account is on a different email), and Phase 9's member comment-delete button is owed before launch.

    Does not do: It drops nothing: both columns are still in every database, production included, with their values, and the live site is unchanged until your next publish and behaves the same after it. It does not finish Increment 7b or Phase 5; the drop needs another publish and another PR. It does not change any screen, any sign-in path or any other account column, and it does not update the plan file's 'two releases' wording.

    You are now trusting: That Replit's publish-time schema step copies dev's tables, where both columns remain, rather than deriving from the code's model (the Phase 3 record says it copies dev's tables; if it offered the drop anyway, the PR asks you to cancel). That nothing in the code reads the two columns by name: the builder's and Fable's searches, and the sign-in suites passing with the columns present and then dropped, are the evidence. And that whoever merges the drop PR first confirms the live release no longer declares the columns, since that is a procedure rather than a check that fails.

    Session (the builder's call): continue — the 0122 follow-up is the last Phase 5 step and waits only on David's next publish; this session holds its context

    Could not assess: The fleet's paid-run ledger in TheAnswerManIsHere/KITT is not reachable from this session (access denied), the plan file is beyond my reach so its text is known only through the PR body's quotations, and the Repl sync and post-merge dev check were not reported by the cutoff, 45 seconds after the merge.


    Generated by Claude Code

  12. TheAnswerManIsHere commented on Nov 3, 2026

    @TheAnswerManIsHere
    OwnerAuthor

    👀 FYI: David's 2026-11-03 publish shipped 1231526 (Increment 7b). Increment 7c is open as PR #847 — Launch Phase 5, Increment 7c: migration 0122 drops captcha_verified and nsfw_mode_enabled. The Repl's main is one commit ahead: Replit's empty "Published your App" deployment commit 0fd06116, which has no file changes. On my recommendation it will be realigned at #847's close-out sync rather than moved to a branch.


    Generated by Claude Code

  13. TheAnswerManIsHere commented on Nov 3, 2026

    @TheAnswerManIsHere
    OwnerAuthor

    Harvest notes: PR #847 — Launch Phase 5, Increment 7c: migration 0122 drops captcha_verified and nsfw_mode_enabled

    • Decision: the contract migration reports the count of true rows it discards and does not copy them. Neither value is needed by any later release. Dev reported 3 and 1.
    • Gotcha (already recorded in migrations-and-backfills.md): dropping a column takes three releases, not two, when the ORM declares it. First stop the reads, then remove the declaration and publish, then drop.
    • Gotcha candidate: every Replit publish adds an empty "Published your App" commit to the Repl's main, which puts it ahead of GitHub's main. The Repl already holds three replit-publish-marker-* branches from earlier publishes. Close-out should expect this commit and realign past it, keeping a local branch, without treating it as David's work. This belongs in replit-environment.md at the next harvest.
    • Alternative rejected: opening a PR for that empty commit. It would carry no diff.

    Generated by Claude Code

  14. TheAnswerManIsHere commented on Nov 3, 2026

    @TheAnswerManIsHere
    OwnerAuthor

    Build report — PR #847 — Launch Phase 5, Increment 7c: migration 0122 drops captcha_verified and nsfw_mode_enabled · differs on 2 points; 3 decisions questioned; partial — something could not be assessed

    The final step of Launch Phase 5: a database migration (0122) that removes the two retired account columns — the old 'passed a captcha' flag and the withdrawn per-account NSFW switch — now that the release which stopped using them is the published one.

    Evidence: workstream Issue #795 — Launch Phase 5 — Account and identity · PR #847 — Launch Phase 5, Increment 7c: migration 0122 drops captcha_verified and nsfw_mode_enabled

    Needs you: Nothing now; at your next publish, Replit's schema step should offer to drop exactly users.captcha_verified and users.nsfw_mode_enabled — if it offers anything else, cancel and tell the builder (the one check only you can make); the Phase 5 UAT list on Issue #795 — Launch Phase 5 — Account and identity stays yours whenever convenient.

    What was built

    Read from the one commit (seven files, 77 lines added, 33 removed; the merged squash e779e9b on main carries the same seven files). A new migration, 0122, checks whether each of the two retired account columns still exists; for each that does, it counts how many accounts had it switched on, writes that count to the server's boot log, then removes the column. It is written so that running it twice, or running it after Replit's publish has already removed the columns, does nothing. It is registered in the migration journal and added to the snapshot checker's short list of hand-written migrations, beside 0115 and 0121. The test that keeps the code's table model and the real database in step loses the temporary two-column exemption that PR #845 — Launch Phase 5, Increment 7b: remove captcha_verified and nsfw_mode_enabled from the model (the drop follows the next publish) had added, so model and database must now match with no exceptions. The NSFW-withdrawal test stops reading the column's value and instead asserts the column is gone (it still checks that the profile and admin edits answer without a server error, which is what would fail if either tried to write the field). The accounts spec and the decisions log move from 'will be dropped' to 'was dropped'. No screen, route or behaviour changes. The builder reports dev's run discarded 3 accounts' captcha flags and 1 account's NSFW switch; production keeps both columns until the next publish.

    Decisions taken on my recommendation

    • Migration 0122 reports how many accounts had each flag switched on and then discards the values, rather than copying them anywhere (decided in PR Launch Phase 5, Increment 7b: remove captcha_verified and nsfw_mode_enabled from the model (the drop follows the next publish) #845 — Launch Phase 5, Increment 7b: remove captcha_verified and nsfw_mode_enabled from the model (the drop follows the next publish), carried out here). — undo: Add a step before the drop that copies the two columns into an archive table — possible for production only until your next publish; after that the values are gone. · Concern: None on substance: by your rulings onboarding replaced the captcha flag and the NSFW opt-in is withdrawn. But the 'report' will in practice exist only for dev (3 and 1); production's columns go at your publish through Replit's schema step, and 0122 then has nothing to count (see Disagreements).
    • Replit's empty 'Published your App' commit on the Repl's main (0fd06116) was stepped past at the close-out sync rather than moved to a pushed branch and a pull request, because it changes no files. — undo: None needed; the PR body says the commit stays in the Repl's reflog, the harvest notes say it was kept as a local Repl branch — either way nothing of yours was in it. · Concern: This bends the letter of the close-out rule (a Repl main ahead of GitHub's is moved to a pushed branch), justified by the empty diff. The harvest notes say every publish produces one of these, so it will recur at each publish until the handling is written down; the builder has flagged it for the next docs harvest.
    • The pre-PR simplification pass was not run, on the ground that this is a migration and its follow-on edits. — undo: Run it; nothing depends on skipping it. · Concern: None on substance; the one leftover it might have caught is the orphaned comment in the parity test (see Disagreements).

    Ramifications

    For you: this is the end of Phase 5's building. One publish stands between here and production matching dev, and at that publish Replit should show exactly two column drops and nothing else; after it, nothing visible changes anywhere. For users: nothing, before or after. For the next unit: the model-versus-database test is back to zero exemptions, so any future drift between the two fails CI rather than waiting to be noticed; removing a column the code's model declares is now a recorded three-release practice (stop the reads, remove the declaration and publish, then drop); every Replit publish leaves an empty marker commit on the Repl's main that each close-out has to step past; and Phase 5's issue stays open only for your UAT, while the next workstream — Issue #846 — Linked sign-in methods and the "Last used" badge — is handed to a fresh session for planning.

    Shipping unfixed

    • Reasonable: Production still holds both columns, with their values, until your next publish; what removes them there is a procedure (approve Replit's schema step when it shows exactly the two drops; cancel if it shows more) rather than a check that fails. — The published release already ignores both columns and the migration does nothing when they are already gone, so whichever of Replit's step or the app's own migration runs first is safe; the only live risk is Replit offering something unexpected, and the instruction to cancel covers it.
    • Reasonable: In the parity test file, the explanatory comment for the removed exemption list was left behind (it still says each entry 'leaves this set in that same change', with no set beneath it), and one NSFW test's title still speaks of 'an account's old column'. — Harmless to behaviour and to CI; a one-line tidy whenever either file is next touched. Nobody named it.
    • Reasonable: The plan's own S23 still says the captcha column 'dies in two releases'; it took three, and the plan file on main is not amended. — The State of Play records the note and the rule that matters now lives in the migrations guide; the plan becomes history when Phase 5 closes.

    Where it disagrees with the builder (2)

    • The decision 'the migration reports the count of true rows it discards rather than copying them' reads as though a record of what was discarded will exist. In practice it will exist only for dev (3 and 1). By the builder's own earlier account, production loses the columns at your publish when you approve Replit's two DROP COLUMN statements, and 0122 — which by its own comment 'reports nothing' when the columns are already gone — will then have nothing to count. Nothing in the PR body or the issue says production's values will vanish uncounted. — By your rulings neither value is worth keeping, and production holds about three accounts, so nothing that matters is lost; but you should not expect a production number, and the undo (copy before drop) closes at your publish, not at this merge — your publish is the one-way door.
    • Nobody mentioned this: removing the exemption list from the schema-parity test left its explanatory comment in place, describing a set that no longer exists. — Small. Stale prose in a test file, the kind the repo's own sweep rules exist to catch; it misleads only a future reader of that file.

    Spend

    • This build: the issue's Spend so far line, as written in the State of Play above (Increment 7c dispatched nothing before this report; the harness reports this session's cumulative cost at $89.62 as of 2026-11-03 05:05 UTC).
    • Paid AI runs, last seven days: no paid-run ledger in KITT yet

    Where we are

    • Planned: Launch Phase 5 — Account and identity: an account becomes a verified, consenting, age-known identity that can leave cleanly, with the data model ready for beta and adult content without shipping either, in seven increments plus the 3b, 4a/4b, 5a/5b, 6a/6b and 7a/7b/7c splits. Increment 7c is the plan's last step.
    • Done: Every increment of the plan is merged. PR Launch Phase 5, Increment 7c: migration 0122 drops captcha_verified and nsfw_mode_enabled #847 merged 3 November at 05:08:53 UTC as squash e779e9b on main, with Build, Test, Frontend Test and all four E2E Smoke shards green on its one commit 42df2bf, and Codex's automatic code review and security review both Completed on that commit with no findings. The builder reports the Repl synced at e779e9b and clean, dev's database with both columns gone (3 and 1 switched-on rows discarded) and the health check ok; production still holds both columns.
    • Next: Your next publish (Replit's schema step should show exactly the two drops) and your UAT list on this issue, which closes it when done. Then Issue Linked sign-in methods and the "Last used" badge #846 — Linked sign-in methods and the "Last used" badge, planned in a fresh session; Phase 9's member comment-delete button is owed before launch.

    Does not do: It does not change production yet: both columns remain there until your next publish. It changes no screen, route or behaviour. It keeps no copy of the old values anywhere — the only record is a count in dev's boot log (3 and 1), and production's will most likely never be counted. It does not amend the plan file's 'two releases' wording. It does not close this issue; your UAT remains.

    You are now trusting: That nothing in the published code (1231526 and later) names either column. That Replit's schema step at publish will offer exactly the two drops, with you as the check that cancels anything more. That the migration's 'only if the column still exists' guards make the order of Replit's step and the app's own migration irrelevant. And that the builder's Repl-side report (the sync, dev's counts, the health check) is accurate.

    Session (the builder's call): archive — Phase 5 is fully built and merged, the Repl is synced, no PR is watched, no check-in is armed, and the harvest notes are on Issue #795; nothing dies with this session

    Could not assess: The fleet's paid-run ledger in TheAnswerManIsHere/KITT is not reachable from this session (access denied); the Repl, the published site and the plan file are beyond the role's reach, so David's publish, the Repl sync, dev's run of 0122 and the plan's wording rest on the builder's report.

    (Spend section condensed from the role's verbatim quotation of the Spend so far line, which appears in full in the State of Play above; everything else verbatim.)


    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

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions