Skip to content

feat(wfctl): plugin verify-capabilities subcommand (workflow#765)#766

Merged
intel352 merged 15 commits into
mainfrom
feat/765-verify-capabilities
May 24, 2026
Merged

feat(wfctl): plugin verify-capabilities subcommand (workflow#765)#766
intel352 merged 15 commits into
mainfrom
feat/765-verify-capabilities

Conversation

@intel352
Copy link
Copy Markdown
Contributor

Summary

Closes workflow#765. Runtime sibling to validate-contract: spawns a plugin binary, calls PluginService.GetManifest directly via gRPC, diffs Name + Version against plugin.json with sentinel-aware Version matrix. Catches the ldflag-missing truth-loop bug that closes the workflow#762/#764 contract.

Architecture

  • New subcommand wfctl plugin verify-capabilities --binary <path> <plugin-dir>.
  • --binary REQUIRED (no build-from-source — operator builds via goreleaser or go build).
  • Inline spawn-and-dial (~40 LOC); helper extraction deferred until a 3rd caller appears.
  • GetManifest called via pb.NewPluginServiceClient(pluginClient.Conn()) to bypass ExternalPluginAdapter.EngineManifest()'s precedence rules.
  • 5 fixture scenarios cover the full diff matrix (good, release-good, missing-ldflag, version-drift, name-drift).

Test plan

  • go test -count=1 -timeout 120s ./cmd/wfctl/... — all 15 verify-capabilities tests PASS
  • go vet ./... clean
  • wfctl plugin verify-capabilities --help prints expected usage
  • TestPluginConformance regression suite still PASS (no helper extraction; conformance untouched)
  • CI green

Design + plan

Iterated through 6 design cycles + 5 plan cycles + alignment-check + scope-lock per superpowers pipeline:

  • docs/plans/2026-05-24-verify-capabilities-design.md (cycle 6 PASS adversarial)
  • docs/plans/2026-05-24-verify-capabilities.md (cycle 5 PASS adversarial + alignment PASS + Locked 2026-05-24T05:01:50Z)

Implementer deviations

  1. Task 7 helper ldflag path corrected: -X github.com/test/%s.Version-X main.Version (fixture is package main; linker symbol is main.Version). Plan body retained as-is (scope-locked); test code carries the corrected form with explanatory comment.
  2. Final-verification conformance regex: plan says TestConformance, actual test names are TestPluginConformance*. Ran with correct pattern; suite green.

Non-goals (deferred)

  • Contract-diff via GetContractRegistry — follow-up issue feat(wfctl): plugin verify-capabilities subcommand (workflow#765) #766 (requires capabilities.iacServices schema on PluginManifest first).
  • Per-type RPCs (GetModuleTypes/GetStepTypes/GetTriggerTypes) — IaC bridge returns Unimplemented.
  • Scaffold-template release.yml wiring — separate follow-up PR on scaffold-workflow-plugin.

intel352 and others added 15 commits May 24, 2026 00:43
Files a design doc for the live-deploy CI matrix deferred from the
2026-05-19 multi-repo QoL sweep. Schema-level validation is insufficient
to promote a plugin to 'verified'; this design adds a weekly OIDC-driven
GitHub Actions matrix that exercises each IaC plugin's
examples/minimal/config.yaml against staging cloud accounts, auto-promotes
on green, demotes on 2 consecutive REDs.

Execution is gated on operator provisioning staging accounts + GitHub
OIDC trust per provider. Document this as the next concrete step.

Companion to workflow#725 (marketplace-verify subcommand). Closes #723.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes the runtime-truth gap left by #762/#764 static check (validate-contract). Spawns plugin binary, calls PluginService.GetManifest, diffs against plugin.json. New subcommand sibling to validate-contract.
…IL → revised)

Cycle-1 had 3 Critical findings:
- F1: diff table fields not on pb.Manifest (only 6 scalars; type lists on separate RPCs)
- F2: IaC bridge returns Unimplemented for type-list RPCs
- F4: handshake export path wrong (external.Handshake, not sdk)

Plus 4 Important + 1 Minor.

Cycle-2 pivots:
- Adopt reviewer Option 3: Manifest scalars + ContractRegistry only (drops per-type RPC walk; collapses F1+F2+F7)
- Adopt reviewer Option 2: drop build-from-source default; require --binary (addresses F5+F8 + cycle-1 self-challenge)
- Adopt reviewer Option 1 partial: extract spawnAndDial helper from plugin_conformance.go (kills F3 duplication)
- Fix F4 import; F5 version-diff matrix; F7 contract-diff for declared-contract half
…2 review)

Cycle-2 FAILed with 2 Critical + 4 Important. Cycle-3 pivots:

- Drop contract-diff entirely (F-NEW-1: plugin.json has no iacResources key; F-NEW-2: BuildContractRegistry emits infra-internal noise). Defer to follow-up issue #766 (introduces capabilities.iacServices schema + server-side BuildContractRegistryForPlugin filter).
- Fix version-diff matrix (F-NEW-3): sentinel set is {"", "(devel)...", "0.0.0"}, cite buildversion.go:36-42. Matrix's isSentinel() predicate covers all SDK-emitted forms.
- Specify test fixtures concretely (F-NEW-5): testdata/verify_capabilities/{good,release-good,missing-ldflag,version-drift,name-drift}/ mirroring plugin_validate_contract precedent.
- CI binary path via jq dist/artifacts.json lookup (F-NEW-6).

Scope reduces to: Manifest.Name exact + Manifest.Version sentinel-pattern matrix. Catches the truth-loop bug (ldflag-missing) the user actually asked about. Contract-diff deferred to follow-up after plugin.json schema gains LHS field.
…+ fixture precedent)

