Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.xandrlabs.ai/llms.txt

Use this file to discover all available pages before exploring further.

When you create a Knowledge Block that builds on existing knowledge, you declare that relationship explicitly in the sources array. Each entry is a kbHash value pointing to a parent KB. The protocol treats these references as edges in a directed acyclic graph (DAG): edges run from child to parent, and the global graph of all published KBs must remain acyclic. This structure makes the full derivation history of any KB traceable without relying on a central index.

The sources array

sources is an array of kbHash strings — one entry per parent KB. A root KB (one that is not derived from anything) has an empty sources array. A KB that synthesizes two prior KBs lists both of their kbHash values:
{
  "type": "synthesis",
  "domain": "software.security",
  "sources": [
    "0x3a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b",
    "0xd7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8"
  ],
  "artifactHash": "0xf3c9a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0",
  "tier": "open",
  "payload": {
    "type": "synthesis",
    "question": "What signing key policies apply to JWT rotation?",
    "answer": "Rotate every 90 days and revoke on compromise.",
    "citations": {
      "0x3a1b...": "Rotate signing keys every 90 days.",
      "0xd7e8...": "Revoke keys immediately on suspected compromise."
    }
  }
}

Normalization before hashing

For identity purposes, sources is treated as a set, not an ordered list. Before computing kbHash, the protocol:
  1. Removes duplicate entries from sources.
  2. Sorts the remaining entries lexicographically.
  3. Checks that no entry matches the KB’s own eventual kbHash (self-reference is forbidden).
Two envelopes that differ only in the order of their parent kbHash values will produce the same kbHash after normalization. You do not need to pre-sort sources before calling kbHashFromEnvelope — normalization is applied automatically.
Sorting at hash time does not mean duplicate or cyclic lineage is valid. Duplicates and cycles are rejected during publication and registry validation. Normalization only defines a deterministic preimage for a well-formed envelope.

Building a derived KB

Use buildDerivedEnvelope from @alx/protocol to construct a KB that references parent KBs. The function handles source normalization (sorting and 0x-prefix normalization) and artifactHash derivation automatically:
import { buildDerivedEnvelope, kbHashFromEnvelope } from "@alx/protocol";

const envelope = buildDerivedEnvelope({
  domain: "software.security",
  sources: [
    "0x3a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b",
    "0xd7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8",
  ],
  tier: "open",
  derivation: {
    type: "compose",
    inputs: [
      {
        kbId: "0x3a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b",
        selectors: ["payload.rationale"],
      },
    ],
    recipe: { strategy: "merge" },
  },
  payload: {
    type: "synthesis",
    question: "What signing key policies apply to JWT rotation?",
    answer: "Rotate every 90 days and revoke on compromise.",
    citations: {},
  },
});

const kbHash = kbHashFromEnvelope(envelope);
buildDerivedEnvelope sorts sources lexicographically and ensures all kbId values in derivation.inputs carry the 0x prefix, so the envelope it returns is ready to hash.

Immutability after publication

Once a KB is published, its lineage is permanently fixed. The published kbHash already commits to the normalized sources array — changing lineage would require a different kbHash, which means it would be a different KB. If you need to revise the lineage of a KB, publish a new KB and reference the old one in its sources array to preserve the history chain. This append-only model ensures no published KB can be silently retroactively modified.
Reference the old KB in sources when publishing a revised version. This keeps the derivation history intact and allows verifiers to trace the full provenance chain.

Parent limits

The reference registry contract allows a maximum of 8 parent KBs per Knowledge Block. Attempts to publish a KB with more than 8 entries in sources will be rejected by the contract.

Validation rules

The protocol enforces the following rules on sources during publication:
RuleEffect
Self-referenceRejected — a KB cannot list itself as a parent
Duplicate entriesRejected during publication (normalized away for hashing only)
Cycles (direct or indirect)Rejected — the global DAG must remain acyclic
More than 8 parentsRejected by the registry contract

Why lineage matters

Lineage is how ALX Protocol makes attribution and value distribution deterministic. Because every KB explicitly declares its parents, the full graph of contributions to any KB is always visible and verifiable. This enables:
  • Attribution — identifying which KBs contributed to a given output.
  • Settlement — distributing value to contributors in proportion to their lineage participation.
  • Traceability — auditing the provenance of any artifact, including in AI pipelines and multi-agent systems.
Changes to lineage always produce a new KB with a new kbHash, so the history of how knowledge evolved is preserved in the graph structure itself. For the identity derivation formula that commits to sources, see Identity. For the canonicalization step that processes sources before hashing, see Canonicalization.