Skip to content

feat: add IaC derivation engine and YAML editing#778

Merged
intel352 merged 3 commits into
mainfrom
feat/iac-derive-engine
May 25, 2026
Merged

feat: add IaC derivation engine and YAML editing#778
intel352 merged 3 commits into
mainfrom
feat/iac-derive-engine

Conversation

@intel352
Copy link
Copy Markdown
Contributor

Summary

  • add yaml.Node-based module appending for derived IaC modules with comment/unknown-key preservation and idempotence by satisfies keys
  • add provider-neutral IaC derivation engine plus strict-proto provider mapper client adapter
  • add wfctl infra derive with dry-run/write modes, non-interactive failures, lightweight interactive provider selection, and docs

Verification

  • GOWORK=off go test ./config/yamledit ./iac/requirements ./iac/derive ./plugin/external/proto ./plugin/external/sdk ./plugin/external ./cmd/wfctl -count=1
  • GOWORK=off go vet ./config/yamledit ./iac/requirements ./iac/derive ./plugin/external/... ./cmd/wfctl
  • GOWORK=off golangci-lint run ./config/yamledit ./iac/requirements ./iac/derive ./plugin/external/... ./cmd/wfctl --timeout=10m
  • GOWORK=off go run ./cmd/wfctl infra derive --help

@codecov
Copy link
Copy Markdown

codecov Bot commented May 25, 2026

@github-actions
Copy link
Copy Markdown

⏱ Benchmark Results

No significant performance regressions detected.

benchstat comparison (baseline → PR)
## benchstat: baseline → PR
baseline-bench.txt:278: parsing iteration count: invalid syntax
baseline-bench.txt:315357: parsing iteration count: invalid syntax
baseline-bench.txt:576829: parsing iteration count: invalid syntax
baseline-bench.txt:907409: parsing iteration count: invalid syntax
baseline-bench.txt:1218822: parsing iteration count: invalid syntax
baseline-bench.txt:1494448: parsing iteration count: invalid syntax
benchmark-results.txt:282: parsing iteration count: invalid syntax
benchmark-results.txt:253120: parsing iteration count: invalid syntax
benchmark-results.txt:554966: parsing iteration count: invalid syntax
benchmark-results.txt:801702: parsing iteration count: invalid syntax
benchmark-results.txt:1047604: parsing iteration count: invalid syntax
benchmark-results.txt:1346855: parsing iteration count: invalid syntax
goos: linux
goarch: amd64
pkg: github.com/GoCodeAlone/workflow/dynamic
cpu: AMD EPYC 7763 64-Core Processor                
                            │ baseline-bench.txt │       benchmark-results.txt        │
                            │       sec/op       │    sec/op     vs base              │
InterpreterCreation-4               8.898m ± 65%   9.707m ± 67%       ~ (p=0.485 n=6)
ComponentLoad-4                     3.713m ±  3%   3.645m ±  0%  -1.83% (p=0.002 n=6)
ComponentExecute-4                  1.952µ ±  3%   1.946µ ±  1%       ~ (p=0.558 n=6)
PoolContention/workers-1-4          1.100µ ±  3%   1.096µ ±  3%       ~ (p=0.426 n=6)
PoolContention/workers-2-4          1.090µ ±  3%   1.091µ ±  4%       ~ (p=0.942 n=6)
PoolContention/workers-4-4          1.096µ ±  1%   1.099µ ±  1%       ~ (p=0.394 n=6)
PoolContention/workers-8-4          1.103µ ±  1%   1.098µ ±  3%       ~ (p=0.667 n=6)
PoolContention/workers-16-4         1.101µ ±  2%   1.099µ ±  1%       ~ (p=0.732 n=6)
ComponentLifecycle-4                3.699m ±  3%   3.668m ±  1%  -0.86% (p=0.009 n=6)
SourceValidation-4                  2.330µ ±  1%   2.327µ ±  1%       ~ (p=0.470 n=6)
RegistryConcurrent-4                791.6n ±  5%   803.6n ±  3%       ~ (p=0.937 n=6)
LoaderLoadFromString-4              3.746m ±  7%   3.693m ±  2%  -1.43% (p=0.026 n=6)
geomean                             19.27µ         19.35µ        +0.41%

                            │ baseline-bench.txt │        benchmark-results.txt         │
                            │        B/op        │     B/op      vs base                │
