SOURCE / PINNED RELEASE
Made of little things.
Napcraft
- Release
- ee47ac6a25df…
- Author-recorded commit
- 410dea87e109…
- License
- LICENSE
- Author’s source reference
- nostr://npub182jczunncwe0jn6frpqwq3e0qjws7yqqnc3auccqv9nte2dnd63scjm4rf/wss%3A%2F%2Fgit.napplet.soy%2F/n-52f9e22f5ce
Archive hash verified: 9e6e0cabb18d0d46…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
# Public world directory — 2026-09-26
Napcraft opens with a searchable list of public worlds and a Join button for each.
Listed worlds remain discoverable after everyone leaves. Creating a world does
not automatically advertise it: a signed-in player chooses **Invite → List
publicly** and approves the public announcement. Guests can browse and join.
**Remove my listing** removes that author's advertisement without deleting the
world, its blocks or its code. Other players may publish their own invitations.
Listings use the shipped `soy.app-data/1` NIP-78 convention through SDK OUTBOX:
collection `worlds`, schema `napcraft.world-directory`, version 1, payload `{code}`.
The host supplies a stable app scope and allowed relays. A deterministic record
ID prevents retry duplicates. The supplied helper checks current revisions,
tombstones and identity, and retries uncertain publication with the same template.
Invalid records are hidden; untrusted titles render as text. Listing failures
never create another world or change the editor's pending saves.
The active worlds backend and its deployment are unchanged. Listings point to
ordinary pinned world codes; the existing CVM rules still authorize every edit.
The directory shows a recent selection of at most 40 records, with local search
and Refresh. It does not claim exhaustive discovery, verified ownership or live
player counts. Relay availability/retention still govern public discovery.
## Verification
- `pnpm verify`: 26 tests passed, plus TypeScript and the single-file build.
Includes invalid listings, deterministic IDs, duplicate invitations, latest
revision/tombstone handling, unchanged retry templates and identity changes.
- `pnpm test:conformance`: 5 passed, 0 failed, 5 skipped. Manifest evidence,
wire envelopes and lifecycle were not measured by this reference-shell run.
- `tests/directory-layout.mjs`: 9 checks passed using explicitly synthetic records
in the real hosted frame. Covers text-only untrusted titles, incomplete query
feedback and seven sizes: 200×160 (minimum notice), 320×560, 900×600, 1440×900,
390×844, 360×640 and 844×390. Join targets are at least 44×44 pixels.
- `tests/public-directory-capability.mjs`: the deployed host acknowledged a
signed announcement, another anonymous browser read it, and removal succeeded.
The temporary capability-test advertisement was removed afterward.
Full published UI verification and release receipts are recorded below after
publication. Test signers are disposable browser fixtures; touch is browser
emulation, not a physical-phone or physical-extension test.
## Tooling and platform findings
soyLI 0.23.4's local preview advertises `soy.app-data/1` and a loopback relay.
After consent, directory publication failed with `app-data-publish-failed: No
relay acknowledged the event` and a relay timeout. A separate signed kind-30078
probe connected to that relay but received no acknowledgement within five
seconds. This isolates the missing acknowledgement from the game's UI, without
establishing the relay's internal cause. The local scenario verified denied
consent and unlisted privacy, but could not certify successful relay publication.
The deployed napplet.soy host passed the independent capability test using its
declared default relays. No app relay override or backend workaround was added.
The shipped app-data guide/helper requires observing `shell.onReady` for host
policy, while the pinned SDK 0.24.4 has no shell export and the inherited guidance
test rejected all injected shell access. Napcraft uses only the documented policy
observer and SDK identity/OUTBOX calls. The test now permits that specific
observer while retaining retired bootstrap/probing prohibitions. The SDK, skills
and template guard should describe this policy-observation exception consistently.
The existing build-scoped recovery-storage limitation is unchanged; see
[the recovery report](consent-recovery-release.md). Public directory scope is
stable across builds and is separate from private pending-save storage.
