Skip to content

docs: ADR 0039 — strict-contracts (c1) ruling + Typed-Provider SDK scaffolding#689

Merged
intel352 merged 1 commit into
mainfrom
docs/adr-0039-strict-contracts-c1-typed-providers
May 16, 2026
Merged

docs: ADR 0039 — strict-contracts (c1) ruling + Typed-Provider SDK scaffolding#689
intel352 merged 1 commit into
mainfrom
docs/adr-0039-strict-contracts-c1-typed-providers

Conversation

@intel352
Copy link
Copy Markdown
Contributor

Summary

Records the two interlocking decisions made mid-execution of plan-2 (plugin-modules-on-iac):

  1. (c1) ruling for plan-2 plugin shipping: aws + gcp v1.1.0 carry strict descriptors in plugin.contracts.json backing legacy sdk.ModuleProvider Go impls. Satisfies wfctl plugin audit without forcing an eager typed-Provider migration. Documented at the proto level via internal/contracts/{aws,gcp}_plan2.proto.
  2. SDK Typed-fields scaffolding (workflow feat(sdk): IaCServeOptions.TypedModules + .TypedSteps (future-prep for typed-Provider migration) #686): IaCServeOptions now carries TypedModules + TypedSteps alongside Modules + Steps; mapBackedProvider implements both contracts; grpc_server's Typed-first → legacy-fallback path is reused.

Decisions also rejected

  • (c2) Relaxing the validator for IaC-bridge plugins — would erode the strict-contracts cutover value (ADR 0024).
  • (B1) Eagerly migrating aws + gcp to typed Providers in plan-2 — would block Phase B/C deletions per the user's "just get the remaining plugins finished up" mandate.

Related

🤖 Generated with Claude Code

…affolding

Records the resolution of two interlocking decisions made mid-execution
of plan-2 (plugin-modules-on-iac):

1. (c1) for plan-2 plugin shipping: aws + gcp v1.1.0 carry strict
   descriptors backing legacy ModuleProvider Go impls, satisfying
   wfctl plugin audit without forcing an eager typed-Provider migration.

2. SDK Typed-fields scaffolding (PR #686 #683): IaCServeOptions now
   carries TypedModules + TypedSteps alongside Modules + Steps;
   mapBackedProvider implements both contracts; grpc_server's
   Typed-first → legacy-fallback path is reused.

(c2) — relaxing the validator — rejected as eroding the strict-cutover
value (decisions/0024). (B1) — eager typed migration — rejected as
blocking the Phase B/C deletions per the user's "just get the remaining
plugins finished up" mandate.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 16, 2026 00:45
@intel352 intel352 merged commit da25959 into main May 16, 2026
14 checks passed
@intel352 intel352 deleted the docs/adr-0039-strict-contracts-c1-typed-providers branch May 16, 2026 00:45
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 adds ADR 0039 to document the accepted strict-contracts ruling for plan-2 plugin shipping and the related Typed Provider SDK scaffolding direction.

Changes:

  • Records the c1 decision: aws/gcp plugins keep legacy providers while adding strict contract descriptors.
  • Documents the TypedModules/TypedSteps SDK scaffolding and future typed migration path.

**Adopt (c1) for plan-2 plugin shipping** + **adopt the SDK Typed-fields extension as future-prep** (workflow PR #686, merged before PR 4/5).

**(c1) shape (shipped in workflow-plugin-aws PR #15 + workflow-plugin-gcp PR #9):**
- Each plugin defines `internal/contracts/{aws,gcp}_plan2.proto` declaring strict-typed config / input / output messages for the new module types (`aws.credentials`, `storage.s3`, `step.s3_upload`, `gcp.credentials`, `storage.gcs`).
@codecov
Copy link
Copy Markdown

codecov Bot commented May 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@github-actions
Copy link
Copy Markdown

⏱ Benchmark Results

No significant performance regressions detected.

benchstat comparison (baseline → PR)
## benchstat: baseline → PR
baseline-bench.txt:276: parsing iteration count: invalid syntax
baseline-bench.txt:336919: parsing iteration count: invalid syntax
baseline-bench.txt:617213: parsing iteration count: invalid syntax
baseline-bench.txt:951429: parsing iteration count: invalid syntax
baseline-bench.txt:1242436: parsing iteration count: invalid syntax
baseline-bench.txt:1547366: parsing iteration count: invalid syntax
benchmark-results.txt:276: parsing iteration count: invalid syntax
benchmark-results.txt:291637: parsing iteration count: invalid syntax
benchmark-results.txt:608630: parsing iteration count: invalid syntax
benchmark-results.txt:952176: parsing iteration count: invalid syntax
benchmark-results.txt:1272766: parsing iteration count: invalid syntax
benchmark-results.txt:1613708: parsing iteration count: invalid syntax
goos: linux
goarch: amd64
pkg: github.com/GoCodeAlone/workflow/dynamic
cpu: AMD EPYC 7763 64-Core Processor                
                            │ benchmark-results.txt │
                            │        sec/op         │
InterpreterCreation-4                  6.719m ± 63%
ComponentLoad-4                        3.547m ±  1%
ComponentExecute-4                     1.917µ ±  1%
PoolContention/workers-1-4             1.088µ ±  2%
PoolContention/workers-2-4             1.076µ ±  2%
PoolContention/workers-4-4             1.072µ ±  1%
PoolContention/workers-8-4             1.076µ ±  1%
PoolContention/workers-16-4            1.077µ ±  1%
ComponentLifecycle-4                   3.561m ±  1%
SourceValidation-4                     2.274µ ±  2%
RegistryConcurrent-4                   799.3n ±  2%
LoaderLoadFromString-4                 3.575m ±  1%
geomean                                18.43µ

                            │ 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

cpu: AMD EPYC 9V74 80-Core Processor                
                            │ baseline-bench.txt │
                            │       sec/op       │
InterpreterCreation-4               6.386m ± 58%
ComponentLoad-4                     3.478m ±  1%
ComponentExecute-4                  1.830µ ±  0%
PoolContention/workers-1-4          1.020µ ±  1%
PoolContention/workers-2-4          1.008µ ±  1%
PoolContention/workers-4-4          1.008µ ±  1%
PoolContention/workers-8-4          1.013µ ±  1%
PoolContention/workers-16-4         1.007µ ±  1%
ComponentLifecycle-4                3.483m ±  1%
SourceValidation-4                  2.085µ ±  1%
RegistryConcurrent-4                734.1n ±  5%
LoaderLoadFromString-4              3.523m ±  1%
geomean                             17.47µ

                            │ 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

pkg: github.com/GoCodeAlone/workflow/middleware
cpu: AMD EPYC 7763 64-Core Processor                
                                  │ benchmark-results.txt │
                                  │        sec/op         │
CircuitBreakerDetection-4                     283.2n ± 4%
CircuitBreakerExecution_Success-4             21.50n ± 0%
CircuitBreakerExecution_Failure-4             66.12n ± 0%
geomean                                       73.84n

                                  │ 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

cpu: AMD EPYC 9V74 80-Core Processor                
                                  │ baseline-bench.txt │
                                  │       sec/op       │
CircuitBreakerDetection-4                  298.9n ± 8%
CircuitBreakerExecution_Success-4          22.68n ± 0%
CircuitBreakerExecution_Failure-4          70.95n ± 0%
geomean                                    78.35n

                                  │ 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

pkg: github.com/GoCodeAlone/workflow/module
cpu: AMD EPYC 7763 64-Core Processor                
                                 │ benchmark-results.txt │
                                 │        sec/op         │
IaCStateBackend_InProcess-4                 319.0n ± 28%
IaCStateBackend_GRPC-4                      9.462m ±  4%
JQTransform_Simple-4                        643.7n ± 37%
JQTransform_ObjectConstruction-4            1.480µ ±  0%
JQTransform_ArraySelect-4                   3.377µ ±  1%
JQTransform_Complex-4                       38.53µ ±  1%
JQTransform_Throughput-4                    1.802µ ±  0%
SSEPublishDelivery-4                        65.78n ±  1%
geomean                                     3.809µ

                                 │ benchmark-results.txt │
                                 │         B/op          │
IaCStateBackend_InProcess-4                416.0 ±  0%
IaCStateBackend_GRPC-4                   5.780Mi ± 13%
JQTransform_Simple-4                     1.273Ki ±  0%
JQTransform_ObjectConstruction-4         1.773Ki ±  0%
JQTransform_ArraySelect-4                2.625Ki ±  0%
JQTransform_Complex-4                    16.22Ki ±  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.833k ± 0%
JQTransform_Simple-4                        10.00 ± 0%
JQTransform_ObjectConstruction-4            15.00 ± 0%
JQTransform_ArraySelect-4                   30.00 ± 0%
JQTransform_Complex-4                       324.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                
                                 │ baseline-bench.txt │
                                 │       sec/op       │
IaCStateBackend_InProcess-4              294.9n ± 22%
IaCStateBackend_GRPC-4                   10.13m ±  0%
JQTransform_Simple-4                     616.6n ± 35%
JQTransform_ObjectConstruction-4         1.407µ ±  0%
JQTransform_ArraySelect-4                3.449µ ±  1%
JQTransform_Complex-4                    41.31µ ±  0%
JQTransform_Throughput-4                 1.753µ ±  0%
SSEPublishDelivery-4                     67.11n ±  4%
geomean                                  3.799µ

                                 │ baseline-bench.txt │
                                 │        B/op        │
IaCStateBackend_InProcess-4             416.0 ±  0%
IaCStateBackend_GRPC-4                5.896Mi ± 10%
JQTransform_Simple-4                  1.273Ki ±  0%
JQTransform_ObjectConstruction-4      1.773Ki ±  0%
JQTransform_ArraySelect-4             2.625Ki ±  0%
JQTransform_Complex-4                 16.22Ki ±  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.856k ± 0%
JQTransform_Simple-4                     10.00 ± 0%
JQTransform_ObjectConstruction-4         15.00 ± 0%
JQTransform_ArraySelect-4                30.00 ± 0%
JQTransform_Complex-4                    324.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                
                                    │ benchmark-results.txt │
                                    │        sec/op         │
SchemaValidation_Simple-4                       1.068µ ± 0%
SchemaValidation_AllFields-4                    1.643µ ± 1%
SchemaValidation_FormatValidation-4             1.572µ ± 1%
SchemaValidation_ManySchemas-4                  1.816µ ± 5%
geomean                                         1.496µ

                                    │ 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

cpu: AMD EPYC 9V74 80-Core Processor                
                                    │ baseline-bench.txt │
                                    │       sec/op       │
SchemaValidation_Simple-4                    1.098µ ± 8%
SchemaValidation_AllFields-4                 1.626µ ± 1%
SchemaValidation_FormatValidation-4          1.581µ ± 2%
SchemaValidation_ManySchemas-4               1.605µ ± 2%
geomean                                      1.459µ

                                    │ 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

pkg: github.com/GoCodeAlone/workflow/store
cpu: AMD EPYC 7763 64-Core Processor                
                                   │ benchmark-results.txt │
                                   │        sec/op         │
EventStoreAppend_InMemory-4                   1.179µ ± 22%
EventStoreAppend_SQLite-4                     1.353m ± 13%
GetTimeline_InMemory/events-10-4              13.76µ ±  1%
GetTimeline_InMemory/events-50-4              75.91µ ±  2%
GetTimeline_InMemory/events-100-4             125.2µ ± 20%
GetTimeline_InMemory/events-500-4             646.3µ ±  1%
GetTimeline_InMemory/events-1000-4            1.320m ±  2%
GetTimeline_SQLite/events-10-4                106.3µ ±  1%
GetTimeline_SQLite/events-50-4                249.1µ ±  1%
GetTimeline_SQLite/events-100-4               424.3µ ±  3%
GetTimeline_SQLite/events-500-4               1.801m ±  1%
GetTimeline_SQLite/events-1000-4              3.525m ±  1%
geomean                                       219.8µ

                                   │ benchmark-results.txt │
                                   │         B/op          │
EventStoreAppend_InMemory-4                    754.5 ± 13%
EventStoreAppend_SQLite-4                    1.988Ki ±  1%
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.10Ki

                                   │ 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

cpu: AMD EPYC 9V74 80-Core Processor                
                                   │ baseline-bench.txt │
                                   │       sec/op       │
EventStoreAppend_InMemory-4                1.122µ ± 18%
EventStoreAppend_SQLite-4                  1.024m ±  2%
GetTimeline_InMemory/events-10-4           12.51µ ±  2%
GetTimeline_InMemory/events-50-4           54.68µ ± 27%
GetTimeline_InMemory/events-100-4          108.9µ ±  0%
GetTimeline_InMemory/events-500-4          556.6µ ±  0%
GetTimeline_InMemory/events-1000-4         1.130m ±  1%
GetTimeline_SQLite/events-10-4             83.73µ ±  1%
GetTimeline_SQLite/events-50-4             218.2µ ±  1%
GetTimeline_SQLite/events-100-4            379.6µ ±  0%
GetTimeline_SQLite/events-500-4            1.652m ±  1%
GetTimeline_SQLite/events-1000-4           3.211m ±  0%
geomean                                    188.2µ

                                   │ baseline-bench.txt │
                                   │        B/op        │
EventStoreAppend_InMemory-4                  772.0 ± 3%
EventStoreAppend_SQLite-4                  1.983Ki ± 1%
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.21Ki

                                   │ 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

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

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