BLOCKER: bind public download authorization to the opened item and current grant #755

Open
opened 2026-10-02 13:09:18 +00:00 by kayg · 21 comments
Owner

Found in the authorized sec-sharing source audit on origin/dev at c4a61e8cf090170f35b1bed3350d9de20c83ecd5. Related sharing decisions: #479 / #461. No product change or live attack was made.

BLOCKER: public download does not bind its open handle to the grant

Status: source-confirmed check-order defect; runtime impact is reasoned.

Evidence on the audit base:

  • crates/plugins/files/src/public.rs:670: authorize checks the link's
    stored item ID against the current path.
  • crates/plugins/files/src/public.rs:1696: download authorizes the grant
    and resolves the target before it acquires the namespace mutation lock.
  • crates/plugins/files/src/public.rs:1701: after the lock wait, the handler
    opens the path. It does not check the item ID again under the lock or check
    the opened handle against that identity.
  • crates/plugins/files/src/public.rs:1709: the counter update checks the
    slug, expiry and download limit. It does not bind the update to the checked
    item ID, password or permissions.
  • crates/plugins/files/src/lib.rs:3672: the authenticated Files download
    takes the namespace lock before it resolves the Share. This is a useful
    existing pattern for the fix.
  • crates/plugins/files/src/lib.rs:909: read_indexed_item_for_user also
    locks before its identity and grant checks.

Reasoned impact: a namespace change during the wait can make the open refer
to a different item at the same path. The old public grant must not apply to
that item (DESIGN §26). A changed link can also pass the counter update with
an old authorization decision. This is an access-control defect, rather
than a claim that a fetched copy can be recalled.

Fix: retain the expensive password check outside the namespace lock. Then
validate the current grant and target identity under the lock, open the
file, and verify its handle identity. Bind the counter update to the same
grant version. Reuse the existing Files read pattern. Release the lock
before streaming the body.

Regression requirement: use isolated test data and a controlled namespace
change to verify that an old grant cannot return replacement bytes. Also
verify that a changed grant cannot pass the counter update. Keep the
existing stale-item and download-limit expectations. Do not rely on timing
or a large request burst.

Staged status: round-7a changes thumbnail families in public.rs. It does
not change this authorization or open sequence.

Duplicate check: reviewed all-state issue titles and related sharing/security reports. No issue for this specific defect was found.

Found in the authorized sec-sharing source audit on `origin/dev` at `c4a61e8cf090170f35b1bed3350d9de20c83ecd5`. Related sharing decisions: #479 / #461. No product change or live attack was made. BLOCKER: public download does not bind its open handle to the grant Status: source-confirmed check-order defect; runtime impact is reasoned. Evidence on the audit base: - `crates/plugins/files/src/public.rs:670`: `authorize` checks the link's stored item ID against the current path. - `crates/plugins/files/src/public.rs:1696`: `download` authorizes the grant and resolves the target before it acquires the namespace mutation lock. - `crates/plugins/files/src/public.rs:1701`: after the lock wait, the handler opens the path. It does not check the item ID again under the lock or check the opened handle against that identity. - `crates/plugins/files/src/public.rs:1709`: the counter update checks the slug, expiry and download limit. It does not bind the update to the checked item ID, password or permissions. - `crates/plugins/files/src/lib.rs:3672`: the authenticated Files download takes the namespace lock before it resolves the Share. This is a useful existing pattern for the fix. - `crates/plugins/files/src/lib.rs:909`: `read_indexed_item_for_user` also locks before its identity and grant checks. Reasoned impact: a namespace change during the wait can make the open refer to a different item at the same path. The old public grant must not apply to that item (DESIGN §26). A changed link can also pass the counter update with an old authorization decision. This is an access-control defect, rather than a claim that a fetched copy can be recalled. Fix: retain the expensive password check outside the namespace lock. Then validate the current grant and target identity under the lock, open the file, and verify its handle identity. Bind the counter update to the same grant version. Reuse the existing Files read pattern. Release the lock before streaming the body. Regression requirement: use isolated test data and a controlled namespace change to verify that an old grant cannot return replacement bytes. Also verify that a changed grant cannot pass the counter update. Keep the existing stale-item and download-limit expectations. Do not rely on timing or a large request burst. Staged status: round-7a changes thumbnail families in `public.rs`. It does not change this authorization or open sequence. Duplicate check: reviewed all-state issue titles and related sharing/security reports. No issue for this specific defect was found.
Author
Owner

Additional source evidence and limit: crates/plugins/files/src/index.rs:1374 removes public-link rows on normal deletion, so the download counter rejects that case. Line 1762 updates link paths in place for moves, preserving the slug while the namespace changes. The fix must bind the post-lock open and counter to the current grant. This remains source evidence with reasoned impact, not a live reproduction.

Additional source evidence and limit: `crates/plugins/files/src/index.rs:1374` removes public-link rows on normal deletion, so the download counter rejects that case. Line 1762 updates link paths in place for moves, preserving the slug while the namespace changes. The fix must bind the post-lock open and counter to the current grant. This remains source evidence with reasoned impact, not a live reproduction.
Author
Owner

Started sharefix on job/sharefix, base 2f4482ded066d9c5d9c59130377907f7fd2916c9 (job/merge-round-7a). Scope: #755 public download current grant and opened item checks; #756 bounded blocking password work. No pushes or deploys. Regression checks use isolated local data.

Started sharefix on `job/sharefix`, base `2f4482ded066d9c5d9c59130377907f7fd2916c9` (`job/merge-round-7a`). Scope: #755 public download current grant and opened item checks; #756 bounded blocking password work. No pushes or deploys. Regression checks use isolated local data.
Author
Owner

Source checks confirm both audit findings. #755: download and preview now recheck a stored grant under the namespace lock, compare the opened inode and change token with the target, and release the lock before streaming. The download counter conditional write includes the same grant ID, owner, path, item ID, password hash, permissions, expiry and options. #756: hashing and verification share two blocking-worker permits and sixteen admission slots; workers keep both permits after request cancellation. The existing successful-password cache and five-attempt pair limit remain. Added aggregate reservations use the existing table (no migration): sixty per link and thirty per verified IP per fifteen-minute window. These work budgets and aggregate thresholds are implementation decisions not specified in DESIGN. Controlled tests check authority changes, replacement identity, limit accounting, cancellation, errors and async progress. Validation is in progress; no success claim yet.

Source checks confirm both audit findings. #755: download and preview now recheck a stored grant under the namespace lock, compare the opened inode and change token with the target, and release the lock before streaming. The download counter conditional write includes the same grant ID, owner, path, item ID, password hash, permissions, expiry and options. #756: hashing and verification share two blocking-worker permits and sixteen admission slots; workers keep both permits after request cancellation. The existing successful-password cache and five-attempt pair limit remain. Added aggregate reservations use the existing table (no migration): sixty per link and thirty per verified IP per fifteen-minute window. These work budgets and aggregate thresholds are implementation decisions not specified in DESIGN. Controlled tests check authority changes, replacement identity, limit accounting, cancellation, errors and async progress. Validation is in progress; no success claim yet.
Author
Owner

Atomic #755 fix committed as f00b76f7747051cc7feb72817a4431a4f92c00ac. The isolated source builds; focused public tests pass:

test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 155 filtered out; finished in 71.20s

Formatting passes. Clippy is still running, and full final gates are pending. The cold build took 32m 14s on the shared host. The #756 slice and local-server checks follow.

Atomic #755 fix committed as `f00b76f7747051cc7feb72817a4431a4f92c00ac`. The isolated source builds; focused public tests pass: ```text test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 155 filtered out; finished in 71.20s ``` Formatting passes. Clippy is still running, and full final gates are pending. The cold build took 32m 14s on the shared host. The #756 slice and local-server checks follow.
Author
Owner

Files Clippy completed successfully:

    Checking calternal-plugin-files v0.0.1 (/home/kayg/Developer/calternal-wt/sharefix/crates/plugins/files)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 43m 25s

The duration includes waiting for the isolated cold build. Read-only review found no confirmed production defect. It identified missing deterministic coverage for a held descriptor and a selected folder child. The added test covers both, including a fresh path read and rejection of the former item ID. The full Files suite is building. The server build and server gates are queued. A bounded local lifecycle/three-User probe and local performance profile are written; neither has run yet.

Files Clippy completed successfully: ```text Checking calternal-plugin-files v0.0.1 (/home/kayg/Developer/calternal-wt/sharefix/crates/plugins/files) Finished `dev` profile [unoptimized + debuginfo] target(s) in 43m 25s ``` The duration includes waiting for the isolated cold build. Read-only review found no confirmed production defect. It identified missing deterministic coverage for a held descriptor and a selected folder child. The added test covers both, including a fresh path read and rejection of the former item ID. The full Files suite is building. The server build and server gates are queued. A bounded local lifecycle/three-User probe and local performance profile are written; neither has run yet.
Author
Owner

The final Files binary compiled and the new password budget, cancellation, oversized-input and atomic rate-limit tests passed. The new folder descriptor test failed at the root-grant recheck. An isolated rerun confirmed that its generic index::record(Folder) refresh invalidated the Folder grant. The fixture now uses index::refresh_parent, the helper used by owner writes, to preserve the Folder identity. Every assertion remains unchanged. The corrected focused suite is queued. This is a new test fixture correction, not a change to an existing expectation.

The two-hour job budget has about 25 minutes left. The server build and server gates remained blocked on the Files test build directory. I stopped those pending commands to prioritize the corrected Files checks. The real-server probe and performance profile are written but have not run. They remain validation gaps until the current server can be built.

The final Files binary compiled and the new password budget, cancellation, oversized-input and atomic rate-limit tests passed. The new folder descriptor test failed at the root-grant recheck. An isolated rerun confirmed that its generic `index::record(Folder)` refresh invalidated the Folder grant. The fixture now uses `index::refresh_parent`, the helper used by owner writes, to preserve the Folder identity. Every assertion remains unchanged. The corrected focused suite is queued. This is a new test fixture correction, not a change to an existing expectation. The two-hour job budget has about 25 minutes left. The server build and server gates remained blocked on the Files test build directory. I stopped those pending commands to prioritize the corrected Files checks. The real-server probe and performance profile are written but have not run. They remain validation gaps until the current server can be built.
Author
Owner

Head: 06a71a516 (job/sharefix). The grant binding, descriptor regression, password worker/rate limits, local lifecycle probe and benchmark are committed as separate concerns.

Final-source Files Clippy passed:

    Checking calternal-plugin-files v0.0.1 (/home/kayg/Developer/calternal-wt/sharefix/crates/plugins/files)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 20m 27s

The corrected focused public tests now have the build directory. The original full suite compiled, passed the password tests and failed the folder fixture; it was stopped after that fixture was corrected. Full Files validation and server/runtime/performance validation are not complete.

Head: `06a71a516` (`job/sharefix`). The grant binding, descriptor regression, password worker/rate limits, local lifecycle probe and benchmark are committed as separate concerns. Final-source Files Clippy passed: ```text Checking calternal-plugin-files v0.0.1 (/home/kayg/Developer/calternal-wt/sharefix/crates/plugins/files) Finished `dev` profile [unoptimized + debuginfo] target(s) in 20m 27s ``` The corrected focused public tests now have the build directory. The original full suite compiled, passed the password tests and failed the folder fixture; it was stopped after that fixture was corrected. Full Files validation and server/runtime/performance validation are not complete.
Author
Owner

Committed fixes for #755 and #756 on job/sharefix. Validation is incomplete at the two-hour job limit.

Built:

  • Public download and inline preview recheck the current grant under the namespace mutation lock. The opened descriptor must match the current path token and selected item ID. Download counters update only the checked grant. The namespace lock ends before streaming.
  • Password creation, updates and verification use bounded blocking workers. Cancellation keeps each permit until the blocking work ends. Input length is checked before admission. Pair, link and verified-IP work reservations are atomic. The existing salted positive-password cache remains.
  • Deterministic grant, descriptor, worker, cancellation and rate-limit tests.
  • An isolated real-server lifecycle probe with a three-User matrix and a local performance profile.

Files:

  • crates/plugins/files/src/public.rs
  • crates/plugins/files/src/lib.rs: test fixture visibility only.
  • tests/adversarial/public_links.mjs
  • bench/public-links-755.mjs

Decisions:

  • Reuse current grant fields as the authority snapshot. No migration is needed. Counter changes do not invalidate concurrent reads.
  • Use two password workers, sixteen admitted requests and a five-second queue wait. Keep five guesses per link/IP pair. Add sixty work reservations per link and thirty per verified IP in fifteen minutes. Aggregate reservations remain after success; correct cached passwords bypass work.
  • Use the existing rate-limit table with wildcard aggregate keys, which cannot be real slugs or IP addresses.
  • The benchmark uses a 64 KiB typical read, a 32 MiB original burst and a bounded cold password burst. The baseline has no matching public-link/password metric. No comparison or measured result is claimed until it runs.

UX gaps closed: changed grants cannot authorize later original-byte reads; password CPU work no longer occupies async request workers. Correct gallery credentials keep the existing cache behavior. No UI files changed.
UX gaps left: no new UI scope. Broader sharing changes in DESIGN §54 remain with their jobs.

Known gaps: final full Files suite, server gates, real-server probe, three-User matrix and benchmark execution remain to be confirmed. No screenshots are needed for this backend-only change. No dependency or migration changes. No push or deploy.

Head: 06a71a516cba67b8e89d5c5182b53bdffd5d132f.
Base: 2f4482ded066d9c5d9c59130377907f7fd2916c9. The required fetch and merge of origin/dev ran once and returned Already up to date.

Gate output (verbatim excerpts):

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

Final-source cargo clippy -p calternal-plugin-files --all-targets -- -D warnings:

    Blocking waiting for file lock on build directory
    Checking calternal-plugin-files v0.0.1 (/home/kayg/Developer/calternal-wt/sharefix/crates/plugins/files)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 20m 27s

Isolated #755 cargo test -p calternal-plugin-files public::tests -- --test-threads=2:

test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 155 filtered out; finished in 71.20s

The initial full Files suite compiled. Its new folder fixture failed; the corrected fixture uses the owner write path parent refresh without changing assertions. The old run was stopped after that correction. Its password tests reported:

test public::tests::password_aggregate_limits_are_atomic ... ok
test public::tests::password_budget_bounds_waiters_and_retains_cancelled_workers ... ok
test public::tests::password_budget_releases_errors_and_rejects_long_input ... ok

The server build and Clippy commands were stopped while waiting for the Files build directory. Server tests did not start. JavaScript syntax checks passed without output. The production web build passed; web source did not change. No runtime or performance result is claimed.

Corrected focused test run, stopped during compilation at the job limit:

    Blocking waiting for file lock on build directory
   Compiling calternal-plugin-files v0.0.1 (/home/kayg/Developer/calternal-wt/sharefix/crates/plugins/files)

Original full Files run (the new fixture failure, unchanged assertions):

test public::tests::folder_link_checks_open_handle_and_selected_identity ... FAILED

Server Clippy output before cancellation:

    Blocking waiting for file lock on package cache
    Blocking waiting for file lock on build directory

Handoff: rerun the corrected focused tests and full Files suite, then build and run server Clippy/tests. Build the production web app, run tests/adversarial/public_links.mjs once with this server, and run bench/public-links-755.mjs once. Record local latency/CPU/RSS against the baseline; no matching metric exists yet. No actual three-User or runtime/performance result is claimed. The worktree is clean. Web build output was removed, and cargo clean was requested for the job target. Review artifacts remain only under ignored artifacts/.

Committed fixes for #755 and #756 on `job/sharefix`. Validation is incomplete at the two-hour job limit. Built: - Public download and inline preview recheck the current grant under the namespace mutation lock. The opened descriptor must match the current path token and selected item ID. Download counters update only the checked grant. The namespace lock ends before streaming. - Password creation, updates and verification use bounded blocking workers. Cancellation keeps each permit until the blocking work ends. Input length is checked before admission. Pair, link and verified-IP work reservations are atomic. The existing salted positive-password cache remains. - Deterministic grant, descriptor, worker, cancellation and rate-limit tests. - An isolated real-server lifecycle probe with a three-User matrix and a local performance profile. Files: - `crates/plugins/files/src/public.rs` - `crates/plugins/files/src/lib.rs`: test fixture visibility only. - `tests/adversarial/public_links.mjs` - `bench/public-links-755.mjs` Decisions: - Reuse current grant fields as the authority snapshot. No migration is needed. Counter changes do not invalidate concurrent reads. - Use two password workers, sixteen admitted requests and a five-second queue wait. Keep five guesses per link/IP pair. Add sixty work reservations per link and thirty per verified IP in fifteen minutes. Aggregate reservations remain after success; correct cached passwords bypass work. - Use the existing rate-limit table with wildcard aggregate keys, which cannot be real slugs or IP addresses. - The benchmark uses a 64 KiB typical read, a 32 MiB original burst and a bounded cold password burst. The baseline has no matching public-link/password metric. No comparison or measured result is claimed until it runs. UX gaps closed: changed grants cannot authorize later original-byte reads; password CPU work no longer occupies async request workers. Correct gallery credentials keep the existing cache behavior. No UI files changed. UX gaps left: no new UI scope. Broader sharing changes in DESIGN §54 remain with their jobs. Known gaps: final full Files suite, server gates, real-server probe, three-User matrix and benchmark execution remain to be confirmed. No screenshots are needed for this backend-only change. No dependency or migration changes. No push or deploy. Head: `06a71a516cba67b8e89d5c5182b53bdffd5d132f`. Base: `2f4482ded066d9c5d9c59130377907f7fd2916c9`. The required fetch and merge of `origin/dev` ran once and returned `Already up to date.` Gate output (verbatim excerpts): `cargo fmt --check`: exit 0, no output. Final-source `cargo clippy -p calternal-plugin-files --all-targets -- -D warnings`: ```text Blocking waiting for file lock on build directory Checking calternal-plugin-files v0.0.1 (/home/kayg/Developer/calternal-wt/sharefix/crates/plugins/files) Finished `dev` profile [unoptimized + debuginfo] target(s) in 20m 27s ``` Isolated #755 `cargo test -p calternal-plugin-files public::tests -- --test-threads=2`: ```text test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 155 filtered out; finished in 71.20s ``` The initial full Files suite compiled. Its new folder fixture failed; the corrected fixture uses the owner write path parent refresh without changing assertions. The old run was stopped after that correction. Its password tests reported: ```text test public::tests::password_aggregate_limits_are_atomic ... ok test public::tests::password_budget_bounds_waiters_and_retains_cancelled_workers ... ok test public::tests::password_budget_releases_errors_and_rejects_long_input ... ok ``` The server build and Clippy commands were stopped while waiting for the Files build directory. Server tests did not start. JavaScript syntax checks passed without output. The production web build passed; web source did not change. No runtime or performance result is claimed. Corrected focused test run, stopped during compilation at the job limit: ```text Blocking waiting for file lock on build directory Compiling calternal-plugin-files v0.0.1 (/home/kayg/Developer/calternal-wt/sharefix/crates/plugins/files) ``` Original full Files run (the new fixture failure, unchanged assertions): ```text test public::tests::folder_link_checks_open_handle_and_selected_identity ... FAILED ``` Server Clippy output before cancellation: ```text Blocking waiting for file lock on package cache Blocking waiting for file lock on build directory ``` Handoff: rerun the corrected focused tests and full Files suite, then build and run server Clippy/tests. Build the production web app, run `tests/adversarial/public_links.mjs` once with this server, and run `bench/public-links-755.mjs` once. Record local latency/CPU/RSS against the baseline; no matching metric exists yet. No actual three-User or runtime/performance result is claimed. The worktree is clean. Web build output was removed, and `cargo clean` was requested for the job target. Review artifacts remain only under ignored `artifacts/`.
Author
Owner

