fix(vv): resolve all 6 V&V issues — field trial unblocked

All findings from the inaugural LeadValidator audit resolved and
confirmed. Release gate: PASS.

VV_ISSUE_002 (BLOCKER): 15 OpenAPI specs verified present covering
all 20 route groups (46 endpoints documented in docs/openapi/)

VV_ISSUE_003 (MAJOR): Remove any types from src/db/pool.ts —
replaced pool.query shim with unknown[] + Object.defineProperty,
zero any types, eslint-disable suppressions removed

VV_ISSUE_004 (MAJOR): Remove raw Pool from ScaffoldController and
HealthDetailedController — injected AgentRepository/CredentialRepository
and DbProbe interface respectively; added CredentialRepository.findActiveClientId()

VV_ISSUE_005 (MAJOR): Add unit tests for 5 untested services —
ComplianceStatusStore, EventPublisher, MarketplaceService,
OIDCTrustPolicyService, UsageService

VV_ISSUE_006 (MAJOR): Add integration tests for 7 missing route
groups — analytics, billing, tiers, webhooks, marketplace,
oidc-trust-policies, oidc-token-exchange

VV_ISSUE_001 (MINOR): Create missing design.md and tasks.md in 4
OpenSpec archives — all archives now complete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
SentryAgent.ai Developer
2026-04-07 04:52:47 +00:00
parent d216096dfb
commit 7441c9f298
49 changed files with 8954 additions and 70 deletions

576
docs/openapi/did.yaml Normal file
View File

@@ -0,0 +1,576 @@
openapi: "3.0.3"
info:
title: SentryAgent.ai — W3C DID & AGNTCY Agent Card
version: 1.0.0
description: |
W3C Decentralized Identifier (DID) and AGNTCY Agent Card endpoints for the
SentryAgent.ai AgentIdP platform.
**Unauthenticated endpoints:**
- `GET /.well-known/did.json` — Instance-level DID Document for the IdP itself
- `GET /api/v1/agents/:agentId/did` — Per-agent W3C DID Document
- `GET /api/v1/agents/:agentId/did/card` — AGNTCY-format agent card
**Authenticated endpoint** (requires Bearer JWT + OPA authorization):
- `GET /api/v1/agents/:agentId/did/resolve` — W3C DID Resolution result
All DID Documents conform to the **W3C DID Core 1.0** specification.
Agent cards conform to the **AGNTCY** agent identity standard (Linux Foundation).
servers:
- url: http://localhost:3000
description: Local development server
- url: https://api.sentryagent.ai
description: Production server
tags:
- name: DID Documents
description: W3C DID Document endpoints (unauthenticated)
- name: DID Resolution
description: Authenticated W3C DID Resolution endpoint
- name: Agent Card
description: AGNTCY agent card endpoint (unauthenticated)
components:
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: |
JWT access token obtained via `POST /api/v1/token`.
Include as `Authorization: Bearer <token>`.
schemas:
PublicKeyJwk:
type: object
description: JWK representation of a public key embedded in a verification method.
required:
- kty
properties:
kty:
type: string
description: Key type (e.g. "EC", "RSA").
example: "EC"
crv:
type: string
description: EC curve (e.g. "P-256").
example: "P-256"
x:
type: string
description: Base64url-encoded EC x coordinate.
example: "f83OJ3D..."
y:
type: string
description: Base64url-encoded EC y coordinate.
example: "x_FEzRu..."
n:
type: string
description: Base64url-encoded RSA modulus.
e:
type: string
description: Base64url-encoded RSA public exponent.
example: "AQAB"
use:
type: string
example: "sig"
kid:
type: string
example: "key-20260328-001"
VerificationMethod:
type: object
description: W3C DID Core 1.0 verification method.
required:
- id
- type
- controller
- publicKeyJwk
properties:
id:
type: string
description: Full DID URL for this verification method.
example: "did:web:api.sentryagent.ai:agents:a1b2c3d4-e5f6-7890-abcd-ef1234567890#key-1"
type:
type: string
description: Verification method type.
example: "JsonWebKey2020"
controller:
type: string
description: DID that controls this key.
example: "did:web:api.sentryagent.ai:agents:a1b2c3d4-e5f6-7890-abcd-ef1234567890"
publicKeyJwk:
$ref: '#/components/schemas/PublicKeyJwk'
DIDService:
type: object
description: A W3C DID Document service endpoint.
required:
- id
- type
- serviceEndpoint
properties:
id:
type: string
example: "did:web:api.sentryagent.ai:agents:a1b2c3d4#agentIdP"
type:
type: string
example: "AgentIdP"
serviceEndpoint:
type: string
format: uri
example: "https://api.sentryagent.ai/api/v1/agents/a1b2c3d4-e5f6-7890-abcd-ef1234567890"
AgntcyExtension:
type: object
description: AGNTCY-specific extension fields embedded in a per-agent DID Document.
required:
- agentId
- agentType
- capabilities
- deploymentEnv
- owner
- version
properties:
agentId:
type: string
format: uuid
example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
agentType:
type: string
example: "screener"
capabilities:
type: array
items:
type: string
example: ["resume:read", "email:send"]
deploymentEnv:
type: string
example: "production"
owner:
type: string
example: "talent-acquisition-team"
version:
type: string
example: "1.4.2"
DIDDocument:
type: object
description: W3C DID Core 1.0 DID Document.
required:
- "@context"
- id
- controller
- verificationMethod
- authentication
properties:
"@context":
type: array
items:
type: string
description: JSON-LD context URIs.
example:
- "https://www.w3.org/ns/did/v1"
- "https://w3id.org/security/suites/jws-2020/v1"
id:
type: string
description: The DID identifier for this document.
example: "did:web:api.sentryagent.ai:agents:a1b2c3d4-e5f6-7890-abcd-ef1234567890"
controller:
type: string
description: DID of the controlling entity.
example: "did:web:api.sentryagent.ai"
verificationMethod:
type: array
items:
$ref: '#/components/schemas/VerificationMethod'
authentication:
type: array
items:
type: string
description: DID URLs referencing verification methods authorized for authentication.
example:
- "did:web:api.sentryagent.ai:agents:a1b2c3d4-e5f6-7890-abcd-ef1234567890#key-1"
assertionMethod:
type: array
items:
type: string
service:
type: array
items:
$ref: '#/components/schemas/DIDService'
agntcy:
$ref: '#/components/schemas/AgntcyExtension'
DIDResolutionResult:
type: object
description: |
W3C DID Resolution result format.
Returned with `Content-Type: application/ld+json;profile="https://w3id.org/did-resolution"`.
required:
- didDocument
- didDocumentMetadata
- didResolutionMetadata
properties:
didDocument:
$ref: '#/components/schemas/DIDDocument'
didDocumentMetadata:
type: object
required:
- created
- updated
- deactivated
properties:
created:
type: string
format: date-time
example: "2026-03-01T08:00:00.000Z"
updated:
type: string
format: date-time
example: "2026-03-28T11:30:00.000Z"
deactivated:
type: boolean
example: false
didResolutionMetadata:
type: object
required:
- contentType
- retrieved
properties:
contentType:
type: string
example: "application/ld+json"
retrieved:
type: string
format: date-time
example: "2026-04-07T09:00:00.000Z"
AgentCard:
type: object
description: |
AGNTCY-format agent card providing a machine-readable identity summary.
Suitable for AGNTCY registry publishing and agent discovery.
required:
- did
- name
- agentType
- capabilities
- owner
- version
- deploymentEnv
- identityProvider
- issuedAt
properties:
did:
type: string
description: W3C DID identifier for this agent.
example: "did:web:api.sentryagent.ai:agents:a1b2c3d4-e5f6-7890-abcd-ef1234567890"
name:
type: string
description: Human-readable agent name (derived from email).
example: "screener-001@sentryagent.ai"
agentType:
type: string
example: "screener"
capabilities:
type: array
items:
type: string
example: ["resume:read", "email:send", "candidate:score"]
owner:
type: string
example: "talent-acquisition-team"
version:
type: string
example: "1.4.2"
deploymentEnv:
type: string
example: "production"
identityProvider:
type: string
format: uri
description: URL of the issuing AgentIdP instance.
example: "https://api.sentryagent.ai"
issuedAt:
type: string
format: date-time
description: ISO 8601 timestamp when this card was generated.
example: "2026-04-07T09:00:00.000Z"
ErrorResponse:
type: object
description: Standard error response envelope.
required:
- code
- message
properties:
code:
type: string
example: "AGENT_NOT_FOUND"
message:
type: string
example: "Agent with the specified ID was not found."
details:
type: object
additionalProperties: true
responses:
Unauthorized:
description: Missing or invalid Bearer token.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
code: "UNAUTHORIZED"
message: "A valid Bearer token is required to access this resource."
Forbidden:
description: Valid token but insufficient permissions.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
code: "FORBIDDEN"
message: "You do not have permission to perform this action."
NotFound:
description: Agent not found.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
code: "AGENT_NOT_FOUND"
message: "Agent with the specified ID was not found."
InternalServerError:
description: Unexpected server error.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
code: "INTERNAL_SERVER_ERROR"
message: "An unexpected error occurred. Please try again later."
paths:
/.well-known/did.json:
get:
operationId: getInstanceDIDDocument
tags:
- DID Documents
summary: Instance-level DID Document
description: |
Returns the W3C DID Document for the SentryAgent.ai AgentIdP instance itself.
This identifies the IdP as a DID controller (`did:web:api.sentryagent.ai`).
Used by external parties to discover the IdP's public keys and service endpoints.
This endpoint is **unauthenticated**.
security: []
responses:
'200':
description: Instance DID Document returned successfully.
content:
application/json:
schema:
$ref: '#/components/schemas/DIDDocument'
example:
"@context":
- "https://www.w3.org/ns/did/v1"
- "https://w3id.org/security/suites/jws-2020/v1"
id: "did:web:api.sentryagent.ai"
controller: "did:web:api.sentryagent.ai"
verificationMethod:
- id: "did:web:api.sentryagent.ai#key-1"
type: "JsonWebKey2020"
controller: "did:web:api.sentryagent.ai"
publicKeyJwk:
kty: "EC"
crv: "P-256"
x: "f83OJ3D..."
y: "x_FEzRu..."
authentication:
- "did:web:api.sentryagent.ai#key-1"
service:
- id: "did:web:api.sentryagent.ai#agentIdP"
type: "AgentIdP"
serviceEndpoint: "https://api.sentryagent.ai/api/v1"
'500':
$ref: '#/components/responses/InternalServerError'
/api/v1/agents/{agentId}/did:
get:
operationId: getAgentDIDDocument
tags:
- DID Documents
summary: Get agent DID Document
description: |
Returns the W3C DID Core 1.0 Document for a specific registered agent.
Returns `410 Gone` if the agent has been decommissioned — the DID Document
is no longer active.
This endpoint is **unauthenticated**.
security: []
parameters:
- name: agentId
in: path
required: true
description: UUID of the agent.
schema:
type: string
format: uuid
example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
responses:
'200':
description: Agent DID Document returned successfully.
content:
application/json:
schema:
$ref: '#/components/schemas/DIDDocument'
example:
"@context":
- "https://www.w3.org/ns/did/v1"
- "https://w3id.org/security/suites/jws-2020/v1"
id: "did:web:api.sentryagent.ai:agents:a1b2c3d4-e5f6-7890-abcd-ef1234567890"
controller: "did:web:api.sentryagent.ai"
verificationMethod:
- id: "did:web:api.sentryagent.ai:agents:a1b2c3d4-e5f6-7890-abcd-ef1234567890#key-1"
type: "JsonWebKey2020"
controller: "did:web:api.sentryagent.ai:agents:a1b2c3d4-e5f6-7890-abcd-ef1234567890"
publicKeyJwk:
kty: "EC"
crv: "P-256"
x: "f83OJ3D..."
y: "x_FEzRu..."
authentication:
- "did:web:api.sentryagent.ai:agents:a1b2c3d4-e5f6-7890-abcd-ef1234567890#key-1"
agntcy:
agentId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
agentType: "screener"
capabilities:
- "resume:read"
- "email:send"
deploymentEnv: "production"
owner: "talent-acquisition-team"
version: "1.4.2"
'404':
$ref: '#/components/responses/NotFound'
'410':
description: Agent has been decommissioned — DID Document is no longer active.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
example:
code: "AGENT_DECOMMISSIONED"
message: "Agent has been decommissioned — DID Document is no longer active"
'500':
$ref: '#/components/responses/InternalServerError'
/api/v1/agents/{agentId}/did/resolve:
get:
operationId: resolveAgentDID
tags:
- DID Resolution
summary: Resolve agent DID (W3C DID Resolution)
description: |
Returns the full W3C DID Resolution result for a specific agent, including
the DID Document, DID Document Metadata, and DID Resolution Metadata.
The response `Content-Type` is:
`application/ld+json;profile="https://w3id.org/did-resolution"`
Requires a valid Bearer JWT and OPA authorization.
security:
- BearerAuth: []
parameters:
- name: agentId
in: path
required: true
description: UUID of the agent to resolve.
schema:
type: string
format: uuid
example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
responses:
'200':
description: DID Resolution result returned successfully.
content:
application/ld+json:
schema:
$ref: '#/components/schemas/DIDResolutionResult'
example:
didDocument:
"@context":
- "https://www.w3.org/ns/did/v1"
id: "did:web:api.sentryagent.ai:agents:a1b2c3d4-e5f6-7890-abcd-ef1234567890"
controller: "did:web:api.sentryagent.ai"
verificationMethod: []
authentication: []
didDocumentMetadata:
created: "2026-03-01T08:00:00.000Z"
updated: "2026-03-28T11:30:00.000Z"
deactivated: false
didResolutionMetadata:
contentType: "application/ld+json"
retrieved: "2026-04-07T09:00:00.000Z"
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalServerError'
/api/v1/agents/{agentId}/did/card:
get:
operationId: getAgentCard
tags:
- Agent Card
summary: Get AGNTCY agent card
description: |
Returns the AGNTCY-format agent card for the specified agent.
The card provides a machine-readable identity summary suitable for
AGNTCY registry publishing and agent discovery by external consumers.
This endpoint is **unauthenticated**.
security: []
parameters:
- name: agentId
in: path
required: true
description: UUID of the agent.
schema:
type: string
format: uuid
example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
responses:
'200':
description: AGNTCY agent card returned successfully.
content:
application/json:
schema:
$ref: '#/components/schemas/AgentCard'
example:
did: "did:web:api.sentryagent.ai:agents:a1b2c3d4-e5f6-7890-abcd-ef1234567890"
name: "screener-001@sentryagent.ai"
agentType: "screener"
capabilities:
- "resume:read"
- "email:send"
- "candidate:score"
owner: "talent-acquisition-team"
version: "1.4.2"
deploymentEnv: "production"
identityProvider: "https://api.sentryagent.ai"
issuedAt: "2026-04-07T09:00:00.000Z"
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalServerError'