DOCS / REFERENCE

Execution plans

Turn a validated result into a work order an operator can follow, without letting the layer that explains a decision start making one.

01A view of a result, not a second solver#

The adapter reads the request and a validated result and nothing else. It calls no solver and no validator, so it cannot produce a placement or bless one, and given the same result it emits the same plan every time. It ships in all four engines: packvium.execution in Python, Packvium\Execution\Plan in PHP, the execution module of the Rust core, and @packvium/engine/execution.js in Node. Over the whole golden corpus the four emit byte-identical plans.

02Facts and presentation are kept apart#

Everything the solver or validator decided sits under facts: placements, the score vector, the status, and the reason and proof level of each item left behind, never softened. Every human-readable sentence sits under presentation and names the fields it came from in cites. A system that reads only facts loses nothing it may rely on.

03A placement is named by what the contract promises#

An item id is an instance counter that engines are not required to agree on, so a step names its placement by container position, item type, orientation and the exact integer position in ticks instead. Inside a valid result that tuple is unique, because two placements cannot share an origin and an orientation.

04Step order is supplied, never guessed#

The order an operator loads in is a claim about physics, and the order a solver happened to place things in is not. Supply a loading order for a container and each step carries its sequence; supply none and the container reports its order as unavailable, with every placement still listed. An order that is not a permutation of the container's placements is refused.

05Why an alternative lost#

When a result carries alternatives, each one is stated by the first position at which its score vector differs from the winner's, and what that position measures. The plan does not blend the vector into one number and does not invent a cause the solver never recorded. A result with no alternatives is well formed and common.

06Operator locks, in Python#

An operator can lock a placement and ask for a re-solve around it. The lock enters as an ordinary constraint, so the re-solve is the normal portfolio under the normal independent validator, and the approved plan is never modified: the re-solve is a separate candidate. A lock reserves its slot rather than forcing it, a lock that cannot hold is reported as missing, and two locks that overlap are refused before any solve. A lock has no representation in the request schema yet, so this part runs in Python only.