{"openapi":"3.1.0","info":{"title":"QA.army Product API","version":"0.9.0","description":"Canonical QA.army REST contract. A Cognito access token, profile API key, or WorkOS Agent Registration access token proves the caller's profile; persisted Workspace membership authorizes every tenant-owned operation, and Run scope is derived server-side from test_id."},"servers":[{"url":"https://api.qa.army","description":"Production product API"}],"security":[{"productBearer":[]}],"paths":{"/v1/openapi.json":{"get":{"security":[],"operationId":"getOpenapiDocument","summary":"Read the public QA.army Product API contract","description":"Returns this canonical OpenAPI 3.1 document as JSON. No credential is accepted or required, and the response contains no customer data.","responses":{"200":{"description":"Canonical public OpenAPI document","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/v1/agent-auth/claim-attempts/link":{"post":{"security":[{"cognitoIdToken":[]}],"operationId":"linkAgentClaimAttempt","summary":"Link a WorkOS claim attempt to the signed-in QA.army profile","description":"Requires a verified email in a Cognito ID token. QA.army derives the profile server-side, sends the bounded attempt token only to the fixed WorkOS link operation, and stores only the returned registration ID. WorkOS organization data never selects a Workspace.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["claim_attempt_token"],"properties":{"claim_attempt_token":{"type":"string","pattern":"^cla_tkn_[A-Za-z0-9]{20,128}$"}}}}}},"responses":{"200":{"description":"The attempt is linked and its one-time user code can be shown on the authenticated claim page.","headers":{"Cache-Control":{"required":true,"schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["registration_id","user_code"],"properties":{"registration_id":{"type":"string","pattern":"^agent_reg_[A-Za-z0-9]{20,64}$"},"user_code":{"type":"string","pattern":"^[A-Z0-9]{4,8}(?:-[A-Z0-9]{4,8})?$"}}}}}},"400":{"$ref":"#/components/responses/ValidationFailed"},"401":{"description":"A valid Cognito ID token with a verified email is required.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}},"application/json":{"schema":{"$ref":"#/components/schemas/GatewayUnauthorized"}}}},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/session":{"get":{"operationId":"getSessionBootstrap","summary":"Resolve the authenticated user's product destination","description":"Lists the caller's persisted memberships server-side and selects their first Workspace, or sends a user with no membership to Workspace creation. The request accepts no Workspace selector.","responses":{"200":{"description":"Authenticated session bootstrap","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionBootstrap"}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/api-keys":{"get":{"security":[{"cognitoAccessToken":[]}],"operationId":"listProfileApiKeys","summary":"List the authenticated user's profile API keys","description":"Returns metadata only. API-key credentials cannot manage credentials.","responses":{"200":{"description":"Profile API-key metadata","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["api_keys"],"properties":{"api_keys":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/ApiKey"}}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}},"post":{"security":[{"cognitoAccessToken":[]}],"operationId":"createProfileApiKey","summary":"Create one profile API key","description":"Creates a user-owned key with no Workspace binding. The plaintext secret appears only in this response and cannot be retrieved later.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":80}}}}}},"responses":{"201":{"description":"Created key metadata and one-time plaintext secret","headers":{"Cache-Control":{"required":true,"schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["api_key","secret"],"properties":{"api_key":{"$ref":"#/components/schemas/ApiKey"},"secret":{"type":"string","pattern":"^qa_live_[a-f0-9]{32}_[A-Za-z0-9_-]{43}$"}}}}}},"400":{"$ref":"#/components/responses/ValidationFailed"},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"$ref":"#/components/responses/Conflict"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/api-keys/{apiKeyId}":{"parameters":[{"name":"apiKeyId","in":"path","required":true,"schema":{"type":"string","pattern":"^key_[a-f0-9]{32}$"}}],"delete":{"security":[{"cognitoAccessToken":[]}],"operationId":"revokeProfileApiKey","summary":"Revoke one profile API key owned by the authenticated user","responses":{"204":{"description":"Key is revoked"},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/workspaces":{"get":{"operationId":"listWorkspaces","summary":"List the caller's Workspaces","description":"Returns only Workspaces with a current persisted membership for the caller.","responses":{"200":{"description":"Membership-filtered Workspace list","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["workspaces"],"properties":{"workspaces":{"type":"array","items":{"$ref":"#/components/schemas/Workspace"}}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}},"post":{"operationId":"createWorkspace","summary":"Create a Workspace and owner membership","description":"Persists display_name on the authenticated QA.army user and creates the Workspace plus OWNER membership in one transaction.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorkspaceRequest"}}}},"responses":{"201":{"description":"Workspace, current user, and server-resolved dashboard destination","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorkspaceResponse"}}}},"400":{"$ref":"#/components/responses/ValidationFailed"},"401":{"$ref":"#/components/responses/Unauthenticated"},"409":{"$ref":"#/components/responses/Conflict"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/workspaces/{workspaceId}":{"parameters":[{"$ref":"#/components/parameters/WorkspaceId"}],"get":{"operationId":"getWorkspaceDashboard","summary":"Get the Workspace dashboard aggregate","description":"Verifies current membership from application state. A missing Workspace and a Workspace owned by another customer both return the same 404 shape.","responses":{"200":{"description":"Workspace details, deterministic free-plan usage, member count, and pending-invitation count","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceDashboard"}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}},"patch":{"operationId":"updateWorkspace","summary":"Update Workspace settings","description":"Requires an OWNER membership. Cross-Workspace requests return the same 404 as an unknown Workspace; a member of this Workspace without the OWNER role receives 403.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWorkspaceRequest"}}}},"responses":{"200":{"description":"Updated Workspace","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["workspace"],"properties":{"workspace":{"$ref":"#/components/schemas/Workspace"}}}}}},"400":{"$ref":"#/components/responses/ValidationFailed"},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/workspaces/{workspaceId}/projects":{"parameters":[{"$ref":"#/components/parameters/WorkspaceId"}],"get":{"operationId":"listProjects","summary":"List Project cards for a Workspace","description":"Returns only Projects derived from the selected Workspace after current membership is verified. Cross-Workspace and unknown selectors return 404.","responses":{"200":{"description":"Workspace Project list","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["projects"],"properties":{"projects":{"type":"array","items":{"$ref":"#/components/schemas/Project"}}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}},"post":{"operationId":"createProject","summary":"Create a web or mobile Project target","description":"Verifies current membership before creating the Project. Mobile requests persist an app name and optional validated .apk/.app.zip filename only; binary content and device configuration are not accepted.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequest"}}}},"responses":{"201":{"description":"Persisted Project target","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["project"],"properties":{"project":{"$ref":"#/components/schemas/Project"}}}}}},"400":{"$ref":"#/components/responses/ValidationFailed"},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/projects/{projectId}/star":{"parameters":[{"$ref":"#/components/parameters/ProjectId"}],"put":{"operationId":"starProject","summary":"Star a Project for the current user","description":"Adds this Project to the current user's first-row favorites. At most three Projects may be starred per user in a Workspace. Unknown and cross-Workspace Project selectors return the same 404 response.","responses":{"200":{"description":"Project star state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectStar"}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}},"delete":{"operationId":"unstarProject","summary":"Remove a Project from the current user's favorites","description":"Removes the current user's star after deriving Workspace scope from the persisted Project. Unknown and cross-Workspace Project selectors return the same 404 response.","responses":{"200":{"description":"Project star state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectStar"}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/workspaces/{workspaceId}/members":{"parameters":[{"$ref":"#/components/parameters/WorkspaceId"}],"get":{"operationId":"listWorkspaceMembers","summary":"List current Workspace members","description":"Requires current membership in the selected Workspace. Cross-Workspace and unknown selectors return the same 404 response.","responses":{"200":{"description":"Current members","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["members"],"properties":{"members":{"type":"array","items":{"$ref":"#/components/schemas/WorkspaceMember"}}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/workspaces/{workspaceId}/invitations":{"parameters":[{"$ref":"#/components/parameters/WorkspaceId"}],"post":{"operationId":"inviteWorkspaceMember","summary":"Persist and email a pending Workspace invitation","description":"Requires an OWNER membership. The invitation is persisted before one bounded email-delivery attempt. A 201 response means Amazon SES accepted every message for delivery and returns delivery_status SENT. Provider failures preserve the pending invitation and return 503 without automatically resending ambiguous attempts. Replaying the same Idempotency-Key never sends an accepted or ambiguous message twice. The request supports a batch of onboarding invitation email addresses. Cross-Workspace and unknown selectors return the same 404 response.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["emails"],"properties":{"emails":{"type":"array","minItems":1,"maxItems":20,"uniqueItems":true,"items":{"type":"string","format":"email","maxLength":254}}}}}}},"responses":{"201":{"description":"Persisted invitation whose email was accepted for delivery","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["invitations"],"properties":{"invitations":{"type":"array","items":{"$ref":"#/components/schemas/PendingInvitation"}}}}}}},"400":{"$ref":"#/components/responses/ValidationFailed"},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/projects/{projectId}/test-groups":{"parameters":[{"$ref":"#/components/parameters/ProjectId"}],"get":{"operationId":"listTestGroups","summary":"List Test Groups for an authorized Project","description":"Derives Workspace scope from the persisted Project and returns 404 for unknown or cross-Workspace Projects.","responses":{"200":{"description":"Project Test Groups","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["test_groups"],"properties":{"test_groups":{"type":"array","items":{"$ref":"#/components/schemas/TestGroup"}}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}},"post":{"operationId":"createTestGroup","summary":"Create a Test Group in an authorized Project","description":"Derives Workspace scope from the persisted Project; request bodies cannot select Workspace scope.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveTestGroupRequest"}}}},"responses":{"201":{"description":"Created Test Group","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["test_group"],"properties":{"test_group":{"$ref":"#/components/schemas/TestGroup"}}}}}},"400":{"$ref":"#/components/responses/ValidationFailed"},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/test-groups/{testGroupId}":{"parameters":[{"$ref":"#/components/parameters/TestGroupId"}],"get":{"operationId":"getTestGroup","summary":"Get one authorized Test Group","description":"Derives Project and Workspace scope from the persisted Test Group; cross-Workspace IDs return 404.","responses":{"200":{"description":"Test Group","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["test_group"],"properties":{"test_group":{"$ref":"#/components/schemas/TestGroup"}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}},"patch":{"operationId":"updateTestGroup","summary":"Update one authorized Test Group","description":"Requires the current version and derives all tenant scope from the stored Test Group.","parameters":[{"$ref":"#/components/parameters/IfMatch"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveTestGroupRequest"}}}},"responses":{"200":{"description":"Updated Test Group","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["test_group"],"properties":{"test_group":{"$ref":"#/components/schemas/TestGroup"}}}}}},"400":{"$ref":"#/components/responses/ValidationFailed"},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/projects/{projectId}/tests":{"parameters":[{"$ref":"#/components/parameters/ProjectId"}],"get":{"operationId":"listTests","summary":"List active Tests for an authorized Project","description":"Derives Workspace scope from the persisted Project and excludes archived Tests.","responses":{"200":{"description":"Project Tests","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["tests"],"properties":{"tests":{"type":"array","items":{"$ref":"#/components/schemas/TestSummary"}}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}},"post":{"operationId":"createTest","summary":"Create a Test and its ordered steps","description":"Derives Workspace scope from the persisted Project and verifies an optional group belongs to that Project.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveTestRequest"}}}},"responses":{"201":{"description":"Created Test","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["test"],"properties":{"test":{"$ref":"#/components/schemas/Test"}}}}}},"400":{"$ref":"#/components/responses/ValidationFailed"},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/projects/{projectId}/test-generations":{"parameters":[{"$ref":"#/components/parameters/ProjectId"}],"post":{"operationId":"createTestGeneration","summary":"Generate and persist one Test for an authorized Web Project","description":"Starts saved-test-first authoring. The server derives Workspace scope from the Project, performs bounded public-Web discovery, obtains a typed plan, validates it, and creates at most one ordinary Test. Provider failures may use a visibly identified deterministic fallback. This operation never creates a Run or invokes a browser.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTestGenerationRequest"}}}},"responses":{"202":{"description":"Accepted Test generation","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["test_generation"],"properties":{"test_generation":{"$ref":"#/components/schemas/TestGeneration"}}}}}},"400":{"$ref":"#/components/responses/ValidationFailed"},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/test-generations/{testGenerationId}":{"parameters":[{"$ref":"#/components/parameters/TestGenerationId"}],"get":{"operationId":"getTestGeneration","summary":"Get safe progress for one authorized Test generation","description":"Derives Project and Workspace scope from the stored TestGeneration. Cross-Workspace IDs return 404. Provider job identifiers, provider secrets, prompts, model reasoning, and raw discovery content are not exposed.","responses":{"200":{"description":"Test generation progress or terminal result","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["test_generation"],"properties":{"test_generation":{"$ref":"#/components/schemas/TestGeneration"}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/test-generations/{testGenerationId}/target-role":{"parameters":[{"$ref":"#/components/parameters/TestGenerationId"}],"put":{"operationId":"setTestGenerationTargetRole","deprecated":true,"summary":"Record legacy executive-role compatibility data","description":"Retained for older clients and persisted generations. Idempotently records one CEO, CMO, CTO, CPO, CIO, or CFO value without influencing the current prompt-driven planning call or saved Test. The server derives Project and Workspace scope from the stored TestGeneration. Cross-Workspace IDs return 404. A different value after the role is fixed returns conflict. This operation never creates a Run.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetTestGenerationTargetRoleRequest"}}}},"responses":{"200":{"description":"Target role accepted","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["test_generation"],"properties":{"test_generation":{"$ref":"#/components/schemas/TestGeneration"}}}}}},"400":{"$ref":"#/components/responses/ValidationFailed"},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/tests/{testId}":{"parameters":[{"$ref":"#/components/parameters/TestId"}],"get":{"operationId":"getTest","summary":"Get one authorized Test with ordered steps","description":"Derives Project and Workspace scope from the persisted Test; cross-Workspace IDs return 404.","responses":{"200":{"description":"Test detail","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["test"],"properties":{"test":{"$ref":"#/components/schemas/Test"}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}},"put":{"operationId":"updateTest","summary":"Replace a Test specification and ordered steps","description":"Requires the current version; stored relationships determine Project and Workspace authority.","parameters":[{"$ref":"#/components/parameters/IfMatch"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveTestRequest"}}}},"responses":{"200":{"description":"Updated Test","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["test"],"properties":{"test":{"$ref":"#/components/schemas/Test"}}}}}},"400":{"$ref":"#/components/responses/ValidationFailed"},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}},"delete":{"operationId":"archiveTest","summary":"Archive one authorized Test","description":"Soft-deletes the Test using its current version; future Run history can retain references.","parameters":[{"$ref":"#/components/parameters/IfMatch"}],"responses":{"204":{"description":"Test archived"},"400":{"$ref":"#/components/responses/ValidationFailed"},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/projects/{projectId}/integrations":{"parameters":[{"$ref":"#/components/parameters/ProjectId"}],"get":{"security":[{"cognitoAccessToken":[]}],"operationId":"listProjectIntegrations","summary":"List safe connection lifecycle for an authorized Project","description":"Derives Workspace authority from the persisted Project. Nango tags, environment labels, and connection IDs are not authorization and are not returned.","responses":{"200":{"description":"Project integrations","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["integrations"],"properties":{"integrations":{"type":"array","items":{"$ref":"#/components/schemas/ProjectIntegration"}}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/projects/{projectId}/integration-connect-sessions":{"parameters":[{"$ref":"#/components/parameters/ProjectId"}],"post":{"security":[{"cognitoAccessToken":[]}],"operationId":"createIntegrationConnectSession","summary":"Create a short-lived Connect session for an allowed provider","description":"Derives Workspace scope from the persisted Project, creates or reuses one QA.army-owned ProjectIntegration, and asks the replaceable adapter for one exact allowed integration. Caller-supplied connection IDs, integration keys, tags, endpoints, and Workspace IDs are rejected.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIntegrationConnectSessionRequest"}}}},"responses":{"201":{"description":"Short-lived Connect session; the token must remain ephemeral","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntegrationConnectSessionResponse"}}}},"400":{"$ref":"#/components/responses/ValidationFailed"},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/integrations/{integrationId}":{"parameters":[{"$ref":"#/components/parameters/IntegrationId"}],"get":{"security":[{"cognitoAccessToken":[]}],"operationId":"getProjectIntegration","summary":"Get safe lifecycle for one authorized ProjectIntegration","description":"Derives Project and Workspace scope from the stored integration; cross-Workspace IDs return 404.","responses":{"200":{"description":"Safe integration lifecycle","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["integration"],"properties":{"integration":{"$ref":"#/components/schemas/ProjectIntegration"}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}},"delete":{"security":[{"cognitoAccessToken":[]}],"operationId":"disconnectProjectIntegration","summary":"Idempotently remove QA.army's provider-connection mapping","description":"Clears only QA.army's opaque mapping. It does not call Nango connection deletion and does not claim provider credential revocation.","responses":{"204":{"description":"QA.army mapping absent; provider revocation is not asserted"},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/integrations/{integrationId}/reconnect-session":{"parameters":[{"$ref":"#/components/parameters/IntegrationId"}],"post":{"security":[{"cognitoAccessToken":[]}],"operationId":"reconnectProjectIntegration","summary":"Create a short-lived reconnect session","description":"Derives the exact opaque provider connection and integration key from the stored ProjectIntegration and preserves its QA.army-owned identity.","responses":{"201":{"description":"Short-lived reconnect session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntegrationConnectSessionResponse"}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/integration-connect-sessions/{connectSessionId}/cancel":{"parameters":[{"$ref":"#/components/parameters/ConnectSessionId"}],"post":{"security":[{"cognitoAccessToken":[]}],"operationId":"cancelIntegrationConnectSession","summary":"Cancel a pending local Connect attempt","description":"Derives integration, Project, and Workspace scope from the stored attempt. Cancellation is idempotent and causes later lifecycle webhooks for that attempt to fail closed.","responses":{"204":{"description":"Connect attempt cancelled or already cancelled"},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/webhooks/nango":{"post":{"security":[],"operationId":"receiveNangoLifecycleWebhook","summary":"Receive one raw-body authenticated Nango lifecycle webhook","description":"Requires application/json within the strict byte limit and validates X-Nango-Hmac-Sha256 over the exact raw body. The legacy plain signature is never accepted as authority. Processing is idempotent and transactional; no event can create a Run or write memory.","parameters":[{"name":"X-Nango-Hmac-Sha256","in":"header","required":true,"schema":{"type":"string","pattern":"^[a-fA-F0-9]{64}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"202":{"description":"Authenticated delivery accepted or safely ignored","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["accepted","duplicate"],"properties":{"accepted":{"const":true},"duplicate":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/ValidationFailed"},"401":{"$ref":"#/components/responses/WebhookAuthenticationFailed"},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"415":{"$ref":"#/components/responses/UnsupportedMediaType"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/runs":{"get":{"operationId":"listRuns","summary":"List persistent Run history for one authorized Test","description":"Returns newest-first Run receipts for a saved Test after resolving Workspace membership server-side. Unknown and cross-Workspace Tests return 404.","parameters":[{"name":"test_id","in":"query","required":true,"schema":{"type":"string","pattern":"^tst_[a-f0-9]{32}$"}},{"name":"before","in":"query","required":false,"schema":{"type":"string","pattern":"^[A-Za-z0-9_-]+$","maxLength":256}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50,"default":20}}],"responses":{"200":{"description":"Persistent newest-first Run history","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["runs","next_before"],"properties":{"runs":{"type":"array","maxItems":50,"items":{"$ref":"#/components/schemas/Run"}},"next_before":{"type":["string","null"],"minLength":1,"maxLength":256,"pattern":"^[A-Za-z0-9_-]+$"}}}}}},"400":{"$ref":"#/components/responses/ValidationFailed"},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}},"post":{"operationId":"createRun","summary":"Create a READY Run from one authorized Test","description":"Accepts only test_id. QA.army resolves Test, optional Test Group, Project, Workspace, membership, target, policy, and credential handles server-side, then persists an immutable hashed RunContext before returning READY.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRunRequest"}}}},"responses":{"201":{"description":"Run context resolved and persisted","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["run"],"properties":{"run":{"$ref":"#/components/schemas/Run"}}}}}},"400":{"$ref":"#/components/responses/ValidationFailed"},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/runs/{runId}":{"parameters":[{"$ref":"#/components/parameters/RunId"}],"get":{"operationId":"getRun","summary":"Get one authorized Run","description":"Returns 404 for unknown or cross-Workspace Runs. The immutable RunContext, secret handles, storage locations, and infrastructure identifiers are not public.","responses":{"200":{"description":"Safe Run status and resolved scope","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["run"],"properties":{"run":{"$ref":"#/components/schemas/Run"}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/runs/{runId}/start":{"parameters":[{"$ref":"#/components/parameters/RunId"}],"post":{"operationId":"startRun","summary":"Start one READY Run in one isolated AgentCore session with one bound Hyperbrowser session","description":"Atomically queues the Run once and dispatches the dedicated control-plane executor, which directly invokes the server-bound Harness without SQS or Fargate. Phase 3 binds one server-configured Hyperbrowser Chrome session whose first page is the deterministic QA.army /loading gate. The caller cannot select a Harness, Runtime, browser provider, session, model, tools, skills, prompt, memory scope, target allowlist, or execution limit.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"202":{"description":"Execution dispatch accepted or idempotently replayed","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["run"],"properties":{"run":{"$ref":"#/components/schemas/Run"}}}}}},"400":{"$ref":"#/components/responses/ValidationFailed"},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/runs/{runId}/events":{"parameters":[{"$ref":"#/components/parameters/RunId"}],"get":{"operationId":"watchRun","summary":"Read normalized Run events after a scan cursor","description":"Phase 2 clients may request application/json for immutable v1 lifecycle rows. Phase 3 clients request application/vnd.venkat.run-events.v2+json for the normalized canonical ledger. Raw AgentCore events, tool arguments, session identifiers, evidence locations, and capabilities remain internal.","parameters":[{"name":"after","in":"query","required":false,"schema":{"type":"integer","minimum":0,"maximum":1000000000,"default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":500,"default":100}}],"responses":{"200":{"description":"Ordered state-event batch and current safe Run status","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["run","events","next_after","terminal"],"properties":{"run":{"$ref":"#/components/schemas/Run"},"events":{"type":"array","items":{"$ref":"#/components/schemas/RunEvent"}},"next_after":{"type":"integer","minimum":0,"maximum":10000},"terminal":{"type":"boolean"}}}},"application/vnd.venkat.run-events.v2+json":{"schema":{"$ref":"#/components/schemas/RunEventPageV2"}}}},"400":{"$ref":"#/components/responses/ValidationFailed"},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/runs/{runId}/cancel":{"parameters":[{"$ref":"#/components/parameters/RunId"}],"post":{"operationId":"cancelRun","summary":"Request cancellation and stop the active isolated session","description":"Preserves the durable Run and captured evidence. A running session is stopped with its server-owned identifier; terminal product outcomes cannot be cancelled.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"202":{"description":"Cancellation dispatch accepted or idempotently replayed","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["run"],"properties":{"run":{"$ref":"#/components/schemas/Run"}}}}}},"400":{"$ref":"#/components/responses/ValidationFailed"},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/runs/{runId}/live-view-capability":{"parameters":[{"$ref":"#/components/parameters/RunId"}],"post":{"operationId":"openRunLiveView","summary":"Issue a short-lived view-only Live View capability for one active Run","description":"Reauthorizes the caller through Aurora and returns a short-lived Hyperbrowser Live View URL only while the Run owns an active Browser binding. The URL is a credential-bearing capability: it is never persisted in Run state or evidence, and callers must discard it when the Run becomes terminal. Unknown, cross-Workspace, expired, inactive, and non-Hyperbrowser bindings return 404.","responses":{"200":{"description":"Ephemeral view-only Live View capability. Cache-Control: no-store, Pragma: no-cache, and Referrer-Policy: no-referrer are mandatory on every successful response because the URL is a bearer capability.","headers":{"Cache-Control":{"required":true,"schema":{"type":"string","const":"no-store"}},"Pragma":{"required":true,"schema":{"type":"string","const":"no-cache"}},"Referrer-Policy":{"required":true,"schema":{"type":"string","const":"no-referrer"}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["live_view"],"properties":{"live_view":{"$ref":"#/components/schemas/LiveViewCapability"}}}}}},"400":{"$ref":"#/components/responses/ValidationFailed"},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/runs/{runId}/evidence":{"parameters":[{"$ref":"#/components/parameters/RunId"}],"get":{"operationId":"listRunEvidence","summary":"List finalized evidence metadata for one authorized terminal Run","description":"Returns stable evidence IDs and integrity metadata only after finalization. A replay is authoritative native full-Chrome video (video/mp4 or video/webm), including Chrome tabs, address bar, toolbar, and page pixels. RRWeb and other page-only representations do not satisfy the replay type. Replay artifacts are ordered by attempt and replay_part; replay_part is contiguous from one within each finalized attempt. Storage keys, Browser identifiers, sessions, and access capabilities are omitted.","responses":{"200":{"description":"Authorized finalized evidence catalog","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["evidence"],"properties":{"evidence":{"type":"array","maxItems":512,"items":{"$ref":"#/components/schemas/EvidenceArtifact"}}}}}}},"400":{"$ref":"#/components/responses/ValidationFailed"},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}},"/v1/evidence/{evidenceId}/open":{"parameters":[{"name":"evidenceId","in":"path","required":true,"schema":{"type":"string","pattern":"^evd_[a-f0-9]{32}$"}}],"post":{"operationId":"openEvidence","summary":"Issue short-lived read access to one authorized finalized artifact","description":"Reauthorizes the caller through Aurora and returns a short-lived HTTPS capability. The capability is never persisted in Run state or evidence metadata.","responses":{"200":{"description":"Short-lived artifact-open capability","headers":{"Cache-Control":{"schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["evidence","capability"],"properties":{"evidence":{"$ref":"#/components/schemas/EvidenceArtifact"},"capability":{"type":"object","additionalProperties":false,"required":["url","expires_at"],"properties":{"url":{"type":"string","format":"uri","pattern":"^https://"},"expires_at":{"type":"string","format":"date-time"}}}}}}}},"400":{"$ref":"#/components/responses/ValidationFailed"},"401":{"$ref":"#/components/responses/Unauthenticated"},"404":{"$ref":"#/components/responses/NotFound"},"503":{"$ref":"#/components/responses/DependencyUnavailable"}}}}},"components":{"securitySchemes":{"productBearer":{"type":"http","scheme":"bearer","description":"A Cognito access token, profile API key, or WorkOS Agent Registration access token. Profile keys use the qa_live_ prefix. A WorkOS token must use the exact QA.army issuer and audience, contain an active linked registration and qa:setup scope, and is limited to the operations below. Every bearer inherits only the linked user's current persisted Workspace memberships; WorkOS organization claims are ignored.","x-qa-army-agent-authorization":{"required_scope":"qa:setup","allowed_operations":["getSessionBootstrap","listWorkspaces","createWorkspace","listProjects","createProject","listTests","createTest","createTestGeneration","getTestGeneration","getTest","listRuns","createRun","getRun","startRun","watchRun","listRunEvidence","openEvidence"],"excluded_surfaces":["profile API-key management","agent claim linking","Nango credential routes","Workspace update, members, and invitations","Test Group management","Test edit and archive","Legacy Test-generation target-role mutation","Run cancellation and Live View"],"capability_denial":"This agent credential is limited to setup. Use an authenticated QA.army user session for this operation.","scope_denial":"Exchange the claimed agent credential for a token containing the qa:setup scope, then retry this request once.","identity_link_denial":"This agent registration is not linked to an active QA.army user. Restart the claim-link ceremony; re-exchanging the same assertion will not repair it."}},"cognitoAccessToken":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Amazon Cognito access token validated by the product API. Membership is resolved from Aurora and never from caller-provided claims or Cognito groups."},"cognitoIdToken":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Amazon Cognito ID token used only by the authenticated agent-claim page. The route requires token_use=id plus a verified email and derives the QA.army profile server-side."}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":true,"description":"Stable client-generated key for this mutation. Reusing a key with the same request replays the original response; a different request returns 409.","schema":{"type":"string","minLength":1,"maxLength":128,"pattern":"^[A-Za-z0-9._:-]+$"}},"WorkspaceId":{"name":"workspaceId","in":"path","required":true,"description":"Stable Workspace selector. It is never sufficient authority by itself.","schema":{"type":"string","pattern":"^wsp_[a-f0-9]{32}$"}},"ProjectId":{"name":"projectId","in":"path","required":true,"description":"Stable Project selector; Workspace membership is derived from its stored parent.","schema":{"type":"string","pattern":"^prj_[a-f0-9]{32}$"}},"TestGroupId":{"name":"testGroupId","in":"path","required":true,"description":"Stable Test Group selector; Project and Workspace scope are server-derived.","schema":{"type":"string","pattern":"^tgr_[a-f0-9]{32}$"}},"TestId":{"name":"testId","in":"path","required":true,"description":"Stable Test selector; Project and Workspace scope are server-derived.","schema":{"type":"string","pattern":"^tst_[a-f0-9]{32}$"}},"RunId":{"name":"runId","in":"path","required":true,"description":"Stable Run selector; Workspace authority is derived from the persisted Run.","schema":{"type":"string","pattern":"^run_[a-f0-9]{32}$"}},"TestGenerationId":{"name":"testGenerationId","in":"path","required":true,"description":"Stable TestGeneration selector; Project and Workspace scope are server-derived.","schema":{"type":"string","pattern":"^tgn_[a-f0-9]{32}$"}},"IntegrationId":{"name":"integrationId","in":"path","required":true,"description":"Stable QA.army-owned integration selector; Project and Workspace scope are server-derived.","schema":{"type":"string","pattern":"^int_[a-f0-9]{32}$"}},"ConnectSessionId":{"name":"connectSessionId","in":"path","required":true,"description":"Stable QA.army-owned Connect-attempt selector; integration, Project, and Workspace scope are server-derived.","schema":{"type":"string","pattern":"^ics_[a-f0-9]{32}$"}},"IfMatch":{"name":"If-Match","in":"header","required":true,"description":"Current positive integer resource version used to prevent lost updates.","schema":{"type":"string","pattern":"^(?:W/)?\"?[1-9][0-9]*\"?$"}}},"responses":{"Unauthenticated":{"description":"The request does not contain a cryptographically valid, unexpired accepted bearer. An agent should exchange its stored assertion or refresh credential for a fresh WorkOS access token and retry once; it must never automatically replay an ambiguous mutation.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}},"application/json":{"schema":{"$ref":"#/components/schemas/GatewayUnauthorized"}}}},"WebhookAuthenticationFailed":{"description":"The Nango raw-body HMAC is missing or invalid.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"Forbidden":{"description":"The authenticated Workspace member lacks the required role, or an agent credential lacks the route capability, qa:setup scope, or active identity link. Follow the stable remediation in the problem title; never broaden scope or retry a possibly mutating request silently.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"NotFound":{"description":"The selected resource is unknown or is outside the caller's Workspace memberships.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"ValidationFailed":{"description":"The request body is invalid.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"Conflict":{"description":"The requested mutation conflicts with current state or a uniqueness constraint.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"DependencyUnavailable":{"description":"A required persistence or provider dependency is temporarily unavailable.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"PayloadTooLarge":{"description":"The raw request body exceeds the endpoint's byte limit.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"UnsupportedMediaType":{"description":"The endpoint requires application/json.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}},"schemas":{"ApiKey":{"type":"object","additionalProperties":false,"required":["id","name","prefix","last_four","created_at","last_used_at","revoked_at"],"properties":{"id":{"type":"string","pattern":"^key_[a-f0-9]{32}$"},"name":{"type":"string","minLength":1,"maxLength":80},"prefix":{"type":"string","pattern":"^qa_live_[a-f0-9]{8}$"},"last_four":{"type":"string","pattern":"^[A-Za-z0-9_-]{4}$"},"created_at":{"type":"string","format":"date-time"},"last_used_at":{"type":["string","null"],"format":"date-time"},"revoked_at":{"type":["string","null"],"format":"date-time"}}},"ProjectIntegration":{"type":"object","additionalProperties":false,"required":["id","project_id","provider","status","provenance","connected_at","updated_at"],"properties":{"id":{"type":"string","pattern":"^int_[a-f0-9]{32}$"},"project_id":{"type":"string","pattern":"^prj_[a-f0-9]{32}$"},"provider":{"enum":["github"]},"status":{"enum":["disconnected","pending","connected","reauthorization_required"]},"provenance":{"const":"nango_cloud"},"connected_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"CreateIntegrationConnectSessionRequest":{"type":"object","additionalProperties":false,"required":["provider"],"properties":{"provider":{"enum":["github"]}}},"IntegrationConnectSessionResponse":{"type":"object","additionalProperties":false,"required":["integration","connect_session"],"properties":{"integration":{"$ref":"#/components/schemas/ProjectIntegration"},"connect_session":{"type":"object","additionalProperties":false,"required":["id","token","expires_at"],"properties":{"id":{"type":"string","pattern":"^ics_[a-f0-9]{32}$"},"token":{"type":"string","minLength":1,"maxLength":4096},"expires_at":{"type":"string","format":"date-time"}}}}},"SessionBootstrap":{"type":"object","additionalProperties":false,"required":["user","destination"],"properties":{"user":{"$ref":"#/components/schemas/SessionUser"},"destination":{"oneOf":[{"$ref":"#/components/schemas/CreateWorkspaceDestination"},{"$ref":"#/components/schemas/WorkspaceDestination"}],"discriminator":{"propertyName":"kind"}}}},"SessionUser":{"type":"object","additionalProperties":false,"required":["id","display_name","email"],"properties":{"id":{"type":"string","pattern":"^usr_[a-f0-9]{32}$"},"display_name":{"type":["string","null"],"maxLength":80},"email":{"type":["string","null"],"format":"email"}}},"CreateWorkspaceDestination":{"type":"object","additionalProperties":false,"required":["kind","path"],"properties":{"kind":{"const":"create_workspace"},"path":{"const":"/onboarding/workspace"}}},"WorkspaceDestination":{"type":"object","additionalProperties":false,"required":["kind","workspace_id","workspace_slug","path"],"properties":{"kind":{"const":"workspace"},"workspace_id":{"type":"string","pattern":"^wsp_[a-f0-9]{32}$"},"workspace_slug":{"$ref":"#/components/schemas/WorkspaceSlug"},"path":{"type":"string","pattern":"^/dashboard/[a-z0-9]+(?:-[a-z0-9]+)*/projects$"}}},"CreateWorkspaceRequest":{"type":"object","additionalProperties":false,"required":["display_name","name","slug"],"properties":{"display_name":{"type":"string","minLength":1,"maxLength":80},"name":{"type":"string","minLength":1,"maxLength":80},"slug":{"$ref":"#/components/schemas/WorkspaceSlug"},"avatar_url":{"type":["string","null"],"format":"uri"}}},"UpdateWorkspaceRequest":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"name":{"type":"string","minLength":1,"maxLength":80},"slug":{"$ref":"#/components/schemas/WorkspaceSlug"},"avatar_url":{"type":["string","null"],"format":"uri"}}},"CreateWorkspaceResponse":{"type":"object","additionalProperties":false,"required":["workspace","current_user","destination"],"properties":{"workspace":{"$ref":"#/components/schemas/Workspace"},"current_user":{"type":"object","additionalProperties":false,"required":["id","display_name"],"properties":{"id":{"type":"string"},"display_name":{"type":"string"}}},"destination":{"$ref":"#/components/schemas/WorkspaceDestination"}}},"WorkspaceSlug":{"type":"string","minLength":3,"maxLength":48,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"Workspace":{"type":"object","additionalProperties":false,"required":["id","name","slug","role","avatar_url","created_at","updated_at"],"properties":{"id":{"type":"string","pattern":"^wsp_[a-f0-9]{32}$"},"name":{"type":"string"},"slug":{"$ref":"#/components/schemas/WorkspaceSlug"},"role":{"type":"string","enum":["owner","member"]},"avatar_url":{"type":["string","null"],"format":"uri"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"WorkspaceDashboard":{"type":"object","additionalProperties":false,"required":["workspace","usage","member_count","pending_invitations"],"properties":{"workspace":{"$ref":"#/components/schemas/Workspace"},"usage":{"$ref":"#/components/schemas/Usage"},"member_count":{"type":"integer","minimum":1},"pending_invitations":{"type":"integer","minimum":0}}},"Usage":{"type":"object","additionalProperties":false,"required":["plan_name","runs_consumed","runs_remaining","resets_at"],"properties":{"plan_name":{"const":"Free"},"runs_consumed":{"const":0},"runs_remaining":{"const":100},"resets_at":{"type":"string","format":"date-time"}}},"WorkspaceMember":{"type":"object","additionalProperties":false,"required":["id","email","display_name","role","status"],"properties":{"id":{"type":"string"},"email":{"type":["string","null"],"format":"email"},"display_name":{"type":["string","null"]},"role":{"type":"string","enum":["owner","member"]},"status":{"const":"active"}}},"PendingInvitation":{"type":"object","additionalProperties":false,"required":["id","email","role","status","delivery_status","created_at"],"properties":{"id":{"type":"string"},"email":{"type":"string","format":"email"},"role":{"const":"member"},"status":{"const":"pending"},"delivery_status":{"const":"SENT","description":"Amazon SES accepted the invitation message for delivery."},"created_at":{"type":"string","format":"date-time"}}},"CreateProjectRequest":{"oneOf":[{"$ref":"#/components/schemas/CreateWebProjectRequest"},{"$ref":"#/components/schemas/CreateMobileProjectRequest"}],"discriminator":{"propertyName":"type"}},"CreateWebProjectRequest":{"type":"object","additionalProperties":false,"required":["name","type","target"],"properties":{"name":{"type":"string","minLength":1,"maxLength":100},"description":{"type":["string","null"],"maxLength":1000},"type":{"const":"web"},"target":{"$ref":"#/components/schemas/WebTarget"}}},"CreateMobileProjectRequest":{"type":"object","additionalProperties":false,"required":["name","type","target"],"properties":{"name":{"type":"string","minLength":1,"maxLength":100},"description":{"type":["string","null"],"maxLength":1000},"type":{"const":"mobile"},"target":{"$ref":"#/components/schemas/MobileTarget"}}},"WebTarget":{"type":"object","additionalProperties":false,"required":["url"],"properties":{"url":{"type":"string","format":"uri","pattern":"^https?://"}}},"MobileTarget":{"type":"object","additionalProperties":false,"required":["app_name"],"properties":{"app_name":{"type":"string","minLength":1,"maxLength":100},"binary_filename":{"type":["string","null"],"maxLength":255,"pattern":"^.+(?:\\.apk|\\.app\\.zip)$"}}},"Project":{"type":"object","additionalProperties":false,"required":["id","workspace_id","name","description","type","target_label","project_dashboard_url","test_count","starred","created_at","updated_at"],"properties":{"id":{"type":"string"},"workspace_id":{"type":"string"},"name":{"type":"string"},"description":{"type":["string","null"]},"type":{"type":"string","enum":["web","mobile"]},"target_label":{"type":"string"},"project_dashboard_url":{"type":"string","format":"uri","pattern":"^https://app\\.qa\\.army/dashboard/[a-z0-9-]+/projects/prj_[a-f0-9]{32}/tests$","description":"Server-owned absolute dashboard URL for this Project; clients must not synthesize frontend paths."},"test_count":{"type":"integer","minimum":0},"starred":{"type":"boolean","description":"Whether the current authenticated user starred this Project."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"ProjectStar":{"type":"object","additionalProperties":false,"required":["project_id","starred"],"properties":{"project_id":{"type":"string","pattern":"^prj_[a-f0-9]{32}$"},"starred":{"type":"boolean"}}},"CreateTestGenerationRequest":{"type":"object","additionalProperties":false,"properties":{"brief":{"type":["string","null"],"maxLength":2000}}},"SetTestGenerationTargetRoleRequest":{"type":"object","additionalProperties":false,"required":["target_role"],"properties":{"target_role":{"type":"string","enum":["CEO","CMO","CTO","CPO","CIO","CFO"]}}},"TestGeneration":{"type":"object","additionalProperties":false,"required":["id","project_id","status","target_role","generation_mode","test_id","warning_code","error_code","source_count","events","prompt_to_test_latency_ms","created_at","updated_at","completed_at"],"properties":{"id":{"type":"string","pattern":"^tgn_[a-f0-9]{32}$"},"project_id":{"type":"string","pattern":"^prj_[a-f0-9]{32}$"},"status":{"type":"string","enum":["QUEUED","DISCOVERING","PLANNING","VALIDATING","READY","FAILED"]},"target_role":{"type":["string","null"],"enum":["CEO","CMO","CTO","CPO","CIO","CFO",null]},"generation_mode":{"type":["string","null"],"enum":["FIRECRAWL_BEDROCK","FIRECRAWL_CLAUDE_FAST","DETERMINISTIC_FALLBACK",null]},"test_id":{"type":["string","null"],"pattern":"^tst_[a-f0-9]{32}$"},"warning_code":{"type":["string","null"],"enum":["DISCOVERY_PARTIAL","DISCOVERY_UNAVAILABLE","PLANNING_UNAVAILABLE",null],"description":"Stable, provider-safe stage result. DISCOVERY_UNAVAILABLE means bounded public-page discovery could not supply planning input; PLANNING_UNAVAILABLE means Test planning could not produce a usable draft. Either unavailable code may accompany the explicit deterministic homepage fallback and never implies that a Run occurred."},"error_code":{"type":["string","null"],"maxLength":100},"source_count":{"type":"integer","minimum":0,"maximum":5},"events":{"type":"array","description":"Append-only, ordered preparation timeline. Provider payloads and internal diagnostics are never exposed.","items":{"$ref":"#/components/schemas/TestGenerationProgressEvent"}},"prompt_to_test_latency_ms":{"type":["integer","null"],"minimum":0,"description":"Server-owned end-to-end latency from acceptance of the create-Test prompt to READY or FAILED. Null while generation is non-terminal. Includes dispatch queueing, discovery, planning, deterministic validation, and the atomic Test save."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"completed_at":{"type":["string","null"],"format":"date-time"}}},"TestGenerationProgressEvent":{"type":"object","additionalProperties":false,"required":["sequence","phase","kind","occurred_at"],"properties":{"sequence":{"type":"integer","minimum":1},"phase":{"type":"string","enum":["QUEUED","DISCOVERING","PLANNING","VALIDATING","READY","FAILED"]},"kind":{"type":"string","enum":["GENERATION_QUEUED","FOCUS_AREA_CAPTURED","DISCOVERY_STARTED","DISCOVERY_HEARTBEAT","PLANNING_STARTED","PLANNING_HEARTBEAT","VALIDATION_STARTED","VALIDATION_HEARTBEAT","FALLBACK_STARTED","GENERATION_READY","GENERATION_FAILED"]},"occurred_at":{"type":"string","format":"date-time"}}},"SaveTestGroupRequest":{"type":"object","additionalProperties":false,"required":["name","description"],"properties":{"name":{"type":"string","minLength":1,"maxLength":100},"description":{"type":["string","null"],"maxLength":1000}}},"TestGroup":{"type":"object","additionalProperties":false,"required":["id","project_id","name","description","version","test_count","created_at","updated_at"],"properties":{"id":{"type":"string","pattern":"^tgr_[a-f0-9]{32}$"},"project_id":{"type":"string","pattern":"^prj_[a-f0-9]{32}$"},"name":{"type":"string"},"description":{"type":["string","null"]},"version":{"type":"integer","minimum":1},"test_count":{"type":"integer","minimum":0},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"SaveTestRequest":{"type":"object","additionalProperties":false,"required":["name","description","group_id","enabled","allow_web_search","deep_thinking","location_override","viewport","device_name","steps"],"properties":{"name":{"type":"string","minLength":1,"maxLength":100},"description":{"type":["string","null"],"maxLength":1000},"group_id":{"type":["string","null"],"pattern":"^tgr_[a-f0-9]{32}$"},"enabled":{"type":"boolean"},"allow_web_search":{"type":"boolean"},"deep_thinking":{"type":"boolean"},"location_override":{"type":["string","null"],"maxLength":100},"viewport":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Viewport"}]},"device_name":{"type":["string","null"],"maxLength":100},"steps":{"type":"array","minItems":1,"maxItems":50,"items":{"$ref":"#/components/schemas/SaveTestStep"}}}},"Viewport":{"type":"object","additionalProperties":false,"required":["width","height"],"properties":{"width":{"type":"integer","minimum":320,"maximum":3840},"height":{"type":"integer","minimum":320,"maximum":2160}}},"SaveTestStep":{"type":"object","additionalProperties":false,"required":["type","instruction","enabled"],"properties":{"type":{"type":"string","enum":["act","assert","login","files","screenshot","javascript","microphone"]},"instruction":{"type":"string","minLength":1,"maxLength":10000},"enabled":{"type":"boolean"}}},"TestStep":{"type":"object","additionalProperties":false,"required":["id","position","type","instruction","enabled"],"properties":{"id":{"type":"string","pattern":"^stp_[a-f0-9]{32}$"},"position":{"type":"integer","minimum":0,"maximum":49},"type":{"type":"string","enum":["act","assert","login","files","screenshot","javascript","microphone"]},"instruction":{"type":"string","minLength":1,"maxLength":10000},"enabled":{"type":"boolean"}}},"TestSummary":{"type":"object","additionalProperties":false,"required":["id","project_id","group_id","name","description","enabled","allow_web_search","deep_thinking","location_override","viewport","device_name","version","step_count","created_at","updated_at"],"properties":{"id":{"type":"string","pattern":"^tst_[a-f0-9]{32}$"},"project_id":{"type":"string","pattern":"^prj_[a-f0-9]{32}$"},"group_id":{"type":["string","null"],"pattern":"^tgr_[a-f0-9]{32}$"},"name":{"type":"string"},"description":{"type":["string","null"]},"enabled":{"type":"boolean"},"allow_web_search":{"type":"boolean"},"deep_thinking":{"type":"boolean"},"location_override":{"type":["string","null"]},"viewport":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Viewport"}]},"device_name":{"type":["string","null"]},"version":{"type":"integer","minimum":1},"step_count":{"type":"integer","minimum":1,"maximum":50},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"Test":{"type":"object","additionalProperties":false,"required":["id","project_id","group_id","name","description","enabled","allow_web_search","deep_thinking","location_override","viewport","device_name","version","step_count","created_at","updated_at","steps"],"properties":{"id":{"type":"string","pattern":"^tst_[a-f0-9]{32}$"},"project_id":{"type":"string","pattern":"^prj_[a-f0-9]{32}$"},"group_id":{"type":["string","null"],"pattern":"^tgr_[a-f0-9]{32}$"},"name":{"type":"string"},"description":{"type":["string","null"]},"enabled":{"type":"boolean"},"allow_web_search":{"type":"boolean"},"deep_thinking":{"type":"boolean"},"location_override":{"type":["string","null"]},"viewport":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Viewport"}]},"device_name":{"type":["string","null"]},"version":{"type":"integer","minimum":1},"step_count":{"type":"integer","minimum":1,"maximum":50},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"steps":{"type":"array","minItems":1,"maxItems":50,"items":{"$ref":"#/components/schemas/TestStep"}}}},"CreateRunRequest":{"type":"object","additionalProperties":false,"required":["test_id"],"properties":{"test_id":{"type":"string","pattern":"^tst_[a-f0-9]{32}$"}}},"Run":{"type":"object","additionalProperties":false,"required":["id","status","workspace_id","project_id","test_group_id","test_id","trigger","triggered_by","context_schema_version","context_hash","cancellation_requested_at","completed_at","outcome_summary","resolved_at","created_at","updated_at"],"properties":{"id":{"type":"string","pattern":"^run_[a-f0-9]{32}$"},"status":{"enum":["READY","QUEUED","PROVISIONING","RUNNING","PASSED","FAILED","ERROR","CANCELLED"]},"workspace_id":{"type":"string","pattern":"^wsp_[a-f0-9]{32}$"},"project_id":{"type":"string","pattern":"^prj_[a-f0-9]{32}$"},"test_group_id":{"type":["string","null"],"pattern":"^tgr_[a-f0-9]{32}$"},"test_id":{"type":"string","pattern":"^tst_[a-f0-9]{32}$"},"trigger":{"const":"manual"},"triggered_by":{"type":"string","pattern":"^usr_[a-f0-9]{32}$"},"context_schema_version":{"enum":[1,2]},"context_hash":{"type":"string","pattern":"^sha256:[a-f0-9]{64}$"},"cancellation_requested_at":{"type":["string","null"],"format":"date-time"},"completed_at":{"type":["string","null"],"format":"date-time"},"outcome_summary":{"type":["string","null"],"maxLength":500},"resolved_at":{"type":"string","format":"date-time"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"EvidenceArtifact":{"type":"object","additionalProperties":false,"required":["evidence_id","run_id","attempt","replay_part","type","media_type","sha256","byte_size","captured_at"],"allOf":[{"if":{"properties":{"type":{"const":"replay"}},"required":["type"]},"then":{"properties":{"replay_part":{"type":"integer","minimum":1,"maximum":128},"media_type":{"type":"string","enum":["video/mp4","video/webm"]}}},"else":{"properties":{"replay_part":{"type":"null"}}}}],"properties":{"evidence_id":{"type":"string","pattern":"^evd_[a-f0-9]{32}$"},"run_id":{"type":"string","pattern":"^run_[a-f0-9]{32}$"},"attempt":{"type":"integer","minimum":1,"maximum":100},"replay_part":{"type":["integer","null"],"minimum":1,"maximum":128,"description":"Contiguous finalized replay-part ordinal; null for non-replay evidence."},"type":{"enum":["state_trace","console","network","command_journal","screenshot","replay","manifest"]},"media_type":{"type":"string","minLength":1,"maxLength":200,"description":"REPLAY is restricted to native full-Chrome video/mp4 or video/webm."},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"byte_size":{"type":"integer","minimum":0},"captured_at":{"type":"string","format":"date-time"}}},"LiveViewViewport":{"type":"object","additionalProperties":false,"required":["width","height"],"properties":{"width":{"type":"integer","minimum":800,"maximum":1920},"height":{"type":"integer","minimum":600,"maximum":1080}}},"LiveViewCapability":{"type":"object","additionalProperties":false,"required":["url","expires_at","viewport"],"properties":{"url":{"type":"string","format":"uri","pattern":"^https://(?:app\\.hyperbrowser\\.ai/live|dp-[a-z0-9](?:[a-z0-9-]{0,58}[a-z0-9])?\\.hxproxy\\.io/browser/[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[1-8][0-9A-Fa-f]{3}-[89A-Ba-b][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}/live/vnc\\.html)\\?(?:[^#\\s&=]+=[^#\\s&]*&)*token=[^#\\s&]+(?:&[^#\\s&=]+=[^#\\s&]*)*$","description":"Ephemeral view-only provider capability; never persist or log it."},"expires_at":{"type":"string","format":"date-time"},"viewport":{"$ref":"#/components/schemas/LiveViewViewport"}}},"RunEvent":{"type":"object","additionalProperties":false,"required":["sequence","state","occurred_at"],"properties":{"sequence":{"type":"integer","minimum":1,"maximum":10000},"state":{"enum":["CREATED","RESOLVING","READY","QUEUED","PROVISIONING","RUNNING","CANCELLATION_REQUESTED","PASSED","FAILED","ERROR","CANCELLED"]},"occurred_at":{"type":"string","format":"date-time"}}},"RunEventV2":{"type":"object","additionalProperties":false,"required":["schema_version","event_id","run_id","attempt","sequence","occurred_at","elapsed_ms","attempt_elapsed_ms","replay_offset_ms","kind","type","phase","state","outcome","correlation","safe_payload","error","evidence_refs"],"properties":{"schema_version":{"const":"run-event.v2"},"event_id":{"type":"string","pattern":"^evt_[A-Za-z0-9]+$"},"run_id":{"type":"string","pattern":"^run_[A-Za-z0-9]+$"},"attempt":{"type":["integer","null"],"minimum":1},"sequence":{"type":"integer","minimum":1,"maximum":1000000000},"occurred_at":{"type":"string","format":"date-time"},"elapsed_ms":{"type":"integer","minimum":0},"attempt_elapsed_ms":{"type":["integer","null"],"minimum":0},"replay_offset_ms":{"type":["integer","null"],"minimum":0,"description":"Browser recording offset when a trusted Browser-owned calibration exists; null for uncalibrated Runtime-relative activity timing."},"kind":{"enum":["run.state","attempt.state","step.state","action","assertion","browser.state","evidence.ready","result.final"]},"type":{"enum":["STATE_CHANGED","RUN_STARTED","STARTED","COMPLETED","SKIPPED","EXECUTE_SAVED_STEP","NAVIGATE","GO_BACK","GO_FORWARD","RELOAD","CLICK","DOUBLE_CLICK","CONTEXT_CLICK","HOVER","FOCUS","BLUR","SCROLL","SWIPE","LONG_PRESS","FILL","TYPE","CLEAR","PRESS_KEY","SELECT_OPTION","CHECK_CONTROL","UNCHECK_CONTROL","DRAG_DROP","UPLOAD_FILE","DOWNLOAD","WAIT","ACCEPT_DIALOG","DISMISS_DIALOG","OPEN_TAB","SELECT_TAB","CLOSE_TAB","CAPTURE_ACCESSIBILITY","CAPTURE_SCREENSHOT","INSPECT_CONSOLE","INSPECT_NETWORK","EVALUATE_JAVASCRIPT","PAGE_LOADED","ELEMENT_VISIBLE","ELEMENT_HIDDEN","TEXT_EQUALS","TEXT_CONTAINS","VALUE_EQUALS","URL_EQUALS","URL_MATCHES","TITLE_EQUALS","TITLE_CONTAINS","COUNT_EQUALS","ATTRIBUTE_EQUALS","ELEMENT_ENABLED","ELEMENT_DISABLED","ELEMENT_CHECKED","ELEMENT_UNCHECKED","NETWORK_RESPONSE_STATUS","NETWORK_RESPONSE_BODY","CONSOLE_NO_ERRORS","ACCESSIBILITY","PRODUCT_FACT","DOWNLOAD_COMPLETED","ALLOCATED","LOADING_READY","LIVE_VIEW_READY","PAGE_NAVIGATED","TAB_OPENED","TAB_SELECTED","TAB_CLOSED","DIALOG_OPENED","DOWNLOAD_STARTED","PAGE_ERROR","CRASHED","DISCONNECTED","STOPPED","CAPTURED","UNAVAILABLE","FINALIZED"]},"phase":{"enum":["STARTED","COMPLETED",null]},"state":{"enum":["CREATED","RESOLVING","READY","QUEUED","PROVISIONING","RUNNING","CANCELLATION_REQUESTED","PASSED","FAILED","ERROR","CANCELLED",null]},"outcome":{"enum":["PASSED","FAILED","ERROR","CANCELLED","SKIPPED",null]},"correlation":{"type":"object","additionalProperties":false,"required":["step_id","parent_event_id","action_id","assertion_id","browser_page_id"],"properties":{"step_id":{"type":["string","null"]},"parent_event_id":{"type":["string","null"]},"action_id":{"type":["string","null"]},"assertion_id":{"type":["string","null"]},"browser_page_id":{"type":["string","null"]}}},"safe_payload":{"type":"object"},"error":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/RunEventErrorV2"}]},"evidence_refs":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/RunEvidenceRefV2"}}},"allOf":[{"oneOf":[{"required":["kind","type","safe_payload"],"properties":{"kind":{"const":"run.state"},"type":{"enum":["STATE_CHANGED","RUN_STARTED"]},"phase":{"type":"null"},"state":{"enum":["CREATED","RESOLVING","READY","QUEUED","PROVISIONING","RUNNING","CANCELLATION_REQUESTED","PASSED","FAILED","ERROR","CANCELLED"]},"outcome":{"type":"null"},"safe_payload":{"$ref":"#/components/schemas/RunStatePayloadV2"}}},{"required":["kind","type","safe_payload"],"properties":{"kind":{"const":"attempt.state"},"type":{"enum":["STARTED","COMPLETED"]},"phase":{"type":"null"},"state":{"type":"null"},"safe_payload":{"$ref":"#/components/schemas/AttemptStatePayloadV2"}}},{"required":["kind","type","safe_payload"],"properties":{"kind":{"const":"step.state"},"type":{"enum":["STARTED","COMPLETED","SKIPPED"]},"phase":{"type":"null"},"state":{"type":"null"},"safe_payload":{"$ref":"#/components/schemas/StepStatePayloadV2"}}},{"required":["kind","type","safe_payload"],"properties":{"kind":{"const":"action"},"type":{"enum":["EXECUTE_SAVED_STEP","NAVIGATE","GO_BACK","GO_FORWARD","RELOAD","CLICK","DOUBLE_CLICK","CONTEXT_CLICK","HOVER","FOCUS","BLUR","SCROLL","SWIPE","LONG_PRESS","FILL","TYPE","CLEAR","PRESS_KEY","SELECT_OPTION","CHECK_CONTROL","UNCHECK_CONTROL","DRAG_DROP","UPLOAD_FILE","DOWNLOAD","WAIT","ACCEPT_DIALOG","DISMISS_DIALOG","OPEN_TAB","SELECT_TAB","CLOSE_TAB","CAPTURE_ACCESSIBILITY","CAPTURE_SCREENSHOT","INSPECT_CONSOLE","INSPECT_NETWORK","EVALUATE_JAVASCRIPT"]},"phase":{"enum":["STARTED","COMPLETED"]},"state":{"type":"null"},"safe_payload":{"$ref":"#/components/schemas/ActionPayloadV2"}}},{"required":["kind","type","safe_payload"],"properties":{"kind":{"const":"assertion"},"type":{"enum":["PAGE_LOADED","ELEMENT_VISIBLE","ELEMENT_HIDDEN","TEXT_EQUALS","TEXT_CONTAINS","VALUE_EQUALS","URL_EQUALS","URL_MATCHES","TITLE_EQUALS","TITLE_CONTAINS","COUNT_EQUALS","ATTRIBUTE_EQUALS","ELEMENT_ENABLED","ELEMENT_DISABLED","ELEMENT_CHECKED","ELEMENT_UNCHECKED","NETWORK_RESPONSE_STATUS","NETWORK_RESPONSE_BODY","CONSOLE_NO_ERRORS","ACCESSIBILITY","PRODUCT_FACT","DOWNLOAD_COMPLETED"]},"phase":{"enum":["STARTED","COMPLETED"]},"state":{"type":"null"},"safe_payload":{"$ref":"#/components/schemas/AssertionPayloadV2"}}},{"required":["kind","type","safe_payload"],"properties":{"kind":{"const":"browser.state"},"type":{"enum":["ALLOCATED","LOADING_READY","LIVE_VIEW_READY","PAGE_NAVIGATED","TAB_OPENED","TAB_SELECTED","TAB_CLOSED","DIALOG_OPENED","DOWNLOAD_STARTED","DOWNLOAD_COMPLETED","PAGE_ERROR","CRASHED","DISCONNECTED","STOPPED"]},"phase":{"type":"null"},"state":{"type":"null"},"outcome":{"type":"null"},"safe_payload":{"$ref":"#/components/schemas/BrowserStatePayloadV2"}}},{"required":["kind","type","safe_payload"],"properties":{"kind":{"const":"evidence.ready"},"type":{"enum":["CAPTURED","UNAVAILABLE"]},"phase":{"type":"null"},"state":{"type":"null"},"outcome":{"type":"null"},"safe_payload":{"$ref":"#/components/schemas/EvidenceReadyPayloadV2"}}},{"required":["kind","type","safe_payload"],"properties":{"kind":{"const":"result.final"},"type":{"const":"FINALIZED"},"phase":{"type":"null"},"state":{"type":"null"},"outcome":{"enum":["PASSED","FAILED","ERROR","CANCELLED"]},"safe_payload":{"$ref":"#/components/schemas/ResultFinalPayloadV2"}}}]}]},"RunEventErrorV2":{"type":"object","additionalProperties":false,"required":["code","category","codes_revision","retryable"],"properties":{"code":{"type":"string","pattern":"^[A-Z][A-Z0-9_]{1,63}$"},"category":{"enum":["RUNTIME","BROWSER","CREDENTIAL","EVIDENCE","POLICY","VALIDATION","PERSISTENCE","UNKNOWN"]},"codes_revision":{"type":"string","pattern":"^[a-z0-9][a-z0-9.-]*\\.v[0-9]+$"},"retryable":{"type":"boolean"}}},"RunEvidenceRefV2":{"type":"object","additionalProperties":false,"required":["evidence_id","kind","relation"],"properties":{"evidence_id":{"type":"string","pattern":"^evd_[A-Za-z0-9]+$"},"kind":{"enum":["SCREENSHOT","ACCESSIBILITY_SNAPSHOT","REPLAY","CONSOLE","NETWORK","STATE_TRACE","CHECKPOINT"]},"relation":{"enum":["SUPPORTS","BEFORE","AFTER","RESULT","REPLAY_SOURCE"]}}},"RunStatePayloadV2":{"type":"object","additionalProperties":false,"required":["reason_code","reason_codes_revision","state_version"],"properties":{"from":{"enum":["CREATED","RESOLVING","READY","QUEUED","PROVISIONING","RUNNING","CANCELLATION_REQUESTED","PASSED","FAILED","ERROR","CANCELLED",null]},"reason_code":{"type":"string","pattern":"^[A-Z][A-Z0-9_]{1,63}$"},"reason_codes_revision":{"type":"string","pattern":"^[a-z0-9][a-z0-9.-]*\\.v[0-9]+$"},"state_version":{"type":"integer","minimum":1},"test_revision":{"type":"integer","minimum":1},"planned_steps":{"type":"integer","minimum":0}}},"AttemptStatePayloadV2":{"type":"object","additionalProperties":false,"required":["reason_code","reason_codes_revision","retryable"],"properties":{"retry_of_attempt":{"type":["integer","null"],"minimum":1},"retry_policy_revision":{"type":"string","pattern":"^[a-z0-9][a-z0-9.-]*\\.v[0-9]+$"},"reason_code":{"type":"string","pattern":"^[A-Z][A-Z0-9_]{1,63}$"},"reason_codes_revision":{"type":"string","pattern":"^[a-z0-9][a-z0-9.-]*\\.v[0-9]+$"},"retryable":{"type":"boolean"},"duration_ms":{"type":"integer","minimum":0}}},"StepSnapshotV2":{"type":"object","additionalProperties":false,"required":["id","position","type","title","enabled"],"properties":{"id":{"type":"string","pattern":"^(?:stp_[a-f0-9]{32}|tststep_[A-Za-z0-9]+)$"},"position":{"type":"integer","minimum":0,"maximum":49},"type":{"enum":["ACT","ASSERT","LOGIN","FILES","SCREENSHOT","JAVASCRIPT","MICROPHONE"]},"title":{"type":"string","minLength":1,"maxLength":500},"enabled":{"type":"boolean"}}},"StepStatePayloadV2":{"type":"object","additionalProperties":false,"required":["step","summary"],"properties":{"step":{"$ref":"#/components/schemas/StepSnapshotV2"},"summary":{"type":"string","minLength":1,"maxLength":500},"duration_ms":{"type":"integer","minimum":0},"passed_assertions":{"type":"integer","minimum":0},"failed_assertions":{"type":"integer","minimum":0},"error_assertions":{"type":"integer","minimum":0},"reason_code":{"type":"string","pattern":"^[A-Z][A-Z0-9_]{1,63}$"}}},"ActionPayloadV2":{"type":"object","additionalProperties":false,"required":["summary","target_label","duration_ms"],"properties":{"summary":{"type":"string","minLength":1,"maxLength":500},"target_label":{"type":["string","null"],"minLength":1,"maxLength":256},"duration_ms":{"type":["integer","null"],"minimum":0},"reason_code":{"type":"string","pattern":"^[A-Z][A-Z0-9_]{1,63}$"}}},"AssertionPayloadV2":{"type":"object","additionalProperties":false,"required":["summary","expectation","actual_summary","duration_ms"],"properties":{"summary":{"type":"string","minLength":1,"maxLength":500},"expectation":{"type":"string","minLength":1,"maxLength":1000},"actual_summary":{"type":["string","null"],"minLength":1,"maxLength":1000},"duration_ms":{"type":["integer","null"],"minimum":0},"reason_code":{"type":"string","pattern":"^[A-Z][A-Z0-9_]{1,63}$"}}},"BrowserStatePayloadV2":{"type":"object","additionalProperties":false,"required":["summary"],"properties":{"summary":{"type":"string","minLength":1,"maxLength":500},"safe_title":{"type":"string","maxLength":500},"safe_origin":{"type":"string","pattern":"^https://[^/?#\\s@]+$","maxLength":2048},"tab_id":{"type":"string","pattern":"^tab_[A-Za-z0-9]+$"},"readiness_marker":{"const":"VENKAT_LOADING_READY"},"viewport_width":{"type":"integer","minimum":320,"maximum":7680},"viewport_height":{"type":"integer","minimum":320,"maximum":4320},"reason_code":{"type":"string","pattern":"^[A-Z][A-Z0-9_]{1,63}$"}}},"EvidenceReadyPayloadV2":{"type":"object","additionalProperties":false,"required":["evidence_id","evidence_kind","required","summary"],"properties":{"evidence_id":{"type":"string","pattern":"^evd_[A-Za-z0-9]+$"},"evidence_kind":{"enum":["SCREENSHOT","ACCESSIBILITY_SNAPSHOT","REPLAY","CONSOLE","NETWORK","STATE_TRACE","CHECKPOINT"]},"required":{"type":"boolean"},"summary":{"type":"string","minLength":1,"maxLength":500},"record_count":{"type":"integer","minimum":0},"unavailable_reason":{"enum":["EXPIRED","DELETED_BY_POLICY","QUARANTINED","CORRUPT","NOT_COMMITTED"]}}},"ResultFinalPayloadV2":{"type":"object","additionalProperties":false,"required":["planned_steps","enabled_steps","passed_steps","failed_steps","error_steps","cancelled_steps","skipped_steps","warning_count","known_failed_assertion_refs","duration_ms","effective_attempt","agentcore_cleanup","browser_cleanup","recording_finalization","evidence_finalization","aggregation_rules_version","result_summary"],"properties":{"planned_steps":{"type":"integer","minimum":0},"enabled_steps":{"type":"integer","minimum":0},"passed_steps":{"type":"integer","minimum":0},"failed_steps":{"type":"integer","minimum":0},"error_steps":{"type":"integer","minimum":0},"cancelled_steps":{"type":"integer","minimum":0},"skipped_steps":{"type":"integer","minimum":0},"warning_count":{"type":"integer","minimum":0},"known_failed_assertion_refs":{"type":"array","maxItems":1000,"items":{"type":"string","pattern":"^asr_[A-Za-z0-9]+$"}},"duration_ms":{"type":"integer","minimum":0},"effective_attempt":{"type":["integer","null"],"minimum":1},"agentcore_cleanup":{"enum":["SUCCEEDED","NOT_REQUIRED","FAILED"]},"browser_cleanup":{"enum":["SUCCEEDED","NOT_REQUIRED","FAILED"]},"recording_finalization":{"enum":["SUCCEEDED","NOT_REQUIRED","FAILED"]},"evidence_finalization":{"enum":["SUCCEEDED","NOT_REQUIRED","FAILED"]},"runtime_finalization":{"enum":["SUCCEEDED","NOT_REQUIRED","FAILED"],"description":"Optional on run-event.v2 for backward compatibility; new Nova Act results record Runtime workflow finalization explicitly."},"runtime_failure_code":{"type":["string","null"],"pattern":"^[A-Z][A-Z0-9_]{1,63}$"},"aggregation_rules_version":{"const":"run-aggregate.v2"},"result_summary":{"type":"string","minLength":1,"maxLength":500}}},"RunEventPageV2":{"type":"object","additionalProperties":false,"required":["schema_version","run_id","run","events","next_after","high_watermark","has_more","terminal"],"properties":{"schema_version":{"const":"run-event-page.v2"},"run_id":{"type":"string","pattern":"^run_[A-Za-z0-9]+$"},"run":{"$ref":"#/components/schemas/Run"},"events":{"type":"array","maxItems":500,"items":{"$ref":"#/components/schemas/RunEventV2"}},"next_after":{"type":"integer","minimum":0,"maximum":1000000000},"high_watermark":{"type":"integer","minimum":0,"maximum":1000000000},"has_more":{"type":"boolean"},"terminal":{"type":"boolean"}}},"Problem":{"type":"object","additionalProperties":false,"required":["type","title","status","code"],"properties":{"type":{"type":"string","format":"uri-reference"},"title":{"type":"string"},"status":{"type":"integer","minimum":400,"maximum":599},"code":{"type":"string"}}},"GatewayUnauthorized":{"type":"object","additionalProperties":false,"required":["message"],"properties":{"message":{"const":"Unauthorized"}}}}}}