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
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
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
d9b675f993
feat: attribute notification delivery attempts
2026-08-06 03:59:08 +02:00
Marc-André Bombeck
e4993af909
test: cover notification diagnostic attribution
2026-08-06 03:57:55 +02:00
Marc-André Bombeck
906118f86e
fix: resolve notification delivery identity
2026-08-06 03:57:23 +02:00
Marc-André Bombeck
913a41b37d
test: cover notification delivery identity
2026-08-06 03:49: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
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
ffe3225639
fix: complete managed Guardian lifecycle
...
Use locked Guardian membership and transactional lifecycle audits.\n\nKeep acceptance and marker changes atomic.
2026-08-06 03:05:19 +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
e5e3590ca3
feat: add managed profile Guardians
...
- Keep the ordinary invitation consent flow for a second Guardian\n- Clear managed Guardian expiry when the invitation is accepted
2026-08-06 02:32:59 +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
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
c3125078b9
chore: resolve sharing lint checks
...
Keep attribution and provider-work tests lint-clean.
2026-08-06 02:13:50 +02:00
Marc-André Bombeck
d404d8275a
fix: preserve import job wipe ownership
...
Keep durable actor attribution from deleting record-owned jobs.
Align provider and idempotency coverage with fail-closed behavior.
2026-08-06 02:11:01 +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
a620a730b9
test: extend sharing boundary guards
...
Cover provider work authority and import actor attribution.
2026-08-06 02:04:04 +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
01562b4aef
test: use the shared browser test entry point
2026-08-06 00:08:54 +02:00
Marc-André Bombeck
8669df4cda
feat: add scoped record invitations
2026-08-05 23:58:30 +02:00
Marc-André Bombeck
4923db6464
fix: preserve account access compatibility
2026-08-05 23:58:26 +02:00
Marc-André Bombeck
e4e773d543
feat: define scoped sharing levels
2026-08-05 23:58:18 +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
e05bad0ec2
chore: refresh the sharing release foundation
2026-08-05 23:14:01 +02:00
Marc-André Bombeck
553e0b4a28
Merge commit 'd07b9249c' into release/v1.37.0
2026-08-05 23:04:39 +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
d07b9249c8
fix: complete dashboard hydration
2026-08-05 23:03:17 +02:00