Skip to content

Validate slot-value type compatibility at plan time #284

Open

Description

@David-Noble-at-work

Context

op.ValidateGraph (introduced in step 15.x of 13.0(n) extract-starlark-from-op) asserts two plan-time invariants:

  1. Required-parameter coverage — every required parameter of an action-bound unit's method has a slot entry.
  2. Bubble-up consistency — no same-named variable is declared with incompatible types across child slots (via Subgraph.mergeBubbled).

It deliberately does not check that a slot's value is compatible with the slot's declared parameter type. This issue tracks adding that check.

Concrete example

node.SetAction(fileWriteText) // method declares: source (string)
node.SetSlot("source", op.ImmediateValue{Value: 42}) // int — incompatible with string

Today this passes ValidateGraph (the slot is present and bound) and fails only at dispatch when the executor coerces the value into the method's parameter type. The error surfaces far from the binding, with execution context noise that obscures the planning mistake.

Scope sketch

For each ExecutableUnit and each parameter on its bound method:

Slot value form Validation
ImmediateValue{Value: v} reflect.TypeOf(v).AssignableTo(param.Type) — direct, plan-time
PromiseValue{UnitRef: id, Slot: s} resolve the producer's declared output type via the registry; check assignability against param.Type. Requires the graph to be linked.
VariableValue{Name: n} the variable's type comes from the slot's param.Type; cross-slot type consistency is already handled by mergeBubbled. No additional check needed here — same-name collisions across slots already surface.

Edge cases

  • any / interface{} params — any concrete type is assignable; check is a no-op.
  • Interface-typed params — reflect.Type.AssignableTo handles this correctly (concrete satisfies interface).
  • Defaulted params — ActionPlanner.Plan already wraps the default in ImmediateValue, so it flows through the Immediate branch.
  • Variadic / Kwargs — skipped (they absorb any types).

Why it's not in step 15

Type compatibility is orthogonal to the structural strip-and-collapse work in step 15. The mergeBubbled check catches one specific kind of type mismatch (same variable, different declared types across slots) but doesn't catch concrete-value-vs-parameter-type mismatches. They're independent invariants.

Filing this so the existing TODO from ValidateGraph documentation has a tracker.

Acceptance

  • ValidateGraph (or a sibling validator) emits one violation per slot with incompatible value type, listing unit ID, slot name, expected type, actual type.
  • PromiseValue resolution path validated (graph must be linked at validation time — already a precondition of ValidateGraph).
  • Tests cover: assignable concrete-to-concrete (OK), incompatible concrete-to-concrete (violation), concrete-to-interface (OK), nil parameter type (skipped — bound method has no signature constraint), promise output type mismatch (violation).

Related


Epic: #444 · Feature: #459

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions