RFD 1037 details: the shape, type rules, the solved plan, replanning, the five

The shape

A domain is a module with use Taskweft.DSL and module attributes.

Attribute Holds
@name The domain name.
@variables A map of name => %{type:, init:}. The state.
@actions Primitives. params, bind, and body.
@methods Compound tasks. params and alternatives.
@todo_list The goal. A call, a goal, or a multigoal.

A body step is %{eval: %{…}} for a guard, or %{pointer_set: "/p", value: v} for an effect. A guard reads state with %{pointer_get: "/p"}.

A problem is a second module. It sets @source to the domain name, it overrides the @variables keys it cares about, and it carries its own @todo_list.

Type rules that catch a writer out

type is mandatory on each variable, and the vocabulary comes from glTF Interactivity. There is no :string type. A stage name, a file handle, and a format are each :ref, which is an opaque value compared for equality.

There is no :enum type either. A named class is capability data, and it belongs in the top-level capabilities key.

The solved plan is a file

Call plan once, and write the result to plan.ex beside the domain. The model image then reads that file, and a cold start needs no planner and no network.

Write it in the same DSL, and not as JSON. One language across the domain, the problem, and the plan means one formatter and one parse check.

Regenerate plan.ex when the domain changes, and never edit it by hand. A hand-edited plan can hold a step order the guards forbid, which is the failure this whole RFD exists to stop.

RETRACTED, 2026-08-25: a plan may be written by hand. The paragraph above stays as written because it names a real hazard. The rule it drew from that hazard is withdrawn.

What the rule cost was measured the first time it was applied. A domain for the CineForm delivery, RFD 1137, was written and checked with Code.string_to_quoted/1, and then no plan could be produced, because the planner serves over MCP at a host this desk was not going to reach mid-task. The domain sat unusable beside a skill that told a reader to run it. A rule that turns a reachable deliverable into an unreachable one costs more than the defect it prevents.

So a hand-written plan.ex is permitted until a pattern appears across enough domains to encode generically. What does not change is the checking: the plan is real Elixir and must parse, the domain’s guards still hold at run time, and a hand-written plan that violates one fails there rather than passing quietly. Say in the file which way it was made, and regenerate from the planner once it is reachable.

Replanning is the payoff

plan takes plan_json and fail_step. A caller that loses a stage replans from that step, and it keeps the work before it.

That is the reason a composite is a domain. A script cannot do it.

The five composites

Model id Networks RFD
seethrough_layer_decomposition 9 0044
weftspun_image_to_world 2 0049
lingbot_map_environment_scan 2 0050
voxhammer_text_mesh_editing 2 0047
voxhammer_image_mesh_editing 2 0048

Each domain lives with its model, and not here. RFD 1000 keeps one source per design. The See-Through pair in 0044-seethrough-layer-decomposition/ is the worked example, because it is the largest of the five.