# Pathrule Pattern: File Uploads and Object Storage (1.0.0)
# ::pathrule:package:file-uploads-object-storage

### [RULE] Create a bounded upload intent before transfer  (path: /src/api)
<!-- scope: folder | priority: high | strict -->

The server authorizes owner, purpose, size, content class, object key, operation, and expiry before any client writes bytes. A broad presigned request or shared storage credential lets clients choose arbitrary keys, overwrite objects, exceed quotas, or upload a type the product never intended to process. Enforce this boundary in /src/api so invalid work stops before it reaches another subsystem or creates an externally visible side effect.

- Generate an opaque server-owned object key that includes no filename, email, tenant secret, or trusted path fragment from the client.
- Bind the upload authorization to one tenant, subject, purpose, object key, method, maximum size, allowed content class, and short expiry.
- Reserve quota and an upload record before transfer, then release it when the intent expires or validation fails.
- Use multipart upload only through a tracked session with bounded part count, total size, completion, abort, and cleanup behavior.

Verification: Attempt key changes, method changes, oversized bodies, expired intents, cross-tenant reuse, duplicate completion, and abandoned multipart sessions; confirm storage and quota remain correct.

---

### [RULE] Quarantine bytes until independent validation completes  (path: /src/uploads)
<!-- scope: folder | priority: high | strict -->

New objects remain unavailable to users and processors until server-side type, structure, policy, and malware checks pass. Filename extensions, Content-Type headers, and browser previews are attacker-controlled hints and cannot establish that content is safe to serve or parse. Enforce this boundary in /src/uploads so invalid work stops before it reaches another subsystem or creates an externally visible side effect.

- Read the stored bytes from quarantine and validate signature, parseability, declared class, size, decompression limits, and product-specific structure.
- Run malware or content-disarm controls appropriate to the allowed type without sending sensitive files to an unapproved external scanner.
- Process risky formats in an isolated, resource-bounded worker with no ambient credentials or unnecessary network access.
- Publish by changing durable application state or copying to a delivery boundary only after every required check succeeds.

Verification: Upload polyglots, mismatched extensions and signatures, malformed archives, decompression bombs, scanner timeout, and clean fixtures; confirm only clean objects become addressable.

---

### [RULE] Authorize every download and serve safe content metadata  (path: /src/api)
<!-- scope: folder | priority: high | strict -->

Object possession and object-store URLs never replace application authorization, response isolation, and content disposition policy. A predictable key or leaked long-lived URL can bypass tenant access, while active content rendered inline can execute in the application's trusted origin. Enforce this boundary in /src/api so invalid work stops before it reaches another subsystem or creates an externally visible side effect.

- Resolve the object through application metadata, authorize the current principal and tenant, then issue a narrow short-lived download or stream it through the service.
- Set a server-controlled safe filename and Content-Disposition according to whether the type may render inline.
- Serve user-controlled active content from an isolated origin with restrictive headers rather than the application's authenticated origin.
- Log access with object and subject identifiers without placing secret URLs or personal filenames in routine telemetry.

Verification: Try cross-tenant IDs, guessed keys, revoked ownership, expired links, header injection filenames, and active HTML or SVG; confirm denial and origin isolation.

---

### [MEMORY] An upload is a two-phase resource  (path: /src/uploads)

Object storage can contain bytes before the application has validated, accepted, or made them visible, so existence is not completion. Track intent-created, transferring, uploaded, validating, ready, rejected, expired, and deleted states with idempotent transitions.

Keep object events as evidence that may trigger validation, not proof that the intended principal completed the intended upload. Reconcile records and storage when events are missing, duplicated, or reordered. Expose only ready objects to product queries and schedule cleanup for every terminal non-ready state. Keep the decision explicit at /src/uploads; moving it into an incidental caller makes behavior depend on which route happened to execute first.

See /src/jobs for reconciliation and scanning and /src/api for download authorization. That related boundary consumes this decision and carries the evidence that proves it still holds.

---

### [SKILL] test-file-upload-pipeline  (path: /)

---
name: test-file-upload-pipeline
description: Test file uploads across authorization, transfer, validation, scanning, publication, delivery, and cleanup failure paths.
---

# Test File Upload Pipeline

Run this procedure whenever the governed surface changes or its operational evidence becomes stale.

1. Create clean, malformed, oversized, mislabeled, polyglot, active-content, archive-bomb, malware-test, duplicate-name, and zero-byte fixtures for every allowed class.
2. Attempt cross-tenant keys, expired and replayed intents, changed methods, multipart abuse, concurrent completion, and quota races through the real storage integration.
3. Inject storage, event, parser, scanner, worker, database, and publish failures before and after each durable transition, then replay events and jobs.
4. Verify only ready objects are downloadable, active content is isolated, rejected and abandoned bytes expire, quotas reconcile, and audit events reveal no secret URL or personal filename.

Record the decision, failed checks, and follow-up owner with the change. A successful run leaves reproducible evidence that another reviewer can inspect without repeating the investigation from memory.
