--- phase: 12.2 review: 12.2-REVIEW.md titles: json findings: - id: CR-01 severity: critical disposition: fixed title: "Form saves can commit before an in-flight upload reaches the deferred session" - id: CR-02 severity: critical disposition: fixed title: "Aborted or network-failed uploads have no idempotency or reconciliation path" - id: CR-03 severity: critical disposition: fixed title: "Core CRUD, settings, and relation mutation JSON bodies are uncapped" - id: WR-01 severity: warning disposition: fixed title: "A field may advertise a maximum file size that its request cap cannot carry" - id: WR-02 severity: warning disposition: fixed title: "Datetime picker bounds use local days while the server validates UTC days" - id: WR-03 severity: warning disposition: fixed title: "Concurrent reorder requests can overwrite the latest order or create a mixed order" - id: WR-04 severity: warning disposition: fixed title: "Pending pivot hydration discards type-conversion errors" open: 0 total: 7 recorded: 2026-10-02T21:15:00Z --- # Phase 12.2: Code Review Disposition | Finding | Severity | Disposition | Source | |---------|----------|-------------|--------| | CR-01 | critical | fixed | 516f9c9 — FormSession.beginUpload / activeUploads; FormView and RelationChildModal refuse save while uploads are in flight | | CR-02 | critical | fixed | 516f9c9 — X-Upload-Id stored on DeferredEnvelope.UploadID; abort deletes a stored file; network loss adopts a single pending extra | | CR-03 | critical | fixed | 516f9c9 — decodeCappedObject / decodeCappedRelationMutation / decodeCappedBulk + writeCRUDError maps MaxBytesError to 413 | | WR-01 | warning | fixed | 516f9c9 — boot rejects maxBytes + 64 KiB multipart overhead above upload_bytes | | WR-02 | warning | fixed | 516f9c9 — datetime bounds are UTC-day instants projected into the local zone | | WR-03 | warning | fixed | 516f9c9 — client serializes reorder (latest snapshot only); server locks visible files with FOR UPDATE | | WR-04 | warning | fixed | 516f9c9 — ShowPivot and updatePendingPivot return lifecycleFailure on lagoon.Fill errors | Dispositions: `open` (recorded, not yet triaged), `fixed`, `skipped`, `deferred`. Set `deferred` by hand and put the reason in the Source cell; both are preserved. A `|` in the reason is kept as prose and escaped on the next run. Re-running the gate keeps every row it can. A row the current review no longer reports is kept and its Source cell flagged, so a finding does not leave this record silently. ONE exception: when a finding id is REUSED by a different finding, the earlier decision cannot keep a row — the id is taken — and it is dropped. A RECORDED decision (anything but `open`) is named on the console when that happens; a row still at `open` is replaced silently, because `open` records no decision to lose.