ELNOR REPO READER TEXT MIRROR Original path: Active Working and Red Team/DOC23 Working/DOC23 Non Operative Proposals/DOC23 Reprompt + Chat + Continuation.md Source repo: /Users/OpenClaw1/Elnor/Elnor Specs Git branch: main Git commit: dbaa25962edc11ab30e8d4ca1715f9ae5bf77331 Generated: 2026-06-09T01:23:58.539Z --- ## Three-section addendum proposal — analysis and decisions ### The decision One standalone addendum, three sections. Rejected: scattering edits across DOC23 R3.2 (too costly, and the three concerns turned out to share one mechanism — so a single package is cleaner than three sets of edits). Re-prompts, in-module chat, and the supporting session-continuation mechanics all extend the OpenClaw/Gateway session in the same way, so they belong together. ### §1 — Re-Prompt System (brief) Pre-scripted re-prompts (`re_prompts: string[]`) defined at design time, attached to specific module kinds: `agent_task`, `coding`, `agent_review_gate`, `red_team`. Author-time and deterministic — not interactive. Fires after the module's primary prompt, in sequence. Compilation points sit in DOC23. Treated as a **sibling** of the in-module chat (§2), not the same thing. Both extend the underlying session and share the §3 continuation mechanics, but they differ on who drives them (author vs user) and when (compile-time vs runtime). The shared plumbing is what makes packaging them together cheap. ### §2 — Module Activation Chat + TaskRunFork (the substantive new design) The central insight that drove the design: **chat is an input mechanism, not a destination.** Plenty of systems offer "chat with this step" and produce ambiguous behavior — does the chat change the run? does it teach the system? does it spawn a variant? The decision: separate the input (the chat itself) from the destinations (feedback, or fork), and make the user pick the destination explicitly via mode. #### ModuleActivationChat — three modes Chat is attached to any module activation, keyed `(module_id, activation_seq)`. Three modes: - **inspect (DEFAULT)** — Read-only conversation against a frozen snapshot of the activation. No state change. Use cases: "Why did you flag this?" / "What sources did you consider here?" / "What was your reasoning at this step?" The chat sees the activation's inputs, outputs, intermediate state, prompts, tool calls, but cannot mutate anything. Backed by a read-only OpenClaw session handle. - **advise** — The conversation produces a `HumanOutcomeFeedbackEvent` (a named-but-currently-undefined schema — needs to be defined as part of this work). That event flows into the existing Feedback Interpreter pipeline (V3.3.1 §14.3). This is teach-from-feedback reached conversationally instead of through a separate teach surface. - **branch** — The chat opens a `TaskRunFork` from this activation, carrying the chat's accumulated `user_directive` as `divergence_inputs`. The user's chat content becomes the fork's authorial reason. The three-mode structure means the user always knows what their words are doing. Inspect is safe by default: accidental chat with a module never mutates the run. Mutation is opt-in via mode switch. #### TaskRunFork — what makes the fork honest Fork point: `(module_id, activation_seq)` — any module activation, not just plan-internal checkpoints. Schema: ``` TaskRunFork { fork_id parent_run_id fork_point: { module_id, activation_seq } fork_disposition: "experimental" | "alternate_path" | "recovery" copied_workspace_refs: string[] // persistent SourceWorkspace copied; // ephemeral RunWorkspace re-derived divergence_inputs?: { user_directive?: string } irrevocable_side_effects_at_fork: Array<{ side_effect_kind: "external_send" | "external_tool_call" | "durable_promotion" | "candidate_accepted" receipt_ref: StorageRef }> created_at } ``` The critical design move: **side effects cannot branch.** An email already sent in the parent run is sent in every branch — the child can't unsend it. A durable promotion to the entity graph that happened before the fork point is present in both branches. A copy-on-write workspace model that implies these are reversible would create exactly the phantom-recovery failure mode this design is meant to avoid (and is the reason a literal Git-style ShadowWorkspace was declined in favor of this approach). The `irrevocable_side_effects_at_fork` field makes the un-undoable visible at the fork point itself. The fork-creation UI surfaces these explicitly: "this email was sent at activation 12; forking from activation 15 will not undo it." The user creates the fork knowing what is and isn't actually reversible. That single field is what makes fork-and-continue an honest primitive instead of a misleading one. `fork_disposition` exists so the system can treat the three kinds of fork differently in UI, retention, and learning: - **experimental** — trying a different approach to see if it's better; can be auto-cleaned after a retention window. - **alternate_path** — deliberate parallel exploration the user wants to keep; long retention; both branches may be referenced going forward. - **recovery** — something went wrong here; the fork is the recovery path; the parent run is the failure record. Recovery forks should never be auto-cleaned because they're part of the failure-and-fix narrative. User gestures: right-click any Run Board event → "fork from here," or, from in-module chat in branch mode, "open this as a fork." #### Why read-only inspect is the default The default-to-read-only choice matters because most chat-with-a-step interactions are diagnostic, not transformative. A user asking "why did this happen" should never accidentally mutate the run by asking. Making mutation explicit (the user must switch out of inspect mode to do it) prevents the whole class of "I was just asking a question and now my run is different" bugs. It also makes inspect mode safely available to reviewers and supervisors who shouldn't have mutation rights at all — the read-only handle naturally enforces the access boundary at the OpenClaw layer instead of relying on UI-level guards. #### Cross-doc obligations - **DOC23 R3.1** — supplies `TaskModuleSessionRef` and the port mechanics for attaching a chat session to an activation. - **DOC11 / OpenClaw** — supplies the read-only session handle (a session that exposes the activation's recorded state but cannot write to it). This is the part that requires native runtime support and is the most consequential dependency for this addendum. - **DOC15 (CIL)** — renders chat context into the LLM prompt **only in branch mode**. Inspect and advise don't feed back into a regenerated run, so they don't need CIL rendering; branch does, because branch starts a new child run that needs the directive injected. - **DOC20** — the three-mode UI toggle, the read-only visual treatment for inspect mode, the explicit-irrevocable-side-effects display in the fork-creation flow. ### §3 — Shared Module Session Continuation Mechanics The "boring" but load-bearing section: the underlying session-continuation primitive that both re-prompts and in-module chat use to extend the OpenClaw/Gateway session past the module's primary completion. Session continuity itself lives in **Addenda A §A9**; this section references it rather than redefining it. The point of factoring this as its own section is that re-prompts and chat aren't unrelated features that happen to use similar plumbing — they're two surfaces over one continuation mechanism. If a third feature later needs session continuation (likely; anything involving "extend the session for follow-up" will), the mechanics are already factored. If no third feature appears, this section is portable and can be folded into DOC23 R3.2 at absorption time without disturbing §1 or §2. ### Packaging summary - **One addendum, three sections.** The unit of work is the addendum; each section is independently understandable. - **Section dependencies:** §1 and §2 both depend on §3. §1 and §2 don't depend on each other (could ship one without the other). - **Suggested build order:** §3 first (the mechanics), then §1 and §2 in parallel. - **Next-build status:** this addendum is the next build after the current review round closes.