Skip to content

chore: harden hook scripts, add Windows/shellcheck/actionlint CI gates - #108

Merged
5uck1ess merged 2 commits into
mainfrom
chore/hardening-and-ci-gates
Jun 10, 2026
Merged

chore: harden hook scripts, add Windows/shellcheck/actionlint CI gates#108
5uck1ess merged 2 commits into
mainfrom
chore/hardening-and-ci-gates

Conversation

@5uck1ess

Copy link
Copy Markdown
Owner

Summary

Hardening pass from the hook/CI review, plus mechanical riders. No behavior changes intended for the happy path — every change is either a robustness guard, a new CI gate, or surfacing a previously swallowed error.

Hooks — uniform fail-open contract

  • safety-check.sh, audit-trail.sh, slop-detect.sh gain set -euo pipefail with guarded jq extractions (the convention rtk-rewrite.sh / security-patterns.sh already document).
  • post-validate.sh, subagent-stop.sh had the inverse bug: strict mode but unguarded jq — malformed stdin killed the hook instead of failing open. Now guarded.
  • slop-detect.sh: fixed latent || echo 0 bug — grep -c already prints 0 on no-match before exiting 1, so the guard produced 0\n0 and broke the integer comparisons.
  • audit-trail.sh: log-write failures (read-only fs, permissions) no longer error every Bash call.
  • stop-gate.sh: removed unused HAS_CONFIG (SC2034) so the new shellcheck gate starts green.

Deliberately NOT changed: the * matcher on devkit-guard.sh in hooks.json. guard.go is default-deny under hard enforcement — narrowing the matcher would let unlisted tools (WebFetch, NotebookEdit, MCP tools) bypass workflow fencing.

CI

  • build-and-test-windows: builds + tests src/ and mcpb/launcher natively on windows-latest per PR. Previously nothing validated Windows compiles before the release pipeline.
  • lint-shell: shellcheck over hooks/*.sh + wrappers (fresh-install job only covered the wrappers).
  • lint-actions: actionlint via rhysd/actionlint docker image (tool author's image, no third-party wrapper action).
  • .github/dependabot.yml: weekly grouped updates for both go.mods and github-actions.

Go — swallowed errors

  • engine.go: GetSteps failure on the final-report path now surfaces (unless a step error already takes precedence).
  • status.go: cost-query failure renders unknown, matching showAllSessions style.
  • workflow.go: agent/budget flag lookup errors are checked (turns a future flag rename into a loud failure instead of a silent zero-value).

Verification

  • go build ./... + go vet ./... clean; 441 tests pass in 6 packages
  • shellcheck -S warning hooks/*.sh bin/devkit bin/mcpb-build mcpb/server/devkit clean
  • hooks/hooks_test.sh: 75/75 pass
  • ci.yml + dependabot.yml YAML-parse clean

5uck1ess added 2 commits June 10, 2026 10:09
Hooks (fail-open contract made uniform):
- safety-check.sh, audit-trail.sh, slop-detect.sh: add set -euo pipefail
  with guarded jq extractions, matching rtk-rewrite.sh convention
- post-validate.sh, subagent-stop.sh: guard previously-unguarded jq calls
  so malformed stdin degrades cleanly instead of killing the hook
- slop-detect.sh: fix latent '|| echo 0' double-output bug (grep -c
  already prints 0 on no-match) that broke integer comparisons
- audit-trail.sh: tolerate log-write failures (read-only fs) silently
- stop-gate.sh: remove unused HAS_CONFIG (SC2034)

CI:
- new windows-latest job: build+test src engine and mcpb/launcher on PR
  (previously Windows breakage only surfaced at release time)
- new lint-shell job: shellcheck hooks/*.sh + wrappers
- new lint-actions job: actionlint via the author's docker image
- new .github/dependabot.yml: weekly gomod (src, mcpb/launcher) +
  github-actions update groups

Go (swallowed errors):
- engine.go: surface GetSteps failure from final-report path unless a
  step error already takes precedence
- status.go: cost-query failure renders 'unknown' like showAllSessions
- workflow.go: check agent/budget flag lookup errors

Verified: go build/vet clean, 441 tests pass, shellcheck clean,
hooks_test.sh 75/75.
The first run of build-and-test-windows surfaced two pre-existing
issues the gate exists to catch:

- mcp tests leaked the server's open devkit.db handle; Windows cannot
  delete a TempDir containing an open file. setupTestServer and
  TestNewServer now t.Cleanup(srv.Close) (LIFO — runs before TempDir
  removal).
- TestDBDirectoryPermissions and TestSessionFileMode assert Unix
  permission bits, which os.Stat does not report on Windows — skip
  there with rationale.

actionlint flagged two pre-existing SC2235 subshell-style nits in
release.yml's version-compare condition — converted to brace groups,
semantically identical.
@5uck1ess
5uck1ess merged commit 3c23c77 into main Jun 10, 2026
9 checks passed
@5uck1ess
5uck1ess deleted the chore/hardening-and-ci-gates branch June 10, 2026 15:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant