Skip to content

fix(wfctl): validate infra secret pseudo-modules#881

Merged
intel352 merged 2 commits into
mainfrom
codex/validate-secrets-pseudo-modules
Jun 7, 2026
Merged

fix(wfctl): validate infra secret pseudo-modules#881
intel352 merged 2 commits into
mainfrom
codex/validate-secrets-pseudo-modules

Conversation

@intel352
Copy link
Copy Markdown
Contributor

@intel352 intel352 commented Jun 7, 2026

Summary

wfctl validate now accepts the infra-only pseudo-module types secrets.generate and secrets.requires without requiring --skip-unknown-types.

These module types are already consumed by wfctl infra plan/align/bootstrap; the validator was the outlier and rejected valid infra configs before plugin/type validation could finish.

Why

While validating GoCodeAlone/buymywishlist#276 against current main, BMW's original infra.eventbus* blocker was already resolved/superseded by the pgchannel migration, but strict validation of infra.yaml still failed on:

error: modules[0].type: unknown module type "secrets.requires"

The fix keeps these types local to CLI validation rather than adding them to the runtime engine's core module registry.

Verification

Red/green invariant:

# With fix absent, new regression fails:
$ GOWORK=off go test ./cmd/wfctl -run TestRunValidateAllowsInfraSecretPseudoModules -count=1
--- FAIL: TestRunValidateAllowsInfraSecretPseudoModules
    main_test.go:267: expected secrets pseudo-modules to validate, got: 1 config(s) failed validation: - modules[1].type: unknown module type "secrets.generate"
FAIL

# With fix restored:
$ GOWORK=off go test ./cmd/wfctl -run TestRunValidateAllowsInfraSecretPseudoModules -count=1
ok  github.com/GoCodeAlone/workflow/cmd/wfctl

Additional local verification:

$ GOWORK=off go test ./cmd/wfctl -run 'TestRunValidate(AllowsInfraSecretPseudoModules|Valid|Invalid|StrictByDefault|LooseAllowsEmptyModules)|TestValidateLocalManifest' -count=1
ok  github.com/GoCodeAlone/workflow/cmd/wfctl

$ GOWORK=off go test ./schema -count=1
ok  github.com/GoCodeAlone/workflow/schema

$ GOWORK=off go test ./cmd/wfctl -count=1
ok  github.com/GoCodeAlone/workflow/cmd/wfctl  161.324s

End-to-end BMW validation using a wfctl binary built from this branch and BMW's pinned plugins installed into /tmp/bmw-wfctl-plugins-issue276:

$ /tmp/wfctl-issue276 validate --allow-no-entry-points --plugin-dir /tmp/bmw-wfctl-plugins-issue276 infra.yaml
PASS infra.yaml (11 modules, 0 workflows, 0 triggers)

$ /tmp/wfctl-issue276 validate --plugin-dir /tmp/bmw-wfctl-plugins-issue276 app.yaml
PASS app.yaml (27 modules, 1 workflows, 0 triggers)
# existing pipeline-reference warnings only

Copilot AI review requested due to automatic review settings June 7, 2026 22:03
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates wfctl validate so it no longer rejects infra-only “pseudo-module” types (secrets.generate, secrets.requires) as unknown module types, aligning validation behavior with existing wfctl infra plan/align/bootstrap usage.

Changes:

  • Allowlist secrets.generate and secrets.requires during CLI config validation via schema.WithExtraModuleTypes(...).
  • Add a regression test ensuring infra configs containing those pseudo-modules validate successfully.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
cmd/wfctl/validate.go Adds extra allowed module types so infra secret pseudo-modules pass schema validation.
cmd/wfctl/main_test.go Adds a regression test covering successful validation of infra secret pseudo-modules.

Comment thread cmd/wfctl/validate.go Outdated
Comment thread cmd/wfctl/main_test.go
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 7, 2026

⏱ Benchmark Results

No significant performance regressions detected.

