Files
thoughtsync/tests
bvandeusenandClaude Opus 4.8 be34fe8619
CI & Build / Python lint (push) Successful in 2s
CI & Build / TypeScript typecheck (push) Successful in 5s
CI & Build / Python tests (push) Successful in 8s
CI & Build / Build & push image (push) Successful in 32s
M9 S4: sync adopts serialization/parse_dt toolkit + normalizes push oracle
DRY:
- serialize.py: serialize_label_sync(label) = base serialize_label + the
  delta-only fields (sync_revision/purged_at/created_at via iso()). sync's
  changes() adopts it; the local _serialize_label_row near-dup is gone.
- sync adopts common.parse_dt (drops the byte-identical _parse_client_dt;
  4 call sites) and common.iso for the note delta augmentation. (Manual-label
  reconciliation was already shared in S3.) Fully folding the note
  re-augmentation into the serializer waits on the notes.py split.
- test_sync: drops the now-redundant _parse_client_dt test (parse_dt is
  covered in test_notes) + its dead import.

Security (issue — push existence-oracle): a foreign-owned id on push was
rejected with "not yours", distinguishing "another user's note" from a free
id. A legit client only pushes ids of notes it created, so that branch is
only hit by a probe (or ~0-prob UUID collision) — now a GENERIC "cannot apply"
rejection that doesn't confirm the id exists. The residual create-vs-reject
status difference is inherent to client-chosen ids over a global PK and is
practically unexploitable (a shared note already exposes its id to recipients).

Sync behavior operator-verified on deploy (no Postgres CI lane).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FRgehjoz7Yv8LkUfADxACm
2026-07-23 21:45:36 -04:00
..