Join Nostr
2026-10-05 20:24:16 UTC

zirp on Nostr: Here's the plan as one coherent product. The organizing idea is a single loop — ...

Here's the plan as one coherent product. The organizing idea is a single loop — express → resolve → materialize → persist — with a durable substrate underneath and a disposable surface on top. Everything from the conversation folds into that.

Product definition

Private Provider is a blank generative surface over a durable personal substrate. You speak an intent; it resolves into a *moment*, a *thing*, or a *rail*; the visible result is only what the moment needs, while identity, data, authority, money, and compute persist locally. The app store disappears; the substrate stays.

The product's two primitives:
• User primitive: moment / thing / rail.
• Engineering primitive: the artifact ladder (pick the lightest rung that works).

Architecture

┌──────────────────────────────┐
│ GLASS (blank surface) │
│ one conversation + cards │
│ generic renderer + sandbox │
└───────────────┬──────────────┘
│ intent
┌───────────────▼──────────────┐
│ RESOLVER │
│ classify → moment/thing/rail │
│ pick rung L0…L3 │
└───────────────┬──────────────┘
┌────────────────┬───────────────┼───────────────┬────────────────┐
▼ ▼ ▼ ▼
L0 view L1 mini-app L2 web app L3 native APK
events+rule blossom zip MKStack/esbuild PRoot toolchain
(declarative) (sandboxed) (WebView/PWA) (plain-Java)
└────────────────┴───────────────┬───────────────┴────────────────┘
▼
┌──────────────────────────────┐
│ SUBSTRATE (durable) │
│ Amber · Citrine (relay) │
│ Blossom · wallet (LN/Cashu) │
│ attested inference │
│ agent: routstrd + Pi │
└──────────────────────────────┘


The layers

| Layer | Job | Concrete pieces |
|---|---|---|
| Glass | Surface: conversation, cards, generic renderer, sandboxed WebView | merged Chat+Pi transcript, Host router, view renderer, webxdc runtime |
| Resolver | Classify intent, choose rung, assemble scope, execute | new; the heart of the product |
| Artifacts | L0 view / L1 mini-app / L2 web / L3 native | declarative spec, Blossom zip, MKStack build, PRoot toolchain |
| Substrate | Durable identity, state, authority, money, compute | Amber, Citrine, Blossom, wallet, attested inference, Pi |

The core loop

