Skip to main content

Agent Lifecycle Management

FieldValue
Document IDASCEND-AGENT-003
Version1.0.0
Last UpdatedDecember 19, 2025
AuthorAscend Engineering Team
PublisherOW-KAI Technologies Inc.
ClassificationEnterprise Client Documentation
ComplianceSOC 2 CC6.1/CC6.2, PCI-DSS 7.1/8.3, HIPAA 164.312, NIST 800-53 AC-2/SI-4

Reading Time: 8 minutes | Skill Level: Intermediate

Overview

Every agent progresses through defined lifecycle states. Understanding these states is critical for proper agent governance and compliance.

Lifecycle States

                            ┌─────────────────────────────────────────────────────────┐
│ AGENT LIFECYCLE STATES │
└─────────────────────────────────────────────────────────┘

┌─────────┐ ┌──────────────────┐ ┌─────────┐
│ DRAFT │───────▶│ PENDING_APPROVAL │───────▶│ ACTIVE │
└─────────┘ └──────────────────┘ └────┬────┘
│ │
│ ┌──────────┼──────────┐
│ │ │ │
│ ▼ │ ▼
│ ┌───────────┐ │ ┌─────────────┐
│ │ SUSPENDED │◀────┘ │ DEPRECATED │
│ └─────┬─────┘ └──────┬──────┘
│ │ │
│ │ │
│ ▼ ▼
│ ┌───────────┐ ┌───────────┐
└────────────────────────────▶│ RETIRED │◀─────────│ RETIRED │
└───────────┘ └───────────┘

State Definitions

# Source: models_agent_registry.py:38
class AgentStatus(str, enum.Enum):
"""Lifecycle status of registered agents."""
DRAFT = "draft" # Being configured
PENDING_APPROVAL = "pending_approval" # Awaiting admin approval
ACTIVE = "active" # Operational
SUSPENDED = "suspended" # Temporarily disabled
DEPRECATED = "deprecated" # Scheduled for removal
RETIRED = "retired" # No longer operational

State Details

StateActions AllowedTransitions ToDescription
draftNonepending_approval, retiredInitial configuration state
pending_approvalNoneactive, draft, retiredAwaiting admin review
activeFullsuspended, deprecatedFully operational
suspendedNoneactive, retiredTemporarily disabled
deprecatedRead-onlyretiredScheduled for removal
retiredNoneNone (terminal)Decommissioned

State Transitions

Draft to Pending Approval

Submit agent for review:

curl -X POST "https://pilot.owkai.app/api/agents/registry/my-agent-001/submit" \
-H "Authorization: Bearer owkai_..."

Pending Approval to Active

Admin approves agent:

curl -X POST "https://pilot.owkai.app/api/agents/registry/my-agent-001/activate" \
-H "Authorization: Bearer owkai_..."
# Source: services/agent_registry_service.py:936
def activate_agent(db, organization_id, agent_id, approved_by):
"""Activate an agent for production use."""
agent = get_agent(db, organization_id, agent_id=agent_id)

if agent.status not in [
AgentStatus.DRAFT.value,
AgentStatus.PENDING_APPROVAL.value,
AgentStatus.SUSPENDED.value
]:
raise ValueError(f"Cannot activate agent in status: {agent.status}")

previous_status = agent.status
agent.status = AgentStatus.ACTIVE.value
agent.approved_at = datetime.now(UTC)
agent.approved_by = approved_by

# Log activation for compliance
log_activity(agent, "activated", approved_by)

return agent

Active to Suspended

Manual suspension:

curl -X POST "https://pilot.owkai.app/api/agents/registry/my-agent-001/suspend" \
-H "Authorization: Bearer owkai_..." \
-H "Content-Type: application/json" \
-d '{
"reason": "Security review required"
}'
# Source: services/agent_registry_service.py:984
def suspend_agent(db, organization_id, agent_id, suspended_by, reason=None):
"""Suspend an agent (emergency disable)."""
agent = get_agent(db, organization_id, agent_id=agent_id)

previous_status = agent.status
agent.status = AgentStatus.SUSPENDED.value
agent.updated_at = datetime.now(UTC)
agent.updated_by = suspended_by

# Log suspension with reason for compliance
log_activity(
agent, "suspended", suspended_by,
previous_state={"status": previous_status},
new_state={"status": "suspended", "reason": reason}
)

logger.warning(f"Agent SUSPENDED: {agent_id} - Reason: {reason}")
return agent

Auto-Suspension

Agents can be automatically suspended when triggers are met:

# Source: services/agent_registry_service.py:522
def check_auto_suspend_triggers(db, agent):
"""Check if any auto-suspend conditions are met."""

if not agent.auto_suspend_enabled:
return {"should_suspend": False}

# Check error rate trigger
if agent.auto_suspend_on_error_rate is not None:
if agent.error_rate_percent >= agent.auto_suspend_on_error_rate * 100:
return {
"should_suspend": True,
"reason": f"Error rate {agent.error_rate_percent:.1f}% exceeds threshold",
"trigger": "error_rate"
}

# Check offline duration trigger
if agent.auto_suspend_on_offline_minutes is not None:
if agent.last_heartbeat:
minutes_offline = (now - agent.last_heartbeat).total_seconds() / 60
if minutes_offline > agent.auto_suspend_on_offline_minutes:
return {
"should_suspend": True,
"reason": f"Agent offline for {minutes_offline:.0f} minutes",
"trigger": "offline_duration"
}