Cleanup completed. The worktree is clean. Web build output was removed.

     Removed 8854 files, 3.3GiB total
Cleanup completed. The worktree is clean. Web build output was removed. ```text Removed 8854 files, 3.3GiB total ```
Author
Owner

Read-only review started on job/rev2-sharefix. Review base: 440e19dce2. Target: 06a71a516. No builds, tests, servers or browsers will run. Findings will be committed in this worktree.

Read-only review started on job/rev2-sharefix. Review base: 440e19dce23040ac8ebaae88f0469b6535b1afcb. Target: 06a71a516. No builds, tests, servers or browsers will run. Findings will be committed in this worktree.
Author
Owner

Independent review of public links — #755

Reviewed head: 06a71a516 on job/sharefix.
Review branch: job/rev2-sharefix.
Review base: 440e19dce23040ac8ebaae88f0469b6535b1afcb.

Result

One P2 test coverage finding. No source-confirmed blocking product defect
was found in the focused changes. Runtime behavior remains unverified.
Add the route regression test below to complete the evidence for #755.

Findings, ranked by severity

P2 — The route tests do not cover the original lock-wait race

File: crates/plugins/files/src/public.rs:2694, with related tests at
lines 2556 and 2643. All line numbers refer to the reviewed head.

opened_public_item_requires_current_identity replaces the file before it
calls download or preview at line 2722. Both route calls start with a stale
Index identity. The old authorization check already rejects that state.
This route assertion cannot detect the old check-order defect.

The grant-change test calls the new helpers directly. The folder test checks
the held descriptor through a helper. These tests cover useful invariants.
However, they still pass if a route omits its new checks after the lock wait.
This leaves the main scheduling regression in #755 without a route test.

Fix: add a test barrier after initial authorization and before lock
acquisition. Use isolated data. Change the target identity or grant at that
barrier. Resume the route. Assert refusal, no file body, and no download
counter increment. Cover both download and preview. Verify that restoring
the old route sequence makes the test fail. Keep existing expectations.
Rule: #755 regression requirement and DESIGN §26.

Tracking: keep this finding on #755. Issue searches for password and
public download found the existing #755 and #756. No separate issue is
needed. No defect outside this branch was confirmed.

Source checks

  • Grant and item: download takes the namespace lock before its second
    grant check (public.rs:1948). open_link_file checks the root identity,
    selected item identity, and the descriptor against the current path token
    (public.rs:961). The owner ID remains part of each Index lookup.
  • Counter: the conditional write matches the grant ID, owner, path,
    item ID, stored permissions, password hash, expiry, limit, presentation
    and hidden-name setting (public.rs:993). Counter changes alone do not
    invalidate parallel reads. Expiry and the limit are checked in the write.
  • Preview: it uses the same open helper, preserves text size and Range
    checks, and checks the grant again before response construction
    (public.rs:1989). Both routes release the namespace lock before body
    streaming. This matches the explicit fix in #755. It does not recall bytes
    from an already opened response.
  • Password work: the process-wide budget has two work permits and
    sixteen admission permits (public.rs:392). Excess requests and waits
    longer than five seconds return 429. Both permits move into the blocking
    closure, so request cancellation cannot admit replacement work while its
    worker still runs (public.rs:425). Owner hashing uses the same budget.
  • Rate limits: pair, link and verified-IP reservations share one
    transaction (public.rs:890). A refused aggregate reservation rolls back
    earlier increments. Empty and oversized passwords are refused before
    reservation. The positive password cache remains available without worker
    admission. Authorization is checked again after an uncached success.
  • Errors: the new busy error says try again shortly. Failed password
    checks say password required. Stale identity and grant checks return
    404. A failed conditional download count returns 403 and no file body.
  • Reuse: searched Files identity, fingerprint and read helpers, and
    the App Password worker pattern. The new code reuses identity_at_path,
    locate, Root reads, user_bytes, and the existing verified-IP helper.
    The test fixture addition in lib.rs:4288 only exposes an existing test
    helper. The two public original-byte routes share their new open checks.
  • Comments: the new module text and helper comments explain the lock,
    grant snapshot, descriptor check, permit lifetime and aggregate counters.
    They cite #755, #756 or DESIGN. The route regression test comment needs
    stronger route evidence, as described in the P2 finding.
  • Test history: read git log -p for the focused changes in public.rs,
    lib.rs and tests/adversarial/public_links.mjs. No existing assertion,
    status expectation or fixture was weakened in those commits. The added
    worker test uses controlled channels and checks unrelated async progress,
    cancellation and bounds. The added lifecycle probe checks ordinary reads,
    password changes, expiry, limits and three Users. None of these tests ran
    in this review.
  • Performance: original bodies stream after the lock is released.
    Password CPU work runs outside the async worker and namespace lock.
    The extra identity checks add Index reads while holding the namespace lock.
    bench/public-links-755.mjs covers a 64 KiB read, cached credentials,
    eight concurrent 32 MiB reads, and a 32-request cold password burst. It
    records p50/p95, CPU and RSS. No measurements or author report were used.

Scope and decisions

The requested origin/dev...06a71a516 diff includes changes from the merged
round-7a branch. Its merge base is c4a61e8cf090170f35b1bed3350d9de20c83ecd5.
The review inspected that diff, then isolated the job changes after
2f4482ded: public.rs, the test fixture visibility in lib.rs, the public
link lifecycle probe, and the benchmark. Unrelated feature changes in the
three-dot diff are outside this review.

Read CLAUDE.md, CONTEXT.md, #755, #756 and relevant DESIGN text (§§21,22,26,54).
DESIGN §58 is absent from the review checkout. At the target head it is
Agent discovery and setup, not an interactive performance contract.
The review therefore used the stated performance owner rules and examined
the hot path directly. No dependency or version changes were proposed.
No product design decisions were made.

Verification and known gaps

Gates: Not run — the LIGHT job forbids builds and tests. There is no
gate output to quote. No servers, browsers, adversarial runs or benchmarks
ran. Compilation, runtime status codes, latency and memory remain unverified.
No product code changed. No merge, push or deployment was made.

Built: two review documents, audit-findings.md and review-sharefix.md.
UX gaps closed: none; this is a source review. UX gaps left: no UI was
tested. The only confirmed review gap is the P2 regression test above.

Review head: 26bb03a24dc61eafa1b894bbdb8d09086aa154a7.
Document check: git diff --check exited 0 with no output.
Working tree: git status --short returned no output after the commit.

# Independent review of public links — #755 Reviewed head: `06a71a516` on `job/sharefix`. Review branch: `job/rev2-sharefix`. Review base: `440e19dce23040ac8ebaae88f0469b6535b1afcb`. ## Result One P2 test coverage finding. No source-confirmed blocking product defect was found in the focused changes. Runtime behavior remains unverified. Add the route regression test below to complete the evidence for #755. ## Findings, ranked by severity ### P2 — The route tests do not cover the original lock-wait race File: `crates/plugins/files/src/public.rs:2694`, with related tests at lines 2556 and 2643. All line numbers refer to the reviewed head. `opened_public_item_requires_current_identity` replaces the file before it calls download or preview at line 2722. Both route calls start with a stale Index identity. The old authorization check already rejects that state. This route assertion cannot detect the old check-order defect. The grant-change test calls the new helpers directly. The folder test checks the held descriptor through a helper. These tests cover useful invariants. However, they still pass if a route omits its new checks after the lock wait. This leaves the main scheduling regression in #755 without a route test. Fix: add a test barrier after initial authorization and before lock acquisition. Use isolated data. Change the target identity or grant at that barrier. Resume the route. Assert refusal, no file body, and no download counter increment. Cover both download and preview. Verify that restoring the old route sequence makes the test fail. Keep existing expectations. Rule: #755 regression requirement and DESIGN §26. Tracking: keep this finding on #755. Issue searches for `password` and `public download` found the existing #755 and #756. No separate issue is needed. No defect outside this branch was confirmed. ## Source checks - **Grant and item:** download takes the namespace lock before its second grant check (`public.rs:1948`). `open_link_file` checks the root identity, selected item identity, and the descriptor against the current path token (`public.rs:961`). The owner ID remains part of each Index lookup. - **Counter:** the conditional write matches the grant ID, owner, path, item ID, stored permissions, password hash, expiry, limit, presentation and hidden-name setting (`public.rs:993`). Counter changes alone do not invalidate parallel reads. Expiry and the limit are checked in the write. - **Preview:** it uses the same open helper, preserves text size and Range checks, and checks the grant again before response construction (`public.rs:1989`). Both routes release the namespace lock before body streaming. This matches the explicit fix in #755. It does not recall bytes from an already opened response. - **Password work:** the process-wide budget has two work permits and sixteen admission permits (`public.rs:392`). Excess requests and waits longer than five seconds return 429. Both permits move into the blocking closure, so request cancellation cannot admit replacement work while its worker still runs (`public.rs:425`). Owner hashing uses the same budget. - **Rate limits:** pair, link and verified-IP reservations share one transaction (`public.rs:890`). A refused aggregate reservation rolls back earlier increments. Empty and oversized passwords are refused before reservation. The positive password cache remains available without worker admission. Authorization is checked again after an uncached success. - **Errors:** the new busy error says `try again shortly`. Failed password checks say `password required`. Stale identity and grant checks return 404. A failed conditional download count returns 403 and no file body. - **Reuse:** searched Files identity, fingerprint and read helpers, and the App Password worker pattern. The new code reuses `identity_at_path`, `locate`, `Root` reads, `user_bytes`, and the existing verified-IP helper. The test fixture addition in `lib.rs:4288` only exposes an existing test helper. The two public original-byte routes share their new open checks. - **Comments:** the new module text and helper comments explain the lock, grant snapshot, descriptor check, permit lifetime and aggregate counters. They cite #755, #756 or DESIGN. The route regression test comment needs stronger route evidence, as described in the P2 finding. - **Test history:** read `git log -p` for the focused changes in `public.rs`, `lib.rs` and `tests/adversarial/public_links.mjs`. No existing assertion, status expectation or fixture was weakened in those commits. The added worker test uses controlled channels and checks unrelated async progress, cancellation and bounds. The added lifecycle probe checks ordinary reads, password changes, expiry, limits and three Users. None of these tests ran in this review. - **Performance:** original bodies stream after the lock is released. Password CPU work runs outside the async worker and namespace lock. The extra identity checks add Index reads while holding the namespace lock. `bench/public-links-755.mjs` covers a 64 KiB read, cached credentials, eight concurrent 32 MiB reads, and a 32-request cold password burst. It records p50/p95, CPU and RSS. No measurements or author report were used. ## Scope and decisions The requested `origin/dev...06a71a516` diff includes changes from the merged round-7a branch. Its merge base is `c4a61e8cf090170f35b1bed3350d9de20c83ecd5`. The review inspected that diff, then isolated the job changes after `2f4482ded`: public.rs, the test fixture visibility in lib.rs, the public link lifecycle probe, and the benchmark. Unrelated feature changes in the three-dot diff are outside this review. Read CLAUDE.md, CONTEXT.md, #755, #756 and relevant DESIGN text (§§21,22,26,54). DESIGN §58 is absent from the review checkout. At the target head it is **Agent discovery and setup**, not an interactive performance contract. The review therefore used the stated performance owner rules and examined the hot path directly. No dependency or version changes were proposed. No product design decisions were made. ## Verification and known gaps Gates: **Not run — the LIGHT job forbids builds and tests.** There is no gate output to quote. No servers, browsers, adversarial runs or benchmarks ran. Compilation, runtime status codes, latency and memory remain unverified. No product code changed. No merge, push or deployment was made. Built: two review documents, `audit-findings.md` and `review-sharefix.md`. UX gaps closed: none; this is a source review. UX gaps left: no UI was tested. The only confirmed review gap is the P2 regression test above. Review head: `26bb03a24dc61eafa1b894bbdb8d09086aa154a7`. Document check: `git diff --check` exited 0 with no output. Working tree: `git status --short` returned no output after the commit.
Author
Owner

