Required PDF attachment handoff — fictional workshop proposal Purpose: only the currently selected, server-validated file enters the submission. Selection, transfer, validation and application acceptance are separate. Input: one PDF, 1–10,000,000 bytes inclusive. The label is 10MB or smaller; 10MB means 10,000,000 bytes here. Empty, password-protected or rejected files cannot complete. Browser checks guide users; the server validates again. Selection: cancelling the picker preserves the current attachment. Selecting a new file excludes the previous one and advances the selection version. Invalid replacement never silently restores the old file. Preserve other form inputs. States: unselected → transferring → receipt confirmed → checking → current attachment usable. At 100%, unknown receipt means Confirming transfer. Known receipt with pending validation means Checking file. Neither permits submission. Completion: match current selection and attempt, server attachment ID, proposal association and validation pass. Compare server status versions so an old checking response cannot regress a completed state. Rejection: give actionable reasons for type, size, empty file, password or failed validation. A validation-service outage is not proof of a defective file; keep it unapproved and provide status checking/recovery. Removal/replacement: immediately invalidate local eligibility and old responses, and invalidate/exclude the old selection on the server. A late success cannot reattach it. UI removal, aborting transport and deletion of temporary server bytes are different outcomes. Same name: a replacement is a new selection and attempt. Associate the server attachment identifier, not just the filename. Unknown result: query the original attempt. Do not resend while it is processing. After a confirmed failure/non-receipt, resend only under an engineering-confirmed same-content/same-attempt deduplication and transition contract. Replacement uses a new attempt. Without that contract, provide status checking and explicit new selection instead of automatic resending. Submit: explain why an unready required attachment blocks submission. The server rechecks ownership, proposal association, selection version and validation consistently with acceptance. Prevent attachment changes during acceptance. If the result is unknown, query the same application identifier; do not create another application. After acceptance: preserve its attachment independently of the editing selection. This example provides no post-acceptance replacement. Decide temporary expiry, permanent retention and deletion separately with the actual service owner. Accessibility: retain a native file input and keyboard access. Announce textual progress/status without unnecessary focus movement. Keep error instructions and the file input reachable. Documents and owners: the proposal explains need, completion criteria and alternatives. The spec maps states, copy, versions, requests/responses and exceptions. Engineering verifies validation, permission, concurrency, deduplication and temporary-file lifetime; QA compares UI sequences with actual attachment IDs; operations needs traceable status and response guidance. Acceptance evidence: execute boundaries, 100%, rejection, checker outage, same-name replacement, late success after removal, old status responses, unknown results, changed permission and changes/duplicates during acceptance. Record environment, version, owner, expected/actual result and evidence. This handoff is not a passed integration test of a real server.