# Check budget exceeded trigger
if agent.auto_suspend_on_budget_exceeded:
if agent.current_daily_spend_usd >= agent.max_daily_budget_usd:
return {
"should_suspend": True,
"reason": f"Budget exceeded: ${agent.current_daily_spend_usd:.2f}",
"trigger": "budget_exceeded"
}

return {"should_suspend": False}

Suspended to Active

Reactivate after suspension:

curl -X POST "https://pilot.owkai.app/api/agents/registry/my-agent-001/activate" \
-H "Authorization: Bearer owkai_..." \
-H "Content-Type: application/json" \
-d '{
"reason": "Security review completed, cleared for operation"
}'

Active to Deprecated

Schedule for removal:

curl -X POST "https://pilot.owkai.app/api/agents/registry/my-agent-001/deprecate" \
-H "Authorization: Bearer owkai_..." \
-H "Content-Type: application/json" \
-d '{
"reason": "Replaced by v2 agent",
"retirement_date": "2025-12-31"
}'

Any State to Retired

Permanent decommission:

curl -X DELETE "https://pilot.owkai.app/api/agents/registry/my-agent-001" \
-H "Authorization: Bearer owkai_..." \
-H "Content-Type: application/json" \
-d '{
"reason": "Agent decommissioned"
}'

State Enforcement

Action Execution Check

# Source: services/agent_registry_service.py:1177
def evaluate_policies(db, organization_id, agent_id, action_context):
"""Evaluate policies including lifecycle state check."""

agent = get_agent(db, organization_id, agent_id=agent_id)

if not agent:
return {"decision": "deny", "reason": "Agent not registered"}

# Check agent status FIRST
if agent.status != AgentStatus.ACTIVE.value:
return {
"decision": "deny",
"reason": f"Agent not active (status: {agent.status})",
"policies": []
}

# Continue with policy evaluation...

Status Check Response

When an inactive agent attempts an action:

{
"decision": "deny",
"reason": "Agent not active (status: suspended)",
"action_id": null,
"risk_score": null,
"policies": [],
"agent_status": "suspended",
"reactivation_required": true
}

Approval Workflow

Require Approval for Activation

For organizations requiring approval before activation:

# Registration creates agent in DRAFT state
registration = client.register(
agent_id="new-agent",
agent_type="autonomous"
)
# Status: draft

# Submit for approval (moves to PENDING_APPROVAL)
client.submit_for_approval("new-agent")
# Status: pending_approval

# Admin reviews and activates
# Status: active (after admin approval)

Approval Requirements

Agent TypeAuto-ActivateApproval Required
advisoryYesNo
supervisedNoAdmin
autonomousNoAdmin + Security
mcp_serverNoAdmin

Approval Audit Trail

{
"agent_id": "autonomous-agent-001",
"activity_type": "activated",
"activity_description": "Agent 'autonomous-agent-001' activated (previous: pending_approval)",
"performed_by": "security-admin@company.com",
"performed_via": "dashboard",
"timestamp": "2025-12-15T10:30:00Z",
"previous_state": {
"status": "pending_approval"
},
"new_state": {
"status": "active"
}
}

Bulk Operations

Suspend All Agents

Emergency: Suspend all agents in organization:

curl -X POST "https://pilot.owkai.app/api/agents/control/suspend-all" \
-H "Authorization: Bearer owkai_..." \
-H "Content-Type: application/json" \
-d '{
"reason": "Security incident - suspending all agents"
}'

Reactivate All Agents

Resume operations:

curl -X POST "https://pilot.owkai.app/api/agents/control/resume-all" \
-H "Authorization: Bearer owkai_..." \
-H "Content-Type: application/json" \
-d '{
"reason": "Security incident resolved - resuming operations"
}'

Compliance Requirements

State Changes Require Audit

All state changes are logged:

# Source: services/agent_registry_service.py:963
# Every state change creates an audit entry
activity = AgentActivityLog(
agent_id=agent.id,
organization_id=organization_id,
activity_type="activated",
activity_description=f"Agent '{agent_id}' activated (previous: {previous_status})",
performed_by=approved_by,
performed_via="api",
previous_state={"status": previous_status},
new_state={"status": AgentStatus.ACTIVE.value},
timestamp=datetime.now(UTC)
)

Compliance Mapping

StandardRequirementImplementation
SOC 2 CC6.1Access provisioningDraft → Pending → Active
SOC 2 CC6.2Access authorizationApproval workflow
NIST AC-2Account managementLifecycle states
NIST AC-2(3)Disable inactiveAuto-suspend
PCI-DSS 8.1.4Remove inactive usersDeprecated → Retired

Best Practices

1. Use Proper Transitions

# Good - proper state transition
agent.submit_for_approval() # draft → pending_approval
admin.activate(agent) # pending_approval → active

# Bad - skipping states
agent.force_activate() # draft → active (bypasses approval)

2. Document State Changes

# Always include reason for state changes
curl -X POST ".../suspend" \
-d '{
"reason": "JIRA-5678: Security audit findings require review"
}'

3. Monitor Auto-Suspensions

# Set up alerts for auto-suspensions
{
"alert_type": "agent_auto_suspended",
"channels": ["slack", "email"],
"recipients": ["security-team@company.com"]
}

4. Plan for Retirement

# Deprecate before retiring
# 1. Mark as deprecated with future retirement date
deprecate(agent, retirement_date="2025-12-31")

# 2. Monitor for any remaining usage
# 3. Retire when confirmed safe
retire(agent, reason="Deprecated period complete, no active usage")

Next Steps


Document Version: 1.0.0 | Last Updated: December 2025