Planning and Validation

Overview

This section explains how workflows are validated, planned, and optimized in the LINQ SDK.

  1. Validation ensures your workflow is structurally correct and free of configuration errors.

  2. Planning uses the Intelligent Scheduling Engine to generate an optimized execution schedule for a workcell.

Validation must succeed before planning can occur.

Planning may incorporate:

  • Hard constraints (dependencies and time constraints)

  • Soft timing preferences (planning_targets)

  • Optimization configuration (PlannerOptions or sequential Optimization Stages)


Validation

Validation checks structural, deterministic, and configuration-level characteristics of a workflow to ensure it can be planned.

Validation occurs in the LINQ Cloud environment.

Validation does not guarantee successful execution — it guarantees the workflow is structurally plannable.

Warning

Validation does not guarantee a workflow will run without issue.

Validation via Python

workflow = Workflow(...)

result = linq.validate_workflow(workflow)

Optional execution-level validation

result = linq.validate_workflow(workflow, validate_for_execution=True)

You can also validate for infeasibility issues:

result = linq.validate_workflow(workflow, validate_for_infeasibility=True)

Validation via CLI

linq workflow validate <path>

Optional flags:

linq workflow validate <path> --validate-drivers
linq workflow validate <path> --validate-infeasibility

What Is Validated?

Core Workflow Structure

  • Task dependencies are logically consistent (no circular references)

  • Time constraints are feasible

  • Slots are correctly defined and non-conflicting

  • Required configuration values are present

Timing Targets (planning_targets)

If planning_targets are defined:

  • Referenced task IDs must exist

  • Anchor edges (start / end) must be valid

  • Span definitions must conform to schema

  • TaskEdgeSpan and TaskEdgeReference structures must be valid

Timing Targets are validated structurally but do not affect feasibility — they influence optimization only.

Execution / Driver Validation (Optional)

When validating for execution:

  • Instrument configurations must match driver requirements

  • Driver versions must exist

  • Transport definitions must be valid

  • Instruments configured with "simulate": true do not require hardware driver initialization for execution-level validation.

Instruments marked with "simulate": true are treated as available without initializing hardware drivers. This affects execution-level validation only. Structural validation, feasibility checks, and planning behavior remain unchanged.

Planning

Planning is the process by which the Intelligent Scheduling Engine converts a validated workflow into a concrete execution plan.

Each planning invocation may produce a different valid schedule depending on:

  • Optimization objectives

  • Search behavior

  • Computation limits

  • Soft preferences (Timing Targets)

All hard constraints are always satisfied.

Planning produces a single execution plan.

Note

Successful planning guarantees deadlock-free execution by resolving all resource conflicts before deployment.

Workflow Inputs to Planning

The scheduling engine operates on the following workflow-level inputs:

1. Tasks

Executable actions on instruments or transport systems.

2. Dependencies

Hard ordering relationships between tasks.

3. Time Constraints

Hard timing relationships between task edges.

These must always be satisfied.

4. Timing Targets (Soft Preferences)

Defined using planning_targets.

Timing Targets:

  • Express preferred timing relationships between task edges

  • Influence optimization without affecting feasibility

  • Are treated as soft objectives

Example:

workflow = Workflow(
    ...,
    planning_targets={
        "peel_consistency": [
            TaskEdgeSpan(
                anchor_a=TaskEdgeReference(task_id=task_a.id, edge="end"),
                anchor_b=TaskEdgeReference(task_id=task_b.id, edge="start"),
            )
        ]
    },
)

Optimization Configuration

Planning behavior can be configured using either:

  • PlannerOptions (single-stage optimization), or

  • Optimization Stages (sequential multi-stage optimization)

These approaches should not be combined for conflicting objective control.


PlannerOptions (Single-Stage Optimization)

PlannerOptions configure a single optimization pass.

options = Options(
    planner=PlannerOptions(
        target_objective=7200,
        max_computation_time=200,
        max_dead_time=5,
        round_robin_load_balancing=True,
        preset="PROD_LARGE",
        optimisation_target="balance_total_plan_duration_and_labware_idle_time",
    )
)

PlannerOptions allow you to control:

  • Objective targets

  • Computation time limits

  • Dead time limits

  • Load balancing behavior

  • Preset optimization profiles

  • Transport concurrency method

  • Feasibility solving strategy

This configuration performs a single planning stage (feasibility).

Additional PlannerOptions Parameters

transport_concurrency

Specifies the method used to handle transport concurrency during planning.

Supported values:

  • "none" — No concurrency allowed (fastest planning, least optimized).

  • "simple" — Transport units are blocked for the entire transport duration (default).

  • "advanced" — Transport units are blocked only during active transport, requiring detailed task time estimates.

  • "transport_v3" — Uses actual timing information from the transport_v3 configuration for more accurate scheduling.

feasibility_stage

Provides advanced configuration for the feasibility solving stage.

Available parameters:

  • max_computation_time — Maximum time (in seconds) to spend during the feasibility stage.

  • workflow_splitting_method — Specifies how workflows are partitioned for feasibility solving.

  • deep_feasibility_solve — Enables deep feasibility solving (default: True).

  • advanced_strategy_options — Configures advanced feasibility strategies, including automatic, chunking, and M×N methods.


Optimization Stages (Advanced Configuration)

Optimization Stages enable sequential multi-objective optimization.

Each stage defines:

  • An objective

  • Stopping conditions

  • A carry-forward rule

Stages execute in order. Each stage refines the plan produced by the previous stage.


OptimisationStage Schema

class OptimisationStage(BaseModel):
    objective: Objective
    stop_at: StoppingConditions
    carry_forward_rule: ObjectivePreservationTarget

Objective Enum Values

Supported objective values:

  • "makespan" — Minimize total plan duration

  • "deadtime" — Minimize idle time

  • "timing_targets" — Optimize alignment with Timing Targets

  • "consistency" — Optimize schedule consistency metrics

  • "slack" — Optimize timing slack

Each stage optimizes one objective.


Stopping Conditions

Control when a stage ends.

class StoppingConditions(BaseModel):
    max_computation_time: Optional[float]
    improvement_timer_limit: int
    target_objective: Optional[float]

max_computation_time

Stop after N seconds.

improvement_timer_limit

Stop if no better solution is found within N seconds.

target_objective

Stop when objective value reaches a specified threshold.

A stage ends when any stopping condition is met.


Carry-Forward Rule

Controls how subsequent stages may affect prior objectives.

carry_forward_rule="lock"  # String value, not an enum

Supported values:

  • "lock" — Objective cannot degrade

  • "same_or_better" — Must remain equal or improved (default)

  • "plus_or_minus_1_percent" — May degrade up to 1%

  • "plus_or_minus_5_percent" — May degrade up to 5%

  • "plus_or_minus_10_percent" — May degrade up to 10%

This enables controlled multi-objective tradeoffs.

Example Multi-Stage Optimization

from linq.workflow import (
    OptimisationStage, 
    StoppingConditions,
)

options = Options(
    planner=PlannerOptions(
        optimisation_stages=[
            OptimisationStage(
                objective="makespan",
                stop_at=StoppingConditions(max_computation_time=60),
                carry_forward_rule="lock"
            ),
            OptimisationStage(
                objective="timing_targets",
                stop_at=StoppingConditions(max_computation_time=30),
                carry_forward_rule="plus_or_minus_5_percent"
            ),
            OptimisationStage(
                objective="deadtime",
                stop_at=StoppingConditions(max_computation_time=30),
                carry_forward_rule="same_or_better"
            ),
        ]
    )
)

Interaction Between Timing Targets and Optimization Stages

Timing Targets are soft preferences that influence optimization but do not affect feasibility.

