Skip to content

feat(wfctl): smart CI generation — cigen analyze→plan→render + ci plan/generate + MCP (PR3/7)#800

Merged
intel352 merged 10 commits into
mainfrom
feat/wfctl-cigen-core
May 30, 2026
Merged

feat(wfctl): smart CI generation — cigen analyze→plan→render + ci plan/generate + MCP (PR3/7)#800
intel352 merged 10 commits into
mainfrom
feat/wfctl-cigen-core

Conversation

@intel352
Copy link
Copy Markdown
Contributor

What

PR3 of the wfctl secrets wizard + smart CI generation cascade (design+plan in workspace:docs/plans/2026-05-30-wfctl-secrets-wizard-and-smart-ci{-design,}.md, adversarial PASS, scope-locked). Replaces template-stamped CI generation with a config-derived analyze → CIPlan → render engine. Independent of PR2; depends only on PR1 (merged).

Tasks (11–16)

  • cigen package (new, exported): Analyze(configs, opts) (*CIPlan, error) derives a platform-neutral plan from the real config.WorkflowConfigPluginInstall (plugin/infra module or .wfctl-lock.yaml), PlanGuard (Protected modules), Migrations (ci.migrations), Build.Docker (Dockerfile), deploy phases (--phase-config), triggers.
  • Secrets union + smoke + Warnings: unions secrets.entries${VAR} in env_vars_secret ∪ iac token/spaces ∪ migrations DB env (deduped); smoke from health_check.http_path + PRIMARY domain; Warnings[] for state-derived secret names (e.g. hash-suffixed DB URL — unknowable pre-apply) and case/alias mismatches (non-UPPER_SNAKE). Raw-map navigation is panic-safe on missing/wrong-type keys.
  • Renderers: RenderGitHubActions (plan / apply[-prereq→-deploy w/ needs] / migrations / smoke jobs, ${{ secrets.NAME }} refs, real plan-guard that fails on replace/destroy, relative paths: filters) and RenderGitLabCI. Output is valid YAML (parse-back tested).
  • CLI: wfctl ci plan (emits CIPlan JSON for AI-stepping) + smart wfctl ci generate (--from-plan / --diff / --exit-code / --phase-config; no silent overwrite). Template consts/funcs removed.
  • MCP: new ci_plan tool + generate_github_actions routed through cigen. scaffold_ci left untouched (it generates a ci: section from a description — the inverse of cigen's role).

Review findings fixed (adversarial + code review)

  • Critical: MCP ci_plan no longer embeds a deleted temp path — Options.ConfigPathAlias gives a stable logical config name.
  • Important: plan-guard is now a real gate (was a no-op || true); paths: filters are checkout-relative (was leaking absolute paths → triggers never fired).

Verification

  • GOWORK=off go test ./cigen/ ./mcp/ ./cmd/wfctl/ → all ok; golangci-lint0 issues.
  • Binary smoke: ci plan config_path is logical (deploy.yaml, not /tmp/...); generated GHA parses as YAML; plan-guard has no || true; paths: relative.
  • New tests: plan-guard-real-gate, relative-paths, config-path-alias, logical-not-temp, two-phase.

Notes

  • Smart Jenkins/CircleCI deferred (the ci-generator plugin keeps template renderers for those; PR5 routes GHA/GitLab through cigen).
  • Copilot review not requested (service down per operator).

🤖 Generated with Claude Code

intel352 and others added 10 commits May 30, 2026 15:55
Introduces cigen package with platform-neutral CIPlan struct and
Analyze() function that derives PluginInstall, PlanGuard, Migrations,
Build, Secrets, Smoke, Phases, and Triggers from typed WorkflowConfig
fields. Includes golden fixture + 4 passing tests.

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

Extends Analyze() to union secrets.entries, ${VAR} refs from
env_vars_secret and iac.provider config fields, and migrations DBEnv
into a deduplicated SecretRef slice. Smoke derives URL+path from an
infra.container_service module's health_check + PRIMARY domain. Warnings
surface state-derived secrets (IaC output / migrations DBEnv) and
non-upper-case secret names. Multisite-shaped fixture + 4 tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
RenderGitHubActions() emits a single workflow file with plan
(PR-only), apply (or apply-prereq→apply-deploy with needs for
multi-phase), optional migrations step in the last apply job,
smoke curl job, wfctl plugin install step, setup-wfctl version pin,
and per-secret ${{ secrets.NAME }} env entries. All output parses
as valid YAML. 6 tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
RenderGitLabCI() emits .gitlab-ci.yml with plan/apply/smoke stages,
merge-request rules, needs-chaining for multi-phase, secret refs as
$NAME CI variables, and plugin install in before_script. No deprecated
'only:' syntax. Output parses as valid YAML. 5 tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replaces the ghaInfraTemplate/ghaBuildTemplate/gitlabCITemplate text
templates and their generateGitHubActions/generateGitLabCI functions
with thin wrappers that build a minimal CIPlan from ciOptions and
delegate to cigen.RenderGitHubActions / cigen.RenderGitLabCI.
runCIGenerate now routes through cigen.Analyze + renderer with full
--write guard, --diff/--exit-code, --from-plan, and --phase-config
flags. Legacy ciOptions + generateCIFiles retained for backward compat.
Updated ci_test.go assertions to match cigen output.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds 'wfctl ci plan' subcommand (ci_plan.go) that calls cigen.Analyze
and writes CIPlan JSON to --out (default stdout). Supports
--phase-config for 2-phase plans, --wfctl-version pin, --branch and
--runner overrides. Tests: runCIPlan writes parseable JSON with
warnings+phases; runCIGenerate --from-plan loads plan and renders
without re-analyzing; --diff exits 0 when files match; --write guard
rejects overwrite without flag.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds new ci_plan MCP tool (handleCIPlan) that writes yaml_content to
a temp file, calls cigen.Analyze, and returns the CIPlan JSON.
Routes handleGenerateGithubActions through cigen.Analyze +
RenderGitHubActions; legacy cd_yaml path retained for backward compat
via mcpGenerateCDWorkflow; ci_yaml now contains cigen output.
mcpAnalyzeFromYAML helper handles temp-file lifecycle for MCP
yaml_content inputs. Updated 3 existing GHA tests + added 3 new
ci_plan tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- resolveOutputPath: respect explicit --out dir for all paths including
  .github/workflows/ subdirectories (was only used for flat names)
- ci_plan: add -c shorthand for --config
- render_gha.go: replace b.WriteString(fmt.Sprintf()) with fmt.Fprintf
- render_gitlab.go: same + use %q for quoted YAML strings
- ci.go: remove unused detectModuleTypes + renderCITemplate; drop bytes/
  text/template/yaml.v3 imports
- mcp/wfctl_tools.go: remove unused mcpGenerateCIWorkflow
golangci-lint: 0 issues

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add --help/-h/help cases to runCI switch so 'wfctl ci --help' returns
nil (exit 0) instead of the error from ciUsage().

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ivize trigger paths; minors

CRITICAL: MCP ci_plan wrote yaml_content to an os.CreateTemp file and
returned a CIPlan whose DeployPhase.ConfigPath pointed at the deleted
/tmp path, so generated CI steps + paths: filter referenced dead paths.
Added Options.ConfigPathAlias; mcpAnalyzeFromYAML now passes a stable
logical name (deploy.yaml / deploy.prereq.yaml).

IMPORTANT: GHA PlanGuard was a no-op (`grep -q ... || true`). Replaced
with a real gate mirroring the multisite infra.yml pattern: visible
`wfctl infra plan | tee`, then `exit 1` when the plan includes
replace/destroy. No `|| true`.

IMPORTANT: writePhasePaths leaked absolute config paths into the GHA
paths: trigger filter (never matches a checkout). Analyze now
relativizes ConfigPath to cwd via filepath.Rel, falling back to
filepath.Base when it escapes cwd.

MINORS: removed redundant `|| m.Type == "iac.provider"`; dropped the
no-op GitLab `variables: {NAME: $NAME}` block (project CI vars are
auto-injected); added explicit parens to the apply if:; added
cigen/testdata/prereq.yaml fixture.

Tests: plan-guard-real-gate, no-plan-guard-when-unset, relative-paths
filter, absolute-path-relativized, alias-verbatim, MCP
config_path-is-logical-not-temp + two-phase logical paths, GitLab
no-redundant-secret-vars.

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

codecov Bot commented May 30, 2026

@github-actions
Copy link
Copy Markdown

⏱ Benchmark Results

No significant performance regressions detected.

benchstat comparison (baseline → PR)
## benchstat: baseline → PR
baseline-bench.txt:303: parsing iteration count: invalid syntax
baseline-bench.txt:320359: parsing iteration count: invalid syntax
baseline-bench.txt:593132: parsing iteration count: invalid syntax
baseline-bench.txt:916056: parsing iteration count: invalid syntax
baseline-bench.txt:1245700: parsing iteration count: invalid syntax
baseline-bench.txt:1792355: parsing iteration count: invalid syntax
benchmark-results.txt:305: parsing iteration count: invalid syntax
benchmark-results.txt:302379: parsing iteration count: invalid syntax
benchmark-results.txt:632989: parsing iteration count: invalid syntax
benchmark-results.txt:930062: parsing iteration count: invalid syntax
benchmark-results.txt:1259103: parsing iteration count: invalid syntax
benchmark-results.txt:1569961: 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 │
                            │       sec/op       │
InterpreterCreation-4               9.898m ± 64%
ComponentLoad-4                     3.579m ±  8%
ComponentExecute-4                  1.942µ ±  2%
PoolContention/workers-1-4          1.088µ ±  3%
PoolContention/workers-2-4          1.087µ ±  2%
PoolContention/workers-4-4          1.090µ ±  1%
PoolContention/workers-8-4          1.087µ ±  1%
PoolContention/workers-16-4         1.114µ ±  2%
ComponentLifecycle-4                3.614m ±  1%
SourceValidation-4                  2.324µ ±  1%
RegistryConcurrent-4                809.4n ±  3%
LoaderLoadFromString-4              3.633m ±  2%
geomean                             19.29µ

                            │ 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

cpu: AMD EPYC 9V74 80-Core Processor                
                            │ benchmark-results.txt │
                            │        sec/op         │
InterpreterCreation-4                  9.681m ± 69%
ComponentLoad-4                        3.469m ±  8%
ComponentExecute-4                     1.847µ ±  2%
PoolContention/workers-1-4             1.048µ ±  1%
PoolContention/workers-2-4             1.032µ ± 10%
PoolContention/workers-4-4             1.005µ ±  2%
PoolContention/workers-8-4             1.011µ ±  2%
PoolContention/workers-16-4            1.016µ ±  1%
ComponentLifecycle-4                   3.549m ±  1%
SourceValidation-4                     2.131µ ±  0%
RegistryConcurrent-4                   796.5n ±  4%
LoaderLoadFromString-4                 3.562m ±  0%
geomean                                18.38µ

                            │ 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

pkg: github.com/GoCodeAlone/workflow/middleware
cpu: AMD EPYC 7763 64-Core Processor                
                                  │ baseline-bench.txt │
                                  │       sec/op       │
CircuitBreakerDetection-4                  287.7n ± 5%
CircuitBreakerExecution_Success-4          21.52n ± 2%
CircuitBreakerExecution_Failure-4          66.16n ± 0%
geomean                                    74.26n

                                  │ 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

cpu: AMD EPYC 9V74 80-Core Processor                
                                  │ benchmark-results.txt │
                                  │        sec/op         │
CircuitBreakerDetection-4                     298.5n ± 4%
CircuitBreakerExecution_Success-4             22.68n ± 1%
CircuitBreakerExecution_Failure-4             70.94n ± 0%
geomean                                       78.30n

                                  │ 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

pkg: github.com/GoCodeAlone/workflow/module
cpu: AMD EPYC 7763 64-Core Processor                
                                 │ baseline-bench.txt │
                                 │       sec/op       │
IaCStateBackend_InProcess-4              326.1n ± 23%
IaCStateBackend_GRPC-4                   9.503m ±  3%
JQTransform_Simple-4                     698.1n ± 30%
JQTransform_ObjectConstruction-4         1.492µ ±  1%
JQTransform_ArraySelect-4                3.372µ ±  1%
JQTransform_Complex-4                    38.56µ ±  1%
JQTransform_Throughput-4                 1.820µ ±  1%
SSEPublishDelivery-4                     64.84n ±  0%
geomean                                  3.862µ

                                 │ baseline-bench.txt │
                                 │        B/op        │
IaCStateBackend_InProcess-4              416.0 ± 0%
IaCStateBackend_GRPC-4                 5.808Mi ± 9%
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.839k ± 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                
                                 │ benchmark-results.txt │
                                 │        sec/op         │
IaCStateBackend_InProcess-4                 291.6n ±  1%
IaCStateBackend_GRPC-4                      11.10m ±  9%
JQTransform_Simple-4                        672.8n ± 31%
JQTransform_ObjectConstruction-4            1.477µ ±  1%
JQTransform_ArraySelect-4                   3.469µ ±  1%
JQTransform_Complex-4                       42.09µ ±  2%
JQTransform_Throughput-4                    1.795µ ±  1%
SSEPublishDelivery-4                        64.58n ±  0%
geomean                                     3.908µ

                                 │ benchmark-results.txt │
                                 │         B/op          │
IaCStateBackend_InProcess-4                 416.0 ± 0%
IaCStateBackend_GRPC-4                    5.719Mi ± 9%
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.860k ± 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                
                                    │ baseline-bench.txt │
                                    │       sec/op       │
SchemaValidation_Simple-4                    1.092µ ± 1%
SchemaValidation_AllFields-4                 1.657µ ± 5%
SchemaValidation_FormatValidation-4          1.581µ ± 2%
SchemaValidation_ManySchemas-4               1.844µ ± 5%
geomean                                      1.516µ

                                    │ 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

cpu: AMD EPYC 9V74 80-Core Processor                
                                    │ benchmark-results.txt │
                                    │        sec/op         │
SchemaValidation_Simple-4                       1.088µ ± 5%
SchemaValidation_AllFields-4                    1.629µ ± 2%
SchemaValidation_FormatValidation-4             1.569µ ± 1%
SchemaValidation_ManySchemas-4                  1.585µ ± 2%
geomean                                         1.449µ

                                    │ 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

pkg: github.com/GoCodeAlone/workflow/store
cpu: AMD EPYC 7763 64-Core Processor                
                                   │ baseline-bench.txt │
                                   │       sec/op       │
EventStoreAppend_InMemory-4                1.201µ ± 14%
EventStoreAppend_SQLite-4                  1.263m ±  3%
GetTimeline_InMemory/events-10-4           14.18µ ±  2%
GetTimeline_InMemory/events-50-4           80.14µ ±  2%
GetTimeline_InMemory/events-100-4          160.7µ ±  3%
GetTimeline_InMemory/events-500-4          800.8µ ± 16%
GetTimeline_InMemory/events-1000-4         1.297m ±  1%
GetTimeline_SQLite/events-10-4             105.1µ ±  1%
GetTimeline_SQLite/events-50-4             248.2µ ±  1%
GetTimeline_SQLite/events-100-4            422.1µ ±  0%
GetTimeline_SQLite/events-500-4            1.808m ±  0%
GetTimeline_SQLite/events-1000-4           3.518m ±  1%
geomean                                    228.4µ

                                   │ baseline-bench.txt │
                                   │        B/op        │
EventStoreAppend_InMemory-4                  806.0 ± 5%
EventStoreAppend_SQLite-4                  1.983Ki ± 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.45Ki

                                   │ 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

cpu: AMD EPYC 9V74 80-Core Processor                
                                   │ benchmark-results.txt │
                                   │        sec/op         │
EventStoreAppend_InMemory-4                   1.078µ ± 13%
EventStoreAppend_SQLite-4                     1.008m ±  7%
GetTimeline_InMemory/events-10-4              13.98µ ±  5%
GetTimeline_InMemory/events-50-4              78.10µ ±  2%
GetTimeline_InMemory/events-100-4             118.7µ ±  1%
GetTimeline_InMemory/events-500-4             617.8µ ±  1%
GetTimeline_InMemory/events-1000-4            1.245m ±  1%
GetTimeline_SQLite/events-10-4                97.01µ ±  1%
GetTimeline_SQLite/events-50-4                242.5µ ±  1%
GetTimeline_SQLite/events-100-4               408.1µ ±  1%
GetTimeline_SQLite/events-500-4               1.759m ±  1%
GetTimeline_SQLite/events-1000-4              3.447m ±  1%
geomean                                       207.3µ

                                   │ benchmark-results.txt │
                                   │         B/op          │
EventStoreAppend_InMemory-4                    746.5 ± 12%
EventStoreAppend_SQLite-4                    1.985Ki ±  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.03Ki

                                   │ 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

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

@intel352 intel352 merged commit 9214c63 into main May 30, 2026
22 checks passed
@intel352 intel352 deleted the feat/wfctl-cigen-core branch May 30, 2026 21:14
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