Commit Graph

12 Commits

Author SHA1 Message Date
vikingowl ec9433d783 chore(lint): clear remaining errcheck and staticcheck findings
Brings the project to a clean `make lint` baseline (0 issues).

Mechanical:
- Wrap deferred resp.Body.Close() in closures (router/discovery.go,
  router/probe.go) so the unchecked return surfaces as `_ = ...`.
- Apply `_ = ...` (single or multi-return blank) to test-file calls
  that intentionally ignore errors: os.MkdirAll / os.WriteFile / os.Chdir
  in setup paths, Close / Shutdown in teardown, Submit / Spawn / Send /
  LoadDir in tests that assert on side effects.

Structural:
- engine.handleRequestTooLarge drops the unused req parameter and
  rebuilds the request from compacted history (SA4009 — argument was
  overwritten before first use).
- provider.ClassifyHTTPStatus and google.applyCapabilityOverrides switch
  to tagged switches over the discriminator (QF1002).
- tui.app.go MouseWheel + inputMode and cmd/gnoma main slm-status use
  tagged switches in place of equality chains (QF1003).
- cmd/gnoma main.go merges a var decl with its immediate assignment
  (S1021).
- Three empty-branch sites (dispatcher_test, loader_test,
  coordinator_test) become real assertions or get the dead `if` removed
  (SA9003).
2026-05-19 17:53:42 +02:00
vikingowl 13b2f5e14d chore(lint): clear dead code and tighten lifecycle errcheck
Removes five unused funcs/vars/fields that golangci-lint had been
flagging (anthropic.toolCallDoneEvent, mistral.translateMessages,
hook.newError, subprocess.vibeParser.lastAssistantMsgID, tui.cBase),
two ineffectual assignments (tui/rendering.go visible-window loop,
subprocess stream_test setup), and a stale if/HasPrefix that's now a
strings.TrimPrefix.

Wires errcheck onto every subprocess / stream lifecycle path so a
failed close or shutdown is at least logged rather than silently
dropped:

- engine/loop.go: stream.Close on both the error and success paths
- mcp/manager.go: Shutdown when StartAll partial-fails; Transport
  close after Initialize failure
- mcp/transport.go: stdin.Close + syscall.Kill on graceful-timeout
  fallback
- slm/download.go: Close propagated as a named-return error on the
  success path; explicitly discarded on the rollback path
- slm/classifier.go, slm/manager.go, hook/prompt.go, context/summarize.go,
  config/write.go, cmd/gnoma/main.go, tool/fs/grep.go: explicit
  ignores or error logging on Close / Shutdown / WalkDir / Scanln

Production-code errcheck and ineffassign are now zero. Remaining
golangci-lint output is test-only Close-in-defer noise plus
stylistic staticcheck QF suggestions, left alone.
2026-05-19 17:05:54 +02:00
vikingowl bb7892c0c2 chore(audit): polish remaining audit findings (M2, H1, H3)
- M2: stop echoing the matched pattern name in the user-visible
  [BLOCKED: ...] message returned by the firewall. The pattern (and
  the matched secret class) still appear in the operator log, but the
  string sent back into the prompt is now generic.

- H1: document Rule.Pattern semantics on the Rule type and pin them
  with a regression test. Pattern is a case-sensitive, exact substring
  match against the JSON-serialised tool arguments — not a glob,
  regex, or whitespace-insensitive match. The new test exercises both
  matches and the documented gotchas (double-space, case drift, tab).

- H3: every code path in CommandExecutor.Execute that converts a hook
  failure into Allow via FailOpen now emits a WARN naming the hook
  and the failure mode (timeout / launch_error / parse_error), so
  chronic hook failure or abuse is visible in operator logs.

Also tightens errcheck on permission/rule.go (Printer.Print on a
strings.Builder cannot error in practice; make the intent explicit).
2026-05-19 17:05:39 +02:00
vikingowl c44db99b41 fix(hook): execute hook Exec as a binary, not via sh -c
Plugin loader resolves HookSpec.Exec as a relative path joined to the
plugin directory, and manifest.checkSafePath rejects absolute paths and
'..' traversal — Exec was always meant to be an executable path.

The hook executor was wrapping it in 'sh -c', adding a redundant shell
interpretation step that turned any space, quote, or metacharacter in
the path into command-injection surface. Switch to exec.Command(path)
with no shell wrapping.

Closes audit finding C3. Adds a regression test that fails under the
old 'sh -c' code path: a canary file created via shell sequencing
remains absent when the executor treats Exec as a literal filename.

Hook command tests now write small /bin/sh scripts to t.TempDir and
point Exec at those — matching production semantics (resolved binary
path) rather than inline shell strings.
2026-05-19 16:30:23 +02:00
vikingowl 1ec90b0ad7 feat: engine hook integration — PreToolUse, PostToolUse, Stop 2026-04-07 01:02:55 +02:00
vikingowl 50bb5f2f6b feat: AgentExecutor — elf-based hook evaluation via elf.Manager 2026-04-07 00:55:19 +02:00
vikingowl 45c0d0c43e feat: PromptExecutor — LLM-based hook evaluation via router 2026-04-07 00:53:53 +02:00
vikingowl 685e3b97f2 feat: ParseHookDefs — config to HookDef conversion with validation 2026-04-07 00:52:00 +02:00
vikingowl 47ae6775f3 feat: Dispatcher — handler chain dispatch, filtering, transform chaining 2026-04-07 00:48:08 +02:00
vikingowl 54df0f2f08 feat: CommandExecutor — shell hook execution with stdin/stdout protocol 2026-04-07 00:38:48 +02:00
vikingowl 0297f56d8f feat: hook payload marshal/unmarshal helpers 2026-04-07 00:37:40 +02:00
vikingowl ea7ec98d76 feat: hook core types — EventType, Action, CommandType, HookDef, Executor 2026-04-07 00:36:18 +02:00