Skip to content

feat(cigen): per-phase secret scoping + migration --format json/--env#805

Merged
intel352 merged 8 commits into
mainfrom
feat/cigen-phase-secret-scoping
May 31, 2026
Merged

feat(cigen): per-phase secret scoping + migration --format json/--env#805
intel352 merged 8 commits into
mainfrom
feat/cigen-phase-secret-scoping

Conversation

@intel352
Copy link
Copy Markdown
Contributor

What

Two fidelity fixes to cigen's GitHub Actions output, narrowing measured gaps vs the hand-tuned multisite workflow (follow-on to v0.67.0; closes the two gaps recorded in cigen/testdata/multisite/GAP.md):

  • Upgrade Modular #3 per-phase secret scoping. Analyze now loads the prereq config from opts.PhaseConfig and runs the existing deriveSecrets per config, so each apply job's env: carries only the secrets that phase's config references. DeployPhase gains Secrets []SecretRef + Scoped bool; the renderer branches its env: source on phase.Scoped (a scoped-but-empty phase emits no block; an unscoped/unloadable phase falls back to the plan-wide union). Measured effect on multisite: apply-prereq drops 6 deploy-only secrets (incl MULTISITE_DB_URL); apply-deploy is unchanged.
  • [WIP] Upgrade Modular #4 migration operational flags. wfctl migrations up now always emits --format json (machine-readable; matches the deployed workflow). --env <env> is derived only when exactly one ci.migrations[0].environments key exists; ≥2 → omitted + a Warnings[] note. Multisite declares no environments:, so it correctly gets --format json and no --env — honest, not faked.

Both flags verified to exist on the real runMigrationsUp (cmd/wfctl/migrations.go: --env, --format text|json).

Scope / non-goals

GHA only (GitLab/Jenkins/CircleCI untouched). No plugin release — wfctl ci generate gets the fix directly; the ci-generator plugin picks it up on its next workflow-dep bump. DeployPhase.{Secrets,Scoped} are additive (json:",omitempty") — old plan.json consumers unaffected.

Evidence (demonstration-fidelity)

cigen/testdata/multisite/{plan.json,generated-infra.yml} regenerated with the real wfctl ci plan/ci generate binary (recipe in GAP.md). A new on-disk golden test (cigen/multisite_evidence_test.go) reads the committed generated-infra.yml and asserts: apply-prereq env lacks MULTISITE_DB_URL, apply-deploy keeps it, --format json present, no --env. GAP.md updated honestly — --env stays in "not derivable" for multisite.

Verification

  • GOWORK=off go test ./cigen/... — green (38 tests, incl 4 new internal-package test files + the on-disk golden)
  • GOWORK=off go build ./cmd/wfctl — exit 0
  • GOWORK=off golangci-lint run --new-from-rev=origin/main ./cigen/... — 0 issues

Pipeline

Full autodev pipeline: design adversarial PASS (2 cycles) → plan adversarial PASS (2 cycles; caught the test-package/compile + fictional-CLI-flag traps) → alignment PASS → scope-lock → implement → code review PASS. Design + plan + lock included.

Rollback

Revert the PR; wfctl ci generate reverts to union-scoping + bare-migrations output. No release, no migration, no state.

🤖 Generated with Claude Code

intel352 and others added 8 commits May 31, 2026 16:26
…er-phase secret scoping + #4 migration flags

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- C1/C2: new tests in internal package cigen files (analyze_phase_test.go, render_gha_phase_test.go) — unexported funcs reachable, own config/strings imports
- C3: Task 5 regen uses REAL ci plan/generate flags (--out, --write; no --stdout/--format/--output-dir) per GAP.md recipe
- Important: add on-disk golden test (multisite_evidence_test.go) locking the committed evidence
- note pre-existing render tests survive (Contains-asserts)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…s to *_phase_test.go)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… --format json) + on-disk golden test; honest GAP.md
@codecov
Copy link
Copy Markdown

codecov Bot commented May 31, 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:307: parsing iteration count: invalid syntax
baseline-bench.txt:309341: parsing iteration count: invalid syntax
baseline-bench.txt:676929: parsing iteration count: invalid syntax
baseline-bench.txt:987736: parsing iteration count: invalid syntax
baseline-bench.txt:1309838: parsing iteration count: invalid syntax
baseline-bench.txt:1623807: parsing iteration count: invalid syntax
benchmark-results.txt:307: parsing iteration count: invalid syntax
benchmark-results.txt:296900: parsing iteration count: invalid syntax
benchmark-results.txt:622119: parsing iteration count: invalid syntax
benchmark-results.txt:1142575: parsing iteration count: invalid syntax
benchmark-results.txt:1477655: parsing iteration count: invalid syntax
benchmark-results.txt:1803723: 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 │       benchmark-results.txt        │
                            │       sec/op       │    sec/op     vs base              │
