All rules
Every rule in the specification, filterable by family, profile, level and posture. An identifier is permanent: never renumbered, never reused.
399 of 399 rules
- API-1Every JSON door applies the same body gate, and reports its refusals
- API-2The turn door and the launch door judge inputs identically
- API-3A session with no workflow is a conflict, not a server error
- API-4Node configuration could be checked ahead of save
- API-5The paginated envelope is a third envelope with four fixed keys
- API-6Paging is clamped silently, and the clamped values are what is reported
- API-7A generic failure is a last resort, never a design
- API-8Every refusal carries a stable machine-readable code
- BR-1An edge is gated only when the source actually made a branch decision
- BR-2The three cases in which a branch decision never gates an edge
- BR-3An active-branch list is a list of names, trimmed and lower-cased
- BR-4An outcome matching no branch is loud, never a silent gate-off
- BR-5Branch gating applies to trigger and data edges alike
- BR-6A stale source does not satisfy an edge
- BR-7A node whose triggers are all unsatisfied is skipped, not executed
- CFG-1An unrecorded gate flag is off
- CFG-10A resolved value is validated against the parameter schema
- CFG-11Type checking matches exactly and never coerces
- CFG-12An unrecognised format passes rather than fails
- CFG-13A processor sees its declared parameters and nothing else
- CFG-14Every declared parameter is present, null when unresolved
- CFG-15A dynamic input is forwarded verbatim
- CFG-16The unified input port is decomposed before resolution
- CFG-17A hidden port cannot be filled through the bundle
- CFG-18Published config defaults cover configurable parameters only
- CFG-2An unrecorded default-exposure flag means exposed
- CFG-3A parameter's effective default comes from the node type, then the schema
- CFG-4Priority 1, a value delivered on a wire
- CFG-5Priority 2, the author's saved config
- CFG-6Priority 3, the effective default, unconditionally
- CFG-7An explicit null at a higher priority wins
- CFG-8Internal parameters take runtime values only
- CFG-9A required parameter that resolves to null fails the node
- CMP-1Compilation is one operation with one failure surface
- CMP-10A node with tools wired to it must be able to receive them
- CMP-11The compiled plan keeps each node's node type identity
- CMP-2Compilation always re-enriches node metadata from the live node types
- CMP-3Structure preconditions are checked before anything is planned
- CMP-4An edge's type is derived, never declared
- CMP-5Only tool, loopback and agent-result cycles are legal
- CMP-6Which nodes reach the execution graph
- CMP-7Trigger dependencies displace data dependencies for ordering
- CMP-8Execution order is a topological order, and no more than that
- CMP-9Tool names are unique per consumer, checked at compile time
- CRON-1A cleared schedule means not scheduled, and every reader says so
- CRON-2Every reason a schedule has no next run carries a stable code
- DATA-1An edge delivers one named output port to one named input port
- DATA-10A tool edge binds a tool, it does not deliver data
- DATA-11A tool's model-facing schema hides the parameters the workflow already fixed
- DATA-12Tools reach only a node that declares itself a tool consumer
- DATA-2Several sources on one port resolve to a single latest value
- DATA-3A trigger edge carries no data
- DATA-4When a node is ready to run
- DATA-5Loopback and tool edges create no execution dependency
- DATA-6Initial data fills a node's ports only where no edge did
- DATA-7Inside a node, a wire outranks configuration outranks the default
- DATA-8Unexposed outputs are stripped where they are produced
- DATA-9The unified output port carries exposed outputs only
- DYN-1Dynamic ports are opt-in, and a node that does not opt in has none
- DYN-2A dynamic port declares a name, a label and a data type
- DYN-3Dynamic port names are constrained and unique across the node
- DYN-4An unconnected dynamic input resolves to null, with its key present
- DYN-5A declared parameter wins a name collision with a dynamic port
- DYN-6Dynamic ports carry no exposure state and are not addressable from outside
- DYN-7Dynamic port definitions are configuration, never a wireable input port
- EDGE-1A handle encodes the node, the direction and the port
- EDGE-2No edge key is structurally required
- EDGE-3A trigger edge is one whose target port is the trigger port
- EDGE-4A loopback edge targets the port named loop_back
- EDGE-5A declared edge type wins over the handle, if it is recognised
- EDGE-6An error edge routes a failure instead of raising it
- EDGE-7A tool-only node is excluded from the execution graph
- EDGE-8A condition on an edge is tolerated, warned about, and ignored
- EDGE-9Two edge vocabularies, and they never mix
- ERR-1A node-level failure becomes an error output, not a thrown failure
- ERR-10A routed failure activates error edges only, and only when it is current
- ERR-11Retry is opt-in, in place, and immediate
- ERR-12Direct synchronous execution has no error-handling divergence
- ERR-13Every execution strategy routes errors identically
- ERR-2Retryability is marked by presence, not by a boolean
- ERR-3A failure that is not node-level fails the run
- ERR-4An interrupt propagates unchanged
- ERR-5A node may stop the run successfully
- ERR-6A node's output must be serializable throughout
- ERR-7An error edge replaces the node's output with an error envelope
- ERR-8An error with nowhere to go fails the run
- ERR-9A run whose every failure was handled completes
- EXPO-1Exposure resolves the same way everywhere it is consulted
- EXPO-10Hiding an input port changes precedence, it does not unset the parameter
- EXPO-11Output stripping covers declared output ports only
- EXPO-12Control outputs are never stripped
- EXPO-13A node type can hide an output outright
- EXPO-14A hidden output's value never reaches anything downstream
- EXPO-15A model may fill only visible, unwired parameters
- EXPO-16Seeding a port's default-exposure decision
- EXPO-17Port display order is cosmetic
- EXPO-2An instance override decides exposure; otherwise the default does
- EXPO-3Overrides are scoped by direction
- EXPO-4A node nobody has touched stores no overrides
- EXPO-5Only an exact false suppresses default exposure
- EXPO-6A processor's exposure suggestion is authoring input only
- EXPO-7Published schemas carry the flag only where the default is hidden
- EXPO-8A port with no stored decision is exposed, whatever the processor suggested
- INT-1An interrupt pauses the run and reports itself in full
- INT-10A queued run seeded from a snapshot performs only the remaining work
- INT-11A terminal run refuses re-entry; re-running makes a new run
- INT-12Only a budget pause resumes itself
- INT-13A checkpoint round-trip preserves cancellation
- INT-14A terminal snapshot is not resumable
- INT-15An engine that cannot use a snapshot refuses it, never restarts
- INT-16A refused signal says why in a code a client can act on
- INT-17A terminal outcome reaps the signals it never observed
- INT-18An expired outward interrupt ends the run it was holding open
- INT-19A machine answers an outbound wait through its own route
- INT-2The interrupt a run reports is the persisted one
- INT-20Call-and-wait creates the interrupt before it makes the call
- INT-22An interrupt is published as 24 keys, every one always present
- INT-23No expiry is a sentinel, and the two expiry paths differ on purpose
- INT-3Resolving an interrupt resumes only a paused run
- INT-4A node resumes only when all four ownership conditions hold
- INT-5Cancel and pause signals are observed between job iterations
- INT-6What a run snapshot contains, and that it never fails the run
- INT-7The workflow version is a structural digest
- INT-8Snapshot validation reports named errors and non-fatal warnings
- INT-9One execution has at most one stored snapshot
- LANG-1Extraction engines query the context; transformation engines bind it
- LANG-10Expression-language validation is a syntax check only
- LANG-11Property-path validation accepts everything evaluation can resolve
- LANG-12A path that does not begin with `$` always passes JSONPath validation
- LANG-13Twig validation is a compile check only
- LANG-14A leading `$` decides JSONPath from property path
- LANG-15A single JSONPath match is unwrapped unless the path selects many
- LANG-16A string context is parsed as JSON where it parses
- LANG-17Dot and bracket path segments are interchangeable everywhere
- LANG-18A trigger mapping value can be escaped as a literal
- LANG-19Extracting all matches for a property path always yields a list
- LANG-2A node's expression engine must be one the implementation provides
- LANG-20Testing whether a path exists
- LANG-21A failed mapper expression fails the node and names the port
- LANG-22An extraction error fails the node and never takes the default
- LANG-23Only a `$`-rooted JSONPath query unwraps a list to its first match
- LANG-24A null extraction is a miss, not a failure
- LANG-25Shaper sentinels resolve before any engine is consulted
- LANG-26A prompt template that fails to render fails the node
- LANG-27A switch compares its value; it does not evaluate it
- LANG-28A condition node's operators are a closed set, and case folding spares the pattern
- LANG-29An expression error fails the node; an empty result does not
- LANG-3An empty expression is not an error
- LANG-4A context that is not a map reaches a transformation engine as `data`
- LANG-6Expression-language evaluation fails loudly
- LANG-7Twig yields an escaped string and treats a missing variable as empty
- LANG-8A property path that cannot be read yields null
- LANG-9A JSONPath query never raises; it falls back to the caller's default
- MAN-1A workflow's launch inputs are declared, never inferred
- MAN-10A declared input name wins over an internal node-keyed key
- MAN-11A declared input delivers to the port its entry binds
- MAN-12The node-keyed input shape is internal and unreachable from outside
- MAN-13An undeclared launch key is refused, and its value never delivered
- MAN-14Strictness polices the caller, never the stored manifest
- MAN-15Launch inputs are checked in one fixed order and answered once
- MAN-16The value check enforces type and enum, and declares the rest
- MAN-17Declared outputs are collected by the same mapping, in reverse
- MAN-18The contract is rebuilt when the manifest changes, and versioned when it is
- MAN-19A workflow declared asynchronous cannot be launched and waited on
- MAN-2A manifest entry names an input and binds it to a port
- MAN-20The API maps a client interface onto the stored manifest
- MAN-21A contract entry states the port's lane as well as its schema
- MAN-3However the manifest was written, one validator refuses a bad entry
- MAN-5The published contract carries structure and nothing else
- MAN-6The author's words win over the node's
- MAN-7Only a flat default is published
- MAN-8An entry that cannot be built is skipped, not fatal
- MAN-9A workflow used as a node cannot build its own contract forever
- MD-1Markdown source can never reach the reader as markup
- MD-2Encoded exactly once, and quoted where a quote would end an attribute
- MEM-1Appending a tool result twice appends it once
- MEM-10A real tool result replaces the placeholder that stood in for it
- MEM-11Both spellings of a tool call's id are read
- MEM-12Concurrent buffer appends are serialized, and never fatal
- MEM-13A session-scoped memory read or write without a real session refuses
- MEM-14An append reports how much of it was new
- MEM-15A denial is final, and a message is not editable
- MEM-16Text becomes a message under three closed rules
- MEM-2An assistant turn is a duplicate only when every call it declares is known
- MEM-3A user turn heals tool calls that were never answered
- MEM-4Assembling messages concatenates in declared port order
- MEM-5Normalizing a conversation makes it sendable to a provider
- MEM-6A user-scoped memory read or write without a real user refuses
- MEM-7A refused scope reaches no storage backend
- MEM-8A session's memory principal is its owner or nobody
- MEM-9Driving a session is a write, and an absent identity owns nothing
- META-1The category list is the standard envelope, and its name is a machine name
- META-3A failed read answers a fixed message and reports the real one
- META-4The workflow schema door publishes a bare document
- META-5An unknown workflow's schema is a bare error document
- META-6The entity tag carries the body variant, not just the schema version
- META-7A conditional schema request is exact string equality and nothing more
- META-8The two schema variants are cached on deliberately different terms
- META-9The editor metadata doors are read-only and gated before the handler
- NET-1An outbound URL is checked before the request, and the check is pinned to it
- NET-2Every redirect hop is re-validated before it is taken
- NET-3The redirect posture is stated, not inherited
- OCX-1External invocation builds flat initial data
- OCX-2External results are retrieved by polling, and only by polling
- OCX-3Polls are scoped by a positive marker, defined once
- OCX-4External invocation honours the configured pipeline identity and mode
- OCX-5A trigger's condition set is a closed vocabulary
- OCX-6The connector validates nothing it publishes
- OCX-7One execution identifier correlates the invocation with every poll
- OCX-8A poll reports every terminal run, cancellation included
- OCX-9Polls page, and paging never strands the caller
- ORC-1Four execution strategies, each with a stable identifier
- ORC-10A run has a scheduler budget, and exhausting it pauses rather than fails
- ORC-11How a run's terminal status is decided
- ORC-12Asynchronous execution returns immediately
- ORC-13Resuming after an interrupt re-enters through the run's own strategy
- ORC-14A unit of work is claimed atomically
- ORC-15A cancelled run is announced like any other terminal outcome
- ORC-2How the execution strategy for a run is resolved
- ORC-3An unknown strategy identifier falls back, and says so
- ORC-4State graph is the interactive-session default only
- ORC-5A strategy's capabilities are declared, not asked for
- ORC-7Direct synchronous execution refuses a workflow that loops
- ORC-8Naming a firing trigger drops the other triggers
- ORC-9A pipeline engine is a ready-work loop
- PIPE-1Run status is read from persisted state, on two routes and one envelope
- PIPE-2The job status summary has one shape on every path
- PIPE-3Status vocabulary is guarded in the summary and raw in the node counts
- PIPE-4Node statuses are keyed by workflow node id and collapse every iteration
- PIPE-5A run's jobs are the ones the run itself names
- PIPE-6Authorization is decided before the handler, and travels with its cacheability
- PIPE-7One job entry shape, published identically by every surface
- PIPE-8Published execution context is filtered, not forwarded
- PIPE-9A timestamp is never fabricated
- PLAY-1Playground sessions and messages are addressed and published by UUID
- PLAY-2Creating a session answers the same row the list publishes
- PLAY-3The message poll has its own envelope, with the flags at the top level
- PLAY-4One message row, three doors, base keys always present
- PLAY-5The session list is ownership-scoped, and an emptied filter means none
- R1.aA node's executor must exist
- R1.bA node with no resolvable node type is not judged by R1
- R1.cA missing executor is reported once per node
- R10A workflow may not expose a port hidden on its node
- R11A configured expression must be valid for its engine at save
- R12A node may not be wired to itself
- R13Two identical edges between the same ports are refused
- R2Node ids are unique within a workflow
- R3Every edge carries a unique id
- R4.aAn exposed workflow port must be named in the permitted alphabet
- R4.bExposure names are unique per side
- R4.cAn exposure entry must name a node that exists
- R4.dAn exposure entry must name a port the node declares
- R4.eAn exposure name may not collide with a reserved runtime name
- R5.aA workflow is bounded to 500 nodes
- R5.bA workflow is bounded to 1000 edges
- R5.cEvery node carries an id
- R6.aConfig is a JSON object
- R6.bRequired config keys must be present
- R6.cAn unknown config key warns but does not block
- R6.dA config value must match its declared type
- R6.eA config value must be one of its enumerated values
- R6.fNumeric bounds apply to numbers only
- R6.gLength bounds count characters, never bytes
- R6.hA pattern mismatch is refused, a broken pattern is not
- R6.iA null config value means unset
- R6.jNo node type, no schema-driven config verdict
- R6.kThere is no separate per-executor config verdict
- R6.lA malformed secret reference warns the author
- R7.aAn edge may not target a hidden input port
- R7.bAn edge may not leave a hidden output port
- R7.cA node instance decides which of its ports are exposed
- R7.dA port the node type does not declare is outside exposure checking
- R7.e/fExposure checking is skipped per endpoint, not per edge
- R8.aAn edge's source node must exist
- R8.bAn edge's target node must exist
- R8.cTwo dangling endpoints are two errors
- R9A node's node type anchor must resolve
- RT-GATE-1A gated node never executes without consent for that exact call
- RT-GATE-11A gated node whose executor cannot be resolved never executes
- RT-GATE-12A resolved secret never persists in the gate prompt
- RT-GATE-13A gate question belongs to the initiator, and an ownerless one is findable
- RT-GATE-14Confirmation governance is its own grant
- RT-GATE-15A shipped side-effecting node type states its policy
- RT-GATE-2Consent is consumed exactly once, declines included
- RT-GATE-3Consent binds to the node and its exact resolved arguments
- RT-GATE-4A declined node routes a structured verdict out its error port
- RT-GATE-5A declined tool call is model-recoverable, never run-fatal
- RT-GATE-6A gate pause leaves no phantom failure in the tool trail
- RT-GATE-7Whether a node asks is a governance decision, resolved in order
- RT-GATE-8Governance can revoke a waiver already stored
- RT-GATE-9Dynamic escalation can add an approval but never remove one
- RT-TOOL-1A tool result carries artifacts alongside its data, never inside it
- RT-TOOL-10A tool-calling pass reports whether it did any work
- RT-TOOL-2A tool node emits artifacts on a reserved key that never reaches the model
- RT-TOOL-3Artifacts leave a tool call on their own port, apart from the model's prose
- RT-TOOL-4A turn's artifacts are persisted on its message and reported on its result
- RT-TOOL-5Artifact collection is opened and released per run
- RT-TOOL-6Artifacts are bounded once, at the point they are collected
- RT-TOOL-7A pause does not destroy artifacts, and does not deliver them twice
- RT-TOOL-8A model's tool arguments are normalized against the tool's own schema
- RT-TOOL-9A tool call executes at most once per run
- SCH-1A node's ports come from its two declared schemas
- SCH-10.aA site's lane configuration overlays the shipped one
- SCH-10The map from a schema type to a port lane
- SCH-11Every node but a start node gets a trigger input
- SCH-12Every node but a terminal node gets a trigger output
- SCH-13A tool-exposed node gets a tool output
- SCH-14Every executable node gets a hidden error output
- SCH-15A reserved port states its exposure only when it diverges
- SCH-16What each reserved port defaults to on the canvas
- SCH-17The unified input port
- SCH-18The unified output port
- SCH-19A unified port's description skips trigger and hidden keys
- SCH-2Gate flags come from the node type, and default off
- SCH-20Visual type is the node type's, and is offered where there is a choice
- SCH-21The reserved config properties every node carries
- SCH-22A config-edit descriptor appears only where one is provided
- SCH-23When a node has a ui schema, and when it has none
- SCH-24A node type that fails to build does not fail the request
- SCH-25Enrichment anchors on the node type and changes nothing else
- SCH-26The catalog an editor reads
- SCH-27A served port omits everything that matches the default
- SCH-28A node's executor is resolved from its node type
- SCH-29Stored metadata is never authoritative at run time
- SCH-3One parameter schema splits into two derived schemas
- SCH-31Config field order applies inside a ui schema only
- SCH-32Every re-enterable node gets a hidden loop-back input
- SCH-33A schema that will not load never rewrites stored parameters
- SCH-34A property's type is a JSON Schema type, not a port lane
- SCH-35Lane derivation is total, and an undeclared port is the sink
- SCH-36One declaration site for the shipped lane vocabulary
- SCH-37A control port declares its lane, never a schema type
- SCH-38.aA retired lane keeps one release of served-but-disabled compatibility
- SCH-38A loop-back input is a control sink, and `any` is retired
- SCH-39Compatibility is asymmetric, and the sink needs rules both ways
- SCH-4A hidden parameter is dropped from everything
- SCH-40A port's lane is consumed at a public boundary
- SCH-41The lane vocabulary is the served payload, not the shipped set
- SCH-42A shape is a named JSON Schema, and the shape id is the lane id
- SCH-43Shape compatibility is nominal and mostly derived
- SCH-44A shape refines another declaration of its lane; four ids are reserved
- SCH-45A stored lane overlay is checked when it is stored
- SCH-46A shape's schema is served on the lane, not on every port
- SCH-5Reserved config-only parameters always carry a default
- SCH-6Which required list a required parameter lands in
- SCH-7An output is exposed unless the node type says otherwise
- SCH-8How a schema property becomes a port
- SCH-9A union type resolves to its first non-null member
- SG-1State merges field by field, and a state value is never mutated
- SG-10A loopback driven from the trigger port belongs to no branch
- SG-11Every node completion writes a checkpoint, and the run writes a last one
- SG-12Where a run's starting state comes from
- SG-13A run records the configuration it resolved and resumes on it
- SG-14Exceeding the iteration budget ends the run, it does not pause it
- SG-15A run reports the identifier of the run it created
- SG-16What a loop is (its body, and that it is keyed by its head)
- SG-17A loop's extent is fixed at launch and every execution carries its rounds
- SG-18Nested loops keep separate rounds, tangled ones are merged
- SG-19A source from an earlier round does not satisfy an edge
- SG-2A node sees run state only where it asks for it, and none of it is persisted
- SG-20A data port no live producer can still fill fails its consumer
- SG-3A node's state update is applied through the reducers once it completes
- SG-4A ForEach node initializes its iterator once and completes on an empty list
- SG-5loop_back is a value on a ForEach node and a bare signal everywhere else
- SG-6Routing is decided per edge and dispatched per target
- SG-7A loop's budget counts rounds of the loop, not executions of a node
- SG-8A node executed more than once keys its results by occurrence
- SG-9An edge condition never decides routing
- SNAP-1The snapshot API carries two casings, and acceptance is the lenient half
- SNAP-2Snapshot access is decided on the snapshot, and absence answered first
- ST-1The status surface answered inside a success envelope
- ST-2An execution was reported by id and status
- ST-3Node statuses passed through, and an untracked run was empty rather than absent
- ST-4The detail view carried derived run metrics
- ST-5An execution was reported with a fixed field set
- ST-6A node was reported with a fixed field set
- ST-7The status vocabulary was closed
- ST-8An update naming an unknown run registered it rather than dropping it
- ST-9Each transition carried a payload defined for it
- STORE-1A request body is bounded before anything is parsed
- STORE-10Read-path repairs must never run on the save path
- STORE-11Status vocabularies are closed sets of strings
- STORE-12A finished turn leaves the session completed, not idle
- STORE-13One name per concept for a node's type
- STORE-14Every surface that returns a workflow returns one object
- STORE-15Searching the workflow list matches a literal substring of the name
- STORE-2A workflow must be named
- STORE-3A client-supplied id never overwrites an existing workflow
- STORE-4Absent collections default to empty, and an update touches only what it sends
- STORE-5A workflow refused by validation is never partially stored
- STORE-6Storing a workflow drops the editor's scratch state
- STORE-7Stored node metadata carries the type anchor and nothing else
- STORE-8A published contract version is three numbers
- STORE-9Import gates run in a fixed order and roll back what they generated
- TRIG-1Overlap is judged against the workflow's own unfinished runs
- TRIG-2Jitter is rolled once and never re-rolled
- TRIG-3A skip is recorded, but it is not an execution
- VAL-LAUNCHThe validator runs again at launch, before anything is created
- W-TAn edge leaving a terminal node warns