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
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
Marc-André Bombeck
09ff1fb23d
feat: enforce managed sharing boundaries
2026-08-06 01:16:18 +02:00
Marc-André Bombeck
d86358f3e4
fix: recover managed sharing boundaries
2026-08-06 00:19:35 +02:00
Marc-André Bombeck
8669df4cda
feat: add scoped record invitations
2026-08-05 23:58:30 +02:00
Marc-André Bombeck
ab14fdb6f3
Let an invitation name its sections and offer management
...
An owner can now narrow a grant to the parts of their record they mean to
share, and can offer the third level. Both decisions are made once, on the
invitation, and neither widens afterwards.
The invite schema takes `scope`: absent or null is the entire record, which
is what every stored grant means and what an owner who does not narrow still
gets. An empty array, a key outside the vocabulary and the whole-record
sentinel are each refused with a 422 naming the field; `inviteGrant` refuses
the same three underneath, and its `invalid_scope` now has an HTTP mapping
instead of falling into the generic refusal.
Offering MANAGE asks for a fresh second factor when the account has one. That
gate resolves through the session cookie and has no Bearer fall-through, so a
token caller is refused first with `sharing.invite.manage_browser_only` rather
than being told it is not authenticated by a route that had just
authenticated it. The consequence is deliberate: management of a health
record is offered from a browser.
The account payload gains `sections` and `level` beside `access` and
`canWrite`, resolved server-side and ordered as the consent screen reads.
`access` was `grant.access === "WRITE" ? "write" : "read"`, which would have
published a grant that can delete entries as read-only; it is a total map
now, so the next level cannot ship silent. The capabilities hook carries both
facts and turns neither into an affordance yet — the edit and delete controls
come back in the release where the routes behind them answer.
The consent surface asks two questions in order rather than laying out a
nineteen-cell grid. The level is three radios, narrowest preselected. What
they can open is two radios, the entire record preselected, and only the
narrow branch expands the eight sections with a sentence each. Both honest
limits are stated above the checkboxes, where the decision is being made: a
section shares everything written in it, and the cross-record surfaces do not
appear for a narrowed grant. Documents carries its own warning, cycle appears
only for an owner who tracks it, and Manage collapses the question to the one
line that answers it.
The Manage sentence says the other person can add, change and remove entries,
including ones the owner entered themselves, and says in the same breath what
it does not reach. The acceptance side gets its own responsibility line rather
than the write one wearing a stronger adjective.
Six locales.
2026-08-05 23:37:00 +02:00
Marc-André Bombeck
feb9d25e87
test: anchor sharing release journeys
2026-08-05 23:29:55 +02:00
Marc-André Bombeck
bd6220bbba
test: add sharing security principals
2026-08-05 23:26:42 +02:00
Marc-André Bombeck
d9e68e7ee3
test: freeze sharing authorization inventories
2026-08-05 23:24:54 +02:00
Marc-André Bombeck
d42d2bb784
Merge branch 'main' into release/v1.37.0
2026-08-05 23:04:36 +02:00
Marc-André Bombeck
1a70044af9
fix: preserve delegated dose facts on replay
2026-08-05 22:48:31 +02:00