Fix: Close verification gate review findings

This commit is contained in:
Gabriel Brown
2026-08-27 00:21:45 -04:00
parent 77f625d7bb
commit 12b858371e
10 changed files with 575 additions and 57 deletions
+184 -24
View File
@@ -89,6 +89,8 @@ ${BOLD}Commands:${RESET}
pattern to run a subset. --safe selects hermetic contracts only.
Plain terminal runs prompt before non-hermetic work. Automation
must grant each required capability with a repeatable --allow.
Each non-hermetic contract announces its exact capabilities
before it starts.
Failures print captured stdout/stderr. Successful stdout stays
quiet; successful stderr is a warning. The default outer timeout
is 180 seconds. Set PANAMA_TEST_TIMEOUT_SECONDS to a positive
@@ -447,12 +449,20 @@ PROMPT
CONTRACT_MANIFEST="tests/contracts.manifest"
CONTRACT_CAPABILITIES=(hermetic live-host live-compositor live-desktop network privileged)
contract_paths() {
local candidate
while IFS= read -r candidate; do
[[ -x "$candidate" || "$candidate" == *_test.py ]] || continue
printf 'tests/%s\n' "${candidate#"$PANAMA_DIR/tests/"}"
done < <(find "$PANAMA_DIR/tests" -type f \
-not -path '*/fixtures/*' -not -path '*__pycache__*' | sort)
}
contract_manifest_entries() {
local line capabilities path
while IFS= read -r line || [[ -n "$line" ]]; do
line="${line%%#*}"
read -r capabilities path _ <<<"$line"
[[ -n "${capabilities:-}" && -n "${path:-}" ]] || continue
[[ "$line" =~ ^[[:space:]]*(#|$) ]] && continue
IFS=$' \t' read -r capabilities path <<<"$line"
printf '%s\t%s\n' "$path" "$capabilities"
done < "$PANAMA_DIR/$CONTRACT_MANIFEST"
}
@@ -464,6 +474,98 @@ require_contract_manifest() {
}
}
validate_contract_manifest() {
require_contract_manifest || return 1
local manifest="$PANAMA_DIR/$CONTRACT_MANIFEST"
local line capabilities path extra previous_comment="" previous_was_comment=0
local previous_path="" capability discovered
local -a capability_list=() findings=()
local -A expected_contracts=() manifest_paths=()
while IFS= read -r discovered; do
expected_contracts["$discovered"]=1
done < <(contract_paths)
while IFS= read -r line || [[ -n "$line" ]]; do
if [[ "$line" =~ ^[[:space:]]*# ]]; then
previous_comment="${line#*#}"
previous_comment="${previous_comment#"${previous_comment%%[![:space:]]*}"}"
previous_comment="${previous_comment%"${previous_comment##*[![:space:]]}"}"
previous_was_comment=1
continue
fi
if [[ "$line" =~ ^[[:space:]]*$ ]]; then
previous_comment=""
previous_was_comment=0
continue
fi
IFS=$' \t' read -r capabilities path extra <<<"$line"
if [[ -z "${capabilities:-}" || -z "${path:-}" || -n "${extra:-}" ]]; then
findings+=("manifest line is not exactly two fields: $line")
previous_comment=""
previous_was_comment=0
continue
fi
if [[ -n "$previous_path" && "$path" < "$previous_path" ]]; then
findings+=('paths are not lexicographically sorted')
fi
previous_path="$path"
if [[ -n "${manifest_paths[$path]:-}" ]]; then
findings+=("duplicate path $path")
fi
manifest_paths["$path"]=1
local -A line_capabilities=()
if [[ "$capabilities" == ,* || "$capabilities" == *, || "$capabilities" == *,,* ]]; then
findings+=("empty capability on $path")
fi
IFS=',' read -r -a capability_list <<<"$capabilities"
for capability in "${capability_list[@]}"; do
[[ -n "$capability" ]] || continue
if [[ -n "${line_capabilities[$capability]:-}" ]]; then
findings+=("duplicate capability $capability on $path")
fi
line_capabilities["$capability"]=1
is_contract_capability "$capability" \
|| findings+=("unknown capability $capability on $path")
done
if [[ -n "${line_capabilities[hermetic]:-}" && ${#line_capabilities[@]} -ne 1 ]]; then
findings+=("hermetic must appear alone on $path")
fi
if [[ "$capabilities" != hermetic ]]; then
if (( previous_was_comment != 1 )); then
findings+=("$path is non-hermetic but lacks a directly preceding comment")
elif [[ -z "$previous_comment" ]]; then
findings+=("$path is non-hermetic but lacks a non-empty directly preceding comment")
fi
fi
previous_comment=""
previous_was_comment=0
done < "$manifest"
for discovered in "${!expected_contracts[@]}"; do
[[ -n "${manifest_paths[$discovered]:-}" ]] \
|| findings+=("missing contract $discovered")
done
for path in "${!manifest_paths[@]}"; do
[[ -n "${expected_contracts[$path]:-}" ]] \
|| findings+=("stale manifest path $path")
done
if (( ${#findings[@]} > 0 )); then
err "Contract manifest validation failed with ${#findings[@]} finding(s):"
printf ' - %s\n' "${findings[@]}" >&2
return 1
fi
}
test_usage() {
err "Usage: ${BOLD}$PROGRAM test [--safe] [--allow <capability>] [pattern]${RESET}"
return 2
@@ -492,10 +594,59 @@ is_contract_capability() {
# --safe runs only contracts the manifest classifies as hermetic and reports
# each external capability it skipped. A plain terminal run asks before any
# selected non-hermetic work. Automation must grant every required capability
# with repeatable --allow flags. Each contract gets an outer timeout, 180
# with repeatable --allow flags. Non-hermetic contracts announce their exact
# capability list before execution. Each contract gets an outer timeout, 180
# seconds by default. PANAMA_TEST_TIMEOUT_SECONDS accepts a positive integer
# override. Failures include captured stdout and stderr. Successful stdout stays
# quiet, while successful stderr is surfaced as a warning.
# override. Failures include captured stdout and stderr. Successful stdout
# stays quiet, while successful stderr is surfaced as a warning.
PANAMA_ACTIVE_CONTRACT_PID=""
PANAMA_CONTRACT_CAPTURE_DIR=""
cleanup_contract_capture() {
if [[ -n "$PANAMA_CONTRACT_CAPTURE_DIR" && -d "$PANAMA_CONTRACT_CAPTURE_DIR" ]]; then
rm -rf -- "$PANAMA_CONTRACT_CAPTURE_DIR" || true
fi
PANAMA_CONTRACT_CAPTURE_DIR=""
}
terminate_active_contract() {
local pid="$PANAMA_ACTIVE_CONTRACT_PID"
PANAMA_ACTIVE_CONTRACT_PID=""
[[ "$pid" =~ ^[1-9][0-9]*$ && "$pid" != "$$" ]] || return 0
# GNU timeout owns a process group whose ID is its PID. Signal that complete
# group so a contract cannot leave descendants behind, with a direct-PID
# fallback for implementations that do not create the group.
kill -TERM -- "-$pid" 2>/dev/null || kill -TERM "$pid" 2>/dev/null || true
wait "$pid" 2>/dev/null || true
}
handle_contract_signal() {
local signal_status="$1"
trap - INT TERM
terminate_active_contract
cleanup_contract_capture
trap - EXIT
exit "$signal_status"
}
prepare_contract_capture() {
local capture_dir=""
if ! capture_dir="$(mktemp -d)"; then
err 'Could not create contract capture directory.'
return 1
fi
if [[ -z "$capture_dir" || ! -d "$capture_dir" ]]; then
err 'Could not create contract capture directory.'
return 1
fi
PANAMA_CONTRACT_CAPTURE_DIR="$capture_dir"
trap cleanup_contract_capture EXIT
trap 'handle_contract_signal 130' INT
trap 'handle_contract_signal 143' TERM
}
cmd_test() {
local timeout_seconds="${PANAMA_TEST_TIMEOUT_SECONDS:-180}"
[[ "$timeout_seconds" =~ ^[1-9][0-9]*$ ]] || {
@@ -503,11 +654,11 @@ cmd_test() {
return 2
}
require_contract_manifest || return 1
validate_contract_manifest || return 1
cmd_test_impl "$timeout_seconds" "$@"
}
cmd_test_impl() (
cmd_test_impl() {
local timeout_seconds="$1"
shift
local pattern="" safe=0 arg capability capabilities rel path
@@ -605,12 +756,10 @@ cmd_test_impl() (
fi
fi
local capture_dir stdout_file stderr_file name run_status index=0
local capture_dir stdout_file stderr_file name run_status index=0 final_status=0
local -a failed=() runner=()
capture_dir="$(mktemp -d)"
trap 'rm -rf -- "$capture_dir"' EXIT
trap 'rm -rf -- "$capture_dir"; exit 130' INT
trap 'rm -rf -- "$capture_dir"; exit 143' TERM
prepare_contract_capture || return 1
capture_dir="$PANAMA_CONTRACT_CAPTURE_DIR"
info "Running ${#suite[@]} contract(s)"
for index in "${!suite[@]}"; do
@@ -624,9 +773,16 @@ cmd_test_impl() (
else
runner=("$path")
fi
capabilities="${manifest_capabilities[$rel]}"
if [[ "$capabilities" != hermetic ]]; then
info "Running $name [$capabilities]"
fi
run_status=0
timeout --signal=TERM --kill-after=5 "$timeout_seconds" \
"${runner[@]}" >"$stdout_file" 2>"$stderr_file" || run_status=$?
"${runner[@]}" >"$stdout_file" 2>"$stderr_file" &
PANAMA_ACTIVE_CONTRACT_PID=$!
wait "$PANAMA_ACTIVE_CONTRACT_PID" || run_status=$?
PANAMA_ACTIVE_CONTRACT_PID=""
if (( run_status == 0 )); then
ok "$name"
if [[ -s "$stderr_file" ]]; then
@@ -655,12 +811,16 @@ cmd_test_impl() (
header "Result"
if (( ${#failed[@]} == 0 )); then
ok "${#suite[@]} contract(s) passed"
return 0
else
err "${#failed[@]} of ${#suite[@]} failed:"
printf ' %s\n' "${failed[@]}" >&2
final_status=1
fi
err "${#failed[@]} of ${#suite[@]} failed:"
printf ' %s\n' "${failed[@]}" >&2
return 1
)
cleanup_contract_capture
trap - EXIT INT TERM
return "$final_status"
}
# ----------------------------------------------------------------------------
# Command: contracts
@@ -721,7 +881,7 @@ cmd_contracts() {
suffix="${suffix#*/}"
done
require_contract_manifest || return 1
validate_contract_manifest || return 1
local -A manifest_capabilities=()
local capabilities
while IFS=$'\t' read -r rel capabilities; do
@@ -732,11 +892,11 @@ cmd_contracts() {
# runner would actually execute.
local -a hits=()
local candidate rel
while IFS= read -r candidate; do
[[ -x "$candidate" || "$candidate" == *_test.py ]] || continue
while IFS= read -r rel; do
candidate="$PANAMA_DIR/$rel"
grep -qF "${patterns[@]}" "$candidate" 2>/dev/null || continue
hits+=("tests/${candidate#"$PANAMA_DIR"/tests/}")
done < <(find "$PANAMA_DIR/tests" -type f -not -path '*/fixtures/*' -not -path '*__pycache__*' | sort)
hits+=("$rel")
done < <(contract_paths)
if (( ${#hits[@]} == 0 )); then
printf 'No contract mentions %s — coverage may be indirect (a harness or a generated artifact); nothing verified.\n' "$path" >&2