Files
NetMesh/docs/research/sftp-resume-endpoint-identity.md

42 lines
2.0 KiB
Markdown
Raw Normal View History

# SFTP restart recovery must not guess another server
Audit baseline: `7b964ead21c1e176999557147914f4975a63f5c8`.
## Confirmed defect
`resolveHostForTransferEndpoint` used a display-name/hostname search when a
recorded host id no longer existed, and returned the first match when multiple
hosts shared a name. Dedicated resume used those credentials to open the target
and start uploading. A saved task for a deleted server could therefore send
its source file to an unrelated same-named server. Both endpoint directions and
folder recovery use this resolver.
Two regressions invoke `resumeTransferWithDedicatedSession`, with the real
resolver, scheduler, credential construction, and resume path but instrumented
bridge I/O. Before the fix, both selected an unrelated endpoint and called
`startStreamTransfer`: a deleted recorded id with one same-named replacement,
and a legacy task without an id with two same-named hosts. Both now stop before
opening or uploading.
## Fix contract
- A recorded host id is authoritative; absence must not fall back to a name.
- Legacy tasks without an id may resolve a name only if exactly one host matches.
- Preserve exact-id recovery, unique-name legacy recovery, and a still-live
original session when vault credentials are absent.
- Never select an arbitrary member of an ambiguous name match.
This does not freeze future edits to the connection options of an existing host
id; a persisted immutable endpoint snapshot would be a separate schema and
migration change. It also does not claim to explain all historical restart
failures from issue #3213 or #2638.
## Verification
`node --test --import tsx application/state/sftp/dedicatedTransferResume.test.ts`:
39 passed, including both regressions and existing single-file/folder restart,
remote-to-remote, source-validation, and live-session fallback tests.
Broader SFTP audit remains in progress in the sibling `codex/sftp-transfer-audit`
worktree; its first control-ordering fix is PR #3284.