docs(01-19): never deploy to user devices — verify post-OTA instead

archy-x250-mad2 is a user's device holding real funds. Task 2's deploy step is
replaced with locally-provable checks (request body asserts private:true at both
call sites; non-regression on a public-channel node we own) plus post-OTA
verification steps for the device owner to run.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
archipelago
2026-07-31 08:04:51 -04:00
co-authored by Claude Opus 5
parent 1f3e56147f
commit 516c3bfa07
@@ -97,21 +97,35 @@ broken Receive flow today.
</task>
<task type="checkpoint:human-verify" gate="blocking">
<name>Task 2: Confirm a real payment arrives on archy-x250-mad2</name>
<name>Task 2: Confirm the fix, then hand off to post-OTA verification</name>
<what-built>
Invoice creation now sets LND's `private` flag, so invoices embed a hop hint
for the node's unannounced channel and become routable from outside.
Invoice creation now sets LND's `private` flag at both call sites, so
invoices embed a hop hint for the node's unannounced channel and become
routable from outside.
</what-built>
<constraint priority="highest">
**`archy-x250-mad2` is a USER'S device holding real funds. Never deploy to
it, SSH to it, or run any command against it.** This fix reaches it only via
the normal OTA release, after the release is confirmed. Any verification
involving that node is performed by its owner after the release lands —
never by us, and never as a direct deploy.
</constraint>
<how-to-verify>
1. Deploy the patched `archipelago` binary to `archy-x250-mad2`.
2. Create a test invoice through the **wallet UI** (not raw `lncli`) — e.g. 100 sats.
3. `lncli decodepayreq <invoice>` → `route_hints` is populated with the
Olympus channel's `chan_id` (was `[]` before this fix).
4. Pay it from a real external wallet. Expected: the payment succeeds.
5. `lncli listinvoices` → that invoice shows a non-empty `htlcs` array and
`state: SETTLED`.
6. Sanity-check a node WITH public channels (e.g. archi-dev-box): creating and
paying an invoice there still works exactly as before.
Verifiable now, without touching any user device:
1. Tests assert the request body sent to LND's `/v1/invoices` carries
`"private": true` for BOTH `handle_lnd_createinvoice` (wallet Receive)
and `create_invoice` (paid-content/peer-files seller flow).
2. On a node under our control with only PUBLIC channels, creating and paying
an invoice still behaves exactly as before — no regression. Note the
limitation honestly: a public-channel node shows empty route hints even
when the fix is correct, so this checks non-regression only.
Post-OTA-release, performed by the device owner:
3. Create an invoice through the **wallet UI** (not raw `lncli`) — e.g. 100 sats.
4. `lncli decodepayreq <invoice>` → `route_hints` populated with the Olympus
channel's `chan_id` (was `[]` before this fix).
5. Pay it from a real external wallet; `lncli listinvoices` shows a non-empty
`htlcs` array and `state: SETTLED`.
</how-to-verify>
<resume-signal>Type "approved", or describe what you saw — which step, what happened instead.</resume-signal>
</task>