@windyroad/voice-tone 0.9.8 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -439,11 +439,6 @@ print(json.dumps({
|
|
|
439
439
|
" "$reason"
|
|
440
440
|
}
|
|
441
441
|
|
|
442
|
-
if [ "$BODY_FILE_ERROR" -eq 1 ]; then
|
|
443
|
-
deny_with_reason "BLOCKED (external-comms gate): body-file could not be read unambiguously from the command checkout. Use one readable UTF-8 --body-file path and review its exact contents before retrying."
|
|
444
|
-
exit 0
|
|
445
|
-
fi
|
|
446
|
-
|
|
447
442
|
permit_with_advisory() {
|
|
448
443
|
local msg="$1"
|
|
449
444
|
python3 -c "
|
|
@@ -452,6 +447,11 @@ print(json.dumps({'systemMessage': sys.argv[1]}))
|
|
|
452
447
|
" "$msg"
|
|
453
448
|
}
|
|
454
449
|
|
|
450
|
+
if [ "$BODY_FILE_ERROR" -eq 1 ]; then
|
|
451
|
+
permit_with_advisory "Governance evidence unavailable (external-comms gate): body-file could not be read unambiguously from the command checkout. Use one readable UTF-8 --body-file path and review its exact contents before retrying."
|
|
452
|
+
exit 0
|
|
453
|
+
fi
|
|
454
|
+
|
|
455
455
|
# ---------- Advisory-only fallback when policy file is absent ----------
|
|
456
456
|
if [ ! -f "$EXTERNAL_COMMS_POLICY_FILE" ]; then
|
|
457
457
|
permit_with_advisory "$EXTERNAL_COMMS_POLICY_FILE not found — $EXTERNAL_COMMS_SUBAGENT_TYPE gate is advisory-only on $SURFACE."
|
|
@@ -537,5 +537,5 @@ VERDICT_PREFIX="${EXTERNAL_COMMS_VERDICT_PREFIX:-EXTERNAL_COMMS_${EXTERNAL_COMMS
|
|
|
537
537
|
COMPLETION_GUIDANCE='On Codex, the calling agent waits for the reviewer to finish, then invokes `interrupt_agent` exactly once on that completed target before retrying; the PostToolUse compatibility hook consumes the completed response and persists its structured verdict, with no transcript parsing or nested codex exec. On Claude Code, the calling agent dispatches the reviewer synchronously (`run_in_background: false`) before retrying; the completion hook does not persist the marker for a background reviewer.'
|
|
538
538
|
REASON=$(printf 'BLOCKED (external-comms gate / %s evaluator): %s draft has not been reviewed by %s. Delegate to %s (subagent_type: '"'"'%s'"'"') with a prompt that starts with the line `SURFACE: %s` and wraps the draft body verbatim inside `<draft>...</draft>` markers (for the changeset-author surface the body is the changeset summary WITHOUT the leading `---` frontmatter block — the gate strips frontmatter before hashing the marker key). The completion hook marks the draft reviewed when the subagent emits %s_VERDICT: PASS — single fire suffices. %s Use %s for an interactive walkthrough. There is no environment-variable override; `BYPASS_RISK_GATE` is unavailable.' \
|
|
539
539
|
"$EXTERNAL_COMMS_EVALUATOR_ID" "$SURFACE" "$EXTERNAL_COMMS_SUBAGENT_TYPE" "$EXTERNAL_COMMS_SUBAGENT_TYPE" "$EXTERNAL_COMMS_SUBAGENT_TYPE" "$SURFACE" "$VERDICT_PREFIX" "$COMPLETION_GUIDANCE" "$EXTERNAL_COMMS_ASSESS_SKILL")
|
|
540
|
-
|
|
540
|
+
permit_with_advisory "Governance evidence unavailable; action permitted. $REASON"
|
|
541
541
|
exit 0
|
|
@@ -154,6 +154,9 @@ _HOOK_INPUT=""
|
|
|
154
154
|
|
|
155
155
|
_parse_input() {
|
|
156
156
|
_HOOK_INPUT=$(cat)
|
|
157
|
+
if ! printf '%s' "$_HOOK_INPUT" | python3 -c 'import json,sys; assert isinstance(json.load(sys.stdin),dict)' 2>/dev/null; then
|
|
158
|
+
_governance_advisory "Hook input could not be parsed."
|
|
159
|
+
fi
|
|
157
160
|
}
|
|
158
161
|
|
|
159
162
|
_get_tool_name() {
|
|
@@ -327,3 +330,8 @@ _is_doc_file() {
|
|
|
327
330
|
esac
|
|
328
331
|
return 1
|
|
329
332
|
}
|
|
333
|
+
|
|
334
|
+
# Mechanical evaluation failures are advisory; never mint approval receipts.
|
|
335
|
+
_governance_advisory() {
|
|
336
|
+
python3 -c 'import json,sys; print(json.dumps({"systemMessage": "Governance evidence unavailable; action permitted. " + sys.argv[1]}))' "$1" || echo 'Governance evidence unavailable; action permitted.' >&2
|
|
337
|
+
}
|
package/hooks/lib/review-gate.sh
CHANGED
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
_REVIEW_GATE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
8
|
source "$_REVIEW_GATE_DIR/gate-helpers.sh"
|
|
9
9
|
|
|
10
|
-
#
|
|
10
|
+
# Validate review receipt; the public gate below converts unavailable evidence to an advisory.
|
|
11
11
|
# Sets REVIEW_GATE_REASON on failure.
|
|
12
12
|
# Usage: check_review_gate "$SESSION_ID" "style-guide" "docs/STYLE-GUIDE.md"
|
|
13
|
-
|
|
13
|
+
_check_review_receipt() {
|
|
14
14
|
local SESSION_ID="$1"
|
|
15
15
|
local SYSTEM="$2" # e.g., "a11y", "voice-tone", "style-guide"
|
|
16
16
|
local POLICY_FILE="$3" # e.g., "docs/STYLE-GUIDE.md"
|
|
@@ -82,24 +82,21 @@ store_review_hash() {
|
|
|
82
82
|
return 0
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
# Emit
|
|
85
|
+
# Emit an advisory for unverifiable review requirements.
|
|
86
86
|
review_gate_deny() {
|
|
87
|
-
|
|
88
|
-
cat <<EOF
|
|
89
|
-
{
|
|
90
|
-
"hookSpecificOutput": {
|
|
91
|
-
"hookEventName": "PreToolUse",
|
|
92
|
-
"permissionDecision": "deny",
|
|
93
|
-
"permissionDecisionReason": "$REASON"
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
EOF
|
|
87
|
+
_governance_advisory "$1"
|
|
97
88
|
}
|
|
98
89
|
|
|
99
|
-
#
|
|
90
|
+
# Permit parsing failures with an unavailable-evidence advisory.
|
|
100
91
|
review_gate_parse_error() {
|
|
101
92
|
cat <<'EOF'
|
|
102
|
-
{ "hookSpecificOutput": { "hookEventName": "PreToolUse", "permissionDecision": "
|
|
103
|
-
"permissionDecisionReason": "
|
|
93
|
+
{ "hookSpecificOutput": { "hookEventName": "PreToolUse", "permissionDecision": "allow",
|
|
94
|
+
"permissionDecisionReason": "Governance evidence unavailable: could not parse hook input; action permitted." } }
|
|
104
95
|
EOF
|
|
105
96
|
}
|
|
97
|
+
|
|
98
|
+
check_review_gate() {
|
|
99
|
+
if _check_review_receipt "$@"; then return 0; fi
|
|
100
|
+
_governance_advisory "$REVIEW_GATE_REASON"
|
|
101
|
+
return 0
|
|
102
|
+
}
|
|
@@ -5,8 +5,34 @@ target="$1"
|
|
|
5
5
|
input="$(cat)"
|
|
6
6
|
tool="$(printf '%s' "$input" | jq -r '.tool_name // empty')"
|
|
7
7
|
|
|
8
|
+
ADVISORIES=""
|
|
9
|
+
collect_gate_output() {
|
|
10
|
+
local output="$1" parsed
|
|
11
|
+
[ -n "$output" ] || return 0
|
|
12
|
+
if ! parsed="$(printf '%s' "$output" | jq -cs '
|
|
13
|
+
if any(.[]; .hookSpecificOutput.permissionDecision == "deny")
|
|
14
|
+
then map(select(.hookSpecificOutput.permissionDecision == "deny"))[0]
|
|
15
|
+
else {systemMessage: map(.systemMessage // .hookSpecificOutput.permissionDecisionReason // "Governance evidence unavailable; action permitted.") | join("\n")} end' 2>/dev/null)"; then
|
|
16
|
+
parsed='{"systemMessage":"Governance evidence unavailable: malformed evaluator output; action permitted."}'
|
|
17
|
+
fi
|
|
18
|
+
if printf '%s' "$parsed" | jq -e '.hookSpecificOutput.permissionDecision == "deny"' >/dev/null 2>&1; then
|
|
19
|
+
printf '%s\n' "$parsed"
|
|
20
|
+
exit 0
|
|
21
|
+
fi
|
|
22
|
+
ADVISORIES="$ADVISORIES
|
|
23
|
+
$parsed"
|
|
24
|
+
}
|
|
25
|
+
flush_advisories() {
|
|
26
|
+
[ -n "$ADVISORIES" ] || return 0
|
|
27
|
+
printf '%s' "$ADVISORIES" | jq -s '{systemMessage: map(.systemMessage // .hookSpecificOutput.permissionDecisionReason // "Governance evidence unavailable; action permitted.") | join("\n")}'
|
|
28
|
+
}
|
|
8
29
|
run_hook() {
|
|
9
|
-
|
|
30
|
+
local output
|
|
31
|
+
if ! output="$(printf '%s' "$1" | "$target" 2>/dev/null)"; then
|
|
32
|
+
collect_gate_output '{"systemMessage":"Governance evaluator unavailable; action permitted. A crashed hook output was discarded."}'
|
|
33
|
+
return 0
|
|
34
|
+
fi
|
|
35
|
+
collect_gate_output "$output"
|
|
10
36
|
}
|
|
11
37
|
|
|
12
38
|
if [ "$tool" = "apply_patch" ]; then
|
|
@@ -16,6 +42,7 @@ if [ "$tool" = "apply_patch" ]; then
|
|
|
16
42
|
payload="$(printf '%s' "$input" | jq --arg path "$path" '.tool_name = "Edit" | .tool_input.file_path = $path')"
|
|
17
43
|
run_hook "$payload" || exit $?
|
|
18
44
|
done <<< "$paths"
|
|
45
|
+
flush_advisories
|
|
19
46
|
exit 0
|
|
20
47
|
fi
|
|
21
48
|
fi
|
|
@@ -25,3 +52,4 @@ if [ "$tool" = "spawn_agent" ] || [ "$tool" = "Agent" ]; then
|
|
|
25
52
|
fi
|
|
26
53
|
|
|
27
54
|
run_hook "$input"
|
|
55
|
+
flush_advisories
|