Skip to content

wfctl audit: 13 CLI fixes, registry data, plugin ecosystem#324

Merged
intel352 merged 26 commits intomainfrom
feat/wfctl-audit
Mar 13, 2026
Merged

wfctl audit: 13 CLI fixes, registry data, plugin ecosystem#324
intel352 merged 26 commits intomainfrom
feat/wfctl-audit

Conversation

@intel352
Copy link
Contributor

Summary

  • 13 CLI fixes: --help exit codes, -data-dir-plugin-dir rename, trailing flag detection, full plugin name resolution (workflow-plugin-authzauthz), plugin-dir honored, update version check, deploy positional config args, init Dockerfile go.sum handling, validate --dir skips non-workflow YAML, validate reports imports, infra error messages, plugin info absolute paths, PluginManifest legacy capabilities UnmarshalJSON
  • Registry data fixes: agent manifest type (internalbuiltin), ratchet downloads, authz name verification, schema validation gap, version sync script
  • Plugin ecosystem: GitHub URL install (owner/repo@version), .wfctl.yaml lockfile support, engine minEngineVersion warning, goreleaser standardization across 12 plugin repos, registry auto-sync CI on release

Design

See: docs/plans/2026-03-12-wfctl-audit-design.md

Implementation Plan

See: docs/plans/2026-03-12-wfctl-audit.md

Changes

Phase Tasks What
A: CLI Fixes 1-13 13 bug fixes and UX improvements in cmd/wfctl/
B: Registry 14-15 Manifest corrections + version sync script in workflow-registry/
C: Ecosystem 16-20 GitHub install, lockfile, minEngineVersion, goreleaser, auto-sync CI

Addresses: PRs #321, #322, Issue #316

🤖 Generated with Claude Code

intel352 and others added 24 commits March 12, 2026 20:12
Addresses PRs #321, #322, and issue #316. Covers 13 CLI fixes,
5 registry data fixes, and holistic plugin ecosystem plan including
goreleaser standardization, GitHub URL install, lockfile support,
minEngineVersion checks, and auto-sync CI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wave 2 design: Okta (~130 steps), Datadog (~120), LaunchDarkly (~100),
Permit.io (~80), Salesforce (~75), OpenLMS (~120) — all MIT, community tier.

Release plan: tag untagged plugins, create validation scenarios 51-59
with mock HTTP backends in workflow-scenarios.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase A: 13 CLI fixes (help exit codes, plugin-dir rename, flag ordering, etc.)
Phase B: 2 registry data fix tasks
Phase C: 5 plugin ecosystem tasks (GitHub URL install, lockfile, goreleaser)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Alignment check identified missing coverage for design requirement B5.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Permit.io fits alongside Casbin in the existing authz plugin
rather than a standalone repo. Same multi-provider pattern as
payments (Stripe + PayPal).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rename the flag from -data-dir to -plugin-dir across runPluginInstall,
runPluginList, runPluginUpdate, runPluginRemove, and runPluginInfo for
consistency with other wfctl commands. Keep -data-dir as a working
deprecated alias. Update pluginUsage() to document -plugin-dir.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add checkTrailingFlags() to detect when flags are passed after
positional arguments, and wire it into runPluginInit,
runRegistryAdd, and runRegistryRemove.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add isHelpRequested() helper that detects flag.ErrHelp propagated through
the pipeline engine. In main():
- No-args case now exits 0 (showing help is not an error)
- Help requests in dispatch exit 0 without printing engine error

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add normalizePluginName() stripping "workflow-plugin-" prefix so users
can reference plugins by short name (e.g. "authz") or full name
(e.g. "workflow-plugin-authz") interchangeably. Wire into FetchManifest
and SearchPlugins.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add isWorkflowYAML() that checks the first 100 lines of a file for
top-level modules:, workflows:, or pipelines: keys. Files found by
--dir that don't match are skipped with a stderr message, preventing
false validation failures on GitHub Actions CI files and other YAML.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Before downloading, compare installed plugin.json version against the
registry manifest version. If equal, print "already at latest version"
and skip. If different, print "Updating from X to Y..." and proceed.
Also adds -config flag to plugin update for registry config override.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Improve the error message from the generic "no config file found" to a
helpful message that explains what the config needs and how to generate one.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Verify that install uses -plugin-dir (custom dir) instead of the
default data/plugins path. This guards the fix from Task 2 that
updated runPluginUpdate to pass --plugin-dir, not --data-dir, when
calling runPluginInstall.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace `COPY go.mod go.sum ./` with `COPY go.mod ./` + `COPY go.sum* ./`
so the generated Dockerfile works whether or not go.sum exists yet.
The glob pattern in the second COPY is a no-op when go.sum is absent.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Read raw YAML to extract the imports: list before calling
config.LoadFromFile. After loading, print "Resolved N import(s): ..."
to stderr so users can see which files were included. This makes the
validate command transparent about include/import resolution.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Allow users to pass the config file as a positional argument instead of
always requiring -config, e.g. `wfctl deploy cloud myapp.yaml`.

