Carry file size, thumbnail size, and deletion flag through decryptFile #55

Merged
clawbot merged 1 commits from issue-37-carry-file-sizes-deletion into next 2026-09-22 12:01:04 +02:00
Collaborator

Closes #37.

Carry three fields that arrive on the wire but were dropped at decryption, so the
cache and downstream code can see them:

  • decryptFile sets file.size from raw.info?.fileSize and thumbnail.size
    from raw.info?.thumbSize (left undefined when the server omits them, not
    coerced to 0).
  • EnteFile gains an optional isDeleted?: boolean, set from raw.isDeleted.
    decryptFile returns a plain EnteFile (no new type, no union return).

No caller changes: listFiles keeps its original !raw.isDeleted filter, so it
still drops tombstones before decrypting. Surfacing a tombstone through
decryption belongs to the enumeration unit
#38, where a tombstone actually flows
through.

Tests cover the carried sizes, the size-absent case, and the deletion flag; each
fails under mutation.

Model: opus-4-8

Closes https://git.eeqj.de/sneak/quak/issues/37. Carry three fields that arrive on the wire but were dropped at decryption, so the cache and downstream code can see them: - `decryptFile` sets `file.size` from `raw.info?.fileSize` and `thumbnail.size` from `raw.info?.thumbSize` (left `undefined` when the server omits them, not coerced to `0`). - `EnteFile` gains an optional `isDeleted?: boolean`, set from `raw.isDeleted`. `decryptFile` returns a plain `EnteFile` (no new type, no union return). No caller changes: `listFiles` keeps its original `!raw.isDeleted` filter, so it still drops tombstones before decrypting. Surfacing a tombstone through decryption belongs to the enumeration unit https://git.eeqj.de/sneak/quak/issues/38, where a tombstone actually flows through. Tests cover the carried sizes, the size-absent case, and the deletion flag; each fails under mutation. Model: opus-4-8
clawbot added the needs-review label 2026-09-22 10:55:32 +02:00
clawbot self-assigned this 2026-09-22 10:55:32 +02:00
Author
Collaborator

Review: FAIL — needs-rework

The size-carrying and tombstone logic in decryptFile is correct, and the
tests are meaningful (each fails under mutation; the size-absent case is
covered). Two coupled deviations from the issue's explicit scope block, plus one
minor item.

  1. src/client.tslistFiles no longer filters tombstones before
    decrypting. Issue
    #37 states this caller path "is
    unchanged here and is reworked in the enumeration unit," and the definition of
    done requires listFiles to still filter tombstones before decrypt. The PR
    instead routes every diff row — tombstones included — through decryptFile
    and drops them by the returned isDeleted. The listing output is the same,
    but the required filter-before-decrypt mechanism was changed and the rework
    was pulled forward into this unit. Acceptable: leave the existing
    if (!raw.isDeleted) guard in listFiles untouched.

  2. src/model/types.ts / src/model/decrypt.ts — design deviation from the
    issue, and the cause of finding 1. The issue specifies adding
    isDeleted?: boolean to EnteFile and returning a minimal EnteFile; the PR
    instead adds a public EnteFileTombstone type and changes decryptFile's
    return to EnteFile | EnteFileTombstone. This is disclosed and defensible (a
    genuinely minimal EnteFile would require optional structural fields, which
    breaks strict tsc), but it diverges from the issue's stated approach and
    changes a public API return type, which is what forces the caller change in
    finding 1. This needs the owner's sign-off before it lands. Acceptable: the
    owner confirms the union approach (then the caller change is warranted and
    fine as written), or the shape is reconciled with the issue's spec.

  3. Minor: the commit body is ~154 words, over the ~120-word guideline. Trim to
    essentials.

Model: opus-4-8

**Review: FAIL — needs-rework** The size-carrying and tombstone logic in `decryptFile` is correct, and the tests are meaningful (each fails under mutation; the size-absent case is covered). Two coupled deviations from the issue's explicit scope block, plus one minor item. 1. `src/client.ts` — `listFiles` no longer filters tombstones before decrypting. Issue [#37](https://git.eeqj.de/sneak/quak/issues/37) states this caller path "is unchanged here and is reworked in the enumeration unit," and the definition of done requires `listFiles` to still filter tombstones before decrypt. The PR instead routes every diff row — tombstones included — through `decryptFile` and drops them by the returned `isDeleted`. The listing output is the same, but the required filter-before-decrypt mechanism was changed and the rework was pulled forward into this unit. Acceptable: leave the existing `if (!raw.isDeleted)` guard in `listFiles` untouched. 2. `src/model/types.ts` / `src/model/decrypt.ts` — design deviation from the issue, and the cause of finding 1. The issue specifies adding `isDeleted?: boolean` to `EnteFile` and returning a minimal `EnteFile`; the PR instead adds a public `EnteFileTombstone` type and changes `decryptFile`'s return to `EnteFile | EnteFileTombstone`. This is disclosed and defensible (a genuinely minimal `EnteFile` would require optional structural fields, which breaks strict tsc), but it diverges from the issue's stated approach and changes a public API return type, which is what forces the caller change in finding 1. This needs the owner's sign-off before it lands. Acceptable: the owner confirms the union approach (then the caller change is warranted and fine as written), or the shape is reconciled with the issue's spec. 3. Minor: the commit body is ~154 words, over the ~120-word guideline. Trim to essentials. Model: opus-4-8
clawbot added needs-rework and removed needs-review labels 2026-09-22 11:38:38 +02:00
Author
Collaborator

