Cloud-SDK extraction — PR 8 (Amendment A2): engine host-wiring for iac.state plugin backends#674
Merged
Merged
Conversation
At plugin-load, the engine type-asserts plugins for IaCStateBackendProvider, calls the plugin's ListBackendNames RPC (cross-checked against its PluginManifest.IaCStateBackends), and registers each backend name — so iac.state backend: azure_blob resolves to a plugin-served gRPC backend with zero manual wiring. Amendment A2 (decisions/0035). Rollback: revert — registry + IaCModule.Init dispatch survive; only the engine auto-population is removed; core backends unaffected.
Contributor
There was a problem hiding this comment.
Pull request overview
Wires the workflow engine to discover and register plugin-served iac.state backends at plugin-load time (Amendment A2 / decisions/0035), enabling iac.state configs to dispatch backend: <name> to a gRPC-backed plugin implementation.
Changes:
- Introduces
plugin.IaCStateBackendProviderand hasExternalPluginAdapterimplement it viaIaCStateBackendClients()using ContractRegistry +ListBackendNames. - Adds an exported
module.RegisterIaCStateBackendwrapper around the package-level backend registry (including reserved-name enforcement at the registry boundary). - Hooks backend registration into
StdEngine.loadPluginInternaland adds bufconn-based adapter tests + registry wrapper test coverage.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| plugin/iac_state_backend_provider.go | Adds optional engine-facing interface for plugins that can provide IaC state backends. |
| plugin/external/adapter.go | Implements backend discovery via ContractRegistry advertisement + ListBackendNames RPC and returns name → client mapping. |
| plugin/external/adapter_test.go | Adds bufconn tests covering advertised/agree, silent manifest, mismatch, and no-service cases. |
| module/iac_state_plugin_registry.go | Exposes RegisterIaCStateBackend wrapper for engine-side registration into the singleton registry. |
| module/iac_state_plugin_registry_test.go | Adds test coverage for the exported registry wrapper and reserved-name rejection. |
| engine.go | Registers plugin-provided backends during plugin load via optional interface type-assertion. |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
⏱ Benchmark Results✅ No significant performance regressions detected. benchstat comparison (baseline → PR)
|
- Source iacStateBackendServiceName from pb.IaCStateBackend_ServiceDesc .ServiceName instead of a hard-coded literal, so it cannot drift if the proto package path / service name changes. - IaCStateBackendClients now errors when the disk manifest declares a non-empty IaCStateBackends list but the plugin does not advertise the IaCStateBackend service — previously this silent misconfiguration was swallowed as (nil, nil). Add test coverage. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment on lines
+5
to
+8
| // IaCStateBackendProvider is the optional interface an external-plugin adapter | ||
| // implements when its plugin serves one or more iac.state backends. The engine | ||
| // type-asserts loaded plugins against it (same pattern as stepRegistrySetter) | ||
| // and populates module's iac.state backend registry. |
Comment on lines
+331
to
+340
| if sb, ok := p.(plugin.IaCStateBackendProvider); ok { | ||
| clients, err := sb.IaCStateBackendClients() | ||
| if err != nil { | ||
| return fmt.Errorf("load plugin %q: iac.state backends: %w", p.EngineManifest().Name, err) | ||
| } | ||
| for name, client := range clients { | ||
| if err := module.RegisterIaCStateBackend(name, client); err != nil { | ||
| return fmt.Errorf("load plugin %q: %w", p.EngineManifest().Name, err) | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Amendment A2 (
decisions/0035) — the host-resolve half. Wires the workflow engine to resolve a plugin-servedIaCStateBackendat plugin-load time, soiac.statebackend: <name>dispatches to it.module.RegisterIaCStateBackendwrapper; newplugin.IaCStateBackendProvideroptional interface;*ExternalPluginAdapter.IaCStateBackendClients()(checks theContractRegistryadvertises the service, calls theListBackendNamesRPC for the live backend names, cross-checks against the plugin'sPluginManifest.IaCStateBackends, returnsname→client);engine.goloadPluginInternalgains the optional-interface type-assert (sibling tostepRegistrySetter/slogLoggerSetter) that populates the registry. Reserved-name rejection is enforced at the registry boundary; a plugin advertising a bad/reserved backend fails plugin-load loudly.Cross-check semantics: the
ListBackendNamesRPC is live truth; when the plugin's disk manifest declares a non-emptyiacStateBackendsit must set-equal the RPC result (else error); a silent manifest accepts the RPC alone (accommodates strict-cutover plugins that leaveGetManifestunimplemented).Scope Manifest
PR Count: 8 · Tasks: 19 · Status: Locked 2026-05-14T18:43:55Z
This is PR 8 —
Task 19— branchfeat/cloud-sdk-extraction-p8-hostwire. Basemain. Depends on PR 7 (#673, merged). May land in parallel with PR 4; both precede PR 5.Test status
6 files (4 source + 2 test).
go build ./...,go vet,go test ./module/ ./plugin/external/green; 4 bufconn-based adapter tests cover advertise+agree / silent-manifest / RPC-manifest-disagree / no-service-advertised. Negative launch check: server boots cleanly on the no-plugin path. The two repo-wide pre-existing failures are unrelated — see PR #668.🤖 Generated with Claude Code