Visual for CLS Closed-Loop System CLS CLS is Nova's Closed-Loop System for verified browser actions: actions become reliable only when Nova can observe the expected result or make uncertainty visible. Overview Verifies Agent model Agent flow When it applies Failure rules MCP contract Agent Tools

CLS

CLS stands for Closed-Loop System. Nova uses it to treat browser actions as verifiable state transitions: an action is not reliable just because a click, input, or submit was dispatched.

CLS belongs to moments where an agent changes page state. Nova can check preconditions, dispatch the action, observe the result, and report whether the expected postcondition was confirmed, contradicted, or still unclear.

This prevents false success. If the page confirms the intended result, the agent can continue from the new state. If the page shows an error, remains ambiguous, or the action never reached the page, the next step should repair, observe again, or stop safely.

CLS connects execution with memory. TOB supplies observed evidence, OK supplies current service facts, PKS can learn from verified successes and failures, and ETM can use the result when deciding whether a task run is really complete.

In short

  • Dispatch is not proof that a browser action succeeded.
  • Commit-point actions need preconditions and postconditions when they can send, submit, log in, switch state, or otherwise change a service.
  • CLS separates pre-dispatch blocks from post-dispatch uncertainty so agents do not repeat dangerous actions blindly.
  • Verified outcomes can feed task progress, PKS health, ALP review, and later guidance.
  • CLS does not grant permission by itself; Nova safety gates and user control still apply.

What CLS verifies

CLS checks the parts of an action that are easy to confuse when an agent only sees tool success.

  1. Preconditions Before dispatch, the current page must still match the expected starting state. If the precondition fails, the action should not run.
  2. Dispatch Nova reports whether the action actually reached the page. A pre-dispatch block is different from a click that fired but did not produce the expected result.
  3. Postconditions After dispatch, Nova checks success, forbidden, and ambiguous signals. This is where “sent” becomes “confirmed”, “failed”, or “unclear”.
  4. Retry safety CLS tells the agent whether it may retry, must not retry, or should check the postcondition first because a repeat could duplicate the action.
  5. Goal resume When a closed-loop goal is active, Nova can expose the current step so an agent can resume after context compression without guessing where it left off.
  6. Learning feedback Verified outcomes provide stronger evidence for task completion, PKS health, and later learning than a raw tool success.

When this matters

Use CLS for actions where the result changes state and a blind retry would be risky: sending a message, submitting a form, confirming a login, changing a model or workspace, dismissing an overlay that controls access, or closing a task step that should only count after visible proof.

CLS model for agents

For an agent, CLS answers four questions: what goal is active, what pre-action state must hold, what result proves success or failure, and what should happen if the result is unclear?

Goal
A durable work objective on a target. It can contain ordered steps and appears as goalContext when active.
Step
One action inside a goal. A step can be planned, dispatched, verifying, done, ambiguous, failed, blocked, or aborted.
Transition contract
The structured agreement for one meaningful action: preconditions, action kind, postconditions, retry policy, and ambiguity policy.
Assertion
A machine-checkable condition such as a fact existing, matching a value, changing, or becoming absent. Assertions can be grouped as all, any, or forbidden.
Guarded commit
The result object that tells the agent what CLS did: dispatch status, verification status, retry advice, failed assertions, and timing.
Action dispatch
The point where the page was actually touched. If actionDispatched is true, a retry may duplicate a submit, send, or state change.
Postcondition-first retry
A recovery rule for non-idempotent actions: inspect the result first, then decide whether another dispatch is safe.

How agents use CLS information

CLS gives agents a verification loop around actions that matter. The agent should read the page, bind or resume the goal, use a guarded action, and then let the returned state decide the next move.

  1. Read the page and goal context The agent starts with nova.perceive. If goalContext is present, it reads the active step before acting.
  2. Create or query a goal when work spans steps For multi-step work, nova.goal_register can create, query, close, or annotate the active closed-loop goal.
  3. Use a guarded commit tool for meaningful actions For common commit points, the agent prefers nova.guarded_send_message, nova.guarded_submit_form, nova.guarded_login, nova.guarded_switch_model, or nova.guarded_switch_sandbox.
  4. Provide a transition contract when using raw input tools If the agent uses nova.click_selector or nova.type_selector for a commit point, it supplies transitionContract with preconditions and postconditions.
  5. Read dispatch and verification separately The agent checks actionDispatched, guardedCommit.dispatchStatus, guardedCommit.verificationStatus, and guardedCommit.retryAdvice.
  6. Continue only from verified state Verified success can advance. Verified failure, a blocked precondition, or an indeterminate result should trigger repair, another observation, or a safe stop.

When CLS state applies

CLS state is trustworthy only inside the current target and action context. A previous result is not permission to assume the page still looks the same after navigation, reload, user interaction, or another agent action.

No active goal goalContext=null
Meaning
Nova has no active closed-loop goal for the current target or owner.
Evidence required
No goalContext appears in the page read. Goal queries can still show terminal or stale states such as completed, failed, aborted or orphaned.
Agent behavior
Use normal page observation, or create a goal if the work needs durable step tracking.
May continue
Only for simple actions.
Active goal goalContext.state=active
Meaning
A closed-loop goal is active and can be resumed.
Evidence required
A current goalId, summary, currentStep, and optional stepStatus are visible to the agent.
Agent behavior
Continue from the current step, not from memory or a guessed plan.
May continue
Yes, after checking the page.
Precondition blocked blocked_precondition
Meaning
The action did not dispatch because the expected start state did not hold.
Evidence required
The response has actionDispatched=false and guardedCommit.preconditionVerdict=failed or a matching reason code.
Agent behavior
Repair the page state or update the contract. Do not claim the action happened.
May continue
No.
Dispatch confirmed actionDispatched=true
Meaning
The action reached the page. The result still needs postcondition interpretation.
Evidence required
The response says actionDispatched=true, possibly with guardedCommit.verificationStatus.
Agent behavior
Do not blindly repeat non-idempotent sends, submits, or login commits.
May continue
Only after verification.
Verified success verified_success
Meaning
Observed page or service state satisfies the success postcondition.
Evidence required
The guarded result returns guardedCommit.verificationStatus=verified_success.
Agent behavior
Advance the goal step, continue the task, and let learning systems use the result as stronger evidence.
May continue
Yes.
Verified failure verified_fail
Meaning
A forbidden or failed outcome was observed after dispatch.
Evidence required
The guarded result returns verified_fail or top-level reasonCode=guarded_commit.postcondition_failed.
Agent behavior
Treat the step as failed and repair from the visible error state.
May continue
No.
Indeterminate indeterminate
Meaning
Nova could not prove success or failure from the available signals.
Evidence required
The result includes indeterminateReason such as ambiguous_signal, page_navigated, timeout, or eval_error.
Agent behavior
Follow retryAdvice. For non-idempotent actions, check the postcondition before any retry.
May continue
Not yet.
Coordinator or goal block blocked_goal|blocked_coordinator
Meaning
The target or goal is already reserved, mismatched, or not in a dispatchable state.
Evidence required
Dispatch status or reason code shows blocked_goal, blocked_coordinator, guarded_commit.coordinator_busy, or guarded_commit.dispatch_prepare_rejected.
Agent behavior
Wait, query the goal, or re-check postconditions before retrying.
May continue
No.

Failure and guard conditions

These are the hard edges an agent or integration should expect from CLS contracts.

Condition Observed signal Agent behavior
Commit point without contract A raw click or submit-like typing action is classified as a commit point and lacks transitionContract; the reason code is guarded_commit.missing_contract. Use a guarded macro or provide transitionContract.postconditions. The action is blocked before dispatch.
Unknown contract field Unknown fields inside transitionContract, postconditions or assertion sets produce invalid params. Fix the request shape instead of assuming extra fields are ignored.
Empty postconditions Commit-point contracts without non-empty success, forbidden or ambiguous buckets fail closed. Define at least one observable result condition before dispatch.
Precondition failed Reason code guarded_commit.precondition_failed and actionDispatched=false. Repair or re-read the page. Do not retry the action until the starting state is true.
Precondition evaluation error Reason code guarded_commit.precondition_error. Treat this as fail-closed. Simplify the assertion or gather a better fact source.
Coordinator busy Reason code guarded_commit.coordinator_busy and often retryAfterMs=1000. Wait for the in-flight guarded action to finish before trying again.
Postcondition failure Top-level status can become failed with reasonCode=guarded_commit.postcondition_failed. Handle the visible failure; do not report the step as complete.
Ambiguous result after dispatch Top-level status can become partial with reason codes such as guarded_commit.ambiguous_signal, guarded_commit.page_navigated, guarded_commit.frame_destroyed, guarded_commit.eval_error, guarded_commit.no_signal_yet or guarded_commit.timeout. Follow retryAdvice and inspect the postcondition before repeating non-idempotent actions.

