Parent epic: https://github.com/DIG-Network/dig_ecosystem/issues/3166
Sibling of: #408
Found by: the #408 lane, during its blast-radius pass.
Nothing in production writes the automated-spend record
SpendJournal and SpendLog::append have no non-test caller anywhere in the workspace. Every
SpendIntent construction is in a test: crates/dig-node-service/src/spend_audit_cli.rs:310 (test
module) and crates/dig-node-service/tests/spend_audit_e2e.rs:36. control.rs and spend_audit_cli.rs
READ the record; nothing produces it. The mirror-coin collateral cycle — the producer the whole SPEC §23
section is written for — does not journal its spends.
Why this is a money lie and not a missing feature
control.spends.list on a real node therefore returns {"spends": [], "complete": true}, and by the
contract's own words that is an answer, not an absence:
spends: [] with complete: true means this node has moved no money unattended that matches the
filters.
So a node that IS signing mirror-coin spends automatically states, in the contract's sanctioned voice,
that it has moved no money unattended. That is worse than the #408 decode failure it sits beside: a
decode failure is loud on the client, whereas an empty page is silently reassuring, and the contract
went to deliberate lengths (complete, unreadable_lines, SpendAuditUnreadable) to make "nothing to
report" distinguishable from "I could not look" — a distinction this bypasses entirely, because the node
genuinely did look at a file nobody writes.
This is the accountability half of the §908 carve-out. The node signs mirror-coin spends without
per-spend approval because the record is readable afterwards. Today it is readable and empty.
Acceptance
The mirror-coin collateral cycle journals through SpendJournal — begin before it is permitted to
sign, and the terminal outcome written as a new revision — so a node that has collateralised a store
shows that spend in control.spends.list. Proven end to end rather than by unit test: a node that
performs the cycle, then a dign spends list that shows the row.
Note the ordering dependency: #408 fixes the SHAPE of the response and must land regardless, but this
ticket is what gives that shape anything to carry. dig-app#289 will otherwise land against a tab that
decodes correctly and renders nothing.
Parent epic: https://github.com/DIG-Network/dig_ecosystem/issues/3166
Sibling of: #408
Found by: the #408 lane, during its blast-radius pass.
Nothing in production writes the automated-spend record
SpendJournalandSpendLog::appendhave no non-test caller anywhere in the workspace. EverySpendIntentconstruction is in a test:crates/dig-node-service/src/spend_audit_cli.rs:310(testmodule) and
crates/dig-node-service/tests/spend_audit_e2e.rs:36.control.rsandspend_audit_cli.rsREAD the record; nothing produces it. The mirror-coin collateral cycle — the producer the whole SPEC §23
section is written for — does not journal its spends.
Why this is a money lie and not a missing feature
control.spends.liston a real node therefore returns{"spends": [], "complete": true}, and by thecontract's own words that is an answer, not an absence:
So a node that IS signing mirror-coin spends automatically states, in the contract's sanctioned voice,
that it has moved no money unattended. That is worse than the #408 decode failure it sits beside: a
decode failure is loud on the client, whereas an empty page is silently reassuring, and the contract
went to deliberate lengths (
complete,unreadable_lines,SpendAuditUnreadable) to make "nothing toreport" distinguishable from "I could not look" — a distinction this bypasses entirely, because the node
genuinely did look at a file nobody writes.
This is the accountability half of the §908 carve-out. The node signs mirror-coin spends without
per-spend approval because the record is readable afterwards. Today it is readable and empty.
Acceptance
The mirror-coin collateral cycle journals through
SpendJournal—beginbefore it is permitted tosign, and the terminal outcome written as a new revision — so a node that has collateralised a store
shows that spend in
control.spends.list. Proven end to end rather than by unit test: a node thatperforms the cycle, then a
dign spends listthat shows the row.Note the ordering dependency: #408 fixes the SHAPE of the response and must land regardless, but this
ticket is what gives that shape anything to carry. dig-app#289 will otherwise land against a tab that
decodes correctly and renders nothing.