SHARING: invite links for people without an account #1035

Closed
opened 2026-10-04 06:23:47 +00:00 by kayg · 18 comments
Owner

Contract: DESIGN §54 "Invite links". A tick "Invite people without an account" in the Share dialog creates an invite link for that share.

  • A person without an account opens the link, creates an account (passkey enrolment as in the existing invite flow; reuse it), and lands on the shared item with the granted access (Share or Collaborate, chosen by the owner, changeable later).
  • Several people can use one link until it expires; default expiry 7 days; at most 5 new accounts per link; the owner sees who joined and can revoke the link (revoking stops new joins; existing members keep access unless revoked individually).
  • Admin switch: Settings → Invitations, "Share links can invite new people" (on by default); when off, the tick is hidden.
  • Security: single-purpose tokens stored hashed, rate limits on join attempts, no account enumeration, the link only grants the one share; isolation matrix + adversarial cases (expired, revoked, over-limit, replay, link for a different item).
  • Copy the link with one tap (no email sending; app email §56 is OPEN).
    Build on the Share dialog issue's seam (coordinate: put the invite section behind one component prop). Two-browser e2e: owner creates a link on a note; a new person signs up via the link and lands on the note with Collaborate; 6th signup refused; revoke stops new joins. Screenshots of every state, 390/820/1440 light/dark.
## Owner (2026-10-04): invite links "very important — I am the only one using the app!" Contract: DESIGN §54 "Invite links". A tick "Invite people without an account" in the Share dialog creates an invite link for that share. - A person without an account opens the link, creates an account (passkey enrolment as in the existing invite flow; reuse it), and lands on the shared item with the granted access (Share or Collaborate, chosen by the owner, changeable later). - Several people can use one link until it expires; default expiry 7 days; at most 5 new accounts per link; the owner sees who joined and can revoke the link (revoking stops new joins; existing members keep access unless revoked individually). - Admin switch: Settings → Invitations, "Share links can invite new people" (on by default); when off, the tick is hidden. - Security: single-purpose tokens stored hashed, rate limits on join attempts, no account enumeration, the link only grants the one share; isolation matrix + adversarial cases (expired, revoked, over-limit, replay, link for a different item). - Copy the link with one tap (no email sending; app email §56 is OPEN). Build on the Share dialog issue's seam (coordinate: put the invite section behind one component prop). Two-browser e2e: owner creates a link on a note; a new person signs up via the link and lands on the note with Collaborate; 6th signup refused; revoke stops new joins. Screenshots of every state, 390/820/1440 light/dark.
Author
Owner

Started invite-1035 on job/invite-1035, base 85294fc72c (origin/dev). Reuse existing passkey enrolment and Files share grants; isolate the dialog section as InviteLinkSection with a path prop. No new dependencies planned. Verification follows the 2026-10-02 policy: per-crate gates, focused tests and feature browser evidence; full matrices reserved for merge round.

Started invite-1035 on job/invite-1035, base 85294fc72cf76a707ef30b2ba38d9c9da75afc57 (origin/dev). Reuse existing passkey enrolment and Files share grants; isolate the dialog section as InviteLinkSection with a path prop. No new dependencies planned. Verification follows the 2026-10-02 policy: per-crate gates, focused tests and feature browser evidence; full matrices reserved for merge round.
Author
Owner

Finding: the existing Notes route reads only the current User's Home (crates/plugins/notes/src/lib.rs:get_note); #1034 owns the recipient editor. This branch returns /n/<calternal-id> after enrolment and grants the existing Files item ID, so the combined merge must verify that #1034 resolves that grant and opens Collaborate. InviteLinkSection.svelte takes path, optional access and onchanged; ShareDialog mounts it behind inviteLinks (default true). No second dialog.

Security implementation: reused existing invite/passkey flow; hashed tokens only; seven-day default; five-account cap; BEGIN IMMEDIATE serializes completion with revocation; account + initial credential + item grant + use count share a transaction. Share invitations are excluded from the admin single-use invite list. Revocation preserves existing grants. Duplicate usernames return the same generic invalid request as other invalid signup input. The existing IP/token/username invite limit remains in use.

Decisions: new Users receive Guest Role and only one item grant. Changing a link's Share/Collaborate access updates its existing recipients' still-present grants; it does not restore individually revoked grants. A copied token stays only in component memory; reopening the dialog can create another link because the Index cannot recover token plaintext. Migration 0013 is free on fetched origin/dev. The migration sequence assertion must extend through 13 because this issue adds that migration; no other existing expectation changes.

Validation so far (verbatim):

svelte-check found 0 errors and 0 warnings
 Test Files  3 passed (3)
      Tests  7 passed (7)
Finding: the existing Notes route reads only the current User's Home (`crates/plugins/notes/src/lib.rs:get_note`); #1034 owns the recipient editor. This branch returns `/n/<calternal-id>` after enrolment and grants the existing Files item ID, so the combined merge must verify that #1034 resolves that grant and opens Collaborate. `InviteLinkSection.svelte` takes `path`, optional `access` and `onchanged`; ShareDialog mounts it behind `inviteLinks` (default true). No second dialog. Security implementation: reused existing invite/passkey flow; hashed tokens only; seven-day default; five-account cap; BEGIN IMMEDIATE serializes completion with revocation; account + initial credential + item grant + use count share a transaction. Share invitations are excluded from the admin single-use invite list. Revocation preserves existing grants. Duplicate usernames return the same generic invalid request as other invalid signup input. The existing IP/token/username invite limit remains in use. Decisions: new Users receive Guest Role and only one item grant. Changing a link's Share/Collaborate access updates its existing recipients' still-present grants; it does not restore individually revoked grants. A copied token stays only in component memory; reopening the dialog can create another link because the Index cannot recover token plaintext. Migration 0013 is free on fetched origin/dev. The migration sequence assertion must extend through 13 because this issue adds that migration; no other existing expectation changes. Validation so far (verbatim): ``` svelte-check found 0 errors and 0 warnings Test Files 3 passed (3) Tests 7 passed (7) ```
Author
Owner

Coordination finding: #1034's current ShareDialog seam is inviteSection?: Snippet<[{ path: string; name: string; dir: boolean }]>. I aligned this branch with that exact prop; the dialog uses InviteLinkSection by default and a supplied snippet can override it. #1034's recipient NoteView resolves incoming owner_id and joins the owner room, so the /n/<calternal-id> join destination matches its normal editor route.

Auth gates passed (verbatim):

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 2m 01s
test result: ok. 91 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 130.14s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

Commits: 56562f526 (web section and reused enrolment), 91c10410b (transactional auth and regression tests). Files/server gates are in progress. The Files check found a fixture writer-method typo and a collapsible-if lint; both are corrected, and its gates will be rerun.

Coordination finding: #1034's current ShareDialog seam is `inviteSection?: Snippet<[{ path: string; name: string; dir: boolean }]>`. I aligned this branch with that exact prop; the dialog uses InviteLinkSection by default and a supplied snippet can override it. #1034's recipient NoteView resolves incoming `owner_id` and joins the owner room, so the `/n/<calternal-id>` join destination matches its normal editor route. Auth gates passed (verbatim): ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 2m 01s test result: ok. 91 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 130.14s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` Commits: 56562f526 (web section and reused enrolment), 91c10410b (transactional auth and regression tests). Files/server gates are in progress. The Files check found a fixture writer-method typo and a collapsible-if lint; both are corrected, and its gates will be rerun.
Author
Owner

Browser finding: OverlaySurface remounts its content when switching between the phone sheet and desktop dialog. That discarded the creation-only invite token during a width change. ShareDialog now owns that memory-only value and binds it into InviteLinkSection; closing the dialog or changing items clears it. Late replies cannot copy an old item's token after navigation or sign-out. The production-build browser probe caught this while collecting the required 390/820/1440 views.

All crate suites passed (verbatim):

test result: ok. 91 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 130.14s
test result: ok. 159 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 183.32s
test result: ok. 163 passed; 0 failed; 6 ignored; 0 measured; 0 filtered out; finished in 15.86s

The focused WAL-concurrency test and all four invite auth regressions also passed. The typed client exposed two contract metadata errors (query location and the scalar bool's default text/plain content type); both now declare the real HTTP JSON contract. Generated parity reports 346 actions and zero adapter gaps. Focused web tests: 3 files / 8 tests passed. Browser evidence is still in progress.

Browser finding: OverlaySurface remounts its content when switching between the phone sheet and desktop dialog. That discarded the creation-only invite token during a width change. ShareDialog now owns that memory-only value and binds it into InviteLinkSection; closing the dialog or changing items clears it. Late replies cannot copy an old item's token after navigation or sign-out. The production-build browser probe caught this while collecting the required 390/820/1440 views. All crate suites passed (verbatim): ``` test result: ok. 91 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 130.14s test result: ok. 159 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 183.32s test result: ok. 163 passed; 0 failed; 6 ignored; 0 measured; 0 filtered out; finished in 15.86s ``` The focused WAL-concurrency test and all four invite auth regressions also passed. The typed client exposed two contract metadata errors (query location and the scalar bool's default text/plain content type); both now declare the real HTTP JSON contract. Generated parity reports 346 actions and zero adapter gaps. Focused web tests: 3 files / 8 tests passed. Browser evidence is still in progress.
Author
Owner

Final browser evidence passes in Chromium and WebKit. Owner controls change all five existing grants from Collaborate to Share, Undo restores Collaborate, touch Copy link announces success, the sixth enrolment is refused, recipient accounts cannot inspect or change the owner's invite link, and the admin policy hides the tick. The setting read now uses the account rate budget; a real middleware regression proves 30 policy reads leave all 20 invite attempts available. Review screenshots are being regenerated with credential masking before attachment.

Unresolved gate finding: the latest full calternal-auth suite failed at the unchanged app_password_revoke_rejects_queued_verification test, store.rs:4126, while calling revoke_app_password (Unavailable). A focused one-test rerun reproduces it in 0.93s. No assertion or fixture was changed. All four share_invites tests and the policy limiter regression pass. This is not being described as host slowness: the focused rerun also fails.

test result: FAILED. 91 passed; 1 failed; 1 ignored; 0 measured; 0 filtered out; finished in 66.64s
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 92 filtered out; finished in 0.93s
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 89 filtered out; finished in 1.28s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 92 filtered out; finished in 0.04s
Final browser evidence passes in Chromium and WebKit. Owner controls change all five existing grants from Collaborate to Share, Undo restores Collaborate, touch Copy link announces success, the sixth enrolment is refused, recipient accounts cannot inspect or change the owner's invite link, and the admin policy hides the tick. The setting read now uses the account rate budget; a real middleware regression proves 30 policy reads leave all 20 invite attempts available. Review screenshots are being regenerated with credential masking before attachment. Unresolved gate finding: the latest full calternal-auth suite failed at the unchanged app_password_revoke_rejects_queued_verification test, store.rs:4126, while calling revoke_app_password (Unavailable). A focused one-test rerun reproduces it in 0.93s. No assertion or fixture was changed. All four share_invites tests and the policy limiter regression pass. This is not being described as host slowness: the focused rerun also fails. ``` test result: FAILED. 91 passed; 1 failed; 1 ignored; 0 measured; 0 filtered out; finished in 66.64s test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 92 filtered out; finished in 0.93s test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 89 filtered out; finished in 1.28s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 92 filtered out; finished in 0.04s ```
Author
Owner

READY FOR MERGE: no

Built #1035 on job/invite-1035. Head: 051d25e98c4dd6c8a9d12a1555cb29a6138b6e9c. Base: 85294fc72cf76a707ef30b2ba38d9c9da75afc57; fetched and merged origin/dev once before gates (already up to date). No push or deploy. Atomic implementation, regression and generated-contract commits are on the branch. Auth migration 0013 was confirmed free on fetched origin/dev.

Implemented item-bound, hash-only Invite links using existing passkey enrolment. A link lasts seven days and admits at most five new Guest accounts. Account, passkey, initial item grant, join history and admission count commit together under BEGIN IMMEDIATE. Current item identity survives rename. Owner management supports joined-person history, Share/Collaborate changes and revocation; revocation preserves existing grants. The on-by-default admin policy needs fresh admin authority to change. The policy read uses the existing account rate budget, leaving the tighter join-attempt budget intact.

The mountable InviteLinkSection uses the exact #1034 inviteSection snippet seam. The join flow uses the existing recovery-key sequence, then navigates to the stable /n/<calternal-id> or /f/<item-id> destination. The typed client and all generated contracts are refreshed. Isolation policy, privileged denial recipes and real cross-User fixture coverage include the new routes.

