[{"data":1,"prerenderedAt":7925},["ShallowReactive",2],{"navigation_docs":3,"-docs-reference-go-flowdsl":968,"-docs-reference-go-flowdsl-surround":7920},[4,27,63,129,287,311,893,902,950,964],{"title":5,"path":6,"stem":7,"children":8,"order":10,"icon":11},"Overview","\u002Fdocs\u002Foverview","docs\u002F1.overview\u002Findex",[9,12,18,24],{"title":5,"path":6,"stem":7,"order":10,"icon":11},1,"i-lucide-info",{"title":13,"path":14,"stem":15,"order":16,"icon":17},"Getting Started","\u002Fdocs\u002Foverview\u002Fgetting-started","docs\u002F1.overview\u002F2.getting-started",2,"i-lucide-rocket",{"title":19,"path":20,"stem":21,"order":22,"icon":23},"Contributing","\u002Fdocs\u002Foverview\u002Fcontributing","docs\u002F1.overview\u002F3.contributing",3,"i-lucide-heart",{"title":5,"path":25,"stem":26,"order":10},"\u002Fdocs\u002Foverview\u002F_dir","docs\u002F1.overview\u002F_dir",{"title":28,"path":29,"stem":30,"children":31,"page":62},"Concepts","\u002Fdocs\u002Fconcepts","docs\u002F2.concepts",[32,37,42,47,53,59],{"title":33,"path":34,"stem":35,"order":10,"icon":36},"Events","\u002Fdocs\u002Fconcepts\u002Fevents","docs\u002F2.concepts\u002F1.events","i-lucide-zap",{"title":38,"path":39,"stem":40,"order":16,"icon":41},"Transports","\u002Fdocs\u002Fconcepts\u002Ftransports","docs\u002F2.concepts\u002F2.transports","i-lucide-network",{"title":43,"path":44,"stem":45,"order":22,"icon":46},"Module System","\u002Fdocs\u002Fconcepts\u002Fmodules","docs\u002F2.concepts\u002F3.modules","i-lucide-puzzle",{"title":48,"path":49,"stem":50,"order":51,"icon":52},"Flows","\u002Fdocs\u002Fconcepts\u002Fflows","docs\u002F2.concepts\u002F4.flows",4,"i-lucide-workflow",{"title":54,"path":55,"stem":56,"order":57,"icon":58},"Scheduler","\u002Fdocs\u002Fconcepts\u002Fscheduler","docs\u002F2.concepts\u002F5.scheduler",5,"i-lucide-clock",{"title":28,"path":60,"stem":61,"order":16},"\u002Fdocs\u002Fconcepts\u002F_dir","docs\u002F2.concepts\u002F_dir",false,{"title":64,"path":65,"stem":66,"children":67,"page":62},"Guides","\u002Fdocs\u002Fguides","docs\u002F3.guides",[68,73,77,81,85,89,93,98,104,110,116,122,126],{"title":69,"path":70,"stem":71,"order":10,"icon":72},"Creating a Go App","\u002Fdocs\u002Fguides\u002Fcreating-go-app","docs\u002F3.guides\u002F1.creating-go-app","i-lucide-terminal",{"title":74,"path":75,"stem":76},"E2E tests & demo videos","\u002Fdocs\u002Fguides\u002Fe2e-and-demo-videos","docs\u002F3.guides\u002F10.e2e-and-demo-videos",{"title":78,"path":79,"stem":80,"icon":17},"Deploying to production","\u002Fdocs\u002Fguides\u002Fdeploying-to-production","docs\u002F3.guides\u002F11.deploying-to-production",{"title":82,"path":83,"stem":84,"order":16,"icon":46},"Creating a Go Module","\u002Fdocs\u002Fguides\u002Fcreating-go-module","docs\u002F3.guides\u002F2.creating-go-module",{"title":86,"path":87,"stem":88,"order":22,"icon":36},"Adding Events","\u002Fdocs\u002Fguides\u002Fadding-events-to-go-module","docs\u002F3.guides\u002F3.adding-events-to-go-module",{"title":90,"path":91,"stem":92,"order":51,"icon":52},"FlowDSL to Service","\u002Fdocs\u002Fguides\u002Fflowdsl-to-redelay","docs\u002F3.guides\u002F4.flowdsl-to-redelay",{"title":94,"path":95,"stem":96,"order":57,"icon":97},"Choosing a Transport","\u002Fdocs\u002Fguides\u002Fchoosing-a-transport","docs\u002F3.guides\u002F5.choosing-a-transport","i-lucide-git-branch",{"title":99,"path":100,"stem":101,"order":102,"icon":103},"Module Browser (\u002Fmodules)","\u002Fdocs\u002Fguides\u002Fmodules-browser","docs\u002F3.guides\u002F6.modules-browser",6,"i-lucide-layout-dashboard",{"title":105,"path":106,"stem":107,"order":108,"icon":109},"Running Flows","\u002Fdocs\u002Fguides\u002Frunning-flows","docs\u002F3.guides\u002F7.running-flows",7,"i-lucide-play-circle",{"title":111,"path":112,"stem":113,"order":114,"icon":115},"Trace + Live Observability","\u002Fdocs\u002Fguides\u002Fobservability","docs\u002F3.guides\u002F8.observability",8,"i-lucide-activity",{"title":117,"path":118,"stem":119,"order":120,"icon":121},"Project AI Assistant","\u002Fdocs\u002Fguides\u002Fai-assistant","docs\u002F3.guides\u002F9.ai-assistant",9,"i-lucide-sparkles",{"title":123,"path":124,"stem":125},"Debug taps — trace live data through any node","\u002Fdocs\u002Fguides\u002Fdebug-taps","docs\u002F3.guides\u002F9.debug-taps",{"title":64,"path":127,"stem":128,"order":22},"\u002Fdocs\u002Fguides\u002F_dir","docs\u002F3.guides\u002F_dir",{"title":130,"path":131,"stem":132,"children":133,"page":62},"Reference","\u002Fdocs\u002Freference","docs\u002F4.reference",[134,139,143,148,153,158,163,168,172,177,182,187,193,199,205,210,215,219,225,230,236,242,247,253,259,263,267,273,278,284],{"title":135,"path":136,"stem":137,"order":10,"icon":138},"Go Framework","\u002Fdocs\u002Freference\u002Fgo-framework","docs\u002F4.reference\u002F01.go-framework","i-simple-icons-go",{"title":140,"path":141,"stem":142,"order":16,"icon":46},"Built-in Modules","\u002Fdocs\u002Freference\u002Fgo-modules","docs\u002F4.reference\u002F02.go-modules",{"title":144,"path":145,"stem":146,"order":22,"icon":147},"Domain Addon Modules","\u002Fdocs\u002Freference\u002Fgo-modules-addons","docs\u002F4.reference\u002F03.go-modules-addons","i-lucide-blocks",{"title":149,"path":150,"stem":151,"order":51,"icon":152},"Go Events","\u002Fdocs\u002Freference\u002Fgo-events","docs\u002F4.reference\u002F04.go-events","i-lucide-radio",{"title":154,"path":155,"stem":156,"order":57,"icon":157},"Email Module","\u002Fdocs\u002Freference\u002Fgo-module-email","docs\u002F4.reference\u002F05.go-module-email","i-lucide-mail",{"title":159,"path":160,"stem":161,"order":102,"icon":162},"Go Core & IR","\u002Fdocs\u002Freference\u002Fgo-core","docs\u002F4.reference\u002F06.go-core","i-lucide-cpu",{"title":164,"path":165,"stem":166,"order":108,"icon":167},"Module Definition Files","\u002Fdocs\u002Freference\u002Fgo-module-files","docs\u002F4.reference\u002F07.go-module-files","i-lucide-file-code",{"title":169,"path":170,"stem":171,"order":114,"icon":72},"CLI Reference","\u002Fdocs\u002Freference\u002Fgo-cli","docs\u002F4.reference\u002F08.go-cli",{"title":173,"path":174,"stem":175,"order":120,"icon":176},"Go Formats","\u002Fdocs\u002Freference\u002Fgo-formats","docs\u002F4.reference\u002F09.go-formats","i-lucide-file-json",{"title":178,"path":179,"stem":180,"order":181,"icon":152},"AsyncAPI Module","\u002Fdocs\u002Freference\u002Fgo-asyncapi","docs\u002F4.reference\u002F10.go-asyncapi",10,{"title":183,"path":184,"stem":185,"order":186,"icon":52},"Go FlowDSL","\u002Fdocs\u002Freference\u002Fgo-flowdsl","docs\u002F4.reference\u002F11.go-flowdsl",11,{"title":188,"path":189,"stem":190,"order":191,"icon":192},"FlowDSL Examples","\u002Fdocs\u002Freference\u002Fflowdsl-examples","docs\u002F4.reference\u002F12.flowdsl-examples",12,"i-lucide-file-code-2",{"title":194,"path":195,"stem":196,"order":197,"icon":198},"FlowDSL Sync","\u002Fdocs\u002Freference\u002Fflowdsl-sync","docs\u002F4.reference\u002F13.flowdsl-sync",13,"i-lucide-refresh-cw",{"title":200,"path":201,"stem":202,"order":203,"icon":204},"Node.js Framework","\u002Fdocs\u002Freference\u002Fjs-framework","docs\u002F4.reference\u002F14.js-framework",14,"i-simple-icons-nodedotjs",{"title":206,"path":207,"stem":208,"order":203,"icon":209},"Python Framework","\u002Fdocs\u002Freference\u002Fpy-framework","docs\u002F4.reference\u002F14.py-framework","i-simple-icons-python",{"title":211,"path":212,"stem":213,"order":214,"icon":204},"Node.js Events","\u002Fdocs\u002Freference\u002Fjs-events","docs\u002F4.reference\u002F15.js-events",15,{"title":216,"path":217,"stem":218,"order":214,"icon":209},"Python Events","\u002Fdocs\u002Freference\u002Fpy-events","docs\u002F4.reference\u002F15.py-events",{"title":220,"path":221,"stem":222,"order":223,"icon":224},"go-ai — LLM Providers, Guard, Ledger","\u002Fdocs\u002Freference\u002Fgo-ai","docs\u002F4.reference\u002F16.go-ai",16,"i-lucide-brain-circuit",{"title":226,"path":227,"stem":228,"order":229,"icon":41},"Infrastructure Modules","\u002Fdocs\u002Freference\u002Fgeneric-infra-modules","docs\u002F4.reference\u002F17.generic-infra-modules",17,{"title":231,"path":232,"stem":233,"order":234,"icon":235},"Flow Templates","\u002Fdocs\u002Freference\u002Fflow-templates","docs\u002F4.reference\u002F18.flow-templates",18,"i-lucide-library-big",{"title":237,"path":238,"stem":239,"order":240,"icon":241},"Assistant (chat + handoff)","\u002Fdocs\u002Freference\u002Fassistant","docs\u002F4.reference\u002F19.assistant",19,"i-lucide-messages-square",{"title":243,"path":244,"stem":245,"order":246,"icon":41},"Coordination","\u002Fdocs\u002Freference\u002Fcoordination","docs\u002F4.reference\u002F20.coordination",20,{"title":248,"path":249,"stem":250,"order":251,"icon":252},"Search (vector)","\u002Fdocs\u002Freference\u002Fsearch","docs\u002F4.reference\u002F21.search",21,"i-lucide-search",{"title":254,"path":255,"stem":256,"order":257,"icon":258},"Profiles","\u002Fdocs\u002Freference\u002Fprofiles","docs\u002F4.reference\u002F22.profiles",22,"i-lucide-bookmark",{"title":260,"path":261,"stem":262},"Flow-driven HTTP endpoints","\u002Fdocs\u002Freference\u002Fflow-driven-endpoints","docs\u002F4.reference\u002F23.flow-driven-endpoints",{"title":264,"path":265,"stem":266},"Deployments","\u002Fdocs\u002Freference\u002Fdeployments","docs\u002F4.reference\u002F24.deployments",{"title":268,"path":269,"stem":270,"order":271,"icon":272},"i18n (translations)","\u002Fdocs\u002Freference\u002Fi18n","docs\u002F4.reference\u002F25.i18n",25,"i-lucide-languages",{"title":274,"path":275,"stem":276,"order":277,"icon":152},"WebSockets","\u002Fdocs\u002Freference\u002Fwebsockets","docs\u002F4.reference\u002F26.websockets",26,{"title":279,"path":280,"stem":281,"order":282,"icon":283},"Localized content","\u002Fdocs\u002Freference\u002Flocalized-content","docs\u002F4.reference\u002F27.localized-content",27,"i-lucide-file-text",{"title":130,"path":285,"stem":286,"order":51},"\u002Fdocs\u002Freference\u002F_dir","docs\u002F4.reference\u002F_dir",{"title":288,"path":289,"stem":290,"children":291,"page":62},"Integrations","\u002Fdocs\u002Fintegrations","docs\u002F5.integrations",[292,296,300,304,308],{"title":293,"path":294,"stem":295,"order":10,"icon":52},"FlowDSL","\u002Fdocs\u002Fintegrations\u002Fflowdsl","docs\u002F5.integrations\u002F1.flowdsl",{"title":297,"path":298,"stem":299,"order":16,"icon":283},"OpenAPI","\u002Fdocs\u002Fintegrations\u002Fopenapi","docs\u002F5.integrations\u002F2.openapi",{"title":301,"path":302,"stem":303,"order":22,"icon":152},"AsyncAPI","\u002Fdocs\u002Fintegrations\u002Fasyncapi","docs\u002F5.integrations\u002F3.asyncapi",{"title":305,"path":306,"stem":307},"MCP Integration","\u002Fdocs\u002Fintegrations\u002Fmcp","docs\u002F5.integrations\u002F4.mcp",{"title":288,"path":309,"stem":310,"order":57},"\u002Fdocs\u002Fintegrations\u002F_dir","docs\u002F5.integrations\u002F_dir",{"title":312,"path":313,"stem":314,"children":315},"FlowDSL Node Catalog","\u002Fdocs\u002Fnodes","docs\u002F5.nodes\u002Findex",[316,317,321,325,329,333,337,341,345,349,353,357,361,365,369,373,377,381,385,389,393,397,401,405,409,413,417,421,425,429,433,437,441,445,449,453,457,461,465,469,473,477,481,485,489,493,497,501,505,509,513,517,521,525,529,533,537,541,545,549,553,557,561,565,569,573,577,581,585,589,593,597,601,605,609,613,617,621,625,629,633,637,641,645,649,653,657,661,665,669,673,677,681,685,689,693,697,701,705,709,713,717,721,725,729,733,737,741,745,749,753,757,761,765,769,773,777,781,785,789,793,797,801,805,809,813,817,821,825,829,833,837,841,845,849,853,857,861,865,869,873,877,881,885,889],{"title":312,"path":313,"stem":314},{"title":318,"path":319,"stem":320,"order":57},"Node Catalog","\u002Fdocs\u002Fnodes\u002F_dir","docs\u002F5.nodes\u002F_dir",{"title":322,"path":323,"stem":324},"Record Alert","\u002Fdocs\u002Fnodes\u002Falerts_record","docs\u002F5.nodes\u002Falerts_record",{"title":326,"path":327,"stem":328},"Log to API Log","\u002Fdocs\u002Fnodes\u002Fapilog_record","docs\u002F5.nodes\u002Fapilog_record",{"title":330,"path":331,"stem":332},"ClickHouse Exec","\u002Fdocs\u002Fnodes\u002Fclickhouse_exec","docs\u002F5.nodes\u002Fclickhouse_exec",{"title":334,"path":335,"stem":336},"ClickHouse Insert","\u002Fdocs\u002Fnodes\u002Fclickhouse_insert","docs\u002F5.nodes\u002Fclickhouse_insert",{"title":338,"path":339,"stem":340},"ClickHouse Query","\u002Fdocs\u002Fnodes\u002Fclickhouse_query","docs\u002F5.nodes\u002Fclickhouse_query",{"title":342,"path":343,"stem":344},"Array Op","\u002Fdocs\u002Fnodes\u002Fcore_array-ops","docs\u002F5.nodes\u002Fcore_array-ops",{"title":346,"path":347,"stem":348},"Assert","\u002Fdocs\u002Fnodes\u002Fcore_assert","docs\u002F5.nodes\u002Fcore_assert",{"title":350,"path":351,"stem":352},"Audit Emit","\u002Fdocs\u002Fnodes\u002Fcore_audit-emit","docs\u002F5.nodes\u002Fcore_audit-emit",{"title":354,"path":355,"stem":356},"Catch","\u002Fdocs\u002Fnodes\u002Fcore_catch","docs\u002F5.nodes\u002Fcore_catch",{"title":358,"path":359,"stem":360},"DateTime","\u002Fdocs\u002Fnodes\u002Fcore_datetime","docs\u002F5.nodes\u002Fcore_datetime",{"title":362,"path":363,"stem":364},"Dead Letter","\u002Fdocs\u002Fnodes\u002Fcore_dead-letter","docs\u002F5.nodes\u002Fcore_dead-letter",{"title":366,"path":367,"stem":368},"Delay","\u002Fdocs\u002Fnodes\u002Fcore_delay","docs\u002F5.nodes\u002Fcore_delay",{"title":370,"path":371,"stem":372},"ForEach","\u002Fdocs\u002Fnodes\u002Fcore_foreach","docs\u002F5.nodes\u002Fcore_foreach",{"title":374,"path":375,"stem":376},"Idempotency Key","\u002Fdocs\u002Fnodes\u002Fcore_idempotency-key","docs\u002F5.nodes\u002Fcore_idempotency-key",{"title":378,"path":379,"stem":380},"If","\u002Fdocs\u002Fnodes\u002Fcore_if","docs\u002F5.nodes\u002Fcore_if",{"title":382,"path":383,"stem":384},"Inspect","\u002Fdocs\u002Fnodes\u002Fcore_inspect","docs\u002F5.nodes\u002Fcore_inspect",{"title":386,"path":387,"stem":388},"JSON Merge","\u002Fdocs\u002Fnodes\u002Fcore_json-merge","docs\u002F5.nodes\u002Fcore_json-merge",{"title":390,"path":391,"stem":392},"JSON Schema Validate","\u002Fdocs\u002Fnodes\u002Fcore_json-schema-validate","docs\u002F5.nodes\u002Fcore_json-schema-validate",{"title":394,"path":395,"stem":396},"JSONPath Extract","\u002Fdocs\u002Fnodes\u002Fcore_jsonpath-extract","docs\u002F5.nodes\u002Fcore_jsonpath-extract",{"title":398,"path":399,"stem":400},"Log","\u002Fdocs\u002Fnodes\u002Fcore_log","docs\u002F5.nodes\u002Fcore_log",{"title":402,"path":403,"stem":404},"Math","\u002Fdocs\u002Fnodes\u002Fcore_math","docs\u002F5.nodes\u002Fcore_math",{"title":406,"path":407,"stem":408},"Merge","\u002Fdocs\u002Fnodes\u002Fcore_merge","docs\u002F5.nodes\u002Fcore_merge",{"title":410,"path":411,"stem":412},"Metric Counter","\u002Fdocs\u002Fnodes\u002Fcore_metric-counter","docs\u002F5.nodes\u002Fcore_metric-counter",{"title":414,"path":415,"stem":416},"Metric Gauge","\u002Fdocs\u002Fnodes\u002Fcore_metric-gauge","docs\u002F5.nodes\u002Fcore_metric-gauge",{"title":418,"path":419,"stem":420},"Mock","\u002Fdocs\u002Fnodes\u002Fcore_mock","docs\u002F5.nodes\u002Fcore_mock",{"title":422,"path":423,"stem":424},"No-op","\u002Fdocs\u002Fnodes\u002Fcore_noop","docs\u002F5.nodes\u002Fcore_noop",{"title":426,"path":427,"stem":428},"Object Omit","\u002Fdocs\u002Fnodes\u002Fcore_object-omit","docs\u002F5.nodes\u002Fcore_object-omit",{"title":430,"path":431,"stem":432},"Object Pick","\u002Fdocs\u002Fnodes\u002Fcore_object-pick","docs\u002F5.nodes\u002Fcore_object-pick",{"title":434,"path":435,"stem":436},"Parallel Fan-Out","\u002Fdocs\u002Fnodes\u002Fcore_parallel","docs\u002F5.nodes\u002Fcore_parallel",{"title":438,"path":439,"stem":440},"Raise","\u002Fdocs\u002Fnodes\u002Fcore_raise","docs\u002F5.nodes\u002Fcore_raise",{"title":442,"path":443,"stem":444},"Rate Limit Check","\u002Fdocs\u002Fnodes\u002Fcore_rate-limit-check","docs\u002F5.nodes\u002Fcore_rate-limit-check",{"title":446,"path":447,"stem":448},"Regex Extract","\u002Fdocs\u002Fnodes\u002Fcore_regex-extract","docs\u002F5.nodes\u002Fcore_regex-extract",{"title":450,"path":451,"stem":452},"Require Fields","\u002Fdocs\u002Fnodes\u002Fcore_require-fields","docs\u002F5.nodes\u002Fcore_require-fields",{"title":454,"path":455,"stem":456},"Rethrow","\u002Fdocs\u002Fnodes\u002Fcore_rethrow","docs\u002F5.nodes\u002Fcore_rethrow",{"title":458,"path":459,"stem":460},"Return","\u002Fdocs\u002Fnodes\u002Fcore_return","docs\u002F5.nodes\u002Fcore_return",{"title":462,"path":463,"stem":464},"HMAC Signature Verify","\u002Fdocs\u002Fnodes\u002Fcore_signature-verify","docs\u002F5.nodes\u002Fcore_signature-verify",{"title":466,"path":467,"stem":468},"String Op","\u002Fdocs\u002Fnodes\u002Fcore_string-ops","docs\u002F5.nodes\u002Fcore_string-ops",{"title":470,"path":471,"stem":472},"Subflow Invoke","\u002Fdocs\u002Fnodes\u002Fcore_subflow-invoke","docs\u002F5.nodes\u002Fcore_subflow-invoke",{"title":474,"path":475,"stem":476},"Switch","\u002Fdocs\u002Fnodes\u002Fcore_switch","docs\u002F5.nodes\u002Fcore_switch",{"title":478,"path":479,"stem":480},"Template Render","\u002Fdocs\u002Fnodes\u002Fcore_template-render","docs\u002F5.nodes\u002Fcore_template-render",{"title":482,"path":483,"stem":484},"Throttle","\u002Fdocs\u002Fnodes\u002Fcore_throttle","docs\u002F5.nodes\u002Fcore_throttle",{"title":486,"path":487,"stem":488},"Timeout","\u002Fdocs\u002Fnodes\u002Fcore_timeout","docs\u002F5.nodes\u002Fcore_timeout",{"title":490,"path":491,"stem":492},"Type Cast","\u002Fdocs\u002Fnodes\u002Fcore_type-cast","docs\u002F5.nodes\u002Fcore_type-cast",{"title":494,"path":495,"stem":496},"Webhook Respond","\u002Fdocs\u002Fnodes\u002Fcore_webhook-respond","docs\u002F5.nodes\u002Fcore_webhook-respond",{"title":498,"path":499,"stem":500},"File Delete","\u002Fdocs\u002Fnodes\u002Ffilesys_delete","docs\u002F5.nodes\u002Ffilesys_delete",{"title":502,"path":503,"stem":504},"Directory List","\u002Fdocs\u002Fnodes\u002Ffilesys_list","docs\u002F5.nodes\u002Ffilesys_list",{"title":506,"path":507,"stem":508},"File Read","\u002Fdocs\u002Fnodes\u002Ffilesys_read","docs\u002F5.nodes\u002Ffilesys_read",{"title":510,"path":511,"stem":512},"File Stat","\u002Fdocs\u002Fnodes\u002Ffilesys_stat","docs\u002F5.nodes\u002Ffilesys_stat",{"title":514,"path":515,"stem":516},"File Write","\u002Fdocs\u002Fnodes\u002Ffilesys_write","docs\u002F5.nodes\u002Ffilesys_write",{"title":518,"path":519,"stem":520},"FTP Delete","\u002Fdocs\u002Fnodes\u002Fftp_delete","docs\u002F5.nodes\u002Fftp_delete",{"title":522,"path":523,"stem":524},"FTP Download","\u002Fdocs\u002Fnodes\u002Fftp_download","docs\u002F5.nodes\u002Fftp_download",{"title":526,"path":527,"stem":528},"FTP List","\u002Fdocs\u002Fnodes\u002Fftp_list","docs\u002F5.nodes\u002Fftp_list",{"title":530,"path":531,"stem":532},"FTP Upload","\u002Fdocs\u002Fnodes\u002Fftp_upload","docs\u002F5.nodes\u002Fftp_upload",{"title":534,"path":535,"stem":536},"HTTP DELETE","\u002Fdocs\u002Fnodes\u002Fhttp_delete","docs\u002F5.nodes\u002Fhttp_delete",{"title":538,"path":539,"stem":540},"HTTP GET","\u002Fdocs\u002Fnodes\u002Fhttp_get","docs\u002F5.nodes\u002Fhttp_get",{"title":542,"path":543,"stem":544},"HTTP POST","\u002Fdocs\u002Fnodes\u002Fhttp_post","docs\u002F5.nodes\u002Fhttp_post",{"title":546,"path":547,"stem":548},"HTTP PUT","\u002Fdocs\u002Fnodes\u002Fhttp_put","docs\u002F5.nodes\u002Fhttp_put",{"title":550,"path":551,"stem":552},"HTTP Request","\u002Fdocs\u002Fnodes\u002Fhttp_request","docs\u002F5.nodes\u002Fhttp_request",{"title":554,"path":555,"stem":556},"Fill Translations","\u002Fdocs\u002Fnodes\u002Fi18n_fill-translations","docs\u002F5.nodes\u002Fi18n_fill-translations",{"title":558,"path":559,"stem":560},"Resolve Locale","\u002Fdocs\u002Fnodes\u002Fi18n_resolve-locale","docs\u002F5.nodes\u002Fi18n_resolve-locale",{"title":562,"path":563,"stem":564},"Translate","\u002Fdocs\u002Fnodes\u002Fi18n_translate","docs\u002F5.nodes\u002Fi18n_translate",{"title":566,"path":567,"stem":568},"Mongo AGGREGATE","\u002Fdocs\u002Fnodes\u002Fmongoops_aggregate","docs\u002F5.nodes\u002Fmongoops_aggregate",{"title":570,"path":571,"stem":572},"Mongo DELETE","\u002Fdocs\u002Fnodes\u002Fmongoops_delete","docs\u002F5.nodes\u002Fmongoops_delete",{"title":574,"path":575,"stem":576},"Mongo FIND","\u002Fdocs\u002Fnodes\u002Fmongoops_find","docs\u002F5.nodes\u002Fmongoops_find",{"title":578,"path":579,"stem":580},"Mongo FIND ONE","\u002Fdocs\u002Fnodes\u002Fmongoops_find-one","docs\u002F5.nodes\u002Fmongoops_find-one",{"title":582,"path":583,"stem":584},"Mongo INSERT","\u002Fdocs\u002Fnodes\u002Fmongoops_insert","docs\u002F5.nodes\u002Fmongoops_insert",{"title":586,"path":587,"stem":588},"Mongo UPDATE","\u002Fdocs\u002Fnodes\u002Fmongoops_update","docs\u002F5.nodes\u002Fmongoops_update",{"title":590,"path":591,"stem":592},"Postgres COPY FROM","\u002Fdocs\u002Fnodes\u002Fpostgres_copy-from","docs\u002F5.nodes\u002Fpostgres_copy-from",{"title":594,"path":595,"stem":596},"Postgres Exec","\u002Fdocs\u002Fnodes\u002Fpostgres_exec","docs\u002F5.nodes\u002Fpostgres_exec",{"title":598,"path":599,"stem":600},"Postgres Query","\u002Fdocs\u002Fnodes\u002Fpostgres_query","docs\u002F5.nodes\u002Fpostgres_query",{"title":602,"path":603,"stem":604},"Postgres Transaction","\u002Fdocs\u002Fnodes\u002Fpostgres_transaction","docs\u002F5.nodes\u002Fpostgres_transaction",{"title":606,"path":607,"stem":608},"RabbitMQ Consume","\u002Fdocs\u002Fnodes\u002Frabbitmq_consume","docs\u002F5.nodes\u002Frabbitmq_consume",{"title":610,"path":611,"stem":612},"RabbitMQ Declare","\u002Fdocs\u002Fnodes\u002Frabbitmq_declare","docs\u002F5.nodes\u002Frabbitmq_declare",{"title":614,"path":615,"stem":616},"RabbitMQ Publish","\u002Fdocs\u002Fnodes\u002Frabbitmq_publish","docs\u002F5.nodes\u002Frabbitmq_publish",{"title":618,"path":619,"stem":620},"Auth Login","\u002Fdocs\u002Fnodes\u002Fredelay_auth-login","docs\u002F5.nodes\u002Fredelay_auth-login",{"title":622,"path":623,"stem":624},"Require Permission","\u002Fdocs\u002Fnodes\u002Fredelay_auth-require-permission","docs\u002F5.nodes\u002Fredelay_auth-require-permission",{"title":626,"path":627,"stem":628},"Validate Token","\u002Fdocs\u002Fnodes\u002Fredelay_auth-validate-token","docs\u002F5.nodes\u002Fredelay_auth-validate-token",{"title":630,"path":631,"stem":632},"Render Email Template","\u002Fdocs\u002Fnodes\u002Fredelay_email-render-template","docs\u002F5.nodes\u002Fredelay_email-render-template",{"title":634,"path":635,"stem":636},"Send Email","\u002Fdocs\u002Fnodes\u002Fredelay_email-send","docs\u002F5.nodes\u002Fredelay_email-send",{"title":638,"path":639,"stem":640},"Send Templated Email","\u002Fdocs\u002Fnodes\u002Fredelay_email-send-templated","docs\u002F5.nodes\u002Fredelay_email-send-templated",{"title":642,"path":643,"stem":644},"Event Source","\u002Fdocs\u002Fnodes\u002Fredelay_event-source","docs\u002F5.nodes\u002Fredelay_event-source",{"title":646,"path":647,"stem":648},"Create Group","\u002Fdocs\u002Fnodes\u002Fredelay_groups-create-group","docs\u002F5.nodes\u002Fredelay_groups-create-group",{"title":650,"path":651,"stem":652},"Delete Group","\u002Fdocs\u002Fnodes\u002Fredelay_groups-delete-group","docs\u002F5.nodes\u002Fredelay_groups-delete-group",{"title":654,"path":655,"stem":656},"Resolve Permissions","\u002Fdocs\u002Fnodes\u002Fredelay_groups-resolve-permissions","docs\u002F5.nodes\u002Fredelay_groups-resolve-permissions",{"title":658,"path":659,"stem":660},"Update Group","\u002Fdocs\u002Fnodes\u002Fredelay_groups-update-group","docs\u002F5.nodes\u002Fredelay_groups-update-group",{"title":662,"path":663,"stem":664},"HTTP Endpoint","\u002Fdocs\u002Fnodes\u002Fredelay_http-endpoint","docs\u002F5.nodes\u002Fredelay_http-endpoint",{"title":666,"path":667,"stem":668},"JSON Stream Source","\u002Fdocs\u002Fnodes\u002Fredelay_json-stream-source","docs\u002F5.nodes\u002Fredelay_json-stream-source",{"title":670,"path":671,"stem":672},"JSON → Event","\u002Fdocs\u002Fnodes\u002Fredelay_json-to-event","docs\u002F5.nodes\u002Fredelay_json-to-event",{"title":674,"path":675,"stem":676},"Kafka Produce","\u002Fdocs\u002Fnodes\u002Fredelay_kafka-produce","docs\u002F5.nodes\u002Fredelay_kafka-produce",{"title":678,"path":679,"stem":680},"Create Short Link","\u002Fdocs\u002Fnodes\u002Fredelay_links-create","docs\u002F5.nodes\u002Fredelay_links-create",{"title":682,"path":683,"stem":684},"Delete Short Link","\u002Fdocs\u002Fnodes\u002Fredelay_links-delete","docs\u002F5.nodes\u002Fredelay_links-delete",{"title":686,"path":687,"stem":688},"Resolve Short Link","\u002Fdocs\u002Fnodes\u002Fredelay_links-resolve","docs\u002F5.nodes\u002Fredelay_links-resolve",{"title":690,"path":691,"stem":692},"LLM Chat","\u002Fdocs\u002Fnodes\u002Fredelay_llm-chat","docs\u002F5.nodes\u002Fredelay_llm-chat",{"title":694,"path":695,"stem":696},"LLM Embed","\u002Fdocs\u002Fnodes\u002Fredelay_llm-embed","docs\u002F5.nodes\u002Fredelay_llm-embed",{"title":698,"path":699,"stem":700},"LLM Guard","\u002Fdocs\u002Fnodes\u002Fredelay_llm-guard","docs\u002F5.nodes\u002Fredelay_llm-guard",{"title":702,"path":703,"stem":704},"LLM Tool Router","\u002Fdocs\u002Fnodes\u002Fredelay_llm-tool-router","docs\u002F5.nodes\u002Fredelay_llm-tool-router",{"title":706,"path":707,"stem":708},"NATS Publish","\u002Fdocs\u002Fnodes\u002Fredelay_nats-publish","docs\u002F5.nodes\u002Fredelay_nats-publish",{"title":710,"path":711,"stem":712},"Mark Notification Read","\u002Fdocs\u002Fnodes\u002Fredelay_notifications-mark-read","docs\u002F5.nodes\u002Fredelay_notifications-mark-read",{"title":714,"path":715,"stem":716},"Send Notification","\u002Fdocs\u002Fnodes\u002Fredelay_notifications-send","docs\u002F5.nodes\u002Fredelay_notifications-send",{"title":718,"path":719,"stem":720},"Redis Stream XADD","\u002Fdocs\u002Fnodes\u002Fredelay_redis-stream-publish","docs\u002F5.nodes\u002Fredelay_redis-stream-publish",{"title":722,"path":723,"stem":724},"S3 Copy Object","\u002Fdocs\u002Fnodes\u002Fredelay_s3-copy-object","docs\u002F5.nodes\u002Fredelay_s3-copy-object",{"title":726,"path":727,"stem":728},"S3 Delete Many","\u002Fdocs\u002Fnodes\u002Fredelay_s3-delete-many","docs\u002F5.nodes\u002Fredelay_s3-delete-many",{"title":730,"path":731,"stem":732},"S3 Head Object","\u002Fdocs\u002Fnodes\u002Fredelay_s3-head-object","docs\u002F5.nodes\u002Fredelay_s3-head-object",{"title":734,"path":735,"stem":736},"S3 List Objects","\u002Fdocs\u002Fnodes\u002Fredelay_s3-list-objects","docs\u002F5.nodes\u002Fredelay_s3-list-objects",{"title":738,"path":739,"stem":740},"Create Schedule","\u002Fdocs\u002Fnodes\u002Fredelay_scheduler-create-schedule","docs\u002F5.nodes\u002Fredelay_scheduler-create-schedule",{"title":742,"path":743,"stem":744},"Cron Trigger","\u002Fdocs\u002Fnodes\u002Fredelay_scheduler-cron-trigger","docs\u002F5.nodes\u002Fredelay_scheduler-cron-trigger",{"title":746,"path":747,"stem":748},"Delete Schedule","\u002Fdocs\u002Fnodes\u002Fredelay_scheduler-delete-schedule","docs\u002F5.nodes\u002Fredelay_scheduler-delete-schedule",{"title":750,"path":751,"stem":752},"Interval Trigger","\u002Fdocs\u002Fnodes\u002Fredelay_scheduler-interval-trigger","docs\u002F5.nodes\u002Fredelay_scheduler-interval-trigger",{"title":754,"path":755,"stem":756},"Search Query","\u002Fdocs\u002Fnodes\u002Fredelay_search-query","docs\u002F5.nodes\u002Fredelay_search-query",{"title":758,"path":759,"stem":760},"Search Upsert","\u002Fdocs\u002Fnodes\u002Fredelay_search-upsert","docs\u002F5.nodes\u002Fredelay_search-upsert",{"title":762,"path":763,"stem":764},"Delete Setting","\u002Fdocs\u002Fnodes\u002Fredelay_settings-delete","docs\u002F5.nodes\u002Fredelay_settings-delete",{"title":766,"path":767,"stem":768},"Get Setting","\u002Fdocs\u002Fnodes\u002Fredelay_settings-get","docs\u002F5.nodes\u002Fredelay_settings-get",{"title":770,"path":771,"stem":772},"Set Setting","\u002Fdocs\u002Fnodes\u002Fredelay_settings-set","docs\u002F5.nodes\u002Fredelay_settings-set",{"title":774,"path":775,"stem":776},"Delete File","\u002Fdocs\u002Fnodes\u002Fredelay_storage-delete","docs\u002F5.nodes\u002Fredelay_storage-delete",{"title":778,"path":779,"stem":780},"Download File","\u002Fdocs\u002Fnodes\u002Fredelay_storage-download","docs\u002F5.nodes\u002Fredelay_storage-download",{"title":782,"path":783,"stem":784},"Generate Presigned URL","\u002Fdocs\u002Fnodes\u002Fredelay_storage-presign-url","docs\u002F5.nodes\u002Fredelay_storage-presign-url",{"title":786,"path":787,"stem":788},"Upload File","\u002Fdocs\u002Fnodes\u002Fredelay_storage-upload","docs\u002F5.nodes\u002Fredelay_storage-upload",{"title":790,"path":791,"stem":792},"Subworkflow","\u002Fdocs\u002Fnodes\u002Fredelay_subworkflow","docs\u002F5.nodes\u002Fredelay_subworkflow",{"title":794,"path":795,"stem":796},"Activate User","\u002Fdocs\u002Fnodes\u002Fredelay_users-activate","docs\u002F5.nodes\u002Fredelay_users-activate",{"title":798,"path":799,"stem":800},"Create Pending User","\u002Fdocs\u002Fnodes\u002Fredelay_users-create-pending","docs\u002F5.nodes\u002Fredelay_users-create-pending",{"title":802,"path":803,"stem":804},"Create User","\u002Fdocs\u002Fnodes\u002Fredelay_users-create-user","docs\u002F5.nodes\u002Fredelay_users-create-user",{"title":806,"path":807,"stem":808},"Delete User","\u002Fdocs\u002Fnodes\u002Fredelay_users-delete-user","docs\u002F5.nodes\u002Fredelay_users-delete-user",{"title":810,"path":811,"stem":812},"Find User By Email","\u002Fdocs\u002Fnodes\u002Fredelay_users-find-by-email","docs\u002F5.nodes\u002Fredelay_users-find-by-email",{"title":814,"path":815,"stem":816},"Get User","\u002Fdocs\u002Fnodes\u002Fredelay_users-get-user","docs\u002F5.nodes\u002Fredelay_users-get-user",{"title":818,"path":819,"stem":820},"List Users","\u002Fdocs\u002Fnodes\u002Fredelay_users-list-users","docs\u002F5.nodes\u002Fredelay_users-list-users",{"title":822,"path":823,"stem":824},"Update User","\u002Fdocs\u002Fnodes\u002Fredelay_users-update-user","docs\u002F5.nodes\u002Fredelay_users-update-user",{"title":826,"path":827,"stem":828},"Request Email Verification (legacy)","\u002Fdocs\u002Fnodes\u002Fredelay_verification-request","docs\u002F5.nodes\u002Fredelay_verification-request",{"title":830,"path":831,"stem":832},"Request Email Verification","\u002Fdocs\u002Fnodes\u002Fredelay_verification-request-email","docs\u002F5.nodes\u002Fredelay_verification-request-email",{"title":834,"path":835,"stem":836},"Request SMS Verification","\u002Fdocs\u002Fnodes\u002Fredelay_verification-request-sms","docs\u002F5.nodes\u002Fredelay_verification-request-sms",{"title":838,"path":839,"stem":840},"Verify Token","\u002Fdocs\u002Fnodes\u002Fredelay_verification-verify","docs\u002F5.nodes\u002Fredelay_verification-verify",{"title":842,"path":843,"stem":844},"Redis DEL","\u002Fdocs\u002Fnodes\u002Fredisops_del","docs\u002F5.nodes\u002Fredisops_del",{"title":846,"path":847,"stem":848},"Redis EXPIRE","\u002Fdocs\u002Fnodes\u002Fredisops_expire","docs\u002F5.nodes\u002Fredisops_expire",{"title":850,"path":851,"stem":852},"Redis GET","\u002Fdocs\u002Fnodes\u002Fredisops_get","docs\u002F5.nodes\u002Fredisops_get",{"title":854,"path":855,"stem":856},"Redis HGET","\u002Fdocs\u002Fnodes\u002Fredisops_hget","docs\u002F5.nodes\u002Fredisops_hget",{"title":858,"path":859,"stem":860},"Redis HSET","\u002Fdocs\u002Fnodes\u002Fredisops_hset","docs\u002F5.nodes\u002Fredisops_hset",{"title":862,"path":863,"stem":864},"Redis INCR","\u002Fdocs\u002Fnodes\u002Fredisops_incr","docs\u002F5.nodes\u002Fredisops_incr",{"title":866,"path":867,"stem":868},"Redis LPOP","\u002Fdocs\u002Fnodes\u002Fredisops_lpop","docs\u002F5.nodes\u002Fredisops_lpop",{"title":870,"path":871,"stem":872},"Redis LPUSH","\u002Fdocs\u002Fnodes\u002Fredisops_lpush","docs\u002F5.nodes\u002Fredisops_lpush",{"title":874,"path":875,"stem":876},"Redis PUBLISH","\u002Fdocs\u002Fnodes\u002Fredisops_publish","docs\u002F5.nodes\u002Fredisops_publish",{"title":878,"path":879,"stem":880},"Redis SET","\u002Fdocs\u002Fnodes\u002Fredisops_set","docs\u002F5.nodes\u002Fredisops_set",{"title":882,"path":883,"stem":884},"SFTP Download","\u002Fdocs\u002Fnodes\u002Fsftp_download","docs\u002F5.nodes\u002Fsftp_download",{"title":886,"path":887,"stem":888},"SFTP Upload","\u002Fdocs\u002Fnodes\u002Fsftp_upload","docs\u002F5.nodes\u002Fsftp_upload",{"title":890,"path":891,"stem":892},"Send SMS","\u002Fdocs\u002Fnodes\u002Fsms_send","docs\u002F5.nodes\u002Fsms_send",{"title":894,"path":895,"stem":896,"children":897,"page":62},"Rfcs","\u002Fdocs\u002Frfcs","docs\u002F6.rfcs",[898],{"title":899,"path":900,"stem":901},"RFC 0001 — Worker Assignment for Flow Deployments","\u002Fdocs\u002Frfcs\u002F0001-worker-assignment","docs\u002F6.rfcs\u002F0001-worker-assignment",{"title":903,"path":904,"stem":905,"children":906,"page":62},"Admin","\u002Fdocs\u002Fadmin","docs\u002F7.admin",[907,912,917,922,927,932,937,941,946],{"title":5,"path":908,"stem":909,"order":910,"icon":911},"\u002Fdocs\u002Fadmin\u002Foverview","docs\u002F7.admin\u002F00.overview",0,"i-lucide-compass",{"title":913,"path":914,"stem":915,"order":10,"icon":916},"Getting started","\u002Fdocs\u002Fadmin\u002Fgetting-started","docs\u002F7.admin\u002F01.getting-started","i-lucide-play",{"title":918,"path":919,"stem":920,"order":16,"icon":921},"Layered architecture","\u002Fdocs\u002Fadmin\u002Flayered-architecture","docs\u002F7.admin\u002F02.layered-architecture","i-lucide-layers",{"title":923,"path":924,"stem":925,"order":22,"icon":926},"Building a custom admin project","\u002Fdocs\u002Fadmin\u002Fbuilding-a-custom-admin-project","docs\u002F7.admin\u002F03.building-a-custom-admin-project","i-lucide-folder-plus",{"title":928,"path":929,"stem":930,"order":51,"icon":931},"Building admin modules","\u002Fdocs\u002Fadmin\u002Fbuilding-admin-modules","docs\u002F7.admin\u002F04.building-admin-modules","i-lucide-package-plus",{"title":933,"path":934,"stem":935,"order":57,"icon":936},"Base module reference","\u002Fdocs\u002Fadmin\u002Freference-base-modules","docs\u002F7.admin\u002F05.reference-base-modules","i-lucide-boxes",{"title":938,"path":939,"stem":940,"order":102,"icon":17},"Deployment","\u002Fdocs\u002Fadmin\u002Fdeployment","docs\u002F7.admin\u002F06.deployment",{"title":942,"path":943,"stem":944,"order":108,"icon":945},"Consuming the base layer (versioned)","\u002Fdocs\u002Fadmin\u002Fconsuming-the-base-layer","docs\u002F7.admin\u002F07.consuming-the-base-layer","i-lucide-package",{"title":947,"path":948,"stem":949,"order":108},"Admin UI","\u002Fdocs\u002Fadmin\u002F_dir","docs\u002F7.admin\u002F_dir",{"title":951,"path":952,"stem":953,"children":954,"page":62},"Services","\u002Fdocs\u002Fservices","docs\u002F8.services",[955,960],{"title":956,"path":957,"stem":958,"order":10,"icon":959},"Custom development & support services","\u002Fdocs\u002Fservices\u002Fcustom-development","docs\u002F8.services\u002F1.custom-development","i-lucide-briefcase",{"title":951,"path":961,"stem":962,"icon":959,"order":963},"\u002Fdocs\u002Fservices\u002F_dir","docs\u002F8.services\u002F_dir",80,{"title":965,"path":966,"stem":967,"order":910},"Dir","\u002Fdocs\u002F_dir","docs\u002F_dir",{"id":969,"title":183,"body":970,"description":7913,"extension":7914,"links":7915,"meta":7916,"navigation":7917,"path":184,"seo":7918,"stem":185,"__hash__":7919},"docs\u002Fdocs\u002F4.reference\u002F11.go-flowdsl.md",{"type":971,"value":972,"toc":7862},"minimark",[973,981,992,996,1002,1020,1031,1041,1045,1067,1071,1077,1081,1089,1092,1189,1192,1501,1508,1517,1638,1659,1677,1780,1793,1797,1808,1838,1841,1871,1883,1887,1900,1915,1922,1929,1932,1990,2026,2033,2040,2064,2079,2086,2089,2147,2154,2157,2181,2188,2195,2224,2288,2294,2297,2316,2478,2485,2488,2522,2527,3026,3031,3280,3287,3298,3350,3357,3374,3407,3414,3423,3500,3505,3559,3564,3645,3651,3658,3668,3687,3694,3697,3730,3742,3749,3758,3777,3788,3795,3817,3922,3927,3981,3991,3996,4020,4027,4038,4043,4052,4055,4061,4066,4110,4122,4144,4212,4248,4254,4288,4296,4301,4330,4340,4349,4374,4405,4426,4430,4572,4584,4591,4613,4704,4707,4746,4757,4763,4770,4776,4785,4808,4812,5014,5021,5030,5101,5108,5117,5170,5174,5193,5199,5211,5237,5261,5269,5275,5282,5297,5303,5314,5411,5424,5514,5528,5533,5618,5628,5631,5677,5683,5707,5710,5781,5832,5855,5858,5903,5910,5982,5985,6026,6043,6086,6103,6107,6115,6135,6138,6145,6152,6167,6216,6255,6271,6300,6303,6357,6394,6414,6427,6456,6470,6476,6480,6494,6580,6583,6591,6605,6627,6631,6637,6640,6665,6675,6679,6700,6715,6738,6756,6759,7099,7103,7116,7133,7136,7156,7160,7167,7170,7237,7240,7264,7269,7272,7345,7348,7469,7472,7504,7508,7525,7531,7538,7544,7549,7564,7568,7620,7622,7637,7654,7660,7663,7669,7672,7693,7706,7709,7729,7736,7738,7791,7797,7852,7858],[974,975,976,977],"p",{},"Module: ",[978,979,980],"code",{},"github.com\u002Fredelay\u002Fgo-flowdsl",[982,983,984,985,991],"callout",{"icon":945,"to":313},"Browse the full ",[986,987,988],"a",{"href":313},[989,990,312],"strong",{}," — 147 nodes across every framework, addon, and infrastructure module, each with a settings table and example snippet.",[993,994,5],"h2",{"id":995},"overview",[974,997,998,1001],{},[978,999,1000],{},"go-flowdsl"," is a standalone Go library for everything FlowDSL and IR: parsing, validation,\ncode generation, SVG diagrams, drift detection, and a flow execution engine.",[974,1003,1004,1007,1008,1011,1012,1015,1016,1019],{},[989,1005,1006],{},"Key property:"," the only external dependencies are ",[978,1009,1010],{},"github.com\u002Fgoogle\u002Fuuid"," and\n",[978,1013,1014],{},"gopkg.in\u002Fyaml.v3",". There is no dependency on ",[978,1017,1018],{},"go-framework",", MongoDB, chi, JWT, zap, or\nany transport backend. This makes it suitable for lightweight workers, build tools, and CLIs\nthat need IR tooling without the full framework stack.",[974,1021,1022,1023,1026,1027,1030],{},"The dependency flows ",[989,1024,1025],{},"from"," go-framework ",[989,1028,1029],{},"into"," go-flowdsl, not the reverse:",[1032,1033,1038],"pre",{"className":1034,"code":1036,"language":1037},[1035],"language-text","go-flowdsl                    ← standalone (uuid + yaml.v3 only)\n       ↑\ngo-framework\u002Fcore\u002Fasyncapi    ← registers AsyncAPI importer into go-flowdsl\u002Fcompile\ngo-framework\u002Fcore\u002Fopenapi     ← registers OpenAPI importer\u002Fexporter into go-flowdsl\u002Fcompile\ngo-framework\u002Fcore\u002Fcompile     ← wraps go-flowdsl\u002Fcompile; adds asyncapi + openapi formats\n","text",[978,1039,1036],{"__ignoreMap":1040},"",[993,1042,1044],{"id":1043},"install","Install",[1032,1046,1050],{"className":1047,"code":1048,"language":1049,"meta":1040,"style":1040},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","go get github.com\u002Fredelay\u002Fgo-flowdsl\n","bash",[978,1051,1052],{"__ignoreMap":1040},[1053,1054,1056,1060,1064],"span",{"class":1055,"line":10},"line",[1053,1057,1059],{"class":1058},"sBMFI","go",[1053,1061,1063],{"class":1062},"sfazB"," get",[1053,1065,1066],{"class":1062}," github.com\u002Fredelay\u002Fgo-flowdsl\n",[993,1068,1070],{"id":1069},"gomod","go.mod",[1032,1072,1075],{"className":1073,"code":1074,"language":1037},[1035],"module github.com\u002Fredelay\u002Fgo-flowdsl\ngo 1.24.0\ntoolchain go1.24.4\n\nrequire (\n    github.com\u002Fflowdsl\u002Fflowdsl-go v0.1.0\n    github.com\u002Fgoogle\u002Fuuid v1.6.0\n    gopkg.in\u002Fyaml.v3 v3.0.1\n)\n",[978,1076,1074],{"__ignoreMap":1040},[993,1078,1080],{"id":1079},"package-reference","Package reference",[1082,1083,1085,1088],"h3",{"id":1084},"ir-canonical-ir-types",[978,1086,1087],{},"ir"," — Canonical IR types",[974,1090,1091],{},"Defines the canonical Intermediate Representation that all import and export formats convert\nto and from. No external dependencies.",[1032,1093,1096],{"className":1094,"code":1095,"language":1059,"meta":1040,"style":1040},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fir\"\n\ndoc := ir.NewDocument(\"My App\", \"1.0.0\")\n\u002F\u002F doc.ID        — auto-generated UUID\n\u002F\u002F doc.Modules   — business\u002Fdomain modules\n\u002F\u002F doc.Entities  — domain aggregates\n\u002F\u002F doc.Events    — business events\n\u002F\u002F doc.Commands  — state-changing intents\n\u002F\u002F doc.Queries   — read operations\n\u002F\u002F doc.Actions   — top-level operations\n\u002F\u002F doc.Workflows — multi-step processes with nodes + edges\n\u002F\u002F doc.Channels  — message\u002Fevent channels\n\u002F\u002F doc.Schemas   — reusable data structure definitions\n\u002F\u002F doc.Packets   — data transfer payloads\n\u002F\u002F doc.Schedules — time-based triggers (cron\u002Finterval)\n\u002F\u002F doc.Migrations — database migration definitions\n\u002F\u002F doc.Metadata  — arbitrary key-value metadata\n\u002F\u002F doc.Provenance — origin and mapping history\n",[978,1097,1098,1103,1109,1114,1119,1124,1129,1134,1139,1144,1149,1154,1159,1164,1169,1174,1179,1184],{"__ignoreMap":1040},[1053,1099,1100],{"class":1055,"line":10},[1053,1101,1102],{},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fir\"\n",[1053,1104,1105],{"class":1055,"line":16},[1053,1106,1108],{"emptyLinePlaceholder":1107},true,"\n",[1053,1110,1111],{"class":1055,"line":22},[1053,1112,1113],{},"doc := ir.NewDocument(\"My App\", \"1.0.0\")\n",[1053,1115,1116],{"class":1055,"line":51},[1053,1117,1118],{},"\u002F\u002F doc.ID        — auto-generated UUID\n",[1053,1120,1121],{"class":1055,"line":57},[1053,1122,1123],{},"\u002F\u002F doc.Modules   — business\u002Fdomain modules\n",[1053,1125,1126],{"class":1055,"line":102},[1053,1127,1128],{},"\u002F\u002F doc.Entities  — domain aggregates\n",[1053,1130,1131],{"class":1055,"line":108},[1053,1132,1133],{},"\u002F\u002F doc.Events    — business events\n",[1053,1135,1136],{"class":1055,"line":114},[1053,1137,1138],{},"\u002F\u002F doc.Commands  — state-changing intents\n",[1053,1140,1141],{"class":1055,"line":120},[1053,1142,1143],{},"\u002F\u002F doc.Queries   — read operations\n",[1053,1145,1146],{"class":1055,"line":181},[1053,1147,1148],{},"\u002F\u002F doc.Actions   — top-level operations\n",[1053,1150,1151],{"class":1055,"line":186},[1053,1152,1153],{},"\u002F\u002F doc.Workflows — multi-step processes with nodes + edges\n",[1053,1155,1156],{"class":1055,"line":191},[1053,1157,1158],{},"\u002F\u002F doc.Channels  — message\u002Fevent channels\n",[1053,1160,1161],{"class":1055,"line":197},[1053,1162,1163],{},"\u002F\u002F doc.Schemas   — reusable data structure definitions\n",[1053,1165,1166],{"class":1055,"line":203},[1053,1167,1168],{},"\u002F\u002F doc.Packets   — data transfer payloads\n",[1053,1170,1171],{"class":1055,"line":214},[1053,1172,1173],{},"\u002F\u002F doc.Schedules — time-based triggers (cron\u002Finterval)\n",[1053,1175,1176],{"class":1055,"line":223},[1053,1177,1178],{},"\u002F\u002F doc.Migrations — database migration definitions\n",[1053,1180,1181],{"class":1055,"line":229},[1053,1182,1183],{},"\u002F\u002F doc.Metadata  — arbitrary key-value metadata\n",[1053,1185,1186],{"class":1055,"line":234},[1053,1187,1188],{},"\u002F\u002F doc.Provenance — origin and mapping history\n",[974,1190,1191],{},"Key types:",[1193,1194,1195,1208],"table",{},[1196,1197,1198],"thead",{},[1199,1200,1201,1205],"tr",{},[1202,1203,1204],"th",{},"Type",[1202,1206,1207],{},"Description",[1209,1210,1211,1222,1232,1242,1255,1305,1315,1325,1335,1345,1363,1372,1381,1391,1401,1411,1421,1431,1441,1451,1461,1471,1481,1491],"tbody",{},[1199,1212,1213,1219],{},[1214,1215,1216],"td",{},[978,1217,1218],{},"Document",[1214,1220,1221],{},"Root container for an entire IR",[1199,1223,1224,1229],{},[1214,1225,1226],{},[978,1227,1228],{},"Module",[1214,1230,1231],{},"Business\u002Fdomain unit with entities, events, actions, workflows, config, settings, CRUD, consumers",[1199,1233,1234,1239],{},[1214,1235,1236],{},[978,1237,1238],{},"Entity",[1214,1240,1241],{},"Business entity or domain aggregate with typed fields",[1199,1243,1244,1249],{},[1214,1245,1246],{},[978,1247,1248],{},"Field",[1214,1250,1251,1252],{},"Single field — type, constraints, nested properties, ",[978,1253,1254],{},"$ref",[1199,1256,1257,1262],{},[1214,1258,1259],{},[978,1260,1261],{},"FieldType",[1214,1263,1264,1265,1268,1269,1268,1272,1268,1275,1268,1278,1268,1281,1268,1284,1268,1287,1268,1290,1268,1293,1268,1296,1268,1299,1268,1302],{},"Enum: ",[978,1266,1267],{},"string",", ",[978,1270,1271],{},"integer",[978,1273,1274],{},"float",[978,1276,1277],{},"boolean",[978,1279,1280],{},"array",[978,1282,1283],{},"object",[978,1285,1286],{},"date",[978,1288,1289],{},"datetime",[978,1291,1292],{},"uuid",[978,1294,1295],{},"binary",[978,1297,1298],{},"ref",[978,1300,1301],{},"enum",[978,1303,1304],{},"any",[1199,1306,1307,1312],{},[1214,1308,1309],{},[978,1310,1311],{},"Event",[1214,1313,1314],{},"Business event — entity_type + action, optional topic and payload",[1199,1316,1317,1322],{},[1214,1318,1319],{},[978,1320,1321],{},"Command",[1214,1323,1324],{},"State-changing intent with input\u002Foutput schemas and emitted events",[1199,1326,1327,1332],{},[1214,1328,1329],{},[978,1330,1331],{},"Query",[1214,1333,1334],{},"Read operation with input\u002Foutput schemas",[1199,1336,1337,1342],{},[1214,1338,1339],{},[978,1340,1341],{},"Action",[1214,1343,1344],{},"Top-level operation — kind (command\u002Fquery\u002Fmutation\u002Fsubscription), method, path, I\u002FO, emits",[1199,1346,1347,1352],{},[1214,1348,1349],{},[978,1350,1351],{},"Workflow",[1214,1353,1354,1355,1358,1359,1362],{},"Multi-step process with ",[978,1356,1357],{},"Node"," graph and ",[978,1360,1361],{},"Edge"," connections",[1199,1364,1365,1369],{},[1214,1366,1367],{},[978,1368,1357],{},[1214,1370,1371],{},"Workflow step — kind (action\u002Fevent\u002Fgateway\u002Fstart\u002Fend\u002Fwait\u002Fcondition\u002Fparallel)",[1199,1373,1374,1378],{},[1214,1375,1376],{},[978,1377,1361],{},[1214,1379,1380],{},"Directed connection between nodes with optional condition",[1199,1382,1383,1388],{},[1214,1384,1385],{},[978,1386,1387],{},"Channel",[1214,1389,1390],{},"Message channel with publish\u002Fsubscribe events, protocol, bindings",[1199,1392,1393,1398],{},[1214,1394,1395],{},[978,1396,1397],{},"Schema",[1214,1399,1400],{},"Reusable data structure definition",[1199,1402,1403,1408],{},[1214,1404,1405],{},[978,1406,1407],{},"Packet",[1214,1409,1410],{},"Data transfer structure (event payload, message body)",[1199,1412,1413,1418],{},[1214,1414,1415],{},[978,1416,1417],{},"Schedule",[1214,1419,1420],{},"Time-based trigger — cron expression or interval",[1199,1422,1423,1428],{},[1214,1424,1425],{},[978,1426,1427],{},"Migration",[1214,1429,1430],{},"Database migration — backend, version, up\u002Fdown SQL",[1199,1432,1433,1438],{},[1214,1434,1435],{},[978,1436,1437],{},"Consumer",[1214,1439,1440],{},"Event consumer — topic, group ID, handler reference, batch size",[1199,1442,1443,1448],{},[1214,1444,1445],{},[978,1446,1447],{},"Provenance",[1214,1449,1450],{},"Origin tracking — source, URI, source ref, mappings",[1199,1452,1453,1458],{},[1214,1454,1455],{},[978,1456,1457],{},"ConfigDefinition",[1214,1459,1460],{},"Module runtime configuration (entries with env vars, types, defaults)",[1199,1462,1463,1468],{},[1214,1464,1465],{},[978,1466,1467],{},"SettingsDefinition",[1214,1469,1470],{},"Admin-UI-editable settings (groups of fields with components)",[1199,1472,1473,1478],{},[1214,1474,1475],{},[978,1476,1477],{},"CRUDDefinition",[1214,1479,1480],{},"CRUD capabilities for an entity (create\u002Fread\u002Fupdate\u002Fdelete\u002Flist)",[1199,1482,1483,1488],{},[1214,1484,1485],{},[978,1486,1487],{},"FlowDSLNode",[1214,1489,1490],{},"Module-exported FlowDSL node — kind, ports, settings, refs to events\u002Factions\u002Fworkflows",[1199,1492,1493,1498],{},[1214,1494,1495],{},[978,1496,1497],{},"FlowDSLPort",[1214,1499,1500],{},"Named input or output port on a FlowDSLNode",[1502,1503,1505,1507],"h4",{"id":1504},"flowdslnode-module-node-exports",[978,1506,1487],{}," — Module node exports",[974,1509,1510,1512,1513,1516],{},[978,1511,1487],{}," describes a FlowDSL node that a module exports. It captures the node identity,\nkind, ports, and settings — enough for the module browser to list nodes and for the generator\nto produce ",[978,1514,1515],{},".flowdsl-node.json"," manifests.",[1032,1518,1520],{"className":1094,"code":1519,"language":1059,"meta":1040,"style":1040},"type FlowDSLNode struct {\n    ID             string            \u002F\u002F unique node identifier (namespace\u002Fslug)\n    Name           string            \u002F\u002F human-readable display name\n    Version        string            \u002F\u002F semver version\n    Summary        string            \u002F\u002F one-line description\n    Description    string            \u002F\u002F full markdown description\n    Kind           string            \u002F\u002F functional category (source, transform, action, subworkflow, etc.)\n    Language       string            \u002F\u002F implementation language (go, python, nodejs)\n    Published      bool              \u002F\u002F publicly visible?\n    Icon           string            \u002F\u002F emoji or icon name for Studio\n    Color          string            \u002F\u002F hex color for Studio card\n    Tags           []string          \u002F\u002F search\u002Ffilter tags\n    Handler        string            \u002F\u002F fully-qualified handler path\n    Protocols      []string          \u002F\u002F supported invocation protocols\n    Inputs         []FlowDSLPort     \u002F\u002F named input ports\n    Outputs        []FlowDSLPort     \u002F\u002F named output ports\n    SettingsSchema map[string]any    \u002F\u002F inline JSON Schema for node configuration\n    ModuleRef      string            \u002F\u002F owning redelay module\n    EventRef       string            \u002F\u002F ties node to a module event\n    ActionRef      string            \u002F\u002F ties node to a module action\n    WorkflowRef    string            \u002F\u002F ties node to a module workflow (for kind=subworkflow)\n    Emits          []string          \u002F\u002F domain event topics this node may publish\n}\n",[978,1521,1522,1527,1532,1537,1542,1547,1552,1557,1562,1567,1572,1577,1582,1587,1592,1597,1602,1607,1612,1617,1622,1627,1632],{"__ignoreMap":1040},[1053,1523,1524],{"class":1055,"line":10},[1053,1525,1526],{},"type FlowDSLNode struct {\n",[1053,1528,1529],{"class":1055,"line":16},[1053,1530,1531],{},"    ID             string            \u002F\u002F unique node identifier (namespace\u002Fslug)\n",[1053,1533,1534],{"class":1055,"line":22},[1053,1535,1536],{},"    Name           string            \u002F\u002F human-readable display name\n",[1053,1538,1539],{"class":1055,"line":51},[1053,1540,1541],{},"    Version        string            \u002F\u002F semver version\n",[1053,1543,1544],{"class":1055,"line":57},[1053,1545,1546],{},"    Summary        string            \u002F\u002F one-line description\n",[1053,1548,1549],{"class":1055,"line":102},[1053,1550,1551],{},"    Description    string            \u002F\u002F full markdown description\n",[1053,1553,1554],{"class":1055,"line":108},[1053,1555,1556],{},"    Kind           string            \u002F\u002F functional category (source, transform, action, subworkflow, etc.)\n",[1053,1558,1559],{"class":1055,"line":114},[1053,1560,1561],{},"    Language       string            \u002F\u002F implementation language (go, python, nodejs)\n",[1053,1563,1564],{"class":1055,"line":120},[1053,1565,1566],{},"    Published      bool              \u002F\u002F publicly visible?\n",[1053,1568,1569],{"class":1055,"line":181},[1053,1570,1571],{},"    Icon           string            \u002F\u002F emoji or icon name for Studio\n",[1053,1573,1574],{"class":1055,"line":186},[1053,1575,1576],{},"    Color          string            \u002F\u002F hex color for Studio card\n",[1053,1578,1579],{"class":1055,"line":191},[1053,1580,1581],{},"    Tags           []string          \u002F\u002F search\u002Ffilter tags\n",[1053,1583,1584],{"class":1055,"line":197},[1053,1585,1586],{},"    Handler        string            \u002F\u002F fully-qualified handler path\n",[1053,1588,1589],{"class":1055,"line":203},[1053,1590,1591],{},"    Protocols      []string          \u002F\u002F supported invocation protocols\n",[1053,1593,1594],{"class":1055,"line":214},[1053,1595,1596],{},"    Inputs         []FlowDSLPort     \u002F\u002F named input ports\n",[1053,1598,1599],{"class":1055,"line":223},[1053,1600,1601],{},"    Outputs        []FlowDSLPort     \u002F\u002F named output ports\n",[1053,1603,1604],{"class":1055,"line":229},[1053,1605,1606],{},"    SettingsSchema map[string]any    \u002F\u002F inline JSON Schema for node configuration\n",[1053,1608,1609],{"class":1055,"line":234},[1053,1610,1611],{},"    ModuleRef      string            \u002F\u002F owning redelay module\n",[1053,1613,1614],{"class":1055,"line":240},[1053,1615,1616],{},"    EventRef       string            \u002F\u002F ties node to a module event\n",[1053,1618,1619],{"class":1055,"line":246},[1053,1620,1621],{},"    ActionRef      string            \u002F\u002F ties node to a module action\n",[1053,1623,1624],{"class":1055,"line":251},[1053,1625,1626],{},"    WorkflowRef    string            \u002F\u002F ties node to a module workflow (for kind=subworkflow)\n",[1053,1628,1629],{"class":1055,"line":257},[1053,1630,1631],{},"    Emits          []string          \u002F\u002F domain event topics this node may publish\n",[1053,1633,1635],{"class":1055,"line":1634},23,[1053,1636,1637],{},"}\n",[974,1639,1640,1643,1644,1647,1648,1268,1651,1654,1655,1658],{},[989,1641,1642],{},"WorkflowRef and subworkflow nodes:"," When ",[978,1645,1646],{},"Kind"," is ",[978,1649,1650],{},"\"subworkflow\"",[978,1652,1653],{},"WorkflowRef"," links the\nnode to an ",[978,1656,1657],{},"ir.Workflow",". The runtime resolves the reference and executes the internal graph.\nThe node's ports are the public interface; the workflow is the private implementation.",[974,1660,1661,1664,1665,1668,1669,1672,1673,1676],{},[989,1662,1663],{},"Emits and lifecycle composition:"," ",[978,1666,1667],{},"Emits"," is a static declaration of the event\ntopics an action\u002Frouter node may publish when it runs — the counterpart to the\nconsume side (a source node's configured ",[978,1670,1671],{},"eventName","). Declared in ",[978,1674,1675],{},"module.yaml",":",[1032,1678,1682],{"className":1679,"code":1680,"language":1681,"meta":1040,"style":1040},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","flowdsl_nodes:\n  - id: orders\u002Fapply-payment\n    kind: router\n    module_ref: orders\n    emits: [order.paid, order.updated]\n    outputs:\n      - name: Applied\n      - name: NotFound\n","yaml",[978,1683,1684,1694,1707,1717,1727,1749,1756,1769],{"__ignoreMap":1040},[1053,1685,1686,1690],{"class":1055,"line":10},[1053,1687,1689],{"class":1688},"swJcz","flowdsl_nodes",[1053,1691,1693],{"class":1692},"sMK4o",":\n",[1053,1695,1696,1699,1702,1704],{"class":1055,"line":16},[1053,1697,1698],{"class":1692},"  -",[1053,1700,1701],{"class":1688}," id",[1053,1703,1676],{"class":1692},[1053,1705,1706],{"class":1062}," orders\u002Fapply-payment\n",[1053,1708,1709,1712,1714],{"class":1055,"line":22},[1053,1710,1711],{"class":1688},"    kind",[1053,1713,1676],{"class":1692},[1053,1715,1716],{"class":1062}," router\n",[1053,1718,1719,1722,1724],{"class":1055,"line":51},[1053,1720,1721],{"class":1688},"    module_ref",[1053,1723,1676],{"class":1692},[1053,1725,1726],{"class":1062}," orders\n",[1053,1728,1729,1732,1734,1737,1740,1743,1746],{"class":1055,"line":57},[1053,1730,1731],{"class":1688},"    emits",[1053,1733,1676],{"class":1692},[1053,1735,1736],{"class":1692}," [",[1053,1738,1739],{"class":1062},"order.paid",[1053,1741,1742],{"class":1692},",",[1053,1744,1745],{"class":1062}," order.updated",[1053,1747,1748],{"class":1692},"]\n",[1053,1750,1751,1754],{"class":1055,"line":102},[1053,1752,1753],{"class":1688},"    outputs",[1053,1755,1693],{"class":1692},[1053,1757,1758,1761,1764,1766],{"class":1055,"line":108},[1053,1759,1760],{"class":1692},"      -",[1053,1762,1763],{"class":1688}," name",[1053,1765,1676],{"class":1692},[1053,1767,1768],{"class":1062}," Applied\n",[1053,1770,1771,1773,1775,1777],{"class":1055,"line":114},[1053,1772,1760],{"class":1692},[1053,1774,1763],{"class":1688},[1053,1776,1676],{"class":1692},[1053,1778,1779],{"class":1062}," NotFound\n",[974,1781,1782,1783,1786,1787,1789,1790,1792],{},"It powers ",[989,1784,1785],{},"lifecycle composition",": a resolver links otherwise-decoupled\nevent-driven flows into one graph by matching what each flow emits against what\nother flows consume (their source node's ",[978,1788,1671],{},"). Nodes whose emitted topic\nis dynamic (chosen from config, e.g. a generic publish node) leave ",[978,1791,1667],{}," empty\nand are resolved from config at graph-build time.",[1502,1794,1796],{"id":1795},"subworkflow-node-generation","Subworkflow node generation",[974,1798,1799,1802,1803,1805,1806,1676],{},[978,1800,1801],{},"SubworkflowNodeFromWorkflow"," creates a subworkflow ",[978,1804,1487],{}," from an ",[978,1807,1657],{},[1032,1809,1811],{"className":1094,"code":1810,"language":1059,"meta":1040,"style":1040},"node := ir.SubworkflowNodeFromWorkflow(wf, \"redelay\", \"orders\")\n\u002F\u002F node.Kind        = \"subworkflow\"\n\u002F\u002F node.WorkflowRef = wf.ID\n\u002F\u002F node.Inputs      — derived from workflow triggers\n\u002F\u002F node.Outputs     — derived from terminal nodes (kind=end or leaf nodes)\n",[978,1812,1813,1818,1823,1828,1833],{"__ignoreMap":1040},[1053,1814,1815],{"class":1055,"line":10},[1053,1816,1817],{},"node := ir.SubworkflowNodeFromWorkflow(wf, \"redelay\", \"orders\")\n",[1053,1819,1820],{"class":1055,"line":16},[1053,1821,1822],{},"\u002F\u002F node.Kind        = \"subworkflow\"\n",[1053,1824,1825],{"class":1055,"line":22},[1053,1826,1827],{},"\u002F\u002F node.WorkflowRef = wf.ID\n",[1053,1829,1830],{"class":1055,"line":51},[1053,1831,1832],{},"\u002F\u002F node.Inputs      — derived from workflow triggers\n",[1053,1834,1835],{"class":1055,"line":57},[1053,1836,1837],{},"\u002F\u002F node.Outputs     — derived from terminal nodes (kind=end or leaf nodes)\n",[974,1839,1840],{},"Port derivation rules:",[1842,1843,1844,1851,1857],"ul",{},[1845,1846,1847,1850],"li",{},[989,1848,1849],{},"Inputs:"," one port per workflow trigger; defaults to a single \"Input\" port if no triggers.",[1845,1852,1853,1856],{},[989,1854,1855],{},"Outputs:"," one port per terminal node (kind=end) or leaf node with no outgoing edges; defaults to \"Output\" if none found.",[1845,1858,1859,1862,1863,1866,1867,1870],{},[989,1860,1861],{},"Error output:"," if any edge has ",[978,1864,1865],{},"condition: \"error\""," or ",[978,1868,1869],{},"\"on_error\"",", an \"Error\" output port is appended.",[974,1872,1873,1874,1877,1878,1882],{},"The framework registry auto-generates subworkflow nodes for any module that provides workflows\nvia ",[978,1875,1876],{},"FlowDSLProvider"," without explicitly defining nodes for them. See the\n",[986,1879,1881],{"href":1880},"#auto-generation-of-subworkflow-nodes","auto-generation section"," below.",[1502,1884,1886],{"id":1885},"manifest-conversion","Manifest conversion",[974,1888,1889,1891,1892,1895,1896,1899],{},[978,1890,1487],{}," has bidirectional conversion to the canonical FlowDSL SDK ",[978,1893,1894],{},"node.Manifest"," type\n(from ",[978,1897,1898],{},"github.com\u002Fflowdsl\u002Fflowdsl-go\u002Fpkg\u002Fnode","):",[1032,1901,1903],{"className":1094,"code":1902,"language":1059,"meta":1040,"style":1040},"manifest := irNode.ToManifest()     \u002F\u002F IR → SDK Manifest (camelCase JSON)\nirNode = ir.FlowDSLNodeFromManifest(manifest) \u002F\u002F SDK Manifest → IR (snake_case JSON)\n",[978,1904,1905,1910],{"__ignoreMap":1040},[1053,1906,1907],{"class":1055,"line":10},[1053,1908,1909],{},"manifest := irNode.ToManifest()     \u002F\u002F IR → SDK Manifest (camelCase JSON)\n",[1053,1911,1912],{"class":1055,"line":16},[1053,1913,1914],{},"irNode = ir.FlowDSLNodeFromManifest(manifest) \u002F\u002F SDK Manifest → IR (snake_case JSON)\n",[974,1916,1917,1918,1921],{},"This bridges the IR layer (snake_case, redelay-specific fields) with the FlowDSL spec layer\n(camelCase, schema-compliant). The SDK dependency is ",[978,1919,1920],{},"github.com\u002Fflowdsl\u002Fflowdsl-go",".",[1082,1923,1925,1928],{"id":1924},"diagnostics-structured-errorwarning-collector",[978,1926,1927],{},"diagnostics"," — Structured error\u002Fwarning collector",[974,1930,1931],{},"Used throughout all validation and compilation stages.",[1032,1933,1935],{"className":1094,"code":1934,"language":1059,"meta":1040,"style":1040},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fdiagnostics\"\n\nc := diagnostics.NewCollector()\nc.Error(\"source\", \"CODE\", \"message\")\nc.Warning(\"source\", \"CODE\", \"message\")\nc.Info(\"source\", \"CODE\", \"message\")\n\nc.HasErrors()  \u002F\u002F bool\nc.Errors()     \u002F\u002F []*Diagnostic  (error-level only)\nc.Warnings()   \u002F\u002F []*Diagnostic  (warning-level only)\nc.All()        \u002F\u002F []*Diagnostic  (all levels)\n",[978,1936,1937,1942,1946,1951,1956,1961,1966,1970,1975,1980,1985],{"__ignoreMap":1040},[1053,1938,1939],{"class":1055,"line":10},[1053,1940,1941],{},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fdiagnostics\"\n",[1053,1943,1944],{"class":1055,"line":16},[1053,1945,1108],{"emptyLinePlaceholder":1107},[1053,1947,1948],{"class":1055,"line":22},[1053,1949,1950],{},"c := diagnostics.NewCollector()\n",[1053,1952,1953],{"class":1055,"line":51},[1053,1954,1955],{},"c.Error(\"source\", \"CODE\", \"message\")\n",[1053,1957,1958],{"class":1055,"line":57},[1053,1959,1960],{},"c.Warning(\"source\", \"CODE\", \"message\")\n",[1053,1962,1963],{"class":1055,"line":102},[1053,1964,1965],{},"c.Info(\"source\", \"CODE\", \"message\")\n",[1053,1967,1968],{"class":1055,"line":108},[1053,1969,1108],{"emptyLinePlaceholder":1107},[1053,1971,1972],{"class":1055,"line":114},[1053,1973,1974],{},"c.HasErrors()  \u002F\u002F bool\n",[1053,1976,1977],{"class":1055,"line":120},[1053,1978,1979],{},"c.Errors()     \u002F\u002F []*Diagnostic  (error-level only)\n",[1053,1981,1982],{"class":1055,"line":181},[1053,1983,1984],{},"c.Warnings()   \u002F\u002F []*Diagnostic  (warning-level only)\n",[1053,1986,1987],{"class":1055,"line":186},[1053,1988,1989],{},"c.All()        \u002F\u002F []*Diagnostic  (all levels)\n",[974,1991,1992,1993,1996,1997,1268,2000,1268,2003,1268,2006,2009,2010,2013,2014,1268,2017,1268,2020,1268,2023,1921],{},"Each ",[978,1994,1995],{},"Diagnostic"," carries: ",[978,1998,1999],{},"Severity",[978,2001,2002],{},"Code",[978,2004,2005],{},"Message",[978,2007,2008],{},"Source",", and optional ",[978,2011,2012],{},"File",",\n",[978,2015,2016],{},"Line",[978,2018,2019],{},"Column",[978,2021,2022],{},"Pointer",[978,2024,2025],{},"Related",[1082,2027,2029,2032],{"id":2028},"schema-json-schema-generator",[978,2030,2031],{},"schema"," — JSON Schema generator",[974,2034,2035,2036,2039],{},"Generates JSON Schema (Draft 2020-12) from Go types via reflection. Used by\n",[978,2037,2038],{},"go-framework\u002Fopenapi"," for struct → JSON Schema conversion.",[1032,2041,2043],{"className":1094,"code":2042,"language":1059,"meta":1040,"style":1040},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fschema\"\n\ns := schema.From(MyStruct{})\n\u002F\u002F returns map[string]any compatible with JSON Schema Draft 2020-12\n",[978,2044,2045,2050,2054,2059],{"__ignoreMap":1040},[1053,2046,2047],{"class":1055,"line":10},[1053,2048,2049],{},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fschema\"\n",[1053,2051,2052],{"class":1055,"line":16},[1053,2053,1108],{"emptyLinePlaceholder":1107},[1053,2055,2056],{"class":1055,"line":22},[1053,2057,2058],{},"s := schema.From(MyStruct{})\n",[1053,2060,2061],{"class":1055,"line":51},[1053,2062,2063],{},"\u002F\u002F returns map[string]any compatible with JSON Schema Draft 2020-12\n",[974,2065,2066,2067,2070,2071,2074,2075,2078],{},"Handles ",[978,2068,2069],{},"json"," tags, ",[978,2072,2073],{},"validate"," tags (required, email, min, max), pointer nullability,\n",[978,2076,2077],{},"time.Time",", slices, maps, and embedded structs.",[1082,2080,2082,2085],{"id":2081},"metadata-ir-metadata-helpers",[978,2083,2084],{},"metadata"," — IR metadata helpers",[974,2087,2088],{},"Extracts summary statistics from a document and stamps compiler metadata.",[1032,2090,2092],{"className":1094,"code":2091,"language":1059,"meta":1040,"style":1040},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fmetadata\"\n\ninfo := metadata.Extract(doc)\n\u002F\u002F info.Title, info.Version, info.Compiler\n\u002F\u002F info.ModuleCount, info.EntityCount, info.EventCount\n\u002F\u002F info.ActionCount, info.WorkflowCount, info.ChannelCount, info.ScheduleCount\n\nmetadata.Stamp(doc)              \u002F\u002F adds compiler version + compiled_at to doc.Metadata\nnames := metadata.ModuleNames(doc)   \u002F\u002F []string\nnames  = metadata.ActionNames(doc)   \u002F\u002F []string\nnames  = metadata.EventNames(doc)    \u002F\u002F []string\n",[978,2093,2094,2099,2103,2108,2113,2118,2123,2127,2132,2137,2142],{"__ignoreMap":1040},[1053,2095,2096],{"class":1055,"line":10},[1053,2097,2098],{},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fmetadata\"\n",[1053,2100,2101],{"class":1055,"line":16},[1053,2102,1108],{"emptyLinePlaceholder":1107},[1053,2104,2105],{"class":1055,"line":22},[1053,2106,2107],{},"info := metadata.Extract(doc)\n",[1053,2109,2110],{"class":1055,"line":51},[1053,2111,2112],{},"\u002F\u002F info.Title, info.Version, info.Compiler\n",[1053,2114,2115],{"class":1055,"line":57},[1053,2116,2117],{},"\u002F\u002F info.ModuleCount, info.EntityCount, info.EventCount\n",[1053,2119,2120],{"class":1055,"line":102},[1053,2121,2122],{},"\u002F\u002F info.ActionCount, info.WorkflowCount, info.ChannelCount, info.ScheduleCount\n",[1053,2124,2125],{"class":1055,"line":108},[1053,2126,1108],{"emptyLinePlaceholder":1107},[1053,2128,2129],{"class":1055,"line":114},[1053,2130,2131],{},"metadata.Stamp(doc)              \u002F\u002F adds compiler version + compiled_at to doc.Metadata\n",[1053,2133,2134],{"class":1055,"line":120},[1053,2135,2136],{},"names := metadata.ModuleNames(doc)   \u002F\u002F []string\n",[1053,2138,2139],{"class":1055,"line":181},[1053,2140,2141],{},"names  = metadata.ActionNames(doc)   \u002F\u002F []string\n",[1053,2143,2144],{"class":1055,"line":186},[1053,2145,2146],{},"names  = metadata.EventNames(doc)    \u002F\u002F []string\n",[1082,2148,2150,2153],{"id":2149},"businessmodel-business-model-parser",[978,2151,2152],{},"businessmodel"," — Business model parser",[974,2155,2156],{},"Parses, normalizes, and exports the Redelay business model YAML format.",[1032,2158,2160],{"className":1094,"code":2159,"language":1059,"meta":1040,"style":1040},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fbusinessmodel\"\n\nspec, err := businessmodel.ParseYAML(r)  \u002F\u002F io.Reader → *BusinessModel\ndoc := businessmodel.Normalize(spec)     \u002F\u002F *BusinessModel → *ir.Document\n",[978,2161,2162,2167,2171,2176],{"__ignoreMap":1040},[1053,2163,2164],{"class":1055,"line":10},[1053,2165,2166],{},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fbusinessmodel\"\n",[1053,2168,2169],{"class":1055,"line":16},[1053,2170,1108],{"emptyLinePlaceholder":1107},[1053,2172,2173],{"class":1055,"line":22},[1053,2174,2175],{},"spec, err := businessmodel.ParseYAML(r)  \u002F\u002F io.Reader → *BusinessModel\n",[1053,2177,2178],{"class":1055,"line":51},[1053,2179,2180],{},"doc := businessmodel.Normalize(spec)     \u002F\u002F *BusinessModel → *ir.Document\n",[1082,2182,2184,2187],{"id":2183},"resolver-module-dependency-resolver",[978,2185,2186],{},"resolver"," — Module dependency resolver",[974,2189,2190,2191,2194],{},"Topological sort of modules by their ",[978,2192,2193],{},"depends_on"," declarations using Kahn's algorithm with\ncycle detection.",[1032,2196,2198],{"className":1094,"code":2197,"language":1059,"meta":1040,"style":1040},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fresolver\"\n\nsorted, diag := resolver.Resolve(doc.Modules)\n\u002F\u002F sorted — []*ir.Module in dependency order (dependencies first)\n\u002F\u002F diag   — *diagnostics.Collector\n",[978,2199,2200,2205,2209,2214,2219],{"__ignoreMap":1040},[1053,2201,2202],{"class":1055,"line":10},[1053,2203,2204],{},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fresolver\"\n",[1053,2206,2207],{"class":1055,"line":16},[1053,2208,1108],{"emptyLinePlaceholder":1107},[1053,2210,2211],{"class":1055,"line":22},[1053,2212,2213],{},"sorted, diag := resolver.Resolve(doc.Modules)\n",[1053,2215,2216],{"class":1055,"line":51},[1053,2217,2218],{},"\u002F\u002F sorted — []*ir.Module in dependency order (dependencies first)\n",[1053,2220,2221],{"class":1055,"line":57},[1053,2222,2223],{},"\u002F\u002F diag   — *diagnostics.Collector\n",[1193,2225,2226,2237],{},[1196,2227,2228],{},[1199,2229,2230,2232,2234],{},[1202,2231,2002],{},[1202,2233,1999],{},[1202,2235,2236],{},"Rule",[1209,2238,2239,2252,2264,2276],{},[1199,2240,2241,2246,2249],{},[1214,2242,2243],{},[978,2244,2245],{},"RES001",[1214,2247,2248],{},"error",[1214,2250,2251],{},"Duplicate module ID",[1199,2253,2254,2259,2261],{},[1214,2255,2256],{},[978,2257,2258],{},"RES002",[1214,2260,2248],{},[1214,2262,2263],{},"Depends on unknown module",[1199,2265,2266,2271,2273],{},[1214,2267,2268],{},[978,2269,2270],{},"RES003",[1214,2272,2248],{},[1214,2274,2275],{},"Circular dependency detected",[1199,2277,2278,2283,2285],{},[1214,2279,2280],{},[978,2281,2282],{},"RES004",[1214,2284,2248],{},[1214,2286,2287],{},"Module is part of a dependency cycle",[1082,2289,2291,2293],{"id":2290},"validate-structural-validator",[978,2292,2073],{}," — Structural validator",[974,2295,2296],{},"Checks an IR Document for structural correctness and referential integrity.",[1032,2298,2300],{"className":1094,"code":2299,"language":1059,"meta":1040,"style":1040},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fvalidate\"\n\ndiag := validate.Validate(doc) \u002F\u002F *diagnostics.Collector\n",[978,2301,2302,2307,2311],{"__ignoreMap":1040},[1053,2303,2304],{"class":1055,"line":10},[1053,2305,2306],{},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fvalidate\"\n",[1053,2308,2309],{"class":1055,"line":16},[1053,2310,1108],{"emptyLinePlaceholder":1107},[1053,2312,2313],{"class":1055,"line":22},[1053,2314,2315],{},"diag := validate.Validate(doc) \u002F\u002F *diagnostics.Collector\n",[1193,2317,2318,2328],{},[1196,2319,2320],{},[1199,2321,2322,2324,2326],{},[1202,2323,2002],{},[1202,2325,1999],{},[1202,2327,2236],{},[1209,2329,2330,2342,2354,2367,2379,2391,2403,2415,2427,2439,2451,2463],{},[1199,2331,2332,2337,2339],{},[1214,2333,2334],{},[978,2335,2336],{},"VAL001",[1214,2338,2248],{},[1214,2340,2341],{},"Document is nil",[1199,2343,2344,2349,2351],{},[1214,2345,2346],{},[978,2347,2348],{},"VAL002",[1214,2350,2248],{},[1214,2352,2353],{},"Document ID is required",[1199,2355,2356,2361,2364],{},[1214,2357,2358],{},[978,2359,2360],{},"VAL003",[1214,2362,2363],{},"warning",[1214,2365,2366],{},"Document version is empty",[1199,2368,2369,2374,2376],{},[1214,2370,2371],{},[978,2372,2373],{},"VAL010",[1214,2375,2248],{},[1214,2377,2378],{},"Duplicate ID",[1199,2380,2381,2386,2388],{},[1214,2382,2383],{},[978,2384,2385],{},"VAL020",[1214,2387,2248],{},[1214,2389,2390],{},"Module depends on unknown module",[1199,2392,2393,2398,2400],{},[1214,2394,2395],{},[978,2396,2397],{},"VAL021",[1214,2399,2363],{},[1214,2401,2402],{},"Event references unknown payload",[1199,2404,2405,2410,2412],{},[1214,2406,2407],{},[978,2408,2409],{},"VAL022",[1214,2411,2363],{},[1214,2413,2414],{},"Action references unknown input",[1199,2416,2417,2422,2424],{},[1214,2418,2419],{},[978,2420,2421],{},"VAL023",[1214,2423,2363],{},[1214,2425,2426],{},"Action references unknown output",[1199,2428,2429,2434,2436],{},[1214,2430,2431],{},[978,2432,2433],{},"VAL030",[1214,2435,2248],{},[1214,2437,2438],{},"Workflow edge references unknown source node",[1199,2440,2441,2446,2448],{},[1214,2442,2443],{},[978,2444,2445],{},"VAL031",[1214,2447,2248],{},[1214,2449,2450],{},"Workflow edge references unknown target node",[1199,2452,2453,2458,2460],{},[1214,2454,2455],{},[978,2456,2457],{},"VAL040",[1214,2459,2248],{},[1214,2461,2462],{},"Module has no name",[1199,2464,2465,2470,2472],{},[1214,2466,2467],{},[978,2468,2469],{},"VAL041",[1214,2471,2363],{},[1214,2473,2474,2475],{},"Module ID should start with ",[978,2476,2477],{},"module.",[1082,2479,2481,2484],{"id":2480},"flowdsl-flowdsl-yaml-parser",[978,2482,2483],{},"flowdsl"," — FlowDSL YAML parser",[974,2486,2487],{},"Parses, validates, normalizes, and exports the FlowDSL YAML application definition format.",[1032,2489,2491],{"className":1094,"code":2490,"language":1059,"meta":1040,"style":1040},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fflowdsl\"\n\nparsed, err := flowdsl.Parse(r)       \u002F\u002F io.Reader → *FlowDSL\ndiag := flowdsl.Validate(parsed)      \u002F\u002F *FlowDSL → *diagnostics.Collector\ndoc := flowdsl.Normalize(parsed)      \u002F\u002F *FlowDSL → *ir.Document\nerr = flowdsl.Export(doc, w)          \u002F\u002F *ir.Document → FlowDSL YAML\n",[978,2492,2493,2498,2502,2507,2512,2517],{"__ignoreMap":1040},[1053,2494,2495],{"class":1055,"line":10},[1053,2496,2497],{},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fflowdsl\"\n",[1053,2499,2500],{"class":1055,"line":16},[1053,2501,1108],{"emptyLinePlaceholder":1107},[1053,2503,2504],{"class":1055,"line":22},[1053,2505,2506],{},"parsed, err := flowdsl.Parse(r)       \u002F\u002F io.Reader → *FlowDSL\n",[1053,2508,2509],{"class":1055,"line":51},[1053,2510,2511],{},"diag := flowdsl.Validate(parsed)      \u002F\u002F *FlowDSL → *diagnostics.Collector\n",[1053,2513,2514],{"class":1055,"line":57},[1053,2515,2516],{},"doc := flowdsl.Normalize(parsed)      \u002F\u002F *FlowDSL → *ir.Document\n",[1053,2518,2519],{"class":1055,"line":102},[1053,2520,2521],{},"err = flowdsl.Export(doc, w)          \u002F\u002F *ir.Document → FlowDSL YAML\n",[974,2523,2524],{},[989,2525,2526],{},"FlowDSL YAML format:",[1032,2528,2530],{"className":1679,"code":2529,"language":1681,"meta":1040,"style":1040},"version: \"1.0\"\ntitle: My Application\nmodules:\n  billing:\n    name: billing\n    description: Billing domain\n    depends_on: [users]\n    provides: [invoices]\nentities:\n  invoice:\n    name: invoice\n    fields:\n      amount: { type: float, required: true }\n      currency: { type: string, default: USD }\nevents:\n  invoice_created:\n    name: invoice_created\n    entity_type: invoice\n    action: created\n    topic: billing.invoices\nactions:\n  create_invoice:\n    name: create_invoice\n    kind: command\n    method: POST\n    path: \u002Finvoices\nworkflows:\n  payment_flow:\n    name: payment_flow\n    triggers: [invoice_created]\n    steps:\n      - id: validate\n        kind: action\n        action: validate_payment\n        next: charge\n      - id: charge\n        kind: action\n        action: charge_card\nchannels:\n  notifications:\n    name: notifications\n    protocol: kafka\nschedules:\n  daily_report:\n    name: daily_report\n    cron: \"0 9 * * *\"\n    action: generate_report\n",[978,2531,2532,2548,2558,2565,2572,2582,2592,2606,2620,2627,2634,2643,2650,2682,2710,2717,2724,2733,2742,2752,2762,2769,2776,2785,2795,2805,2815,2822,2830,2840,2855,2863,2875,2886,2897,2908,2919,2928,2938,2946,2954,2964,2975,2983,2991,3001,3016],{"__ignoreMap":1040},[1053,2533,2534,2537,2539,2542,2545],{"class":1055,"line":10},[1053,2535,2536],{"class":1688},"version",[1053,2538,1676],{"class":1692},[1053,2540,2541],{"class":1692}," \"",[1053,2543,2544],{"class":1062},"1.0",[1053,2546,2547],{"class":1692},"\"\n",[1053,2549,2550,2553,2555],{"class":1055,"line":16},[1053,2551,2552],{"class":1688},"title",[1053,2554,1676],{"class":1692},[1053,2556,2557],{"class":1062}," My Application\n",[1053,2559,2560,2563],{"class":1055,"line":22},[1053,2561,2562],{"class":1688},"modules",[1053,2564,1693],{"class":1692},[1053,2566,2567,2570],{"class":1055,"line":51},[1053,2568,2569],{"class":1688},"  billing",[1053,2571,1693],{"class":1692},[1053,2573,2574,2577,2579],{"class":1055,"line":57},[1053,2575,2576],{"class":1688},"    name",[1053,2578,1676],{"class":1692},[1053,2580,2581],{"class":1062}," billing\n",[1053,2583,2584,2587,2589],{"class":1055,"line":102},[1053,2585,2586],{"class":1688},"    description",[1053,2588,1676],{"class":1692},[1053,2590,2591],{"class":1062}," Billing domain\n",[1053,2593,2594,2597,2599,2601,2604],{"class":1055,"line":108},[1053,2595,2596],{"class":1688},"    depends_on",[1053,2598,1676],{"class":1692},[1053,2600,1736],{"class":1692},[1053,2602,2603],{"class":1062},"users",[1053,2605,1748],{"class":1692},[1053,2607,2608,2611,2613,2615,2618],{"class":1055,"line":114},[1053,2609,2610],{"class":1688},"    provides",[1053,2612,1676],{"class":1692},[1053,2614,1736],{"class":1692},[1053,2616,2617],{"class":1062},"invoices",[1053,2619,1748],{"class":1692},[1053,2621,2622,2625],{"class":1055,"line":120},[1053,2623,2624],{"class":1688},"entities",[1053,2626,1693],{"class":1692},[1053,2628,2629,2632],{"class":1055,"line":181},[1053,2630,2631],{"class":1688},"  invoice",[1053,2633,1693],{"class":1692},[1053,2635,2636,2638,2640],{"class":1055,"line":186},[1053,2637,2576],{"class":1688},[1053,2639,1676],{"class":1692},[1053,2641,2642],{"class":1062}," invoice\n",[1053,2644,2645,2648],{"class":1055,"line":191},[1053,2646,2647],{"class":1688},"    fields",[1053,2649,1693],{"class":1692},[1053,2651,2652,2655,2657,2660,2663,2665,2668,2670,2673,2675,2679],{"class":1055,"line":197},[1053,2653,2654],{"class":1688},"      amount",[1053,2656,1676],{"class":1692},[1053,2658,2659],{"class":1692}," {",[1053,2661,2662],{"class":1688}," type",[1053,2664,1676],{"class":1692},[1053,2666,2667],{"class":1062}," float",[1053,2669,1742],{"class":1692},[1053,2671,2672],{"class":1688}," required",[1053,2674,1676],{"class":1692},[1053,2676,2678],{"class":2677},"sfNiH"," true",[1053,2680,2681],{"class":1692}," }\n",[1053,2683,2684,2687,2689,2691,2693,2695,2698,2700,2703,2705,2708],{"class":1055,"line":203},[1053,2685,2686],{"class":1688},"      currency",[1053,2688,1676],{"class":1692},[1053,2690,2659],{"class":1692},[1053,2692,2662],{"class":1688},[1053,2694,1676],{"class":1692},[1053,2696,2697],{"class":1062}," string",[1053,2699,1742],{"class":1692},[1053,2701,2702],{"class":1688}," default",[1053,2704,1676],{"class":1692},[1053,2706,2707],{"class":1062}," USD",[1053,2709,2681],{"class":1692},[1053,2711,2712,2715],{"class":1055,"line":214},[1053,2713,2714],{"class":1688},"events",[1053,2716,1693],{"class":1692},[1053,2718,2719,2722],{"class":1055,"line":223},[1053,2720,2721],{"class":1688},"  invoice_created",[1053,2723,1693],{"class":1692},[1053,2725,2726,2728,2730],{"class":1055,"line":229},[1053,2727,2576],{"class":1688},[1053,2729,1676],{"class":1692},[1053,2731,2732],{"class":1062}," invoice_created\n",[1053,2734,2735,2738,2740],{"class":1055,"line":234},[1053,2736,2737],{"class":1688},"    entity_type",[1053,2739,1676],{"class":1692},[1053,2741,2642],{"class":1062},[1053,2743,2744,2747,2749],{"class":1055,"line":240},[1053,2745,2746],{"class":1688},"    action",[1053,2748,1676],{"class":1692},[1053,2750,2751],{"class":1062}," created\n",[1053,2753,2754,2757,2759],{"class":1055,"line":246},[1053,2755,2756],{"class":1688},"    topic",[1053,2758,1676],{"class":1692},[1053,2760,2761],{"class":1062}," billing.invoices\n",[1053,2763,2764,2767],{"class":1055,"line":251},[1053,2765,2766],{"class":1688},"actions",[1053,2768,1693],{"class":1692},[1053,2770,2771,2774],{"class":1055,"line":257},[1053,2772,2773],{"class":1688},"  create_invoice",[1053,2775,1693],{"class":1692},[1053,2777,2778,2780,2782],{"class":1055,"line":1634},[1053,2779,2576],{"class":1688},[1053,2781,1676],{"class":1692},[1053,2783,2784],{"class":1062}," create_invoice\n",[1053,2786,2788,2790,2792],{"class":1055,"line":2787},24,[1053,2789,1711],{"class":1688},[1053,2791,1676],{"class":1692},[1053,2793,2794],{"class":1062}," command\n",[1053,2796,2797,2800,2802],{"class":1055,"line":271},[1053,2798,2799],{"class":1688},"    method",[1053,2801,1676],{"class":1692},[1053,2803,2804],{"class":1062}," POST\n",[1053,2806,2807,2810,2812],{"class":1055,"line":277},[1053,2808,2809],{"class":1688},"    path",[1053,2811,1676],{"class":1692},[1053,2813,2814],{"class":1062}," \u002Finvoices\n",[1053,2816,2817,2820],{"class":1055,"line":282},[1053,2818,2819],{"class":1688},"workflows",[1053,2821,1693],{"class":1692},[1053,2823,2825,2828],{"class":1055,"line":2824},28,[1053,2826,2827],{"class":1688},"  payment_flow",[1053,2829,1693],{"class":1692},[1053,2831,2833,2835,2837],{"class":1055,"line":2832},29,[1053,2834,2576],{"class":1688},[1053,2836,1676],{"class":1692},[1053,2838,2839],{"class":1062}," payment_flow\n",[1053,2841,2843,2846,2848,2850,2853],{"class":1055,"line":2842},30,[1053,2844,2845],{"class":1688},"    triggers",[1053,2847,1676],{"class":1692},[1053,2849,1736],{"class":1692},[1053,2851,2852],{"class":1062},"invoice_created",[1053,2854,1748],{"class":1692},[1053,2856,2858,2861],{"class":1055,"line":2857},31,[1053,2859,2860],{"class":1688},"    steps",[1053,2862,1693],{"class":1692},[1053,2864,2866,2868,2870,2872],{"class":1055,"line":2865},32,[1053,2867,1760],{"class":1692},[1053,2869,1701],{"class":1688},[1053,2871,1676],{"class":1692},[1053,2873,2874],{"class":1062}," validate\n",[1053,2876,2878,2881,2883],{"class":1055,"line":2877},33,[1053,2879,2880],{"class":1688},"        kind",[1053,2882,1676],{"class":1692},[1053,2884,2885],{"class":1062}," action\n",[1053,2887,2889,2892,2894],{"class":1055,"line":2888},34,[1053,2890,2891],{"class":1688},"        action",[1053,2893,1676],{"class":1692},[1053,2895,2896],{"class":1062}," validate_payment\n",[1053,2898,2900,2903,2905],{"class":1055,"line":2899},35,[1053,2901,2902],{"class":1688},"        next",[1053,2904,1676],{"class":1692},[1053,2906,2907],{"class":1062}," charge\n",[1053,2909,2911,2913,2915,2917],{"class":1055,"line":2910},36,[1053,2912,1760],{"class":1692},[1053,2914,1701],{"class":1688},[1053,2916,1676],{"class":1692},[1053,2918,2907],{"class":1062},[1053,2920,2922,2924,2926],{"class":1055,"line":2921},37,[1053,2923,2880],{"class":1688},[1053,2925,1676],{"class":1692},[1053,2927,2885],{"class":1062},[1053,2929,2931,2933,2935],{"class":1055,"line":2930},38,[1053,2932,2891],{"class":1688},[1053,2934,1676],{"class":1692},[1053,2936,2937],{"class":1062}," charge_card\n",[1053,2939,2941,2944],{"class":1055,"line":2940},39,[1053,2942,2943],{"class":1688},"channels",[1053,2945,1693],{"class":1692},[1053,2947,2949,2952],{"class":1055,"line":2948},40,[1053,2950,2951],{"class":1688},"  notifications",[1053,2953,1693],{"class":1692},[1053,2955,2957,2959,2961],{"class":1055,"line":2956},41,[1053,2958,2576],{"class":1688},[1053,2960,1676],{"class":1692},[1053,2962,2963],{"class":1062}," notifications\n",[1053,2965,2967,2970,2972],{"class":1055,"line":2966},42,[1053,2968,2969],{"class":1688},"    protocol",[1053,2971,1676],{"class":1692},[1053,2973,2974],{"class":1062}," kafka\n",[1053,2976,2978,2981],{"class":1055,"line":2977},43,[1053,2979,2980],{"class":1688},"schedules",[1053,2982,1693],{"class":1692},[1053,2984,2986,2989],{"class":1055,"line":2985},44,[1053,2987,2988],{"class":1688},"  daily_report",[1053,2990,1693],{"class":1692},[1053,2992,2994,2996,2998],{"class":1055,"line":2993},45,[1053,2995,2576],{"class":1688},[1053,2997,1676],{"class":1692},[1053,2999,3000],{"class":1062}," daily_report\n",[1053,3002,3004,3007,3009,3011,3014],{"class":1055,"line":3003},46,[1053,3005,3006],{"class":1688},"    cron",[1053,3008,1676],{"class":1692},[1053,3010,2541],{"class":1692},[1053,3012,3013],{"class":1062},"0 9 * * *",[1053,3015,2547],{"class":1692},[1053,3017,3019,3021,3023],{"class":1055,"line":3018},47,[1053,3020,2746],{"class":1688},[1053,3022,1676],{"class":1692},[1053,3024,3025],{"class":1062}," generate_report\n",[974,3027,3028],{},[989,3029,3030],{},"Validation error codes:",[1193,3032,3033,3043],{},[1196,3034,3035],{},[1199,3036,3037,3039,3041],{},[1202,3038,2002],{},[1202,3040,1999],{},[1202,3042,2236],{},[1209,3044,3045,3056,3068,3083,3097,3109,3121,3137,3151,3165,3180,3195,3210,3224,3240,3252,3266],{},[1199,3046,3047,3052,3054],{},[1214,3048,3049],{},[978,3050,3051],{},"FDL001",[1214,3053,2248],{},[1214,3055,2341],{},[1199,3057,3058,3063,3065],{},[1214,3059,3060],{},[978,3061,3062],{},"FDL002",[1214,3064,2363],{},[1214,3066,3067],{},"Version is empty",[1199,3069,3070,3075,3077],{},[1214,3071,3072],{},[978,3073,3074],{},"FDL010",[1214,3076,2248],{},[1214,3078,3079,3080],{},"Event missing ",[978,3081,3082],{},"entity_type",[1199,3084,3085,3090,3092],{},[1214,3086,3087],{},[978,3088,3089],{},"FDL011",[1214,3091,2248],{},[1214,3093,3079,3094],{},[978,3095,3096],{},"action",[1199,3098,3099,3104,3106],{},[1214,3100,3101],{},[978,3102,3103],{},"FDL012",[1214,3105,2363],{},[1214,3107,3108],{},"Event payload field has invalid type",[1199,3110,3111,3116,3118],{},[1214,3112,3113],{},[978,3114,3115],{},"FDL020",[1214,3117,2248],{},[1214,3119,3120],{},"Workflow step missing ID",[1199,3122,3123,3128,3130],{},[1214,3124,3125],{},[978,3126,3127],{},"FDL021",[1214,3129,2363],{},[1214,3131,3132,3133,3136],{},"Step ",[978,3134,3135],{},"next"," references unknown step",[1199,3138,3139,3144,3146],{},[1214,3140,3141],{},[978,3142,3143],{},"FDL022",[1214,3145,2363],{},[1214,3147,3132,3148,3136],{},[978,3149,3150],{},"on_error",[1199,3152,3153,3158,3160],{},[1214,3154,3155],{},[978,3156,3157],{},"FDL023",[1214,3159,2363],{},[1214,3161,3132,3162,3164],{},[978,3163,3096],{}," references unknown action",[1199,3166,3167,3172,3174],{},[1214,3168,3169],{},[978,3170,3171],{},"FDL024",[1214,3173,2363],{},[1214,3175,3132,3176,3179],{},[978,3177,3178],{},"event"," references unknown event",[1199,3181,3182,3187,3189],{},[1214,3183,3184],{},[978,3185,3186],{},"FDL025",[1214,3188,2363],{},[1214,3190,3132,3191,3194],{},[978,3192,3193],{},"kind"," is not a recognised value",[1199,3196,3197,3202,3204],{},[1214,3198,3199],{},[978,3200,3201],{},"FDL030",[1214,3203,2363],{},[1214,3205,3206,3207,3209],{},"Module ",[978,3208,2193],{}," unknown module",[1199,3211,3212,3217,3219],{},[1214,3213,3214],{},[978,3215,3216],{},"FDL040",[1214,3218,2363],{},[1214,3220,3221,3222,3164],{},"Schedule ",[978,3223,3096],{},[1199,3225,3226,3231,3233],{},[1214,3227,3228],{},[978,3229,3230],{},"FDL050",[1214,3232,2363],{},[1214,3234,3235,3236,3239],{},"Channel ",[978,3237,3238],{},"protocol"," not recognised",[1199,3241,3242,3247,3249],{},[1214,3243,3244],{},[978,3245,3246],{},"FDL060",[1214,3248,2363],{},[1214,3250,3251],{},"Action field has invalid type",[1199,3253,3254,3259,3261],{},[1214,3255,3256],{},[978,3257,3258],{},"FDL061",[1214,3260,2363],{},[1214,3262,3263,3264,3239],{},"Action ",[978,3265,3193],{},[1199,3267,3268,3273,3275],{},[1214,3269,3270],{},[978,3271,3272],{},"FDL062",[1214,3274,2363],{},[1214,3276,3263,3277,3179],{},[978,3278,3279],{},"emits",[1082,3281,3283,3286],{"id":3282},"modfile-module-file-io",[978,3284,3285],{},"modfile"," — Module file I\u002FO",[974,3288,3289,3290,3293,3294,3297],{},"Loads, saves, and exports ",[978,3291,3292],{},"ir.Module"," and ",[978,3295,3296],{},"ir.Document"," values as YAML or JSON.",[1032,3299,3301],{"className":1094,"code":3300,"language":1059,"meta":1040,"style":1040},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fmodfile\"\n\n\u002F\u002F Load a module from any reader — DetectFormat infers YAML\u002FJSON from filename.\nm, err := modfile.LoadModule(r, modfile.DetectFormat(filename))\n\n\u002F\u002F Save a module.\nerr = modfile.SaveModule(m, w, modfile.FormatYAML)\n\n\u002F\u002F Save a full document.\nerr = modfile.SaveDocument(doc, w, modfile.FormatYAML)\n",[978,3302,3303,3308,3312,3317,3322,3326,3331,3336,3340,3345],{"__ignoreMap":1040},[1053,3304,3305],{"class":1055,"line":10},[1053,3306,3307],{},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fmodfile\"\n",[1053,3309,3310],{"class":1055,"line":16},[1053,3311,1108],{"emptyLinePlaceholder":1107},[1053,3313,3314],{"class":1055,"line":22},[1053,3315,3316],{},"\u002F\u002F Load a module from any reader — DetectFormat infers YAML\u002FJSON from filename.\n",[1053,3318,3319],{"class":1055,"line":51},[1053,3320,3321],{},"m, err := modfile.LoadModule(r, modfile.DetectFormat(filename))\n",[1053,3323,3324],{"class":1055,"line":57},[1053,3325,1108],{"emptyLinePlaceholder":1107},[1053,3327,3328],{"class":1055,"line":102},[1053,3329,3330],{},"\u002F\u002F Save a module.\n",[1053,3332,3333],{"class":1055,"line":108},[1053,3334,3335],{},"err = modfile.SaveModule(m, w, modfile.FormatYAML)\n",[1053,3337,3338],{"class":1055,"line":114},[1053,3339,1108],{"emptyLinePlaceholder":1107},[1053,3341,3342],{"class":1055,"line":120},[1053,3343,3344],{},"\u002F\u002F Save a full document.\n",[1053,3346,3347],{"class":1055,"line":181},[1053,3348,3349],{},"err = modfile.SaveDocument(doc, w, modfile.FormatYAML)\n",[1082,3351,3353,3356],{"id":3352},"modgen-go-module-scaffolder",[978,3354,3355],{},"modgen"," — Go module scaffolder",[974,3358,3359,3360,3362,3363,1268,3366,3369,3370,3373],{},"Generates Go source file stubs from an ",[978,3361,3292],{},". Produces ",[978,3364,3365],{},"module.go",[978,3367,3368],{},"schemas.go",", and\n",[978,3371,3372],{},"handler.go"," ready for business logic implementation. Existing files are not overwritten.",[1032,3375,3377],{"className":1094,"code":3376,"language":1059,"meta":1040,"style":1040},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fmodgen\"\n\nresult, err := modgen.Scaffold(m, modgen.Options{OutputDir: \".\u002Fmodules\u002Forders\"})\nfor _, path := range result.Files {\n    fmt.Println(\"wrote\", path)\n}\n",[978,3378,3379,3384,3388,3393,3398,3403],{"__ignoreMap":1040},[1053,3380,3381],{"class":1055,"line":10},[1053,3382,3383],{},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fmodgen\"\n",[1053,3385,3386],{"class":1055,"line":16},[1053,3387,1108],{"emptyLinePlaceholder":1107},[1053,3389,3390],{"class":1055,"line":22},[1053,3391,3392],{},"result, err := modgen.Scaffold(m, modgen.Options{OutputDir: \".\u002Fmodules\u002Forders\"})\n",[1053,3394,3395],{"class":1055,"line":51},[1053,3396,3397],{},"for _, path := range result.Files {\n",[1053,3399,3400],{"class":1055,"line":57},[1053,3401,3402],{},"    fmt.Println(\"wrote\", path)\n",[1053,3404,3405],{"class":1055,"line":102},[1053,3406,1637],{},[1082,3408,3410,3413],{"id":3409},"nodegen-flowdsl-node-generator",[978,3411,3412],{},"nodegen"," — FlowDSL node generator",[974,3415,3416,3417,3419,3420,3422],{},"Generates FlowDSL node manifests (",[978,3418,1515],{},") and Go handler scaffolds from\n",[978,3421,3292],{}," definitions. Inspects events, actions, commands, and workflows to produce\nappropriate node definitions.",[1032,3424,3426],{"className":1094,"code":3425,"language":1059,"meta":1040,"style":1040},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fnodegen\"\n\nresult, err := nodegen.FromIRModule(m, nodegen.Options{\n    Namespace:   \"myapp\",\n    GoModule:    \"github.com\u002Fmyorg\u002Fmyapp\",\n    GoPackage:   \"nodes\",\n    OutputDir:   \".\u002Fnodes\u002F\",\n    ManifestDir: \".\u002Fnodes\u002Fmanifests\u002F\",\n})\nfor _, path := range result.Manifests {\n    fmt.Println(\"manifest:\", path)\n}\nfor _, path := range result.Handlers {\n    fmt.Println(\"handler:\", path)\n}\n",[978,3427,3428,3433,3437,3442,3447,3452,3457,3462,3467,3472,3477,3482,3486,3491,3496],{"__ignoreMap":1040},[1053,3429,3430],{"class":1055,"line":10},[1053,3431,3432],{},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fnodegen\"\n",[1053,3434,3435],{"class":1055,"line":16},[1053,3436,1108],{"emptyLinePlaceholder":1107},[1053,3438,3439],{"class":1055,"line":22},[1053,3440,3441],{},"result, err := nodegen.FromIRModule(m, nodegen.Options{\n",[1053,3443,3444],{"class":1055,"line":51},[1053,3445,3446],{},"    Namespace:   \"myapp\",\n",[1053,3448,3449],{"class":1055,"line":57},[1053,3450,3451],{},"    GoModule:    \"github.com\u002Fmyorg\u002Fmyapp\",\n",[1053,3453,3454],{"class":1055,"line":102},[1053,3455,3456],{},"    GoPackage:   \"nodes\",\n",[1053,3458,3459],{"class":1055,"line":108},[1053,3460,3461],{},"    OutputDir:   \".\u002Fnodes\u002F\",\n",[1053,3463,3464],{"class":1055,"line":114},[1053,3465,3466],{},"    ManifestDir: \".\u002Fnodes\u002Fmanifests\u002F\",\n",[1053,3468,3469],{"class":1055,"line":120},[1053,3470,3471],{},"})\n",[1053,3473,3474],{"class":1055,"line":181},[1053,3475,3476],{},"for _, path := range result.Manifests {\n",[1053,3478,3479],{"class":1055,"line":186},[1053,3480,3481],{},"    fmt.Println(\"manifest:\", path)\n",[1053,3483,3484],{"class":1055,"line":191},[1053,3485,1637],{},[1053,3487,3488],{"class":1055,"line":197},[1053,3489,3490],{},"for _, path := range result.Handlers {\n",[1053,3492,3493],{"class":1055,"line":203},[1053,3494,3495],{},"    fmt.Println(\"handler:\", path)\n",[1053,3497,3498],{"class":1055,"line":214},[1053,3499,1637],{},[974,3501,3502],{},[989,3503,3504],{},"Generated output per module:",[1193,3506,3507,3516],{},[1196,3508,3509],{},[1199,3510,3511,3513],{},[1202,3512,2012],{},[1202,3514,3515],{},"Contents",[1209,3517,3518,3528,3542],{},[1199,3519,3520,3525],{},[1214,3521,3522],{},[978,3523,3524],{},"manifests\u002F\u003Cslug>.flowdsl-node.json",[1214,3526,3527],{},"Node manifest for each event, action, command, and workflow",[1199,3529,3530,3535],{},[1214,3531,3532],{},[978,3533,3534],{},"nodes_generated.go",[1214,3536,3537,3538,3541],{},"Go handler stubs implementing ",[978,3539,3540],{},"node.NodeHandler"," interface",[1199,3543,3544,3549],{},[1214,3545,3546],{},[978,3547,3548],{},"nodes_registry.go",[1214,3550,3551,3554,3555,3558],{},[978,3552,3553],{},"FlowDSLNodes()"," function returning ",[978,3556,3557],{},"[]*ir.FlowDSLNode"," for module wiring",[974,3560,3561],{},[989,3562,3563],{},"Node generation rules:",[1193,3565,3566,3579],{},[1196,3567,3568],{},[1199,3569,3570,3573,3576],{},[1202,3571,3572],{},"IR element",[1202,3574,3575],{},"Node kind",[1202,3577,3578],{},"Notes",[1209,3580,3581,3595,3616,3629],{},[1199,3582,3583,3587,3592],{},[1214,3584,3585],{},[978,3586,1311],{},[1214,3588,3589],{},[978,3590,3591],{},"source",[1214,3593,3594],{},"One output port named after the event",[1199,3596,3597,3601,3608],{},[1214,3598,3599],{},[978,3600,1341],{},[1214,3602,3603,1866,3605],{},[978,3604,3096],{},[978,3606,3607],{},"transform",[1214,3609,3610,3611,3613,3614],{},"Queries become ",[978,3612,3607],{},"; mutations become ",[978,3615,3096],{},[1199,3617,3618,3622,3626],{},[1214,3619,3620],{},[978,3621,1321],{},[1214,3623,3624],{},[978,3625,3096],{},[1214,3627,3628],{},"Input\u002Foutput ports",[1199,3630,3631,3635,3640],{},[1214,3632,3633],{},[978,3634,1351],{},[1214,3636,3637],{},[978,3638,3639],{},"subworkflow",[1214,3641,3642,3643],{},"Ports derived via ",[978,3644,1801],{},[974,3646,3647,3650],{},[978,3648,3649],{},"FromFlowDocument"," additionally extracts nodes from workflow step graphs in a FlowDSL document.",[1082,3652,3654,3657],{"id":3653},"modsvg-svg-diagram-generator",[978,3655,3656],{},"modsvg"," — SVG diagram generator",[974,3659,3660,3661,3663,3664,3667],{},"Generates an SVG visual diagram from an ",[978,3662,3292],{}," showing entities, events, config, CRUD,\nsettings, commands, queries, workflows, schedules, consumers, dependencies, and provides.\nSupports dark mode via ",[978,3665,3666],{},"prefers-color-scheme"," CSS media query.",[1032,3669,3671],{"className":1094,"code":3670,"language":1059,"meta":1040,"style":1040},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fmodsvg\"\n\nerr := modsvg.Generate(w, m) \u002F\u002F io.Writer, *ir.Module\n",[978,3672,3673,3678,3682],{"__ignoreMap":1040},[1053,3674,3675],{"class":1055,"line":10},[1053,3676,3677],{},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fmodsvg\"\n",[1053,3679,3680],{"class":1055,"line":16},[1053,3681,1108],{"emptyLinePlaceholder":1107},[1053,3683,3684],{"class":1055,"line":22},[1053,3685,3686],{},"err := modsvg.Generate(w, m) \u002F\u002F io.Writer, *ir.Module\n",[1082,3688,3690,3693],{"id":3689},"modsync-drift-detection",[978,3691,3692],{},"modsync"," — Drift detection",[974,3695,3696],{},"Compares a declared IR module against another (e.g. a runtime export) and reports structural\ndrift.",[1032,3698,3700],{"className":1094,"code":3699,"language":1059,"meta":1040,"style":1040},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fmodsync\"\n\nreport := modsync.Compare(declared, actual) \u002F\u002F both *ir.Module\nfor _, diff := range report.Diffs {\n    fmt.Printf(\"[%s] %s: %s\\n\", diff.Kind, diff.Path, diff.Message)\n}\n",[978,3701,3702,3707,3711,3716,3721,3726],{"__ignoreMap":1040},[1053,3703,3704],{"class":1055,"line":10},[1053,3705,3706],{},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fmodsync\"\n",[1053,3708,3709],{"class":1055,"line":16},[1053,3710,1108],{"emptyLinePlaceholder":1107},[1053,3712,3713],{"class":1055,"line":22},[1053,3714,3715],{},"report := modsync.Compare(declared, actual) \u002F\u002F both *ir.Module\n",[1053,3717,3718],{"class":1055,"line":51},[1053,3719,3720],{},"for _, diff := range report.Diffs {\n",[1053,3722,3723],{"class":1055,"line":57},[1053,3724,3725],{},"    fmt.Printf(\"[%s] %s: %s\\n\", diff.Kind, diff.Path, diff.Message)\n",[1053,3727,3728],{"class":1055,"line":102},[1053,3729,1637],{},[974,3731,3732,3733,1268,3736,1268,3739,1921],{},"Diff kinds: ",[978,3734,3735],{},"added",[978,3737,3738],{},"removed",[978,3740,3741],{},"changed",[1082,3743,3745,3748],{"id":3744},"modval-module-yaml-validator",[978,3746,3747],{},"modval"," — Module YAML validator",[974,3750,3751,3752,3754,3755,1921],{},"Validates naming conventions, reference integrity, and structural rules for ",[978,3753,3292],{},"\nfiles — the same checks run by ",[978,3756,3757],{},"redelayctl validate-module",[1032,3759,3761],{"className":1094,"code":3760,"language":1059,"meta":1040,"style":1040},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fmodval\"\n\ndiag := modval.Validate(m) \u002F\u002F *ir.Module → *diagnostics.Collector\n",[978,3762,3763,3768,3772],{"__ignoreMap":1040},[1053,3764,3765],{"class":1055,"line":10},[1053,3766,3767],{},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fmodval\"\n",[1053,3769,3770],{"class":1055,"line":16},[1053,3771,1108],{"emptyLinePlaceholder":1107},[1053,3773,3774],{"class":1055,"line":22},[1053,3775,3776],{},"diag := modval.Validate(m) \u002F\u002F *ir.Module → *diagnostics.Collector\n",[974,3778,3779,3780,3783,3784,3787],{},"Rules include: required fields (ID, name), semver version, entity IDs prefixed with module\nID, event names containing a dot separator, config keys ",[978,3781,3782],{},"UPPER_SNAKE_CASE",", settings keys\n",[978,3785,3786],{},"lower_snake_case",", CRUD entity refs match declared entities, no duplicate IDs, no\nself-dependencies.",[1082,3789,3791,3794],{"id":3790},"compile-base-compile-pipeline",[978,3792,3793],{},"compile"," — Base compile pipeline",[974,3796,3797,3798,3293,3800,3802,3803,3293,3806,3809,3810,3813,3814,1921],{},"Plugin-based compilation pipeline. Built-in importers handle ",[978,3799,2483],{},[978,3801,2152],{},".\n",[978,3804,3805],{},"go-framework\u002Fcore\u002Fasyncapi",[978,3807,3808],{},"go-framework\u002Fcore\u002Fopenapi"," register additional importers\nand exporters via ",[978,3811,3812],{},"RegisterImporter","\u002F",[978,3815,3816],{},"RegisterExporter",[1032,3818,3820],{"className":1094,"code":3819,"language":1059,"meta":1040,"style":1040},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fcompile\"\n\n\u002F\u002F Register a custom importer (done by go-framework core packages at init time).\ncompile.RegisterImporter(\"asyncapi\", myAsyncAPIImporter)\ncompile.RegisterExporter(\"openapi\", myOpenAPIExporter)\n\n\u002F\u002F Import a source format into IR.\ndoc, err := compile.Import(compile.FormatFlowDSL, r)\n\n\u002F\u002F Validate + resolve + enrich.\nresult := compile.Compile(doc)\nresult.Document    \u002F\u002F *ir.Document — enriched\nresult.Diagnostics \u002F\u002F *diagnostics.Collector\nresult.Modules     \u002F\u002F []*ir.Module in dependency order\nresult.HasErrors() \u002F\u002F bool\n\n\u002F\u002F One-step import + compile.\nresult, err = compile.ImportAndCompile(compile.FormatFlowDSL, r)\n\n\u002F\u002F Export to a format.\nerr = compile.Export(doc, compile.FormatFlowDSL, w)\n",[978,3821,3822,3827,3831,3836,3841,3846,3850,3855,3860,3864,3869,3874,3879,3884,3889,3894,3898,3903,3908,3912,3917],{"__ignoreMap":1040},[1053,3823,3824],{"class":1055,"line":10},[1053,3825,3826],{},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fcompile\"\n",[1053,3828,3829],{"class":1055,"line":16},[1053,3830,1108],{"emptyLinePlaceholder":1107},[1053,3832,3833],{"class":1055,"line":22},[1053,3834,3835],{},"\u002F\u002F Register a custom importer (done by go-framework core packages at init time).\n",[1053,3837,3838],{"class":1055,"line":51},[1053,3839,3840],{},"compile.RegisterImporter(\"asyncapi\", myAsyncAPIImporter)\n",[1053,3842,3843],{"class":1055,"line":57},[1053,3844,3845],{},"compile.RegisterExporter(\"openapi\", myOpenAPIExporter)\n",[1053,3847,3848],{"class":1055,"line":102},[1053,3849,1108],{"emptyLinePlaceholder":1107},[1053,3851,3852],{"class":1055,"line":108},[1053,3853,3854],{},"\u002F\u002F Import a source format into IR.\n",[1053,3856,3857],{"class":1055,"line":114},[1053,3858,3859],{},"doc, err := compile.Import(compile.FormatFlowDSL, r)\n",[1053,3861,3862],{"class":1055,"line":120},[1053,3863,1108],{"emptyLinePlaceholder":1107},[1053,3865,3866],{"class":1055,"line":181},[1053,3867,3868],{},"\u002F\u002F Validate + resolve + enrich.\n",[1053,3870,3871],{"class":1055,"line":186},[1053,3872,3873],{},"result := compile.Compile(doc)\n",[1053,3875,3876],{"class":1055,"line":191},[1053,3877,3878],{},"result.Document    \u002F\u002F *ir.Document — enriched\n",[1053,3880,3881],{"class":1055,"line":197},[1053,3882,3883],{},"result.Diagnostics \u002F\u002F *diagnostics.Collector\n",[1053,3885,3886],{"class":1055,"line":203},[1053,3887,3888],{},"result.Modules     \u002F\u002F []*ir.Module in dependency order\n",[1053,3890,3891],{"class":1055,"line":214},[1053,3892,3893],{},"result.HasErrors() \u002F\u002F bool\n",[1053,3895,3896],{"class":1055,"line":223},[1053,3897,1108],{"emptyLinePlaceholder":1107},[1053,3899,3900],{"class":1055,"line":229},[1053,3901,3902],{},"\u002F\u002F One-step import + compile.\n",[1053,3904,3905],{"class":1055,"line":234},[1053,3906,3907],{},"result, err = compile.ImportAndCompile(compile.FormatFlowDSL, r)\n",[1053,3909,3910],{"class":1055,"line":240},[1053,3911,1108],{"emptyLinePlaceholder":1107},[1053,3913,3914],{"class":1055,"line":246},[1053,3915,3916],{},"\u002F\u002F Export to a format.\n",[1053,3918,3919],{"class":1055,"line":251},[1053,3920,3921],{},"err = compile.Export(doc, compile.FormatFlowDSL, w)\n",[974,3923,3924],{},[989,3925,3926],{},"Built-in format constants:",[1193,3928,3929,3945],{},[1196,3930,3931],{},[1199,3932,3933,3936,3939,3942],{},[1202,3934,3935],{},"Constant",[1202,3937,3938],{},"Value",[1202,3940,3941],{},"Import",[1202,3943,3944],{},"Export",[1209,3946,3947,3964],{},[1199,3948,3949,3954,3959,3962],{},[1214,3950,3951],{},[978,3952,3953],{},"compile.FormatFlowDSL",[1214,3955,3956],{},[978,3957,3958],{},"\"flowdsl\"",[1214,3960,3961],{},"yes",[1214,3963,3961],{},[1199,3965,3966,3971,3976,3978],{},[1214,3967,3968],{},[978,3969,3970],{},"compile.FormatBusinessModel",[1214,3972,3973],{},[978,3974,3975],{},"\"businessmodel\"",[1214,3977,3961],{},[1214,3979,3980],{},"—",[974,3982,3983,3984,1268,3987,3990],{},"Additional formats (",[978,3985,3986],{},"asyncapi",[978,3988,3989],{},"openapi",") are registered by go-framework packages.",[974,3992,3993],{},[989,3994,3995],{},"Compilation stages:",[3997,3998,3999,4005,4011],"ol",{},[1845,4000,4001,4004],{},[989,4002,4003],{},"Validate"," — structural correctness (IDs, references, module naming conventions)",[1845,4006,4007,4010],{},[989,4008,4009],{},"Resolve"," — topological sort of modules by dependencies (Kahn's algorithm)",[1845,4012,4013,4016,4017],{},[989,4014,4015],{},"Enrich"," — promote module-level entities\u002Fevents\u002Factions\u002Fworkflows to document level; warn on unresolved ",[978,4018,4019],{},"provides",[1082,4021,4023,4026],{"id":4022},"runtime-flow-execution-engine",[978,4024,4025],{},"runtime"," — Flow execution engine",[974,4028,4029,4030,4033,4034,4037],{},"Executes FlowDSL workflows. Nodes are dispatched to registered ",[978,4031,4032],{},"NodeHandler"," functions by\nnode ID, node name, or kind. Execution state can be persisted via a ",[978,4035,4036],{},"Checkpoint","\nimplementation for resumable long-running runs.",[1502,4039,4041],{"id":4040},"nodehandler",[978,4042,4032],{},[1032,4044,4046],{"className":1094,"code":4045,"language":1059,"meta":1040,"style":1040},"type NodeHandler func(ctx context.Context, step *Step) error\n",[978,4047,4048],{"__ignoreMap":1040},[1053,4049,4050],{"class":1055,"line":10},[1053,4051,4045],{},[974,4053,4054],{},"This is a plain function type — not an interface.",[1502,4056,4058],{"id":4057},"step",[978,4059,4060],{},"Step",[974,4062,4063,4064,1676],{},"Per-node execution context passed to every ",[978,4065,4032],{},[1032,4067,4069],{"className":1094,"code":4068,"language":1059,"meta":1040,"style":1040},"type Step struct {\n    Node        *ir.Node       \u002F\u002F IR definition of the current node\n    Workflow    *ir.Workflow   \u002F\u002F IR definition of the owning workflow\n    ExecutionID string         \u002F\u002F unique run ID\n    Attempt     int            \u002F\u002F 1-based attempt count (1 on first try)\n    Input       map[string]any \u002F\u002F data from the previous step or trigger\n    Output      map[string]any \u002F\u002F written by the handler; passed to the next step\n}\n",[978,4070,4071,4076,4081,4086,4091,4096,4101,4106],{"__ignoreMap":1040},[1053,4072,4073],{"class":1055,"line":10},[1053,4074,4075],{},"type Step struct {\n",[1053,4077,4078],{"class":1055,"line":16},[1053,4079,4080],{},"    Node        *ir.Node       \u002F\u002F IR definition of the current node\n",[1053,4082,4083],{"class":1055,"line":22},[1053,4084,4085],{},"    Workflow    *ir.Workflow   \u002F\u002F IR definition of the owning workflow\n",[1053,4087,4088],{"class":1055,"line":51},[1053,4089,4090],{},"    ExecutionID string         \u002F\u002F unique run ID\n",[1053,4092,4093],{"class":1055,"line":57},[1053,4094,4095],{},"    Attempt     int            \u002F\u002F 1-based attempt count (1 on first try)\n",[1053,4097,4098],{"class":1055,"line":102},[1053,4099,4100],{},"    Input       map[string]any \u002F\u002F data from the previous step or trigger\n",[1053,4102,4103],{"class":1055,"line":108},[1053,4104,4105],{},"    Output      map[string]any \u002F\u002F written by the handler; passed to the next step\n",[1053,4107,4108],{"class":1055,"line":114},[1053,4109,1637],{},[1502,4111,4113,4114,4117,4118,4121],{"id":4112},"node-io-binding-inputmap-outputmap","Node I\u002FO binding (",[978,4115,4116],{},"$inputMap"," \u002F ",[978,4119,4120],{},"$outputMap",")",[974,4123,4124,4125,4128,4129,4132,4133,4136,4137,4140,4141,1676],{},"The runtime is an ",[989,4126,4127],{},"accumulating-packet"," model: each node's ",[978,4130,4131],{},"Input"," is the\nprevious node's whole ",[978,4134,4135],{},"Output",", and edges route but never transform. To reuse a\ngeneric node in a flow whose packet uses different field names — without editing\nthe node — set two ",[989,4138,4139],{},"reserved keys"," in the node's ",[978,4142,4143],{},"Config",[1032,4145,4147],{"className":1679,"code":4146,"language":1681,"meta":1040,"style":1040},"config:\n  $inputMap:  { address: \"customer.shipping_address\" }   # node field ← packet path\n  $outputMap: { Valid: \"shipping_valid\" }                # node output → flow key\n",[978,4148,4149,4156,4186],{"__ignoreMap":1040},[1053,4150,4151,4154],{"class":1055,"line":10},[1053,4152,4153],{"class":1688},"config",[1053,4155,1693],{"class":1692},[1053,4157,4158,4161,4163,4166,4169,4171,4173,4176,4179,4182],{"class":1055,"line":16},[1053,4159,4160],{"class":1688},"  $inputMap",[1053,4162,1676],{"class":1692},[1053,4164,4165],{"class":1692},"  {",[1053,4167,4168],{"class":1688}," address",[1053,4170,1676],{"class":1692},[1053,4172,2541],{"class":1692},[1053,4174,4175],{"class":1062},"customer.shipping_address",[1053,4177,4178],{"class":1692},"\"",[1053,4180,4181],{"class":1692}," }",[1053,4183,4185],{"class":4184},"sHwdD","   # node field ← packet path\n",[1053,4187,4188,4191,4193,4195,4198,4200,4202,4205,4207,4209],{"class":1055,"line":22},[1053,4189,4190],{"class":1688},"  $outputMap",[1053,4192,1676],{"class":1692},[1053,4194,2659],{"class":1692},[1053,4196,4197],{"class":1688}," Valid",[1053,4199,1676],{"class":1692},[1053,4201,2541],{"class":1692},[1053,4203,4204],{"class":1062},"shipping_valid",[1053,4206,4178],{"class":1692},[1053,4208,4181],{"class":1692},[1053,4210,4211],{"class":4184},"                # node output → flow key\n",[974,4213,4214,4215,4217,4218,4221,4222,4224,4225,4228,4229,4232,4233,4236,4237,1011,4240,4243,4244,4247],{},"Before the handler runs, ",[978,4216,4116],{}," pre-populates ",[978,4219,4220],{},"step.Input[\"address\"]"," from\nthe dotted path (additive — the passthrough packet is untouched). After it runs,\n",[978,4223,4120],{}," copies ",[978,4226,4227],{},"step.Output[\"Valid\"]"," to ",[978,4230,4231],{},"step.Output[\"shipping_valid\"]","\n(non-destructive). Both are no-ops when absent, so existing flows are\nunaffected; there is no ",[978,4234,4235],{},"ir.Node"," struct change. Applied in both ",[978,4238,4239],{},"Start",[978,4241,4242],{},"Resume",". In Flow Studio these are edited via the Inspector's ",[989,4245,4246],{},"I\u002FO Binding","\nsection.",[1502,4249,4251],{"id":4250},"retrypolicy",[978,4252,4253],{},"RetryPolicy",[1032,4255,4257],{"className":1094,"code":4256,"language":1059,"meta":1040,"style":1040},"type RetryPolicy struct {\n    MaxAttempts   int           \u002F\u002F 1 = no retries (default)\n    InitialDelay  time.Duration\n    BackoffFactor float64       \u002F\u002F 2.0 = exponential doubling\n    MaxDelay      time.Duration \u002F\u002F caps delay between retries\n}\n",[978,4258,4259,4264,4269,4274,4279,4284],{"__ignoreMap":1040},[1053,4260,4261],{"class":1055,"line":10},[1053,4262,4263],{},"type RetryPolicy struct {\n",[1053,4265,4266],{"class":1055,"line":16},[1053,4267,4268],{},"    MaxAttempts   int           \u002F\u002F 1 = no retries (default)\n",[1053,4270,4271],{"class":1055,"line":22},[1053,4272,4273],{},"    InitialDelay  time.Duration\n",[1053,4275,4276],{"class":1055,"line":51},[1053,4277,4278],{},"    BackoffFactor float64       \u002F\u002F 2.0 = exponential doubling\n",[1053,4280,4281],{"class":1055,"line":57},[1053,4282,4283],{},"    MaxDelay      time.Duration \u002F\u002F caps delay between retries\n",[1053,4285,4286],{"class":1055,"line":102},[1053,4287,1637],{},[974,4289,4290,1647,4293,1921],{},[978,4291,4292],{},"DefaultRetryPolicy",[978,4294,4295],{},"RetryPolicy{MaxAttempts: 1}",[1502,4297,4299,3541],{"id":4298},"checkpoint-interface",[978,4300,4036],{},[1032,4302,4304],{"className":1094,"code":4303,"language":1059,"meta":1040,"style":1040},"type Checkpoint interface {\n    Save(ctx context.Context, exec *ExecutionRecord) error\n    Load(ctx context.Context, executionID string) (*ExecutionRecord, error)\n    SaveStep(ctx context.Context, step *StepRecord) error\n}\n",[978,4305,4306,4311,4316,4321,4326],{"__ignoreMap":1040},[1053,4307,4308],{"class":1055,"line":10},[1053,4309,4310],{},"type Checkpoint interface {\n",[1053,4312,4313],{"class":1055,"line":16},[1053,4314,4315],{},"    Save(ctx context.Context, exec *ExecutionRecord) error\n",[1053,4317,4318],{"class":1055,"line":22},[1053,4319,4320],{},"    Load(ctx context.Context, executionID string) (*ExecutionRecord, error)\n",[1053,4322,4323],{"class":1055,"line":51},[1053,4324,4325],{},"    SaveStep(ctx context.Context, step *StepRecord) error\n",[1053,4327,4328],{"class":1055,"line":57},[1053,4329,1637],{},[974,4331,4332,4335,4336,4339],{},[978,4333,4334],{},"MemoryCheckpoint"," is the built-in in-process implementation used by default when\n",[978,4337,4338],{},"EngineConfig.Checkpoint"," is nil.",[1502,4341,4343,3293,4346],{"id":4342},"executionrecord-and-steprecord",[978,4344,4345],{},"ExecutionRecord",[978,4347,4348],{},"StepRecord",[974,4350,4351,4353,4354,2013,4357,1268,4360,1268,4363,1268,4365,1268,4367,1268,4370,4373],{},[978,4352,4345],{}," is the top-level persisted record for a workflow run. It contains an ",[978,4355,4356],{},"ID",[978,4358,4359],{},"WorkflowID",[978,4361,4362],{},"Status",[978,4364,4131],{},[978,4366,4135],{},[978,4368,4369],{},"Error",[978,4371,4372],{},"Steps []*StepRecord",", and timestamps.",[974,4375,4376,4378,4379,1268,4382,1268,4385,1268,4388,2013,4390,1268,4393,1268,4395,1268,4397,1268,4399,1268,4402,1921],{},[978,4377,4348],{}," records one node's execution: ",[978,4380,4381],{},"ExecutionID",[978,4383,4384],{},"NodeID",[978,4386,4387],{},"NodeName",[978,4389,4362],{},[978,4391,4392],{},"Attempt",[978,4394,4131],{},[978,4396,4135],{},[978,4398,4369],{},[978,4400,4401],{},"StartedAt",[978,4403,4404],{},"CompletedAt",[974,4406,4407,4408,1268,4411,1268,4414,1268,4417,1268,4420,1268,4423,1921],{},"Status values: ",[978,4409,4410],{},"pending",[978,4412,4413],{},"running",[978,4415,4416],{},"completed",[978,4418,4419],{},"failed",[978,4421,4422],{},"retrying",[978,4424,4425],{},"skipped",[1502,4427,4429],{"id":4428},"engine-api","Engine API",[1032,4431,4433],{"className":1094,"code":4432,"language":1059,"meta":1040,"style":1040},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fruntime\"\n\n\u002F\u002F Create engine — MemoryCheckpoint used when no Checkpoint is supplied.\neng := runtime.NewEngine(runtime.EngineConfig{})\n\n\u002F\u002F Register a handler for a specific node ID or name.\neng.RegisterHandler(\"validate_payment\", func(ctx context.Context, step *runtime.Step) error {\n    step.Output[\"valid\"] = true\n    return nil\n})\n\n\u002F\u002F Register a fallback handler for all nodes of a given kind.\neng.RegisterKindHandler(ir.NodeKindAction, fallbackHandler)\n\n\u002F\u002F Set a per-node retry policy (keyed by node ID or name).\neng.SetRetryPolicy(\"charge_card\", runtime.RetryPolicy{\n    MaxAttempts:   3,\n    InitialDelay:  2 * time.Second,\n    BackoffFactor: 2.0,\n    MaxDelay:      30 * time.Second,\n})\n\n\u002F\u002F Start a workflow. Runs synchronously — call in a goroutine for non-blocking behaviour.\nexec, err := eng.Start(ctx, wf, map[string]any{\"user_id\": \"abc\"})\n\u002F\u002F exec.Status — completed or failed\n\u002F\u002F exec.Output — output from the last node\n\n\u002F\u002F Resume a previously started execution, skipping already-completed steps.\nexec, err = eng.Resume(ctx, wf, exec.ID)\n",[978,4434,4435,4440,4444,4449,4454,4458,4463,4468,4473,4478,4482,4486,4491,4496,4500,4505,4510,4515,4520,4525,4530,4534,4538,4543,4548,4553,4558,4562,4567],{"__ignoreMap":1040},[1053,4436,4437],{"class":1055,"line":10},[1053,4438,4439],{},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fruntime\"\n",[1053,4441,4442],{"class":1055,"line":16},[1053,4443,1108],{"emptyLinePlaceholder":1107},[1053,4445,4446],{"class":1055,"line":22},[1053,4447,4448],{},"\u002F\u002F Create engine — MemoryCheckpoint used when no Checkpoint is supplied.\n",[1053,4450,4451],{"class":1055,"line":51},[1053,4452,4453],{},"eng := runtime.NewEngine(runtime.EngineConfig{})\n",[1053,4455,4456],{"class":1055,"line":57},[1053,4457,1108],{"emptyLinePlaceholder":1107},[1053,4459,4460],{"class":1055,"line":102},[1053,4461,4462],{},"\u002F\u002F Register a handler for a specific node ID or name.\n",[1053,4464,4465],{"class":1055,"line":108},[1053,4466,4467],{},"eng.RegisterHandler(\"validate_payment\", func(ctx context.Context, step *runtime.Step) error {\n",[1053,4469,4470],{"class":1055,"line":114},[1053,4471,4472],{},"    step.Output[\"valid\"] = true\n",[1053,4474,4475],{"class":1055,"line":120},[1053,4476,4477],{},"    return nil\n",[1053,4479,4480],{"class":1055,"line":181},[1053,4481,3471],{},[1053,4483,4484],{"class":1055,"line":186},[1053,4485,1108],{"emptyLinePlaceholder":1107},[1053,4487,4488],{"class":1055,"line":191},[1053,4489,4490],{},"\u002F\u002F Register a fallback handler for all nodes of a given kind.\n",[1053,4492,4493],{"class":1055,"line":197},[1053,4494,4495],{},"eng.RegisterKindHandler(ir.NodeKindAction, fallbackHandler)\n",[1053,4497,4498],{"class":1055,"line":203},[1053,4499,1108],{"emptyLinePlaceholder":1107},[1053,4501,4502],{"class":1055,"line":214},[1053,4503,4504],{},"\u002F\u002F Set a per-node retry policy (keyed by node ID or name).\n",[1053,4506,4507],{"class":1055,"line":223},[1053,4508,4509],{},"eng.SetRetryPolicy(\"charge_card\", runtime.RetryPolicy{\n",[1053,4511,4512],{"class":1055,"line":229},[1053,4513,4514],{},"    MaxAttempts:   3,\n",[1053,4516,4517],{"class":1055,"line":234},[1053,4518,4519],{},"    InitialDelay:  2 * time.Second,\n",[1053,4521,4522],{"class":1055,"line":240},[1053,4523,4524],{},"    BackoffFactor: 2.0,\n",[1053,4526,4527],{"class":1055,"line":246},[1053,4528,4529],{},"    MaxDelay:      30 * time.Second,\n",[1053,4531,4532],{"class":1055,"line":251},[1053,4533,3471],{},[1053,4535,4536],{"class":1055,"line":257},[1053,4537,1108],{"emptyLinePlaceholder":1107},[1053,4539,4540],{"class":1055,"line":1634},[1053,4541,4542],{},"\u002F\u002F Start a workflow. Runs synchronously — call in a goroutine for non-blocking behaviour.\n",[1053,4544,4545],{"class":1055,"line":2787},[1053,4546,4547],{},"exec, err := eng.Start(ctx, wf, map[string]any{\"user_id\": \"abc\"})\n",[1053,4549,4550],{"class":1055,"line":271},[1053,4551,4552],{},"\u002F\u002F exec.Status — completed or failed\n",[1053,4554,4555],{"class":1055,"line":277},[1053,4556,4557],{},"\u002F\u002F exec.Output — output from the last node\n",[1053,4559,4560],{"class":1055,"line":282},[1053,4561,1108],{"emptyLinePlaceholder":1107},[1053,4563,4564],{"class":1055,"line":2824},[1053,4565,4566],{},"\u002F\u002F Resume a previously started execution, skipping already-completed steps.\n",[1053,4568,4569],{"class":1055,"line":2832},[1053,4570,4571],{},"exec, err = eng.Resume(ctx, wf, exec.ID)\n",[974,4573,4574,4575,4578,4579,1866,4581,4583],{},"Handler resolution order for a node: node ID → node name → node ",[978,4576,4577],{},"ActionRef"," → kind fallback.\nAn on-error edge (edge with ",[978,4580,1865],{},[978,4582,1869],{},") routes execution to an\nerror-handling node instead of aborting the workflow.",[1502,4585,4587,4590],{"id":4586},"stepobserver-real-time-step-lifecycle-hooks",[978,4588,4589],{},"StepObserver"," — real-time step lifecycle hooks",[974,4592,4593,4594,4596,4597,4600,4601,4604,4605,4608,4609,4612],{},"A ",[978,4595,4589],{}," receives step events ",[989,4598,4599],{},"inline with handler execution",", not in a\npost-run batch. Observers are the hook ",[978,4602,4603],{},"flowexec"," uses to emit ",[978,4606,4607],{},"node.started"," \u002F\n",[978,4610,4611],{},"node.done"," events with true wall-clock timestamps while the workflow is still\nrunning.",[1032,4614,4616],{"className":1094,"code":4615,"language":1059,"meta":1040,"style":1040},"type StepEventKind string\n\nconst (\n    StepEventStarted StepEventKind = \"started\"\n    StepEventDone    StepEventKind = \"done\"\n    StepEventFailed  StepEventKind = \"failed\"\n    StepEventRetried StepEventKind = \"retried\"\n)\n\ntype StepEvent struct {\n    Kind     StepEventKind\n    Step     *Step       \u002F\u002F same pointer the handler saw\n    Attempt  int         \u002F\u002F 1-based\n    Err      error       \u002F\u002F non-nil on Failed \u002F Retried\n    Duration time.Duration\n}\n\ntype StepObserver func(ev StepEvent)\n",[978,4617,4618,4623,4627,4632,4637,4642,4647,4652,4657,4661,4666,4671,4676,4681,4686,4691,4695,4699],{"__ignoreMap":1040},[1053,4619,4620],{"class":1055,"line":10},[1053,4621,4622],{},"type StepEventKind string\n",[1053,4624,4625],{"class":1055,"line":16},[1053,4626,1108],{"emptyLinePlaceholder":1107},[1053,4628,4629],{"class":1055,"line":22},[1053,4630,4631],{},"const (\n",[1053,4633,4634],{"class":1055,"line":51},[1053,4635,4636],{},"    StepEventStarted StepEventKind = \"started\"\n",[1053,4638,4639],{"class":1055,"line":57},[1053,4640,4641],{},"    StepEventDone    StepEventKind = \"done\"\n",[1053,4643,4644],{"class":1055,"line":102},[1053,4645,4646],{},"    StepEventFailed  StepEventKind = \"failed\"\n",[1053,4648,4649],{"class":1055,"line":108},[1053,4650,4651],{},"    StepEventRetried StepEventKind = \"retried\"\n",[1053,4653,4654],{"class":1055,"line":114},[1053,4655,4656],{},")\n",[1053,4658,4659],{"class":1055,"line":120},[1053,4660,1108],{"emptyLinePlaceholder":1107},[1053,4662,4663],{"class":1055,"line":181},[1053,4664,4665],{},"type StepEvent struct {\n",[1053,4667,4668],{"class":1055,"line":186},[1053,4669,4670],{},"    Kind     StepEventKind\n",[1053,4672,4673],{"class":1055,"line":191},[1053,4674,4675],{},"    Step     *Step       \u002F\u002F same pointer the handler saw\n",[1053,4677,4678],{"class":1055,"line":197},[1053,4679,4680],{},"    Attempt  int         \u002F\u002F 1-based\n",[1053,4682,4683],{"class":1055,"line":203},[1053,4684,4685],{},"    Err      error       \u002F\u002F non-nil on Failed \u002F Retried\n",[1053,4687,4688],{"class":1055,"line":214},[1053,4689,4690],{},"    Duration time.Duration\n",[1053,4692,4693],{"class":1055,"line":223},[1053,4694,1637],{},[1053,4696,4697],{"class":1055,"line":229},[1053,4698,1108],{"emptyLinePlaceholder":1107},[1053,4700,4701],{"class":1055,"line":234},[1053,4702,4703],{},"type StepObserver func(ev StepEvent)\n",[974,4705,4706],{},"Two registration paths, per-run wins over engine-wide:",[1032,4708,4710],{"className":1094,"code":4709,"language":1059,"meta":1040,"style":1040},"\u002F\u002F Engine-wide observer — fires for every run unless overridden.\neng.SetStepObserver(func(ev runtime.StepEvent) { ... })\n\n\u002F\u002F Per-run observer via context. Concurrent runs do not interfere —\n\u002F\u002F each carries its own observer through context.\nctx = runtime.WithStepObserver(ctx, myObserver)\nexec, _ := eng.Start(ctx, wf, input)\n",[978,4711,4712,4717,4722,4726,4731,4736,4741],{"__ignoreMap":1040},[1053,4713,4714],{"class":1055,"line":10},[1053,4715,4716],{},"\u002F\u002F Engine-wide observer — fires for every run unless overridden.\n",[1053,4718,4719],{"class":1055,"line":16},[1053,4720,4721],{},"eng.SetStepObserver(func(ev runtime.StepEvent) { ... })\n",[1053,4723,4724],{"class":1055,"line":22},[1053,4725,1108],{"emptyLinePlaceholder":1107},[1053,4727,4728],{"class":1055,"line":51},[1053,4729,4730],{},"\u002F\u002F Per-run observer via context. Concurrent runs do not interfere —\n",[1053,4732,4733],{"class":1055,"line":57},[1053,4734,4735],{},"\u002F\u002F each carries its own observer through context.\n",[1053,4737,4738],{"class":1055,"line":102},[1053,4739,4740],{},"ctx = runtime.WithStepObserver(ctx, myObserver)\n",[1053,4742,4743],{"class":1055,"line":108},[1053,4744,4745],{},"exec, _ := eng.Start(ctx, wf, input)\n",[974,4747,4748,4749,4752,4753,4756],{},"Firing order is ",[978,4750,4751],{},"Started → (Retried × N) → Done|Failed"," per step. Observers run\nsynchronously on the executor goroutine — keep them fast (send to a channel,\nappend to a ring buffer, etc.). Panics inside an observer are recovered but\nsurface as ",[978,4754,4755],{},"run.failed"," with the panic message.",[974,4758,4759,4760,1921],{},"Tests: ",[978,4761,4762],{},"go-flowdsl\u002Fruntime\u002Fobserver_test.go",[1082,4764,4766,4769],{"id":4765},"spec-studio-spec-document-converters",[978,4767,4768],{},"spec"," — Studio spec document converters",[974,4771,4772,4773,4775],{},"Bidirectional converters between the canonical ",[978,4774,1657],{}," (flat nodes + edges used at\nruntime) and the Studio spec document format (nested flows, components, visual metadata).",[1032,4777,4779],{"className":1094,"code":4778,"language":1059,"meta":1040,"style":1040},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fspec\"\n",[978,4780,4781],{"__ignoreMap":1040},[1053,4782,4783],{"class":1055,"line":10},[1053,4784,4778],{},[974,4786,4787,4788,4790,4791,4793,4794,4796,4797,2013,4800,4803,4804,4807],{},"The ",[978,4789,1657],{}," is the runtime representation stored by ",[978,4792,4603],{},". The spec ",[978,4795,1218],{}," is\nthe editing representation used by the FlowDSL Studio frontend — it carries ",[978,4798,4799],{},"flows",[978,4801,4802],{},"components.nodes",", and ",[978,4805,4806],{},"x-ui"," visual metadata (positions, icons, colors).",[1502,4809,4811],{"id":4810},"types","Types",[1193,4813,4814,4822],{},[1196,4815,4816],{},[1199,4817,4818,4820],{},[1202,4819,1204],{},[1202,4821,1207],{},[1209,4823,4824,4844,4861,4881,4896,4919,4933,4951,4973,4998],{},[1199,4825,4826,4830],{},[1214,4827,4828],{},[978,4829,1218],{},[1214,4831,4832,4833,4835,4836,1268,4839,1268,4841],{},"Top-level spec document — ",[978,4834,2483],{}," version, ",[978,4837,4838],{},"info",[978,4840,4799],{},[978,4842,4843],{},"components",[1199,4845,4846,4851],{},[1214,4847,4848],{},[978,4849,4850],{},"Info",[1214,4852,4853,4854,1268,4856,1268,4858],{},"Document metadata — ",[978,4855,2552],{},[978,4857,2536],{},[978,4859,4860],{},"description",[1199,4862,4863,4868],{},[1214,4864,4865],{},[978,4866,4867],{},"Flow",[1214,4869,4870,4871,4874,4875,4877,4878],{},"Single flow — ",[978,4872,4873],{},"nodes"," (map of ",[978,4876,1254],{}," pointers), ",[978,4879,4880],{},"edges",[1199,4882,4883,4888],{},[1214,4884,4885],{},[978,4886,4887],{},"NodeRef",[1214,4889,4890,4892,4893],{},[978,4891,1254],{}," pointer into ",[978,4894,4895],{},"#\u002Fcomponents\u002Fnodes\u002F...",[1199,4897,4898,4902],{},[1214,4899,4900],{},[978,4901,1361],{},[1214,4903,4904,4905,1268,4907,1268,4910,1268,4913,1268,4916],{},"Directed connection — ",[978,4906,1025],{},[978,4908,4909],{},"to",[978,4911,4912],{},"when",[978,4914,4915],{},"packet",[978,4917,4918],{},"delivery",[1199,4920,4921,4926],{},[1214,4922,4923],{},[978,4924,4925],{},"DeliveryPolicy",[1214,4927,4928,4929,4932],{},"Edge delivery mode — ",[978,4930,4931],{},"mode"," (direct, ephemeral, durable, stream, checkpoint)",[1199,4934,4935,4940],{},[1214,4936,4937],{},[978,4938,4939],{},"Components",[1214,4941,4942,4943,1268,4945,1268,4948],{},"Shared definitions — ",[978,4944,4873],{},[978,4946,4947],{},"packets",[978,4949,4950],{},"policies",[1199,4952,4953,4958],{},[1214,4954,4955],{},[978,4956,4957],{},"NodeDef",[1214,4959,4960,4961,1268,4964,1268,4966,1268,4968,1268,4971],{},"Node component — ",[978,4962,4963],{},"operationId",[978,4965,2552],{},[978,4967,3193],{},[978,4969,4970],{},"settings",[978,4972,4806],{},[1199,4974,4975,4980],{},[1214,4976,4977],{},[978,4978,4979],{},"XUI",[1214,4981,4982,4983,1268,4986,1268,4989,1268,4992,1268,4995],{},"Canvas visual metadata — ",[978,4984,4985],{},"position",[978,4987,4988],{},"icon",[978,4990,4991],{},"color",[978,4993,4994],{},"registryId",[978,4996,4997],{},"group",[1199,4999,5000,5005],{},[1214,5001,5002],{},[978,5003,5004],{},"XYPos",[1214,5006,5007,5008,1268,5011],{},"Canvas coordinates — ",[978,5009,5010],{},"x",[978,5012,5013],{},"y",[1502,5015,5017,5020],{"id":5016},"fromworkflow-ir-to-spec",[978,5018,5019],{},"FromWorkflow"," — IR to spec",[1032,5022,5024],{"className":1094,"code":5023,"language":1059,"meta":1040,"style":1040},"doc := spec.FromWorkflow(wf) \u002F\u002F *ir.Workflow → *spec.Document\n",[978,5025,5026],{"__ignoreMap":1040},[1053,5027,5028],{"class":1055,"line":10},[1053,5029,5023],{},[1842,5031,5032,5043,5083,5091],{},[1845,5033,1992,5034,5036,5037,5039,5040,5042],{},[978,5035,4235],{}," becomes an entry in ",[978,5038,4802],{}," and a ",[978,5041,1254],{}," pointer in the flow.",[1845,5044,5045,5046,5049,5050,1268,5052,5049,5055,1268,5058,5049,5061,2013,5064,5049,5067,1268,5069,5049,5072,1268,5075,5049,5077,1268,5079,5049,5081,1921],{},"Node kinds are mapped: ",[978,5047,5048],{},"start","→",[978,5051,3591],{},[978,5053,5054],{},"end",[978,5056,5057],{},"terminal",[978,5059,5060],{},"gateway",[978,5062,5063],{},"router",[978,5065,5066],{},"condition",[978,5068,5063],{},[978,5070,5071],{},"wait",[978,5073,5074],{},"checkpoint",[978,5076,3178],{},[978,5078,3591],{},[978,5080,3096],{},[978,5082,3096],{},[1845,5084,5085,5086,5088,5089,1921],{},"Edge conditions become ",[978,5087,4912],{},", labels become ",[978,5090,4860],{},[1845,5092,5093,5094,5097,5098,5100],{},"Returns ",[978,5095,5096],{},"nil"," for ",[978,5099,5096],{}," input.",[1502,5102,5104,5107],{"id":5103},"toworkflow-spec-to-ir",[978,5105,5106],{},"ToWorkflow"," — spec to IR",[1032,5109,5111],{"className":1094,"code":5110,"language":1059,"meta":1040,"style":1040},"wf := spec.ToWorkflow(doc, \"main\") \u002F\u002F *spec.Document, flowID → *ir.Workflow\n",[978,5112,5113],{"__ignoreMap":1040},[1053,5114,5115],{"class":1055,"line":10},[1053,5116,5110],{},[1842,5118,5119,5125,5157,5164],{},[1845,5120,5121,5122,5124],{},"Resolves ",[978,5123,1254],{}," pointers to component node definitions.",[1845,5126,5127,5128,5049,5130,1268,5132,5049,5134,1268,5136,5049,5138,2013,5140,3813,5142,3813,5145,3813,5147,3813,5150,3813,5153,5049,5155,1921],{},"Spec kinds are mapped back: ",[978,5129,3591],{},[978,5131,5048],{},[978,5133,5057],{},[978,5135,5054],{},[978,5137,5063],{},[978,5139,5060],{},[978,5141,3607],{},[978,5143,5144],{},"llm",[978,5146,5074],{},[978,5148,5149],{},"publish",[978,5151,5152],{},"integration",[978,5154,3639],{},[978,5156,3096],{},[1845,5158,5159,5160,5163],{},"If ",[978,5161,5162],{},"flowID"," is empty, uses the first flow in the document.",[1845,5165,5093,5166,5097,5168,5100],{},[978,5167,5096],{},[978,5169,5096],{},[1502,5171,5173],{"id":5172},"round-trip-guarantee","Round-trip guarantee",[974,5175,5176,5179,5180,5183,5184,5186,5187,5189,5190,5192],{},[978,5177,5178],{},"FromWorkflow(wf)"," → ",[978,5181,5182],{},"ToWorkflow(doc, flowID)"," preserves all structural information\n(node IDs, names, kinds, edges, conditions). Visual metadata (",[978,5185,4806],{},") is generated on\n",[978,5188,5019],{}," with default values and round-trips through ",[978,5191,5106],{}," without loss.",[1082,5194,5196,5198],{"id":5195},"flowexec-orchestration-storage-sinks-flowexec",[978,5197,4603],{}," — orchestration, storage, sinks {#flowexec}",[974,5200,5201,5203,5204,5206,5207,5210],{},[978,5202,4603],{}," is a subpackage of ",[978,5205,1000],{}," that sits on top of ",[978,5208,5209],{},"runtime.Engine"," and adds the\nthree things real applications need but the raw engine does not provide:",[3997,5212,5213,5224,5230],{},[1845,5214,5215,5216,5219,5220,5223],{},"An ",[989,5217,5218],{},"executor"," that wraps ",[978,5221,5222],{},"Engine.Start"," and emits lifecycle events for every run, node, and edge.",[1845,5225,5215,5226,5229],{},[989,5227,5228],{},"immutable flow store"," — flow documents saved as append-only versions identified by a\ncontent hash, with head\u002Fpublished pointers.",[1845,5231,5232,5233,5236],{},"A pluggable ",[989,5234,5235],{},"sink"," abstraction for persisting events and run summaries (Mongo time-series,\nClickHouse, no-op).",[974,5238,5239,5241,5242,5244,5245,5247,5248,5250,5251,3293,5254,5257,5258],{},[978,5240,4603],{}," has no dependency on ",[978,5243,1018],{},"; it builds on ",[978,5246,4025],{}," + ",[978,5249,1087],{}," plus the Go\nMongoDB driver (only for the ",[978,5252,5253],{},"mongostore",[978,5255,5256],{},"mongots"," sink implementations — pick ",[978,5259,5260],{},"memstore",[1842,5262,5263],{},[1845,5264,5265,5268],{},[978,5266,5267],{},"noop"," for zero external deps).",[1032,5270,5273],{"className":5271,"code":5272,"language":1037},[1035],"go-flowdsl\u002F\n  flowexec\u002F\n    executor.go        Executor, Options, RunInput, RunAsync\n    sink\u002F              FlowEventSink, UsageSink, Reader, Combined, FlowEvent, FlowRun\n    sink\u002Fnoop\u002F         No-op sink for tests and Mongo-less deployments\n    sink\u002Fmongots\u002F      Mongo time-series sink (flow_events + flow_runs)\n    store\u002F             Store interface + Flow \u002F FlowVersion \u002F FlowDeployment types\n    store\u002Fmemstore\u002F    In-memory store for tests\n    store\u002Fmongostore\u002F  MongoDB-backed store with versionHash indexes\n    module\u002F            HTTP module — flow + deployment CRUD routes\n",[978,5274,5272],{"__ignoreMap":1040},[1502,5276,5278,5281],{"id":5277},"flowdeployment-the-caller-facing-routing-table",[978,5279,5280],{},"FlowDeployment"," — the caller-facing routing table",[974,5283,5284,5285,5289,5290,5292,5293,5296],{},"Flow + FlowVersion give you ",[5286,5287,5288],"em",{},"immutable diagrams",". ",[978,5291,5280],{}," sits above both as the\n",[989,5294,5295],{},"business-level binding"," every consumer module references:",[1032,5298,5301],{"className":5299,"code":5300,"language":1037},[1035],"Module config → DeploymentID → FlowDeployment.variants:\n                                  - stable       → flow.X (or pinned ver.Y)   90%\n                                  - canary       → flow.Z (or pinned ver.W)   10%\n                                  - experiment_a → flow.Q                      0%  (staged)\n",[978,5302,5300],{"__ignoreMap":1040},[974,5304,5305,5306,5309,5310,5313],{},"One deployment, many flows. Weights are session-sticky (FNV-1a hash of the configured\n",[978,5307,5308],{},"StickyBy"," key bucketed into a CDF), so A\u002FB tests between radically different flow\n",[5286,5311,5312],{},"shapes"," live in a single config knob without flapping users between variants on reloads.",[1032,5315,5317],{"className":1094,"code":5316,"language":1059,"meta":1040,"style":1040},"import flowstore \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fflowexec\u002Fstore\"\n\n\u002F\u002F Once at boot: make sure the deployment exists. Safe to call every\n\u002F\u002F startup — existing deployments are returned untouched.\ndep, _ := flowstore.EnsureDeployment(ctx, s, flowstore.CreateDeploymentInput{\n    ID:   \"assistant\",\n    Name: \"Production Assistant\",\n    Variants: []flowstore.FlowDeploymentVariant{\n        {Label: \"stable\", FlowID: \"assistant-v1\", Weight: 100},\n    },\n    StickyBy: flowstore.StickySession,\n})\n\n\u002F\u002F On every incoming request: resolve which flow + version to run for\n\u002F\u002F this session. Same (deployment, session_id) always → same variant.\nresolved, err := flowstore.ResolveDeployment(ctx, s, \"assistant\", map[string]any{\n    \"session_id\": sessionID,\n}, nil)\n\u002F\u002F resolved.Label == \"stable\", resolved.FlowID, resolved.Version ready for the executor.\n",[978,5318,5319,5324,5328,5333,5338,5343,5348,5353,5358,5363,5368,5373,5377,5381,5386,5391,5396,5401,5406],{"__ignoreMap":1040},[1053,5320,5321],{"class":1055,"line":10},[1053,5322,5323],{},"import flowstore \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fflowexec\u002Fstore\"\n",[1053,5325,5326],{"class":1055,"line":16},[1053,5327,1108],{"emptyLinePlaceholder":1107},[1053,5329,5330],{"class":1055,"line":22},[1053,5331,5332],{},"\u002F\u002F Once at boot: make sure the deployment exists. Safe to call every\n",[1053,5334,5335],{"class":1055,"line":51},[1053,5336,5337],{},"\u002F\u002F startup — existing deployments are returned untouched.\n",[1053,5339,5340],{"class":1055,"line":57},[1053,5341,5342],{},"dep, _ := flowstore.EnsureDeployment(ctx, s, flowstore.CreateDeploymentInput{\n",[1053,5344,5345],{"class":1055,"line":102},[1053,5346,5347],{},"    ID:   \"assistant\",\n",[1053,5349,5350],{"class":1055,"line":108},[1053,5351,5352],{},"    Name: \"Production Assistant\",\n",[1053,5354,5355],{"class":1055,"line":114},[1053,5356,5357],{},"    Variants: []flowstore.FlowDeploymentVariant{\n",[1053,5359,5360],{"class":1055,"line":120},[1053,5361,5362],{},"        {Label: \"stable\", FlowID: \"assistant-v1\", Weight: 100},\n",[1053,5364,5365],{"class":1055,"line":181},[1053,5366,5367],{},"    },\n",[1053,5369,5370],{"class":1055,"line":186},[1053,5371,5372],{},"    StickyBy: flowstore.StickySession,\n",[1053,5374,5375],{"class":1055,"line":191},[1053,5376,3471],{},[1053,5378,5379],{"class":1055,"line":197},[1053,5380,1108],{"emptyLinePlaceholder":1107},[1053,5382,5383],{"class":1055,"line":203},[1053,5384,5385],{},"\u002F\u002F On every incoming request: resolve which flow + version to run for\n",[1053,5387,5388],{"class":1055,"line":214},[1053,5389,5390],{},"\u002F\u002F this session. Same (deployment, session_id) always → same variant.\n",[1053,5392,5393],{"class":1055,"line":223},[1053,5394,5395],{},"resolved, err := flowstore.ResolveDeployment(ctx, s, \"assistant\", map[string]any{\n",[1053,5397,5398],{"class":1055,"line":229},[1053,5399,5400],{},"    \"session_id\": sessionID,\n",[1053,5402,5403],{"class":1055,"line":234},[1053,5404,5405],{},"}, nil)\n",[1053,5407,5408],{"class":1055,"line":240},[1053,5409,5410],{},"\u002F\u002F resolved.Label == \"stable\", resolved.FlowID, resolved.Version ready for the executor.\n",[974,5412,5413,5416,5417,5420,5421,1899],{},[989,5414,5415],{},"Admin HTTP surface"," (registered by ",[978,5418,5419],{},"go-flowdsl\u002Fflowexec\u002Fmodule",", admin-gated via\n",[978,5422,5423],{},"admin:access",[1193,5425,5426,5439],{},[1196,5427,5428],{},[1199,5429,5430,5433,5436],{},[1202,5431,5432],{},"Method",[1202,5434,5435],{},"Path",[1202,5437,5438],{},"Purpose",[1209,5440,5441,5454,5466,5478,5490,5502],{},[1199,5442,5443,5446,5451],{},[1214,5444,5445],{},"GET",[1214,5447,5448],{},[978,5449,5450],{},"\u002Fdeployments",[1214,5452,5453],{},"List (cursor pagination)",[1199,5455,5456,5459,5463],{},[1214,5457,5458],{},"POST",[1214,5460,5461],{},[978,5462,5450],{},[1214,5464,5465],{},"Create",[1199,5467,5468,5470,5475],{},[1214,5469,5445],{},[1214,5471,5472],{},[978,5473,5474],{},"\u002Fdeployments\u002F{id}",[1214,5476,5477],{},"Read",[1199,5479,5480,5483,5487],{},[1214,5481,5482],{},"PATCH",[1214,5484,5485],{},[978,5486,5474],{},[1214,5488,5489],{},"Replace variants \u002F stickyBy \u002F labels",[1199,5491,5492,5495,5499],{},[1214,5493,5494],{},"DELETE",[1214,5496,5497],{},[978,5498,5474],{},[1214,5500,5501],{},"Delete (flows untouched)",[1199,5503,5504,5506,5511],{},[1214,5505,5458],{},[1214,5507,5508],{},[978,5509,5510],{},"\u002Fdeployments\u002F{id}\u002Fvariants\u002Ffrom-template",[1214,5512,5513],{},"Provision a new flow from a template, publish v1, append as variant — all in one call",[974,5515,5516,5517,5520,5521,5524,5525,5527],{},"Consumer modules (assistant, community, any future module) stay thin: they hold a\n",[978,5518,5519],{},"DeploymentID"," in config and call ",[978,5522,5523],{},"ResolveDeployment"," per request. Adding a canary flow\nis a curl against ",[978,5526,5510],{},"; no module redeploy needed.",[1502,5529,5530],{"id":5218},[978,5531,5532],{},"Executor",[1032,5534,5536],{"className":1094,"code":5535,"language":1059,"meta":1040,"style":1040},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fflowexec\"\n\nex := flowexec.New(flowexec.Options{\n    Engine: eng,     \u002F\u002F a *runtime.Engine with handlers registered\n    Sink:   sink,    \u002F\u002F a sink.FlowEventSink — mongots, noop, or a custom decorator\n})\n\nexec, runID, err := ex.Run(ctx, flowexec.RunInput{\n    Workflow:    wf,\n    VersionID:   version.ID,\n    VersionHash: version.VersionHash,\n    Input:       map[string]any{\"user\": \"u1\"},\n    Labels:      map[string]string{\"source\": \"api\"},\n})\n\n\u002F\u002F Fire and forget; subscribe to SSE for progress.\nrunID, errCh, err := ex.RunAsync(ctx, flowexec.RunInput{Workflow: wf})\n",[978,5537,5538,5543,5547,5552,5557,5562,5566,5570,5575,5580,5585,5590,5595,5600,5604,5608,5613],{"__ignoreMap":1040},[1053,5539,5540],{"class":1055,"line":10},[1053,5541,5542],{},"import \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fflowexec\"\n",[1053,5544,5545],{"class":1055,"line":16},[1053,5546,1108],{"emptyLinePlaceholder":1107},[1053,5548,5549],{"class":1055,"line":22},[1053,5550,5551],{},"ex := flowexec.New(flowexec.Options{\n",[1053,5553,5554],{"class":1055,"line":51},[1053,5555,5556],{},"    Engine: eng,     \u002F\u002F a *runtime.Engine with handlers registered\n",[1053,5558,5559],{"class":1055,"line":57},[1053,5560,5561],{},"    Sink:   sink,    \u002F\u002F a sink.FlowEventSink — mongots, noop, or a custom decorator\n",[1053,5563,5564],{"class":1055,"line":102},[1053,5565,3471],{},[1053,5567,5568],{"class":1055,"line":108},[1053,5569,1108],{"emptyLinePlaceholder":1107},[1053,5571,5572],{"class":1055,"line":114},[1053,5573,5574],{},"exec, runID, err := ex.Run(ctx, flowexec.RunInput{\n",[1053,5576,5577],{"class":1055,"line":120},[1053,5578,5579],{},"    Workflow:    wf,\n",[1053,5581,5582],{"class":1055,"line":181},[1053,5583,5584],{},"    VersionID:   version.ID,\n",[1053,5586,5587],{"class":1055,"line":186},[1053,5588,5589],{},"    VersionHash: version.VersionHash,\n",[1053,5591,5592],{"class":1055,"line":191},[1053,5593,5594],{},"    Input:       map[string]any{\"user\": \"u1\"},\n",[1053,5596,5597],{"class":1055,"line":197},[1053,5598,5599],{},"    Labels:      map[string]string{\"source\": \"api\"},\n",[1053,5601,5602],{"class":1055,"line":203},[1053,5603,3471],{},[1053,5605,5606],{"class":1055,"line":214},[1053,5607,1108],{"emptyLinePlaceholder":1107},[1053,5609,5610],{"class":1055,"line":223},[1053,5611,5612],{},"\u002F\u002F Fire and forget; subscribe to SSE for progress.\n",[1053,5614,5615],{"class":1055,"line":229},[1053,5616,5617],{},"runID, errCh, err := ex.RunAsync(ctx, flowexec.RunInput{Workflow: wf})\n",[974,5619,5620,5623,5624,5627],{},[978,5621,5622],{},"RunInput.RunID"," can be pre-populated by the caller; if non-empty it is used verbatim instead\nof a fresh UUID. ",[978,5625,5626],{},"RunAsync"," always pre-generates the ID and stamps it back onto the input, so\nsubscribers can attach to the event stream before the run begins emitting events.",[974,5629,5630],{},"Every run produces:",[1842,5632,5633,5649],{},[1845,5634,5635,5636,5639,5640,5643,5644,1866,5646,5648],{},"One ",[978,5637,5638],{},"FlowRun"," row written at start (",[978,5641,5642],{},"Status: \"running\"",") and updated at end (",[978,5645,4416],{},[978,5647,4419],{},").",[1845,5650,5651,5652,5655,5656,4117,5658,4117,5660,5663,5664,1866,5667,5669,5670,5673,5674,5676],{},"Kind-",[978,5653,5654],{},"run.started"," → per-node ",[978,5657,4607],{},[978,5659,4611],{},[978,5661,5662],{},"node.failed"," → kind-",[978,5665,5666],{},"run.completed",[978,5668,4755],{}," events. Node events are derived from ",[978,5671,5672],{},"exec.Steps"," after ",[978,5675,5222],{}," returns (the engine lacks hooks today; node events will move to real-time emission once hooks land).",[1502,5678,5680,3541],{"id":5679},"sinkfloweventsink-interface",[978,5681,5682],{},"sink.FlowEventSink",[1032,5684,5686],{"className":1094,"code":5685,"language":1059,"meta":1040,"style":1040},"type FlowEventSink interface {\n    RecordFlowEvent(ctx context.Context, ev FlowEvent) error\n    RecordFlowRun(ctx context.Context, run FlowRun) error\n}\n",[978,5687,5688,5693,5698,5703],{"__ignoreMap":1040},[1053,5689,5690],{"class":1055,"line":10},[1053,5691,5692],{},"type FlowEventSink interface {\n",[1053,5694,5695],{"class":1055,"line":16},[1053,5696,5697],{},"    RecordFlowEvent(ctx context.Context, ev FlowEvent) error\n",[1053,5699,5700],{"class":1055,"line":22},[1053,5701,5702],{},"    RecordFlowRun(ctx context.Context, run FlowRun) error\n",[1053,5704,5705],{"class":1055,"line":51},[1053,5706,1637],{},[974,5708,5709],{},"Event kinds:",[1193,5711,5712,5721],{},[1196,5713,5714],{},[1199,5715,5716,5718],{},[1202,5717,1646],{},[1202,5719,5720],{},"When",[1209,5722,5723,5732,5746,5761,5771],{},[1199,5724,5725,5729],{},[1214,5726,5727],{},[978,5728,5654],{},[1214,5730,5731],{},"Immediately after the executor accepts a run",[1199,5733,5734,5740],{},[1214,5735,5736,4117,5738],{},[978,5737,5666],{},[978,5739,4755],{},[1214,5741,5742,5743,5745],{},"After ",[978,5744,5222],{}," returns",[1199,5747,5748,5756],{},[1214,5749,5750,4117,5752,4117,5754],{},[978,5751,4607],{},[978,5753,4611],{},[978,5755,5662],{},[1214,5757,5758,5759],{},"One pair per step in ",[978,5760,5672],{},[1199,5762,5763,5768],{},[1214,5764,5765],{},[978,5766,5767],{},"packet.emit",[1214,5769,5770],{},"Reserved for future packet-emission events",[1199,5772,5773,5778],{},[1214,5774,5775],{},[978,5776,5777],{},"edge.deliver",[1214,5779,5780],{},"Reserved for future edge-delivery events",[974,5782,5783,5786,5787,1268,5790,1268,5793,1268,5796,1268,5798,1268,5801,2013,5804,1268,5807,1268,5810,5813,5814,5817,5818,1268,5820,1268,5822,2013,5825,5828,5829,5831],{},[978,5784,5785],{},"FlowEvent"," carries ",[978,5788,5789],{},"RunID",[978,5791,5792],{},"FlowID",[978,5794,5795],{},"VersionHash",[978,5797,4384],{},[978,5799,5800],{},"Timestamp",[978,5802,5803],{},"Seq",[978,5805,5806],{},"DurationMs",[978,5808,5809],{},"ErrorMsg",[978,5811,5812],{},"Payload",", and a ",[978,5815,5816],{},"Meta"," block (",[978,5819,5792],{},[978,5821,5789],{},[978,5823,5824],{},"AssistantID",[978,5826,5827],{},"UserID","). Every event is stamped with ",[978,5830,5795],{}," so past runs remain replay-correct even\nafter the flow is edited and re-published.",[974,5833,5834,1664,5839,5841,5842,3293,5844,5846,5847,5850,5851,5854],{},[989,5835,5836,5837,1921],{},"Strict emission order via ",[978,5838,5803],{},[978,5840,5803],{}," is a per-run monotonically-increasing counter\nassigned by the Executor in the exact order events are produced. It serves as the tie-breaker\nwhenever multiple events share a millisecond timestamp — which happens for pass-through\nentry\u002Fexit nodes whose ",[978,5843,4401],{},[978,5845,4404],{}," resolve to the same wall-clock ms.\n",[978,5848,5849],{},"mongots.ListRunEvents"," sorts by ",[978,5852,5853],{},"(ts asc, seq asc)"," so consumers see a strict total order;\nclients (Studio, custom dashboards) MUST treat that order as canonical and not re-sort.",[974,5856,5857],{},"Available implementations:",[1193,5859,5860,5869],{},[1196,5861,5862],{},[1199,5863,5864,5867],{},[1202,5865,5866],{},"Package",[1202,5868,5438],{},[1209,5870,5871,5881],{},[1199,5872,5873,5878],{},[1214,5874,5875],{},[978,5876,5877],{},"sink\u002Fnoop",[1214,5879,5880],{},"Drops everything. Default when Mongo is not wired.",[1199,5882,5883,5888],{},[1214,5884,5885],{},[978,5886,5887],{},"sink\u002Fmongots",[1214,5889,5890,5891,5894,5895,5898,5899,5902],{},"Writes ",[978,5892,5893],{},"flow_events"," as a time-series collection and ",[978,5896,5897],{},"flow_runs"," as a regular collection. Implements ",[978,5900,5901],{},"Reader"," for historical queries.",[1502,5904,5906,5909],{"id":5905},"storestore-immutable-versioning",[978,5907,5908],{},"store.Store"," — immutable versioning",[1032,5911,5913],{"className":1094,"code":5912,"language":1059,"meta":1040,"style":1040},"type Store interface {\n    CreateFlow(ctx, CreateFlowInput) (*Flow, error)\n    GetFlow(ctx, id) (*Flow, error)\n    UpdateFlow(ctx, id, name, description, labels) (*Flow, error)\n    DeleteFlow(ctx, id) error\n    ListFlows(ctx, ListFlowsOptions) ([]*Flow, nextCursor, error)\n\n    SaveVersion(ctx, SaveVersionInput) (*FlowVersion, error)\n    GetVersion(ctx, id) (*FlowVersion, error)\n    ListVersions(ctx, flowID, ListVersionsOptions) ([]*FlowVersion, nextCursor, error)\n\n    PublishVersion(ctx, flowID, versionID) (*Flow, error)\n    GetPublishedVersion(ctx, flowID) (*FlowVersion, error)\n}\n",[978,5914,5915,5920,5925,5930,5935,5940,5945,5949,5954,5959,5964,5968,5973,5978],{"__ignoreMap":1040},[1053,5916,5917],{"class":1055,"line":10},[1053,5918,5919],{},"type Store interface {\n",[1053,5921,5922],{"class":1055,"line":16},[1053,5923,5924],{},"    CreateFlow(ctx, CreateFlowInput) (*Flow, error)\n",[1053,5926,5927],{"class":1055,"line":22},[1053,5928,5929],{},"    GetFlow(ctx, id) (*Flow, error)\n",[1053,5931,5932],{"class":1055,"line":51},[1053,5933,5934],{},"    UpdateFlow(ctx, id, name, description, labels) (*Flow, error)\n",[1053,5936,5937],{"class":1055,"line":57},[1053,5938,5939],{},"    DeleteFlow(ctx, id) error\n",[1053,5941,5942],{"class":1055,"line":102},[1053,5943,5944],{},"    ListFlows(ctx, ListFlowsOptions) ([]*Flow, nextCursor, error)\n",[1053,5946,5947],{"class":1055,"line":108},[1053,5948,1108],{"emptyLinePlaceholder":1107},[1053,5950,5951],{"class":1055,"line":114},[1053,5952,5953],{},"    SaveVersion(ctx, SaveVersionInput) (*FlowVersion, error)\n",[1053,5955,5956],{"class":1055,"line":120},[1053,5957,5958],{},"    GetVersion(ctx, id) (*FlowVersion, error)\n",[1053,5960,5961],{"class":1055,"line":181},[1053,5962,5963],{},"    ListVersions(ctx, flowID, ListVersionsOptions) ([]*FlowVersion, nextCursor, error)\n",[1053,5965,5966],{"class":1055,"line":186},[1053,5967,1108],{"emptyLinePlaceholder":1107},[1053,5969,5970],{"class":1055,"line":191},[1053,5971,5972],{},"    PublishVersion(ctx, flowID, versionID) (*Flow, error)\n",[1053,5974,5975],{"class":1055,"line":197},[1053,5976,5977],{},"    GetPublishedVersion(ctx, flowID) (*FlowVersion, error)\n",[1053,5979,5980],{"class":1055,"line":203},[1053,5981,1637],{},[974,5983,5984],{},"Two collections, two invariants:",[1842,5986,5987,6011],{},[1845,5988,5989,5993,5994,1268,5997,1268,5999,6002,6003,6006,6007,6010],{},[989,5990,5991],{},[978,5992,4867],{}," is mutable. It holds ",[978,5995,5996],{},"Name",[978,5998,1207],{},[978,6000,6001],{},"Labels",", and two pointers:\n",[978,6004,6005],{},"HeadVersionID"," (newest saved) and ",[978,6008,6009],{},"PublishedVersionID"," (what runs resolve to).",[1845,6012,6013,6018,6019,6021,6022,6025],{},[989,6014,6015],{},[978,6016,6017],{},"FlowVersion"," is append-only. It holds the full ",[978,6020,1657],{}," document plus\n",[978,6023,6024],{},"VersionHash = sha256(workflow JSON)",". Once saved, versions never change.",[974,6027,6028,6031,6032,6035,6036,5289,6039,6042],{},[978,6029,6030],{},"SaveVersion"," hashes the incoming document, inserts a new ",[978,6033,6034],{},"flow_versions"," row, and atomically\nadvances ",[978,6037,6038],{},"Flow.HeadVersionID",[978,6040,6041],{},"PublishVersion"," is a pointer flip — no document rewrites, no\ncascading updates. Past runs reference versions by ID and hash, so replay is deterministic.",[1193,6044,6045,6058],{},[1196,6046,6047],{},[1199,6048,6049,6052,6055],{},[1202,6050,6051],{},"Backend",[1202,6053,6054],{},"Dependencies",[1202,6056,6057],{},"Use for",[1209,6059,6060,6072],{},[1199,6061,6062,6066,6069],{},[1214,6063,6064],{},[978,6065,5260],{},[1214,6067,6068],{},"stdlib only",[1214,6070,6071],{},"tests, ephemeral demos",[1199,6073,6074,6078,6083],{},[1214,6075,6076],{},[978,6077,5253],{},[1214,6079,6080],{},[978,6081,6082],{},"mongo-driver",[1214,6084,6085],{},"production",[974,6087,6088,6091,6092,6095,6096,4803,6099,6102],{},[978,6089,6090],{},"mongostore.EnsureIndexes"," creates indexes on ",[978,6093,6094],{},"flow_versions.flowID+createdAt"," (desc),\n",[978,6097,6098],{},"flow_versions.versionHash",[978,6100,6101],{},"flows.updatedAt"," (desc).",[1502,6104,6106],{"id":6105},"zero-dependency-deployments","Zero-dependency deployments",[974,6108,6109,6110,5247,6112,1676],{},"For workers that should run flows without a database, pair ",[978,6111,5260],{},[978,6113,6114],{},"sinknoop",[1032,6116,6118],{"className":1094,"code":6117,"language":1059,"meta":1040,"style":1040},"st := memstore.New()\nsnk := sinknoop.New()\nex := flowexec.New(flowexec.Options{Engine: eng, Sink: snk})\n",[978,6119,6120,6125,6130],{"__ignoreMap":1040},[1053,6121,6122],{"class":1055,"line":10},[1053,6123,6124],{},"st := memstore.New()\n",[1053,6126,6127],{"class":1055,"line":16},[1053,6128,6129],{},"snk := sinknoop.New()\n",[1053,6131,6132],{"class":1055,"line":22},[1053,6133,6134],{},"ex := flowexec.New(flowexec.Options{Engine: eng, Sink: snk})\n",[974,6136,6137],{},"This keeps flowexec usable in serverless or test scenarios where MongoDB is not available.",[974,6139,6140,6141,1921],{},"For HTTP endpoints, SSE event streaming, and framework integration, see the\n",[986,6142,6144],{"href":6143},"\u002Fdocs\u002Freference\u002Fgo-modules-addons#flowexec","flowexec addon module",[1502,6146,6148,6151],{"id":6147},"metrics-live-rollups-slos-recommendations-metrics",[978,6149,6150],{},"metrics"," — live rollups, SLOs, recommendations {#metrics}",[974,6153,6154,6157,6158,6162,6163,6166],{},[978,6155,6156],{},"flowexec\u002Fmetrics"," is the aggregation layer that powers Flow Studio's\n",[986,6159,6161],{"href":6160},"\u002Fdocs\u002Fguides\u002Fobservability#live-mode-aggregate-health","Live mode",". The runtime produces a\n",[978,6164,6165],{},"Frame"," per flow per tick (default 1 s); subscribers receive the current frame over SSE and an\noptional archival sink persists frames to ClickHouse.",[1032,6168,6170],{"className":1094,"code":6169,"language":1059,"meta":1040,"style":1040},"type Frame struct {\n    Ts          time.Time\n    WindowMs    int64\n    Meta        Meta                          \u002F\u002F tenantId, flowId, versionHash, assistantId, userId\n    Nodes       map[string]NodeMetrics        \u002F\u002F per-node rollup, keyed by nodeId\n    Edges       map[string]EdgeMetrics        \u002F\u002F per-edge rollup, keyed by \"${from}__${to}\"\n    Channels    map[string]ChannelMetrics     \u002F\u002F per-transport backend (kafka lag, redis depth, …)\n    Suggestions []Suggestion                  \u002F\u002F server-evaluated rule output\n}\n",[978,6171,6172,6177,6182,6187,6192,6197,6202,6207,6212],{"__ignoreMap":1040},[1053,6173,6174],{"class":1055,"line":10},[1053,6175,6176],{},"type Frame struct {\n",[1053,6178,6179],{"class":1055,"line":16},[1053,6180,6181],{},"    Ts          time.Time\n",[1053,6183,6184],{"class":1055,"line":22},[1053,6185,6186],{},"    WindowMs    int64\n",[1053,6188,6189],{"class":1055,"line":51},[1053,6190,6191],{},"    Meta        Meta                          \u002F\u002F tenantId, flowId, versionHash, assistantId, userId\n",[1053,6193,6194],{"class":1055,"line":57},[1053,6195,6196],{},"    Nodes       map[string]NodeMetrics        \u002F\u002F per-node rollup, keyed by nodeId\n",[1053,6198,6199],{"class":1055,"line":102},[1053,6200,6201],{},"    Edges       map[string]EdgeMetrics        \u002F\u002F per-edge rollup, keyed by \"${from}__${to}\"\n",[1053,6203,6204],{"class":1055,"line":108},[1053,6205,6206],{},"    Channels    map[string]ChannelMetrics     \u002F\u002F per-transport backend (kafka lag, redis depth, …)\n",[1053,6208,6209],{"class":1055,"line":114},[1053,6210,6211],{},"    Suggestions []Suggestion                  \u002F\u002F server-evaluated rule output\n",[1053,6213,6214],{"class":1055,"line":120},[1053,6215,1637],{},[974,6217,6218,5786,6221,6224,6225,4608,6228,6231,6232,4117,6235,6238,6239,6242,6243,6246,6247,6250,6251,6254],{},[978,6219,6220],{},"NodeMetrics",[989,6222,6223],{},"two cadences"," side-by-side: ",[978,6226,6227],{},"Completed",[978,6229,6230],{},"Failed"," reset every frame (drives rate + error-rate), while\n",[978,6233,6234],{},"CompletedTotal",[978,6236,6237],{},"FailedTotal"," are monotonically-increasing counters\nsince aggregator boot. The Studio canvas chips show both — the rate\nfirst, then a ",[978,6240,6241],{},"Σ"," total so users can tell at a glance how many packets\na node has handled since Live mode started. ",[978,6244,6245],{},"EdgeMetrics"," follows the\nsame pattern with ",[978,6248,6249],{},"Delivered"," (window) and ",[978,6252,6253],{},"DeliveredTotal"," (cumulative).",[974,6256,6257,6260,6261,6263,6264,6267,6268,6270],{},[989,6258,6259],{},"Identity"," rides on ",[978,6262,5816],{},", never on routing metadata. Topic names, collection names, and\nClickHouse table names stay content-agnostic; multi-tenant deployments filter on ",[978,6265,6266],{},"meta.tenantId","\non the read side. Future Kafka\u002FNATS exporters carry ",[978,6269,5816],{}," as message headers.",[1032,6272,6274],{"className":1094,"code":6273,"language":1059,"meta":1040,"style":1040},"type MetricsSink interface {\n    RecordFrame(ctx context.Context, frame Frame) error\n    ListFrames(ctx context.Context, flowID string, since time.Time, limit int) ([]Frame, error)\n    Subscribe(flowID string, buf int) (\u003C-chan Frame, func())\n}\n",[978,6275,6276,6281,6286,6291,6296],{"__ignoreMap":1040},[1053,6277,6278],{"class":1055,"line":10},[1053,6279,6280],{},"type MetricsSink interface {\n",[1053,6282,6283],{"class":1055,"line":16},[1053,6284,6285],{},"    RecordFrame(ctx context.Context, frame Frame) error\n",[1053,6287,6288],{"class":1055,"line":22},[1053,6289,6290],{},"    ListFrames(ctx context.Context, flowID string, since time.Time, limit int) ([]Frame, error)\n",[1053,6292,6293],{"class":1055,"line":51},[1053,6294,6295],{},"    Subscribe(flowID string, buf int) (\u003C-chan Frame, func())\n",[1053,6297,6298],{"class":1055,"line":57},[1053,6299,1637],{},[974,6301,6302],{},"Implementations:",[1193,6304,6305,6313],{},[1196,6306,6307],{},[1199,6308,6309,6311],{},[1202,6310,5866],{},[1202,6312,5438],{},[1209,6314,6315,6325,6343],{},[1199,6316,6317,6322],{},[1214,6318,6319],{},[978,6320,6321],{},"metrics\u002Finproc",[1214,6323,6324],{},"Always-on aggregator. Per-flow mutex on the hot path, 5-minute ring buffer, non-blocking fan-out to SSE subscribers. Default tick 1 s, default ring size 300 frames.",[1199,6326,6327,6332],{},[1214,6328,6329],{},[978,6330,6331],{},"metrics\u002Fclickhouse",[1214,6333,6334,6335,6338,6339,6342],{},"Batched archival sink. Frames fan out to flat ",[978,6336,6337],{},"Row","s (one per node\u002Fedge\u002Fchannel); ",[978,6340,6341],{},"Driver"," interface isolates the network call so drivers ship separately. Safe to wire with empty URL (returns nil sink).",[1199,6344,6345,6350],{},[1214,6346,6347],{},[978,6348,6349],{},"metrics\u002Frules",[1214,6351,6352,6353,6356],{},"Server-side recommendation engine. Stateless ",[978,6354,6355],{},"Apply(frame, workflow) []Suggestion",". Seven baseline rules covering capacity, reliability, SLOs, transport upgrades, backpressure.",[974,6358,6359,1664,6362,6365,6366,6369,6370,1268,6373,3369,6376,6379,6380,6382,6383,6385,6386,6389,6390,6393],{},[989,6360,6361],{},"Executor integration.",[978,6363,6364],{},"flowexec.Options"," gained a ",[978,6367,6368],{},"Metrics MetricsRecorder"," field — any\nsink that implements ",[978,6371,6372],{},"RecordEvent(ev)",[978,6374,6375],{},"RegisterEdges(flowID, meta, keys)",[978,6377,6378],{},"RegisterEdgeMode(flowID, key, mode)",". When set, every ",[978,6381,5785],{}," the Executor emits is also\nhanded to the aggregator (same emit closure, so ",[978,6384,5803],{}," ordering is preserved). Before a run\nfires, ",[978,6387,6388],{},"RegisterEdges"," pre-seeds the flow's edge keys so empty edges render at 0\u002Fs and the rule\nengine has each edge's ",[978,6391,6392],{},"DeliveryMode"," to reason about.",[1032,6395,6397],{"className":1094,"code":6396,"language":1059,"meta":1040,"style":1040},"agg := inproc.New(inproc.Options{TickInterval: time.Second, Downstream: chSink})\nagg.Start(ctx)\nex := flowexec.New(flowexec.Options{Engine: eng, Sink: bcast, Metrics: agg})\n",[978,6398,6399,6404,6409],{"__ignoreMap":1040},[1053,6400,6401],{"class":1055,"line":10},[1053,6402,6403],{},"agg := inproc.New(inproc.Options{TickInterval: time.Second, Downstream: chSink})\n",[1053,6405,6406],{"class":1055,"line":16},[1053,6407,6408],{},"agg.Start(ctx)\n",[1053,6410,6411],{"class":1055,"line":22},[1053,6412,6413],{},"ex := flowexec.New(flowexec.Options{Engine: eng, Sink: bcast, Metrics: agg})\n",[974,6415,6416,1664,6419,6422,6423,6426],{},[989,6417,6418],{},"SLOs as first-class IR fields.",[978,6420,6421],{},"ir.Node.SLO"," declares per-node service-level objectives\nthat the ",[978,6424,6425],{},"rules"," package enforces:",[1032,6428,6430],{"className":1094,"code":6429,"language":1059,"meta":1040,"style":1040},"type NodeSLO struct {\n    P95LatencyMs  int64   \u002F\u002F hard ceiling on p95 latency (ms)\n    MaxErrorRate  float64 \u002F\u002F upper bound on failures \u002F total (0..1)\n    MaxSaturation float64 \u002F\u002F upper bound on (inflight \u002F capacity)\n}\n",[978,6431,6432,6437,6442,6447,6452],{"__ignoreMap":1040},[1053,6433,6434],{"class":1055,"line":10},[1053,6435,6436],{},"type NodeSLO struct {\n",[1053,6438,6439],{"class":1055,"line":16},[1053,6440,6441],{},"    P95LatencyMs  int64   \u002F\u002F hard ceiling on p95 latency (ms)\n",[1053,6443,6444],{"class":1055,"line":22},[1053,6445,6446],{},"    MaxErrorRate  float64 \u002F\u002F upper bound on failures \u002F total (0..1)\n",[1053,6448,6449],{"class":1055,"line":51},[1053,6450,6451],{},"    MaxSaturation float64 \u002F\u002F upper bound on (inflight \u002F capacity)\n",[1053,6453,6454],{"class":1055,"line":57},[1053,6455,1637],{},[974,6457,6458,6459,6462,6463,6466,6467,1921],{},"Zero on any field means \"no SLO on that dimension\". Breaches fire a ",[978,6460,6461],{},"slo","-kind ",[978,6464,6465],{},"Suggestion","\nwith severity ",[978,6468,6469],{},"critical",[974,6471,6472,6473,6475],{},"See ",[986,6474,111],{"href":112}," for the user-facing walkthrough,\nwire format, and canvas rendering.",[1502,6477,6479],{"id":6478},"cross-container-live-metrics-fan-out","Cross-container live-metrics fan-out",[974,6481,6482,6483,6486,6487,6490,6491,1676],{},"In multi-container deployments, any ",[978,6484,6485],{},"api"," container can run a flow but only the\n",[978,6488,6489],{},"admin-api"," container serves the Studio Live SSE. The two are bridged through\nthe ",[986,6492,6493],{"href":244},"Coordination layer",[1193,6495,6496,6508],{},[1196,6497,6498],{},[1199,6499,6500,6503,6505],{},[1202,6501,6502],{},"Component",[1202,6504,2012],{},[1202,6506,6507],{},"Role",[1209,6509,6510,6540,6557],{},[1199,6511,6512,6517,6522],{},[1214,6513,6514],{},[978,6515,6516],{},"coordFrameSink",[1214,6518,6519],{},[978,6520,6521],{},"flowexec\u002Fmodule\u002Fcoord_forward.go",[1214,6523,6524,6525,6528,6529,6532,6533,6536,6537,1921],{},"Wraps ",[978,6526,6527],{},"inproc.Sink","; writes every flushed ",[978,6530,6531],{},"metrics.Frame"," to the coord stream ",[978,6534,6535],{},"live:\u003CflowID>"," via ",[978,6538,6539],{},"Coordinator.AppendStream",[1199,6541,6542,6547,6550],{},[1214,6543,6544],{},[978,6545,6546],{},"frameHasSignal",[1214,6548,6549],{},"same file",[1214,6551,6552,6553,6556],{},"Producer-side filter. Drops frames with no node activity, no edge traffic, and no ",[978,6554,6555],{},"versionHash"," so idle aggregators in containers not running the flow don't pollute the stream.",[1199,6558,6559,6564,6569],{},[1214,6560,6561],{},[978,6562,6563],{},"handleFlowLiveSSE",[1214,6565,6566],{},[978,6567,6568],{},"flowexec\u002Fmodule\u002Fadmin\u002Fadmin.go",[1214,6570,6571,6572,6575,6576,6579],{},"SSE handler on ",[978,6573,6574],{},"GET \u002Fflows\u002F{id}\u002Flive",". Reads from ",[978,6577,6578],{},"Coordinator.ReadStream(ctx, \"live:\"+flowID, StreamEnd)"," when a Coordinator is wired; falls back to the local in-proc aggregator otherwise.",[974,6581,6582],{},"The module is safe on a single-container setup: with no Coordinator the sink is\na pass-through and the SSE handler reads directly from its own aggregator.",[974,6584,6585,1664,6588,6590],{},[989,6586,6587],{},"Instant first paint.",[978,6589,6563],{}," now emits a topology-only seed\nframe the moment the SSE connection opens — zeroed counters for every node and\nedge pulled straight from the published workflow. The Studio canvas therefore\nrenders every badge immediately instead of waiting up to one flush tick plus\ncoord propagation (~1-3 s). Subsequent real frames overwrite the seed.",[974,6592,6593,6596,6597,6600,6601,6604],{},[989,6594,6595],{},"Staleness watchdog."," Each live connection runs a forwarder goroutine\n(",[978,6598,6599],{},"runCoordForwarder",") that re-opens the coord reader after ",[978,6602,6603],{},"coordIdleTimeout","\nseconds of silence (default 45 s). This is the defense against NATS\nOrderedConsumer stalls, transient broker hiccups, or any issue that silently\nstops delivering messages without closing the subscription. The HTTP response\nstream stays up the whole time — only the coord reader is swapped — so the\nStudio widget never sees a disconnect.",[974,6606,6607,1664,6610,6613,6614,6617,6618,6621,6622,6626],{},[989,6608,6609],{},"Per-producer attribution.",[978,6611,6612],{},"metrics.Meta.InstanceID"," is stamped onto every\nemitted frame with the value of ",[978,6615,6616],{},"HOSTNAME"," (Docker sets this to the container\nid) or ",[978,6619,6620],{},"os.Hostname"," as a fallback. Admin-api can use this to tell \"how many\ncontainers are reporting for this flow\" and is the hook for the planned\n",[986,6623,6625],{"href":6624},"#multi-container-aggregation-planned","multi-container aggregator"," that will\nsum window counters across producers per tick.",[1502,6628,6630],{"id":6629},"multi-container-aggregation-planned","Multi-container aggregation (planned)",[974,6632,6633,6634,6636],{},"Today the admin-api SSE handler forwards frames from every container as-is.\nIn a deployment where multiple ",[978,6635,6485],{}," containers run the same flow, the Studio\ncanvas sees frames from each container in turn — each carries only that\ncontainer's window counters. A canvas that wants the global rate must sum\nthe window counters from all containers for the same tick.",[974,6638,6639],{},"Planned design:",[3997,6641,6642,6648,6651,6658],{},[1845,6643,6644,6645,1921],{},"Admin-api maintains a small in-memory map ",[978,6646,6647],{},"(flowID, tickSecond) → aggregatedFrame",[1845,6649,6650],{},"Incoming coord frames are matched to the map by rounded timestamp (1 s\ngranularity) and added: window counters sum, totals sum, inflight sums,\nlatency percentiles merge via weighted mean (approximate — exact quantile\nmerging needs t-digest or similar).",[1845,6652,6653,6654,6657],{},"When a frame from every known ",[978,6655,6656],{},"InstanceID"," has arrived for a tick (or a\nshort timeout expires), the aggregate is flushed to the SSE client.",[1845,6659,6660,6661,6664],{},"InstanceID list is discovered from the frames themselves — first-seen\nper ",[978,6662,6663],{},"(flowID, 5-minute window)"," — so scale-out happens automatically.",[974,6666,6667,6668,6670,6671,6674],{},"Groundwork in this release: ",[978,6669,6656],{}," on ",[978,6672,6673],{},"metrics.Meta",". Aggregator layer\nitself is not yet implemented — follow-up work.",[1082,6676,6678],{"id":6677},"module-http-surface-public-vs-admin","Module HTTP surface — public vs admin",[974,6680,6681,6684,6685,6688,6689,6692,6693,6696,6697,6699],{},[978,6682,6683],{},"flowexec\u002Fmodule\u002Fmodule.go"," registers the executor, metrics aggregator, template\nprovider, and usage sink — ",[989,6686,6687],{},"but no HTTP routes",". Every flow \u002F run \u002F deployment\nendpoint lives in ",[978,6690,6691],{},"flowexec\u002Fmodule\u002Fadmin"," (",[978,6694,6695],{},"id: flowexec-admin",", depends on\n",[978,6698,4603],{},"). Blank-import the admin companion only in admin-api:",[1032,6701,6703],{"className":1094,"code":6702,"language":1059,"meta":1040,"style":1040},"\u002F\u002F cmd\u002Fadmin-api admin_imports.go\nimport _ \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fflowexec\u002Fmodule\u002Fadmin\"\n",[978,6704,6705,6710],{"__ignoreMap":1040},[1053,6706,6707],{"class":1055,"line":10},[1053,6708,6709],{},"\u002F\u002F cmd\u002Fadmin-api admin_imports.go\n",[1053,6711,6712],{"class":1055,"line":16},[1053,6713,6714],{},"import _ \"github.com\u002Fredelay\u002Fgo-flowdsl\u002Fflowexec\u002Fmodule\u002Fadmin\"\n",[974,6716,6717,6718,6721,6722,1268,6725,6728,6729,6731,6732,1921],{},"This means ",[978,6719,6720],{},"cmd\u002Fapi"," can run flows (the engine + sinks are registered by the\ncore module) but its public HTTP surface carries zero ",[978,6723,6724],{},"\u002Fflows",[978,6726,6727],{},"\u002Fruns",", or\n",[978,6730,5450],{}," paths. The regression is locked in by\n",[986,6733,6735],{"href":6734},"\u002Fdocs\u002Freference\u002Fgo-framework#testing-ci-guardrails",[978,6736,6737],{},"TestOpenAPIHasNoFlowAdminPaths",[974,6739,6740,6741,6744,6745,6748,6749,6752,6753,5648],{},"All admin routes are gated on ",[978,6742,6743],{},"auth.RequireActiveUser + auth.RequirePermission(\"admin:access\")","\nand sit under ",[978,6746,6747],{},"modules.AdminPrefix()"," (default ",[978,6750,6751],{},"\u002Fadmin",", override via\n",[978,6754,6755],{},"ADMIN_ROUTE_PREFIX",[974,6757,6758],{},"Full route table — flows + versions + runs + live + deployments, all in the\nadmin companion:",[1193,6760,6761,6771],{},[1196,6762,6763],{},[1199,6764,6765,6767,6769],{},[1202,6766,5432],{},[1202,6768,5435],{},[1202,6770,5438],{},[1209,6772,6773,6784,6795,6807,6818,6829,6841,6860,6872,6884,6896,6908,6920,6932,6948,6960,6971,6983,6995,7007,7022,7034,7045,7056,7067,7077,7088],{},[1199,6774,6775,6777,6781],{},[1214,6776,5445],{},[1214,6778,6779],{},[978,6780,6724],{},[1214,6782,6783],{},"List flows (cursor pagination)",[1199,6785,6786,6788,6792],{},[1214,6787,5458],{},[1214,6789,6790],{},[978,6791,6724],{},[1214,6793,6794],{},"Create flow",[1199,6796,6797,6799,6804],{},[1214,6798,5445],{},[1214,6800,6801],{},[978,6802,6803],{},"\u002Fflows\u002F{id}",[1214,6805,6806],{},"Read flow",[1199,6808,6809,6811,6815],{},[1214,6810,5482],{},[1214,6812,6813],{},[978,6814,6803],{},[1214,6816,6817],{},"Update name \u002F description \u002F labels",[1199,6819,6820,6822,6826],{},[1214,6821,5494],{},[1214,6823,6824],{},[978,6825,6803],{},[1214,6827,6828],{},"Delete flow",[1199,6830,6831,6833,6838],{},[1214,6832,5445],{},[1214,6834,6835],{},[978,6836,6837],{},"\u002Fflows\u002F{id}\u002Fversions",[1214,6839,6840],{},"List versions",[1199,6842,6843,6845,6849],{},[1214,6844,5458],{},[1214,6846,6847],{},[978,6848,6837],{},[1214,6850,6851,6852,6855,6856,6859],{},"Save a new version (supports ",[978,6853,6854],{},"?format=spec"," for Studio-native ",[978,6857,6858],{},"spec.Document"," bodies)",[1199,6861,6862,6864,6869],{},[1214,6863,5445],{},[1214,6865,6866],{},[978,6867,6868],{},"\u002Fflows\u002F{id}\u002Fversions\u002F{vid}",[1214,6870,6871],{},"Read a version",[1199,6873,6874,6876,6881],{},[1214,6875,5458],{},[1214,6877,6878],{},[978,6879,6880],{},"\u002Fflows\u002F{id}\u002Fpublish",[1214,6882,6883],{},"Publish a version or set weighted variants",[1199,6885,6886,6888,6893],{},[1214,6887,5458],{},[1214,6889,6890],{},[978,6891,6892],{},"\u002Fflows\u002F{id}\u002Frollback",[1214,6894,6895],{},"Rollback to a prior published version",[1199,6897,6898,6900,6905],{},[1214,6899,5445],{},[1214,6901,6902],{},[978,6903,6904],{},"\u002Fflows\u002F{id}\u002Froute",[1214,6906,6907],{},"Read the currently-published route \u002F variants",[1199,6909,6910,6912,6917],{},[1214,6911,5445],{},[1214,6913,6914],{},[978,6915,6916],{},"\u002Fflows\u002F{id}\u002Fpublish-history",[1214,6918,6919],{},"Audit log of publish actions",[1199,6921,6922,6924,6929],{},[1214,6923,5445],{},[1214,6925,6926],{},[978,6927,6928],{},"\u002Fflows\u002Ftemplates",[1214,6930,6931],{},"List embedded + module-contributed templates",[1199,6933,6934,6936,6941],{},[1214,6935,5445],{},[1214,6937,6938],{},[978,6939,6940],{},"\u002Fflows\u002Ftemplates\u002F*",[1214,6942,6943,6944,6947],{},"Read one template (",[978,6945,6946],{},"id"," may contain slashes)",[1199,6949,6950,6952,6957],{},[1214,6951,5458],{},[1214,6953,6954],{},[978,6955,6956],{},"\u002Fflows\u002F{id}\u002Fruns",[1214,6958,6959],{},"Launch a run",[1199,6961,6962,6964,6968],{},[1214,6963,5445],{},[1214,6965,6966],{},[978,6967,6956],{},[1214,6969,6970],{},"List runs for the flow (cursor pagination)",[1199,6972,6973,6975,6980],{},[1214,6974,5445],{},[1214,6976,6977],{},[978,6978,6979],{},"\u002Fruns\u002F{runID}",[1214,6981,6982],{},"Read one run",[1199,6984,6985,6987,6992],{},[1214,6986,5445],{},[1214,6988,6989],{},[978,6990,6991],{},"\u002Fruns\u002F{runID}\u002Fevents",[1214,6993,6994],{},"SSE stream of run events",[1199,6996,6997,6999,7004],{},[1214,6998,5445],{},[1214,7000,7001],{},[978,7002,7003],{},"\u002Fruns\u002F{runID}\u002Fevents\u002Fhistory",[1214,7005,7006],{},"Historical event replay",[1199,7008,7009,7011,7016],{},[1214,7010,5445],{},[1214,7012,7013],{},[978,7014,7015],{},"\u002Fflows\u002F{id}\u002Flive",[1214,7017,7018,7019,7021],{},"SSE stream of live ",[978,7020,6531],{}," rollups",[1199,7023,7024,7026,7031],{},[1214,7025,5445],{},[1214,7027,7028],{},[978,7029,7030],{},"\u002Fflows\u002F{id}\u002Fmetrics\u002Fhistory",[1214,7032,7033],{},"Historical frames",[1199,7035,7036,7038,7042],{},[1214,7037,5445],{},[1214,7039,7040],{},[978,7041,5450],{},[1214,7043,7044],{},"List deployments",[1199,7046,7047,7049,7053],{},[1214,7048,5458],{},[1214,7050,7051],{},[978,7052,5450],{},[1214,7054,7055],{},"Create deployment",[1199,7057,7058,7060,7064],{},[1214,7059,5445],{},[1214,7061,7062],{},[978,7063,5474],{},[1214,7065,7066],{},"Read deployment",[1199,7068,7069,7071,7075],{},[1214,7070,5482],{},[1214,7072,7073],{},[978,7074,5474],{},[1214,7076,5489],{},[1199,7078,7079,7081,7085],{},[1214,7080,5494],{},[1214,7082,7083],{},[978,7084,5474],{},[1214,7086,7087],{},"Delete deployment (flows untouched)",[1199,7089,7090,7092,7096],{},[1214,7091,5458],{},[1214,7093,7094],{},[978,7095,5510],{},[1214,7097,7098],{},"Provision + publish + bind in one call",[1082,7100,7102],{"id":7101},"auto-generation-of-subworkflow-nodes-auto-generation-of-subworkflow-nodes","Auto-generation of subworkflow nodes {#auto-generation-of-subworkflow-nodes}",[974,7104,7105,7106,7108,7109,7111,7112,7115],{},"The go-framework module registry automatically generates subworkflow ",[978,7107,1487],{}," entries for\nany module that provides workflows via ",[978,7110,1876],{},". This means modules only need to\nimplement ",[978,7113,7114],{},"FlowDSLFragments()"," — the corresponding node definitions are created at runtime.",[974,7117,7118,7119,7122,7123,7125,7126,7128,7129,7132],{},"The auto-generation runs inside ",[978,7120,7121],{},"Registry.IRModules()"," after collecting both workflows and\nexplicit nodes. For each workflow, it checks whether a ",[978,7124,1487],{}," with a matching\n",[978,7127,1653],{}," already exists. If not, it calls ",[978,7130,7131],{},"ir.SubworkflowNodeFromWorkflow()"," to generate\none automatically.",[974,7134,7135],{},"This ensures:",[1842,7137,7138,7145,7153],{},[1845,7139,7140,7141,7144],{},"Every module workflow is visible in ",[978,7142,7143],{},"\u002Fmodules.json"," and the module browser UI",[1845,7146,7147,7148,7150,7151],{},"Modules can override auto-generated nodes by providing an explicit ",[978,7149,1487],{}," with the same ",[978,7152,1653],{},[1845,7154,7155],{},"The module browser shows step count and workflow reference for subworkflow nodes",[1082,7157,7159],{"id":7158},"flowdsl-node-subpackage-pattern-flowdsl-node-subpackages","FlowDSL node subpackage pattern {#flowdsl-node-subpackages}",[974,7161,7162,7163,7166],{},"Modules that export FlowDSL nodes use a ",[978,7164,7165],{},"flowdsl\u002F"," subdirectory that registers as a separate\ncompanion module. This keeps the FlowDSL node YAML definitions and registration code isolated\nfrom the core module logic.",[974,7168,7169],{},"Each subpackage has four files:",[1193,7171,7172,7180],{},[1196,7173,7174],{},[1199,7175,7176,7178],{},[1202,7177,2012],{},[1202,7179,5438],{},[1209,7181,7182,7194,7209,7227],{},[1199,7183,7184,7188],{},[1214,7185,7186],{},[978,7187,1675],{},[1214,7189,7190,7191,4121],{},"Node definitions (embedded via ",[978,7192,7193],{},"go:embed",[1199,7195,7196,7201],{},[1214,7197,7198],{},[978,7199,7200],{},"ir.go",[1214,7202,7203,5247,7206],{},[978,7204,7205],{},"\u002F\u002Fgo:embed module.yaml",[978,7207,7208],{},"var moduleYAML []byte",[1199,7210,7211,7215],{},[1214,7212,7213],{},[978,7214,3365],{},[1214,7216,7217,7220,7221,7223,7224],{},[978,7218,7219],{},"init()"," factory + ",[978,7222,1228],{}," struct embedding ",[978,7225,7226],{},"modules.IRBase",[1199,7228,7229,7234],{},[1214,7230,7231],{},[978,7232,7233],{},"module_test.go",[1214,7235,7236],{},"Factory registration, manifest, node catalog, kind checks",[974,7238,7239],{},"Opt-in via blank import alongside the parent module:",[1032,7241,7243],{"className":1094,"code":7242,"language":1059,"meta":1040,"style":1040},"import (\n    _ \"github.com\u002Fredelay\u002Fgo-framework\u002Fmodules\u002Fauth\"         \u002F\u002F core module\n    _ \"github.com\u002Fredelay\u002Fgo-framework\u002Fmodules\u002Fauth\u002Fflowdsl\"  \u002F\u002F FlowDSL nodes\n)\n",[978,7244,7245,7250,7255,7260],{"__ignoreMap":1040},[1053,7246,7247],{"class":1055,"line":10},[1053,7248,7249],{},"import (\n",[1053,7251,7252],{"class":1055,"line":16},[1053,7253,7254],{},"    _ \"github.com\u002Fredelay\u002Fgo-framework\u002Fmodules\u002Fauth\"         \u002F\u002F core module\n",[1053,7256,7257],{"class":1055,"line":22},[1053,7258,7259],{},"    _ \"github.com\u002Fredelay\u002Fgo-framework\u002Fmodules\u002Fauth\u002Fflowdsl\"  \u002F\u002F FlowDSL nodes\n",[1053,7261,7262],{"class":1055,"line":51},[1053,7263,4656],{},[974,7265,7266],{},[989,7267,7268],{},"Node catalog by repository:",[974,7270,7271],{},"go-framework:",[1193,7273,7274,7290],{},[1196,7275,7276],{},[1199,7277,7278,7281,7284,7287],{},[1202,7279,7280],{},"Subpackage",[1202,7282,7283],{},"Factory",[1202,7285,7286],{},"Nodes",[1202,7288,7289],{},"Kinds",[1209,7291,7292,7310,7328],{},[1199,7293,7294,7299,7304,7307],{},[1214,7295,7296],{},[978,7297,7298],{},"modules\u002Fauth\u002Fflowdsl",[1214,7300,7301],{},[978,7302,7303],{},"auth-flowdsl",[1214,7305,7306],{},"7",[1214,7308,7309],{},"1 action, 1 transform, 1 router, 4 source",[1199,7311,7312,7317,7322,7325],{},[1214,7313,7314],{},[978,7315,7316],{},"modules\u002Fusers\u002Fflowdsl",[1214,7318,7319],{},[978,7320,7321],{},"users-flowdsl",[1214,7323,7324],{},"8",[1214,7326,7327],{},"3 action, 2 transform, 3 source",[1199,7329,7330,7335,7340,7342],{},[1214,7331,7332],{},[978,7333,7334],{},"modules\u002Fgroups\u002Fflowdsl",[1214,7336,7337],{},[978,7338,7339],{},"groups-flowdsl",[1214,7341,7306],{},[1214,7343,7344],{},"3 action, 1 transform, 3 source",[974,7346,7347],{},"go-modules:",[1193,7349,7350,7362],{},[1196,7351,7352],{},[1199,7353,7354,7356,7358,7360],{},[1202,7355,7280],{},[1202,7357,7283],{},[1202,7359,7286],{},[1202,7361,7289],{},[1209,7363,7364,7382,7400,7417,7434,7452],{},[1199,7365,7366,7371,7376,7379],{},[1214,7367,7368],{},[978,7369,7370],{},"scheduler\u002Fflowdsl",[1214,7372,7373],{},[978,7374,7375],{},"scheduler-flowdsl",[1214,7377,7378],{},"4",[1214,7380,7381],{},"2 source (with settings_schema), 2 action",[1199,7383,7384,7389,7394,7397],{},[1214,7385,7386],{},[978,7387,7388],{},"settings\u002Fflowdsl",[1214,7390,7391],{},[978,7392,7393],{},"settings-flowdsl",[1214,7395,7396],{},"3",[1214,7398,7399],{},"1 transform (with NotFound), 2 action",[1199,7401,7402,7407,7412,7414],{},[1214,7403,7404],{},[978,7405,7406],{},"storage\u002Fflowdsl",[1214,7408,7409],{},[978,7410,7411],{},"storage-flowdsl",[1214,7413,7378],{},[1214,7415,7416],{},"2 action, 2 transform (1 NotFound, 1 settings_schema)",[1199,7418,7419,7424,7429,7431],{},[1214,7420,7421],{},[978,7422,7423],{},"notifications\u002Fflowdsl",[1214,7425,7426],{},[978,7427,7428],{},"notifications-flowdsl",[1214,7430,7396],{},[1214,7432,7433],{},"2 action, 1 source",[1199,7435,7436,7441,7446,7449],{},[1214,7437,7438],{},[978,7439,7440],{},"verification\u002Fflowdsl",[1214,7442,7443],{},[978,7444,7445],{},"verification-flowdsl",[1214,7447,7448],{},"2",[1214,7450,7451],{},"1 action, 1 router (Valid\u002FInvalid)",[1199,7453,7454,7459,7464,7466],{},[1214,7455,7456],{},[978,7457,7458],{},"links\u002Fflowdsl",[1214,7460,7461],{},[978,7462,7463],{},"links-flowdsl",[1214,7465,7396],{},[1214,7467,7468],{},"2 action, 1 transform (with NotFound)",[974,7470,7471],{},"go-module-email:",[1193,7473,7474,7486],{},[1196,7475,7476],{},[1199,7477,7478,7480,7482,7484],{},[1202,7479,7280],{},[1202,7481,7283],{},[1202,7483,7286],{},[1202,7485,7289],{},[1209,7487,7488],{},[1199,7489,7490,7494,7499,7501],{},[1214,7491,7492],{},[978,7493,2483],{},[1214,7495,7496],{},[978,7497,7498],{},"email-flowdsl",[1214,7500,7378],{},[1214,7502,7503],{},"2 action, 1 transform, 1 source",[1082,7505,7507],{"id":7506},"flowdsl-sdk-dependency","FlowDSL SDK dependency",[974,7509,7510,7512,7513,7515,7516,7519,7520,3293,7522,7524],{},[978,7511,1000],{}," depends on the FlowDSL Go SDK (",[978,7514,1920],{},") for canonical\nnode manifest types. The SDK provides zero-dependency types in ",[978,7517,7518],{},"pkg\u002Fnode"," (manifest, ports,\nsettings schema) that both ",[978,7521,1087],{},[978,7523,3412],{}," packages use for manifest generation and\nconversion.",[1032,7526,7529],{"className":7527,"code":7528,"language":1037},[1035],"github.com\u002Fflowdsl\u002Fflowdsl-go    ← zero-dep canonical types\n       ↑\ngithub.com\u002Fredelay\u002Fgo-flowdsl    ← IR layer + code generation\n       ↑\ngithub.com\u002Fredelay\u002Fgo-framework  ← module registry + modspec browser\n",[978,7530,7528],{"__ignoreMap":1040},[993,7532,7534,7537],{"id":7533},"cmdflowdsl-cli",[978,7535,7536],{},"cmd\u002Fflowdsl"," — CLI",[974,7539,7540,7541,7543],{},"The standalone ",[978,7542,2483],{}," CLI provides portable toolchain commands with no framework\ndependencies.",[974,7545,7546],{},[989,7547,7548],{},"Install:",[1032,7550,7552],{"className":1047,"code":7551,"language":1049,"meta":1040,"style":1040},"go install github.com\u002Fredelay\u002Fgo-flowdsl\u002Fcmd\u002Fflowdsl@latest\n",[978,7553,7554],{"__ignoreMap":1040},[1053,7555,7556,7558,7561],{"class":1055,"line":10},[1053,7557,1059],{"class":1058},[1053,7559,7560],{"class":1062}," install",[1053,7562,7563],{"class":1062}," github.com\u002Fredelay\u002Fgo-flowdsl\u002Fcmd\u002Fflowdsl@latest\n",[1082,7565,7567],{"id":7566},"commands","Commands",[1193,7569,7570,7578],{},[1196,7571,7572],{},[1199,7573,7574,7576],{},[1202,7575,1321],{},[1202,7577,1207],{},[1209,7579,7580,7590,7600,7610],{},[1199,7581,7582,7587],{},[1214,7583,7584],{},[978,7585,7586],{},"flowdsl validate \u003Cfile>",[1214,7588,7589],{},"Validate a FlowDSL YAML file; exit 1 on errors",[1199,7591,7592,7597],{},[1214,7593,7594],{},[978,7595,7596],{},"flowdsl gen \u003Cmodule.yaml> [-o outdir]",[1214,7598,7599],{},"Scaffold a Go module from IR module YAML",[1199,7601,7602,7607],{},[1214,7603,7604],{},[978,7605,7606],{},"flowdsl svg \u003Cmodule.yaml> [-o out.svg]",[1214,7608,7609],{},"Generate SVG diagram from IR module YAML",[1199,7611,7612,7617],{},[1214,7613,7614],{},[978,7615,7616],{},"flowdsl compile \u003Cfile> [-f format] [--out json|yaml]",[1214,7618,7619],{},"Compile to enriched IR document",[1502,7621,2073],{"id":2073},[1032,7623,7625],{"className":1047,"code":7624,"language":1049,"meta":1040,"style":1040},"flowdsl validate app.flow.yaml\n",[978,7626,7627],{"__ignoreMap":1040},[1053,7628,7629,7631,7634],{"class":1055,"line":10},[1053,7630,2483],{"class":1058},[1053,7632,7633],{"class":1062}," validate",[1053,7635,7636],{"class":1062}," app.flow.yaml\n",[974,7638,7639,7640,7643,7644,3813,7647,3813,7650,7653],{},"Parses the file and runs ",[978,7641,7642],{},"flowdsl.Validate",". Prints all diagnostics with ",[978,7645,7646],{},"[E]",[978,7648,7649],{},"[W]",[978,7651,7652],{},"[I]","\nprefixes. On success:",[1032,7655,7658],{"className":7656,"code":7657,"language":1037},[1035],"ok — no issues found\n",[978,7659,7657],{"__ignoreMap":1040},[974,7661,7662],{},"On failure (exit code 1):",[1032,7664,7667],{"className":7665,"code":7666,"language":1037},[1035],"[E] FDL010: event \"order_event\" has no entity_type\n[W] FDL002: version is empty\n",[978,7668,7666],{"__ignoreMap":1040},[1502,7670,7671],{"id":7671},"gen",[1032,7673,7675],{"className":1047,"code":7674,"language":1049,"meta":1040,"style":1040},"flowdsl gen modules\u002Forders.module.yaml -o .\u002Fmodules\u002Forders\u002F\n",[978,7676,7677],{"__ignoreMap":1040},[1053,7678,7679,7681,7684,7687,7690],{"class":1055,"line":10},[1053,7680,2483],{"class":1058},[1053,7682,7683],{"class":1062}," gen",[1053,7685,7686],{"class":1062}," modules\u002Forders.module.yaml",[1053,7688,7689],{"class":1062}," -o",[1053,7691,7692],{"class":1062}," .\u002Fmodules\u002Forders\u002F\n",[974,7694,7695,7696,7698,7699,7701,7702,7705],{},"Loads the ",[978,7697,3292],{}," YAML, validates it with ",[978,7700,3747],{},", then scaffolds Go source files via\n",[978,7703,7704],{},"modgen.Scaffold",". Prints each written file path. Existing files are not overwritten.",[1502,7707,7708],{"id":7708},"svg",[1032,7710,7712],{"className":1047,"code":7711,"language":1049,"meta":1040,"style":1040},"flowdsl svg modules\u002Fauth.module.yaml -o auth.svg\n",[978,7713,7714],{"__ignoreMap":1040},[1053,7715,7716,7718,7721,7724,7726],{"class":1055,"line":10},[1053,7717,2483],{"class":1058},[1053,7719,7720],{"class":1062}," svg",[1053,7722,7723],{"class":1062}," modules\u002Fauth.module.yaml",[1053,7725,7689],{"class":1062},[1053,7727,7728],{"class":1062}," auth.svg\n",[974,7730,7731,7732,7735],{},"Generates an SVG diagram and writes it to the specified file. Omit ",[978,7733,7734],{},"-o"," to write to stdout.",[1502,7737,3793],{"id":3793},[1032,7739,7741],{"className":1047,"code":7740,"language":1049,"meta":1040,"style":1040},"flowdsl compile app.flow.yaml                        # FlowDSL → IR as JSON (default)\nflowdsl compile app.flow.yaml --out yaml             # FlowDSL → IR as YAML\nflowdsl compile model.yaml -f businessmodel          # businessmodel → IR as JSON\n",[978,7742,7743,7756,7773],{"__ignoreMap":1040},[1053,7744,7745,7747,7750,7753],{"class":1055,"line":10},[1053,7746,2483],{"class":1058},[1053,7748,7749],{"class":1062}," compile",[1053,7751,7752],{"class":1062}," app.flow.yaml",[1053,7754,7755],{"class":4184},"                        # FlowDSL → IR as JSON (default)\n",[1053,7757,7758,7760,7762,7764,7767,7770],{"class":1055,"line":16},[1053,7759,2483],{"class":1058},[1053,7761,7749],{"class":1062},[1053,7763,7752],{"class":1062},[1053,7765,7766],{"class":1062}," --out",[1053,7768,7769],{"class":1062}," yaml",[1053,7771,7772],{"class":4184},"             # FlowDSL → IR as YAML\n",[1053,7774,7775,7777,7779,7782,7785,7788],{"class":1055,"line":22},[1053,7776,2483],{"class":1058},[1053,7778,7749],{"class":1062},[1053,7780,7781],{"class":1062}," model.yaml",[1053,7783,7784],{"class":1062}," -f",[1053,7786,7787],{"class":1062}," businessmodel",[1053,7789,7790],{"class":4184},"          # businessmodel → IR as JSON\n",[974,7792,7793,7794,7796],{},"Runs the full Import + Compile pipeline and writes the enriched ",[978,7795,3296],{}," to stdout.\nDiagnostics go to stderr. Exit code 1 if compilation errors occur.",[1193,7798,7799,7811],{},[1196,7800,7801],{},[1199,7802,7803,7806,7809],{},[1202,7804,7805],{},"Flag",[1202,7807,7808],{},"Default",[1202,7810,1207],{},[1209,7812,7813,7834],{},[1199,7814,7815,7823,7827],{},[1214,7816,7817,1268,7820],{},[978,7818,7819],{},"-f",[978,7821,7822],{},"--format",[1214,7824,7825],{},[978,7826,2483],{},[1214,7828,7829,7830,1866,7832],{},"Input format: ",[978,7831,2483],{},[978,7833,2152],{},[1199,7835,7836,7841,7845],{},[1214,7837,7838],{},[978,7839,7840],{},"--out",[1214,7842,7843],{},[978,7844,2069],{},[1214,7846,7847,7848,1866,7850],{},"Output format: ",[978,7849,2069],{},[978,7851,1681],{},[974,7853,7854,7855,1921],{},"For the heavier CLI with asyncapi\u002Fopenapi import, scaffold, audit, diff, and convert\ncommands, see the ",[986,7856,7857],{"href":170},"redelayctl reference",[7859,7860,7861],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":1040,"searchDepth":16,"depth":16,"links":7863},[7864,7865,7866,7867,7909],{"id":995,"depth":16,"text":5},{"id":1043,"depth":16,"text":1044},{"id":1069,"depth":16,"text":1070},{"id":1079,"depth":16,"text":1080,"children":7868},[7869,7871,7873,7875,7877,7879,7881,7883,7885,7887,7889,7891,7893,7895,7897,7899,7901,7903,7905,7906,7907,7908],{"id":1084,"depth":22,"text":7870},"ir — Canonical IR types",{"id":1924,"depth":22,"text":7872},"diagnostics — Structured error\u002Fwarning collector",{"id":2028,"depth":22,"text":7874},"schema — JSON Schema generator",{"id":2081,"depth":22,"text":7876},"metadata — IR metadata helpers",{"id":2149,"depth":22,"text":7878},"businessmodel — Business model parser",{"id":2183,"depth":22,"text":7880},"resolver — Module dependency resolver",{"id":2290,"depth":22,"text":7882},"validate — Structural validator",{"id":2480,"depth":22,"text":7884},"flowdsl — FlowDSL YAML parser",{"id":3282,"depth":22,"text":7886},"modfile — Module file I\u002FO",{"id":3352,"depth":22,"text":7888},"modgen — Go module scaffolder",{"id":3409,"depth":22,"text":7890},"nodegen — FlowDSL node generator",{"id":3653,"depth":22,"text":7892},"modsvg — SVG diagram generator",{"id":3689,"depth":22,"text":7894},"modsync — Drift detection",{"id":3744,"depth":22,"text":7896},"modval — Module YAML validator",{"id":3790,"depth":22,"text":7898},"compile — Base compile pipeline",{"id":4022,"depth":22,"text":7900},"runtime — Flow execution engine",{"id":4765,"depth":22,"text":7902},"spec — Studio spec document converters",{"id":5195,"depth":22,"text":7904},"flowexec — orchestration, storage, sinks {#flowexec}",{"id":6677,"depth":22,"text":6678},{"id":7101,"depth":22,"text":7102},{"id":7158,"depth":22,"text":7159},{"id":7506,"depth":22,"text":7507},{"id":7533,"depth":16,"text":7910,"children":7911},"cmd\u002Fflowdsl — CLI",[7912],{"id":7566,"depth":22,"text":7567},"API reference for go-flowdsl — FlowDSL parsing, validation, compilation, and code generation.","md",null,{},{"order":186,"icon":52},{"title":183,"description":7913},"vvOn3vdgU6I6zlIzce1CmE2jv4XqVTF8AHxP_8kIhCg",[7921,7923],{"title":178,"path":179,"stem":180,"description":7922,"order":181,"icon":152,"children":-1},"Auto-generated AsyncAPI 2.6 spec served with interactive AsyncAPI Studio UI.",{"title":188,"path":189,"stem":190,"description":7924,"order":191,"icon":192,"children":-1},"Real-world FlowDSL flow definitions — from minimal single-event services to multi-module pipelines.",1790332223783]