Cycle-3 FAILed: 2 Critical (sentinel-set drift; fixture precedent miscited). Cycle-4 fixes:

- F-CYCLE3-1: isSentinel() superset includes 'dev' to match SDK sentinel set {"", "dev", "(devel)"} from buildversion.go:36-42 + plugin.json '0.0.0' + HasPrefix '(devel)'.
- F-CYCLE3-2: Cite correct precedent — plugin_conformance_test.go:buildFixtureBinary with per-fixture go.mod + replace directive + GOWORK=off. Validate-contract is pure-static; never builds. Per-fixture layout spec includes go.mod template.
- F-CYCLE3-3: Add preflight binary-path validation + security note explicit; jq fallback ('// ""') guards against null returns.
- F-CYCLE3-4: Rewrite Surface row honestly — conformance-flag (--mode manifest-verify) is technically viable since checkTypedIaCPlugin handles non-IaC too; pick new-subcommand on separation-of-concerns basis (truth-check vs typed-IaC scan).
- F-CYCLE3-5: Explicit fixture PluginManifest.Validate() prereqs documented (name + version + author + description all required).
…t + fixture path + jq filter)

Cycle-4 FAIL: 3 Important. Cycle-5 fixes:
- spawn-helper cut-point explicit (line 504 only; IaC-validation lines 505-513 stay in conformance caller)
- fixture build is in-place (NOT copy-to-TempDir) + main.go at fixture root matching precedent
- jq filter pins goos==linux + goarch matching runner (uname -m sed map x86_64→amd64, aarch64→arm64)
…es fully)

Cycle-5 FAIL: 3 Important regressions on cycle-4 fixes. Cycle-6 fixes:
- F5-1: jq filter (goos+goarch pin) now propagated to BOTH Synopsis AND CI integration blocks (was only in Synopsis); strike 'any arch — only needs ONE binary' rationale (false: wrong-arch binary won't exec).
- F5-2: pin -mod=readonly + check in fixture go.sum; sidesteps both source-tree pollution (mod=mod writes go.sum) and copy-to-TempDir overhead; maintenance note for regen on SDK dep bumps.
- F5-3: explicit defer-transform note — line 484's defer client.Kill() returned as func() cleanup, caller defers; literal extraction would either kill plugin too early OR leak processes.
- Reconcile line-range citations: 462-504 throughout (was 462-515 in Behavior step 2).
9 tasks, 1 PR. Pairs with design doc cycle-6 PASS adversarial.
…le-1 review)

