Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4edf42ce9f | ||
|
|
2f53346b8c | ||
|
|
dcc0677270 |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "skills",
|
"name": "skills",
|
||||||
"description": "Mathias's engineering skills library, plus the hooks and MCP servers that make it enforceable: TDD, clean code, debugging, specs, discovery, CI, and secret hygiene.",
|
"description": "Mathias's engineering skills library, plus the hooks and MCP servers that make it enforceable: TDD, clean code, debugging, specs, discovery, CI, and secret hygiene.",
|
||||||
"version": "0.19.1",
|
"version": "0.19.2",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Mathias",
|
"name": "Mathias",
|
||||||
"url": "https://git.d-ma.be/mathias"
|
"url": "https://git.d-ma.be/mathias"
|
||||||
|
|||||||
@@ -41,7 +41,17 @@ if [ ! -f "$CONFIG" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -f "$ENVFILE" ]; then
|
if [ ! -f "$ENVFILE" ]; then
|
||||||
|
# EXPECTED IN CI, and permanently so. The env-file holds live credentials, so
|
||||||
|
# it is not on the runner and must not be -- which means this check can only
|
||||||
|
# ever verify on a host that has one. infra#368 added jq to the runner image
|
||||||
|
# believing that would let CI verify; it removed the jq branch below and
|
||||||
|
# changed nothing else, because this branch is the binding one.
|
||||||
|
#
|
||||||
|
# Said plainly so nobody concludes CI covers this. It does not, it cannot,
|
||||||
|
# and putting ~/.op-env on the runner to make it would be trading a real
|
||||||
|
# secret for a green tick.
|
||||||
echo "ERROR: no such env-file: $ENVFILE -- cannot verify MCP variables" >&2
|
echo "ERROR: no such env-file: $ENVFILE -- cannot verify MCP variables" >&2
|
||||||
|
echo " (expected in CI: this check only verifies on a host with ~/.op-env)" >&2
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ decision_for() {
|
|||||||
_tool=${2:-Bash}
|
_tool=${2:-Bash}
|
||||||
jq -n --arg t "$_tool" --arg c "$_cmd" \
|
jq -n --arg t "$_tool" --arg c "$_cmd" \
|
||||||
'{tool_name: $t, tool_input: {command: $c}}' \
|
'{tool_name: $t, tool_input: {command: $c}}' \
|
||||||
| sh "$GUARD" \
|
| "$GUARD" \
|
||||||
| jq -r '.hookSpecificOutput.permissionDecision // "MISSING"'
|
| jq -r '.hookSpecificOutput.permissionDecision // "MISSING"'
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,6 +42,20 @@ expect() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Invoked as a PROGRAM above, never as `sh "$GUARD"`. Claude Code executes the
|
||||||
|
# hook directly, so its `#!/usr/bin/env bash` shebang decides the interpreter;
|
||||||
|
# piping it into `sh` overrides that and tests something production never runs.
|
||||||
|
#
|
||||||
|
# It is not academic. On Debian /bin/sh is dash, which has no `set -o
|
||||||
|
# pipefail`, so the guard died on line 23 before reading a byte of input and
|
||||||
|
# every deny case returned empty -- 20 of 20 assertions failed in CI while
|
||||||
|
# passing on a host where /bin/sh happens to be bash. A security gate that
|
||||||
|
# tests green and cannot start is the worst of both.
|
||||||
|
if [ ! -x "$GUARD" ]; then
|
||||||
|
printf 'FAIL: %s is not executable -- it must run via its own shebang\n' "$GUARD"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
if [ ! -f "$GUARD" ]; then
|
if [ ! -f "$GUARD" ]; then
|
||||||
printf 'FAIL: %s does not exist\n' "$GUARD"
|
printf 'FAIL: %s does not exist\n' "$GUARD"
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
Reference in New Issue
Block a user