> ## Documentation Index
> Fetch the complete documentation index at: https://smithers-feat-claude-workflow-mirror.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# <DecisionTable>

> Flat rule table that replaces nested Branch trees with declarative routing.

```ts theme={null}
// Props
import { DecisionTable } from "smithers-orchestrator";

type DecisionTableProps = {
  id?: string;
  rules: DecisionRule[];
  default?: ReactElement; // rendered when no rule matches
  strategy?: "first-match" | "all-match"; // default "first-match"
  skipIf?: boolean;
};

type DecisionRule = {
  when: boolean; // evaluated at render time
  then: ReactElement;
  label?: string;
};
```

```tsx theme={null}
<DecisionTable
  rules={[
    {
      when: triage.severity === "critical",
      then: (
        <Task id="page-oncall" output={outputs.page} agent={pagerAgent}>
          Page the on-call engineer immediately.
        </Task>
      ),
    },
    {
      when: triage.severity === "high",
      then: <Task id="assign-senior" output={outputs.assign}>{{ assignee: "senior-pool" }}</Task>,
    },
  ]}
  default={<Task id="default-assign" output={outputs.assign}>{{ assignee: "general-pool" }}</Task>}
/>
```

## Notes

* `first-match` builds nested Branches; order matters.
* `all-match` wraps every matching rule in a Parallel; no ordering guarantee.

## Source

The `<DecisionTable>` implementation and the files it imports, straight from the package source. This section is generated; edit the source, not this block.

<CodeGroup>
  ```js DecisionTable.js theme={null}
  // @smithers-type-exports-begin
  /** @typedef {import("./DecisionRule.ts").DecisionRule} DecisionRule */
  /** @typedef {import("./DecisionTableProps.ts").DecisionTableProps} DecisionTableProps */
  // @smithers-type-exports-end

  import React from "react";
  import { Branch } from "./Branch.js";
  import { Parallel } from "./Parallel.js";
  /**
   * Structured deterministic routing. Replaces deeply nested Branches with a
   * flat, declarative rule table.
   *
   * - `"first-match"` builds nested Branch elements so the first matching rule wins.
   * - `"all-match"` gathers all matching rules' `then` elements into a Parallel.
   *
   * Composes Branch and Parallel internally.
   * @param {DecisionTableProps} props
   */
  export function DecisionTable(props) {
      if (props.skipIf)
          return null;
      const { rules, strategy = "first-match" } = props;
      if (strategy === "all-match") {
          const matching = rules.filter((r) => r.when).map((r) => r.then);
          if (matching.length === 0) {
              return props.default ?? null;
          }
          return React.createElement(Parallel, { id: props.id }, ...matching);
      }
      // "first-match": build nested Branches from the last rule backward.
      // The innermost else is the default fallback.
      let fallback = props.default ?? null;
      for (let i = rules.length - 1; i >= 0; i--) {
          const rule = rules[i];
          fallback = React.createElement(Branch, {
              if: rule.when,
              then: rule.then,
              else: fallback,
          });
      }
      return fallback;
  }
  ```

  ```js Branch.js theme={null}
  import React from "react";
  import { SmithersError } from "@smithers-orchestrator/errors/SmithersError";
  /** @typedef {import("./BranchProps.ts").BranchProps} BranchProps */

  /**
   * @param {BranchProps} props
   */
  export function Branch(props) {
      // <Branch> resolves its subtree from the `then`/`else` props; any JSX children
      // would be silently dropped, removing those tasks from the graph with no
      // feedback. Fail fast instead. (Checked before skipIf so a stray-children
      // mistake still surfaces even on a skipped branch.)
      if (props.children !== undefined && props.children !== null) {
          throw new SmithersError("INVALID_INPUT", `<Branch> does not take children. Use the "then" and "else" props instead, e.g. ` +
              `<Branch if={cond} then={<Task .../>} else={<Task .../>} />. ` +
              `Children passed to <Branch> are silently ignored and would drop those tasks from the graph.`);
      }
      if (props.skipIf)
          return null;
      const chosen = props.if ? props.then : (props.else ?? null);
      // The branch is resolved to `chosen` at render time, so the host element
      // carries no props of its own (align with the sanitizing structural components).
      return React.createElement("smithers:branch", {}, chosen);
  }
  ```

  ```js Parallel.js theme={null}
  import React from "react";
  /** @typedef {import("./ParallelProps.ts").ParallelProps} ParallelProps */

  /**
   * @param {ParallelProps} props
   */
  export function Parallel(props) {
      if (props.skipIf)
          return null;
      // Align prop sanitization with other structural components
      const next = {
          maxConcurrency: props.maxConcurrency,
          id: props.id,
      };
      return React.createElement("smithers:parallel", next, props.children);
  }
  ```

  ```ts DecisionRule.ts theme={null}
  import type React from "react";

  export type DecisionRule = {
  	/** Condition evaluated at render time. */
  	when: boolean;
  	/** Element to render when this rule matches. */
  	then: React.ReactElement;
  	/** Optional display label for the rule. */
  	label?: string;
  };
  ```

  ```ts DecisionTableProps.ts theme={null}
  import type React from "react";
  import type { DecisionRule } from "./DecisionRule.ts";

  export type DecisionTableProps = {
  	/** ID prefix for generated wrapper nodes. */
  	id?: string;
  	/** Ordered list of rules. Each rule has a `when` condition and a `then` element. */
  	rules: DecisionRule[];
  	/** Fallback element rendered when no rules match. */
  	default?: React.ReactElement;
  	/** `"first-match"` (default): first matching rule wins. `"all-match"`: all matching rules run in parallel. */
  	strategy?: "first-match" | "all-match";
  	skipIf?: boolean;
  };
  ```
</CodeGroup>