InterpreterCreation-4               2.027Mi ± 0%   2.027Mi ± 0%       ~ (p=0.513 n=6)
ComponentLoad-4                     2.180Mi ± 0%   2.180Mi ± 0%       ~ (p=0.818 n=6)
ComponentExecute-4                  1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-1-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-2-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-4-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-8-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-16-4         1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
ComponentLifecycle-4                2.183Mi ± 0%   2.183Mi ± 0%       ~ (p=1.000 n=6)
SourceValidation-4                  1.984Ki ± 0%   1.984Ki ± 0%       ~ (p=1.000 n=6) ¹
RegistryConcurrent-4                1.133Ki ± 0%   1.133Ki ± 0%       ~ (p=1.000 n=6) ¹
LoaderLoadFromString-4              2.182Mi ± 0%   2.182Mi ± 0%       ~ (p=0.509 n=6)
geomean                             15.25Ki        15.25Ki       -0.00%
¹ all samples are equal

                            │ baseline-bench.txt │        benchmark-results.txt        │
                            │     allocs/op      │  allocs/op   vs base                │
InterpreterCreation-4                15.68k ± 0%   15.68k ± 0%       ~ (p=1.000 n=6)
ComponentLoad-4                      18.02k ± 0%   18.02k ± 0%       ~ (p=1.000 n=6)
ComponentExecute-4                    25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-1-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-2-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-4-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-8-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-16-4           25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
ComponentLifecycle-4                 18.07k ± 0%   18.07k ± 0%       ~ (p=1.000 n=6) ¹
SourceValidation-4                    32.00 ± 0%    32.00 ± 0%       ~ (p=1.000 n=6) ¹
RegistryConcurrent-4                  2.000 ± 0%    2.000 ± 0%       ~ (p=1.000 n=6) ¹
LoaderLoadFromString-4               18.06k ± 0%   18.06k ± 0%       ~ (p=1.000 n=6) ¹
geomean                               183.3         183.3       +0.00%
¹ all samples are equal

pkg: github.com/GoCodeAlone/workflow/middleware
                                  │ baseline-bench.txt │       benchmark-results.txt       │
                                  │       sec/op       │   sec/op     vs base              │
CircuitBreakerDetection-4                  290.0n ± 4%   285.4n ± 4%  -1.59% (p=0.041 n=6)
CircuitBreakerExecution_Success-4          21.54n ± 0%   21.46n ± 1%       ~ (p=0.117 n=6)
CircuitBreakerExecution_Failure-4          66.52n ± 3%   66.10n ± 0%  -0.62% (p=0.004 n=6)
geomean                                    74.63n        73.98n       -0.87%

                                  │ baseline-bench.txt │       benchmark-results.txt        │
                                  │        B/op        │    B/op     vs base                │
CircuitBreakerDetection-4                 144.0 ± 0%     144.0 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Success-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Failure-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                              ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                  │ baseline-bench.txt │       benchmark-results.txt        │
                                  │     allocs/op      │ allocs/op   vs base                │
CircuitBreakerDetection-4                 1.000 ± 0%     1.000 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Success-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Failure-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                              ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/module
                                 │ baseline-bench.txt │       benchmark-results.txt        │
                                 │       sec/op       │    sec/op     vs base              │
IaCStateBackend_InProcess-4              311.7n ± 23%   310.4n ± 30%       ~ (p=1.000 n=6)
IaCStateBackend_GRPC-4                   9.860m ±  2%   9.518m ±  4%  -3.46% (p=0.026 n=6)
JQTransform_Simple-4                     717.4n ± 38%   701.0n ± 35%       ~ (p=0.589 n=6)
JQTransform_ObjectConstruction-4         1.675µ ±  1%   1.584µ ±  1%  -5.40% (p=0.002 n=6)
JQTransform_ArraySelect-4                3.794µ ±  2%   3.533µ ±  1%  -6.87% (p=0.002 n=6)
JQTransform_Complex-4                    42.21µ ±  1%   39.68µ ±  1%  -6.00% (p=0.002 n=6)
JQTransform_Throughput-4                 2.026µ ±  1%   1.904µ ±  1%  -6.07% (p=0.002 n=6)
SSEPublishDelivery-4                     64.41n ±  2%   64.74n ±  1%       ~ (p=0.699 n=6)
geomean                                  4.082µ         3.928µ        -3.79%

                                 │ baseline-bench.txt │        benchmark-results.txt         │
                                 │        B/op        │     B/op      vs base                │
IaCStateBackend_InProcess-4             416.0 ±  0%       416.0 ± 0%       ~ (p=1.000 n=6) ¹
IaCStateBackend_GRPC-4                5.831Mi ± 15%     5.913Mi ± 9%       ~ (p=0.937 n=6)
JQTransform_Simple-4                  1.273Ki ±  0%     1.273Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ObjectConstruction-4      1.773Ki ±  0%     1.773Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ArraySelect-4             2.625Ki ±  0%     2.625Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Complex-4                 16.22Ki ±  0%     16.22Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Throughput-4              1.984Ki ±  0%     1.984Ki ± 0%       ~ (p=1.000 n=6) ¹
SSEPublishDelivery-4                    0.000 ±  0%       0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                             ²                 +0.17%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                 │ baseline-bench.txt │        benchmark-results.txt        │
                                 │     allocs/op      │  allocs/op   vs base                │
IaCStateBackend_InProcess-4              2.000 ± 0%      2.000 ± 0%       ~ (p=1.000 n=6) ¹
IaCStateBackend_GRPC-4                  6.841k ± 0%     6.835k ± 0%       ~ (p=0.165 n=6)
JQTransform_Simple-4                     10.00 ± 0%      10.00 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ObjectConstruction-4         15.00 ± 0%      15.00 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ArraySelect-4                30.00 ± 0%      30.00 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Complex-4                    324.0 ± 0%      324.0 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Throughput-4                 17.00 ± 0%      17.00 ± 0%       ~ (p=1.000 n=6) ¹
SSEPublishDelivery-4                     0.000 ± 0%      0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                             ²                -0.01%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/schema
                                    │ baseline-bench.txt │       benchmark-results.txt        │
                                    │       sec/op       │    sec/op     vs base              │
SchemaValidation_Simple-4                   1.119µ ± 14%   1.111µ ± 12%       ~ (p=0.394 n=6)
SchemaValidation_AllFields-4                1.685µ ±  4%   1.671µ ±  2%       ~ (p=0.310 n=6)
SchemaValidation_FormatValidation-4         1.607µ ±  2%   1.597µ ±  2%       ~ (p=0.394 n=6)
SchemaValidation_ManySchemas-4              1.839µ ±  2%   1.816µ ±  3%       ~ (p=0.329 n=6)
geomean                                     1.536µ         1.523µ        -0.85%

                                    │ baseline-bench.txt │       benchmark-results.txt        │
                                    │        B/op        │    B/op     vs base                │
SchemaValidation_Simple-4                   0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_AllFields-4                0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_FormatValidation-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_ManySchemas-4              0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                                ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                    │ baseline-bench.txt │       benchmark-results.txt        │
                                    │     allocs/op      │ allocs/op   vs base                │
SchemaValidation_Simple-4                   0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_AllFields-4                0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_FormatValidation-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_ManySchemas-4              0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                                ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/store
                                   │ baseline-bench.txt │        benchmark-results.txt        │
                                   │       sec/op       │    sec/op     vs base               │
EventStoreAppend_InMemory-4                1.284µ ± 13%   1.214µ ± 25%        ~ (p=1.000 n=6)
EventStoreAppend_SQLite-4                  1.445m ± 14%   1.373m ±  5%        ~ (p=0.093 n=6)
GetTimeline_InMemory/events-10-4           13.39µ ±  3%   13.42µ ± 12%        ~ (p=0.937 n=6)
GetTimeline_InMemory/events-50-4           76.54µ ±  1%   61.01µ ±  0%  -20.29% (p=0.002 n=6)
GetTimeline_InMemory/events-100-4          127.2µ ± 20%   122.9µ ±  1%   -3.33% (p=0.026 n=6)
GetTimeline_InMemory/events-500-4          637.8µ ±  1%   631.8µ ±  1%        ~ (p=0.240 n=6)
GetTimeline_InMemory/events-1000-4         1.290m ±  2%   1.288m ±  0%        ~ (p=0.310 n=6)
GetTimeline_SQLite/events-10-4             109.4µ ±  3%   107.1µ ±  1%   -2.05% (p=0.009 n=6)
GetTimeline_SQLite/events-50-4             252.1µ ±  1%   248.0µ ±  1%   -1.65% (p=0.002 n=6)
GetTimeline_SQLite/events-100-4            423.8µ ±  2%   421.6µ ±  1%        ~ (p=0.310 n=6)
GetTimeline_SQLite/events-500-4            1.802m ±  1%   1.821m ±  1%   +1.07% (p=0.002 n=6)
GetTimeline_SQLite/events-1000-4           3.612m ±  3%   3.527m ±  1%   -2.35% (p=0.009 n=6)
geomean                                    223.0µ         215.1µ         -3.53%

                                   │ baseline-bench.txt │         benchmark-results.txt         │
                                   │        B/op        │     B/op       vs base                │
EventStoreAppend_InMemory-4                  799.0 ± 9%     832.0 ± 10%       ~ (p=1.000 n=6)
EventStoreAppend_SQLite-4                  1.983Ki ± 1%   1.984Ki ±  2%       ~ (p=0.511 n=6)
GetTimeline_InMemory/events-10-4           7.953Ki ± 0%   7.953Ki ±  0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-50-4           46.62Ki ± 0%   46.62Ki ±  0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-100-4          94.48Ki ± 0%   94.48Ki ±  0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-500-4          472.8Ki ± 0%   472.8Ki ±  0%       ~ (p=1.000 n=6)
GetTimeline_InMemory/events-1000-4         944.3Ki ± 0%   944.3Ki ±  0%       ~ (p=0.145 n=6)
GetTimeline_SQLite/events-10-4             16.74Ki ± 0%   16.74Ki ±  0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-50-4             87.14Ki ± 0%   87.14Ki ±  0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-100-4            175.4Ki ± 0%   175.4Ki ±  0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-500-4            846.1Ki ± 0%   846.1Ki ±  0%       ~ (p=0.448 n=6)
GetTimeline_SQLite/events-1000-4           1.639Mi ± 0%   1.639Mi ±  0%       ~ (p=0.864 n=6)
geomean                                    67.41Ki        67.64Ki        +0.34%
¹ all samples are equal

                                   │ baseline-bench.txt │        benchmark-results.txt        │
                                   │     allocs/op      │  allocs/op   vs base                │
EventStoreAppend_InMemory-4                  7.000 ± 0%    7.000 ± 0%       ~ (p=1.000 n=6) ¹
EventStoreAppend_SQLite-4                    53.00 ± 0%    53.00 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-10-4             125.0 ± 0%    125.0 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-50-4             653.0 ± 0%    653.0 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-100-4           1.306k ± 0%   1.306k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-500-4           6.514k ± 0%   6.514k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-1000-4          13.02k ± 0%   13.02k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-10-4               382.0 ± 0%    382.0 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-50-4              1.852k ± 0%   1.852k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-100-4             3.681k ± 0%   3.681k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-500-4             18.54k ± 0%   18.54k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-1000-4            37.29k ± 0%   37.29k ± 0%       ~ (p=1.000 n=6) ¹
geomean                                     1.162k        1.162k       +0.00%
¹ all samples are equal

Benchmarks run with go test -bench=. -benchmem -count=6.
Regressions ≥ 20% are flagged. Results compared via benchstat.

@intel352 intel352 merged commit f12a800 into main May 25, 2026
28 checks passed
@intel352 intel352 deleted the feat/iac-derive-engine branch May 25, 2026 05:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant