- nc chunked-upload MOVE assembly (#12): both branches now funnel through
update_file_streaming_with_perms, whose internal fork enforces Update on
the existing file OR Create on the parent folder / drive root. Pre-fix,
the create branch went through plain upload_file_streaming with no
authz.require — a Viewer on a shared drive could MKCOL → PUT chunks →
MOVE and land a brand-new file. Error mapping switched to AppError::from
so denials keep the graduated 403/404 shape.
- trash empty-for-drive: route through authz.require(Delete, Drive) instead
of the bespoke drives_with_delete_for check + hardcoded not_found. Viewer
now gets 403 (has Read), outsider stays 404 (no Read, anti-enum). Emits
the standard authz.denied event with visibility field instead of the
ad-hoc trash.empty_drive_rejected.
- tests/api/trash_per_drive.hurl: flip Viewer/Editor asserts 404 → 403;
new Step 11b regression pin for finding #10 (Editor restore + delete
attempts must 403 AND body must not contain "success":true — trips if
the historical substring-match-on-"not found" hack ever comes back).