Applied to: runDeployDocker, runK8sGenerate, runK8sApply, runDeployCloud.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… format

Add custom UnmarshalJSON on PluginManifest that detects whether the
capabilities field is an array (new CapabilityDecl format) or an object
(legacy registry format with moduleTypes/stepTypes/triggerTypes).

When the legacy object format is detected, its type lists are merged into
the top-level ModuleTypes, StepTypes, and TriggerTypes fields so callers
always find types in a consistent location regardless of plugin.json format.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Resolve pluginDir to absolute path before displaying the binary path,
so users see /absolute/path/to/plugin instead of relative data/plugins/foo.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add MinEngineVersion field to PluginManifest and checkEngineCompatibility()
to plugin/loader.go. The loader calls this on every plugin load — if the
running engine version is older than the plugin's declared minimum, a WARNING
is printed to stderr. No hard fail to allow testing newer plugins against
older engines.

SetEngineVersion() on PluginLoader threads the engine version through.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add parseGitHubRef() to detect owner/repo[@Version] references.
Add installFromGitHub() to query GitHub Releases API and download
assets matching {repo}_{os}_{arch}.tar.gz.

In runPluginInstall, when the registry lookup fails and the input
looks like a GitHub ref, fall back to direct GitHub installation.
This allows: wfctl plugin install GoCodeAlone/workflow-plugin-authz@v0.3.1

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add PluginLockfile/PluginLockEntry types with load/save that preserve
all other .wfctl.yaml fields (project, git, deploy) on round-trip.

Wire into plugin install:
- `wfctl plugin install` (no args): reads .wfctl.yaml plugins section
  and installs all pinned entries
- `wfctl plugin install <name>@<version>`: after successful install,
  updates/creates the plugins entry in .wfctl.yaml

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Reference .goreleaser.yml for plugin repos documenting required conventions:
- binary using {{ .ProjectName }} template
- archives include plugin.json
- before/after hooks to template plugin.json version from release tag

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two bugs in Task 16 GitHub install fallback:
1. Pass pluginName (version-stripped) to FetchManifest, not nameArg
   which may carry @Version suffix and cause lookup failures.
2. Compute destDir after normalizing the repo short name so
   owner/repo installs go to data/plugins/<shortname> not the raw input.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Task 17: installFromLockfile now passes just the plugin name (no @Version)
to runPluginInstall so updateLockfile doesn't fire and overwrite the pinned
entry in .wfctl.yaml during a lockfile-driven restore.

Task 18: checkEngineCompatibility uses slog.Warn instead of fmt.Fprintf
to stderr, consistent with the rest of the codebase. Remove unused "os"
import from loader.go.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 13, 2026 00:58
Copy link
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.

Copilot reviewed 30 out of 30 changed files in this pull request and generated no comments.

intel352 and others added 2 commits March 12, 2026 21:22
Replace local file path reference with ^0.2.0 from GitHub Packages
registry. Fixes CI failures where the local tarball doesn't exist.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 13, 2026 01:31
@github-actions
Copy link

github-actions bot commented Mar 13, 2026

⏱ Benchmark Results

No significant performance regressions detected.

benchstat comparison (baseline → PR)
## benchstat: baseline → PR
baseline-bench.txt:244: parsing iteration count: invalid syntax
baseline-bench.txt:308306: parsing iteration count: invalid syntax
baseline-bench.txt:590691: parsing iteration count: invalid syntax
baseline-bench.txt:908815: parsing iteration count: invalid syntax
baseline-bench.txt:1202777: parsing iteration count: invalid syntax
baseline-bench.txt:1501101: parsing iteration count: invalid syntax
benchmark-results.txt:244: parsing iteration count: invalid syntax
benchmark-results.txt:383057: parsing iteration count: invalid syntax
benchmark-results.txt:708276: parsing iteration count: invalid syntax
benchmark-results.txt:1011526: parsing iteration count: invalid syntax
benchmark-results.txt:1360352: parsing iteration count: invalid syntax
benchmark-results.txt:1733385: parsing iteration count: invalid syntax
goos: linux
goarch: amd64
pkg: github.com/GoCodeAlone/workflow/dynamic
cpu: AMD EPYC 9V74 80-Core Processor                
                            │ baseline-bench.txt │
                            │       sec/op       │
