Cosmic Bull

Rendered from catalog/DISCOVERY.md at commit 6a510c665a53 in the project repository. The committed file is the source of truth; this page is a rendering of it.

Discovery record — the portfolio manifest and its verifier

Objective. Turn Cosmic Bull's growing software inventory into something that can be discovered, understood, reused, and eventually exposed through cosmicbull.net — and decide what, if anything, should be built, and what belongs on-chain versus in the repository.

Date. 2026-09-22. Chain. pearl-1, height 628232+.

This record follows docs/DISCOVERY_AND_REUSE.md. It is written before the implementation, and the decision it reaches is a refusal to build the obvious thing — so the reasoning matters more than usual, and a reviewer should be able to disagree with it on evidence.


1. The candidate shapes

Three shapes were considered from the start, and named explicitly so that rejecting one is a recorded decision rather than an omission:

ShapeVerdict
(a)A machine-readable manifest in the repository describing every package with provenanceBUILD
(b)A tool that verifies those manifest claims against the live chainBUILD — this is the novel part
(c)A new on-chain catalog/registry realmREFUSED — see §5

2. Sources searched

#SourceMethodResult
1Cosmic Bull's own catalogRead catalog/{README,applications,primitives}.md, pearl/DEPLOYMENT.md, pearl/INFRASTRUCTURE.md, all committed DISCOVERY.md/FIXES.md/README.md3 registries already live; no machine-readable data anywhere in the repo
2Cosmic Bull's own /p/ and /r/ sourcesgit ls-files; read every deployed package's on-chain outlineSee §3
3On-chain pearl-1All 647 package paths enumerated via vm/qpaths; keyword sweep then deliberate sampling of unhinted namesSee §4
4Public Gno / GitHub ecosystemgnolang/gno toolchain source (pinned, chain-matched), gnoweb, awesome-gno, gnopm, moul/gno-contracts, tx-indexer, GnoScan, docs.gno.landSee §6
5The chain's own query surfaceRead gno.land/pkg/sdk/vm/handler.go in the pinned toolchain; then executed each query against pearl-1See §4.1 — decisive

Coverage — stated honestly

The on-chain sweep enumerated all 647 paths but read 12 packages in depth. The selection rule was: the four mandated targets, then a ~30-term keyword grep over names, then deliberate sampling of unhinted names to test the grep's blind spot (r/moul/present/v2, p/moul/nestedpkg/v1, r/moul/x/daily/linktree/v1, r/g16m0r…/bountyboard — all negative).

That blind-spot test is required here because of a recorded prior miss: our own permbook discovery found that p/samcrew/basedao is a live role-and-member store matching none of access|perm|rbac|role|auth|acl|grant. Four negative samples is mild evidence the grep caught the real candidates. It is not a sample that licenses an ecosystem-wide claim. The 45-package nftmarket cluster, the ~85-package r/moul set and most of r/gnoswap were sampled, not enumerated. A basedao-class miss remains possible in the unread remainder.

Accordingly: no relevant existing implementation was found in the searched sources. Not "none exists".


3. Cosmic Bull's own inventory — the first reuse question

Three of our own live realms are registries. Each was evaluated as the home for this capability before anything new was considered.

RealmWhat it actually storesClassificationDecision
r/…/service_registryname → {owner, registrant, pkgPath, description, serviceType, metadata}, with Resolve/TryResolve/ListServices/ListByType/RenderCOSMIC BULL EXISTING PRIMITIVE — reusedThis is the on-chain half. It already is a package directory with descriptions and freeform metadata. Building a second one would duplicate our own deployed work
r/…/upgrade_registryaddress → {owner, name, deprecated, successor} migration chainsRELATED — complementaryNot reused: address-keyed, carries no path or description. Supplies a supersession axis the manifest records as data instead
r/…/permission_registryresource → permission → holder ACLNOT RELEVANTAccess control, not inventory
p/…/permbook, p/…/duebookCapability primitives owned by a consumer realmNOT RELEVANTNeither indexes packages

The finding that governs this whole record: a new "Cosmic Bull package registry" realm would be an EXACT DUPLICATE of service_registry, which is live, audited (1 RED + 7 YELLOW, all resolved), and currently holds 1 of 1000 entries against a 1 of 20 per-owner quota.

