Skip to content

feat(wfctl): add audit repo quality gate command - #543

Merged
intel352 merged 3 commits into
mainfrom
copilot/design-wfctl-repo-audit-gate
May 5, 2026
Merged

intel352 merged 3 commits into
mainfrom
copilot/design-wfctl-repo-audit-gate

Conversation

Copilot AI commented May 5, 2026 •

Copy link
Copy Markdown
Contributor

Implements wfctl audit repo — a local/CI quality gate that catches portable-path, safety, and documentation issues before PR push/merge, as outlined in the design issue.

Changes

  • cmd/wfctl/repo_audit.go — Core implementation with 6 built-in checks:

    • non_portable_path — non-ASCII, control chars, Windows-invalid chars
    • unsafe_path_traversal / unsafe_absolute_path — directory traversal and absolute paths
    • missing_doc_frontmatter / malformed_frontmatter — structured docs without valid YAML frontmatter
    • index_drift — plan files missing from docs/plans/INDEX.md
  • cmd/wfctl/repo_audit_test.go — 12 tests covering checks, JSON output, strict mode, config ignores, and flag handling

  • cmd/wfctl/audit.go — Wire repo into existing audit router

  • docs/WFCTL.md — Document command, flags, check codes, and config format

Usage

wfctl audit repo                          # scan CWD
wfctl audit repo --dir /path --json       # machine-readable for CI/MCP/agents
wfctl audit repo --strict                 # fail on warnings

Project-level config via .wfctl.yaml:

audit:
  checks:
    portable_paths: true
    doc_frontmatter: false
  ignores:
    - "vendor/*"
    - "testdata/*"

Design choices

  • Language-agnostic checks only in core; language-specific packs belong in plugins
  • --json uses stable lower-case field names matching existing audit plans/audit plugins output shape
  • Skips .git, node_modules, vendor, .next automatically
  • Local and CI behavior are identical by design

Copilot AI requested review from Copilot and removed request for Copilot May 5, 2026 07:39
Copilot AI linked an issue May 5, 2026 that may be closed by this pull request
Add `wfctl audit repo` subcommand that runs portable, cross-platform
quality gate checks on repository files before PR push/merge:

- non_portable_path: detects non-ASCII, control chars, Windows-invalid chars
- unsafe_path_traversal: detects ../ path traversal
- unsafe_absolute_path: detects absolute paths
- missing_doc_frontmatter: warns on structured docs without YAML frontmatter
- malformed_frontmatter: errors on unclosed frontmatter delimiters
- index_drift: warns on plan files not referenced in INDEX.md

Supports --json for machine-readable output (CI/MCP/agents),
--strict mode, and project config via .wfctl.yaml audit section
for enabling/disabling checks and ignore patterns.

Agent-Logs-Url: https://github.com/GoCodeAlone/workflow/sessions/9157fc90-89fe-4a16-bab7-1105b087f9b6

Co-authored-by: intel352 <[email protected]>
Copilot AI requested review from Copilot and removed request for Copilot May 5, 2026 07:51
Copilot AI changed the title [WIP] Design quality gate for wfctl repo audit feat(wfctl): add audit repo quality gate command May 5, 2026
Copilot AI requested a review from intel352 May 5, 2026 07:54
@intel352
intel352 marked this pull request as ready for review May 5, 2026 08:14
Copilot AI review requested due to automatic review settings May 5, 2026 08:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds wfctl audit repo, a repository-level quality gate under the existing wfctl audit command tree, intended for local/CI use to detect unsafe/non-portable paths and documentation/index hygiene issues.

Changes:

  • Adds a new audit repo implementation with JSON/plaintext output, strict mode, and .wfctl.yaml-based configuration (checks + ignores).
  • Wires the new repo subject into the wfctl audit router/usage output.
  • Documents the new command, flags, check codes, and config format in docs/WFCTL.md.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 11 comments.

File Description
docs/WFCTL.md Documents wfctl audit repo, its flags, built-in checks, and .wfctl.yaml config shape
cmd/wfctl/repo_audit.go Implements repo scanning, checks, config loading, and report rendering
cmd/wfctl/repo_audit_test.go Adds unit tests for routing, output modes, strict mode, ignores, and individual checks
cmd/wfctl/audit.go Routes wfctl audit repo and updates audit usage/help text