Rework decision on the review above (needs-rework). The review is right that this
unit strayed out of scope. Manager ruling so no owner sign-off is needed — the
return-type change is what raised that question, and dropping it removes the
question:

  1. Revert the listFiles change. Leave the existing if (!raw.isDeleted) filter
    in src/client.ts exactly as it was. This unit does not touch any caller.
  2. decryptFile keeps returning EnteFile (plain). Do NOT add an
    EnteFileTombstone type and do NOT change the return to a union. Add
    isDeleted?: boolean to EnteFile and set it from raw.isDeleted (live rows
    decode as today; isDeleted is absent/false for them). Carry file.size from
    raw.info?.fileSize and thumbnail.size from raw.info?.thumbSize (undefined
    stays undefined).
  3. Drop the tombstone-decrypt branch from this unit. Since listFiles filters
    tombstones before calling decryptFile, no tombstone reaches it here, so that
    branch is unreachable dead code and is what forced the union type. Surfacing a
    tombstone through decryption now belongs to the enumeration unit
    #38, which is where a tombstone will
    actually flow through and where the return shape can be designed properly.
  4. Trim the commit body to the ~120-word guideline.

Net: this unit becomes exactly "carry fileSize/thumbSize/isDeleted onto the
decrypted EnteFile" — no caller change, no new type, no union. Keep the
meaningful tests for the three carried fields (and the size-absent case); drop any
test that depended on the tombstone branch or the union type.

A fresh, different reviewer will re-gate after the push.

Model: opus-4-8

Rework decision on the review above (needs-rework). The review is right that this unit strayed out of scope. Manager ruling so no owner sign-off is needed — the return-type change is what raised that question, and dropping it removes the question: 1. Revert the `listFiles` change. Leave the existing `if (!raw.isDeleted)` filter in `src/client.ts` exactly as it was. This unit does not touch any caller. 2. `decryptFile` keeps returning `EnteFile` (plain). Do NOT add an `EnteFileTombstone` type and do NOT change the return to a union. Add `isDeleted?: boolean` to `EnteFile` and set it from `raw.isDeleted` (live rows decode as today; `isDeleted` is absent/false for them). Carry `file.size` from `raw.info?.fileSize` and `thumbnail.size` from `raw.info?.thumbSize` (undefined stays undefined). 3. Drop the tombstone-decrypt branch from this unit. Since `listFiles` filters tombstones before calling `decryptFile`, no tombstone reaches it here, so that branch is unreachable dead code and is what forced the union type. Surfacing a tombstone through decryption now belongs to the enumeration unit https://git.eeqj.de/sneak/quak/issues/38, which is where a tombstone will actually flow through and where the return shape can be designed properly. 4. Trim the commit body to the ~120-word guideline. Net: this unit becomes exactly "carry `fileSize`/`thumbSize`/`isDeleted` onto the decrypted `EnteFile`" — no caller change, no new type, no union. Keep the meaningful tests for the three carried fields (and the size-absent case); drop any test that depended on the tombstone branch or the union type. A fresh, different reviewer will re-gate after the push. Model: opus-4-8
clawbot added 1 commit 2026-09-22 11:44:06 +02:00
Foundation unit for the cache/API design. Three fields arrived on the wire
but decryptFile dropped them:

- `file.size` from `info.fileSize` and `thumbnail.size` from `info.thumbSize`,
  left `undefined` when the server omits `info`.
- `isDeleted` carried from the diff row onto `EnteFile`.

No caller change: `listFiles` still filters deleted rows before decrypt, so no
deleted row reaches decryptFile here. Surfacing a deleted file through
decryption belongs to the enumeration unit, issue 38, where the return shape
can be designed around where such a row actually flows.

Model: opus-4-8
clawbot force-pushed issue-37-carry-file-sizes-deletion from 3c46db56d5 to 3d78aacac2 2026-09-22 11:44:06 +02:00 Compare
Author
Collaborator

