Approvals

The operator review queue that gates code changes and capital-tier promotions — pending vs history, the smart classifier, approval modes, and bulk actions.

The approval queue is where you, the operator, sign off on the changes the system wants to make to itself. It governs two classes of action: code-level changes an agent proposes (code edits, skill-update proposals, config changes) and capital-tier promotions that move a strategy toward real risk. Nothing in either class advances without passing through this queue — unless you have explicitly told it otherwise.

The queue lives at the /approval route. Policy that decides which actions need review lives at /settings/approvals. This page covers both: how to clear the queue day to day, and how to tune what lands in it.

Forven is a research tool. Approving a promotion records your decision to advance a strategy through the pipeline; it does not predict that the strategy will be profitable, and nothing here is financial advice. Approvals are a discipline gate, not a forecast.

Why approvals exist

The brain orchestrates the pipeline, and agents do the work — but agents never act on capital or change code on their own. When the brain reaches a transition that consumes something irreversible (your money, your codebase), it does not execute. It files an approval row and waits for a human.

Concretely, an approval is created when:

  • A code-edit or config task is queued (code_change, code_fix, code_strategy, config_change, strategy_archive) whose task_type is in approval_required_task_types.
  • The brain queues a promotion to a capital-consuming stage — a strategy_promotion_approval (advancing toward paper or live) or a strategy_dethrone_recommendation.
  • A skill-update proposal (skill_update_proposal) wants to write to the memory bank.

One important carve-out: if the actor that triggered the change is already a human or first-class caller — api, manual, user, or ui — no approval row is created. The reasoning is that you already expressed intent by taking the action directly. The queue exists to gate autonomous actions, not your own.

Pending vs History

The /approval page has two views:

  • Pending — items awaiting a decision. This is your work queue.
  • History — past decisions (approved, denied, revised). This is your audit trail.

Each pending item is a card showing the change being proposed, the strategy or target it affects, and two badges:

  • An approval-mode badge (smart / manual / off) telling you which policy governs this type of item.
  • A classifier badge (auto_approve / escalate / hold) — the smart classifier's recommendation, if it has run.

The smart classifier

Every pending item can be run through a smart-approval classifier — an ML recommendation that decides how the item should be routed. It weighs the approval type, the target, prior history, and your operator preferences, then returns one of:

  • auto_approve — low-risk, matches a pattern you have approved before.
  • escalate — needs a closer look; possibly hand off to the escalation owner.
  • hold — do not auto-act; wait for explicit review.

The classifier is advisory. It populates the badge and enables bulk actions; it never decides on its own unless the relevant approval mode is set to let it (see below). If a recommendation is missing or stale, re-run it with the Classify action on the row, which calls POST /api/approvals/{approval_id}/classify.

Smart mode requires the classifier to have run. If you set a type to smart but never classify its items, they sit in Pending like any manual item.

Approval modes

Each approval type has a mode that governs how strictly it is reviewed. The mode is policy — it is configured at /settings/approvals, and the /approval page reflects it but does not set it.

Mode (UI)BehaviorPublic/API synonym
smartAuto-approves rows the classifier marks auto_approve; everything else waits for you.mixed
manualAlways requires an operator decision, regardless of classifier output.manual
offAuto-approves everything of this type — no review.auto

The API surface uses the words manual / auto / mixed; the settings UI presents them as manual / off / smart. They are the same three policies. Modes are read via GET /api/approvals/modes, which also returns per-type deadlines (escalation if an item is not acted on in time) and the configured escalation owner.

Choose deliberately:

  • manual is the safe default for anything touching capital or code.
  • smart is a reasonable middle ground once the classifier has learned your patterns for a low-stakes type.
  • off removes the human entirely. Use it only for types you are certain are harmless.

Auto-approval toggles

The /approval page also exposes two coarse, page-level toggles for the highest-leverage types:

  • Promotions — auto-approve all strategy promotions.
  • Code edits — auto-approve all code changes.

Each toggle pops a confirmation warning before it takes effect, because each one removes a human from a consequential loop. Flipping a toggle updates the underlying bot-operations settings — it is the same policy surface as the per-type modes, exposed as a fast switch.

The inspector drawer

Click Details on any approval to open the inspector — a right-hand drawer (roughly 780px wide) with two analysis tabs:

  • Diagnosis — the troubleshoot timeline and root-cause analysis. For approvals tied to a failed task, this is where you see why it failed and the recommended fix. You can launch a fresh troubleshoot run from here.
  • Execution — a live watch on the linked task's timeline: tool calls, status, and output as the work runs.

Together these let you make an informed call without leaving the page: Diagnosis tells you what the change is and whether it is sound; Execution lets you watch the result if you approve.

The inspector is a modal drawer. It is reachable by deep link via the ?approval_id= query parameter (for example /approval?approval_id=123), but closing it resets context — it is not a navigable page of its own.

Steps: review and clear a pending change

  1. Open /approval and stay on the Pending view.
  2. Scan the cards. If a row has no classifier badge and you want a recommendation, click Classify to run the smart classifier on it.
  3. Click Details to open the inspector drawer.
  4. Read the Diagnosis tab for the root cause and recommended fix.
  5. Switch to the Execution tab to watch the linked task timeline if the work is already running.
  6. Decide:
    • Approve — the change proceeds; the linked task transitions to running.
    • Deny — the change is rejected; the task stays pending and can be resubmitted or cancelled.
    • Revise — bounce it back for rework. Enter feedback in the field below the card, then click Revise.
    • Handoff — assign it to the escalation owner instead of deciding yourself.
  7. The item moves to History once decided.

What you'll see: the card leaves the Pending list and appears in History with your decision and timestamp. If you approved a promotion, the strategy advances to its next pipeline stage; if you approved a code edit, the linked task begins executing and you can follow it in the task queue.

Bulk approve

When several items share the classifier's auto_approve recommendation, you do not need to clear them one by one. Bulk approve acts on all currently auto_approve-classified rows at once — useful after a discovery run produces a batch of similar, low-risk promotions. Classify first, confirm the recommendations look right, then bulk approve.

The decision actions, by API

If you script against the local API, the approval actions map to these operator-gated endpoints under /api/approvals (all require the operator key — see the REST & WebSocket API reference):

GET   /api/approvals                       List approvals (filter by status/type/target/owner)
POST  /api/approvals/{id}/approve          Approve
POST  /api/approvals/{id}/deny             Deny
POST  /api/approvals/{id}/revise           Send back for rework (with feedback)
POST  /api/approvals/{id}/classify         Re-run the smart classifier
GET   /api/approvals/modes                 Get modes + deadlines + escalation owner

A minimal approve from PowerShell, against the local backend on 127.0.0.1:8003:

$headers = @{ "x-operator-key" = $env:FORVEN_OPERATOR_KEY }
Invoke-RestMethod -Method Post `
  -Uri "http://127.0.0.1:8003/api/approvals/123/approve" `
  -Headers $headers

Relationship to autonomy

Approvals are the per-item gate. They are distinct from — and complementary to — the system-wide autonomy modes, which decide whether the brain is even allowed to generate the kind of work that produces approvals. In manual autonomy, the autonomous loops are frozen, so few approvals appear; in auto, the pipeline runs end to end and the queue is where you stay in the loop. Think of autonomy mode as the throttle and the approval queue as the steering wheel.

Caveats

  • Policy is backend-enforced. The /approval page reflects modes but cannot set them — change them at /settings/approvals (or via config). Setting a type to smart without ever running the classifier leaves its items waiting in Pending.
  • The inspector resets on close. Deep links via ?approval_id= work, but closing the drawer clears context; there is no standalone approval URL.
  • Revise is not a soft approve. Revising bounces the change back to the agent with your feedback; the task stays open until it is resubmitted and approved.
  • Auto-approval removes a human from a consequential loop. The off mode and the page-level toggles exist for low-stakes types — be deliberate about which ones you trust.
  • Promotion gates — the automated checks an approval sits on top of.
  • Agents — the brain and agent layer that file approvals.
  • Autonomy modes — the system-wide throttle that governs how much lands in the queue.