/**
 * skillsFromDirRoutes — the `routes:` half of the on-disk runbook grammar.
 *
 * ## What a file may say about routing, and why it is this little
 *
 * `skillsFromDir` reads prose, `tools:` and `steps:` — everything about ONE
 * skill — and stopped exactly where the value was supposed to start: the
 * routing. A directory of runbooks still had to be hand-wired into a graph in
 * code, which is the work the graph exists to remove.
 *
 * This module adds the missing key under the SAME security law the tools list
 * follows: **the file PICKS, it never DEFINES.**
 *
 *   ---
 *   name: billing
 *   tools: lookup_order, issue_refund
 *   routes:
 *     - escalation: on issue_refund status=denied
 *     - receipts: on issue_refund
 *     - audit
 *   ---
 *
 * A route names a SKILL ID and, optionally, a guard. Both halves are picks:
 *
 *   • the id is resolved against the skills THIS DIRECTORY declares — an id
 *     nothing here declares is refused at load, by name, listing what is
 *     available. Never a half-graph: one bad id fails the whole load, because
 *     a graph missing one edge routes silently wrong, which is worse than a
 *     graph that refuses to exist;
 *   • the guard is one of the two DATA conditions a route already has
 *     (`onToolReturn`, `onToolStatus`), and the tool it names must be one of
 *     this file's own `tools:` — the same law `steps:` follows, for the same
 *     reason (an edge out of this skill fires on this skill's work).
 *
 * Nothing is evaluated, imported or resolved as a path. The strings can only
 * MATCH — against ids the loader already read off disk and against a closed
 * status vocabulary.
 *
 * ## What a file CANNOT express, said plainly
 *
 * A `when:` predicate is CODE. There is no honest way for a markdown file to
 * carry it: reading one would mean evaluating a string, which is the one thing
 * this loader exists never to do. So the grammar has no `when` and no
 * expression language of any kind — a conditional a file cannot express is a
 * conditional that stays in code:
 *
 *   skillGraph({ skills, steps: [{ from: 'billing', to: 'escalation',
 *                                  when: r => JSON.parse(r.result).tier > 2 }] });
 *
 * Anything that is not one of the three forms is refused with the whole grammar
 * quoted, rather than half-understood by a parser inventing a mini-language.
 *
 * Zone: HOST (it belongs to the file loader). Pure over strings all the same —
 * it reads no filesystem; `skillsFromDir.ts` hands it the parsed lines.
 */
import type { SkillGraphStep } from './skillGraph.js';
import { type ToolResultStatus } from '../semantics/toolOutcome.js';
/**
 * One frontmatter list item, structurally — `skillsFromDir`'s module-private
 * `ListItem` satisfies it unchanged, so the two never import each other.
 */
export interface RouteItem {
    /** Text before the first `:` — the target skill id. */
    readonly key: string;
    /** Text after the first `:` — the guard. Undefined when the item has none. */
    readonly value?: string;
    /** 1-based line number in the file. Every refusal quotes it. */
    readonly line: number;
}
/** One route as the FILE declared it: a target id and a parsed guard. The id is
 *  still unresolved here — a file cannot know what the rest of the directory
 *  carries, so that refusal waits for {@link toGraphSteps}. */
export interface DeclaredRoute {
    readonly to: string;
    readonly onToolReturn?: string;
    readonly onToolStatus?: readonly ToolResultStatus[];
    readonly line: number;
}
/**
 * Read one file's `routes:` items into declared routes, refusing every shape
 * the grammar does not carry. Pure; every message names the file and the line,
 * because "malformed routes" over a directory of forty runbooks has told the
 * author nothing.
 *
 * @param items      the `routes:` block-list items, in file order.
 * @param file       the path, quoted by every refusal.
 * @param toolNames  this file's own `tools:` — a guard may only name one of
 *                   them (undefined when the file declared no tools at all).
 */
export declare function readDeclaredRoutes(items: readonly RouteItem[], file: string, toolNames: readonly string[] | undefined): readonly DeclaredRoute[];
/**
 * Resolve one file's declared routes into graph steps, refusing an id no
 * SKILL.md in the directory declares.
 *
 * The refusal lists what IS available and fails the whole load. A route to a
 * name nothing declares is the one mistake that cannot be reported later: the
 * loader would return a skill set the graph then wires with a missing edge, and
 * a graph that silently does not route is exactly the failure the check-up
 * exists to prevent. Half a graph is not a smaller version of the graph.
 *
 * @param from   the id of the skill whose file declared these routes.
 * @param file   that skill's path, quoted by the refusal.
 * @param known  every skill id the directory declared.
 */
export declare function toGraphSteps(from: string, routes: readonly DeclaredRoute[], file: string, known: ReadonlySet<string>): readonly SkillGraphStep[];
