Registry & persistence lifecycle
The registry is the durable index of the agent fleet. It links what the upstream layers produced onto a swappable store, and duplicates none of their logic.
Persistence layer
Persistence is an abstraction, not a database binding. A single immutable PersistedRecord wraps any domain object (envelope, assessment, identity, trust profile, passport, reputation) with uniform metadata; conversion helpers only wrap existing to_dict() output, no business logic.
| Piece | Role |
|---|---|
PersistedRecord | record_id · record_type · created_at · updated_at · source_id · payload · metadata · persistence_version |
record_id | deterministic "{type}:{source_id}" when a source id exists, else a uuid |
PersistenceStore (ABC) | put · get · exists · list(record_type=) · delete |
MemoryPersistenceStore | in-memory dict, the runtime default |
JsonPersistenceStore | path required (ValueError if empty); sorted JSON; atomic temp + os.replace; corrupt file → empty; never auto-writes a default path |
Registry lifecycle
PersistentAgentRegistry sits on a store and coordinates the four domain records plus a per-agent AgentRegistryEntry index (itself persisted, as record type agent_registry_entry). Each register_identity / update_trust_profile / update_passport / update_reputation call persists the domain record via the persistence helpers and upserts the index entry.
sequenceDiagram autonumber participant H as registry_observe handler participant R as PersistentAgentRegistry participant S as PersistenceStore H->>R: register_identity(identity) R->>S: put(identity_record(identity)) R->>R: _upsert(agent_id, identity_record_id, operation_count) R->>S: put(make_record(agent_registry_entry, entry)) H->>R: update_trust_profile(profile) R->>S: put(trust_profile_record) + _upsert(latest_trust_score) H->>R: update_passport(passport) R->>S: put(passport_record) + _upsert(latest_passport_status) H->>R: update_reputation(reputation) R->>S: put(reputation_record) + _upsert(latest_reputation_score) R-->>H: AgentRegistryEntryRegistry observe, link domain records + upsert the per-agent index. Source: registry/engine.py.
The runtime binds one process-lifetime registry: _registry = PersistentAgentRegistry(MemoryPersistenceStore()). State survives across requests but not restarts, appropriate for this phase. Swapping in JsonPersistenceStore(path) makes it durable with no other change. list() returns every entry; delete(agent_id) cascades to the linked domain records.
Upsert semantics
_upsert is where the index stays consistent under repeated observation:
created_atis preserved across updates;updated_atadvances to now.- metadata is merged, not replaced.
- updates drop
Noneso a partial observation never clobbers an existing value with nothing (applied = {k:v for k,v in changes.items() if v is not None}). - cached latest values (
latest_trust_score,latest_reputation_score,latest_passport_status,operation_count) are what the Control Center reads.
agent_unknown rather than raising, so POST /api/v1/registry/observe always returns a valid entry. When nothing usable is supplied, the handler still registers a safe agent_unknown entry.