mirror of
https://github.com/boshu2/agentops.git
synced 2026-09-14 15:08:13 +08:00
e431339c40
## What AgentOps 3.0 goes **fully hookless**. This removes the entire hook product surface — the product is now skills + the `ao` CLI with **zero hooks**. CI is the authoritative gate. ## Deleted - `hooks/` — 46 hook scripts + `hooks.json` + examples (whole directory) - `cli/embedded/hooks/` + embedded `hooks.json` + `embedded/lib/hook-helpers.sh` - `lib/hook-helpers.sh` - `ao hooks` CLI command: `cli/cmd/ao/hooks.go`, `hooks_run.go` + 5 hook test files; `cli/internal/bridge/hooks.go`; `cli/internal/doctor/fix_hooks.go` + test - Codex hook manifest (`hooks/codex-hooks.json`) + handler/audit scripts (`scripts/audit-codex-hooks.sh`, `install-dev-hooks.sh`, `test-hooks-output.sh`, `test-codex-hookless-lifecycle.sh`, `test-hookless-rpi-phased.sh`) - Hook lease surface: `docs/contracts/hook-lease-*`, `schemas/hook-lease.v1.schema.json`, `scripts/check-hook-lease-inventory.sh`, `check-hook-port-replacements.sh`, `generate-hook-lease-inventory.py` - Hook docs: `docs/HOOKS.md`, `cli/docs/HOOKS.md`, `docs/architecture/hook-noise-audit.md`, `docs/contracts/hook-runtime-contract.md` - `tests/hooks/` (whole dir) + hook test scripts; 5 hook eval suites + fixtures ## CI gates removed `hook-preflight`, `validate-hooks-doc-parity`, `hook-output-schema-lint` (+ scripts/bats), the hook eval suites, the `test-runtime-codex-smoke` / `test-codex-native-install` / `test-codex-plugin-install` hook-handler assertions, the cli-integration hook-lifecycle steps, the bats `tests/hooks/*` glob + orphan-hooks audit, and the `--with-hooks` install path. `embedded-sync` now validates only lib/skills. Both summary `needs:` lists + the summary echo + `docs/contracts/ci-jobs.yaml` updated; `validate-ci-policy-parity` passes (66 rows). `.codex-plugin/plugin.json` drops the "Hooks" capability. ## Load-bearing PRESERVED (reported, not forced) - **`cli/cmd/ao/codex_runtime.go`** — the codex runtime *lifecycle profile* (`HookCapable`/`HookConfigured` detection) is a runtime-capability abstraction used by 6 `validate-codex-*` CI gates, distinct from the hook product. Deleting it is a separate refactor. - **`hooks-authoring` skill** + `schemas/hooks-manifest.v1.schema.json` — reframed as an opt-in "author your own hooks" guide. Deleting the skill cascades into catalog/domain-map/dispositions/context-map golden files (skill-count sync), out of scope for the hook-product removal. - **`scripts/pre-push-gate.sh`** — retired local gate (not in CI); self-skips deleted hook scripts via `[[ -x ]]` guards; its 55 bats tests still pass. - Domain-enforcement audit keeps the `enforced`-mode schema for backward-compatible JSON readers, but the hookless resolver only returns `audited`/`unavailable`. ## Verification `go build` / `go vet` clean; `go test ./...` = **11849 passed, 0 failed** (68 pkgs). gofmt clean on all touched files. Green: registry `--check` (0 hooks), `regen-codex-hashes --check`, `validate-ci-policy-parity`, `check-wiring-closure`, `validate-embedded-sync`, `validate-manifests`, `validate-agents-split`, `doc-release` (0 broken links), `generate-cli-reference --check`, `heal.sh --strict`, codex/claude/plugin smoke tests, baseline-audit (0 stale). Diff: 231 files, +354 / −39803. Closes-scenario: soc-57b7f#remove-all-hooks Bounded-context: BC5-Runtime Evidence: .github/workflows/validate.yml
259 lines
9.6 KiB
Bash
Executable File
259 lines
9.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# test-codex-native-install.sh
|
|
# Verifies the checked-in Codex-native bundle + install flow.
|
|
#
|
|
# What it checks:
|
|
# 1) shellcheck on codex install scripts
|
|
# 2) skill integrity gate (heal --strict)
|
|
# 3) checked-in skills-codex bundle is complete
|
|
# 4) install-codex.sh succeeds into temp HOME
|
|
# 5) Installed native plugin cache contains expected skill count and required files
|
|
# 6) Codex entrypoint files are runtime-agnostic (no ~/.codex/skills hardcoding)
|
|
# 7) Generated SKILL.md files use $skill syntax (no known /skill references)
|
|
#
|
|
# Usage:
|
|
# bash scripts/test-codex-native-install.sh
|
|
# bash scripts/test-codex-native-install.sh --only research,vibe
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
cd "$REPO_ROOT"
|
|
|
|
ONLY_CSV=""
|
|
SKIP_LINT="false"
|
|
|
|
usage() {
|
|
cat <<'EOF'
|
|
test-codex-native-install.sh
|
|
|
|
Options:
|
|
--only <a,b,c> Test only selected skills
|
|
--skip-lint Skip shellcheck + markdownlint
|
|
--help Show this help
|
|
|
|
Examples:
|
|
bash scripts/test-codex-native-install.sh
|
|
bash scripts/test-codex-native-install.sh --only research,vibe
|
|
EOF
|
|
}
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--only)
|
|
ONLY_CSV="${2:-}"
|
|
shift 2
|
|
;;
|
|
--skip-lint)
|
|
SKIP_LINT="true"
|
|
shift 1
|
|
;;
|
|
--help|-h)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo "Unknown arg: $1" >&2
|
|
usage >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
done
|
|
|
|
fail() {
|
|
echo "FAIL: $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
info() {
|
|
echo "INFO: $*"
|
|
}
|
|
|
|
require_cmd() {
|
|
command -v "$1" >/dev/null 2>&1 || fail "Required command not found: $1"
|
|
}
|
|
|
|
require_file() {
|
|
[[ -f "$1" ]] || fail "Required file missing: $1"
|
|
}
|
|
|
|
INSTALL_SCRIPT="$REPO_ROOT/scripts/install-codex-plugin.sh"
|
|
PUBLIC_INSTALL_SCRIPT="$REPO_ROOT/scripts/install-codex.sh"
|
|
HEAL_SCRIPT="$REPO_ROOT/skills/heal-skill/scripts/heal.sh"
|
|
CODEX_MANIFEST="$REPO_ROOT/.codex-plugin/plugin.json"
|
|
CODEX_MARKETPLACE="$REPO_ROOT/plugins/marketplace.json"
|
|
CODEX_SKILL_MANIFEST="$REPO_ROOT/skills-codex/.agentops-manifest.json"
|
|
|
|
require_file "$INSTALL_SCRIPT"
|
|
require_file "$PUBLIC_INSTALL_SCRIPT"
|
|
require_file "$HEAL_SCRIPT"
|
|
require_file "$CODEX_MANIFEST"
|
|
require_file "$CODEX_MARKETPLACE"
|
|
require_file "$CODEX_SKILL_MANIFEST"
|
|
require_cmd bash
|
|
require_cmd find
|
|
require_cmd awk
|
|
require_cmd sed
|
|
require_cmd jq
|
|
require_cmd rg
|
|
|
|
if [[ "$SKIP_LINT" != "true" ]]; then
|
|
require_cmd shellcheck
|
|
require_cmd markdownlint
|
|
|
|
info "Running shellcheck on codex install scripts"
|
|
shellcheck "$INSTALL_SCRIPT" "$PUBLIC_INSTALL_SCRIPT"
|
|
|
|
info "Running markdownlint on install docs"
|
|
markdownlint \
|
|
README.md \
|
|
AGENTS.md \
|
|
docs/reference.md \
|
|
docs/CONTRIBUTING.md \
|
|
docs/ARCHITECTURE.md \
|
|
docs/troubleshooting.md \
|
|
docs/INCIDENT-RUNBOOK.md
|
|
fi
|
|
|
|
info "Running strict skill integrity gate"
|
|
bash "$HEAL_SCRIPT" --strict >/dev/null
|
|
|
|
info "Checking checked-in Codex-native bundle"
|
|
[[ -s "$CODEX_SKILL_MANIFEST" ]] || fail "Checked-in Codex manifest is empty: $CODEX_SKILL_MANIFEST"
|
|
|
|
timestamp="$(date +%Y%m%d-%H%M%S)"
|
|
HOME_ROOT="/tmp/codex-native-install-test-${timestamp}"
|
|
CODEX_HOME="$HOME_ROOT/.codex"
|
|
PLUGIN_ROOT="$CODEX_HOME/plugins/cache/agentops-marketplace/agentops/local"
|
|
PLUGIN_SKILLS="$PLUGIN_ROOT/skills-codex"
|
|
|
|
info "Installing AgentOps via the public Codex installer into temp HOME"
|
|
HOME="$HOME_ROOT" AGENTOPS_BUNDLE_ROOT="$REPO_ROOT" AGENTOPS_INSTALL_REF="test-local" \
|
|
bash "$PUBLIC_INSTALL_SCRIPT" >/dev/null
|
|
|
|
[[ -d "$PLUGIN_SKILLS" ]] || fail "Plugin skills directory not created: $PLUGIN_SKILLS"
|
|
|
|
expected_count=0
|
|
if [[ -n "$ONLY_CSV" ]]; then
|
|
IFS=',' read -r -a selected <<<"$ONLY_CSV"
|
|
for skill in "${selected[@]}"; do
|
|
skill="$(echo "$skill" | xargs)"
|
|
[[ -n "$skill" ]] || continue
|
|
[[ -d "$REPO_ROOT/skills-codex/$skill" ]] || fail "Converted skill not found: skills-codex/$skill"
|
|
expected_count=$((expected_count + 1))
|
|
done
|
|
else
|
|
expected_count="$(find "$REPO_ROOT/skills-codex" -mindepth 1 -maxdepth 1 -type d | wc -l | tr -d ' ')"
|
|
fi
|
|
|
|
installed_count="$(find "$PLUGIN_SKILLS" -mindepth 1 -maxdepth 1 -type d | wc -l | tr -d ' ')"
|
|
[[ "$installed_count" == "$expected_count" ]] || fail "Installed count mismatch (expected $expected_count, got $installed_count)"
|
|
[[ ! -e "$HOME_ROOT/.agents/skills" ]] || fail "Unexpected ~/.agents/skills raw mirror created"
|
|
[[ ! -e "$CODEX_HOME/skills" ]] || fail "Unexpected ~/.codex/skills raw mirror created"
|
|
|
|
info "Verifying installed plugin files"
|
|
while IFS= read -r skill_dir; do
|
|
[[ -n "$skill_dir" ]] || continue
|
|
[[ -f "$skill_dir/SKILL.md" ]] || fail "Missing SKILL.md in $skill_dir"
|
|
[[ -f "$skill_dir/prompt.md" ]] || fail "Missing prompt.md in $skill_dir"
|
|
head -n 1 "$skill_dir/SKILL.md" | rg -q '^---$' || fail "Missing YAML frontmatter in $skill_dir/SKILL.md"
|
|
done < <(find "$PLUGIN_SKILLS" -mindepth 1 -maxdepth 1 -type d | sort)
|
|
|
|
[[ -f "$CODEX_HOME/config.toml" ]] || fail "Missing config.toml in $CODEX_HOME"
|
|
rg -q '^\[features\]$' "$CODEX_HOME/config.toml" || fail "config.toml missing [features] section"
|
|
rg -q '^plugins = true$' "$CODEX_HOME/config.toml" || fail "config.toml missing plugins = true"
|
|
rg -q '^\[ui\]$' "$CODEX_HOME/config.toml" || fail "config.toml missing [ui] section"
|
|
rg -q '^suppress_unstable_features_warning = true$' "$CODEX_HOME/config.toml" || fail "config.toml missing suppress_unstable_features_warning = true"
|
|
rg -q '^\[plugins\."agentops@agentops-marketplace"\]$' "$CODEX_HOME/config.toml" || fail "config.toml missing AgentOps plugin block"
|
|
rg -q '^enabled = true$' "$CODEX_HOME/config.toml" || fail "config.toml missing enabled = true"
|
|
if rg -q '^hooks = true$' "$CODEX_HOME/config.toml"; then
|
|
fail "default install should not enable hooks = true"
|
|
fi
|
|
if rg -q '^codex_hooks[[:space:]]*=' "$CODEX_HOME/config.toml"; then
|
|
fail "config.toml still contains deprecated codex_hooks"
|
|
fi
|
|
[[ ! -f "$CODEX_HOME/hooks.json" ]] || fail "Default install should not create ~/.codex/hooks.json"
|
|
rg -q '"install_mode": "native-plugin"' "$CODEX_HOME/.agentops-codex-install.json" \
|
|
|| fail "install metadata missing native-plugin mode"
|
|
rg -q '"hook_runtime": "hookless-default"' "$CODEX_HOME/.agentops-codex-install.json" \
|
|
|| fail "install metadata missing hookless-default hook_runtime field"
|
|
rg -q '"hooks_installed": false' "$CODEX_HOME/.agentops-codex-install.json" \
|
|
|| fail "install metadata should record hooks_installed=false"
|
|
rg -q '"user_skills_root": null' "$CODEX_HOME/.agentops-codex-install.json" \
|
|
|| fail "install metadata should not record a raw skills mirror"
|
|
|
|
info "Verifying --codex-home installs into the target Codex home (hookless)"
|
|
EXPLICIT_HOME_ROOT="/tmp/codex-native-plugin-explicit-${timestamp}"
|
|
EXPLICIT_CODEX_HOME="${EXPLICIT_HOME_ROOT}/explicit/.codex"
|
|
REAL_HOME_ROOT="${EXPLICIT_HOME_ROOT}/real-home"
|
|
mkdir -p "$EXPLICIT_CODEX_HOME"
|
|
HOME="$REAL_HOME_ROOT" bash "$INSTALL_SCRIPT" \
|
|
--repo-root "$REPO_ROOT" \
|
|
--codex-home "$EXPLICIT_CODEX_HOME" \
|
|
--version "test-local" \
|
|
--update-command "test-local" >/dev/null
|
|
[[ ! -f "$EXPLICIT_CODEX_HOME/hooks.json" ]] || fail "hookless install must not create hooks.json under --codex-home"
|
|
[[ -f "$EXPLICIT_CODEX_HOME/.agentops-codex-install.json" ]] || fail "install metadata missing under --codex-home"
|
|
rg -q '"hooks_installed": false' "$EXPLICIT_CODEX_HOME/.agentops-codex-install.json" \
|
|
|| fail "explicit install metadata should record hooks_installed=false"
|
|
|
|
info "Checking Codex entrypoint files for runtime-agnostic instructions"
|
|
entrypoint_files=()
|
|
while IFS= read -r -d '' file; do
|
|
entrypoint_files+=("$file")
|
|
done < <(find "$REPO_ROOT/skills-codex" -type f \( -name "SKILL.md" -o -name "prompt.md" \) -print0)
|
|
|
|
if rg -n "\$HOME/.codex/skills|~/.codex/skills" "${entrypoint_files[@]}" >/dev/null 2>&1; then
|
|
fail "Found stale ~/.codex/skills references in Codex entrypoint files"
|
|
fi
|
|
|
|
# Build regex alternation from known converted skill names.
|
|
skill_pattern="$(
|
|
find "$REPO_ROOT/skills-codex" -mindepth 1 -maxdepth 1 -type d -exec basename {} \; \
|
|
| sort \
|
|
| awk '
|
|
BEGIN { ORS="" }
|
|
{
|
|
gsub(/[][(){}.^$*+?|\\-]/, "\\\\&", $0)
|
|
if (NR > 1) { printf "|" }
|
|
printf "%s", $0
|
|
}
|
|
'
|
|
)"
|
|
[[ -n "$skill_pattern" ]] || fail "Could not build skill-name regex for slash-command check"
|
|
|
|
info "Checking Codex entrypoint files for known slash-command references"
|
|
if [[ "${#entrypoint_files[@]}" -eq 0 ]]; then
|
|
fail "No Codex entrypoint files found for slash-command check"
|
|
fi
|
|
|
|
if rg --pcre2 -n "(^|[^A-Za-z0-9_./])/(${skill_pattern})(?![A-Za-z0-9-])" "${entrypoint_files[@]}" >/dev/null 2>&1; then
|
|
fail "Found known /skill command references in skills-codex output"
|
|
fi
|
|
|
|
info "Checking openai-docs Codex install flow for duplicate setup drift"
|
|
openai_skill="$REPO_ROOT/skills-codex/openai-docs/SKILL.md"
|
|
legacy_codex_settings_pattern="~"
|
|
legacy_codex_settings_pattern="${legacy_codex_settings_pattern}/.codex/settings.json"
|
|
require_file "$openai_skill"
|
|
[[ "$(rg -c '^\*\*In Codex:\*\*$' "$openai_skill")" == "1" ]] \
|
|
|| fail "Expected exactly one '**In Codex:**' section in $openai_skill"
|
|
rg -q 'codex mcp add openaiDeveloperDocs --url https://developers.openai.com/mcp' "$openai_skill" \
|
|
|| fail "Missing Codex MCP install command in $openai_skill"
|
|
if rg -q "$legacy_codex_settings_pattern" "$openai_skill"; then
|
|
fail "Found duplicate Codex settings-file install flow in $openai_skill"
|
|
fi
|
|
|
|
info "Checking shared Codex backend references"
|
|
shared_skill="$REPO_ROOT/skills-codex/shared/SKILL.md"
|
|
require_file "$shared_skill"
|
|
rg -q '\| Codex session agents \| `references/backend-codex-subagents\.md` \|' "$shared_skill" \
|
|
|| fail "Missing Codex session-agent backend mapping in $shared_skill"
|
|
|
|
echo ""
|
|
echo "PASS: Codex-native install flow verified"
|
|
echo " skills tested: $installed_count"
|
|
echo " home root: $HOME_ROOT"
|
|
echo " plugin root: $PLUGIN_ROOT"
|