Repository navigation
Final audit, continued: the verified units landing after #580 - #581
Merged
Merged
Conversation
…es to a calendar URL once (0363) Two SRV-001 medium leads, each re-derived from the source, fixed with a failing-first test, reviewed, reworked where the review found anything, re-reviewed, and mutation-proven at HEAD before landing. m21. 0264 narrowed family_facts UPDATE and DELETE by category only, so on the seven ordinary categories any member could rewrite or delete any row — a parent's household "Emergency contact" among them — from the browser's own RLS-bound client, and rememberConfirmed's label probe let the Add form do the same without an id. The service now applies mayChangeFact on the create path and the label probe refuses a row the caller may not write; 0357 (unapplied, in the ledger) re-creates the two policies with the same rule — a manager, a memory about me, or one I wrote. Its probe's control runs first and it is proven three ways on private clones. Two residuals its re-review found are recorded, not smoothed over: ownership keys on created_by, set on INSERT only; and INSERT stays open with no uniqueness on the label. m36. A calendar whose first sync failed was left in the family's list and the next press of "Add & Sync Now" inserted the same URL again, so every school event came in two or three times. The action now looks for the family's row first and re-syncs it, removes a row it created whose first sync failed, refuses a link longer than the index can hold, and catches the race loser's 23505 by syncing the winner's row; 0363 (unapplied, in the ledger) makes (family_id, url) unique. Four sentences in seven locales. Proofs: m36 red without its source (11 of 11), green with it; m21 red without lib/services/memory/index.ts on outcome, green with it; 21 neighbouring suites and the catalogue, document, tally and version guards green on the staged set; 0357 and 0363 applied twice onto a HEAD database and every probe replayed there, 72 of 72, twice. Ratchet pinned at 0364. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
…e does not reach the money (0345), and the plan price reads in the reader's locale
Three units, each re-derived from the source, fixed with a failing-first
test, reviewed, reworked, re-reviewed and mutation-proven at HEAD. They
share two files (the billing page and the billing module), so they land
together and were proven together.
m7+m8. "Two parents" was a rule in TypeScript alone: 0251's decide policy
let any signed-in adult PATCH an approval to approved over /rest/v1, which
closed the request, denied the second parent a vote, and wrote no trust
audit row. 0344 (unapplied, in the ledger) adds two BEFORE UPDATE
triggers: a move into approved or modified must be earned by the row's
own votes under its own model and threshold, a vote is signed only as
yourself, and a pending row's rule cannot be rewritten. The concierge
panel's Approve and Dismiss now route an approval-backed run through
decide(), and a finished plan is stamped completed so it counts in the
family's week. Three residuals its re-review raised are recorded in
SRV-001 and the ledger, not closed: a rejection is not final in the
database, the executor still runs raw edited_payload with skipTrust, and
an adult can PATCH a run's metadata to drop its approval_id.
m10+m11. The step-up the money pages demanded was never a database rule,
so a password-only session could DELETE /rest/v1/budgets directly. 0345
(unapplied, in the ledger) adds session_cleared_step_up() — aal2, or no
factor enrolled — and RESTRICTIVE insert, update and delete guards on
budgets, savings_goals and bills. Every money action requires aal2, the
billing page sends an aal1 manager to step-up with a return path, and
the twelve client call sites route a refusal there instead of a bare
error.
billing-and-pricing (AQ-01). /pricing, the plan manager, the upgrade
modal, the trial gate and the Stripe service fee read the plan price and
the fee in the reader's locale; the per-month suffix, "billed monthly"
and "billed {amount}/yr · save {percent}%" are catalogue keys. Nine
sentences in seven locales. The hand-written-currency ratchet is set to
its live count, 38, and now says so.
Proofs: 32 red without the sources, green with them (124 tests); per
file, twelve source files go behaviourally red when reverted alone and
six only fail to load (their sibling imports them); 65 neighbouring
suites and every guard green on the staged set; both probes
mutation-tested three ways on clones of a HEAD template with the
migrations applied; 0344 and 0345 applied twice onto a HEAD database and
every probe replayed there, 74 of 74, twice.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
…cery list a vote reaches, and a graph that is on screen before the toast says so Five units, each re-derived from the source, fixed with a failing-first test, reviewed, reworked, re-reviewed and mutation-proven at HEAD. AUTHZ-011 → FIXED. 0365 (unapplied, in the ledger) puts three guards in the database: RESTRICTIVE writes on social_settings behind social_has_permission(…, 'manage_settings'), so a child can no longer lift the family's publish lock over /rest/v1; a trigger that lets a trip link only a document its caller can read from its own household; and a SECURITY DEFINER trigger — found by the review of the fix — that refuses to move a document to another household while a trip links it. 19 cases, 13 red with the migration absent. SEC-008 → FIXED. GET/POST /api/blog/like, POST /api/blog/subscribe and POST /api/ab/track bind the visitor to the request's own bubaly_vid through the helper SEC-006/007 share; a body naming another visitor is refused, no cookie is a 400 or an anonymous event, and the like route's delete arm reads its result. 15 of 40 cases red with the routes reverted. One orphaned catalogue key removed from all seven locales. m13+m14. The urgent fallback number is normalized to E.164 before it is stored and refused with a sentence that says the form it needs when it cannot be; no country code is guessed. 0356 (unapplied, in the ledger) normalizes the rows already there, keeps what they held, and adds the CHECK the column's own comment claimed. m32, m33+m34. A failed read of the family's grocery list never forks a second one; a failed read of the vote or its winning recipe adds nothing and says so; a bare-string ingredient no longer refuses the whole dinner; tapping Grocery twice on a won vote lists the dinner once. m19. A rebuilt graph is on screen before the toast says so, and a modal cannot be dismissed while its save is in flight. Eight sentences in seven locales. Proofs: every unit red without its source (13/19, 15/40, 12/16, 21/35, 11/11), green with it; 76 suites and every guard green on the staged set; 0356 and 0365 applied twice onto a database built from HEAD's migrations and every probe replayed there, 76 of 76, twice. Ratchet pinned at 0366. finalaudit: FIXED 98 · OPEN 11. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
… rule can be corrected after it is saved SRV-001 leads m1 and m2+m3, re-derived from the source, fixed with failing-first tests, reviewed, reworked, re-reviewed and mutation-proven at HEAD. Generated FAQ answers are rows in marketing_aeo_questions, world-readable on one predicate with no join back to their page, so when a page was archived, deleted, renamed or a blog post unpublished, its route went dark but its answers kept rendering — on /faq, in every live article of the same category, and with a body citing a URL that now answers 404. Nothing self-healed it. The take-down actions and the legacy bridge's three paths now retire the answers themselves; 0355 (unapplied, in the ledger) makes it a property of the tables — four AFTER triggers bound to SECURITY DEFINER functions with a pinned search_path move a page's published answers to 'answered' in the take-down's own transaction, and the backfill retires what pages already dark left behind. The marketing platform page also lets a brand rule be corrected after it is saved and re-queues a retried job rather than a neighbour. Five keys in seven locales. Proofs: 19 of 22 red without the sources, green with them; each of the five source files behaviourally red when reverted alone; 22 neighbouring suites and every guard green on the staged set; both probes mutation-tested three ways on clones of a HEAD template with 0355 applied; 0355 applied twice onto a database built from HEAD's migrations and every probe replayed there, 78 of 78, twice. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
…them import tests/medications-fixture-module-graph.test.ts walks each fixture's import graph so a new value import is caught before the fixture fails to mount, and it caught two on CI: budgets-view and savings-view now route a refused money write through lib/auth/step-up-client (0345's application half), so finance-read-states lists it and the lib/auth/mfa it reads its path from; and the trial paywall gate prints the yearly price through formatCents in the reader's locale, so signout-form-boundaries lists lib/wallet/ledger, mocks lib/marketing/value's PLAN_CURRENCY, and gives its locale-provider mock the useLocale the gate now calls — with the locale injected into the page script, where the Node-side variable does not exist (the first cut referenced it and the gate threw on mount). Both specs pass on the pre-installed Chromium here (43 of 43), the module-graph guard is green, and no test was weakened. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
PR #579 landed on main as 0344–0380, taking every number this branch had used: 0344, 0345, 0355, 0356, 0357, 0363 and 0365. The seven files keep their names and move into the block this branch holds, 0381–0387: 0344 -> 0381 two_parents_means_two_parents_in_the_database_too 0345 -> 0382 a_password_alone_does_not_delete_the_familys_budget 0355 -> 0383 an_archived_page_takes_its_public_answers_with_it 0356 -> 0384 the_urgent_fallback_number_is_stored_the_only_way_it_can_be_used 0357 -> 0385 a_member_only_rewrites_their_own_memory 0363 -> 0386 a_family_subscribes_to_a_calendar_url_once 0365 -> 0387 a_child_cannot_lift_the_publish_lock_or_link_a_document_they_cannot_read Every reference in a line this branch wrote follows: the migration headers and their cross-references (including the file:line pointers, whose line numbers did not move), the eight probes' notices, HOLDS lines, \ir includes and fixture identifiers, the tests that read a migration by path, the source comments that cite one, the seven ledger entries in docs/PENDING_PROD_MIGRATIONS.md (now in numeric order after 0360), the finalaudit.md rows that name them, and the version-safety paragraphs. The pin moves to 0388. Nothing main wrote changes: the only remaining hits for the old numbers are main's UI-ROUTE-03xx census ids. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
Brings in PR #579 (34 migrations renumbered into 0344–0380) and #582's release note. Five files conflicted; each resolution keeps both sides' intent and both sides' tests: - lib/guardian/twilio.ts: main's xml() escapes text and attribute values alike (a superset of this branch's escapeXmlText/escapeXmlAttr), so every builder uses it; this branch's twimlDial rationale and its findOwnedNumberSid/releaseNumber additions stay. - lib/contact-center/phone.ts: both functions. normalizeFallbackPhone is the write-side rule (E.164, country code required, letters refused); toCallableE164 is main's read-side normalizer for rows written before it, and its header now says how the two relate. - app/(app)/dashboard/contact-center/actions.ts: the save goes through normalizeFallbackPhone and refuses with actions.enterTheFallbackNumberIn, which this branch's test asserts by sentence; main's account of why is folded into the comment. main's actions.forwardingNumberNotCallable stays in the seven catalogues, unused. - lib/services/approvals/index.ts: main's re-read-and-retry on a lost write race (attempt < VOTE_RETRIES) around this branch's changed/changedByMe audit note. - tests/migration-version-safety.test.ts: main's paragraph on 0344–0380, then this branch's seven paragraphs for 0381–0387; the pin is 0388. Two files main alone changed had to move for this branch's tests: - app/api/contact-center/voice/route.ts: a stored fallback that reads as a number is normalized and dialled (main). One that does not is no longer treated as "no number": it goes into the <Dial> escaped, as this branch's test asserts, and the message-taking verbs follow it, so the caller is still asked for a message when that Dial fails. 0384 clears such rows. - tests/a-child-cannot-lift-the-publish-lock-or-link-a-document-they-cannot- read.test.ts: its reading of social_has_permission learns the deny-list arm 0348 introduced (p_permission <> 'manage_access'); without it the admin role fell out of the matrix and the test reported the database refusing a parent the live probe shows it admits. No assertion changed. finalaudit.md is the union of both sides plus #582's release section; the index is regenerated (FIXED 98 · OPEN 11, unchanged) and the two clauses of main's forwarding-number row that the merged code made untrue now describe what the code does. Verified on a private database: 398 migrations applied, 0 failed; 115 probes pass twice; the version audit's next number is 0388. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
…, and the engines; a dashboard setting the page could not read is not a yes; a dining page that neither hides a failed read nor guesses a total
Five units that share files — the family modules, home and auto, engines
and digests (AQ-01 / I18N-003), m15 and m16+m17 (SRV-001) — plus m35's
three review follow-ups, landing together because dining-module,
voting-module, consensus and the home dashboard are each touched by two
of them. Every unit was re-derived, fixed, reviewed, reworked,
re-reviewed and proven at HEAD.
AQ-01. Fifty keys move the sentences around money into the catalogue,
and every amount is formatted for the reader through formatCents with a
named currency: the closet, dining, inventory, family-signals and
relationship modules, the poll's consensus explanation and the AI
explanation's budget cap; the Needs-You page, the home page, the
briefing route and its decisions, the car's insurance and service
clients, the home service client and the assistant's tools; the
autopilot, decisions and reasoning engines, the food score, the hard
signals, the calm, kitchen, reasoning and family-signals pages, the kids'
submit page, the missions review card and the two crons. The engines
group changed more than formatting: a subscription suggestion's title
had been worded once, in en-US by whichever scan inserted it, so every
screen now re-words it for its own reader from the facts in its payload.
The dead key serviceClient.totalLogged, whose value was the defect
("Total logged: $"), is gone from all seven locales. The hand-written
currency ratchet falls from 38 to 20 and says so.
m15. A dashboard settings read that failed is no longer normalized to the
permissive default: readDashSettings closes the customization permission
and reports the settings as unknown, and the home dashboard withholds the
Family button, the "Set by a parent" caption and "Set family default".
m16+m17. The dining page's four tile figures are counted and summed by
the database over the whole family and arrive as props; null renders as
"—" and never as 0; a batched read degrades like a single one.
m35 follow-ups. The gate comment says what the forgiving read does, the
actions test's mock carries getAISettings so a reverted action no longer
passes by accident, and a panel test pins that a refused setting whose
re-read also fails leaves no control on screen and never the refused
value.
Proofs: with every other unit's files present, reverting one unit's
files alone goes red — family modules 29, home and auto 16, engines and
digests 42, m16+m17 18 of 437; m15's two action files 2 each, its
permissions module a load failure and its dashboard wiring unpinned
(recorded); 46 neighbouring suites and every guard green on the staged
set; eslint clean. Coverage gaps the re-reviews named are recorded in
finalaudit rather than smoothed over.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
…t could not be read is not a cleared one
AQ-01 / I18N-003, the marketplace group: listings, auctions, negotiations,
the price coach, price history, saved searches, the assistant, the
close-auctions cron and the fifteen marketplace pages and panels that
render them read money through formatCents in the reader's locale; the
English sentences around each amount move to the catalogue (70 keys in
seven locales) and six retired keys that ended in a hand-typed "$" are
removed from all seven. A shared money-unit helper places the currency
unit on the side the reader's locale writes it and pads the input on
that side. Two outcome tests: one asserts, for every translated
catalogue, that the reader's own sentence carries the formatted amount
and no literal "$"; the other clicks through to the offer box, the
counter box, the agreed line and Quick Post's suggestion and pins the
unit's side. The hand-written-currency ceiling falls from 20 to 8, and
its header names the eight sites that remain.
SRV-001 m5: a failed read of the social links used to reach the admin
page as {} - the value that means "nothing configured" - so the page
drew six blanks and one Save replaced the whole app_settings row with {}
and emptied the homepage's Organization sameAs. The page now refuses to
render an editable form over a read that did not answer; the write is a
compare-and-set that re-reads the row itself, refuses a submission built
on anything else, and writes nothing when the re-read fails; the audit
row keeps what a save replaced and carries via: 'site_admin'. Six blank
fields remain a legitimate submission.
finalaudit.md records both landings with their mutation proofs and the
re-reviews' out-of-scope notes.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
The browser kept one submission id across a failed save, and withIdempotency answered a retry under that key with whatever row the key had already written - so a person who fixed the date or the title after a failed Save saw "Task added" and got the first press's row. The guard is opt-in (rejectChangedRetry), set only by the todo, calendar-event and chore actions whose key is a browser submission id: a retry whose title, dates, assignee or other columns differ from the saved row is refused with already_saved and a sentence naming the row that exists and saying nothing was added or changed, in seven locales. An unchanged retry still answers the same row silently; the executor's step keys and the trips' pet-care tasks pass no option and behave as before, pinned. The three modals re-mint their id on that refusal, and Quick Add drops its id before it branches on the result. Two decisions the re-review confirmed are recorded in the test's header: reminder submissions carry fixed content per suggestion, so there is nothing to refuse; a routine's Apply is keyed (routine, week) by design. Proof at HEAD: 15 of 38 red with the sources reverted, green with them; 26 suites that import the changed units green; eslint clean. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
…nd proven; index FIXED 99 · OPEN 10 The row's verdict cell now opens with what closed and what it does not claim - the three family-scoped-index erasure scans that need the owner's migration, the unwrapped control plant in the automation-runs probe, and that nothing here is a statement about production - and keeps its history unchanged below. The index is regenerated by docs/audit/finding-index.py and the prose tally matches it. Also: the onboarding-facts test's comment now says why 'onboarding' is the wrong provenance value rather than merely an unavailable one, matching the header of lib/onboarding/facts.ts it points at. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
…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
…in production Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
Owner
Author
|
E2E on Failing case: Why it is not this PR's:
Action: re-running the failed job once, per the flake rule. If it fails a second time it is real and I will root-cause it here. Generated by Claude Code |
NewWorldVenture
marked this pull request as ready for review
September 27, 2026 01:41
NewWorldVenture
pushed a commit
that referenced
this pull request
Sep 27, 2026
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
…dropped
The login form's phone button - the primary way in - rendered enabled from
the server with no handler, and once hydrated its handler refused a form
that had not mounted yet. A tap in that window did nothing, and the phone
form never opened. CI's phone-login E2E hit exactly this three times under
load: it clicked right after domcontentloaded and waited 120 s for a phone
field that never appeared. On a slow phone, a family got the same silence.
The button is now held disabled until the form mounts, as the email
fieldset already was, so the wait is visible and Playwright's click waits
for it. The signup form's three entry buttons had the same shape and get
the same treatment.
tests/e2e/login-readiness.spec.ts gains the case: the phone entry is
disabled before hydration, an early tap waits, and the phone form opens
once mounted. Red with the fix reverted ("Expected: disabled, Received:
enabled"), green with it; the four fixture-based login, signup, password
and kid-login specs pass locally, 93 of 93; the six unit suites that
render either form pass, 113 of 113; eslint clean.
finalaudit's #581 release note, which had called the failure a hang worth
one re-run, now records the root cause.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
NewWorldVenture
pushed a commit
that referenced
this pull request
Sep 27, 2026
main brought PR #579 (C1-K: thirty-four member-write boundary migrations at 0344–0380, their probes, trust fail-safes) and #582 (a finalaudit note). Thirty-six files conflicted; finalaudit.md and the seven catalogues auto-merged (index regenerated: 124 rows, FIXED 96 · OPEN 13, prose tally agreeing; catalogues valid at 13,956 keys each). Resolutions. For 34 of the 36 conflicted files this branch's side is byte-identical to the side close-out-556 (f55f3591) resolved against the same main content from the same base (7e54596), so its resolutions are taken verbatim; the classes are recorded in d41ac300's message (both sides' discarded-write bindings, wroteNoRows checks joining main's role gates and family filters, .then().catch() rejection handlers carrying main's log markers, toCallableE164, the shared xml() escaper, the wallet routes' error bindings). Two were merged by hand: - components/modules/behavior-module.tsx: main's delete handler (family filter, `data`/`!data?.length`, `canRemove`, which main's a-child-cannot-erase-their-behavior-log pins) with this branch's confirmed save (`data: saved` + wroteNoRows) and its manager-only Log control; the comment no longer cites a migration this branch dropped. - tests/migration-version-safety.test.ts: main's paragraphs, then this branch's ten, pinned at 0419. Migrations renumbered a fifth time (main's 0344–0380 collided with the 0361–0370 the author assigned in C1-S9-89) to the slots f55f3591 had already replayed and probed against this tree: 0361→0406 social tokens service-role only 0362→0407 no TRUNCATE for the public roles 0363→0408 household secrets are not child-readable 0364→0409 marketplace parties are not editable 0365→0410 a review belongs to whoever wrote it 0366→0411 deleting a review is rewriting it 0367→0414 a health record is written by a parent 0368→0415 a paperwork stamp does not rewrite its siblings 0369→0416 a private journal is private 0370→0418 a public bucket serves what you put in it 0412, 0413 and 0417 stay empty: they are f55f3591's copies of the three migrations the author dropped in C1-S9-89 (social restriction, location trail, record-about-you; confirmed by content against c8b5c56's 0324/0325/0329), and the drop stands. The ten files take f55f3591's content, which differs from the author's only by number citations except 0416, whose SELECT rule takes main's 0364 owner-or-manager form (a sibling never reads another member's entry; a parent reads only one its owner marked not private) because main's private-journal-check.sql pins it; recorded in the header, finalaudit C1-S8-07 and PENDING_PROD_MIGRATIONS. Every reference rewritten: the nine probes (eight now byte-identical to f55f3591's; health-record keeps the author's comment on the logged_by control), sensitive-role-boundary-check (the author's own a349bd6 reconciliation of the token controls, kept, citing 0406), PENDING_PROD rows and the 0406 header's history, finalaudit B1 / C1-S8-07 / C1-S9-89 and every backticked or path-style filename, lib/database.types.ts and paperwork/actions.ts (0327→0415), health-visits and immunizations (0326→0414), insurance-module (0328→0416), care-module (cites C1-S8-09 rather than the dropped 0329), and the tests that read the migrations by name (social-tokens, household-binder, public-bucket, paperwork-stamp, manager-gated-table). Tests adapted (from d41ac300, assertion strength kept): a-dialled-number reads main's shared xml(); a-forwarding-number's fake answers .select() with the affected rows; a-voice-log-failure pins the same best-effort properties against lib/voice/history; a-fire-and-forget's ai-settings anchor moves to main's log wording; a-client-write-reads-what-it-changed accepts a file whose only confirmed writes are spelt with the bare `data` (its C1-S9-81 closet paragraph from 0cf0eb2 kept). Verified together with the merge of dcc0b42 (#581) that follows; the numbers are on that commit. 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
main brought PR #581: migrations 0381–0387 (two-parent approvals in the database, the money step-up guard, archived-page answers, the E.164 fallback number, member memories, calendar feed uniqueness, AUTHZ-011), their probes, the AQ-01 currency work and finalaudit rows (index FIXED 99 · OPEN 10). Twenty-two files conflicted. This branch's ten migrations keep 0406–0418: no collision. Resolutions: - catalogues (7): key union; billing.serviceFeeAddedAtCheckout takes main's text, whose placeholder is {amount} (AQ-01, pinned by main's a-german-family-reads-their-plan-price test). - concierge/actions.ts: main's decide() route for approval-gated runs (0381) — the branch's two direct approval_requests stamps go with main's change, the executed-path one having written `approved` with no votes; kept from the branch: legacyStatusFor on the autopilot record (C1-S9-72), the confirmed `stamped`/`dismissed` writes (C1-S9-48), the error-bound plan read; main's completed_at on every terminal run (only state=completed is counted). - contact-center/actions.ts: main's normalizeFallbackPhone (country code required, 0384's rule) on the write path, the branch's C1-S7-05 reason. - lib/contact-center/server.ts: main's compare-and-swap claim, which subsumes C1-S9-69's confirmed save; the branch's failure log kept. - billing/page.tsx: main's aal2 guard and locale-formatted amount with the branch's cautious notice on a refused settings read (C1-S9-71). - recipes/vote/actions.ts: main's grocery-service path (covers C1-S9-75); the branch's close/reopen confirmations kept. - admin/marketing/platform: main's stored-status read, the branch's C1-S9-61 note on the unconfirmed default clear. approvals service, twilio, chores-module, autopilot/scan, marketplace saved/store: unions. - tests: service-memory keeps the branch's zero-rows case and takes main's author-or-subject teen case; upgrade-modal uses the branch's at() with main's suffix match; the version pin has main's seven paragraphs, then the branch's ten, at 0419. Tests adapted to the other side, assertion strength kept: a-dialled-number pins normalizeFallbackPhone and asserts it refuses the same payloads and clears on empty; a-write-the-user-is-told-about-is- confirmed asserts the concierge writes no approval row and decides through decide(), and holds the run close that moved into the approvals service to logged-not-raised; a-bought-number's fake models .is() and answers the claim with the number written; a-dropped-component-read- error follows main's tr/{amount} spelling. Found by the verification and fixed without weakening: - catalogues: a block-level pick had dropped the branch's billing.serviceFeeShownAtCheckout and actions.couldNotCheckThatRefresh; redone as a key-level three-way union (14,104 keys in each locale). - a-visitor-is-hearted-subscribed-and-bucketed-only-as-itself (main): its in-memory fake answered every write with null; it now returns the changed rows when a write asks for .select(), as PostgREST does, which is what C1-S9-62's re-activation confirmation reads. - an-unconfirmed-write-outside-actions-ratchet: main's retireAeoQuestionsForPath is deliberately unconfirmed (a page with no published answers retires zero rows); annotated beside the write and the baseline moves 51 → 52, as C1-S9-89 did for main's twin edge prune. The approvals service's C1-S9-65 reason moved back beside its write. - a-write-the-user-is-told-about-is-confirmed: the forward_to_phone pin reads fallback.value; the executed-stamp ordering is checked against the success return it guards, now that decide()'s path returns first. Also: finalaudit gains C1-S9-92 (this renumbering and both merges), the B1 row, C1-S8-07 and every filename citation carry the 04xx numbers, and C1-S6-11's pointer to the dropped 0324 is struck through to main's 0319. Verified on a private database bootstrapped from this tree: 408 migrations applied, 0 failed (the two best-effort marketplace seed errors are main's; SEED_ALL.sql and pg-bootstrap.sh are byte-identical to it); run-probes.sh twice — 128 passed, 0 skipped, 0 failed, of 128, both runs. audit-migration-versions: 408 files, next 0419. vitest on the 580 files that changed or import a changed source, the guard suites included: 8,990 of 8,991; the one, a-failed-vault-probe-does-not-save-a-second- copy, reads node_modules/@supabase/postgrest-js by a checkout-relative path this worktree lacks and passes 16/16 where it exists. finalaudit index: 124 rows, FIXED 99 · OPEN 10, prose agreeing. eslint: 0 errors on the 571 .ts/.tsx files that differ from main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
NewWorldVenture
pushed a commit
that referenced
this pull request
Sep 27, 2026
…ing guards use at() CI on 6e297ca caught two things the merge of main let through, both flagged by this branch's own whole-tree ratchets. lib/guardian/twilio.ts: main's releaseNumber (from #581) called fetchExternal, which this branch had renamed to fetchWithDeadline and whose module it had removed. The merge kept the branch's import and main's call, so releaseNumber named a function that no longer exists - a ReferenceError at runtime, leaving a number that should be released billing. It now calls fetchWithDeadline with the same arguments. tests/a-page-that-could-not-read-does-not-answer.test.ts (two asserts) and tests/the-add-form-is-not-a-way-around-the-memory-edit-gate.test.ts (one) came from main with ordering asserted on a bare indexOf, which passes when the statement it names is deleted. They now use at() from tests/helpers/source-order.ts, so absence fails. Verified: both ratchets, both edited tests and every test that imports the Twilio client pass, 25 files and 274 tests; eslint clean on the three files. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
NewWorldVenture
pushed a commit
that referenced
this pull request
Sep 27, 2026
…uplicate with a probe main's #581 brings 0381-0387, whose numbers the block had already left. Nineteen files conflicted; each keeps both sides' intent: - concierge: main's decide() routing for a queued run's approval, with this branch's read-back on the run's own status updates (and its test case for a filtered dismiss); the direct approval stamps main removed stay removed; - recipe vote: main's route through the grocery service's addItems; 0443 is still reached through ensureDefaultList, and main's grocery-list test models 0443's function over the same state its list read answers from; - calendar feeds: main's find-or-subscribe flow, with its raw save error classified rather than returned (the-database-does-not-talk-to-the-browser); - paywall, graph, inventory, relationship: main's locale money and read-back, this branch's catalogue sentences and safe links; - catalogues: key union in all seven locales; - version pin: main's paragraphs through 0387, then this branch's block, rewritten for 0426-0443 and the four unused numbers; pin 0444. Each of the four duplicates dropped in the renumber is now shown by a probe going red with the file put back on a copy of the replayed chain: 0427 by driving-score-write-boundary-check, 0436 by access-record-write-boundary-check, 0437 by main's private-journal-check, and 0431 by a new step in locator-write-boundary-check that pins main's 0379 rule (with 0431 a child files a check-in naming no member, and a parent cannot file one for a child). The guards found, and this fixes: three guardian routes that dropped write errors, a duplicated inbound-secret block in .env.example, and main's tests whose fixtures predate this branch's rules (an active member, a private image answered from the network). The 32 newly gated tables' twelve silent or unscoped call sites are recorded in KNOWN_UNFIXED, not swept here. The earlier renumber had spliced a drop annotation into file names and ranges; those read cleanly again. Recorded in finalaudit.md Q70, audit/status.md and docs/PENDING_PROD_MIGRATIONS.md (0438 is coupled with app code). Verified at this state: replay 412/412, probes 137/137 twice, none skipped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
NewWorldVenture
added a commit
that referenced
this pull request
Sep 27, 2026
Final audit, continued: the verified units landing after #581
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this is
The next tranche of the final audit's verified units, landing one at a time as each finishes its re-derivation → fix → review → rework → re-review → mutation-proof cycle. Nothing here is marked done on an agent's word: every unit was reverted in a clean worktree at HEAD (test kept, source removed: red; source restored: green), its neighbouring suites and every document guard were run on the staged set, and every migration was applied twice onto a database built from HEAD's migrations with every probe replayed there twice.
Merged with main
maintook #579 (another session's pass C1-K, migrations 0344–0380) and #582 while this PR was open. This branch's seven migrations collided on number and were renumbered 0381–0387 (git mv, names intact, every reference rewritten — 779 replacements, plus ten earlier probes whose comments still said the old numbers), thenmainat6ff770dawas merged in. Conflicts were resolved keeping both sides' intent and tests:xml()escaping in the Twilio client,normalizeFallbackPhone(write side) besidetoCallableE164(read side for legacy rows), the vote re-read-and-retry beside thechangedByMeaudit note, and main'ssocial_has_permissionCASE arm taught to the permission-matrix test's parser rather than a case deleted. Full replay after the merge: 398 migrations, 115 of 115 probes twice, 38 test files green.Units in this PR
family_factsUPDATE/DELETE carry the member rule the service applies), m36 (0386: a calendar URL is subscribed once; a failed first sync leaves nothing behind), m7+m8 (0381: "two parents" is a rule the database keeps), m10+m11 (0382: a password alone does not reach the family's money), m1/m2+m3 (0383: an archived page takes its public answers with it), m13+m14 (0384: the urgent fallback number is stored as E.164 or refused with the form it needs), m32/m33+m34 (a failed grocery or vote read forks nothing and says so), m19 (a rebuilt graph is on screen before the toast), m15 (a dashboard setting that could not be read is not a yes), m16+m17 (the dining page neither hides a failed read nor guesses a total), m5 (a social-links form that could not be read is not a cleared one), m37 (a retried Add whose content changed is not told "Task added"), and m35's three review follow-ups.(family_id)index each).Migrations
0381–0387 — all unapplied, each with a
docs/PENDING_PROD_MIGRATIONS.mdentry and its own boundary probe. Agents do not apply migrations to production; the owner does. Version pin at 0388. Production's migration ledger still stops at 0177 (recorded in the Release · #579 section of finalaudit.md).finalaudit.md
Index regenerated by
docs/audit/finding-index.py: FIXED 99 · CHECKED 2 · PARTIAL 4 · OWNER'S 7 · OPEN 10 · BLOCKED 1 · SUPERSEDED 1. The release line records #580, #579 and #582 onmainand in production. PRODUCTION READY stays NO: four production secrets unset, no migration past 0177 applied, owner decisions pending.🤖 Generated with Claude Code
https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
Generated by Claude Code