InterpreterCreation-4              10.334m ± 55%   9.785m ± 65%       ~ (p=0.093 n=6)
ComponentLoad-4                     3.572m ±  5%   3.583m ±  1%       ~ (p=0.818 n=6)
ComponentExecute-4                  1.933µ ±  1%   1.945µ ±  1%       ~ (p=0.065 n=6)
PoolContention/workers-1-4          1.104µ ±  1%   1.099µ ±  3%       ~ (p=0.729 n=6)
PoolContention/workers-2-4          1.071µ ±  7%   1.095µ ±  2%       ~ (p=0.065 n=6)
PoolContention/workers-4-4          1.075µ ±  1%   1.091µ ±  1%  +1.49% (p=0.009 n=6)
PoolContention/workers-8-4          1.082µ ±  1%   1.089µ ±  0%  +0.65% (p=0.037 n=6)
PoolContention/workers-16-4         1.084µ ±  1%   1.096µ ±  2%  +1.11% (p=0.004 n=6)
ComponentLifecycle-4                3.595m ±  1%   3.591m ±  1%       ~ (p=0.485 n=6)
SourceValidation-4                  2.308µ ±  1%   2.327µ ±  1%  +0.80% (p=0.026 n=6)
RegistryConcurrent-4                804.3n ±  3%   806.2n ±  5%       ~ (p=0.699 n=6)
LoaderLoadFromString-4              3.629m ±  2%   3.605m ±  2%       ~ (p=0.065 n=6)
geomean                             19.24µ         19.25µ        +0.06%

                            │ baseline-bench.txt │        benchmark-results.txt         │
                            │        B/op        │     B/op      vs base                │
InterpreterCreation-4               2.027Mi ± 0%   2.027Mi ± 0%       ~ (p=0.589 n=6)
ComponentLoad-4                     2.180Mi ± 0%   2.180Mi ± 0%       ~ (p=0.258 n=6)
ComponentExecute-4                  1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-1-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-2-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-4-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-8-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-16-4         1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
ComponentLifecycle-4                2.183Mi ± 0%   2.183Mi ± 0%       ~ (p=0.074 n=6)
SourceValidation-4                  1.984Ki ± 0%   1.984Ki ± 0%       ~ (p=1.000 n=6) ¹
RegistryConcurrent-4                1.133Ki ± 0%   1.133Ki ± 0%       ~ (p=1.000 n=6) ¹
LoaderLoadFromString-4              2.182Mi ± 0%   2.182Mi ± 0%       ~ (p=0.677 n=6)
geomean                             15.25Ki        15.25Ki       -0.00%
¹ all samples are equal

                            │ baseline-bench.txt │        benchmark-results.txt        │
                            │     allocs/op      │  allocs/op   vs base                │
InterpreterCreation-4                15.68k ± 0%   15.68k ± 0%       ~ (p=1.000 n=6)
ComponentLoad-4                      18.02k ± 0%   18.02k ± 0%       ~ (p=1.000 n=6)
ComponentExecute-4                    25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-1-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-2-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-4-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-8-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-16-4           25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
ComponentLifecycle-4                 18.07k ± 0%   18.07k ± 0%       ~ (p=1.000 n=6) ¹
SourceValidation-4                    32.00 ± 0%    32.00 ± 0%       ~ (p=1.000 n=6) ¹
RegistryConcurrent-4                  2.000 ± 0%    2.000 ± 0%       ~ (p=1.000 n=6) ¹
LoaderLoadFromString-4               18.06k ± 0%   18.06k ± 0%       ~ (p=1.000 n=6) ¹
geomean                               183.3         183.3       +0.00%
¹ all samples are equal

pkg: github.com/GoCodeAlone/workflow/middleware
                                  │ baseline-bench.txt │       benchmark-results.txt       │
                                  │       sec/op       │   sec/op     vs base              │
CircuitBreakerDetection-4                  285.2n ± 5%   285.8n ± 4%       ~ (p=0.485 n=6)
CircuitBreakerExecution_Success-4          21.47n ± 3%   21.55n ± 0%       ~ (p=0.071 n=6)
CircuitBreakerExecution_Failure-4          66.06n ± 1%   66.22n ± 0%       ~ (p=0.065 n=6)
geomean                                    73.96n        74.16n       +0.27%

                                  │ baseline-bench.txt │       benchmark-results.txt        │
                                  │        B/op        │    B/op     vs base                │
