Skip to content

Return the melt target and seam from one call so a mis-aimed deletion is visible, not silent #217

Description

@MichaelTaylor3d

Task

Have dig-app-core expose one call that takes a ProfileIx once and returns both the
MeltTarget (what the prompt names) and the MeltSeams (what gets melted), so a mis-aimed deletion
becomes visible instead of silent.

Why — and what is NOT wrong today

There is no live vulnerability. At dig-app.rs:4170 and :4218 the same ProfileIx(ix) is passed
to both calls, and the prompt's identity comes from the same anchor the seam melts. The security gate on
dig-app PR #216 confirmed it end to end.

And dig-account's rejection is a guarantee, not luck: dig-account-0.20.0/src/melt/melter.rs:536
refuses a signature under a key the index does not hold, before signing.

But that guarantee has a shape. It catches a half-wrong aim — one where the target and the seam
disagree. It cannot catch a consistently wrong aim, where both are wrong in the same way. And the
final index hand-off happens in bin/dig-app.rs, which this codebase repeatedly calls a test-free
zone
: reverting that line to the active slot still compiles, and nothing catches it.

That is exactly the defect the same PR already fixed once. Before it, delete_profile called
start_melt(app_seams(), …) where the installed seam was bound to whichever profile was active — so
pressing delete on any non-active card would have melted the active profile's two singletons,
irreversibly, with no layer below able to notice.

The fix, and why this shape rather than the bigger one

The lane that fixed it proposed moving the whole handler into core. This is cheaper and buys more:
take ix once, return both halves together.

Then a future mis-aim changes what the prompt names — the person about to authorise an irreversible
destruction sees the wrong profile's name and DID, and stops. It converts a silent wrong-destruction into
a visible one, which is the only protection that works when the calling site cannot be tested.

Scope

crates/dig-app-core/src/profile_melt/aim.rs already holds aim_at and returns
Result<MeltSeams, MeltUnaimed>. Extend it — or add one call beside it — to return the target too.
Update both call sites (dig-app.rs:4170, :4218) to consume it, so ix is written once.

Test

Assert the returned target and seam are derived from the same index — with at least three profiles
where the pressed one is neither first nor active, since a single-profile fixture agrees with every wrong
implementation.

Done when

bin/dig-app.rs names a profile index exactly once on the delete path, and the prompt's identity and the
melt's aim provably come from that one value.

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