docs/protocol-interface.mdpinned to impactium@637886d

Protocol interface reference

Impactium's public surface is its own protobuf message surface — typed Msg and query definitions declared once in .proto and code-generated into every client. One versioned schema describes the whole chain. This page is the map of that surface and how to read it as machine truth.

Applications run on a real on-chain execution layer: registered, capability-scoped, versioned and governed through x/app.

Why there is no ABI. A per-contract ABI exists to decode calls against bytecode nobody declared in advance. Impactium has no such bytecode, so there is nothing to decode against — the schema is the interface, and it is the same schema for every client. That is a property of the interface, not a limit on capability.

Protobuf, not ABI

Every interaction is a typed protobuf message wrapped in a signed transaction. Each message carries a type_url of the form /impactium.<module>.v1.Msg<Name>, and the app routes it to the owning module by that URL. There is no per-contract bytecode or ABI to track — one versioned schema describes the whole chain.

Clients are generated from those .proto files, not hand-written: prost for the Rust node, buf-generated TypeScript for the wallet and dashboards. That is why a transaction signed by the TypeScript wallet is byte-for-byte identical to what the Rust chain expects — and it is checked: a committed signing vector (tx-signing-vector.json) fails the build if the wire format ever drifts. See Verifiable, not trusted.

The message surface

Module Domain Messages (/impactium.<module>.v1.…)
x/identity Entity and Product behavior within classifications MsgRegisterEntity, MsgRegisterProduct, MsgFoundingBootstrap, MsgRotateKey, MsgSetKeyholders, MsgProposeRecovery, MsgApproveRecovery, MsgCancelRecovery, MsgUpdateNode, MsgRecognizeSentience, MsgSetApprovalPolicy, MsgRecordApproval
x/spore Referral spawning and the governed spawn rate MsgSpawnWallet, MsgProposeSpawnRate, MsgVoteSpawnRate
x/mint Claim → attest → mint MsgSubmitClaim, MsgAttest, MsgLogPersonalImpact, MsgAttestContribution
x/constitution K-ladder governance MsgProposeArticle, MsgAdvanceStage, MsgVote, MsgRatifyArticle
x/actioncatalog The ActionCatalog MsgProposeAction, MsgVoteAction
x/truecost 0TRUECOST MsgDeliver, MsgSplit
x/validators Governed admission MsgAdmitValidator, MsgRemoveValidator
x/resource Chain Resources and the commit graph MsgPublishRelease, MsgCertifyResource, MsgDeprecateRelease, MsgRecordPush
x/app The L2 app substrate MsgRegisterApp, MsgUpgradeApp, MsgDeprecateApp, MsgSetAppStatus
x/notary The Substrate — notary positions and the recovery second factor MsgGrantNotary, MsgWitnessRecovery
x/org Organizations, formation and ownership MsgRegisterOrgDetails, MsgAddMember, MsgRemoveMember, MsgSetRole, MsgProposeOrgFormation, MsgAcceptFormation, MsgSetOwnership
x/document Living documents — immutable version layers with per-version signatures MsgCreateDocument, MsgAddDocumentVersion, MsgSignDocumentVersion, MsgDeprecateDocumentVersion
x/domain ImpactDomain policy and the openness bonus MsgProposeDomainPolicy, MsgVoteDomainPolicy, MsgProposeOpennessBonus, MsgVoteOpennessBonus
x/classification The classification registry MsgSetClass
x/network The ordered registration layer ladder — Self through Global — the networks founded on each rung, and a node's registration at each one, admitted under that network's own rule MsgSetNetworkLayer, MsgFoundNetwork, MsgRegisterAtLayer, MsgDeregisterAtLayer, MsgRequestRegistration, MsgApproveRegistration
x/lexicon 0SACREDNUMBERS — numerals that carry their own frame (^GRID is a quadrant with two axes; 4 is four). Each declaration's kind is its mutability rule: universal is never amendable, structural needs a recorded justification, calibration is the tunable surface. Also holds 0LORE — where a term came from, with each source carrying its own verification status MsgDeclareSacredNumber, MsgAmendSacredNumber, MsgRecordLore
x/bliss Bliss job scheduling on the L2 substrate MsgEnqueueJob
x/alias Human-readable names bound to ids MsgReserveAlias
x/upgrade Scheduled consensus upgrades (Evolutions) MsgScheduleUpgrade, MsgCancelUpgrade

One module exposes no direct messages: x/capsule (the non-transferable Capsule type is minted only through an internal authority handed to x/mint — there is no user-facing message to move or create one).

x/notary still does most of its work through a post-execution hook — it seals every successful transaction and maintains the schema-version registry without a message. Its two messages exist because it is also the Substrate (decisions §23): it grants notary positions and witnesses that the real owner is behind a key recovery, which is what stops a Keyholder threshold from being sufficient on its own.

Applications: the execution layer

An application on Impactium is not a blob of bytecode at an address. It is a registered, capability-scoped entry in x/app, and the registry is what decides whether it may run at all.

What a registration carries Why it exists
an entrypoint names the implementation the manifest stands for
declared capabilities each names a foreign module the app may touch, and the access it gets. Anything not declared is refused at dispatch — an app's reach is enumerated, not discovered
a status — REGISTERED / ACTIVE / DEPRECATED only ACTIVE executes. Deprecating an app through governance stops it on the very next transaction, with no binary change and no restart
a version, with upgrade history MsgUpgradeApp supersedes a manifest; prior versions stay readable
app-scoped state (app/{app_id}/…) one app cannot read or clobber another's keys

The registry governs execution rather than describing it. An app that x/app has never heard of is refused outright: absence is not permission, or the registry would be optional for anything that forgot to register.

Applications today are native — compiled into the node, so shipping the code is itself the act of admitting it, which is why the founding manifest is seeded ACTIVE rather than awaiting review. Bliss is the first. The L2 execution layer is where applications that are not their own module will live, which is what app/{app_id}/… state partitioning exists for.

The capability list is what you read to know an app's reach: you can see what it is permitted to touch before it touches it.

Events: the machine-readable state changes

Every state-changing message returns typed events carrying enough data to reconstruct the graph without re-executing the chain. That is a hard authoring rule, not a convenience: it is the contract Karma's indexer reads to build the Hive-Knowledge Graph, and it bounds verification — a fact in the graph must be provable from (event + state proof), never from "trust the indexer." The event catalog is the machine-readable half of every human-readable page here.

Queries

  • Direct against a node — the chain's ABCI query returns state values. prove=true is not yet honored, and query responses contain no proof operations. The store supports ICS23 proofs, but proof generation is not yet connected to the ABCI query path; a returned value alone does not prove membership against a committed state root.
  • Rich reads — Karma's typed GraphQL API, for history, downline walks, and provenance. proofPath locates committed keys for capsules and releases; Entity and Product paths are not yet exposed. Independent verification requires a separately supplied proof and trusted state root until node query proof delivery is available.

The machine-readable source

The .proto definitions are the single source of truth for messages, events, and queries; the committed signing vector drift-guards the wire format. As the source opens toward Genesis, the protos and their generated clients ship as part of that release — so an integrator can regenerate a byte-compatible client in any supported language rather than trusting a hand-maintained SDK.