They may be optimized in two ways:

  • Indirectly, via PlannerOptions optimization targets

  • Directly, by defining an Optimization Stage with the objective "timing_targets"

Optimization Stages allow you to explicitly control how Timing Targets are prioritized relative to other objectives such as makespan or deadtime.

Example multi-stage strategy:

  1. Minimize makespan ("lock")

  2. Optimize timing_targets ("plus_or_minus_5_percent")

  3. Reduce deadtime ("same_or_better")

In this configuration:

  • The first stage minimizes total duration and locks it.

  • The second stage improves alignment with Timing Targets without degrading makespan beyond the allowed threshold.

  • The third stage reduces idle time while preserving prior objectives.

Hard constraints (dependencies and time constraints) are always enforced.

Timing Targets never invalidate feasibility.

Working with Plans

The lifecycle of initiating a workflow is as follows:

  1. Validate

  2. Create

  3. Plan

  4. Publish

  5. Deploy

  6. Start


Validate Workflow

linq workflow validate --path=quickstart.py --workflow=workflow

Create Workflow

Creating a workflow stages the workflow in the LINQ API, making it available to the planner and other downstream functions.

linq workflow create --path=quickstart.py --workflow=workflow

This returns a workflow ID.

To view staged workflows:

linq workflow list

Start Plan

To start a plan:

linq workflow plan start --workflow-id=<workflow-id>

Start Plan

Start a Plan Using a Hint

You can optionally provide a previously generated plan as a hint when starting a new planning run.

Using a hint allows the planner to reuse a previous plan as a starting point, which can reduce planning time and improve continuity between planning iterations.

To use a specific plan as a hint:

linq workflow plan start \
  --workflow-id=<workflow-id> \
  --hint-plan-id=<plan-id>

To use the most recently completed plan for the workflow:

linq workflow plan start \
  --workflow-id=<workflow-id> \
  --hint-plan-id=latest

Check Plan Status

If latest is specified, LINQ automatically selects the most recently completed plan associated with the workflow. If no completed plans are available, the command returns an error.

How Plan Hints Work

A plan hint provides the planner with an existing plan as a starting point for a new planning run.

The planner uses the hinted plan to guide optimization while continuing to search for a valid solution. The resulting plan may differ from the hinted plan if a better solution is found or if workflow changes require a different schedule.

Plan hints can be useful when:

  • Iteratively refining the same workflow.

  • Replanning after making small workflow changes.

  • Reducing planning time for workflows that have already been planned successfully.

Check Plan Status

To check the current progress of your plan:

linq workflow plan status --workflow-id=<workflow-id> --plan-id=<plan-id>

Plan statuses are:

Plan statuses are:

  • PENDING — the plan is currently being computed.

  • COMPLETED — the plan was computed successfully.

  • FAILED — the plan could not be computed.

  • CANCELLED — the plan was cancelled before completion.

  • UPLOADED — a pre-computed plan was uploaded.

Multi-Stage Planning

Multi-stage planning begins with a Feasibility stage, then progresses through one or more configured Optimization Stages.

  • Feasibility — Determines whether a valid plan can be created by satisfying the workflow’s hard constraints.

  • Optimization Stages — Progressively refine the feasible plan according to each stage’s configured optimization objective.

During planning, the current best plan may become available before planning has completed. As the planner progresses through the Feasibility stage and each configured Optimization Stage, updated plans may become available for retrieval.

When using multi-stage planning, the plan status provides additional details:

  • stage_detail — Indicates which planning stage has completed (for example, “Feasibility completed” or “Optimization stage 1 (makespan) completed”).

  • result_available — Indicates whether the current plan can be retrieved using get_plan_result(). This may be intermediate results while planning is still in progress, or the final plan once planning has completed.