UX gaps closed

  • Created links remain available when the responsive overlay switches between sheet and dialog; closing or changing the item clears the memory-only token. Late creation replies cannot copy an old item's token.
  • Phone controls stay within the sheet. Copy link has a 44 px touch target and uses the shared styled component.
  • Owner access changes update existing grants, with Undo. Revoke and create also have Undo. History refreshes after joining; real loading/error/retry states use the existing API adapter.
  • Browser tests activate the invite tick and recovery confirmation by keyboard, tap Copy link, change access, Undo, and revoke through owner controls. Recipient isolation and admin denial are checked against the real local server.

Evidence

Review archive: 66 production-build screenshots and gate logs. Phone 390, tablet 820 and desktop 1440; light/dark; macOS platform emulated. Includes empty/created invite dialog, passkey/recovery/done/full join states, joined/revoked history, admin policy and policy-off dialog. Chromium performs real virtual-passkey enrolment; WebKit verifies authenticated owner UI. Credentials are masked in attachments. Claude remains the visual reviewer. Build artifacts were removed; cargo clean reclaimed 9.5 GiB. Worktree is clean.

Gate output (verbatim summaries)

cargo fmt --check: exit 0, no output.

cargo clippy -p calternal-auth --all-targets -- -D warnings:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 06s

cargo test -p calternal-auth -- --test-threads=4:

test result: FAILED. 91 passed; 1 failed; 1 ignored; 0 measured; 0 filtered out; finished in 66.64s

The unchanged app_password_revoke_rejects_queued_verification fails at store.rs:4126: revoke_app_password(...).await.unwrap() receives Unavailable. Its focused one-test rerun also fails. No existing assertion or fixture was weakened.

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 92 filtered out; finished in 0.93s

Focused own regressions (share_invites and rate_limit_isolated_by_peer_ip):

test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 89 filtered out; finished in 1.28s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 92 filtered out; finished in 0.04s

cargo clippy -p calternal-plugin-files --all-targets -- -D warnings and cargo test -p calternal-plugin-files:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 24.81s
test result: ok. 159 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 183.32s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cargo clippy -p calternal-server --all-targets -- -D warnings and cargo test -p calternal-server:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 5m 16s
test result: ok. 163 passed; 0 failed; 6 ignored; 0 measured; 0 filtered out; finished in 15.86s

bun run check and focused Vitest (inviteLinks, auth/routes, auth/passkeys; maxWorkers=2):

svelte-check found 0 errors and 0 warnings
 Test Files  3 passed (3)
      Tests  8 passed (8)

bun e2e/invite-1035.mjs:

invite-1035: 5 Guests granted one item; sixth refused; revocation preserves grants; policy hides invite tick; Chromium + WebKit evidence captured

Registry tests: 12 passed; admin-classification tests: 14 passed; cross-User classification tests: 8 passed. Offline matrix and parity output:

Cross-User classification gate: 348 operations classified
Generated entry point classification: 984 tools classified
Admin coverage: 40 reviewed operations; contract and Rust guards agree
Parity matrix: 346 API actions, 126 shortcuts, 2 static commands, 140 menu actions, 51 settings groups, 0 actions with adapter gaps

Known gaps / UX gaps left

  • The recipient's normal shared Note editor belongs to parallel #1034. This branch verifies the stable destination and exact grant; the combined branch must verify render, actual Collaborate editing and persistence. --notes now requires a recipient edit to appear in the owner's Note and survive recipient reload. That optional integration branch has not been executed here.
  • Full Auth gate is red at the existing queued app-password test and its focused rerun. Resolve that gate before merge; do not classify it as host slowness without evidence.
  • Joined-person updates reach an open visible dialog within five seconds via a bounded poll. Auth enrolment does not yet emit Files' in-memory invalidation. History reads are capped at the newest 100 links.
  • Performance profile is added, but no measurements were run: the latest verification policy allows perf runs only for performance issues. No baseline comparison is claimed.

Decisions

DESIGN does not assign a Role to item invitees: use Guest for least authority. Share/Collaborate updates affect still-existing grants for this invited item; they never recreate individually removed grants. Return plaintext tokens only at creation and keep them in dialog memory; reopening requires a new invite link to obtain a copyable token. The five admission slots remain consumed if a joined User is deleted. Use a five-second visible-dialog poll as the interim Auth-to-Files history bridge. Existing account traffic handles policy reads rather than spending invite attempts. Added Tower 0.5.3 as a test-only dependency to exercise the real middleware (verified with cargo search; MIT-compatible).

For the merge round

  • Resolve the queued app-password test, then cargo test -p calternal-auth -- --test-threads=4 must be green.
  • With combined #1034/#1035 server and production web build: cd apps/web && bun e2e/invite-1035.mjs --notes. Must prove invited Collaborate access edits the normal Note and persists into the owner's content and across reload.
  • cd apps/web && bun run test -- --maxWorkers=2; full web suite, plus bun run test:e2e and bun run test:e2e:auth for shell and enrolment integration.
  • tests/adversarial/run-split.sh: run the complete authz, cross-User and hostile-input round on the combined branch. Own focused coverage already exercises expiry/revocation/policy/replay/last-slot concurrency and owner/recipient isolation.

Files

Cargo.lock
apps/web/e2e/invite-1035.mjs
apps/web/src/lib/auth/components/CreateAccountFlow.svelte
apps/web/src/lib/auth/passkeys.ts
apps/web/src/lib/files/InviteLinkSection.svelte
apps/web/src/lib/files/ShareDialog.svelte
apps/web/src/lib/files/inviteLinks.test.ts
apps/web/src/lib/files/inviteLinks.ts
apps/web/src/routes/settings/admin/InvitationsGroup.svelte
bench/invite-1035.py
contracts/actions.json
contracts/openapi.json
crates/calternal-auth/Cargo.toml
crates/calternal-auth/migrations/0013_share_invites.sql
crates/calternal-auth/src/api.rs
crates/calternal-auth/src/lib.rs
crates/calternal-auth/src/store.rs
crates/calternal-server/src/wire.rs
crates/plugins/files/src/invite_links.rs
crates/plugins/files/src/lib.rs
docs/parity-matrix.md
packages/api-client/src/generated.ts
scripts/action_registry.py
tests/adversarial/authz_matrix.py
tests/adversarial/xuser_matrix.py
tests/parity/admin-denial.json
READY FOR MERGE: no Built #1035 on `job/invite-1035`. Head: `051d25e98c4dd6c8a9d12a1555cb29a6138b6e9c`. Base: `85294fc72cf76a707ef30b2ba38d9c9da75afc57`; fetched and merged origin/dev once before gates (already up to date). No push or deploy. Atomic implementation, regression and generated-contract commits are on the branch. Auth migration 0013 was confirmed free on fetched origin/dev. Implemented item-bound, hash-only Invite links using existing passkey enrolment. A link lasts seven days and admits at most five new Guest accounts. Account, passkey, initial item grant, join history and admission count commit together under BEGIN IMMEDIATE. Current item identity survives rename. Owner management supports joined-person history, Share/Collaborate changes and revocation; revocation preserves existing grants. The on-by-default admin policy needs fresh admin authority to change. The policy read uses the existing account rate budget, leaving the tighter join-attempt budget intact. The mountable InviteLinkSection uses the exact #1034 `inviteSection` snippet seam. The join flow uses the existing recovery-key sequence, then navigates to the stable `/n/<calternal-id>` or `/f/<item-id>` destination. The typed client and all generated contracts are refreshed. Isolation policy, privileged denial recipes and real cross-User fixture coverage include the new routes. **UX gaps closed** - Created links remain available when the responsive overlay switches between sheet and dialog; closing or changing the item clears the memory-only token. Late creation replies cannot copy an old item's token. - Phone controls stay within the sheet. Copy link has a 44 px touch target and uses the shared styled component. - Owner access changes update existing grants, with Undo. Revoke and create also have Undo. History refreshes after joining; real loading/error/retry states use the existing API adapter. - Browser tests activate the invite tick and recovery confirmation by keyboard, tap Copy link, change access, Undo, and revoke through owner controls. Recipient isolation and admin denial are checked against the real local server. **Evidence** [Review archive: 66 production-build screenshots and gate logs](https://git.kayg.org/attachments/b58c58f4-e6e0-4ea8-8347-fd31a4c12dc0). Phone 390, tablet 820 and desktop 1440; light/dark; macOS platform emulated. Includes empty/created invite dialog, passkey/recovery/done/full join states, joined/revoked history, admin policy and policy-off dialog. Chromium performs real virtual-passkey enrolment; WebKit verifies authenticated owner UI. Credentials are masked in attachments. Claude remains the visual reviewer. Build artifacts were removed; `cargo clean` reclaimed 9.5 GiB. Worktree is clean. **Gate output (verbatim summaries)** `cargo fmt --check`: exit 0, no output. `cargo clippy -p calternal-auth --all-targets -- -D warnings`: ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 06s ``` `cargo test -p calternal-auth -- --test-threads=4`: ``` test result: FAILED. 91 passed; 1 failed; 1 ignored; 0 measured; 0 filtered out; finished in 66.64s ``` The unchanged `app_password_revoke_rejects_queued_verification` fails at store.rs:4126: `revoke_app_password(...).await.unwrap()` receives `Unavailable`. Its focused one-test rerun also fails. No existing assertion or fixture was weakened. ``` test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 92 filtered out; finished in 0.93s ``` Focused own regressions (`share_invites` and `rate_limit_isolated_by_peer_ip`): ``` test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 89 filtered out; finished in 1.28s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 92 filtered out; finished in 0.04s ``` `cargo clippy -p calternal-plugin-files --all-targets -- -D warnings` and `cargo test -p calternal-plugin-files`: ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 24.81s test result: ok. 159 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 183.32s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `cargo clippy -p calternal-server --all-targets -- -D warnings` and `cargo test -p calternal-server`: ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 5m 16s test result: ok. 163 passed; 0 failed; 6 ignored; 0 measured; 0 filtered out; finished in 15.86s ``` `bun run check` and focused Vitest (inviteLinks, auth/routes, auth/passkeys; maxWorkers=2): ``` svelte-check found 0 errors and 0 warnings Test Files 3 passed (3) Tests 8 passed (8) ``` `bun e2e/invite-1035.mjs`: ``` invite-1035: 5 Guests granted one item; sixth refused; revocation preserves grants; policy hides invite tick; Chromium + WebKit evidence captured ``` Registry tests: 12 passed; admin-classification tests: 14 passed; cross-User classification tests: 8 passed. Offline matrix and parity output: ``` Cross-User classification gate: 348 operations classified Generated entry point classification: 984 tools classified Admin coverage: 40 reviewed operations; contract and Rust guards agree Parity matrix: 346 API actions, 126 shortcuts, 2 static commands, 140 menu actions, 51 settings groups, 0 actions with adapter gaps ``` **Known gaps / UX gaps left** - The recipient's normal shared Note editor belongs to parallel #1034. This branch verifies the stable destination and exact grant; the combined branch must verify render, actual Collaborate editing and persistence. `--notes` now requires a recipient edit to appear in the owner's Note and survive recipient reload. That optional integration branch has not been executed here. - Full Auth gate is red at the existing queued app-password test and its focused rerun. Resolve that gate before merge; do not classify it as host slowness without evidence. - Joined-person updates reach an open visible dialog within five seconds via a bounded poll. Auth enrolment does not yet emit Files' in-memory invalidation. History reads are capped at the newest 100 links. - Performance profile is added, but no measurements were run: the latest verification policy allows perf runs only for performance issues. No baseline comparison is claimed. **Decisions** DESIGN does not assign a Role to item invitees: use Guest for least authority. Share/Collaborate updates affect still-existing grants for this invited item; they never recreate individually removed grants. Return plaintext tokens only at creation and keep them in dialog memory; reopening requires a new invite link to obtain a copyable token. The five admission slots remain consumed if a joined User is deleted. Use a five-second visible-dialog poll as the interim Auth-to-Files history bridge. Existing account traffic handles policy reads rather than spending invite attempts. Added Tower 0.5.3 as a test-only dependency to exercise the real middleware (verified with cargo search; MIT-compatible). **For the merge round** - Resolve the queued app-password test, then `cargo test -p calternal-auth -- --test-threads=4` must be green. - With combined #1034/#1035 server and production web build: `cd apps/web && bun e2e/invite-1035.mjs --notes`. Must prove invited Collaborate access edits the normal Note and persists into the owner's content and across reload. - `cd apps/web && bun run test -- --maxWorkers=2`; full web suite, plus `bun run test:e2e` and `bun run test:e2e:auth` for shell and enrolment integration. - `tests/adversarial/run-split.sh`: run the complete authz, cross-User and hostile-input round on the combined branch. Own focused coverage already exercises expiry/revocation/policy/replay/last-slot concurrency and owner/recipient isolation. **Files** ``` Cargo.lock apps/web/e2e/invite-1035.mjs apps/web/src/lib/auth/components/CreateAccountFlow.svelte apps/web/src/lib/auth/passkeys.ts apps/web/src/lib/files/InviteLinkSection.svelte apps/web/src/lib/files/ShareDialog.svelte apps/web/src/lib/files/inviteLinks.test.ts apps/web/src/lib/files/inviteLinks.ts apps/web/src/routes/settings/admin/InvitationsGroup.svelte bench/invite-1035.py contracts/actions.json contracts/openapi.json crates/calternal-auth/Cargo.toml crates/calternal-auth/migrations/0013_share_invites.sql crates/calternal-auth/src/api.rs crates/calternal-auth/src/lib.rs crates/calternal-auth/src/store.rs crates/calternal-server/src/wire.rs crates/plugins/files/src/invite_links.rs crates/plugins/files/src/lib.rs docs/parity-matrix.md packages/api-client/src/generated.ts scripts/action_registry.py tests/adversarial/authz_matrix.py tests/adversarial/xuser_matrix.py tests/parity/admin-denial.json ```
Author
Owner

Orchestrator review: backend, join flow (passkey, recovery key, done screen) approved from the screenshots. The red Auth test app_password_revoke_rejects_queued_verification fails on dev too; filed as #1041 with its own fix job, so it does not block this branch.

The Share-dialog section gets reviewed inside the unified #1034 dialog. Issues seen in chromium-created-1440: the title appears twice (sheet header plus dialog title), the raw .md filename shows, the PEOPLE copy says "Invite people from Settings" right above the invite toggle, Revoke is a full-width button, and the copy toast overlaps Revoke. These get fixed when the two branches combine.

Orchestrator review: backend, join flow (passkey, recovery key, done screen) approved from the screenshots. The red Auth test `app_password_revoke_rejects_queued_verification` fails on dev too; filed as #1041 with its own fix job, so it does not block this branch. The Share-dialog section gets reviewed inside the unified #1034 dialog. Issues seen in chromium-created-1440: the title appears twice (sheet header plus dialog title), the raw `.md` filename shows, the PEOPLE copy says "Invite people from Settings" right above the invite toggle, Revoke is a full-width button, and the copy toast overlaps Revoke. These get fixed when the two branches combine.
Author
Owner

Integrated approved head 051d25e98 into job/share-1034 at 7cd8d8c64. The default InviteLinkSection is mounted in the unified dialog through inviteSection; its memory-only creation token remains owned by the dialog. f1f36613c aligns the phone header with content, presents item titles without transport suffixes, replaces the stale Settings empty-state copy with the invite-link path, and keeps Revoke compact. Auth on the combined origin/dev base passes:

test result: ok. 96 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 96.25s

Recipient names now refresh after joins, rather than retaining the old session list. Full web suite passes:

 Test Files  162 passed (162)
      Tests  1130 passed (1130)

Running the production bun e2e/invite-1035.mjs --notes acceptance and full sharing screenshot set; final integration report follows on both issues.

Integrated approved head 051d25e98 into job/share-1034 at 7cd8d8c64. The default InviteLinkSection is mounted in the unified dialog through inviteSection; its memory-only creation token remains owned by the dialog. f1f36613c aligns the phone header with content, presents item titles without transport suffixes, replaces the stale Settings empty-state copy with the invite-link path, and keeps Revoke compact. Auth on the combined origin/dev base passes: ``` test result: ok. 96 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 96.25s ``` Recipient names now refresh after joins, rather than retaining the old session list. Full web suite passes: ``` Test Files 162 passed (162) Tests 1130 passed (1130) ``` Running the production `bun e2e/invite-1035.mjs --notes` acceptance and full sharing screenshot set; final integration report follows on both issues.
Author
Owner

Integration finding: #1035's unchanged --notes fixture uses the imported calternal-id invite-note-1035. Notes path_for_id accepts that exact ID, and invite_links correctly returns its stable /n/ destination. #1034 shared_note alone required Uuid::parse_str, so that valid imported Note could not open for its recipient. Removed the UUID-only subset: the parameter remains a bound SQL identity lookup, with unchanged live grant and filesystem identity checks. Added shared_imported_note_identity_opens_and_revokes to prove authorized imported content, unknown-ID 404 and revoke 404. No existing assertion or fixture was changed. Gates and acceptance are running against the combined implementation.

Integration finding: #1035's unchanged --notes fixture uses the imported calternal-id `invite-note-1035`. Notes path_for_id accepts that exact ID, and invite_links correctly returns its stable /n/ destination. #1034 shared_note alone required Uuid::parse_str, so that valid imported Note could not open for its recipient. Removed the UUID-only subset: the parameter remains a bound SQL identity lookup, with unchanged live grant and filesystem identity checks. Added shared_imported_note_identity_opens_and_revokes to prove authorized imported content, unknown-ID 404 and revoke 404. No existing assertion or fixture was changed. Gates and acceptance are running against the combined implementation.
Author
Owner

Combined #1034/#1035 integration report. The approved invite section is mounted; --notes recipient editing and persistence passed. Imported Note identity rejection is fixed with a regression.

