- Your access policy decides which invocations dispatch immediately.
- Invocations your policy holds require an approval record before dispatch.
- Approval or denial applies to one exact invocation.
- Every outcome is recorded under the original user-facing request.
The approval gate
Agents and unprivileged callers do not receive a tool that can turn a pending request into an approved one. The human decision arrives through a separate approval surface.What your policy is
Code in your runner repository. There is no rule builder and no JSON: a policy is a function that receives one invocation and returns a decision.because is shown to whoever approves and stored on the audit record, so write
it as the sentence you would want an approver to read.
An action carries its own policy in its own file, next to the code it
governs, and reads that action’s typed input:
policy.ts at the runner package root:
environment (the environment the call is dispatched to)
and via ("human" or "agent").
A capability with no policy falls to its hazard: reads dispatch, writes and
delegated code wait for a human. Writing no policy at all changes nothing.
A
never is an answer, not a step toward one. Nothing is recorded as pending
and no approver is asked, so it cannot be released by clicking a button.Gating on effect, not on arguments
Most capabilities name their target in their arguments, so a policy readsinput. A SQL predicate does not: update orders set status = 'x' where …
names its rows only when it is evaluated.
So Postgres writes preview themselves. The statement is rewritten into a read
that reports the exact rows it would change, the columns it would assign, and
every table a foreign key would carry it into. Your policy decides on that:
Direct web writes from an authenticated organization owner or admin can use
inline self-approval: the control plane creates and records the approval under
that web identity, then dispatches without a second approval card. Member
requests that the policy holds remain pending. Delegated code with hazard
unknown always remains pending for separate review.What an approver reviews
An approval is tied to the invocation already recorded by the control plane:The stable operation name and human-readable title.
The project and environment whose runner would execute the operation.
The schema-validated input for this invocation.
The caller attribution carried from Slack, MCP, the web app, or another
configured interface.
Approve or deny, plus the decision time and approver attribution available
from the configured approval channel.
Pending approval lifecycle
Slack, MCP, and member-initiated web invocations that the policy holds, along withunknown delegated workloads, follow this pending path:
1
Create the request
The caller submits a typed action. The control plane validates its routing
context and sees that the policy holds it for approval.
2
Persist pending state
The control plane creates an approval request linked to the original ask and
capability invocation. It does not dispatch the work yet.
3
Notify a human
Polycore presents the operation, target, and arguments in the configured
approval surface, such as Slack or the web dashboard.
4
Apply one decision
The approval store accepts one transition out of pending state. A repeated
or conflicting decision cannot release the same request twice.
5
Dispatch or close
Approval releases the recorded invocation to the selected runner. Denial
closes it without downstream execution.
6
Record the outcome
Success, failure, or denial remains linked to the requester, approver,
project, environment, capability, and timing.
Audit model
Polycore records two useful levels of activity.Request
One user-facing ask, including its caller, interface, input, overall
outcome, and final answer. A request may involve more than one governed
operation.
Capability invocation
One dispatch attempt under that request, including capability, arguments,
project, environment, runner, duration, result, and linked approval when
applicable.
Example: one request, two invocations
What is recorded
Audit records may include:- Caller and originating interface.
- Project, environment, and runner.
- Capability name. Approval records also carry the gated hazard.
- Validated arguments.
- Start time, duration, and outcome.
- A structured result or failure, capped at approximately 32 KiB of JSON with explicit truncation metadata when the cap is exceeded.
- Approval status and decision attribution.
- The final user-facing answer for agent requests.
Inputs and outputs can contain customer data even though credentials stay
runner-side. During integration, we identify sensitive fields, keep outputs
bounded, and decide where actions should redact or summarize data before it
returns.
Interface behavior
- Slack
- MCP
- Dashboard
A request your policy clears replies in the conversation. A held request
produces an approval card and waits. The outcome returns to the same request
context.
Validation checklist
Before a policy-gated capability is considered ready, we verify:The runner executes no policy-gated dispatch without an approval decision
recorded for that invocation.
Denial leaves the downstream system unchanged and remains visible in audit.
Repeated decisions do not execute the invocation twice.
Downstream failures are recorded and shown to the requester without being
reported as success.
Caller, target environment, arguments, and approver context are reviewable
together.