Round 2 started on job/sharefix, head/base 06a71a516cba67b8e89d5c5182b53bdffd5d132f. Read the contract, DESIGN §§21,22,26,54, issue history and independent review. One P2 finding: add deterministic post-authorization route coverage for both original-byte routes. No dependency or migration changes planned. Latest verification policy reserves full matrices, release builds and non-performance benchmarks for the merge round; focused local lifecycle regression remains in this job.

Round 2 started on `job/sharefix`, head/base `06a71a516cba67b8e89d5c5182b53bdffd5d132f`. Read the contract, DESIGN §§21,22,26,54, issue history and independent review. One P2 finding: add deterministic post-authorization route coverage for both original-byte routes. No dependency or migration changes planned. Latest verification policy reserves full matrices, release builds and non-performance benchmarks for the merge round; focused local lifecycle regression remains in this job.
Author
Owner

P2 route coverage added in public.rs: task-local, test-only barriers pause download and preview after initial authorization and before namespace lock acquisition. Four isolated cases change either the item's identity or the stored password. Assertions require 404, a JSON error body without file disposition or replacement content, and download_count = 0. Existing expectations are unchanged. origin/dev merged once without conflicts as 98675b214200acf08df635635d4b79c270d8c1cc; only sandbox support and DESIGN text changed. Focused regression compilation is in progress from the cleaned job target.

P2 route coverage added in `public.rs`: task-local, test-only barriers pause download and preview after initial authorization and before namespace lock acquisition. Four isolated cases change either the item's identity or the stored password. Assertions require 404, a JSON error body without file disposition or replacement content, and download_count = 0. Existing expectations are unchanged. `origin/dev` merged once without conflicts as `98675b214200acf08df635635d4b79c270d8c1cc`; only sandbox support and DESIGN text changed. Focused regression compilation is in progress from the cleaned job target.
Author
Owner

Checkpoint: 9825eb1b89442297e7869df5e699626dd770939c adds the review P2 route regression in public.rs. The worktree is clean. cargo fmt --check: exit 0, no output. The cold dependency build is still in progress; compilation and tests have NOT passed yet. This test-only slice was committed within the checkpoint window to preserve the work while builds continue. Production route behavior is unchanged by this commit.

Checkpoint: `9825eb1b89442297e7869df5e699626dd770939c` adds the review P2 route regression in `public.rs`. The worktree is clean. `cargo fmt --check`: exit 0, no output. The cold dependency build is still in progress; compilation and tests have NOT passed yet. This test-only slice was committed within the checkpoint window to preserve the work while builds continue. Production route behavior is unchanged by this commit.
Author
Owner

The committed Files source compiled. The full suite is running (166 tests), with no failures so far. New route and corrected fixture evidence:

test public::tests::folder_link_checks_open_handle_and_selected_identity ... ok
test public::tests::public_download_revalidates_after_authorization_before_lock ... ok
test public::tests::public_preview_revalidates_after_authorization_before_lock ... ok
test public::tests::password_aggregate_limits_are_atomic ... ok
test public::tests::password_budget_bounds_waiters_and_retains_cancelled_workers ... ok
test public::tests::password_budget_releases_errors_and_rejects_long_input ... ok

The first cold compile succeeded in 59m 29s. Its original filter matched zero tests after splitting the regression names; it is not counted as regression evidence. The complete Files suite above executes both committed regression tests. Server gates and the focused local lifecycle/three-User check remain pending.

The committed Files source compiled. The full suite is running (166 tests), with no failures so far. New route and corrected fixture evidence: ```text test public::tests::folder_link_checks_open_handle_and_selected_identity ... ok test public::tests::public_download_revalidates_after_authorization_before_lock ... ok test public::tests::public_preview_revalidates_after_authorization_before_lock ... ok test public::tests::password_aggregate_limits_are_atomic ... ok test public::tests::password_budget_bounds_waiters_and_retains_cancelled_workers ... ok test public::tests::password_budget_releases_errors_and_rejects_long_input ... ok ``` The first cold compile succeeded in 59m 29s. Its original filter matched zero tests after splitting the regression names; it is not counted as regression evidence. The complete Files suite above executes both committed regression tests. Server gates and the focused local lifecycle/three-User check remain pending.
Author
Owner

Full Files suite passed on 9825eb1b89442297e7869df5e699626dd770939c. Both review P2 route tests and the corrected folder descriptor fixture passed. No existing assertion was changed.

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

The ignored test is the existing loopback/rclone 10,000-file transfer test. Final formatting, Files Clippy, server Clippy/tests and a debug server build are starting, in sequence. The vulnerable original route sequence was not restored or executed; that requested negative reproduction is not claimed. Current-code defensive regressions and normal local lifecycle/three-User checks are the validation scope.

Full Files suite passed on `9825eb1b89442297e7869df5e699626dd770939c`. Both review P2 route tests and the corrected folder descriptor fixture passed. No existing assertion was changed. ```text test result: ok. 165 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 497.65s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` The ignored test is the existing loopback/rclone 10,000-file transfer test. Final formatting, Files Clippy, server Clippy/tests and a debug server build are starting, in sequence. The vulnerable original route sequence was not restored or executed; that requested negative reproduction is not claimed. Current-code defensive regressions and normal local lifecycle/three-User checks are the validation scope.
Author
Owner

Final formatting and both per-crate Clippy gates passed on 9825eb1b89442297e7869df5e699626dd770939c.

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

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

    Checking calternal-plugin-files v0.0.1 (/home/kayg/Developer/calternal-wt/sharefix/crates/plugins/files)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 12m 05s

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

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 4m 28s

Server tests, the debug server build and focused local lifecycle/three-User validation are next. No production source changed in this round. No full workspace gates or performance measurements ran.