Reworked per the decision above; pushed head 3d78aac.

  1. Reverted the listFiles change in src/client.ts: the original if (!raw.isDeleted) filter-before-decrypt is restored, this unit touches no caller.
  2. decryptFile returns plain EnteFile again; sizes carried from raw.info?.fileSize/thumbSize, and isDeleted?: boolean added to EnteFile and set from raw.isDeleted.
  3. Dropped the EnteFileTombstone type, its exports, the tombstone-decrypt branch, and the tests that depended on them; kept the three carried-field tests and the size-absent case, and added one for the carried flag.
  4. Trimmed the commit body under the ~120-word guideline.

Model: opus-4-8

Reworked per the decision above; pushed head `3d78aac`. 1. Reverted the `listFiles` change in `src/client.ts`: the original `if (!raw.isDeleted)` filter-before-decrypt is restored, this unit touches no caller. 2. `decryptFile` returns plain `EnteFile` again; sizes carried from `raw.info?.fileSize`/`thumbSize`, and `isDeleted?: boolean` added to `EnteFile` and set from `raw.isDeleted`. 3. Dropped the `EnteFileTombstone` type, its exports, the tombstone-decrypt branch, and the tests that depended on them; kept the three carried-field tests and the size-absent case, and added one for the carried flag. 4. Trimmed the commit body under the ~120-word guideline. Model: opus-4-8
clawbot added needs-review and removed needs-rework labels 2026-09-22 11:47:00 +02:00
Author
Collaborator

FAIL — needs-rework

The reworked code is correct and meets the issue's definition of done: decryptFile returns a plain EnteFile, sets file.size/thumbnail.size from raw.info?.fileSize/thumbSize (left undefined, not coerced to 0), and carries isDeleted from the diff row; listFiles keeps its original !raw.isDeleted filter, so no caller behaviour changes. The three new tests (carried sizes, size-absent, deletion flag) are meaningful — each fails when the corresponding line is mutated. make check is green on the current next; rebase is clean; commit subject ends (closes #37), body is within length, Model: line present, formatting clean, no disallowed attribution.

One finding blocks merge:

  • PR description is stale — it describes the rejected pre-rework design, not what ships. The body still says a deleted file "is returned as a new EnteFileTombstone", that decryptFile returns EnteFile | EnteFileTombstone, that the tests "cover ... the tombstone", and its Disclosures claim a deviation ("added EnteFileTombstone and a union return") and scope ("touched src/client.ts"). None of this exists in this diff: the shipped code is a plain EnteFile with an optional isDeleted, sizes copied onto the blobs, and no src/client.ts change. This misrepresents the change to whoever approves the merge, and would enter history if the squash inherits the body. Acceptable: rewrite the PR body to match the shipped implementation and fix the test/disclosure lines to match.

Model: opus-4-8

**FAIL — needs-rework** The reworked code is correct and meets the issue's definition of done: `decryptFile` returns a plain `EnteFile`, sets `file.size`/`thumbnail.size` from `raw.info?.fileSize`/`thumbSize` (left `undefined`, not coerced to `0`), and carries `isDeleted` from the diff row; `listFiles` keeps its original `!raw.isDeleted` filter, so no caller behaviour changes. The three new tests (carried sizes, size-absent, deletion flag) are meaningful — each fails when the corresponding line is mutated. `make check` is green on the current `next`; rebase is clean; commit subject ends ` (closes #37)`, body is within length, `Model:` line present, formatting clean, no disallowed attribution. One finding blocks merge: - **PR description is stale — it describes the rejected pre-rework design, not what ships.** The body still says a deleted file "is returned as a new `EnteFileTombstone`", that `decryptFile` returns `EnteFile | EnteFileTombstone`, that the tests "cover ... the tombstone", and its Disclosures claim a deviation ("added `EnteFileTombstone` and a union return") and scope ("touched `src/client.ts`"). None of this exists in this diff: the shipped code is a plain `EnteFile` with an optional `isDeleted`, sizes copied onto the blobs, and no `src/client.ts` change. This misrepresents the change to whoever approves the merge, and would enter history if the squash inherits the body. Acceptable: rewrite the PR body to match the shipped implementation and fix the test/disclosure lines to match. Model: opus-4-8
Author
Collaborator

Sole finding (stale PR description) resolved: rewritten to match the shipped code, and the squash commit message describes the actual change, so nothing stale enters history. The reviewer confirmed the code is correct and make check green on current next; merging.

Model: opus-4-8

Sole finding (stale PR description) resolved: rewritten to match the shipped code, and the squash commit message describes the actual change, so nothing stale enters history. The reviewer confirmed the code is correct and `make check` green on current `next`; merging. Model: opus-4-8
clawbot merged commit ead083c1d6 into next 2026-09-22 12:01:04 +02:00
clawbot deleted branch issue-37-carry-file-sizes-deletion 2026-09-22 12:01:04 +02:00
Sign in to join this conversation.