You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
vibed/pages/.beans/pages-saom--core-policy-mod...

2.3 KiB

title status type priority created_at updated_at parent blocked_by
Core policy modules: slug, mime, upload validation, headers completed feature normal 2026-07-13T02:09:08Z 2026-07-13T02:42:56Z pages-77lk
pages-lxjz

Implement src/core/ per design doc §2.2, §2.3, §2.6, §4.5 — pure Rust, no worker deps, compiles + unit-tested natively.

slug.rs: validate_slug() enforcing ^[a-z0-9][a-z0-9-]{0,62}$ after lowercasing, reserved-name list from design §2.3, and default_slug_from_filename() (my-project.zip -> my-project, lowercased, invalid chars -> hyphen, collapse repeats/trim). mime.rs: extension->MIME allowlist (html, htm, css, js, mjs, json, txt, md, png, jpg, jpeg, gif, svg, webp, avif, ico, woff, woff2, ttf, otf, wasm, map, xml, webmanifest, mp3, mp4, webm, pdf); unknown -> application/octet-stream. upload.rs: UploadLimits (10 MiB compressed, 25 MiB uncompressed total, 5 MiB per file, 300 entries, path len 180, depth 10) and build_manifest(kind, bytes) -> Result<Vec<(String, Vec)>, UploadError>. Html kind -> single index.html entry. Zip kind: use zip crate, reject path traversal (.. segments, absolute, backslash), reject duplicates, skip directories, enforce limits while decompressing (count streamed bytes, abort on breach), require root index.html. Typed UploadError with user-facing Display messages. headers.rs: constants for CSP sandbox value (design §2.1), nosniff, referrer-policy, cache-control.

  • slug.rs + tests (valid/invalid/reserved/default-name derivation)
  • mime.rs + tests
  • upload.rs + tests (traversal, bomb via high-ratio zip, dup entries, missing index.html, happy paths html+zip) using zip writer in tests to build fixtures
  • headers.rs + tests
  • full validation suite passes (both targets)

Summary of Changes

src/core/ implemented by a Sonnet agent, adversarial Opus review (verdict: APPROVE, no bypasses found).

  • slug.rs (grammar + 17 reserved names + default_slug_from_filename), mime.rs (allocation-free allowlist), upload.rs (streaming zip validation: traversal, bombs, limits; html manifest), headers.rs (CSP sandbox etc.).
  • 72 native unit tests + 4 doctests incl. crafted-zip attack fixtures and accept-at-limit boundary cases (added post-review).
  • Design doc §2.2 wording reconciled (path length is bytes).