Skip to content

Page audit B11: a PIN child's refused save says why; a quick second vote is not refused - #624

Merged
NewWorldVenture merged 2 commits into
mainfrom
claude/bubaly-repo-connect-etzqg7
Sep 28, 2026
Merged

NewWorldVenture merged 2 commits into
mainfrom
claude/bubaly-repo-connect-etzqg7

Conversation

@NewWorldVenture

Copy link
Copy Markdown
Owner

Page-audit batch B11. A child signed in through /kid-login with a PIN, then used every control and form that session can reach on a local production build of main:

  • 350 routes rendered, 268 of them reachable by the child
  • 1,050 clicks
  • 106 form submissions
  • 10 direct writes made with the child's own token

Every write boundary held. The full record is under "B11" in finalaudit.md.

Findings fixed

P-24: a refused save told the child "Minified React error #441". Adding a licence showed that text. The media library and social connect pages fell to "This page hit a snag". Production keeps only a thrown action's digest, so:

  • useActionError now reads the refusal from the digest (refusalForThrown) and never shows React's redaction text.
  • The auto, home, paperwork, social and contact-interaction actions throw refusalError(…, refusalForError(error)).
  • SocialAccessError carries ACTION_REFUSED:notAllowed, so the section shows "That wasn't saved · Your account can't make that change · Back to the form".

P-25: /api/ai/relationship and /api/ai/weekly-briefing answered a missing AI key with 500. They now answer 503, like their sibling AI routes. 18 more routes have the same pattern; they're recorded as open in finalaudit.md and not changed here.

P-26: a second vote before realtime delivered the first got a 409, and the vote didn't change.

  • The watchlist's first vote is an upsert on (title_id, member_id).
  • A single-choice poll clears the member's vote by poll and member, and a duplicate insert isn't reported as an error.
  • Both re-read their votes after every write.

Verification

  • Retest as the child on a rebuilt local production build:
    • the licence form reads "Your account can't make that change.";
    • the media library and social connect pages show the refusal card;
    • two quick watchlist votes leave the second one;
    • Tacos then Pizza on a single-choice poll leaves one vote, Pizza.
  • New test tests/a-refusal-a-form-shows-survives-production.test.ts: 15 cases, and 4 of its original 11 fail on the previous lib/actions/refusal.ts. Existing boundary and ratchet tests were updated to the new calls.
  • Typecheck is clean.
  • Unit suite: 21,467 pass. The 3 failures are the Node 24 pin and stream-runtime tests, which can't pass in this Node 22 container (blocker B7); CI runs Node 24.

🤖 Generated with Claude Code

https://claude.ai/code/session_01TRY21ZKsFrfB3qtoP972A4


Generated by Claude Code

…refused

Page audit B11 signed in a child through /kid-login and pressed every
control and submitted every form that session can reach (268 routes,
1,050 clicks, 106 submissions, 10 direct writes with its own token).

P-24: a refused save read "Minified React error #441" (licences) or fell
to "This page hit a snag" (media library, social connect). Production
keeps only a thrown action's digest, so useActionError now reads the
refusal from it (refusalForThrown) and never shows React's redaction
text; five action files and SocialAccessError carry the refusal digest.

P-25: relationship and weekly briefing answer a provider failure with
503, like their sibling AI routes, not 500. Eighteen more routes are
recorded as open.

P-26: the watchlist and family poll decided insert/update from votes
that arrive by realtime, so a second tap inserted again and got a 409.
The watchlist upserts on (title, member); a single-choice poll clears
by poll and member and accepts its own duplicate; both re-read after
each write.

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

vercel Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
bubaly Ignored Ignored Sep 28, 2026 12:04am UTC

Request Review

@NewWorldVenture
NewWorldVenture marked this pull request as ready for review September 27, 2026 23:54
#619's API-SWEEP-04 checks isAIConfigured() before the provider call in
the relationship and weekly-briefing routes; B11's P-25 answers a failure
during the call with 503. Both are kept, and the two route tests mock
both helpers. P-25's list of eighteen further routes is withdrawn in
finalaudit.md, superseded by API-SWEEP-04.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TRY21ZKsFrfB3qtoP972A4
@NewWorldVenture
NewWorldVenture merged commit 33effdf into main Sep 28, 2026
1 check passed
NewWorldVenture pushed a commit that referenced this pull request Sep 28, 2026
…24 to P-26 are B11's, so B14's findings are P-27 to P-31

B11 (#624) recorded its own P-24, P-25 and P-26 while B14 ran. B14's five
findings are renumbered P-27 to P-31 in its section, its batch row and
the three MAIN rows that cite them; the code and tests carry no P number.
Both sections are kept, B11 first. Register B recounted from its rows:
14,229 = 13,663 / 511 / 45 / 9 / 1 (0.32%).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DXw2nu25BjyRfA6Fg3YiMS
NewWorldVenture pushed a commit that referenced this pull request Sep 28, 2026
finalaudit only: both dated top entries kept (B14 first, as the newer);
main's Last Updated with this branch's note; this branch's SEC-001 move
(Failed 0); both claim rows. Recounted from the rows: 14,229 = 13,663
NOT STARTED + 512 IN PROGRESS + 45 FIXED + PASS + 9 BLOCKED + 0 FAIL.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01776xJyhVe8xJQvTGeNfT9T
NewWorldVenture pushed a commit that referenced this pull request Sep 28, 2026
…fixes kept

#619 ran the same API sweep and cron pass as this branch, in parallel, and
landed first. Where both fixed the same defect (Google connect with no
credentials, billing's Stripe key source, the webhook secret, unsent mail
reported as sent), main's version is kept: every overlapping route is main's
file. This branch's duplicate fixes are dropped, as is its Google test, whose
case main's covers with a better answer (`gcal=not_configured`).

What this branch still adds:
- SEC-001: 0459, its probe, the E2E spec and the CSP change (unchanged).
- API-SWEEP-08: /api/email/invite evaluated its family-wide limit on the
  member's session, which rate_limit_hit (0179) refuses, so every invite
  answered 429. The limit now runs on the service client, and main's invite
  test gets the matching mock export.
- Driven tests that pass against main's fixes, kept as extra coverage: the
  no-key answer for all four billing routes, invite/welcome/referral/admin
  re-send, the no-provider digest counts, and the rate-limit key guard.

finalaudit.md: main's API/JOB rows and sweep section are kept, and
API-SWEEP-08 is added to its table. This branch's duplicate SWEEP-001..003 and
PAY-002 findings are removed (main's tally stands: FIXED 122). The top entry
records the duplication, SEC-001, the page-board reconciliation and the Next 16
re-crawl. Register B, recounted: 14,229 = 13,180 + 1,003 + 37 + 9 + 0 FAIL.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
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