This is the same call made before, and it is made the same way: a reusable permission capability was refused as an exact duplicate of the deployed permbook. Consistency here is the point.


4. On-chain findings

PackageWhat it isClassWhy
r/samcrew/memba_appstore_v2Curated app store; Listing keyed by PkgPath with Name/Tagline/Descr/Category/IconCID/AppURL; ListLiveJSON(offset,limit)RELATED — closest prior artRight shape, wrong model: a 1 GNOT listing fee into a third party's treasury, a foreign curator's approval, and no version/dependency/provenance/audit fields. Live state queried: ListLiveJSON(0,20)[]deployed and empty
r/g1klfr7…/homePersonal home realm with a project portfolio: Project{Name, Description, PkgPath, Category}RELATED — exact intent, toy qualityProves the idea exists on-chain. Not reusable: plain map so ListProjects/Render iterate in non-deterministic order, GetProject panics on unknown names, Render is unbounded and unescaped
r/g1n4pl5…/gnomi/hubv2Module router: SetModule/GetModule/ListModules"name|path"RELATED (weak)Names and paths only — the minimal index skeleton, none of the metadata that makes an inventory understandable
r/g1mv005…/gnomemepad/metaOff-chain presentation metadata for token launches, in a realm separate from the thing it describesRELATED — pattern onlyThe separation pattern is directly applicable: metadata about frozen packages need not touch them. §6 requires exactly that
r/samcrew/agent_registry_v2AI-agent marketplace: endpoints, prepaid credits, reviewsNOT RELEVANTIndexes callable off-chain agents with an escrow economy. No PkgPath field at all
p/gnoland/boards/exts/hubImmutable DTO snapshot types for the boards forumNOT RELEVANTThe name is misleading — a defensive-copy layer, not an index. The inverse of the basedao lesson
r/demo/defi/grc20regGRC20 token registryNOT RELEVANT — one idea takenRegisters tokens, not packages. But its registration is self-proving: the key derives from cur.Previous().PkgPath(), so a realm cannot register under another realm's path. This is the benchmark §5 is judged against
r/docs/registryNOT DEPLOYED on pearl-1Confirmed two ways: absent from the 647-path list, and a live vm/qpaths query on gno.land/r/docs/ returns empty. There is no r/docs namespace on this chain
r/leon/hor ("Hall of Realms")NOT DEPLOYED on pearl-1Named by r/docs/registry's own render text as a canonical registry. Grep confirms only p/leon/{coinsort,ctg,svgbtn} exist here

4.1 The decisive finding — the chain is already the registry

The chain's own query surface was read from the pinned toolchain (gno.land/pkg/sdk/vm/handler.go) and then executed against pearl-1. It already serves most of what an index would store:

QueryReturnsVerified on pearl-1
vm/qpathsevery deployed path under a prefix or @namespace✅ 647 paths; 20 under our namespace
vm/qpkgmeta_json{path, status, creator, height}chain-attested, not author-declaredfeeledgercreator g1ut6…agvm3, height 572441, matching our record exactly
vm/qdocpackage_doc, imports, funcs[] with a crossing flag, types[], values[]feeledger → 18 funcs, 1 type, imports [errors, gno.land/p/nt/avl/v0]
vm/qfileverbatim source bytes✅ used for every byte-match in this portfolio
/tx?hash=the deploy transaction itselffeb4b559… → height 572441, MsgAddPackage, naming the feeledger path

gnomod.toml cannot carry descriptive metadata: the schema (gnovm/pkg/gnomod/file.go:11-45) is Module, Gno, Ignore, Draft, Private, Replace[], AddPkg — there is no description, author, license, tags or repository field, and AddPkg is chain-injected ("filled by the vmkeeper… not intended to be used offchain").

What the chain does NOT answer, and therefore what is genuinely missing:


5. Why an on-chain catalog realm is REFUSED

