Cosmic Bull

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

Discovery record — a developer-facing API reference

Objective. Evolve Cosmic Bull from a verified software inventory into a usable public developer ecosystem: make the software discoverable and usable by developers, design for cosmicbull.net as the eventual public entry point, and decide whether the next step is static infrastructure, a web interface, an API, additional metadata, developer tooling, or a combination.

Date. 2026-09-22. Chain. pearl-1, at fc13fd9, 20 packages.

Companion to catalog/DISCOVERY.md, which is the discovery record for the manifest and its verifier. That record established provenance. This one is about comprehension: a developer who trusts the provenance still cannot call the code.

The decision here is again mostly a set of refusals, so the reasoning matters more than the conclusion and a reviewer should be able to disagree on evidence.


1. The candidate shapes

ShapeVerdict
(a)A static site at cosmicbull.net rendering the portfolioDEFERRED — §6
(b)An HTTP/JSON API serving portfolio and package dataREFUSED — §6
(c)A new on-chain docs or package-metadata realmREFUSED — §6
(d)Add README.md to the four /p/ primitivesNOT EXECUTABLE — §5
(e)A generated, chain-derived API reference in the repositoryBUILD — §7

2. What already exists — measured, not assumed

Every figure below was produced this session by querying pearl-1 directly.

2.1 gnoweb is already a live developer interface for this portfolio

https://pearl.testnets.gno.land serves four views per package. All were fetched and returned HTTP 200 for our packages:

ViewSuffixWhat it gives a developer
Content(none)Render() output for a realm; a file listing for a /p/ package
Source$sourceSource browser plus a computed Package Info panel — namespace, path, creator, block, code stats
Help$helpGodoc-style API page and a generated gnokey maketx call command, pre-filled with the pkgpath, the function, -chainid "pearl-1" and the pearl RPC
State?stateRealm state

This is decisive for the architecture. A godoc renderer, a source browser and a call builder are already shipped, already live, and already pointed at our packages. Building any of the three would be duplicate infrastructure.

2.2 The chain answers vm/qdoc with far more than gnoweb renders

vm/qdoc is derived by the node from the deployed bytes, so it carries the same authority as the byte-match checks in verify_catalog.py. Its per-function record is {type, name, crossing, signature, doc, params[], results[], file, line}; its per-type record is {name, type, doc, alias, kind, fields[], file, line}.

$help renders exported top-level functions only. It renders no methods and has no Types section. That was confirmed by comparing the rendered symbol list against vm/qdoc for seven packages; the rule held exactly in all seven.

For the sixteen realms this costs nothing — a realm's entire public API is top-level crossing functions, so coverage is complete:

Realmqdoc exported top-levelrendered by $help
service_registry1515
vault1818
fee_split1515

For the four /p/ primitives — the reusable half of the portfolio, and the half this objective is literally about — it costs almost everything:

PackageExported funcsExported methodsExported typesTotalRendered by $help
coinio30033
feeledger3131173
duebook2202242
permbook3182233
total115156711

11 of 67 — 16%. Every method and every type is invisible. feeledger is a ledger whose Deposit, Withdraw, BalanceOf, UsersTotal and FeesAccrued appear nowhere in the only public interface that exists; duebook's Schedule/Claim/Expire lifecycle likewise; permbook's Grant/Revoke/Has likewise. coinio is fully covered only because it has no methods at all.

2.3 The /p/ landing view is a two-file directory listing

With no Render() and no README.md, gnoweb's default Content tab for p/…/feeledger is, verbatim:

/p/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/feeledger
Directory · 2 Files
feeledger.gno
gnomod.toml

All four primitives hold exactly {<name>.gno, gnomod.toml} — a file set already checked against the chain by verify_catalog.py C4. By contrast p/nt/avl/v0 ships ten files including a README.md, and renders it.

2.4 Five realms have no package doc at all

vm/qdoc returns package_doc of length 0 for fee_split, permission_registry, service_registry, timelock_guardian and upgrade_registry — the five earliest deployments. Their $help Overview section is empty.

2.5 In the repository

No function signature is documented in prose anywhere in the repo. catalog/primitives.md lists function names for the primitives and nothing about parameters, results, errors, or ordering constraints. The consumer contracts exist but are narrative rules. The three demo realms (coindemo, duebook_demo, permbook_demo) are working reference implementations and are not linked from any primitive's documentation as such.


3. Sources searched

#SourceMethodResult
1Cosmic Bull's own catalogRead catalog/*, docs/*, pearl/DEPLOYMENT.md, every committed README.md§2.5
2Cosmic Bull's own /p/ and /r/ sourcesvm/qdoc and vm/qfile on all 20 deployed packages§2.2–§2.4
3On-chain pearl-1Namespace enumeration via vm/qpaths; vm/qdoc executed against all 20§2.2
4Public Gno / GitHub ecosystemgnoweb source and live behaviour, gnopm, GnoScan, tx-indexer, r/docs, r/leon/hor, gnolang/gno issues and PRs§4

Coverage, stated honestly. This record's ecosystem search was narrower than DISCOVERY.md §2's, because it inherits that record's 647-path enumeration rather than repeating it. It adds a targeted search for documentation tooling. It supports "no relevant existing implementation was found in the searched sources" and nothing stronger.


4. Ecosystem findings and classification

FindingClassBearing
gnoweb $help / $source / Content / ?stateREUSABLE EXISTING INFRASTRUCTURE — reusedShips godoc-for-top-level-funcs, a source browser, and a call builder, live, for all 20 packages. Forecloses shapes (a) and (b) as rebuilds, and bounds (e) to the 16% gap it does not cover
vm/qdocREUSABLE EXISTING PRIMITIVE — reusedNode-derived from deployed bytes, so chain-attested in the same sense as vm/qfile. This is the raw material for (e)
r/…/service_registryCOSMIC BULL EXISTING PRIMITIVE — already reusedHolds 5 of our 20 as pkgPath + description + serviceType. It is a directory, not documentation: it has no field for a signature and adding one would be a redeploy
gnopmRELATED — not a duplicateDependency and version management. A go doc-shaped web server is discussed in its design notes as future work, not shipped
GnoScan, tx-indexerRELATEDTransaction and account explorers. Neither renders a package API
r/docs / r/docs/registryABSENT on pearl-1Confirmed in DISCOVERY.md §4 — there is no r/docs namespace on this chain
r/leon/hor (Hall of Realms)ABSENT on pearl-1Same
gnolang/gno #522"gno doc command + rpc + gnoweb view"RELATED — verified OPENThe $help view exists; the issue's remaining scope (remote packages, manual pages, the HTTP viewer/generator) is open. DISCOVERY.md §8 flagged this issue's status as unverified; this record closes that gap
gnolang/gno PR #6194"publish a static gnoweb preview for every pull request"RELATED — direct precedentOPEN, not draft. Crawl-gnoweb-into-a-static-site is an upstream pattern, not an invention
gnolang/gno PR #6191"community-realm notice on packages outside a trusted list"RISK — reported, not actioned. See §8OPEN, draft

No EXACT DUPLICATE was found in the searched sources for a generated, chain-derived API reference covering the methods and types of a specific set of deployed packages.


5. Shape (d) is not executable, and that is the load-bearing constraint

The obvious repair for §2.3 and §2.4 is to write a README.md and a package doc comment and put them on chain. It is worth naming plainly why that is not on the table, because the rest of the decision follows from it:

A package's bytes are immutable after addpkg. There is no edit. The only mechanism that would change what vm/qdoc and gnoweb return is deploying the package again at a new path — and CLAUDE.md §6 forbids modifying or redeploying an already-live application, with fee_split v1 and the registries named explicitly as frozen. All four primitives and all sixteen realms are live.

So the 16% figure in §2.2, the bare directory listing in §2.3, and the five empty Overviews in §2.4 are permanent properties of the deployed artifacts. They can be compensated for elsewhere. They cannot be fixed in place.

This is what rules out the on-chain answer on engineering grounds rather than policy grounds: there is no on-chain edit available, and a second deployment carrying documentation for the first would be a new, forgeable copy of what vm/qdoc already derives from the real bytes — strictly worse than reading the bytes, and a new drift surface besides.


6. The refusals and the deferral

(c) A new on-chain docs realm — REFUSED

All four reasons in DISCOVERY.md §5 apply unchanged. A fifth is specific to documentation: vm/qdoc is derived by the node from the deployed bytes, so it cannot disagree with the code. A realm holding documentation would hold text a publisher typed in, which can. Replacing a derived fact with a self-attested one is a downgrade presented as a feature.

The user's brief also says directly: "Do not create a duplicate on-chain registry."

(b) An HTTP/JSON API — REFUSED

The chain's ABCI surface is the API. It is publicly reachable at https://rpc.pearl.testnets.gno.land:443, it is the same surface verify_catalog.py uses, and verify_catalog.py --json already emits a machine-readable run. An API service in front of it would add an availability dependency, a trust hop, and a cache that can be stale — in exchange for data anyone can already query directly. That is the "unnecessary infrastructure" the brief warns against.

(a) A static site at cosmicbull.net — DEFERRED, not refused

Deferred rather than refused because it is the right eventual shape and the brief names it as the destination. It is not the right next step:

The deferral has a condition attached, so it is a decision and not a shrug: when the generated reference in §7 exists and is verified, the remaining work for a site is templating, and that is the point at which building one is justified.


7. The decision — BUILD (e)

A generated, chain-derived API reference in the repository, verified the same way everything else here is verified.

ArtifactKindWhy
tools/gen_api_docs.pyrepoReads vm/qdoc live from pearl-1 and emits one Markdown API page per package — package doc, exported functions, exported types, exported methods grouped by receiver, full signatures, per-parameter docs, and the crossing flag
catalog/api/*.mdrepo, generatedThe committed output. Human-readable, greppable, diffable, and linkable from anywhere
--check moderepoRegenerates from the live chain and diffs against what is committed. Exit 1 on drift, exit 2 if it could not complete
tools/test_gen_api_docs.shrepo§7a: the checker is code, so it is tested like code

Why generated and committed, rather than generated on demand

Because a generated file that nobody checks is prose again. Committing the output and shipping a --check mode makes the documentation subject to the same rule as every other claim in this repository: it is re-derivable from the chain by a command anyone can run, and if it ever stops matching, a command says so.

What this deliberately does NOT do


8. Reported, not actioned — the namespace risk

gnolang/gno PR #6191 (OPEN, draft) adds a "community realm" notice to gnoweb for any package outside a trusted namespace list. Trust is held by namespace, and the open registration path accepts human-readable names only.

Cosmic Bull's twenty packages are deployed under the address-based namespace g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3. If that PR merges as drafted, every one of our gnoweb pages — the interface §2.1 establishes as our primary developer surface — would carry an untrusted-realm notice.

This is reported and not acted on. Registering a human-readable namespace is a chain write against a system realm that changes the identity surface of all twenty live packages at once, and it is outside the scope of this objective (CLAUDE.md §10). It is a decision for a human, on these facts:


9. Limits of this record