diff --git a/.roo/rules/00-identity.md b/.roo/rules/00-identity.md index 4849ea2..1e58a1a 100644 --- a/.roo/rules/00-identity.md +++ b/.roo/rules/00-identity.md @@ -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). \ No newline at end of file +- 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. \ No newline at end of file diff --git a/.roo/rules/01-bigmind-core.md b/.roo/rules/01-bigmind-core.md index 18a8222..317bd35 100644 --- a/.roo/rules/01-bigmind-core.md +++ b/.roo/rules/01-bigmind-core.md @@ -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. \ No newline at end of file +- 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. \ No newline at end of file diff --git a/.roo/rules/06-anti-loop.md b/.roo/rules/06-anti-loop.md new file mode 100644 index 0000000..ab39ab5 --- /dev/null +++ b/.roo/rules/06-anti-loop.md @@ -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.* diff --git a/plans/bigmind-loop-fix.md b/plans/bigmind-loop-fix.md new file mode 100644 index 0000000..0143ea4 --- /dev/null +++ b/plans/bigmind-loop-fix.md @@ -0,0 +1,149 @@ +# BigMind Session Loop — Root Cause & Fix Plan + +**Date:** 2026-04-10 +**Reported by:** Patrick +**Severity:** High — caused 6 identical wasted sessions with $0+ API cost per loop + +--- + +## Problem Statement + +BigMind's session ritual, combined with mode-specific behavior rules, creates a self-reinforcing +resumption loop when a session ends as `partial`. The model loads prior context, sees an incomplete +task, and autonomously attempts to resume it — without ever waiting for user input. This produces +a chain of identical `partial` sessions that only breaks when Patrick manually intervenes. + +Observed: 6 identical sessions titled *"Prepared large-scale CannaManage branding generation"*, +all `partial`, all spawned from one session ending before image generation completed in pic-gen mode. + +--- + +## Root Cause Analysis + +### Loop Trigger Chain + +``` +[Session N] ends partial (task: CannaManage branding generation) + │ + ▼ +[Session N+1] memory_start_session() → loads context + │ + │ Context shows: last outcome = partial + │ Rule 1: "search before every task, avoid redundant work" + │ → model reads: "prior task incomplete, I must finish it" + │ + ▼ +memory_announce_focus() called with prior session's task + │ → locks in wrong objective BEFORE user speaks + │ + ▼ +Mode rules (pic-gen) fire: "generate images now" + │ → autonomous action without user instruction + │ + ▼ +Hits context/token/tool limit → session ends partial + │ + └──────────────────────────────────────────► REPEAT +``` + +### Three Compounding Failures + +#### Failure 1: Rule 1 — No "partial = history only" clause +Rule 1 says to load context and search for prior work. It has **no explicit instruction** +that sessions marked `partial` are historical records, NOT resumption requests. +The model's default behavior is to treat incomplete work as a pending obligation. + +#### Failure 2: memory_announce_focus — Called on prior context, not current task +The architect rules say to call `memory_announce_focus()` as part of the startup ritual. +But when no user message has been received yet, the model has nothing to announce except +the prior session's objective — which is the wrong task for the new session. + +#### Failure 3: Mode interaction amplification +Modes with strong "do the task" personalities (pic-gen, code) compound the loop. When +context suggests "there's pending image generation work", pic-gen mode's instructions +say to start generating — creating autonomous action before the user speaks. + +--- + +## Fix Design + +### Fix 1: Rule 1 Addendum — Partial Sessions Are History + +Add explicit text to Rule 1 in `01-bigmind-core.md`: + +> **`partial`, `blocked`, or `abandoned` outcomes are historical records only.** +> They do NOT constitute task queues, resumption requests, or pending obligations. +> A new session begins fresh. The current session's task is determined solely by +> what the user writes in their first message — never by the outcome of a prior session. + +### Fix 2: New Rule 9 — Anti-Loop Guardrail + +Add Rule 9 to `01-bigmind-core.md`: + +> **Rule 9: Detect and Break Loops Before They Start** +> +> If `memory_start_session()` context shows 2 or more recently closed sessions with: +> - Near-identical headlines or topics, AND +> - `partial` or `blocked` outcome +> +> → **Do NOT attempt to resume the repeated task.** +> → Instead: acknowledge the loop to the user, summarize what context was accumulated +> across the repeated sessions, and ask: "What would you like to do?" +> +> Never assume the correct action is to retry a failed/partial task silently. + +### Fix 3: memory_announce_focus — Wait for User Input + +Add a constraint to Rule 3 (announce focus): + +> **`memory_announce_focus()` must reflect the CURRENT session's task.** +> Call it only AFTER the user has given a clear instruction for this conversation. +> Do NOT announce focus derived from prior session outcomes before the user speaks. +> During the startup ritual (steps 1-4 of Rule 1), use a placeholder focus if needed: +> `memory_announce_focus(session_id, "Awaiting user task assignment")` + +### Fix 4: Mode Interaction Safety Clause + +Add a universal safety rule (applies to all modes): + +> **Session ritual completion ≠ task authorization.** +> Completing `memory_start_session()` + `memory_list_hypotheses()` + `memory_announce_focus()` +> does NOT authorize beginning any task. Work begins only when the user explicitly assigns it +> in the current conversation. Prior session context is reference material, not instruction. + +--- + +## Files to Change + +| File | Change | +|------|--------| +| `.roo/rules/01-bigmind-core.md` | Add Rule 9, add partial=history clause to Rule 1, add focus guard to Rule 3 | +| `.roo/rules/00-identity.md` | Add mode-interaction safety clause | + +--- + +## Risk Assessment + +| Risk | Likelihood | Mitigation | +|------|-----------|------------| +| Model ignores new rules in long context | Medium | Rules are loaded via rules files, not context — they apply per-session | +| Fix breaks legitimate resumption (e.g., user explicitly asks to continue) | Low | Rules say "task determined by user's first message" — explicit resumption request still works | +| New Rule 9 fires falsely on legitimate repeated partial tasks | Low | Trigger requires near-identical headlines AND repeated partial — normal work produces diverse headlines | + +--- + +## Success Criteria + +1. Starting a new session after a partial pic-gen session → model waits for user input, no autonomous generation +2. Starting a new session after 2+ identical partial sessions → model acknowledges the loop and asks what to do +3. User explicitly asking "continue the branding generation" → model correctly resumes (rule only prevents silent resumption) + +--- + +## Implementation Order + +1. Patch `.roo/rules/01-bigmind-core.md` — add Rule 9 + partial=history clause + focus guard +2. Patch `.roo/rules/00-identity.md` — add mode interaction safety clause +3. Test by starting a new session in pic-gen mode with partial history in context +4. Push to Gitea +