[workflow]

The [workflow] process configuration consumed by ubc agent.

Only ubc agent reads and validates this table, so a key it does not know fails the ubc agent commands that read it and no other command. No path in it is resolved. Its keys inherit across extend one by one, so a child that declares only [workflow.diagnostics] keeps the base’s [[workflow.stages]]. A key the child declares is taken whole: its [workflow.diagnostics] replaces the base’s rather than merging with it.

Guide: Workflow.

workflow.change_request
Type:
table

The [workflow.change_request] sub-table: where a change request is authored. Absent means the project declares no change-request flow.

workflow.change_request.route
Type:
table

Where a change request is authored (the route shape a stage uses).

workflow.change_request.route.granularity
Type:
string

The authoring granularity (global, per-need, per-root, or single).

Values:

  • "global": One authoring run for the whole graph.

  • "per-need": One authoring run per produced need.

  • "per-root": One authoring run per trace-chain root and its subtree.

  • "single": A single authoring run.

workflow.change_request.route.group_field
Type:
string

The optional grouping field, omitted from the emitted route dict when None.

workflow.change_request.route.path
Type:
string

The authoring path template (with {stream} / {id} placeholders).

workflow.change_request.route.scope
Type:
string

The authoring scope (stream or global).

Values:

  • "stream": Authored under a per-stream subtree.

  • "global": Authored at one global location.

  • "feature": Deprecated alias for stream, kept so a [workflow] authored before the feature -> stream rename keeps validating.

workflow.diagnostics
Type:
table

The diagnostics gate: which reported diagnostics on a workflow need hold its stage. Every key is optional; an absent table applies the same defaults as an empty one.

workflow.diagnostics.allow
Type:
array of strings
Default:
[]

Diagnostic codes that never hold a stage, whatever their severity. An entry matches a code exactly, or with a trailing .* a whole family.

workflow.diagnostics.deny
Type:
array of strings
Default:
[]

Diagnostic codes that always hold a stage, even below severity or schema_severity. Same matching as allow; when both match, the more specific entry wins.

workflow.diagnostics.schema_severity
Type:
string
Default:
"warning"

The lowest schema-rule severity that holds a stage, for schema-definition findings (needs.schema_definition_*): info, warning, violation, or none. Defaults to warning. Schema-network findings (needs.schema_network_info / _warning / _violation) judge the links between needs, which the workflow’s trace gates already cover in stage order, so no bar holds them; list a code under deny to hold on it anyway.

Values:

  • "none": Never hold a stage on schema-definition findings.

  • "info": Hold on info-or-worse schema-definition findings.

  • "warning": Hold on warning-or-worse schema-definition findings.

  • "violation": Hold only on violation-level schema-definition findings.

workflow.diagnostics.severity
Type:
string
Default:
"warning"

The lowest severity of a diagnostic that holds the stage of the need it is reported on: info, warning, error, or none to never hold. Defaults to warning. Schema-validation findings use schema_severity instead.

Values:

  • "none": Never hold a stage on a diagnostic’s severity.

  • "info": Hold on info-or-worse diagnostics.

  • "warning": Hold on warning-or-worse diagnostics.

  • "error": Hold only on error-level diagnostics.

workflow.diagram
Type:
table

The [workflow.diagram] sub-table: the diagram-gate config. Absent, or enabled = false, keeps the gate off (and the doctor then requires no diagram tool); enabled = true selects which engine’s tool the gate — and the doctor — require.

workflow.diagram.enabled
Type:
boolean
Default:
true

Whether the diagram gate is enabled (a present table is opt-in; set enabled = false to keep it parsed-but-off).

workflow.diagram.engine
Type:
string
Default:
"mermaid"

The gate engine: mermaid, plantuml, or both.

Values:

  • "mermaid": Validate .. mermaid:: blocks via mmdc.

  • "plantuml": Validate plantuml blocks via the plantuml binary.

  • "both": Validate both engines.

workflow.diagram.format
Type:
string

The diagram SYNTAX the runner should author any diagram as (e.g. mermaid or plantuml). Independent of the gate’s enabled / engine: it is the authoring directive injected into the runner prompt (“author it as a mermaid directive”), so a project can pin a diagram format for authoring even when the diagram GATE is off. None injects no format hint.

workflow.exempt_status
Type:
array of strings
Default:
[]

Statuses whose needs are dropped before coverage is computed.

workflow.icons
Type:
table of strings
Default:
{}

A map from a need type name to the icon it renders with in the workflow view. A type not listed here uses the default icon chosen for that type.

Each entry: The icon a need type renders with in the workflow view. One of a fixed set of presentation-neutral icon names; the editor offers these choices and rejects any other value.

Values:

  • "feature": A user-facing feature / user story / epic.

  • "req": A requirement (system, software, component, …).

  • "arch": An architecture / design element.

  • "code": A source-code artefact.

  • "test": A test / verification case.

  • "spec": A specification document.

  • "risk": A risk / FMEA entry.

  • "decision": A decision record.

  • "task": A task / work item.

  • "fsr": A functional safety requirement.

  • "hazard": A hazard / HARA entry.

  • "safety_goal": A safety goal.

  • "release": A release / milestone.

  • "people": A person / team / role.

  • "interface": An interface / API / port.

  • "component": A component / module / block.

  • "settings": A settings / configuration element.

workflow.lifecycle
Type:
table

The [workflow.lifecycle] sub-table: states for the deterministic status_undeclared gate. None (absent) or a present table with an empty/omitted states list keeps the gate off; a present table with a non-empty states list runs it.