benchstat comparison (baseline → PR)
## benchstat: baseline → PR
baseline-bench.txt:304: parsing iteration count: invalid syntax
baseline-bench.txt:304988: parsing iteration count: invalid syntax
baseline-bench.txt:660123: parsing iteration count: invalid syntax
baseline-bench.txt:993403: parsing iteration count: invalid syntax
baseline-bench.txt:1299131: parsing iteration count: invalid syntax
baseline-bench.txt:1570500: parsing iteration count: invalid syntax
benchmark-results.txt:304: parsing iteration count: invalid syntax
benchmark-results.txt:323843: parsing iteration count: invalid syntax
benchmark-results.txt:628254: parsing iteration count: invalid syntax
benchmark-results.txt:898183: parsing iteration count: invalid syntax
benchmark-results.txt:1465055: parsing iteration count: invalid syntax
benchmark-results.txt:1765890: 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 │
                            │       sec/op       │
InterpreterCreation-4               8.640m ± 64%
ComponentLoad-4                     3.581m ±  1%
ComponentExecute-4                  1.948µ ±  1%
PoolContention/workers-1-4          1.077µ ±  3%
PoolContention/workers-2-4          1.083µ ±  1%
PoolContention/workers-4-4          1.085µ ±  1%
PoolContention/workers-8-4          1.092µ ±  1%
PoolContention/workers-16-4         1.090µ ±  3%
ComponentLifecycle-4                3.608m ±  0%
SourceValidation-4                  2.337µ ±  2%
RegistryConcurrent-4                794.3n ±  3%
LoaderLoadFromString-4              3.614m ±  2%
geomean                             18.99µ

                            │ baseline-bench.txt │
                            │        B/op        │
InterpreterCreation-4               2.027Mi ± 0%
ComponentLoad-4                     2.180Mi ± 0%
ComponentExecute-4                  1.203Ki ± 0%
PoolContention/workers-1-4          1.203Ki ± 0%
PoolContention/workers-2-4          1.203Ki ± 0%
PoolContention/workers-4-4          1.203Ki ± 0%
PoolContention/workers-8-4          1.203Ki ± 0%
PoolContention/workers-16-4         1.203Ki ± 0%
ComponentLifecycle-4                2.183Mi ± 0%
SourceValidation-4                  1.984Ki ± 0%
RegistryConcurrent-4                1.133Ki ± 0%
LoaderLoadFromString-4              2.182Mi ± 0%
geomean                             15.25Ki

                            │ baseline-bench.txt │
                            │     allocs/op      │
InterpreterCreation-4                15.68k ± 0%
ComponentLoad-4                      18.02k ± 0%
ComponentExecute-4                    25.00 ± 0%
PoolContention/workers-1-4            25.00 ± 0%
PoolContention/workers-2-4            25.00 ± 0%
PoolContention/workers-4-4            25.00 ± 0%
PoolContention/workers-8-4            25.00 ± 0%
PoolContention/workers-16-4           25.00 ± 0%
ComponentLifecycle-4                 18.07k ± 0%
SourceValidation-4                    32.00 ± 0%
RegistryConcurrent-4                  2.000 ± 0%
LoaderLoadFromString-4               18.06k ± 0%
geomean                               183.3

cpu: AMD EPYC 9V74 80-Core Processor                
                            │ benchmark-results.txt │
                            │        sec/op         │
InterpreterCreation-4                  9.061m ± 67%
ComponentLoad-4                        3.508m ±  7%
ComponentExecute-4                     1.839µ ±  1%
PoolContention/workers-1-4             1.009µ ±  1%
PoolContention/workers-2-4             1.009µ ±  4%
PoolContention/workers-4-4             1.010µ ±  3%
PoolContention/workers-8-4             1.012µ ±  0%
PoolContention/workers-16-4            1.007µ ±  1%
ComponentLifecycle-4                   3.505m ±  1%
SourceValidation-4                     2.080µ ±  3%
RegistryConcurrent-4                   740.1n ±  5%
LoaderLoadFromString-4                 3.538m ±  1%
geomean                                18.01µ

                            │ benchmark-results.txt │
                            │         B/op          │
