Skip to content

Versioned compliance review API

The JWT-authenticated review API lives under /api/v2/agent-compliance/workflow. Each request uses the caller's primary organisation, assigned workflow permissions, and existing agent subscription restrictions.

Access and onboarding

Method Path Purpose
GET /access Feature enablement, workflow roles, primary organization_id and organization_name, Super admin status
POST /onboarding/send-code Email a code to the authenticated account address; available before account approval
POST /onboarding/verify Verify { "code": "123456" } and resolve organisation membership
GET /portfolio Current agent versions, owning teams, review states and blocker counts

Codes expire after ten minutes, allow five guesses, and can be requested once per minute, up to ten times per day. Verification normally creates pending membership and returns status: "awaiting_role_assignment"; Super admin grants workflow permissions. If the matching active organisation has Potential customer enabled, successful verification activates membership, approves and enables the account, completes onboarding, and grants the three customer workflow roles. The response returns status: "ready", organization_id, organization_name, and message. Public or ambiguous domains and rejected memberships require administrator assignment (status: "needs_admin_assignment").

The organisation setting defaults to false. Super admins can update it with PATCH /api/v2/core/organizations/{organization_id} and { "potential_customer": true }. Organisation list, detail, and update responses include potential_customer. Turning it off affects future approvals only; existing accounts and grants are unchanged. It is independent of demo_mode, Free/Paid entitlements, and assessment customer tiers.

Reviews

Paths below are relative to /agents/{agent_id}. IDs are UUIDs except mapper-provided obligation identifiers.

Method Path Purpose
GET / Obligations versions and their review IDs
POST /reviews Start current completed mapping review using { "version_id": "UUID" }
GET /reviews/{review_id} Read obligations, decisions, evidence metadata, revision, status, and history
PUT /reviews/{review_id}/obligations/{obligation_id}/legal Save applicability, priority, blocker flag and comment
PUT /reviews/{review_id}/obligations/{obligation_id}/engineering Save Engineering completion and comment
POST /reviews/{review_id}/transition Submit, complete, sign off, or return work
GET /reviews/{review_id}/obligations.md Download the most recently submitted Legal requirements
GET /reviews/{review_id}/history/{revision} Read an immutable event snapshot, including previous Legal submissions
POST /reviews/{review_id}/obligations/{obligation_id}/evidence Multipart file and revision; PNG, MP4 or WebM
GET /reviews/{review_id}/evidence/{evidence_id} Authorised download URL valid for 300 seconds
POST /versions/preview Propose updated facts using { "changelog": "..." }; does not create a version
POST /versions/confirm Confirm { "token": "...", "twin": {...} }; creates a mapping version

Every review mutation requires its latest integer revision. A stale revision returns HTTP 409 without saving. Historical versions are read-only. Version proposals expire after one hour and are bound to the user, organisation, agent, and baseline version.

A completed mapper job may report partial coverage or uncertain applicability. Neither blocks Legal review. Review output includes mapping_coverage, and obligation requirement objects retain assessment status, reason, and missing_facts. Every returned obligation requires an explicit Legal decision before submission. Coverage remains recorded in submission history and partial-coverage Markdown exports; Legal decisions do not overwrite the mapper's original coverage or imply review of unreturned obligations.

Legal payload example:

{
  "revision": 1,
  "applicability": "applies",
  "priority": "critical",
  "release_blocker": true,
  "comment": "Demonstrate that personal information is redacted."
}

Applicability values are undecided, applies, and does_not_apply. Priority values are normal, high, and critical.

Engineering payloads contain revision, engineering_complete, and optional engineering_comment. Transition payloads contain revision, action, and optional reason. Actions are submit_legal, complete_engineering, accept_evidence, signoff, return_legal, and return_engineering; returning work requires a reason.

Administration

Only Super admin can call these endpoints:

Method Path Payload / result
PUT /admin/organizations/{organization_id} { "enabled": true } enables reviews for that organisation
GET /admin/organizations/{organization_id}/users Members and workflow role grants
PUT /admin/organizations/{organization_id}/users/{user_id} { "roles": ["legal", "engineering", "release"] } replaces grants

An empty roles list revokes workflow permissions. Granting roles activates the organisation membership and approves the account; normal account setup requirements still apply. Custom organisation role names and global admin roles do not confer workflow permissions.

Feature-disabled organisations retain existing compliance APIs. Enabled organisations must use review endpoints for decision writes and the release-controlled path for new mapping versions. These reviews do not automatically publish public compliance claims.

Portfolio progress fields

Each /portfolio agent row includes submission, total_obligations, applies, does_not_apply, legal_acted, legal_pending, engineering_acted, and engineering_pending. Counts refer to the latest live obligations version. Legal Acted on means a saved applicability decision. Before a completed mapping has a review, all returned obligations count as Legal pending. Locked agent content is excluded.

Engineering Acted on counts applicable obligations with saved implementation and any required verified evidence for the current obligation expectations revision and after any correction request. The dashboard includes Engineering obligation totals only for versions already handed off by Legal and excludes reviews returned to Legal. Release sign-off counters derive from awaiting_signoff and legally_ready agent states; upstream waiting agents are separate counts.

Batch Engineering progress

PUT /agents/{agent_id}/reviews/{review_id}/engineering-progress saves multiple Engineering edits atomically. Send revision and an obligations array containing obligation_id, engineering_complete, and engineering_comment for each changed obligation. Only applicable obligations may be updated. The endpoint enforces Engineering permissions, current-version/team ownership, unique and known IDs, and revision checks. A successful save returns the updated review with one revision increment and an engineering_save_batch audit event. Invalid batches save nothing.

The dashboard's Submit evidence to Legal action saves pending edits first, then requests the existing complete_engineering transition using the returned revision. Required evidence and implementation gates still apply. If handoff fails after saving, progress remains saved for retry.

PUT /agents/{agent_id}/reviews/{review_id}/legal-draft saves multiple Legal obligation edits atomically. Send revision and an obligations array, each item containing obligation_id, applicability, priority, release_blocker, and comment. IDs must be unique and belong to the review. The endpoint enforces Legal permissions, the current version, Legal ownership, and revision checks. A successful save returns the updated review and increments its revision once, with one legal_save_batch audit event. An invalid item or stale revision saves none of the batch.

The dashboard's Submit to Engineering action saves pending edits using this endpoint, then submits using the returned revision. If handoff fails after saving, the Legal draft remains saved and the user can retry submission.

Demo administration

These routes use the same workflow API prefix and require an authenticated Super admin:

Method Path relative to /api/v2/agent-compliance/workflow Result
GET /admin/organizations/{organization_id}/demo-agents List the three registered demos that exist in the organisation.
POST /admin/organizations/{organization_id}/demo-agents Create missing demos; preserve existing runs. Requires an active shared organisation with reviews enabled.
POST /admin/organizations/{organization_id}/demo-agents/{agent_id}/reset Start a fresh synthetic mapping and Legal review version for the selected demo.

Reset accepts {"version_id":"current-version-uuid","revision":1}. Use the current values returned by the list route. Stale values return 409; refresh before retrying. Normal agents and demo IDs from a different organisation return 404. Non-Super-admin users receive 403.

Each demo contains five undecided obligations across two fictional acts. Reset retains previous versions and their evidence, and records the acting Super admin in the new review's audit history.

Collaboration and CSV round trips

All paths below are relative to /agents/{agent_id}/reviews/{review_id} and use the same authentication, tenant, subscription, role, current-version, and optimistic revision guards as review writes.

Method Path Payload / result
GET /obligations.csv UTF-8 CSV with a BOM, signed fixed context, and editable Legal fields.
POST /csv/preview Multipart file and revision; returns changed, unchanged, row errors, proposed changes, and an import token.
POST /csv/apply JSON revision and token; saves the previewed changes as a Legal draft.
POST /messages JSON revision, body, optional source obligation_id; appends a discussion message.
POST /documents Multipart revision, file, optional obligation_id; archives the original and adds a discussion attachment.
GET /artifacts/{artifact_id} Authorised document/import download URL, valid for 300 seconds.
POST /evidence Multipart revision, file, and obligation_ids as a JSON string array; attaches evidence to 1–100 applicable obligations atomically.
POST /evidence-decisions JSON revision, obligation_ids, decision (accepted or changes_requested), optional feedback; Legal evidence acceptance. Corrections require feedback.
POST /scope Multipart revision, summary, changes_agent_facts boolean, file; Engineering proposes scope and hands back to Legal.
POST /scope/{proposal_id}/decision JSON revision, accept boolean, reason; Legal accepts or rejects the scope proposal.
POST /scope/{proposal_id}/preview JSON changelog; Legal previews facts for an accepted product-scope change. Use the existing /agents/{agent_id}/versions/confirm with the returned token.

Documents accept PDF with selectable text, DOCX, Markdown, or text up to 10 MB. Extracted document text and any truncation warnings are retained with the original artifact. Evidence accepts PNG/MP4/WebM under the existing limits. CSV is limited to 2 MB. A CSV preview with errors cannot be applied. Valid preview tokens expire after one hour, are user/review/revision-bound, and cannot be replayed after apply. No-op imports still record the source artifact. Successful imports increment the revision for the batch save, if any, and again for the import audit event; always use the returned revision.

CSV fixed columns are tracking_id, obligation_id, act_id, requirement, agent_version, review_id, and review_revision, protected by row_signature. Editable columns are applicability, priority, release_blocker, comment, expected_evidence, acceptance_criteria, and interaction_example. Formula-like cell values are escaped on export and restored on import. Fixed-column edits, duplicate/unknown IDs, invalid values, and old review revisions are rejected. Partial files update only included rows. Do not build an importer that matches by row position or requirement text.

Legal save payloads additionally accept expected_evidence, acceptance_criteria, and interaction_example (up to 20,000 characters each). Submitted snapshots freeze those fields. GET /obligations.md?scope=applies is the default; scope=all includes explicitly labelled non-applicable requirements. The frontend proxy preserves the query string.

Expectations and acceptance states

complete_engineering now transitions to legal_evidence_review. Legal calls /evidence-decisions to accept applicable obligations or request corrections. A correction returns only the selected obligations to Engineering and preserves other acceptance. Corrected evidence must have been uploaded after the request and match the obligation's expectation_revision. Legal's accept_evidence transition requires every applicable obligation to be accepted and moves to awaiting_signoff. Release then uses signoff.

tracking_id is a UUIDv5 scoped by agent ID, act ID, and source obligation ID. Mapper ingestion adds it server-side; review rows also persist it. Stable source identity retains the tracking ID across mapping versions. Unknown replacement IDs are treated as new obligations, never automatically matched by text. Review output additionally includes expected_evidence, acceptance_criteria, interaction_example, expectation_revision, evidence_status, evidence_feedback, evidence_requested_at, messages, scope_proposals, artifacts, and the latest submitted handoff_changes. Portfolio rows include evidence_accepted and evidence_pending; the evidence-review stage belongs to Legal.

Within one agent version, a new Legal submission increments expectation_revision only for obligations whose Legal fields changed. Unchanged implementation, evidence, and acceptance stay valid. A new agent version still requires explicit Legal reconfirmation and does not inherit evidence or sign-off.

Accepted scope changes marked changes_agent_facts=true block another handoff on the old version. Legal must preview and confirm the changed facts using the scoped endpoint. The preview uses the archived PRD text, scope summary, and Legal decision. It archives the exact changelog input and emits a preview event, but does not create an agent version until confirmation. Normal version previews remain Release-only. Refresh the review after preview because its audit revision changes.

Artifact provenance

New workflow artifacts use immutable server-generated keys under compliance/{organization_id}/agents/{agent_id}/versions/{version_id}/reviews/{review_id}/. Evidence keys additionally identify the stable obligation, expectation revision, and unique evidence artifact. Documents identify their kind, originating review revision, and unique artifact. The original filename is metadata rather than an identity key.

The database records uploader, original filename, content type, size, SHA-256, bucket, object key, and S3 version ID when supplied by S3. Signed downloads bind to the stored object version when available. Messages, scope decisions, submitted expectation changes, and evidence acceptance events retain their relationships. Acceptance snapshots identify the accepted evidence and checksums. Bulk evidence uploads create a separate immutable evidence object for each selected obligation; the checksums identify shared source bytes. Existing pre-upgrade evidence remains readable at its original path.

Engineering evidence-reference CSV

Relative to /agents/{agent_id}/reviews/{review_id}:

Method Path Payload / result
POST /evidence-csv/preview Multipart revision and file; returns row errors, changes, reference count in changed, and an apply token.
POST /evidence-csv/apply JSON revision and token; returns the updated review.

Engineering-only, current-version/team and subscription checks apply. CSV requires obligation_id, artifact_id, artifact_detail, with optional artifact_path; order is flexible. The obligation identifier may be the source ID or tracking UUID. Without a separate path column, artifact_id is used as the external path. All rows must refer to applicable obligations in this review. Duplicate obligation/artifact pairs and invalid or empty fields reject the whole preview. Several distinct artifacts per obligation, or one artifact supporting several obligations, are allowed. Limits: UTF-8, 2 MB, 100 references, ID/path up to 2,000 characters, detail up to 20,000.

The preview captures the server's current expectations revision and preserves the original uploaded CSV. Confirmation is bound to the previewing user and review revision and expires after one hour. A successful import appends reference records and exchanges, resets affected evidence acceptance to pending, and emits one evidence_csv_import event. Implementation completion and Legal decisions remain unchanged. A repeated apply token is rejected after the revision advances.

Evidence output includes optional reference: {artifact_id, artifact_path, artifact_detail}. Reference records use content type application/vnd.carver.evidence-reference+csv. verified_at confirms storage of the reference record; it does not assert that Eli accessed or verified the external file. Paths are never fetched server-side. References satisfy the evidence-presence gate for the current expectations, including after an evidence correction request, while Legal acceptance remains mandatory. The original CSV and per-obligation reference records retain checksums and version context in private storage.