Commit Graph

2 Commits

Author SHA1 Message Date
rabbitblood
f1bede31a8 feat(precommit): add secret scan to bundled pre-commit hook (defense-in-depth for #2090-style leaks)
Adds a secret-scan gate alongside the existing internal-paths block in
the runtime's bundled pre-commit hook. Runs on every commit in every
repo (not scoped to Molecule-AI public repos like the internal-paths
block) — refuses any staged addition matching a high-value credential
shape and prints a recovery message that does NOT echo the secret value.

Pattern set covers GitHub family (ghp_, ghs_, gho_, ghu_, ghr_,
github_pat_), Anthropic / OpenAI / Slack / AWS — same shape as the
tenant-proxy CI scanner; keep aligned when either side adds a pattern.

Single hook file dispatches both checks (renamed
pre-commit-block-internal-paths.sh → pre-commit-checks.sh) so each
agent commit pays one git-config + one hook-install surface, not two.
Both checks share the existing fast-paths (skip if GIT_AUTHOR_NAME
unset; skip during rebase / cherry-pick / merge / revert).

End-to-end test exercises a real bash subprocess against a real temp
git repo with real staged content. Three cases:
 - ghs_-prefixed token in package.json (the actual #2090 vector) → refuse
 - clean README → pass through
 - sk-ant- key in a non-Molecule-AI repo → refuse (secret scan is universal,
   internal-paths block is not)

Skipped when bash is not on PATH so Windows test environments without
WSL stay green.

Bumps version 0.1.15 → 0.1.16.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 11:57:39 -07:00
rabbitblood
89739bf848 feat: pre-commit hook to block internal paths in public monorepo (A)
Anti-leak proposal item A. Companion to D (decision tree in role
prompts, separate PR on org-templates).

Why a local pre-commit hook
===========================

Agents try to `git add /research/foo.md` despite SHARED_RULES, the
.gitignore patterns, and the CI gate. Each leak attempt costs ~5 cycles
(PR opens, CI fails, agent retries with workaround) and pollutes git
history with reverts.

A pre-commit hook converts the failure from "PR opens then fails" →
"commit refused immediately, with the recovery command printed in the
same error message the agent reads." Agents act on what's in the
current response context — putting the redirect command literally in
the failure output is the highest-density feedback we can provide.

What changes
============

- molecule_runtime/scripts/pre-commit-block-internal-paths.sh —
  bash hook. Checks `git remote get-url origin`, only enforces in
  Molecule-AI/molecule-monorepo + molecule-core. In every other repo
  (internal, plugins, templates, third-party) it's a no-op.

  When forbidden paths are staged, refuses the commit with the redirect
  recipe + the alternative public-facing paths + the workflow-edit path
  for legitimate exceptions.

- molecule_runtime/precommit_hook.py — install_pre_commit_hook():
  1. Extracts bundled hook to ~/.molecule-runtime/git-hooks/pre-commit
  2. chmod +x
  3. Sets core.hooksPath globally — UNLESS already set by an operator
     (then logs a warning + skips, doesn't clobber)

- molecule_runtime/main.py — calls install_pre_commit_hook() at
  step 0.2, right after install_credential_helper()

- pyproject.toml bumped to 0.1.11

Both A and D together close the loop: D ensures the agent knows the
right path before writing; A enforces it at the local git boundary if
the agent forgets. CI gate remains the third backstop for anything
that gets pushed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 00:48:47 -07:00