Validation Review API Contracts And Response Semantics
Canonical Contract Source
Validation review APIs are defined in /docs/architecture/specs/platform-api.openapi.yaml under the Validation tag.
Endpoint Matrix
| Route | OperationId | Success Code | Semantics |
|---|---|---|---|
POST /v2/validation-runs | createValidationRunV2 | 202 | Starts a validation run and returns queued/accepted run metadata. |
GET /v2/validation-runs/{runId} | getValidationRunV2 | 200 | Returns run status (queued, running, completed, failed) and final decision state. |
GET /v2/validation-runs/{runId}/artifact | getValidationRunArtifactV2 | 200 | Returns canonical artifact payload (validation_run or compact snapshot). |
POST /v2/validation-runs/{runId}/review | submitValidationRunReviewV2 | 202 | Accepts trader/agent review decision for the run. |
POST /v2/validation-runs/{runId}/render | createValidationRunRenderV2 | 202 | Queues optional HTML/PDF render generation from canonical JSON. |
POST /v2/validation-bots/registrations/invite-code | registerValidationBotInviteCodeV2 | 201 | Self-registers a user-owned bot through invite-code trial flow (rate-limited). |
POST /v2/validation-bots/registrations/partner-bootstrap | registerValidationBotPartnerBootstrapV2 | 201 | Self-registers a user-owned bot through partner key/secret bootstrap flow. |
POST /v2/validation-bots/{botId}/keys/rotate | rotateValidationBotKeyV2 | 201 | Rotates bot key and returns a newly issued raw key once. |
POST /v2/validation-bots/{botId}/keys/{keyId}/revoke | revokeValidationBotKeyV2 | 200 | Revokes a bot key metadata record without exposing raw key. |
GET /v2/validation-sharing/runs/{runId}/invites | listValidationRunInvitesV2 | 200 | Lists email invites for one run scope only. |
POST /v2/validation-sharing/runs/{runId}/invites | createValidationRunInviteV2 | 201 | Creates a run-level invite by email. |
POST /v2/validation-sharing/invites/{inviteId}/revoke | revokeValidationInviteV2 | 200 | Revokes an existing invite. |
POST /v2/validation-sharing/invites/{inviteId}/accept | acceptValidationInviteOnLoginV2 | 200 | Accepts invite and grants run-level share in Shared Validation flow. |
POST /v2/validation-baselines | createValidationBaselineV2 | 201 | Promotes an existing run as baseline for replay/regression checks. |
POST /v2/validation-regressions/replay | replayValidationRegressionV2 | 202 | Compares baseline vs candidate run and returns merge/release gate decisions. |
Canonical Artifact Semantics
validation_runJSON is authoritative for merge/release and audit.validation_llm_snapshotis a compact derivative for agent analysis.- Render artifacts (
html,pdf) are derived and must not replace canonical JSON records. finalDecisionuses contract enum values:pass,conditional_pass,fail.
Bot Onboarding Paths
- Invite-code trial path:
- route:
POST /v2/validation-bots/registrations/invite-code - request schema:
CreateBotInviteRegistrationRequest - required fields:
inviteCode,botName - includes
429response for rate-limit enforcement
- route:
- Partner bootstrap path:
- route:
POST /v2/validation-bots/registrations/partner-bootstrap - request schema:
CreateBotPartnerBootstrapRequest - required fields:
partnerKey,partnerSecret,ownerEmail,botName
- route:
- Both paths return
BotRegistrationResponsewith:botmetadata (ownerUserId,registrationPath)registrationaudit metadataissuedKey(including show-oncerawKey)
Key Lifecycle Semantics
- Create:
- initial bot registration response includes
issuedKey.rawKeyandissuedKey.key.
- initial bot registration response includes
- Show once:
BotIssuedApiKey.rawKeyis explicitly one-time return only.BotKeyMetadatanever exposesrawKey.
- Rotate:
- route:
POST /v2/validation-bots/{botId}/keys/rotate - returns fresh
issuedKey.rawKey+keymetadata.
- route:
- Revoke:
- route:
POST /v2/validation-bots/{botId}/keys/{keyId}/revoke - returns
BotKeyMetadataResponsewithstatus=revokedandrevokedAt.
- route:
Actor Linkage Model
- Actor type is explicit via
ValidationActorTypeenum:user | bot. ValidationRun.actorusesValidationRunActorMetadata(actorType,actorId, optionaluserId, optionalbotId,metadata).ValidationInvite.invitedByActorTypeuses same actor enum.- Bots are user-owned (
Bot.ownerUserId), and v2 has no brand model (brand/brandIdabsent by contract).
Run-Level Sharing Semantics
- Sharing scope is run-level only:
- all shared routes (invite lifecycle + shared review writes) are under
/v2/validation-sharing/....
- all shared routes (invite lifecycle + shared review writes) are under
- Permission model is canonicalized to
ValidationSharePermission = view | review:viewis read-only shared access.reviewpermits shared review writes throughPOST /v2/validation-sharing/runs/{runId}/review.
- Backward compatibility:
- legacy permission aliases (
comment,decide) normalize toreview.
- legacy permission aliases (
- Invite targeting is email-only:
CreateValidationInviteRequestrequiresemailand does not includeuserId.
- Invite lifecycle states:
pending,accepted,revoked,expired.
- Granted share lifecycle states:
active,revoked(ValidationRunShare).
- Invite acceptance:
AcceptValidationInviteRequestrequiresacceptedEmail.- response includes both updated
inviteand created/updatedshare.
Review Decision Semantics
reviewerTypeis constrained toagentortrader.decisionis constrained topass,conditional_pass, orfail.findingsare structured entries withpriority,confidence,summary, andevidenceRefs.- Trader review is policy-controlled (
requireTraderReview) and optional by profile.
Identity, Auth, and Request Correlation
- Global API auth uses bearer token or API key per OpenAPI security schemes.
- Bot self-registration routes declare
security: []and rely on invite-code or partner credentials in request payload/body. - Clients must not call provider services directly; integration flows stay on Platform API routes.
- User/tenant scope must be derived from authenticated session context, not caller-provided identity headers.
X-Request-Idis used for trace correlation across web proxy and Platform API.Idempotency-Keyshould be supplied for write calls (POST) to avoid duplicate effects.
Error and Retry Semantics
400indicates invalid payload or policy shape.401indicates missing/invalid auth context.404indicates unknown run/baseline resource.409indicates conflict (duplicate pending invite,already-revoked, or other state conflict cases).429is used by invite-code registration path for rate limiting.- Retrying write calls should reuse the same
Idempotency-Keyonly when payload is unchanged.
Governance Checks
Run these checks for contract and docs alignment:
npx --yes --package=@redocly/cli@1.34.5 redocly lint docs/architecture/specs/platform-api.openapi.yaml
pytest backend/tests/contracts/test_openapi_contract_v2_validation_freeze.py
pytest backend/tests/contracts/test_platform_api_v2_handlers.py
npm --prefix docs/portal-site run ci
Traceability
- Child issue: #313
- Parent issue: #310
- Validation web proxy auth:
/frontend/src/lib/validation/server/auth.ts - Validation web proxy transport:
/frontend/src/lib/validation/server/platform-api.ts - Contract governance:
/.github/workflows/contracts-governance.yml - Docs governance:
/.github/workflows/docs-governance.yml