Skip to main content

Governance API

Table of Contents

Top

upsquad/governance/v1/approval.proto

Approval

Approval is the read-projection of a governance_approvals row + its resolved fields.

FieldTypeLabelDescription
approval_idstringapproval_id is the UUID primary key.
org_idstringorg_id is the tenant scope.
session_idstringsession_id is the paused session awaiting this approval.
agent_idstringagent_id is the agent that requested the action.
tool_namestringtool_name identifies the gated tool.
targetstringtarget is the specific resource.
statusstringstatus is one of pending
templatestringtemplate is the dev_only
required_clearanceint32required_clearance — minimum clearance the decider must hold.
requested_atgoogle.protobuf.Timestamprequested_at is the insertion wall-clock time.
deadlinegoogle.protobuf.Timestampdeadline is the scheduler-enforced expiry.
resolved_atgoogle.protobuf.Timestampresolved_at is set iff status in {approved,denied,expired}.
resolved_bystringresolved_by is the operator_id that won first-write (empty on expiry).
resolution_reasonstringresolution_reason is the operator-provided rationale, if any.
channels_dispatchedstringrepeatedchannels_dispatched is the set of adapters that have fanned out.
delegation_chainDelegationLinkrepeateddelegation_chain records the delegation hops (LLD 8 populates).
policy_idstringpolicy_id that produced requires_approval.
escalation_levelint32escalation_level — 0 original; incremented on each escalation (LLD 9).
metadataApproval.MetadataEntryrepeatedmetadata is the per-request context captured at RequestApproval time (issue #1675), round-tripped from the governance_approvals.metadata JSONB column so it is visible on the ListApprovals read path — not only GetApproval. It carries a human-readable "summary" key the approvals queue renders BEFORE a decision (e.g. "Appoint Vaisakh as additional admin of Go-to-Market"), plus structured keys (op_type, unit_id, unit_name, candidate_name, op_lines, …) per gated change kind. Names are resolved at request time (a later rename does not rewrite the summary). Empty for pre-#1675 approvals — clients must degrade gracefully.
action_typestringaction_type is the governance action that raised the approval (e.g. "tool_call", "approval_gate" for workflow/coordinator governance gates, "a2a_egress", "org_draft_publish"). It is round-tripped from the governance_approvals.action_type column — written by every open path — so the Approvals queue can render workflow context and the client resume router (client#492) can route on the real primary signal instead of the tool_name fallback (issue #1679 / WF-01). Empty only for legacy rows predating the column default; clients must degrade gracefully.
agent_namestringagent_name is the DISPLAY NAME of the requesting agent, captured at RequestApproval time and denormalised onto the row (issue #2325).

"Who is asking" is a first-order input to an approval decision — an L4 request from the principal architect and an L4 request from a smoke-test delegate warrant different scrutiny — and before #2325 only the raw agent_id UUID reached the reviewer.

WRITE-TIME, NOT A READ-TIME JOIN (architect ruling on #2325): - Correctness. An approval is a point-in-time decision record. A join to agents.name on the read path would show the reviewer the agent's CURRENT name — or nothing at all after a retire/delete — not who actually asked. This mirrors the #1675 precedent documented on metadata above: names are resolved at request time, and a later rename does not rewrite the record. - Scaling. A per-row join on the hot ListApprovals path to render a display string is a cost paid on every queue poll, forever.

Empty when the requester could not be resolved to a name: a sessionless / system request that carries no agent_id, an agents row already gone at lookup time, or a legacy row predating migration 185. Clients MUST degrade to rendering agent_id. |

Approval.MetadataEntry

FieldTypeLabelDescription
keystring
valuestring

DelegateRequest

DelegateRequest transfers approval authority to another member. Behaviour deferred to LLD 8.

FieldTypeLabelDescription
org_idstringorg_id for RLS.
approval_idstringapproval_id of the pending approval.
from_member_idstringfrom_member_id is the current approver.
to_member_idstringto_member_id is the delegatee (must satisfy required_clearance).
reasonstringreason is an audit-trail explanation.

DelegateResponse

DelegateResponse returns the updated approval.

FieldTypeLabelDescription
approvalApprovalapproval is the post-delegation row.

DelegationLink is one hop in the delegation chain.

FieldTypeLabelDescription
from_member_idstringfrom_member_id is the delegator.
to_member_idstringto_member_id is the delegatee.
to_clearanceint32to_clearance is the delegatee's clearance at delegation time.
atgoogle.protobuf.Timestampat is the delegation wall-clock time.
reasonstringreason is the audit-trail explanation.

EmergencyRotateHMACRequest

EmergencyRotateHMACRequest is the admin-authenticated payload for rotating a tenant's approval-callback HMAC key out-of-band.

FieldTypeLabelDescription
org_idstringorg_id is the tenant whose HMAC secret should be rotated.
reasonstringreason is a free-form audit-trail explanation for why the admin triggered the rotation (e.g. "suspected leak in incident X-2026-042").

EmergencyRotateHMACResponse

EmergencyRotateHMACResponse reports the rotation outcome. The actor (admin subject) is recorded in the audit row server-side; it is never returned in the response body.

FieldTypeLabelDescription
previous_key_idstringprevious_key_id identifies the key that was just retired. Empty if the tenant had no prior secret (first rotation after migration).
new_key_idstringnew_key_id identifies the freshly-issued secret.
rotated_atgoogle.protobuf.Timestamprotated_at is the wall-clock time the rotation committed.

GetApprovalRequest

GetApprovalRequest identifies a single approval.

FieldTypeLabelDescription
org_idstringorg_id for RLS.
approval_idstringapproval_id is the UUID to fetch.

GetApprovalResponse

GetApprovalResponse wraps a single Approval for GetApproval. Carries optional risk + impact enrichment for the redesigned client portal /approvals detail panel (GAP-6, tracker #1031). Both fields are populated server-side by the GetApproval handler; clients that pre- date GAP-6 simply ignore the new fields, so the surface remains backwards compatible.

FieldTypeLabelDescription
approvalApprovalapproval is the requested row.
riskRiskAssessmentrisk is a heuristic assessment derived from the recent history of (agent_id, tool_name) approvals for the tenant. Always populated; an empty store yields RISK_LEVEL_LOW with similar_count=0.
impact_summarystringimpact_summary is a one-line plain-English description of what committing this approval would let the agent do — composed from template + tool_name + target. Never localised (English only) and never empty for a well-formed approval.

ListApprovalsRequest

ListApprovalsRequest carries page-based pagination + optional filters.

FieldTypeLabelDescription
org_idstringorg_id for RLS.
status_filterstringstatus_filter, if set, restricts to approvals with this status.
session_id_filterstringsession_id_filter, if set, restricts to approvals for this session.
pageint32page is the 1-based page number (default 1).
page_sizeint32page_size caps at 100 (default 50).

ListApprovalsResponse

ListApprovalsResponse carries a single page plus the total count.

FieldTypeLabelDescription
approvalsApprovalrepeatedapprovals is the current page, ordered by requested_at DESC.
total_countint32total_count is the unpaginated count matching the filter.

ListRecentDecisionsRequest

ListRecentDecisionsRequest carries the window + cursor for the historical-decisions read.

FieldTypeLabelDescription
org_idstringorg_id for RLS.
window_daysint32window_days bounds the resolved_at lower bound to now() - N days. Default 7 when zero/unset; clamped server-side to [1, 90] so the table scan stays bounded.
page_sizeint32page_size caps at 100 (default 50). Server clamps invalid values.
page_tokenstringpage_token is the opaque cursor returned by a previous response. Empty for the first page.
verdict_filterstringverdict_filter restricts the result set to one of "approved", "denied", or "expired". Empty returns all three buckets.
agent_id_filterstringagent_id_filter restricts the result set to decisions on a single agent's approvals. Empty matches all agents.

ListRecentDecisionsResponse

ListRecentDecisionsResponse carries one page plus the next cursor.

FieldTypeLabelDescription
decisionsRecentDecisionrepeateddecisions is the current page, ordered by decided_at DESC.
next_page_tokenstringnext_page_token is empty when no further pages exist; otherwise pass it back as ListRecentDecisionsRequest.page_token.

RecentDecision

RecentDecision is the trimmed projection of a resolved approval row for the Approvals "Recent decisions" tab. Drops args, metadata, and the delegation chain so this list endpoint stays cheap.

FieldTypeLabelDescription
idstringid is the approval UUID.
verdictstringverdict is one of "approved"
decided_atgoogle.protobuf.Timestampdecided_at is the wall-clock time the decision was recorded (governance_approvals.resolved_at).
decided_bystringdecided_by is the operator member_id that won first-write. Empty string when verdict=="expired" (no operator on scheduler-driven expiry).
summarystringsummary is a short human-readable label for the gated action, server-built from tool_name + target. Examples: "github.merge owner/repo#42" "tool_call deploy.production"
tool_namestringtool_name is preserved verbatim so UIs can group / filter without string-parsing the summary.
targetstringtarget is preserved verbatim for the same reason.
agent_idstringagent_id of the requesting agent, surfaced for the per-agent column.
session_idstringsession_id of the paused session that owned the approval.

RecordDecisionRequest

RecordDecisionRequest is the single converged entry point for all approval decisions regardless of channel. First-write-wins.

FieldTypeLabelDescription
org_idstringorg_id for RLS.
approval_idstringapproval_id of the pending approval to resolve.
decisionDecisiondecision is the recorded outcome (required; must be APPROVED or DENIED).
operator_idstringoperator_id is the member recording the decision.
reasonstringreason is a human-readable explanation written to the audit trail.
channelChannelchannel identifies the adapter that recorded the decision.
idempotency_keystringidempotency_key prevents double-submission from webhook retries.
response_payloadbytesresponse_payload is the LBE-B answer envelope {choice, text, answered_by} for a user_input prompt (#2238 / #2249). It is written atomically with the status flip through the SAME first-write CAS (Store.TryResolveWithPayload), so the resolved row is the answer's single source of truth (the interpreter reads it back as ${step.choice} / ${step.text}). ADDITIVE and OPTIONAL: nil/empty on every approval_gate / tool_call decision, which resolve byte-identically to the pre-#2249 path. Raw JSON bytes so the server does not re-serialize the caller's envelope. LBE-B2 (#2249).

RecordDecisionResponse

RecordDecisionResponse reports the first-write-wins outcome.

FieldTypeLabelDescription
resultRecordResultresult is OK, DUPLICATE, or CONFLICT per §6 state machine.
approvalApprovalapproval is the current post-transaction row.

RequestApprovalRequest

RequestApprovalRequest carries the fields needed to open a pending approval. Dedup is on (org_id, session_id, tool_name, args_sha256).

FieldTypeLabelDescription
org_idstringorg_id is the tenant scope (RLS).
team_idstringteam_id scopes the approval to a team.
session_idstringsession_id ties the approval to a paused agent session.
agent_idstringagent_id is the agent that requested the action.
member_idstringmember_id is the agent's effective member identity.
clearanceint32clearance of the requesting principal.
action_typestringaction_type is the governance action type (e.g. "tool_call").
tool_namestringtool_name identifies the gated tool.
targetstringtarget is the specific resource (e.g. "github.merge").
argsbytesargs is the full tool args payload (truncated > 256 KiB).
args_sha256stringargs_sha256 is the dedup key; sha256 over the full args bytes.
policy_idstringpolicy_id is the policy that produced requires_approval.
required_clearanceint32required_clearance — minimum clearance the decider must hold.
templatestringtemplate is one of dev_only
deadlinegoogle.protobuf.Timestampdeadline is the scheduler-enforced expiry wall-clock time.
channelsstringrepeatedchannels enumerate the fan-out adapters (LLD 7 implements dispatch).
metadataRequestApprovalRequest.MetadataEntryrepeatedmetadata is arbitrary per-request context for audit.

RequestApprovalRequest.MetadataEntry

FieldTypeLabelDescription
keystring
valuestring

RequestApprovalResponse

RequestApprovalResponse carries the approval_id and dedup status.

FieldTypeLabelDescription
approval_idstringapproval_id is the UUID of the (possibly pre-existing) pending row.
was_deduplicatedboolwas_deduplicated is true when an open approval matched the dedup key.
deadlinegoogle.protobuf.Timestampdeadline is the effective expiry (the existing row's expires_at on dedup, or the requested deadline on fresh insert).

RequestChangesRequest

RequestChangesRequest is the operator-driven 'Send back for changes' payload (GAP-9). The approval MUST currently be status='pending'; resolved approvals (approved/denied/expired) cannot be sent back.

FieldTypeLabelDescription
org_idstringorg_id for RLS.
approval_idstringapproval_id of the pending approval to flag.
operator_idstringoperator_id is the member sending the approval back. Recorded on the approval_events row as actor_member_id.
commentstringcomment is the free-text rationale shown to the requester. Required; empty comments are rejected with InvalidArgument because the whole point of the action is the message back.

RequestChangesResponse

RequestChangesResponse acknowledges the request and returns the post-write delegation chain so the dashboard can re-render without a follow-up GetApproval call.

FieldTypeLabelDescription
successboolsuccess is true when the audit row was committed. False today is unreachable — failures surface as gRPC errors, not success=false — but the field is kept so callers can branch defensively if a future wave adds soft-failure modes.
updated_chainDelegationLinkrepeatedupdated_chain is the delegation chain at the time of the write, ordered oldest → newest. Empty when no delegations exist.

RiskAssessment

RiskAssessment carries the heuristic risk score and the inputs that produced it. Fields are stable and additive; clients can ignore fields they do not yet understand.

FieldTypeLabelDescription
levelRiskLevellevel is the bucketed risk tier (see RiskLevel docs).
similar_countint32similar_count is the number of recent approvals (LookbackN=20) matching (agent_id, tool_name) for this tenant. Includes the current pending row when the dedup key already existed.
explanationstringexplanation is a human-readable, English-only sentence describing why the level was chosen — e.g. "3 of last 5 approvals for this (agent, tool) were denied". Never empty; defaults to a no-history sentence when similar_count == 0.
approved_countint32approved_count is the number of resolved-approved rows in the lookback window. Sum of approved+denied+expired may be < similar_count when some rows are still pending.
denied_countint32denied_count is the number of resolved-denied rows in the lookback window.
expired_countint32expired_count is the number of resolved-expired rows in the lookback window.

Channel

Channel identifies the adapter that recorded a decision. Dashboard is the built-in operator UI; the others are LLD 7 adapters.

NameNumberDescription
CHANNEL_UNSPECIFIED0CHANNEL_UNSPECIFIED is the zero value.
CHANNEL_DASHBOARD1CHANNEL_DASHBOARD is the operator console.
CHANNEL_EMAIL2CHANNEL_EMAIL is the signed email reply webhook.
CHANNEL_SLACK3CHANNEL_SLACK is the Slack interactive message webhook.
CHANNEL_SCM4CHANNEL_SCM is the SCM (GitHub/GitLab) review webhook.
CHANNEL_API5CHANNEL_API is a direct programmatic RecordDecision caller.

Decision

Decision is the outcome recorded by RecordDecision.

NameNumberDescription
DECISION_UNSPECIFIED0DECISION_UNSPECIFIED is the zero value; never a valid input.
DECISION_APPROVED1DECISION_APPROVED resumes the paused session with operator_input.
DECISION_DENIED2DECISION_DENIED terminates the paused session.

RecordResult

RecordResult disambiguates RecordDecision outcomes.

NameNumberDescription
RECORD_RESULT_UNSPECIFIED0RECORD_RESULT_UNSPECIFIED is the zero value.
RECORD_RESULT_OK1RECORD_RESULT_OK — first writer, state transitioned.
RECORD_RESULT_DUPLICATE2RECORD_RESULT_DUPLICATE — same decision already recorded, or idempotency_key collision. State unchanged; idempotent from the caller's perspective.
RECORD_RESULT_CONFLICT3RECORD_RESULT_CONFLICT — a different decision already won. State unchanged; channel_conflict event written for auditability.

RiskLevel

RiskLevel buckets the heuristic risk score into UI-friendly tiers. LOW = green, MED = amber, HIGH = red on the dashboard verdict bar.

NameNumberDescription
RISK_LEVEL_UNSPECIFIED0RISK_LEVEL_UNSPECIFIED is the zero value; never returned by the server.
RISK_LEVEL_LOW1RISK_LEVEL_LOW — no recent denials; non-critical template.
RISK_LEVEL_MED2RISK_LEVEL_MED — at least one recent denial OR full_pipeline template.
RISK_LEVEL_HIGH3RISK_LEVEL_HIGH — denial-rate >= 40% in recent window OR critical_path template.

ApprovalAdminService

ApprovalAdminService hosts platform-admin-only RPCs on the approval subsystem. Callers MUST carry clearance >= PLATFORM_ADMIN (100). This is a narrow, explicitly-separate service so admin surfaces and tenant surfaces cannot accidentally share an auth middleware or a Connect handler mount. Wave 2.1 (#424) migrates the previous HTTP admin endpoint (POST /internal/admin/approvals/rotate-hmac) onto this service.

Method NameRequest TypeResponse TypeDescription
EmergencyRotateHMACEmergencyRotateHMACRequestEmergencyRotateHMACResponseEmergencyRotateHMAC rotates the approval-callback HMAC key for a tenant with grace_until=now and revokes every outstanding signed link for the old key. Audit row attributes action=admin and records the Clerk subject of the admin operator. Enforced server-side: platform-admin clearance gate + per-org rate limit (1/min) to prevent a compromised admin credential from thrashing tenant HMAC secrets. See LLD §6 + PR #423 blocker 5.

ApprovalService

ApprovalService is the tenant-facing entry point for the Wave 2 approval-chain engine. All mutating RPCs are first-write-wins on approval status (founder decision #6) and dedup on (org_id, session_id, tool_name, args_sha256).

Method NameRequest TypeResponse TypeDescription
RequestApprovalRequestApprovalRequestRequestApprovalResponseRequestApproval is called from the runtime (MCP middleware / worker control plane) when a governance Check returns requires_approval. Idempotent on (org_id, session_id, tool_name, args_sha256): when an approval for the same dedup key is already pending, the existing approval_id is returned and was_deduplicated=true. Caller is responsible for invoking LifecycleService.PauseSession with correlation_id=approval_id after this returns.
RecordDecisionRecordDecisionRequestRecordDecisionResponseRecordDecision is the single converged entry point for all channels (dashboard, email webhook, Slack webhook, SCM webhook, API). Transactionally UPDATE ... WHERE status='pending' — first writer wins; losers get RECORD_RESULT_CONFLICT (different decision) or RECORD_RESULT_DUPLICATE (identical decision or idempotency_key collision). On OK: audit + approval_events written in the same tx, LifecycleService.ResumeSession (APPROVED) or TerminateSession (DENIED) invoked on the paused session.
DelegateDelegateRequestDelegateResponseDelegate transfers approval authority to another member. The delegatee MUST have clearance >= required_clearance. LLD 8 will implement the behaviour; the RPC is defined here for contract stability so channel adapters can reference it today.
GetApprovalGetApprovalRequestGetApprovalResponseGetApproval returns a single approval by id, RLS-scoped to org_id.
ListApprovalsListApprovalsRequestListApprovalsResponseListApprovals returns a paginated list of approvals for the tenant.
RequestChangesRequestChangesRequestRequestChangesResponseRequestChanges marks the approval as awaiting requester response and posts a comment to the approval thread. Powers the 'Send back for changes' button on the operator triage workspace (GAP-9). The approval row stays status='pending' and the delegation chain stays in WAITING — only an append-only audit row of type 'changes_requested' is written. The operator's free-text comment is carried in that event's payload so the dashboard timeline can render the conversation. Returns the updated chain so the client does not need a follow-up GetApproval round-trip.
ListRecentDecisionsListRecentDecisionsRequestListRecentDecisionsResponseListRecentDecisions returns approvals that have been resolved (approved

Top

upsquad/governance/v1/egress.proto

AddEntryRequest

AddEntryRequest appends a new allow-list entry for the calling tenant.

FieldTypeLabelDescription
tenant_idstringtenant_id is the owning tenant UUID.
domain_patternstringdomain_pattern is the egress target (exact host or *.suffix); no scheme, no path.
justificationstringjustification is the free-form reason string (>= 20 chars, server-enforced).
reasonReasonreason is the categorical Reason enum value for the entry.

AddEntryResponse

AddEntryResponse carries the server-materialised entry with its assigned id + created_at.

FieldTypeLabelDescription
entryAllowlistEntryentry is the newly created entry.

AllowlistEntry

AllowlistEntry is a single row of the tenant_egress_allowlist surfaced to the admin RPCs. Maps 1:1 to the PG row plus computed revoked/active state.

FieldTypeLabelDescription
idstringid is the server-assigned UUID primary key of the entry.
tenant_idstringtenant_id is the owning tenant UUID. Every entry is tenant-scoped.
domain_patternstringdomain_pattern is the egress target (exact host or *.suffix); no scheme, no path.
added_bystringadded_by is the member UUID that created the entry.
justificationstringjustification is the free-form reason string (>= 20 chars).
reasonReasonreason is the categorical Reason enum value for the entry.
created_atgoogle.protobuf.Timestampcreated_at is the wall-clock time the entry was inserted.
revoked_atgoogle.protobuf.Timestamprevoked_at is the wall-clock time the entry was soft-deleted, or unset while the entry is active.

ListAllowlistRequest

ListAllowlistRequest asks for the non-revoked allow-list entries for the calling tenant.

FieldTypeLabelDescription
tenant_idstringtenant_id is the owning tenant UUID.

ListAllowlistResponse

ListAllowlistResponse carries the current active allow-list entries.

FieldTypeLabelDescription
entriesAllowlistEntryrepeatedentries is the list of non-revoked entries ordered by created_at asc.

RevokeEntryRequest

RevokeEntryRequest soft-deletes an existing allow-list entry by ID.

FieldTypeLabelDescription
tenant_idstringtenant_id is the owning tenant UUID (double-checked against entry_id to prevent cross-tenant revocation).
entry_idstringentry_id is the UUID of the entry to revoke.

RevokeEntryResponse

RevokeEntryResponse carries the revoked entry with revoked_at set.

FieldTypeLabelDescription
entryAllowlistEntryentry is the revoked entry post-update.

Reason

Reason enumerates the allowed values of tenant_egress_allowlist.reason. The enum order is append-only; renumbering is a breaking change.

NameNumberDescription
REASON_UNSPECIFIED0REASON_UNSPECIFIED is the default/unknown sentinel; requests that send this value are rejected by the server.
REASON_MCP_INTEGRATION1REASON_MCP_INTEGRATION marks an entry created as part of enabling an MCP tool integration (auto-seeded from the integration catalog).
REASON_TENANT_WEBHOOK2REASON_TENANT_WEBHOOK marks an entry for an outbound tenant-owned webhook (approval callbacks, agent lifecycle notifications).
REASON_THIRD_PARTY_API3REASON_THIRD_PARTY_API marks an entry for a general third-party SaaS API the tenant has authorised.
REASON_INTERNAL_SERVICE4REASON_INTERNAL_SERVICE marks an entry for a platform-internal service reachable over the public internet (e.g. an isolated microservice with no private-network reach).
REASON_OTHER5REASON_OTHER is a catch-all for entries that do not fit the above categories; the justification must explain the use case.

EgressService

EgressService exposes the tenant egress allow-list admin RPCs.

Method NameRequest TypeResponse TypeDescription
ListAllowlistListAllowlistRequestListAllowlistResponseListAllowlist returns non-revoked entries for the calling tenant.
AddEntryAddEntryRequestAddEntryResponseAddEntry appends a new allow-list entry. The server enforces justification length >= 20 chars and rejects TLD-only wildcards.
RevokeEntryRevokeEntryRequestRevokeEntryResponseRevokeEntry soft-deletes an entry by ID. The audit trail is preserved.

Top

upsquad/governance/v1/governance.proto

AuditEvent

AuditEvent represents a single row from the agent_audit_log table.

FieldTypeLabelDescription
event_idstringevent_id is the primary key (UUID).
timestampgoogle.protobuf.Timestamptimestamp is when the event was created.
agent_idstringagent_id is the agent that performed the action.
session_idstringsession_id is the session in which the action occurred.
action_typestringaction_type is the type of action (e.g. "tool_call", "llm_call").
input_hashstringinput_hash is the hash of the action input.
output_hashstringoutput_hash is the hash of the action output.
detailstringdetail is the JSONB detail column serialised as a JSON string.
duration_msint32duration_ms is the action duration in milliseconds.
token_usagestringtoken_usage is the JSONB token usage column serialised as a JSON string.

CascadeTraceEntry

CascadeTraceEntry records the outcome of a single cascade layer walk.

FieldTypeLabelDescription
layerstringlayer is one of "platform", "org", "org_unit", "member".
scope_idstringscope_id is the id of the scope row walked for this layer.
verdictstringverdict is the layer-local verdict before cascade merging.
reasonstringreason is a short explanation of why this layer produced that verdict.
policy_idstringpolicy_id is the matched policy id for this layer, empty when the layer produced a default verdict with no policy row.

CheckRequest

CheckRequest carries the agent action details for governance evaluation.

FieldTypeLabelDescription
org_idstring
team_idstring
agent_idstring
member_idstring
clearanceint32
action_typestring
targetstring
metadataCheckRequest.MetadataEntryrepeated

CheckRequest.MetadataEntry

FieldTypeLabelDescription
keystring
valuestring

CheckResponse

CheckResponse carries the governance verdict.

FieldTypeLabelDescription
verdictstringverdict is one of "allow", "deny", "requires_approval".
reasonstringreason is a human-readable explanation of the decision.
denied_bystringdenied_by indicates which layer denied: "platform", "org", "org_unit", "member", or empty.
policy_idstringpolicy_id is the ID of the policy that triggered the decision.
approval_idstringapproval_id is set when verdict is "requires_approval".
cascade_traceCascadeTraceEntryrepeatedcascade_trace is the ordered list of per-layer verdicts evaluated during a 4-layer cascade Check (Wave D). Empty when the engine is configured with no CascadeStore (legacy 3-layer path).
conflict_idstringconflict_id is reserved for Wave E — always empty in Wave D.

EvaluateDryRunRequest

EvaluateDryRunRequest runs the cascade without creating approvals.

FieldTypeLabelDescription
action_typestringaction_type is the governed action (e.g. "tool_call").
targetstringtarget is the fine-grained target.
member_idstringmember_id is the caller member id.
agent_idstringagent_id is the agent performing the action (optional).
team_idstringteam_id is the legacy team id (optional).
clearanceint32clearance is the caller clearance level.
metadataEvaluateDryRunRequest.MetadataEntryrepeatedmetadata propagates any extra context.
simulate_policiesGovernancePolicyrepeatedsimulate_policies overlays candidate policies on top of persisted rows for the duration of this call.

EvaluateDryRunRequest.MetadataEntry

FieldTypeLabelDescription
keystring
valuestring

GovernancePolicy

GovernancePolicy is the stored representation of a policy row at any cascade layer.

FieldTypeLabelDescription
idstringid is the policy uuid.
org_idstringorg_id is the owning tenant.
scope_typestringscope_type is one of "org", "org_unit", "member".
scope_idstringscope_id is the org_unit id, member id, or empty string for "org".
action_typestringaction_type is the governed action (e.g. "tool_call").
targetstringtarget is the fine-grained target (e.g. "github_create_pr" or "*").
effectstringeffect is one of "allow", "deny", "requires_approval".
min_clearanceint32min_clearance is the clearance floor enforced by this policy.
conditionsstringconditions is the JSON-encoded condition map.

ListAuditEventsRequest

ListAuditEventsRequest carries optional filters and pagination for querying the agent_audit_log table. All filters are optional; omitting a filter means "match all" for that dimension. Results are returned newest-first.

FieldTypeLabelDescription
start_timegoogle.protobuf.Timestampoptionalstart_time lower-bounds the created_at filter (inclusive).
end_timegoogle.protobuf.Timestampoptionalend_time upper-bounds the created_at filter (exclusive).
agent_idstringoptionalagent_id filters events to a single agent.
action_typestringoptionalaction_type filters events by action type (e.g. "tool_call", "llm_call").
pageint32page is the 1-based page number. Defaults to 1.
page_sizeint32page_size is the number of events per page. Max 100, default 50.

ListAuditEventsResponse

ListAuditEventsResponse carries a page of audit events plus total count.

FieldTypeLabelDescription
eventsAuditEventrepeatedevents is the list of audit events for the requested page.
total_countint32total_count is the total number of events matching the filters.

ListPoliciesRequest

ListPoliciesRequest filters policies by scope layer.

FieldTypeLabelDescription
scope_typestringscope_type is one of "org", "org_unit", "member".
scope_idstringscope_id is the unit_id / member_id; empty selects all rows for the layer in the caller's org.
action_typestringaction_type optionally filters by governed action.
page_sizeint32page_size caps returned rows (default 50, max 200).
page_tokenstringpage_token is an opaque pagination token returned by a prior call.

ListPoliciesResponse

ListPoliciesResponse returns a page of policies.

FieldTypeLabelDescription
policiesGovernancePolicyrepeatedpolicies is the returned page.
next_page_tokenstringnext_page_token is empty when no more rows exist.

OrgDateScope

OrgDateScope verifies every chained session for org in [since, until). Empty since / until disables that bound.

FieldTypeLabelDescription
org_idstring
sincegoogle.protobuf.Timestamp
untilgoogle.protobuf.Timestamp

PutMemberPolicyRequest

PutMemberPolicyRequest upserts a member-scoped policy.

FieldTypeLabelDescription
member_idstringmember_id is the target member.
action_typestringaction_type is the governed action.
targetstringtarget is the fine-grained target or "*".
effectstringeffect is one of "allow", "deny", "requires_approval".
min_clearanceint32min_clearance is the clearance floor.
conditionsstringconditions is the JSON-encoded condition map.

PutMemberPolicyResponse

PutMemberPolicyResponse echoes the upserted row.

FieldTypeLabelDescription
policyGovernancePolicypolicy is the stored policy after upsert.

PutOrgUnitPolicyRequest

PutOrgUnitPolicyRequest upserts an org_unit-scoped policy.

FieldTypeLabelDescription
unit_idstringunit_id is the target org_unit.
action_typestringaction_type is the governed action.
targetstringtarget is the fine-grained target or "*".
effectstringeffect is one of "allow", "deny", "requires_approval".
min_clearanceint32min_clearance is the clearance floor.
conditionsstringconditions is the JSON-encoded condition map (may be empty).

PutOrgUnitPolicyResponse

PutOrgUnitPolicyResponse echoes the upserted row.

FieldTypeLabelDescription
policyGovernancePolicypolicy is the stored policy after upsert.

ResolveApprovalRequest

ResolveApprovalRequest asks for the resolution of a pending approval.

FieldTypeLabelDescription
org_idstring
approval_idstring

ResolveApprovalResponse

ResolveApprovalResponse carries the approval resolution result.

FieldTypeLabelDescription
verdictstringverdict is one of "allow", "deny".
reasonstringreason is a human-readable explanation.
approval_idstringapproval_id echoes back the approval ID.

SessionScope

SessionScope verifies the chain for a single (org, session).

FieldTypeLabelDescription
org_idstring
session_idstring

VerifyChainRequest

VerifyChainRequest selects the scope to verify. Exactly one of the scope oneof variants must be set.

FieldTypeLabelDescription
sessionSessionScope
org_rangeOrgDateScope

VerifyChainResponse

VerifyChainResponse reports the outcome of a verifier walk.

FieldTypeLabelDescription
okboolok is true only when every chain_epoch>=1 row in scope linked correctly (prev_hash / row_hash / content invariants all held).
total_rowsint32total_rows is the count of chained rows inspected.
broken_at_rowint32broken_at_row is 1-based within the failing session; 0 when ok.
broken_row_idstringbroken_row_id is the id of the first offending row; empty when ok.
session_idstringsession_id echoes the failing session (session scope) or the first broken session (org scope). Empty when ok.
verified_atgoogle.protobuf.Timestampverified_at is the wall-clock time the walk completed.
sessions_verifiedint32sessions_verified is the number of chained sessions walked (org scope).
sessions_brokenint32sessions_broken is the number of sessions that broke (org scope).
broken_reasonstringbroken_reason is a human-readable reason for the first break; empty when ok.

GovernanceService

GovernanceService exposes the governance engine over gRPC.

Method NameRequest TypeResponse TypeDescription
CheckCheckRequestCheckResponseCheck evaluates org + team + clearance policies for the given action.
ResolveApprovalResolveApprovalRequestResolveApprovalResponseResolveApproval polls for an approval resolution until resolved or timeout.
PutOrgUnitPolicyPutOrgUnitPolicyRequestPutOrgUnitPolicyResponsePutOrgUnitPolicy upserts a governance policy scoped to a single org_unit (Wave D — 4-layer cascade). Requires guardrails.edit on the target org_unit.
PutMemberPolicyPutMemberPolicyRequestPutMemberPolicyResponsePutMemberPolicy upserts a governance policy scoped to a single member (tightest cascade layer; overrides org_unit / org). Requires guardrails.edit.
ListPoliciesListPoliciesRequestListPoliciesResponseListPolicies returns paginated governance policies filtered by scope_type (org
EvaluateDryRunEvaluateDryRunRequestCheckResponseEvaluateDryRun runs the 4-layer cascade without mutating state, returning the full cascade_trace for UI preview / debugging. Does NOT create approval rows.
ListAuditEventsListAuditEventsRequestListAuditEventsResponseListAuditEvents returns a paginated list of audit log entries for the calling tenant, with optional time-range and attribute filters.

Deprecated: use upsquad.audit.v1.AuditService.ListAuditEvents instead. This method is retained for backward compatibility with client portal versions deployed before the AuditService extraction (#404) and will be removed after the portal migration window closes. | | VerifyChain | VerifyChainRequest | VerifyChainResponse | VerifyChain walks the audit-log hash chain for the requested scope and reports integrity. Available scopes: a single session, or an org over a date range. Authorisation is enforced at the gateway (COMPLIANCE_AUDITOR clearance or above). See LLD docs/lld/wave1-item4-audit-hash-chain.md.

Deprecated: use upsquad.audit.v1.AuditService.VerifyChain instead. See the note on ListAuditEvents above — same migration window. |

Scalar Value Types

.proto TypeNotesC++JavaPythonGoC#PHPRuby
doubledoubledoublefloatfloat64doublefloatFloat
floatfloatfloatfloatfloat32floatfloatFloat
int32Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead.int32intintint32intintegerBignum or Fixnum (as required)
int64Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead.int64longint/longint64longinteger/stringBignum
uint32Uses variable-length encoding.uint32intint/longuint32uintintegerBignum or Fixnum (as required)
uint64Uses variable-length encoding.uint64longint/longuint64ulonginteger/stringBignum or Fixnum (as required)
sint32Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s.int32intintint32intintegerBignum or Fixnum (as required)
sint64Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s.int64longint/longint64longinteger/stringBignum
fixed32Always four bytes. More efficient than uint32 if values are often greater than 2^28.uint32intintuint32uintintegerBignum or Fixnum (as required)
fixed64Always eight bytes. More efficient than uint64 if values are often greater than 2^56.uint64longint/longuint64ulonginteger/stringBignum
sfixed32Always four bytes.int32intintint32intintegerBignum or Fixnum (as required)
sfixed64Always eight bytes.int64longint/longint64longinteger/stringBignum
boolboolbooleanbooleanboolboolbooleanTrueClass/FalseClass
stringA string must always contain UTF-8 encoded or 7-bit ASCII text.stringStringstr/unicodestringstringstringString (UTF-8)
bytesMay contain any arbitrary sequence of bytes.stringByteStringstr[]byteByteStringstringString (ASCII-8BIT)