Agent interpretation example

The example shows CLS as a contract: the agent states the action goal, Nova verifies the postcondition, and the response tells the agent whether the next step may continue.

Guarded action request

{
  "tool": "nova.guarded_send_message",
  "arguments": {
    "targetId": "active",
    "text": "Please summarize the selected article.",
    "transitionContract": {
      "postconditions": {
        "success": {
          "any": [
            {
              "factKey": "chat.streamActive.started",
              "operator": "eq",
              "expected": true
            },
            {
              "factKey": "chat.assistantTurnCreated",
              "operator": "eq",
              "expected": true
            }
          ]
        }
      }
    }
  }
}

Relevant response fields

{
  "structuredContent": {
    "ok": true,
    "status": "ok",
    "actionDispatched": true,
    "guardedCommit": {
      "dispatchStatus": "dispatched",
      "verificationStatus": "verified_success",
      "retryAdvice": "do_not_retry",
      "outcomeVerdict": "satisfied"
    }
  }
}

Agent interpretation

{
  "treatAs": "verified action outcome",
  "mayContinue": true,
  "doNotRepeat": "actionDispatched is true and the send is non-idempotent",
  "memorySignal": "success can support task progress and future learning"
}

MCP contract

This is the deterministic layer below the explanation. It lists CLS fields that agents and integrators should treat as contract signals rather than free prose.

Execution rule: No commit-point action is complete until its current postcondition is observed or uncertainty is explicitly surfaced.