InterpreterCreation-4               6.113m ± 77%
ComponentLoad-4                     3.477m ± 13%
ComponentExecute-4                  1.939µ ±  2%
PoolContention/workers-1-4          1.056µ ±  4%
PoolContention/workers-2-4          1.055µ ±  2%
PoolContention/workers-4-4          1.050µ ±  0%
PoolContention/workers-8-4          1.047µ ±  1%
PoolContention/workers-16-4         1.061µ ±  2%
ComponentLifecycle-4                3.517m ±  4%
SourceValidation-4                  2.095µ ±  4%
RegistryConcurrent-4                763.5n ±  4%
LoaderLoadFromString-4              3.508m ±  2%
geomean                             17.87µ

                            │ baseline-bench.txt │
                            │        B/op        │
InterpreterCreation-4               1.944Mi ± 0%
ComponentLoad-4                     2.097Mi ± 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.099Mi ± 0%
SourceValidation-4                  1.984Ki ± 0%
RegistryConcurrent-4                1.133Ki ± 0%
LoaderLoadFromString-4              2.099Mi ± 0%
geomean                             15.05Ki

                            │ baseline-bench.txt │
                            │     allocs/op      │
InterpreterCreation-4                15.09k ± 0%
ComponentLoad-4                      17.43k ± 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                 17.48k ± 0%
SourceValidation-4                    32.00 ± 0%
RegistryConcurrent-4                  2.000 ± 0%
LoaderLoadFromString-4               17.47k ± 0%
geomean                               181.2

cpu: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                            │ benchmark-results.txt │
                            │        sec/op         │
InterpreterCreation-4                  6.376m ± 66%
ComponentLoad-4                        3.345m ±  1%
ComponentExecute-4                     1.898µ ±  2%
PoolContention/workers-1-4             1.194µ ±  2%
PoolContention/workers-2-4             1.186µ ±  0%
PoolContention/workers-4-4             1.189µ ±  1%
PoolContention/workers-8-4             1.193µ ±  1%
PoolContention/workers-16-4            1.205µ ±  1%
ComponentLifecycle-4                   3.401m ±  1%
SourceValidation-4                     2.315µ ±  0%
RegistryConcurrent-4                   962.1n ±  4%
LoaderLoadFromString-4                 3.418m ±  0%
geomean                                19.21µ

                            │ benchmark-results.txt │
                            │         B/op          │
InterpreterCreation-4                  1.944Mi ± 0%
ComponentLoad-4                        2.097Mi ± 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.099Mi ± 0%
SourceValidation-4                     1.984Ki ± 0%
RegistryConcurrent-4                   1.133Ki ± 0%
LoaderLoadFromString-4                 2.099Mi ± 0%
geomean                                15.05Ki

                            │ benchmark-results.txt │
                            │       allocs/op       │
InterpreterCreation-4                   15.09k ± 0%
ComponentLoad-4                         17.43k ± 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                    17.48k ± 0%
SourceValidation-4                       32.00 ± 0%
RegistryConcurrent-4                     2.000 ± 0%
LoaderLoadFromString-4                  17.47k ± 0%
geomean                                  181.2

pkg: github.com/GoCodeAlone/workflow/middleware
cpu: AMD EPYC 9V74 80-Core Processor                
                                  │ baseline-bench.txt │
                                  │       sec/op       │
CircuitBreakerDetection-4                  298.4n ± 4%
CircuitBreakerExecution_Success-4          22.70n ± 2%
CircuitBreakerExecution_Failure-4          70.31n ± 0%
geomean                                    78.09n

                                  │ 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: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                                  │ benchmark-results.txt │
                                  │        sec/op         │
CircuitBreakerDetection-4                     451.7n ± 4%
CircuitBreakerExecution_Success-4             59.77n ± 0%
CircuitBreakerExecution_Failure-4             64.67n ± 1%
geomean                                       120.4n

                                  │ 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 9V74 80-Core Processor                
                                 │ baseline-bench.txt │
                                 │       sec/op       │