Shape (c) is the obvious thing to build and it is the wrong thing to build. Four independent reasons, any one of which would be sufficient:

  1. It duplicates our own deployed work. service_registry already stores pkgPath + description + serviceType + freeform metadata with enumeration. §7 of CLAUDE.md classifies that as EXACT DUPLICATE.
  2. It would re-store, in weaker form, facts the chain already attests. vm/qpkgmeta_json returns creator and height written by the chain at deploy. A realm holding a second copy holds a forgeable copy: the publisher types it in. Replacing a chain-attested fact with a self-attested one is a downgrade presented as a feature.
  3. It cannot be made self-proving. grc20reg is safe because the key derives from cur.Previous().PkgPath() — a realm cannot register under another realm's path. No equivalent proof exists for a catalog entry describing a frozen /p/ package that will never call anything. Every field an index cares about — description, audit status, commit SHA — is inherently an attestation. Our own service_registry says so on Resolve: "A resolution is an ATTESTATION, NOT A PROOF." A new realm inherits that and adds nothing.
  4. The ecosystem's prevailing principle says not to. gnopm's design note states it directly: "No centralized registry exists. Instead, chains serve as the registry." vm/qpaths is that registry.

Cost is a fifth reason and deliberately the weakest: ~5M ugnot to publish claims that are already free to query.


6. Off-chain findings

FindingClassBearing on the decision
moul/gno-contracts/contracts.json{pkgpath, kind, name, version, description, deps, published:{network:{uploaded:bool}}}RELATED — closest prior art, shape adoptedThe nearest comparable artifact in the ecosystem. Its evidence model is the gap we fill: "uploaded": true is a bare boolean — no chain-id, no tx hash, no height, no deployer, no content hash. It records whether code is on a network, never how, when, or that the bytes match
gnopm / gnomod.lockRELATED"Chain is the registry" — argues against (c), for (a)+(b)
gnoweb /search.json, $source overviewRELATEDSolves browsing. Never asserts "these bytes match commit X"
tx-indexer GraphQL — MsgAddPackage{creator, package}, MemFile.bodyREUSABLE EXISTING PRIMITIVEDeployed bytes are retrievable from the transaction itself — an independent corroborator of a vm/qfile byte-match. Not adopted now (endpoint unverified for pearl-1); recorded as the third evidence source
awesome-gnoNOT RELEVANTHuman-curated markdown; no machine-readable data, no deployed paths with provenance
Foundry broadcast/<script>/<chainid>/, OpenZeppelin .openzeppelin/<network>.jsonRELATED (non-Gno)Two ideas adopted: partition by chain-id, and key integrity on a content hash
A Gno doc-site generated from chain datanone foundNo pkg.go.dev equivalent exists. gno doc -remote and vm/qdoc are the raw material

No EXACT DUPLICATE was found in the searched sources for a verifier that proves inventory claims against chain bytes.


7. The decision

Build (a) + (b) as repository infrastructure. Deploy nothing new. Reuse service_registry for on-chain discoverability.

ArtifactKindWhy here and not elsewhere
catalog/portfolio.jsonrepoThe chain cannot hold a description (gnomod.toml schema forbids it) and should not hold a second copy of what it already attests
tools/verify_catalog.pyrepoThe novel contribution. Proves every manifest claim against live pearl-1 and the committed source — three-way agreement
tools/test_verify_catalog.shrepo§7a: the checker is code, so it is tested like code. A tool that only ever reports PASS is worse than no tool
4 × RegisterService on service_registryon-chainReuse. Gives the reusable /p/ primitives on-chain discoverability without deploying a byte

What makes (b) worth building

Today, catalog/README.md claims "nothing is deployed that this catalog does not record." That claim is true. It was established by hand, in a conversation, and the last repo-wide audit found "stale counts across 13 docs" — prose drift is the failure mode, and it scales with the inventory.

verify_catalog.py turns that sentence into a re-runnable proof, two-sided: every manifest entry must exist on chain with matching bytes, and every on-chain package in the namespace must appear in the manifest. An undocumented deploy and a phantom record both become exit 1.

The on-chain step, and its honest limit

Registering the four /p/ primitives in service_registry is reuse, not construction — no bytes are deployed, and the realm's [addpkg] height is unchanged, which is the proof of that. It addresses a recorded gap: both permbook and duebook carry "known limitation — one consumer; its reusability is a design argument, not a demonstrated fact."

It does not make those registrations proofs. service_registry's INTEGRATOR CONTRACT applies unchanged and in full: attestation-not-proof, name-is-not-authorization, target-can-change.


8. Limits of this record