Files
freemo 1885990081
CI / build (push) Waiting to run
CI / docker (push) Blocked by required conditions
CI / helm (push) Waiting to run
CI / push-validation (push) Waiting to run
CI / status-check (push) Blocked by required conditions
CI / lint (push) Waiting to run
CI / typecheck (push) Waiting to run
CI / security (push) Waiting to run
CI / quality (push) Waiting to run
CI / unit_tests (push) Waiting to run
CI / integration_tests (push) Waiting to run
CI / e2e_tests (push) Waiting to run
CI / coverage (push) Blocked by required conditions
CI / benchmark-publish (push) Waiting to run
build: auto opencode agents rewritten
2026-04-27 12:49:08 -04:00
..

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:

  1. Always set limit to its maximum available value:
    • Forgejo MCP tools: limit=50
    • Direct REST/curl calls: limit=50 or higher
  2. After each list response, count the returned items.
  3. If the count equals limit, fetch the next page (page=N+1).
  4. Continue until receiving a page with fewer items than limit.
  5. 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_URL
  • FORGEJO_PAT (or reviewer PAT if this is a review worker)
  • FORGEJO_USERNAME
  • FORGEJO_PASSWORD
  • GIT_USER_NAME
  • GIT_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.