Cycle 1 FAIL: 4 Critical (fictional EngineManifest signature; fixture wrong PluginManifest type; missing-ldflag mechanics wrong; fixture json shape diverges). Cycle 2:
- Drop Task 1 (spawnAndDial extraction) per reviewer Option 3; inline ~40 LOC. Eliminates I2 verification-class mismatch on refactor-without-test.
- C1: GetManifest direct via pb.NewPluginServiceClient(pluginClient.Conn()) — bypasses adapter precedence.
- C2: fixture uses sdk.PluginManifest (sdk-package value), Manifest() returns value (no error).
- C3: initial Version='dev' so ResolveBuildVersion falls back to '(devel)' for missing-ldflag.
- C4: minimal plugin.json (only PluginManifest fields).
8 tasks now (was 9). Single PR.
… rebase + tighten test)

Cycle 2 FAIL 3 Critical + 2 Important. Cycle 3:
- Rebased onto current main (validate-contract + registry-sync now exist in dispatcher).
- Restructured Tasks 2/3/4 'append imports' instructions: explicit 'Edit the SINGLE existing import block' with warnings; Task 4 Step 1 specifies final import-block shape end-to-end (eliminates C-2-2 + C-2-3 duplicate-import compile failures).
- Fixture go-directive 1.24 → 1.26.0 to match workflow root (eliminates I-2-1).
- Name-drift fixture ldflag tag changed v0.1.0 → v0.0.0 so plugin.json '0.0.0' + binary 'v0.0.0' Version matrix PASSes; Name is isolated failure under test. Test assertion tightened from 'mismatch' to 'name:' substring; verify-capabilities error now embeds joined failure list so test can assert without stderr capture (eliminates I-2-2).
… + generator hazards)

Cycle 3 FAIL: 1 Critical (Task 7 reintroduced duplicate-import-block; cycle-3 fix missed Task 7). Cycle 4:
- Task 7 Step 1: replace literal 'import (...)' snippet with explicit 'Edit existing single import block' instruction.
- Task 7 name-drift test comment: clarified which matrix row fires (declared=='0.0.0' branch returns PASS; isSentinel('v0.0.0') false).
- Task 5 generator: embed relative 'replace github.com/GoCodeAlone/workflow => ../../../../..' DIRECTLY in heredoc (no $REPO_ROOT indirection, no sed dance); PLACEHOLDER for module name substituted via fixed-text sed. Eliminates shell-quoting hazard on worktrees with spaces.
- Task 6 generator: same direct-replace pattern.
…k 7 missing fmt)