Example status progression:

  1. status=PENDING, result_available=False — Planning has started and no plan is available yet.

  2. status=PENDING, result_available=True, stage_detail="Feasibility completed" — The first feasible plan is available.

  3. status=PENDING, result_available=True, stage_detail="Optimization stage 2 (deadtime) completed" — An updated plan is available after Optimization Stage 2.

  4. status=COMPLETED, result_available=True — The final optimized plan is available.

Retrieving Intermediate Results

When result_available=True, you can retrieve the current plan even while status=PENDING.

This allows you to:

  • Inspect the current plan before planning has completed.

  • Use an intermediate plan as a hint for a future planning run.

  • Publish intermediate solutions.

Note: An updated plan is uploaded as the Feasibility stage and each configured Optimization Stage completes. If planning is cancelled or fails after a plan has been uploaded, the most recently uploaded plan remains available. Plans in CANCELLED or FAILED state with result_available=True are valid hint plans and can be supplied to workflow plan start using --hint-plan-id.

Retrieve Plan Result

Once the plan is complete (or an intermediate result is available), retrieve the task execution details:

linq workflow plan result --workflow-id=<workflow-id> --plan-id=<plan-id>

This endpoint returns:

  • The final plan when status=COMPLETED

  • Intermediate plans when status=PENDING and result_available=True

  • Returns 404 if result_available=False

Optional flags:

--watch
--silent
--metrics
  • --watch polls for updates.

  • --silent suppresses terminal output.

  • --metrics includes detailed performance metrics.

List Plans

To view all running and completed plans:

linq workflow plan list

To filter by workflow:

linq workflow plan list --workflow-id <workflow-id>

Plan Metrics

When using the --metrics flag with:

linq workflow plan result --workflow-id=<workflow-id> --plan-id=<plan-id> --metrics

Available metrics include:

  • total_plan_duration

  • plan_solve_duration

  • create_model_duration

  • search_duration

  • time_to_feasible

  • total_deadtime

  • batches_requested

  • instrument_utilization

  • times

  • solutions

These metrics provide insight into model build time, search time, solution quality progression, and overall workflow efficiency.


Visualizations

To visualize a plan’s output as Gantt charts showing resource utilization and timing, use the Python SDK visualization functions.

Instrument-Centric View

Instrument-Centric View:

from linq.visualize import show_instrument_plot

# Get plan result first
result = linq.get_plan_result(
    workflow_id=workflow_id,
    plan_id=plan_id
)

# Display instrument utilization Gantt chart
show_instrument_plot(result=result)

The instrument view shows time on the x-axis, instruments on the y-axis, with labware colored by type. This helps analyze how well each instrument is utilized and identify bottlenecks.

Labware-Centric View

from linq.visualize import show_labware_plot

# Display labware utilization Gantt chart
show_labware_plot(result=result)

The labware view shows time on the x-axis, labware on the y-axis, with instruments colored by type. This helps track the complete journey of each labware item through the workflow.

These visualizations help you:

  • Analyze resource utilization patterns

  • Identify scheduling bottlenecks

  • Understand task sequencing and timing

  • Verify workflow correctness before deployment


Scheduler Versioning

Every workflow can be pinned to a specific scheduler version.

To view available scheduler versions:

linq scheduler-versions

Pin a workflow to a specific scheduler version using the appropriate CLI option during workflow creation or planning.

Pinning a scheduler version allows you to freeze behavior for reproducibility while still allowing new workflows to use the latest scheduler improvements.


Replanning

Replanning occurs when the original plan no longer aligns with real-time execution.

Replanning may be triggered by:

  • Inaccurate task duration estimates

  • Runtime errors

  • Conditional branch outcomes that differ from expectations

Replanning happens locally on the workcell and leverages prior solve information to compute updates efficiently.

To reduce replanning, ensure accurate task time estimates.


Summary

Planning in LINQ:

  • Enforces all hard constraints (dependencies and time constraints)

  • Supports soft timing preferences via planning_targets

  • Enables advanced staged optimization with controlled tradeoffs

  • Produces a single executable plan

  • Guarantees deadlock-free scheduling