8. Commands

Draft protocolSource at 169cbd2 ↗Excerpt SHA-256 99cd37a…e29

A command is the only way an account or the governance multisig changes chain state. This chapter fixes the closed catalog of seventeen commands, the shape of a content commitment and the scheme registry that gives one meaning, and the validity rules of the publication, project, username, cleanup, and system families. Per-command read and write sets, guards, and write order are in the state machine, and canonical field order, bounds, and guard positions are in encoding section 4.

8.1 Catalog

A command is one tagged, signed instruction that a block executes as a unit. A command family is the group of commands that share a record family and a set of guards. The catalog is the closed set of commands a ruleset admits.

R-8.1. The catalog contains exactly seventeen commands, and a command whose tag is not in the catalog is invalid.

R-8.2. Commands in a block execute in one flat, strict, per-block order (section 12).

R-8.3. A block that contains one deterministically invalid command is invalid: a proposer MUST execute each candidate while building and MUST exclude one that is invalid, and a verifier MUST reject the whole block rather than skip the offending command.

R-8.4. Every command that applies emits exactly one CommandFinalized event (section 14).

R-8.5. Execution derives expiries, allocated revisions, and domain digests, and a command that supplies an alternative value for a derived field is invalid.

Checks performed on a command before it reaches a block are therefore advisory and never change validity, because block execution is the only authority (section 12, with admission policy in operations). A CommandFinalized event is not a cryptographic receipt on its own (section 15).

The catalog:

Command Actor Authorization Transition
INIT_ACCOUNT account genesis witness initialize policy if funded and uninitialized
ROOT_CONFIGURE account root quorum replace owners and threshold; bump version; identity unchanged
KEY_AUTHORIZE account root quorum authorize with a fresh generation, atomically replacing an invalidated resident key, or renew an unexpired current generation
KEY_REVOKE account root quorum One deletes and discharges one key; All advances the delegation epoch without a scan; both uncharged
PROJECT_CREATE account root/ACCOUNT create project; optional creator-asserted origin commitment
PROJECT_SET_METADATA account controller using root/ACCOUNT LWW slug and description; maintain the unique slug claim atomically
PROJECT_SET_STATUS account controller or maintainer using root/ACCOUNT/PROJECT; unfreeze controller only ACTIVE or FROZEN; bumps a lifecycle sub-revision that transfers do not touch
ROLE_SET account controller or maintainer using root/ACCOUNT/PROJECT; section 8.4 restricts which grants grant or revoke a role; grants get a new role_grant_generation
TRANSFER_OFFER account controller using root/ACCOUNT only set, update, replace an expired offer, or clear it
TRANSFER_ACCEPT account named destination using root/ACCOUNT only accepts a live offer; rotates control_generation, deactivating all prior grants in O(1)
PUSH account root/ACCOUNT/PROJECT/WRITE + role append commitments and apply ref ops atomically; a ref create locks a deposit, a ref delete discharges it
RECLAIM account root or an unscoped active key of class WRITE or above delete one objectively stale record and discharge its deposit to the stored payer (section 9)
USERNAME_CLAIM account root/ACCOUNT; restoration owner-only claim, extend a resolving lease, restore during grace, or atomically rename
USERNAME_RELEASE account root/ACCOUNT end resolution now; one grace period from release
IMPORT_CREDITS system settlement proof strict-advance beneficiary cumulative credit
SCHEDULE_RELEASE system governance multisig activate, defer, cancel, or emergency-activate a protocol release (section 18)
VALIDATOR_SET_SCHEDULE system governance multisig under DynamicReshareV1, append or cancel a validator-set entry for a future epoch; always invalid under FixedEpochZeroV1

Several things are deliberately outside the catalog. Links, reactions, merge requests, verifications, and account metadata are off-chain signed messages (section 8.7). A fork is PROJECT_CREATE carrying an origin commitment (section 8.4). Commit bundles, ref updates, and ref deletes are operations inside PUSH (section 8.3), and a merge request's terminal step, which accepts the request and then moves the ref, is an ordinary PUSH. Project archive and project remove are covered by the FROZEN status (section 8.4). Content that requires chain-backed publication and order is represented by a commit and published through PUSH, so there is no separate attestation command and no content-proof subsystem; the relationship between a commit and its files belongs to the scheme, which is mkit for the primary scheme.

8.2 Commitments and the scheme registry

A commitment is the pair {scheme_id, native_id} naming one content-addressed object outside the chain. Its CommitmentId is the BLAKE3 digest of that pair under the domain registry of section 6. A scheme is a registered content-addressing system, and its scheme_id is the digest of its scheme descriptor.

Commitment       = { scheme_id, native_id }
SchemeDescriptor = { name, hash_algorithm, id_length, object_format_version,
                     addressing_epoch, canonical_decoding, permitted_kinds,
                     per_kind_preimage_rules }

R-8.6. A validator checks only that native_id has exactly the length registered for its scheme, and that check proves neither the object's kind nor its availability.

R-8.7. A verifier that holds object bytes recomputes the identity under the registered scheme, parsing the object's kind from the bytes' own prologue and dispatching to that kind's preimage rule, so a kind-dependent rule is unambiguous.

R-8.8. Where a scheme defines a commit object, a publication verifier additionally requires that the object a commitment names is a commit object of that scheme.

R-8.9. A new scheme is added only by a versioned-state release (section 18), never by a proposer.

R-8.10. A project's scheme is fixed at creation, and a push carrying a commitment under any other scheme is invalid.

Registered at launch:

Scheme Identity Notes
mkit-blake3 32-byte BLAKE3 object id; flat BLAKE3(bytes) for commit, tag, blob, remix; domain-bound BMT root for tree and chunked blob; format epoch bmt-v1 the primary scheme; the commitment names an mkit commit object
git-sha1 20-byte git object id externally hosted native-git projects; GitHub is SHA-1 only
git-sha256 32-byte git object id registered now so the git transition needs no release

mkit's git import is a re-signed fork that yields mkit ids, so a repository imported from git publishes mkit-blake3 commitments, and its original git identifiers may be attested off chain (section 8.7) and never on chain.

8.3 PUSH

PUSH publishes commitments into a project's permanent membership log and applies reference operations, in one atomic command.

PUSH    { project_id,
          commitments: [Commitment; <= max_commitments_per_push],
          ref_ops:     [RefOp;      <= max_ref_ops_per_push] }     # signed intent
RefOp   = CREATE { ref_name: RefName, target: Commitment }
        | SET    { ref_name: RefName, expected_revision, target: Commitment }
        | DELETE { ref_name: RefName, expected_revision }
Witness = SameCommand(index) | Location(loc) | Proof(anchor_size, loc, inclusion_proof)

The intent is encoded under encoding section 4 and the unsigned evidence under encoding section 5. Per-variant guards and write order are in state machine section 5.

Reference names

A ref name is a protocol label and not a filesystem path, and an adapter enforces its own safe path handling. The state key uses ref_name_digest = BLAKE3("makechain.ref-name" || canonical(ref_name)), whose domain is registered in section 6, so clear names are never duplicated in validity state and travel only in block bodies.

R-8.11. A RefName is nonempty valid UTF-8 of at most max_ref_name_bytes bytes, contains no ASCII control character, meaning none of U+0000 through U+001F and not U+007F, and is a case-sensitive exact byte string on which no Unicode normalization, case folding, trimming, or path rewriting occurs in signing or in execution.

R-8.12. A ref name travels in the signed intent and never as an unsigned display hint, and a client derives any displayed name from the decoded signed intent and escapes it for presentation without changing the signed bytes.

Reference operations

