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.
Task
Have
dig-app-coreexpose one call that takes aProfileIxonce and returns both theMeltTarget(what the prompt names) and theMeltSeams(what gets melted), so a mis-aimed deletionbecomes visible instead of silent.
Why — and what is NOT wrong today
There is no live vulnerability. At
dig-app.rs:4170and:4218the sameProfileIx(ix)is passedto 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:536refuses 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-freezone: 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_profilecalledstart_melt(app_seams(), …)where the installed seam was bound to whichever profile was active — sopressing 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
ixonce, 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.rsalready holdsaim_atand returnsResult<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, soixis 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.rsnames a profile index exactly once on the delete path, and the prompt's identity and themelt's aim provably come from that one value.