Skip to content

Compliance & Attestation

The Agent Registry enforces ongoing compliance through a combination of agent status management and periodic attestation. Registration alone is not sufficient -- agents must continuously prove they are still operating within their declared parameters.


Agent Status Lifecycle

Every agent in the registry has a status that governs whether it is considered compliant. The following state diagram shows all possible transitions.

stateDiagram-v2
    [*] --> Active: registerAgent()
    Active --> Suspended: suspendAgent() [regulator]
    Active --> Revoked: revokeAgent() [regulator]
    Active --> Terminated: terminateSelf() [agent/creator]
    Suspended --> Active: reactivateAgent() [regulator]
    Revoked --> [*]: permanent
    Terminated --> [*]: permanent

Status Definitions

Status Description Who Triggers Reversible?
Active Agent is registered and operational. This is the only status that can be compliant. registerAgent() or reactivateAgent() --
Suspended Temporarily disabled by a regulator. The agent cannot operate but may be restored. suspendAgent() by regulator Yes, via reactivateAgent()
Revoked Permanently removed by a regulator. The agent's wallet mapping is deleted. revokeAgent() by regulator No
Terminated Voluntarily shut down by the agent, its creator, or its Haftungsperson. The wallet mapping is deleted. terminateSelf() by agent/creator/Haftungsperson No

Permanent States

Revoked and Terminated are permanent. Once an agent enters either state, it cannot be reactivated. The wallet-to-agent mapping is deleted, freeing the wallet address for potential reuse by a new agent.


Attestation Rules

The Requirement

Agents must call attestCompliance() at least once within the attestation grace period to remain compliant. The default grace period is 7 days (604,800 seconds).

Parameter Default Value Configurable?
attestationGracePeriod 7 days (604,800 seconds) Yes, via setAttestationGracePeriod() (owner only)

Initial Attestation

When an agent is first registered, lastAttestation is automatically set to block.timestamp. This means a newly registered agent is considered compliant for the first 7 days without any additional action.

Subsequent Attestations

After the initial 7-day window, the agent (or an authorized party) must call attestCompliance() to reset the timer. Each call sets lastAttestation to the current block.timestamp.

Who Can Attest

The onlyAgentOrCreator modifier governs who can call attestCompliance(). Three parties are authorized:

Party Relationship Typical Use Case
Agent wallet The agent's own operational wallet (agentWallet) Automated heartbeat from the agent itself
Creator The wallet that originally registered the agent (creator) Manual attestation by the developer
Haftungsperson The legally responsible human entity (haftungsperson) Oversight attestation by the responsible party

Automated Attestation

In most deployments, the agent itself runs a cron job or background task that calls attestCompliance() every few days. The Python and TypeScript SDKs both provide a simple attest(agentId) method for this purpose.


Compliance Check Logic

The isRegisteredAndCompliant() function is the single source of truth for compliance. Here is the exact logic from the smart contract:

function isRegisteredAndCompliant(address agentWallet) external view returns (bool) {
    uint256 agentId = walletToAgent[agentWallet];
    if (agentId == 0) return false;                        // Not registered
    AgentRecord storage a = agents[agentId];
    if (a.status != AgentStatus.Active) return false;      // Not active
    if (block.timestamp > a.lastAttestation + attestationGracePeriod)
        return false;                                       // Attestation lapsed
    return true;
}

Three conditions must ALL be true for compliance:

  1. The wallet must be mapped to a registered agent (agentId != 0)
  2. The agent's status must be Active
  3. The current time must be within lastAttestation + attestationGracePeriod

Compliance Matrix

Status Attestation isRegisteredAndCompliant() KYA Result
Active Current true Compliant
Active Lapsed false Non-compliant
Suspended Current false Non-compliant
Suspended Lapsed false Non-compliant
Revoked -- false Non-compliant
Terminated -- false Non-compliant
Not registered -- false Not registered

Status Takes Priority

Even if an agent's attestation is current, it is not compliant unless its status is Active. Conversely, an Active agent with a lapsed attestation is also not compliant. Both conditions are required.


What Happens When Attestation Lapses

When an agent fails to attest within the grace period:

  1. isRegisteredAndCompliant() returns false for the agent's wallet
  2. KYA checks return isCompliant: false for the agent
  3. Infrastructure providers deny service (if they implement KYA)
  4. The agent remains registered -- it is not deleted or suspended, just non-compliant
  5. The agent can recover by calling attestCompliance() at any time to reset the timer
graph LR
    A["Agent registered<br/>(auto-attested)"] -->|"7 days pass"| B["Attestation lapsed<br/>(non-compliant)"]
    B -->|"attestCompliance()"| C["Attestation current<br/>(compliant again)"]
    C -->|"7 days pass"| B

No Automatic Suspension

A lapsed attestation does not trigger an automatic status change. The agent remains Active but non-compliant. This is by design -- the agent may have a temporary outage and should be able to recover without regulator intervention.


Regulatory Actions

Regulators (and the contract owner) have special powers to manage agent compliance.

Suspend an Agent

function suspendAgent(uint256 agentId, string calldata reason)
    external agentExists(agentId) onlyRegulator

Temporarily disables an agent. A reason string is included in the AgentSuspended event for auditability. The agent can be reactivated later.

Revoke an Agent

function revokeAgent(uint256 agentId, string calldata reason)
    external agentExists(agentId) onlyRegulator

Permanently removes an agent. The wallet-to-agent mapping is deleted. This is irreversible.

Reactivate an Agent

function reactivateAgent(uint256 agentId)
    external agentExists(agentId) onlyRegulator

Restores a Suspended agent to Active status. Also resets lastAttestation to the current timestamp, giving the agent a fresh 7-day window. Only works for Suspended agents -- Revoked and Terminated agents cannot be reactivated.

Self-Termination

function terminateSelf(uint256 agentId)
    external agentExists(agentId) onlyAgentOrCreator(agentId)

Allows the agent, its creator, or its Haftungsperson to voluntarily shut down the agent. This is permanent.


Regulator Management

The contract owner can add and remove regulators.

Function Description
addRegulator(address) Grants regulator privileges to an address
removeRegulator(address) Revokes regulator privileges from an address

Owner Is Always a Regulator

The onlyRegulator modifier checks regulators[sender] || sender == owner. The contract owner always has regulator powers, regardless of the regulators mapping.


Events

Every compliance action emits an event for auditability.

Event Emitted By Fields
ComplianceAttested attestCompliance() agentId, timestamp
AgentSuspended suspendAgent() agentId, by (regulator address), reason
AgentRevoked revokeAgent() agentId, by (regulator address), reason
AgentReactivated reactivateAgent() agentId, by (regulator address)
AgentTerminated terminateSelf() agentId

Further Reading