Skip to content

Replace file approval waits with temporary receive codes and prepare v0.4.0 - #19

Merged
CodePandaaAI merged 1 commit into
masterfrom
refactor-networking
Aug 28, 2026
Merged

Replace file approval waits with temporary receive codes and prepare v0.4.0#19
CodePandaaAI merged 1 commit into
masterfrom
refactor-networking

Conversation

@CodePandaaAI

Copy link
Copy Markdown
Owner

Why this change exists

This update began with a simple question:

Do file transfers still need an HTTP request waiting for someone to press
Accept or Decline?

The old flow worked, but it required several connected pieces:

  • an incoming-offer screen
  • an Accept/Decline decision
  • a deferred result connecting the UI to the HTTP request
  • a decision timeout
  • waiting states
  • coordination between acceptance and cancellation

Those pieces were understandable when text and files shared the same idea.
Text has since become a small, independent direct-delivery flow. That left
files as the only feature carrying the complete waiting system.

Instead of repeatedly simplifying that system, this change removes the need
for it.

The new idea

Every fresh Sync360 application session receives a temporary four-digit
file receive code.

The same code is visible on both the Send and Receive screens. When someone
wants to send files to that device, they select their files and target
device, then enter the code shown on the target.

The receiving device already knows its own code, so it can answer
immediately:

  • the code matches and the receiver is ready
  • the code is incorrect
  • the receiver is busy
  • the receiver could not prepare the file transfer

There is no receiver-side Accept or Decline screen and no HTTP request
waiting for a person to make a decision.

What the flow feels like now

  1. Open Sync360 on both devices.
  2. Read the four-digit code shown on the target device.
  3. Select files and click the target device.
  4. Enter the code.
  5. If it matches and the receiver is idle, the transfer starts.

The code is requested for every file send. Sending devices do not remember
it.

A fresh application session generates another code. Navigating between
screens or recomposing the UI does not change it.

Why this is simpler

The receiver no longer needs to publish an offer state and wait for the UI.

There is no deferred user decision, decision timeout, waiting-for-files
state, or Accept/Cancel timing gap.

The receiver performs one short atomic operation:

  1. Check that it is idle.
  2. Compare the code.
  3. Prepare the TCP receiver.
  4. Reserve the receiving state.
  5. Return the result.

Two simultaneous offers cannot both claim the receiver, and direct text
cannot claim it during the same operation.

What has not changed

The actual file-transfer foundation remains intact.

Files still use:

  • a unique operation ID
  • sender identity for matching cancellation
  • best-effort cancellation
  • a 30-second timeout if the accepted sender never opens TCP
  • one raw TCP connection for the complete batch
  • streamed bytes instead of loading whole files into memory
  • file index and size validation
  • sender and receiver progress
  • final success and completed-file counts
  • platform-specific incomplete-file cleanup

This change simplifies admission to a file transfer. It does not replace
the proven streaming and cleanup path underneath it.

Receive-code lifetime

The code is generated once by the application-scoped incoming controller.

Both the Send and Receive screens read that exact value. They do not
generate independent codes.

The code is:

  • kept only in memory
  • not stored between fresh application sessions
  • not advertised through device discovery
  • not remembered by sending devices
  • removed from the receiver's retained transfer metadata after acceptance

Failure behavior

Failure is explicit and bounded:

  • incorrect code: the sender receives a clear error and no receiver state changes
  • busy receiver: the sender is told that the target is busy
  • preparation failure: the sender does not start TCP
  • missing TCP sender after acceptance: the receiver clears the operation after 30 seconds
  • cancellation: the sender closes its local transfer and requests matching receiver cleanup
  • transfer failure: the current incomplete file is removed where supported
  • later file failure: files already completed remain in Downloads

Cancellation is still best effort. If cancellation and the offer cross on
the network in the opposite order, the receiver may remain reserved until
its 30-second timeout, but it recovers automatically and does not receive
file bytes from the cancelled sender.

Compatibility warning

This is a breaking file-protocol change.

The file-offer request now contains a receive code, and the response now
contains an explicit status. Sync360 0.4.0 therefore cannot transfer files
with 0.3.0 or older builds.

Both devices must be updated to 0.4.0.

The advertised preview protocol version intentionally remains 1 for now.
Because of that preview-stage decision, old and new devices may still
discover each other even though their file request formats are
incompatible. Seeing a device in the nearby list does not guarantee
cross-version compatibility.

Security position

The four-digit code is a convenience check, not authentication.

It reduces accidental or casual unwanted file sends, but:

  • it has only 9,000 possible values
  • it travels over cleartext HTTP
  • attempts are not currently rate-limited
  • HTTP and raw TCP are not encrypted
  • sender identity is not cryptographically verified
  • file integrity is not cryptographically verified

Current builds should still be used only on private networks controlled by
the user.

Release preparation

This PR prepares Sync360 0.4.0:

  • Android version name 0.4.0
  • Android version code 4
  • Desktop package version 0.4.0
  • iOS marketing version 0.4.0
  • iOS project build number 4
  • protocol metadata remains 1
  • Windows MSI upgrade UUID remains unchanged
  • public documentation reflects the new flow and compatibility boundary

File sharing previously used the same general approval idea that text
sharing once used. The sender posted an offer, the HTTP request remained
open, and the receiver had to accept or decline it before the transfer
could continue.

After separating text into its own direct-delivery flow, the file path was
the only place that still needed this waiting system. Instead of trying to
make the waiting machinery smaller, this change asks whether that machinery
is still necessary.

Replace the receiver-side Accept/Decline step with a temporary four-digit
receive code.

Generate one code for each fresh application session and keep it only in
memory. Show the same code on both the Send and Receive screens so it is
available from the default screen. Do not advertise it through discovery,
persist it, or remember entered codes on sending devices.

When sending files, ask for the target device's code before creating the
transfer. Validate the input as exactly four ASCII digits in the UI,
ViewModel, and outgoing controller. Include the entered code with the file
metadata offer.

Make the receiver answer the file offer immediately with an accepted,
invalid-code, receiver-busy, or preparation-failed result. Under the
existing operation mutex, atomically check that the receiver is idle,
compare the code, prepare the platform TCP receiver, and publish the
ReceivingFiles state before returning acceptance.

Remove the file decision machinery that is no longer needed:

- remove UserDecision and CompletableDeferred
- remove IncomingFileOffer and WaitingForFiles states
- remove the receiver Accept/Decline screen
- remove the suspended decision request and its 50-second timeout
- remove the old Accept/Cancel response race

Keep the parts that still protect file-transfer correctness:

- operation IDs and sender IDs
- best-effort remote cancellation
- platform-owned first-connection timeout
- transfer progress and completed-file counts
- raw TCP framing and streamed file bytes
- file index and promised-size validation
- incomplete-file cleanup
- final batch result handling

Update navigation so compact devices open Receive when file reception
begins, and replace the old waiting-for-approval sender state with a clear
Preparing Files state.

Prepare preview version 0.4.0 across Android, Desktop, and iOS. Increment
Android and iOS build numbers to 4 while preserving the permanent Windows
MSI upgrade identity.

Refresh the README, changelog, architecture, development, roadmap, privacy,
security, store, screenshot, and project-context documentation. Explain
that the receive code is a convenience against accidental or casual sends,
not authentication, because it has a small keyspace, travels over cleartext
HTTP, and currently has no attempt throttling.

BREAKING CHANGE: the file-offer request and response format is incompatible
with Sync360 0.3.0 and older. Both devices must use matching 0.4.0 builds.
The advertised preview protocol version intentionally remains 1 for now,
so discovery may still show an older incompatible device.

No Gradle build, automated test, or runtime transfer test was performed.
@CodePandaaAI
CodePandaaAI merged commit 124a724 into master Aug 28, 2026
4 checks passed
@CodePandaaAI
CodePandaaAI deleted the refactor-networking branch August 28, 2026 06:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant