c44db99b41
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.