Marc-André Bombeck
c11c462e57
fix: answer a duplicate measurement with 409 on both write paths
...
The batch path had no unique-violation handling at all, so one duplicate
anywhere in the transaction answered 500 — indistinguishable from a
server fault, and what every client retries against. The single path
narrowed with instanceof, the form prisma-errors.ts exists to replace.
2026-08-06 20:56:16 +02:00
Marc-André Bombeck
8fcbdcc0df
test(02-12.1): prove the record-session fence end to end
...
- give every acceptance case a stable id and assert the mapping from a
runnable artifact, recording which cases execute in the ordinary gate
and which await the browser stage
- add the browser spec for the cases no cooperative layer can reach:
peers reconciling to an exact context, an aborted switch response, a
closed initiator, a delayed response, and the offline disk layers
2026-08-06 19:33:15 +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
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
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
e8ce0e277a
test(02-11): verify final claim uses database time
...
- Keep a stale application clock from authorizing an expired Guardian\n
2026-08-06 13:47:42 +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
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
6ecf0cc8ff
style(02-11): format notification attribution test
...
- Apply the repository formatter to the existing integration test
2026-08-06 09:37:42 +02:00
Marc-André Bombeck
f5a02c2d29
test(02-11): cover guardian egress races
...
- Exercise revocation and expiry against blocked channel egress\n- Require a direct retention index for notification events
2026-08-06 09:35:43 +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
be4ee9ac6d
test: cover guardian notification preferences
2026-08-06 05:30:49 +02:00
Marc-André Bombeck
b231a7892c
test(02-12): retire sharing inventory anchors
...
- remove obsolete inventory-only journey declarations\n- select persistent shared-record journeys by Playwright project config
2026-08-06 05:16:32 +02:00
Marc-André Bombeck
5e8b90bcc1
Merge notification delivery identity
2026-08-06 05:12:42 +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
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
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
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
b78d64cb98
test: cover notification delivery authority
...
- Require active Guardian authority for managed delivery\n- Cover inactive and mismatched grants
2026-08-06 04:27:27 +02:00
Marc-André Bombeck
201a24e404
Merge managed record settings
2026-08-06 04:05:16 +02:00
Marc-André Bombeck
906118f86e
fix: resolve notification delivery identity
2026-08-06 03:57:23 +02:00
Marc-André Bombeck
6a1d1dd6e8
fix: preserve managed target defaults
...
- Return effective threshold ranges after managed updates\n- Localize closed Coach and Insights display inventories
2026-08-06 03:52:49 +02:00
Marc-André Bombeck
3bb9349171
test: cover notification attribution constraints
2026-08-06 03:49:42 +02:00
Marc-André Bombeck
6108a71d80
feat: separate notification subjects and recipients
2026-08-06 03:46:57 +02:00
Marc-André Bombeck
6771b9060f
test: cover notification attribution persistence
2026-08-06 03:43:35 +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
493437207e
test: cover managed Guardian invitation lifecycle
2026-08-06 03:14:47 +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
Marc-André Bombeck
55291ad32d
test: cover managed Guardian lifecycle races
...
Exercise cookie routes, transaction rollback, and record-serialized races.
2026-08-06 03:01:12 +02:00
Marc-André Bombeck
523ab3220b
fix: serialize managed profile Guardians
...
Protect every Guardian-reducing lifecycle transition with a record lock.\n\nReturn a recoverable refusal when the final Guardian remains.
2026-08-06 02:50:30 +02:00
Marc-André Bombeck
5059bc9b69
test: cover managed profile Guardian races
...
- Exercise concurrent final-Guardian reductions against Postgres\n- Cover recoverable account and profile deletion paths
2026-08-06 02:36:08 +02:00
Marc-André Bombeck
665f223dc4
test: cover managed profile Guardian consent
...
- Pin ordinary second-Guardian acceptance\n- Pin non-expiring accepted Guardian grants
2026-08-06 02:29:55 +02:00
Marc-André Bombeck
58434a2b44
feat: create managed profiles atomically
...
- Require a fresh cookie MFA proof before creation\n- Create the credential-less profile and initial Guardian grant together
2026-08-06 02:28:56 +02:00
Marc-André Bombeck
d95c48f48d
feat: classify managed record settings
...
- Inventory every Settings destination as an explicit access class\n- Fail closed for unknown deep-link destinations
2026-08-06 02:28:29 +02:00
Marc-André Bombeck
1eb0d22285
test: add record settings contract
...
- Cover record-keyed DTO and cache behavior\n- Pin actor identity separately from the active record
2026-08-06 02:25:53 +02:00
Marc-André Bombeck
51cbbae17f
test: cover managed profile creation
...
- Prove truthful profile attributes and the initial Guardian grant\n- Prove grant-write failure rolls the profile transaction back
2026-08-06 02:25:19 +02:00
Marc-André Bombeck
f5ca810643
chore: format sharing authority controls
...
Apply repository formatting to provider and import coverage.
2026-08-06 02:05:24 +02:00
Marc-André Bombeck
620817b10b
fix: retain import actor attribution
...
Persist record and actor identities through job completion.\nWrite one bounded transactional completion audit per job.
2026-08-06 02:00:35 +02:00
Marc-André Bombeck
adb932052c
fix: keep managed system work operator-scoped
...
Resolve managed record credentials through the operator policy for system work.
2026-08-06 01:53:04 +02:00
Marc-André Bombeck
2b2080f48c
test: pin import actor attribution
...
Cover durable record and actor attribution across completion retries.
2026-08-06 01:52:43 +02:00
Marc-André Bombeck
e209db24f4
fix: block delegated provider egress
...
Carry bounded work authority through queues and revalidate it at dispatch.\nResolve shared records without personal credentials.
2026-08-06 01:49:33 +02:00
Marc-André Bombeck
f7a06df2bc
test: pin provider origin controls
2026-08-06 01:38:35 +02:00
Marc-André Bombeck
60b842f614
fix: reauthorize delegated replay
...
- Recheck the live grant before returning cached delegated responses
- Refuse cached replay when the acting record cannot be resolved safely
2026-08-06 01:29:07 +02:00
Marc-André Bombeck
f8b05d541e
test: pin delegated replay revocation
...
- Cover active, revoked, and own-record cache replay against Postgres
2026-08-06 01:22:33 +02:00