Variable Type / values Default Effect
goalContext object or null on perception responses null when no active goal applies Resume anchor for the active closed-loop goal on the current target.
goalContext.goalId / summary string; string computed Identifies the current goal and gives the agent a compact human-readable goal anchor.
goalContext.mode agent_driven | runtime_assisted | fully_autonomous agent_driven on goal create Indicates how much of the goal is controlled by the agent versus runtime assistance.
goalContext.state active active when surfaced Perception surfaces only active goal context for resume. Goal queries can also show terminal states.
goalContext.currentStep / totalSteps integer; integer computed Shows where the agent is inside the active step plan.
goalContext.stepStatus planned | ready | blocked | dispatched | verifying | done | ambiguous | failed | aborted | null null when no step exists Tells the agent whether the current step is still planned, already dispatched, verifying, finished, or blocked.
goalContext.stepAction string or null null Human-readable action description for the current step.
nova.goal_register MCP tool available in CLS-capable Nova sessions Creates, queries, closes, or annotates closed-loop goals.
op create | query | close | annotate required Selects the goal register operation.
targetId string create defaults to active; query optional; interaction tools default to active when omitted Scopes a goal or action to the intended browser tab or sandbox target.
agentId string optional on guarded action tools Identifies the calling agent for guarded macros and claim-aware execution. It is agent metadata, not user-visible page state.
goalId string required for close/annotate and targeted query Identifies the goal being queried, closed, or annotated.
summary string required for create Defines the goal summary that later appears in goalContext.
mode agent_driven | runtime_assisted | fully_autonomous agent_driven Defines goal execution style.
preconditions assertion set optional on goal create Stores goal-level conditions that should already hold when the goal opens.
ownerAgentId / sidecarSessionId string; string optional Binds a goal to an agent owner or sidecar session for safer resume and handoff. When omitted, no owner or session binding is set.
leaseMs integer 1000-600000 120000 Limits how long a goal lease may stay alive without progress.
steps array, max 50 optional Defines an ordered step plan for the goal.
steps[].actionDesc string required for each step Names a goal step for agent resume and activity tracking.
steps[].contract transitionContract object optional Stores the closed-loop contract for this step.
includeSteps / includeEvents / eventsLimit boolean; boolean; integer 1-200 true; false; 50 Controls how much step and event detail a goal query returns.
state completed | failed | aborted required for close Closes a goal with a terminal state.
content / source string; string content required for annotate; source defaults to agent Adds an annotation event to a goal.
legacy aliases preconditionsJson, steps[].contractJson, ownerAgent, ownerSession, leaseTimeoutMs accepted for compatibility Compatibility names for older clients. New integrations should prefer structured fields and must not mix structured and legacy forms.
transitionContract object on click/type/guarded tools required for detected commit points; auto-generated by guarded macros Defines preconditions, postconditions, retry policy, ambiguity policy, and stability settings for one state-changing action.
transitionContract.actionKind dismiss_overlay | send_message | submit_form | select_option | custom custom for raw contracts; macro-specific for guarded tools Selects action-specific stability defaults.
transitionContract.preconditions assertion set: all / any / forbidden optional Conditions that must be evaluated before dispatch. Failed preconditions block the action.
transitionContract.postconditions.success / forbidden / ambiguous assertion sets at least one non-empty bucket for commit points Defines which observed outcomes count as success, failure, or ambiguity.
assertion.factKey / operator / expected / frameId string; eq | not_eq | neq | exists | not_exists | contains | gt | lt | gte | lte; JSON; string or null factKey and operator required Single machine-checkable condition used inside preconditions or postconditions.
transitionContract.retryPolicy idempotent | non_idempotent | no_retry non_idempotent Controls whether a repeat dispatch may be safe. Sends, submits, and logins are usually non-idempotent.
transitionContract.ambiguityPolicy signal | retry_once | abort signal Controls how ambiguous postcondition matches influence retry advice.
transitionContract.stabilityWindowMs / stabilityMs integer 500-30000; integer 0-5000 action template defaults Optional observation window and hold duration. Runtime clamps values to guarded-safe bounds.
actionDispatched boolean computed True only after the page was actually touched. If true, agents must avoid blind duplicate sends/submits.
guardedCommit.transitionId string generated Correlates one guarded transition through dispatch and verification.
guardedCommit.dispatchStatus dispatched | blocked_precondition | blocked_goal | blocked_coordinator computed Says whether the action dispatched or was blocked before reaching the page.
guardedCommit.verificationStatus verified_success | verified_fail | indeterminate | skipped | pending computed Post-action outcome classification.
guardedCommit.indeterminateReason no_signal_yet | ambiguous_signal | page_navigated | frame_destroyed | timeout | eval_error | null null Explains why CLS could not prove success or failure.
guardedCommit.retryAdvice safe_to_retry | do_not_retry | check_postcondition_first computed Guides recovery after failure or uncertainty.
guardedCommit.preconditionVerdict / outcomeVerdict satisfied | failed | unknown | null computed Shows whether the evaluated precondition or postcondition assertion set passed.
guardedCommit.failedAssertions[] factKey, op, expected, observed, passed, error only when assertions fail or are unknown Shows which assertion caused a block, failure, or ambiguous result.
guardedCommit.startedAt / completedAt / durationMs integer timestamps; integer duration computed Shows when guarded verification started, when it ended, and how long it took.
stage / verifyState / retryAdvice string; verified | likely | uncertain | failed; retry advice string or null computed when supported by the tool Compact top-level orientation for where the tool stopped, how strong ad-hoc verification was, and whether recovery needs caution.
status / reasonCode / retryable / retryAfterMs top-level response signals computed Compact tool result signals for blocked, partial, failed, or retryable outcomes.
Agent Tools

MCP tools for agents. These variables and tool names are intended for agents and integrators. They are not normal user controls in the interface.

Variable Meaning
nova.goal_register Record a work goal
nova.guarded_send_message Send a message with outcome checks
nova.guarded_submit_form Submit a form with outcome checks
nova.guarded_switch_model Switch model with outcome checks
nova.guarded_switch_sandbox Switch sandbox with outcome checks
nova.guarded_login Run a guarded login flow
nova.perceive Reads the current page and can return the active closed-loop goal context.
nova.click_selector Clicks a selector or CTA reference; commit-point clicks can use a transition contract and return a guarded commit result.
nova.type_selector Types into a selector; submit-style typing can use a transition contract and return a guarded commit result.