Browse Source

fix: revert codemaps to match shipped behavior (drop unmerged #795 claims)

Michael Henke 2 weeks ago
parent
commit
0c20741c4c

+ 1 - 1
.slim/codemap.json

@@ -1,7 +1,7 @@
 {
   "metadata": {
     "version": "1.0.0",
-    "last_run": "2026-07-16T23:19:53.828Z",
+    "last_run": "2026-07-16T23:33:10.792Z",
     "root": "/home/mhenke/Projects/oh-my-opencode-slim/.slim/worktrees/update-codemaps-796",
     "include_patterns": [
       "src/**/*.ts",

+ 7 - 17
src/hooks/foreground-fallback/codemap.md

@@ -16,8 +16,7 @@ Runtime model fallback system for foreground (interactive) agent sessions. When
   - `sessionModel`: Maps sessionID → current model string ("providerID/modelID")
   - `sessionAgent`: Maps sessionID → agent name
   - `sessionTried`: Maps sessionID → Set of models already attempted
-  - `inProgress`: Set of sessions with active fallback in flight (strict — cleared in `finally` so the genuine fallback-response idle still reconciles)
-  - `lastFallbackAt`: Maps sessionID → timestamp of last accepted re-prompt; `wasFallbackRecent()` returns true within `FALLBACK_GRACE_WINDOW_MS` (5s), letting task-session-manager suppress spurious abort-induced cancellations without blocking the genuine idle (issue #765)
+  - `inProgress`: Set of sessions with active fallback in flight
   - `lastTrigger`: Maps sessionID → timestamp for deduplication
 
 ### Fallback Chain Resolution
@@ -38,9 +37,7 @@ Runtime model fallback system for foreground (interactive) agent sessions. When
 ### State Management
 - **Deduplication window**: 5-second cooldown (`DEDUP_WINDOW_MS`) to prevent multiple triggers for same rate-limit event
 - **Session cleanup**: `session.deleted` event handler removes all per-session state to prevent memory leaks
-- **In-progress tracking**: Prevents concurrent fallback attempts on same session (`inProgress`, cleared in `finally`)
-- **Grace window**: `wasFallbackRecent()` stays true for 5s after a successful re-prompt — distinct from the strict in-flight flag — so late abort-induced `session.deleted` and cancelled/error status are suppressed while the genuine fallback-response idle still reconciles (issue #765)
-- **Retry-without-abort**: When `promptAsync` throws on a busy session (original rate-limited response still in flight), retries up to `FALLBACK_REPROMPT_RETRIES` (3) without aborting. Abort is kept as last resort only (avoids "Task cancelled" in parent, issue #765)
+- **In-progress tracking**: Prevents concurrent fallback attempts on same session
 
 ## Flow
 
@@ -52,22 +49,17 @@ ForegroundFallbackManager.handleEvent()
 Retryable error detection via isRetryableError()
-tryFallback(sessionID) or tryFallbackWithAbort(sessionID)
-    [deduplicated, in-progress guarded]
-    ↓
-Abort current rate-limited prompt (with timeout) [tryFallbackWithAbort only]
+tryFallback(sessionID) [deduplicated, in-progress guarded]
 Resolve fallback chain for session
+Abort current rate-limited prompt (with timeout)
+    ↓
 Retrieve last user message from session history
-execFallback(sessionID)
-  ├─ Re-prompt with next model via promptAsync()
-  │   (busy session: retry up to 3x without abort; abort only as last resort)
-  ├─ markFallbackDone(sessionID) — arms 5s grace window
-  └─ Update session state with new model
+Re-prompt session with next model via promptAsync()
-tryFallback/tryFallbackWithAbort finally: clear inProgress
+Update session state with new model
 Log fallback event
 ```
@@ -77,8 +69,6 @@ Log fallback event
 2. **Message retrieval**: Queries session messages via `client.session.messages()` and finds last user message
 3. **Model switching**: Uses `parseModelReference()` to extract providerID/modelID from chain entry
 4. **Re-prompting**: Calls `promptAsync()` which queues prompt and returns immediately (non-blocking)
-5. **Retry-without-abort**: When `promptAsync` throws on a busy session, retries up to `FALLBACK_REPROMPT_RETRIES` (3) without aborting. Abort is last-resort only if the session never settles — avoids triggering "Task cancelled" in the parent orchestrator (issue #765)
-6. **Grace window**: `markFallbackDone()` records the time of successful re-prompt; `wasFallbackRecent()` exposes a 5s window for task-session-manager to suppress abort artifacts
 
 ## Integration
 

+ 5 - 26
src/hooks/task-session-manager/codemap.md

@@ -8,8 +8,8 @@ Manages V2 background job-board state for task execution and injected completion
 
 The directory follows a **Facade + Strategy** pattern where `index.ts` acts as the facade that composes and orchestrates behavior across three specialized strategy modules:
 
-- **index.ts**: Main facade that wires hooks into OpenCode's lifecycle and coordinates between the job board, pending calls, and task context tracking. Implements the plugin hook interface (`tool.execute.before`, `tool.execute.after`, `experimental.chat.messages.transform`, `event`). Accepts `wasFallbackRecent`, `isFallbackInProgress`, and `onJobTerminal` callbacks for coordination with `foreground-fallback`.
-- **pending-call-tracker.ts**: Tracks in-flight task calls using a capped ordered map (`MAX_PENDING_TASK_CALLS`) to correlate launch output safely. Provides call ID generation, storage, `findByParent`, `peekByParent` (used for early `session.created` registration, issue #765), and cleanup.
+- **index.ts**: Main facade that wires hooks into OpenCode's lifecycle and coordinates between the job board, pending calls, and task context tracking. Implements the plugin hook interface (`tool.execute.before`, `tool.execute.after`, `experimental.chat.messages.transform`, `event`).
+- **pending-call-tracker.ts**: Tracks in-flight task calls using a capped ordered map (`MAX_PENDING_TASK_CALLS`) to correlate launch output safely. Provides call ID generation, storage, retrieval, and cleanup for pending task invocations.
 - **task-context-tracker.ts**: Manages read context from child sessions with line-count and file caps. Stores context per task ID and provides pruning to prevent unbounded growth.
 
 All modules depend on `BackgroundJobBoard` from `src/utils/background-job-board.ts` as the single source of truth for active jobs, terminal unreconciled jobs, reusable completed sessions, aliases, read context, and LRU caps.
@@ -36,10 +36,8 @@ All modules depend on `BackgroundJobBoard` from `src/utils/background-job-board.
 2. **Task Launch (`tool.execute.after`)**
    - Registers task launches in the job board with task ID, parent session ID, agent type, and description
    - Parses task output to extract task ID, status, or launch information
-   - Suppresses spurious cancelled/error status within the fallback grace window (issue #765)
    - Adds read context to the job board for completed or terminal unreconciled tasks
    - Handles late-cancelled tasks by normalizing output and updating state accordingly
-   - Fires `onJobTerminal` when a task reaches a terminal state
 
 3. **Context Tracking**
    - Extracts read files from `read` tool outputs using `extractReadFiles`
@@ -48,40 +46,24 @@ All modules depend on `BackgroundJobBoard` from `src/utils/background-job-board.
 
 4. **Message Injection (`experimental.chat.messages.transform`)**
    - Injects a `<system-reminder>` part containing the `### Background Job Board` section into user messages for managed sessions
-   - Updates existing board parts in-place (replaces text on existing synthetic parts rather than creating duplicates)
    - Lists active, unreconciled, and reusable sessions
    - Remembers injected terminal jobs to reconcile them on parent idle events
-   - Fires `onJobTerminal` when an injected completion makes a job terminal
 
 5. **Lifecycle Events (`event`)**
-   - `session.created`: Adds new task IDs to pending managed set; performs early board registration via `peekByParent` when a `parentID` is present (issue #765)
-   - `session.idle` / `session.status` (idle): Reconciles injected terminal jobs for the parent session; skips idle reconciliation when `isFallbackInProgress`; fires `onJobTerminal` for terminal jobs
+   - `session.created`: Adds new task IDs to pending managed set
+   - `session.idle` / `session.status` (idle): Reconciles injected terminal jobs for the parent session
    - `session.status` (busy): Marks sessions as running from live session state
-   - `session.status` (injected completion): Suppresses cancelled/error status within the fallback grace window; fires `onJobTerminal` for terminal state transitions
-   - `session.deleted`: Clears job state, child jobs, pending call records, and `terminalJobNotified` entries
-   - Phantom job cleanup: When `isFallbackInProgress`, drops the single phantom running job (exactly one other running job for the parent) during `session.created` nets
+   - `session.deleted`: Clears job state, child jobs, and pending call records for the session
 
 ### Data & Control Flow
 
 ```
 User task call → tool.execute.before → PendingTaskCall created → task ID resolved/reused
-→ session.created → early board registration via peekByParent (issue #765)
 → tool.execute.after → BackgroundJobBoard.registerLaunch() → context extracted/added
-    │  (suppress cancelled/error within fallback grace window)
-    └─ onJobTerminal(parentSessionID) if terminal
 → Message transform → BackgroundJobBoard.formatForPrompt() injected as a system-reminder message part
-    │  (update existing board parts in-place; fire onJobTerminal for new terminals)
 → session.idle → reconcileInjectedTerminalJobs() → BackgroundJobBoard.markReconciled()
-    │  (skip if isFallbackInProgress; fire onJobTerminal)
-→ session.deleted → cleanup all per-session state
 ```
 
-### Fallback Coordination (issue #765)
-The hook coordinates with `foreground-fallback` via three callbacks:
-1. **`isFallbackInProgress(sessionID)`**: When true, idle events for the parent and children are skipped, and phantom jobs are cleaned up during `session.created` nets
-2. **`wasFallbackRecent(sessionID)`**: When true (within 5s of `markFallbackDone`), cancelled/error status updates from the abort are suppressed in both injected-completion and `tool.execute.after` paths — the job stays running so the genuine fallback-response idle can reconcile it
-3. **`onJobTerminal(parentSessionID)`**: Fires when a background job reaches terminal state via injected completion, `tool.execute.after`, or `session.idle` reconciliation — prompts the parent orchestrator with `(Background job completed.)` so it re-evaluates even when no child idle fires
-
 ## Integration
 
 ### Consumers
@@ -100,9 +82,6 @@ The hook coordinates with `foreground-fallback` via three callbacks:
 - `readContextMinLines`: Minimum lines to include in read context
 - `readContextMaxFiles`: Maximum files to include in read context
 - `shouldManageSession`: Predicate to determine which sessions are managed by this hook
-- `wasFallbackRecent?`: Callback to check if a fallback re-prompt was accepted within the grace window (5s). When true, cancelled/error status updates are suppressed (issue #765)
-- `isFallbackInProgress?`: Callback to check if a session is mid-fallback. When true, idle events are skipped and phantom jobs are cleaned up
-- `onJobTerminal?`: Callback fired when a background job reaches a terminal state; nudges the parent orchestrator via `promptAsync` to re-evaluate
 
 ### Events & Hooks