Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude/skills/release/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

Any *other* file conflicting is not expected and needs real investigation (usually: `origin/main` moved between when this branch's base was chosen and now, surfacing content `beta/main` hasn't seen — resolve by taking the newer, `origin/main`-based side, since that's always the more current code). Commit the resolution as `git commit -m "merge: reconcile beta/main history for v<beta-version> release"`.
6. **Run tests locally** — ALL of these must pass before proceeding:
- **If this branch/worktree has no `.venv` yet** (e.g. it was cut fresh via `git worktree add ... origin/main`, per the Worktree Conventions in `CLAUDE.md`), create one before running anything: check `.python-version` for the pinned interpreter (use `pyenv exec` if the system `python3` is older — mismatched versions surface as unrelated-looking `TypeError`s on `X | None` syntax deep in imports, not as a version error), then `python3 -m venv .venv && .venv/bin/pip install -r requirements-dev.txt -r backend/requirements.txt`. `.venv` is gitignored, so it never comes along with the worktree/branch even though other worktrees in the repo each have their own.
- **If this branch/worktree has no `.venv` yet** (e.g. it was cut fresh via `git worktree add ... origin/main`, per the Worktree Conventions in `docs/agents/local-agent-environment.md`), create one before running anything: check `.python-version` for the pinned interpreter (use `pyenv exec` if the system `python3` is older — mismatched versions surface as unrelated-looking `TypeError`s on `X | None` syntax deep in imports, not as a version error), then `python3 -m venv .venv && .venv/bin/pip install -r requirements-dev.txt -r backend/requirements.txt`. `.venv` is gitignored, so it never comes along with the worktree/branch even though other worktrees in the repo each have their own.
- `pytest -m "not slow"` (includes scenario discovery regression tests)
- `pytest core/bess/tests/unit/test_scenario_discovery.py -v` (show individual scenario results)
- `npx vitest run` (frontend tests)
Expand Down
9 changes: 5 additions & 4 deletions .claude/skills/sweep-prs/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ when any of these hold:
| Detached or locked | Almost always another agent's live session. |

Read ownership with `claude agents --json` run **unscoped** (from `~`) —
per `CLAUDE.md`'s Worktree Conventions, sibling worktrees never appear in
the project-scoped view, and missing one is exactly the collision this gate
exists to prevent.
per `docs/agents/local-agent-environment.md`'s Worktree Conventions, sibling
worktrees never appear in the project-scoped view, and missing one is exactly
the collision this gate exists to prevent.

### 2. Classify

Expand Down Expand Up @@ -159,7 +159,8 @@ nothing is indistinguishable from a broken one.
## Hard constraints

- Never push without `./scripts/quality-check.sh` green.
- Never `git stash` — denied repo-wide, one shared stack (`CLAUDE.md`).
- Never `git stash` — denied repo-wide, one shared stack
(`docs/agents/local-agent-environment.md`).
- Never `--force` / `--force-with-lease` on someone else's branch.
- Never merge a PR, take it out of draft, or close it.
- One commit per PR per sweep: `chore: merge main into <branch>`.
Expand Down
575 changes: 1 addition & 574 deletions CLAUDE.md

Large diffs are not rendered by default.

585 changes: 585 additions & 0 deletions docs/agents/local-agent-environment.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/agents/skill-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ status (Needs input / Working / Completed) instead of juggling editor windows.
Agent View is a dashboard, not an IDE — each session's worktree is a real folder
you open in VS Code or `cd` into to run tests/scripts. **Sibling and native
worktrees are both first-class** (siblings only drop out of the *project-scoped*
view); see [Worktree Conventions](../../CLAUDE.md).
view); see [Worktree Conventions](local-agent-environment.md).

## Where to go next

Expand Down
42 changes: 39 additions & 3 deletions scripts/quality-check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,8 @@ MUST_BE_DENIED = [
# Checked against deny + ask: a prompt is an acceptable outcome for these.
MUST_BE_GUARDED = [
# git's global options may precede the subcommand -- the hook this
# replaced normalised for exactly this, and CLAUDE.md teaches `git -C` as
# replaced normalised for exactly this, and local-agent-environment.md
# teaches `git -C` as
# the cross-checkout idiom, so it is the spelling most likely to be used.
"git --no-pager gc --prune=now",
"git -C sub tag -d v9.9.0",
Expand Down Expand Up @@ -356,14 +357,16 @@ MUST_NOT_BE_GUARDED = [
"git push origin v9.9.0",
"git -C .claude/worktrees/x push origin main",
"git -c push.default=current push beta main",
# Read-only stash inspection, which CLAUDE.md and rules.md both promise
# Read-only stash inspection, which local-agent-environment.md and
# rules.md both promise
# keeps working. A blanket `git -* stash *` DENY caught these, and deny has
# no override -- so the cross-checkout recipe was hard-blocked, not merely
# prompted. That is why the stash twins name a verb.
"git stash list", "git stash show",
"git -C sub stash list",
"git -C .claude/worktrees/x stash show",
# implement-issue Step 4 prunes worktrees in a loop; CLAUDE.md argues that
# implement-issue Step 4 prunes worktrees in a loop;
# local-agent-environment.md argues that
# must stay unattended. A `git -* prune*` twin caught `worktree prune` and
# `remote prune` through the same greedy glob, so the twin was dropped.
"git -C /main worktree prune", "git worktree prune",
Expand Down Expand Up @@ -512,6 +515,39 @@ then
ERRORS=$((ERRORS + 1))
fi

echo ""
echo "📋 Checking agent context budget..."
echo "-------------------------------------------"

# Every bot stage loads CLAUDE.md before it does anything, on the main agent
# and again on its sub-agent, and re-sends it on every turn. It is the largest
# single item in the fixed context floor, so its size is a per-run cost on
# Stages 1-5 and on every local session.
#
# It reached 45,488 B once, of which 33,743 B (74%) was one section describing
# this machine -- the macOS sandbox, podman, worktrees, Playwright, the
# permission rules. None of it can apply on a fresh ubuntu runner under
# `--permission-mode bypassPermissions`, and it was billed on every turn of
# every stage anyway (#650).
#
# The fix was to RELOCATE that content, not delete it: it lives in
# docs/agents/local-agent-environment.md and is reached through the Agent
# Documentation Index like every other doc. This gate keeps it from creeping
# back inline. If you need to raise the cap, move content into docs/agents/
# and link it instead -- that is the mechanism CLAUDE.md already uses.
CLAUDE_MD_MAX_BYTES=16000
CLAUDE_MD_BYTES=$(wc -c < CLAUDE.md | tr -d ' ')

if [ "$CLAUDE_MD_BYTES" -gt "$CLAUDE_MD_MAX_BYTES" ]; then
echo "❌ CLAUDE.md is ${CLAUDE_MD_BYTES} B, over the ${CLAUDE_MD_MAX_BYTES} B budget"
echo " Every bot stage loads this file on every turn, on two agents."
echo " Move the new material into docs/agents/ and link it from the"
echo " Agent Documentation Index rather than raising the cap (#650)."
ERRORS=$((ERRORS + 1))
else
echo "✅ CLAUDE.md within context budget (${CLAUDE_MD_BYTES} B / ${CLAUDE_MD_MAX_BYTES} B)"
fi

echo ""
echo "📋 Checking scenario discovery coverage..."
echo "-------------------------------------------"
Expand Down
6 changes: 3 additions & 3 deletions scripts/verify-sandbox.sh
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ fi
# allow-within-deny primitive, so allowWrite cannot re-open them. A "created"
# here would mean the sandbox is looser than this repo's docs assume.
check "git worktree add is blocked (use EnterWorktree)" blocked "$wt" \
"the sandbox allowed a .git/config + .git/worktrees write. Either the write policy changed or the sandbox is not applied; re-read CLAUDE.md Permissions before trusting anything here. (No error to quote -- this check fails precisely when the command SUCCEEDED.)"
"the sandbox allowed a .git/config + .git/worktrees write. Either the write policy changed or the sandbox is not applied; re-read docs/agents/local-agent-environment.md Permissions before trusting anything here. (No error to quote -- this check fails precisely when the command SUCCEEDED.)"

# NOTE ON `rm -rf`, which is the reason settings.json leaves rm unattended.
# There is deliberately no probe for it, because a safe one cannot be written.
Expand Down Expand Up @@ -136,9 +136,9 @@ else
cl=skipped
fi
check "Bash writing .claude/settings.json is blocked (use Edit/Write)" blocked "$cl" \
"the sandbox allowed a write to the settings file that governs it. Either the deny list changed or the sandbox is not applied -- re-derive before trusting CLAUDE.md's Permissions section."
"the sandbox allowed a write to the settings file that governs it. Either the deny list changed or the sandbox is not applied -- re-derive before trusting docs/agents/local-agent-environment.md's Permissions section."

# 4b. The paths CLAUDE.md is unsure about. These are reported, not asserted:
# 4b. The paths docs/agents/local-agent-environment.md is unsure about. These are reported, not asserted:
# the earlier claim that they were denied came from misreading the binary's
# GitHub Actions config as the local one, so measure rather than restate.
touch scripts/.sandbox-probe 2>/dev/null && sc=allowed || sc=blocked
Expand Down
3 changes: 2 additions & 1 deletion scripts/worktree-setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,8 @@ while kill -0 "$install_pid" 2>/dev/null; do
echo "" >&2
echo " mkdir \"$BROWSER_CACHE/.probe\" # 'Operation not permitted' = sandbox" >&2
echo "" >&2
echo " See CLAUDE.md 'Why each non-default knob is there', and confirm" >&2
echo " See docs/agents/local-agent-environment.md 'Why each non-default" >&2
echo " knob is there', and confirm" >&2
echo " with scripts/verify-sandbox.sh in a FRESH session." >&2
echo "" >&2
echo " Dependency sharing above completed — only the browsers are missing." >&2
Expand Down
Loading