Marc-André Bombeck
31b4857d8b
feat(02-12.1): carry and verify the record context from the browser
...
- attach the asserted context to every same-origin request inside the
three fetch entries, so no call site classifies itself
- discard a response whose echoed context contradicts the adopted one;
serve one that carries no echo, which is what keeps the public poll
and every actor surface working
- adopt from /api/auth/me and the switch response, and from nothing else
- send the epoch on every switch and retry once after reconciling
- hold and reconcile on the 409 instead of leaving the record
2026-08-06 19:10:02 +02:00
Marc-André Bombeck
3a99de312e
fix(02-12.1): check record context before an idempotent replay
...
- evaluate the fence in the wrapper above findCached, so a stale request
neither replays a body, learns a cell exists, nor inserts a claim
- return the refusal rather than throwing: one route composes the
wrapper outside apiHandler, where a throw escapes the envelope
- read the claim and the session's own context on one session lookup
2026-08-06 18:54:20 +02:00
Marc-André Bombeck
45fec0fc1b
feat(02-12.1): refuse a record request whose context has moved
...
- both record resolvers check the fence after authentication and before
the carrier, off the one session row that also decides the scope
- POST /api/account/switch takes an optional expectedEpoch and writes
conditionally, so concurrent switchers resolve to one outcome
- GET /api/auth/me publishes the context a browser bootstraps from
- every response that resolved a record scope echoes it back
- regenerate the API contract
2026-08-06 18:21:40 +02:00
Marc-André Bombeck
59359738c8
feat(02-12.1): decide record-session context in one place
...
- add an import-free contract module both bundles can name, holding the
header names, the parse and the verdict
- add the server fence: header read, wide-event stamp, and the refusal
- add RecordSessionChangedError as a third sibling on the existing
sharing-error arm, so the 409 needs no new serialisation branch
2026-08-06 17:59:07 +02:00
Marc-André Bombeck
5c9befc0ae
feat(02-12.1): stamp a record-context epoch on every session
...
- add sessions.record_epoch, owned by a BEFORE UPDATE trigger so the
ON DELETE SET NULL path and raw SQL writes cannot skip it
- normalise pre-existing rows so epoch zero means never switched
- project the epoch off the row getSession already loads
2026-08-06 17:52:10 +02:00
Marc-André Bombeck
a08e82d0be
Merge commit '38214e472' into work/v137-record-session-fence
2026-08-06 17:10:56 +02:00
Marc-André Bombeck
38214e4726
fix(02-12): hold peer tabs during record switches
...
- Clear scoped reads before the server session changes
- Reconcile every tab with a fresh access response
2026-08-06 15:06:12 +02:00
Marc-André Bombeck
c42df8cbc3
fix(02-12): gate record preload scope
...
- Wait for a validated account scope before warming record reads
- Abort scoped preloads and discard handoffs across record transitions
- Cover malformed scope reloads and fresh own-record recovery
2026-08-06 14:32:32 +02:00
Marc-André Bombeck
2ae3a66816
fix(02-11): bound APNs provider delivery
...
- Time out stalled provider sends without unhandled late rejections\n- Record a transient timeout outcome for cascade fallback\n- Cover timeout fallback with unit and integration tests
2026-08-06 14:10:28 +02:00
Marc-André Bombeck
c56d1ca50b
fix(02-11): protect guardian egress data lifecycle
...
- Exclude and erase egress claims with recipient-side lookup support\n- Serialize data wipes with managed-profile Guardian authorization\n- Cover last-Guardian and queued-claim wipe races
2026-08-06 14:05:59 +02:00
Marc-André Bombeck
21e111c06c
fix(02-12): refuse malformed record access
...
- Preserve absent-server compatibility while rejecting published invalid blocks\n- Partition refused record reads and withhold protected presentation
2026-08-06 14:03:13 +02:00
Marc-André Bombeck
4b79f83cf7
fix(02-11): release guardian lock before provider egress
...
- Commit a final authorization claim under the lifecycle lock\n- Keep provider calls and retry outcomes outside database transactions\n- Retain authorization claims with notification delivery diagnostics
2026-08-06 13:46:42 +02:00
Marc-André Bombeck
b844d04676
fix(02-12): reject divergent shared-record state
...
- Verify the active record matches its canonical switcher entry\n- Skip the owner OCR probe in delegated Labs records
2026-08-06 13:39:37 +02:00
Marc-André Bombeck
1818bd874b
fix(02-11): authorize guardian egress under lock
...
- Hold the managed-profile lock through every provider send\n- Add the notification event retention index and race coverage
2026-08-06 09:42:47 +02:00
Marc-André Bombeck
358bb39465
fix(02-12): keep scoped record polls dormant
...
- suppress whole-record achievements reads for narrowed grants\n- stabilize record journey response assertions
2026-08-06 08:34:02 +02:00
Marc-André Bombeck
60b4845fea
feat(02-11): secure guardian notification delivery
...
- Remove record-mutating affordances from Guardian channel payloads\n- Reject managed Telegram callbacks and verify channel attribution
2026-08-06 05:44:41 +02:00
Marc-André Bombeck
accb98e223
test(02-11): cover guardian notification channel safety
...
- Cover non-interactive Guardian payloads across delivery channels\n- Reject Telegram callbacks tied to managed records
2026-08-06 05:37:05 +02:00
Marc-André Bombeck
59de92b62e
fix: isolate guardian notification preferences
2026-08-06 05:33:02 +02:00
Marc-André Bombeck
a78189b7f6
feat: add guardian notification fanout
2026-08-06 05:23:38 +02:00
Marc-André Bombeck
5e8b90bcc1
Merge notification delivery identity
2026-08-06 05:12:42 +02:00
Marc-André Bombeck
f6b9c8e882
fix(02-12): fail closed in record presentation
...
- retain elevated chrome only for internally consistent payloads\n- fall back to the caller record on malformed access entries
2026-08-06 05:07:27 +02:00
Marc-André Bombeck
6c4dd2d96b
feat(02-12): route scoped records to granted domains
...
- keep shared navigation independent of actor module preferences\n- open scoped records at their first allowed destination\n- announce record access and kind in doorway names
2026-08-06 05:02:37 +02:00
Marc-André Bombeck
affd356677
test: retain sustained safety event claims
...
- exercise the shared notification claim boundary\n- preserve rolling sustained-run dedup coverage
2026-08-06 04:59:50 +02:00
Marc-André Bombeck
9eab70f032
feat(02-12): add scoped profile summary
...
- expose bounded read-only profile facts for shared records\n- keep profile navigation separate from Settings mutations
2026-08-06 04:59:25 +02:00
Marc-André Bombeck
9ba37342d7
fix: claim notification events atomically
...
- serialize rolling event claims before delivery\n- keep provider egress outside the transaction
2026-08-06 04:57:50 +02:00
Marc-André Bombeck
ba7bf49fae
test: cover atomic notification event claims
...
- race record event claims through PostgreSQL\n- require safety producers to honor the claim
2026-08-06 04:53:50 +02:00
Marc-André Bombeck
60f91d27d7
fix: validate account access payloads
...
- Share the closed access schema with OpenAPI\n- Fail closed on malformed or stale record metadata
2026-08-06 04:52:46 +02:00
Marc-André Bombeck
69f97b268c
fix: erase notification anchors with record data
...
- remove record event anchors during data deletion\n- retain sustained safety dedup coverage
2026-08-06 04:48:47 +02:00
Marc-André Bombeck
9c4c7b2b7d
fix: retain notification anchor boundaries
...
- classify local notification anchors outside backups\n- keep reminder dedup fixtures on record events
2026-08-06 04:46:45 +02:00
Marc-André Bombeck
c6b5d5df63
test: cover account access payload parsing
...
- Preserve canonical shared and manage payloads\n- Reject malformed and stale access metadata
2026-08-06 04:46:15 +02:00
Marc-André Bombeck
10a58a7e6a
test: cover recipient-scoped Telegram persistence
...
- retain independent recipient reminder slots\n- verify chat updates and recipient cascade cleanup
2026-08-06 04:44:08 +02:00
Marc-André Bombeck
027f2b4355
fix: suppress premature managed safety delivery
...
- keep direct safety notifications to ordinary self-delivery\n- move safety dedup anchors out of delivery diagnostics
2026-08-06 04:41:40 +02:00
Marc-André Bombeck
ce94f4773f
fix: reject partial notification attribution
...
- retain only complete delivery principal pairs\n- preserve legacy self-delivery records
2026-08-06 04:39:36 +02:00
Marc-André Bombeck
8b275c87db
test: cover partial notification attribution
...
- reject one-sided delivery identities\n- avoid ambiguous push-attempt ledger writes
2026-08-06 04:38:48 +02:00
Marc-André Bombeck
fa46f27b01
feat: scope Telegram reminder tracking to recipients
...
- keep delegated recipient slots independent\n- bind callback cleanup to the recipient account
2026-08-06 04:38:09 +02:00
Marc-André Bombeck
5807879439
test: cover recipient-scoped telegram reminders
...
- Keep identical slots separate for each recipient\n- Update one slot when a recipient changes chat
2026-08-06 04:33:35 +02:00
Marc-André Bombeck
9380ea0f18
feat: separate notification event anchors
...
- Store record-scoped scheduler events outside delivery attempts\n- Keep delivery diagnostics free of bookkeeping rows
2026-08-06 04:32:52 +02:00
Marc-André Bombeck
2999b75ea6
test: cover notification event anchors
...
- Require record-scoped reminder deduplication\n- Keep anchors independent of delivery recipients
2026-08-06 04:29:54 +02:00
Marc-André Bombeck
1ba73a4d51
fix: enforce notification delivery authority
...
- Require active Guardian authority before cross-record delivery\n- Serialize managed delivery checks with lifecycle changes
2026-08-06 04:29:18 +02:00
Marc-André Bombeck
ba3be7ba9b
feat: distinguish managed record access
2026-08-06 04:18:05 +02:00
Marc-André Bombeck
afae57207c
feat: scope shared record navigation
2026-08-06 04:13:59 +02:00
Marc-André Bombeck
2ccd022410
test: update notification sender attempt mocks
...
- Exercise identity-aware delivery attempt recording\n- Keep self-delivery assertions explicit
2026-08-06 04:05:33 +02:00
Marc-André Bombeck
201a24e404
Merge managed record settings
2026-08-06 04:05:16 +02:00
Marc-André Bombeck
437d916fc6
fix: guard managed setting label inventories
...
- Treat inherited property names as unavailable settings
- Preserve legacy tile aliases only for declared entries
2026-08-06 04:01:00 +02:00
Marc-André Bombeck
906118f86e
fix: resolve notification delivery identity
2026-08-06 03:57:23 +02:00
Marc-André Bombeck
6108a71d80
feat: separate notification subjects and recipients
2026-08-06 03:46:57 +02:00
Marc-André Bombeck
247ac8494c
fix: complete managed record settings
...
- Expose canonical defaults and reject invalid settings families\n- Localize Guardian controls and refresh dependent caches
2026-08-06 03:40:13 +02:00
Marc-André Bombeck
e788675b82
feat: configure managed record settings
...
- Scope writable settings to the selected managed record\n- Render typed Guardian controls with separated audit attribution
2026-08-06 03:21:02 +02:00
Marc-André Bombeck
389f2a042b
fix: complete managed Guardian invitation lifecycle
2026-08-06 03:19:34 +02:00
Marc-André Bombeck
32380b1935
fix: clear revoked Guardian sessions
...
Return a removed Guardian's browsers to their own record.
2026-08-06 03:08:51 +02:00