mirror of
https://github.com/boshu2/agentops.git
synced 2026-09-14 15:08:13 +08:00
d972fa2090
## What Prepare AgentOps 4.0.0 across the Claude plugin, Codex plugin, skills and CLI. Claude writers capture the supplied check status during its original invocation, and plugin conformance verifies exact skill membership and link destinations. Full release security now scans the repository and blocks on Python collection failures that previously produced a false green result. ## Why The 3.6.0-to-current interval removes published commands and 20 skill names, so this is a major release with migration instructions. Release validation also exposed stale skill assertions and test prerequisites that need to match the current product contracts without weakening acceptance. ## How I tested - Native Claude Opus/Haiku success, failing-check and direct-writer trials: each check ran once, and the direct child returned plain JSON. - Actual fresh installs and upgrades from 3.6.0 in isolated Codex and Claude homes: 34 skills, expected agents, and exact installed package bytes. - Exact candidate `b721d02559e1495be6095ad97b820e88ceb4a049`: all 73 full repository gates, regeneration parity, and the complete local release rehearsal passed. All 12 security tools ran with zero skips, tool errors, critical findings or high-severity security findings. The unchanged advisory policy reports 35 quality-high findings on unchanged files. - Python: 327 tests and 72 subtests passed. Hosted Bats: 1,509 passed, 31 environment-dependent skips, zero failures. Go lint/build/vet/race/shuffle checks and CLI smoke/integration passed. - All 11 hosted checks passed, including Windows correctness, macOS/Linux installation, security, and the six-target no-publish GoReleaser snapshot. Local archive checksums and a real macOS CLI initialization/status/version smoke also passed. - Fresh author-distinct review passed all four acceptance criteria and all 35 changed paths with no unchecked acceptance. Canonical subject and caller-intent verification passed; verdict digest `68af2c935ed0106cd91b3950f5d168e662f4071f660fcbd113c36b7cd0f0426e` binds manifest `7affc77e25eaff69ba36c5ce05582b4f0385c954b76b62c02b97f97041f489b2`. ## Checklist - [x] Breaking changes documented in the migration guide and complete release notes. - [x] No credentials or private runtime proof included. - [x] Final full release checks pass on the exact candidate. - [x] Fresh author-distinct final PASS is recorded before merge. This prepares the release candidate; it does not publish a tag or release. Coverage limits remain explicit: native plugin tests used isolated macOS homes and local marketplaces, guard installation remains opt-in, and reader instructions do not prove sandbox confinement. Semgrep retains pre-existing warning-level parser diagnostics. Snapshot metadata follows the existing 3.6.0 tag; this is a packaging rehearsal, not a published 4.0.0 archive.
149 lines
4.0 KiB
Bash
Executable File
149 lines
4.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
cd "$REPO_ROOT"
|
|
|
|
MODE="quick"
|
|
JSON_OUTPUT=false
|
|
REQUIRE_TOOLS=false
|
|
|
|
usage() {
|
|
cat <<'USAGE'
|
|
Usage: scripts/security-gate.sh [--mode quick|full] [--json] [--require-tools]
|
|
|
|
Runs the unified security gate using scripts/toolchain-validate.sh.
|
|
|
|
Options:
|
|
--mode quick|full quick = changed scope, skip slow tests (default); full = repository-wide suite
|
|
--json output machine-readable summary JSON
|
|
--require-tools fail if any scanner reports not_installed/error
|
|
-h, --help show this help
|
|
USAGE
|
|
}
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--mode)
|
|
MODE="${2:-}"
|
|
shift 2
|
|
;;
|
|
--json)
|
|
JSON_OUTPUT=true
|
|
shift
|
|
;;
|
|
--require-tools)
|
|
REQUIRE_TOOLS=true
|
|
shift
|
|
;;
|
|
-h|--help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo "Unknown option: $1" >&2
|
|
usage >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [[ "$MODE" != "quick" && "$MODE" != "full" ]]; then
|
|
echo "Invalid mode: $MODE (expected quick or full)" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Canonical scanner invocation contract: scripts/toolchain-validate.sh --gate
|
|
TOOLCHAIN_SCRIPT="${SECURITY_GATE_TOOLCHAIN_SCRIPT:-scripts/toolchain-validate.sh}"
|
|
if [[ ! -x "$TOOLCHAIN_SCRIPT" ]]; then
|
|
echo "Missing executable: $TOOLCHAIN_SCRIPT" >&2
|
|
exit 1
|
|
fi
|
|
|
|
RUN_ID="$(date -u +%Y%m%dT%H%M%SZ)-${MODE}"
|
|
SECURITY_BASE="${SECURITY_GATE_OUTPUT_DIR:-${TMPDIR:-/tmp}/agentops-security}"
|
|
SECURITY_DIR="$SECURITY_BASE/$RUN_ID"
|
|
mkdir -p "$SECURITY_DIR"
|
|
|
|
TOOLCHAIN_ARGS=(--all --gate --json)
|
|
if [[ "$MODE" == "quick" ]]; then
|
|
TOOLCHAIN_ARGS=(--quick --gate --json)
|
|
fi
|
|
|
|
set +e
|
|
TOOLCHAIN_OUTPUT="$($TOOLCHAIN_SCRIPT "${TOOLCHAIN_ARGS[@]}" 2>&1)"
|
|
TOOLCHAIN_EXIT=$?
|
|
set -e
|
|
|
|
SUMMARY_JSON="$SECURITY_DIR/summary.json"
|
|
printf '%s\n' "$TOOLCHAIN_OUTPUT" > "$SUMMARY_JSON"
|
|
|
|
TOOLING_SRC="${TOOLCHAIN_OUTPUT_DIR:-${TMPDIR:-/tmp}/agentops-tooling}"
|
|
if [[ -d "$TOOLING_SRC" ]]; then
|
|
cp -a "$TOOLING_SRC/." "$SECURITY_DIR/" 2>/dev/null || true
|
|
fi
|
|
|
|
if command -v jq >/dev/null 2>&1 && jq empty "$SUMMARY_JSON" >/dev/null 2>&1; then
|
|
GATE_STATUS="$(jq -r '.gate_status // "UNKNOWN"' "$SUMMARY_JSON")"
|
|
MISSING_TOOLS="$(jq -r '[.tools[] | select(. == "not_installed" or . == "error")] | length' "$SUMMARY_JSON")"
|
|
|
|
EXTENDED_JSON="$SECURITY_DIR/security-gate-summary.json"
|
|
jq -n \
|
|
--arg mode "$MODE" \
|
|
--arg run_id "$RUN_ID" \
|
|
--arg output_dir "$SECURITY_DIR" \
|
|
--argjson toolchain "$(cat "$SUMMARY_JSON")" \
|
|
--arg gate_status "$GATE_STATUS" \
|
|
--argjson missing_tools "$MISSING_TOOLS" \
|
|
--arg require_tools "$REQUIRE_TOOLS" \
|
|
'{
|
|
mode: $mode,
|
|
run_id: $run_id,
|
|
output_dir: $output_dir,
|
|
gate_status: $gate_status,
|
|
missing_tool_count: $missing_tools,
|
|
require_tools: ($require_tools == "true"),
|
|
toolchain: $toolchain
|
|
}' > "$EXTENDED_JSON"
|
|
|
|
if [[ "$REQUIRE_TOOLS" == "true" && "$MISSING_TOOLS" -gt 0 ]]; then
|
|
if [[ "$JSON_OUTPUT" == "true" ]]; then
|
|
cat "$EXTENDED_JSON"
|
|
else
|
|
echo "Security gate FAILED: missing/error tools detected ($MISSING_TOOLS)"
|
|
echo "Report: $EXTENDED_JSON"
|
|
fi
|
|
exit 4
|
|
fi
|
|
|
|
if [[ "$JSON_OUTPUT" == "true" ]]; then
|
|
cat "$EXTENDED_JSON"
|
|
else
|
|
echo "Security gate mode: $MODE"
|
|
echo "Gate status: $GATE_STATUS"
|
|
echo "Missing/error tools: $MISSING_TOOLS"
|
|
echo "Report: $EXTENDED_JSON"
|
|
fi
|
|
else
|
|
if [[ "$JSON_OUTPUT" == "true" ]]; then
|
|
jq -n \
|
|
--arg mode "$MODE" \
|
|
--arg run_id "$RUN_ID" \
|
|
--arg output_dir "$SECURITY_DIR" \
|
|
--arg raw "$TOOLCHAIN_OUTPUT" \
|
|
'{mode: $mode, run_id: $run_id, output_dir: $output_dir, parse_error: true, raw_output: $raw}'
|
|
else
|
|
echo "Security gate warning: toolchain output was not valid JSON"
|
|
echo "Raw output saved to: $SUMMARY_JSON"
|
|
fi
|
|
exit 1
|
|
fi
|
|
|
|
# Preserve toolchain gate semantics for findings.
|
|
if [[ "$TOOLCHAIN_EXIT" -ne 0 ]]; then
|
|
exit "$TOOLCHAIN_EXIT"
|
|
fi
|
|
|
|
exit 0
|