Operation Requires Deposit effect
CREATE absence of the named ref at this operation's position in the command charges the ref creation fee and locks the ref deposit
SET a resident ref with exactly the expected revision keeps the deposit and its stored payer unchanged
DELETE a resident ref with exactly the expected revision discharges the deposit to its stored payer

Deposit mechanics are in section 9.

R-8.13. The command's authority context binds the project mutation counter whenever the command contains a CREATE (section 7).

R-8.14. Commitments are appended to the membership log in list order, the entry at zero-based list index i taking location log_size_before_command + i, where log_size_before_command is the membership log size after every earlier command of the block has applied in the block's flat order, a discarded candidate being no part of the block and consuming no location.

R-8.15. Ref operations apply after the appends, in operation order, compare-and-set against each ref's current revision.

R-8.16. A SET to the current target carrying the current expected revision is a valid no-op.

R-8.17. Any failure of any part of the command invalidates the whole command.

R-8.18. A commitment-only PUSH, carrying no ref operation, is valid whenever the actor is authorized and the account is funded.

R-8.19. Duplicate commitments in the log are allowed and charged, and a client with no usable witness republishes the commitment in the same command.

R-8.20. A finalized ref update proves publication of its target and does not prove inclusion of any earlier chunk of a multi-command upload.

R-8.21. Fast-forward and ancestry relationships between ref targets are not consensus rules, and every authorized writer, including one using a project-scoped WRITE key, may create, force-update, or delete any ref, subject only to compare-and-set and to project status.

Deduplication of commitments is a client and indexer duty. Protected refs and approval thresholds are outside the launch protocol.

Membership witnesses

A witness is unsigned evidence in the envelope that binds one non-delete ref operation to a membership of the same project.

R-8.22. The signed intent names every ref target by its full Commitment, and the envelope carries exactly one witness per non-delete ref operation, in operation order, and no witness for a DELETE.

R-8.23. A gateway or a relayer MAY replace a witness without a new signature from the actor, and every witness is counted in the command's worst-case resource vector and enters command_root through the complete envelope (sections 10 and 11).

R-8.24. Execution recomputes the leaf Keccak256(project_id || scheme_id || native_id) from the signed intent and requires the witness to resolve to exactly that leaf.

Form Evidence supplied Valid when
SameCommand(index) a zero-based index into this command's commitments the index is in range and the entry it names is the operation's signed target commitment, so the witness resolves to the location this command appends it at; this is the universal fallback and is charged like any publication
Location(loc) one membership-log location loc lies in the executing parent's canonical [floor, size) range and one point read at loc yields the required leaf
Proof(anchor_size, loc, inclusion_proof) an inclusion proof for an older location parent_floor < anchor_size <= parent_size, anchor_size is a commit boundary on the executing parent's ancestry, loc < anchor_size, and the proof verifies the required leaf under the root at anchor_size

The bound at the floor is strict because reconstructing the root at size S needs the retained commit operation at S - 1 and its floor.

R-8.25. A validator derives the trusted root at anchor_size from its own canonical prefix and never from the proof the client supplied.

R-8.26. Eligibility of a location or an anchor is defined by the executing parent's canonical range and ancestry, and never by what a node happens to have finalized or retained locally.

R-8.27. A wrong, non-boundary, or out-of-range witness is deterministic invalidity, while a journal read error on an eligible location is transient inability, and neither outcome is ever nonmembership.

For a persisted prefix a validator reconstructs that root from a local historical proof of the retained commit at S - 1; for a speculative parent whose prefix is not yet persisted it uses the retained ancestor batch whose root is the root at S, keeping ancestor handles for the verification horizon. A proof made against any recent finalized commit therefore stays valid while the membership window covers its anchor, so ordinary inclusion delay never invalidates a signed push. One binding applies everywhere, with no strict mode and no loose mode. A resolved witness proves exactly that the target was published into this project's permanent history by an authorized writer, and the signed ref operation itself attributes the update.

Charge

