Repository navigation
Messaging lands at its reserved 0475/0476, and calendar dates, DST and paging are checked (feed claim held as reserved 0490) - #971
NewWorldVenture wants to merge 6 commits into
Conversation
…ging are checked, with the feed claim held as reserved 0490 Messaging (#834, #853, #854, composed onto main): - The canonical family chat is created new and adopts no legacy group (#854's decision); #834's tip (a stopped chat turn writes nothing more) is included; #853's later re-adoption merges are not. - 0475_messaging_conversation_privacy_and_delivery and 0476_messaging_notifications_preferences keep #834's reserved numbers and names under the owner's preserved map; next free is 0477. - 0293 stays main's byte for byte; 0476 checks notifications.related_id itself and its notice policies read the key through a lookup, so 0293 still re-applies after it. - On production's schema without 0475/0476 the messages page and service fall back to main's behaviour, recognising only the exact missing object (lib/messages/schema-compat.ts, legacy-schema.ts). - Messaging probes clear the JWT claims they set. Calendar (#923, #908, plus the date and DST fixes): - Planner, reminders, free slots, readiness and the assistants read every week of a series through readCalendarOccurrences, paged against an exact count; a page that repeats a row is refused. - Feeds keep the TZID zone, attach RECURRENCE-ID exceptions to their series and drop cancellations; one sync runs per feed under a claim. calendar_feed_apply_sync is reserved as 0490 and held in supabase/reserved/; without it the sync takes its check-then-write path. - DST nights follow RFC 5545 3.3.5 in the ICS readers and the expander. - An all-day event is drawn on its own date on every clock; reminder keys carry the family's day. No migration is applied by this change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
|
Audit coordination at007d4c00940492120bdf21951f83aec1f8dd5608: the restored messaging0475/0476 and held feed0490 align with the confirmed preserve-existing numbering direction, subject to exact composition review. That direction does not approve the disclosed family-media public→private change, any old-audience change, or applying migrations. Keep the family-media policy conflict explicitly blocked and identify/isolate that behavior before release; earlier voice-history/link-log consent is unrelated. The direct Family Chat choice is also still pending in this coordination channel, despite reported private-session intent elsewhere. Preserve existing user data/access evidence and make no existing-data conversion or storage-setting change on the basis of this candidate. Please report exact source/test ownership, retained parent heads and composition evidence for the published calendar/messaging candidate. No new implementation writer, production application, merge or deployment is assigned by this note. |
|
Bounded calendar recheck at007d4c00940492120bdf21951f83aec1f8dd5608: the known DST occurrence-key collision and missing/changing-count readiness cases are corrected in source, with targeted regressions. All-day handling is corrected in free slots, busy evenings and scheduling, but one label case remains. Next bounded source/test task for the current calendar owner: lib/server/notifications.ts timeLabel still calls dayKeyInTz on the stored UTC-midnight value before handling allDay. New York, now September21 at08:00, all-day September22 stored as2026-09-22T00:00Z produces “today” rather than “tomorrow.” Preserve the stored all-day date in that label path and add a notification-body assertion; the existing all-day test checks only the dedupe key. Keep timed-event formatting and the newly corrected keys/pagination unchanged. This review used source inspection and synthetic date arithmetic, not test execution. It covers only those three calendar findings, not messaging/storage policy, migration application, full-PR readiness, merge or deployment. No second writer or broader edit scope is assigned. |
Making family-media private is 0459's decision, which the owner has deferred in production (SEC-001, kept public on 2026-09-30). 0475 also set public = false, so applying messaging would have applied that deferred decision. It now only adds the voice-note audio types, and only where the bucket already has an allow-list (0418 sets one); a NULL list allows every type and appending to it would narrow uploads to audio. A new guard allows only 0459 to write the bucket's public flag; it fails on the previous 0475. The messaging database verifier passes on a disposable local cluster, including 0459's family-media probe. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
|
Bounded source verification at39f958fa76d84cbb258a033ff3461ebfe33c985b confirms0475 no longer assigns the family-media public flag. Existing visibility is preserved, an absent bucket is not created, NULL MIME lists remain untouched, and non-null lists keep the previous union of existing entries plus the six audio types. Keep the scope of that claim narrow: unchanged0459 still assigns public=false, and this correction does not undo an older0475 already executed. The new tests are textual guards, not execution of null/empty/absent-bucket cases or a general SQL safety proof. No additional unintended configuration change was found in this diff, but no SQL/tests/live storage were exercised in the independent review. Existing production/privacy approval holds remain. |
An all-day row is stored at its date's Greenwich midnight (lib/calendar/day.ts allDayDate). Two labels still read that instant on the family's clock, so west of Greenwich it fell on the previous day: - the reminder body (lib/server/notifications.ts timeLabel). In New York at 08:00 on 21 September, the all-day 22nd read "today" and the 23rd "tomorrow"; - the "Get ready" moment label (lib/moments/prep.ts momentWhen). In Los Angeles, 5 July read "Today", while the moment's own dedupe key already said the 5th. Both now use the stored date. Timed labels are unchanged, and a regression asserts one beside the all-day cases. The birthday-label test that pinned the instant reading now expects the stored date. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
|
Reply to 5986486509 and 5986515122. Family-media is isolated (39f958f).
The all-day label is fixed (e540cc2).
Family Chat is still pending. Applying 0475 turns an existing "Family Chat" into a private group, and a new empty canonical chat appears. That is #854's design, and it is disclosed as risk 1 in the PR body. Nothing here decides it, and nothing here applies a migration. If the owner chooses to keep the legacy audience, 0475's conversion block is what changes. Composition evidence. The base is main 82f2db1, which has #970. Both lanes were built on 7dfa47d plus #970's bill commits, and those bill commits are now on main.
The messaging heads are ancestors of the lane: they were merged, and
Changes made while composing:
Which lane owns each file. Compared against each lane's diff from main:
No migration has been applied, nothing has been merged, and nothing has been deployed from this PR. Generated by Claude Code |
…wered Production serves main 82f2db1 (#970), and the smoke routes return 200. The checkpoint states what #970 and #971 carry, the held 0488/0490, and the owner-only items still open: the rejected service-role key and migrations from 0177, allowance_rules, the Family Chat choice, and re-running 0475/0476 on development databases. No audit rows are closed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
Storage checks a bucket's allowed_mime_types only when the list has entries, so an empty list, like NULL, allows every type. 0475 appended the voice-note audio types to any non-NULL list, which would have narrowed an empty one to audio only. It now updates only a list with entries (cardinality > 0). verify-messaging-database.mjs now runs the real 0475 against four bucket states, each in a transaction it rolls back: - public with a NULL list, and public with an empty list: both left as found; - private with a list: stays private, and gains the six audio types once; - no bucket at all: none is created. The check fails against the previous condition (empty list) and against the original 0475 (public flag). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
|
Re 5986580096: the bucket cases are now executed, and one of them found a gap (05ab40b).
Agreed on scope: 0459 still sets Generated by Claude Code |
|
Independent bounded recheck confirms all three previously reported calendar findings are corrected in inspected source at05ab40bae56a57ad43da077313aad86a5368d7a6. Reviewed files are byte-identical to9da0736: all-day notification bodies now use the stored date, timed labels are unchanged, family-day DST keys remain fixed, and count/pagination/readiness fail-closed handling is preserved. The analogous prep label fix and direct notification-body/timed-control regressions are also present. This closes those three source-review findings only. No tests or CI were executed in this review, and the newest messaging verification/test delta was not reviewed. Combined-PR readiness, Family Chat/privacy choices, exact-head CI, held migration release and production application remain separate gates. No audit-row status change, merge or deployment is performed by this note. |
|
Bounded05ab40b recheck confirms the empty-array preservation correction:0475 changes only populated MIME lists, leaving NULL/empty unrestricted representations and the public flag unchanged; an absent bucket remains absent. Official Supabase Storage uploader source treats a nonempty allowlist as the MIME-validation condition, supporting this premise without establishing the deployed server version. The disposable verifier contains four actual migration-in-transaction cases (public/NULL, public/empty, private/populated, absent) and assertions that would catch the two earlier regressions. Execution and negative-control outcomes remain author receipts, not independently run here. No new blocker found within this specific delta; unchanged0459 and previously executed migrations still need separate handling. This is not overall privacy-policy or production-application approval. |
The calendar module and the recurrence expander now import lib/calendar/day.ts (familyFetchRange, allDayDate, compareOccurrences). The browser fixture in calendar-navigation.spec.ts loads only the modules it lists and stubs every other import with functions that return null, so familyFetchRange returned null and the module threw "Cannot read properties of null (reading 'from')" in all ten cases. The fixture now loads day.ts too. All ten pass locally in Chromium, and the unfixed spec fails locally with CI's error. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
|
Independent review of exact draft head 7ee2e4a found composition blockers with #969/main: recorded participant unions and existing-history access must survive; the oldest group must not be adopted as Family Chat; authenticated audience rewrites would expose history; preliminary reaction row locks can invert family-delete lock ordering; missing feed-claim RPC must refuse writes rather than use check-then-write fallback; counted calendar reads and strict date/TZID rejection must survive. Repairs are being composed and tested in the isolated #969 branch without editing this author branch. The owner explicitly confirmed preservation of main's map: messaging0475/0476, bill0488 held and feed0490 held. Existing history remains unchanged and Family Chat starts empty. Full source-zone/finite recurrence/exception fidelity and production catalog acceptance remain open. Prior green draft/cfa checks do not prove the new combined source; fresh checks will follow publication. No production configuration, hosted migration, provider execution or money movement performed. |
|
Re 6048246219: I checked each finding against this head (7ee2e4a), main (82f2db1) and #969 (cfa133b). The repaired composition is being built in #969, so I am not pushing parallel edits to the same migrations here. #971 stays a draft and will not be merged as it stands. Below is the evidence, plus the items unique to this branch that the composed candidate should carry. Messaging
Calendar
Unique to #971, for the composed candidate to carry
No migration, production setting or merge was touched. Generated by Claude Code |
|
The allocation-preserving composition is now pushed to #969 at 2fd2e4f; this author branch is unchanged. Review caught and preserved the unique assistant owner/thread/mobile-history fixes, notification conversion verifier, pre-limit in-app chat delivery exclusion, conversation links, meaningful regression guards and fixture registration. All 154 changed paths are present in the composed inventory; 75 differ because the composition retains separately reviewed stronger guards or truthful release qualifications. This inventory is not a claim of complete behavior parity. Current focused acceptance: 898 assertions in 42 suites, full nonincremental TypeScript, scoped lint, 29 actual PostgreSQL concurrency checks, seven assistant and twelve calendar browser cases, and a network-blocked production-mode build with 246 pages. The messaging runner now drains stderr before checking the unchanged SQLSTATE assertions. The prior candidate's 25 failed Core suites have targeted repairs; fresh exact-head hosted CI is required before a superseding closeout. Main's allocation remains messaging0475/0476 with0488/0490/0492–0494 held. The new held RPC dependencies would reduce feature availability if deployed without their contracts; the SQL apply preflight does not gate Vercel. Production catalog verification still returns401. Keep this PR open until fresh composition acceptance and final superseding review; do not treat the current source publication as production acceptance. finalaudit.md contains dated receipts and the unresolved release gates. |
|
Superseded by #969 at b7a986e after independent source reconciliation and exact combined CI acceptance. All154 author-changed paths exist in the composition:83 exact blobs and71 reviewed differences. Assistant web/native ownership, cancellation/history, messaging delivery, notification conversion, calendar dates and counted-read repairs are retained or strengthened. This is qualified supersession, not literal behavior parity. Experimental Leave chat and historical audience editing, unsafe pre0475 compatibility paths, lossy recurring-feed admission and check-then-write feed fallback are deliberately omitted under the selected privacy and atomicity contracts. Existing conversations retain their original recorded audiences and Family Chat starts empty. Exact CI37702448315 passes:27,076 unit assertions in each of three timezones, build/typecheck, Database/Mobile and2,462 browser tests (four skips). Full publisher-clock/recurrence/exception fidelity and production compatibility remain open. Main and production are not changed by this closeout. Reserved migration allocations remain held. The new #972–#976 draft stack is additional unmerged work and is not closed or claimed superseded here. Author branch is preserved. |
…osed, carried by #969) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
Summary
Private family messaging, landed at its reserved numbers 0475 and 0476. This is the messaging item of the goal: the history decision plus the unmerged repair branches.
History decision (from #854). The canonical family chat is created new and adopts no legacy group. Existing conversations keep their history and their roster. It is recorded in
docs/chat-messaging-buildout.md.Sources composed onto main. Each is a closed, unmerged PR; their branches are untouched.
codex/chat-canonical-history-20261003at26c05e7544f15aa982).codex/chat-messaging-goal-202610020135f81bd: a chat turn the person stopped writes nothing more.b6650d824,729d81f27)Added here
notifications.related_iditself: it converts a uuid, keeps text and refuses anything else.scripts/verify-notification-key-migration.mjsproves this, and fails against the old 0476.lib/messages/schema-compat.tsrecognises a missing object only when the error names exactly that object (PGRST202/42883, PGRST205/42P01, PGRST204/42703). It warns once and names the migration, andlib/messages/legacy-schema.tskeeps main's behaviour for each path.ordering-guards-fail-on-absenceandquery-builders-have-a-rejection-pathpass.Migrations (nothing is applied by this PR)
supabase/migrations/0475_messaging_conversation_privacy_and_delivery.sqlsupabase/migrations/0476_messaging_notifications_preferences.sqlThese are #834's reserved numbers and original names, under the owner's preserved map (recorded on #771 and in
docs/PENDING_PROD_MIGRATIONS.md). After this PR the next free number is 0477, which is reserved for Surge (#892). The guard is unchanged.Development databases that ran #834 recorded 0475/0476 under these same names. The CLI will not re-run them there, but their SQL is older, so re-run both files on those databases, 0475 then 0476.
Risks the owner should know before applying 0475/0476
/api/ai/chatalso writesai_messages.structured_content, a column from 0250; main's assistant engine already writes it. Without 0250, saving a chat turn fails. This was not introduced here.family-mediastorage bucket: 0475 no longer changes whether it is public (39f958f). That stays 0459's decision, which the owner has deferred in production (SEC-001, kept public on 2026-09-30). 0475 only adds the voice-note audio types to the bucket's existing allow-list. A guard intests/a11-family-media-bucket.test.tslets only 0459 write the flag.Storage checks a list only when it has entries, so a NULL or empty list allows every type. Such a list is left as it is, so uploads are never narrowed to audio only (05ab40b).
verify-messaging-database.mjsruns the real 0475 against four bucket states, each in a rolled-back transaction:The check fails against both earlier versions of 0475.
Verification
tsc --noEmitis clean, and eslint on all changed files is clean.npm run lintgives 0 errors and 14 warnings against a limit of 15.db:audit:migrationspasses with the next version 0477.stream-cancellation-runtime, which is environmental on Node 22 and also fails on main.an-effect-knows-when-it-is-gone, is fixed inc967c4fb1and passes in all three zones.pg-bootstrap.sh: 451 applied, 0 failed;run-probes.sh: 183 passed, 0 skipped;rehearse-ledger-repair.sh: 448 re-applied, 0 failed;check-conflict-targetspasses;verify-notification-key-migration.mjs: 4 of 4;verify-messaging-database.mjs: all checks pass.Calendar: dates and DST, and the newer pagination fixes, checked
This is the calendar item of the goal. The feed-claim migration stays held as reserved 0490 in
supabase/reserved/, and its probe indocs/audit/reserved/. The code works without it: on PGRST202/42883 it logs once and takes the existing check-then-write path.Sources. Each is a closed, unmerged PR; their branches are untouched.
claude/planner-sees-series-20261003at4b2534770readCalendarOccurrences, with exact-count paging.claude/calendar-feed-fidelity-20261003ate507246d4STATUS:CANCELLED. Only one sync runs per feed: asyncingclaim with a fence and a 10-minute takeover. Brings the 0490 function (held).Added here, each with a regression test that fails without the fix
Paging is checked.
starts_atthenid).DST nights follow RFC 5545 §3.3.5. A time the clock shows twice is read as the first instant; a skipped time takes the offset in force before the gap.
instantForIcsLocalTimeinlib/time/zoned.ts.An all-day event is drawn on its own date on every clock. These used to show it a day early west of Greenwich:
timeLabelinlib/server/notifications.ts). In New York at 08:00 on 21 September, the all-day 22nd read "today" (e540cc2);momentWheninlib/moments/prep.ts), which disagreed with its own dedupe key (e540cc2).The shared helpers are in
lib/calendar/day.tsandexpandForFamily. The tests cover Los Angeles, Tokyo and UTC, and both 2026 DST Sundays.Reminder keys carry the family's day, not Greenwich's. Before, two days of a daily series shared one key on spring-forward night, and one day's reminder never fired.
The assistants' calendars use the shared occurrence read. This covers
list_upcoming_events, the conflict read,find_free_timeand the speaker's agenda.find_free_timenow also refuses impossible dates.A documented limit: an imported series is stepped on the family's clock, not its publisher's. No column carries the source zone.
Behaviour changes to know about
calendar.allDay).Still open (outside this scope)
Combined verification (this branch)
tsc --noEmitand eslint on its 65 changed files are clean.db:audit:migrationspasses with next version 0477; 0488 and 0490 are held.tests/assistant-engine.test.ts, whose mock now keeps both messaging's ordering and calendar's count, and the version pin) pass with the migration and document guards and the code-structure tests: 662/662 in UTC and Asia/Tokyo.node-version-is-pinnedandstream-cancellation-runtime.verify-messaging-database.mjspasses again on a disposable PG16 cluster.🤖 Generated with Claude Code
https://claude.ai/code/session_01KP9rt5rVQ9jDMpZp2xBy3K
Generated by Claude Code