Repository navigation
Description
Problem
Part of #588. This is the existing gitleaks task-orchestration slice of #329.
At origin/main (a0347a715fab580ece45edfcb3d13509620459a8), devtools:gitleaks is still an inline shell task that runs the pinned scanner, preserves its status and rejects an unexplained zero-commit scan (.devtools/tasks/security.toml:24). Its current invocation is gitleaks git --verbose --redact . (.devtools/tasks/security.toml:33), with scanner version 8.30.1 pinned at .config/mise/conf.d/10-devtools-tools.toml:48, matching #551's examined scanner contract. Move that orchestration to tested Go; keep #551's separate scan-boundary change explicit.
Acceptance criteria
- AC1: The migrated task retains the current scanner invocation and repository configuration behavior, including all-ref history coverage; this port cannot narrow coverage to the checked-out branch.
- AC2: Scanner output remains redacted and retains the current rule, repository-relative path, line and permitted verbose metadata, with the scanner's nonzero status preserved.
- AC3: A scan without a positive scanned-commit count fails with the current guard diagnostic unless HEAD is readable and its validated history has no patch content; that legitimate contentless case retains the scanner status and current explanatory notice.
- AC4: Missing repository, unborn HEAD, failed Git validation and nonzero scanner/start/read failures cannot become a successful guard result, and a scanner's partial output cannot replace its nonzero exit status.
- AC5: Existing scanner rules and exact fixture exceptions retain their current results; default private-key detection remains enabled outside an explicitly accepted exception.
- AC6: Existing standalone, aggregate, commit, PR and reusable-workflow callers retain their task name, argument behavior and failure propagation, including extra task arguments currently ignored by the frozen body; this port adds no direct merge-time or pre-push scan and changes no workflow trigger or history checkout.
- AC7: Non-functional: the task ends with a thin shell wrapper that probes Go subcommand support without writes or consuming input, uses the frozen task shell when binary or capability is absent, and preserves supported execution's streams and status without fallback or a repeated scan after failure.
- AC8: Non-functional: native orchestration works on Linux, macOS and Windows without an N-2 configuration or binary-floor change.
- AC9: Help and adoption documentation describe the unchanged default scope, zero-count guard, private-scanner distinction, fallback and rollback, without claiming fix(leaks): scope local gates to branch history and the staged tree #551's local mode already exists.
- AC10: Non-functional: orchestration leaves repository refs, index and working files unchanged.
Scope and non-goals
In scope: only the task orchestration and its consumer wrapper, caller compatibility, documentation and tests. Current callers include mise.toml:748, mise.toml:813, packages/agents/source/skills/commit/shared/scripts/commit.sh:165, packages/agents/source/skills/pr/shared/scripts/create-pr.sh:191 and .github/workflows/scan-gitleaks.yml:37. Scanner-specific regressions are in tests/tasks/gitleaks.bats:16, tests/tasks/gitleaks.bats:32, tests/tasks/gitleaks.bats:55, tests/tasks/gitleaks.bats:62, tests/tasks/gitleaks.bats:75, tests/tasks/gitleaks.bats:89, tests/tasks/gitleaks.bats:98 and tests/tasks/gitleaks.bats:128.
Overlap: AC1 absorbs the unchanged all-ref CI contract of #551 AC6; AC2 and AC5 absorb the existing redaction and rule/exception preservation part of #551 AC8; AC3 and AC4 absorb only the already-existing status/zero-count guard part of #551 AC5. #551 still owns explicit local/ci modes, strict origin-base selection, branch-added history, full-index scanning, its caller-mode changes, additional zero-exit diagnostic hardening, documentation of those new modes and exact-head approval of reduced local coverage. #573 is its implementation, not evidence that those changes are already on this baseline. This port neither implements nor closes #551. Future #551 behavior must not extend this port's frozen fallback.
No #501 source-loading AC is absorbed by gitleaks: AC6 preserves the independent private-scanner gate alongside it. All private-list lookup, notices and provisioning remain #501, and this issue does not close it.
Non-goals: implementing the scanner, changing/upgrading its rules or version, changing allowed markers, adding baselines, parsing allow-marker justification, changing the private-strings scanner, narrowing local history or CI coverage, or changing workflow triggers. This port does not silently adopt #551's intentional policy change. Compatibility fallback removal is a separate N-2 follow-up under D9.
Approach
Move the scoped orchestration to tested Go, with failing cases first. The mechanism is the implementer's choice within these outcomes. Keep the existing task shell frozen for compatibility.
Dependencies
Blocked by #753 before replacement enforcement is activated; cite its merged protection evidence. #329 tracks the migration and #661 governs compatibility. #551 and #573 own the excluded local-mode change; #501 owns private-list sourcing. #333 supplies binary distribution without raising the minimum pin required by this port.
Size
S. One pull request for existing scanner orchestration, its wrapper and regression coverage.
Verify plan
First write failing Go cases for a scanner that prints a clean-looking result then exits nonzero and a contentful history reported as zero scanned commits. Port every case in tests/tasks/gitleaks.bats before reducing shell coverage.
- AC1: a recording scanner asserts exact argv and configuration discovery. Disposable fixture repositories contain a synthetic finding on the checked-out history, an unrelated local branch, a fetched branch and a tag independently; each retains current all-ref detection. Compare results with the frozen task.
- AC2: scanner stubs with statuses 0, 1 and another nonzero status and output on both streams, plus a real synthetic-token fixture; compare the task's combined scanner-output stream and status with shell. Assert rule, relative location, line and allowed verbose metadata and absence of synthetic secret bytes.
- AC3: positive counts, zero counts in contentful history, empty-file root commits, contentless commit histories and scanner nonzero status in a legitimate contentless history; assert exact guard status and diagnostics and retention of scanner failure.
- AC4: outside-repository, unborn, failed HEAD/history validation, missing scanner, failed output storage/read and output-then-failure cases; none may report clean completion. Compare existing failure statuses and safe diagnostics with the frozen task. Broader zero-exit diagnostic interpretation remains fix(leaks): scope local gates to branch history and the staged tree #551.
- AC5: run the default private-key fixture, exact synthetic-key exception and neighboring/prefixed/suffixed paths from the current Bats suite; verify default rules still detect findings outside the exact exception.
- AC6: recording caller fixtures and unchanged workflow assertions prove the same task and arguments run with blocking failure propagation for standalone, aggregates, commit and PR, including unattended forms, and reusable CI. Run extra-argument fixtures against the frozen body and Go wrapper and preserve their ignored-argument behavior; mode parsing remains fix(leaks): scope local gates to branch history and the staged tree #551. Assert no new merge/pre-push scan, trigger or checkout change; keep the independent private-scanner call.
- AC7: actual task with missing binary, older binary lacking capability, supported success/failure and clean-looking output followed by failure; assert a side-effect-free probe, one scan, exact streams/status and no fallback after supported execution. Probe errors must refuse instead of guessing absent capability.
- AC8: native platform matrix and unchanged N-2 fixtures; use shell parity where Bash exists. Record 20 warm task invocations using the same recording scanner for shell and Go to isolate orchestration overhead; investigate regressions.
- AC10: compare refs, index and working files before and after each outcome.
- AC9: compare help/adoption text with the tested invocation and guard; verify fallback and rollback in a disposable fixture and explicitly check that local-mode support is not claimed.
- Run the branch implementation through
mise run test-hooks tests/tasks/gitleaks.batsand affected caller/workflow regressions, thenmise run check, fresh coverage and both coverage floors. Verify build(agents): protect replacement Go enforcement paths #753 protects enforcement and registration. If maintained skill sources change, run generation, token measurement and deployment in order, thenmise run check-generated-skills. - Definition of done: D1 each AC is verified at the merged head, with the commands and results cited in the pull request's Verification. D2 an independent review approves the exact merged head, and every finding has a recorded disposition. D3 required checks pass with no gate loosened. D4 the leak scans the repository specifies are clean, and every post made for this work (comments, descriptions) passes the per-post leak review before it is posted. D5 every commit is signed. D6 the documentation matches, or the description says
No doc impactwith the reason. D7 every commit carries anAssisted-bytrailer and the pull request carries theprovenance:agent-assistedlabel. D8 the change stays within the pull request size limits. D9 follow-up work, including deferred review findings, is filed as issues, each with a Problem section and numbered acceptance criteria and linking this issue; the pull request's Related section lists them, and any code that defers work links its issue. D10 the merge closes this issue through a closing reference, the project board shows the state Done, and a finalStatus:comment names the merge commit.
Risks
A lost subprocess status or false zero-count exception can turn an incomplete scan green. This port preserves the current guard rather than claiming #551's broader hardening. The open local-mode implementation must not be overwritten as part of a parity port: if #573 lands first, this body's scope and evidence must be refreshed before implementation to preserve it. Undo: revert this PR to restore the original task body and caller behavior.
Operator authority
standing rule names the operator: #753 must protect replacement enforcement before activation, with its required exact-head owner review. #551 retains the separate owner approval for any local-history reduction; this port grants no such reduction.
Metadata
Metadata
Assignees
Labels
Type
Fields
Priority
Work type
Projects
- StatusShow more project fieldsBacklog
Activity
tbhb-agent commentedon Oct 26, 2026
Refinement: READY —
devtools:gitleaksGo task-orchestration port is well-scoped, testable, and aligned withorigin/mainModel: gemini-4-argon-high
Checked
origin/mainata0347a715fab580ece45edfcb3d13509620459a8):.devtools/tasks/security.toml:24defines["devtools:gitleaks"]with an inline Bash body (.devtools/tasks/security.toml:26-49) that invokesgitleaks git --verbose --redact .(.devtools/tasks/security.toml:33), captures its exit status (.devtools/tasks/security.toml:32-33,48), and fails when the output lacks[1-9][0-9]* commits scannedunlessHEADresolves andgit log -p --format= HEADcontains no^[+-]patch lines (.devtools/tasks/security.toml:36-47)..config/mise/conf.d/10-devtools-tools.toml:48pinsgitleaks = "8.30.1".docs/script-inventory.md:270and parent issue Port check-leaks and the pre-push installer to agentrepo #329 list.devtools/tasks/security.toml(devtools:gitleaks, 12 source lines) as the gitleaks task-orchestration slice under epic Replace complex shell with tested Go, starting with gates and merging #588.HEAD, failed Git validation, or partial output before nonzero exit (AC4), default private-key detection and exact.gitleaks.tomlpath-exception behavior at.devtools/config/gitleaks.toml:1-9anddocs/gitleaks.md:1-9(AC5), and caller/workflow preservation (AC6).docs/compatibility.md:1-35(AC8), and preservation of repository refs, index, and working tree (AC10).docs/gitleaks.md:1-9,docs/consumer-workflows.md:42) without claiming#551's local mode exists.#501and#551/#573separation):origin/main:mise.toml:748([tasks.security]),mise.toml:813([tasks.check-all]),packages/agents/source/skills/commit/shared/scripts/commit.sh:165,packages/agents/source/skills/pr/shared/scripts/create-pr.sh:191, and.github/workflows/scan-gitleaks.yml:37(with diagnosis routing atpackages/agents/source/skills/fix-pr/shared/scripts/diagnose.sh:115).tests/tasks/gitleaks.bats:16,tests/tasks/gitleaks.bats:32,tests/tasks/gitleaks.bats:55,tests/tasks/gitleaks.bats:62,tests/tasks/gitleaks.bats:75,tests/tasks/gitleaks.bats:89,tests/tasks/gitleaks.bats:98, andtests/tasks/gitleaks.bats:128(along with the companion fixture-policy tests attests/tasks/gitleaks.bats:143andtests/tasks/gitleaks.bats:156, covered by AC5 and Verify plan).#551's--mode local/--mode ciflags, origin-base resolution, branch-history narrowing, full-index snapshot scanning, caller-mode changes, and local-history coverage reduction (implemented in open PR#573)..devtools/scripts/check-leaks.shprivate-strings loading, source notices, and provisioning in#501, preserving the separatedevtools:lint-leakscalls atpackages/agents/source/skills/commit/shared/scripts/commit.sh:164andpackages/agents/source/skills/pr/shared/scripts/create-pr.sh:190.## Dependenciesfor protecting replacement Go enforcement paths andagentreposubcommand registration in.agents/agent-skills.conf:4,9) isopenand labeledrefinement:ready.docs/compatibility.md:1-35) isclosed(done onorigin/main).openand labeledrefinement:ready.#329for.devtools/scripts/install-pre-push.sh:1-119) isopen(currently withoutrefinement:ready), and is not a prerequisite for#814becausedevtools:gitleaks(.devtools/tasks/security.toml:24-49) does not touchinstall-pre-push.shor.git/hooks/pre-pushand AC6 explicitly excludes pre-push changes.Sfits one pull request (replacing a 23-line task body in.devtools/tasks/security.toml:26-49and portingtests/tasks/gitleaks.bats:1-181to Go tests while keeping the frozen fallback wrapper).mise run check, coverage floors,#753protection verification, and conditional skill generation checks.#573, and clean revert recovery.#753's exact-head owner review requirement for protected replacement enforcement paths (.agents/agent-skills.conf:4,8,9) and distinguishes#551's separate owner approval for local-history reduction.Gaps
None
Split
None — Size
Sfits a single pull request.Definition of done
The definition of done for #814 (Feature). Tick each item and give its evidence. (A ticked box indicates planning coverage in the issue body, not completed implementation work.)
## Verify plandefines concrete checks for AC1–AC10 and explicitly requires D1 verification of each AC at the merged head with commands and results cited in the PR'sVerificationsection.## Verify plan(D2) requires independent review approval of the exact merged head and a recorded disposition for every finding.## Verify planrequiresmise run test-hooks tests/tasks/gitleaks.bats, caller/workflow regressions,mise run check, coverage floors, and D3 (required checks pass with no gate loosened), while## Operator authorityrecords the exact-head owner review rules under#753and.agents/agent-skills.conf:4,8,9.check-leaks.shwith the repository's private-strings list, and the leak review of each post.## Verify plan(D4) requires repository leak scans and per-post leak review before posting any comments or descriptions.## Verify plan(D5) explicitly requires every commit to be signed.docs/, CHANGELOG or help text), or the Verification section says "No doc impact" and why.## Verify planitem cover help and adoption documentation (docs/gitleaks.md:1-9,docs/consumer-workflows.md:42), and D6 in## Verify planrequires matching docs or an explicitNo doc impactrationale.provenance:agent-assistedlabel.## Verify plan(D7) requires anAssisted-bytrailer on every commit and theprovenance:agent-assistedlabel on the pull request.## Sizescopes the work to a singleSpull request, and## Verify plan(D8) requires staying within pull request size limits.## Scope and non-goalsidentifies compatibility fallback removal after the N-2 window as a follow-up under D9, and## Verify plan(D9) requires filing follow-up and deferred-finding issues with aProblemsection and numbered ACs, listing them inRelated, and linking them from any code that defers work.Status:comment names the merge commit.## Verify plan(D10) requires closing the issue via merge reference, setting the project board state toDone, and recording the merge commit in a finalStatus:comment.Round: 1 of 3