chore(agent): commit the machine tier and the doctrine text the checkout was already running
Landing blocker for #61 and #63: the deployment checkout is 12 commits behind and `merge --ff-only` refuses while tracked paths are dirty. Discard is not available here (workspace policy: no `checkout`/`stash` on shared state), so the dirt is committed. - `agent/APPEND_SYSTEM.md`: the point-of-use / one-work-log / PR-link doctrine, already byte-identical to `origin/main` (`cmp` against the trunk blob: no difference). No new prose — the commit exists so the trunk merge can proceed. - `agent/config.yml` and `agent/managed-skills/**`: the machine-live tier the heartbeat owns (AGENTS.md § Live-sync tiers). `ALLOW_SECRETS=1` was used, deliberately and after auditing the staged diff by hand: the only credential-shaped strings in it are two copies of `AKIA0000000000000EXAMPLE` — the inert all-zero AWS example id — and they appear inside the two skill pages that teach that exact placeholder shape. This checkout is still running the pre-#61 hook; the merged gate (value-scoped placeholder filter, `71601f7`) exempts this value, so the refusal dies with this landing. No `--no-verify` was used: the gate ran and its verdict is recorded here. Refs #61
This commit is contained in:
1 parent
004962ffce
commit
8af40c402b
79 files changed
+2771
-332
No files matched your search
@@ -0,0 +1,51 @@
|
||||
---
|
||||
name: grep-secret-gate-hook-traps
|
||||
description: "Write a zero-dependency grep-based pre-commit secret gate that fails closed: the GNU grep -- one-shot trap, POSIX ERE limits, bracket collating elements, and rc=2-as-success in command substitution."
|
||||
---
|
||||
|
||||
# Fail-closed grep secret gate (pre-commit hook)
|
||||
|
||||
Use when writing/auditing a bash pre-commit hook (or any CI tripwire) that scans
|
||||
staged content with `grep -E` for credential shapes — no gitleaks available.
|
||||
|
||||
## The four traps (all personally earned; each silently PASSES bad content)
|
||||
|
||||
1. **`--` is a ONE-SHOT end-of-options marker.** `grep -nE -- 'p1' -- 'p2' 'p3'`
|
||||
takes the later `--` and patterns as FILE names → rc=2, errors on stderr.
|
||||
Correct multi-pattern form: repeat `-e` for every pattern; never `--`.
|
||||
2. **`if hits=$(... | grep ...)` treats rc=2 as success.** Any non-zero-but-not-1
|
||||
(broken pattern, unreadable file) enters the `then` branch with EMPTY output.
|
||||
Never branch on the substitution's truthiness. Capture rc explicitly:
|
||||
`hits=$(...); rc=$?` then: `rc>=2` → BLOCK (fail closed — a dead regex is
|
||||
worse than none), `rc==1` → clean, `rc==0` → hits.
|
||||
3. **POSIX ERE (`grep -E`) has no `(?:...)` groups.** Use plain `(...)`.
|
||||
4. **`[:-]` inside a bracket expression starts a collating element** →
|
||||
`grep: repetition-operator operand invalid` (rc=2, see trap 2). Put `-` FIRST
|
||||
in every class: `[-A-Za-z0-9/+=_.:+]`.
|
||||
|
||||
## Gate structure that works
|
||||
|
||||
- Scan **staged content**, not the working tree: `git show ":$f"` over
|
||||
`git diff --cached --name-only --diff-filter=ACM`.
|
||||
- Denylist doc/fixture paths (`README`, `docs?/`, `tests?/`, `*.example`) — else
|
||||
the hook blocks its own patterns and every test fixture.
|
||||
- Report `BLOCKED <file>:<line>` only — never echo the matched secret.
|
||||
- Wire with tracked `hooks/pre-commit` + `git config core.hooksPath hooks`
|
||||
(lives in the COMMON git dir config → one set in the main checkout covers
|
||||
every worktree). Fresh clones are unprotected until it's set; document it.
|
||||
- Worktrees lacking `hooks/` while `core.hooksPath` is set: git dies on commit
|
||||
(`cannot run ... No such file or directory`) — merge main in, don't unset.
|
||||
- Do NOT ship the hook in an npm plugin artifact (`files`): node_modules never
|
||||
runs git; pin its ABSENCE in the pack test instead.
|
||||
|
||||
## Test it red-first through the real seam (bats)
|
||||
|
||||
`git init` a fixture repo, `cp` the real hook in, `git config core.hooksPath hooks`,
|
||||
then drive REAL `git commit` and assert:
|
||||
- credential-shaped `.env` (RFC-2606 domains / all-zero ids as inert fixtures) →
|
||||
non-zero AND `git log` count unchanged (blocks, not warns);
|
||||
- PEM header line → blocked;
|
||||
- clean prose → passes;
|
||||
- the hook committing ITSELF → passes (trap 1/3/4 usually die here);
|
||||
- exit-code masking: `bats ... | tail` returns tail's rc — never `&& commit`
|
||||
behind a piped suite, or you commit on red.
|
||||
Reference in new issue
Block a user