Skip to content

test(wfctl): state-file v0.14.2 → v1.0.0 read-path pre-flight (Task 31)#608

Merged
intel352 merged 2 commits into
mainfrom
feat/state-compat-task31
May 10, 2026
Merged

test(wfctl): state-file v0.14.2 → v1.0.0 read-path pre-flight (Task 31)#608
intel352 merged 2 commits into
mainfrom
feat/state-compat-task31

Conversation

@intel352

Copy link
Copy Markdown
Contributor

Summary

Task 31 of the strict-contracts force-cutover plan (docs/plans/2026-05-10-strict-contracts-force-cutover.md, rev5).

Adds the cycle 1 I-4 pre-flight test that catches the cascade-block risk for PR 5 BEFORE that PR merges. The strict-contracts cutover changes the wfctl ↔ plugin gRPC envelope but MUST NOT change the on-disk JSON state-file format (interfaces.ResourceState / iacStateRecord schema invariant per the design's State-file compat invariant).

Independent of the PR 2 stack — modifies only test infrastructure. Base is main.

What's added

  • test/fixtures/state-v0.14.2.json — fixture in v0.14.2 schema shape (snake_case keys, Status field, no SchemaVersion). Synthetic, carries an _fixture_metadata header noting the operator should replace it with a real coredump-staging/iac-state/<resource>.json snapshot from the Spaces backend during PR 4 prep (per plan §Step 1). The synthetic version lets the test run in CI; the operator-captured replacement provides real-world fidelity.

  • cmd/wfctl/state_compat_test.go — two pre-flight tests:

    • TestStateFileCompat_v0_14_2_to_v1_0_0 — reads the fixture via iacStateRecord (the v1.0.0 wire decoder used by loadFSState and spacesWfctlStateStore.ListResources), then converts via iacRecordToResourceState and asserts ID, Type, Provider, ProviderID, AppliedConfig, Outputs all survive the decode + conversion path
    • TestStateFileCompat_v0_14_2_NoUnknownFieldsLost — re-decodes with DisallowUnknownFields() so any v0.14.2 field that v1.0.0 silently drops surfaces as a test failure. Strips the _fixture_metadata header before strict decode (synthetic annotation only — the strip becomes a no-op once the operator replaces with a real capture)

If these tests FAIL

Per Task 31 §If FAIL — PR 5 cascade-block surfaces:

  • File a separate workflow PR (feat: state-file v0.14.2 compat shim) adding the compatibility layer
  • Hold PR 5 (and consequently PRs 6–9) until the shim PR merges
  • Document the gap in PR 4's CHANGELOG

Verification

  • GOWORK=off go test -race ./cmd/wfctl/... → PASS (2/2 new tests pass)
  • GOWORK=off go vet ./cmd/wfctl/ → clean

Rollback

Revert this commit. The pre-flight is purely additive — test fixture + Go test. Production state-file decode pipeline is unaffected.

Test plan

  • TestStateFileCompat_v0_14_2_to_v1_0_0 passes
  • TestStateFileCompat_v0_14_2_NoUnknownFieldsLost passes (no unexpected fields)
  • Race-mode wfctl test suite passes
  • Operator replaces synthetic fixture with real coredump-staging snapshot during PR 4 prep (deferred — operator action)

🤖 Generated with Claude Code

Task 31 of the strict-contracts force-cutover plan
(docs/plans/2026-05-10-strict-contracts-force-cutover.md, rev5).

Adds the cycle 1 I-4 pre-flight test that catches the cascade-block
risk for PR 5 BEFORE it merges. The strict-contracts cutover changes
the wfctl <-> plugin gRPC envelope but MUST NOT change the on-disk
JSON state-file format (interfaces.ResourceState / iacStateRecord
schema invariant per the design §State-file compat invariant).

- test/fixtures/state-v0.14.2.json — fixture in v0.14.2 schema
  shape (snake_case keys, Status field, no SchemaVersion). The
  fixture is synthetic — it carries an _fixture_metadata header
  noting the operator MUST replace it with a real
  coredump-staging/iac-state/<resource>.json snapshot from the
  Spaces backend during PR 4 prep (per Task 31 §Step 1). The
  synthetic version lets the test run in CI; the operator-captured
  replacement provides real-world fidelity.

- cmd/wfctl/state_compat_test.go — two pre-flight tests:

  - TestStateFileCompat_v0_14_2_to_v1_0_0: reads the fixture via
    iacStateRecord (the v1.0.0 wire decoder used by loadFSState
    and spacesWfctlStateStore.ListResources), then converts via
    iacRecordToResourceState and asserts ID, Type, Provider,
    ProviderID, AppliedConfig, and Outputs all survive the
    decode + conversion path.

  - TestStateFileCompat_v0_14_2_NoUnknownFieldsLost: re-decodes
    the fixture with json.Decoder.DisallowUnknownFields() to
    surface any v0.14.2 field that v1.0.0's decoder silently
    drops. Strips the _fixture_metadata header before strict
    decode (synthetic-fixture annotation only; once the operator
    replaces the fixture with a real capture, the strip is a
    no-op).

If these tests FAIL: PR 5 cascade-block surfaces (per Task 31
§If FAIL).
- File a separate workflow PR (feat: state-file v0.14.2 compat
  shim) that adds the compatibility layer.
- Hold PR 5 (and consequently PRs 6–9) until the shim PR
  merges.
- Document the gap in PR 4's CHANGELOG.

Verification: GOWORK=off go test -race ./cmd/wfctl/... PASS;
GOWORK=off go vet ./cmd/wfctl/ clean.

Rollback: revert this commit. The pre-flight is purely additive —
test fixture + Go test. Production state-file decode pipeline is
unaffected.
Copilot AI review requested due to automatic review settings May 10, 2026 06:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 wfctl pre-flight compatibility test to ensure strict-contracts gRPC envelope changes don’t inadvertently break the on-disk IaC JSON state-file format (v0.14.2 → v1.0.0 decode path), using a committed fixture intended to be replaced later with a real captured snapshot.

Changes:

  • Added a v0.14.2-shaped state JSON fixture (snake_case, status, no SchemaVersion) with a _fixture_metadata header.
  • Added wfctl tests that (1) decode v0.14.2 state through the current iacStateRecord path and convert to interfaces.ResourceState, and (2) strict-decode with DisallowUnknownFields() after stripping _fixture_metadata.

Reviewed changes

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

File Description
test/fixtures/state-v0.14.2.json Adds a synthetic v0.14.2-shaped state-file fixture for CI and later operator replacement.
cmd/wfctl/state_compat_test.go Adds compatibility tests and a helper to locate fixtures across different go test working directories.

Comment thread cmd/wfctl/state_compat_test.go Outdated
Comment on lines +75 to +76
if state.ProviderID == "" {
t.Errorf("ProviderID is empty after decode (must default to ResourceID when source is empty)")
Comment on lines +78 to +83
if state.AppliedConfig == nil {
t.Errorf("AppliedConfig is nil after decode (config map dropped during conversion)")
}
if state.Outputs == nil {
t.Errorf("Outputs is nil after decode (outputs map dropped during conversion)")
}
Comment thread cmd/wfctl/state_compat_test.go Outdated
Comment on lines +115 to +116
dec := json.NewDecoder(strings.NewReader(string(stripped)))
dec.DisallowUnknownFields()
@github-actions

github-actions Bot commented May 10, 2026

Copy link
Copy Markdown

⏱ Benchmark Results

No significant performance regressions detected.

benchstat comparison (baseline → PR)
## benchstat: baseline → PR
baseline-bench.txt:262: parsing iteration count: invalid syntax
baseline-bench.txt:361088: parsing iteration count: invalid syntax
baseline-bench.txt:697557: parsing iteration count: invalid syntax
baseline-bench.txt:964129: parsing iteration count: invalid syntax
baseline-bench.txt:1280207: parsing iteration count: invalid syntax
baseline-bench.txt:1793820: parsing iteration count: invalid syntax
benchmark-results.txt:262: parsing iteration count: invalid syntax
benchmark-results.txt:316517: parsing iteration count: invalid syntax
benchmark-results.txt:595863: parsing iteration count: invalid syntax
benchmark-results.txt:865558: parsing iteration count: invalid syntax
benchmark-results.txt:1141382: parsing iteration count: invalid syntax
benchmark-results.txt:1648908: 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                 3.555m ± 245%
ComponentLoad-4                       3.577m ±   2%
ComponentExecute-4                    1.958µ ±   0%
PoolContention/workers-1-4            1.094µ ±   1%
PoolContention/workers-2-4            1.091µ ±   1%
PoolContention/workers-4-4            1.094µ ±   1%
PoolContention/workers-8-4            1.111µ ±   2%
PoolContention/workers-16-4           1.135µ ±   2%
ComponentLifecycle-4                  3.689m ±   1%
SourceValidation-4                    2.410µ ±   1%
RegistryConcurrent-4                  870.4n ±  10%
LoaderLoadFromString-4                3.639m ±   1%
geomean                               17.99µ

                            │ 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              3.340m ± 210%
ComponentLoad-4                    3.528m ±   1%
ComponentExecute-4                 1.855µ ±   1%
PoolContention/workers-1-4         1.017µ ±   1%
PoolContention/workers-2-4         1.017µ ±   2%
PoolContention/workers-4-4         1.022µ ±   1%
PoolContention/workers-8-4         1.059µ ±   3%
PoolContention/workers-16-4        1.024µ ±   1%
ComponentLifecycle-4               3.591m ±   1%
SourceValidation-4                 2.104µ ±   0%
RegistryConcurrent-4               754.9n ±   2%
LoaderLoadFromString-4             3.630m ±   2%
geomean                            16.84µ

                            │ 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                    286.7n ± 10%
CircuitBreakerExecution_Success-4            21.54n ±  0%
CircuitBreakerExecution_Failure-4            66.14n ±  0%
geomean                                      74.20n

                                  │ 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.2n ± 1%
CircuitBreakerExecution_Success-4          22.70n ± 1%
CircuitBreakerExecution_Failure-4          70.91n ± 0%
geomean                                    78.30n

                                  │ 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         │
JQTransform_Simple-4                        926.5n ± 29%
JQTransform_ObjectConstruction-4            1.550µ ± 14%
JQTransform_ArraySelect-4                   3.534µ ±  1%
JQTransform_Complex-4                       39.55µ ±  1%
JQTransform_Throughput-4                    1.836µ ±  1%
SSEPublishDelivery-4                        65.49n ±  1%
geomean                                     1.700µ

                                 │ benchmark-results.txt │
                                 │         B/op          │
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       │
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       │
JQTransform_Simple-4                     861.5n ± 30%
JQTransform_ObjectConstruction-4         1.425µ ±  3%
JQTransform_ArraySelect-4                3.469µ ±  3%
JQTransform_Complex-4                    41.95µ ±  8%
JQTransform_Throughput-4                 1.770µ ±  4%
SSEPublishDelivery-4                     64.27n ±  1%
geomean                                  1.652µ

                                 │ baseline-bench.txt │
                                 │        B/op        │
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      │
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.104µ ± 1%
SchemaValidation_AllFields-4                    1.657µ ± 2%
SchemaValidation_FormatValidation-4             1.598µ ± 2%
SchemaValidation_ManySchemas-4                  1.819µ ± 2%
geomean                                         1.518µ

                                    │ 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.110µ ±  4%
SchemaValidation_AllFields-4                1.659µ ± 16%
SchemaValidation_FormatValidation-4         1.591µ ±  1%
SchemaValidation_ManySchemas-4              1.598µ ±  4%
geomean                                     1.471µ

                                    │ 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.169µ ± 10%
EventStoreAppend_SQLite-4                     1.367m ±  6%
GetTimeline_InMemory/events-10-4              14.87µ ±  4%
GetTimeline_InMemory/events-50-4              82.21µ ±  2%
GetTimeline_InMemory/events-100-4             133.5µ ± 25%
GetTimeline_InMemory/events-500-4             667.3µ ±  1%
GetTimeline_InMemory/events-1000-4            1.369m ±  1%
GetTimeline_SQLite/events-10-4                111.3µ ±  1%
GetTimeline_SQLite/events-50-4                261.4µ ±  1%
GetTimeline_SQLite/events-100-4               443.6µ ±  1%
GetTimeline_SQLite/events-500-4               1.874m ±  1%
GetTimeline_SQLite/events-1000-4              3.640m ±  0%
geomean                                       229.1µ

                                   │ benchmark-results.txt │
                                   │         B/op          │
EventStoreAppend_InMemory-4                    745.0 ± 11%
EventStoreAppend_SQLite-4                    1.984Ki ±  3%
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

cpu: AMD EPYC 9V74 80-Core Processor                
                                   │ baseline-bench.txt │
                                   │       sec/op       │
EventStoreAppend_InMemory-4                1.074µ ± 20%
EventStoreAppend_SQLite-4                  1.044m ±  3%
GetTimeline_InMemory/events-10-4           12.90µ ±  2%
GetTimeline_InMemory/events-50-4           72.92µ ±  2%
GetTimeline_InMemory/events-100-4          144.1µ ±  1%
GetTimeline_InMemory/events-500-4          556.7µ ± 36%
GetTimeline_InMemory/events-1000-4         1.155m ±  2%
GetTimeline_SQLite/events-10-4             83.11µ ±  1%
GetTimeline_SQLite/events-50-4             218.2µ ±  1%
GetTimeline_SQLite/events-100-4            389.4µ ±  2%
GetTimeline_SQLite/events-500-4            1.699m ±  0%
GetTimeline_SQLite/events-1000-4           3.302m ±  0%
geomean                                    199.0µ

                                   │ baseline-bench.txt │
                                   │        B/op        │
EventStoreAppend_InMemory-4                  758.0 ± 7%
EventStoreAppend_SQLite-4                  1.986Ki ± 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.12Ki

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

Per cycle 4 code-review PR 608 MINOR-1/2/3 (Copilot-flagged):

MINOR-1 — ProviderID strict-equality (was non-empty check). The
old check would pass silently if `provider_id` stops decoding
because iacRecordToResourceState falls back to ResourceID. Pin to
state.ProviderID == record.ProviderID (fixture has
DO00FIXTURE1234567890) so a silent provider_id decode regression
fails the test loudly.

MINOR-2 — AppliedConfig + Outputs key assertions (were nil-only
checks). The old checks would pass when the maps decoded as
empty {} — silent map-content drop. Pin one known fixture key per
map: AppliedConfig["name"] == "iac-state-spaces-key";
Outputs["access_key"] non-empty.

MINOR-3 — bytes.NewReader cleanup. Replaces
strings.NewReader(string(stripped)) ([]byte→string→Reader) with
bytes.NewReader(stripped) (direct []byte→Reader). Removes the
unnecessary string conversion. strings import dropped, bytes
added.

Verification: GOWORK=off go test ./cmd/wfctl/ -run TestStateFileCompat
-count=1 → PASS (2/2); gofmt clean.

Rollback: revert this commit; assertions return to non-empty
form (which still validates the read pipeline doesn't panic but
permits silent map-content drops).
@intel352 intel352 merged commit 81ca10b into main May 10, 2026
18 checks passed
@intel352 intel352 deleted the feat/state-compat-task31 branch May 10, 2026 07:24
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