1. Express. One conversation. No tabs.
2. Classify. The resolver labels the request:
• Moment — one-shot; dissolves.
• Thing — durable, named, shareable; gets a persistent card/tile.
• Rail — needs authority (pay, sign, publish); shows the gate, then recedes.
3. Choose rung. The lightest artifact that satisfies it:
• L0 — declarative view. No code. A filter + render rule over events. Safe, portable, instant. (Ditto's content types / themes-as-events.)
• L1 — sandboxed mini-app. Portable HTML/JS zip on Blossom, referenced by a Nostr event, run in a sandbox, state as addressable events. Share the event, share the app. No install.
• L2 — generated web app. MKStack-template React app, compiled in-browser (esbuild-wasm) or in PRoot, run in a WebView/PWA, identity/data via a Nostrify-style bridge. Pinnable.
• L3 — native APK. Only for system integration, launcher presence, or background services. The existing private-provider chain. One-tap install.
4. Scope. Before execution, mint a scoped grant: which event kinds/tags are readable, which capabilities are allowed (camera, files), which signing is permitted. One plain-language prompt, not a toggle wall.
5. Materialize. Build/assemble, present the surface, run it.
6. Persist. Write state as addressable events to the local relay; syndicate deliberately.

The durable spine (what never dissolves)

• Identity — Amber. NIP-46; the key never leaves the signer. Per-request approval, per-app scoping.
• State — Citrine. The local relay: home replica, Tor reachable, public read-only / whitelisted read-write. This is the read model the whole product projects from.
• Artifacts — Blossom. Code and media as content-addressed blobs.
• Money — wallet. Lightning/Cashu; meters generation and usage; pays inference.
• Compute — routstrd + Pi. Local agent; heavy inference off-device, attested; on-device build toolchain.
• Convention — Nostr kinds. NIP-reuse first, kind = schema, tags = semantics, alt on custom kinds. This is what keeps generated artifacts interoperable.

The agent contract (how generation stays reliable)

Mirror MKStack's pattern. Two skills, one discipline:

• `android-on-device` (exists) — the L3 native rung.
• `nostr-moment` (new) — the L0–L2 rungs: template, component set, render-rule schema, NIP-reuse rules, tag discipline, scope declaration.
• The discipline — always reuse an existing NIP before inventing a kind; declare scope; declare state kind and d-tag; emit a manifest, not a monolith.

Generation is composition within a bounded substrate, not freeform invention. That's the reliability lesson from MKStack and Shakespeare.

The moment manifest

Every durable artifact is described by a signed, addressable event:

kind: <custom, NIP-31 alt="Private Provider app">
d: <app instance id>
name, icon, version
rung: view | mini-app | web | native
artifact: blossom-hash | inline | none
render: declarative spec (L0) | entrypoint (L1/L2) | package (L3)
state: state kind + d-tag
scope: readable kinds/tags · capabilities · signing grants


The manifest is the app. Share it, fork it, upgrade it. Versioning and distribution come from the kind semantics, not custom code.

Scoping and safety

• Citrine exposes *scoped virtual views* of the event graph, not the whole relay.
• Amber enforces per-app/per-request signing permissions.
• The Glass mediates capabilities (camera, files, network) and runs L1/L2 code in a sandbox.
• A generated surface never holds the nsec and never sees the full store. L0 is declarative (no code at all); L1/L2 are sandboxed; L3 is plain-Java-bounded.

The honesty gates (kept visible)

Spend · Sign · Not private · Publish · Install · Scope. Each appears only in its moment. The harness hides chrome, never consent.

Roadmap

Phase 0 — Substrate wiring (mostly exists). Amber, Citrine, wallet, attestation, agent, native build. Prove one end-to-end *thing* (L3) built, signed, published, installed, launched.

Phase 1 — Unify the surface. Merge Chat + Pi into one conversation. Panels become headless services behind a Host router. Keep tabs as fallback.

Phase 2 — Resolver + L0. Build the classifier and the declarative view renderer. Manifest event schema. Scope model. This delivers the on-demand *feel* with no code execution at all.

Phase 3 — L1 mini-app. Sandboxed WebView runtime, Blossom artifacts, share-an-event distribution. This is the sweet spot: shareable on-demand apps with no install.

Phase 4 — L2 web rung. Nostrify-style bridge to Citrine/Amber, MKStack-style template and skill, in-browser or in-PRoot compile, PWA/pin.

Phase 5 — Blank glass. Conversation becomes default; chrome appears on demand; onboarding collapses to signer → backup → top up → talk.

Phase 6 — Sharing, groups, self-update. Group instances (NIP-29/Concord-style), moment sharing, and Private Provider updating itself through its own loop.

Phase 7 — Trust hardening. Recovery, redundancy/pinning, metadata privacy, scope enforcement, battery/background survival.

What exists vs. what's new

| Reuse | New |
|---|---|
| Amber/NIP-46 signer, wallet, attested inference | Resolver (classify + rung selection) |
| PiSession agent, android-on-device skill | Unified conversation surface |
| Native build/sign/publish chain | Declarative view renderer + manifest kind |
| ngit/Blossom/Nostr plumbing | Sandboxed WebView runtime + L1/L2 builders |
| Panels' logic | Headless services + scope/capability model |
| Attestation watcher | Nostr-moment skill + template |

Risks / open questions

• Android survival of relay + signer + agent under Doze/battery limits.
• WebView security for generated JS — sandboxing is non-negotiable.
• NIP fragmentation — the main threat to portability; the agent contract must enforce reuse.
• Key recovery — the fragile link; a permanent key is a permanent liability.
• Bundle a relay or depend on Citrine? Integration choice.
• Adopt webxdc verbatim or a variant? Compatibility vs. control.
• Declarative DSL scope — how much can L0 express before it needs code?
• Multi-device conflict semantics — event merges vs. transactional expectations.

Success condition

A user expresses an intent and receives a working, private, shareable capability in the moment — persisted on a substrate they own, disposable as a surface, and escalatable to native only when it must be. No app store, no tab hunting, no maintenance burden for what was never worth keeping.

Private Provider stops being an app with five windows and becomes a glass with one conversation, a resolver, a ladder, and a substrate it controls. That's the coherent product: talk → it resolves → the lightest artifact appears → the durable spine keeps what matters.