VIEWPORT
For teams

Approval policies

Who decides what, when it auto-approves, and how long it waits. Per-workflow tuning that scales the team.

The default Viewport policy is "everyone in the routing audience can approve, first-resolves wins." That's the right default for most flows. Once your team grows, you tune.

What you can tune

Per-workflow, in the YAML:

approvals:
  plan_review:
    routing:
      audience: team:platform        # or user:..., share_group:..., role:admin
      auto_approve_if:
        - files_changed_lte: 5
        - changed_paths_match: ["*.test.ts", "*.md"]
      ttl: 30m
      on_timeout: auto_deny           # | escalate | hold

  approval_gate:
    routing:
      audience: share_group:on-call
      ttl: 5m
      on_timeout: escalate
      escalate_to: team:platform

  context_candidate:
    routing:
      audience: team:platform
      auto_approve_if:
        - source_session_authored_by_user
        - confidence_gte: 0.8
      ttl: 24h
      on_timeout: auto_deny

Every field is optional. Defaults are sensible: team-of-creator or share-with-list as the audience, 1h TTL, auto-deny on timeout, no auto-approve.

Routing audiences

Audience expressionWho sees the item
user:alice@acme.comOne specific person.
team:platformAll current members of the team. Membership changes apply immediately.
share_group:on-callAll current members of the share group.
role:adminAnyone with admin role on the workspace.
role:ownerThe single org owner.
routed_shareWhoever has share access to the underlying resource. (Default.)

Multiple audiences can be combined:

audience:
  - team:platform
  - share_group:on-call

The audience is the union of the listed sets.

Auto-approve rules

Each rule is a boolean predicate that, if true, skips the human and writes the auto-approval to the audit log. Available predicates (and more in the reference):

  • files_changed_lte: N
  • lines_changed_lte: N
  • changed_paths_match: ["..."]
  • cost_estimate_usd_lte: 0.50
  • source_session_authored_by_user
  • confidence_gte: 0.8
  • tags_include: ["safe"]
  • tags_exclude: ["destructive", "auth"]
  • hour_of_day_between: [9, 18]

Predicates AND together. To OR, use multiple auto_approve_if blocks. (We may add explicit any: syntax later.)

TTL and timeout behavior

ttl: 30m
on_timeout: auto_deny | escalate | hold
  • auto_deny. The agent gets a deny signal. Workflow takes the deny branch (or stops, if no branch is declared).
  • escalate. Pair with escalate_to: .... The item re-routes to a new audience after the TTL.
  • hold. The item stays open forever. Useful for non-time-sensitive gates that just need a thoughtful human.

TTL accepts 30s, 15m, 1h, 24h, 7d.

Per-environment overrides

For a workflow that runs in both dev and prod, you can override per environment:

approvals:
  approval_gate:
    routing:
      audience: team:platform
    environments:
      dev:
        auto_approve_if:
          - tags_include: ["dev-safe"]
      prod:
        audience: role:admin
        ttl: 1h
        on_timeout: escalate
        escalate_to: team:platform-leads

environments overlays on top of the base block. Unspecified fields inherit.

Per-actor overrides

Trust a senior dev to auto-approve their own plans up to a higher threshold:

approvals:
  plan_review:
    actor_overrides:
      - actor: user:lead@acme.com
        auto_approve_if:
          - files_changed_lte: 20

Their own sessions auto-pass to that limit. Other actors fall back to the global rule.

Audit log of every decision

Every auto-approve, every human decision, every escalation, every timeout writes a row to the audit log with the actor (or system:auto-approve / system:timeout), the inbox item id, the rule that fired, and the resulting state. See Audit log.

Common patterns

Pattern: aggressive auto-approve for docs.

plan_review:
  auto_approve_if:
    - changed_paths_match: ["docs/**", "*.md"]
    - files_changed_lte: 20

Pattern: never auto-approve auth.

plan_review:
  routing:
    audience: role:admin
  exclude_auto_approve_if:
    - changed_paths_match: ["**/auth/**", "**/login/**", "**/middleware/auth*"]

exclude_auto_approve_if is a hard veto on auto-approval. Any matching rule kills auto and forces human review.

Pattern: on-call routing with team escalation.

approval_gate:
  routing:
    audience: share_group:on-call
    ttl: 10m
    on_timeout: escalate
    escalate_to: team:platform

If on-call doesn't decide in 10 minutes, the whole platform team gets paged.

Where to go next

On this page