Skip to content

Commit e464a76

Browse files
author
Meli
committed
docs: propose broker operations NIP with executable safety model
Add the fifteen-action Buzz-local NIP-BA draft, finite retry/isolation model, partial wire oracle and examples. Document semantic clarifications, verification boundaries and the fixed upstream comparison without claiming production correctness or universal superiority. Independent review pending. Co-authored-by: Meli <5aaa86bce934fc3445fc254aab560a40923f10252f92107e665073dede0e04d3@buzz.block.builderlab.xyz> Signed-off-by: Meli <5aaa86bce934fc3445fc254aab560a40923f10252f92107e665073dede0e04d3@buzz.block.builderlab.xyz>
1 parent 7a9a523 commit e464a76

6 files changed

Lines changed: 1634 additions & 0 deletions

File tree

docs/formal/nip-broker/NOTE.md

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
# NIP-BA assurance and compatibility note
2+
3+
Status: draft, awaiting independent redteam. Normative text is
4+
[`../../nips/NIP-BA.md`](../../nips/NIP-BA.md). This note is evidence, not extra
5+
normative protocol hidden to improve the word count.
6+
7+
## Sources and scope
8+
9+
This is a separate proposal on main, not a change to runtime behavior or a
10+
claim that the existing SDK/host conforms:
11+
12+
- Original nine-operation prose: block/buzz#6790,
13+
`804ce76c167d0f435cbff65e7e3f4aad720915f6`, `docs/agent-broker.md`.
14+
- Fifteen-operation Rust contract: block/buzz#6922,
15+
`115e7975a11d7d4d95043cb847abd13c1a32f370`,
16+
`crates/buzz-sdk/src/broker/{actions,mod.rs,wire.rs,correlate.rs}`.
17+
- Client integration: block/buzz#6967,
18+
`3d2ea5b89adccf980879b9841e9a6b517b588b57`.
19+
- Buzz-local NIPs from this branch's main base
20+
`7a9a5233d9d755e715be0c585cf7850e935d28cf`.
21+
22+
The remote-agent vision presently hands a signing key to the substrate. This
23+
proposes optional different custody, not a replacement deployment management
24+
plane. All durable user-visible state remains relay-scoped; the host's retry
25+
journal is execution safety state, not an alternative source of channel truth.
26+
27+
## Deliberate clarifications beyond editorial compression
28+
29+
The wire names, argument/outcome members, 15 action versions, and numerical
30+
limits follow #6922. The following need host/client agreement before adoption;
31+
they are **not assertions of already-implemented behavior**:
32+
33+
1. Retry key includes community as well as principal. Atomic durable admission,
34+
in-flight joining, crash fencing, evidence-only reconciliation, and permanent
35+
retry tombstones close unspecified safety gaps. Availability/storage cost is
36+
intentional: finite retention without a new wire epoch cannot safely permit
37+
an old ID to execute again.
38+
2. Authenticate/authorize release on every retry, including revoked sessions.
39+
A retry refusal is attempt-local and must not clear earlier uncertainty.
40+
This corrects the original blanket “failed means never happened” wording.
41+
3. Specify memory core mapping to `profile`, absence/tombstones, exact compact
42+
size encoding, and observer partial-acceptance non-identifiability. No prefix
43+
guarantee was present in #6922; none is invented here.
44+
4. Cursor filter binding/invalid-cursor refusal, thread ancestry validation,
45+
exact unsigned integer syntax, and current membership are explicit host
46+
obligations. They are not all enforced by the baseline SDK deserializer.
47+
5. Clarify publication acknowledgement, partial lifecycle/watchdog effects,
48+
sorted changed-field subset, ambiguous-name refusal, and creation not implying
49+
a booted runtime.
50+
6. Remove false claims that NIP-46 cannot inspect intent or that closed string
51+
schemas prevent all secret transmission. Storage reads intentionally return
52+
decrypted application content.
53+
54+
Remaining flexibility is explicit: deployment resource limits, initial read
55+
window/order/cursor lifetime, runtime/provider/model defaults, provisioning and
56+
deletion machinery, runtime telemetry body, and ownership-depth policy. This
57+
spec does not standardize runtime-to-owner telemetry interpretation. A claim of
58+
full cross-runtime interoperability would need that companion profile.
59+
60+
## Finite transition system
61+
62+
Run with Python 3.10+ (standard library only):
63+
64+
```sh
65+
python3 docs/formal/nip-broker/model.py
66+
```
67+
68+
`model.py` defines an explicit transition relation and breadth-first explores
69+
all reachable states until a fixed point, not random traces or a depth cutoff.
70+
A state is `(records, allowed, uncertain)`. Each record is
71+
`(digest, phase, dispatches, effects, final)`, with final as a ghost observation
72+
that survives result erasure. One shared request ID, two unequal body digests,
73+
three contexts `(community,principal) = (0,0),(0,1),(1,0)` exercise collisions.
74+
One ID is a symmetry abstraction, not proof for arbitrarily many IDs. Work on
75+
different IDs can interact through real operation state, which is outside this
76+
model. `effects` is a Boolean abstraction of “any effect took hold,” not the
77+
number of relay events.
78+
79+
Transitions: admission, digest conflict, wait timeout, dispatch, effect,
80+
completion, crash, reconciliation, result erasure, retry, and revocation.
81+
Dispatch is atomically admitted once. Revocation prevents future dispatch and
82+
stored-result release; it cannot recall already dispatched work. Reconciliation
83+
may reveal real effects but never runs the operation again. Crashed work can
84+
remain unknown forever. Lost responses are modeled by allowing completion to
85+
occur without client observation and later retry; HTTP packet order is not
86+
modeled. Reconciliation evidence is assumed truthful.
87+
88+
### Checked invariants and mutation witnesses
89+
90+
| Property | Normative seam | Deliberately broken transition |
91+
|---|---|---|
92+
| At most one dispatch per context/ID | Execution 2–5, retention | Concurrent redispatch, restart executor, evict protection |
93+
| Known failure has no effects | Result and Execution 6 | Crash misreported as failure |
94+
| Success has effect evidence | Published / completion | Baseline assertion (no separate mutant yet) |
95+
| No cross-context stored-result release | Session / K definition | Drop community or principal |
96+
| No release after revocation | Session / retry authorization | Replay bypasses revocation |
97+
| Different bytes do not replay | Execution 1/3 | Ignore digest |
98+
| Refusal retains previous uncertainty | Results, bold retry caveat | Clear uncertainty on refusal |
99+
100+
Nine deliberate mutations must each produce a counterexample for their expected
101+
property; the process exits nonzero if the baseline violates an invariant or a
102+
mutation survives. This tests model guards, **not production guards**. Claims
103+
about production regressions require binding the actual host implementation,
104+
which this PR does not supply.
105+
106+
### What this does not prove
107+
108+
Not a proof of JSON-parser correctness, cryptography, credential entropy, TLS,
109+
Nostr event construction, thread ancestry resolution, pagination completeness,
110+
NIP-AE convergence, lifecycle atomicity, or actual host behavior. Authorization
111+
is abstracted to a Boolean; no policy engine is modeled. No fairness or liveness
112+
claim: permanent partitions and unavailable reconciliation can remain unknown.
113+
The at-most-once dispatch invariant does not establish exactly-once remote
114+
effects. Multi-step operation adapters must separately establish their effect
115+
and failure semantics. No malicious-host security theorem is possible when the
116+
host holds the identity key.
117+
118+
## Upstream comparison protocol
119+
120+
Fixed before drafting: upstream NIPs 01, 05, 07, 09, 10, 29, 42, 44, 46, 98 at
121+
`488b787848fcf1c6c3498c253264b8121b1a9692`. This is a purposive dependency/API/
122+
security sample, not a random sample supporting a 90th-percentile assertion.
123+
124+
Dimensions: normative precision; independent implementability; failure/retry
125+
clarity; security boundaries; reproducible verification; economy of expression.
126+
Each gets 0 absent, 1 major gaps, 2 usable with questions, 3 explicit adequate,
127+
4 unusually strong. N/A must not be scored zero. Independent review must cite
128+
evidence and may reject the rubric. No averages may hide a weaker dimension.
129+
Strictly better on every dimension requires every score to exceed the
130+
comparator's; Pareto superiority (no weaker, at least one stronger) is a
131+
separate, weaker criterion. Adoption, deployed interoperability, and ecosystem
132+
maturity are additional dimensions that an unimplemented draft cannot beat by
133+
editing prose. No “superior to 9/10” conclusion is asserted here.
134+
135+
136+
## Executable wire examples
137+
138+
```sh
139+
python3 -m unittest discover -s docs/formal/nip-broker -v
140+
```
141+
142+
`vectors.json` contains a request and corresponding result for each of the 15
143+
actions. `wire.py` is a dependency-free, independently written **partial wire
144+
oracle**, not a production implementation or a full conformance certificate.
145+
It checks closed shapes, scalar normalization, integer widths, UTF-8, identity
146+
syntax, size limits, status/code pairs and selected response correlations.
147+
`test_wire.py` systematically inserts unknown/null/duplicate members into the
148+
example objects and exercises boundaries and byte-distinct equivalent JSON.
149+
Example event IDs and d-tags are illustrative, not cryptographic vectors; the
150+
checker does not verify signatures,
151+
read-filter membership, ancestry, address derivation, or operation execution.
152+
153+
A deliberately bypassed closed-object guard admits a forbidden `scope` member;
154+
the normal guard rejects it. An encoding regression was reproduced before the
155+
fix: Python's JSON decoder accepted UTF-16 input. The oracle now decodes bytes
156+
as UTF-8 explicitly. Neither experiment establishes a production SDK regression.
157+
158+
## Comparison findings (author assessment; independent review pending)
159+
160+
The fixed sample is not exchangeable: a browser capability, an event deletion
161+
request and a distributed action service solve different problems. Absence of
162+
an execution journal in a signature or serialization standard is **not a defect**.
163+
Consequently, numerical totals would reward our chosen problem and hide tradeoffs.
164+
The six dimensions above are inspection questions, not measured universal ranks.
165+
These are concrete strengths to preserve or learn from, and limits to our claim:
166+
167+
| NIP at the pinned revision | Evidence in that document | NIP-BA comparison boundary |
168+
|---|---|---|
169+
| [01][n01] | Events/signatures specifies serialization; relay flow defines OK, CLOSED, EOSE and tie ordering | We add operation uncertainty, but depend on its event machinery; not strictly more precise in every dimension |
170+
| [05][n05] | Security Constraints forbids redirects; Notes distinguishes identification from verification and preserves pubkey identity across remapping | Comparable explicit trust boundary; much narrower and economical protocol |
171+
| [07][n07] | Two required browser methods, optional encryption methods, extension timing and implementation link | Our failure contract is fuller; its tiny API is easier to implement and explain for its task |
172+
| [09][n09] | Client Usage requires author matching; warns deletion cannot be guaranteed; deleting a deletion has no effect | Both explicitly bound promises; no reason to demand an action journal from a deletion-request event |
173+
| [10][n10] | Marked e tags distinguish parent/root and document legacy ambiguity | We reuse this idea rather than surpass it; its kind-1 scope is not our kind-9 profile |
174+
| [29][n29] | Relay-scoped group identity, forks/migrations, independent subgroup membership, reconstruction events | Our retry namespace is explicit, but UUID-only actions and out-of-band provisioning are less general |
175+
| [42][n42] | Connection-scoped challenges, request retry examples, auth-required/restricted distinction | We add revoked-result rules; our bearer provisioning is less specified than its challenge exchange |
176+
| [44][n44] | Limitations, exact algorithm/pseudocode, external audit, published positive/negative vectors | A finite retry model is not a cryptographic audit; no verification superiority claimed |
177+
| [46][n46] | Two connection flows, permission requests, secret validation, logout limitations, auth challenge examples | We add reads/execution safety; it specifies discovery and connection establishment that we leave out of band |
178+
| [98][n98] | URL/method/time checks, optional body binding, wire example and reference implementation | We require retry-byte identity but solve a different authentication problem and are less compact |
179+
180+
NIP-BA's current strengths are explicit attempt-local failure semantics, durable
181+
retry protection, a small executable safety model with negative witnesses, and
182+
all-action wire examples. Its weaknesses remain companion runtime telemetry
183+
semantics, out-of-band provisioning/policy, unbounded lifetime journal growth
184+
controlled only by admission quotas, no production host, and no independent
185+
client/host interoperability run. Economy must be judged relative to scope,
186+
not by rewarding the document with the fewest absolute words.
187+
188+
**The requested “superior in all dimensions to at least 9/10” target is not
189+
established.** No editing-only stopping rule can supply deployment maturity or
190+
an independent implementation. This proposal should be judged on an auditable
191+
contract and resolved review findings, not a fabricated league table.
192+
193+
[n01]: https://github.com/nostr-protocol/nips/blob/488b787848fcf1c6c3498c253264b8121b1a9692/01.md
194+
195+
[n05]: https://github.com/nostr-protocol/nips/blob/488b787848fcf1c6c3498c253264b8121b1a9692/05.md
196+
197+
[n07]: https://github.com/nostr-protocol/nips/blob/488b787848fcf1c6c3498c253264b8121b1a9692/07.md
198+
199+
[n09]: https://github.com/nostr-protocol/nips/blob/488b787848fcf1c6c3498c253264b8121b1a9692/09.md
200+
201+
[n10]: https://github.com/nostr-protocol/nips/blob/488b787848fcf1c6c3498c253264b8121b1a9692/10.md
202+
203+
[n29]: https://github.com/nostr-protocol/nips/blob/488b787848fcf1c6c3498c253264b8121b1a9692/29.md
204+
205+
[n42]: https://github.com/nostr-protocol/nips/blob/488b787848fcf1c6c3498c253264b8121b1a9692/42.md
206+
207+
[n44]: https://github.com/nostr-protocol/nips/blob/488b787848fcf1c6c3498c253264b8121b1a9692/44.md
208+
209+
[n46]: https://github.com/nostr-protocol/nips/blob/488b787848fcf1c6c3498c253264b8121b1a9692/46.md
210+
211+
[n98]: https://github.com/nostr-protocol/nips/blob/488b787848fcf1c6c3498c253264b8121b1a9692/98.md
212+
213+
214+
## Reproduction result before independent review (2026-09-03)
215+
216+
Python 3.14, three-context baseline: **1,481,544 reachable states and 16,102,044
217+
transitions**, exhausted with no invariant violation. All nine mutations yielded
218+
a counterexample for their designated property. Wire suite: **9 test groups
219+
passed**, including positive request/result vectors for every action.
220+
Model source SHA-256: `0f87f39917e044c4767be3d9a75fe1aed65325be9316dbebdab7c6847c7447a5`.
221+
Rerun the commands above; model stdout contains the complete mutation traces.
222+
223+
`just ci` was attempted on base `7a9a5233d9d755e715be0c585cf7850e935d28cf`
224+
with only these documentation/model additions. The initial attempt timed out;
225+
a subsequent invocation selected an old PATH compiler and failed the MSRV check.
226+
With the installed Rust 1.95.0 toolchain selected explicitly, repository checks
227+
and the full 463-test CLI package passed, but `test-unit` stopped in buzz-acp at
228+
`acp::tests::keepalive_resets_idle_past_deadline` (82 passed, one failed before
229+
fail-fast). Later CI stages did not run. **Full repository CI is not green**;
230+
this note does not diagnose that failure as a flake or as caused by this change.
231+
232+
Independent redteam requested from Eva; findings and disposition remain pending.
233+
This is a reviewable draft, not approval of a production broker.

0 commit comments

Comments
 (0)