R2D2-MERIDIAN/docs/mips/README.md
Joshua Belke 051cd966b0
Some checks failed
helm chart / lint + unittest + render matrix (push) Has been cancelled
helm chart / install on kind (gated) (push) Has been cancelled
helm chart / publish chart to GHCR (push) Has been cancelled
Meridian Harness / Build (aarch64-unknown-linux-musl) (push) Has been cancelled
Meridian Harness / Build (x86_64-unknown-linux-musl) (push) Has been cancelled
Meridian Harness / Publish rolling release (push) Has been cancelled
Meridian Harness / Publish tagged release (push) Has been cancelled
CI / Detect Changed Paths (push) Has been cancelled
CI / Dead Token Reference Guard (push) Has been cancelled
Docker image / Build (linux/amd64) (push) Has been cancelled
Docker image / Build (linux/arm64) (push) Has been cancelled
Docker image / Build public push gateway (linux/amd64) (push) Has been cancelled
Docker image / Build public push gateway (linux/arm64) (push) Has been cancelled
CI / Rust Lint (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Isolated DB Gate (push) Has been cancelled
CI / Desktop Core (push) Has been cancelled
CI / Desktop Smoke E2E (1) (push) Has been cancelled
CI / Desktop Smoke E2E (2) (push) Has been cancelled
CI / Desktop Smoke E2E (3) (push) Has been cancelled
CI / Desktop Smoke E2E (4) (push) Has been cancelled
CI / Desktop (push) Has been cancelled
CI / Desktop E2E Relay (push) Has been cancelled
CI / Desktop E2E Integration (1/2) (push) Has been cancelled
CI / Desktop E2E Integration (2/2) (push) Has been cancelled
CI / Desktop E2E Integration (push) Has been cancelled
CI / Backend Integration (relay e2e) (push) Has been cancelled
CI / Relay E2E (push) Has been cancelled
CI / Web (push) Has been cancelled
CI / Admin Web (push) Has been cancelled
CI / Mobile (push) Has been cancelled
CI / Security (push) Has been cancelled
CI / Server Cross-Compile (push) Has been cancelled
CI / Server Cross-Compile-1 (push) Has been cancelled
CI / Windows Rust (x86_64-pc-windows-msvc) (push) Has been cancelled
CI / Desktop Build (macOS) (push) Has been cancelled
Docker image / Merge release multi-arch manifest (push) Has been cancelled
Docker image / Merge debug multi-arch manifest (push) Has been cancelled
Docker image / Publish public push gateway image (push) Has been cancelled
docs(mips): adopt MIP-RT and withdraw the on-chain payments scope
Protocol council, 2026-08-20, parallel mode, five seats — Protocol Steward
(chair), Interop Skeptic, Enforcement Auditor, plus Revocation Guardian and
Second-Node Skeptic borrowed at the charter cap of two. Each seat received
only its charter row, the decision sentence and the evidence. Call: approve
with conditions, 5/5 concurring, no seat blocking at close.

**Withdrawn, not deferred — and none of the prior call's conditions fired.**
`meridian-ded` approved on-chain payments on 2026-08-02 against three
reversal conditions: a competing upstream payments NIP merging, a measured
fake-claim burden, and an upstream x402 Kaspa scheme. All three verified
NOT fired. The reversal proceeds on different grounds and the record says
so plainly: the requirement was never present, rather than refuted — no
counterparty outside the issuing community, no reachable public chain from
an exercise network. A scope held "deferred" on conditions that never fired
is inventory with no owner or expiry, and it keeps a chain-settled second
system of record alive as a live option.

The chair initially **blocked** the withdrawal limb, because "withdrawn"
was being chosen blind to the one trigger the prior council said would
point the other way: the NIPs mirror was pinned at `8228afb5`, dated
2026-07-31 — *before* the call being reversed. Lifted only after fetching
refs (working tree still pinned, confirmed by `rev-parse`) and re-running
the sweep: `origin/master` = `656cecc7` (2026-08-08), delta two commits
touching only `29.md` and `47.md`, zero hits tree-wide for
`x402|kaspa|erc-20|eip-681|eip-3009|stablecoin`. `git ls-remote` returned
the same head on 2026-08-20, so the twelve-day gap is upstream quiet, not
stale data.

That check also revealed it is a **weaker instrument than it looks**, which
is why `docs/AGENTS.md` now carries the rule rather than the anecdote:
upstream `c538775` moved NIP-47's authorization models and wallet
extensions out of `nostr-protocol/nips` entirely, into
`nostr-wallet-connect/nwc` — 332 of 351 changed lines — behind an open
numeric `extensions` namespace that nothing here mirrors. A future payment
scheme can now merge upstream without ever appearing in the grep that just
cleared this decision. So a scan record must state the mirror's commit hash
*and* its commit date separately from the scan date, and name the surface it
actually covered; the mirror is merged-state only and cannot see an open PR.

Three amendments the council made to the spec, all at DRAFT deliberately
because deferring any of them forces a renumber:

- **Kind `50416`, a consumer-signed spend hold**, accepted before serving.
  Without it `50412` is a post-hoc self-report by the party that gained the
  resource, and ingest rejects an overdraft only after the GPU-seconds are
  already gone.
- **The epoch rule is rewritten.** Wire `epoch` is advisory and ignored on
  input; the relay assigns it per `(community, holder, class)`; it is
  absorbing at *any* epoch, following the MIP-MS pattern, resolved
  fail-closed. Without this a peer transfer at `epoch n+1` reinstates a
  holder reclaimed at `epoch n` — the monotonic-revocation law, live on one
  relay today.
- **The arbiter is registered at scaling axis A1**, with `SELECT … FOR
  UPDATE` in the same transaction as the ledger append.

MIP-RT is a **non-monetary internal resource instrument, not a payment
rail**, and the support matrix now says exactly that: nine payment rows keep
`Reject` with strengthened rationale, an MIP-RT row is added, and there is
**no NIP-CP row** — that was the withdrawn bead's ask.

The register row cites `meridian-8t6h` (Phase 1), not the closing Phase 0
bead: `just check-mips` requires a non-terminal row to name a live bead, so
pointing it at `meridian-yzr6` would turn the gate red the moment that bead
closed. Bead created and row repointed before closing, not after.

Verified: `check-mips`, `check-architecture-map`, `check-kinds`,
`check-feature-specs`, `check-external-copy` all exit 0. `check-stellar` and
`check-gauntlet` exit 1, both pre-existing and provably not from this work —
`check-stellar`'s findings are byte-identical to a baseline captured before
any edit, and `check-gauntlet` fails on F001/F003 marked open against beads
already closed in the committed export at HEAD.

Beads: meridian-yzr6 (Phase 0), meridian-grxu (minutes), meridian-8t6h (Phase 1)
Signed-off-by: Joshua Belke <joshua@innovationhub-act.org>
2026-08-20 18:34:48 -04:00

11 KiB
Raw Permalink Blame History

MIP registry

Meridian Implementation Possibilities — repo-local proposals documenting what Meridian-compatible relay and client software may implement. A MIP is optional by construction, exactly as an upstream NIP is; that optionality is why an implementation has to be able to say which MIPs it actually honours.

draft

Deconfliction

Upstream Nostr NIPs are numeric (NIP-01, NIP-42). Repo-local proposals are two uppercase letters (MIP-OF, MIP-AS). Digits and letters are disjoint, so the namespaces cannot collide and no registry negotiation with upstream is required.

docs/nips/ is retained for profiles of genuinely upstream NIPs. Everything repo-local migrates here under MRDN-201.

Lifecycle

State Means What just check-mips requires
DRAFT Problem and wire shape stated. No code. a row, a file whose status line agrees with it, and at least one open bead
REVIEW Council seated; reversal evidence named. the above, plus the recorded call in the bead
IMPLEMENTABLE Wire format frozen; golden vectors published. the above, plus an § Enforcement points table in which every row names a check, and every just recipe it names exists
ENFORCED A reader exists. the above, plus the id in ENFORCED_MIPS (crates/meridian-relay/src/nip11.rs), plus a live re-probe
WITHDRAWN Reason recorded. a reason; no live bead required

Every state above is earned, not asserted. Until 2026-08-06 it was asserted: a fabricated ENFORCED row passed just check-mips and just check-kinds, because the stated criterion — check-kinds green — is vacuous for the MIPs that add no event kind, which is most of them. That is the failure named two paragraphs down, reproduced one level up: a register that advertises support the tree does not have. scripts/mip-registry-core.mjs now decides each row against the tree, and the requirement attaches at the state where it bites rather than retroactively at DRAFT.

ENFORCED is the one state a check cannot fully grant. It is a claim about a running relay, and green CI proves nothing about one — so check-mips verifies only the offline half (a reader is in the allowlist) and the live re-probe stays the gauntlet's live gate. An agent may drive a MIP to IMPLEMENTABLE unattended; ENFORCED is where the probe, not a human opinion, decides.

ENFORCED is the only state that permits NIP-11 advertisement. A relay advertises its MIPs in NIP-11 supported_extensions as mip-xx, and the control plane's relay detail view (POST /v1/meridian/relays/info) renders that list as the relay's active MIPs — so the register above and what a relay claims are checkable against each other from the operator console.

The rule is here because this repo has already paid for its absence. NIP-17 was advertised for months while kind:10050 was rejected by the ingest allowlist, so conformant third-party clients feature-detected support and then failed silently — the worst failure shape available, because the client did everything right. Any field that promises frames the relay will reject reproduces that bug, and a register row is such a field.

Register

MIP Title Layer State Bead
MIP-RG Proposal registry, lifecycle, numbering Process DRAFT meridian-5ynm
MIP-OF Opaque frame envelope Wire DRAFT meridian-tdq
MIP-XP Negotiated exchange profiles (P0–P3) Link DRAFT meridian-2e2
MIP-SF Session frames Wire DRAFT meridian-owl
MIP-QC QoS classes and congestion contracts Scheduling DRAFT meridian-2e9, meridian-9j8
MIP-LF Leaf forwarding Topology DRAFT meridian-yl8p
MIP-MQ MQTT interoperability Interop DRAFT meridian-i39r
MIP-KN Kinematic state payload schema Payload DRAFT meridian-ss1
MIP-TL Scalar telemetry payload schema Payload DRAFT meridian-lim7
MIP-MS Media sessions — the control plane for continuous media Media DRAFT meridian-7xh3.1
MIP-AS AIS feed profile Profile DRAFT meridian-hgjj
MIP-CT Drone backbone telemetry — symbol identity (SIDC/XSIDC) Profile DRAFT meridian-9qll.1, meridian-f6gu
MIP-TC Compact Track Code — the disadvantaged-link bearer codec Bearer DRAFT meridian-qtl8, meridian-n6lt, meridian-hzdl, meridian-3itl
MIP-MI Motion imagery profile — STANAG 4609 Profile DRAFT meridian-7xh3.1
MIP-DD DDIL sessions and reconciliation Link DRAFT meridian-bm32
MIP-CU Custody and application acknowledgment Delivery DRAFT meridian-8qkw
MIP-AD Adapter contract — units, CRS, time base, lossiness Ingest DRAFT meridian-qi7f
MIP-ML MAVLink v1/v2 profile Profile DRAFT meridian-is42
MIP-RI Remote ID profile — ASTM F3411 / prEN 4709-002 Profile DRAFT meridian-n4jr
MIP-DS ROS 2 / DDS profile Profile DRAFT meridian-fsjp
MIP-NM NMEA 0183 profile Profile DRAFT meridian-fqeu
MIP-AB ADS-B and the cooperative air picture — 1090ES, UAT 978, GDL 90 Profile DRAFT meridian-768v
MIP-TK Cursor on Target / TAK interoperability Profile DRAFT meridian-doty
MIP-CN Channel canvas — the shared per-channel document Document DRAFT meridian-d7o
MIP-RT Resource tokens — non-monetary compute allocation with precedence classes Allocation DRAFT meridian-8t6h

A profile MIP adds no mechanism. It binds an existing envelope, payload schema, and link profile to one real-world feed, and states which enforcement point rejects a frame that does not conform.

Vehicle and drone protocol profiles bind through MIP-AD, the adapter contract. The full ETL surface — proposed, characterized and blocked — is the drone protocol coverage register. A row in that register is not a commitment schedule; ENFORCED here is.

Independent convergence — what it is and is not

On 2026-08-06 an external architecture review with no access to this repository independently derived the wire shape of ten registered MIPs: OF (binary envelope), XP (negotiated per-link auth), SF (no signature per sample), QC (eight delivery classes), LF (fusion as ordinary clients), CT (symbology rendered client-side), MI and MS (media outside the payload path), KN and TL (kinematic and scalar telemetry schemas). It also converged on Design Law independently — opaque routing keys with no human-readable mission names, and a hot path that calls no store synchronously.

Record this as reversal evidence, not as conformance or implementation evidence. Two designs agreeing raises the cost of re-litigating the wire shape; it says nothing about whether a reader exists. Only ENFORCED says that, and only ENFORCED permits NIP-11 advertisement.

The same review's two genuine gaps became MIP-DD and MIP-CU. Its other proposals — a second durable event journal, and per-region provisioning counts — were withdrawn under refusals R2 and R8 respectively, by agreement with the reviewer.

Capability packs are not MIPs

Onboarding offers domain capability packs (AIS, ADS-B, 2525/APP-6E, STANAG 4609, MAVLink, TAK, Remote ID). A pack is a named bundle of MIPs a deployment has moved to ENFORCED — a UI grouping over this register, never a second registry. See meridian-4guo.

A pack is available on a relay only when every MIP in its row is ENFORCED and advertised by that relay. Partial support is not support: a pack that lights up while one member MIP is still DRAFT is the NIP-17 failure above, wearing a friendlier label.

Pack Requires Missing
AIS MIP-OF, MIP-XP, MIP-QC, MIP-KN, MIP-AS —
ADS-B MIP-OF, MIP-XP, MIP-QC, MIP-KN, MIP-TL, MIP-AD, MIP-AB —
APP-6E MIP-OF, MIP-XP, MIP-QC, MIP-KN, MIP-AD, MIP-CT —
STANAG-4609 MIP-OF, MIP-XP, MIP-QC, MIP-KN, MIP-AD, MIP-MS, MIP-CT, MIP-MI —
MAVLINK MIP-OF, MIP-XP, MIP-QC, MIP-KN, MIP-TL, MIP-AD, MIP-ML —
TAK MIP-OF, MIP-XP, MIP-QC, MIP-KN, MIP-TL, MIP-CT, MIP-AD, MIP-TK —
REMOTE-ID MIP-OF, MIP-XP, MIP-QC, MIP-KN, MIP-AD, MIP-RI —

Requires is the whole dependency closure, not just the profile. It is the transitive union of every Depends on line the row reaches — for AIS, the one in MIP-AS, plus anything that declares. Listing only the profile would be the same bug one level down: availability is computed over this row and nothing else, so a pack naming only MIP-CT would light up the moment MIP-CT turned ENFORCED, while the MIP-OF/MIP-KN/MIP-XP/MIP-QC substrate it cannot run without was still DRAFT. just check-mips fails a row that omits a declared dependency. A pack whose Missing cell is non-empty can never become available; it names the work.

This table is the source of the client's pack view. just check-mips regenerates desktop/src/shared/mips/registry.generated.json from this file and fails when the two disagree, so the register stays the one registry.

Driving a MIP without a human in the loop

The register is built to be executed from, not just read. Every row names a live bead, so bd ready surfaces MIP work like any other, and the state a row claims is decided against the tree rather than by whoever edited the row.

  1. Pick a row and claim its bead.
  2. DRAFT — write MIP-XX.md; the status line and the row must agree.
  3. REVIEW — seat the matching council ($consult-council-approval) and record the call, its conditions, and its reversal evidence in the bead.
  4. IMPLEMENTABLE — freeze the wire format, publish golden vectors under crates/meridian-conformance/, and write the § Enforcement points table so that every normative MUST maps to a check that fails.
  5. ENFORCED — land the reader, add the id to ENFORCED_MIPS, and re-probe a live relay. This step is live-gated and is the one an unattended loop stops at.

just check-mips refuses every step taken out of order. What it cannot refuse is an enforcement row that names a real command asserting nothing — that is the reversal evidence on the gate itself, recorded in meridian-o3ws.