mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 02:54:26 +00:00
docs(agents): merge the tool-specific files into AGENTS.md
CLAUDE.md and GEMINI.md existed as per-runtime extensions of AGENTS.md, and only one of them carried anything at all: GEMINI.md stated that it had no additions, while CLAUDE.md held rules that bind every runtime anyway — the permission announcement, the make-over-raw preference, the loop, chain and heredoc bans, the stream-the-log-to-/tmp rule, the CI-evidence rule, the push ban and the comment rule. A rule that binds every agent does not belong in one agent's file. AGENTS.md absorbs them and now states that no tool-specific extension file exists; agents whose runtime auto-loads a different filename reach it through their own configuration instead. The filenames were machinery as much as prose. The PR templates, the branch and pull-request scope tables, the settings and security docs that justified the loop deny by "the textual CLAUDE.md rule", six requirement documents whose push instruction linked ../../CLAUDE.md, and a test docstring citing the shell-loop ban all named them, and now name AGENTS.md. scripts/meta/resolve/pr/scope.sh deliberately keeps matching CLAUDE.md and GEMINI.md: this change deletes them, and without those patterns the change itself would not classify as agent-scope. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
5b8465260f
commit
f40d627a1b
16 files changed
+71
-104
No files matched your search
@@ -5,8 +5,8 @@ Briefly describe the change to the agent instruction files and the expected effe
|
||||
Examples:
|
||||
|
||||
* Add a new repository rule to `AGENTS.md`
|
||||
* Fix contradictory guidance between `AGENTS.md` and `CLAUDE.md`
|
||||
* Improve instruction clarity for `GEMINI.md`
|
||||
* Fix contradictory guidance between `AGENTS.md` and `docs/agents/*`
|
||||
* Improve instruction clarity for `AGENTS.md`
|
||||
|
||||
---
|
||||
|
||||
@@ -24,8 +24,8 @@ Select the primary intent of this PR:
|
||||
List the touched agent instruction files.
|
||||
|
||||
* [ ] `AGENTS.md`
|
||||
* [ ] `CLAUDE.md`
|
||||
* [ ] `GEMINI.md`
|
||||
* [ ] `roles/<role>/AGENTS.md`
|
||||
* [ ] `docs/agents/*`
|
||||
|
||||
Additional notes:
|
||||
|
||||
@@ -61,7 +61,7 @@ Key points:
|
||||
Describe how the instruction change was validated.
|
||||
|
||||
* [ ] Conflicting or ambiguous guidance checked
|
||||
* [ ] Consistency between `AGENTS.md`, `CLAUDE.md`, and `GEMINI.md` verified
|
||||
* [ ] Consistency between `AGENTS.md`, `roles/<role>/AGENTS.md`, and `docs/agents/*` verified
|
||||
* [ ] Examples, workflows, or affected contributor paths reviewed
|
||||
|
||||
---
|
||||
|
||||
@@ -6,21 +6,17 @@
|
||||
- You MUST read every file under `docs/contributing/` (full directory walk, including subdirectories) for the full contributor guidance.
|
||||
- You MUST read every file under `docs/agents/` (full directory walk, including subdirectories) for the agent execution flow.
|
||||
- This file extends CONTRIBUTING.md with agent-specific instructions; on conflict between CONTRIBUTING.md and this file, this file wins.
|
||||
- This file is runtime-agnostic and binding for every agent (Claude Code, Codex, Gemini CLI, other). There are no tool-specific extension files.
|
||||
|
||||
## Tool-Specific Extensions 🧩
|
||||
## Permission State Announcement at Session Start 📢
|
||||
|
||||
At the start of every conversation, the agent MUST load its matching extension file in addition to AGENTS.md:
|
||||
|
||||
- Claude Code → [CLAUDE.md](CLAUDE.md)
|
||||
- Gemini CLI → [GEMINI.md](GEMINI.md)
|
||||
|
||||
Agents MUST NOT read another tool's extension file. On conflict between AGENTS.md and the agent's own tool-specific extension file, the tool-specific file wins.
|
||||
At the start of every new conversation, you MUST read [.claude/settings.json](.claude/settings.json) and output a one-time summary: sandbox status with concrete `allowWrite`/`denyRead` paths, plus the counts of `permissions.allow`/`ask`/`deny`. Derive content from the live file; do not hardcode. Do not repeat unless the operator asks, and do not propose `/sandbox` when it is already active.
|
||||
|
||||
## Reloading Instructions 🔄
|
||||
|
||||
If agent instructions change mid-conversation (AGENTS.md, the tool-specific extension file, or any file referenced from them), the agent might not reload them automatically. Trigger a reload with:
|
||||
If agent instructions change mid-conversation (AGENTS.md or any file referenced from it), the agent might not reload them automatically. Trigger a reload with:
|
||||
|
||||
> "Re-read AGENTS.md and the tool-specific extension file (CLAUDE.md or GEMINI.md) and apply all updated instructions."
|
||||
> "Re-read AGENTS.md and apply all updated instructions."
|
||||
|
||||
## Permission Model 🔐
|
||||
|
||||
@@ -41,6 +37,50 @@ Agents whose runtime does not consult `.claude/settings.json` MUST still enforce
|
||||
|
||||
Changes to the policy MUST edit [`.claude/settings.json`](.claude/settings.json). Per-entry rationale: [settings.md](docs/contributing/tools/agents/claude/settings.md); sandbox layer: [sandbox.md](docs/contributing/tools/agents/claude/sandbox.md).
|
||||
|
||||
## Interaction Rules 💬
|
||||
|
||||
- A question MUST NOT modify files, code, or state. Only explicit commands MAY.
|
||||
- You MUST prefer commands permitted in [.claude/settings.json](.claude/settings.json) over commands that require interactive approval when an equivalent exists.
|
||||
|
||||
## Code Execution ⚙️
|
||||
|
||||
- You MUST prefer `make` targets over raw `docker`/`docker compose`/`ansible-playbook`/`python`/shell invocations whenever an equivalent target exists in the [`Makefile`](Makefile). Inspect the `Makefile` first; fall back to the raw command only when no target covers the operation. The reason is operational consistency, not permissioning. Raw commands also auto-allow under the sandbox.
|
||||
- **`docker exec` is FORBIDDEN. ⛔** You MUST NEVER invoke `docker exec` (nor nested `docker exec … docker exec …` into the DiD stack) directly. Always reach the live stack through `make` targets (e.g. `make compose-exec`, or the role-specific targets the `Makefile` exposes). If no `make` target covers what you need, ask the operator instead of falling back to raw `docker exec`.
|
||||
- You SHOULD run sandbox-confined commands directly on the host. The sandbox bounds what they can read, write, and reach. See [sandbox.md](docs/contributing/tools/agents/claude/sandbox.md).
|
||||
- For commands that legitimately cannot run inside the sandbox (e.g. operations needing access to `~/.ssh` or `~/.gnupg`), use `make compose-up` to start the stack and `make compose-exec` to drop into a container shell. The repository is mounted at `/opt/src/infinito` (see [compose.yml](compose.yml)), so code changes are immediately available there.
|
||||
- Commands listed under `permissions.ask` in [.claude/settings.json](.claude/settings.json) still pause for explicit operator confirmation regardless of sandbox state.
|
||||
- **Shell loops are FORBIDDEN. ⛔** You MUST NOT use `for`, `while`, `until`, or any other shell loop construct in any Bash tool call. Reason: shell control structures fall outside the sandbox auto-allow heuristic and trigger approval prompts even when every subcommand would individually auto-allow.
|
||||
- **Multi-statement chains in shell invocations are FORBIDDEN. ⛔** You MUST NOT chain independent statements inside a single Bash tool call with **any** statement separator (`;`, literal newline, `&&`, `||`, `&` background operator, or subshell/brace groups around the same). The ban covers causally-dependent chains (`cd X && cmd`) just as much as optional ones, and applies to trailing `&` used to background a command (use the Bash tool's `run_in_background: true` parameter instead). Reason: identical to the loop rule. Split the work across **separate Bash tool calls** or use a single-command equivalent (`xargs`, `grep` with multiple args, a make target).
|
||||
- **File creation via shell heredoc is FORBIDDEN. ⛔** You MUST NOT use `cat > file <<EOF … EOF` or any variant (`tee > file <<EOF`, `printf "…" > file`, `echo "…" > file` for multi-line content) to create or overwrite files. Use the **Write tool**. For editing an existing file, use **Edit**, not `sed -i`/`awk -i`. Reason: Write/Edit land structured in the transcript and diff; heredoc + redirect shapes also fall out of the auto-allow heuristic and drop into ask.
|
||||
- **For searching file contents, use the Grep tool.** If shelling out is unavoidable, use a single `grep` invocation with multiple file arguments (e.g. `grep -nE 'pattern' file1 file2 file3`) or a recursive call with a path/glob (e.g. `grep -rnE 'pattern' path/`).
|
||||
|
||||
## Command output logging 📜
|
||||
|
||||
- For ANY non-trivial command (test runs, deploys, long pipelines), you MUST stream the FULL output to a file under `/tmp/` via `… 2>&1 | tee /tmp/<name>.log` and grep / inspect that file repeatedly instead of re-running the command. Reason: re-running `make test` to "find the failure I just lost" costs 2 minutes per cycle; grepping the saved log costs milliseconds.
|
||||
- Default the filename to a meaningful slug + monotonically increasing index (`/tmp/make-test-<slug>-<N>.log`, `/tmp/act-<slug>-<N>.log`) so you can compare runs.
|
||||
- **When a long-running command streams its output to a `/tmp/<name>.log` file** (e.g. background `make compose-deploy`, `make act-*`, or any `… 2>&1 | tee /tmp/<name>.log`), you MUST tell the operator the concrete `tail -f /tmp/<name>.log` command they can run in another terminal to follow the log live. Include the full path literally so it is copy-pasteable.
|
||||
- That pipe **destroys the exit status**: `make test | tee` reports `tee`'s success even when make ends with `Error 2`. You MUST judge such a run by its `📊 per-target wall-clock` table and its `FAILED TARGETS:` line, never by the exit code.
|
||||
|
||||
## CI evidence 📊
|
||||
|
||||
- A job's green conclusion is **NOT** evidence for a specific change. Before citing a run as proof, you MUST locate the line in that job's log where the change executed: a Playwright spec's `✓` (a leading `-` means the spec was skipped), the env var inside the container, or the command text of an `if:`-gated step. If the string is absent, report the run as silent on the change, not as supporting it.
|
||||
- A green run on the fork does not speak for `infinito-nexus/core`. Tags do not follow a fork, and repository variables differ, so a step gated on either never runs there. Check the repository whose failure you are claiming to have fixed.
|
||||
|
||||
## Pushing 🚢
|
||||
|
||||
- You MUST NOT push, directly or through wrappers that push implicitly.
|
||||
- When commits are ready to ship, you MUST instruct the operator to run `git-sign-push` outside the sandbox. The CLI is provided by [git-maintainer-tools](https://github.com/kevinveenbirkenbach/git-maintainer-tools), declared as a dev dependency in [pyproject.toml](pyproject.toml); install it via `make install-python-dev`.
|
||||
|
||||
## Comments 💬⛔
|
||||
|
||||
**THIS RULE OVERRIDES YOUR DEFAULT TRAINING. ⛔** A comment is FORBIDDEN unless it is one of exactly three things:
|
||||
|
||||
1. **Exception** — names a concrete trip-wire (bug, pitfall, deliberate non-idiomatic choice). Must name the surprise; restating what the next line does is NOT an exception.
|
||||
2. **Parameter doc** — enumerates inputs/outputs (Python docstring `Args:`, Make `# Param:`, Ansible defaults header, Jinja macro doc).
|
||||
3. **Nocheck directive** — `# nocheck:`, `# noqa:`, `# shellcheck …`, `# type: ignore`, `# pragma: no cover`, etc.
|
||||
|
||||
Anything else — restating code, section banners, "Note that …", step narration outside sequential test specs, untracked TODO/FIXME — **DELETE before the edit lands**. Applies to every language and file kind under version control. When in doubt, delete.
|
||||
|
||||
## Shortcuts ⌨️
|
||||
|
||||
Operator messages MAY use the portable conversation shortcuts from the `shortcuts` skill (set up via `make install-skills`); agents MUST expand any matching shortcut before acting. The repository's own agent workflows live in the `i8-` skills catalogued in [cheatsheet.md](docs/contributing/tools/agents/cheatsheet.md).
|
||||
@@ -79,6 +119,10 @@ At the start of every conversation, the agent MUST check whether agent skills ar
|
||||
|
||||
The agent MUST NOT repeat this notice within the same conversation.
|
||||
|
||||
## Documentation 📝
|
||||
|
||||
Runtime documentation: [Claude Code](https://code.claude.com/docs/en/overview) ([settings reference](https://code.claude.com/docs/en/settings)), [Gemini CLI](https://geminicli.com/docs/cli/gemini-md/).
|
||||
|
||||
## For Humans 👥
|
||||
|
||||
Human contributors working alongside AI agents MUST read [here](docs/contributing/tools/agents/common.md).
|
||||
@@ -1,63 +0,0 @@
|
||||
# CLAUDE.md
|
||||
|
||||
## Startup: MUST DO at the Start of Every Conversation 🚀
|
||||
|
||||
You MUST read `AGENTS.md` and follow all instructions in it at the start of every conversation before doing anything else.
|
||||
|
||||
## Permission State Announcement at Session Start 📢
|
||||
|
||||
At the start of every new conversation (after reading `AGENTS.md`), you MUST read [.claude/settings.json](.claude/settings.json) and output a one-time summary: sandbox status with concrete `allowWrite`/`denyRead` paths, plus the counts of `permissions.allow`/`ask`/`deny`. Derive content from the live file; do not hardcode. Do not repeat unless the operator asks, and do not propose `/sandbox` when it is already active.
|
||||
|
||||
## Interaction Rules 💬
|
||||
|
||||
- A question MUST NOT modify files, code, or state. Only explicit commands MAY.
|
||||
- You MUST prefer commands permitted in [.claude/settings.json](.claude/settings.json) over commands that require interactive approval when an equivalent exists.
|
||||
|
||||
## Code Execution ⚙️
|
||||
|
||||
- You MUST prefer `make` targets over raw `docker`/`docker compose`/`ansible-playbook`/`python`/shell invocations whenever an equivalent target exists in the [`Makefile`](Makefile). Inspect the `Makefile` first; fall back to the raw command only when no target covers the operation. The reason is operational consistency, not permissioning. Raw commands also auto-allow under the sandbox.
|
||||
- **`docker exec` is FORBIDDEN. ⛔** You MUST NEVER invoke `docker exec` (nor nested `docker exec … docker exec …` into the DiD stack) directly. Always reach the live stack through `make` targets (e.g. `make compose-exec`, or the role-specific targets the `Makefile` exposes). If no `make` target covers what you need, ask the operator instead of falling back to raw `docker exec`.
|
||||
- You SHOULD run sandbox-confined commands directly on the host. The sandbox bounds what they can read, write, and reach. See [sandbox.md](docs/contributing/tools/agents/claude/sandbox.md).
|
||||
- For commands that legitimately cannot run inside the sandbox (e.g. operations needing access to `~/.ssh` or `~/.gnupg`), use `make compose-up` to start the stack and `make compose-exec` to drop into a container shell. The repository is mounted at `/opt/src/infinito` (see [compose.yml](compose.yml)), so code changes are immediately available there.
|
||||
- Commands listed under `permissions.ask` in [.claude/settings.json](.claude/settings.json) still pause for explicit operator confirmation regardless of sandbox state.
|
||||
- **Shell loops are FORBIDDEN. ⛔** You MUST NOT use `for`, `while`, `until`, or any other shell loop construct in any Bash tool call. Reason: shell control structures fall outside the sandbox auto-allow heuristic and trigger approval prompts even when every subcommand would individually auto-allow.
|
||||
- **Multi-statement chains in shell invocations are FORBIDDEN. ⛔** You MUST NOT chain independent statements inside a single Bash tool call with **any** statement separator (`;`, literal newline, `&&`, `||`, `&` background operator, or subshell/brace groups around the same). The ban covers causally-dependent chains (`cd X && cmd`) just as much as optional ones, and applies to trailing `&` used to background a command (use the Bash tool's `run_in_background: true` parameter instead). Reason: identical to the loop rule. Split the work across **separate Bash tool calls** or use a single-command equivalent (`xargs`, `grep` with multiple args, a make target).
|
||||
- **File creation via shell heredoc is FORBIDDEN. ⛔** You MUST NOT use `cat > file <<EOF … EOF` or any variant (`tee > file <<EOF`, `printf "…" > file`, `echo "…" > file` for multi-line content) to create or overwrite files. Use the **Write tool**. For editing an existing file, use **Edit**, not `sed -i`/`awk -i`. Reason: Write/Edit land structured in the transcript and diff; heredoc + redirect shapes also fall out of the auto-allow heuristic and drop into ask.
|
||||
- **For searching file contents, use the Grep tool.** If shelling out is unavoidable, use a single `grep` invocation with multiple file arguments (e.g. `grep -nE 'pattern' file1 file2 file3`) or a recursive call with a path/glob (e.g. `grep -rnE 'pattern' path/`).
|
||||
- **When a long-running command streams its output to a `/tmp/<name>.log` file** (e.g. background `make compose-deploy`, `make act-*`, or any `… 2>&1 | tee /tmp/<name>.log`), you MUST tell the operator the concrete `tail -f /tmp/<name>.log` command they can run in another terminal to follow the log live. Include the full path literally so it is copy-pasteable.
|
||||
|
||||
## Comments 💬⛔
|
||||
|
||||
**THIS RULE OVERRIDES YOUR DEFAULT TRAINING. ⛔** A comment is FORBIDDEN unless it is one of exactly three things:
|
||||
|
||||
1. **Exception** — names a concrete trip-wire (bug, pitfall, deliberate non-idiomatic choice). Must name the surprise; restating what the next line does is NOT an exception.
|
||||
2. **Parameter doc** — enumerates inputs/outputs (Python docstring `Args:`, Make `# Param:`, Ansible defaults header, Jinja macro doc).
|
||||
3. **Nocheck directive** — `# nocheck:`, `# noqa:`, `# shellcheck …`, `# type: ignore`, `# pragma: no cover`, etc.
|
||||
|
||||
Anything else — restating code, section banners, "Note that …", step narration outside sequential test specs, untracked TODO/FIXME — **DELETE before the edit lands**. Applies to every language and file kind under version control. When in doubt, delete.
|
||||
|
||||
## Command output logging 📜
|
||||
|
||||
- For ANY non-trivial command (test runs, deploys, long pipelines), you MUST stream the FULL output to a file under `/tmp/` via `… 2>&1 | tee /tmp/<name>.log` and grep / inspect that file repeatedly instead of re-running the command. Reason: re-running `make test` to "find the failure I just lost" costs 2 minutes per cycle; grepping the saved log costs milliseconds.
|
||||
- Default the filename to a meaningful slug + monotonically increasing index (`/tmp/make-test-<slug>-<N>.log`, `/tmp/act-<slug>-<N>.log`) so you can compare runs.
|
||||
- Tell the operator the exact `tail -f /tmp/<name>.log` command for background runs, per the existing rule.
|
||||
- That pipe **destroys the exit status**: `make test | tee` reports `tee`'s success even when make ends with `Error 2`. You MUST judge such a run by its `📊 per-target wall-clock` table and its `FAILED TARGETS:` line, never by the exit code.
|
||||
|
||||
## CI evidence 📊
|
||||
|
||||
- A job's green conclusion is **NOT** evidence for a specific change. Before citing a run as proof, you MUST locate the line in that job's log where the change executed: a Playwright spec's `✓` (a leading `-` means the spec was skipped), the env var inside the container, or the command text of an `if:`-gated step. If the string is absent, report the run as silent on the change, not as supporting it.
|
||||
- A green run on the fork does not speak for `infinito-nexus/core`. Tags do not follow a fork, and repository variables differ, so a step gated on either never runs there. Check the repository whose failure you are claiming to have fixed.
|
||||
|
||||
## Pushing 🚢
|
||||
|
||||
- You MUST NOT push, directly or through wrappers that push implicitly.
|
||||
- When commits are ready to ship, you MUST instruct the operator to run `git-sign-push` outside the sandbox. The CLI is provided by [git-maintainer-tools](https://github.com/kevinveenbirkenbach/git-maintainer-tools), declared as a dev dependency in [pyproject.toml](pyproject.toml); install it via `make install-python-dev`.
|
||||
|
||||
## Configuration 🛠️
|
||||
|
||||
- Project-level permissions and sandbox rules are defined in [.claude/settings.json](.claude/settings.json).
|
||||
- See [code.claude.com](https://code.claude.com/docs/en/settings) for documentation on how to modify it.
|
||||
|
||||
## Documentation 📝
|
||||
|
||||
See the [Claude Code documentation](https://code.claude.com/docs/en/overview) for further information. For human contributor guidance on working with agents, see [here](docs/contributing/tools/agents/common.md).
|
||||
@@ -1,13 +0,0 @@
|
||||
# GEMINI.md
|
||||
|
||||
## Purpose
|
||||
|
||||
This file extends [AGENTS.md](AGENTS.md) with Gemini-specific additions. You MUST read `AGENTS.md` first as the entry point for all agent instructions.
|
||||
|
||||
## Current Status
|
||||
|
||||
- No Gemini-specific additions are currently defined.
|
||||
|
||||
## Documentation
|
||||
|
||||
See the [Gemini CLI documentation](https://geminicli.com/docs/cli/gemini-md/). For human contributor guidance on working with agents, see [here](docs/contributing/tools/agents/common.md).
|
||||
@@ -6,7 +6,7 @@ The branch prefix MUST match the type of change. The [PR workflow](pull-request.
|
||||
|
||||
| Branch prefix | Scope | Matching files | CI behavior |
|
||||
|---|---|---|---|
|
||||
| `agent` | Changes to agent instructions or prompts | `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, `docs/agents/*` | Skips [orchestrator](../../../../.github/workflows/call-orchestrator.yml), finishes green through the lightweight scope gate. |
|
||||
| `agent` | Changes to agent instructions or prompts | `AGENTS.md`, `roles/<role>/AGENTS.md`, `docs/agents/*` | Skips [orchestrator](../../../../.github/workflows/call-orchestrator.yml), finishes green through the lightweight scope gate. |
|
||||
| `documentation` | Documentation-only changes | `**/*.md`, `**/*.rst` (outside agent paths) | Skips [orchestrator](../../../../.github/workflows/call-orchestrator.yml), finishes green through the lightweight scope gate. |
|
||||
| `feature` | New features or enhancements | `*` | Runs the full [orchestrator](../../../../.github/workflows/call-orchestrator.yml) pipeline. |
|
||||
| `fix` | Bug fixes | `*` | Runs the full [orchestrator](../../../../.github/workflows/call-orchestrator.yml) pipeline. |
|
||||
|
||||
@@ -10,8 +10,8 @@ You MUST pick the template that matches your change. The table below links the a
|
||||
| Workstation and `desk-*` changes | [workstation.md](../../../../.github/PULL_REQUEST_TEMPLATE/workstation.md) |
|
||||
| Shared system changes such as `sys-*`, `svc-*`, `dev-*`, `drv-*`, `pkgmgr`, `update-*`, or `user-*` | [system.md](../../../../.github/PULL_REQUEST_TEMPLATE/system.md) |
|
||||
| CI/CD and workflow changes | [pipeline.md](../../../../.github/PULL_REQUEST_TEMPLATE/pipeline.md) |
|
||||
| Documentation-only changes limited to `.md` or `.rst` files outside `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, and `docs/agents/*` | [documentation.md](../../../../.github/PULL_REQUEST_TEMPLATE/documentation.md) |
|
||||
| Agent-specific changes limited to `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, or `docs/agents/*` | [agents.md](../../../../.github/PULL_REQUEST_TEMPLATE/agents.md) |
|
||||
| Documentation-only changes limited to `.md` or `.rst` files outside `AGENTS.md` and `docs/agents/*` | [documentation.md](../../../../.github/PULL_REQUEST_TEMPLATE/documentation.md) |
|
||||
| Agent-specific changes limited to `AGENTS.md` or `docs/agents/*` | [agents.md](../../../../.github/PULL_REQUEST_TEMPLATE/agents.md) |
|
||||
|
||||
## Branch Naming 🏷️
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ The `Bash(*)` allow lets the agent run any Makefile target without prompting. Th
|
||||
|
||||
## Assumption 8: Shell control-flow loops are never necessary 🔁
|
||||
|
||||
[CLAUDE.md](../../../../../CLAUDE.md) forbids `for` / `while` / `until` loops in Bash invocations, and `Bash(for *)` / `Bash(while *)` / `Bash(until *)` are in `deny` to enforce the rule. Every task has a flat-form equivalent: a single `grep` with multiple file arguments, `xargs`, a recursive glob, or a dedicated tool.
|
||||
[AGENTS.md](../../../../../AGENTS.md) forbids `for` / `while` / `until` loops in Bash invocations, and `Bash(for *)` / `Bash(while *)` / `Bash(until *)` are in `deny` to enforce the rule. Every task has a flat-form equivalent: a single `grep` with multiple file arguments, `xargs`, a recursive glob, or a dedicated tool.
|
||||
|
||||
**Why this matters:** Loops can hide destructive operations (for example `for f in $(ls); do rm "$f"; done`) behind a single approval step. The deny rule converts a rule violation into a hard failure, so the agent receives concrete feedback and refactors to the flat form.
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ These operations are unconditionally blocked, regardless of any `allow` entry or
|
||||
|
||||
| Permission | Reason |
|
||||
|---|---|
|
||||
| `for *` / `while *` / `until *` | Shell control-flow loops (`for f in ...; do ...; done`, `while read ...`, `until cond; do ...`). See Assumption 8 in [security.md](security.md) for why loops are banned at the policy layer rather than in the textual [CLAUDE.md](../../../../../CLAUDE.md) rule alone. The sandbox auto-allow heuristic does not recognise loop keywords, so this deny has no cost versus any alternative (allow would also require explicit entries; ask would deadlock). |
|
||||
| `for *` / `while *` / `until *` | Shell control-flow loops (`for f in ...; do ...; done`, `while read ...`, `until cond; do ...`). See Assumption 8 in [security.md](security.md) for why loops are banned at the policy layer rather than in the textual [AGENTS.md](../../../../../AGENTS.md) rule alone. The sandbox auto-allow heuristic does not recognise loop keywords, so this deny has no cost versus any alternative (allow would also require explicit entries; ask would deadlock). |
|
||||
| `gh api * -X DELETE *` / `gh api * --method DELETE *` | DELETE is irreversible from the API surface: deleting a release, branch ref, deploy key, or webhook destroys data with no undo. Both `-X` and `--method` spellings are blocked so neither shorthand slips through. |
|
||||
| `gh api * -X PUT *` / `gh api * --method PUT *` | PUT replaces a resource wholesale. On endpoints like branch protection or rulesets, a PUT silently overwrites the entire policy with whatever payload is sent; partial JSON drops every unspecified field. PATCH (the merge variant) still goes through `ask`. |
|
||||
| `gh api * /actions/secrets*:*` | Touches GitHub Actions secrets: reading metadata, creating, updating, or deleting. Even GETs leak secret names; mutations rotate credentials CI depends on. Out-of-band secret management only. |
|
||||
|
||||
@@ -2,14 +2,13 @@
|
||||
|
||||
AI assistants are welcome, but they MUST follow the same workflow as humans.
|
||||
|
||||
- You MUST treat [AGENTS.md](../../../../AGENTS.md) as the entry point for all agent-specific execution instructions. Tool-specific files such as `CLAUDE.md` and `GEMINI.md` extend `AGENTS.md` and MUST NOT contradict it.
|
||||
- You MUST treat [AGENTS.md](../../../../AGENTS.md) as the single, runtime-agnostic source of agent-specific execution instructions. There are no tool-specific extension files.
|
||||
- You MUST NOT invent commands, workflows, or files that do not exist.
|
||||
- You MUST NEVER expose secrets in prompts, code, screenshots, or logs.
|
||||
- You MUST treat AI output as a draft that must be reviewed for wrong assumptions, duplicate logic, and security mistakes.
|
||||
- You MUST keep explanations simple and explicit.
|
||||
- You MUST state assumptions clearly.
|
||||
|
||||
For tool-specific configuration and additional instructions, see [CLAUDE.md](../../../../CLAUDE.md) and [GEMINI.md](../../../../GEMINI.md).
|
||||
For a full reference of permitted Claude Code operations and their security rationale, see [claude/](claude/README.md).
|
||||
|
||||
For further support, visit the AI forum at [s.infinito.nexus/aihub](https://s.infinito.nexus/aihub) or join the Matrix group #ai:infinito.nexus.
|
||||
@@ -44,4 +44,4 @@ The implementation of this requirement MUST be executed autonomously by the agen
|
||||
- [x] **Iteration loop.** The agent MUST follow the [Workflow Loop](../agents/action/iteration/workflow.md) for every change to GitHub Actions workflows the implementation touches, and the [Compose Loop](../agents/action/iteration/compose.md) for every change inside `roles/svc-runner/`. The agent MUST NOT skip the loop's debug-locally step in favour of remote CI reruns.
|
||||
- [x] **No `ask` prompts mid-run.** The agent MUST NOT trigger any tool call that routes through `permissions.ask` in [.claude/settings.json](../../.claude/settings.json) during implementation. Where a tool would otherwise route through `ask`, the agent MUST select an equivalent already covered by `permissions.allow`, or rephrase the operation to fit the sandbox. The single permitted exception is the final commit at the end of the run.
|
||||
- [x] **No interruptions.** Bug fixes, deploy failures, lint failures, `make test` failures, healthcheck flaps, and similar issues MUST be resolved at their root inside this same iteration without prompting the operator. Workarounds, ad-hoc skips, retry-until-green loops, or "track in a follow-up" deferrals MUST NOT be used.
|
||||
- [x] **One commit at the end.** The agent MUST NOT create any intermediate commit. ALL changes (role, CLI, tests, documentation, and the ticked checkboxes in this document) MUST be combined into ONE commit, created only after every Acceptance Criterion above is checked off (`- [x]`) and `make test` is green. Per-step commits, checkpoint commits, and partial commits MUST NOT be created. The agent MUST NOT push; the operator runs `git-sign-push` outside the sandbox per [CLAUDE.md](../../CLAUDE.md).
|
||||
- [x] **One commit at the end.** The agent MUST NOT create any intermediate commit. ALL changes (role, CLI, tests, documentation, and the ticked checkboxes in this document) MUST be combined into ONE commit, created only after every Acceptance Criterion above is checked off (`- [x]`) and `make test` is green. Per-step commits, checkpoint commits, and partial commits MUST NOT be created. The agent MUST NOT push; the operator runs `git-sign-push` outside the sandbox per [AGENTS.md](../../AGENTS.md).
|
||||
@@ -202,7 +202,7 @@ The implementation of this requirement MUST be executed autonomously by the agen
|
||||
- [ ] **Iteration loop.** The agent MUST follow the [Compose Loop](../agents/action/iteration/compose.md) for every change inside `roles/svc-swarm-node/`, `roles/svc-prx-openresty/` (swarm-mode adaptations), `roles/svc-storage-nfs-server/`, `roles/svc-storage-nfs-client/`, and `roles/web-app-mediawiki/` (pilot). The agent MUST follow the [Workflow Loop](../agents/action/iteration/workflow.md) for every change to `.github/workflows/test-deploy-swarm-nfs.yml`. The agent MUST NOT skip the loop's debug-locally step in favour of remote CI reruns.
|
||||
- [ ] **No `ask` prompts mid-run.** The agent MUST NOT trigger any tool call that routes through `permissions.ask` in [.claude/settings.json](../../.claude/settings.json) during implementation. Where a tool would otherwise route through `ask`, the agent MUST select an equivalent already covered by `permissions.allow`, or rephrase the operation to fit the sandbox. The single permitted exception is the final commit at the end of the run.
|
||||
- [ ] **No interruptions.** Bug fixes, deploy failures, lint failures, `make test` failures, healthcheck flaps, swarm-init flakes, NFS mount races, workflow reruns until green — every issue MUST be resolved at its root inside this same iteration without prompting the operator. Workarounds, ad-hoc skips, retry-until-green loops, or "track in a follow-up" deferrals MUST NOT be used.
|
||||
- [ ] **One commit at the end.** The agent MUST NOT create any intermediate commit. ALL changes (the three new roles, the openresty swarm-mode adaptations, the pilot role updates, the CI workflow, schema entries, group_vars defaults, documentation, and the ticked checkboxes in this document) MUST be combined into ONE commit, created only after every Acceptance Criterion above is checked off (`- [x]`), `make test` is green, and `.github/workflows/test-deploy-swarm-nfs.yml` is green on its first scheduled run. Per-step commits, checkpoint commits, and partial commits MUST NOT be created. The agent MUST NOT push; the operator runs `git-sign-push` outside the sandbox per [CLAUDE.md](../../CLAUDE.md).
|
||||
- [ ] **One commit at the end.** The agent MUST NOT create any intermediate commit. ALL changes (the three new roles, the openresty swarm-mode adaptations, the pilot role updates, the CI workflow, schema entries, group_vars defaults, documentation, and the ticked checkboxes in this document) MUST be combined into ONE commit, created only after every Acceptance Criterion above is checked off (`- [x]`), `make test` is green, and `.github/workflows/test-deploy-swarm-nfs.yml` is green on its first scheduled run. Per-step commits, checkpoint commits, and partial commits MUST NOT be created. The agent MUST NOT push; the operator runs `git-sign-push` outside the sandbox per [AGENTS.md](../../AGENTS.md).
|
||||
|
||||
## See Also
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ The implementation of this requirement MUST be executed autonomously by the agen
|
||||
- [x] **Iteration loops.** The agent MUST follow the [Compose Loop](../agents/action/iteration/compose.md) for every change inside `roles/web-app-penpot/`, and the [Playwright Loop](../agents/action/iteration/playwright.md) for every change to the role's Playwright spec. The debug-locally step MUST NOT be skipped in favour of remote CI reruns.
|
||||
- [x] **No `ask` prompts mid-run.** The agent MUST NOT trigger any tool call that routes through `permissions.ask` in [.claude/settings.json](../../.claude/settings.json) during implementation. Where a tool would otherwise route through `ask`, the agent MUST select an equivalent covered by `permissions.allow`, or rephrase the operation to fit the sandbox. The single permitted exception is the final commit.
|
||||
- [x] **No interruptions.** Bug fixes, deploy failures, lint failures, `make test` failures, and healthcheck flaps MUST be resolved at their root inside this same iteration without prompting the operator. Workarounds, ad-hoc skips, retry-until-green loops, or "track in a follow-up" deferrals MUST NOT be used.
|
||||
- [ ] **One commit at the end.** ALL changes (role, meta, Playwright spec, documentation, marketplace entry, and the ticked checkboxes in this document) MUST be combined into ONE commit, created only after every Acceptance Criterion above is checked off (`- [x]`) and `make test` is green. The agent MUST NOT push; the operator runs `git-sign-push` outside the sandbox per [CLAUDE.md](../../CLAUDE.md).
|
||||
- [ ] **One commit at the end.** ALL changes (role, meta, Playwright spec, documentation, marketplace entry, and the ticked checkboxes in this document) MUST be combined into ONE commit, created only after every Acceptance Criterion above is checked off (`- [x]`) and `make test` is green. The agent MUST NOT push; the operator runs `git-sign-push` outside the sandbox per [AGENTS.md](../../AGENTS.md).
|
||||
|
||||
## See Also
|
||||
|
||||
|
||||
@@ -301,7 +301,7 @@ The agent MUST execute this requirement **autonomously**. Open clarifications on
|
||||
|
||||
- The agent MUST NOT create any git commit until every Acceptance Criterion in this document is checked off (`- [x]`).
|
||||
- A single commit (or a tight, related sequence) lands the whole role addition; no half-scaffolded intermediate commits.
|
||||
- When all ACs are met, `make test` is green, and the three variants deploy cleanly, the agent instructs the operator to run `git-sign-push` outside the sandbox (per [CLAUDE.md](../../CLAUDE.md)). The agent MUST NOT push.
|
||||
- When all ACs are met, `make test` is green, and the three variants deploy cleanly, the agent instructs the operator to run `git-sign-push` outside the sandbox (per [AGENTS.md](../../AGENTS.md)). The agent MUST NOT push.
|
||||
|
||||
## Context
|
||||
|
||||
|
||||
@@ -230,7 +230,7 @@ The agent MUST execute this requirement **autonomously** once Proposed Decisions
|
||||
## Commit Policy
|
||||
|
||||
- Single commit (or a tight, related sequence) lands the whole ansible-flavor addition; no half-scaffolded intermediate commits.
|
||||
- When all ACs are checked off, `make test` is green, and the four variants deploy cleanly, the agent instructs the operator to run `git-sign-push` outside the sandbox (per [CLAUDE.md](../../CLAUDE.md)). The agent MUST NOT push.
|
||||
- When all ACs are checked off, `make test` is green, and the four variants deploy cleanly, the agent instructs the operator to run `git-sign-push` outside the sandbox (per [AGENTS.md](../../AGENTS.md)). The agent MUST NOT push.
|
||||
|
||||
## Context
|
||||
|
||||
|
||||
@@ -209,7 +209,7 @@ Execute autonomously; open a clarification only when a decision is genuinely amb
|
||||
|
||||
- No git commit until every Acceptance Criterion is checked off (`- [x]`).
|
||||
- A single commit (or a tight related sequence) lands the whole role addition.
|
||||
- When all ACs are met and the variants deploy cleanly, instruct the operator to run `git-sign-push` outside the sandbox (per [CLAUDE.md](../../CLAUDE.md)). The agent MUST NOT push.
|
||||
- When all ACs are met and the variants deploy cleanly, instruct the operator to run `git-sign-push` outside the sandbox (per [AGENTS.md](../../AGENTS.md)). The agent MUST NOT push.
|
||||
|
||||
## Context
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ class TestRuntimeLookupPerformance(unittest.TestCase):
|
||||
hit the cache and stay under theirs.
|
||||
|
||||
Using a single for-loop here is test-code-only and not production code
|
||||
generating files/tasks; the CLAUDE.md shell-loop ban does not apply.
|
||||
generating files/tasks; the AGENTS.md shell-loop ban does not apply.
|
||||
"""
|
||||
warm = _simulate_ansible_variables(self.shared_applications, self.shared_users)
|
||||
t0 = time.process_time()
|
||||
|
||||
Reference in new issue
Block a user