docs(ci): reconcile push-as-CI gate reality (age-push-equals-ci-0ua.4)

This commit is contained in:
Test
2026-06-19 10:24:08 -04:00
committed by Boden Fuller
parent d4dbf05fe2
commit 7af3e9a381
7 changed files with 84 additions and 48 deletions
+6 -4
View File
@@ -4,10 +4,12 @@
#
# Pre-push hook: delegates to bd for issue tracking.
#
# The previous shared push-gate invocation (scripts/pre-push-gate.sh) was
# retired by soc-g2r9. CI (.github/workflows/validate.yml + claude-code-review)
# is the sole authoritative push gate. See:
# docs/contracts/local-pre-push-gate-retirement.md
# Historical bd shim. This tracked .githooks directory is not the live AgentOps
# cockpit gate on current installs; core.hooksPath points at .git/hooks, where
# scripts/install-pre-push-gate.sh chains scripts/hooks/pre-push.local.
# The old CI-only gate decision in local-pre-push-gate-retirement.md is
# superseded. Current direct-main release authority is local pre-push + ao gate
# + full randomized race + pawl check; GitHub Actions are tag/PR/manual backstop.
set -euo pipefail
+31 -9
View File
@@ -1,12 +1,29 @@
# CI/CD Architecture
CI ensures code quality, security, and release integrity for the AgentOps repository. Every push and PR runs the validation pipeline. Release tag pushes run a full, non-path-filtered Validate verdict for the exact tagged SHA. Releases are automated through GoReleaser with SBOM generation and SLSA provenance attestation.
AgentOps uses a local push-as-CI gate for routine direct-main work. The release authority for a normal `main` push is the installed local cockpit gate: `.git/hooks/pre-push` chains to `scripts/hooks/pre-push.local`, builds a fresh `ao`, runs `ao gate check --fast`, runs the full `go test ./... -race -shuffle=on -count=1` suite for pushes to `main`, and then checks the head-bound pawl verdict. GitHub Actions remain useful telemetry and a tag/PR/manual backstop; they are not the routine release gate for direct-main pushes.
Release tag pushes run a full, non-path-filtered Validate verdict for the exact tagged SHA. Releases are automated through GoReleaser with SBOM generation and SLSA provenance attestation.
## Live Main-Push Path
```text
git push origin HEAD:main
-> .git/hooks/pre-push
-> scripts/hooks/pre-push.local
-> go build ./...
-> ao gate check --fast
-> go test ./... -race -shuffle=on -count=1
-> scripts/check-pawl-pre-push.sh
-> remote main fast-forward
```
The tracked `.githooks/` directory is legacy `bd` hook plumbing. It is inert for the current AgentOps cockpit gate: Git uses `.git/hooks` unless `core.hooksPath` says otherwise, and `scripts/install-pre-push-gate.sh` installs/chains the live gate in the shared `.git/hooks` directory.
## Workflow Map
| Workflow | File | Trigger | Purpose |
|----------|------|---------|---------|
| Validate | `validate.yml` | Push to `main`, `v*` tag push, PRs to `main` | Primary quality gate; tag pushes force every path-filtered release lane on and allowlist PR-only evidence jobs |
| Validate | `validate.yml` | Push to `main`, `v*` tag push, PRs to `main` | Backstop telemetry for routine `main`; authoritative blocking gate for release tags, PRs, and manual validation; tag pushes force every path-filtered release lane on and allowlist PR-only evidence jobs |
| Release Publisher | `release.yml` | Tag push (`v*`), manual dispatch | Build, publish, attest releases |
| Nightly | `nightly.yml` | Daily 6am UTC, manual | Public proof harness: full test suite + retrieval + security + compile cycle + Dream report-shape validation over repo-visible artifacts |
| Nightly RPI Brief | `nightly-rpi-brief.yml` | Daily 11:30am UTC, manual | Builds a two-week Nightly evidence digest and updates the `$agentops:rpi --auto` prompt packet issue |
@@ -223,17 +240,22 @@ One CI check is intentionally **not** wired into the local gate:
## Hookless by default - local gate is the release authority
AgentOps 3.0 ships **zero hooks**. The hooks were deleted, not demoted. What a
pre-commit, pre-push, or session hook used to enforce implicitly is now enforced
by explicit local commands, primarily `scripts/pre-push-gate.sh` and
`ao gate check`. GitHub Actions remain available as manual or release-tag
backstops, but they are not the routine release authority.
AgentOps 3.0 ships **zero runtime hooks by default**. Repository contributors can
opt into the local cockpit gate by running `scripts/install-pre-push-gate.sh`,
which installs the current gate into the shared `.git/hooks` directory for the
main checkout and linked worktrees. What a session hook used to enforce
implicitly is now enforced by explicit local commands and this installed
pre-push chain, primarily `ao gate check --fast`, the push-to-main full race
suite, and the pawl pre-push check. GitHub Actions remain available as manual,
PR, and release-tag backstops, but they are not the routine release authority.
The workflow is guided by skills plus the `ao` CLI; context flows through explicit
channels (`ao inject` / context packets through ports), not hook side effects.
If you want a bounded gate of your own (block a dangerous operation, bootstrap a
session, run a parity check), author it with the `hooks-authoring` skill.
AgentOps does not ship one.
session, run a parity check), author it with the `hooks-authoring` skill. Do not
infer live gate behavior from tracked `.githooks/`; use `git config --get
core.hooksPath` and `scripts/install-pre-push-gate.sh` to inspect or refresh the
actual hook chain.
## Security Gate
+1 -1
View File
@@ -8,7 +8,7 @@ This guide lists what was removed in 3.0 and what to use instead.
`ao hooks install`, `--with-hooks`, and the embedded hook surface are gone. AgentOps no longer installs or runs hooks.
**Use instead:** skills + the `ao` CLI guide the workflow; **CI is the authoritative gate** (`.github/workflows/validate.yml`). What a PreToolUse/PostToolUse hook used to enforce locally, a CI job now enforces on push. For the in-session knowledge loop, the skills (`/rpi`, `/evolve`, `/post-mortem`) call the `ao` commands directly instead of relying on hook side effects.
**Use instead:** skills + the `ao` CLI guide the workflow; the **installed local cockpit pre-push gate is routine release authority** (`scripts/install-pre-push-gate.sh` -> `.git/hooks/pre-push` -> `scripts/hooks/pre-push.local`), while `.github/workflows/validate.yml` remains tag/PR/manual backstop telemetry. What a PreToolUse/PostToolUse hook used to enforce locally is now enforced by the explicit local gate before main pushes. For the in-session knowledge loop, the skills (`/rpi`, `/evolve`, `/post-mortem`) call the `ao` commands directly instead of relying on hook side effects.
## Removed: the daemon (`ao daemon` / `agentopsd`)
+6 -5
View File
@@ -143,9 +143,9 @@ They will. Anthropic's Managed Agents is the first move; others will follow. Tha
┌──────────────────────────────────────────────────────────────────┐
│ AgentOps at a Glance │
├───────────────────┬──────────────────────┬───────────────────────┤
│ 75 shared skills │ `ao` Control Plane │ CI-gated (hookless) │
│ plus runtime │ repo-native retrieval│ validate.yml is the │
│ artifacts │ goals, and automation│ authoritative gate │
│ 75 shared skills │ `ao` Control Plane │ local pre-push gate │
│ plus runtime │ repo-native retrieval│ + CI backstop │
│ artifacts │ goals, and automation│ routine release path │
└───────────────────┴──────────────────────┴───────────────────────┘
```
@@ -194,7 +194,8 @@ GOALS.md
### Lifecycle — Hookless Enforcement
AgentOps 3.0 is hookless: nothing auto-fires at session boundaries. The lifecycle
runs through explicit skills and `ao` commands, with CI as the authoritative gate.
runs through explicit skills and `ao` commands, with the installed local cockpit
pre-push gate as routine authority and CI as tag/PR/manual backstop telemetry.
(An opt-in `hooks-authoring` skill exists if you want to add your own hooks;
AgentOps ships none by default.)
@@ -207,7 +208,7 @@ Session ends /post-mortem + ao forge Harvest learnings
Loop closure ao flywheel + /retro Close the learning loop
Plan review /pre-mortem Require review before risky work
Code review /vibe + ao ratchet Block over-complex / unready edits
PR validation validate.yml (CI) Execute compiled validation gates
Backstop validation validate.yml (CI) Re-run compiled validation gates
```
### CLI Command Groups
+1 -1
View File
@@ -2,7 +2,7 @@
> Which `ao` commands are called by which skills — and vice versa.
Auto-audited 2026-04-24; targeted runtime-proof update 2026-04-28. 90 generated CLI command headings, 69 source skills. (AgentOps 3.0 is hookless — there is no runtime hook surface; lifecycle work is driven by skills + the `ao` CLI, with CI as the authoritative gate.)
Auto-audited 2026-04-24; targeted runtime-proof update 2026-04-28. 90 generated CLI command headings, 69 source skills. (AgentOps 3.0 is hookless — there is no runtime hook surface; lifecycle work is driven by skills + the `ao` CLI, with the installed local cockpit pre-push gate as routine authority and CI as tag/PR/manual backstop telemetry.)
Registry-first note: `/plan`, `/pre-mortem`, `/research`, `/vibe`, and `/post-mortem` now also read or write `.agents/findings/registry.jsonl` directly via skill contract. Those file-native prevention reads are intentionally not counted as `ao` command invocations in the tables below.
+20 -15
View File
@@ -17,16 +17,19 @@ hooks:
2. **The `ao` CLI** — the deterministic tool surface (`ao session bootstrap`,
`ao inject`, `ao corpus inject --query`, `ao validate`, `ao goals measure`),
reachable in two ways: shell (Codex/NTM) or **MCP** (`ao mcp serve`, hosted/SDK).
3. **CI as the authoritative gate** — `.github/workflows/validate.yml` runs the
standards/scenario/holdout checks as CI jobs, **not** as PreToolUse hooks.
3. **Local cockpit gate as routine authority** — the installed `.git/hooks/pre-push`
path runs `scripts/hooks/pre-push.local`; `.github/workflows/validate.yml` runs
standards/scenario/holdout checks as tag/PR/manual backstop telemetry, **not**
as PreToolUse hooks.
A runtime-specific Agent definition is emitted by `ao agent bundle` (`--managed`
| `--codex-ntm`) and graded by the **same** CI gate as interactive work
(`.github/workflows/agent-output-validate.yml`).
| `--codex-ntm`) and can be graded by the agent-output backstop workflow
(`.github/workflows/agent-output-validate.yml`) when run through PR/tag/manual
validation.
## 1. Hook-intent → hookless equivalent (zero hooks required)
| Old hook *intent* | Claude (Managed Agent / SDK / MCP-`ao`) | Codex / NTM (shell-`ao` / tmux / ssh bushido) | CI gate (authoritative) |
| Old hook *intent* | Claude (Managed Agent / SDK / MCP-`ao`) | Codex / NTM (shell-`ao` / tmux / ssh bushido) | Local gate / CI backstop |
|---|---|---|---|
| **Orientation** (SessionStart) | `ao session bootstrap` + `session-bootstrap` skill in instructions | `ssh bushido 'cd repo && ao session bootstrap'` | n/a (read-path) |
| **Standards injection** (Edit) | `standards` skill loaded into instructions; `ao validate` | same skill text via `ao agent bundle --codex-ntm` | `validate.yml` standards/scenario jobs |
@@ -34,9 +37,10 @@ A runtime-specific Agent definition is emitted by `ao agent bundle` (`--managed`
| **Commit / output review** (commit-review) | the PR + `agent-output-validate.yml` | same (Codex output bundled, then validated) | `claude-review` + `agent-output-validate.yml` |
| **Holdout isolation** (holdout-isolation-gate) | rubric projection strips ground truth *by construction*; payloads never carry holdout | same — the Outcomes/local score is the only thing that crosses | `Outcomes holdout-leak gate` (`check-outcomes-holdout-leak.sh`, deny-by-default) |
**Conclusion: zero hooks are required.** Every old-hook intent maps onto a skill,
an `ao` subcommand, and a CI job. The CI gate is the enforcement boundary; the
skill/`ao` layer is advisory-by-design (an agent that ignores them simply fails CI).
**Conclusion: zero runtime hooks are required.** Every old-hook intent maps onto a
skill, an `ao` subcommand, the local cockpit pre-push gate, and a CI backstop. The
installed local gate is the routine enforcement boundary; CI replays the contract
for tag/PR/manual validation.
## 2. Managed Agents Agent definition + self-hosted sandbox
@@ -73,12 +77,13 @@ surfaces. AgentOps treats these strictly as an **optional adapter** — the wiri
lives in [`skills/agent-native/references/sdk-hook-adapter.md`](https://github.com/boshu2/agentops/blob/main/skills/agent-native/references/sdk-hook-adapter.md),
never as the primary guardrail.
**Why CI is the default gate, not these hooks:** a hook runs *inside* the agent's
own process — the same actor it is meant to police — so it is advisory and
bypassable, and it drifts per-runtime (Claude SDK ≠ Codex ≠ Managed Agent). CI
runs *after* the agent, on a neutral host, against the PR — one gate, every
runtime, non-bypassable. The SDK hook adapter is a convenience (fail fast in the
loop); the CI gate is the contract.
**Why the local cockpit gate is the default enforcement boundary, not these
hooks:** a hook runs *inside* the agent's own process — the same actor it is
meant to police — so it is advisory and bypassable, and it drifts per-runtime
(Claude SDK ≠ Codex ≠ Managed Agent). The installed local cockpit gate binds
routine main pushes before they leave the workstation; CI replays the contract
for tag/PR/manual validation. The SDK hook adapter is a convenience (fail fast in
the loop), not the release authority.
## 4. Non-goals (explicit)
@@ -94,7 +99,7 @@ loop); the CI gate is the contract.
- [`/agent-native` skill](https://github.com/boshu2/agentops/blob/main/skills/agent-native/SKILL.md) — the how-to (this doc is the why/mechanism).
- `cli/cmd/ao/agent.go` (`ao agent bundle`), `cli/cmd/ao/mcp_serve.go` (`ao mcp serve`).
- `.github/workflows/agent-output-validate.yml` — the authoritative output gate.
- `.github/workflows/agent-output-validate.yml` — backstop output validation.
- Fleet topology (bushido sandbox, tailnet `100.109.17.108`, Dolt 3306): operator hub.
- Open follow-ons: the managed-dispatch CLI (`ao managed dispatch`) and the
self-hosted bushido Managed-Agents sandbox registration are the code/ops slices
@@ -1,9 +1,11 @@
# Historical ADR: Local Pre-Push Gate Retirement
# Superseded Historical ADR: Local Pre-Push Gate Retirement
> Superseded on 2026-06-08 by `ag-3l86`: GitHub Actions became a quota SPOF,
> so AgentOps returned release authority to the local cockpit gate and direct
> pushes to `main`. Keep this document as historical context for the older
> CI-only experiment, not as current workflow doctrine.
> CI-only experiment, not as current workflow doctrine. If this file disagrees
> with `scripts/hooks/pre-push.local`, `scripts/install-pre-push-gate.sh`, or
> `docs/CI-CD.md`, those current-path surfaces win.
`scripts/pre-push-gate.sh` is the local mirror of `.github/workflows/validate.yml`.
The mirror has drifted three times in observable ways during the 2026-05-19
@@ -18,13 +20,13 @@ GitHub Actions workflows under `.github/workflows/`. Current doctrine reverses
that: the local cockpit gate is the release authority for normal direct-main
work.
Authoritative gate:
Historical authoritative gate in this superseded decision:
- `.github/workflows/validate.yml`
- `.github/workflows/release.yml`
- the `claude-code-review` required check
Non-authoritative (retiring):
Historical non-authoritative surfaces in this superseded decision:
- `scripts/pre-push-gate.sh`
- the ~12 helper scripts under `scripts/check-*.sh` invoked only by the gate
@@ -32,8 +34,9 @@ Non-authoritative (retiring):
isolation (the bats that test the gate itself stay until the gate is
deleted)
`.githooks/pre-push` keeps its `bd hooks run pre-push` invocation; that piece
is `bd` issue-tracker plumbing, not a gate.
`.githooks/pre-push` kept its `bd hooks run pre-push` invocation; that piece was
tracker plumbing, not the AgentOps cockpit gate. Current installs use
`.git/hooks/pre-push` chaining `scripts/hooks/pre-push.local`.
## Why this rather than the alternatives
@@ -51,10 +54,13 @@ loop per push instead of a 10-20s local one. The session of 2026-05-19 spent
several multi-minute self-correction PR cycles per local-gate-was-wrong event,
so the per-push cost is dominated by the per-incident cost we just removed.
## What replaces local enforcement
## What replaced the superseded decision
Nothing immediate. The retirement is the point. Specific past concerns and
how they map onto the new shape:
The older CI-only experiment was reversed. Current normal `main` pushes are
gated locally by `.git/hooks/pre-push -> scripts/hooks/pre-push.local -> ao gate
check --fast -> go test ./... -race -shuffle=on -count=1 -> pawl pre-push`.
GitHub Actions are tag/PR/manual backstop telemetry. Specific past concerns and
how they map onto the old shape:
- **Speed of feedback.** CI takes 30-90s on the fast path. Operators who
want a local sanity check can run `cd cli && make test` or `bats
@@ -81,10 +87,10 @@ This PR locks in the decision without the deletion churn:
tracking continues to work.
- Files four follow-up beads for the actual removal waves.
After this PR lands, `git push` will no longer run the local gate. CI is the
sole gate. The orphaned files stay on disk until the follow-up waves delete
them, which keeps each follow-up PR a single coherent arc with a single
rollback semantic.
After the historical PR landed, `git push` no longer ran the local gate and CI
was treated as the sole gate. That is no longer true. The current local gate is
installed by `scripts/install-pre-push-gate.sh` and sourced from
`scripts/hooks/pre-push.local`.
## Follow-up work