Over three merged changes and one accepted proposal in nad-agent, a few lessons crystallized that we have not seen written down elsewhere.
1. Validation before the prompt beats the prompt
A bare confirm? y/N teaches the human to type y. What changed
behavior was building a resolved preview before the question: the checksummed recipient the
transaction will actually use, the amount, the fee expectation for the current gas mode, the
balance before and after, and a simulated outcome. The human confirms a concrete effect, not
an intention.
To: 0x92936497B6ad2BA84b3f7Af22C9afF15f00b13B5
Amount: 0.01 MON
Gas: dry-run (simulated, nothing broadcast)
Balance: 0.5 -> 0.49 MON
confirm? [y/N]
2. Split the provably wrong from the probably wrong
A recipient whose mixed-case checksum fails is provably wrong: refuse it before the prompt even renders, with a non-zero exit in scripted mode. A send the simulator says will revert, or an amount above the current balance, is probably wrong: surface it as a warning line inside the preview and let the human decide.
Collapsing these two classes into one is what makes wallets either unsafe (everything is a warning) or unusable (everything is a refusal). Agents retry around soft errors, so the hard class must be genuinely hard.
3. Spend the friction budget where the stakes are
Per-action confirmation is the baseline, but not every context deserves equal friction. Switching the wallet to mainnet asks for one explicit typed acknowledgement per session, then stays out of the way. Escalate friction with stakes; do not tax every step equally, or the human stops reading.
4. Confirmation semantics must survive pipes
Agents do not only run in interactive terminals. Piped and scripted runs need the same confirm flow: answers are consumed from the script in order, a missing answer cancels the action, and a cancelled or refused write exits non-zero so an orchestrating agent sees the failure instead of assuming success. A permission model that only exists in a TTY is a demo, not a model.
5. The two industry models are halves, not alternatives
Per-step approval covers what the human can see; a declarative policy covers what the agent could do while nobody is looking. We have proposed the second half for nad-agent as a policy file the wallet enforces before the prompt: a per-send cap, a per-session budget, an address allowlist, each violation named explicitly.
Approval and lock-down compose: the policy bounds the blast radius, the preview makes each step inside those bounds legible.
No server to save you
None of this requires a custodial setup or a cloud. The whole flow runs against a local model and a self-custodial account, which is exactly why the guardrails have to live in the wallet code itself: there is no server to save you.
The work referenced here
- PR #38: mainnet guardrails (red banner, status warning, one-time send acknowledgement).
- PR #39: reliable non-TTY confirm semantics for piped and scripted runs.
- PR #43: resolved send preview (checksummed recipient, balance impact, simulation).
- Issue #46: declarative spend policy proposal (per-send cap, session budget, allowlist), accepted by the maintainer.
Feedback welcome, especially from teams shipping their own agent wallets.
Prooflines, August 2026.