Universal Agent Rules
These rules apply to every agent in the CleverAgents system without exception. No agent, at any tier or role, is exempt from any of these rules.
Rule 1 — Exhaustive Pagination
Every tool call, REST/curl request, or any other command that returns a list must be treated as potentially paginated and incomplete.
Required protocol:
- Always set
limitto its maximum available value:- Forgejo MCP tools:
limit=50 - Direct REST/curl calls:
limit=50or higher
- Forgejo MCP tools:
- After each list response, count the returned items.
- If the count equals
limit, fetch the next page (page=N+1). - Continue until receiving a page with fewer items than
limit. - Concatenate all pages before processing. Never act on a partial set.
This rule applies to every list-returning call without exception:
Forgejo MCP tools, curl REST calls, bash commands (find, git log,
git branch -r, etc.), and any other list-producing operation.
Partial-page stop condition (exact):
returned_count < limit → this is the last page, stop
returned_count == limit → there may be more, fetch page+1
Bash pagination pattern:
PAGE=1
ALL_ITEMS=()
while true; do
BATCH=$(curl -s "${FORGEJO_URL}/api/v1/some/endpoint?limit=50&page=${PAGE}" \
-H "Authorization: token ${FORGEJO_PAT}")
# process BATCH items...
COUNT=$(echo "$BATCH" | jq length)
[ "$COUNT" -lt 50 ] && break
PAGE=$((PAGE + 1))
done
Why this matters: Missing a page means silently skipping work items, causing incorrect escalation decisions, duplicate filings, or incomplete audits. The cost of an extra API call is always less than the cost of a missed item.
Rule 2 — Label Management via forgejo-label-manager
All label operations must go through the forgejo-label-manager subagent.
Forbidden operations — no agent may use these directly:
| Forbidden | Reason |
|---|---|
forgejo_add_issue_labels |
Direct label application bypasses validation |
forgejo_edit_issue with label fields |
Direct mutation bypasses label manager |
forgejo_create_label |
Labels are never created by agents during operation |
forgejo_create_org_label |
Same — never create labels |
forgejo_create_repo_label |
Same — never create labels |
forgejo_list_repo_labels |
Must use org-level labels only; repo-level labels not authoritative |
Any curl POST/PUT/PATCH to label endpoints |
Bypasses forgejo-label-manager |
Required pattern:
Need to apply, remove, or check labels?
→ Invoke forgejo-label-manager subagent
→ Pass: issue/PR number, repo info, desired label names, operation type
→ forgejo-label-manager validates org-level existence, then applies via PUT (replace-all)
Why PUT (replace-all) not POST (add)?
Exclusive labels (e.g. State/Open, State/Closed) are mutually exclusive
within their prefix group. Using POST to add a label leaves conflicting labels
behind. forgejo-label-manager always uses PUT to safely replace the full set.
Org-level labels only:
All labels applied by agents must exist at the organization level. Labels are defined once at the org level and inherited by all repos. Repo-level labels are not used by the autonomous agent system.
Rule 3 — Bot Signature on All Forgejo Content
Every piece of content created on Forgejo by an agent — issue bodies, PR descriptions, comments — must end with this exact signature block.
Pool supervisor workers:
---
**Automated by CleverAgents Bot**
Supervisor: [Your Pool Name] | Agent: [your-agent-name]
Utility subagents (no pool):
---
**Automated by CleverAgents Bot**
Agent: [your-agent-name]
Placement: Always the last content in the body — after all other text, after code blocks, after any closing notes. Never buried in the middle.
Values: Use the values given in your system prompt. Do not invent or guess the pool name or agent name — they are always provided in context.
Rule 4 — Credential Flow: Workers Never Read Environment Variables
All credentials flow downward through prompt text only. No agent below
product-builder may read environment variables.
The hierarchy:
product-builder
→ reads: FORGEJO_PAT, FORGEJO_USERNAME, FORGEJO_PASSWORD,
FORGEJO_REVIEWER_PAT, FORGEJO_REVIEWER_USERNAME, FORGEJO_REVIEWER_PASSWORD,
GIT_USER_NAME, GIT_USER_EMAIL, FORGEJO_URL, FORGEJO_OWNER, FORGEJO_REPO,
CA_MAX_PARALLEL_WORKERS
→ stores as local variables for the session
product-builder launches supervisors
→ embeds ALL credentials explicitly in each supervisor's prompt text
supervisors launch workers
→ embed ALL credentials explicitly in each worker's prompt text
workers use credentials
→ from prompt text only — never from os.environ, never from echo $VAR
Every worker prompt MUST include:
- Repository owner and name
FORGEJO_URLFORGEJO_PAT(or reviewer PAT if this is a review worker)FORGEJO_USERNAMEFORGEJO_PASSWORDGIT_USER_NAMEGIT_USER_EMAIL- Any other credentials the specific task requires
If a supervisor omits any of these, the worker cannot proceed. Supervisors bear full responsibility for including complete credentials in every worker prompt.
Rule 5 — localhost:4096 Restriction
Only async-agent-util is permitted to make HTTP calls to the OpenCode
server at localhost:4096 (or 127.0.0.1:4096).
What this means in practice:
| Agent type | Permitted action |
|---|---|
async-agent-util |
Direct HTTP to localhost:4096 — this is its sole purpose |
| All other agents | FORBIDDEN from calling localhost:4096 under any circumstances |
Required pattern for all non-manager agents:
Need to launch, monitor, or terminate an async agent session?
→ Invoke async-agent-util via the Task tool
→ Pass the operation name and all parameters in the prompt
→ async-agent-util makes the localhost:4096 call on your behalf
→ async-agent-util returns the result to you
Operations async-agent-util handles:
| Operation | What it does |
|---|---|
| Create session | POST /session — creates a new named session |
prompt_async |
POST /session/{id}/prompt_async — fire-and-forget agent launch (returns 204) |
| Get status | GET /session/{id} — check if session is busy or idle |
| Get messages | GET /session/{id}/message — retrieve agent output |
| Delete session | DELETE /session/{id} — terminate and clean up |
Why the restriction? localhost:4096 is the OpenCode server control plane.
Unrestricted access from any agent would create uncontrolled recursive session
spawning, resource exhaustion, and untraceable agent genealogies. Channeling
all access through async-agent-util provides a single audit point and
prevents these failure modes.
Violating this rule is a critical architecture violation and will be detected by system-watchdog's deep session inspection.