/**
 * design/140 §6 1c — BUILT-IN named workflows offered by the `Workflow` tool's `{name}` calling surface,
 * mirroring the built-in agents precedent (src/agents/builtin-agents.ts: GA default-on, opt out via a
 * deployment config flag, same-name deployment registration SHADOWS the built-in):
 *  - `RunWorkflowToolDeps.builtinWorkflows: false` (threaded from `RunnerDeps.builtinWorkflows`) removes
 *    them wholesale;
 *  - a deployment `WorkflowScriptStore.resolveName` hit for the SAME NAME wins (the built-in is consulted
 *    only when the deployment registry does not resolve the name).
 *
 * The first built-in is `discussion` — the round-based collab profile design/140 §1 verified live
 * (docs/DESIGN-140-VERIFICATION-2026-07-11.md B 面: 2 members × 2 rounds + finalizer, 8.2s/10.5K tokens,
 * round 2 genuinely responding to round 1). It is pure SCRIPT CONTENT over the existing primitives — zero
 * new runtime mechanism:
 *  - args schema (ALL optional — zero-config must run): `{ topic, members?: [{ role, prompt?, model? }],
 *    rounds?, finalizer?: { prompt?, model? } }`; a bare STRING args is accepted as the topic.
 *  - budget: reuses the workflow `budget` hard ceiling + DETERMINISTIC in-script truncation (a rounds/member
 *    cap and a `budget.remaining()` early-stop — never an evaluator agent; design/140 §1 "预算" row).
 *  - `meta.whenToUse` carries the REQUIRED negative boundary (when-NOT-to-use: single factual question /
 *    budget-sensitive runs — design/140 §4 "两投影").
 */
import type { NamedWorkflowListing } from "./workflow-script-store.js";
/** The built-in round-based discussion workflow's registered name. */
export declare const DISCUSSION_WORKFLOW_NAME = "discussion";
/**
 * The registered name this built-in carried before the C-R14 vocabulary ruling (2026-08-16): "team" now
 * names the agent-teams family (persistent named teammates) only, and a one-off multi-agent debate is a
 * "discussion".
 *
 * RETENTION, as a fact rather than a plan: the ruling's original "kept resolvable for ONE minor" window
 * LAPSED. The alias has stayed on the public export surface from the 5.37.0 window through 7.x, across
 * BOTH the 6.0.0 and 7.0.0 BREAKING windows. It is therefore retained until a removal is announced in a
 * named BREAKING window's ship post — no minor removes it by default.
 *
 * @deprecated Use {@link DISCUSSION_WORKFLOW_NAME}. The retired spelling still RESOLVES via
 * {@link canonicalWorkflowName}, but the listing/card face shows the new name only.
 */
export declare const TEAM_DISCUSSION_WORKFLOW_NAME = "discussion";
/**
 * Map a REQUESTED built-in workflow name to its canonical name — identity for every name that is not a
 * retired alias. The canonical name is the authority: a resolution reached through an alias returns the
 * canonical definition (its `meta.name`, hence every run/card projection, is the new name).
 *
 * @deprecated together with the alias table — it becomes an identity function when that table is removed
 * in an announced BREAKING window (C-R14).
 */
export declare function canonicalWorkflowName(name: string): string;
/**
 * The retired spellings that address a given canonical built-in name (empty for every name with no
 * alias). Callers that probe the deployment registry per built-in name (the card's shadow probe) must
 * probe these too, so a deployment entry registered under EITHER spelling shadows the same built-in.
 *
 * @deprecated together with the alias table (C-R14).
 */
