Files
orgchain/SPEC.md
T
teahubxyzandClaude Opus 5.5 7c9306402d Orgchain v1.9: lineage/v0 as an ordinals metaprotocol, rehearsed on regtest
SPEC.md writes lineage/v0 down as an ordinals metaprotocol: the envelope
fields, chain order, authority by verified parents, every rule, ownership by
sat. bin/lineage-index.mjs reads lineage events from a real ord server and
folds them with the same reducer the lab uses.

tools/regtest rehearses the sample on Bitcoin Core regtest with standardness
on: the lab's own action code signs on a chain funded only by coins imported
from regtest (LocalChain.importCoin), each beat's transactions are broadcast
byte for byte and mined, ord indexes them, and --compare checks the same
events in the same beats, the same metadata and parents, every inscription
in the same output and the same trees. tests/indexer.test.js replays a
recorded run.

The first rehearsal found that reveals committed to tapscript's re-encoded
tapleaf, which real Bitcoin rejects. They now commit to the exact script
bytes, and the local chain checks script paths per BIP-341/342, still
loading reveals made before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H4upF5LVwmPDDqrhdUfnXh
2026-10-15 02:04:35 -07:00

7.2 KiB

lineage/v0

lineage/v0 is an ordinals metaprotocol for lineage holdings: LLCs, the orgs and agents they birth, the belts and decisions on their record, and the items they make. Every event is an inscription. The chain orders the events and proves who was allowed to make each one; the state (the trees) is stored nowhere, and every indexer that applies these rules to the same inscriptions gets the same trees.

Status: test networks only (Orgchain's in-browser chain and Bitcoin Core regtest). The reference implementation is reduce() in src/orgchain/lineage.js; src/indexer/ord.js and bin/lineage-index.mjs run it over a real ord index.

1. Inscriptions

lineage/v0 uses these fields of the ord envelope (inscriptions):

tag field use
7 metaprotocol exactly lineage/v0; inscriptions without it are not lineage's
5 metadata a CBOR map: op and its fields (section 4), all strings, in 520-byte pushes (Orgchain keeps it under 2048 bytes)
3 parent the inscription id of the node that authorizes the event; exactly one, except for found
1 content type text/plain;charset=utf-8; the body is a short label such as birth time, ignored by the rules
2 pointer puts a child's inscription in its own output when the parent is spent first

The body, delegate (tag 11) and properties (tag 17) carry no meaning here; properties may later carry display traits such as a belt's colour, never authority. Unknown odd tags are ignored. Never use unknown even tags: ord treats such an inscription as unbound, so it has no location.

A reveal is a script-path spend whose tapleaf commits to the envelope script's exact bytes (BIP-341). Orgchain's reveals before v1.9 committed to a re-encoded script; real Bitcoin rejects those, and Orgchain's local chain still loads them.

2. Order

Events fold in chain order: block height, then transaction order in the block, then envelope order in the transaction. ord's inscription numbers follow the same order. Unconfirmed events are provisional, and ord indexes none.

Within a block, the miner sets the order. Events that share an authority are chained, because each one spends that authority's inscription, so their order is fixed. Independent events may land in any order, and outside the conflicts in section 6 that changes nothing.

3. Nodes and authority

A node is created by an accepted found (a holding) or birth (an org or an agent), and its id is that event's inscription id. Each node has a kind (holding, org or agent), a status (active or closed), and, below a holding, an edge: derived (the parent holds the child's seed) or adopted (it graduated and holds its own root). A child's index counts its parent's earlier children of the same kind, orgs and agents separately, and is never reused.

An event's parent is the node that authorizes it, and it counts only if the inscribing transaction spends that node's inscription: ord records a parent only then (provenance). Indexers use ord's recorded parents, never the raw tag. So acting for a node means holding its inscription, and moving the inscription moves the authority.

4. Events

op parent metadata effect
found none name a holding; no active holding may already have that name
birth an active holding or org name, kind (org or agent, default org) a child; the parent may not already have an active child of that name
award an active holding or org to, skill, belt (white, green or black) to (any other active node, in any holding) holds that belt in that skill, replacing its earlier belt in it
decide an active node title (required), why (optional) a decision on the node's record
make an active node name, note (optional) an item, made and first held by the node; a node makes one item per name
graduate the child's parent, active of (an active org child, not yet adopted) the edge becomes adopted, and the org becomes a holding of its own (section 5)
close the node itself, active none the node closes, with every active derived descendant; adopted ones stay open

Names (holdings, children, skills, items) are 1 to 40 lowercase letters, digits or hyphens, starting and ending with a letter or digit, because they become domains. Text fields are trimmed, and only their first characters count: 140 for a title, 400 for a why, 280 for a note. Agents do not birth or award. An event that breaks a rule is rejected: it stays on the chain and changes nothing. Any other op is rejected.

5. Holdings and graduation

A holding is a root: a found, or an org that graduated. When an org graduates, it and its descendants still in the old holding re-root under it, and it joins the holdings. Its parent stays its parent, so where it came from stays on the record, and its old holding's tree keeps a row for it. A graduation event belongs to both holdings.

In Orgchain a graduation is followed by a handoff: the org's fresh root claims its inscription, and the derived key that held it countersigns. After that, only the new root can act for the org.

6. Order-sensitive conflicts

Where independent events conflict within one block, the block's order decides. These are the cases: a close and an act by one of its derived descendants; an award and its recipient's close; two foundings with the same name.

7. Ownership, items and deals

Whoever controls the output that holds an inscription's sat holds that node or item; for indexers that is ord's satpoint. Items move like any inscription. A deal is not an event: it is one transaction that carries the item and the buyer's coins in, and the item to the buyer, the price to the holder and the buyer's change out. The buyer signs its inputs first (SIGHASH_ALL) and the holder countersigns the item's. ord sees the item move, and nothing else needs indexing.

8. Keys

Indexers need no keys. Keys say where a node's inscription is expected to live, and who can sign for it. Each holding has a 24-word root (BIP-39), and an org's seed is BIP-85 from its parent's (m/83696968'/39'/0'/24'/i') until it graduates. An org is account 0 of its seed and its agents are accounts 1 to n. Each account holds its inscription at its BIP-86 Taproot address (m/86'/coin'/account'/0/0), keeps its money at BIP-84 SegWit, and has a NIP-06 npub.

9. Versions and other chains

Tag 7 carries the version. A new version is a new string with its own rules, which v0 indexers ignore. The events and the rules are chain-agnostic. What another chain must supply is its own proof of order and of authority (a signature by the node's key where nothing is spent). Each holding's events would live on one home chain, and an org-signed keyring would bind a node's keys across chains.

10. Conformance

tools/regtest rehearses Orgchain's sample on Bitcoin Core regtest, byte for byte, and bin/lineage-index.mjs --compare checks that ord and the lab tell the same story: the same events in the same beats, the same metadata and parents, the same trees, and every inscription in the same output. tests/indexer.test.js replays a recorded run.