JQTransform_Simple-4                     850.1n ± 28%
JQTransform_ObjectConstruction-4         1.416µ ±  2%
JQTransform_ArraySelect-4                3.420µ ±  1%
JQTransform_Complex-4                    40.64µ ±  2%
JQTransform_Throughput-4                 1.753µ ±  1%
SSEPublishDelivery-4                     56.55n ±  1%
geomean                                  1.597µ

                                 │ 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

cpu: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                                 │ benchmark-results.txt │
                                 │        sec/op         │
JQTransform_Simple-4                        958.0n ± 19%
JQTransform_ObjectConstruction-4            1.476µ ±  1%
JQTransform_ArraySelect-4                   3.148µ ±  0%
JQTransform_Complex-4                       34.78µ ±  0%
JQTransform_Throughput-4                    1.777µ ±  1%
SSEPublishDelivery-4                        72.77n ±  0%
geomean                                     1.648µ

                                 │ 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

pkg: github.com/GoCodeAlone/workflow/schema
cpu: AMD EPYC 9V74 80-Core Processor                
                                    │ baseline-bench.txt │
                                    │       sec/op       │
SchemaValidation_Simple-4                    1.087µ ± 1%
SchemaValidation_AllFields-4                 1.641µ ± 2%
SchemaValidation_FormatValidation-4          1.583µ ± 2%
SchemaValidation_ManySchemas-4               1.600µ ± 2%
geomean                                      1.458µ

                                    │ 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: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                                    │ benchmark-results.txt │
                                    │        sec/op         │
SchemaValidation_Simple-4                      1.011µ ± 14%
SchemaValidation_AllFields-4                   1.521µ ±  7%
SchemaValidation_FormatValidation-4            1.477µ ±  1%
SchemaValidation_ManySchemas-4                 1.522µ ±  4%
geomean                                        1.363µ

                                    │ 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 9V74 80-Core Processor                
                                   │ baseline-bench.txt │
                                   │       sec/op       │
EventStoreAppend_InMemory-4                1.157µ ± 14%
EventStoreAppend_SQLite-4                  1.133m ±  6%
GetTimeline_InMemory/events-10-4           12.91µ ±  3%
GetTimeline_InMemory/events-50-4           56.05µ ± 29%
GetTimeline_InMemory/events-100-4          112.6µ ±  5%
GetTimeline_InMemory/events-500-4          579.2µ ±  1%
GetTimeline_InMemory/events-1000-4         1.179m ±  1%
GetTimeline_SQLite/events-10-4             93.30µ ±  0%
GetTimeline_SQLite/events-50-4             234.1µ ±  1%
GetTimeline_SQLite/events-100-4            399.7µ ±  1%
GetTimeline_SQLite/events-500-4            1.739m ±  6%
GetTimeline_SQLite/events-1000-4           3.406m ±  1%
geomean                                    198.6µ

                                   │ baseline-bench.txt │
                                   │        B/op        │
EventStoreAppend_InMemory-4                  781.5 ± 8%
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.29Ki

                                   │ 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: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                                   │ benchmark-results.txt │
                                   │        sec/op         │
EventStoreAppend_InMemory-4                   1.106µ ±  4%
EventStoreAppend_SQLite-4                     1.122m ±  7%
GetTimeline_InMemory/events-10-4              13.73µ ±  2%
GetTimeline_InMemory/events-50-4              74.77µ ±  4%
GetTimeline_InMemory/events-100-4             135.8µ ± 14%
GetTimeline_InMemory/events-500-4             599.8µ ±  1%
GetTimeline_InMemory/events-1000-4            1.221m ±  1%
GetTimeline_SQLite/events-10-4                81.63µ ±  1%
GetTimeline_SQLite/events-50-4                232.6µ ±  1%
GetTimeline_SQLite/events-100-4               415.6µ ±  0%
GetTimeline_SQLite/events-500-4               1.870m ±  2%
GetTimeline_SQLite/events-1000-4              3.674m ±  2%
geomean                                       208.8µ

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

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

Copy link
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.

Copilot reviewed 31 out of 32 changed files in this pull request and generated no comments.

Files not reviewed (1)
  • ui/package-lock.json: Language not supported

@intel352 intel352 merged commit 31f2154 into main Mar 13, 2026
15 checks passed
@intel352 intel352 deleted the feat/wfctl-audit branch March 13, 2026 01:46
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