feat: implement ADR-0012 — AGENTS.md refactor (issue 0015)
Create AGENTS.md at repo root and core/AGENTS.md as provider-agnostic sources of always-on rules. Slim both CLAUDE.md files to thin adapters. Deploy core/AGENTS.md → ~/.agents/AGENTS.md via deploy-manifest.sh. Update three test suites to check correct locations post-refactor. All automated tests pass (57 instructions, 106 install, 25 governance). HITL behavioral test plan in test-instructions-and-docs.sh scenarios 9–12. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -63,14 +63,15 @@ contains "@.*governance\.md" "$CLAUDE_PROVIDER" \
|
||||
&& pass "@import for governance.md present in providers/claude-code/CLAUDE.md" \
|
||||
|| fail "@import for governance.md missing from providers/claude-code/CLAUDE.md"
|
||||
|
||||
# Communication and Behavior rules must be retained unchanged
|
||||
contains "[Cc]hallenge" "$CLAUDE_PROVIDER" \
|
||||
&& pass "providers CLAUDE.md: challenge-bad-ideas rule retained" \
|
||||
|| fail "providers CLAUDE.md: challenge-bad-ideas rule missing — may have been overwritten"
|
||||
# Communication and Behavior rules moved to core/AGENTS.md by issue 0015 — verify correct location
|
||||
CORE_AGENTS="$REPO_ROOT/core/AGENTS.md"
|
||||
contains "[Cc]hallenge" "$CORE_AGENTS" \
|
||||
&& pass "core/AGENTS.md: challenge-bad-ideas rule present (moved from providers CLAUDE.md, issue 0015)" \
|
||||
|| fail "core/AGENTS.md: challenge-bad-ideas rule missing — may have been lost in 0015 refactor"
|
||||
|
||||
contains "[Ii]rreversible" "$CLAUDE_PROVIDER" \
|
||||
&& pass "providers CLAUDE.md: irreversible-ops confirmation rule retained" \
|
||||
|| fail "providers CLAUDE.md: irreversible-ops confirmation rule missing"
|
||||
contains "[Ii]rreversible" "$CORE_AGENTS" \
|
||||
&& pass "core/AGENTS.md: irreversible-ops confirmation rule present (moved from providers CLAUDE.md, issue 0015)" \
|
||||
|| fail "core/AGENTS.md: irreversible-ops confirmation rule missing — may have been lost in 0015 refactor"
|
||||
|
||||
echo ""
|
||||
|
||||
@@ -150,10 +151,11 @@ contains "Resolved" "$ROADMAP" \
|
||||
&& pass "ROADMAP.md: always-on refinement open question marked resolved" \
|
||||
|| fail "ROADMAP.md: always-on refinement open question not resolved"
|
||||
|
||||
REPO_CLAUDE="$REPO_ROOT/CLAUDE.md"
|
||||
contains "[Gg]overnance" "$REPO_CLAUDE" \
|
||||
&& pass "CLAUDE.md: governance workstream referenced" \
|
||||
|| fail "CLAUDE.md: governance workstream not referenced"
|
||||
# Repo CLAUDE.md is now a thin adapter importing AGENTS.md — check AGENTS.md for governance reference
|
||||
REPO_AGENTS="$REPO_ROOT/AGENTS.md"
|
||||
contains "[Gg]overnance" "$REPO_AGENTS" \
|
||||
&& pass "AGENTS.md: governance workstream referenced (repo CLAUDE.md imports AGENTS.md)" \
|
||||
|| fail "AGENTS.md: governance workstream not referenced"
|
||||
|
||||
echo ""
|
||||
echo "Results: $PASS passed, $FAIL failed"
|
||||
|
||||
@@ -52,6 +52,14 @@ while IFS= read -r -d '' deployed; do
|
||||
fi
|
||||
done < <(find "$TEMP_HOME/.claude/core" -type f -print0)
|
||||
|
||||
echo ""
|
||||
echo "--- core/AGENTS.md → ~/.agents/AGENTS.md (0015) ---"
|
||||
if diff -q "$REPO_ROOT/core/AGENTS.md" "$TEMP_HOME/.agents/AGENTS.md" > /dev/null 2>&1; then
|
||||
pass "core/AGENTS.md deployed and matches source"
|
||||
else
|
||||
fail "~/.agents/AGENTS.md — missing or differs from source"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "--- skills deployed to ~/.agents/skills/ ---"
|
||||
while IFS= read -r -d '' src_skill; do
|
||||
@@ -168,6 +176,13 @@ else
|
||||
fail "idempotent: ~/.claude/skills symlink broken after second install"
|
||||
fi
|
||||
|
||||
# AGENTS.md still correct after second run
|
||||
if diff -q "$REPO_ROOT/core/AGENTS.md" "$TEMP_HOME/.agents/AGENTS.md" > /dev/null 2>&1; then
|
||||
pass "idempotent: ~/.agents/AGENTS.md correct after second install"
|
||||
else
|
||||
fail "idempotent: ~/.agents/AGENTS.md corrupted after second install"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Results: $PASS passed, $FAIL failed"
|
||||
[[ $FAIL -eq 0 ]]
|
||||
|
||||
@@ -25,27 +25,15 @@ CLAUDE="$REPO_ROOT/providers/claude-code/CLAUDE.md"
|
||||
&& pass "CLAUDE.md exists" \
|
||||
|| { fail "CLAUDE.md missing"; }
|
||||
|
||||
# Communication rules — check for distinctive, stable concepts
|
||||
contains "directly" "$CLAUDE" \
|
||||
&& pass "communication: answer-directly rule present" \
|
||||
|| fail "communication: answer-directly rule missing"
|
||||
# Communication + Behavior rules moved to core/AGENTS.md by issue 0015 — verified in 0015 section.
|
||||
# providers/claude-code/CLAUDE.md is now a thin adapter; these rules must NOT be inline here.
|
||||
! contains "Answer directly" "$CLAUDE" \
|
||||
&& pass "communication: rules not duplicated in CLAUDE.md (moved to core/AGENTS.md)" \
|
||||
|| fail "communication: rules still inline in CLAUDE.md — 0015 refactor incomplete"
|
||||
|
||||
contains "[Cc]hallenge" "$CLAUDE" \
|
||||
&& pass "communication: challenge-bad-ideas rule present" \
|
||||
|| fail "communication: challenge-bad-ideas rule missing"
|
||||
|
||||
contains "it depends" "$CLAUDE" \
|
||||
&& pass "communication: no-bare-it-depends rule present" \
|
||||
|| fail "communication: no-bare-it-depends rule missing"
|
||||
|
||||
contains "[Ss]often" "$CLAUDE" \
|
||||
&& pass "communication: no-softening rule present" \
|
||||
|| fail "communication: no-softening rule missing"
|
||||
|
||||
# Behavior rules
|
||||
contains "[Ii]rreversible" "$CLAUDE" \
|
||||
&& pass "behavior: irreversible-ops confirmation rule present" \
|
||||
|| fail "behavior: irreversible-ops confirmation rule missing"
|
||||
! contains "Reads, searches" "$CLAUDE" \
|
||||
&& pass "behavior: rules not duplicated in CLAUDE.md (moved to core/AGENTS.md)" \
|
||||
|| fail "behavior: rules still inline in CLAUDE.md — 0015 refactor incomplete"
|
||||
|
||||
# Content index — must reference each on-demand file
|
||||
contains "coding" "$CLAUDE" \
|
||||
@@ -190,6 +178,117 @@ done
|
||||
&& pass "docs/issues/ unchanged" \
|
||||
|| fail "docs/issues/ missing"
|
||||
|
||||
echo ""
|
||||
|
||||
# ─── 0015: AGENTS.md refactor ────────────────────────────────────────────────
|
||||
|
||||
echo "--- 0015: AGENTS.md refactor ---"
|
||||
|
||||
REPO_AGENTS="$REPO_ROOT/AGENTS.md"
|
||||
CORE_AGENTS="$REPO_ROOT/core/AGENTS.md"
|
||||
REPO_CLAUDE="$REPO_ROOT/CLAUDE.md"
|
||||
GLOBAL_CLAUDE="$REPO_ROOT/providers/claude-code/CLAUDE.md"
|
||||
MANIFEST="$REPO_ROOT/scripts/deploy-manifest.sh"
|
||||
ARCH="$REPO_ROOT/docs/spec/architecture.md"
|
||||
|
||||
# repo-level AGENTS.md
|
||||
[[ -f "$REPO_AGENTS" ]] \
|
||||
&& pass "AGENTS.md exists at repo root" \
|
||||
|| fail "AGENTS.md missing at repo root"
|
||||
|
||||
! contains "@import" "$REPO_AGENTS" \
|
||||
&& pass "AGENTS.md: no @import syntax (self-contained)" \
|
||||
|| fail "AGENTS.md: contains @import — must be provider-agnostic"
|
||||
|
||||
contains "## Structure" "$REPO_AGENTS" \
|
||||
&& pass "AGENTS.md: ## Structure section present" \
|
||||
|| fail "AGENTS.md: ## Structure section missing"
|
||||
|
||||
contains "## Key rules" "$REPO_AGENTS" \
|
||||
&& pass "AGENTS.md: ## Key rules section present" \
|
||||
|| fail "AGENTS.md: ## Key rules section missing"
|
||||
|
||||
contains "CONTEXT\.md" "$REPO_AGENTS" \
|
||||
&& pass "AGENTS.md: CONTEXT.md read instruction present" \
|
||||
|| fail "AGENTS.md: CONTEXT.md read instruction missing"
|
||||
|
||||
# repo-level CLAUDE.md is a thin adapter
|
||||
contains "@AGENTS\.md" "$REPO_CLAUDE" \
|
||||
&& pass "repo CLAUDE.md: imports @AGENTS.md" \
|
||||
|| fail "repo CLAUDE.md: @AGENTS.md import missing"
|
||||
|
||||
contains "@CONTEXT\.md" "$REPO_CLAUDE" \
|
||||
&& pass "repo CLAUDE.md: auto-loads @CONTEXT.md" \
|
||||
|| fail "repo CLAUDE.md: @CONTEXT.md auto-load missing"
|
||||
|
||||
! contains "## Key rules" "$REPO_CLAUDE" \
|
||||
&& pass "repo CLAUDE.md: ## Key rules not duplicated (moved to AGENTS.md)" \
|
||||
|| fail "repo CLAUDE.md: ## Key rules still present — content not migrated"
|
||||
|
||||
! contains "## Structure" "$REPO_CLAUDE" \
|
||||
&& pass "repo CLAUDE.md: ## Structure not duplicated (moved to AGENTS.md)" \
|
||||
|| fail "repo CLAUDE.md: ## Structure still present — content not migrated"
|
||||
|
||||
# core/AGENTS.md
|
||||
[[ -f "$CORE_AGENTS" ]] \
|
||||
&& pass "core/AGENTS.md exists" \
|
||||
|| fail "core/AGENTS.md missing"
|
||||
|
||||
! contains "@import" "$CORE_AGENTS" \
|
||||
&& pass "core/AGENTS.md: no @import syntax (self-contained)" \
|
||||
|| fail "core/AGENTS.md: contains @import — must be provider-agnostic"
|
||||
|
||||
contains "## Communication" "$CORE_AGENTS" \
|
||||
&& pass "core/AGENTS.md: ## Communication section present" \
|
||||
|| fail "core/AGENTS.md: ## Communication section missing"
|
||||
|
||||
contains "## Behavior" "$CORE_AGENTS" \
|
||||
&& pass "core/AGENTS.md: ## Behavior section present" \
|
||||
|| fail "core/AGENTS.md: ## Behavior section missing"
|
||||
|
||||
contains "[Cc]hallenge" "$CORE_AGENTS" \
|
||||
&& pass "core/AGENTS.md: challenge-bad-ideas rule present" \
|
||||
|| fail "core/AGENTS.md: challenge-bad-ideas rule missing"
|
||||
|
||||
contains "it depends" "$CORE_AGENTS" \
|
||||
&& pass "core/AGENTS.md: no-bare-it-depends rule present" \
|
||||
|| fail "core/AGENTS.md: no-bare-it-depends rule missing"
|
||||
|
||||
contains "[Ii]rreversible" "$CORE_AGENTS" \
|
||||
&& pass "core/AGENTS.md: irreversible-ops confirmation rule present" \
|
||||
|| fail "core/AGENTS.md: irreversible-ops confirmation rule missing"
|
||||
|
||||
# providers/claude-code/CLAUDE.md is a thin adapter
|
||||
contains "@~/\.agents/AGENTS\.md" "$GLOBAL_CLAUDE" \
|
||||
&& pass "global CLAUDE.md: imports @~/.agents/AGENTS.md" \
|
||||
|| fail "global CLAUDE.md: @~/.agents/AGENTS.md import missing"
|
||||
|
||||
contains "governance\.md" "$GLOBAL_CLAUDE" \
|
||||
&& pass "global CLAUDE.md: governance.md @import present" \
|
||||
|| fail "global CLAUDE.md: governance.md @import missing"
|
||||
|
||||
! contains "Answer directly" "$GLOBAL_CLAUDE" \
|
||||
&& pass "global CLAUDE.md: Communication rules not duplicated (moved to core/AGENTS.md)" \
|
||||
|| fail "global CLAUDE.md: Communication rules still inline — content not migrated"
|
||||
|
||||
! contains "Reads, searches" "$GLOBAL_CLAUDE" \
|
||||
&& pass "global CLAUDE.md: Behavior rules not duplicated (moved to core/AGENTS.md)" \
|
||||
|| fail "global CLAUDE.md: Behavior rules still inline — content not migrated"
|
||||
|
||||
# deploy-manifest.sh
|
||||
contains "core/AGENTS\.md:\.agents/AGENTS\.md" "$MANIFEST" \
|
||||
&& pass "deploy-manifest.sh: core/AGENTS.md → .agents/AGENTS.md entry present" \
|
||||
|| fail "deploy-manifest.sh: core/AGENTS.md → .agents/AGENTS.md entry missing"
|
||||
|
||||
# docs/spec/architecture.md
|
||||
contains "core/AGENTS\.md" "$ARCH" \
|
||||
&& pass "architecture.md: core/AGENTS.md entry present" \
|
||||
|| fail "architecture.md: core/AGENTS.md entry missing"
|
||||
|
||||
contains "~/\.agents/AGENTS\.md" "$ARCH" \
|
||||
&& pass "architecture.md: ~/.agents/AGENTS.md deployment path present" \
|
||||
|| fail "architecture.md: ~/.agents/AGENTS.md deployment path missing"
|
||||
|
||||
echo ""
|
||||
echo "Results: $PASS passed, $FAIL failed"
|
||||
echo ""
|
||||
@@ -243,4 +342,17 @@ echo " 8. Ask agent to write a test requiring a mocked database."
|
||||
echo " Expect: agent pushes back and proposes an integration test."
|
||||
echo " PASS (2026-05-17)"
|
||||
echo ""
|
||||
echo "0015 — AGENTS.md refactor (run after install.sh; rules now sourced from ~/.agents/AGENTS.md)"
|
||||
echo " 9. Ask an exploratory design question."
|
||||
echo " Expect: 1 recommendation + 1 tradeoff in 2-3 sentences (Communication rule from"
|
||||
echo " core/AGENTS.md still applies via @~/.agents/AGENTS.md in ~/.claude/CLAUDE.md)."
|
||||
echo " 10. Ask agent to edit a file."
|
||||
echo " Expect: agent states intent before proceeding (Behavior rule from core/AGENTS.md)."
|
||||
echo " 11. Ask agent to push a commit."
|
||||
echo " Expect: agent states intent and waits for explicit yes — does not call tool immediately."
|
||||
echo " 12. Verify no rule was lost: open ~/.agents/AGENTS.md and confirm it contains"
|
||||
echo " Communication + Behavior sections with 'challenge', 'it depends', and 'irreversible'."
|
||||
echo " Open ~/.claude/CLAUDE.md and confirm it contains only @~/.agents/AGENTS.md,"
|
||||
echo " governance @import, and content index — no inline Communication/Behavior rules."
|
||||
echo ""
|
||||
[[ $FAIL -eq 0 ]]
|
||||
|
||||
Reference in New Issue
Block a user