R-8.28. The signed intent carries max_charge, the ceiling on the command's gross non-refundable charges, including evidence bytes and proof work, plus every new deposit lock the command creates.

R-8.29. A deposit discharged by the same command never reduces that running total, and a command whose total exceeds max_charge is invalid.

R-8.30. A gateway may replace a witness only within max_charge, and a larger proof that would exceed it requires a new signature.

Section 9 uses this definition of max_charge unchanged. Intent-level status is tracked separately from the envelope-specific command_id, which changes when evidence is replaced.

Commitments carry no descriptor

R-8.31. A commitment carries no descriptor, so commit parents, tree, author, and message are not block fields.

Commit metadata is derived by indexers from the objects themselves and labeled object_verified, or carried as off-chain signed messages and labeled publisher_asserted (section 8.7 and history query). object_verified means decoded from bytes whose identity was recomputed under the registered scheme, and it neither authenticates a claimed author nor establishes that an embedded signing key belongs to that author. A publication receipt attributes the on-chain act to its publishing account, independently of any content-author claim and of any object signature (section 15).

8.4 Projects

A project is the permanent unit of publication and authority, identified by project_id = BLAKE3("makechain.project" || chain_id || creator || client_salt), which is immutable. Its controller is the account in Project.owner. A role grant is a ProjectRole record naming a grantee as maintainer or writer.

Origin

The optional origin of PROJECT_CREATE is a creator-asserted source-content reference, and it is not a proven source project, not an ancestry relationship, and not an endorsement.

R-8.32. An origin follows its own registered scheme's id-length rule, need not use the new project's scheme, creates no membership leaf, and satisfies no ref witness.

An application that needs to establish that an origin commitment was published in a named project attaches a separately verified publication receipt (section 15), while a claimed content relationship is verified by the scheme, which is mkit for the primary scheme.

Slugs and metadata

The ProjectMetadata record is keyed by project id and holds the project's slug and description. A SlugClaim record is keyed by (owner, slug) and binds that pair to one project in the same validity database. A slug is valid only in canonical form, and no normalization is performed: the character rule and length bounds shared by slugs and usernames are fixed by encoding section 3.3 and encoding section 13, a string outside canonical form is invalid rather than adjusted, and the check applies before lookup and before signing. Project metadata is permanent.

R-8.33. A claim on an occupied (owner, slug) pair is invalid.

R-8.34. Each project has exactly one matching claim, and no claim may outlive or disagree with its project (section 9).

R-8.35. A slug change atomically deletes the old claim and creates a new one, a transfer performs that same exchange under the destination's namespace, and where that namespace already holds the old slug the accepting command MUST supply a free new slug.

R-8.36. Each claim carries an incarnation (project_id, allocated_counter) drawn from the project's mutation counter, so returning to an old owner and slug pair never reuses a claim identity.

R-8.37. A claim is a deposited record: creation pays its fee and locks its deposit, deletion discharges the stored payer's deposit, and the signer of the command pays for the successor claim (section 9).

R-8.38. A description-only update does not recreate an unchanged slug claim, while a claim creation counts toward new_records even when the old claim is deleted in the same command (section 10).

R-8.39. PROJECT_SET_METADATA carries expected_project_mutation_counter exactly when its slug changes, because moving a slug allocates a child record, and omits it for a description-only update (section 7).

Status and publicity

R-8.40. A project has exactly two statuses, ACTIVE and FROZEN, and is permanent once created, with no deletion and no archival status.

R-8.41. Everything in a block is public, including commitments, ref names in bodies, collaborator accounts, and timing, and the protocol has no public or private project classification, no visibility field, and no reader role.

R-8.42. PROJECT_SET_STATUS bumps a lifecycle sub-revision that transfer commands never advance, so an incident-response freeze cannot be staled by a routine offer.

Project roles govern publication and administration and never access to object bytes, which stay outside consensus (section 17).

Who may do what