workflow.lifecycle.states
Type:
array of strings
Default:
[]

The declared lifecycle states, in order. The first entry is the state a new need opens in.

workflow.lifecycle.transitions
Type:
array of (table or array of strings)
Default:
[]

The legal state transitions. Each entry is either the { from, to } table form ([[workflow.lifecycle.transitions]]) or the positional [from, to] pair, so a project can write whichever reads better.

Each entry: One [workflow.lifecycle] transition, accepting either the { from, to } table form or the positional [from, to] pair. A transition that is neither shape is rejected at parse time.

Forms:

  • a table with from: The { from = "...", to = "..." } table form ([[workflow.lifecycle.transitions]]).

  • an array of strings: The positional [from, to] pair form.

workflow.lifecycle.transitions[].from
Type:
string

The source state.

workflow.lifecycle.transitions[].to
Type:
string

The destination state.

workflow.orphan_exempt_types
Type:
array of strings
Default:
[]

Need types excluded from the orphan check only.

workflow.release_disallow_status
Type:
array of strings
Default:
[]

Statuses forbidden at release time.

workflow.stages
Type:
array of tables
Default:
[]

The [[workflow.stages]] entries, in declaration order.

Each entry: One [[workflow.stages]] entry: the full per-stage model the heartbeat surfaces. depends_on drives blocked; author_skill / review_skill are the per-stage skills; route is where the agent authors; trace / require_code are the gate config.

produces is OPTIONAL: a stage with no produces is a CODE-STAGE — it authors no need and is gated solely by its require_code (which must then carry an explicit type). A need-producing stage sets produces exactly as before.

workflow.stages[].author_skill
Type:
string

The stage’s authoring skill name, or None.

workflow.stages[].authoring
Type:
string

Project-specific authoring directive for this stage (free text), injected into the runner prompt’s INSTRUCTION section so HOW-MANY / WHAT-SHAPE policy (e.g. “decompose into the full set of requirements”) lives in config rather than in the generic skill prose. None (absent) injects nothing — the skill alone drives the stage.

workflow.stages[].depends_on
Type:
array of strings
Default:
[]

The ids of stages this stage depends on (drives blocked).

workflow.stages[].id
Type:
string

The stage id (the [[workflow.stages]] entry’s id).

workflow.stages[].optional
Type:
boolean
Default:
false

Whether this stage is optional: informational-only, never a required blocking step in the dependency chain. An optional stage is never forced as blocked or next in the agent flow — it surfaces only when the agent catches it during the process. Absent → false, so a stage without this key stays required.

workflow.stages[].produces
Type:
string

The need type the stage produces, or None for a CODE-STAGE.

workflow.stages[].require_code
Type:
table

The stage’s require_code field-presence gate, or None when absent.

workflow.stages[].require_code.field
Type:
string
Default:
"code_url"

The need field the gate ranges over (e.g. code_url).

workflow.stages[].require_code.min
Type:
integer
Default:
1

The minimum required non-empty values in field.

workflow.stages[].require_code.type
Type:
string

The explicit gated type, or None to default to the stage’s produces.

workflow.stages[].review_skill
Type:
string

The stage’s review skill name, or None.

workflow.stages[].route
Type:
table

Where the stage’s needs are authored, or None (rejected by the workflow-model parse — every stage must declare a route).

workflow.stages[].route.granularity
Type:
string

The authoring granularity (global, per-need, per-root, or single).

Values:

  • "global": One authoring run for the whole graph.

  • "per-need": One authoring run per produced need.

  • "per-root": One authoring run per trace-chain root and its subtree.

  • "single": A single authoring run.

workflow.stages[].route.group_field
Type:
string

The optional grouping field, omitted from the emitted route dict when None.

workflow.stages[].route.path
Type:
string

The authoring path template (with {stream} / {id} placeholders).

workflow.stages[].route.scope
Type:
string

The authoring scope (stream or global).

Values:

  • "stream": Authored under a per-stream subtree.

  • "global": Authored at one global location.

  • "feature": Deprecated alias for stream, kept so a [workflow] authored before the feature -> stream rename keeps validating.

workflow.stages[].trace
Type:
array of tables
Default:
[]

The stage’s trace gate edges.

Each entry: One [[workflow.stages.trace]] edge: the produced type traces UP to up via link. direction routes the edge: both (with non-empty up) is a bidirectional trace edge, incoming / outgoing are single-ended rules.

workflow.stages[].trace[].direction
Type:
string
Default:
"both"

The edge direction: both (bidirectional), incoming, or outgoing.

Values:

  • "both": Bidirectional: the produced child must trace UP via link to a need of the up type, and every up need must be covered DOWN by a need of the type this stage produces (both the trace_forward and trace_backward gates). A link whose far end is a need of some other type does not count.

  • "incoming": Backward only: the up (parent) type must carry the incoming link. This direction builds no trace edge today, so it raises no trace gap of its own. The stage still declares a trace gate and still owns orphan gaps on the up type.

  • "outgoing": Forward only: the produced child must carry the outgoing link. This direction builds no trace edge today, so it raises no trace gap of its own. The stage still declares a trace gate.

Type:
string

The link name the trace edge follows.

workflow.stages[].trace[].min
Type:
integer
Default:
1

The minimum required link count. Under both, only links whose far end carries the required type count toward it. Under incoming or outgoing no trace gate counts it, so it is only the number the authoring prompt dictates to whoever writes the need.

workflow.stages[].trace[].up
Type:
string

The upstream need type the produced type traces UP to.