Skip to content

Final audit, continued: the verified units landing after #541 - #580

Merged
NewWorldVenture merged 6 commits into
mainfrom
claude/roadmap-implementation-ld8bon
Sep 26, 2026
Merged

NewWorldVenture merged 6 commits into
mainfrom
claude/roadmap-implementation-ld8bon

Conversation

@NewWorldVenture

Copy link
Copy Markdown
Owner

Continues the audit from #541 (merged at 533554be). Each unit here was re-derived from the source, fixed with a failing-first test, reviewed, reworked where the review found anything, and mutation-proven in a clean worktree at HEAD before it was committed.

In this PR so far

SRV-001 medium leads: m20, m22–m27, m31, m39–m41, m4.
SEC-007: /api/mkt/track binds the visitor to the request's own cookie through the helper SEC-006 introduced; two orphan keys removed.
AQ-01 / I18N-003: the paperwork, purchases and trips group reads money in the reader's locale, with the prose moved to the catalogue (28 keys, seven locales).

Migrations added, all unapplied and recorded in docs/PENDING_PROD_MIGRATIONS.md: 0349 (one saved copy of a provider recipe per family), 0352 (a child cannot clear the household's money warnings), 0360 (a head-out reminder goes with its departure plan). Each has a boundary probe that is red without it. The version ratchet expects 0361.

Verification

At the committed state: 31 test files / 569 tests pass, including the catalogue key guard, the tally guard, the version ratchet, the currency and locale ratchets and the probe meta-tests. Every unit's application files go behaviourally red with the fix reverted and the test kept.

finalaudit.md: FIXED 95 · CHECKED 2 · PARTIAL 4 · OWNER'S 7 · OPEN 14 · BLOCKED 1 · SUPERSEDED 1 (124 rows). PRODUCTION READY: NO — migrations 0318+ are not applied to production, and applying them is the owner's action.

🤖 Generated with Claude Code

https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K


Generated by Claude Code

…ht verified units land together

Each unit was re-derived from the source, fixed with a failing-first test,
reviewed, reworked where the review found anything, re-reviewed, and then
mutation-proven in a clean worktree at HEAD against the staged blobs
(source reverted, test kept: red; restored: green). Where a unit's test
reads its migration by path, the whole-unit revert only fails to load, so
each file was reverted on its own: every application file goes
behaviourally red (m26+m27: 9, 2, 4 and 1 failures; m31: 6).

m26+m27 (0352): a child or guest could dismiss or delete the household's
money warnings over /rest/v1, because 0168 gave the writes to membership
and the row is one per family per advisory. Writes move to
can_manage_family with 0275's restrictive guards; SELECT stays on
membership. The action refuses a non-manager with a sentence, validates
the client's payload, and reports a refused write instead of
revalidating as if it had landed. Two probes hold it.

m31 (0349): "Save to vault" probed for a duplicate before inserting, and
0054 never made the triple unique, so two saves in the same second both
landed. A partial unique index closes it (AI variants and hand-typed
recipes stay writable); the action reports a failed probe instead of
reading it as "not saved yet".

m39+m40+m41 (0360): a plan the table would refuse put a head-out reminder
on the calendar first and left it there; Remove read a failed lookup as
"no reminder"; deleting the event a plan was for cascaded the plan and
stranded the reminder. Limits are checked before any write, a reminder
whose plan insert failed is withdrawn, Remove fails closed, and an AFTER
DELETE trigger takes the reminder with the plan.

m20: a food-score snapshot is filed on the family's day. m22-m24: a
moment's prep read that failed no longer reads as "nothing ticked", a tap
saves only the one step it knows, and the failed state is shown. m25: a
dismissed moment is quiet for the family's day, not the server's. m4:
resetting a service blurb clears the custom copy, and a failed settings
read is not a settings page.

SEC-007: /api/mkt/track binds the visitor to the request's own bubaly_vid
cookie through the helper SEC-006 introduced; a body naming another
visitor is refused, and the banner stops sending the id. The real
ConsentManager is driven across a cookie rotation. Two orphan keys the
two fixes left behind are removed from all seven catalogues.

AQ-01, paperwork group: fees and reminders in the paperwork module, the
inbox page, the triage engine and the paperwork actions read in the
reader's locale, with the prose moved to the catalogue (28 keys, seven
locales) and a de-DE outcome test that fails 9 of 10 with the sources
reverted.

Catalogues: 46 keys added in all seven real locales, 2 removed; the
placeholder locales are untouched. 0349, 0352 and 0360 are recorded in
docs/PENDING_PROD_MIGRATIONS.md, unapplied; the version ratchet now
expects 0361 with a paragraph for each.

