@windyroad/architect 1.0.1 → 1.1.0-preview.1304
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.
|
@@ -11,22 +11,44 @@ tool_name() {
|
|
|
11
11
|
printf '%s' "$INPUT" | jq -r '.tool_name // ""' 2>/dev/null || true
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
ADVISORIES=""
|
|
15
|
+
collect_gate_output() {
|
|
16
|
+
local output="$1" parsed
|
|
17
|
+
[ -n "$output" ] || return 0
|
|
18
|
+
if ! parsed="$(printf '%s' "$output" | jq -cs '
|
|
19
|
+
if any(.[]; .hookSpecificOutput.permissionDecision == "deny")
|
|
20
|
+
then map(select(.hookSpecificOutput.permissionDecision == "deny"))[0]
|
|
21
|
+
else {systemMessage: map(.systemMessage // .hookSpecificOutput.permissionDecisionReason // "Governance evidence unavailable; action permitted.") | join("\n")} end' 2>/dev/null)"; then
|
|
22
|
+
parsed='{"systemMessage":"Governance evidence unavailable: malformed evaluator output; action permitted."}'
|
|
23
|
+
fi
|
|
24
|
+
if printf '%s' "$parsed" | jq -e '.hookSpecificOutput.permissionDecision == "deny"' >/dev/null 2>&1; then
|
|
25
|
+
printf '%s\n' "$parsed"
|
|
26
|
+
exit 0
|
|
27
|
+
fi
|
|
28
|
+
ADVISORIES="$ADVISORIES
|
|
29
|
+
$parsed"
|
|
30
|
+
}
|
|
31
|
+
flush_advisories() {
|
|
32
|
+
[ -n "$ADVISORIES" ] || return 0
|
|
33
|
+
printf '%s' "$ADVISORIES" | jq -s '{systemMessage: map(.systemMessage // .hookSpecificOutput.permissionDecisionReason // "Governance evidence unavailable; action permitted.") | join("\n")}'
|
|
34
|
+
}
|
|
14
35
|
run_gate() {
|
|
15
|
-
local output status
|
|
16
|
-
local child="$1"
|
|
36
|
+
local output status child="$1"
|
|
17
37
|
shift
|
|
18
|
-
output="$(printf '%s' "$INPUT" | "$SCRIPT_DIR/$child" "$@")"
|
|
38
|
+
output="$(printf '%s' "$INPUT" | "$SCRIPT_DIR/$child" "$@" 2>/dev/null)"
|
|
19
39
|
status=$?
|
|
20
|
-
[
|
|
21
|
-
|
|
22
|
-
|
|
40
|
+
if [ "$status" -ne 0 ]; then
|
|
41
|
+
collect_gate_output '{"systemMessage":"Governance evaluator unavailable; action permitted. A crashed hook output was discarded."}'
|
|
42
|
+
return 0
|
|
43
|
+
fi
|
|
44
|
+
collect_gate_output "$output"
|
|
23
45
|
}
|
|
24
46
|
|
|
25
47
|
run_side_effect() {
|
|
26
48
|
local output status
|
|
27
49
|
local child="$1"
|
|
28
50
|
shift
|
|
29
|
-
output="$(printf '%s' "$INPUT" | "$SCRIPT_DIR/$child" "$@")"
|
|
51
|
+
output="$(printf '%s' "$INPUT" | "$SCRIPT_DIR/$child" "$@" 2>/dev/null)"
|
|
30
52
|
status=$?
|
|
31
53
|
[ -z "$output" ] || printf '%s\n' "$output"
|
|
32
54
|
return "$status"
|
|
@@ -109,3 +131,5 @@ if messages:
|
|
|
109
131
|
esac
|
|
110
132
|
;;
|
|
111
133
|
esac
|
|
134
|
+
|
|
135
|
+
[ "$EVENT" != pre-tool ] || flush_advisories
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
_ARCHITECT_GATE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
8
|
source "$_ARCHITECT_GATE_DIR/gate-helpers.sh"
|
|
9
9
|
|
|
10
|
-
#
|
|
10
|
+
# Validate architect receipt; the public gate below converts unavailable evidence to an advisory.
|
|
11
11
|
# Sets ARCHITECT_GATE_REASON on failure with an explicit recovery directive
|
|
12
12
|
# naming the wr-architect:agent subagent_type (P215 / RFC-021 — mirrors the
|
|
13
13
|
# sibling REVIEW_GATE_REASON pattern in review-gate.sh). Downstream
|
|
@@ -15,7 +15,7 @@ source "$_ARCHITECT_GATE_DIR/gate-helpers.sh"
|
|
|
15
15
|
# append this reason to their BLOCKED deny message so the agent sees a clear
|
|
16
16
|
# recovery affordance without having to read source.
|
|
17
17
|
# Usage: check_architect_gate "$SESSION_ID"
|
|
18
|
-
|
|
18
|
+
_check_architect_receipt() {
|
|
19
19
|
local SESSION_ID="$1"
|
|
20
20
|
local MARKER="/tmp/architect-reviewed-${SESSION_ID}"
|
|
21
21
|
local TTL_SECONDS="${ARCHITECT_TTL:-3600}"
|
|
@@ -66,10 +66,16 @@ check_architect_gate() {
|
|
|
66
66
|
return 1 # No marker, deny
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
#
|
|
69
|
+
# Permit parsing failures with an unavailable-evidence advisory
|
|
70
70
|
architect_gate_parse_error() {
|
|
71
71
|
cat <<'EOF'
|
|
72
|
-
{ "hookSpecificOutput": { "hookEventName": "PreToolUse", "permissionDecision": "
|
|
73
|
-
"permissionDecisionReason": "
|
|
72
|
+
{ "hookSpecificOutput": { "hookEventName": "PreToolUse", "permissionDecision": "allow",
|
|
73
|
+
"permissionDecisionReason": "Governance evidence unavailable: could not parse hook input; action permitted." } }
|
|
74
74
|
EOF
|
|
75
75
|
}
|
|
76
|
+
|
|
77
|
+
check_architect_gate() {
|
|
78
|
+
if _check_architect_receipt "$@"; then return 0; fi
|
|
79
|
+
_governance_advisory "$ARCHITECT_GATE_REASON"
|
|
80
|
+
return 0
|
|
81
|
+
}
|
|
@@ -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
|
+
}
|