CircuitBreakerDetection-4                 144.0 ± 0%     144.0 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Success-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Failure-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                              ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                  │ baseline-bench.txt │       benchmark-results.txt        │
                                  │     allocs/op      │ allocs/op   vs base                │
CircuitBreakerDetection-4                 1.000 ± 0%     1.000 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Success-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Failure-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                              ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/module
                                 │ baseline-bench.txt │       benchmark-results.txt        │
                                 │       sec/op       │    sec/op     vs base              │
IaCStateBackend_InProcess-4              311.8n ± 32%   344.1n ± 21%       ~ (p=0.394 n=6)
IaCStateBackend_GRPC-4                   9.454m ±  8%   9.563m ±  3%       ~ (p=0.485 n=6)
JQTransform_Simple-4                     689.4n ± 36%   702.8n ± 28%       ~ (p=0.818 n=6)
JQTransform_ObjectConstruction-4         1.526µ ±  1%   1.512µ ±  4%       ~ (p=0.368 n=6)
JQTransform_ArraySelect-4                3.417µ ±  1%   3.535µ ±  5%  +3.45% (p=0.028 n=6)
JQTransform_Complex-4                    39.90µ ±  1%   38.23µ ±  1%  -4.19% (p=0.002 n=6)
JQTransform_Throughput-4                 1.885µ ±  2%   1.818µ ±  1%  -3.56% (p=0.002 n=6)
SSEPublishDelivery-4                     65.03n ±  1%   64.80n ±  8%       ~ (p=0.065 n=6)
geomean                                  3.884µ         3.919µ        +0.90%

                                 │ baseline-bench.txt │        benchmark-results.txt         │
                                 │        B/op        │     B/op      vs base                │
IaCStateBackend_InProcess-4              416.0 ± 0%       416.0 ± 0%       ~ (p=1.000 n=6) ¹
IaCStateBackend_GRPC-4                 5.885Mi ± 7%     6.003Mi ± 4%       ~ (p=0.485 n=6)
JQTransform_Simple-4                   1.273Ki ± 0%     1.273Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ObjectConstruction-4       1.773Ki ± 0%     1.773Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ArraySelect-4              2.625Ki ± 0%     2.625Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Complex-4                  16.31Ki ± 0%     16.31Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Throughput-4               1.984Ki ± 0%     1.984Ki ± 0%       ~ (p=1.000 n=6) ¹
SSEPublishDelivery-4                     0.000 ± 0%       0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                             ²                 +0.25%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                 │ baseline-bench.txt │        benchmark-results.txt        │
                                 │     allocs/op      │  allocs/op   vs base                │
IaCStateBackend_InProcess-4              2.000 ± 0%      2.000 ± 0%       ~ (p=1.000 n=6) ¹
IaCStateBackend_GRPC-4                  6.836k ± 0%     6.833k ± 0%       ~ (p=0.294 n=6)
JQTransform_Simple-4                     10.00 ± 0%      10.00 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ObjectConstruction-4         15.00 ± 0%      15.00 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ArraySelect-4                30.00 ± 0%      30.00 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Complex-4                    328.0 ± 0%      328.0 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Throughput-4                 17.00 ± 0%      17.00 ± 0%       ~ (p=1.000 n=6) ¹
SSEPublishDelivery-4                     0.000 ± 0%      0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                             ²                -0.01%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/schema
                                    │ baseline-bench.txt │       benchmark-results.txt       │
                                    │       sec/op       │   sec/op     vs base              │
SchemaValidation_Simple-4                   1.135µ ±  7%   1.097µ ± 2%       ~ (p=0.065 n=6)
SchemaValidation_AllFields-4                1.675µ ± 14%   1.681µ ± 3%       ~ (p=0.818 n=6)
SchemaValidation_FormatValidation-4         1.578µ ±  2%   1.585µ ± 4%       ~ (p=0.699 n=6)
SchemaValidation_ManySchemas-4              1.843µ ±  3%   1.808µ ± 4%       ~ (p=0.472 n=6)
geomean                                     1.533µ         1.516µ       -1.11%

                                    │ baseline-bench.txt │       benchmark-results.txt        │
                                    │        B/op        │    B/op     vs base                │
SchemaValidation_Simple-4                   0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_AllFields-4                0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_FormatValidation-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_ManySchemas-4              0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                                ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                    │ baseline-bench.txt │       benchmark-results.txt        │
                                    │     allocs/op      │ allocs/op   vs base                │
SchemaValidation_Simple-4                   0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_AllFields-4                0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_FormatValidation-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_ManySchemas-4              0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                                ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/store
                                   │ baseline-bench.txt │        benchmark-results.txt        │
                                   │       sec/op       │    sec/op     vs base               │
EventStoreAppend_InMemory-4                1.165µ ± 13%   1.181µ ± 11%        ~ (p=0.589 n=6)
EventStoreAppend_SQLite-4                  1.320m ±  3%   1.390m ±  5%   +5.34% (p=0.015 n=6)
GetTimeline_InMemory/events-10-4           14.02µ ±  5%   14.60µ ±  4%   +4.13% (p=0.026 n=6)
GetTimeline_InMemory/events-50-4           77.92µ ±  2%   81.47µ ±  3%   +4.56% (p=0.009 n=6)
GetTimeline_InMemory/events-100-4          158.5µ ±  2%   163.4µ ±  5%        ~ (p=0.180 n=6)
GetTimeline_InMemory/events-500-4          628.5µ ± 23%   823.3µ ±  2%  +30.99% (p=0.002 n=6)
GetTimeline_InMemory/events-1000-4         1.269m ±  1%   1.312m ± 21%   +3.39% (p=0.002 n=6)
GetTimeline_SQLite/events-10-4             104.9µ ±  1%   106.1µ ±  1%   +1.14% (p=0.002 n=6)
GetTimeline_SQLite/events-50-4             246.2µ ±  0%   248.1µ ±  1%   +0.79% (p=0.004 n=6)
GetTimeline_SQLite/events-100-4            419.2µ ±  1%   424.5µ ±  1%   +1.28% (p=0.015 n=6)
GetTimeline_SQLite/events-500-4            1.780m ±  1%   1.810m ±  2%   +1.68% (p=0.002 n=6)
GetTimeline_SQLite/events-1000-4           3.469m ±  1%   3.515m ±  1%   +1.30% (p=0.002 n=6)
geomean                                    221.8µ         232.1µ         +4.65%

                                   │ baseline-bench.txt │        benchmark-results.txt         │
                                   │        B/op        │     B/op      vs base                │
EventStoreAppend_InMemory-4                 781.5 ± 11%     804.0 ± 7%       ~ (p=0.699 n=6)
EventStoreAppend_SQLite-4                 1.986Ki ±  2%   1.983Ki ± 2%       ~ (p=0.450 n=6)
GetTimeline_InMemory/events-10-4          7.953Ki ±  0%   7.953Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-50-4          46.62Ki ±  0%   46.62Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-100-4         94.48Ki ±  0%   94.48Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-500-4         472.8Ki ±  0%   472.8Ki ± 0%       ~ (p=0.080 n=6)
GetTimeline_InMemory/events-1000-4        944.3Ki ±  0%   944.3Ki ± 0%       ~ (p=0.719 n=6)
GetTimeline_SQLite/events-10-4            16.74Ki ±  0%   16.74Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-50-4            87.14Ki ±  0%   87.14Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-100-4           175.4Ki ±  0%   175.4Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-500-4           846.1Ki ±  0%   846.1Ki ± 0%       ~ (p=1.000 n=6)
GetTimeline_SQLite/events-1000-4          1.639Mi ±  0%   1.639Mi ± 0%       ~ (p=1.000 n=6)
geomean                                   67.29Ki         67.44Ki       +0.22%
¹ all samples are equal

                                   │ baseline-bench.txt │        benchmark-results.txt        │
                                   │     allocs/op      │  allocs/op   vs base                │
EventStoreAppend_InMemory-4                  7.000 ± 0%    7.000 ± 0%       ~ (p=1.000 n=6) ¹
EventStoreAppend_SQLite-4                    53.00 ± 0%    53.00 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-10-4             125.0 ± 0%    125.0 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-50-4             653.0 ± 0%    653.0 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-100-4           1.306k ± 0%   1.306k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-500-4           6.514k ± 0%   6.514k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-1000-4          13.02k ± 0%   13.02k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-10-4               382.0 ± 0%    382.0 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-50-4              1.852k ± 0%   1.852k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-100-4             3.681k ± 0%   3.681k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-500-4             18.54k ± 0%   18.54k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-1000-4            37.29k ± 0%   37.29k ± 0%       ~ (p=1.000 n=6) ¹
geomean                                     1.162k        1.162k       +0.00%
¹ all samples are equal

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

@intel352 intel352 merged commit 1afc67b into main May 31, 2026
22 checks passed
@intel352 intel352 deleted the feat/cigen-phase-secret-scoping branch May 31, 2026 20:59
intel352 added a commit that referenced this pull request May 31, 2026
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.

1 participant