Cycle 4 FAIL: 2 Critical (compile blockers). Cycle 5:
- Task 1: ship test file with only strings + testing (was pre-staging os + path/filepath which Task 1 functions don't use → 'imported and not used').
- Task 2: explicitly says 'Edit the existing SINGLE import block to add os + path/filepath' when those imports are first used.
- Task 7: now adds 'fmt' AND 'os/exec' (was only os/exec; helper uses fmt.Sprintf and test uses fmt.Sprintf('%v', err) → undefined: fmt).
Each task's import additions match its actual code usage.
@intel352 intel352 merged commit 827158b into main May 24, 2026
21 checks passed
@intel352 intel352 deleted the feat/765-verify-capabilities branch May 24, 2026 05:29
@codecov
Copy link
Copy Markdown

codecov Bot commented May 24, 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:276: parsing iteration count: invalid syntax
baseline-bench.txt:334444: parsing iteration count: invalid syntax
baseline-bench.txt:641048: parsing iteration count: invalid syntax
baseline-bench.txt:945420: parsing iteration count: invalid syntax
baseline-bench.txt:1263448: parsing iteration count: invalid syntax
baseline-bench.txt:1599356: parsing iteration count: invalid syntax
benchmark-results.txt:276: parsing iteration count: invalid syntax
benchmark-results.txt:375919: parsing iteration count: invalid syntax
benchmark-results.txt:766931: parsing iteration count: invalid syntax
benchmark-results.txt:1124928: parsing iteration count: invalid syntax
benchmark-results.txt:1511671: parsing iteration count: invalid syntax
benchmark-results.txt:1793948: 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              3.960m ± 160%
ComponentLoad-4                    3.465m ±   0%
ComponentExecute-4                 1.832µ ±   2%
PoolContention/workers-1-4         1.022µ ±   1%
PoolContention/workers-2-4         1.019µ ±   2%
PoolContention/workers-4-4         1.040µ ±   1%
PoolContention/workers-8-4         1.033µ ±   1%
PoolContention/workers-16-4        1.033µ ±   2%
ComponentLifecycle-4               3.489m ±   1%
SourceValidation-4                 2.080µ ±   1%
RegistryConcurrent-4               737.5n ±   5%
LoaderLoadFromString-4             3.553m ±   1%
geomean                            16.92µ

                            │ 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: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                            │ benchmark-results.txt │
                            │        sec/op         │
InterpreterCreation-4                  9.022m ± 66%
ComponentLoad-4                        3.444m ± 10%
ComponentExecute-4                     1.842µ ±  1%
PoolContention/workers-1-4             1.178µ ±  2%
PoolContention/workers-2-4             1.193µ ±  0%
PoolContention/workers-4-4             1.194µ ±  2%
PoolContention/workers-8-4             1.179µ ±  1%
PoolContention/workers-16-4            1.216µ ±  3%
ComponentLifecycle-4                   3.482m ±  4%
SourceValidation-4                     2.264µ ±  0%
RegistryConcurrent-4                   931.6n ±  7%
LoaderLoadFromString-4                 3.621m ±  1%
geomean                                19.81µ

                            │ 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 9V74 80-Core Processor                
                                  │ baseline-bench.txt │
                                  │       sec/op       │
CircuitBreakerDetection-4                 303.0n ± 12%
CircuitBreakerExecution_Success-4         22.65n ±  0%
CircuitBreakerExecution_Failure-4         71.03n ±  1%
geomean                                   78.71n

                                  │ 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                     455.0n ± 1%
CircuitBreakerExecution_Success-4             59.79n ± 0%
CircuitBreakerExecution_Failure-4             64.94n ± 0%
geomean                                       120.9n

                                  │ 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       │
IaCStateBackend_InProcess-4              297.5n ±  1%
IaCStateBackend_GRPC-4                   10.40m ± 12%
JQTransform_Simple-4                     649.9n ± 32%
JQTransform_ObjectConstruction-4         1.422µ ±  1%
JQTransform_ArraySelect-4                3.472µ ±  1%
JQTransform_Complex-4                    42.02µ ±  2%
JQTransform_Throughput-4                 1.774µ ±  0%
SSEPublishDelivery-4                     63.65n ±  0%
geomean                                  3.838µ

                                 │ baseline-bench.txt │
                                 │        B/op        │
IaCStateBackend_InProcess-4             416.0 ±  0%
IaCStateBackend_GRPC-4                5.721Mi ± 15%
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      │
IaCStateBackend_InProcess-4              2.000 ± 0%
IaCStateBackend_GRPC-4                  6.869k ± 0%
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         │
IaCStateBackend_InProcess-4                 341.9n ±  7%
IaCStateBackend_GRPC-4                      9.665m ± 25%
JQTransform_Simple-4                        680.1n ± 36%
JQTransform_ObjectConstruction-4            1.505µ ±  1%
JQTransform_ArraySelect-4                   3.220µ ±  2%
JQTransform_Complex-4                       36.43µ ±  0%
JQTransform_Throughput-4                    1.862µ ±  1%
SSEPublishDelivery-4                        76.17n ±  0%
geomean                                     3.924µ

                                 │ benchmark-results.txt │
                                 │         B/op          │
IaCStateBackend_InProcess-4                 416.0 ± 0%
IaCStateBackend_GRPC-4                    5.782Mi ± 9%
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       │
IaCStateBackend_InProcess-4                 2.000 ± 0%
IaCStateBackend_GRPC-4                     6.869k ± 0%
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.098µ ± 22%
SchemaValidation_AllFields-4                1.645µ ±  4%
SchemaValidation_FormatValidation-4         1.573µ ±  1%
SchemaValidation_ManySchemas-4              1.603µ ±  2%
geomean                                     1.461µ

                                    │ 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.028µ ± 6%
SchemaValidation_AllFields-4                    1.512µ ± 1%
SchemaValidation_FormatValidation-4             1.491µ ± 1%
SchemaValidation_ManySchemas-4                  1.509µ ± 4%
geomean                                         1.367µ

                                    │ 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.118µ ± 11%
EventStoreAppend_SQLite-4                  1.172m ± 12%
GetTimeline_InMemory/events-10-4           12.27µ ±  1%
GetTimeline_InMemory/events-50-4           67.64µ ± 19%
GetTimeline_InMemory/events-100-4          110.0µ ±  4%
GetTimeline_InMemory/events-500-4          563.9µ ±  0%
GetTimeline_InMemory/events-1000-4         1.141m ±  0%
GetTimeline_SQLite/events-10-4             85.59µ ±  2%
GetTimeline_SQLite/events-50-4             220.3µ ±  0%
GetTimeline_SQLite/events-100-4            384.6µ ±  2%
GetTimeline_SQLite/events-500-4            1.678m ±  1%
GetTimeline_SQLite/events-1000-4           3.239m ±  1%
geomean                                    195.0µ

                                   │ baseline-bench.txt │
                                   │        B/op        │
EventStoreAppend_InMemory-4                  751.5 ± 9%
EventStoreAppend_SQLite-4                  1.985Ki ± 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.07Ki

                                   │ 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.123µ ± 21%
EventStoreAppend_SQLite-4                     979.5µ ±  6%
GetTimeline_InMemory/events-10-4              13.63µ ±  2%
GetTimeline_InMemory/events-50-4              75.12µ ±  2%
GetTimeline_InMemory/events-100-4             117.9µ ±  2%
GetTimeline_InMemory/events-500-4             601.5µ ±  1%
GetTimeline_InMemory/events-1000-4            1.202m ±  1%
GetTimeline_SQLite/events-10-4                79.81µ ±  2%
GetTimeline_SQLite/events-50-4                228.6µ ±  1%
GetTimeline_SQLite/events-100-4               414.0µ ±  1%
GetTimeline_SQLite/events-500-4               1.882m ±  1%
GetTimeline_SQLite/events-1000-4              3.749m ±  2%
geomean                                       203.8µ

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

                                   │ 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 added a commit that referenced this pull request May 24, 2026
…766) (workflow#765) (#769)

* feat(wfctl): plugin verify-capabilities subcommand skeleton (workflow#765)

* feat(wfctl): verify-capabilities preflight binary-path validation (workflow#765)

* feat(wfctl): verify-capabilities sentinel-pattern Version diff matrix (workflow#765)

* feat(wfctl): wire inline spawn + direct GetManifest + Name/Version diff (workflow#765)

* test(wfctl): verify-capabilities fixtures (4 build-pass scenarios) (workflow#765)

* test(wfctl): name-drift fixture (binary advertises mismatched Name) (workflow#765)

* test(wfctl): verify-capabilities integration tests (5 scenarios) (workflow#765)

* docs: add Verify-Capabilities section to PLUGIN_RELEASE_GATES (workflow#765)
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.

wfctl plugin verify-capabilities — runtime manifest-vs-plugin.json check

1 participant