docs: repoint migrated issue refs to spirekeeper numbers
Follow-up to the satmachineadmin->spirekeeper issue migration. The 20 open issues were recreated on aiolabs/spirekeeper with reassigned numbers; this repoints in-repo references to the migrated issues at their new spirekeeper numbers (#3->#1, #4->#2, #8->#4, #9->#5, #10->#6, #17->#11, #21->#12, #28->#16, #44->#20). References to closed/non- migrated satmachineadmin issues (#20/#22/#26/#29/#32/#37/#38/#39) stay pointing at the original repo where they were resolved. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
40639ee437
commit
439c47ceae
8 changed files with 14 additions and 14 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -10,5 +10,5 @@ data/
|
|||
|
||||
# uv lockfile — pyproject.toml still uses [tool.poetry] syntax, so uv lock
|
||||
# produces a header-only file that pins nothing. Ignore until the
|
||||
# PEP 621 migration lands (aiolabs/satmachineadmin#28).
|
||||
# PEP 621 migration lands (aiolabs/spirekeeper#16).
|
||||
uv.lock
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ def _build_partial_dispense_memo(
|
|||
async def settle_lp_balance(
|
||||
client: DcaClient, machine: Machine, data: SettleBalanceData
|
||||
) -> DcaPayment:
|
||||
"""Operator UX action — closes satmachineadmin#4.
|
||||
"""Operator UX action — closes spirekeeper#2.
|
||||
|
||||
Settle an LP's remaining fiat balance from the operator's chosen funding
|
||||
wallet at the rate the operator specified. Records a leg_type='settlement'
|
||||
|
|
@ -271,7 +271,7 @@ async def settle_lp_balance(
|
|||
async def apply_partial_dispense_and_redistribute(
|
||||
settlement_id: str, data: PartialDispenseData
|
||||
) -> DcaSettlement:
|
||||
"""Operator UX action — closes satmachineadmin#3.
|
||||
"""Operator UX action — closes spirekeeper#1.
|
||||
|
||||
When a bitSpire dispense fails mid-transaction (e.g., dispenser jam after
|
||||
6 of 10 bills), the operator confirms the actual amount dispensed and we
|
||||
|
|
@ -619,7 +619,7 @@ async def _pay_one_dca_leg(
|
|||
errors=errors,
|
||||
)
|
||||
# Best-effort auto-forward to LP's external LN address (closes
|
||||
# satmachineadmin#8). Skip if the DCA leg failed (nothing to forward).
|
||||
# spirekeeper#4). Skip if the DCA leg failed (nothing to forward).
|
||||
# If autoforward fails, sats stay in the LP's LNbits wallet — the
|
||||
# explicit safety constraint.
|
||||
if (
|
||||
|
|
@ -643,7 +643,7 @@ async def _attempt_autoforward(
|
|||
settlement: DcaSettlement,
|
||||
amount_sats: int,
|
||||
) -> None:
|
||||
"""LP auto-forward (best-effort) — closes satmachineadmin#8.
|
||||
"""LP auto-forward (best-effort) — closes spirekeeper#4.
|
||||
|
||||
Resolves the LP's configured LN address, requests a bolt11 invoice for
|
||||
the DCA leg's sat amount, and pays it from the LP's LNbits wallet. Each
|
||||
|
|
|
|||
|
|
@ -303,7 +303,7 @@ None of those need to change. The new layers slot in *above* them.
|
|||
| **S0 — Seed‑URL pairing + ATM keypair separation** | Provisioning script generates a fresh `nsec` for the ATM (already does — we just stop overwriting it with the operator's). Operator pastes a one‑shot QR/seed URL containing `{atm_npub, operator_npub, relay_list, signed_delegation_token}` at ATM first boot. | G3 (most of it), G9 | 1 week | None — purely on our side. Use existing NIP‑26 spec. |
|
||||
| **S1 — NIP‑40 expiration on all kind‑21000** | Every RPC carries `["expiration", now+5min]`. Handler refuses past‑expiration. ATM clock check on boot (warn if drift > 60s). | G4 | 1–2 days | Relay must support NIP‑40 (most do). |
|
||||
| **S2 — NIP‑26 delegation enforcement in nostr‑transport** | Handler parses `delegation` tag, validates sig over conditions, checks conditions match the event, looks up operator pubkey in roster. Reject events without a valid delegation. | G3 (rest), G7 (partially) | 1–2 weeks | LNbits PR upstream (or vendored fork on `aiolabs/lnbits` branch `nostr-transport-nip26`). |
|
||||
| **S3 — NIP‑57‑style settlement receipts** | After LNbits internal payment legs complete, publish a signed receipt event per settlement (and per leg if we want leg‑level audit). ATM subscribes; operator dashboard renders receipts side‑by‑side with `dca_settlements`. | G2, G7 | 1–2 weeks | **Kind allocation — DO NOT USE `kind:21001`.** That kind is claimed by CLINK (Offers) — collision caught during the 2026‑06‑02 CLINK primer review. Rotation off 21001 is tracked at `aiolabs/satmachineadmin#44`; target is the aiolabs reserved band **`22000–22099`** per the workspace rule in `~/dev/CLAUDE.md` (§ "Nostr kind allocations — avoid the CLINK band"). The earlier 21001 lock across `aiolabs/lnbits#22`, `aiolabs/satmachineadmin#17`, and the satmachine ATM is **SUPERSEDED** — pick the new kind before any of those land. Reusing `kind:9735` (zap receipt) is also off the table: NIP‑57 semantics don't apply to bitSpire cash‑out settlements. |
|
||||
| **S3 — NIP‑57‑style settlement receipts** | After LNbits internal payment legs complete, publish a signed receipt event per settlement (and per leg if we want leg‑level audit). ATM subscribes; operator dashboard renders receipts side‑by‑side with `dca_settlements`. | G2, G7 | 1–2 weeks | **Kind allocation — DO NOT USE `kind:21001`.** That kind is claimed by CLINK (Offers) — collision caught during the 2026‑06‑02 CLINK primer review. Rotation off 21001 is tracked at `aiolabs/spirekeeper#20`; target is the aiolabs reserved band **`22000–22099`** per the workspace rule in `~/dev/CLAUDE.md` (§ "Nostr kind allocations — avoid the CLINK band"). The earlier 21001 lock across `aiolabs/lnbits#22`, `aiolabs/spirekeeper#11`, and the satmachine ATM is **SUPERSEDED** — pick the new kind before any of those land. Reusing `kind:9735` (zap receipt) is also off the table: NIP‑57 semantics don't apply to bitSpire cash‑out settlements. |
|
||||
| **S4 — NIP‑78 per‑machine config + fleet roster** | Operator publishes `kind:30078` config + `kind:30000` fleet list. Handler cross‑checks ATM npub ∈ fleet; reads max‑withdraw/fee policy from config. | G1, G9 | 1 week | Define config schema; backwards‑compat path for pre‑NIP‑78 machines. |
|
||||
| **S5 — `sender_pubkey` persistence + signed metadata in Payment.extra** | When the dispatcher writes a Payment row, it stamps `Payment.extra.sender_pubkey`, `delegation_root`, and an HMAC over the key fields keyed by the LNbits server's own secret. Mutation post‑write breaks the HMAC. | G2 (DB‑side), G5, G6 | 3–5 days | LNbits PR — fairly localised. |
|
||||
| **S6 — Rate limiting + roster‑gated auto‑account** | Auto‑account‑from‑npub only fires if the npub appears in some operator's NIP‑78 fleet OR if an explicit "open enrollment" flag is set. Relay/handler‑level rate limit per pubkey. | G8, G9 | 1 week | LNbits PR. |
|
||||
|
|
@ -374,7 +374,7 @@ For an auditor or new contributor doing a walk‑through:
|
|||
| `~/dev/nostr-protocol/nips/57.md` | Lightning zaps & signed receipts. | Pattern source for S3. |
|
||||
| `~/dev/nostr-protocol/nips/78.md` | App‑specific replaceable events. | Source for S4. |
|
||||
|
||||
Existing Forgejo issues this report supersedes/consolidates: `aiolabs/satmachineadmin#9` (v2 epic), `#11` (security audit findings), `#12` (ATM pairing + bunker deep‑dive), `aiolabs/lamassu-next#44` (Payment.extra split). This document is the design that closes the security‑relevant subset of those.
|
||||
Existing Forgejo issues this report supersedes/consolidates: `aiolabs/spirekeeper#5` (v2 epic), `#11` (security audit findings), `#12` (ATM pairing + bunker deep‑dive), `aiolabs/lamassu-next#44` (Payment.extra split). This document is the design that closes the security‑relevant subset of those.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ async def m001_satmachine_v2_initial(db):
|
|||
concurrent process_settlement invocations.
|
||||
* notes on dca_settlements — append-only audit memo for partial-
|
||||
dispense recompute + operator-authored notes (see
|
||||
aiolabs/satmachineadmin#10 for the future structured audit table).
|
||||
aiolabs/spirekeeper#6 for the future structured audit table).
|
||||
"""
|
||||
# 1. Drop legacy v1 tables. IF EXISTS handles both fresh-install
|
||||
# paths (no-op) and migration from a v1 schema (cleans up).
|
||||
|
|
|
|||
|
|
@ -478,7 +478,7 @@ class UpdateSuperConfigData(BaseModel):
|
|||
|
||||
|
||||
class PartialDispenseData(BaseModel):
|
||||
"""Resolves satmachineadmin#3 — operator confirms actual bills dispensed
|
||||
"""Resolves spirekeeper#1 — operator confirms actual bills dispensed
|
||||
when bitSpire reports an error mid-dispense.
|
||||
|
||||
Either `dispensed_fraction` (0..1) for ratio-based recompute, or
|
||||
|
|
@ -550,7 +550,7 @@ class AppendSettlementNoteData(BaseModel):
|
|||
|
||||
|
||||
class SettleBalanceData(BaseModel):
|
||||
"""Resolves satmachineadmin#4 — operator settles small remaining LP balance
|
||||
"""Resolves spirekeeper#2 — operator settles small remaining LP balance
|
||||
from their own wallet at a specified exchange rate.
|
||||
|
||||
Use case: an LP has a small remaining fiat balance (e.g. 47 GTQ) that
|
||||
|
|
|
|||
2
nip44.py
2
nip44.py
|
|
@ -18,7 +18,7 @@ back to the helpers in this module against the stored `account.prvkey`.
|
|||
This module's runtime export footprint is therefore:
|
||||
- `encrypt_for` / `decrypt_from` — called by the LocalSigner fallback in
|
||||
`cassette_transport` until every operator on the instance is bunker-backed
|
||||
(S7 / aiolabs/satmachineadmin#21). Then those calls disappear too.
|
||||
(S7 / aiolabs/spirekeeper#12). Then those calls disappear too.
|
||||
- Everything else (encrypt_with_conversation_key, decrypt_with_conversation_key,
|
||||
get_conversation_key, padding helpers, error classes) is **test-only**:
|
||||
referenced by `tests/test_nip44_v2.py` to validate the wire format against
|
||||
|
|
|
|||
|
|
@ -1427,7 +1427,7 @@
|
|||
</q-dialog>
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- SETTLE BALANCE DIALOG (closes satmachineadmin#4) -->
|
||||
<!-- SETTLE BALANCE DIALOG (closes spirekeeper#2) -->
|
||||
<!-- =============================================================== -->
|
||||
<q-dialog v-model="settleBalanceDialog.show" persistent>
|
||||
<q-card :style="{minWidth: '480px', maxWidth: '95vw'}">
|
||||
|
|
|
|||
|
|
@ -458,7 +458,7 @@ async def api_settle_client_balance(
|
|||
data: SettleBalanceData,
|
||||
user: User = Depends(check_user_exists),
|
||||
) -> DcaPayment:
|
||||
"""Operator UX — closes satmachineadmin#4.
|
||||
"""Operator UX — closes spirekeeper#2.
|
||||
|
||||
Settle an LP's remaining fiat balance from the operator's chosen funding
|
||||
wallet at the specified exchange rate. The amount_fiat is capped at the
|
||||
|
|
@ -692,7 +692,7 @@ async def api_partial_dispense(
|
|||
data: PartialDispenseData,
|
||||
user: User = Depends(check_user_exists),
|
||||
) -> DcaSettlement:
|
||||
"""Operator UX — resolves satmachineadmin#3.
|
||||
"""Operator UX — resolves spirekeeper#1.
|
||||
|
||||
Recompute the split for a settlement that didn't dispense the full
|
||||
amount (jam, mid-tx error). Provide one of dispensed_fraction (0..1)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue