From e470434a12df104147632262dd3320d588b3328a Mon Sep 17 00:00:00 2001 From: Enrico Piovesan Date: Tue, 7 Jul 2026 18:08:58 -0600 Subject: [PATCH] Governance v1.1.0: agent token-discipline rules and hygiene warnings - ai-agent-hardening.md: single canonical agent doc, no versions in prose, no state snapshots, .claudeignore required, lazy-read map, PR-body superset, lean ladder and claim-before-code org-wide - baseline gate warns (non-blocking) on violations; blocking in next major - rollout adds starter .claudeignore; self-compliance for this repo --- .claudeignore | 4 ++ .github/workflows/reusable-governance.yml | 26 ++++++++++ .governance-version | 2 +- CHANGELOG.md | 7 +++ docs/ai-agent-hardening.md | 59 ++++++++++++++++++++--- scripts/org/rollout_governance.sh | 17 +++++++ 6 files changed, 108 insertions(+), 7 deletions(-) create mode 100644 .claudeignore diff --git a/.claudeignore b/.claudeignore new file mode 100644 index 0000000..a9a68aa --- /dev/null +++ b/.claudeignore @@ -0,0 +1,4 @@ +# OS/IDE noise +.DS_Store +.idea/ +.vscode/ diff --git a/.github/workflows/reusable-governance.yml b/.github/workflows/reusable-governance.yml index b953156..359e13d 100644 --- a/.github/workflows/reusable-governance.yml +++ b/.github/workflows/reusable-governance.yml @@ -46,6 +46,32 @@ jobs: *) echo "::error::.governance-version must contain a release tag like v1.0.0"; exit 1 ;; esac + # Token-discipline conventions from docs/ai-agent-hardening.md. + # Warnings only in governance 1.x; blocking in the next major release. + - name: Agent-doc hygiene (warnings only) + run: | + ver="$(cat .governance-version)" + if [ ! -e ".claudeignore" ]; then + echo "::warning::no .claudeignore — agents index build artifacts and vendor trees, wasting tokens (docs/ai-agent-hardening.md)" + fi + for f in CLAUDE.md AGENTS.md; do + [ -e "$f" ] || continue + stale="$(grep -oiE 'governance version v?[0-9]+\.[0-9]+(\.[0-9]+)?' "$f" | head -1 || true)" + if [ -n "$stale" ] && ! echo "$stale" | grep -q "${ver#v}"; then + echo "::warning file=$f::hardcoded '$stale' but .governance-version is $ver — never write version numbers in prose, point at .governance-version" + fi + done + if [ -e CLAUDE.md ] && [ -e AGENTS.md ]; then + c=$(wc -c < CLAUDE.md); a=$(wc -c < AGENTS.md) + if [ "$c" -gt 2000 ] && [ "$a" -gt 2000 ]; then + echo "::warning::CLAUDE.md (${c}B) and AGENTS.md (${a}B) are both substantial — one must be canonical, the other a pointer plus tool-specific coordination only (docs/ai-agent-hardening.md)" + fi + fi + if [ -e CLAUDE.md ] && [ "$(wc -c < CLAUDE.md)" -gt 8192 ]; then + echo "::warning file=CLAUDE.md::over 8KB — this file is loaded into every agent session; keep it under ~6KB (docs/ai-agent-hardening.md)" + fi + exit 0 + # The spec-alignment script needs PR context (body file, base/head SHAs) # and runs inside each repo's own CI per docs/quality-standards.md, so # here we only verify it is wired in — running it again would duplicate diff --git a/.governance-version b/.governance-version index 0ec25f7..795460f 100644 --- a/.governance-version +++ b/.governance-version @@ -1 +1 @@ -v1.0.0 +v1.1.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c9ff3d..b84ee88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to the org-wide governance in this repository are documented The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versions follow [Semantic Versioning](https://semver.org/): a **major** bump means a rule change that can newly block merges in consuming repos; **minor** adds rules or tooling that are backwards-compatible; **patch** is clarification only. +## [1.1.0] - 2026-07-07 + +### Added + +- Token-discipline rules in `docs/ai-agent-hardening.md`: single canonical agent doc (CLAUDE.md canonical, AGENTS.md = pointer + tool-coordination only), no version numbers in prose (point at `.governance-version`), no state snapshots in docs (live queries instead), `.claudeignore` required, lazy doc-reading map, PR-body section superset, bounded `gh` queries, org-wide lean-implementation ladder and claim-before-you-code rule +- Baseline gate emits **warnings** (non-blocking) for: missing `.claudeignore`, hardcoded governance versions that drift from `.governance-version`, substantial CLAUDE.md+AGENTS.md duplication, CLAUDE.md over 8KB. These become blocking checks in the next **major** release. + ## [1.0.2] - 2026-07-07 ### Fixed diff --git a/docs/ai-agent-hardening.md b/docs/ai-agent-hardening.md index ad1c28a..7d4facd 100644 --- a/docs/ai-agent-hardening.md +++ b/docs/ai-agent-hardening.md @@ -1,13 +1,55 @@ # AI-Agent Hardening Rules -These are the conventions every `traverse-framework` repo's `CLAUDE.md`/`AGENTS.md` should encode, so an AI coding agent working in any repo here behaves consistently regardless of which repo it's in. +Conventions every `traverse-framework` repo encodes so AI coding agents behave consistently — and cheaply — in any repo here. The baseline governance gate warns on violations of the token-discipline rules; they become blocking in the next major governance release. -## Required in every repo's CLAUDE.md / AGENTS.md +## Required in every repo -- A pointer to this governance repo and the pinned version it has adopted (see `constitution.md`'s Governance section on deliberate version adoption) -- The repo's own product scope (what's in/out for its current milestone) — this is repo-specific and does not belong in the shared constitution -- The repo's own build/test/run commands -- The repo's own directory structure +- `CLAUDE.md` — the **single canonical agent document** (see structure below) +- `AGENTS.md` — a pointer to `CLAUDE.md`, plus *only* content that is genuinely tool-coordination-specific (e.g. the multi-agent claim protocol). Never a second copy of structure/commands/style. +- `.claudeignore` — excludes build artifacts, lockfiles, coverage output, and vendor/generated trees from agent indexing +- `.governance-version` — the **only** place the adopted governance version is written + +## Canonical CLAUDE.md structure + +Keep it under ~6 KB. It is loaded into every agent session — every byte here is paid on every task. + +1. Pointer to this governance repo (never restate its rules, never write its version number — say "see `.governance-version`") +2. The repo's product scope (what's in/out for the current milestone) +3. Build/test/run commands +4. Directory structure (top level only) +5. Repo-specific rules that exist nowhere else + +## Single Source of Truth (token discipline) + +- **Never duplicate between CLAUDE.md and AGENTS.md.** One canonical doc; the other points to it. Duplicates always drift, and drift means agents act on stale facts. +- **Never write version numbers in prose.** Point at `.governance-version`, `Cargo.toml`, `package.json` — the file that CI actually reads. +- **Never snapshot live state into docs.** No "approved specs" tables (that's `specs/governance/approved-specs.json`), no board-status tables (that's the Project board). Give the query instead: + ```bash + jq -r '.specs[].id' specs/governance/approved-specs.json + gh project item-list --owner traverse-framework --format json --limit 300 \ + --jq '.items[] | select(.status == "Ready") | .content.number' + ``` +- **Read docs lazily, by task.** Do not preload the whole governance corpus. Map: + + | Task touches | Read first | + |---|---| + | architecture, contracts, versioned surfaces | `constitution.md`, `docs/compatibility-policy.md` | + | merge gates, coverage, what blocks a PR | `docs/quality-standards.md` | + | a rule you want to break | `docs/exception-process.md` | + | repo processes going wrong | `docs/antipatterns.md` | + | everything else | the repo's `CLAUDE.md` and the governing spec only | + +- **PR bodies use the section superset** (`## Summary`, `## Governing Spec`, `## Project Item`, `## Definition of Done`, `## Validation`) so hygiene gates pass on the first attempt — a failed gate re-run costs a full agent round-trip. +- **Bound your queries.** Always `--limit` on `gh` list commands; prefer `--jq` server-side filtering over dumping JSON into context. + +## Lean Implementation Ladder (before adding any code) + +1. Is the change required by the active issue and governing spec? +2. Can existing code, contracts, or config already satisfy it? +3. Can a schema, test, or doc update solve it without new abstraction? +4. Add only the minimum new structure needed. + +Minimality never justifies violating a repo's architecture boundary (e.g. business logic in a UI layer). ## Code Style Rules (apply everywhere) @@ -16,6 +58,10 @@ These are the conventions every `traverse-framework` repo's `CLAUDE.md`/`AGENTS. - Deterministic: same inputs must produce the same outputs - Explicit errors over silent failure; document the failure mode +## Multi-Agent Coordination (apply everywhere) + +**Claim before you code. One issue = one agent.** Before starting work: no `agent:*` label on the issue, no existing `*/issue--*` branch, status is Ready. If claimed — stop and pick another ticket; never "help" a claimed ticket. Repos with active boards keep the claim/release command sequences in their `AGENTS.md`. + ## Governance Rules An Agent Must Follow (apply everywhere) 1. Every feature starts with a spec in that repo's `specs/` — no spec, no merge @@ -30,4 +76,5 @@ These are the conventions every `traverse-framework` repo's `CLAUDE.md`/`AGENTS. - Add a spec directly to `approved-specs.json` without explicit human review/approval - Relicense, remove, or weaken the CLA requirement - Duplicate this repo's governance content into a consuming repo instead of pointing to a pinned version +- Duplicate content between CLAUDE.md and AGENTS.md, or snapshot registry/board state into either - Bypass the spec-alignment or coverage gates to make a PR pass diff --git a/scripts/org/rollout_governance.sh b/scripts/org/rollout_governance.sh index 0ddff40..05e99a4 100755 --- a/scripts/org/rollout_governance.sh +++ b/scripts/org/rollout_governance.sh @@ -125,6 +125,23 @@ for repo in "${repos[@]}"; do } > "$dir/.github/dependabot.yml" fi + if [ ! -e "$dir/.claudeignore" ]; then + cat > "$dir/.claudeignore" <<'EOF' +# Build artifacts, lockfiles, coverage, vendor trees — never index these +target/ +node_modules/ +dist/ +build/ +coverage/ +*.lock +Cargo.lock +package-lock.json +.DS_Store +.idea/ +.vscode/ +EOF + fi + if [ ! -e "$dir/CLAUDE.md" ] && [ ! -e "$dir/AGENTS.md" ]; then cat > "$dir/CLAUDE.md" <