mirror of
https://github.com/boshu2/agentops.git
synced 2026-09-14 15:08:13 +08:00
23c0026500
## Summary Closes the findings from the v3.3.0 release-viability audit of main. **Surface truth (High):** `ao constraint`, `ao goals trace`, `ao session memory`, and `ao skills edit` are production tombstones but docs/cli-surface.md documented them as `public-tested`/`covered` (the test binary keeps constraint live, and the generated doc reflected the test build). Added `deprecated` allowlist rows, dropped the stale constraint-subcommand rows, regrouped constraint with its tombstone peers in the default spine, regenerated both surface projections, and added `TestCathedralCutTombstonesSurvivePruning` pinning the invariant that every Cathedral Cut verb keeps an executable tombstone. **Installer hardening (Medium):** `install-bd.sh` now fails closed when no published checksum exists for a release asset (explicit `--no-verify` overrides), and the curl|bash path verifies the fetched `installer-common.sh` against a pinned SHA-256 before sourcing it (drift-guarded by a new install-bd.bats test). **Docs (Medium/Low):** UPGRADING.md no longer links the MIGRATION-3.0.md file the Cathedral Cut deleted; CHANGELOG 3.3.0 `### Removed` now names `yield`, `constraint`, and the 3.2 `verify` front door and links the MIGRATION.md map. **Gate scripts (Low):** flywheel/provenance gate scripts build `ao` into `mktemp -d` scratch dirs instead of fixed world-known /tmp paths (symlink/TOCTOU on shared hosts). **Bonus (surfaced by the push gate):** `scripts/lib/preamble.sh` mis-resolved REPO_ROOT under git hook env (GIT_DIR without GIT_WORK_TREE), which made `go.cli-architecture` refuse every worktree-origin push touching `cli/cmd/ao/**`. Fixed by scrubbing the hook-injected discovery env around the rev-parse. ## Validation - `go build && go vet && go test ./...`: 5,085 tests green, golangci-lint clean - `ao gate check --fast`: 27/27 pass, including under simulated hook env - bats install-bd suite 6/6 incl. new pin drift test; shellcheck clean on all touched scripts - markdownlint clean; doc-release gate passes; tombstone exit codes verified on the built binary
92 lines
4.5 KiB
Bash
Executable File
92 lines
4.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# check-provenance-chain.sh — provenance.chain local gate (age-gate-the-ungated-egwt.9).
|
|
#
|
|
# Verify the committed provenance ledger's hash chain AT THE PRE-PUSH AUTHORITY
|
|
# BOUNDARY. `ao provenance verify` already exists and is CI-gated, but CI is a
|
|
# rare backstop; the LOCAL pre-push gate (the release authority) only EMITTED
|
|
# provenance edges before this gate — it never verified the chain it was about
|
|
# to push. This moves tamper-evidence to the authority boundary: a tampered
|
|
# field, a forged hash, or a reordered row in docs/provenance/ledger.jsonl fails
|
|
# the push loudly, naming the first broken FILE LINE.
|
|
#
|
|
# WHAT IT RUNS: `ao provenance verify [--json]`. That reads
|
|
# docs/provenance/ledger.jsonl EXACTLY as it sits on disk (in place — no
|
|
# re-sort, no re-chain, unlike `provenance export --verify`) and checks each
|
|
# record's prev_hash/payload_hash/hash. Exit 0 = intact (or absent/empty
|
|
# ledger, which is an intact empty chain for a fresh clone); non-zero names the
|
|
# first bad line. This is a linear JSONL scan — under ~2s beyond the one-time
|
|
# ao-binary resolution that sibling gates already pay.
|
|
#
|
|
# EMIT-vs-VERIFY ORDERING (age-gate-the-ungated-egwt.9): the pre-push sequence's
|
|
# provenance FEEDER — scripts/post-land-provenance-emit.sh — runs AFTER a
|
|
# successful push, from a DISPOSABLE worktree off origin/main, and pushes its
|
|
# ledger growth as its OWN separate `#trivial` commit. It NEVER appends to the
|
|
# pushing checkout's working tree during the gate run. Therefore:
|
|
# * THIS check reads the ledger as `ao provenance verify` resolves it (the
|
|
# repo-root working tree = the committed HEAD state a clean push carries),
|
|
# so it verifies the exact bytes being pushed.
|
|
# * A fresh emit-append CANNOT make this check fail spuriously: the emitter's
|
|
# re-emit-on-race path (see post-land-provenance-emit.sh header) re-chains
|
|
# onto the CURRENT trunk tail in its own worktree and pushes a subsequent
|
|
# commit; that commit's OWN push runs this gate again on ITS committed
|
|
# ledger. No append lands in the pushing tree between change-detection and
|
|
# this check within a single push.
|
|
# We deliberately do NOT diff HEAD's ledger against the worktree copy: the gate
|
|
# convention (mirrored from scripts/check-provenance-orphans.sh) is to consume
|
|
# `ao provenance verify` in place; `ao` reads the repo-root ledger, which for a
|
|
# clean push IS HEAD's ledger. A left-over uncommitted append would already be
|
|
# rejected by the commit-scope/pawl gates before reaching a push.
|
|
#
|
|
# REPAIR: a break is NEVER a hand-edit. Find the first bad entry with
|
|
# `ao provenance verify`; the fix is a deliberate re-seal (a coordinator
|
|
# decision), never an in-place patch of the ledger bytes.
|
|
#
|
|
# Bounded-context: BC4-Factory. Evidence: pre-push gate + .github/workflows/validate.yml.
|
|
#
|
|
# Exit 0 = healthy chain (or absent/empty). Exit 1 = broken chain (line named).
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
ROOT="${REPO_ROOT:-$(cd "$SCRIPT_DIR/.." && pwd)}"
|
|
|
|
# Resolve the ao binary the way sibling gate scripts do (mirror
|
|
# check-provenance-orphans.sh / check-flywheel-compounding.sh): prefer an
|
|
# explicit AO_BIN, then the pre-built CI binary, else build a scratch binary so
|
|
# the gate works on a fresh checkout. No `-tags` are needed — `ao provenance`
|
|
# is a spine command that builds with plain `go build ./cmd/ao`.
|
|
AO="${AO_BIN:-}"
|
|
if [[ -z "$AO" ]]; then
|
|
if [[ -x "$ROOT/cli/bin/ao" ]]; then
|
|
AO="$ROOT/cli/bin/ao"
|
|
elif command -v ao >/dev/null 2>&1; then
|
|
AO="ao"
|
|
else
|
|
scratch="$(mktemp -d "${TMPDIR:-/tmp}/ao-provenance-chain-check.XXXXXX")"
|
|
trap 'rm -rf "$scratch"' EXIT
|
|
AO="$scratch/ao"
|
|
(cd "$ROOT/cli" && go build -o "$AO" ./cmd/ao) >/dev/null 2>&1 \
|
|
|| { echo "PROVENANCE_CHAIN_GATE: FAIL — could not build ao for the chain gate" >&2; exit 1; }
|
|
fi
|
|
fi
|
|
|
|
echo "=== provenance.chain gate (ao provenance verify) ==="
|
|
|
|
# Run from the repo root so `ao` resolves the committed ledger via its
|
|
# repo-root discovery (resolveLedgerPath walks up to docs+schemas / .git).
|
|
set +e
|
|
out="$(cd "$ROOT" && "$AO" provenance verify 2>&1)"
|
|
rc=$?
|
|
set -e
|
|
|
|
echo "$out"
|
|
|
|
if [[ $rc -ne 0 ]]; then
|
|
echo "PROVENANCE_CHAIN_GATE: FAIL — docs/provenance/ledger.jsonl hash chain is broken." >&2
|
|
echo " Find the first bad entry with 'ao provenance verify'." >&2
|
|
echo " Repair is a DELIBERATE re-seal (coordinator decision) — never hand-edit the ledger." >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "PROVENANCE_CHAIN_GATE: OK (committed ledger chain intact)"
|