Browse documentation
Docs/Functionality

Choose a procedure during a workflow

A reusable process can accept named procedures through PROCESS parameters. Inside it, bind a Boolean choice between two procedures, then RUN that method. This example gives a request either…

Choose a procedure during a workflow

A reusable process can accept named procedures through PROCESS parameters. Inside it, bind a Boolean choice between two procedures, then RUN that method. This example gives a request either a brief answer or an answer checked by a second participant. Both procedures return the same result shape.

# Runnable Desktop workflow: choose a brief or checked answer before RUN.
# Profiles analysis and fact-checker are admitted one-call responders without tools.
# Both recipes accept the same question, roles and result shape. All definitions
# are digest-pinned before Start; choosing a method does not choose new authority.

PROCESS brief_answer(question) WITH analyst, checker
  answer = ASK(analyst, "Answer the question using the supplied facts.", question)
  {answer: answer, assessment: "No independent review was requested."}
END

PROCESS reviewed_answer(question) WITH analyst, checker
  answer = ASK(analyst, "Answer the question using the supplied facts.", question)
  assessment = ASK(checker, "Check the answer against the supplied facts.",
    {question: question, answer: answer})
  {answer: answer, assessment: assessment}
END

PROCESS respond(question, careful, PROCESS brief, PROCESS reviewed) WITH analyst, checker
  method = careful THEN reviewed ELSE brief
  RUN method(question) USING analyst = analyst, checker = checker
END

TEAM desk
  analyst USING "analysis"
  checker USING "fact-checker"
END

question = "The supplied schedule says the library closes at 6 pm. When does it close?"
careful = TRUE
pending = respond(question, careful, brief_answer, reviewed_answer) USING desk
# Inert until explicit Start. Maximum: two model turns/calls, two frames including
# root, four logical participant identities. FALSE selects only one model call.
# The assessment is a model judgment; it is not a verified fact or domain receipt.

The compiler checks both alternatives before Start: inputs, results, exact role mappings, room requirements, transitive operations and the union of the call graph. A bad alternative is rejected even if careful currently selects the other one. Logical work bounds use the more expensive alternative, composed with the rest of the process. Provider costs still use the host's separate profile and root limits.

The Boolean decision is evaluated where method is bound. Only the selected RUN executes; it receives fresh participant identities and private histories. It copies the supplied responder configurations, not their learned conversation. A local alias such as selected = method retains the same decision. The selected name is a process target: it cannot be returned, put into a model prompt, or shared as ordinary data. A model may supply a validated Boolean that selects between authored procedures; it cannot supply an executable process-name string.

Run it in Desktop

  1. Save the source in Author.
  2. Open Agent → Tasks → Processes and select pending.
  3. Choose models for analysis and fact-checker, then Start process.
  4. With careful = TRUE, inspect the analyst's answer, the checker's assessment, and the structured result. With careful = FALSE, a new run calls only the analyst and returns the explicit notice that no independent review occurred.

Both responder configurations must be available at Start, including the one unused by a particular choice. Editing careful or the procedures affects new runs; an existing run retains its admitted source and input values. A model's assessment remains a judgment, not proof that the answer is correct.

Pass the selected method to another process

A wrapper can receive the selected method through its existing PROCESS parameter. Using the definitions above, add:

PROCESS apply(question, PROCESS method) WITH analyst, checker
  RUN method(question) USING analyst = analyst, checker = checker
END

Then replace the final line inside respond with:

  RUN apply(question, method) USING analyst = analyst, checker = checker

The choice stays bound in respond; apply receives the selected procedure. It can forward that procedure through further PROCESS parameters. Each wrapper adds a child frame and fresh private participant histories. Both specializations are checked before Start, and admission includes the more expensive candidate. This example now reserves three frames and six participant identities, while still making at most two model calls. Native execution is tested; the forwarding variant has not yet been demonstrated in Desktop.

Compose independent choices

A newsroom can choose its drafting method separately from its review method:

PROCESS newsroom(facts, detailed, checked) WITH writer, editor
  drafting = detailed THEN detailed_draft ELSE brief_draft
  reviewing = checked THEN independent_review ELSE review_note
  RUN prepare(facts, drafting, reviewing) USING writer = writer, editor = editor
END

prepare accepts two PROCESS parameters, runs the chosen drafting procedure, then passes its answer to the chosen review procedure. The complete newsroom sample contains all definitions and the team. All four combinations execute in native tests. Desktop execution of this new sample remains unverified.

Each decision is evaluated at its binding, and aliases reuse that decision. The compiler checks every combination before Start. Admission reserves the largest execution path, not the sum of mutually exclusive paths. Expanding combinations costs compiler work and artifact space: a call permits at most 256 combinations before expansion, subject to the existing whole-program specialization, slot and artifact limits, which can reject smaller programs. No inference runs during compilation.

Layer decisions without repeating them

A later choice may select an earlier method binding. For example, replace respond with this version and supply escalate as its third ordinary argument:

PROCESS respond(question, careful, escalate, PROCESS brief, PROCESS reviewed) WITH analyst, checker
  routine = careful THEN reviewed ELSE brief
  method = escalate THEN reviewed ELSE routine
  RUN method(question) USING analyst = analyst, checker = checker
END

The routine decision is captured first. Escalation can require review without repeating that decision. Both bindings stay control-only and can be aliased or passed through PROCESS parameters. Each predicate is evaluated at its binding; using a prior method never reevaluates its condition. These are two explicit binding steps, not a promise of lazy evaluation of an inline nested conditional. Layered decisions count toward the same finite expansion and nesting budgets.

Current scope

This supports local Boolean choices whose two alternatives are named processes or statically supplied PROCESS parameters, and aliases of those choices. It also works inside bounded traversal: each iteration binds its own decision. The existing branch and child execution path supplies suspension, cancellation and recovery; no second scheduler or evaluator is involved.

A named or locally selected child can receive independently selected decisions in several PROCESS parameters. For example, after declaring two compatible workflow procedures, workflow = urgent THEN fast_workflow ELSE careful_workflow can be followed by RUN workflow(facts, drafting, reviewing). The compiler checks each receiving workflow with every argument combination. The receiving-workflow decision also counts toward the expansion budget. Native tests execute all eight combinations of a receiving-workflow decision and two argument decisions.

Container-selected references and choices supplied directly at plan construction remain unimplemented. Layered named bindings are supported, including when forwarded into a selected receiving workflow. General process-reference values and the broader component SDK are still in progress. Use explicit authored branches and wrappers for those compositions today.

Nest alternatives directly

When a decision matters only within another alternative, write it there:

PROCESS respond(question, careful, escalate, PROCESS brief, PROCESS reviewed) WITH analyst, checker
  method = escalate THEN reviewed ELSE (careful THEN reviewed ELSE brief)
  RUN method(question) USING analyst = analyst, checker = checker
END

The outer predicate is captured once. The inner predicate is evaluated only when its alternative is selected. An error in an unselected predicate cannot fail this binding. Aliases and forwarding through PROCESS parameters preserve that captured choice; they do not reevaluate predicates. All candidate methods still undergo compatibility and budget checks before execution. Nesting consumes the existing finite specialization budget and cannot admit generated code or model strings.