docs release evidence p15 t03 backend processing - AlexandreZanata/Abastevo GitHub Wiki
P15-T03 — Bounded backend media processing
Status: LOCAL_DONE on codex/phase-15-lightweight-photos (phase PR
#39, draft). Issue: #36 (slice 3 of 5; issue stays open until the
phase PR merges). No migration, camera, storage or live-provider
contact in this slice.
Slice acceptance (frozen before coding)
- T03 (this commit) — forward revalidation lane beside deployed
v1:
media.InspectForward(JPEG magic + strict structure + 1600 edge / 2 MP header caps, zero pixel allocation on bombs),media.SanitizeForward(full decode + decoder-output re-encode across qualities 85/70/55, ≤3 attempts, >256 KiB refuses instead of crushing),application.VerifyForward(one download capped one byte past the 256 KiB server cap, claim bind, forward caps, sanitized JPEG upload, immutable copy expiry from first receipt = VERIFYING instant + 24 h). No client value widens anything: download bound, pixel caps, qualities and deadline are server constants; session MaxBytes never governs this lane. Worker concurrency stays serial per process (existing dispatcher: one claimed job at a time), so one image is ever in flight and the 2 MP header cap bounds its RSS; measured below. Cutover from v1 lands in P15-T04 with the timestamp migration; v1 untouched here.
What changed
adapters/media/forward.go—InspectForward,SanitizeForward,ForwardQualities(len == 3 attempts).application/verify.go— additiveOutcome.ExpiresAt(forward deadline; v1 leaves it zero).application/forward_verify.go—VerifyForwardorchestration with stable v1 reason codes.- Tests:
forward_test.go(happy, 20000² bomb header, 1601 edge, forged PNG/empty/truncated, EXIF strip + re-inspect, noisy over-cap refuse, 2 MP measured memory) +forward_verify_test.go(happy + expiry math, client-budget independence, corrupt/forged refusals, claim mismatch, terminal replay, interrupted upload).
RED → GREEN
- RED proven by accepting the first encode unconditionally (cap
check neutered): the noisy over-cap frame verifies instead of
refusing
too-large; GREEN on restore.
Validation (exact commands, this host)
cd backend && GOTOOLCHAIN=go1.27.1 go build ./... && sqlc vet
gofmt -l internal/modules/evidence
GOTOOLCHAIN=go1.27.1 go vet ./internal/modules/evidence/...
GOTOOLCHAIN=go1.27.1 go test -count=1 ./internal/modules/evidence/...
GOTOOLCHAIN=go1.27.1 go test -count=1 -race -tags=integration ./internal/modules/evidence/...
git diff --check
Outcome: build + sqlc vet clean (no schema change); 6 new
media + 6 new application suites green; whole evidence/...
unit + -race integration green; measured 2 MP sanitize heap
growth 3.3 MB vs 32 MiB hypothesis (10× headroom);
gofmt/vet/diff --check clean; secrets scan clean.
Limits (not claimed)
- Lane proven but not wired: v1 Verify serves traffic until the
T04 cutover +
received_atmigration (UpdatedAt-at-VERIFYING is the documented first-receipt proxy here). - 2 MP smooth-frame measurement is host-RSS evidence, not the P12-device + worker-RSS matrix (release horizon per owner decision pattern).
Rollback
Pure addition (one media file + test, one application file + test, one additive struct field): deleting them restores the tree. No migration, no flag, v1 behavior unchanged.
Next
P15-T04 expiry deletion and restore enforcement (#37, same branch). Issue #36 stays open until the phase PR merges.