Comment thread cmd/wfctl/repo_audit.go Outdated
Comment thread cmd/wfctl/repo_audit.go Outdated
Comment thread cmd/wfctl/repo_audit.go Outdated
Comment thread cmd/wfctl/repo_audit.go Outdated
Comment thread cmd/wfctl/repo_audit.go
Comment on lines +380 to +390
data, err := os.ReadFile(configPath)
if err != nil {
return cfg
}

var raw struct {
Audit repoAuditConfig `yaml:"audit"`
}
if err := yaml.Unmarshal(data, &raw); err != nil {
return cfg
}
Comment thread cmd/wfctl/repo_audit_test.go Outdated
Comment on lines +148 to +156
func TestRunAuditRepoStrictMode(t *testing.T) {
dir := t.TempDir()
writeRepoAuditFile(t, filepath.Join(dir, "file:name.txt"), "content\n")

var out bytes.Buffer
err := runAuditWithOutput([]string{"repo", "--dir", dir, "--strict"}, &out)
if err == nil {
t.Fatal("expected strict mode to fail on warnings")
}
Comment on lines +162 to +169
func TestRunAuditRepoConfigIgnores(t *testing.T) {
dir := t.TempDir()
writeRepoAuditFile(t, filepath.Join(dir, "file:name.txt"), "content\n")
writeRepoAuditFile(t, filepath.Join(dir, ".wfctl.yaml"), `audit:
ignores:
- "file:name.txt"
`)

Comment on lines +180 to +187
func TestRunAuditRepoConfigDisableCheck(t *testing.T) {
dir := t.TempDir()
writeRepoAuditFile(t, filepath.Join(dir, "file:name.txt"), "content\n")
writeRepoAuditFile(t, filepath.Join(dir, ".wfctl.yaml"), `audit:
checks:
portable_paths: false
`)

Comment thread cmd/wfctl/repo_audit.go Outdated
@intel352

intel352 commented May 5, 2026

Copy link
Copy Markdown
Contributor

@copilot apply changes based on the comments in this thread

Also address all failing linter issues https://github.com/GoCodeAlone/workflow/actions/runs/25364420657/job/74374726883?pr=543

- Fix nilerr lint: WalkDir callback records ERROR finding instead of
  silently swallowing per-entry errors
- Fix comment: update "Skip hidden directories" to "common noise directories"
- Use path.Match (slash-based) in isIgnored to fix Windows path matching
- Remove unsafe_paths from walk (WalkDir never yields ../ or absolute
  paths; checkUnsafePath stays as a pure validator for config strings)
- Fix loadRepoAuditConfig: return error when config file exists but
  fails to parse; only silently skip missing default config
- Update --config flag description to document actual resolution behavior
- Skip symlinks in doc frontmatter check via d.Type().IsRegular()
- Fix tests: eliminate file:name.txt (Windows-invalid) filesystem
  creation; use checkPortablePath directly or index_drift/frontmatter
  triggers instead; add TestRunAuditRepoConfigParseError
- Update docs to remove unsafe_paths and align --config default description

Agent-Logs-Url: https://github.com/GoCodeAlone/workflow/sessions/87e90e21-01ab-438d-ad51-f9a16eba4b93

Co-authored-by: intel352 <[email protected]>

Copilot AI commented May 5, 2026

Copy link
Copy Markdown
Contributor Author

@copilot apply changes based on the comments in this thread

Also address all failing linter issues...

Addressed all review comments in commit 4e793d5:

  • nilerr / WalkDir errors: callback now appends an ERROR finding (using err) and continues walking; //nolint:nilerr matches the established codebase pattern
  • Directory skip comment: updated to "common noise directories"
  • path.Match vs filepath.Match: isIgnored now uses path.Match (slash-based) since relPath is already normalised with forward slashes
  • Dead unsafe_paths check: removed from the walk entirely; checkUnsafePath stays as a pure function for validating user-supplied path strings, as documented
  • Config parse errors: loadRepoAuditConfig now returns (repoAuditConfig, error) — silently skips a missing default config but propagates YAML parse failures to the caller
  • --config flag description: updated to "defaults to <dir>/.wfctl.yaml" to match actual resolution
  • Symlink safety: checkDocFrontmatter is only called when d.Type().IsRegular()
  • Windows-invalid filenames in tests: all tests using file:name.txt on disk replaced — non-portable path check now calls checkPortablePath directly; strict/ignore/disable tests use index_drift or doc_frontmatter triggers instead

@github-actions

github-actions Bot commented May 5, 2026

Copy link
Copy Markdown

⏱ Benchmark Results

✅ No significant performance regressions detected.

benchstat comparison (baseline → PR)
## benchstat: baseline → PR
baseline-bench.txt:260: parsing iteration count: invalid syntax
baseline-bench.txt:301914: parsing iteration count: invalid syntax
baseline-bench.txt:622726: parsing iteration count: invalid syntax
baseline-bench.txt:906974: parsing iteration count: invalid syntax
baseline-bench.txt:1179765: parsing iteration count: invalid syntax
baseline-bench.txt:1453036: parsing iteration count: invalid syntax
benchmark-results.txt:260: parsing iteration count: invalid syntax
benchmark-results.txt:309483: parsing iteration count: invalid syntax
benchmark-results.txt:625777: parsing iteration count: invalid syntax
benchmark-results.txt:937295: parsing iteration count: invalid syntax
benchmark-results.txt:1265301: parsing iteration count: invalid syntax
benchmark-results.txt:1545724: 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              4.879m ± 127%   3.818m ± 163%       ~ (p=0.310 n=6)
ComponentLoad-4                    3.724m ±   1%   3.596m ±   6%       ~ (p=0.394 n=6)
ComponentExecute-4                 1.996µ ±   1%   1.929µ ±   1%  -3.33% (p=0.002 n=6)
PoolContention/workers-1-4         1.129µ ±   4%   1.084µ ±   3%  -4.03% (p=0.004 n=6)
PoolContention/workers-2-4         1.122µ ±   1%   1.089µ ±   1%  -2.94% (p=0.002 n=6)
PoolContention/workers-4-4         1.132µ ±   2%   1.091µ ±   3%  -3.62% (p=0.004 n=6)
PoolContention/workers-8-4         1.126µ ±   1%   1.094µ ±   4%       ~ (p=0.061 n=6)
PoolContention/workers-16-4        1.122µ ±   2%   1.097µ ±   1%  -2.23% (p=0.006 n=6)
ComponentLifecycle-4               3.769m ±   2%   3.613m ±   1%  -4.14% (p=0.002 n=6)
SourceValidation-4                 2.322µ ±   1%   2.248µ ±   1%  -3.17% (p=0.002 n=6)
RegistryConcurrent-4               815.0n ±   5%   782.7n ±   5%       ~ (p=0.093 n=6)
LoaderLoadFromString-4             4.013m ±   2%   3.628m ±   0%  -9.60% (p=0.002 n=6)
geomean                            18.74µ          17.70µ         -5.58%

                            │ baseline-bench.txt │        benchmark-results.txt         │
                            │        B/op        │     B/op      vs base                │
InterpreterCreation-4               2.027Mi ± 0%   2.027Mi ± 0%       ~ (p=0.818 n=6)
ComponentLoad-4                     2.180Mi ± 0%   2.180Mi ± 0%       ~ (p=0.180 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.634 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.333 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                  292.6n ± 5%   285.6n ± 7%  -2.43% (p=0.041 n=6)
CircuitBreakerExecution_Success-4          21.57n ± 0%   21.54n ± 1%       ~ (p=0.286 n=6)
CircuitBreakerExecution_Failure-4          65.94n ± 0%   65.89n ± 2%       ~ (p=0.697 n=6)
geomean                                    74.66n        74.01n       -0.87%

                                  │ 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               │
JQTransform_Simple-4                     952.3n ± 30%   871.6n ± 29%        ~ (p=0.240 n=6)
JQTransform_ObjectConstruction-4         1.580µ ±  0%   1.454µ ± 15%        ~ (p=0.054 n=6)
JQTransform_ArraySelect-4                3.661µ ±  2%   3.287µ ±  0%  -10.22% (p=0.002 n=6)
JQTransform_Complex-4                    40.73µ ±  1%   38.43µ ±  1%   -5.65% (p=0.002 n=6)
JQTransform_Throughput-4                 1.916µ ±  1%   1.775µ ±  0%   -7.36% (p=0.002 n=6)
SSEPublishDelivery-4                     71.01n ±  1%   73.03n ±  5%        ~ (p=0.065 n=6)
geomean                                  1.768µ         1.658µ         -6.23%

                                 │ baseline-bench.txt │        benchmark-results.txt         │
                                 │        B/op        │     B/op      vs base                │
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.22Ki ± 0%     16.22Ki ± 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.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                 │ baseline-bench.txt │       benchmark-results.txt        │
                                 │     allocs/op      │ allocs/op   vs base                │
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                    324.0 ± 0%     324.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.00%               ²
¹ 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.091µ ± 21%   1.100µ ± 22%       ~ (p=0.818 n=6)
SchemaValidation_AllFields-4                1.680µ ±  5%   1.671µ ±  5%       ~ (p=0.485 n=6)
SchemaValidation_FormatValidation-4         1.599µ ±  2%   1.589µ ±  1%       ~ (p=0.132 n=6)
SchemaValidation_ManySchemas-4              1.831µ ±  3%   1.812µ ±  4%       ~ (p=0.589 n=6)
geomean                                     1.522µ         1.516µ        -0.34%

                                    │ 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.199µ ± 11%   1.202µ ± 7%       ~ (p=0.699 n=6)
EventStoreAppend_SQLite-4                  1.506m ±  6%   1.494m ± 6%       ~ (p=0.589 n=6)
GetTimeline_InMemory/events-10-4           13.78µ ±  3%   13.49µ ± 2%       ~ (p=0.093 n=6)
GetTimeline_InMemory/events-50-4           61.15µ ± 29%   74.29µ ± 2%       ~ (p=0.394 n=6)
GetTimeline_InMemory/events-100-4          122.1µ ±  0%   119.3µ ± 0%  -2.31% (p=0.002 n=6)
GetTimeline_InMemory/events-500-4          631.5µ ±  1%   615.3µ ± 0%  -2.58% (p=0.002 n=6)
GetTimeline_InMemory/events-1000-4         1.286m ±  0%   1.260m ± 1%  -1.99% (p=0.002 n=6)
GetTimeline_SQLite/events-10-4             111.4µ ±  1%   105.3µ ± 0%  -5.52% (p=0.002 n=6)
GetTimeline_SQLite/events-50-4             253.9µ ±  1%   242.7µ ± 0%  -4.41% (p=0.002 n=6)
GetTimeline_SQLite/events-100-4            423.9µ ±  1%   411.0µ ± 1%  -3.05% (p=0.002 n=6)
GetTimeline_SQLite/events-500-4            1.815m ±  0%   1.755m ± 1%  -3.28% (p=0.002 n=6)
GetTimeline_SQLite/events-1000-4           3.527m ±  1%   3.403m ± 1%  -3.52% (p=0.002 n=6)
geomean                                    218.1µ         216.2µ       -0.86%

                                   │ baseline-bench.txt │        benchmark-results.txt         │
                                   │        B/op        │     B/op      vs base                │
EventStoreAppend_InMemory-4                 757.5 ± 13%     793.5 ± 6%       ~ (p=0.234 n=6)
EventStoreAppend_SQLite-4                 1.984Ki ±  2%   1.985Ki ± 2%       ~ (p=0.853 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.455 n=6)
GetTimeline_InMemory/events-1000-4        944.3Ki ±  0%   944.3Ki ± 0%       ~ (p=0.061 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%  -0.00% (p=0.045 n=6)
GetTimeline_SQLite/events-1000-4          1.639Mi ±  0%   1.639Mi ± 0%       ~ (p=1.000 n=6)
geomean                                   67.11Ki         67.37Ki       +0.39%
¹ 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 5ff9444 into main May 5, 2026
17 of 18 checks passed
@intel352
intel352 deleted the copilot/design-wfctl-repo-audit-gate branch May 5, 2026 14:27
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.

Design wfctl repo audit quality gate

3 participants