export declare function retiredWorkflowNameAliases(canonicalName: string): string[];
/**
 * Every spelling that addresses the SAME registry slot as `requested`, in lookup order: the requested
 * spelling first (so a deployment entry registered under the exact name the caller used always wins), then
 * its canonical name, then that canonical name's other retired spellings. Deduplicated in insertion order,
 * so a name with no alias yields exactly `[requested]` — one probe, unchanged from before the alias existed.
 *
 * SINGLE SOURCE on purpose. The deployment registry is consulted from two places — the `{name}` execute
 * path and the tool card's shadow probe — and design/140's card≡execute invariant means a SPELLING
 * asymmetry between them is a lie on the card, not a cosmetic difference: the first draft of this rename
 * probed the alias only on ONE side, so a deployment that had registered the RETIRED spelling was reported
 * as shadowing the built-in on the card while a canonical-name call silently launched the built-in instead
 * (found in adversarial review). Both sides iterate this list; neither builds its own.
 *
 * SCOPE of that guarantee, stated precisely: this aligns the two sites on WHICH SPELLINGS they ask about.
 * The other card/execute asymmetries are older than this helper and unchanged by it — the card swallows a
 * probe exception and keeps going while execute returns a structured error, the card treats any non-
 * `undefined` answer as a shadow while execute refuses a malformed shape, the card resolves at mount time
 * while execute resolves per call, and `list()` can overlay rows `resolveName` never answered. Equivalence
 * holds for a stable, well-formed registry; it was never total, and this helper does not make it so.
 *
 * NOTE for store implementers: a single resolution may therefore call `resolveName` more than once, with
 * different spellings, until one answers. `resolveName` must be a stable, side-effect-free lookup.
 *
 * Callers must apply the deployment's `builtinWorkflows` opt-out BEFORE using this: the equivalence is a
 * fact about the built-in registry, so a deployment that removed the built-ins removed the alias with them.
 *
 * @deprecated together with the alias table — collapses to `[requested]` when that table is removed in an
 * announced BREAKING window (C-R14).
 */
export declare function workflowNameProbeOrder(requested: string): string[];
/**
 * The `discussion` script source (design/140 §1 table row 1, live-verified shape: for-loop rounds +
 * `agent()` members with transcript re-feed + a schema'd finalizer). Deterministic by construction — no
 * clock/randomness reads (locked by test against `workflowScriptReadsClockOrRandom`).
 */
export declare const DISCUSSION_SCRIPT = "export const meta = {\n  name: \"discussion\",\n  description: \"Round-based discussion: configurable members debate a topic across rounds (each member sees the transcript so far), then a finalizer synthesizes a structured verdict.\",\n  whenToUse: \"Use for a genuinely contested question that benefits from several perspectives arguing across rounds - design trade-offs, plan or risk reviews, adversarial critique of a proposal. Do NOT use it for a single factual question, a task with one obvious answer, or a budget-sensitive run: every round costs one agent call per member, so a discussion is never cheaper than asking once. args (all optional): { topic, members?: [{ role, prompt?, model? }], rounds?, finalizer?: { prompt?, model? } }. Hard ceilings: members is capped at 6 and rounds is capped at 5 regardless of what you pass; the run reports it via log() and a capped field on the result when a request exceeds either.\",\n  phases: [\n    { title: \"Discussion\" },\n    { title: \"Synthesis\" },\n  ],\n};\n// Zero-config runnable (design/140 \u00A76 1c): every arg has an opinionated fallback.\nconst raw = args;\nconst a = raw !== null && typeof raw === \"object\" && !Array.isArray(raw) ? raw : {};\nconst topic =\n  typeof a.topic === \"string\" && a.topic.trim() !== \"\"\n    ? a.topic\n    : typeof raw === \"string\" && raw.trim() !== \"\"\n      ? raw // ergonomic form: a bare string args IS the topic\n      : \"No topic was provided. Discuss: what information should a caller supply to make a discussion like this productive, and when should they NOT convene one?\";\nconst defaultMembers = [\n  { role: \"advocate\", prompt: \"Make the strongest constructive case. Propose concrete options and argue their benefits with specifics.\" },\n  { role: \"skeptic\", prompt: \"Stress-test every claim made so far. Surface risks, hidden costs, failure modes, and cheaper alternatives.\" },\n];\nconst rawMembers = Array.isArray(a.members) && a.members.length > 0 ? a.members : defaultMembers;\nconst members = rawMembers.slice(0, 6).map((m, i) => {\n  const mm = m !== null && typeof m === \"object\" ? m : {};\n  const member = {\n    role: typeof mm.role === \"string\" && mm.role.trim() !== \"\" ? mm.role : \"member-\" + (i + 1),\n    prompt: typeof mm.prompt === \"string\" && mm.prompt.trim() !== \"\" ? mm.prompt : \"Contribute your own distinct perspective: be concrete, give reasons, and engage with what others said.\",\n  };\n  if (typeof mm.model === \"string\" && mm.model.trim() !== \"\") member.model = mm.model;\n  // Slot-tools carrier (design/140 \u2461-3 + F4): a member may BE a registered agent type ({agent:\"reviewer\"}) \u2014\n  // persona/tools/model then come from the deployment's AgentDefinition (role library), args stay thin.\n  if (typeof mm.agent === \"string\" && mm.agent.trim() !== \"\") member.agent = mm.agent;\n  return member;\n});\n// Deterministic budget truncation (design/140 \u00A71 \u9884\u7B97 row): a HARD rounds ceiling + member cap \u2014 never an\n// evaluator agent. The engine's budget/maxAgents hard stops remain the backstop.\nconst requestedRounds = Math.floor(Number(a.rounds));\nconst normalizedRounds = Number.isFinite(requestedRounds) && requestedRounds >= 1 ? requestedRounds : 2;\nconst rounds = Math.min(normalizedRounds, 5);\n// RB-380 disclosure: the member/round slices above are silent by construction (Array.prototype.slice /\n// Math.min just drop the excess) \u2014 record + surface it instead of a caller finding out only by counting\n// transcript entries. Fires only when a request actually exceeded a ceiling (never on the common path).\nconst capNotes = [];\nif (rawMembers.length > 6) capNotes.push(\"requested \" + rawMembers.length + \" members, capped at 6\");\nif (normalizedRounds > 5) capNotes.push(\"requested \" + normalizedRounds + \" rounds, capped at 5\");\nfor (const note of capNotes) log(\"discussion: \" + note);\nconst fin = a.finalizer !== null && typeof a.finalizer === \"object\" && !Array.isArray(a.finalizer) ? a.finalizer : {};\nconst finalizerPrompt = typeof fin.prompt === \"string\" && fin.prompt.trim() !== \"\"\n  ? fin.prompt\n  : \"You are the synthesis lead. Read the full discussion transcript and produce the final verdict: the decision/answer, the key supporting points, and the strongest unresolved dissent (if any). Do not introduce new arguments of your own.\";\nconst clip = (s) => { const t = String(s); return t.length > 4000 ? t.slice(0, 4000) + \" ...[truncated]\" : t; };\nconst isBudgetStop = (e) => e !== null && typeof e === \"object\" && e.code === \"workflow.budget_exceeded\";\n\nphase(\"Discussion\");\nconst transcript = [];\nlet truncated = null;\nfor (let r = 1; r <= rounds && truncated === null; r++) {\n  // Deterministic early stop on an exhausted budget (a live read of the engine budget; the engine's\n  // hard WorkflowBudgetExceededError remains the backstop if a member call itself crosses the line).\n  if (budget.total !== null && budget.remaining() <= 0) { truncated = \"budget exhausted before round \" + r; break; }\n  for (const m of members) {\n    const history = transcript.length === 0 ? \"(none yet - you open the discussion)\" : transcript.join(\"\\n\\n\");\n    const spec = {\n      objective:\n        \"Discussion on: \" + topic + \"\\n\\n\" +\n        'You are \"' + m.role + '\" in round ' + r + \" of \" + rounds + \".\\n\" +\n        \"Your brief: \" + m.prompt + \"\\n\\n\" +\n        \"Transcript so far:\\n\" + history + \"\\n\\n\" +\n        \"Respond to the strongest points others made (do not repeat yourself), then advance your own position. Be concise: a few tight paragraphs at most.\",\n    };\n    if (m.model !== undefined) spec.modelName = m.model;\n    let res;\n    try {\n      res = await agent(spec, m.agent !== undefined ? { label: m.role + \"-r\" + r, phase: \"Discussion\", agentType: m.agent } : { label: m.role + \"-r\" + r, phase: \"Discussion\" });\n    } catch (e) {\n      // The engine's budget hard stop: keep what the discussion already produced instead of failing the run.\n      if (isBudgetStop(e)) { truncated = \"budget exhausted at \" + m.role + \", round \" + r; break; }\n      throw e;\n    }\n    const text = res && res.terminal && res.terminal.kind === \"completed\" ? clip(res.result) : \"(no contribution - agent ended \" + (res && res.terminal ? res.terminal.kind : \"unknown\") + \")\";\n    transcript.push(m.role + \" (round \" + r + \"): \" + text);\n  }\n}\n\nphase(\"Synthesis\");\nconst finalSpec = {\n  objective:\n    finalizerPrompt + \"\\n\\nTopic: \" + topic + \"\\n\\nFull transcript:\\n\" +\n    (transcript.length === 0 ? \"(the discussion produced no contributions)\" : transcript.join(\"\\n\\n\")) +\n    (truncated ? \"\\n\\nNote: the discussion was cut short (\" + truncated + \").\" : \"\"),\n};\nif (typeof fin.model === \"string\" && fin.model.trim() !== \"\") finalSpec.modelName = fin.model;\nlet verdict = null;\ntry {\n  verdict = await agent(finalSpec, {\n    label: \"finalizer\",\n    phase: \"Synthesis\",\n    schema: {\n      type: \"object\",\n      properties: {\n        decision: { type: \"string\", description: \"The final answer/decision, one paragraph.\" },\n        keyPoints: { type: \"array\", items: { type: \"string\" }, description: \"The strongest supporting points from the discussion.\" },\n        dissent: { type: \"string\", description: \"The strongest unresolved counter-position, if any.\" },\n      },\n      required: [\"decision\", \"keyPoints\"],\n    },\n  });\n} catch (e) {\n  // Budget died before synthesis: return the transcript honestly rather than failing the whole run.\n  if (!isBudgetStop(e)) throw e;\n  truncated = truncated === null ? \"budget exhausted before synthesis\" : truncated;\n}\n\nreturn {\n  topic,\n  rounds,\n  members: members.map((m) => m.role),\n  ...(capNotes.length > 0 ? { capped: capNotes } : {}),\n  ...(truncated ? { truncated } : {}),\n  transcript,\n  verdict: verdict && verdict.structuredOutput !== undefined ? verdict.structuredOutput : (verdict ? verdict.result : null),\n};\n";
/**
 * @deprecated Use {@link DISCUSSION_SCRIPT}. Retired spelling retained (C-R14; the original one-minor
 * window lapsed — removal needs an announced BREAKING window) so a deployment importing the constant by
 * its old name keeps compiling; the value is the SAME script (its `meta.name`
 * is the new `discussion`).
 */
export declare const TEAM_DISCUSSION_SCRIPT = "export const meta = {\n  name: \"discussion\",\n  description: \"Round-based discussion: configurable members debate a topic across rounds (each member sees the transcript so far), then a finalizer synthesizes a structured verdict.\",\n  whenToUse: \"Use for a genuinely contested question that benefits from several perspectives arguing across rounds - design trade-offs, plan or risk reviews, adversarial critique of a proposal. Do NOT use it for a single factual question, a task with one obvious answer, or a budget-sensitive run: every round costs one agent call per member, so a discussion is never cheaper than asking once. args (all optional): { topic, members?: [{ role, prompt?, model? }], rounds?, finalizer?: { prompt?, model? } }. Hard ceilings: members is capped at 6 and rounds is capped at 5 regardless of what you pass; the run reports it via log() and a capped field on the result when a request exceeds either.\",\n  phases: [\n    { title: \"Discussion\" },\n    { title: \"Synthesis\" },\n  ],\n};\n// Zero-config runnable (design/140 \u00A76 1c): every arg has an opinionated fallback.\nconst raw = args;\nconst a = raw !== null && typeof raw === \"object\" && !Array.isArray(raw) ? raw : {};\nconst topic =\n  typeof a.topic === \"string\" && a.topic.trim() !== \"\"\n    ? a.topic\n    : typeof raw === \"string\" && raw.trim() !== \"\"\n      ? raw // ergonomic form: a bare string args IS the topic\n      : \"No topic was provided. Discuss: what information should a caller supply to make a discussion like this productive, and when should they NOT convene one?\";\nconst defaultMembers = [\n  { role: \"advocate\", prompt: \"Make the strongest constructive case. Propose concrete options and argue their benefits with specifics.\" },\n  { role: \"skeptic\", prompt: \"Stress-test every claim made so far. Surface risks, hidden costs, failure modes, and cheaper alternatives.\" },\n];\nconst rawMembers = Array.isArray(a.members) && a.members.length > 0 ? a.members : defaultMembers;\nconst members = rawMembers.slice(0, 6).map((m, i) => {\n  const mm = m !== null && typeof m === \"object\" ? m : {};\n  const member = {\n    role: typeof mm.role === \"string\" && mm.role.trim() !== \"\" ? mm.role : \"member-\" + (i + 1),\n    prompt: typeof mm.prompt === \"string\" && mm.prompt.trim() !== \"\" ? mm.prompt : \"Contribute your own distinct perspective: be concrete, give reasons, and engage with what others said.\",\n  };\n  if (typeof mm.model === \"string\" && mm.model.trim() !== \"\") member.model = mm.model;\n  // Slot-tools carrier (design/140 \u2461-3 + F4): a member may BE a registered agent type ({agent:\"reviewer\"}) \u2014\n  // persona/tools/model then come from the deployment's AgentDefinition (role library), args stay thin.\n  if (typeof mm.agent === \"string\" && mm.agent.trim() !== \"\") member.agent = mm.agent;\n  return member;\n});\n// Deterministic budget truncation (design/140 \u00A71 \u9884\u7B97 row): a HARD rounds ceiling + member cap \u2014 never an\n// evaluator agent. The engine's budget/maxAgents hard stops remain the backstop.\nconst requestedRounds = Math.floor(Number(a.rounds));\nconst normalizedRounds = Number.isFinite(requestedRounds) && requestedRounds >= 1 ? requestedRounds : 2;\nconst rounds = Math.min(normalizedRounds, 5);\n// RB-380 disclosure: the member/round slices above are silent by construction (Array.prototype.slice /\n// Math.min just drop the excess) \u2014 record + surface it instead of a caller finding out only by counting\n// transcript entries. Fires only when a request actually exceeded a ceiling (never on the common path).\nconst capNotes = [];\nif (rawMembers.length > 6) capNotes.push(\"requested \" + rawMembers.length + \" members, capped at 6\");\nif (normalizedRounds > 5) capNotes.push(\"requested \" + normalizedRounds + \" rounds, capped at 5\");\nfor (const note of capNotes) log(\"discussion: \" + note);\nconst fin = a.finalizer !== null && typeof a.finalizer === \"object\" && !Array.isArray(a.finalizer) ? a.finalizer : {};\nconst finalizerPrompt = typeof fin.prompt === \"string\" && fin.prompt.trim() !== \"\"\n  ? fin.prompt\n  : \"You are the synthesis lead. Read the full discussion transcript and produce the final verdict: the decision/answer, the key supporting points, and the strongest unresolved dissent (if any). Do not introduce new arguments of your own.\";\nconst clip = (s) => { const t = String(s); return t.length > 4000 ? t.slice(0, 4000) + \" ...[truncated]\" : t; };\nconst isBudgetStop = (e) => e !== null && typeof e === \"object\" && e.code === \"workflow.budget_exceeded\";\n\nphase(\"Discussion\");\nconst transcript = [];\nlet truncated = null;\nfor (let r = 1; r <= rounds && truncated === null; r++) {\n  // Deterministic early stop on an exhausted budget (a live read of the engine budget; the engine's\n  // hard WorkflowBudgetExceededError remains the backstop if a member call itself crosses the line).\n  if (budget.total !== null && budget.remaining() <= 0) { truncated = \"budget exhausted before round \" + r; break; }\n  for (const m of members) {\n    const history = transcript.length === 0 ? \"(none yet - you open the discussion)\" : transcript.join(\"\\n\\n\");\n    const spec = {\n      objective:\n        \"Discussion on: \" + topic + \"\\n\\n\" +\n        'You are \"' + m.role + '\" in round ' + r + \" of \" + rounds + \".\\n\" +\n        \"Your brief: \" + m.prompt + \"\\n\\n\" +\n        \"Transcript so far:\\n\" + history + \"\\n\\n\" +\n        \"Respond to the strongest points others made (do not repeat yourself), then advance your own position. Be concise: a few tight paragraphs at most.\",\n    };\n    if (m.model !== undefined) spec.modelName = m.model;\n    let res;\n    try {\n      res = await agent(spec, m.agent !== undefined ? { label: m.role + \"-r\" + r, phase: \"Discussion\", agentType: m.agent } : { label: m.role + \"-r\" + r, phase: \"Discussion\" });\n    } catch (e) {\n      // The engine's budget hard stop: keep what the discussion already produced instead of failing the run.\n      if (isBudgetStop(e)) { truncated = \"budget exhausted at \" + m.role + \", round \" + r; break; }\n      throw e;\n    }\n    const text = res && res.terminal && res.terminal.kind === \"completed\" ? clip(res.result) : \"(no contribution - agent ended \" + (res && res.terminal ? res.terminal.kind : \"unknown\") + \")\";\n    transcript.push(m.role + \" (round \" + r + \"): \" + text);\n  }\n}\n\nphase(\"Synthesis\");\nconst finalSpec = {\n  objective:\n    finalizerPrompt + \"\\n\\nTopic: \" + topic + \"\\n\\nFull transcript:\\n\" +\n    (transcript.length === 0 ? \"(the discussion produced no contributions)\" : transcript.join(\"\\n\\n\")) +\n    (truncated ? \"\\n\\nNote: the discussion was cut short (\" + truncated + \").\" : \"\"),\n};\nif (typeof fin.model === \"string\" && fin.model.trim() !== \"\") finalSpec.modelName = fin.model;\nlet verdict = null;\ntry {\n  verdict = await agent(finalSpec, {\n    label: \"finalizer\",\n    phase: \"Synthesis\",\n    schema: {\n      type: \"object\",\n      properties: {\n        decision: { type: \"string\", description: \"The final answer/decision, one paragraph.\" },\n        keyPoints: { type: \"array\", items: { type: \"string\" }, description: \"The strongest supporting points from the discussion.\" },\n        dissent: { type: \"string\", description: \"The strongest unresolved counter-position, if any.\" },\n      },\n      required: [\"decision\", \"keyPoints\"],\n    },\n  });\n} catch (e) {\n  // Budget died before synthesis: return the transcript honestly rather than failing the whole run.\n  if (!isBudgetStop(e)) throw e;\n  truncated = truncated === null ? \"budget exhausted before synthesis\" : truncated;\n}\n\nreturn {\n  topic,\n  rounds,\n  members: members.map((m) => m.role),\n  ...(capNotes.length > 0 ? { capped: capNotes } : {}),\n  ...(truncated ? { truncated } : {}),\n  transcript,\n  verdict: verdict && verdict.structuredOutput !== undefined ? verdict.structuredOutput : (verdict ? verdict.result : null),\n};\n";
/** One built-in named workflow: the registered name + its self-contained script source. The name is the
 *  routing key of the `{name}` calling surface; the script's `meta.name` matches it (locked by test). */
export interface BuiltinWorkflowDefinition {
    name: string;
    script: string;
}
/**
 * The built-in named-workflow registry. Order = card listing order.
 *
 * RB-342 (2026-07-29): the previous note called this a "CC `HCe`-analog shape". `HCe` is not a workflow
 * symbol in the 220 corpus at all (it is a memoized JSX local in a renderer, pretty220 885850+) — the name
 * came from an older bundle and drifted, the standing hazard with minified identifiers. The real 220
 * counterpart is the built-in workflow list behind `Rsn()` / `Dft()` (451216 / 454626), and the shape
 * matches only PARTLY:
 *
 *  - **Registry, not literal.** 220's backing array is initialised EMPTY (`kSd = []`, 451221) and filled at
 *    startup by feature-gated registrars (`DRo`, 451207 — two callers, `code-review` @496716 and
 *    `deep-research` @497127, each behind its own enablement check); `Rsn()` additionally returns `[]`
 *    wholesale when its gate is off. sema's list is a compile-time literal with no gating. Same role,
 *    different lifecycle — do not read "CC ships these built-ins unconditionally" out of this function.
 *  - **Shadowing holds; ordering does not transfer.** 220 resolves by concatenating
 *    `[...builtins.filter(name not taken), ...userLevel, ...projectLevel]` (454641-454647): a
 *    deployment-defined workflow of the same name REMOVES the built-in, which is the same net rule as
 *    {@link resolveBuiltinWorkflow} being the second lookup. But 220 lists built-ins FIRST and enforces the
 *    shadow by filtering, while sema enforces it by lookup order — so the listing order here is sema's own
 *    choice, not a parity constraint.
 */
export declare function builtinWorkflowDefinitions(): BuiltinWorkflowDefinition[];
/** Resolve a built-in workflow by name (the `{name}` surface's SECOND lookup — a deployment
 *  `scriptStore.resolveName` hit for the same name shadows this, design/140 §6 1c). A retired spelling
 *  (C-R14, one minor) resolves through {@link canonicalWorkflowName} to the SAME definition, so the
 *  returned `name` — and therefore every downstream projection — is the canonical one. */
export declare function resolveBuiltinWorkflow(name: string): BuiltinWorkflowDefinition | undefined;
/** design/140 §6 1b — the built-ins' listing projection rows (name + description + whenToUse, parsed from
 *  each script's static meta). Consumed by the Workflow tool card renderer. */
export declare function builtinWorkflowListings(): NamedWorkflowListing[];
