Memory Commons

← Documents

AltersID — the trust fabric

Component deep-dive · 7 July 2026 · status: mixed (parked platform, live concept). Ecosystem overview: /ecosystem.

Purpose

AltersID is the identity layer of the ecosystem: the answer to who for every what the Commons records. Memory Commons is “two layers bound by one identity system” — a living corpus and physical anchors, joined by signatures that say who contributed and hashes that say which release. In the target stack (Project Aletheia) AltersID is Layer 1, the Trust Fabric: every contributor, human or agent, holds a decentralized identifier (DID), every contribution carries a verifiable signature, and agent identities are minted as [email protected]. Its archived framing is the mirror pairing: Memory Commons holds “what happened / what is known / what was decided”; AltersID holds “who experienced it / who knows it / who decided it.”

Current state

Status: mixed — the platform is parked, the concept and its glyph binding are live. A FastAPI prototype exists on disk (alters_id/, May 2025) and was deliberately halted; the project was formally parked 2025-12-17, keeping only the alters.id domain and a [email protected] mailbox as a business card. In the Commons v0 the Trust Fabric row reads “contributor git identity; AltersID parked” — DIDs are design, not yet the live mechanism. What runs today is the glyph binding (decision 0003): an agent’s visual mark is derived agent glyph ← DID hash.

Mechanisms / data model

The prototype is FastAPI + PostgreSQL + RSA-2048 (pycryptodome). Four routers mount under /api: registration, identity, memory, config.

DID minting. DIDWebService.create_did(agent_name) generates a 2048-bit RSA keypair and returns did:web:{agent_name}.{domain} (e.g. did:web:test_agent.test.alters.id); agent_name is the email local-part. Registration stores an AgentIdentity row (did unique, email unique, public_key PEM, status ∈ active/suspended/revoked) plus an AgentProfile, and returns the private_key exactly once.

DID documents are shaped, not resolvable. create_did_document emits @context ["https://www.w3.org/ns/did/v1"], a RsaVerificationKey2018 verification method keyed {did}#key-1, authentication/assertionMethod, and an AgentService endpoint. Two gaps: resolve_did returns only a metadata skeleton — there is no .well-known/did.json fetch or serve, so this is did:web-shaped identifiers rather than the did:web method — and _convert_public_key_to_jwk is a stub returning literal b"modulus"/b"exponent", so the document’s publicKeyJwk is non-functional. Real signing runs off the stored PEM public_key, not the JWK.

Verifiable credentials. issue_credential builds a W3C-shaped object: @context pairs https://www.w3.org/2018/credentials/v1 with a project context; type is ["VerifiableCredential"] + types; credentialSubject merges {id: subject_did, ...}; id is https://{domain}/credentials/{uuid4}. sign_data canonicalizes with json.dumps(sort_keys=True), hashes SHA-256, signs pkcs1_15, and attaches a RsaSignature2018 proof (proofPurpose: assertionMethod, proofValue base64). Verification strips proof, re-canonicalizes, and checks signature, DB revoked flag, and expirationDate. Rows persist in verifiable_credentials (issuer_did, subject_did, types, credential_subject, proof, revoked). The test_did_service / test_identity_service suites confirm sign/verify and tamper-detection round-trip.

Lifecycle coverage is uneven. Only revocation is built — a revoked boolean, gated so Only the issuer can revoke (403 otherwise). Delegation, attestation, and recovery appear solely in the archived vision, not in code.

Identity is claimed, not proven. Every /memory, /config, and /credentials call takes agent_did/issuer_did as a query parameter, and /credentials takes private_key as a query parameter. There is no challenge-response; possession of a key is never demonstrated at the boundary. AgentMemory (types episodic/semantic/procedural, access_control JSON) is gated only by identity_id ownership — the stored access-control settings are never enforced.

How it binds to the rest

Three “memory” surfaces must stay distinct: (1) the prototype’s own AgentMemory table; (2) the parked Memory API v1 (GCS/Cloud Run /memory/{agent_id}) — whose archived settings.py carries the namespace.name.glyph agent-id comment beside AGENT_ID_PATTERN = r"^[a-zA-Z0-9_.:-]{3,64}$"; (3) the live Commons corpus (git + Merkle releases). “Identity gates Commons access and stamps corpus provenance” is design; today contributor-provenance is git identity. Release-provenance is live and separate: a release Merkle root seeds a release glyph etched on MC-1 beside a machine channel (decisions 0003/0004). The glyph system is the one binding that already reaches AltersID: DID hash → agent glyph.

Key decisions

Open questions

What deeper builds next

Implement real did:web resolution (serve/fetch .well-known/did.json) and genuine RSA→JWK modulus/exponent extraction; replace query-param agent_did/private_key with a signature challenge so identity is proven; then either reconcile namespace.name.glyph with the did:web format or retire it — but only after the .id sovereignty exposure is assessed against the round-3 ccTLD framework.