The same fact lived in nine hand-kept places and they disagreed about 58
proposals. This makes the file the only authority and everything else a
projection of it.
ONE VOCABULARY, in vocabulary.json, read by the lint, the generator and the
doc site. Three words, each answering "can I rely on this?" and nothing else:
Draft nothing implements it yet, or its own text says the work is ahead
Final the thing it specifies exists in the code
Living governance and process: amended in place, never finished
Eight spellings folded in. `Active` was the one doing real damage: on four Meta
and Process HIPs it meant living, on 48 others it meant shipped, and one word
doing two jobs is why nothing agreed. `Review` and `Last Call` described a
queue rather than a document, and a proposal under review is still one you
cannot build against.
STATUS IS EARNED, not declared. Every Standards Track proposal was checked
against the estate: 235 have their implementation, and eight do not and say so.
HIP-0095 carries a twelve-week plan ending at "mainnet launch" and has no code.
HIP-0525 specifies an all-machine meeting while apps/meet refuses a machine a
seat. HIP-0078 names a prover at a "planned location" that does not exist.
HIP-0114 is the cog.* procedure set, and that procedure set returns nothing.
HIP-0003, HIP-0102, HIP-0305 and HIP-0901 likewise: looked, found nothing.
SIXTEEN TOMBSTONES DELETED rather than statused. A dead document kept alive in
the index is one concept wearing two names. Each successor exists and carries
the text, and the 90 references that pointed at a tombstone now point at it --
whole markdown links at once, so link text cannot outlive its target. Three of
the sixteen were pure compatibility: HIP-0028 specified a migration off a
Bitnami chart, HIP-0029 dual-engine MySQL, HIP-0030 a schema-deprecation
policy. We ship no backwards compatibility, so we do not specify it.
Nine links were already broken and had been since the corpus was renumbered:
short-form ./hip-5.md paths that never existed. Two named the wrong proposal --
one cited "HIP-1: Hanzo Multimodal Models" where multimodal is HIP-0003.
THE GENERATOR REFUSES more often than it writes, because a short table looks
exactly as authoritative as a complete one. Rows must equal files; a shrinking
index must say by how much; a section whose input is missing is an error, not
an omission; nothing is written until all of it validates. Its self-test breaks
the corpus eleven ways and requires each to refuse AND leave README byte-
identical -- a guard that reports after half-writing has protected nothing.
The lint's second implementation of the same comparison is gone.
The site rendered 52 proposals with a fallback grey badge and counted them
toward none of its three stat tiles, because docs/lib/source.ts declared a
status union by hand: it admitted a `Stagnant` no file has ever carried and
omitted the one 52 files did. Five components each kept their own copy of the
colours. All six now read vocabulary.json.
8.8 KiB
hip, title, type, category, status, author, requires, created
| hip | title | type | category | status | author | requires | created |
|---|---|---|---|---|---|---|---|
| 0079 | Q-Chain — Quasar Finality Block Standard | Standards Track | Infrastructure | Final | Hanzo AI | HIP-0077, HIP-0078, HIP-0084 | 2026-05-10 |
HIP-0079: Q-Chain — Quasar Finality Block Standard
Abstract
Q-Chain is the compact finality-block log for the Quasar consensus engine. Each Q-Block carries the minimum information needed for finality: roots of the validator / DKG / identity state held in Z-Chain (HIP-0078) plus a single Pulsar-M-65 threshold signature (HIP-0084) that proves the current epoch's committee finalised the block. Q-Chain does not carry raw ML-DSA validator pubkeys, raw ML-DSA per-validator signatures, raw DKG transcript messages, or raw attestation blobs — those live in Z-Chain.
The result: a finality lane whose per-block size is bounded and small (a few hundred bytes plus one ~3.3 KB Pulsar-M-65 signature), independent of validator-set size. Adding validators makes Z-Chain heavier, not Q-Chain.
Specification
Q-Block structure
QBlock {
version uint16
network_id uint32
chain_id uint32
height uint64
round_or_view uint32
parent_qblock_hash [32]byte
// State roots — Z-Chain anchors. Each MUST equal the latest
// accepted EpochCommitment field for the current epoch.
lux_state_root [32]byte // Lux primary state at this height
zchain_state_root [32]byte // anchors EpochCommitment.zchain_state_root
validator_set_root [32]byte // anchors EpochCommitment.validator_registry_root
committee_root [32]byte // anchors EpochCommitment.committee_root
dkg_transcript_root [32]byte // anchors EpochCommitment.dkg_transcript_root
group_public_key_hash [32]byte // anchors EpochCommitment.group_public_key_hash
// Payload anchors — block-specific data lives elsewhere.
payload_root [32]byte // application transactions
da_root [32]byte // data-availability commitment
// Cert envelope.
proof_system_id ProofSystemID // = 0x10 STARK_FRI_SHA3_PQ canonical (0x80/0x81 refused)
hash_suite_id HashSuiteID // = 0x01 SHA3_NIST canonical
sig_scheme_id SigSchemeID // = 0x52 Pulsar-M-65 default; 0x53 for high-value roots
// Signature.
signer_bitmap_or_weight_commitment []byte // who attested (committee bitmap or weight Merkle root)
pulsar_m_threshold_signature []byte // single threshold sig over the canonical transcript
}
What Q-Chain MUST NOT carry
Hard exclusions:
- Full validator ML-DSA-65 public keys (live in Z-Chain
identity_root). - Per-validator ML-DSA-65 identity signatures (live in Z-Chain validator-registration proofs).
- Full DKG ceremony messages (live in Z-Chain
dkg_transcript_root). - Per-validator attestation blobs (live in Z-Chain).
- Z-Chain proof bytes for non-epoch-boundary blocks (the cert
references
zchain_state_rootby hash; the proof itself only ships at epoch boundaries).
A Q-Block that carries any of these violates the spec and MUST be rejected. The wire format does not have fields to hold them; this is an enforcement-by-construction guarantee.
Canonical transcript binding
The transcript Pulsar-M signs over for a Q-Block is computed as:
TranscriptHash = TupleHash256(
[ "Q-Chain/v1",
version, // 2 bytes BE
network_id, // 4
chain_id, // 4
height, // 8
round_or_view, // 4
parent_qblock_hash,
lux_state_root,
zchain_state_root,
validator_set_root,
committee_root,
dkg_transcript_root,
group_public_key_hash,
payload_root,
da_root,
[proof_system_id], // 1
[hash_suite_id], // 1
[sig_scheme_id], // 1
signer_bitmap_or_weight_commitment ],
customization = "PULSAR-M-Q-BLOCK-V1")
TupleHash256 per NIST SP 800-185 is used for unambiguous length-prefixed
tuple hashing. Customisation tags pin the protocol version; bumping
"v1" → "v2" is the only way to reuse the same transcript bytes for a
breaking change. Hash family is HashSuiteID = 0x01 SHA3_NIST only —
HashSuite-mismatched Q-Blocks are not produceable on Lux primary network.
Acceptance rule
A full node accepts a Q-Block at height H iff every of the following holds:
parent_qblock_hashmatches the chain tip.zchain_state_rootmatches the latest accepted Z-Chain epoch root.validator_set_rootmatches the latest accepted Z-Chainvalidator_registry_root(per EpochCommitment).committee_rootmatches the latest accepted Z-Chaincommittee_root.dkg_transcript_rootmatches the latest accepted Z-Chaindkg_transcript_root.group_public_key_hashmatches the latest accepted Z-Chaingroup_public_key_hash.proof_system_idis NOT in the forbidden set (IsForbiddenInPQMode() == false); strict-PQ networks require0x10 STARK_FRI_SHA3_PQ.hash_suite_id == 0x01 SHA3_NIST.sig_scheme_id∈ {0x52 Pulsar-M-65,0x53 Pulsar-M-87} for mainnet; testnet may also accept0x51 Pulsar-M-44.signer_bitmap_or_weight_commitmentsatisfies the configured threshold (43-of-64 default per HIP-0084).pulsar_m_threshold_signatureverifies under unmodified FIPS 204 ML-DSA.Verify against the canonical transcript hash and the group public key derived fromgroup_public_key_hash.
If any check fails, the block is rejected and a slashing-evidence record is produced per HIP-0084 §"Identifiable abort".
Production defaults
| parameter | value |
|---|---|
version |
0x0001 |
proof_system_id |
0x10 (STARK_FRI_SHA3_PQ) |
hash_suite_id |
0x01 (SHA3_NIST) |
sig_scheme_id |
0x52 (Pulsar-M-65) |
| committee size | 64 |
| BFT fault bound | f = 21 |
| threshold | 43-of-64 |
| epoch length | network-configurable; start 1 hour |
| DKG cadence | once per epoch (HIP-0084) |
| online signing | preprocessing-enabled |
| abort handling | identifiable abort required |
High-value roots (governance, bridges, slashing, archival) MAY
upgrade sig_scheme_id to 0x53 Pulsar-M-87 for the duration of
the operation. Block consumers MUST accept either.
What changes for Quasar mode
PQModeQuasar (consensus/config/pq_mode.go) maps to:
proof_system_id = 0x10 STARK_FRI_SHA3_PQhash_suite_id = 0x01 SHA3_NISTsig_scheme_id = 0x52 Pulsar-M-65(default) or0x53 Pulsar-M-87(high-value)
The legacy "Pulsar.R + Groth16/BN254 Z-Chain rollup" wire shape from the prior HIP-0077 is retired with the migration to Z-Chain v1 (HIP-0078 Phase 3 flag day).
Security considerations
- No silent downgrade. A Q-Block that carries
proof_system_id = 0x80or0x81is refused before signature verification. The forbidden markers exist on the wire so a misconfigured operator's block is named, not silently accepted. - Single threshold sig per block. Multi-sig fallback paths (per-validator BLS + ML-DSA, classical/PQ hybrid) are NOT in this HIP. A future variant MAY add hybrid-cert support but it lives in a follow-up HIP, not here.
- Root tampering. All root fields are bound into the transcript; flipping any one breaks signature verification.
- Signer-bitmap forgery. Bitmap is bound into the transcript and
validated against
committee_root; an attacker who flips a bit must produce a valid Pulsar-M sig over the modified transcript, which reduces to forging Pulsar-M. - Replay across networks.
network_idandchain_idare bound into the transcript; a Q-Block valid on Lux mainnet is not valid on a tenant network.
Adoption order
- Wire format frozen (this HIP).
consensus/pkg/wire/qblock.goreference encoder/decoder.- Test vectors at
~/work/lux/consensus/qblock-vectors/covering acceptance, refusal-on-forbidden-proof-system, transcript binding. - Quasar driver (
consensus/protocol/quasar/) consumes Q-Blocks fromWitnessSet.Runoutputs. - Q-Chain VM at
chains/quasarvm(planned location) implements acceptance rule. - Phase 2 of HIP-0078 ships, gating the
proof_system_id = 0x10requirement on Lux primary network.
References
- HIP-0077 — Mesh Identity, Gossip & Payments (parent).
- HIP-0078 — Z-Chain PQ Identity Rollup (root source).
- HIP-0084 — Pulsar-M DKG (signing primitive).
- FIPS 204 — ML-DSA verification target.
- FIPS 202 + NIST SP 800-185 — TupleHash256 transcript family.