Skip to content

hashTree does not frame file byte length, so two distinct client-asset trees can digest identically and the prune deletes an edited copy #1670

Description

@philcunliffe

Duplicate of #1669 (same finding, keyed there); the deferred-finding marker moved to #1669 so retries reuse that identity.

Source: #1667 at d3133d6
Location: src/core/runtime/client_asset_ledger.js:258-276
Severity: minor

Evidence

Reproduced independently at d3133d6 and on a clean origin/master (0bd0035) worktree: trees {a:"", b:"hello"} and {a:"f:b\nhello"} both digest 561a36c026fd225bfef889ab7b15796c46e4d8aba852f55615e7248d6b02573c under digestClientAsset, byte-identical on both heads, so this PR neither introduces nor worsens it. A crafted edit that preserves the digest lets pruneOneAsset reach recorded.has(digest) === true (src/core/runtime/client_assets.js:864) and fs.rm the user's edited copy, and lets the refresh report it unchanged.

Expected behavior

Two distinct trees never digest equal; a user-edited copy always moves the digest and is withheld from the prune.

Why deferral is safe

Safe outside this PR, and not on pre-existence alone: the obvious repair (frame the byte length) changes every digest the hasher produces, invalidating every digest recorded in client-assets.json and marking every installed asset asset_edited on the next boot, which is the exact migration hazard Accepted LLP 0401 #migration (llp/0401:61) cites when rejecting the copier-side alternative, so the repair needs its own migration decision (versioned digest prefix, one-boot re-record, or an accepted asset_edited wave) rather than a hunk inside a one-issue symlink fix; and the delete-path consequence is reachable only through a deliberately crafted self-edit to a copy the user already owns, never by accident or remotely. Already filed as issue #1669 with neutral:fix; reuse that identity.

Acceptance condition

A test stages two distinct skill trees whose current digests collide (the pair above suffices) and asserts they digest differently after the fix, plus whatever the chosen migration decides happens to a client-assets.json written by the previous release.

Evidenced behavioral defect; eligible for automatic repair.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions