Implements all P0 features per OpenSpec change phase-1-mvp-implementation: - Agent Registry Service (CRUD) — full lifecycle management - OAuth 2.0 Token Service (Client Credentials flow) - Credential Management (generate, rotate, revoke) - Immutable Audit Log Service Tech: Node.js 18+, TypeScript 5.3+ strict, Express 4.18+, PostgreSQL 14+, Redis 7+ Standards: OpenAPI 3.0 specs, DRY/SOLID, zero `any` types Quality: 18 unit test suites, 244 tests passing, 97%+ coverage OpenAPI: 4 complete specs (14 endpoints total) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
5.7 KiB
ADDED Requirements
Requirement: Register a new AI agent
The system SHALL create a new agent identity record with a system-assigned immutable UUID (agentId) when a valid CreateAgentRequest is received. The email field SHALL be unique across all agents. The agent SHALL be created with status: active. The system SHALL enforce a free-tier limit of 100 registered agents per account.
Scenario: Successful agent registration
- WHEN a POST request to
/agentsis received with a validCreateAgentRequestbody and a valid Bearer token - THEN the system creates the agent, assigns a UUID
agentId, setsstatustoactive, setscreatedAtandupdatedAtto the current timestamp, and returns201with the fullAgentobject
Scenario: Duplicate email rejected
- WHEN a POST request to
/agentsis received with anemailthat is already registered - THEN the system returns
409 Conflictwithcode: AGENT_ALREADY_EXISTS
Scenario: Free tier limit enforced
- WHEN a POST request to
/agentsis received and the account already has 100 registered agents - THEN the system returns
403 Forbiddenwithcode: FREE_TIER_LIMIT_EXCEEDEDanddetails.limit: 100
Scenario: Invalid request body rejected
- WHEN a POST request to
/agentsis received with a missing required field or invalid field value (e.g. invalid semver, invalid email, invalid capability pattern) - THEN the system returns
400 Bad Requestwithcode: VALIDATION_ERRORanddetailsidentifying the failing field
Requirement: Retrieve a single agent by ID
The system SHALL return the full Agent record for a given agentId.
Scenario: Agent found
- WHEN a GET request to
/agents/{agentId}is received with a valid Bearer token and a UUID that exists in the registry - THEN the system returns
200 OKwith the fullAgentobject
Scenario: Agent not found
- WHEN a GET request to
/agents/{agentId}is received with a UUID that does not exist - THEN the system returns
404 Not Foundwithcode: AGENT_NOT_FOUND
Requirement: List agents with pagination and filtering
The system SHALL return a paginated list of agents, orderd by createdAt descending, optionally filtered by owner, agentType, and/or status.
Scenario: Successful paginated list
- WHEN a GET request to
/agentsis received with optionalpage,limit,owner,agentType,statusquery parameters and a valid Bearer token - THEN the system returns
200 OKwith aPaginatedAgentsResponsecontainingdata,total,page, andlimit
Scenario: Invalid pagination parameters rejected
- WHEN a GET request to
/agentsis received withlimitgreater than 100 orpageless than 1 - THEN the system returns
400 Bad Requestwithcode: VALIDATION_ERROR
Requirement: Update agent metadata
The system SHALL partially update a mutable agent record. agentId, email, and createdAt SHALL be immutable. Setting status to decommissioned SHALL be a one-way irreversible operation.
Scenario: Successful partial update
- WHEN a PATCH request to
/agents/{agentId}is received with a valid partialUpdateAgentRequestbody and a valid Bearer token - THEN the system updates only the provided fields, sets
updatedAtto the current timestamp, and returns200 OKwith the full updatedAgentobject
Scenario: Attempt to modify immutable field rejected
- WHEN a PATCH request to
/agents/{agentId}contains theemailfield - THEN the system returns
400 Bad Requestwithcode: IMMUTABLE_FIELDanddetails.field: email
Scenario: Decommissioned agent cannot be updated
- WHEN a PATCH request to
/agents/{agentId}targets an agent withstatus: decommissioned - THEN the system returns
403 Forbiddenwithcode: AGENT_DECOMMISSIONED
Requirement: Decommission (soft-delete) an agent
The system SHALL set an agent's status to decommissioned and revoke all of its active credentials. The agent record SHALL be retained for audit purposes. This operation SHALL be irreversible.
Scenario: Successful decommission
- WHEN a DELETE request to
/agents/{agentId}is received with a valid Bearer token and the agent exists and is not already decommissioned - THEN the system sets
statustodecommissioned, revokes all active credentials for this agent, and returns204 No Content
Scenario: Already decommissioned agent rejected
- WHEN a DELETE request to
/agents/{agentId}is received for an agent that is alreadydecommissioned - THEN the system returns
409 Conflictwithcode: AGENT_ALREADY_DECOMMISSIONED
Requirement: Authentication required on all agent endpoints
All agent endpoints SHALL require a valid Bearer JWT in the Authorization header.
Scenario: Missing token rejected
- WHEN any request to
/agentsor/agents/{agentId}is received without anAuthorization: Bearerheader - THEN the system returns
401 Unauthorizedwithcode: UNAUTHORIZED
Scenario: Invalid token rejected
- WHEN any request to
/agentsor/agents/{agentId}is received with an expired, malformed, or revoked Bearer token - THEN the system returns
401 Unauthorizedwithcode: UNAUTHORIZED
Requirement: Rate limiting on all agent endpoints
The system SHALL enforce a rate limit of 100 requests per minute per authenticated client. Rate limit state SHALL be tracked in Redis.
Scenario: Rate limit exceeded
- WHEN a client sends more than 100 requests to any agent endpoint within a 60-second window
- THEN the system returns
429 Too Many RequestswithX-RateLimit-Limit,X-RateLimit-Remaining: 0, andX-RateLimit-Resetheaders