At the staged state: 31 test files, 569 tests pass, including the
catalogue key guard, the tally guard, the ratchet, the currency and
locale ratchets, and the probe meta-tests. finalaudit.md: SEC-007 FIXED,
AQ-01 records the landed group, SRV-001 lists the units; FIXED 95, OPEN 14.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
@vercel

vercel Bot commented Sep 26, 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 26, 2026 7:55pm UTC

Request Review

…s are measured missing

Records the release as measured: #541 merged to main at 533554b, main's
CI green in all four jobs, and production serving that revision per its
own /api/build-info. /api/health on production answers database, auth
and service role ok and status degraded, naming CRON_SECRET,
CHILD_LOGIN_SECRET, MARKETING_UNSUB_SECRET and GUARDIAN_INTERNAL_SECRET
as unset. Per lib/health/status.ts, every scheduled job answers 401
without the first and no child can sign in without the second. The four
ENV rows move to BLOCKED on the owner setting them in Vercel, and the
gap is listed under Critical Blockers as PROD-ENV. PRODUCTION READY
stays NO.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
Thirty-nine committed probes gained a negative control that runs first,
each was critiqued read-only against the migrations, and each is being
mutation-tested three ways on private database clones. Thirty-two are
proven or fixed-and-re-proven; seven are in the fix stage. Two findings
from the mutation stage are recorded: rls-isolation's UPDATE and DELETE
refusals were vacuous behind the SELECT policy and now mirror the
invariant statement by statement, and family-scoped-index's tightened
rule found three erasure scans that need a total (family_id) index each.
All 39 pass 65 of 65 twice on a clean replay.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
`readAISettings` answered a failed `family_ai_settings` read with the
defaults — Bubaly on, `execute`, memory on — and the callers that enforce
a family's opt-out consumed that answer. So a paused family had AI-agent
writes go through the trust engine, the routines cron file the work they
had paused, and Bubaly keep what it noticed for a family that switched
memory off, for as long as the read failure lasted.

Re-deriving the lead against HEAD found eight enforcing callers, not
the three first named. Every one now reads strictly: `loadAISettingsFor`
is the strict read for a caller without a scope, `loadAISettings`
delegates to it, and `readAISettings` is gone. On a failed read the tool
gate answers a retryable error that says the settings could not be read
(a new gate kind, `unverified`, never "switched off"); the cron marks
the run skipped for that reason and advances the schedule exactly as a
pause does, so one occurrence is lost and never the routine; memory
refuses the AI-noticed fact; the shared AI gate denies without opening
an approval; recall and the memory slice fail rather than hand the model
"nothing is remembered"; onboarding reports what it did not write and
still finishes; capture throws; the concierge action reads before the
trust engine. The planner and quiet hours stay on the forgiving
`getAISettings` by choice, and its header now says which callers may.

tests/an-opt-out-that-cannot-be-read-is-still-an-opt-out.test.ts drives
the real settings module against a query that times out: 8 fail-closed
cases and 4 controls. Mutation-proven at HEAD: 23 red without the
source, green with it; 64 neighbouring suites green. Three sentences in
seven locales. finalaudit: SEC-009 OPEN → FIXED; index FIXED 96 · OPEN 13.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
…tion-proven three ways

Every probe here gained a negative control that runs first — the same
actor, the same predicate, the same columns, with the one thing the guard
keys on flipped, required to LAND — was critiqued read-only against the
migrations, sent back where the critique found a fault, and then
mutation-tested on private database clones: as written (exit 0), with
the governing guard loosened (red on a refusal assertion), and with the
guard intact plus a decoy refusal (red on the control). A probe counts
only if a passing three-way run ended at or after its last edit.

Two probes stay at their committed versions until their mutation runs
finish: automation-runs-pin-what-a-member-may-queue and
money-write-boundary.

Replayed before landing the way CI replays them — HEAD's migrations
bootstrapped into a fresh database, then every probe in docs/audit:
69 of 69 pass, twice on the same database.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
…, with 0343's own probe

The last two, automation-runs-pin-what-a-member-may-queue and
money-write-boundary, were mutation-tested on clones of a template
rebuilt from HEAD's migrations and came back PROVEN; chore-award-amount,
family-facts-provenance and ui-only-manager-gate went through a second
fix-and-re-prove pass after their critiques and land again. The probe
for 0343 (only a parent mints or revokes an assistant key), which the
m9 landing left behind, lands with its control and its three-way proof.

social-access-symmetry named AUTHZ-011's migration by its file stem
before that migration had landed, which the document guard rightly
refused on CI; the inventory now describes it as pending, without a
stem a reader could try to apply.

Replayed before landing the way CI replays them: HEAD's migrations into
a fresh database, then every probe in docs/audit — 70 of 70, twice on
the same database. Three document guards green on the staged set.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
@NewWorldVenture
NewWorldVenture marked this pull request as ready for review September 26, 2026 20:19
@NewWorldVenture
NewWorldVenture merged commit 7e54596 into main Sep 26, 2026
8 checks passed
NewWorldVenture pushed a commit that referenced this pull request Sep 26, 2026
… and four duplicates dropped

main merged #541 and #580 and landed its own 0318-0360, so all twenty-one of
this branch's migrations (0318-0338) collided with files already applied to
production. 98 conflicting files, resolved file by file. Where both sides
fixed the same bug, main's version was taken because it is in production. Where
main's version had its own hole, it was patched on top:
- a DATE column bucketed a day early in weekly.ts;
- raw photo URLs in the reworked lightbox would have undone SEC-001;
- getPublicUrl came back in the inventory module.

The block moves to 0361-0381, above main's held gaps. Running main's probes on
the merged chain, rather than comparing names, found four of the branch's
migrations duplicating main's fix for the same subject. Each swept the
permissive policy main's guards stand on, so main's negative controls could no
longer fail:
- 0364 duplicates main's 0298;
- 0368 duplicates main's 0306, 0322 and 0324;
- 0376 duplicates main's 0318;
- 0377 duplicates main's 0319.
All four are dropped, and their numbers are recorded as permanently unused.
0367 keeps only safety_check_ins, and main's stricter locator rule stands.
0361's closing assertion no longer flags a RESTRICTIVE policy, which cannot
grant.

The branch's guards, pointed at main's code, found and this commit fixes:
- ten filtered writes on tables main had just gated;
- twelve raw Postgres messages returned to the page;
- a private LIKE escaper, whose `*` rule now lives in the shared one;
- three probe pairs sharing fixture ids.

Thirty-four English-only keys are translated into all six catalogues. The
ungated-i18n ceiling (2,807 -> 2,819) and the lint budget (12 -> 18) move with
their derivations written in the files.

Verified: replay 374/374, probes 91/91 run twice, tsc clean, lint 0 errors,
vitest 18,684/18,687 (the three are this container's Node 22), build exit 0.
Recorded in finalaudit.md Q68.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TRY21ZKsFrfB3qtoP972A4
NewWorldVenture pushed a commit that referenced this pull request Sep 26, 2026
main has moved 250 commits under a parallel audit (#541, #580) and already
applied migrations 0318-0360 in production. This branch's 24 migrations
are numbered 0318-0341, and main's migration workflow applies by version,
so pushing them unchanged would have silently skipped all 24 in
production. They need 0361+, minus two that main's own migrations
supersede (0319 by main's 0335, 0320 by main's 0319); 0330 is half-covered
by main's 0318.

A trial merge has 437 conflict hunks across 156 files, mostly both audits
fixing the same things differently. Resolving by main's side was refused
as destructive; the merge was aborted and nothing is lost. The row names
the two ways forward for the owner to choose.

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 26, 2026
Main moved to 7e54596 while the first merge was being gated. No new
migration numbers, so 0361-0370 stand.

- sensitive-role-boundary-check.sql: main's controls required a manager
  to read and insert social_account_tokens; 0361 makes that store
  unreachable for every JWT. The controls now assert 0361's rule where
  can_manage_family says yes, with the seeded row counted as the owner.
- The ten renumbered migrations and the probe still cited their old
  numbers (main's 0318-0330 are different files); corrected.
- withdrawHeadOutEvent returned true on a zero-row delete, telling the
  family an orphaned head-out event was gone while RLS kept it; now
  confirmed with .select('id').
- Nine guards re-pointed: fakes that modelled unconfirmed calls, mocks
  missing getLocaleContext/loadAISettings, bare indexOf, and the
  manager-gated pin gains money_timeline_insights (0352).

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 27, 2026
…numbers

The renumber to 0381–0387 rewrote every reference in the files this branch
added after #580, but probes landed with #580 already pointed at those
migrations by their old numbers - approval-dedupe, automation-runs,
money-write-boundary, family-facts-provenance, document-category-
classifier, document-vault-boundary, rls-isolation, privileged-rpc-grants,
family-keeps-a-manager and only-a-parent-mints-or-revokes-an-assistant-key.
After the merge those old numbers name main's own migrations, so each
comment and exception sentence now says 0381, 0382, 0385, 0386 or 0387.
Comments and message text only; no probe's SQL changes. Mentions of main's
0344–0365 in main's own probes are left as written.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
NewWorldVenture pushed a commit that referenced this pull request Sep 27, 2026
…in production

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
NewWorldVenture added a commit that referenced this pull request Sep 27, 2026
Migrations 0381–0387 (unapplied, each in the ledger with its probe), SRV-001's remaining medium leads, AUTHZ-011, SEC-008, SEC-009, AUDIT-011's 39 re-controlled probes, and money in the reader's locale across the family modules, home and auto, the engines, billing and the marketplace. Merged with main at 6ff770d. PRODUCTION READY stays NO.
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