docs(plantare): mark bilateral signed record shipped
Flip plantare-bilateral.md from "design, not yet built" to "v1 shipped", summarize what landed (transport / schema v12 / service / UI), resolve the open questions inline with the decisions made, and list the honest follow-ups (durable outbox, accept-after-restart, rating anchor, provenance DAG, paper/group/forgiveness sync).
This commit is contained in:
parent
e78656bc07
commit
4ab146b157
1 changed files with 55 additions and 14 deletions
|
|
@ -1,8 +1,29 @@
|
|||
# Plantaré — the bilateral signed record (design, not yet built)
|
||||
# Plantaré — the bilateral signed record
|
||||
|
||||
Status: **design locked, implementation deferred.** This doc specifies the two-sided
|
||||
Plantaré so a later session can build it without re-deciding. It is the "formulario
|
||||
bilateral firmado" that other docs wait on:
|
||||
Status: **v1 shipped (2026-07-14).** The two-sided signed Plantaré — the "formulario
|
||||
bilateral firmado" other docs waited on — is now built end-to-end: transport in
|
||||
`commons_core`, schema v12 + repo, `PlantareService`, and UI (propose from a chat,
|
||||
accept/decline on the ledger). What's left is noted under "Deferred to a follow-up"
|
||||
below. This doc keeps the original design for reference; the "Open questions" are now
|
||||
resolved inline.
|
||||
|
||||
Built (commit series `feat(plantare): …`, 2026-07-14):
|
||||
- **Transport** — `PlantarePledge` (canonical, byte-stable core + two BIP-340 Schnorr
|
||||
stubs), `PlantareCrypto` (sign/verify over SHA-256 of the core), `PlantareTransport` +
|
||||
`NostrPlantareTransport` (propose→accept→counter-sign / decline over NIP-17 gift wrap
|
||||
carrying a tagged JSON payload; the message inbox skips these and vice-versa).
|
||||
- **Schema v12** — the deferred columns on `Plantares` (`pledgeId`, `debtorKey`,
|
||||
`creditorKey`, `debtorSignature`, `creditorSignature`, `movementId`, `remoteState`,
|
||||
`returnKind`, `workHours`), all nullable/defaulted so v1 local rows are untouched;
|
||||
guarded migration + schema dump + migration test.
|
||||
- **`PlantareService`** — signs my stub, sends, and reconciles incoming moves into the
|
||||
ledger (verifies stubs before storing; pending proposals held in memory keyed by
|
||||
pledge id, relay redelivers on reconnect).
|
||||
- **UI** — propose sheet reached from the chat overflow menu; accept/decline + handshake
|
||||
badges (awaiting signature / signed by both / declined) on the Plantares screen.
|
||||
|
||||
This doc originally specified the two-sided Plantaré so a later session could build it
|
||||
without re-deciding. It is the "formulario bilateral firmado" that other docs wait on:
|
||||
|
||||
- [`data-model.md` §2.7](data-model.md) — the `Plantare` entity, whose `debtor_key`,
|
||||
`creditor_key`, `debtor_signature`/`creditor_signature` and `movement_id` columns are
|
||||
|
|
@ -147,14 +168,34 @@ An `accepted` Plantaré is the **strong anchor** for a rating (both parties prov
|
|||
real deal), upgrading the current soft, per-conversation anchoring — closing the
|
||||
[`open-decisions.md`](open-decisions.md) / [`network-trust.md`](network-trust.md) item.
|
||||
|
||||
## Open questions (for the build session)
|
||||
## Resolved in the v1 build (2026-07-14)
|
||||
|
||||
- **Conflict / divergence:** if A and B end up with mismatched payloads (edited after
|
||||
propose), which wins? Likely: accept is over an immutable hash; any change re-proposes.
|
||||
- **Revocation / forgiveness sync:** `forgiven` is one-sided today; should it propagate to the
|
||||
counterparty's copy, or stay each party's own view?
|
||||
- **Expiry:** does `dueBy` passing change `remoteState`, or only the UI nudge (as in Phase 1)?
|
||||
- **Paper ingest:** signature model for a Plantaré where one side has no key (photo/QR of a
|
||||
paper stub) — store as `creditorSignature` null, `counterparty` free text.
|
||||
- **Group/collective party:** a seed bank (not a person) as creditor — ties to the
|
||||
collective-identity question in `sharing-model.md` §6.
|
||||
- **Conflict / divergence:** RESOLVED as anticipated — the two signatures cover the
|
||||
canonical core (everything except the signatures), and the `pledgeId` is part of that
|
||||
core. Any edit changes the signing hash, so an accept always closes the *exact* payload
|
||||
proposed; a changed pledge is a different id and must be re-proposed. `PlantareCrypto`
|
||||
enforces this; the "editing after signing invalidates the stub" test pins it.
|
||||
- **Revocation / forgiveness sync:** kept **one-sided** for v1 — `status`
|
||||
(`open`/`returned`/`forgiven`) stays each party's own view, distinct from the shared
|
||||
`remoteState` handshake. Propagating a forgive to the counterparty is a follow-up (it'd
|
||||
need a signed "released" move).
|
||||
- **Expiry:** `dueBy` passing is a **UI nudge only** (overdue styling), as in Phase 1 — it
|
||||
does not change `remoteState`.
|
||||
- **Paper ingest:** the schema already supports it (nullable keys/signatures + free-text
|
||||
`counterparty`); no UI path yet — deferred.
|
||||
- **Group/collective party:** deferred — still tied to the collective-identity question in
|
||||
`sharing-model.md` §6.
|
||||
|
||||
## Deferred to a follow-up
|
||||
|
||||
- **Durable send outbox.** Propose/accept send best-effort over the current session; if
|
||||
offline the local row is recorded but the move isn't queued for retry. A durable outbox
|
||||
(like `offer_outbox`) should back it so a proposal made offline goes out on reconnect.
|
||||
- **Accept after restart before redelivery.** Pending proposals live in memory (refilled by
|
||||
NIP-17 redelivery on reconnect); accepting one the relay hasn't redelivered yet shows a
|
||||
gentle "offline / reconnecting" nudge rather than reconstructing the pledge from the row.
|
||||
- **Rating anchor.** An `accepted` Plantaré is now a provable closed deal, but the rating
|
||||
flow isn't yet wired to require/prefer it (the "strong anchor" upgrade).
|
||||
- **Provenance DAG.** `movementId` is stored; building the distributed procedence graph
|
||||
from accepted pledges is not done.
|
||||
- **Forgiveness/paper/group** as above.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue