{
  "name": "forge.identity",
  "language": "python",
  "version": "0.1.0",
  "description": "Python identity package; imports are explicit from this package.",
  "manifest": "forge-py/pyproject.toml",
  "manifestSha256": "7f96957378b21995bf2e583af2afd1b9e6fb3b0089ff3559d62c7e012a034696",
  "status": "source-reference",
  "registryPublicationVerified": false,
  "route": "/libraries/python/identity",
  "features": {},
  "files": [
    {
      "path": "forge-py/src/forge/identity/__init__.py",
      "sha256": "932b964d9c669884f65c38b46f8ee0d897fc3dddcddc5c0fc0c51f4a5e85f691",
      "artifactSha256": "a7a72cfa86aa1407978ba05e8c9c279455dd920b5be37b5f6d72428a8aef8cd5",
      "url": "/reference/source/forge-py/src/forge/identity/__init__.py.txt",
      "declarations": []
    },
    {
      "path": "forge-py/src/forge/identity/agent_identity.py",
      "sha256": "29772125018bd01be1a924306258f75eaf1bbdcf8b7442ae8ba9861e5cb5bbf9",
      "artifactSha256": "1bae8f71bc9811e5c15e6d92df09b1ecce37bb2d719a3ea1a947e8b823b4950c",
      "url": "/reference/source/forge-py/src/forge/identity/agent_identity.py.txt",
      "declarations": [
        {
          "name": "OasDocumentRef",
          "line": 32,
          "signature": "class OasDocumentRef()",
          "documentation": "A reference to an OAS Identity Document.\n\nIn the Python SDK, the OAS document is stored as a JSON-serializable\ndictionary. Cryptographic operations act on the document's proof material\nand verification methods.\n\nArgs:\n    id: The DID string from the document.\n    data: The full document data as a dictionary.\n\nExample:\n    >>> doc = OasDocumentRef(id=\"did:oas:test:hmr:alice\", data={\"id\": \"did:oas:test:hmr:alice\"})\n    >>> doc.id\n    'did:oas:test:hmr:alice'"
        },
        {
          "name": "OasDocumentRef.has_proof",
          "line": 53,
          "signature": "def has_proof(self) -> bool",
          "documentation": "Return True if the document contains a proof section.\n\nReturns:\n    True if a proof section is present."
        },
        {
          "name": "OasDocumentRef.has_lineage",
          "line": 62,
          "signature": "def has_lineage(self) -> bool",
          "documentation": "Return True if the document contains a lineage section.\n\nReturns:\n    True if a lineage section is present."
        },
        {
          "name": "OasDocumentRef.lineage_generation",
          "line": 71,
          "signature": "def lineage_generation(self) -> int | None",
          "documentation": "Return the lineage generation number if present.\n\nReturns:\n    The generation number, or None if no lineage section."
        },
        {
          "name": "OasDocumentRef.human_root_did",
          "line": 85,
          "signature": "def human_root_did(self) -> str | None",
          "documentation": "Return the human root DID from the lineage section if present.\n\nReturns:\n    The human root DID string, or None if no lineage section."
        },
        {
          "name": "OasDocumentRef.to_json",
          "line": 98,
          "signature": "def to_json(self) -> str",
          "documentation": "Serialize the document to a JSON string.\n\nReturns:\n    JSON string representation."
        },
        {
          "name": "OasDocumentRef.from_json",
          "line": 107,
          "signature": "def from_json(data: str) -> OasDocumentRef",
          "documentation": "Deserialize an OAS document from a JSON string.\n\nArgs:\n    data: JSON string representation.\n\nReturns:\n    The deserialized OasDocumentRef.\n\nRaises:\n    ValueError: If the JSON is invalid or missing the ``id`` field."
        },
        {
          "name": "WasmKeyRef",
          "line": 128,
          "signature": "class WasmKeyRef()",
          "documentation": "A reference to an Ed25519 keypair managed by the active crypto backend.\n\nThe Python SDK retains public key bytes for verification and may keep\nprivate key bytes in memory when the active backend is the bundled\nsoftware implementation.\n\nArgs:\n    public_key_bytes: The 32-byte Ed25519 verifying (public) key.\n    key_id: An opaque identifier for the keypair in the crypto backend.\n    private_key_bytes: Optional 32-byte Ed25519 signing key seed.\n\nExample:\n    >>> key = WasmKeyRef(public_key_bytes=bytes(32), key_id=\"test-key-1\")\n    >>> len(key.public_key_bytes)\n    32"
        },
        {
          "name": "ForgeAgentIdentity",
          "line": 151,
          "signature": "class ForgeAgentIdentity()",
          "documentation": "A Forge agent's cryptographic identity, binding an OAS DID, keypair, and lineage.\n\nEvery Forge agent has a ``ForgeAgentIdentity`` from creation. The identity\nincludes the agent's Ed25519 keypair reference (via WASM bridge), the OAS\nDID document, and the lineage proof chain.\n\nSee ANVIL Specification section 11.1 -- OAS Identity Binding.\n\nSecurity:\n    - The ``__repr__`` implementation never exposes the private key.\n    - Signing operations are delegated to the WASM bridge module.\n    - The keypair reference (``WasmKeyRef``) only holds the public key bytes.\n\nExample:\n    >>> from forge.identity.lineage import create_hmr_identity\n    >>> hmr = create_hmr_identity(\"test\", \"alice\")\n    >>> hmr.did\n    'did:oas:test:hmr:alice'\n    >>> hmr.kind\n    'hmr'\n    >>> hmr.lineage_depth\n    0"
        },
        {
          "name": "ForgeAgentIdentity.__init__",
          "line": 176,
          "signature": "def __init__(self, did: str, kind: str, keypair: WasmKeyRef, document: OasDocumentRef, lineage_depth: int) -> None",
          "documentation": "Create a new ForgeAgentIdentity from its constituent parts.\n\nThis is the internal constructor used by the lineage module.\nExternal callers should use ``create_hmr_identity`` or\n``derive_agent_identity`` instead.\n\nANVIL Spec section 11.1 -- OAS Identity Binding.\n\nArgs:\n    did: The ``did:oas`` identifier string.\n    kind: The entity kind (e.g., ``\"hmr\"``, ``\"mhr\"``, ``\"agent\"``).\n    keypair: The Ed25519 keypair reference.\n    document: The signed OAS Identity Document.\n    lineage_depth: The number of derivation steps from the human root.\n\nRaises:\n    InvalidIdentityError: If the DID is empty or the document ID\n        does not match the provided DID."
        },
        {
          "name": "ForgeAgentIdentity.did",
          "line": 218,
          "signature": "def did(self) -> str",
          "documentation": "Return the ``did:oas`` identifier string for this agent.\n\nReturns:\n    The DID string.\n\nExample:\n    >>> from forge.identity.lineage import create_hmr_identity\n    >>> hmr = create_hmr_identity(\"test\", \"alice\")\n    >>> hmr.did\n    'did:oas:test:hmr:alice'"
        },
        {
          "name": "ForgeAgentIdentity.kind",
          "line": 233,
          "signature": "def kind(self) -> str",
          "documentation": "Return the entity kind (e.g., ``\"hmr\"``, ``\"mhr\"``, ``\"agent\"``).\n\nReturns:\n    The entity kind string.\n\nExample:\n    >>> from forge.identity.lineage import create_hmr_identity\n    >>> hmr = create_hmr_identity(\"test\", \"alice\")\n    >>> hmr.kind\n    'hmr'"
        },
        {
          "name": "ForgeAgentIdentity.keypair",
          "line": 248,
          "signature": "def keypair(self) -> WasmKeyRef",
          "documentation": "Return a reference to the WASM-managed keypair.\n\nSecurity:\n    This provides access to the public key only. The signing key\n    is managed by the WASM bridge and never enters Python memory.\n\nReturns:\n    The WasmKeyRef for this identity."
        },
        {
          "name": "ForgeAgentIdentity.document",
          "line": 261,
          "signature": "def document(self) -> OasDocumentRef",
          "documentation": "Return a reference to the signed OAS Identity Document.\n\nThe document contains the full DID document structure including\nverification methods, authentication references, lineage section,\nand document proof.\n\nReturns:\n    The OasDocumentRef.\n\nExample:\n    >>> from forge.identity.lineage import create_hmr_identity\n    >>> hmr = create_hmr_identity(\"test\", \"alice\")\n    >>> hmr.document.has_proof\n    True"
        },
        {
          "name": "ForgeAgentIdentity.lineage_depth",
          "line": 280,
          "signature": "def lineage_depth(self) -> int",
          "documentation": "Return the lineage depth (number of derivation steps from human root).\n\n- ``0`` for HMR and MHR root entities.\n- ``1`` for agents derived directly from a root.\n- ``n`` for agents ``n`` steps removed from the root.\n\nSee ANVIL Spec section 11.2 -- Lineage Propagation.\n\nReturns:\n    The lineage depth as a non-negative integer.\n\nExample:\n    >>> from forge.identity.lineage import create_hmr_identity\n    >>> hmr = create_hmr_identity(\"test\", \"alice\")\n    >>> hmr.lineage_depth\n    0"
        },
        {
          "name": "ForgeAgentIdentity.verifying_key_bytes",
          "line": 300,
          "signature": "def verifying_key_bytes(self) -> bytes",
          "documentation": "Return the raw 32-byte Ed25519 verifying (public) key bytes.\n\nThis is the agent's public key that can be shared freely. Use it\nto verify signatures produced by the agent's signing key.\n\nReturns:\n    A 32-byte bytes object containing the Ed25519 public key.\n\nExample:\n    >>> from forge.identity.lineage import create_hmr_identity\n    >>> hmr = create_hmr_identity(\"test\", \"alice\")\n    >>> len(hmr.verifying_key_bytes())\n    32"
        },
        {
          "name": "ForgeAgentIdentity.sign",
          "line": 317,
          "signature": "def sign(self, message: bytes) -> bytes",
          "documentation": "Sign a message with this agent's Ed25519 signing key.\n\nUses the configured crypto backend to produce an Ed25519 signature.\n\nArgs:\n    message: The raw bytes to sign.\n\nReturns:\n    A 64-byte Ed25519 signature.\n\nExample:\n    >>> from forge.identity.lineage import create_hmr_identity\n    >>> hmr = create_hmr_identity(\"test\", \"alice\")\n    >>> sig = hmr.sign(b\"audit trail entry\")\n    >>> len(sig)\n    64"
        },
        {
          "name": "ForgeAgentIdentity.verify",
          "line": 344,
          "signature": "def verify(self, message: bytes, signature: bytes) -> bool",
          "documentation": "Verify an Ed25519 signature against this agent's public key.\n\nUses the configured crypto backend for Ed25519 verification.\n\nArgs:\n    message: The original message that was signed.\n    signature: The 64-byte Ed25519 signature to verify.\n\nReturns:\n    True if the signature is valid, False otherwise.\n\nExample:\n    >>> from forge.identity.lineage import create_hmr_identity\n    >>> hmr = create_hmr_identity(\"test\", \"alice\")\n    >>> sig = hmr.sign(b\"test\")\n    >>> hmr.verify(b\"test\", sig)\n    True\n    >>> hmr.verify(b\"tampered\", sig)\n    False"
        },
        {
          "name": "ForgeAgentIdentity.to_dict",
          "line": 372,
          "signature": "def to_dict(self) -> dict[str, Any]",
          "documentation": "Serialize the identity to a dictionary.\n\nSecurity: The private key reference is NOT included in the output.\nOnly the public key bytes are serialized (hex-encoded).\n\nReturns:\n    Dictionary representation of the identity."
        },
        {
          "name": "ForgeAgentIdentity.from_dict",
          "line": 390,
          "signature": "def from_dict(data: dict[str, Any]) -> ForgeAgentIdentity",
          "documentation": "Deserialize an identity from a dictionary.\n\nNote: The private key is not restored. A new WasmKeyRef is created\nwith only the public key bytes. Signing operations require the caller\nto reconnect a secure key source before use.\n\nArgs:\n    data: Dictionary representation of the identity.\n\nReturns:\n    The deserialized ForgeAgentIdentity.\n\nRaises:\n    InvalidIdentityError: If required fields are missing.\n    KeyError: If the dictionary is missing expected keys."
        }
      ]
    },
    {
      "path": "forge-py/src/forge/identity/error.py",
      "sha256": "3f85e17efbfaaa4ac2c9540f3447a9c915d80ff05ca6c40047dc5260501244e0",
      "artifactSha256": "e7d20d249f9fb3e95a08ed763b76d439242efbb1bee72343f710b92f528ddf28",
      "url": "/reference/source/forge-py/src/forge/identity/error.py.txt",
      "declarations": [
        {
          "name": "ForgeIdentityError",
          "line": 16,
          "signature": "class ForgeIdentityError(ForgeError)",
          "documentation": "Base exception for all forge-identity operations.\n\nSubclasses carry actionable context: what failed, why, and the\nrelevant ANVIL specification section."
        },
        {
          "name": "IdentityDerivationError",
          "line": 24,
          "signature": "class IdentityDerivationError(ForgeIdentityError)",
          "documentation": "HKDF key derivation failed for the specified derivation path.\n\nThis indicates a failure in the cryptographic key derivation process\nwhen creating a child agent identity from a parent.\n\nSee ANVIL Spec section 11.1 -- OAS Identity Binding.\n\nArgs:\n    parent_did: The parent's DID from which derivation was attempted.\n    path: The HKDF derivation path that was used.\n    reason: A description of why the derivation failed.\n\nExample:\n    >>> err = IdentityDerivationError(\"did:oas:test:hmr:alice\", \"agent/bot\", \"HKDF failed\")\n    >>> \"alice\" in str(err)\n    True"
        },
        {
          "name": "IdentityDerivationError.__init__",
          "line": 43,
          "signature": "def __init__(self, parent_did: str, path: str, reason: str) -> None",
          "documentation": ""
        },
        {
          "name": "LineageVerificationError",
          "line": 53,
          "signature": "class LineageVerificationError(ForgeIdentityError)",
          "documentation": "Lineage chain verification failed for the specified identity.\n\nThe cryptographic chain from the agent to its human root could not be\nverified. This may indicate a tampered identity, a missing parent\ndocument, or an invalid proof signature.\n\nSee ANVIL Spec section 11.2 -- Lineage Propagation.\n\nArgs:\n    did: The DID of the identity whose lineage failed verification.\n    reason: A description of why verification failed.\n\nExample:\n    >>> err = LineageVerificationError(\"did:oas:test:agent:bot\", \"parent not found\")\n    >>> \"bot\" in str(err)\n    True"
        },
        {
          "name": "LineageVerificationError.__init__",
          "line": 72,
          "signature": "def __init__(self, did: str, reason: str) -> None",
          "documentation": ""
        },
        {
          "name": "ChainTooDeepError",
          "line": 78,
          "signature": "class ChainTooDeepError(ForgeIdentityError)",
          "documentation": "Lineage chain exceeds the maximum allowed generation depth.\n\nANVIL Spec section 11.2 defines a maximum lineage depth to prevent\nunbounded delegation chains. The default maximum is 16.\n\nArgs:\n    depth: The actual depth of the lineage chain.\n    max_depth: The configured maximum depth.\n\nExample:\n    >>> err = ChainTooDeepError(20, 16)\n    >>> \"20\" in str(err) and \"16\" in str(err) and \"ANVIL\" in str(err)\n    True"
        },
        {
          "name": "ChainTooDeepError.__init__",
          "line": 94,
          "signature": "def __init__(self, depth: int, max_depth: int) -> None",
          "documentation": ""
        },
        {
          "name": "InvalidIdentityError",
          "line": 103,
          "signature": "class InvalidIdentityError(ForgeIdentityError)",
          "documentation": "The identity is malformed or fails structural validation.\n\nThis covers cases like missing DID fields, invalid document structure,\nor inconsistent lineage sections.\n\nArgs:\n    reason: A description of the structural problem.\n\nExample:\n    >>> err = InvalidIdentityError(\"missing verification method\")\n    >>> \"missing\" in str(err)\n    True"
        },
        {
          "name": "InvalidIdentityError.__init__",
          "line": 118,
          "signature": "def __init__(self, reason: str) -> None",
          "documentation": ""
        },
        {
          "name": "IdentityPersistenceError",
          "line": 123,
          "signature": "class IdentityPersistenceError(ForgeIdentityError)",
          "documentation": "Saving or loading an identity to/from persistent storage failed.\n\nThis may indicate I/O errors, permission problems, or corrupted\nidentity files on disk.\n\nArgs:\n    reason: A description of the persistence failure.\n\nExample:\n    >>> err = IdentityPersistenceError(\"file not found: /tmp/id.json\")\n    >>> \"file not found\" in str(err)\n    True"
        },
        {
          "name": "IdentityPersistenceError.__init__",
          "line": 138,
          "signature": "def __init__(self, reason: str) -> None",
          "documentation": ""
        }
      ]
    },
    {
      "path": "forge-py/src/forge/identity/glyph.py",
      "sha256": "7cad42cfd1a68b4c9950fb95b197548b076d113e813ce03f41e209216619ecff",
      "artifactSha256": "da955a8764319b8bcff4b1fca104d063bdf36b28ffe4880cd484e4031c0d815d",
      "url": "/reference/source/forge-py/src/forge/identity/glyph.py.txt",
      "declarations": [
        {
          "name": "GlyphEntityKind",
          "line": 24,
          "signature": "class GlyphEntityKind(Enum)",
          "documentation": "Entity kinds supported by the glyph system.\n\nMaps to the upstream ``oas-glyph`` entity kind taxonomy:\n\n========= =============== ================\nKind      Upstream Value  Visual Motif\n========= =============== ================\nHMR       0               Shield (human)\nMHR       1               Multi-shield\nENR       2               Grid (entity)\nAGENT     3               Diamond (agent)\nORG       4               Hexagon (org)\n========= =============== ================"
        },
        {
          "name": "GlyphEntityKind.parse_kind",
          "line": 47,
          "signature": "def parse_kind(s: str) -> GlyphEntityKind | None",
          "documentation": "Parse a kind string into a GlyphEntityKind.\n\nArgs:\n    s: A lowercase kind string.\n\nReturns:\n    The parsed kind, or None if unknown.\n\nExample:\n    >>> GlyphEntityKind.parse_kind(\"agent\")\n    <GlyphEntityKind.AGENT: 'agent'>"
        },
        {
          "name": "GlyphEntityKind.as_str",
          "line": 65,
          "signature": "def as_str(self) -> str",
          "documentation": "Return the canonical string representation.\n\nReturns:\n    Lowercase kind name."
        },
        {
          "name": "GlyphEntityKind.as_u8",
          "line": 73,
          "signature": "def as_u8(self) -> int",
          "documentation": "Return the numeric value used in payload encoding.\n\nReturns:\n    Integer 0-4 matching the upstream oas-glyph discriminants."
        },
        {
          "name": "GlyphEntityKind.from_u8",
          "line": 89,
          "signature": "def from_u8(v: int) -> GlyphEntityKind | None",
          "documentation": "Reconstruct a GlyphEntityKind from its numeric value.\n\nArgs:\n    v: The numeric value.\n\nReturns:\n    The kind, or None if the value is invalid."
        },
        {
          "name": "GlyphColor",
          "line": 109,
          "signature": "class GlyphColor()",
          "documentation": "An RGB color triple.\n\nAll channels are 8-bit unsigned (0-255).\n\nArgs:\n    r: Red channel.\n    g: Green channel.\n    b: Blue channel."
        },
        {
          "name": "GlyphColor.to_hex",
          "line": 124,
          "signature": "def to_hex(self) -> str",
          "documentation": "Format as a CSS hex color string.\n\nReturns:\n    Hex color string (e.g., ``#ff8040``).\n\nExample:\n    >>> GlyphColor(255, 128, 64).to_hex()\n    '#ff8040'"
        },
        {
          "name": "GlyphColor.rgb",
          "line": 137,
          "signature": "def rgb(r: int, g: int, b: int) -> GlyphColor",
          "documentation": "Create a color from RGB components.\n\nArgs:\n    r: Red channel (0-255).\n    g: Green channel (0-255).\n    b: Blue channel (0-255).\n\nReturns:\n    A new GlyphColor."
        },
        {
          "name": "GlyphColor.to_dict",
          "line": 150,
          "signature": "def to_dict(self) -> dict[str, int]",
          "documentation": "Serialize to a dictionary.\n\nReturns:\n    Dictionary with r, g, b keys."
        },
        {
          "name": "GlyphColor.from_dict",
          "line": 159,
          "signature": "def from_dict(data: dict[str, int]) -> GlyphColor",
          "documentation": "Deserialize from a dictionary.\n\nArgs:\n    data: Dictionary with r, g, b keys.\n\nReturns:\n    The deserialized GlyphColor."
        },
        {
          "name": "GlyphPalette",
          "line": 172,
          "signature": "class GlyphPalette()",
          "documentation": "A color palette derived from the DID hash.\n\nArgs:\n    primary: The primary color.\n    secondary: The secondary color.\n    accent: The accent color.\n    background: The background color."
        },
        {
          "name": "GlyphDescriptor",
          "line": 189,
          "signature": "class GlyphDescriptor()",
          "documentation": "The glyph input contract: describes what to render.\n\nArgs:\n    did: The agent's DID string.\n    kind: The entity kind.\n    label: Optional human-readable label.\n\nExample:\n    >>> desc = GlyphDescriptor(\n    ...     did=\"did:oas:l1fe:agent:data-analyst\",\n    ...     kind=GlyphEntityKind.AGENT,\n    ...     label=\"Data Analyst\",\n    ... )\n    >>> desc.did\n    'did:oas:l1fe:agent:data-analyst'"
        },
        {
          "name": "GlyphDescriptor.to_dict",
          "line": 211,
          "signature": "def to_dict(self) -> dict[str, Any]",
          "documentation": "Serialize to a dictionary.\n\nReturns:\n    Dictionary representation."
        },
        {
          "name": "GlyphDescriptor.from_dict",
          "line": 223,
          "signature": "def from_dict(data: dict[str, Any]) -> GlyphDescriptor",
          "documentation": "Deserialize from a dictionary.\n\nArgs:\n    data: Dictionary representation.\n\nReturns:\n    The deserialized GlyphDescriptor."
        },
        {
          "name": "GlyphDescriptor.to_json",
          "line": 238,
          "signature": "def to_json(self) -> str",
          "documentation": "Serialize to JSON string.\n\nReturns:\n    JSON string."
        },
        {
          "name": "GlyphDescriptor.from_json",
          "line": 247,
          "signature": "def from_json(data: str) -> GlyphDescriptor",
          "documentation": "Deserialize from JSON string.\n\nArgs:\n    data: JSON string.\n\nReturns:\n    The deserialized GlyphDescriptor."
        },
        {
          "name": "GlyphRenderTarget",
          "line": 259,
          "signature": "class GlyphRenderTarget(Enum)",
          "documentation": "Render target selection.\n\n``WEB``: SVG output for web rendering.\n``TERMINAL``: ANSI-colored terminal output."
        },
        {
          "name": "GlyphRenderFormat",
          "line": 270,
          "signature": "class GlyphRenderFormat(Enum)",
          "documentation": "Output format tag for render results."
        },
        {
          "name": "GlyphRenderOptions",
          "line": 281,
          "signature": "class GlyphRenderOptions()",
          "documentation": "Render options controlling the glyph output.\n\nArgs:\n    target: The render target (Web or Terminal).\n    width: Desired width in pixels (Web) or columns (Terminal).\n    height: Desired height in pixels (Web) or rows (Terminal).\n    color_override: Optional background color override."
        },
        {
          "name": "GlyphRenderResult",
          "line": 298,
          "signature": "class GlyphRenderResult()",
          "documentation": "The output of a glyph render operation.\n\nArgs:\n    format: The output format.\n    data: The rendered data bytes.\n    width: Width of the rendered output.\n    height: Height of the rendered output."
        },
        {
          "name": "GlyphRenderResult.svg_data",
          "line": 313,
          "signature": "def svg_data(self) -> str | None",
          "documentation": "Extract the rendered data as a UTF-8 string if text-based.\n\nReturns ``None`` for binary formats like PNG.\n\nReturns:\n    The string data, or None for binary formats."
        },
        {
          "name": "derive_palette",
          "line": 334,
          "signature": "def derive_palette(did: str, kind: GlyphEntityKind) -> GlyphPalette",
          "documentation": "Derive a deterministic color palette from a DID string.\n\nUses SHA-256 of the DID to derive hue values, producing a unique\nbut deterministic palette for each identity.\n\nArgs:\n    did: The DID string.\n    kind: The entity kind.\n\nReturns:\n    A GlyphPalette with four derived colors."
        }
      ]
    },
    {
      "path": "forge-py/src/forge/identity/lineage.py",
      "sha256": "4ff72aeae5c99adbd3c91035fafd98b7b4ec540456f03b635296c43d19f56aa4",
      "artifactSha256": "3b90452e2492ffc1143d29939b3bcf9b8dbd388bd4360077172bc80dd76aef67",
      "url": "/reference/source/forge-py/src/forge/identity/lineage.py.txt",
      "declarations": [
        {
          "name": "LineageProof",
          "line": 51,
          "signature": "class LineageProof()",
          "documentation": "A cryptographic proof linking a child identity to its parent.\n\nEach hop in the lineage chain produces a ``LineageProof`` that contains\nthe parent DID, the derivation path used, a signature from the parent's\nkey, and a timestamp.\n\nANVIL Spec section 11.2 -- Lineage Propagation.\n\nArgs:\n    proof_type: The proof type identifier (``\"AgentLineageProof2025\"``).\n    parent_did: The DID of the parent identity.\n    child_did: The DID of the child identity.\n    derivation_path: The HKDF derivation path used.\n    signature_hex: The hex-encoded parent signature over the proof payload.\n    created: The ISO 8601 timestamp when the proof was created.\n\nExample:\n    >>> proof = LineageProof(\n    ...     proof_type=\"AgentLineageProof2025\",\n    ...     parent_did=\"did:oas:test:hmr:alice\",\n    ...     child_did=\"did:oas:test:agent:bot\",\n    ...     derivation_path=\"agent/bot\",\n    ...     signature_hex=\"deadbeef\" * 16,\n    ...     created=\"2026-01-15T00:00:00+00:00\",\n    ... )\n    >>> proof.proof_type\n    'AgentLineageProof2025'"
        },
        {
          "name": "LineageProof.to_dict",
          "line": 88,
          "signature": "def to_dict(self) -> dict[str, Any]",
          "documentation": "Serialize the proof to a dictionary.\n\nReturns:\n    Dictionary representation."
        },
        {
          "name": "LineageProof.from_dict",
          "line": 104,
          "signature": "def from_dict(data: dict[str, Any]) -> LineageProof",
          "documentation": "Deserialize a proof from a dictionary.\n\nArgs:\n    data: Dictionary representation.\n\nReturns:\n    The deserialized LineageProof."
        },
        {
          "name": "LineageChain",
          "line": 124,
          "signature": "class LineageChain()",
          "documentation": "A complete lineage chain from child to root.\n\nThe chain is an ordered sequence of ``LineageProof`` objects, from the\nmost recent child to the oldest ancestor (the root).\n\nANVIL Spec section 11.2 -- Lineage Propagation.\n\nArgs:\n    proofs: Ordered tuple of lineage proofs (child-to-root).\n    root_did: The DID of the chain's root identity (HMR or MHR).\n\nExample:\n    >>> chain = LineageChain(proofs=(), root_did=\"did:oas:test:hmr:alice\")\n    >>> chain.depth\n    0"
        },
        {
          "name": "LineageChain.depth",
          "line": 146,
          "signature": "def depth(self) -> int",
          "documentation": "Return the chain depth (number of hops from root).\n\nReturns:\n    The number of proofs in the chain."
        },
        {
          "name": "LineageChain.is_root",
          "line": 155,
          "signature": "def is_root(self) -> bool",
          "documentation": "Return True if this chain represents a root identity (no proofs).\n\nReturns:\n    True if the chain has zero proofs."
        },
        {
          "name": "LineageChain.to_dict",
          "line": 163,
          "signature": "def to_dict(self) -> dict[str, Any]",
          "documentation": "Serialize the chain to a dictionary.\n\nReturns:\n    Dictionary representation."
        },
        {
          "name": "LineageChain.from_dict",
          "line": 175,
          "signature": "def from_dict(data: dict[str, Any]) -> LineageChain",
          "documentation": "Deserialize a chain from a dictionary.\n\nArgs:\n    data: Dictionary representation.\n\nReturns:\n    The deserialized LineageChain."
        },
        {
          "name": "create_hmr_identity",
          "line": 188,
          "signature": "def create_hmr_identity(namespace: str, identifier: str) -> ForgeAgentIdentity",
          "documentation": "Create a new Human Root (HMR) identity.\n\nGenerates a fresh Ed25519 keypair, constructs an OAS\nIdentity Document for a ``did:oas:<namespace>:hmr:<identifier>`` DID,\nand signs it.\n\nHMR identities are the ultimate trust anchors in the lineage chain.\nEvery derived agent traces back to an HMR.\n\nSee ANVIL Spec section 11.1 -- OAS Identity Binding.\n\nArgs:\n    namespace: The OAS namespace (e.g., ``\"l1fe\"``, ``\"test\"``).\n    identifier: The unique identifier within the namespace.\n\nReturns:\n    A ForgeAgentIdentity with lineage depth 0 and kind ``\"hmr\"``.\n\nRaises:\n    InvalidIdentityError: If the resulting identity fails structural validation.\n\nExample:\n    >>> hmr = create_hmr_identity(\"test\", \"alice\")\n    >>> hmr.did\n    'did:oas:test:hmr:alice'\n    >>> hmr.kind\n    'hmr'\n    >>> hmr.lineage_depth\n    0"
        },
        {
          "name": "create_mhr_identity",
          "line": 226,
          "signature": "def create_mhr_identity(namespace: str, identifier: str) -> ForgeAgentIdentity",
          "documentation": "Create a new Multi-Human Root (MHR) identity.\n\nSimilar to ``create_hmr_identity`` but for machine-originated root entities.\nMHR identities use ``did:oas:<namespace>:mhr:<identifier>``.\n\nSee ANVIL Spec section 11.1 -- OAS Identity Binding.\n\nArgs:\n    namespace: The OAS namespace (e.g., ``\"l1fe\"``, ``\"test\"``).\n    identifier: The unique identifier within the namespace.\n\nReturns:\n    A ForgeAgentIdentity with lineage depth 0 and kind ``\"mhr\"``.\n\nRaises:\n    InvalidIdentityError: If the resulting identity fails structural validation.\n\nExample:\n    >>> mhr = create_mhr_identity(\"test\", \"system1\")\n    >>> mhr.did\n    'did:oas:test:mhr:system1'\n    >>> mhr.kind\n    'mhr'\n    >>> mhr.lineage_depth\n    0"
        },
        {
          "name": "derive_agent_identity",
          "line": 260,
          "signature": "def derive_agent_identity(parent: ForgeAgentIdentity, name: str, namespace: str, *, max_depth: int=DEFAULT_MAX_LINEAGE_DEPTH) -> ForgeAgentIdentity",
          "documentation": "Derive a child agent identity from a parent identity.\n\nPerforms the complete agent derivation workflow per ANVIL Spec section 11.2:\n\n1. Validates the parent's lineage depth does not exceed the maximum.\n2. Derives a child Ed25519 keypair using HKDF-SHA256.\n3. Generates an AgentLineageProof2025 linking child to parent.\n4. Constructs a signed OAS Identity Document with a complete lineage section.\n\nThe child's lineage depth is ``parent.lineage_depth + 1``.\n\nArgs:\n    parent: The parent identity (HMR, MHR, or another agent).\n    name: The child agent's identifier (e.g., ``\"analyzer\"``, ``\"scraper\"``).\n    namespace: The child's namespace (often the same as the parent's).\n    max_depth: Maximum allowed lineage depth (default: 16).\n\nReturns:\n    A ForgeAgentIdentity with kind ``\"agent\"`` and an incremented lineage depth.\n\nRaises:\n    ChainTooDeepError: If the parent's lineage depth plus one exceeds ``max_depth``.\n    InvalidIdentityError: If the resulting identity fails structural validation.\n\nExample:\n    >>> hmr = create_hmr_identity(\"test\", \"alice\")\n    >>> agent = derive_agent_identity(hmr, \"analyzer\", \"test\")\n    >>> agent.did\n    'did:oas:test:agent:analyzer'\n    >>> agent.kind\n    'agent'\n    >>> agent.lineage_depth\n    1"
        },
        {
          "name": "verify_lineage_chain",
          "line": 376,
          "signature": "def verify_lineage_chain(identity: ForgeAgentIdentity, document_store: dict[str, dict[str, Any]] | None=None) -> LineageChain",
          "documentation": "Verify the lineage chain for a given agent identity.\n\nWalks the cryptographic chain from the agent to its human root,\nverifying each hop's AgentLineageProof2025 signature against the\nresolved parent document's public key.\n\nSee ANVIL Spec section 11.2 -- Lineage Propagation.\n\nArgs:\n    identity: The agent identity whose lineage to verify.\n    document_store: A mapping from DID strings to OAS document\n        dictionaries. Used to resolve parent documents. If None,\n        only root identities (depth 0) can be verified.\n\nReturns:\n    A LineageChain containing all verified proofs.\n\nRaises:\n    LineageVerificationError: If any step of the verification fails\n        (missing parent, invalid signature, etc.).\n\nExample:\n    >>> hmr = create_hmr_identity(\"test\", \"alice\")\n    >>> chain = verify_lineage_chain(hmr)\n    >>> chain.depth\n    0"
        }
      ]
    },
    {
      "path": "forge-py/src/forge/identity/local_dev.py",
      "sha256": "5307c95a3523b807d5717d3ca74323bf82b1e12c237507e5a07e494da25e0d5a",
      "artifactSha256": "6f4dc06e38fa5637cbbd76d85036e2e321a50924899f3de22821a53a763cf94e",
      "url": "/reference/source/forge-py/src/forge/identity/local_dev.py.txt",
      "declarations": [
        {
          "name": "forge_dev_did",
          "line": 35,
          "signature": "def forge_dev_did(machine_id: str, kind: str, identifier: str) -> str",
          "documentation": "Construct a local dev DID string.\n\nArgs:\n    machine_id: The 16-char hex machine identifier from the profile.\n    kind: One of ``\"mhr\"``, ``\"hmr\"``, ``\"agent\"``, ``\"org\"``.\n    identifier: The entity name or derived fingerprint.\n\nReturns:\n    A DID string in ``did:forge-dev:<machine-id>:<kind>:<identifier>`` format.\n\nExample:\n    >>> forge_dev_did(\"a1b2c3d4e5f6a7b8\", \"agent\", \"data-analyst\")\n    'did:forge-dev:a1b2c3d4e5f6a7b8:agent:data-analyst'"
        },
        {
          "name": "derive_machine_id",
          "line": 53,
          "signature": "def derive_machine_id(profile_name: str) -> str",
          "documentation": "Derive a deterministic machine identifier from the current machine.\n\nThe ID is stable across sessions on the same machine for the same user\nand same profile, ensuring agent DIDs remain consistent across restarts.\n\nAlgorithm::\n\n    SHA-256(\"forge-dev-root:\" + hostname + \":\" + username + \":\" + profile_name)\n\ntruncated to the first 8 bytes, hex-encoded to 16 characters.\n\nArgs:\n    profile_name: The profile name (e.g., ``\"default\"``, ``\"alice\"``).\n\nReturns:\n    A 16-character hex string.\n\nExample:\n    >>> id1 = derive_machine_id(\"default\")\n    >>> id2 = derive_machine_id(\"default\")\n    >>> id1 == id2\n    True\n    >>> len(id1)\n    16"
        },
        {
          "name": "derive_machine_id_from_parts",
          "line": 84,
          "signature": "def derive_machine_id_from_parts(hostname: str, username: str, profile_name: str) -> str",
          "documentation": "Derive a machine identifier from explicit hostname, username, and profile.\n\nThis is the deterministic core of ``derive_machine_id``, exposed for\ncross-language parity testing where hostname and username must be fixed.\n\nArgs:\n    hostname: The machine hostname.\n    username: The OS username.\n    profile_name: The profile name.\n\nReturns:\n    A 16-character hex string.\n\nExample:\n    >>> derive_machine_id_from_parts(\"dev-machine\", \"alice\", \"default\")\n    ... # doctest: +SKIP\n    'a1b2c3d4e5f6a7b8'"
        },
        {
          "name": "validate_forge_dev_did",
          "line": 110,
          "signature": "def validate_forge_dev_did(did: str) -> str | None",
          "documentation": "Validate that a string is a valid forge-dev DID.\n\nArgs:\n    did: The DID string to validate.\n\nReturns:\n    None if valid, or an error message string if invalid.\n\nExample:\n    >>> validate_forge_dev_did(\"did:forge-dev:a1b2c3d4e5f6a7b8:agent:bot\")\n    >>> validate_forge_dev_did(\"did:oas:x:agent:bot\")\n    \"DID 'did:oas:x:agent:bot' does not use the 'forge-dev' method...\""
        },
        {
          "name": "LocalOrg",
          "line": 161,
          "signature": "class LocalOrg()",
          "documentation": "A local organization for grouping dev identities.\n\nIn production, orgs are managed by external services. In local dev,\nan org is a named container with a deterministic ID.\n\nArgs:\n    name: Human-readable org name. Defaults to ``\"local\"``."
        },
        {
          "name": "LocalOrg.id",
          "line": 174,
          "signature": "def id(self) -> str",
          "documentation": "Return the deterministic org ID.\n\nFormat: ``forge-dev-org:<name>``.\n\nReturns:\n    The org identifier string."
        },
        {
          "name": "ForgeDevIdentity",
          "line": 186,
          "signature": "class ForgeDevIdentity()",
          "documentation": "A local development identity wrapping agent metadata.\n\nThis is intentionally simplified compared to the Rust implementation\n(which wraps a full ``ForgeAgentIdentity`` with Ed25519 keys). The\nPython version stores the DID, kind, and metadata for development use.\n\nArgs:\n    did: The ``did:forge-dev`` identifier string.\n    kind: The entity kind (e.g., ``\"mhr\"``, ``\"agent\"``).\n    org_id: The local org this identity belongs to.\n    created_at: ISO 8601 creation timestamp.\n    lineage_depth: Lineage depth from the root identity."
        },
        {
          "name": "ForgeDevIdentity.to_dict",
          "line": 214,
          "signature": "def to_dict(self) -> dict[str, Any]",
          "documentation": "Serialize to a dictionary.\n\nReturns:\n    Dictionary representation."
        },
        {
          "name": "ForgeDevIdentity.from_dict",
          "line": 229,
          "signature": "def from_dict(data: dict[str, Any]) -> ForgeDevIdentity",
          "documentation": "Deserialize from a dictionary.\n\nArgs:\n    data: Dictionary representation.\n\nReturns:\n    The deserialized ForgeDevIdentity."
        },
        {
          "name": "LocalDevProfile",
          "line": 248,
          "signature": "class LocalDevProfile()",
          "documentation": "A local development profile providing identity without external services.\n\n``LocalDevProfile`` provisions a local root identity, derives agent\nidentities on demand, and groups them under a local organization.\n\nArgs:\n    root: The local developer's root identity.\n    org: The local organization context.\n    agents: Registry of derived agent identities, keyed by agent name.\n    machine_id: The 16-character hex machine identifier.\n    profile_name: The profile name."
        },
        {
          "name": "LocalDevProfile.create",
          "line": 269,
          "signature": "def create(profile_name: str='default') -> LocalDevProfile",
          "documentation": "Create a new local dev profile.\n\nDerives a machine ID from the current system and creates a root\nidentity with ``kind=mhr``.\n\nArgs:\n    profile_name: The profile name.\n\nReturns:\n    A new LocalDevProfile."
        },
        {
          "name": "LocalDevProfile.agent_identity",
          "line": 304,
          "signature": "def agent_identity(self, agent_name: str) -> ForgeDevIdentity",
          "documentation": "Derive or retrieve a cached agent identity.\n\nAgent identities are derived lazily from the root identity.\nOnce derived, they are cached in the profile.\n\nArgs:\n    agent_name: The agent's identifier (e.g., ``\"data-analyst\"``).\n\nReturns:\n    The cached or newly derived ForgeDevIdentity."
        },
        {
          "name": "LocalDevProfile.agent_count",
          "line": 336,
          "signature": "def agent_count(self) -> int",
          "documentation": "Return the number of cached agent identities.\n\nReturns:\n    The agent count."
        },
        {
          "name": "LocalDevProfile.to_dict",
          "line": 344,
          "signature": "def to_dict(self) -> dict[str, Any]",
          "documentation": "Serialize to a dictionary.\n\nReturns:\n    Dictionary representation."
        }
      ]
    },
    {
      "path": "forge-py/src/forge/identity/persistence.py",
      "sha256": "957815486ba4e3fd0be40a432daf5b3d21f38855444cd84ce0a846ff968cd44d",
      "artifactSha256": "a330cdb6755ebc937f20ba255ff51bc707af5b8e769efbd12c47f1e15932bca7",
      "url": "/reference/source/forge-py/src/forge/identity/persistence.py.txt",
      "declarations": [
        {
          "name": "IdentityStore",
          "line": 27,
          "signature": "class IdentityStore(ABC)",
          "documentation": "Abstract base class for identity persistence backends.\n\nImplementations provide storage for ``ForgeAgentIdentity`` objects,\nkeyed by DID string.\n\nExample:\n    >>> store = MemoryIdentityStore()\n    >>> from forge.identity.lineage import create_hmr_identity\n    >>> hmr = create_hmr_identity(\"test\", \"alice\")\n    >>> store.save(hmr)\n    >>> loaded = store.load(hmr.did)\n    >>> loaded is not None and loaded.did == hmr.did\n    True"
        },
        {
          "name": "IdentityStore.save",
          "line": 44,
          "signature": "def save(self, identity: ForgeAgentIdentity) -> None",
          "documentation": "Save an identity to the store.\n\nArgs:\n    identity: The identity to persist.\n\nRaises:\n    IdentityPersistenceError: If the save operation fails."
        },
        {
          "name": "IdentityStore.load",
          "line": 55,
          "signature": "def load(self, did: str) -> ForgeAgentIdentity | None",
          "documentation": "Load an identity from the store by DID.\n\nArgs:\n    did: The DID string to look up.\n\nReturns:\n    The identity if found, or None if not in the store.\n\nRaises:\n    IdentityPersistenceError: If the load operation fails."
        },
        {
          "name": "IdentityStore.delete",
          "line": 69,
          "signature": "def delete(self, did: str) -> bool",
          "documentation": "Delete an identity from the store.\n\nArgs:\n    did: The DID string to delete.\n\nReturns:\n    True if the identity was found and deleted, False if not found.\n\nRaises:\n    IdentityPersistenceError: If the delete operation fails."
        },
        {
          "name": "IdentityStore.list_dids",
          "line": 83,
          "signature": "def list_dids(self) -> list[str]",
          "documentation": "List all DID strings in the store.\n\nReturns:\n    A list of DID strings."
        },
        {
          "name": "MemoryIdentityStore",
          "line": 91,
          "signature": "class MemoryIdentityStore(IdentityStore)",
          "documentation": "In-memory identity store for testing and development.\n\nIdentities are stored in a Python dictionary and are not persisted\nacross process restarts.\n\nExample:\n    >>> store = MemoryIdentityStore()\n    >>> store.list_dids()\n    []"
        },
        {
          "name": "MemoryIdentityStore.__init__",
          "line": 103,
          "signature": "def __init__(self) -> None",
          "documentation": ""
        },
        {
          "name": "MemoryIdentityStore.save",
          "line": 106,
          "signature": "def save(self, identity: ForgeAgentIdentity) -> None",
          "documentation": "Save an identity to the in-memory store.\n\nArgs:\n    identity: The identity to save."
        },
        {
          "name": "MemoryIdentityStore.load",
          "line": 114,
          "signature": "def load(self, did: str) -> ForgeAgentIdentity | None",
          "documentation": "Load an identity from the in-memory store by DID.\n\nArgs:\n    did: The DID string to look up.\n\nReturns:\n    The identity if found, or None."
        },
        {
          "name": "MemoryIdentityStore.delete",
          "line": 125,
          "signature": "def delete(self, did: str) -> bool",
          "documentation": "Delete an identity from the in-memory store.\n\nArgs:\n    did: The DID string to delete.\n\nReturns:\n    True if found and deleted, False otherwise."
        },
        {
          "name": "MemoryIdentityStore.list_dids",
          "line": 139,
          "signature": "def list_dids(self) -> list[str]",
          "documentation": "List all DIDs in the in-memory store.\n\nReturns:\n    A list of DID strings."
        },
        {
          "name": "save_identity",
          "line": 152,
          "signature": "def save_identity(identity: ForgeAgentIdentity, path: Path | str) -> None",
          "documentation": "Save an agent identity to a JSON file at the specified path.\n\nThe identity is serialized as a JSON object containing the DID, kind,\npublic key (hex-encoded), full document data, and lineage depth.\n\nSecurity:\n    **WARNING**: The signing key reference is stored without encryption.\n    In production, use encrypted storage (AES-256-GCM or similar). This\n    function is suitable for development and testing only.\n\nSee ANVIL Spec section 11.1 -- OAS Identity Binding.\n\nArgs:\n    identity: The agent identity to save.\n    path: The filesystem path to write the JSON file to.\n\nRaises:\n    IdentityPersistenceError: If serialization or file I/O fails.\n\nExample:\n    >>> from forge.identity.lineage import create_hmr_identity\n    >>> import tempfile, os\n    >>> hmr = create_hmr_identity(\"test\", \"alice\")\n    >>> path = os.path.join(tempfile.mkdtemp(), \"test-id.json\")\n    >>> save_identity(hmr, path)"
        },
        {
          "name": "load_identity",
          "line": 190,
          "signature": "def load_identity(path: Path | str) -> ForgeAgentIdentity",
          "documentation": "Load an agent identity from a JSON file at the specified path.\n\nReads and deserializes the identity JSON, reconstructs the public key\nreference, parses the OAS document, and returns a ``ForgeAgentIdentity``.\n\nSee ANVIL Spec section 11.1 -- OAS Identity Binding.\n\nArgs:\n    path: The filesystem path to read the JSON file from.\n\nReturns:\n    A ForgeAgentIdentity reconstructed from the persisted data.\n\nRaises:\n    IdentityPersistenceError: If the file cannot be read, the JSON is\n        malformed, or the identity fails validation.\n\nExample:\n    >>> from forge.identity.lineage import create_hmr_identity\n    >>> import tempfile, os\n    >>> hmr = create_hmr_identity(\"test\", \"alice\")\n    >>> path = os.path.join(tempfile.mkdtemp(), \"test-id.json\")\n    >>> save_identity(hmr, path)\n    >>> loaded = load_identity(path)\n    >>> loaded.did == hmr.did\n    True"
        }
      ]
    }
  ]
}