R-8.43. The actor's project authority and the actor's key capability are independent requirements, and a command satisfying only one of them is invalid.

R-8.44. Account root authorization authenticates the actor and never bypasses project authority.

R-8.45. A role grant names maintainer or writer, and granting a role to the current controller is invalid.

Action Project authority Key capability in addition to root While FROZEN
PUSH, including every ref operation controller, maintainer, or writer ACCOUNT, PROJECT, or WRITE; scope must match invalid
Set slug or description controller ACCOUNT allowed
Grant/re-grant maintainer controller ACCOUNT or PROJECT invalid
Grant/re-grant writer controller or current maintainer ACCOUNT or PROJECT invalid
Revoke maintainer controller ACCOUNT or PROJECT allowed
Revoke writer controller or current maintainer ACCOUNT or PROJECT allowed
Freeze controller or current maintainer ACCOUNT or PROJECT allowed, subject to lifecycle CAS
Unfreeze controller ACCOUNT or PROJECT allowed, subject to lifecycle CAS
Set/update/clear transfer offer controller ACCOUNT allowed
Accept live transfer offer named destination account ACCOUNT allowed; status preserved

R-8.46. A maintainer MUST NOT replace a maintainer grant with a writer grant as a way to revoke or demote it, and both the old role and the new role must be within the acting maintainer's authority.

R-8.47. The controller may revoke any stale grant, RECLAIM may remove one without project authority (section 8.6), and both reclaim and account-key revocation remain valid while a project is FROZEN.

The state machine enumerates these rules per command variant and introduces no additional permission.

Roles

A ProjectRole is keyed by (project, grantee) and stores both issued_control_generation and grant_generation. The second is drawn from the project's mutation counter and identifies the individual grant for compare-and-set.

R-8.48. A role authorizes nothing unless its issued_control_generation equals the project's current control_generation.

R-8.49. An intent's role_grant_generation must equal the stored grant_generation, and an intent whose value differs is invalid (section 7).

R-8.50. A re-grant replaces the record in place, discharging its old deposit and locking a new one, and never adds a key.

R-8.51. A deactivated grant stays resident until the current controller revokes it or anyone reclaims it, and either transition discharges its deposit to the account that paid it and never to the new controller.

Transfer

A TransferOffer is keyed by project id, names exactly one destination, and binds its issuing control generation.

R-8.52. Every set, update, clear, and acceptance binds the expected offer revision, and creation of an offer from absence additionally binds the project mutation counter.

R-8.53. An update of a still-live offer allocates a new revision and keeps the offer's deposit metadata, while replacing an expired resident offer discharges the old deposit and charges a fresh fee and deposit.

R-8.54. Clearing an offer reads the raw record and discharges its deposit even after expiry.

R-8.55. Acceptance requires the named destination, an unexpired offer, and the offer's current issuing control generation, and it consumes the offer and discharges its deposit in the same transition, so a consumed offer can never transfer the project again after ownership has changed.

R-8.56. Acceptance rotates control_generation, which deactivates every prior grant in O(1) and without a scan.

R-8.57. Refs carry over to the new controller with their deposits and their stored payers unchanged.

R-8.58. A self-transfer is invalid.

R-8.59. TRANSFER_OFFER and TRANSFER_ACCEPT require a root witness or an ACCOUNT key, which closes the two-command theft path available to a compromised PROJECT key.

R-8.60. TRANSFER_ACCEPT always carries expected_project_mutation_counter, because it always allocates the destination owner's slug claim (section 7).

A paid round trip through a second account is an intentional O(1) reset of the grant set, and its event carries the control generation rather than an exact count of deactivated grants (section 14).

8.5 Usernames