InterpreterCreation-4                  2.027Mi ± 0%
ComponentLoad-4                        2.180Mi ± 0%
ComponentExecute-4                     1.203Ki ± 0%
PoolContention/workers-1-4             1.203Ki ± 0%
PoolContention/workers-2-4             1.203Ki ± 0%
PoolContention/workers-4-4             1.203Ki ± 0%
PoolContention/workers-8-4             1.203Ki ± 0%
PoolContention/workers-16-4            1.203Ki ± 0%
ComponentLifecycle-4                   2.183Mi ± 0%
SourceValidation-4                     1.984Ki ± 0%
RegistryConcurrent-4                   1.133Ki ± 0%
LoaderLoadFromString-4                 2.182Mi ± 0%
geomean                                15.25Ki

                            │ benchmark-results.txt │
                            │       allocs/op       │
InterpreterCreation-4                   15.68k ± 0%
ComponentLoad-4                         18.02k ± 0%
ComponentExecute-4                       25.00 ± 0%
PoolContention/workers-1-4               25.00 ± 0%
PoolContention/workers-2-4               25.00 ± 0%
PoolContention/workers-4-4               25.00 ± 0%
PoolContention/workers-8-4               25.00 ± 0%
PoolContention/workers-16-4              25.00 ± 0%
ComponentLifecycle-4                    18.07k ± 0%
SourceValidation-4                       32.00 ± 0%
RegistryConcurrent-4                     2.000 ± 0%
LoaderLoadFromString-4                  18.06k ± 0%
geomean                                  183.3

pkg: github.com/GoCodeAlone/workflow/middleware
cpu: AMD EPYC 7763 64-Core Processor                
                                  │ baseline-bench.txt │
                                  │       sec/op       │
CircuitBreakerDetection-4                  286.7n ± 6%
CircuitBreakerExecution_Success-4          21.47n ± 0%
CircuitBreakerExecution_Failure-4          65.61n ± 1%
geomean                                    73.92n

                                  │ baseline-bench.txt │
                                  │        B/op        │
CircuitBreakerDetection-4                 144.0 ± 0%
CircuitBreakerExecution_Success-4         0.000 ± 0%
CircuitBreakerExecution_Failure-4         0.000 ± 0%
geomean                                              ¹
¹ summaries must be >0 to compute geomean

                                  │ baseline-bench.txt │
                                  │     allocs/op      │
CircuitBreakerDetection-4                 1.000 ± 0%
CircuitBreakerExecution_Success-4         0.000 ± 0%
CircuitBreakerExecution_Failure-4         0.000 ± 0%
geomean                                              ¹
¹ summaries must be >0 to compute geomean

cpu: AMD EPYC 9V74 80-Core Processor                
                                  │ benchmark-results.txt │
                                  │        sec/op         │
CircuitBreakerDetection-4                    295.4n ± 19%
CircuitBreakerExecution_Success-4            22.66n ±  0%
CircuitBreakerExecution_Failure-4            71.21n ±  1%
geomean                                      78.12n

                                  │ benchmark-results.txt │
                                  │         B/op          │
CircuitBreakerDetection-4                    144.0 ± 0%
CircuitBreakerExecution_Success-4            0.000 ± 0%
CircuitBreakerExecution_Failure-4            0.000 ± 0%
geomean                                                 ¹
¹ summaries must be >0 to compute geomean

                                  │ benchmark-results.txt │
                                  │       allocs/op       │
CircuitBreakerDetection-4                    1.000 ± 0%
CircuitBreakerExecution_Success-4            0.000 ± 0%
CircuitBreakerExecution_Failure-4            0.000 ± 0%
geomean                                                 ¹
¹ summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/module
cpu: AMD EPYC 7763 64-Core Processor                
                                 │ baseline-bench.txt │
                                 │       sec/op       │
IaCStateBackend_InProcess-4              315.4n ± 34%
IaCStateBackend_GRPC-4                   9.436m ±  4%
JQTransform_Simple-4                     653.9n ± 38%
JQTransform_ObjectConstruction-4         1.514µ ±  1%
JQTransform_ArraySelect-4                3.462µ ±  1%
JQTransform_Complex-4                    39.59µ ±  1%
JQTransform_Throughput-4                 1.843µ ±  0%
SSEPublishDelivery-4                     66.83n ±  2%
geomean                                  3.864µ

                                 │ baseline-bench.txt │
                                 │        B/op        │
IaCStateBackend_InProcess-4             416.0 ±  0%
IaCStateBackend_GRPC-4                5.914Mi ± 11%
JQTransform_Simple-4                  1.273Ki ±  0%
JQTransform_ObjectConstruction-4      1.773Ki ±  0%
JQTransform_ArraySelect-4             2.625Ki ±  0%
JQTransform_Complex-4                 16.31Ki ±  0%
JQTransform_Throughput-4              1.984Ki ±  0%
SSEPublishDelivery-4                    0.000 ±  0%
geomean                                             ¹
¹ summaries must be >0 to compute geomean

                                 │ baseline-bench.txt │
                                 │     allocs/op      │
IaCStateBackend_InProcess-4              2.000 ± 0%
IaCStateBackend_GRPC-4                  6.832k ± 0%
JQTransform_Simple-4                     10.00 ± 0%
JQTransform_ObjectConstruction-4         15.00 ± 0%
JQTransform_ArraySelect-4                30.00 ± 0%
JQTransform_Complex-4                    328.0 ± 0%
JQTransform_Throughput-4                 17.00 ± 0%
SSEPublishDelivery-4                     0.000 ± 0%
geomean                                             ¹
¹ summaries must be >0 to compute geomean

cpu: AMD EPYC 9V74 80-Core Processor                
                                 │ benchmark-results.txt │
                                 │        sec/op         │
IaCStateBackend_InProcess-4                 296.5n ± 34%
IaCStateBackend_GRPC-4                      10.18m ±  1%
JQTransform_Simple-4                        641.7n ± 37%
JQTransform_ObjectConstruction-4            1.460µ ±  1%
JQTransform_ArraySelect-4                   3.517µ ±  0%
JQTransform_Complex-4                       41.96µ ±  0%
JQTransform_Throughput-4                    1.792µ ±  0%
SSEPublishDelivery-4                        63.64n ±  6%
geomean                                     3.843µ

                                 │ benchmark-results.txt │
                                 │         B/op          │
IaCStateBackend_InProcess-4                 416.0 ± 0%
IaCStateBackend_GRPC-4                    5.873Mi ± 9%
JQTransform_Simple-4                      1.273Ki ± 0%
JQTransform_ObjectConstruction-4          1.773Ki ± 0%
JQTransform_ArraySelect-4                 2.625Ki ± 0%
JQTransform_Complex-4                     16.31Ki ± 0%
JQTransform_Throughput-4                  1.984Ki ± 0%
SSEPublishDelivery-4                        0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

                                 │ benchmark-results.txt │
                                 │       allocs/op       │
IaCStateBackend_InProcess-4                 2.000 ± 0%
IaCStateBackend_GRPC-4                     6.856k ± 0%
JQTransform_Simple-4                        10.00 ± 0%
JQTransform_ObjectConstruction-4            15.00 ± 0%
JQTransform_ArraySelect-4                   30.00 ± 0%
JQTransform_Complex-4                       328.0 ± 0%
JQTransform_Throughput-4                    17.00 ± 0%
SSEPublishDelivery-4                        0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/schema
cpu: AMD EPYC 7763 64-Core Processor                
                                    │ baseline-bench.txt │
                                    │       sec/op       │
SchemaValidation_Simple-4                    1.109µ ± 9%
SchemaValidation_AllFields-4                 1.665µ ± 7%
SchemaValidation_FormatValidation-4          1.583µ ± 2%
SchemaValidation_ManySchemas-4               1.792µ ± 3%
geomean                                      1.513µ

                                    │ baseline-bench.txt │
                                    │        B/op        │
SchemaValidation_Simple-4                   0.000 ± 0%
SchemaValidation_AllFields-4                0.000 ± 0%
SchemaValidation_FormatValidation-4         0.000 ± 0%
SchemaValidation_ManySchemas-4              0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

                                    │ baseline-bench.txt │
                                    │     allocs/op      │
SchemaValidation_Simple-4                   0.000 ± 0%
SchemaValidation_AllFields-4                0.000 ± 0%
SchemaValidation_FormatValidation-4         0.000 ± 0%
SchemaValidation_ManySchemas-4              0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

cpu: AMD EPYC 9V74 80-Core Processor                
                                    │ benchmark-results.txt │
                                    │        sec/op         │
SchemaValidation_Simple-4                       1.092µ ± 4%
SchemaValidation_AllFields-4                    1.615µ ± 2%
SchemaValidation_FormatValidation-4             1.571µ ± 2%
SchemaValidation_ManySchemas-4                  1.629µ ± 2%
geomean                                         1.457µ

                                    │ benchmark-results.txt │
                                    │         B/op          │
SchemaValidation_Simple-4                      0.000 ± 0%
SchemaValidation_AllFields-4                   0.000 ± 0%
SchemaValidation_FormatValidation-4            0.000 ± 0%
SchemaValidation_ManySchemas-4                 0.000 ± 0%
geomean                                                   ¹
¹ summaries must be >0 to compute geomean

                                    │ benchmark-results.txt │
                                    │       allocs/op       │
SchemaValidation_Simple-4                      0.000 ± 0%
SchemaValidation_AllFields-4                   0.000 ± 0%
SchemaValidation_FormatValidation-4            0.000 ± 0%
SchemaValidation_ManySchemas-4                 0.000 ± 0%
geomean                                                   ¹
¹ summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/store
cpu: AMD EPYC 7763 64-Core Processor                
                                   │ baseline-bench.txt │
                                   │       sec/op       │
EventStoreAppend_InMemory-4                1.253µ ± 12%
EventStoreAppend_SQLite-4                  1.316m ±  5%
GetTimeline_InMemory/events-10-4           14.27µ ±  3%
GetTimeline_InMemory/events-50-4           78.68µ ± 22%
GetTimeline_InMemory/events-100-4          123.9µ ±  1%
GetTimeline_InMemory/events-500-4          636.2µ ±  0%
GetTimeline_InMemory/events-1000-4         1.300m ±  1%
GetTimeline_SQLite/events-10-4             71.88µ ±  1%
GetTimeline_SQLite/events-50-4             216.4µ ±  2%
GetTimeline_SQLite/events-100-4            394.9µ ±  3%
GetTimeline_SQLite/events-500-4            1.786m ±  3%
GetTimeline_SQLite/events-1000-4           3.592m ±  2%
geomean                                    210.3µ

                                   │ baseline-bench.txt │
                                   │        B/op        │
EventStoreAppend_InMemory-4                  770.0 ± 9%
EventStoreAppend_SQLite-4                  1.983Ki ± 2%
GetTimeline_InMemory/events-10-4           7.953Ki ± 0%
GetTimeline_InMemory/events-50-4           46.62Ki ± 0%
GetTimeline_InMemory/events-100-4          94.48Ki ± 0%
GetTimeline_InMemory/events-500-4          472.8Ki ± 0%
GetTimeline_InMemory/events-1000-4         944.3Ki ± 0%
GetTimeline_SQLite/events-10-4             16.74Ki ± 0%
GetTimeline_SQLite/events-50-4             87.14Ki ± 0%
GetTimeline_SQLite/events-100-4            175.4Ki ± 0%
GetTimeline_SQLite/events-500-4            846.1Ki ± 0%
GetTimeline_SQLite/events-1000-4           1.639Mi ± 0%
geomean                                    67.20Ki

                                   │ baseline-bench.txt │
                                   │     allocs/op      │
EventStoreAppend_InMemory-4                  7.000 ± 0%
EventStoreAppend_SQLite-4                    53.00 ± 0%
GetTimeline_InMemory/events-10-4             125.0 ± 0%
GetTimeline_InMemory/events-50-4             653.0 ± 0%
GetTimeline_InMemory/events-100-4           1.306k ± 0%
GetTimeline_InMemory/events-500-4           6.514k ± 0%
GetTimeline_InMemory/events-1000-4          13.02k ± 0%
GetTimeline_SQLite/events-10-4               382.0 ± 0%
GetTimeline_SQLite/events-50-4              1.852k ± 0%
GetTimeline_SQLite/events-100-4             3.681k ± 0%
GetTimeline_SQLite/events-500-4             18.54k ± 0%
GetTimeline_SQLite/events-1000-4            37.29k ± 0%
geomean                                     1.162k

cpu: AMD EPYC 9V74 80-Core Processor                
                                   │ benchmark-results.txt │
                                   │        sec/op         │
EventStoreAppend_InMemory-4                   1.041µ ± 11%
EventStoreAppend_SQLite-4                     1.073m ±  4%
GetTimeline_InMemory/events-10-4              13.41µ ±  5%
GetTimeline_InMemory/events-50-4              72.16µ ±  3%
GetTimeline_InMemory/events-100-4             146.9µ ± 25%
GetTimeline_InMemory/events-500-4             562.4µ ±  1%
GetTimeline_InMemory/events-1000-4            1.143m ±  1%
GetTimeline_SQLite/events-10-4                57.07µ ±  0%
GetTimeline_SQLite/events-50-4                188.3µ ±  1%
GetTimeline_SQLite/events-100-4               349.2µ ±  1%
GetTimeline_SQLite/events-500-4               1.627m ±  2%
GetTimeline_SQLite/events-1000-4              3.191m ±  0%
geomean                                       188.3µ

                                   │ benchmark-results.txt │
                                   │         B/op          │
EventStoreAppend_InMemory-4                     745.5 ± 2%
EventStoreAppend_SQLite-4                     1.983Ki ± 2%
GetTimeline_InMemory/events-10-4              7.953Ki ± 0%
GetTimeline_InMemory/events-50-4              46.62Ki ± 0%
GetTimeline_InMemory/events-100-4             94.48Ki ± 0%
GetTimeline_InMemory/events-500-4             472.8Ki ± 0%
GetTimeline_InMemory/events-1000-4            944.3Ki ± 0%
GetTimeline_SQLite/events-10-4                16.74Ki ± 0%
GetTimeline_SQLite/events-50-4                87.14Ki ± 0%
GetTimeline_SQLite/events-100-4               175.4Ki ± 0%
GetTimeline_SQLite/events-500-4               846.1Ki ± 0%
GetTimeline_SQLite/events-1000-4              1.639Mi ± 0%
geomean                                       67.02Ki

                                   │ benchmark-results.txt │
                                   │       allocs/op       │
EventStoreAppend_InMemory-4                     7.000 ± 0%
EventStoreAppend_SQLite-4                       53.00 ± 0%
GetTimeline_InMemory/events-10-4                125.0 ± 0%
GetTimeline_InMemory/events-50-4                653.0 ± 0%
GetTimeline_InMemory/events-100-4              1.306k ± 0%
GetTimeline_InMemory/events-500-4              6.514k ± 0%
GetTimeline_InMemory/events-1000-4             13.02k ± 0%
GetTimeline_SQLite/events-10-4                  382.0 ± 0%
GetTimeline_SQLite/events-50-4                 1.852k ± 0%
GetTimeline_SQLite/events-100-4                3.681k ± 0%
GetTimeline_SQLite/events-500-4                18.54k ± 0%
GetTimeline_SQLite/events-1000-4               37.29k ± 0%
geomean                                        1.162k

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

@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 7, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@intel352 intel352 merged commit b0f429a into main Jun 7, 2026
22 checks passed
@intel352 intel352 deleted the codex/validate-secrets-pseudo-modules branch June 7, 2026 23:02
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.

2 participants