READY FOR MERGE: yes (SLOW-only gate exception below; screenshots attached for Claude's visual review).

Head: 9016bfae6631d5dc9f382c2c2ac0910bb8a9589e on job/share-1034. No push, deploy or merge to dev/main.

Built:

  • Merged origin/dev and approved job/invite-1035. Preserved #1036 Home image uploads and pending decorations outside Y.js history. Mounted invites in the unified Share dialog.
  • Public Notes use the existing read-only Note editor and shared prose styles. Headings, lists and links render; frontmatter, file cards, byte sizes and Preview are absent. Private references use styled neutral labels. Download Markdown remains a secondary action when allowed. Long Notes scroll without clipping.
  • User/Group search with keyboard selection, one Share/Collaborate control and one Add access button. Current access changes and removal keep Undo. Invite joins and dialog reopen refresh names. Empty instances point to the inline invite section.
  • Shared rows show Note title, from-name, access and original grant date; no internal paths. The grant date survives access changes. Phone header and content insets match. Note titles resolve from the Note Index even when opened through Files; Files/Photos omit the transport suffix.
  • Fixed an integration defect: valid imported Note identities such as invite-note-1035 were rejected as non-UUID. Bound identity lookup and live grant checks remain the authority. Added a read/revoke regression; unknown identities stay 404.

Files:
apps/web/src/lib/files/{ShareDialog,RecipientPicker,InviteLinkSection,PublicLinkPage}.svelte, RecipientPicker.svelte.test.ts, api.ts, api.test.ts, sharing.svelte.ts; apps/web/src/lib/notes/{NoteEditorSurface.svelte,noteProse.css,api.ts}; apps/web/src/lib/components/NoteList.svelte; apps/web/src/routes/notes/+page.svelte; apps/web/e2e/share-1034.mjs; crates/plugins/files/src/{lib.rs,shares.rs}; contracts/openapi.json; packages/api-client/src/generated.ts. Merge resolution also retained both behaviors in NoteImageView.svelte and editorHost.ts and the approved Auth/invite flow.

Evidence:

  • 66 sharing screenshots + raw gate logs. Includes person chosen, two Users + Group, Files/Photos/folders, public Notes and Shared list.
  • 72 invite screenshots + raw gate logs. Includes the empty instance with the unified invite section, join steps and recipient editing after reload. Chromium and WebKit evidence.
  • Both sets cover 390/820/1440 px, light/dark and macOS platform rendering. Test data exists only in real local test servers. No artifacts committed.
  • Ran bun e2e/share-1034.mjs and bun e2e/invite-1035.mjs --notes against the production web build. Acceptance checked read-only access, denied raw collaboration socket, live edits, revocation, folder inheritance, private-reference redaction, invite exhaustion, recipient persistence, policy and Undo. No requested acceptance checks deferred.

Gate output (verbatim summaries; complete output in the archives):
cargo fmt --check: exit 0, no output.

cargo clippy -p calternal-auth --all-targets -- -D warnings

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 32s

cargo test -p calternal-auth

test result: ok. 96 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 96.25s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cargo clippy -p calternal-plugin-files --all-targets -- -D warnings

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 19.99s

cargo test -p calternal-plugin-files

test result: FAILED. 162 passed; 1 failed; 1 ignored; 0 measured; 0 filtered out; finished in 346.03s

cargo test -p calternal-plugin-files internal_temp_paths_never_enter_index_during_atomic_write_reconcile_storm

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 163 filtered out; finished in 112.15s

cargo test -p calternal-plugin-files shared_imported_note_identity_opens_and_revokes

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 163 filtered out; finished in 0.56s

cargo clippy -p calternal-server --all-targets -- -D warnings

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 57s

cargo test -p calternal-server

test result: ok. 164 passed; 0 failed; 6 ignored; 0 measured; 0 filtered out; finished in 32.13s

bun run check

svelte-check found 0 errors and 0 warnings

bun run test -- --maxWorkers=2

 Test Files  162 passed (162)
      Tests  1130 passed (1130)

focused Files API / recipient picker Vitest

 Test Files  2 passed (2)
      Tests  13 passed (13)

bun e2e/share-1034.mjs

PASS #1034: two-User Share → Collaborate → revoke, recursive folder, public Note and 60 macOS screenshots

bun e2e/invite-1035.mjs --notes

invite-1035: 5 Guests granted one item; sixth refused; revocation preserves grants; policy hides invite tick; Chromium + WebKit evidence captured

The Share script's printed count was stale (60); the archive contains 66 PNGs. Corrected the count in the final test commit without rerunning acceptance for a log-only edit. The final commit after that adds a module doc comment only.

Known gaps:

  • The full Files suite hit its existing five-minute reconciliation-storm deadline. Primary output: writes, reconcile scans, and watcher adoption complete within five minutes: Elapsed(()). The subsequent atomic write 692 failed: entry not found occurred after the timeout removed the temporary test directory. The unchanged focused test passed in 112.15s. No timeout, fixture or assertion was weakened. Treat this as SLOW-only under the job rule; the full suite is not reported green.
  • Visual approval belongs to Claude; the complete replacement evidence is attached.

UX gaps closed: formatted public reading; searchable recipients; duplicate Share controls; empty-instance invite route; stale joined names; inline access/Undo; path-free Shared metadata; phone header inset; file suffixes in dialog titles; imported-identity join/editor persistence; duplicate public title; list markers and long-Note clipping.
UX gaps left: none found in the requested send-back flow.

Decisions:

  • Reuse the existing Note editor and extract its prose CSS rather than maintain a separate public renderer.
  • Show the original grant date, preserving it when access changes. For inherited access use the matching live grant, preferring Collaborate.
  • Files and Photos have no separate title field in their current entry model; use their visible name stem. Notes always use their actual title.
  • Refresh cached people on dialog open and invite changes; retain ordinary cached reads.

For the merge round: no requested acceptance work deferred. Run the combined branch gates and visual review under the normal merge-round policy. Performance measurements were not run: this is not a performance issue, as required by the latest verification policy. Existing shared-notes-1034 and invite-1035 bench profiles remain available.

Re-read touched module comments. cargo clean removed 9.4 GiB; deleted production web build output after acceptance. Working tree clean. Atomic code/test commits are in branch history.

Combined #1034/#1035 integration report. The approved invite section is mounted; `--notes` recipient editing and persistence passed. Imported Note identity rejection is fixed with a regression. READY FOR MERGE: yes (SLOW-only gate exception below; screenshots attached for Claude's visual review). Head: `9016bfae6631d5dc9f382c2c2ac0910bb8a9589e` on `job/share-1034`. No push, deploy or merge to dev/main. Built: - Merged origin/dev and approved job/invite-1035. Preserved #1036 Home image uploads and pending decorations outside Y.js history. Mounted invites in the unified Share dialog. - Public Notes use the existing read-only Note editor and shared prose styles. Headings, lists and links render; frontmatter, file cards, byte sizes and Preview are absent. Private references use styled neutral labels. Download Markdown remains a secondary action when allowed. Long Notes scroll without clipping. - User/Group search with keyboard selection, one Share/Collaborate control and one Add access button. Current access changes and removal keep Undo. Invite joins and dialog reopen refresh names. Empty instances point to the inline invite section. - Shared rows show Note title, from-name, access and original grant date; no internal paths. The grant date survives access changes. Phone header and content insets match. Note titles resolve from the Note Index even when opened through Files; Files/Photos omit the transport suffix. - Fixed an integration defect: valid imported Note identities such as `invite-note-1035` were rejected as non-UUID. Bound identity lookup and live grant checks remain the authority. Added a read/revoke regression; unknown identities stay 404. Files: `apps/web/src/lib/files/{ShareDialog,RecipientPicker,InviteLinkSection,PublicLinkPage}.svelte`, `RecipientPicker.svelte.test.ts`, `api.ts`, `api.test.ts`, `sharing.svelte.ts`; `apps/web/src/lib/notes/{NoteEditorSurface.svelte,noteProse.css,api.ts}`; `apps/web/src/lib/components/NoteList.svelte`; `apps/web/src/routes/notes/+page.svelte`; `apps/web/e2e/share-1034.mjs`; `crates/plugins/files/src/{lib.rs,shares.rs}`; `contracts/openapi.json`; `packages/api-client/src/generated.ts`. Merge resolution also retained both behaviors in `NoteImageView.svelte` and `editorHost.ts` and the approved Auth/invite flow. Evidence: - [66 sharing screenshots + raw gate logs](https://git.kayg.org/attachments/11e3c1a9-d2d5-431b-bf8c-71e1b512d5ad). Includes person chosen, two Users + Group, Files/Photos/folders, public Notes and Shared list. - [72 invite screenshots + raw gate logs](https://git.kayg.org/attachments/0739b321-6a09-4a8f-ac03-1ee311738e88). Includes the empty instance with the unified invite section, join steps and recipient editing after reload. Chromium and WebKit evidence. - Both sets cover 390/820/1440 px, light/dark and macOS platform rendering. Test data exists only in real local test servers. No artifacts committed. - Ran `bun e2e/share-1034.mjs` and `bun e2e/invite-1035.mjs --notes` against the production web build. Acceptance checked read-only access, denied raw collaboration socket, live edits, revocation, folder inheritance, private-reference redaction, invite exhaustion, recipient persistence, policy and Undo. No requested acceptance checks deferred. Gate output (verbatim summaries; complete output in the archives): `cargo fmt --check`: exit 0, no output. `cargo clippy -p calternal-auth --all-targets -- -D warnings` ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 32s ``` `cargo test -p calternal-auth` ``` test result: ok. 96 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 96.25s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `cargo clippy -p calternal-plugin-files --all-targets -- -D warnings` ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 19.99s ``` `cargo test -p calternal-plugin-files` ``` test result: FAILED. 162 passed; 1 failed; 1 ignored; 0 measured; 0 filtered out; finished in 346.03s ``` `cargo test -p calternal-plugin-files internal_temp_paths_never_enter_index_during_atomic_write_reconcile_storm` ``` test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 163 filtered out; finished in 112.15s ``` `cargo test -p calternal-plugin-files shared_imported_note_identity_opens_and_revokes` ``` test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 163 filtered out; finished in 0.56s ``` `cargo clippy -p calternal-server --all-targets -- -D warnings` ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 57s ``` `cargo test -p calternal-server` ``` test result: ok. 164 passed; 0 failed; 6 ignored; 0 measured; 0 filtered out; finished in 32.13s ``` `bun run check` ``` svelte-check found 0 errors and 0 warnings ``` `bun run test -- --maxWorkers=2` ``` Test Files 162 passed (162) Tests 1130 passed (1130) ``` `focused Files API / recipient picker Vitest` ``` Test Files 2 passed (2) Tests 13 passed (13) ``` `bun e2e/share-1034.mjs` ``` PASS #1034: two-User Share → Collaborate → revoke, recursive folder, public Note and 60 macOS screenshots ``` `bun e2e/invite-1035.mjs --notes` ``` invite-1035: 5 Guests granted one item; sixth refused; revocation preserves grants; policy hides invite tick; Chromium + WebKit evidence captured ``` The Share script's printed count was stale (60); the archive contains 66 PNGs. Corrected the count in the final test commit without rerunning acceptance for a log-only edit. The final commit after that adds a module doc comment only. Known gaps: - The full Files suite hit its existing five-minute reconciliation-storm deadline. Primary output: `writes, reconcile scans, and watcher adoption complete within five minutes: Elapsed(())`. The subsequent `atomic write 692 failed: entry not found` occurred after the timeout removed the temporary test directory. The unchanged focused test passed in 112.15s. No timeout, fixture or assertion was weakened. Treat this as SLOW-only under the job rule; the full suite is not reported green. - Visual approval belongs to Claude; the complete replacement evidence is attached. UX gaps closed: formatted public reading; searchable recipients; duplicate Share controls; empty-instance invite route; stale joined names; inline access/Undo; path-free Shared metadata; phone header inset; file suffixes in dialog titles; imported-identity join/editor persistence; duplicate public title; list markers and long-Note clipping. UX gaps left: none found in the requested send-back flow. Decisions: - Reuse the existing Note editor and extract its prose CSS rather than maintain a separate public renderer. - Show the original grant date, preserving it when access changes. For inherited access use the matching live grant, preferring Collaborate. - Files and Photos have no separate title field in their current entry model; use their visible name stem. Notes always use their actual title. - Refresh cached people on dialog open and invite changes; retain ordinary cached reads. For the merge round: no requested acceptance work deferred. Run the combined branch gates and visual review under the normal merge-round policy. Performance measurements were not run: this is not a performance issue, as required by the latest verification policy. Existing shared-notes-1034 and invite-1035 bench profiles remain available. Re-read touched module comments. `cargo clean` removed 9.4 GiB; deleted production web build output after acceptance. Working tree clean. Atomic code/test commits are in branch history.
Author
Owner

Merge round 7b5 starts on job/7b-reconcile, base a1f3a0797. Assemble the requested Photo probe fixes and Month Task guards, upload recovery #1051, and Share/Groups/invite links. Preserve the 7b migrations and move new sharing migrations after them. Regenerate contracts, run per-crate gates for all crates and the requested web/editor/share/invite flows. No adversarial matrix, push or deploy.

Merge round 7b5 starts on `job/7b-reconcile`, base `a1f3a0797`. Assemble the requested Photo probe fixes and Month Task guards, upload recovery #1051, and Share/Groups/invite links. Preserve the 7b migrations and move new sharing migrations after them. Regenerate contracts, run per-crate gates for all crates and the requested web/editor/share/invite flows. No adversarial matrix, push or deploy.
Author
Owner

7b5 integration findings (#867, #1034, #1035):

  • Sharing used NORMAL for Group and invite Security state writes. Use FULL authority, with BEGIN IMMEDIATE for read/change transactions. Preserve 7b grant durability.
  • Stored Group grants can have no current Users. Move/delete operations must update files_grants, not the expanded files_shares read view.
  • Incoming Note reads must not enter the owned revision or transport cache. A new regression checks editor → viewer → revoke on repeated reads. It passes 10/10 Note cache tests.
  • Retired public edits removed fields and helpers now needed by 7b public-read race guards. Keep stable item ID, password snapshot and trusted IP for current read checks. Retain denial-only public edit routes.
  • Preserve the full 7b Card, Contents, native link focus, Task Note and pending-edit behavior while adding Share to the same header actions.
  • Migration numbering: db 0015_groups; Files 0023_public_links_view_only and 0024_group_grants; Auth 0013_share_invites. Production 6074f71d1 and c39ffe5d9 have no migration-file differences. The upgrade test pins both 7b and sharing versions and keeps all prior receipts.
  • tower 0.5.3 is verified with cargo search. No third-party dependency version is changed.

No adversarial matrix, push or deploy. Gates remain in progress.

7b5 integration findings (#867, #1034, #1035): - Sharing used NORMAL for Group and invite Security state writes. Use FULL authority, with BEGIN IMMEDIATE for read/change transactions. Preserve 7b grant durability. - Stored Group grants can have no current Users. Move/delete operations must update files_grants, not the expanded files_shares read view. - Incoming Note reads must not enter the owned revision or transport cache. A new regression checks editor → viewer → revoke on repeated reads. It passes 10/10 Note cache tests. - Retired public edits removed fields and helpers now needed by 7b public-read race guards. Keep stable item ID, password snapshot and trusted IP for current read checks. Retain denial-only public edit routes. - Preserve the full 7b Card, Contents, native link focus, Task Note and pending-edit behavior while adding Share to the same header actions. - Migration numbering: db 0015_groups; Files 0023_public_links_view_only and 0024_group_grants; Auth 0013_share_invites. Production 6074f71d1 and c39ffe5d9 have no migration-file differences. The upgrade test pins both 7b and sharing versions and keeps all prior receipts. - tower 0.5.3 is verified with cargo search. No third-party dependency version is changed. No adversarial matrix, push or deploy. Gates remain in progress.
Author
Owner

#867 integration finding: fresh sharing server startup fails with cannot create AFTER trigger on view: files_shares. The schema upgrade alone passed because it did not install the app change bridge. The fix attaches grant triggers to files_grants, expands Group members, refreshes pre-sharing trigger definitions on startup, and invalidates User epochs when Group membership or active state changes. The production upgrade regression now installs the bridge twice and checks a Group grant revoke/member removal without a Group-keyed journal head. Focused gates are compiling.

Generated OpenAPI/actions/client and seven new Group admin-denial fixtures are committed as 58d1951ae. Action-registry unit tests: Ran 27 tests in 1.966s / OK.

Decision for review: sharing has no performance adoption metadata. The initial combined-release coverage ledger records 19,340 exact, expiring sites (previous 19,139: 451 removed, 652 new). Absent budgets, bounds, readiness and tests remain absent, not invented passing contracts. No access/session/accessibility waiver is added. origin/dev has no ratchet; this is the initial release baseline. This is a net increase of 201 adoption gaps and remains an explicit known gap; future ratchet checks retain their existing non-growth rule. Perf measurement is not run because this issue is release verification, not a performance issue.

#867 integration finding: fresh sharing server startup fails with `cannot create AFTER trigger on view: files_shares`. The schema upgrade alone passed because it did not install the app change bridge. The fix attaches grant triggers to `files_grants`, expands Group members, refreshes pre-sharing trigger definitions on startup, and invalidates User epochs when Group membership or active state changes. The production upgrade regression now installs the bridge twice and checks a Group grant revoke/member removal without a Group-keyed journal head. Focused gates are compiling. Generated OpenAPI/actions/client and seven new Group admin-denial fixtures are committed as 58d1951ae. Action-registry unit tests: `Ran 27 tests in 1.966s` / `OK`. Decision for review: sharing has no performance adoption metadata. The initial combined-release coverage ledger records 19,340 exact, expiring sites (previous 19,139: 451 removed, 652 new). Absent budgets, bounds, readiness and tests remain absent, not invented passing contracts. No access/session/accessibility waiver is added. origin/dev has no ratchet; this is the initial release baseline. This is a net increase of 201 adoption gaps and remains an explicit known gap; future ratchet checks retain their existing non-growth rule. Perf measurement is not run because this issue is release verification, not a performance issue.
Author
Owner

The final schema + bridge regression passes: test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 217 filtered out; finished in 1.19s. Commit 33855fd58 also closes the shared-reading accessibility and shared focus-token gaps. The full web suite passes: Test Files 222 passed (222) / Tests 1510 passed (1510); Svelte reports svelte-check found 0 errors and 4 warnings in 3 files.

Browser findings to retain for review (no existing assertion changed):

  • bun e2e/share-1034.mjs passes its two-User share/collaborate/revoke and recursive-grant assertions, then stops during File inspector screenshots. It expects the dialog name Info; the existing 7b FilesBrowser uses the selected item's name (Review.txt) for its Inspector. Changing the existing title to satisfy the older expectation would undo 7b's Inspector contract.
  • bun e2e/invite-1035.mjs --notes creates and enrols the invite recipient, then expects **/notes/invite-note-1035. The actual navigation is https://localhost:<port>/n/invite-note-1035, the canonical stable Note route in DESIGN §33. The owner rule forbids changing a wrong existing expectation without an explicit behavior change. Both expectations remain for the orchestrator's decision. These failures stop the remaining requested acceptance steps and screenshot sets; they are not claimed as passed.

Per-crate Rust gates continue. No adversarial matrix ran. Current staging readiness remains no until the full acceptance flows complete.

The final schema + bridge regression passes: `test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 217 filtered out; finished in 1.19s`. Commit 33855fd58 also closes the shared-reading accessibility and shared focus-token gaps. The full web suite passes: `Test Files 222 passed (222)` / `Tests 1510 passed (1510)`; Svelte reports `svelte-check found 0 errors and 4 warnings in 3 files`. Browser findings to retain for review (no existing assertion changed): - `bun e2e/share-1034.mjs` passes its two-User share/collaborate/revoke and recursive-grant assertions, then stops during File inspector screenshots. It expects the dialog name `Info`; the existing 7b FilesBrowser uses the selected item's name (`Review.txt`) for its Inspector. Changing the existing title to satisfy the older expectation would undo 7b's Inspector contract. - `bun e2e/invite-1035.mjs --notes` creates and enrols the invite recipient, then expects `**/notes/invite-note-1035`. The actual navigation is `https://localhost:<port>/n/invite-note-1035`, the canonical stable Note route in DESIGN §33. The owner rule forbids changing a wrong existing expectation without an explicit behavior change. Both expectations remain for the orchestrator's decision. These failures stop the remaining requested acceptance steps and screenshot sets; they are not claimed as passed. Per-crate Rust gates continue. No adversarial matrix ran. Current staging readiness remains no until the full acceptance flows complete.
Author
Owner

Fixed a real UX consistency gap in incoming Notes: a revoked route removed its body and its Files subscription, so a later restored grant left that open view missing. The view now retains only its route/owner identity after revoke. A later Files event performs another authorized read and restores the current access mode. Session end clears that identity. The new #1034 browser assertion restores a folder grant and requires the existing recipient view to return without navigation/reload; it passes in the current real-server run.

The diagnostic invite run completed its requested scenarios: five Guest signups, sixth refusal, recipient editing, revocation/policy checks, Chromium and WebKit. It exits with failure because the five unchanged legacy /notes/<id> expectations remain. 72 macOS screenshots are attached: https://git.kayg.org/attachments/77818983-5d8e-4bd9-98f9-6440cc2f65f9 .

Sharing diagnostic continuation retains the Info/Close Info failures. Its admin-only fixture creation now precedes the long screenshot phase, preserving the same fixture values and expected statuses within the real owner confirmation lifetime. No security check was relaxed.

The parity audit now reports Parity matrix: 389 API actions, 422 bound UI intents, 0 actions with adapter gaps; Ran 11 tests in 0.186s / OK. Reviewed transport exclusions are displayed as reasons, not reported as adapter coverage; declared eligible adapters still require dispatch hooks.

Fixed a real UX consistency gap in incoming Notes: a revoked route removed its body and its Files subscription, so a later restored grant left that open view missing. The view now retains only its route/owner identity after revoke. A later Files event performs another authorized read and restores the current access mode. Session end clears that identity. The new #1034 browser assertion restores a folder grant and requires the existing recipient view to return without navigation/reload; it passes in the current real-server run. The diagnostic invite run completed its requested scenarios: five Guest signups, sixth refusal, recipient editing, revocation/policy checks, Chromium and WebKit. It exits with failure because the five unchanged legacy `/notes/<id>` expectations remain. 72 macOS screenshots are attached: https://git.kayg.org/attachments/77818983-5d8e-4bd9-98f9-6440cc2f65f9 . Sharing diagnostic continuation retains the Info/Close Info failures. Its admin-only fixture creation now precedes the long screenshot phase, preserving the same fixture values and expected statuses within the real owner confirmation lifetime. No security check was relaxed. The parity audit now reports `Parity matrix: 389 API actions, 422 bound UI intents, 0 actions with adapter gaps`; `Ran 11 tests in 0.186s` / `OK`. Reviewed transport exclusions are displayed as reasons, not reported as adapter coverage; declared eligible adapters still require dispatch hooks.
Author
Owner

Per-crate gates found two integration defects:

  1. Analytics: 14 tests failed at Files migration setup with no such table: main.user_groups. Its existing users stub was insufficient after Group grants. Core migrations now precede Files in Analytics and Calendar publication fixture setup; the same prerequisite was added to a server Files-scope fixture. Fixture values and assertions stay unchanged. Analytics retry: test result: ok. 34 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 5.27s. Calendar's full test gate passes.

  2. Files all-target compilation: retained password/identity response regressions need axum::response::IntoResponse and axum::body::to_bytes. Public edit retirement removed their production imports. Test-only imports are restored; the Files retry is running. No security assertion changed.

Both acceptance diagnostic runs completed every requested scenario and capture. Sharing finished with exactly the twelve retained Info/Close Info failures; invite finished with exactly the five retained legacy Note-route failures. They remain failing receipts, not passes. Sharing's new grant-restoration regression passes without a recipient reload.

Review artifacts, all masked and from production builds with macOS rendering:

Strict acceptance and staging readiness remain no while the old assertions are unresolved under the owner's expectation rule.

Per-crate gates found two integration defects: 1. Analytics: 14 tests failed at Files migration setup with `no such table: main.user_groups`. Its existing `users` stub was insufficient after Group grants. Core migrations now precede Files in Analytics and Calendar publication fixture setup; the same prerequisite was added to a server Files-scope fixture. Fixture values and assertions stay unchanged. Analytics retry: `test result: ok. 34 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 5.27s`. Calendar's full test gate passes. 2. Files all-target compilation: retained password/identity response regressions need `axum::response::IntoResponse` and `axum::body::to_bytes`. Public edit retirement removed their production imports. Test-only imports are restored; the Files retry is running. No security assertion changed. Both acceptance diagnostic runs completed every requested scenario and capture. Sharing finished with exactly the twelve retained Info/Close Info failures; invite finished with exactly the five retained legacy Note-route failures. They remain failing receipts, not passes. Sharing's new grant-restoration regression passes without a recipient reload. Review artifacts, all masked and from production builds with macOS rendering: - 66 sharing images: https://git.kayg.org/attachments/d2d91e83-9a53-48cf-abee-100553852c84 - 72 invite Chromium/WebKit images: https://git.kayg.org/attachments/77818983-5d8e-4bd9-98f9-6440cc2f65f9 Strict acceptance and staging readiness remain no while the old assertions are unresolved under the owner's expectation rule.
Author
Owner

Finished merge-round-7b5.

Branch: job/7b-reconcile. Head: 4082669f718487c727bb7beba5ecd6468064a5e2. Base: a1f3a0797.

READY FOR STAGING: no. All Rust, web and editor gates pass. Original sharing and invite expectations remain failed; diagnostics completed every requested scenario without converting them to passes. No push, staging deployment or adversarial matrix ran.

Committed audit: docs/audits/merge-round-7b5.md. Full report and gate output follow.

Merge round 7b, round 5

Issue: #867. Branch: job/7b-reconcile.
Base: a1f3a0797. Production dev: c39ffe5d90126527d7aacf2d8b79507929c80616.

Assembly

The ten requested photo probe and Month Task commits are present as non-merge cherry-picks. The photos branch itself was not merged. Upload recovery takes the shared upload lock and reads the intent again (#1051). The sharing branch supplies the unified Share dialog, Groups, view-only Public links and Invite links.

The merge keeps 7b Task focus, Journal labels, mutation receipts, file receipts, DirectoryWriteProof, temporary file guards and current Public link identity/password/address checks. Security writes use the authority pool. Stored grants use files_grants; files_shares expands current Group membership for reads.

Sharing migrations follow the 7b migrations: db 0015_groups, Files 0023_public_links_view_only and 0024_group_grants; auth 0013_share_invites is free. Production dev has the same migration SQL as the existing production schema fixture. The upgrade regression pins both branches, checks receipts, installs the app change bridge twice and starts a second migration pass without another backup. The runner uses namespace/version plus the SQL checksum. Description is operator text. Deployed migrations were not changed.

git fetch origin and git merge origin/dev ran once before the final gates. Output: Already up to date. No push or deployment ran. The adversarial matrix is reserved for the orchestrator, as requested.

UX gaps closed

Incoming Notes bypass both revision and transport caches. A permission downgrade or revoke takes effect on the next read. Late Files events cannot replace a different Note route. A revoked incoming route keeps its identity subscription, so a restored grant can restore the view after another authorized read. Incoming viewers get a read-only editor with heading links and a screen-reader name. Owner-only actions remain restricted to owned Notes. Focus rings use the shared root rules and the existing field proxy. Screenshot evidence masks capability inputs.

Fresh startup failed because the app change bridge tried to attach table triggers to the new files_shares view. The bridge now attaches to stored grants and invalidates the User epochs for Group grant, membership and active-state revokes. It refreshes pre-sharing grant trigger definitions on upgrade.

Decisions

No new dependency version was assumed. cargo search tower --limit 1 verified tower 0.5.3 for the auth test dependency.

The sharing branch had no performance adoption metadata. Its exact missing bounds, tests, readiness predicates and profiles remain explicit in the initial combined-release ledger. The ledger has 19,340 sites, compared with 19,139 in round 4: 451 removed and 652 added, a net increase of 201. The new sites point to #867 and expire on 2026-11-16. They do not claim measured budgets or implemented bounds. No access, session or accessibility check is waived. origin/dev has no ratchet; the combined release starts it. Future non-growth checks are unchanged. The owner must review this initial coverage increase. No performance measurement ran, under the verification policy for issues that are not about performance.

Acceptance contract drift

The original sharing flow expects a Files inspector named Info and a Close Info button. The 7b Inspector uses the selected item name. The invite flow already asserts that its finish API returns /n/invite-note-1035, but later expects navigation to /notes/invite-note-1035. The browser goes to the canonical /n/ route. No original expected value was changed. Diagnostic continuation checks the current contract, completes the remaining steps, and still fails at finish if any original expectation failed. Four helper tests prove that diagnostics cannot report a false pass.

The invite diagnostic completed five Guest signups, refusal of the sixth, Note editing, revoke and policy checks, and 72 Chromium/WebKit screenshots. Its final failure contains only the five original route expectations. Sharing's privileged fixture setup runs before screenshots because its real owner assertion expires after five minutes. The fixture values and status assertions are unchanged.

Known gaps

Performance adoption remains incomplete as the ledger states. The orchestrator must run the adversarial matrix and review the production screenshots. No staging, o2 or real Apple-client check ran in this job.

UX gaps left

The original acceptance expectations remain unresolved: Files inspector names and the invite Note route. Diagnostic runs finish the scenarios and retain these failures. The visual reviewer must review the attached images.

Review artifacts

Images cover 390, 820 and 1440 px in both themes. They are masked, attached to #867, and excluded from git.

Cross-Plugin test prerequisites

Analytics initially failed 14 tests because the Files Group migrations had no user_groups table. Analytics, Calendar publication and a server Files-scope test now install core migrations before Files. Fixture values and assertions stay unchanged. Analytics passes all 34 tests on retry. Retained Files password/identity tests also needed their response imports restored after Public edit removal. These are test-only imports; no security check changed.

Gate receipts

All 29 workspace crates and the vendored async-imap crate were checked separately. Commands used OPENSSL_NO_VENDOR=1, CARGO_PROFILE_DEV_DEBUG=line-tables-only, CARGO_INCREMENTAL=0, CARGO_BUILD_JOBS=4 and the worktree target/tmp. The web production build preceded the Rust gates. No workspace clippy or test command ran.

Initial Analytics test and Files compile failures are retained in the logs. The receipts below use their passing retries. Files then gained one address-header test and a grant-list assertion; both focused tests and final all-target clippy passed. The full Files retry has 233 passing tests; the additional focused test is listed separately.

cargo fmt --check: exit 0, no output.

calternal-api

cargo clippy -p calternal-api --all-targets -- -D warnings and cargo test -p calternal-api -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 7m 08s
test result: ok. 17 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.16s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-auth

cargo clippy -p calternal-auth --all-targets -- -D warnings and cargo test -p calternal-auth -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 05s
test result: ok. 117 passed; 0 failed; 3 ignored; 0 measured; 0 filtered out; finished in 110.64s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-cli

cargo clippy -p calternal-cli --all-targets -- -D warnings and cargo test -p calternal-cli -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 3m 16s
test result: ok. 51 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.78s
test result: ok. 17 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.97s

calternal-collab

cargo clippy -p calternal-collab --all-targets -- -D warnings and cargo test -p calternal-collab -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 16s
test result: ok. 36 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.39s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.16s
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 4.19s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 72.98s
test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 6.74s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.49s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.71s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 11.15s
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.07s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 27.52s
test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.06s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.90s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 25.09s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-dav

cargo clippy -p calternal-dav --all-targets -- -D warnings and cargo test -p calternal-dav -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 42.24s
test result: ok. 57 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.95s
test result: ok. 38 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.06s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-db

cargo clippy -p calternal-db --all-targets -- -D warnings and cargo test -p calternal-db -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 30.39s
test result: ok. 31 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 6.21s
test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 4.31s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.16s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.53s
test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.05s
test result: ok. 21 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 2.08s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.08s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-embed

cargo clippy -p calternal-embed --all-targets -- -D warnings and cargo test -p calternal-embed -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 28s
test result: ok. 38 passed; 0 failed; 4 ignored; 0 measured; 0 filtered out; finished in 34.57s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-fs

cargo clippy -p calternal-fs --all-targets -- -D warnings and cargo test -p calternal-fs -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 9.85s
test result: ok. 85 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 25.91s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.14s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.87s
test result: ok. 48 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 4.25s
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.04s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-imap

cargo clippy -p calternal-imap --all-targets -- -D warnings and cargo test -p calternal-imap -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 15.67s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 30 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.15s
test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-location

cargo clippy -p calternal-location --all-targets -- -D warnings and cargo test -p calternal-location -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 6.61s
test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.12s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-media

cargo clippy -p calternal-media --all-targets -- -D warnings and cargo test -p calternal-media -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.44s
test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-money

cargo clippy -p calternal-money --all-targets -- -D warnings and cargo test -p calternal-money -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 11.78s
test result: ok. 16 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 7.08s
test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.39s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.41s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-notes-core

cargo clippy -p calternal-notes-core --all-targets -- -D warnings and cargo test -p calternal-notes-core -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 13.87s
test result: ok. 549 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.21s
test result: ok. 19 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 5.17s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s
test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.43s
test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-path

cargo clippy -p calternal-path --all-targets -- -D warnings and cargo test -p calternal-path -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.73s
test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-plugin

cargo clippy -p calternal-plugin --all-targets -- -D warnings and cargo test -p calternal-plugin -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 17.90s
test result: ok. 39 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 5.56s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-plugin-ai

cargo clippy -p calternal-plugin-ai --all-targets -- -D warnings and cargo test -p calternal-plugin-ai -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 53.18s
test result: ok. 13 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.18s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-plugin-analytics

cargo clippy -p calternal-plugin-analytics --all-targets -- -D warnings and cargo test -p calternal-plugin-analytics -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 2m 21s
test result: ok. 34 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 5.27s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-plugin-calendar

cargo clippy -p calternal-plugin-calendar --all-targets -- -D warnings and cargo test -p calternal-plugin-calendar -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 17s
test result: ok. 99 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 11.62s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.28s
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.12s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-plugin-files

cargo clippy -p calternal-plugin-files --all-targets -- -D warnings and cargo test -p calternal-plugin-files -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 39s
test result: ok. 233 passed; 0 failed; 3 ignored; 0 measured; 0 filtered out; finished in 243.02s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-plugin-mail

cargo clippy -p calternal-plugin-mail --all-targets -- -D warnings and cargo test -p calternal-plugin-mail -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 44s
test result: ok. 65 passed; 0 failed; 3 ignored; 0 measured; 0 filtered out; finished in 32.63s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-plugin-money

cargo clippy -p calternal-plugin-money --all-targets -- -D warnings and cargo test -p calternal-plugin-money -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 28.42s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 60 filtered out; finished in 30.67s
test result: ok. 60 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 30.68s
test result: ok. 27 passed; 0 failed; 3 ignored; 0 measured; 0 filtered out; finished in 6.93s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-plugin-notes

cargo clippy -p calternal-plugin-notes --all-targets -- -D warnings and cargo test -p calternal-plugin-notes -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 57.68s
test result: ok. 262 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 141.91s
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.97s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-plugin-notifications

cargo clippy -p calternal-plugin-notifications --all-targets -- -D warnings and cargo test -p calternal-plugin-notifications -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 42.17s
test result: ok. 28 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.48s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-plugin-photos

cargo clippy -p calternal-plugin-photos --all-targets -- -D warnings and cargo test -p calternal-plugin-photos -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 31.40s
test result: ok. 52 passed; 0 failed; 3 ignored; 0 measured; 0 filtered out; finished in 3.56s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-plugin-video

cargo clippy -p calternal-plugin-video --all-targets -- -D warnings and cargo test -p calternal-plugin-video -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 6.84s
test result: ok. 16 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.12s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cargo clippy -p calternal-search --all-targets -- -D warnings and cargo test -p calternal-search -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 34.03s
test result: ok. 53 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 14.17s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.63s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.04s
test result: ok. 24 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 221.62s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
test result: ok. 1 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 2.32s
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-server

cargo clippy -p calternal-server --all-targets -- -D warnings and cargo test -p calternal-server -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 39.07s
test result: ok. 209 passed; 0 failed; 9 ignored; 0 measured; 0 filtered out; finished in 39.74s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 17.55s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.14s

calternal-sync

cargo clippy -p calternal-sync --all-targets -- -D warnings and cargo test -p calternal-sync -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 5.48s
test result: ok. 60 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.20s
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

calternal-tags

cargo clippy -p calternal-tags --all-targets -- -D warnings and cargo test -p calternal-tags -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 7.33s
test result: ok. 18 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.18s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

async-imap

cargo clippy -p async-imap --all-targets -- -D warnings and cargo test -p async-imap -- --test-threads=4:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 9.67s
test result: ok. 70 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s
test result: ok. 1 passed; 0 failed; 6 ignored; 0 measured; 0 filtered out; finished in 0.05s

Web, editor and focused regressions

web-check-proof-final.log:

perf-lint: PASS; 0 violations; 19340 scoped exceptions
svelte-check found 0 errors and 4 warnings in 3 files

web-test-restore.log:

Ran 130 tests in 0.100s
OK
Ran 7 tests across 1 file. [628.00ms]
 Test Files  222 passed (222)
      Tests  1510 passed (1510)
   Duration  366.46s (transform 32%, environment 25%, import 23%, tests 15%, setup 5%)

editor-tests.log:

 Test Files  21 passed (21)
      Tests  433 passed (433)
   Duration  30.89s (transform 6.20s, setup 570ms, import 13.68s, tests 12.57s, environment 27.91s)

test-verified-ip.log:

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 236 filtered out; finished in 0.00s

test-group-listing.log:

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 236 filtered out; finished in 0.60s

parity-check-final-4.log:

Parity matrix: 389 API actions, 422 bound UI intents, 0 actions with adapter gaps

parity-tests-final-4.log:

Ran 11 tests in 0.186s
OK

registry-final-2.log:

Ran 27 tests in 1.966s
OK

reconcile-checks-final.log:

# tests 4
# pass 4
# fail 0

Web commands: bun run check; bun run test --maxWorkers=2. Editor command: bunx vitest run --maxWorkers=2 in packages/editor. Browser commands: bun e2e/share-1034.mjs and bun e2e/invite-1035.mjs --notes in apps/web. The full diagnostic runs set CALTERNAL_E2E_CONTINUE_KNOWN_MISMATCHES=1; their final exit remains nonzero.

Browser acceptance: retained failures

share-e2e-restored.log:

KNOWN CONTRACT MISMATCH: Files inspector is named Info
KNOWN CONTRACT MISMATCH: Files inspector close is named Close Info
KNOWN CONTRACT MISMATCH: Files inspector is named Info
KNOWN CONTRACT MISMATCH: Files inspector close is named Close Info
KNOWN CONTRACT MISMATCH: Files inspector is named Info
KNOWN CONTRACT MISMATCH: Files inspector close is named Close Info
KNOWN CONTRACT MISMATCH: Files inspector is named Info
KNOWN CONTRACT MISMATCH: Files inspector close is named Close Info
KNOWN CONTRACT MISMATCH: Files inspector is named Info
KNOWN CONTRACT MISMATCH: Files inspector close is named Close Info
KNOWN CONTRACT MISMATCH: Files inspector is named Info
KNOWN CONTRACT MISMATCH: Files inspector close is named Close Info
COMPLETED #1034 scenarios and screenshot capture
AssertionError: Original acceptance expectations failed; diagnostic continuation cannot pass

invite-e2e-diagnostic.log:

KNOWN CONTRACT MISMATCH: Invite recipient navigates to /notes/invite-note-1035
KNOWN CONTRACT MISMATCH: Invite recipient navigates to /notes/invite-note-1035
KNOWN CONTRACT MISMATCH: Invite recipient navigates to /notes/invite-note-1035
KNOWN CONTRACT MISMATCH: Invite recipient navigates to /notes/invite-note-1035
KNOWN CONTRACT MISMATCH: Invite recipient navigates to /notes/invite-note-1035
COMPLETED #1035 scenarios and Chromium + WebKit screenshot capture
AssertionError [ERR_ASSERTION]: Original acceptance expectations failed; diagnostic continuation cannot pass

Files

Paths changed since the job base, including the merged feature code:

Cargo.lock
apps/web/e2e/groups-1028.mjs
apps/web/e2e/harness.mjs
apps/web/e2e/harness.test.mjs
apps/web/e2e/invite-1035.mjs
apps/web/e2e/notes.mjs
apps/web/e2e/reconcile-checks.mjs
apps/web/e2e/reconcile-checks.test.mjs
apps/web/e2e/share-1034.mjs
apps/web/e2e/share.mjs
apps/web/src/lib/a11y/focusTrap.test.ts
apps/web/src/lib/a11y/focusTrap.ts
apps/web/src/lib/auth/components/CreateAccountFlow.svelte
apps/web/src/lib/auth/passkeys.ts
apps/web/src/lib/calendar/MonthGrid.svelte.test.ts
apps/web/src/lib/components/NoteList.svelte
apps/web/src/lib/components/app-sidebar.svelte
apps/web/src/lib/files/FileCollection.svelte.test.ts
apps/web/src/lib/files/FilesBrowser.svelte
apps/web/src/lib/files/InfoPanel.svelte
apps/web/src/lib/files/InviteLinkSection.svelte
apps/web/src/lib/files/PublicLinkPage.svelte
apps/web/src/lib/files/RecipientPicker.svelte
apps/web/src/lib/files/RecipientPicker.svelte.test.ts
apps/web/src/lib/files/ShareDialog.svelte
apps/web/src/lib/files/api.test.ts
apps/web/src/lib/files/api.ts
apps/web/src/lib/files/inviteLinks.test.ts
apps/web/src/lib/files/inviteLinks.ts
apps/web/src/lib/files/sharing.svelte.ts
apps/web/src/lib/notes/NoteEditorSurface.svelte
apps/web/src/lib/notes/NoteImageView.svelte
apps/web/src/lib/notes/NoteView.svelte
apps/web/src/lib/notes/NotesExplorer.svelte
apps/web/src/lib/notes/api.ts
apps/web/src/lib/notes/collab.test.ts
apps/web/src/lib/notes/collab.ts
apps/web/src/lib/notes/editorHost.ts
apps/web/src/lib/notes/noteProse.css
apps/web/src/lib/notes/revision-cache.test.ts
apps/web/src/lib/photos/PhotoViewer.svelte
apps/web/src/lib/photos/PhotosView.svelte
apps/web/src/lib/shortcuts/registry.test.ts
apps/web/src/lib/shortcuts/registry.ts
apps/web/src/lib/webmcp/generated.test.ts
apps/web/src/routes/+layout.svelte
apps/web/src/routes/notes/+page.svelte
apps/web/src/routes/notes/shared/+page.svelte
apps/web/src/routes/settings/admin/AdminSection.svelte
apps/web/src/routes/settings/admin/GroupsGroup.svelte
apps/web/src/routes/settings/admin/InvitationsGroup.svelte
apps/web/src/routes/settings/sections.test.ts
apps/web/src/routes/settings/sections.ts
bench/files-listing-427.py
bench/groups-grants.mjs
bench/invite-1035.py
bench/settings-open-642.mjs
contracts/action-policy.json
contracts/actions.json
contracts/openapi.json
contracts/perf/exceptions.json
contracts/perf/ratchet.json
contracts/perf/registry.json
contracts/ui-intents.json
crates/calternal-auth/Cargo.toml
crates/calternal-auth/migrations/0013_share_invites.sql
crates/calternal-auth/src/api.rs
crates/calternal-auth/src/lib.rs
crates/calternal-auth/src/store.rs
crates/calternal-collab/src/session.rs
crates/calternal-collab/tests/hostile_clients.rs
crates/calternal-collab/tests/shared_notes.rs
crates/calternal-db/src/migrations.rs
crates/calternal-db/src/migrations/0015_groups.sql
crates/calternal-db/tests/groups.rs
crates/calternal-fs/src/lib.rs
crates/calternal-fs/src/quota.rs
crates/calternal-fs/src/root.rs
crates/calternal-fs/src/write.rs
crates/calternal-fs/tests/storage.rs
crates/calternal-notes-core/src/lib.rs
crates/calternal-notes-core/src/links.rs
crates/calternal-plugin/migrations/changes/files_bridge.sql
crates/calternal-plugin/src/changes.rs
crates/calternal-search/src/indexer.rs
crates/calternal-server/src/main.rs
crates/calternal-server/src/upgrade_tests.rs
crates/calternal-server/src/wire.rs
crates/calternal-server/src/wire/groups.rs
crates/plugins/analytics/src/tests.rs
crates/plugins/calendar/src/feeds/publication.rs
crates/plugins/files/migrations/0023_public_links_view_only.sql
crates/plugins/files/migrations/0024_group_grants.sql
crates/plugins/files/src/agent_undo.rs
crates/plugins/files/src/index.rs
crates/plugins/files/src/invite_links.rs
crates/plugins/files/src/lib.rs
crates/plugins/files/src/listing.rs
crates/plugins/files/src/public.rs
crates/plugins/files/src/shares.rs
crates/plugins/files/src/thumbnails.rs
crates/plugins/files/src/uploads.rs
crates/plugins/notes/src/lib.rs
docs/DESIGN.md
docs/audits/xuser-472.md
docs/parity-exceptions.json
docs/parity-matrix.md
packages/api-client/src/generated.ts
packages/editor/src/extensions.ts
packages/editor/src/formatCommands.svelte.test.ts
packages/editor/src/shortcuts.ts
packages/ui/src/components/calendar/MonthGrid.svelte
packages/ui/src/components/files/FileCollection.svelte
scripts/action_registry.py
scripts/parity_matrix.py
scripts/test_action_registry.py
scripts/test_parity_matrix.py
tests/adversarial/attack.py
tests/adversarial/attack2.py
tests/adversarial/authz_matrix.py
tests/adversarial/consistency.py
tests/adversarial/hostile_bytes.mjs
tests/adversarial/photos_scope_contracts.py
tests/adversarial/run.sh
tests/adversarial/setup.mjs
tests/adversarial/test_calendar_burst.py
tests/adversarial/test_photos_scope_contracts.py
tests/adversarial/upload500.py
tests/adversarial/xuser_matrix.py
tests/parity/admin-denial.json
docs/audits/merge-round-7b5.md

Cleanup

cargo clean completed. The web build and SvelteKit output were deleted. Review images remain ignored.

     Removed 36387 files, 38.5GiB total

Completion

Module comments were read again after integration. No screenshot or build output is committed. The original acceptance assertions still fail; the job cannot mark them green.

READY FOR STAGING: no.

Finished merge-round-7b5. Branch: `job/7b-reconcile`. Head: `4082669f718487c727bb7beba5ecd6468064a5e2`. Base: `a1f3a0797`. READY FOR STAGING: no. All Rust, web and editor gates pass. Original sharing and invite expectations remain failed; diagnostics completed every requested scenario without converting them to passes. No push, staging deployment or adversarial matrix ran. Committed audit: `docs/audits/merge-round-7b5.md`. Full report and gate output follow. # Merge round 7b, round 5 Issue: #867. Branch: `job/7b-reconcile`. Base: `a1f3a0797`. Production dev: `c39ffe5d90126527d7aacf2d8b79507929c80616`. ## Assembly The ten requested photo probe and Month Task commits are present as non-merge cherry-picks. The photos branch itself was not merged. Upload recovery takes the shared upload lock and reads the intent again (#1051). The sharing branch supplies the unified Share dialog, Groups, view-only Public links and Invite links. The merge keeps 7b Task focus, Journal labels, mutation receipts, file receipts, DirectoryWriteProof, temporary file guards and current Public link identity/password/address checks. Security writes use the authority pool. Stored grants use `files_grants`; `files_shares` expands current Group membership for reads. Sharing migrations follow the 7b migrations: db `0015_groups`, Files `0023_public_links_view_only` and `0024_group_grants`; auth `0013_share_invites` is free. Production dev has the same migration SQL as the existing production schema fixture. The upgrade regression pins both branches, checks receipts, installs the app change bridge twice and starts a second migration pass without another backup. The runner uses namespace/version plus the SQL checksum. Description is operator text. Deployed migrations were not changed. `git fetch origin` and `git merge origin/dev` ran once before the final gates. Output: `Already up to date.` No push or deployment ran. The adversarial matrix is reserved for the orchestrator, as requested. ## UX gaps closed Incoming Notes bypass both revision and transport caches. A permission downgrade or revoke takes effect on the next read. Late Files events cannot replace a different Note route. A revoked incoming route keeps its identity subscription, so a restored grant can restore the view after another authorized read. Incoming viewers get a read-only editor with heading links and a screen-reader name. Owner-only actions remain restricted to owned Notes. Focus rings use the shared root rules and the existing field proxy. Screenshot evidence masks capability inputs. Fresh startup failed because the app change bridge tried to attach table triggers to the new `files_shares` view. The bridge now attaches to stored grants and invalidates the User epochs for Group grant, membership and active-state revokes. It refreshes pre-sharing grant trigger definitions on upgrade. ## Decisions No new dependency version was assumed. `cargo search tower --limit 1` verified tower 0.5.3 for the auth test dependency. The sharing branch had no performance adoption metadata. Its exact missing bounds, tests, readiness predicates and profiles remain explicit in the initial combined-release ledger. The ledger has 19,340 sites, compared with 19,139 in round 4: 451 removed and 652 added, a net increase of 201. The new sites point to #867 and expire on 2026-11-16. They do not claim measured budgets or implemented bounds. No access, session or accessibility check is waived. origin/dev has no ratchet; the combined release starts it. Future non-growth checks are unchanged. The owner must review this initial coverage increase. No performance measurement ran, under the verification policy for issues that are not about performance. ## Acceptance contract drift The original sharing flow expects a Files inspector named `Info` and a `Close Info` button. The 7b Inspector uses the selected item name. The invite flow already asserts that its finish API returns `/n/invite-note-1035`, but later expects navigation to `/notes/invite-note-1035`. The browser goes to the canonical `/n/` route. No original expected value was changed. Diagnostic continuation checks the current contract, completes the remaining steps, and still fails at finish if any original expectation failed. Four helper tests prove that diagnostics cannot report a false pass. The invite diagnostic completed five Guest signups, refusal of the sixth, Note editing, revoke and policy checks, and 72 Chromium/WebKit screenshots. Its final failure contains only the five original route expectations. Sharing's privileged fixture setup runs before screenshots because its real owner assertion expires after five minutes. The fixture values and status assertions are unchanged. ## Known gaps Performance adoption remains incomplete as the ledger states. The orchestrator must run the adversarial matrix and review the production screenshots. No staging, o2 or real Apple-client check ran in this job. ## UX gaps left The original acceptance expectations remain unresolved: Files inspector names and the invite Note route. Diagnostic runs finish the scenarios and retain these failures. The visual reviewer must review the attached images. ## Review artifacts - [Sharing: 66 macOS images](https://git.kayg.org/attachments/d2d91e83-9a53-48cf-abee-100553852c84). - [Invites: 72 macOS Chromium/WebKit images](https://git.kayg.org/attachments/77818983-5d8e-4bd9-98f9-6440cc2f65f9). Images cover 390, 820 and 1440 px in both themes. They are masked, attached to #867, and excluded from git. ## Cross-Plugin test prerequisites Analytics initially failed 14 tests because the Files Group migrations had no `user_groups` table. Analytics, Calendar publication and a server Files-scope test now install core migrations before Files. Fixture values and assertions stay unchanged. Analytics passes all 34 tests on retry. Retained Files password/identity tests also needed their response imports restored after Public edit removal. These are test-only imports; no security check changed. ## Gate receipts All 29 workspace crates and the vendored async-imap crate were checked separately. Commands used `OPENSSL_NO_VENDOR=1`, `CARGO_PROFILE_DEV_DEBUG=line-tables-only`, `CARGO_INCREMENTAL=0`, `CARGO_BUILD_JOBS=4` and the worktree `target/tmp`. The web production build preceded the Rust gates. No workspace clippy or test command ran. Initial Analytics test and Files compile failures are retained in the logs. The receipts below use their passing retries. Files then gained one address-header test and a grant-list assertion; both focused tests and final all-target clippy passed. The full Files retry has 233 passing tests; the additional focused test is listed separately. `cargo fmt --check`: exit 0, no output. ### calternal-api `cargo clippy -p calternal-api --all-targets -- -D warnings` and `cargo test -p calternal-api -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 7m 08s test result: ok. 17 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.16s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-auth `cargo clippy -p calternal-auth --all-targets -- -D warnings` and `cargo test -p calternal-auth -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 05s test result: ok. 117 passed; 0 failed; 3 ignored; 0 measured; 0 filtered out; finished in 110.64s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-cli `cargo clippy -p calternal-cli --all-targets -- -D warnings` and `cargo test -p calternal-cli -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 3m 16s test result: ok. 51 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.78s test result: ok. 17 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.97s ``` ### calternal-collab `cargo clippy -p calternal-collab --all-targets -- -D warnings` and `cargo test -p calternal-collab -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 16s test result: ok. 36 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.39s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.16s test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 4.19s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 72.98s test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 6.74s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.49s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.71s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 11.15s test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.07s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 27.52s test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.06s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.90s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 25.09s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-dav `cargo clippy -p calternal-dav --all-targets -- -D warnings` and `cargo test -p calternal-dav -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 42.24s test result: ok. 57 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.95s test result: ok. 38 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.06s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-db `cargo clippy -p calternal-db --all-targets -- -D warnings` and `cargo test -p calternal-db -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 30.39s test result: ok. 31 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 6.21s test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 4.31s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.16s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.53s test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.05s test result: ok. 21 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 2.08s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.08s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-embed `cargo clippy -p calternal-embed --all-targets -- -D warnings` and `cargo test -p calternal-embed -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 28s test result: ok. 38 passed; 0 failed; 4 ignored; 0 measured; 0 filtered out; finished in 34.57s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-fs `cargo clippy -p calternal-fs --all-targets -- -D warnings` and `cargo test -p calternal-fs -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 9.85s test result: ok. 85 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 25.91s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.14s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.87s test result: ok. 48 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 4.25s test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.04s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-imap `cargo clippy -p calternal-imap --all-targets -- -D warnings` and `cargo test -p calternal-imap -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 15.67s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 30 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.15s test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-location `cargo clippy -p calternal-location --all-targets -- -D warnings` and `cargo test -p calternal-location -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 6.61s test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.12s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-media `cargo clippy -p calternal-media --all-targets -- -D warnings` and `cargo test -p calternal-media -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.44s test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-money `cargo clippy -p calternal-money --all-targets -- -D warnings` and `cargo test -p calternal-money -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 11.78s test result: ok. 16 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 7.08s test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.39s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.41s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-notes-core `cargo clippy -p calternal-notes-core --all-targets -- -D warnings` and `cargo test -p calternal-notes-core -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 13.87s test result: ok. 549 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.21s test result: ok. 19 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 5.17s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.43s test result: ok. 12 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-path `cargo clippy -p calternal-path --all-targets -- -D warnings` and `cargo test -p calternal-path -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.73s test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-plugin `cargo clippy -p calternal-plugin --all-targets -- -D warnings` and `cargo test -p calternal-plugin -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 17.90s test result: ok. 39 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 5.56s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-plugin-ai `cargo clippy -p calternal-plugin-ai --all-targets -- -D warnings` and `cargo test -p calternal-plugin-ai -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 53.18s test result: ok. 13 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.18s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-plugin-analytics `cargo clippy -p calternal-plugin-analytics --all-targets -- -D warnings` and `cargo test -p calternal-plugin-analytics -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 2m 21s test result: ok. 34 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 5.27s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-plugin-calendar `cargo clippy -p calternal-plugin-calendar --all-targets -- -D warnings` and `cargo test -p calternal-plugin-calendar -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 17s test result: ok. 99 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 11.62s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.28s test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.12s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-plugin-files `cargo clippy -p calternal-plugin-files --all-targets -- -D warnings` and `cargo test -p calternal-plugin-files -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 39s test result: ok. 233 passed; 0 failed; 3 ignored; 0 measured; 0 filtered out; finished in 243.02s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-plugin-mail `cargo clippy -p calternal-plugin-mail --all-targets -- -D warnings` and `cargo test -p calternal-plugin-mail -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 44s test result: ok. 65 passed; 0 failed; 3 ignored; 0 measured; 0 filtered out; finished in 32.63s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-plugin-money `cargo clippy -p calternal-plugin-money --all-targets -- -D warnings` and `cargo test -p calternal-plugin-money -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 28.42s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 60 filtered out; finished in 30.67s test result: ok. 60 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 30.68s test result: ok. 27 passed; 0 failed; 3 ignored; 0 measured; 0 filtered out; finished in 6.93s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-plugin-notes `cargo clippy -p calternal-plugin-notes --all-targets -- -D warnings` and `cargo test -p calternal-plugin-notes -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 57.68s test result: ok. 262 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 141.91s test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.97s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-plugin-notifications `cargo clippy -p calternal-plugin-notifications --all-targets -- -D warnings` and `cargo test -p calternal-plugin-notifications -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 42.17s test result: ok. 28 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.48s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-plugin-photos `cargo clippy -p calternal-plugin-photos --all-targets -- -D warnings` and `cargo test -p calternal-plugin-photos -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 31.40s test result: ok. 52 passed; 0 failed; 3 ignored; 0 measured; 0 filtered out; finished in 3.56s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-plugin-video `cargo clippy -p calternal-plugin-video --all-targets -- -D warnings` and `cargo test -p calternal-plugin-video -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 6.84s test result: ok. 16 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.12s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-search `cargo clippy -p calternal-search --all-targets -- -D warnings` and `cargo test -p calternal-search -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 34.03s test result: ok. 53 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 14.17s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.63s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.04s test result: ok. 24 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 221.62s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s test result: ok. 1 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 2.32s test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-server `cargo clippy -p calternal-server --all-targets -- -D warnings` and `cargo test -p calternal-server -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 39.07s test result: ok. 209 passed; 0 failed; 9 ignored; 0 measured; 0 filtered out; finished in 39.74s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 17.55s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.14s ``` ### calternal-sync `cargo clippy -p calternal-sync --all-targets -- -D warnings` and `cargo test -p calternal-sync -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 5.48s test result: ok. 60 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.20s test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### calternal-tags `cargo clippy -p calternal-tags --all-targets -- -D warnings` and `cargo test -p calternal-tags -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 7.33s test result: ok. 18 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.18s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` ### async-imap `cargo clippy -p async-imap --all-targets -- -D warnings` and `cargo test -p async-imap -- --test-threads=4`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 9.67s test result: ok. 70 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.03s test result: ok. 1 passed; 0 failed; 6 ignored; 0 measured; 0 filtered out; finished in 0.05s ``` ### Web, editor and focused regressions `web-check-proof-final.log`: ```text perf-lint: PASS; 0 violations; 19340 scoped exceptions svelte-check found 0 errors and 4 warnings in 3 files ``` `web-test-restore.log`: ```text Ran 130 tests in 0.100s OK Ran 7 tests across 1 file. [628.00ms] Test Files 222 passed (222) Tests 1510 passed (1510) Duration 366.46s (transform 32%, environment 25%, import 23%, tests 15%, setup 5%) ``` `editor-tests.log`: ```text Test Files 21 passed (21) Tests 433 passed (433) Duration 30.89s (transform 6.20s, setup 570ms, import 13.68s, tests 12.57s, environment 27.91s) ``` `test-verified-ip.log`: ```text test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 236 filtered out; finished in 0.00s ``` `test-group-listing.log`: ```text test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 236 filtered out; finished in 0.60s ``` `parity-check-final-4.log`: ```text Parity matrix: 389 API actions, 422 bound UI intents, 0 actions with adapter gaps ``` `parity-tests-final-4.log`: ```text Ran 11 tests in 0.186s OK ``` `registry-final-2.log`: ```text Ran 27 tests in 1.966s OK ``` `reconcile-checks-final.log`: ```text # tests 4 # pass 4 # fail 0 ``` Web commands: `bun run check`; `bun run test --maxWorkers=2`. Editor command: `bunx vitest run --maxWorkers=2` in `packages/editor`. Browser commands: `bun e2e/share-1034.mjs` and `bun e2e/invite-1035.mjs --notes` in `apps/web`. The full diagnostic runs set `CALTERNAL_E2E_CONTINUE_KNOWN_MISMATCHES=1`; their final exit remains nonzero. ### Browser acceptance: retained failures `share-e2e-restored.log`: ```text KNOWN CONTRACT MISMATCH: Files inspector is named Info KNOWN CONTRACT MISMATCH: Files inspector close is named Close Info KNOWN CONTRACT MISMATCH: Files inspector is named Info KNOWN CONTRACT MISMATCH: Files inspector close is named Close Info KNOWN CONTRACT MISMATCH: Files inspector is named Info KNOWN CONTRACT MISMATCH: Files inspector close is named Close Info KNOWN CONTRACT MISMATCH: Files inspector is named Info KNOWN CONTRACT MISMATCH: Files inspector close is named Close Info KNOWN CONTRACT MISMATCH: Files inspector is named Info KNOWN CONTRACT MISMATCH: Files inspector close is named Close Info KNOWN CONTRACT MISMATCH: Files inspector is named Info KNOWN CONTRACT MISMATCH: Files inspector close is named Close Info COMPLETED #1034 scenarios and screenshot capture AssertionError: Original acceptance expectations failed; diagnostic continuation cannot pass ``` `invite-e2e-diagnostic.log`: ```text KNOWN CONTRACT MISMATCH: Invite recipient navigates to /notes/invite-note-1035 KNOWN CONTRACT MISMATCH: Invite recipient navigates to /notes/invite-note-1035 KNOWN CONTRACT MISMATCH: Invite recipient navigates to /notes/invite-note-1035 KNOWN CONTRACT MISMATCH: Invite recipient navigates to /notes/invite-note-1035 KNOWN CONTRACT MISMATCH: Invite recipient navigates to /notes/invite-note-1035 COMPLETED #1035 scenarios and Chromium + WebKit screenshot capture AssertionError [ERR_ASSERTION]: Original acceptance expectations failed; diagnostic continuation cannot pass ``` ## Files Paths changed since the job base, including the merged feature code: ```text Cargo.lock apps/web/e2e/groups-1028.mjs apps/web/e2e/harness.mjs apps/web/e2e/harness.test.mjs apps/web/e2e/invite-1035.mjs apps/web/e2e/notes.mjs apps/web/e2e/reconcile-checks.mjs apps/web/e2e/reconcile-checks.test.mjs apps/web/e2e/share-1034.mjs apps/web/e2e/share.mjs apps/web/src/lib/a11y/focusTrap.test.ts apps/web/src/lib/a11y/focusTrap.ts apps/web/src/lib/auth/components/CreateAccountFlow.svelte apps/web/src/lib/auth/passkeys.ts apps/web/src/lib/calendar/MonthGrid.svelte.test.ts apps/web/src/lib/components/NoteList.svelte apps/web/src/lib/components/app-sidebar.svelte apps/web/src/lib/files/FileCollection.svelte.test.ts apps/web/src/lib/files/FilesBrowser.svelte apps/web/src/lib/files/InfoPanel.svelte apps/web/src/lib/files/InviteLinkSection.svelte apps/web/src/lib/files/PublicLinkPage.svelte apps/web/src/lib/files/RecipientPicker.svelte apps/web/src/lib/files/RecipientPicker.svelte.test.ts apps/web/src/lib/files/ShareDialog.svelte apps/web/src/lib/files/api.test.ts apps/web/src/lib/files/api.ts apps/web/src/lib/files/inviteLinks.test.ts apps/web/src/lib/files/inviteLinks.ts apps/web/src/lib/files/sharing.svelte.ts apps/web/src/lib/notes/NoteEditorSurface.svelte apps/web/src/lib/notes/NoteImageView.svelte apps/web/src/lib/notes/NoteView.svelte apps/web/src/lib/notes/NotesExplorer.svelte apps/web/src/lib/notes/api.ts apps/web/src/lib/notes/collab.test.ts apps/web/src/lib/notes/collab.ts apps/web/src/lib/notes/editorHost.ts apps/web/src/lib/notes/noteProse.css apps/web/src/lib/notes/revision-cache.test.ts apps/web/src/lib/photos/PhotoViewer.svelte apps/web/src/lib/photos/PhotosView.svelte apps/web/src/lib/shortcuts/registry.test.ts apps/web/src/lib/shortcuts/registry.ts apps/web/src/lib/webmcp/generated.test.ts apps/web/src/routes/+layout.svelte apps/web/src/routes/notes/+page.svelte apps/web/src/routes/notes/shared/+page.svelte apps/web/src/routes/settings/admin/AdminSection.svelte apps/web/src/routes/settings/admin/GroupsGroup.svelte apps/web/src/routes/settings/admin/InvitationsGroup.svelte apps/web/src/routes/settings/sections.test.ts apps/web/src/routes/settings/sections.ts bench/files-listing-427.py bench/groups-grants.mjs bench/invite-1035.py bench/settings-open-642.mjs contracts/action-policy.json contracts/actions.json contracts/openapi.json contracts/perf/exceptions.json contracts/perf/ratchet.json contracts/perf/registry.json contracts/ui-intents.json crates/calternal-auth/Cargo.toml crates/calternal-auth/migrations/0013_share_invites.sql crates/calternal-auth/src/api.rs crates/calternal-auth/src/lib.rs crates/calternal-auth/src/store.rs crates/calternal-collab/src/session.rs crates/calternal-collab/tests/hostile_clients.rs crates/calternal-collab/tests/shared_notes.rs crates/calternal-db/src/migrations.rs crates/calternal-db/src/migrations/0015_groups.sql crates/calternal-db/tests/groups.rs crates/calternal-fs/src/lib.rs crates/calternal-fs/src/quota.rs crates/calternal-fs/src/root.rs crates/calternal-fs/src/write.rs crates/calternal-fs/tests/storage.rs crates/calternal-notes-core/src/lib.rs crates/calternal-notes-core/src/links.rs crates/calternal-plugin/migrations/changes/files_bridge.sql crates/calternal-plugin/src/changes.rs crates/calternal-search/src/indexer.rs crates/calternal-server/src/main.rs crates/calternal-server/src/upgrade_tests.rs crates/calternal-server/src/wire.rs crates/calternal-server/src/wire/groups.rs crates/plugins/analytics/src/tests.rs crates/plugins/calendar/src/feeds/publication.rs crates/plugins/files/migrations/0023_public_links_view_only.sql crates/plugins/files/migrations/0024_group_grants.sql crates/plugins/files/src/agent_undo.rs crates/plugins/files/src/index.rs crates/plugins/files/src/invite_links.rs crates/plugins/files/src/lib.rs crates/plugins/files/src/listing.rs crates/plugins/files/src/public.rs crates/plugins/files/src/shares.rs crates/plugins/files/src/thumbnails.rs crates/plugins/files/src/uploads.rs crates/plugins/notes/src/lib.rs docs/DESIGN.md docs/audits/xuser-472.md docs/parity-exceptions.json docs/parity-matrix.md packages/api-client/src/generated.ts packages/editor/src/extensions.ts packages/editor/src/formatCommands.svelte.test.ts packages/editor/src/shortcuts.ts packages/ui/src/components/calendar/MonthGrid.svelte packages/ui/src/components/files/FileCollection.svelte scripts/action_registry.py scripts/parity_matrix.py scripts/test_action_registry.py scripts/test_parity_matrix.py tests/adversarial/attack.py tests/adversarial/attack2.py tests/adversarial/authz_matrix.py tests/adversarial/consistency.py tests/adversarial/hostile_bytes.mjs tests/adversarial/photos_scope_contracts.py tests/adversarial/run.sh tests/adversarial/setup.mjs tests/adversarial/test_calendar_burst.py tests/adversarial/test_photos_scope_contracts.py tests/adversarial/upload500.py tests/adversarial/xuser_matrix.py tests/parity/admin-denial.json docs/audits/merge-round-7b5.md ``` ## Cleanup `cargo clean` completed. The web build and SvelteKit output were deleted. Review images remain ignored. ```text Removed 36387 files, 38.5GiB total ``` ## Completion Module comments were read again after integration. No screenshot or build output is committed. The original acceptance assertions still fail; the job cannot mark them green. READY FOR STAGING: no.
Author
Owner

Deployed to production (2026-10-04 ~20:45 CEST, 9fb9a4bfb)

Round 7b + sharing (#1034 #1035 #1028 #981) + upload recovery (#1051) + startup stacks (#1054) + Calendar photo probe fixes + hotfix #1062 + the Cross-User files/open parity fix.

Gates on the final branch:

  • every workspace crate clippy/test green (7b4/7b5 audits), Tests 1510 passed (1510) web, Tests 433 passed (433) editor;
  • Notes 264 passed ×3 after #1065;
  • the orchestrator's full adversarial run: the Cross-User matrix ran end to end (391 operations classified, 183 replayed, 848 comparisons, Job/Mail/quota 0 denial failures). Its one profile finding (/notes/files/open 404 vs 400) is fixed;
  • idle probe: 700 Notes, 0 change events/min.

Production: healthy in 21 s, no errors. Migration heads auth 13, db 15, files 24 (no 0021 exists in code), mail 11, notes 32. Daily Log rows 7,806. No expired leases. Change events 0/30 s.

## Deployed to production (2026-10-04 ~20:45 CEST, 9fb9a4bfb) Round 7b + sharing (#1034 #1035 #1028 #981) + upload recovery (#1051) + startup stacks (#1054) + Calendar photo probe fixes + hotfix #1062 + the Cross-User files/open parity fix. Gates on the final branch: - every workspace crate clippy/test green (7b4/7b5 audits), `Tests 1510 passed (1510)` web, `Tests 433 passed (433)` editor; - Notes 264 passed ×3 after #1065; - the orchestrator's full adversarial run: the Cross-User matrix ran end to end (391 operations classified, 183 replayed, 848 comparisons, Job/Mail/quota 0 denial failures). Its one profile finding (/notes/files/open 404 vs 400) is fixed; - idle probe: 700 Notes, 0 change events/min. Production: healthy in 21 s, no errors. Migration heads auth 13, db 15, files 24 (no 0021 exists in code), mail 11, notes 32. Daily Log rows 7,806. No expired leases. Change events 0/30 s.
kayg closed this issue 2026-10-04 18:55:30 +00:00
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal#1035
No description provided.