@ansible-flow/core 0.86.0 → 0.88.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/ai/describe.js +8 -7
- package/dist/ai/handlers.js +27 -25
- package/dist/ai/handlers.js.map +1 -1
- package/dist/ai/ops.js +8 -7
- package/dist/ai/reference.js +2 -2
- package/dist/ai/scenarios.js +12 -8
- package/dist/awx/import.js +7 -6
- package/dist/catalog/draft.d.ts +2 -0
- package/dist/catalog/draft.js +23 -4
- package/dist/catalog/draft.js.map +2 -2
- package/dist/chunks/{chunk-BXHI5EQM.js → chunk-2DT5DOSO.js} +43 -1
- package/dist/chunks/chunk-2DT5DOSO.js.map +7 -0
- package/dist/chunks/{chunk-DHU774ES.js → chunk-2KB3J3R5.js} +2 -2
- package/dist/chunks/{chunk-EAJFZKPB.js → chunk-37FKZNRN.js} +3 -3
- package/dist/chunks/{chunk-TPRZZHXA.js → chunk-57KJYXWA.js} +7 -7
- package/dist/chunks/{chunk-JTWR3TGG.js → chunk-7ALTNZCI.js} +4 -4
- package/dist/chunks/{chunk-UXIXXEIW.js → chunk-APBEHKCF.js} +2 -2
- package/dist/chunks/{chunk-ZAYNYPCX.js → chunk-ARA3VJR2.js} +2 -2
- package/dist/chunks/{chunk-7GLSXIZ3.js → chunk-BSX6G7QY.js} +5 -5
- package/dist/chunks/{chunk-H7Z2FBRD.js → chunk-CATQHJS6.js} +8 -8
- package/dist/chunks/{chunk-J7KCGVHU.js → chunk-CCWUUVSG.js} +2 -2
- package/dist/chunks/{chunk-C6SQEXL5.js → chunk-CNQ7M7HA.js} +2 -2
- package/dist/chunks/{chunk-NT62IE3Y.js → chunk-CNYGDBID.js} +2 -2
- package/dist/chunks/chunk-FIKPXL6E.js +23 -0
- package/dist/chunks/chunk-FIKPXL6E.js.map +7 -0
- package/dist/chunks/{chunk-CM23ODBB.js → chunk-J5LYSQ3L.js} +2 -2
- package/dist/chunks/{chunk-72LO6GQE.js → chunk-KXD6FX2Z.js} +2 -2
- package/dist/chunks/{chunk-4RMWFRWG.js → chunk-LELKMVJG.js} +45 -7
- package/dist/chunks/chunk-LELKMVJG.js.map +7 -0
- package/dist/chunks/{chunk-XOPGOWNQ.js → chunk-O5Y3AZ4X.js} +1 -1
- package/dist/chunks/chunk-O5Y3AZ4X.js.map +7 -0
- package/dist/chunks/{chunk-5XGAGNH5.js → chunk-OGNFHW5O.js} +7 -13
- package/dist/chunks/chunk-OGNFHW5O.js.map +7 -0
- package/dist/chunks/chunk-OJZSZBHW.js +45 -0
- package/dist/chunks/chunk-OJZSZBHW.js.map +7 -0
- package/dist/chunks/{chunk-R4MW3DRT.js → chunk-OW32YCZ6.js} +2 -2
- package/dist/chunks/{chunk-2QQC4IZ7.js → chunk-PNLY5IWM.js} +8 -8
- package/dist/chunks/chunk-PNLY5IWM.js.map +7 -0
- package/dist/chunks/{chunk-76T45V37.js → chunk-TBFB7A2Z.js} +5 -1
- package/dist/chunks/{chunk-76T45V37.js.map → chunk-TBFB7A2Z.js.map} +2 -2
- package/dist/chunks/{chunk-BXJOUAXV.js → chunk-TEJARYAE.js} +3 -3
- package/dist/chunks/{chunk-T5UB4MBB.js → chunk-TOTSB4HG.js} +41 -1
- package/dist/chunks/chunk-TOTSB4HG.js.map +7 -0
- package/dist/chunks/{chunk-MZ6IJWB2.js → chunk-TPMACJFA.js} +4 -4
- package/dist/chunks/{chunk-CXVJWFGT.js → chunk-WTVGCMGV.js} +8 -4
- package/dist/chunks/chunk-WTVGCMGV.js.map +7 -0
- package/dist/chunks/{chunk-6MLYGFT6.js → chunk-XJAMBKE3.js} +6 -2
- package/dist/chunks/chunk-XJAMBKE3.js.map +7 -0
- package/dist/chunks/{chunk-ABYJBONR.js → chunk-ZXUXX3YY.js} +4 -4
- package/dist/engine/binding.js +3 -1
- package/dist/engine/bypass.js +4 -2
- package/dist/engine/engines.js +9 -5
- package/dist/engine/files.js +9 -5
- package/dist/engine/optionA.js +8 -4
- package/dist/engine/partial.js +3 -1
- package/dist/engine/partial.js.map +1 -1
- package/dist/engine/preview.js +9 -5
- package/dist/engine/preview.js.map +1 -1
- package/dist/engine/writePlan.js +12 -9
- package/dist/export/drawio.js +3 -3
- package/dist/export/layoutCheck.js +3 -3
- package/dist/export/scene.js +2 -2
- package/dist/export/svg.js +4 -4
- package/dist/flow/commands.d.ts +10 -0
- package/dist/flow/commands.js +3 -1
- package/dist/flow/facts.d.ts +6 -0
- package/dist/flow/facts.js +13 -0
- package/dist/flow/facts.js.map +7 -0
- package/dist/flow/findingCodes.js +1 -1
- package/dist/flow/localFiles.d.ts +17 -0
- package/dist/flow/localFiles.js +14 -0
- package/dist/flow/localFiles.js.map +7 -0
- package/dist/flow/save.js +3 -1
- package/dist/flow/save.js.map +1 -1
- package/dist/flow/validate.js +3 -2
- package/dist/import/outline.js +9 -7
- package/dist/import/playbook.js +6 -5
- package/dist/import/source.js +3 -2
- package/dist/lens/caption.js +1 -1
- package/dist/lens/data.js +3 -1
- package/dist/lens/index.js +11 -9
- package/dist/lens/index.js.map +1 -1
- package/dist/lens/types.d.ts +2 -0
- package/dist/lens/types.js +1 -1
- package/dist/messageCheck.js +2 -0
- package/dist/messageCheck.js.map +2 -2
- package/dist/protocol.d.ts +29 -0
- package/dist/run/command.d.ts +13 -4
- package/dist/run/command.js +19 -0
- package/dist/run/command.js.map +3 -3
- package/dist/scenario/live.js +11 -7
- package/dist/scenario/simulate.js +10 -6
- package/dist/view/flowFacts.js +12 -9
- package/dist/view/flowFacts.js.map +1 -1
- package/dist/view/route.d.ts +3 -1
- package/dist/view/route.js +1 -1
- package/dist/view/serverChange.d.ts +23 -0
- package/dist/view/serverChange.js +48 -0
- package/dist/view/serverChange.js.map +7 -0
- package/package.json +1 -1
- package/dist/chunks/chunk-2QQC4IZ7.js.map +0 -7
- package/dist/chunks/chunk-4RMWFRWG.js.map +0 -7
- package/dist/chunks/chunk-5XGAGNH5.js.map +0 -7
- package/dist/chunks/chunk-6MLYGFT6.js.map +0 -7
- package/dist/chunks/chunk-BXHI5EQM.js.map +0 -7
- package/dist/chunks/chunk-CXVJWFGT.js.map +0 -7
- package/dist/chunks/chunk-T5UB4MBB.js.map +0 -7
- package/dist/chunks/chunk-XOPGOWNQ.js.map +0 -7
- /package/dist/chunks/{chunk-DHU774ES.js.map → chunk-2KB3J3R5.js.map} +0 -0
- /package/dist/chunks/{chunk-EAJFZKPB.js.map → chunk-37FKZNRN.js.map} +0 -0
- /package/dist/chunks/{chunk-TPRZZHXA.js.map → chunk-57KJYXWA.js.map} +0 -0
- /package/dist/chunks/{chunk-JTWR3TGG.js.map → chunk-7ALTNZCI.js.map} +0 -0
- /package/dist/chunks/{chunk-UXIXXEIW.js.map → chunk-APBEHKCF.js.map} +0 -0
- /package/dist/chunks/{chunk-ZAYNYPCX.js.map → chunk-ARA3VJR2.js.map} +0 -0
- /package/dist/chunks/{chunk-7GLSXIZ3.js.map → chunk-BSX6G7QY.js.map} +0 -0
- /package/dist/chunks/{chunk-H7Z2FBRD.js.map → chunk-CATQHJS6.js.map} +0 -0
- /package/dist/chunks/{chunk-J7KCGVHU.js.map → chunk-CCWUUVSG.js.map} +0 -0
- /package/dist/chunks/{chunk-C6SQEXL5.js.map → chunk-CNQ7M7HA.js.map} +0 -0
- /package/dist/chunks/{chunk-NT62IE3Y.js.map → chunk-CNYGDBID.js.map} +0 -0
- /package/dist/chunks/{chunk-CM23ODBB.js.map → chunk-J5LYSQ3L.js.map} +0 -0
- /package/dist/chunks/{chunk-72LO6GQE.js.map → chunk-KXD6FX2Z.js.map} +0 -0
- /package/dist/chunks/{chunk-R4MW3DRT.js.map → chunk-OW32YCZ6.js.map} +0 -0
- /package/dist/chunks/{chunk-BXJOUAXV.js.map → chunk-TEJARYAE.js.map} +0 -0
- /package/dist/chunks/{chunk-MZ6IJWB2.js.map → chunk-TPMACJFA.js.map} +0 -0
- /package/dist/chunks/{chunk-ABYJBONR.js.map → chunk-ZXUXX3YY.js.map} +0 -0
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../../../src/core/lens/data.ts"],
|
|
4
|
-
"sourcesContent": ["// Data lens (04 \u00A77, decision 14): what each node reads and writes, and the data wires derived from\n// `from:` references. A reference into another level is drawn from the producer to the subflow\n// that contains the consumer, on the producer's level.\nimport { liftOf, resolveFrom } from '../flow/dataRefs';\nimport { exprRefs, templated } from '../flow/jinja';\nimport { modelOf, ROOT } from '../flow/model';\nimport type { FlowDocument, FlowNode, Ulid } from '../flow/types';\nimport { isWork, listChip, title, visibleAt } from './common';\nimport type { DataWire, LensChip, LensFinding, LensItem, LensView } from './types';\n\nexport function dataLens(doc: FlowDocument): LensView {\n const model = modelOf(doc);\n const flowInputs = doc.flow.inputs ?? {};\n const start = model.levels.get(ROOT)?.nodes.find((n) => n?.type === 'start')?.id;\n const chips: Record<Ulid, LensChip[]> = {};\n const wires = new Map<string, DataWire>();\n const findings: LensFinding[] = [];\n /** `key.output` \u2192 consumers. */\n const readers = new Map<string, Set<Ulid>>();\n const inputUse = new Map<string, Set<Ulid>>();\n\n const wire = (from: Ulid, to: Ulid, label: string, text: string) => {\n if (from === to) return;\n const id = `data:${from}>${to}`;\n const w = wires.get(id);\n if (!w) wires.set(id, { id, from, to, label, title: text });\n else if (!w.label.split(', ').includes(label)) {\n w.label = `${w.label}, ${label}`;\n w.title = `${w.title}\\n${text}`;\n }\n };\n\n for (const { node, level } of model.nodes.values()) {\n if (!isWork(node)) continue;\n const ins = Object.keys(node.inputs ?? {});\n const outs = Object.keys(node.outputs ?? {});\n chips[node.id] = [listChip('in: ', ins), listChip('out: ', outs)].filter(\n (c): c is LensChip => !!c,\n );\n // AFD-112: an input a Timing setting reads at run time says so on its wire.\n const timing = timingReads(node);\n for (const [name, field] of Object.entries(node.inputs ?? {})) {\n const from = field?.from;\n const readBy = timing.get(name)?.join(', ');\n const by = readBy ? ` \u00B7 ${readBy}` : '';\n if (!from) {\n // AFD-106 (round 3: R7): required or not, nothing feeds it (the validator's input-unfed).\n if (field?.default === undefined && field?.type !== 'host_list')\n findings.push({\n id: `data:unfed:${node.id}.${name}`,\n lens: 'data',\n severity: 'warning',\n title: `${node.title} has no value for ${name}`,\n detail: `The input ${name} has no default and no \\`from:\\`. Wire it to a flow input or an upstream output.`,\n node: node.id,\n nodes: [node.id],\n fixes: [{ label: 'Open Details', properties: node.id }],\n });\n continue;\n }\n const src = resolveFrom(model, node, level, 'inputs', from);\n // Inside a subflow, <subflow>.<input> reads its input: drawn where the subflow gets it.\n if (src.kind === 'impl' || src.kind === 'subflowInput') continue;\n if (src.kind === 'unresolved') {\n findings.push(unresolved(node.id, node.title, name, from, src.why));\n continue;\n }\n if (src.kind === 'flow') {\n const out = src.name;\n inputUse.set(out, (inputUse.get(out) ?? new Set()).add(node.id));\n const to = start ? visibleAt(model, node.id, ROOT) : undefined;\n if (start && to) wire(start, to, out, `flow.${out} \u2192 ${node.title}.${name}${by}`);\n continue;\n }\n const producer = src.node.id;\n const p = model.nodes.get(producer);\n if (!p) continue;\n const out = src.name;\n // By producer ID: keys repeat across levels.\n const key = `${producer}.${out}`;\n readers.set(key, (readers.get(key) ?? new Set()).add(node.id));\n const to = visibleAt(model, node.id, p.level);\n if (to)\n wire(\n producer,\n to,\n out === name ? out : `${out} \u2192 ${name}`,\n `${from} \u2192 ${node.title}.${name}${by}`,\n );\n }\n }\n\n // A subflow output reads the inner output it lifts (AFD-7, AFD-21).\n for (const { node } of model.nodes.values())\n for (const out of node.type === 'subflow' ? Object.keys(node.outputs ?? {}) : []) {\n const lift = liftOf(node, out);\n if (!lift || !('inner' in lift)) continue;\n const key = `${lift.inner.id}.${lift.output}`;\n readers.set(key, (readers.get(key) ?? new Set()).add(node.id));\n }\n\n const variables: LensItem[] = [];\n for (const { node } of model.nodes.values()) {\n for (const out of Object.keys(node.outputs ?? {})) {\n const users = [...(readers.get(`${node.id}.${out}`) ?? [])];\n variables.push({\n key: `var:${node.id}.${out}`,\n label: `${node.key}.${out}`,\n detail: users.length\n ? `read by ${users.map((u) => title(model, u)).join(', ')}`\n : 'not read',\n nodes: [node.id, ...users],\n tone: users.length ? undefined : 'muted',\n });\n if (users.length === 0)\n findings.push({\n id: `data:unused-output:${node.id}.${out}`,\n lens: 'data',\n severity: 'info',\n title: `${node.title} writes ${out}, which nothing reads`,\n detail: `No node input refers to ${node.key}.${out}. Remove the output, or wire it where it is needed.`,\n node: node.id,\n nodes: [node.id],\n fixes: [{ label: 'Open Details', properties: node.id }],\n });\n }\n }\n const inputs: LensItem[] = Object.keys(flowInputs).map((name) => {\n const users = [...(inputUse.get(name) ?? [])];\n return {\n key: `input:${name}`,\n label: `flow.${name}`,\n detail: users.length\n ? `read by ${users.map((u) => title(model, u)).join(', ')}`\n : 'not read by a node input',\n nodes: users,\n tone: users.length ? undefined : 'muted',\n };\n });\n const dataWires = [...wires.values()];\n return {\n lens: 'data',\n chips,\n dataWires,\n stats: [\n { label: 'data wires', value: String(dataWires.length) },\n {\n label: 'unresolved',\n value: String(findings.filter((f) => f.severity === 'warning').length),\n },\n {\n label: 'unused outputs',\n value: String(findings.filter((f) => f.id.startsWith('data:unused')).length),\n },\n ],\n sections: [\n { title: 'Flow inputs', items: inputs, empty: 'The flow has no inputs.' },\n { title: 'Node outputs', items: variables, empty: 'No node declares outputs.' },\n ],\n findings,\n notes: dataWires.length === 0 ? ['No data wires: no node input has a from: reference.'] : [],\n };\n}\n\nfunction unresolved(\n node: Ulid,\n nodeTitle: string,\n name: string,\n from: string,\n why: string,\n): LensFinding {\n return {\n id: `data:unresolved:${node}.${name}`,\n lens: 'data',\n severity: 'warning',\n title: `${nodeTitle}: ${name} reads ${from}, which does not exist`,\n detail: `\"${from}\" ${why}.`,\n node,\n nodes: [node],\n fixes: [{ label: 'Open Details', properties: node }],\n };\n}\n\nconst TIMING_WORDS: Record<string, string> = {\n retries: 'Retries',\n delay: 'Delay',\n timeout: 'Timeout',\n};\n\n/** AFD-112: each input the step's Timing reads at run time, with the fields that read it. */\nfunction timingReads(node: FlowNode): Map<string, string[]> {\n const out = new Map<string, string[]>();\n for (const [key, word] of Object.entries(TIMING_WORDS)) {\n const v = node.settings?.[key as keyof NonNullable<FlowNode['settings']>];\n if (!templated(v)) continue;\n for (const name of exprRefs(v)) out.set(name, [...(out.get(name) ?? []), word]);\n }\n return out;\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["out", "to"]
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../../../src/core/engine/optionA.ts"],
|
|
4
|
-
"sourcesContent": ["// Option A code generation (handoff 05, ADR-0003, ADR-0009): one playbook per flow level, one play\n// per node, host sets routed between plays with group_by, and a final outcome play that fails the\n// hosts left on open ports or failed end nodes (no host ever fails inside a node play).\n\nimport {\n bubbles,\n type LevelTaken,\n levelTaken,\n portKey,\n unreachableBubbles,\n} from '../flow/bubbling';\nimport {\n capturedOutputs,\n captureTaskName,\n groupPart,\n outputVar,\n registerName,\n} from '../flow/dataNames';\nimport { portAccepted } from '../flow/decisions';\nimport { privilegeOf } from '../flow/inherit';\nimport { conditionExpr } from '../flow/jinja';\nimport { buildModel, type FlowModel, type Level, ROOT } from '../flow/model';\nimport { isFailPort, legalPorts, portsFor } from '../flow/ports';\nimport { rollingObstacles } from '../flow/rolling';\nimport { planSegments, type Segment } from '../flow/segments';\nimport type { Edge, FlowDocument, FlowNode, Ulid } from '../flow/types';\nimport type { Finding } from '../flow/validate';\nimport { plainText } from '../view/markdown';\nimport { bindingTask, inputVars, isIncludeTasks, stubFacts } from './binding';\nimport { withoutDisabled } from './bypass';\nimport { effectiveTargets } from './targets';\nimport type {\n Engine,\n GeneratedFile,\n GenerateOptions,\n GenerateResult,\n HostTerm,\n PlanStep,\n PlayRange,\n Route,\n RunPlan,\n SegmentFile,\n} from './types';\nimport { checksum, jinjaLiteral, timeoutValue } from './util';\nimport {\n Comment,\n comment,\n commentLine,\n flow,\n type Out,\n type OutMap,\n oneLine,\n writeBlock,\n} from './yamlWriter';\n\nexport const CHECKSUM_PREFIX = '# Checksum: ';\n\ninterface LevelCtx {\n level: Level;\n /** Keys of the enclosing subflow nodes, outermost first. */\n path: string[];\n file: string;\n /** Host pattern of a start node (root) or of the subflow's entry (inner levels). */\n entry: string;\n parent?: { node: FlowNode; ctx: LevelCtx };\n}\n\n/** Every line break YAML (1.1 and 1.2) knows: a Note's text is split on all of them (AFD-66). */\nconst LINE_BREAK = /\\r\\n|[\\r\\n\\u0085\\u2028\\u2029]/;\n\ninterface Chunk {\n node?: Ulid;\n lines: string[];\n}\n\ninterface OutcomeEntry {\n order: number;\n groups: string[];\n name: string;\n msg: string;\n}\n\n/** A segment build: the segment and the whole flow's outcome (failed only in leaf segments). */\ninterface SegmentRun {\n seg: Segment;\n outcome: OutcomeEntry[];\n}\n\nclass Generator {\n private readonly model: FlowModel;\n private readonly findings: Finding[] = [];\n private readonly routes: Record<string, Route> = {};\n private readonly outcome: OutcomeEntry[] = [];\n private readonly targets = new Map<string, string>();\n private readonly takenOf = new Map<Level, LevelTaken>();\n private readonly files: { ctx: LevelCtx; chunks: Chunk[] }[] = [];\n private order = 0;\n private todo = false;\n /** Approvals a local run passes unless afd_approvals says otherwise (AFD-21). */\n private approvals: string[] = [];\n /** Work nodes that run on an inventory_target (AFD-14). */\n private readonly overrides: Map<Ulid, string>;\n /** AFD-114: the plays of a scenario build, as the simulator runs them. */\n private readonly steps: PlanStep[] = [];\n private startInput?: string;\n /** The rolling subflow whose play the steps are blocks of (AFD-55): events land on it. */\n private rollingSub?: Ulid;\n\n constructor(\n private readonly doc: FlowDocument,\n private readonly opts: GenerateOptions,\n private readonly segment?: SegmentRun,\n ) {\n this.model = buildModel(doc);\n this.overrides = effectiveTargets(this.model);\n }\n\n /** become and become_user for a node's play (AFD-52: inherited from subflows in format 2). */\n private privilege(node: FlowNode): { become?: true; become_user?: string } {\n const p = privilegeOf(this.model, node);\n return {\n ...(p.become ? { become: true as const } : {}),\n ...(p.become_user ? { become_user: p.become_user } : {}),\n };\n }\n\n run(): GenerateResult {\n const root = this.model.levels.get(ROOT);\n const start = this.startPattern();\n if (!root || !start) return this.result(false);\n const ctx: LevelCtx = { level: root, path: [], file: `${this.doc.flow.key}.yml`, entry: start };\n if (!this.level(ctx)) return this.result(false);\n const outcome = this.outcomePlay();\n if (outcome) this.files[0]?.chunks.push({ lines: outcome });\n return this.result(true);\n }\n\n /** What the outcome play of the whole flow fails (segment builds reuse it). */\n outcomeEntries(): OutcomeEntry[] {\n return [...this.outcome];\n }\n\n // ---- AWX segments (AFD-11, ADR-0016) ---------------------------------------------------------\n\n /**\n * One segment's root playbook: restore the carried host sets (continuations), the segment's top-\n * level plays (subflow levels are the shared level files), then either carry the hosts waiting\n * at the gate and those bound for the outcome to the next segment, or, in a leaf, the outcome.\n */\n segmentRun(): GenerateResult {\n const { seg, outcome } = this.segment as SegmentRun;\n const root = this.model.levels.get(ROOT);\n const start = this.startPattern();\n if (!root || !start) return this.result(false);\n const ctx: LevelCtx = {\n level: root,\n path: [],\n file: `${this.doc.flow.key}.seg_${seg.name}.yml`,\n entry: start,\n };\n if (seg.finish) this.files.push({ ctx, chunks: [] });\n else if (!this.level(ctx)) return this.result(false);\n const chunks = this.files[0]?.chunks ?? [];\n chunks.unshift(...this.prelude(ctx, seg));\n // Segments never fail hosts themselves: the whole flow's outcome runs in the leaves.\n this.outcome.length = 0;\n this.outcome.push(...outcome);\n if (seg.gate) chunks.push({ lines: writeBlock([this.carry(seg.gate)], 0) });\n else {\n const play = this.outcomePlay();\n if (play) chunks.push({ lines: play });\n }\n return this.result(true);\n }\n\n private prelude(ctx: LevelCtx, seg: Segment): Chunk[] {\n if (!seg.entry && !seg.finish) return [];\n const tag = flow([`flow_${this.doc.flow.id}`]);\n const out: Chunk[] = [\n {\n lines: writeBlock(\n [\n {\n name: `[${this.doc.flow.key}] Segment ${seg.name}: restore host sets`,\n hosts: 'localhost',\n gather_facts: false,\n tags: tag,\n tasks: [\n {\n name: 'restore the host sets the previous segment carried',\n 'ansible.builtin.add_host': { name: '{{ item.1 }}', groups: '{{ item.0.key }}' },\n loop: \"{{ (afd_hostsets | default({})) | dict2items | subelements('value') }}\",\n loop_control: { label: '{{ item.0.key }}: {{ item.1 }}' },\n },\n ...(seg.finish\n ? [\n {\n name: 'only after an approval no host reached',\n 'ansible.builtin.fail': {\n msg: 'A segment before this one did not finish: see its AWX job',\n },\n when: 'not (afd_gate_empty | default(false) | bool)',\n },\n ]\n : []),\n ],\n },\n ],\n 0,\n ),\n },\n ];\n const gate = seg.entry ? this.model.nodes.get(seg.entry.approval)?.node : undefined;\n if (gate && seg.entry) {\n const port = seg.entry.outcome;\n const waiting = this.group([], gate.key, 'waiting');\n // AFD-272: AWX cannot tell a timeout from a rejection, so its rejected segment takes both;\n // a runner that can (runSegments) says which with afd_gate_outcome, and the hosts take the\n // timeout port when the approval has one.\n const timeout =\n port === 'rejected' && portsFor(gate).some((p) => p.name === 'timeout')\n ? [\n {\n test: \"(afd_gate_outcome | default('rejected')) == 'timeout'\",\n group: this.target(ctx, gate, 'timeout'),\n port: 'timeout',\n },\n ]\n : [];\n out.push({\n node: gate.id,\n lines: writeBlock(\n [\n {\n // The route suffix maps AWX events back to the approval node.\n name: `[${gate.key}] ${jinjaLiteral(oneLine(gate.title))}: route`,\n hosts: `{{ groups['${waiting}'] | default([]) | join(',') or 'afd_no_hosts' }}`,\n gather_facts: false,\n tags: flow([`node_${gate.id}`]),\n vars: { flow_node_id: gate.id },\n tasks: [choose(gate, timeout, { group: this.target(ctx, gate, port), port })],\n },\n ],\n 0,\n ),\n });\n }\n return out;\n }\n\n /** set_stats for the next segment, then stop this job when nobody waits at the gate. */\n private carry(gateId: Ulid): OutMap {\n const gate = this.model.nodes.get(gateId)?.node as FlowNode;\n const waiting = this.group([], gate.key, 'waiting');\n const groups = [...new Set([...this.outcome.flatMap((e) => e.groups), waiting])];\n const empty = `groups['${waiting}'] | default([]) | length == 0`;\n return {\n name: `[${this.doc.flow.key}] Segment ${this.segment?.seg.name}: carry host sets`,\n hosts: 'localhost',\n gather_facts: false,\n tags: flow([`flow_${this.doc.flow.id}`]),\n tasks: [\n {\n name: 'carry the hosts waiting for approval and those bound for the outcome',\n 'ansible.builtin.set_stats': {\n data: {\n afd_hostsets: Object.fromEntries(\n groups.map((g) => [g, `{{ groups['${g}'] | default([]) }}`]),\n ),\n afd_gate_empty: `{{ ${empty} }}`,\n },\n per_host: false,\n aggregate: false,\n },\n },\n {\n name: `[${gate.key}] no host reached ${jinjaLiteral(oneLine(gate.title))}`,\n 'ansible.builtin.fail': {\n msg: `No host reached [${gate.key}] ${jinjaLiteral(oneLine(gate.title))}: the approval is skipped and the flow finishes`,\n },\n when: empty,\n },\n ],\n };\n }\n\n // ---- inputs and routing -------------------------------------------------------------------\n\n /** The flow input that seeds start (decision 23): `targets: true`, else the first host_list. */\n private startPattern(): string | undefined {\n const inputs = Object.entries(this.doc.flow?.inputs ?? {});\n const hostLists = inputs.filter(([, f]) => f?.type === 'host_list');\n const chosen = hostLists.find(([, f]) => f.targets) ?? hostLists[0];\n if (!chosen) {\n this.finding('codegen-no-targets', 'error', 'The flow needs a host_list input to target', [\n 'flow',\n 'inputs',\n ]);\n return undefined;\n }\n // A list from the run inputs, or the comma-separated text an AWX survey answers (AFD-59).\n const name = chosen[0];\n this.startInput = name;\n return `{{ ${name} if ${name} is string else ${name} | join(',') }}`;\n }\n\n /** What takes the ports of the level's steps, once per level. */\n private taken(ctx: LevelCtx): LevelTaken {\n let taken = this.takenOf.get(ctx.level);\n if (!taken) {\n taken = levelTaken(ctx.level.edges, ctx.parent?.node);\n this.takenOf.set(ctx.level, taken);\n }\n return taken;\n }\n\n private group(path: string[], key: string, port: string): string {\n return `flow_${[...path, key].map(groupPart).join('__')}_${groupPart(port)}`;\n }\n\n /**\n * Group a node's output port routes into: its own group when wired (or open), the parent's port\n * group when the port leaves a subflow level through its boundary or bubbles up (ADR-0004).\n * An open fail port is recorded for the outcome play.\n */\n private target(ctx: LevelCtx, node: FlowNode, port: string): string {\n const memo = `${node.id}|${port}`;\n const known = this.targets.get(memo);\n if (known) return known;\n const own = this.group(ctx.path, node.key, port);\n let target = own;\n const taken = this.taken(ctx);\n const wired = taken.wired.has(portKey(node.id, port));\n const parent = ctx.parent;\n if (!wired && parent) {\n const exported = Object.entries(parent.node.subflow?.boundary?.outputs ?? {}).find(\n ([, refs]) => (refs ?? []).some((r) => r?.node === node.id && r.port === port),\n );\n if (exported) target = this.target(parent.ctx, parent.node, exported[0]);\n else if (bubbles(parent.node, node.id, port, taken))\n target = this.target(parent.ctx, parent.node, port);\n }\n if (target === own) {\n this.routes[own] = { node: node.id, port };\n if (!wired && isFailPort(port)) this.openPort(node, port, own);\n }\n this.targets.set(memo, target);\n return target;\n }\n\n private openPort(node: FlowNode, port: string, group: string): void {\n const decision = portAccepted(this.doc, node.id, port);\n const where = `[${node.key}] ${jinjaLiteral(oneLine(node.title))}`;\n this.outcome.push({\n order: this.order,\n groups: [group],\n name: decision ? `[${node.key}] ${port} open on purpose` : `[${node.key}] ${port} is open`,\n msg: decision\n ? `Stopped at ${where}: ${port} open on purpose (${jinjaLiteral(oneLine(decision.reason ?? 'no reason'))})`\n : `Stopped at ${where}: ${port} is not wired`,\n });\n }\n\n private sources(ctx: LevelCtx, node: FlowNode, edges: Edge[]): string[] {\n const out: string[] = [];\n for (const e of edges) {\n if (e.to.node !== node.id || e.to.port !== 'in') continue;\n const from = this.model.nodes.get(e.from.node)?.node;\n if (!from) continue;\n // A continuation segment starts at its approval, not at the flow targets.\n if (from.type === 'start' && this.segment?.seg.entry && !ctx.parent) continue;\n out.push(from.type === 'start' ? ctx.entry : this.target(ctx, from, e.from.port));\n }\n if (ctx.parent && ctx.parent.node.subflow?.boundary?.in === node.id) out.push(ctx.entry);\n return [...new Set(out)];\n }\n\n // ---- levels ----------------------------------------------------------------------------------\n\n private level(ctx: LevelCtx): boolean {\n const nodes = ctx.level.nodes.filter((n): n is FlowNode => !!n && typeof n === 'object');\n const ids = new Set(nodes.map((n) => n.id));\n const edges = ctx.level.edges.filter(\n (e): e is Edge => !!e?.from && !!e.to && ids.has(e.from.node) && ids.has(e.to.node),\n );\n const order = topoOrder(nodes, edges);\n if (!order) {\n const where = ctx.parent ? `level [${ctx.parent.node.key}]` : 'top level';\n this.finding('codegen-cycle', 'error', `The ${where} has a cycle; plays need an order`, []);\n return false;\n }\n const file = { ctx, chunks: [] as Chunk[] };\n this.files.push(file);\n for (const node of order) {\n this.order++;\n if (this.segment && !ctx.parent && !this.segment.seg.nodes.has(node.id)) continue;\n if (node.type === 'start') continue;\n if (node.type === 'end') {\n this.endNode(ctx, node, edges);\n continue;\n }\n const hosts = this.sources(ctx, node, edges);\n if (hosts.length === 0) {\n this.finding(\n 'codegen-no-input',\n 'warning',\n `Nothing leads to \"${node.title}\": no play is generated for it`,\n this.model.nodes.get(node.id)?.path ?? [],\n node.id,\n );\n continue;\n }\n if (node.type === 'subflow' && (node.subflow?.nodes?.length ?? 0) > 0) {\n if (!this.subflowLevel(ctx, node, hosts, file.chunks)) return false;\n continue;\n }\n // Its own target or an enclosing subflow's; decisions, approvals, parallels and joins\n // always run on the arriving hosts.\n const over = this.overrides.get(node.id);\n if (over) {\n // A blank line between the node's plays; a comment stays with the play it describes.\n const plays = this.overridePlays(ctx, node, hosts, over);\n file.chunks.push({\n node: node.id,\n lines: plays.flatMap((p, i) => [\n ...(i > 0 && !(plays[i - 1] instanceof Comment) ? [''] : []),\n ...writeBlock([p], 0),\n ]),\n });\n continue;\n }\n if (node.impl?.kind === 'playbook' && node.impl.ref && !this.opts.stubAll) {\n file.chunks.push({ node: node.id, lines: this.playbookNode(ctx, node, hosts) });\n continue;\n }\n const play = this.play(ctx, node, hosts, edges);\n file.chunks.push({ node: node.id, lines: writeBlock([play], 0) });\n }\n return true;\n }\n\n private subflowLevel(ctx: LevelCtx, node: FlowNode, hosts: string[], chunks: Chunk[]): boolean {\n const level = this.model.levels.get(node.id);\n if (!level) return true;\n const path = [...ctx.path, node.key];\n const file = `${this.doc.flow.key}.${path.join('.')}.yml`;\n chunks.push({\n node: node.id,\n lines: [\n commentLine(`[${node.key}] ${oneLine(node.title)}: subflow level, see ${file}`),\n ...writeBlock([{ import_playbook: file, tags: flow([`node_${node.id}`]) }], 0),\n ],\n });\n // Ports of the subflow node itself: wired ones feed this level, open ones reach the outcome.\n for (const p of portsFor(node)) if (p.direction === 'out') this.target(ctx, node, p.name);\n // A segment imports the level file the whole-flow build writes.\n if (this.segment) return true;\n const inner: LevelCtx = { level, path, file, entry: hosts.join(':'), parent: { node, ctx } };\n const rolling = node.settings?.rolling;\n if (rolling === undefined) return this.level(inner);\n const obstacles = rollingObstacles(this.model, node).map((o) => `${o.node.title}: ${o.why}`);\n for (const n of level.nodes)\n if (n && this.overrides.has(n.id) && !obstacles.some((o) => o.startsWith(`${n.title}:`)))\n obstacles.push(`${n.title}: it runs on an inventory_target, in plays of its own`);\n if (obstacles.length === 0) return this.rollingLevel(inner, rolling);\n this.finding(\n 'rolling-unsupported',\n 'error',\n `\"${node.title}\" cannot roll (${obstacles.join('; ')}): its steps run play by play`,\n this.model.nodes.get(node.id)?.path ?? [],\n node.id,\n );\n return this.level(inner);\n }\n\n /**\n * A rolling subflow's level (AFD-55): one play with `serial`, so each batch of hosts goes through\n * every step before the next batch starts. Each step is a block for the hosts that arrived at it\n * (its routing groups, as the play-per-step level uses), with the vars, tags and privilege its\n * own play would have; its routing, rescue and captures are the same tasks.\n */\n private rollingLevel(ctx: LevelCtx, batch: string | number): boolean {\n const sub = ctx.parent?.node as FlowNode;\n const nodes = ctx.level.nodes.filter((n): n is FlowNode => !!n && typeof n === 'object');\n const ids = new Set(nodes.map((n) => n.id));\n const edges = ctx.level.edges.filter(\n (e): e is Edge => !!e?.from && !!e.to && ids.has(e.from.node) && ids.has(e.to.node),\n );\n const order = topoOrder(nodes, edges);\n if (!order) {\n this.finding(\n 'codegen-cycle',\n 'error',\n `The level [${sub.key}] has a cycle; plays need an order`,\n [],\n );\n return false;\n }\n const blocks: Out[] = [];\n this.rollingSub = sub.id;\n for (const node of order) {\n this.order++;\n if (node.type === 'start') continue;\n if (node.type === 'end') {\n this.endNode(ctx, node, edges);\n continue;\n }\n const hosts = this.sources(ctx, node, edges);\n if (hosts.length === 0) {\n this.finding(\n 'codegen-no-input',\n 'warning',\n `Nothing leads to \"${node.title}\": no play is generated for it`,\n this.model.nodes.get(node.id)?.path ?? [],\n node.id,\n );\n continue;\n }\n const play = this.play(ctx, node, hosts, edges);\n for (const t of this.noteLines(node.id)) blocks.push(comment(t));\n // Every host of the play enters at the entry; the others arrive through their groups.\n const groups = hosts.filter((h) => h !== ctx.entry);\n blocks.push({\n name: play.name,\n block: play.tasks,\n vars: play.vars,\n become: play.become,\n become_user: play.become_user,\n tags: play.tags,\n when: hosts.includes(ctx.entry)\n ? undefined\n : `inventory_hostname in (${groups.map((g) => `groups['${g}'] | default([])`).join(' + ')})`,\n });\n }\n this.rollingSub = undefined;\n this.files.push({\n ctx,\n chunks: [\n {\n node: sub.id,\n lines: writeBlock(\n [\n {\n name: `[${sub.key}] ${jinjaLiteral(oneLine(sub.title))}: rolling, ${batch} at a time`,\n hosts: ctx.entry,\n gather_facts: false,\n serial: batch,\n tags: flow([`node_${sub.id}`]),\n vars: { flow_node_id: sub.id },\n tasks: blocks,\n },\n ],\n 0,\n ),\n },\n ],\n });\n return true;\n }\n\n private endNode(ctx: LevelCtx, node: FlowNode, edges: Edge[]): void {\n const groups = edges\n .filter((e) => e.to.node === node.id)\n .map((e) => {\n const from = this.model.nodes.get(e.from.node)?.node;\n return from && from.type !== 'start' ? this.target(ctx, from, e.from.port) : undefined;\n })\n .filter((g): g is string => !!g);\n if (node.outcome !== 'failed' || groups.length === 0) return;\n this.outcome.push({\n order: this.order,\n groups: [...new Set(groups)],\n name: `[${node.key}] ${jinjaLiteral(oneLine(node.title))}`,\n msg: `Ended at [${node.key}] ${jinjaLiteral(oneLine(node.title))} (outcome: failed)`,\n });\n }\n\n // ---- inventory_target (AFD-14) -------------------------------------------------------------\n\n /**\n * A node that runs on its inventory_target (AFD-14): the arriving hosts are marked, the binding\n * runs once on the target, and the arriving hosts leave together. They take ok_hosts when every\n * target host finished (or the failed share stays within max_fail_percentage), else failed_hosts\n * (timeout when a target host timed out and the port is enabled). A target that matches no host\n * fails them too: the work never ran.\n */\n private overridePlays(ctx: LevelCtx, node: FlowNode, hosts: string[], target: string): Out[] {\n const tag = `node_${node.id}`;\n // AFD-145: a play name is rendered too; Ansible stops the whole run on an undefined name.\n const title = `[${node.key}] ${jinjaLiteral(oneLine(node.title))}`;\n const settings = node.settings ?? {};\n const own = (part: string) => this.group(ctx.path, node.key, part);\n const arrived = own('arriving');\n const done = own('target_done');\n const timedOut = own('target_timeout');\n const failedOnTarget = own('target_failed');\n const enabled = new Set(portsFor(node).map((p) => p.name));\n const path = this.model.nodes.get(node.id)?.path ?? [];\n const impl = node.impl?.ref ? node.impl : undefined;\n const kind = this.opts.stubAll ? 'todo' : (impl?.kind ?? 'todo');\n const sim = this.opts.simulate && kind === 'todo';\n for (const p of portsFor(node)) if (p.direction === 'out') this.target(ctx, node, p.name);\n const never = ['unreachable', 'unchanged'].filter((p) => enabled.has(p));\n if (kind === 'playbook' && enabled.has('timeout')) never.push('timeout');\n if (never.length > 0)\n this.finding(\n 'codegen-target-ports',\n 'warning',\n `\"${node.title}\" runs on its inventory_target (${target}): arriving hosts never take ${never.join(', ')}`,\n path,\n node.id,\n );\n const timeoutPort = enabled.has('timeout') && kind !== 'playbook';\n const arriving = `{{ groups['${arrived}'] | default([]) }}`;\n const guard: OutMap = {\n name: `[${node.key}] no host arrived`,\n 'ansible.builtin.meta': 'end_play',\n when: 'afd_arriving | length == 0',\n };\n const plays: Out[] = [\n {\n name: `${title}: arriving hosts`,\n hosts: hosts.join(':'),\n gather_facts: false,\n tags: flow([tag]),\n vars: { flow_node_id: node.id },\n tasks: [{ name: `[${node.key}] arriving`, 'ansible.builtin.group_by': { key: arrived } }],\n },\n ];\n const inputs = inputVars(this.model, ctx.level.id, node, 'hostvars[afd_arriving | first]');\n\n if (kind === 'playbook') {\n const root = (this.opts.root ?? '../../..').replace(/\\/+$/, '');\n const ref = (impl?.ref ?? '').replace(/^\\.?\\//, '');\n plays.push(\n comment(\n `${title}: playbook ${ref} on ${target}; its plays should target \"{{ afd_hosts }}\"`,\n ),\n {\n import_playbook: `${root}/${ref}`,\n vars: {\n afd_target_pattern: target,\n afd_arriving: arriving,\n afd_hosts: `{{ (afd_arriving | length > 0) | ternary(afd_target_pattern, 'afd_no_hosts') }}`,\n ...((impl?.params ?? {}) as OutMap),\n ...inputs,\n },\n tags: flow([tag]),\n },\n {\n // Hosts that failed inside the playbook left the run; the rest finished.\n name: `${title}: target done`,\n hosts: target,\n gather_facts: false,\n tags: flow([tag]),\n vars: { flow_node_id: node.id, afd_arriving: arriving },\n tasks: [\n guard,\n ...this.captures(node),\n { name: `[${node.key}] target done`, 'ansible.builtin.group_by': { key: done } },\n ],\n },\n );\n } else {\n const vars: OutMap = {\n flow_node_id: node.id,\n afd_arriving: arriving,\n ...this.repoRoot(node),\n ...inputs,\n };\n if (this.opts.simulate) {\n const key = [...ctx.path, node.key].join('/');\n vars.afd_sim = `{{ (afd_simulate | default({}))['${key}'] | default({}) }}`;\n }\n const timeout = timeoutValue(settings.timeout);\n const reg = registerName(node, impl);\n const extra: Out[] = [];\n let body: OutMap;\n if (impl && kind !== 'todo') body = bindingTask(node, impl, timeout);\n else {\n const facts = stubFacts(node);\n if (facts) extra.push(facts);\n this.todo = true;\n const failing = ['failed', ...(enabled.has('timeout') ? ['timeout'] : [])];\n body = {\n name: `[${node.key}] TODO`,\n 'ansible.builtin.debug': {\n msg: `TODO: ${jinjaLiteral(oneLine(node.intent || node.title))}`,\n },\n failed_when: sim\n ? `inventory_hostname in ${failing.map((p) => `afd_sim.${p} | default([])`).join(' + ')}`\n : undefined,\n };\n }\n const finished: OutMap = {\n name: `[${node.key}] target done`,\n 'ansible.builtin.group_by': {\n key:\n kind === 'module'\n ? `{{ '${failedOnTarget}' if (${reg}.unreachable | default(false)) else '${done}' }}`\n : done,\n },\n };\n const timedTest = sim\n ? simIn('timeout')\n : '(ansible_failed_result.timedout | default(false))';\n plays.push({\n name: title,\n hosts: target,\n gather_facts: false,\n serial: settings.serial,\n ...this.privilege(node),\n tags: flow([tag, ...(settings.tags ?? [])]),\n vars,\n tasks: [\n guard,\n {\n block: [body, ...extra, ...this.captures(node), finished],\n rescue: [\n {\n name: `[${node.key}] target failed`,\n 'ansible.builtin.group_by': {\n key: timeoutPort\n ? `{{ '${timedOut}' if ${timedTest} else '${failedOnTarget}' }}`\n : failedOnTarget,\n },\n },\n failureRecord(node, [...ctx.path, node.key].join('/')),\n ],\n },\n ],\n });\n }\n\n // Route the arriving hosts on the target's result; outputs come from the first finished host.\n const limit = settings.max_fail_percentage;\n const failed =\n typeof limit === 'number'\n ? `afd_target | length == 0 or (afd_target_failed | length) * 100 > ${limit} * (afd_target | length)`\n : 'afd_target | length == 0 or afd_target_failed | length > 0';\n const failedGroup = this.target(ctx, node, 'failed_hosts');\n const failGroup = timeoutPort\n ? `('${this.target(ctx, node, 'timeout')}' if (groups['${timedOut}'] | default([]) | length > 0) else '${failedGroup}')`\n : `'${failedGroup}'`;\n const outputs = [\n ...new Set(\n Object.keys(node.outputs ?? {})\n .map((o) => outputVar(this.model, node, o).split(/[.[]/)[0] as string)\n .filter(Boolean),\n ),\n ];\n const failPorts = ['failed_hosts', ...(timeoutPort ? ['timeout'] : [])];\n const tasks: Out[] = [\n {\n name: `[${node.key}] target matched no host`,\n 'ansible.builtin.debug': {\n msg: 'inventory_target {{ afd_target_pattern }} matched no host: every arriving host takes failed_hosts',\n },\n when: 'afd_target | length == 0',\n run_once: true,\n },\n {\n name: `[${node.key}] target hosts that did not finish`,\n 'ansible.builtin.debug': { msg: \"{{ afd_target_failed | join(', ') }}\" },\n when: 'afd_target_failed | length > 0',\n run_once: true,\n },\n ];\n // One per variable, only when the target host set it, as a step's captures (AFD-53): a stub\n // registers nothing, and an unguarded read failed every arriving host (found by AFD-114).\n for (const o of outputs)\n tasks.push({\n name: `[${node.key}] outputs from the target (${o})`,\n 'ansible.builtin.set_fact': { [o]: `{{ hostvars[afd_target_done | first].${o} }}` },\n when: `afd_target_done | length > 0 and hostvars[afd_target_done | first].${o} is defined`,\n });\n // AFD-186: the arriving hosts take the target's failure, so the step on failed_hosts reads it.\n tasks.push({\n name: `[${node.key}] failure from the target`,\n 'ansible.builtin.set_fact': Object.fromEntries(\n FAILURE_FACTS.map((f) => [\n f,\n `{{ hostvars[afd_target_failed | first].${f} | default(none) }}`,\n ]),\n ),\n when: 'afd_target_failed | length > 0',\n });\n tasks.push(...failPorts.flatMap((p) => this.portComment(ctx, node, p)), {\n name: `[${node.key}] route ${['ok_hosts', ...failPorts].join(', ')}`,\n 'ansible.builtin.group_by': {\n key: `{{ ${failGroup} if (${failed}) else '${this.target(ctx, node, 'ok_hosts')}' }}`,\n },\n });\n if (enabled.has('always')) tasks.push(route(node, 'always', this.target(ctx, node, 'always')));\n plays.push({\n name: `${title}: route`,\n hosts: arrived,\n gather_facts: false,\n tags: flow([tag]),\n vars: {\n flow_node_id: node.id,\n afd_target_pattern: target,\n afd_target: \"{{ query('ansible.builtin.inventory_hostnames', afd_target_pattern) }}\",\n afd_target_done: `{{ groups['${done}'] | default([]) }}`,\n afd_target_failed: '{{ afd_target | difference(afd_target_done) }}',\n },\n tasks,\n });\n if (this.planning)\n this.steps.push({\n ...this.stepBase(ctx, node, hosts),\n kind: 'target',\n pattern: target,\n todo: `TODO: ${oneLine(node.intent || node.title)}`,\n ...(typeof limit === 'number' ? { maxFail: limit } : {}),\n });\n return plays;\n }\n\n // ---- the plan of a scenario build (AFD-114) ------------------------------------------------\n\n /** A scenario build (simulate, every step a stub) of the whole flow records its plan. */\n private get planning(): boolean {\n return !!this.opts.simulate && !!this.opts.stubAll && !this.segment;\n }\n\n /** The output ports of a node the generator routed, with their (resolved) groups. */\n private routedPorts(node: FlowNode): Record<string, string> {\n const out: Record<string, string> = {};\n const prefix = `${node.id}|`;\n for (const [memo, group] of this.targets)\n if (memo.startsWith(prefix)) out[memo.slice(prefix.length)] = group;\n return out;\n }\n\n private stepBase(ctx: LevelCtx, node: FlowNode, hosts: string[]) {\n const terms: HostTerm[] = hosts\n .flatMap((h) => h.split(':'))\n .filter(Boolean)\n .map((h) => (h.startsWith('{{') ? { start: true as const } : { group: h }));\n return {\n node: node.id,\n attribute: this.rollingSub ?? node.id,\n key: [...ctx.path, node.key].join('/'),\n label: `[${node.key}] ${oneLine(node.title)}`,\n hosts: terms,\n ports: this.routedPorts(node),\n serial: node.settings?.serial !== undefined,\n };\n }\n\n private record(ctx: LevelCtx, node: FlowNode, hosts: string[], edges: Edge[]): void {\n if (!this.planning) return;\n const base = this.stepBase(ctx, node, hosts);\n switch (node.type) {\n case 'decision':\n case 'approval':\n case 'parallel':\n this.steps.push({ ...base, kind: node.type });\n return;\n case 'join': {\n const members: string[] = [];\n for (const e of edges) {\n const from = e.to.node === node.id ? this.model.nodes.get(e.from.node)?.node : undefined;\n const group =\n from && from.type !== 'start' && this.targets.get(`${from.id}|${e.from.port}`);\n if (group) members.push(group);\n }\n this.steps.push({\n ...base,\n kind: 'join',\n mode: node.join_mode === 'any' ? 'any' : 'all',\n members,\n });\n return;\n }\n default: {\n const limit = node.settings?.max_fail_percentage;\n this.steps.push({\n ...base,\n kind: 'task',\n todo: `TODO: ${oneLine(node.intent || node.title)}`,\n // AFD-144: the hosts this step fails, as the generated code counts them.\n ...(typeof limit === 'number' ? { maxFail: { limit } } : {}),\n });\n }\n }\n }\n\n // ---- plays -----------------------------------------------------------------------------------\n\n /**\n * A playbook binding: `import_playbook` cannot sit inside a play, so the node is the import (its\n * plays target `afd_hosts`, the hosts arriving here) and a play that routes the hosts still\n * active to ok_hosts. Hosts that fail inside the playbook stop there (ADR-0011).\n */\n private playbookNode(ctx: LevelCtx, node: FlowNode, hosts: string[]): string[] {\n const tag = `node_${node.id}`;\n const root = (this.opts.root ?? '../../..').replace(/\\/+$/, '');\n const ref = (node.impl?.ref ?? '').replace(/^\\.?\\//, '');\n const pattern = hosts.join(':');\n if (\n portsFor(node).some(\n (p) => p.name !== 'failed_hosts' && p.direction === 'out' && p.name !== 'ok_hosts',\n )\n )\n this.finding(\n 'codegen-playbook-ports',\n 'warning',\n `\"${node.title}\" runs a playbook: only ok_hosts can be routed, other ports stay empty`,\n this.model.nodes.get(node.id)?.path ?? [],\n node.id,\n );\n for (const p of portsFor(node)) if (p.direction === 'out') this.target(ctx, node, p.name);\n return [\n commentLine(\n `[${node.key}] ${oneLine(node.title)}: playbook ${oneLine(ref)}; its plays should target \"{{ afd_hosts }}\"`,\n ),\n ...writeBlock(\n [\n {\n import_playbook: `${root}/${ref}`,\n vars: {\n afd_hosts: pattern,\n ...((node.impl?.params ?? {}) as OutMap),\n ...inputVars(this.model, ctx.level.id, node),\n },\n tags: flow([tag]),\n },\n {\n name: `[${node.key}] ${jinjaLiteral(oneLine(node.title))}: route`,\n hosts: pattern,\n gather_facts: false,\n tags: flow([tag]),\n tasks: [\n ...this.captures(node),\n route(node, 'ok_hosts', this.target(ctx, node, 'ok_hosts')),\n ],\n },\n ],\n 0,\n ),\n ];\n }\n\n private play(ctx: LevelCtx, node: FlowNode, hosts: string[], edges: Edge[]): OutMap {\n const tag = `node_${node.id}`;\n const vars: OutMap = {\n flow_node_id: node.id,\n ...this.repoRoot(node),\n ...inputVars(this.model, ctx.level.id, node),\n };\n if (this.opts.simulate) {\n const key = [...ctx.path, node.key].join('/');\n vars.afd_sim = `{{ (afd_simulate | default({}))['${key}'] | default({}) }}`;\n }\n const settings = node.settings ?? {};\n let tasks: Out[];\n switch (node.type) {\n case 'decision':\n tasks = this.decisionTasks(ctx, node);\n break;\n case 'approval':\n tasks =\n this.segment?.seg.gate === node.id && !ctx.parent\n ? [\n {\n name: `[${node.key}] wait for approval in AWX`,\n 'ansible.builtin.group_by': { key: this.group([], node.key, 'waiting') },\n },\n ]\n : this.approvalTasks(ctx, node, vars);\n break;\n case 'parallel':\n tasks = legalPorts(node)\n .filter((p) => p.enabled && p.name.startsWith('branch_'))\n .map((p) => route(node, p.name, this.target(ctx, node, p.name)));\n break;\n case 'join':\n tasks = this.joinTasks(ctx, node, edges);\n break;\n default:\n tasks = this.taskTasks(ctx, node);\n }\n this.record(ctx, node, hosts, edges);\n return {\n name: `[${node.key}] ${jinjaLiteral(oneLine(node.title))}`,\n hosts: hosts.join(':'),\n gather_facts: false,\n serial: settings.serial,\n ...this.privilege(node),\n tags: flow([tag, ...(settings.tags ?? [])]),\n vars,\n tasks,\n };\n }\n\n /**\n * A step's outputs that are not its register, copied into its own variables for the hosts that\n * finished it (AFD-53), so another step setting the same fact cannot change what readers get. An\n * output the code did not set stays unset, and its reader fails as it would have.\n */\n private captures(node: FlowNode): Out[] {\n return capturedOutputs(this.model, node).map(([out, name]) => ({\n name: captureTaskName(node.key, out),\n 'ansible.builtin.set_fact': { [name]: `{{ ${out} }}` },\n when: `${out} is defined`,\n }));\n }\n\n /**\n * AFD-177: `afd_repo_root`, the repository as an absolute path, for a step whose code reads it\n * or runs files the flow cannot see (a task file, a role). playbook_dir is generated/ and Ansible\n * does not let a play change it; shared files use `{{ afd_repo_root | default(playbook_dir) }}`.\n */\n private repoRoot(node: FlowNode): OutMap {\n const impl = node.impl;\n if (!impl?.ref || impl.kind === 'playbook') return {};\n const reads =\n impl.kind === 'role' ||\n isIncludeTasks(impl.ref) ||\n JSON.stringify([impl.params ?? null, impl.keywords ?? null]).includes('afd_repo_root');\n if (!reads) return {};\n const root = (this.opts.root ?? '../../..').replace(/\\/+$/, '');\n return { afd_repo_root: `{{ (playbook_dir ~ '/${root}') | ansible.builtin.realpath }}` };\n }\n\n private taskTasks(ctx: LevelCtx, node: FlowNode): Out[] {\n const enabled = new Set(portsFor(node).map((p) => p.name));\n const impl = node.impl?.ref ? node.impl : undefined;\n const kind =\n !this.opts.stubAll && (impl?.kind === 'module' || impl?.kind === 'role') ? impl.kind : 'todo';\n const sim = this.opts.simulate && kind === 'todo';\n const timeout = timeoutValue(node.settings?.timeout);\n const reg = registerName(node, impl);\n const on = (port: string) => this.target(ctx, node, port);\n\n let body: OutMap;\n const extra: Out[] = [];\n if (kind !== 'todo' && impl) {\n body = bindingTask(node, impl, timeout);\n } else {\n const facts = stubFacts(node);\n if (facts) extra.push(facts);\n this.todo = true;\n const failing = ['failed', ...(enabled.has('timeout') ? ['timeout'] : [])];\n body = {\n name: `[${node.key}] TODO`,\n 'ansible.builtin.debug': {\n msg: `TODO: ${jinjaLiteral(oneLine(node.intent || node.title))}`,\n },\n failed_when: sim\n ? `inventory_hostname in ${failing.map((p) => `afd_sim.${p} | default([])`).join(' + ')}`\n : undefined,\n };\n }\n\n // ok_hosts, refined by unchanged (module results or simulation) and unreachable (module\n // results ignore unreachable so the host stays routable, ADR-0009).\n const okChoices: Choice[] = [];\n if (kind === 'module') {\n const group = enabled.has('unreachable')\n ? on('unreachable')\n : this.unreachableNotEnabled(ctx, node);\n okChoices.push({ test: `(${reg}.unreachable | default(false))`, group, port: 'unreachable' });\n if (enabled.has('unchanged'))\n okChoices.push({ test: `not ${reg}.changed`, group: on('unchanged'), port: 'unchanged' });\n } else if (sim) {\n for (const port of ['unreachable', 'unchanged'])\n if (enabled.has(port)) okChoices.push({ test: simIn(port), group: on(port), port });\n }\n const okRoute = choose(node, okChoices, { group: on('ok_hosts'), port: 'ok_hosts' });\n\n const failChoices: Choice[] = [];\n if (enabled.has('timeout')) {\n const test = sim ? simIn('timeout') : '(ansible_failed_result.timedout | default(false))';\n failChoices.push({ test, group: on('timeout'), port: 'timeout' });\n }\n // AFD-144: max_fail_percentage counts the hosts this step failed, in a group of its own. The\n // port groups can be a parent subflow's, which already hold the hosts other steps failed.\n const limit = node.settings?.max_fail_percentage;\n const failedHere =\n typeof limit === 'number' ? this.group(ctx.path, node.key, 'failed_here') : undefined;\n const unreachableHere = okChoices.find((c) => c.port === 'unreachable');\n const counted: Out[] = failedHere\n ? [\n {\n name: `[${node.key}] count the failure`,\n 'ansible.builtin.group_by': { key: failedHere },\n },\n ]\n : [];\n const rescue: Out[] = [\n ...['failed_hosts', ...failChoices.map((c) => c.port)].flatMap((p) =>\n this.portComment(ctx, node, p),\n ),\n ...counted,\n choose(node, failChoices, { group: on('failed_hosts'), port: 'failed_hosts' }),\n failureRecord(node, [...ctx.path, node.key].join('/')),\n ];\n const countUnreachable: Out[] =\n failedHere && unreachableHere\n ? [\n {\n name: `[${node.key}] count the unreachable`,\n 'ansible.builtin.group_by': { key: failedHere },\n when: unreachableHere.test,\n },\n ]\n : [];\n const block: OutMap = {\n block: [body, ...extra, ...this.captures(node), okRoute, ...countUnreachable],\n rescue,\n };\n if (enabled.has('always')) block.always = [route(node, 'always', on('always'))];\n const tasks: Out[] = [block];\n\n if (typeof limit === 'number' && failedHere) {\n const count = `groups['${failedHere}'] | default([]) | length`;\n tasks.push({\n name: `[${node.key}] max_fail_percentage ${limit} exceeded`,\n 'ansible.builtin.fail': {\n msg: `Flow stopped at [${node.key}]: {{ ${count} }} of {{ ansible_play_hosts_all | length }} hosts failed`,\n },\n when: `(${count}) * 100 > ${limit} * (ansible_play_hosts_all | length)`,\n });\n }\n return tasks;\n }\n\n /**\n * Module hosts that turn unreachable on a node without the port: they bubble to an enclosing\n * subflow's `unreachable` when it has one, else they fail in the outcome play.\n */\n private unreachableNotEnabled(ctx: LevelCtx, node: FlowNode): string {\n const parent = ctx.parent;\n if (parent && unreachableBubbles(parent.node))\n return this.target(parent.ctx, parent.node, 'unreachable');\n const group = this.group(ctx.path, node.key, 'unreachable');\n if (!this.routes[group]) {\n this.routes[group] = { node: node.id, port: 'unreachable' };\n this.outcome.push({\n order: this.order,\n groups: [group],\n name: `[${node.key}] unreachable`,\n msg: `Stopped at [${node.key}] ${jinjaLiteral(oneLine(node.title))}: host unreachable (the unreachable port is not enabled)`,\n });\n }\n return group;\n }\n\n /** Comment in the rescue saying where an open, decided or bubbling fail port leads. */\n private portComment(ctx: LevelCtx, node: FlowNode, port: string): Out[] {\n const target = this.target(ctx, node, port);\n const own = this.group(ctx.path, node.key, port);\n if (target !== own) {\n const r = this.routes[target];\n const owner = r ? this.model.nodes.get(r.node)?.node : undefined;\n return owner ? [comment(`${port} leaves this level as [${owner.key}] ${r?.port}`)] : [];\n }\n if (this.taken(ctx).wired.has(portKey(node.id, port))) return [];\n const decided = !!portAccepted(this.doc, node.id, port);\n return [\n comment(\n decided\n ? `${port} is open on purpose: these hosts stop in the outcome play`\n : `${port} is open: these hosts fail in the outcome play`,\n ),\n ];\n }\n\n private decisionTasks(ctx: LevelCtx, node: FlowNode): Out[] {\n const yes = this.target(ctx, node, 'true');\n const no = this.target(ctx, node, 'false');\n const condition = node.condition?.trim();\n if (!condition || this.opts.stubAll) {\n this.todo = true;\n const choices = this.opts.simulate\n ? [{ test: simIn('false'), group: no, port: 'false' }]\n : [];\n const pick = choose(node, choices, { group: yes, port: 'true' });\n return [\n {\n name: `[${node.key}] TODO`,\n 'ansible.builtin.debug': {\n msg: condition\n ? `Scenario: ${jinjaLiteral(oneLine(node.title))} takes true unless afd_simulate sends a host to false`\n : `TODO: ${jinjaLiteral(oneLine(node.title))} has no condition yet, so every host takes true`,\n },\n },\n pick,\n ];\n }\n const error = this.group(ctx.path, node.key, 'condition_error');\n this.routes[error] = { node: node.id, port: 'condition_error' };\n this.outcome.push({\n order: this.order,\n groups: [error],\n name: `[${node.key}] condition error`,\n msg: `Stopped at [${node.key}] ${jinjaLiteral(oneLine(node.title))}: the condition could not be evaluated`,\n });\n return [\n {\n block: [\n choose(node, [{ test: `not (${conditionExpr(condition)})`, group: no, port: 'false' }], {\n group: yes,\n port: 'true',\n }),\n ],\n rescue: [\n {\n name: `[${node.key}] condition could not be evaluated`,\n 'ansible.builtin.group_by': { key: error },\n },\n ],\n },\n ];\n }\n\n private approvalTasks(ctx: LevelCtx, node: FlowNode, vars: OutMap): Out[] {\n const enabled = new Set(portsFor(node).map((p) => p.name));\n const ports = ['approved', ...['rejected', 'timeout'].filter((p) => enabled.has(p))];\n // A local run approves unless the extra var afd_approvals names another outcome for this\n // approval (AFD-21); AWX workflow runs wait in a real approval node (AFD-11).\n const key = [...ctx.path, node.key].join('/');\n this.approvals.push(key);\n vars.afd_approval = `{{ (afd_approvals | default({}))['${key}'] | default('approved') }}`;\n const pick = 'afd_approval';\n const choices: Choice[] = ports\n .slice(1)\n .map((port) => ({ test: `${pick} == '${port}'`, group: this.target(ctx, node, port), port }));\n if (this.opts.simulate) {\n for (const port of ['rejected', 'timeout'])\n if (enabled.has(port))\n choices.push({ test: simIn(port), group: this.target(ctx, node, port), port });\n }\n return [\n {\n name: `[${node.key}] local approval`,\n 'ansible.builtin.debug': {\n msg: `${jinjaLiteral(oneLine(node.title))}: {{ afd_approval }} in this local run (afd_approvals chooses; AWX workflow runs wait in an approval node)`,\n },\n run_once: true,\n },\n {\n name: `[${node.key}] afd_approvals outcome`,\n 'ansible.builtin.fail': {\n msg: `afd_approvals['${key}'] must be one of ${ports.join(', ')}`,\n },\n when: `${pick} not in [${ports.map((p) => `'${p}'`).join(', ')}]`,\n },\n choose(node, choices, { group: this.target(ctx, node, 'approved'), port: 'approved' }),\n ];\n }\n\n private joinTasks(ctx: LevelCtx, node: FlowNode, edges: Edge[]): Out[] {\n const ok = this.target(ctx, node, 'ok_hosts');\n if (node.join_mode === 'any') return [route(node, 'ok_hosts', ok)];\n const member: string[] = [];\n for (const e of edges) {\n const from = e.to.node === node.id ? this.model.nodes.get(e.from.node)?.node : undefined;\n if (from && from.type !== 'start')\n member.push(\n `inventory_hostname in groups['${this.target(ctx, from, e.from.port)}'] | default([])`,\n );\n }\n const all = member.join(' and ') || 'true';\n if (portsFor(node).some((p) => p.name === 'failed_hosts')) {\n const failed = this.target(ctx, node, 'failed_hosts');\n return [\n choose(node, [{ test: `not (${all})`, group: failed, port: 'failed_hosts' }], {\n group: ok,\n port: 'ok_hosts',\n }),\n ];\n }\n return [{ ...route(node, 'ok_hosts', ok), when: all }];\n }\n\n // ---- outcome and files -------------------------------------------------------------------------\n\n private outcomePlay(): string[] | undefined {\n if (this.outcome.length === 0) return undefined;\n const entries = [...this.outcome].sort((a, b) => a.order - b.order);\n const groups = [...new Set(entries.flatMap((e) => e.groups))];\n const play: OutMap = {\n name: `[${this.doc.flow.key}] Outcome`,\n hosts: groups.join(':'),\n gather_facts: false,\n tags: flow([`flow_${this.doc.flow.id}`]),\n tasks: entries.map((e) => ({\n name: e.name,\n 'ansible.builtin.fail': { msg: e.msg },\n when: e.groups\n .map((g) => `inventory_hostname in groups['${g}'] | default([])`)\n .join(' or '),\n })),\n };\n return [\n '# Hosts left on open ports or failed end nodes fail here, after every branch ran (ADR-0009).',\n ...writeBlock([play], 0),\n ];\n }\n\n /**\n * The Notes on a node as comment text (AFD-66): Markdown made plain, one line per line. Every\n * YAML line break is a split, so no text can end the comment and become code.\n */\n private noteLines(id: Ulid): string[] {\n const level = this.model.levels.get(this.model.nodes.get(id)?.level ?? '');\n const out: string[] = [];\n for (const a of level?.annotations ?? []) {\n if (!a || (a.kind ?? 'note') !== 'note' || a.on !== id) continue;\n const lines = plainText(String(a.text ?? ''))\n .split(LINE_BREAK)\n .map((l) => l.trimEnd())\n .filter((l, i, all) => l !== '' || (i > 0 && i < all.length - 1));\n lines.forEach((l, i) => {\n out.push(i === 0 ? `Note: ${l}` : ` ${l}`.trimEnd());\n });\n }\n return out;\n }\n\n private result(ok: boolean): GenerateResult {\n const eol = this.opts.eol ?? '\\n';\n const files: GeneratedFile[] = [];\n const plays: Record<Ulid, PlayRange> = {};\n if (ok) {\n for (const { ctx, chunks } of this.files) {\n const header = this.header(ctx);\n const body: string[] = [];\n for (const chunk of chunks) {\n body.push('');\n // AFD-66: the Notes on the node, above its code (outside its play range).\n if (chunk.node) body.push(...this.noteLines(chunk.node).map(commentLine));\n const start = header.length + 1 + body.length;\n body.push(...chunk.lines);\n if (chunk.node)\n plays[chunk.node] = { file: ctx.file, start, end: start + chunk.lines.length };\n }\n const bodyText = body.map((l) => `${l}\\n`).join('');\n const lines = [...header, `${CHECKSUM_PREFIX}${checksum(bodyText)}`, ...body];\n files.push({ name: ctx.file, text: lines.join(eol) + eol, level: ctx.level.id });\n }\n }\n const plan: RunPlan | undefined =\n ok && this.planning\n ? {\n ...(this.startInput ? { start: this.startInput } : {}),\n steps: this.steps,\n outcome: [...this.outcome]\n .sort((a, b) => a.order - b.order)\n .map(({ groups, name, msg }) => ({ groups, name, msg })),\n }\n : undefined;\n return {\n ok,\n files,\n findings: this.findings,\n routes: this.routes,\n plays,\n ...(plan ? { plan } : {}),\n };\n }\n\n private header(ctx: LevelCtx): string[] {\n const f = this.doc.flow;\n const level = ctx.parent\n ? `, level [${ctx.parent.node.key}] ${oneLine(ctx.parent.node.title)}`\n : '';\n const lines = [\n commentLine(\n `GENERATED by Ansible Flow Designer from ../${oneLine(this.opts.source)} (flow ${oneLine(String(f.key))}, version ${oneLine(String(f.version))}${level}).`,\n ),\n '# Do not edit by hand: change the flow and save it. Option A engine (ADR-0009).',\n ];\n if (this.segment)\n lines.push(\n commentLine(\n `AWX workflow segment \"${oneLine(this.segment.seg.name)}\" (ADR-0016): the workflow runs it, with the host sets of the segment before it.`,\n ),\n );\n else if (!ctx.parent && this.todo)\n lines.push('# Unbound nodes run TODO messages: run with --check until every node is bound.');\n if (!this.segment && !ctx.parent && this.approvals.length > 0)\n lines.push(\n `# Local runs pass approvals ${this.approvals.map((k) => `[${k}]`).join(', ')} automatically; choose another outcome with -e '{\"afd_approvals\": {\"${this.approvals[0]}\": \"rejected\"}}'.`,\n );\n if (this.opts.simulate)\n lines.push('# SIMULATION build: afd_simulate sends chosen hosts down other ports.');\n if (this.opts.stubAll)\n lines.push('# SCENARIO build: every step runs as its stub; no binding runs (AFD-58).');\n return lines;\n }\n\n private finding(\n code: string,\n severity: Finding['severity'],\n message: string,\n path: Finding['path'],\n node?: Ulid,\n ): void {\n this.findings.push({ code, severity, message, path, node });\n }\n}\n\n/** Kahn's algorithm; ties keep document order. Undefined when the level has a cycle. */\nfunction topoOrder(nodes: FlowNode[], edges: Edge[]): FlowNode[] | undefined {\n const index = new Map(nodes.map((n, i) => [n.id, i]));\n const indegree = new Map(nodes.map((n) => [n.id, 0]));\n for (const e of edges) indegree.set(e.to.node, (indegree.get(e.to.node) ?? 0) + 1);\n const ready = nodes.filter((n) => indegree.get(n.id) === 0);\n const out: FlowNode[] = [];\n while (ready.length > 0) {\n ready.sort((a, b) => (index.get(a.id) ?? 0) - (index.get(b.id) ?? 0));\n const n = ready.shift() as FlowNode;\n out.push(n);\n for (const e of edges) {\n if (e.from.node !== n.id) continue;\n const left = (indegree.get(e.to.node) ?? 0) - 1;\n indegree.set(e.to.node, left);\n if (left === 0) ready.push(nodes[index.get(e.to.node) ?? 0] as FlowNode);\n }\n }\n return out.length === nodes.length ? out : undefined;\n}\n\nfunction simIn(port: string): string {\n return `inventory_hostname in afd_sim.${port} | default([])`;\n}\n\ninterface Choice {\n test: string;\n group: string;\n port: string;\n}\n\n/** AFD-186: what a step's rescue keeps of a failure, as host facts later plays can read. */\nconst FAILURE_FACTS = ['afd_failed_result', 'afd_failed_task', 'afd_failed_node'] as const;\n\n/**\n * The failure as host facts (AFD-186): every step is its own play, so the step its failed_hosts\n * lead to cannot see ansible_failed_result. Written after the routing, and never fails the rescue.\n */\nfunction failureRecord(node: FlowNode, keyPath: string): OutMap {\n return {\n name: `[${node.key}] keep the failure`,\n 'ansible.builtin.set_fact': {\n afd_failed_result: '{{ ansible_failed_result | default({}) }}',\n afd_failed_task: \"{{ ansible_failed_task.name | default('') }}\",\n afd_failed_node: keyPath,\n },\n ignore_errors: true,\n };\n}\n\nfunction route(node: FlowNode, port: string, group: string): OutMap {\n return { name: `[${node.key}] route ${port}`, 'ansible.builtin.group_by': { key: group } };\n}\n\n/** A group_by whose key picks the first matching choice, else the fallback port's group. */\nfunction choose(\n node: FlowNode,\n choices: Choice[],\n fallback: { group: string; port: string },\n): OutMap {\n if (choices.length === 0) return route(node, fallback.port, fallback.group);\n const expr = choices.reduceRight(\n (rest, c) => `'${c.group}' if ${c.test} else ${rest}`,\n `'${fallback.group}'`,\n );\n const ports = [fallback.port, ...choices.map((c) => c.port)];\n return {\n name: `[${node.key}] route ${[...new Set(ports)].join(', ')}`,\n 'ansible.builtin.group_by': { key: `{{ ${expr} }}` },\n };\n}\n\nexport const optionA: Engine = {\n id: 'option-a',\n generate: (asWritten, options) => {\n // AFD-242: disabled nodes are not generated; the path closes over them (engine/bypass).\n const doc = withoutDisabled(asWritten);\n const whole = new Generator(doc, options);\n const result = whole.run();\n if (!result.ok) return result;\n const plan = planSegments(buildModel(doc));\n if (!plan) return result;\n if (plan.problems.length > 0 || plan.segments.length === 0)\n return {\n ...result,\n findings: [\n ...result.findings,\n ...plan.problems.map((p) => ({\n code: 'codegen-segments',\n severity: 'warning' as const,\n message: `${p.message}; local and skeleton runs approve automatically`,\n path: [],\n node: p.node,\n })),\n ],\n };\n const outcome = whole.outcomeEntries();\n const files = [...result.files];\n const segments: SegmentFile[] = [];\n for (const seg of plan.segments) {\n const r = new Generator(doc, options, { seg, outcome }).segmentRun();\n const file = r.files[0];\n if (!r.ok || !file) return { ...result, findings: [...result.findings, ...r.findings] };\n files.push(file);\n segments.push({\n name: seg.name,\n file: file.name,\n gate: seg.gate,\n entry: seg.entry,\n parent: seg.parent,\n finish: seg.finish,\n });\n }\n return { ...result, files, segments };\n },\n};\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|