Skip to content

Add optional IaC provider job runner contract#850

Merged
intel352 merged 2 commits into
mainfrom
feat/iac-provider-runner
Jun 3, 2026
Merged

Add optional IaC provider job runner contract#850
intel352 merged 2 commits into
mainfrom
feat/iac-provider-runner

Conversation

@intel352
Copy link
Copy Markdown
Contributor

@intel352 intel352 commented Jun 3, 2026

Summary

  • add optional IaCProviderRunner proto service, generated bindings, SDK auto-registration, and providerclient accessor
  • add interfaces.IaCProviderRunner plus JobHandle/JobStatusReply/JobState types
  • wire step.sandbox_exec exec_env: provider-ephemeral through a named provider Runner() accessor
  • document provider-ephemeral and keep provider-specific implementations in plugins

Refs #840. This is the workflow-core slice; provider plugin implementations and registry capability flags remain follow-up work. #731 intentionally ignored per direction. #704 was rechecked against workflow-plugin-infra and left deferred.

Verification

RED before implementation:

$ GOWORK=off go test ./plugin/external/proto ./interfaces ./iac/providerclient ./module
FAIL — missing IaCProviderRunner generated types, interfaces.JobHandle/JobStatusReply, providerclient.RunnerProvider, and provider-ephemeral resolver wiring

GREEN after implementation:

$ GOWORK=off go test ./plugin/external/proto ./plugin/external/sdk ./interfaces ./iac/providerclient ./module ./wftest/bdd
ok

$ GOWORK=off golangci-lint run --new-from-rev=origin/main
0 issues.

$ GOWORK=off go test ./...
ok all packages

Note: buf lint is not a clean repo gate today; it reports pre-existing package/service naming violations across plugin/external/proto. The new enum zero value was adjusted to avoid adding the avoidable enum-zero lint violation.

Copilot AI review requested due to automatic review settings June 3, 2026 05:44
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

Adds a new optional IaC provider “job runner” contract to the typed IaC plugin surface, and wires step.sandbox_exec to support a new exec_env: provider-ephemeral mode that delegates execution to the selected provider’s runner capability.

Changes:

  • Introduces optional gRPC service IaCProviderRunner (proto + generated bindings) and SDK auto-registration / contract registry advertisement.
  • Adds interfaces.IaCProviderRunner plus job handle/status/state types, and adds an iac/providerclient accessor (Runner()) gated by advertised services.
  • Wires step.sandbox_exec execution environment provider-ephemeral through a named IaC provider service’s runner accessor, and documents the new mode.

Reviewed changes

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

Show a summary per file
File Description
wftest/bdd/strict_iac.go Extends strict contract registration assertions to include IaCProviderRunner.
plugin/external/sdk/iacserver.go Auto-registers IaCProviderRunner when implemented by a provider server.
plugin/external/sdk/contracts_logcapture_test.go Adds test coverage ensuring the contract registry advertises the runner service.
plugin/external/proto/iac.proto Adds IaCProviderRunner service and Job* messages/enums to the IaC proto.
plugin/external/proto/iac.pb.go Regenerates protobuf Go types for the new runner service/messages.
plugin/external/proto/iac_proto_test.go Extends optional-service interface distinctness test to include runner.
plugin/external/proto/iac_grpc.pb.go Regenerates gRPC bindings for IaCProviderRunner.
plugin/external/adapter.go Updates adapter documentation to include the new optional runner capability.
module/sandbox_remote_runners.go Reserves provider-ephemeral so it can’t be shadowed by a remote runner name.
module/sandbox_remote_runners_test.go Updates reserved-name test to include provider-ephemeral.
module/provider_ephemeral_runner.go Implements a sandbox runner that executes via interfaces.IaCProviderRunner.
module/pipeline_step_sandbox_exec.go Adds provider config and routes exec_env: provider-ephemeral through resolver.
module/execenv_factory.go Adds provider-ephemeral resolver wiring that looks up a provider service runner accessor.
module/execenv_factory_test.go Adds tests for provider-ephemeral resolution and a fake runner provider.
interfaces/iac_provider.go Adds IaCProviderRunner, JobHandle, JobStatusReply, and JobState types.
interfaces/iac_provider_test.go Adds tests verifying runner optional-interface satisfaction/non-satisfaction.
iac/providerclient/adapter.go Adds advertised-service gated runner client adapter + proto/type conversions.
iac/providerclient/adapter_test.go Adds round-trip tests for advertised/unadvertised runner capability behavior.
docs/WFCTL.md Documents step.sandbox_exec execution environments including provider-ephemeral.
docs/AGENT_GUIDE.md Notes core-vs-plugin boundary for the shared runner contract and plugin implementations.
Files not reviewed (1)
  • plugin/external/proto/iac_grpc.pb.go: Language not supported

Comment thread module/provider_ephemeral_runner.go Outdated
Comment thread module/provider_ephemeral_runner.go
@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 3, 2026

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 3, 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:334109: parsing iteration count: invalid syntax
baseline-bench.txt:655551: parsing iteration count: invalid syntax
baseline-bench.txt:972745: parsing iteration count: invalid syntax
baseline-bench.txt:1275218: parsing iteration count: invalid syntax
baseline-bench.txt:1556916: parsing iteration count: invalid syntax
benchmark-results.txt:304: parsing iteration count: invalid syntax
benchmark-results.txt:298583: parsing iteration count: invalid syntax
benchmark-results.txt:564714: parsing iteration count: invalid syntax
benchmark-results.txt:813214: parsing iteration count: invalid syntax
benchmark-results.txt:1294451: parsing iteration count: invalid syntax
benchmark-results.txt:1573809: 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                  10.17m ± 68%
ComponentLoad-4                        3.838m ±  3%
ComponentExecute-4                     2.016µ ±  1%
PoolContention/workers-1-4             1.155µ ±  3%
PoolContention/workers-2-4             1.115µ ±  1%
PoolContention/workers-4-4             1.132µ ±  4%
PoolContention/workers-8-4             1.119µ ±  1%
PoolContention/workers-16-4            1.127µ ±  1%
ComponentLifecycle-4                   3.741m ±  3%
SourceValidation-4                     2.353µ ±  0%
RegistryConcurrent-4                   815.9n ±  3%
LoaderLoadFromString-4                 3.878m ±  3%
geomean                                19.97µ

                            │ 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               8.330m ± 63%
ComponentLoad-4                     3.584m ±  2%
ComponentExecute-4                  1.848µ ±  2%
PoolContention/workers-1-4          1.047µ ±  3%
PoolContention/workers-2-4          1.022µ ±  1%
PoolContention/workers-4-4          1.024µ ±  1%
PoolContention/workers-8-4          1.025µ ±  4%
PoolContention/workers-16-4         1.026µ ±  2%
ComponentLifecycle-4                3.574m ±  1%
SourceValidation-4                  2.093µ ±  1%
RegistryConcurrent-4                753.3n ±  4%
LoaderLoadFromString-4              3.595m ±  3%
geomean                             18.16µ

                            │ 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                     292.4n ± 2%
CircuitBreakerExecution_Success-4             21.55n ± 1%
CircuitBreakerExecution_Failure-4             66.33n ± 0%
geomean                                       74.78n

                                  │ 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                 296.0n ± 14%
CircuitBreakerExecution_Success-4         22.68n ±  2%
CircuitBreakerExecution_Failure-4         70.96n ±  0%
geomean                                   78.10n

                                  │ 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                 327.5n ± 22%
IaCStateBackend_GRPC-4                      10.01m ±  2%
JQTransform_Simple-4                        747.2n ± 31%
JQTransform_ObjectConstruction-4            1.589µ ±  4%
JQTransform_ArraySelect-4                   3.529µ ±  1%
JQTransform_Complex-4                       40.47µ ±  2%
JQTransform_Throughput-4                    1.919µ ±  1%
SSEPublishDelivery-4                        67.83n ±  1%
geomean                                     4.050µ

                                 │ benchmark-results.txt │
                                 │         B/op          │
IaCStateBackend_InProcess-4                416.0 ±  0%
IaCStateBackend_GRPC-4                   5.966Mi ± 10%
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.840k ± 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                
                                 │ baseline-bench.txt │
                                 │       sec/op       │
IaCStateBackend_InProcess-4              298.5n ± 28%
IaCStateBackend_GRPC-4                   10.26m ±  3%
JQTransform_Simple-4                     648.2n ± 35%
JQTransform_ObjectConstruction-4         1.427µ ±  9%
JQTransform_ArraySelect-4                3.511µ ±  6%
JQTransform_Complex-4                    43.83µ ±  3%
JQTransform_Throughput-4                 1.782µ ±  1%
SSEPublishDelivery-4                     64.77n ±  1%
geomean                                  3.870µ

                                 │ baseline-bench.txt │
                                 │        B/op        │
IaCStateBackend_InProcess-4             416.0 ±  0%
IaCStateBackend_GRPC-4                5.858Mi ± 12%
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.857k ± 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                
                                    │ benchmark-results.txt │
                                    │        sec/op         │
SchemaValidation_Simple-4                      1.110µ ± 23%
SchemaValidation_AllFields-4                   1.696µ ±  5%
SchemaValidation_FormatValidation-4            1.589µ ±  1%
SchemaValidation_ManySchemas-4                 1.823µ ±  1%
geomean                                        1.528µ

                                    │ 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.073µ ±  2%
SchemaValidation_AllFields-4                1.616µ ± 13%
SchemaValidation_FormatValidation-4         1.563µ ±  4%
SchemaValidation_ManySchemas-4              1.597µ ±  1%
geomean                                     1.442µ

                                    │ 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.299µ ± 22%
EventStoreAppend_SQLite-4                     1.367m ±  7%
GetTimeline_InMemory/events-10-4              14.49µ ±  4%
GetTimeline_InMemory/events-50-4              81.38µ ±  3%
GetTimeline_InMemory/events-100-4             144.5µ ± 15%
GetTimeline_InMemory/events-500-4             648.2µ ±  1%
GetTimeline_InMemory/events-1000-4            1.329m ±  0%
GetTimeline_SQLite/events-10-4                74.46µ ±  1%
GetTimeline_SQLite/events-50-4                221.7µ ±  2%
GetTimeline_SQLite/events-100-4               405.5µ ±  2%
GetTimeline_SQLite/events-500-4               1.837m ±  1%
GetTimeline_SQLite/events-1000-4              3.679m ±  4%
geomean                                       218.4µ

                                   │ benchmark-results.txt │
                                   │         B/op          │
EventStoreAppend_InMemory-4                     792.0 ± 4%
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.36Ki

                                   │ 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.011µ ± 22%
EventStoreAppend_SQLite-4                  1.101m ±  7%
GetTimeline_InMemory/events-10-4           13.43µ ±  5%
GetTimeline_InMemory/events-50-4           77.02µ ±  3%
GetTimeline_InMemory/events-100-4          113.3µ ± 35%
GetTimeline_InMemory/events-500-4          569.3µ ±  2%
GetTimeline_InMemory/events-1000-4         1.157m ±  0%
GetTimeline_SQLite/events-10-4             58.29µ ±  1%
GetTimeline_SQLite/events-50-4             191.6µ ±  1%
GetTimeline_SQLite/events-100-4            355.0µ ±  1%
GetTimeline_SQLite/events-500-4            1.658m ±  0%
GetTimeline_SQLite/events-1000-4           3.262m ±  0%
geomean                                    187.1µ

                                   │ baseline-bench.txt │
                                   │        B/op        │
EventStoreAppend_InMemory-4                  786.5 ± 9%
EventStoreAppend_SQLite-4                  1.981Ki ± 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.31Ki

                                   │ 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.

@intel352 intel352 merged commit 80c50eb into main Jun 3, 2026
28 checks passed
@intel352 intel352 deleted the feat/iac-provider-runner branch June 3, 2026 06:10
intel352 added a commit that referenced this pull request Jun 3, 2026
…nal providers (infra-admin PR13/13, ADR 0021) (#851)

* feat(providerclient): wire ResourceDriver gRPC service into Adapter (PR-2)

Implements the deferred PR-2 migration in iac/providerclient.Adapter:
- Adds IaCServiceResourceDriver const ("workflow.plugin.external.iac.ResourceDriver")
- Adds resourceDriverAdapter implementing interfaces.ResourceDriver (all 8 methods:
  Create/Read/Update/Delete/Diff/HealthCheck/Scale/SensitiveKeys) PLUS the optional
  interfaces.Troubleshooter (Troubleshoot) using the same JSON-bytes convention
  (config_json/outputs_json) as the existing typed adapter
- Compile-time guards: var _ interfaces.ResourceDriver and
  var _ interfaces.Troubleshooter on *resourceDriverAdapter (mirror typedResourceDriver)
- Wires advertisement-gated pb.ResourceDriverClient in New(); nil when not advertised
- Replaces the ErrProviderMethodUnimplemented stub with a live implementation
- Adds ResourceDriverProvider accessor interface mirroring RegionListerProvider/
  RunnerProvider pattern; not-advertised path still returns ErrProviderMethodUnimplemented
- mapResourceDriverGRPCError maps codes.NotFound/AlreadyExists/ResourceExhausted/
  Unavailable/DeadlineExceeded/Unauthenticated/PermissionDenied/InvalidArgument/
  FailedPrecondition/Unimplemented to engine sentinels. Wraps with %w/%w (sentinel +
  original gRPC error) so callers recover BOTH the sentinel (errors.Is) AND the gRPC
  status (status.Code walking the unwrap chain); default case keeps method attribution
  while preserving the status via %w

Closes the runtime advertisement gap: plugin/external/adapter.go
advertisedOptionalIaCServices() now forwards IaCServiceResourceDriver (and
IaCServiceRunner, which #850 added but the switch never matched) from the
plugin's ContractRegistry to providerclient.New, so the WiringHook-registered
adapter constructs the real ResourceDriver client. Without this, the adapter
stayed nil and ApplyPlanWithHooks -> provider.ResourceDriver(type) still hit
ErrProviderMethodUnimplemented end-to-end.

- Tests (providerclient): bufconn round-trip for all 8 CRUD methods + Troubleshoot;
  negative advertisement gate; table-driven gRPC error-mapping test covering all 10
  status codes (asserts both the errors.Is sentinel AND status.Code recovery via the
  unwrap chain)
- Tests (plugin/external): advertisedOptionalIaCServices forwards ResourceDriver
  (and Runner) when advertised / excludes when not; end-to-end WiringHook ->
  GetService -> ResourceDriver(type) returns the real bridge and Create round-trips
  WITH config_json echoed back to prove the Config JSON survives the boundary;
  unadvertised plugin still returns the unimplemented error

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(providerclient): Scale errors on out-of-int32 replicas + Unimplemented wraps gRPC err (Copilot)

- Scale rejects out-of-int32-range replicas explicitly (was clampInt32 → silent
  saturation → unintended scale); mirrors typedResourceDriver.Scale.
- mapResourceDriverGRPCError Unimplemented case wraps the original gRPC error
  (%w) so status.Code stays recoverable, consistent with the other mapped cases
  + translateRPCErr.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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