A username is a leased, account-owned name, held as a lease plus a grace period and priced at a flat annual price. A UsernameLease record holds the lease. The permanent AccountUsername record holds the account's current-name pointer, its rename-cooldown metadata, and its monotonic name allocation counter. Two deadlines govern a name: the resolution deadline, before which the name resolves, and the reservation deadline, before which only its owner may take it. The minimum length, the rename cooldown, the one-year lease duration, and the maximum horizon username_horizon_ms are chainspec parameters whose launch values are in section 19 and whose exact durations are pinned by encoding section 13.

INV-AUTH-05. Username ownership is unique; a release or rename never shortens the owner-only grace.

Leases and counters

R-8.61. A name shorter than the chainspec minimum length is invalid.

R-8.62. AccountUsername is created lazily, by the first name operation that needs to mutate it, that creation pays the ordinary permanent-record fee and consumes a creation reservation (sections 9 and 10), and while the record is absent an operation's guard uses the initial counter base.

R-8.63. Each new UsernameLease has incarnation (owner_account, allocated_counter) and a checked revision, and allocation increments the owner's surviving counter, so a name deleted and later claimed by another account never reuses an incarnation.

R-8.64. Every operation on a resident lease binds that lease's expected incarnation and revision, and a claim by a new owner additionally binds that owner's name allocation counter.

R-8.65. At most one name resolves for an account at a time, while a released name may retain a reservation during grace.

Cooldown

R-8.66. Every claim or restoration that selects a different name enforces the rename cooldown and advances the cooldown metadata.

R-8.67. Cooldown metadata retains the last selected name and the time it was selected, even after release, expiry, or reclaim, and a replacement or a reclaim never deletes it and never deletes the owner's allocation counter.

R-8.68. An explicit release followed by a claim does not bypass the cooldown, and the first selection an account makes has no cooldown.

USERNAME_CLAIM

USERNAME_CLAIM has exactly four variants: claim, extend, restore, and rename.

R-8.69. A rename releases the account's current name and claims or restores the requested name atomically, subject to the cooldown.

R-8.70. During grace only the prior owner may restore the lease, and after grace anyone may claim the name as a fresh incarnation.

R-8.71. A restoration preserves the deposit and the incarnation, advances the revision, pays the lease price, and establishes a new resolution term measured from consensus time.

R-8.72. Where another name currently resolves for that account, both a restoration and a fresh claim MUST use the atomic rename variant, which may neither bypass the cooldown nor leave two resolving names.

Extension by a third party

R-8.73. Anyone holding root authority or an unscoped ACCOUNT key may pay to extend a currently resolving lease.

R-8.74. An extension advances the lease revision and extends from the existing resolution deadline by paid whole-year increments, and it never restores a released or naturally expired name, never changes the owner or the deposit payer, and never changes the current-name pointer.

R-8.75. An extension is bounded by block_timestamp_ms + username_horizon_ms, and an extension that would exceed the horizon is invalid, never partially charged, and never silently shortened.

R-8.76. Restorations and fresh claims are subject to the same horizon.

The two deadlines

R-8.77. Every successful claim, restoration, and extension sets the reservation deadline to the resulting resolution deadline plus grace, with checked arithmetic.

R-8.78. At natural expiry, resolution ends and the owner reservation is retained until lease_expiry + grace.

R-8.79. Releasing or renaming an active name ends resolution immediately, forfeits the unused prepaid term without refund, and starts one full grace period measured from the release timestamp.

R-8.80. Releasing a name already in grace neither shortens nor extends its reservation, and a redundant release of a name already in grace is invalid.

R-8.81. Both deadlines are consensus-time predicates evaluated on read (section 9).

R-8.82. The record stays resident with its deposit until a claim made after the reservation deadline replaces it or a reclaim deletes it, and either transition discharges the deposit to the stored payer.

R-8.83. A release advances the lease revision and clears a matching current-name pointer, and a replacement or a reclaim clears the former owner's pointer only if both the name and the incarnation still match.

R-8.84. RECLAIM is never valid during a username's grace.

Front-running of a new username claim by a gateway or a proposer, and sniping of a name after its grace, are accepted at launch and are stated in section 4. The absence of a public mempool is not a defense against those parties.

8.6 RECLAIM and the remaining account and system commands

RECLAIM

RECLAIM is the permissionless cleanup command. Section 9 owns the staleness predicates, the deposit mechanics, and the lazy-expiry model that make a record reclaimable.

R-8.85. Retired; its content is R-9.42.

R-8.86. Retired; its content is R-9.43 and R-9.47.

R-8.87. Retired; its content is R-9.44.

R-8.88. Retired; its content is R-9.45 and R-9.46.

Discovery of reclaimable records is indexer work, and the protocol keeps no queue, no sweep, and no job for it.

Account commands

Section 7 owns account identity, the keychain, root authorization, and replay. INIT_ACCOUNT initializes the policy of a funded, uninitialized account under its genesis witness, and is charged (section 7). ROOT_CONFIGURE replaces the account's owner set and threshold under its current root quorum, leaving AccountId unchanged (section 7.5). KEY_AUTHORIZE and KEY_REVOKE authorize, renew, and revoke keychain entries under that same quorum, with the variant conditions and the keychain_revision binding in section 7.3.

System commands

A system command carries no account authorization context. IMPORT_CREDITS is authorized by a finalized settlement proof and strictly advances the proved beneficiary's credited cumulative (section 16). SCHEDULE_RELEASE is authorized by the governance multisig and activates, defers, cancels, or emergency-activates a protocol release under the schedule rules of section 18. VALIDATOR_SET_SCHEDULE is authorized by the governance multisig and, under DynamicReshareV1, appends or cancels a validator-set entry for a future epoch, while under FixedEpochZeroV1 every variant of it is deterministically invalid for every payload and mutates no state (section 13).

8.7 Off-chain signed messages

Links, reactions, merge-request discussion, profile data, external-address verifications, and a project's availability-layer announcements are carried by an application-owned signed-message service and are not commands. An off-chain message is attributable to an on-chain identity because it is signed by a delegated key of the signing account's keychain and binds that account, the key's generation, and the key's issuing delegation epoch (section 7). The envelope profile, signer rules, ingress bounds, and service guarantees, including the rule that deletion is a second signed message honored by cooperating services and never enforced by consensus, are in off-chain signed messages.

R-8.89. The SOCIAL capability class, nested below WRITE, authorizes no command, so a key of that class can neither spend credits nor move a ref (section 7).

R-8.90. A project-scoped key may sign only project-scoped message kinds whose predicate binds its exact project id, and never account profiles and never account-wide external-address verifications.

R-8.91. A project's availability layers are announced off chain, by messages signed with the project's keys, and the chain records no locator, while an on-chain locator is a possible later release (section 17 and availability profile).

R-8.92. An off-chain message or an mkit attestation attached separately to a commit is not included in that commit's content commitment and gains no chain inclusion and no ordering guarantee merely by naming it.

A later published commit may bind such content under the native scheme, which does not retroactively prove when the content was created and does not replace the signed-message service's own acceptance and revocation checks.

8.8 Rationale

This subsection is informative.

The catalog holds only what benefits from being ordered by every validator forever. Links, reactions, and review discussion are signed envelopes bound to on-chain identity through the keychain, and a review's only consensus-relevant step is a reference move, an ordinary push. The push is atomic because a ref naming an unpublished commit is the one inconsistency the chain cannot repair afterwards, and the ref-to-membership binding is mandatory because the chain holds no objects. A commit descriptor stays off chain: a publisher's unverified assertion would duplicate the object, could contradict itself across publications with no authoritative winner, and would reattribute imported history to the importer. The scheme registry is closed and extended by release, because an arbitrary scheme would turn a membership proof into proof of publication of a string. The primary scheme is the object store's own identity. A minimum username length avoids selling scarce short names at a flat price, a rename cooldown blunts griefing, and commit-reveal is the documented response if front-running becomes unacceptable.