Core concepts
Node / @node — executable capability
A capability, not a workflow position. Either a Python handler (@node) or a provider-backed constructor. The node returns a proposal — nothing commits until every gate passes.What it is
A node packages one executable capability the graph can select. input_schema and output_schema are required. Use OpenInput when the node does not need to constrain workflow state.
The node returns output, state_updates, and an optional next_state. That result is a proposal. Nothing a node returns commits state by itself.
Python SDKpython
@node(
id="VerifyIdentity",
input_schema=OpenInput, # required — what workflow state the node expects
output_schema=EmptyOutput, # required — what the node produces
prerequisites=(), # optional — node ids that must have already run
)
def verify_identity(ctx):
"""Verify the caller owns the order."""
return ctx.result(output={}, state_updates={"verified": True})Tools live on nodes
Tools are capabilities on a node (tools=("lookup_order",)), never graph vertices. Handlers call them through ctx.tools; undeclared calls are denied fail-closed.
Python SDKpython
@node(id="Verify", tools=("lookup_order",), input_schema=OpenInput, output_schema=EmptyOutput)
def verify(ctx):
order = ctx.tools.invoke("lookup_order", {"order_id": "ord_1"})
return ctx.result(output={}, state_updates={"amount": order["amount"]})Grounded in neosyntropy-framework/docs/concepts-explained.md §2.