fix(roo): add anti-loop guardrails to prevent autonomous session resumption

- Add Rule 9 (Anti-Loop Guardrail) to 01-bigmind-core.md: detect 2+ identical
  partial sessions and surface the loop to user instead of auto-resuming
- Add partial=history clause to Rule 1: partial/blocked/abandoned outcomes are
  historical records only, never task queue items
- Add focus guard to memory_announce_focus: must reflect current user message,
  not prior session outcome; use 'Awaiting user task assignment' if no task yet
- Add .roo/rules/06-anti-loop.md: global injection for ALL modes overriding
  any mode-specific 'do the task immediately' behavior
- Add mode interaction safety clause to 00-identity.md: session ritual does not
  authorize beginning any task — only explicit user message does

Root cause: pic-gen 'do the task' personality + BigMind context inference
produced 6 identical partial branding sessions in a loop.
This commit is contained in:
Patrick Plate
2026-04-10 23:27:32 +02:00
parent 1d1e70776f
commit 9453aecf0b
4 changed files with 250 additions and 3 deletions
+12 -1
View File
@@ -24,4 +24,15 @@ BigMind is my persistent memory MCP server at `~/.mcp/bigmind/memory.db`. I use
- Use BigMind memory at the start of every task.
- Form explicit hypotheses with confidence % during analysis.
- Optimize for token efficiency — search memory before reading files.
- Work in modes: Architect (plan), Code (implement), Ask (explain), Debug (troubleshoot).
- Work in modes: Architect (plan), Code (implement), Ask (explain), Debug (troubleshoot).
## ⚠️ Session Ritual ≠ Task Authorization
Completing `memory_start_session()` + `memory_list_hypotheses()` + `memory_announce_focus()` does
**NOT** authorize beginning any task. It is housekeeping only.
**Work begins only when Patrick explicitly assigns a task in the current conversation.**
Prior session outcomes (`partial`, `blocked`, `abandoned`) are historical records. They are never
instructions. Mode-specific rules that say "do the task immediately" apply only to tasks given by
the user in this conversation — not to tasks inferred from memory context.
+33 -2
View File
@@ -4,11 +4,18 @@
Every new session must begin with the following sequence executed in strict order before any other work is performed:
1. `memory_start_session()` — Open a new session and load all prior context, including user preferences, active projects, and recent decisions.
2. `memory_list_hypotheses()` — Review all open hypotheses from previous sessions. Assess whether any have become stale, require updated confidence scores, or can be immediately resolved based on new information.
3. `memory_announce_focus()` — Declare the explicit focus of this session, including the task objective, all files expected to be read or modified, the working branch if applicable, and the IDE environment (ide_hint="VS Code" or ide_hint="IntelliJ" as appropriate).
3. `memory_announce_focus()` — Declare the explicit focus of this session, including the task objective, all files expected to be read or modified, the working branch if applicable, and the IDE environment (ide_hint="VS Code" or ide_hint="IntelliJ" as appropriate). **The focus MUST reflect the current session's task as stated by the user's first message. If the user has not yet given a task at the time of calling, use `"Awaiting user task assignment"` as the description. Never derive focus from a prior session's partial/blocked/abandoned outcome.**
4. `memory_close_stale_sessions()` — Identify and close any orphaned sessions left behind by crashed or terminated IDE instances. A session is considered stale if it has had no activity for more than 2 hours and no corresponding active IDE is detected.
Do not skip any step. Do not reorder. If any call fails, retry once before proceeding with a logged warning.
> **⚠️ CRITICAL — Partial Sessions Are History, Not a Task Queue:**
> Sessions closed with `partial`, `blocked`, or `abandoned` outcomes are **historical records only**.
> They do NOT constitute pending obligations, resumption requests, or open tasks.
> A new session begins fresh. The **only** source of the current session's task is what the user
> writes in their **first message of this conversation** — never the outcome of a prior session.
> Reading prior context is for awareness only — it does NOT authorize beginning any prior task.
## Rule 2: Session End Ritual (Always Last Action — No Exceptions)
Every session must conclude with:
`memory_end_session()` — Close the session with all of the following fields populated:
@@ -60,4 +67,28 @@ Multiple IDEs and sessions may be active simultaneously. Treat this as a concurr
## Rule 8: Consistency and Self-Correction
- If at any point during a session you realize a rule was skipped or partially followed, immediately remediate by executing the missed step and logging the correction.
- Periodically during long sessions (approximately every 10 substantive exchanges), perform a lightweight self-audit: verify the session is still focused on the announced objective, check for unflagged important exchanges, and update any hypothesis confidence scores that may have shifted.
- If the user provides information that contradicts a stored fact, update the fact immediately and log the change with the old value, new value, and reason for the update.
- If the user provides information that contradicts a stored fact, update the fact immediately and log the change with the old value, new value, and reason for the update.
## Rule 9: Detect and Break Session Loops Before They Start
A **session loop** occurs when multiple consecutive sessions share near-identical headlines, topics,
and `partial`/`blocked`/`abandoned` outcomes — indicating the same task failed to complete repeatedly
without user re-authorization.
**Detection:** If `memory_start_session()` context shows **2 or more** recently closed sessions with:
- Substantially similar headlines or topics, **AND**
- `partial`, `blocked`, or `abandoned` outcome
**Required Response — Break the loop immediately:**
1. Do NOT attempt to resume or retry the repeated task silently
2. Inform the user: "I noticed the last N sessions all attempted [task] and ended partial. I won't auto-resume that. What would you like to do?"
3. Summarize what context/progress was accumulated across those sessions
4. Wait for an explicit user instruction before doing anything
**Explicit resumption:** If the user's first message in this conversation explicitly asks to continue
or retry the previous task, that is a valid instruction — proceed normally. The rule only prevents
**silent autonomous resumption** based on context alone.
**Mode interaction:** This rule applies regardless of mode. Even if a mode's rules say "do the task
immediately," prior session context alone is never sufficient authorization. Only the user's live
message in this conversation authorizes action.
+56
View File
@@ -0,0 +1,56 @@
# Anti-Loop Guardrail — Mandatory for All Modes
## ⛔ Never Resume Past Work Without Explicit User Authorization
This rule applies to **every mode** (code, architect, debug, pic-gen, ask, homelab, paisy, etc.)
and **overrides any mode-specific "do the task immediately" instructions**.
### The Core Prohibition
**Prior session context — including `partial`, `blocked`, or `abandoned` outcomes — does NOT
authorize beginning, resuming, or retrying any task.**
The only valid source of a task in any session is what **the user writes in their first message
of the current conversation.**
### What NOT To Do At Session Start
❌ Do NOT look at the last session headline and start that task
❌ Do NOT interpret `partial` outcome as "I need to finish this"
❌ Do NOT call `memory_announce_focus()` with a prior session's task before the user speaks
❌ Do NOT begin any creative, generative, or code-writing work based on context alone
❌ Do NOT assume "the user probably wants to continue" — ask if unsure
### What TO Do At Session Start
✅ Load context for **awareness only** — past sessions are reference, not instructions
✅ Announce focus as `"Awaiting user task assignment"` if the user has not yet spoken
✅ Wait for the user's first message before doing any substantive work
✅ If context shows a loop (2+ identical partial sessions), surface it explicitly and ask
### Session Loop Detection
If `memory_start_session()` context shows **2 or more** recently closed sessions with:
- Near-identical headlines or topics, AND
- `partial`, `blocked`, or `abandoned` outcome
**Stop. Do not resume.** Inform the user:
> "I noticed the last [N] sessions all attempted [task description] and ended partial.
> I won't auto-resume that — it's likely causing a loop. What would you like to do?"
Then wait for an explicit instruction.
### Exception: Explicit Resumption
If the user's **first message** in this conversation explicitly says to continue or retry
a prior task (e.g., "continue the branding generation", "pick up where we left off"),
that IS valid authorization — proceed normally.
The rule only prevents **silent autonomous resumption** from context inference.
---
*This file is loaded for all modes via `.roo/rules/`. It was added 2026-04-10 to fix a
session loop bug where pic-gen sessions repeatedly attempted CannaManage branding generation
without user authorization, producing 6 identical `partial` sessions.*