Final formatting and both per-crate Clippy gates passed on `9825eb1b89442297e7869df5e699626dd770939c`. `cargo fmt --check`: exit 0, no output. `cargo clippy -p calternal-plugin-files --all-targets -- -D warnings`: ```text Checking calternal-plugin-files v0.0.1 (/home/kayg/Developer/calternal-wt/sharefix/crates/plugins/files) Finished `dev` profile [unoptimized + debuginfo] target(s) in 12m 05s ``` `cargo clippy -p calternal-server --all-targets -- -D warnings`: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 4m 28s ``` Server tests, the debug server build and focused local lifecycle/three-User validation are next. No production source changed in this round. No full workspace gates or performance measurements ran.
Author
Owner

Validation progress: formatting, Files Clippy, server Clippy and the full Files suite have passed. The server unit-test target has finished compilation and is linking now; no server test result is claimed yet. The local debug build and public_links.mjs lifecycle/three-User check follow in the same sequential pipeline. Head remains 9825eb1b89442297e7869df5e699626dd770939c; the worktree is clean and there is no uncommitted code. Cargo has four build jobs and tests have two threads. No additional source change was needed after the review regression.

Validation progress: formatting, Files Clippy, server Clippy and the full Files suite have passed. The server unit-test target has finished compilation and is linking now; no server test result is claimed yet. The local debug build and `public_links.mjs` lifecycle/three-User check follow in the same sequential pipeline. Head remains `9825eb1b89442297e7869df5e699626dd770939c`; the worktree is clean and there is no uncommitted code. Cargo has four build jobs and tests have two threads. No additional source change was needed after the review regression.
Author
Owner

Server tests passed on 9825eb1b89442297e7869df5e699626dd770939c:

    Finished `test` profile [unoptimized + debuginfo] target(s) in 26m 31s
test result: ok. 161 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 103.44s

All required per-crate Rust gates have passed. The debug server build is now running so the focused local lifecycle/three-User check can use this branch. The live check has not run yet. No extra source fixes were needed, and existing expectations remain unchanged.

Server tests passed on `9825eb1b89442297e7869df5e699626dd770939c`: ```text Finished `test` profile [unoptimized + debuginfo] target(s) in 26m 31s test result: ok. 161 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 103.44s ``` All required per-crate Rust gates have passed. The debug server build is now running so the focused local lifecycle/three-User check can use this branch. The live check has not run yet. No extra source fixes were needed, and existing expectations remain unchanged.
Author
Owner

All required Rust gates passed. The normal debug server target is still building. Its compiler has waited on disk I/O; there is no reported compile error. The focused local lifecycle/three-User check remains pending and is not claimed as passed. Head is unchanged (9825eb1b89442297e7869df5e699626dd770939c), with no uncommitted code. The job continues toward that live check; no repeat suites, release build or benchmark has run.

All required Rust gates passed. The normal debug server target is still building. Its compiler has waited on disk I/O; there is no reported compile error. The focused local lifecycle/three-User check remains pending and is not claimed as passed. Head is unchanged (`9825eb1b89442297e7869df5e699626dd770939c`), with no uncommitted code. The job continues toward that live check; no repeat suites, release build or benchmark has run.
Author
Owner

Round 2 report — #755 / #756

Head: 9825eb1b89442297e7869df5e699626dd770939c on job/sharefix.
Start head: 06a71a516cba67b8e89d5c5182b53bdffd5d132f.
Merged origin/dev once, at c4faf184df726a9375ae0c13bdfb6018ac2cf57e, in commit 98675b214200acf08df635635d4b79c270d8c1cc. This includes 440e19dce. No push or deployment was made.

Built:

  • Added task-local test barriers to download and preview, after initial authorization and before namespace lock acquisition. They compile only in tests.
  • Added two named route regressions. Each changes either the item identity or password at that barrier, then requires 404, a JSON error without file disposition or replacement bytes, and download_count = 0.
  • Reused the isolated owner fixture. No existing expectation changed. No production behavior changed in this round.

Files:

  • Changed this round: crates/plugins/files/src/public.rs (commit 9825eb1b8).
  • Existing branch changes validated: that file, the fixture visibility in crates/plugins/files/src/lib.rs, and tests/adversarial/public_links.mjs.
  • Existing performance profile: bench/public-links-755.mjs; not measured in this job.

Findings and validation:

  • The corrected folder fixture passed. Both new route regressions passed. Password work bounds, cancellation and atomic reservation tests passed.
  • Full Files tests and both per-crate Clippy gates passed. Server tests passed.
  • One focused check ran against this branch's real local server. It passed reads, rename and replacement, password changes and cache use, limits, expiry, and a three-User matrix. No failure required another source fix.
  • The first cold test compilation used a filter whose name changed when the tests were split. It matched zero tests and is not regression evidence. The later full Files run executed both committed tests.
  • Doc comments in the touched files were read again before this report.

Gate and validation output (verbatim summaries):

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

Files Clippy (cargo clippy -p calternal-plugin-files --all-targets -- -D warnings)

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 12m 05s

Files tests (cargo test -p calternal-plugin-files -- --test-threads=2)

    Finished `test` profile [unoptimized + debuginfo] target(s) in 53m 04s
test result: ok. 165 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 497.65s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

Server Clippy (cargo clippy -p calternal-server --all-targets -- -D warnings)

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 4m 28s

Server tests (cargo test -p calternal-server -- --test-threads=2)

    Finished `test` profile [unoptimized + debuginfo] target(s) in 26m 31s
test result: ok. 161 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 103.44s

Debug server build (cargo build -p calternal-server)

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 99m 56s

Production web build (cd apps/web && bun run build)

✓ built in 21.79s
✓ built in 28ms
✓ built in 1m 11s
  ✔ done

Focused live check (bun tests/adversarial/public_links.mjs)

public-link lifecycle, password cache, limit and three-User matrix: PASS

UX gaps closed:

  • This round closes route-level regression coverage for post-authorization changes. It verifies the branch's existing public-link lifecycle and User isolation fixes. No UI feature was added.

UX gaps left:

  • No UI change or screenshot scope. Broader sharing UI work remains with its own jobs.

Decisions:

  • No new product decisions. Task-local barriers isolate parallel tests and add no production hook.
  • Existing branch decisions remain: compare stored authority fields without a migration; counters alone do not invalidate reads. Use two password workers, sixteen admitted requests, a five-second wait, five pair attempts, sixty link reservations and thirty verified-IP reservations per fifteen minutes. DESIGN does not set these numeric work budgets.

Known gaps:

  • The original vulnerable route sequence was not restored or executed. The requested old-sequence negative reproduction is not claimed; current-code defensive regressions passed.
  • One Files test and five server tests are ignored by their suites. The server's separate-process live-app test passed. No ignored performance/stress profile was added to this run.
  • No benchmark numbers are claimed. The latest verification policy reserves performance work outside this non-performance job. docs/perf/baseline.json has no matching public-link/password-work metric.
  • Full web suites, full e2e and broad matrices did not run, per the latest verification policy. No dependency or migration change.

For the merge round:

  • cd apps/web && bun run check && bun run test: validate the combined web branch.
  • cd apps/web && bun run test:e2e: validate the combined production app.
  • python3 tests/adversarial/xuser_matrix.py and python3 tests/adversarial/authz_matrix.py: the broader User isolation and authorization matrices on the merge round's local fixture.
  • On the perf VM, with CALTERNAL_SERVER_BIN set to the shared release binary: flock /root/perf.lock bash -c 'uptime; bun bench/public-links-755.mjs'. Record load inside the lock, then record latency, CPU and RSS. There is no matching baseline metric yet.

Cleanup:

  • Cargo cleanup and removal of the web build output completed. The worktree is clean. Review logs remain only in ignored artifacts/.
     Removed 15972 files, 8.7GiB total

Automatic approval review rejected the initial rm -rf cleanup command. The scoped Python cleanup completed successfully instead.

Round 2 report — #755 / #756 Head: `9825eb1b89442297e7869df5e699626dd770939c` on `job/sharefix`. Start head: `06a71a516cba67b8e89d5c5182b53bdffd5d132f`. Merged `origin/dev` once, at `c4faf184df726a9375ae0c13bdfb6018ac2cf57e`, in commit `98675b214200acf08df635635d4b79c270d8c1cc`. This includes `440e19dce`. No push or deployment was made. Built: - Added task-local test barriers to download and preview, after initial authorization and before namespace lock acquisition. They compile only in tests. - Added two named route regressions. Each changes either the item identity or password at that barrier, then requires 404, a JSON error without file disposition or replacement bytes, and download_count = 0. - Reused the isolated owner fixture. No existing expectation changed. No production behavior changed in this round. Files: - Changed this round: `crates/plugins/files/src/public.rs` (commit `9825eb1b8`). - Existing branch changes validated: that file, the fixture visibility in `crates/plugins/files/src/lib.rs`, and `tests/adversarial/public_links.mjs`. - Existing performance profile: `bench/public-links-755.mjs`; not measured in this job. Findings and validation: - The corrected folder fixture passed. Both new route regressions passed. Password work bounds, cancellation and atomic reservation tests passed. - Full Files tests and both per-crate Clippy gates passed. Server tests passed. - One focused check ran against this branch's real local server. It passed reads, rename and replacement, password changes and cache use, limits, expiry, and a three-User matrix. No failure required another source fix. - The first cold test compilation used a filter whose name changed when the tests were split. It matched zero tests and is not regression evidence. The later full Files run executed both committed tests. - Doc comments in the touched files were read again before this report. Gate and validation output (verbatim summaries): `cargo fmt --check`: exit 0, no output. Files Clippy (`cargo clippy -p calternal-plugin-files --all-targets -- -D warnings`) ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 12m 05s ``` Files tests (`cargo test -p calternal-plugin-files -- --test-threads=2`) ```text Finished `test` profile [unoptimized + debuginfo] target(s) in 53m 04s test result: ok. 165 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 497.65s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` Server Clippy (`cargo clippy -p calternal-server --all-targets -- -D warnings`) ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 4m 28s ``` Server tests (`cargo test -p calternal-server -- --test-threads=2`) ```text Finished `test` profile [unoptimized + debuginfo] target(s) in 26m 31s test result: ok. 161 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 103.44s ``` Debug server build (`cargo build -p calternal-server`) ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 99m 56s ``` Production web build (`cd apps/web && bun run build`) ```text ✓ built in 21.79s ✓ built in 28ms ✓ built in 1m 11s ✔ done ``` Focused live check (`bun tests/adversarial/public_links.mjs`) ```text public-link lifecycle, password cache, limit and three-User matrix: PASS ``` UX gaps closed: - This round closes route-level regression coverage for post-authorization changes. It verifies the branch's existing public-link lifecycle and User isolation fixes. No UI feature was added. UX gaps left: - No UI change or screenshot scope. Broader sharing UI work remains with its own jobs. Decisions: - No new product decisions. Task-local barriers isolate parallel tests and add no production hook. - Existing branch decisions remain: compare stored authority fields without a migration; counters alone do not invalidate reads. Use two password workers, sixteen admitted requests, a five-second wait, five pair attempts, sixty link reservations and thirty verified-IP reservations per fifteen minutes. DESIGN does not set these numeric work budgets. Known gaps: - The original vulnerable route sequence was not restored or executed. The requested old-sequence negative reproduction is not claimed; current-code defensive regressions passed. - One Files test and five server tests are ignored by their suites. The server's separate-process live-app test passed. No ignored performance/stress profile was added to this run. - No benchmark numbers are claimed. The latest verification policy reserves performance work outside this non-performance job. `docs/perf/baseline.json` has no matching public-link/password-work metric. - Full web suites, full e2e and broad matrices did not run, per the latest verification policy. No dependency or migration change. For the merge round: - `cd apps/web && bun run check && bun run test`: validate the combined web branch. - `cd apps/web && bun run test:e2e`: validate the combined production app. - `python3 tests/adversarial/xuser_matrix.py` and `python3 tests/adversarial/authz_matrix.py`: the broader User isolation and authorization matrices on the merge round's local fixture. - On the perf VM, with `CALTERNAL_SERVER_BIN` set to the shared release binary: `flock /root/perf.lock bash -c 'uptime; bun bench/public-links-755.mjs'`. Record load inside the lock, then record latency, CPU and RSS. There is no matching baseline metric yet. Cleanup: - Cargo cleanup and removal of the web build output completed. The worktree is clean. Review logs remain only in ignored `artifacts/`. ```text Removed 15972 files, 8.7GiB total ``` Automatic approval review rejected the initial `rm -rf` cleanup command. The scoped Python cleanup completed successfully instead.
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#755
No description provided.