Elnor Repo Reader

DOC23 Add B Review Studio D1.md

Active Working and Red Team/DOC23 Working/DOC23 Non Operative Proposals/DOC23 Add B Review Studio D1.md

Short text page 0b76311a80ec. Generated 2026-06-09T01:23:58.539Z from commit dbaa25962edc11ab30e8d4ca1715f9ae5bf77331. Worktree: clean.

Open readable HTML page · Open raw txt · Open path URL

ELNOR REPO READER TEXT MIRROR
Original path: Active Working and Red Team/DOC23 Working/DOC23 Non Operative Proposals/DOC23 Add B Review Studio D1.md
Source repo: /Users/OpenClaw1/Elnor/Elnor Specs
Git branch: main
Git commit: dbaa25962edc11ab30e8d4ca1715f9ae5bf77331
Generated: 2026-06-09T01:23:58.539Z

---

````
# DOC23 Addenda B — Review Studio (Human Review & Agent-Assisted Revision)

**Type:** Design spec unit (draft, pending architect review + multi-LLM red-team).
**Target home:** `Current Specs/DOC23/DOC23 Addenda B/` (new module). Liftable into the consolidated adjudication card as a section; the card otherwise carries a one-line pointer.
**Module type id:** `step.review_studio`
**Status of dependencies:** A-01 finding model (event/record/view + `EvaluationAuthorityBasis`) is summarized in §2 at the level Review Studio relies on; its full adjudication remains a card Layer-1 item. The Gemini math/C-cluster audit is unrelated and remains a card row.

**Grounding rule (no phantom features):** every contract below traces to a cited section in DOC23 R3.1, Outcome Evaluator-Revisor V3.3.1, DOC20 R4.3, or DOC23 Addenda B Core R0.7.1 — or is explicitly flagged `OPEN_FOR_ARCHITECT_REVIEW`. Citations are inline. Appendix B is the consolidated operative-vs-net-new log.

---

## 0. Scope and non-goals

### 0.1 In scope
- The `step.review_studio` module (placeable form) and the intrinsic evaluate-revise gate (policy-toggled form).
- The complete human-review **input model** (`HumanReviewResult`, defined as a superset of DOC20's `DocumentReviewRequest`).
- **Materialization** of human comments into lifecycle-tracked objects (findings / run-scoped criteria) so they resurface across re-evaluation.
- The **agent-collaboration** layer: session continuity to the producing agent + the agent-selection ladder + agent-assisted in-place revision.
- The **output/routing** model and how it decomposes into the existing Feedback Interpreter pipeline (V3.3.1 §14).
- **Versioning / provenance / revalidation** wiring for human and co-authored edits.
- The **exposure** primitives: `LifecycleActorEnvelope`, the per-owner read contract, the gated (reserved) write capability.

### 0.2 Non-goals (explicit `slice.negative_space`)
- **NOT** redoing the automated Revisor's graph orchestration (V3.3.1 §6–§11). Review Studio does not plan or dispatch across the task graph (§1.2).
- **NOT** rewriting DOC20 UI mechanics beyond the review surface. DOC20-owned changes are collected, clearly labeled and liftable, in Appendix A. UI here is specified to **mockup-ready** depth (contracts tight, UI light).
- **NOT** building the Human-Review→Orchestrator engine or the review-gate learning-reasoner. Both are reserved (§11).
- This unit does **not** touch the memory-spec flatten. DOC23 is outside the flatten scope (Flatten plan §1.2); findings/comments/revisions remain DOC23/DOC20-owned task-system truth, not memory-system truth.

---

## 1. The module, and the boundary against the automated Revisor

### 1.1 One paragraph
Review Studio is a task-graph checkpoint where the human (a) reviews an output, (b) optionally **collaborates with the agent that produced it** — its working session resumed — to revise the artifact **in place** or get advice, and (c) **routes** the (possibly revised) version onward. It is the interactive, collaborative form of the current `step.user_review_gate` (DOC23 R3.1 §3.2.3): same "pause the run, human decides" spine, but with the DOC20 Document Viewer as the review surface and an agent-assist channel attached.

### 1.2 Boundary vs the automated Revisor (load-bearing — prevents two orchestrators)
| | Automated Revisor (V3.3.1 §6–§11) | Review Studio (this unit) |
|---|---|---|
| Driver | Agent-automated | Human-driven, agent-assisted |
| Operates on | The **task graph** (re-runs modules, escalates to Task Agent §6.9, forks) | **One artifact, in place** |
| Trigger | Findings / outcomes (revalidation cascade) | Human at a checkpoint |
| Output | Repaired graph state + new artifact version | Revised artifact version + a routing decision |
| Orchestration | Yes (RevisionPlan, RevisionDispatcher §11.1) | **No** — it co-edits one output, then hands off |

They **compose**: Review Studio's revised version can be routed into the automated loop, and the automated loop's output can land at a Review Studio checkpoint. The agent-assist inside Review Studio is a **scoped single-artifact edit** the human directs (the producing agent makes the changes), producing a new co-authored version — it is explicitly *not* a graph redo. This boundary is the reason the two do not collide.

### 1.3 Relationship to the other checkpoints
Review Studio is the **human-driven** checkpoint; it does not replace the other DOC23 review constructs:
- `step.agent_review_gate` (R3.1 §3.2.4) remains the **agent-reviews-agent** checkpoint.
- `step.panel` (R3.1 §3.2.5), a pointer to a DOC12 room, is the **forum** rung of the assist ladder (§6.1), used for multi-agent collaborative review.
- The `human_review_gate` experiment-winner **routing disposition** (Addenda A R227) opens a Review Studio surface when an experiment routes to human review.

---

## 2. Foundational dependency — the finding model (A-01), as relied on here

Review Studio renders Evaluator findings as anchored comments and lets the human dispose them; it also creates human-authored findings. It therefore depends on the A-01 finding model. The elements relied on (full definition and adjudication: card Layer 1):

```ts
// Immutable audit record of a finding as first observed in a given evaluation round.
interface EvaluationFindingEvent {
  finding_event_id: string
  outcome_id: string
  target_artifact_ref: string
  target_version_ref: string                 // findings are version-pinned (V3.3.1 §5.7)
  target_scope_ref: TargetScopeRef | null     // the anchor; maps to a DOC20 CommentAnchor (§3.6)
  detected_at: string
  severity: FindingSeverity                    // IMPORTANCE, never a halt (§2.1)
  assurance_basis: AssuranceBasis[]            // how much trust the finding carries
  authority_basis: EvaluationAuthorityBasis[]  // who/what authorizes it (9-value FD enum)
  body: string
  schema_version: 1
}

// Mutable lifecycle row keyed to the event; carries current state.
interface EvaluationFindingRecord {
  finding_id: string
  origin_event_id: string
  state: FindingState                          // V3.3.1 §5.7 / §0.4.4
  target_version_ref: string
  actor: LifecycleActorEnvelope                // §9.1 — who created/last-changed it
  superseded_by_finding_id: string | null
  resolved_by_receipt_ref: string | null       // only Revisor receipts mark `resolved` (§5.7.2)
  schema_version: 1
}

// Read-only projection the UI renders (the "copy"). No new truth store.
interface FeedbackFindingView {
  finding_id: string
  display_state: FindingState
  anchor: TargetScopeRef | null
  severity: FindingSeverity
  body: string
  history: FindingStateTransition[]            // per-round snapshots → cross-round drift view
  schema_version: 1
}
```

### 2.1 Severity is importance, not a halt (propagated decision)
`FindingSeverity` drives revision priority and human-review surfacing. It **never halts** the run. Only mechanical/system errors halt execution (`StepExecutionFailureKind`, DOC23 R3.1). An output is not auto-"passed" while serious findings are unresolved; it stays in the revision loop, and if unresolvable the termination logic (V3.3.1 §6.7.3) **escalates** (Gate-4 human review or "rely with limitations") rather than halting. Irreversible external actions (filing, sending) remain gated by an action permission — that is an action gate, not a finding block.

---

## 3. Input model — everything the user can submit at a Review Studio checkpoint

### 3.1 Complete input taxonomy (grounded in the current modules)
From the DOC23 gate (R3.1 §3.2.3 / §6.5.4) and the DOC20 review surface (§6.6.2, §6.10.4, §6.16.8):

1. **Decision** — Approve / Reject / Revise (incl. email APPROVE/REJECT/REVISE). [DOC23 §3.2.3]
2. **Rejection reason** (free text). [DOC23 §6.5.4]
3. **General instruction** (free text). [DOC23 textarea; DOC20 Send-to-Agent `instruction`]
4. **Attachments** (FileRef[]). [DOC23 revision payload; DOC20 §7.18]
5. **Anchored in-line comment** — `CommentAnchor` (text/page/line) + body + threaded replies. [DOC20 §6.6.2/§6.6.3]
6. **General / unanchored comment** — `UnanchoredAnchor`. [DOC20 §6.6.2]
7. **Comment status change** — open/resolved/deleted. [DOC20 §6.6.2]
8. **Per-tracked-change accept/reject** (+ Accept/Reject All). [DOC20 §6.10.4/§6.10.5]
9. **Direct document edit** → new version. [DOC20 §6.16.9/§6.16.11]
10. **Per-finding disposition** — Accept / Reject / Reject-with-modification + comment (this unit, built on DOC20 comment affordances + A-01).
11. **Send-to-Agent controls** — `context_scope`, `output_mode` (respond_in_chat | send_with_instructions), `result_format` (revise_artifact | convert_to_note | respond_in_comments), `agent_id`, `chat_id`. [DOC20 §6.16.8]

### 3.2 `HumanReviewResult` — defined as a superset of DOC20 `DocumentReviewRequest`
DOC20 already owns the human-review→agent request/response contract (`DocumentReviewRequest` / `DocumentReviewResultEvent`, §6.16.8). Review Studio does **not** create a parallel request schema; it **extends** that contract with the evaluate-loop layer. (Owner-boundary note → OP-A, §12.)

```ts
// Reuses DOC20 DocumentReviewRequest fields (agent_id, chat_id, context_scope,
// selected_comment_ids, comments[], instruction, output_mode, result_format)
// and adds the evaluate-loop fields below.
interface HumanReviewResult extends DocumentReviewRequest {
  review_id: string
  task_id: string
  run_id: string
  gate_id: string                              // placeable module id OR intrinsic gate id (§4)

  // --- interaction axis (ADD #1; closes the advise-vs-revise gap) ---
  interaction_mode: "revise" | "advise"        // advise = no document mutation; answer in chat/comments

  // --- top-level decision (only meaningful for interaction_mode = "revise") ---
  decision: "approve" | "send_for_revision" | "reject"  // terminal; see §5.4 action model
  rejection_reason: string | null              // + honors DOC23 on_reject_action (pause|redirect|abort)
  redirect_target_ref: string | null           // when on_reject_action = redirect (R3.1 §3.2.3)

  // --- structured dispositions ---
  finding_dispositions: FindingDisposition[]   // per-finding accept/reject/modify + comment + anchor
  general_directives: GeneralDirective[]       // unanchored comments/instructions → run-scoped criteria
  tracked_change_dispositions: TrackedChangeDisposition[] | null  // ADD #5 (signal of which Revisor edits were rejected)

  // --- artifact + provenance ---
  reviewed_artifact_version_ref: string        // NEW version if edited, else the reviewed version
  artifact_edited_by_human: boolean
  edit_provenance: "none" | "human_direct" | "human_directed_agent"  // co-authored when agent assisted (§6.3)

  // --- routing + follow-up ---
  routing: ReviewRoutingDecision               // §7
  requested_followup: FollowupIntent[] | null  // multi-step intent captured as data (reserved engine, §11)

  // --- attachments (ADD #6) ---
  attachments: AttachmentRef[]                  // review-global; per-disposition attachments live on the disposition

  actor: LifecycleActorEnvelope                 // §9.1
  ui_source: ReviewUiSource                     // ADD #8
  created_at: string
  schema_version: 1
}

type ReviewUiSource =                           // extends DOC20/V3.3.1 ui_source enums
  | "review_studio_card" | "document_viewer" | "email_reply" | "api"

interface FindingDisposition {
  finding_id: string | null                    // null => a NEW anchored comment that becomes a finding (§3.5)
  anchor: TargetScopeRef | null                // DOC20 CommentAnchor (§3.6)
  disposition: "accept" | "reject" | "reject_with_modification"
  comment: string | null                       // the modification / rationale
  authority_class: HumanFeedbackAuthorityClass // V3.3.1 §14.6 (controlling vs advisory)
  research_request: ResearchNeedRef | null     // optional (Grok §5.9 import)
  attachments: AttachmentRef[] | null
}

interface GeneralDirective {
  directive_id: string
  text: string
  scope: "this_artifact_goal" | "this_outcome" | "this_run"
  authority_class: HumanFeedbackAuthorityClass
  attachments: AttachmentRef[] | null
}

interface TrackedChangeDisposition {           // DOC20 §6.10.5 produces tracked_change_accept/reject
  change_id: string
  decision: "accept" | "reject"
}
```

### 3.3 `requested_result_format` (ADD #2)
The DOC20 `result_format` field (`revise_artifact` | `convert_to_note` | `respond_in_comments`) sets the downstream output contract. It is carried on `HumanReviewResult` (inherited from `DocumentReviewRequest`) and is authoritative for what the assisting agent returns. `respond_in_comments` / `respond_in_chat` imply `interaction_mode = "advise"`.

### 3.4 `context_scope` and agent/chat targeting (ADD #3, #4)
`context_scope` (`full` | `comments_only` | `selected_comments`) and `agent_id` / `chat_id` are inherited from `DocumentReviewRequest`. `agent_id` lets the human **re-target** which agent handles the assist — this is the user-facing override of the routing in §6. Default resolution is the producing agent's session (§6.2).

**Channel limits:** the email-reply channel (R3.1 §3.2.3) carries only the coarse decision (APPROVE/REJECT/REVISE) plus free-text revision and attachments; anchored per-finding dispositions and in-place edits require the Document Viewer surface (§5).

### 3.5 Materialization — the mechanism that makes comments persist across re-evaluation
The Feedback Interpreter (V3.3.1 §14.3) is a one-shot intake service; resurfacing comes from the **finding/outcome lifecycle**, not from the Interpreter. Review Studio therefore materializes inputs into lifecycle objects at intake:

- **Anchored comment / per-finding modification → a human-authored `EvaluationFindingEvent`** (`assurance_basis` includes `human_label`; `target_version_ref` pinned; `target_scope_ref` = the anchor). It then rides `findings_to_address` (V3.3.1 §7.1), the Revision Compiler routes it to a module (§6.4), and the finding lifecycle resurfaces it every re-evaluation until `resolved` / `superseded_by_revision` / `unrecoverable` (§5.7). Finding creation by a human actor is authorized via §9.1 (`author_kind = "human"`).
- **General directive → a run-scoped `Criterion`** on the run's `EvaluationOutcomeDefinition` (V3.3.1 §5.1.1), minted by the Outcome Compiler from the directive text. The Evaluator then re-checks it on every re-evaluation, version-independently, until satisfied; a failing criterion yields a finding (outcome-level, `target_criterion_id = null`) that routes like any other.

Extend `InterpretedOutcomeFeedback` (V3.3.1 §14.3.1) output accordingly:
```ts
interface InterpretedOutcomeFeedback {
  // existing:
  proposed_revision_request?: RevisionRequest          // V3.3.1 §14.4 (current run)
  proposed_durable_candidate?: DirectInstructionCandidate  // V3.3.1 §14.7 (teaching)
  // ADD:
  proposed_findings?: EvaluationFindingEvent[]         // span corrections (anchored)
  proposed_run_criteria?: RunScopedCriterion[]         // goal corrections (general)
}
```

#### 3.5.1 Governance guardrails on run-scoped criteria
- Human-authored, **scoped to this run only** — never raises the pass bar for any other run.
- **Inspector-visible** with provenance ("added from your review comment").
- Outcome-set mutation in the revision path is already contemplated (`added_outcome_id`, V3.3.1 §11 status model), so this is not a foreign construct.

### 3.6 Comment ↔ finding reconciliation (ADD #7)
- A finding's `target_scope_ref` maps onto a DOC20 `CommentAnchor` (text/page/line/unanchored). Click-finding→highlight is the existing click-comment→highlight behavior (DOC20 §6.6.7).
- Map comment-status ↔ finding-state: DOC20 `orphaned` ↔ A-01 `superseded_by_revision`; `resolved` ↔ the finding's resolved/dismissed state. The conversational thread (DOC20 §6.6.3, event-sourced) stays DOC20-owned; dispositions carry `thread_root_id` so the exchange is linked, not duplicated.

---

## 4. The hybrid gate — placeable module + intrinsic loop gate

### 4.1 Placeable module `step.review_studio`
A drop-in checkpoint for arbitrary points in a graph. Superset of `step.user_review_gate` (R3.1 §3.2.3).

```
Config (adds to user_review_gate config):
  review_instructions: string
  surface: "review_studio"                     // opens the DOC20 Document Viewer in review mode (§5)
  load_findings: boolean                       // load Evaluator findings as anchored finding-comments
  allow_agent_assist: boolean                  // enable the collaboration channel (§6); default true
  default_assist_target: "producing_agent" | "task_agent" | "none"   // default producing_agent (§6.2)
  interaction_modes_allowed: ("revise" | "advise")[]                 // default both
  on_reject_action: "pause" | "redirect" | "abort"                    // R3.1 §3.2.3
  redirect_target / max_redirects / max_revisions                     // R3.1 §3.2.3
  revision_delivery: "wired_target" | "to_revisor" | "to_producing_module" | "auto_previous" | "smart"

Ports:
  data_in        (Input)  — content to review
  findings_in    (Input, optional) — A-01 finding views; presence => load as finding-comments
  plan_in        (Input, optional) — a Revisor RevisionPlan; presence => plan-review layout
  approved_out   (Output) — fires with the (possibly revised) version on Approve / proceed
  rejected_out   (Output) — fires with rejection_reason + payload
  revision_out   (Output) — fires with the full HumanReviewResult (decomposed downstream, §7)
  feedback_out   (Output, optional) — teaching feedback (HumanOutcomeFeedbackEvent) only
  signal_out     (Output) — "decision made" (fires regardless)
  error_out      (Output) — notification-delivery failure only
```
Typed `findings_in` / `plan_in` make the graph self-documenting and let the surface adapt (§5.2).

### 4.2 Intrinsic gate (no wiring, no Loop Controller)
The evaluate-revise loop raises a Review Studio gate automatically at its natural points, toggled by per-task/outcome policy — same Review Card, no module wiring, and **no Loop Controller** (avoids the R3.1 §6.2 re-activation wart, since the loop owns re-activation):

```ts
type IntrinsicGatePoint =
  | "post_evaluation"        // after Evaluator, BEFORE Revisor plans (findings review)
  | "post_revision_plan"     // review the Revisor's plan before execution
  | "post_revision_exec"     // review a produced revision
  | "pre_final_acceptance"   // final-pass review before reliance

interface IntrinsicReviewGatePolicy {
  enabled_points: IntrinsicGatePoint[]
  // defaults: post_evaluation/plan/exec OFF; pre_final_acceptance ON (Gate-4)
  default_assist_target: "producing_agent" | "task_agent" | "none"
  schema_version: 1
}
```
Timing correction: findings review is **after the Evaluator / before the Revisor**, not "when the task finishes."

---

## 5. The review surface (review mode over the DOC20 Document Viewer)

### 5.1 Reuse, don't rebuild
The gate opens the **DOC20 Document Viewer** (§6.16) in a `doc` tab in "review mode" rather than rendering a minimal Review Card body. This reuses the Word (mammoth.js), PDF (PDF.js), Markdown/code renderers, the tabbed right panel `[Comments][Send to Agent]` (§6.16.6/§6.16.8), anchored comments (§6.6.2), tracked changes (§6.10), and Convert-to-Note editing (§6.16.9). Findings load into the Comments panel as a **`finding` comment kind**, anchored via `target_scope_ref` → `CommentAnchor`. The legacy Review Card (R3.1 §13.9) remains the lightweight fallback for text-only review.

### 5.2 Surface adapts to inputs (per the typed ports, §4.1)
| Inputs present | Surface |
|---|---|
| `data_in` only | Document preview; Comments panel empty/closed |
| `data_in` + `findings_in` | Findings as anchored finding-comments; per-finding actions (§5.3) |
| `findings_in`, no doc focus | Finding list / chat-style review |
| `plan_in` | Plan-review layout: plan steps as side-panel items with approve / drop / modify |

`RendererCapabilities` (DOC20) hides actions a renderer cannot support (e.g., inline editing on a preview-only DOCX). UI depth here is **mockup-ready**; pixel/interaction detail and all new DOC20 surfaces are in Appendix A.

### 5.3 Per-finding actions
Accept / Reject / Reject-with-modification, each with an optional comment box (Word-comment ergonomics). Maps to `FindingDisposition` (§3.2). Reject-with-modification supplies the corrective instruction that the assist agent or Revisor consumes.

### 5.4 Action model — three layers, and what "Revise" means
Actions at the surface fall into three distinct layers; conflating them is what made "Revise" ambiguous.

**Layer 1 — Per-finding / per-comment actions** (Comments panel): Accept / Reject / Reject-with-modification + comment (§5.3). These dispose individual items; they do not end the checkpoint.

**Layer 2 — In-Studio collaboration** (chat / assist / edit), which loops and does **not** end the checkpoint:
- **Discuss** — advise mode (`interaction_mode = "advise"`): ask the assist agent, no document mutation.
- **Revise with Agent** — the agent edits the artifact in place (`AssistRevisionRequest`, §6.3) -> new version, addressing your comments/instructions **here, now**.
- **Edit** — you edit directly -> new version (§8.1).

**Layer 3 — Terminal decision** (ends the checkpoint, fires a port + routing, §7.1): **Approve / Proceed**, **Send for Revision**, **Reject**.

**The two meanings of "revise":** the terminal **Send for Revision** routes the artifact **plus your dispositions/directives** to a revision *target* (Revisor / producing module / wired target / next step) to be addressed *elsewhere* — the original `revision_out` semantics, with your comments/instructions as the payload. Layer-2 **Revise with Agent** addresses the same comments/instructions *in place*. Both "address comments and instructions"; the difference is **where**.

**After an in-place revision** no new terminal button is needed — Approve/Proceed, Send for Revision, Reject still cover "what next." Refinements: the **Approve** label is context-aware ("Approve" for review-only; "Accept revision & continue" after an in-place revision); **Send for Revision** carries a target picker (next step · Revisor · specific module · Task Agent · forum). The genuinely new controls are the Layer-2 affordances (Discuss / Revise with Agent / Edit) — what was missing, not a fourth terminal button.

---

## 6. Agent collaboration — session continuity and the agent-selection ladder

### 6.1 The ladder (all rungs map to operative primitives)
| Rung | Mechanism | Citation |
|---|---|---|
| Producing agent, **same session** (default) | Module session continuation via `TaskModuleSessionRef` + `session_persist` | Core R0.7.1 §3170/§3449/§10363; Reprompt §7.1 → Addenda A §A9 |
| Producing agent, **new scoped thread** | Module follow-up session (`followup_session_id`) | Core R0.7.1 §261/§9397 |
| **Another module's** agent | Select by `module_ref` → its session | Core R0.7.1 §10363 |
| **Task Agent** | Task Agent contextual side-panel chat (task/run/module/artifact scope, attachments) | Core R0.7.1 §260/§9604 |
| **Forum** | DOC12 room (Plan Review Forum / role-scoped critique) | V3.3.1 §14.9 |
| **Branch the run** | `TaskRunFork` | Core R0.7.1 §8622 |

### 6.2 Default target resolution
The default assist target is the **producing agent, session resumed**, resolved from the artifact's provenance: the module/run that produced `reviewed_artifact_version_ref` → its `TaskModuleSessionRef`. The picker's candidate list = "agents involved in this task" (derivable from the run graph) + Task Agent + forum, with the producer pre-selected. `agent_id` on `HumanReviewResult` (§3.4) is the explicit override. If the producing module is not an agent (a deterministic module) or has no resumable session, the default falls back to the Task Agent — or to `none` (review-only) when `allow_agent_assist = false`.

### 6.3 Agent-assisted in-place revision (the scoped op)
When the human asks the assist agent to make a change, the agent — its session resumed so it knows how the output was produced — edits **this artifact only** as directed, producing a new version with `edit_provenance = "human_directed_agent"` and a co-authored `LifecycleActorEnvelope` (`author_kind = "module"`, with the directing human recorded). This is **not** the automated Revisor's graph plan (§1.2); it is a single-artifact edit. The resulting version triggers the same revalidation cascade as a human edit (§8.2).

```ts
interface AssistRevisionRequest {            // thin wrapper over DOC20 DocumentReviewRequest
  review_id: string
  assist_target: AssistTargetRef             // resolved per §6.1/§6.2
  session_ref: TaskModuleSessionRef | FollowupSessionRef | null  // null => fresh session
  directive: string                          // the in-place change requested
  scope_ref: TargetScopeRef | null           // optional span
  result_format: "revise_artifact" | "convert_to_note" | "respond_in_comments"
  schema_version: 1
}
```

### 6.4 Operative vs net-new here
Operative: session continuation/follow-up, Task Agent chat, fork, forum, and the `DocumentReviewRequest` request/response. Net-new: (a) defaulting the assist target to the producing agent's session; (b) the in-place assist op as a scoped single-artifact edit distinct from the Revisor; (c) the checkpoint chat UI — which the reprompt/chat/continuation addendum already proposes (ModuleActivationChat: inspect/advise/branch), so it slots in rather than starting cold. The architect has elected to **adopt** the ModuleActivationChat surface, so the checkpoint chat UI is in scope here; its detailed spec lands when that addendum is folded in (OBL-RS-08).

### 6.5 Assist result handling and iteration
An assist action returns a DOC20 `DocumentReviewResultEvent` (disposition `revised_artifact` | `chat_response` | `note_created` | `comments_replied`, §6.16.8) **back to the review surface**, not straight onward:
- `revised_artifact` / `note_created` -> a new version loaded into the viewer for the human to review.
- `comments_replied` -> threaded replies appear under the relevant finding-comments.
- `chat_response` -> answer in the chat (advise mode).

The Studio session can **iterate** — discuss / revise / edit, review the result, repeat — bounded by `max_revisions` (R3.1 §3.2.3). Only when satisfied does the human take the Layer-3 terminal decision (§5.4). Each assist round is attributed via the `LifecycleActorEnvelope` (§9.1) and, when it mutates the artifact, emits a `human_authored_version_created` receipt that triggers revalidation (§8.2).

---

## 7. Output and routing

### 7.1 The routing decision
After review (and any in-place revision), the human routes the (possibly revised) version:

```ts
type ReviewRoutingDecision =                              // the terminal decision (one of three; see §5.4)
  | { kind: "approve" }                                   // proceed with the current/revised version -> approved_out -> next step
  | { kind: "send_for_revision"; target_ref: string; via: RoutingVia }  // route artifact + dispositions/directives to be addressed
  | { kind: "reject" }                                    // honors on_reject_action (pause|redirect|abort)
// NOTE: "advise" is NOT a terminal routing -- it is a session mode (interaction_mode, §3.2);
// an advise-only session still terminates with approve / send_for_revision / reject.

type RoutingVia =
  | "wired_target" | "to_revisor" | "to_producing_module" | "next_step" | "task_agent" | "forum"
```

### 7.2 Decomposition into the existing Feedback Interpreter pipeline
This is the **Tier-1 Human-Review -> Revisor path** (§11.1): in scope and buildable now (mostly wiring), and it already reaches multiple modules via the Revisor's `RepairTarget` routing and Task Agent escalation.

`revision_out` carries the whole `HumanReviewResult`, but routing **decomposes** it into the existing V3.3.1 §14 pipeline rather than inventing new routing:
- Each `FindingDisposition` and `GeneralDirective` → a `HumanOutcomeFeedbackEvent` (§14.2; targets optional, so un-pinned is supported) with the appropriate `authority_class` (§14.6: `current_run_instruction` = controlling vs `current_run_preference` = advisory).
- The Feedback Interpreter (§14.3) parses these into a `proposed_revision_request` → Revisor (current run) and/or the materialized `proposed_findings` / `proposed_run_criteria` (§3.5). Routing of the request to the Revisor — including the no-current-plan and completed-plan cases — is the existing §14.4 rule.
- **Teaching** feedback (improve the module, not this revision) → `feedback_out` only, as a `HumanOutcomeFeedbackEvent` with a durable authority class → `DirectInstructionCandidate` (§14.7). Kept separate from the revision path.
- A human-edited or co-authored **version** is referenced forward (not re-sent); CIL/DOC15 auto-frames provenance to the next module ("continuation of task X, human-reviewed at a gate; here is the version + directives; revise"). Directives self-describe via their anchors.

### 7.3 Port behavior recap
`approved_out` (proceed, with the revised version) · `rejected_out` (reason + payload, honoring `on_reject_action`) · `revision_out` (full `HumanReviewResult`, decomposed per §7.2) · `feedback_out` (teaching only) · `signal_out` · `error_out`. The intrinsic gate (§4.2) uses the same outputs internally without external wiring.

---

## 8. Versioning, provenance, and the revalidation trigger

### 8.1 Editing is version-creating and method-agnostic
Any human edit (in-app tiptap/Convert-to-Note, DOC20 §6.16.9; or external native app) and any agent-assisted in-place edit (§6.3) produces a **new artifact version** with human / co-authored provenance; the prior version is preserved (DOC20 versions artifacts: `v{N}`, `artifacts_current.json` + events). The reference is sent forward. External-app editing builds on DOC20's "Open External" action: on external save, ingest as a new version. The editing **contract** is method-agnostic — however edited, the result is a new version referenced forward.

### 8.2 GAP/fix — a human (or co-authored) edit must trigger the revalidation cascade
The revalidation cascade (V3.3.1 §11.21) and the dirty-flip (§10.5) are triggered by **revision-step** mutations only: `RevisionOperationReceipt` with `operation_kind in { candidate_version_accepted, direct_fix_applied, rollback_apply }` (`RevisionOperationKind`, §0.4.7). A human-authored version is **not** a revision step and emits none of these — so as specced, a human edit would not refresh findings, and the Revisor could plan against a stale version.

**Fix (preferred — honest provenance):** add a `RevisionOperationKind` value `human_authored_version_created` and include it in the §11.21 trigger set. The review-gate edit path emits a `RevisionOperationReceipt` of that kind. The cascade then fires identically: dependent outcomes (declared via `OutcomeDependencySpec.declared_dependencies`, §11.21.1) → `dirty` → Evaluator re-runs against the human's version → findings whose target section no longer exists → `superseded_by_revision` (§5.7.1) → Revisor plans against the current version.

**Zero-schema alternative (noted, not preferred):** model the human edit as a `CandidateArtifactVersion` that is immediately accepted, reusing `candidate_version_accepted`. It fires the cascade with no enum change but mislabels provenance ("candidate" = produced by revision, §0.4.5); rejected because this unit values truthful history.

### 8.3 `human_resolved` provenance (adopted)
A finding a human resolves by editing (not deleting) does not acquire the `resolved` state — §5.7.2 reserves `resolved` for findings carried in a Revisor `RevisionExecutionReceipt.addressed_findings`, which a human edit does not produce. **Decision: adopt a distinct `human_resolved` provenance** so a human-fixed finding is attributed truthfully rather than silently superseded:
- Add `human_resolved` to `FindingState` (or as a resolution-provenance facet on the resolved transition), set when re-evaluation against a human/co-authored version finds the targeted defect gone and a `human_authored_version_created` receipt (§8.2) is the cause.
- Distinct from `superseded_by_revision` (the section changed/disappeared) and from Revisor-`resolved` (a `RevisionExecutionReceipt` addressed it). Carries the `LifecycleActorEnvelope` (§9.1) so authorship is explicit.

---

## 9. Exposure — multi-actor envelope, read contract, gated write

### 9.1 `LifecycleActorEnvelope` (the multi-actor primitive)
Generalizes the existing per-object authorship (`comment.author`, `attachment.created_by`, tracked-change attribution) so a finding/comment/criterion/transition created by a human, an evaluator, the Revisor, a module, or the Task Agent is structurally identical, differing only in actor + authority. It is an extension of the converged `GovernanceEnvelope` Layer-1 mixin (card Layer 1).

```ts
interface LifecycleActorEnvelope {
  author_kind: "human" | "evaluator" | "revisor" | "module" | "task_agent"
  author_ref: string                          // UserRef | ModuleRef | AgentRef
  on_behalf_of_ref: string | null             // co-authored: directing human for author_kind="module"
  authority_class: HumanFeedbackAuthorityClass | ModuleAuthorityClass  // V3.3.1 §14.6, extended
  basis: AssuranceBasis                        // human_label | model:<id> | evaluator | ...
  taint_class: TaintClass                      // rides the object; consumers treat content as data
  policy_decision_ref: string                  // every WRITE is an EC PolicyDecision, not the actor's call
  schema_version: 1
}
```

### 9.2 Per-owner READ contract (build now; first consumer is Review Studio itself)
Expose the lifecycle as a **derived projection published by each owning subsystem** — DOC23 publishes finding/outcome/revision reads; DOC20 publishes comment/anchor reads — via the patterns already in use (cross-module query API, V3.3.1 §4.9.2; signal pub/sub, §14.8.4; derived read-models "derived, not invented," §11.1.1).

```ts
interface LifecycleReadQuery {                 // pull; modeled on V3.3.1 §4.9.2 (read-only, no cross-mutation)
  by: "artifact" | "outcome" | "task" | "run"
  ref: string
  include: ("findings" | "comments" | "revisions" | "history")[]
  schema_version: 1
}
// returns the existing view types (FeedbackFindingView, DOC20 comment views,
// RevisionExecutionRecord/Summary), privilege/AccessTier-filtered (§16.6) under default-deny (§16.5).

interface LifecycleEventSubscription {         // push; over §14.8 signals + finding-state transitions
  events: ("finding_created" | "finding_resolved" | "finding_superseded"
         | "revision_applied" | "directive_raised" | "directive_satisfied")[]
  scope_ref: string
  schema_version: 1
}
```
Read guardrails: projection only, never an authoritative store (§11.1.1); privilege/AccessTier filtering (§16.6); `taint_class` rides the view; reads never mutate the owner.

### 9.3 Gated WRITE capability (declared; behaviors reserved)
A typed capability so future modules can interact in the same manner, gated behind `LifecycleActorEnvelope` + an EC `PolicyDecision`. "Can module M create/resolve finding F?" is a policy decision, not M's call (preserves one-compiled-evaluator). Per-module write **behaviors are reserved** (§11) — only the contract + authority gate land now.

```ts
interface LifecycleWriteCapability {
  op: "create_finding" | "transition_finding" | "add_comment" | "add_run_criterion"
  actor: LifecycleActorEnvelope                // author_kind != "human" requires capability declaration
  target_ref: string
  payload_ref: string
  requires_policy_decision: true
  schema_version: 1
}
```

---

## 10. Lints and fixtures

### 10.1 New lints
```
review_studio.finding_disposition_without_anchor_or_id
review_studio.general_directive_not_materialized_to_finding_or_criterion
review_studio.run_criterion_scope_wider_than_run
review_studio.human_edit_without_revalidation_trigger          // §8.2
review_studio.advise_mode_mutated_artifact                     // interaction_mode=advise must not change the doc
review_studio.result_format_unhonored_by_assist_output
review_studio.intrinsic_gate_used_loop_controller              // intrinsic gate must not require one (§4.2)
review_studio.advise_treated_as_terminal_routing            // advise is a session mode, not a terminal (§5.4)
review_studio.terminal_decision_not_approve_send_or_reject   // Layer-3 must be one of three (§5.4)
lifecycle.read_projection_treated_as_truth_store               // §9.2
lifecycle.read_without_privilege_filter                        // §16.6
lifecycle.write_without_policy_decision                        // §9.3
lifecycle.actor_envelope_missing
review_result.duplicates_document_review_request_schema        // must extend, not fork (§3.2)
```

### 10.2 Golden fixtures (executable assertions; gate level in brackets)
```
GS-RS-01  per-finding disposition -> human-authored finding -> Revisor routes to module        [slice]
GS-RS-02  general directive -> run-scoped criterion -> persists across re-eval until satisfied  [cross_slice]
GS-RS-03  human deletes section with a finding -> human_authored_version_created -> cascade ->
          finding superseded_by_revision -> Revisor plans against current version               [cross_slice]
GS-RS-04  advise mode: agent answers in comments/chat, artifact unchanged                       [slice]
GS-RS-05  agent-assisted in-place edit -> new co-authored version -> route "proceed"             [cross_slice]
GS-RS-06  default assist target resolves to producing agent's session; override via agent_id     [slice]
GS-RS-07  intrinsic post_evaluation gate raised with no module wiring and no Loop Controller     [slice]
GS-RS-08  teaching feedback -> feedback_out -> DirectInstructionCandidate (not the revision path) [slice]
GS-RS-09  read query returns privilege-filtered views; cross-matter read denied by default       [final_switchover]
GS-RS-10  assist result returns to surface; session iterates within max_revisions before terminal decision [cross_slice]
```

---

## 11. Reserved sections (contract reserved, behaviors deferred)

### 11.1 Revision pathways: in scope, the evaluator-bridge, and the reserved orchestrator
Three tiers, deliberately separated so we do not build a second orchestrator (§1.2):

- **Tier 1 — Human-Review -> Revisor (IN SCOPE, buildable now).** A review's dispositions/directives drive the Revisor to revise the artifact / repair via the existing loop. Already contracted (HumanOutcomeFeedbackEvent -> Feedback Interpreter -> RevisionRequest -> Revisor, V3.3.1 §14); Review Studio wires into it (§7.2). **Not reserved** — mostly wiring. The Revisor already reaches **multiple modules** on its own via `RepairTarget` routing (§6.4) and Task Agent escalation (§6.9), so Tier 1 already covers much of the multi-module need.
- **Tier 2 — The evaluator-bridge (recommended multi-module path; a pattern, not new machinery).** Route the human's intent **through an Evaluator**: the comments/directives become an Evaluator's findings/criteria (the materialization in §3.5 is exactly this), and the existing Revisor consumes them and does its normal multi-module job, escalating to the Task Agent where needed. Yields human-driven multi-module revision by reusing Evaluator -> Revisor -> Task-Agent, with **no new orchestrator**. It also "forces clearer goals," since intent must be expressed as checkable findings/criteria.
- **Tier 3 — Human-Review -> Orchestrator engine (RESERVED).** A dedicated engine where human review directly drives runtime multi-module orchestration, bypassing the Evaluator/Revisor. **Reserved**, because it would be a second orchestrator overlapping the Revisor's (the §1.2 boundary). Architect's framing: this is essentially the existing "ask ELNOR for a task -> Task Agent designs it -> it is revised" flow, surfaced with a different level of explanation and made re-runnable mid-task. Its building blocks already exist — `TaskRunFork` (Core R0.7.1 §8622), `graph_patch_proposal` (the Revisor->Task Agent escalation output, V3.3.1 §6.9), and the Task Agent's graph-design/revision role — so assembling it later is expected to be cheap, which is why it is deferred rather than built now. Build Tier 1 + use the Tier 2 bridge in the interim; `requested_followup: FollowupIntent[]` (§3.2) captures multi-step intent as data meanwhile.

### 11.2 Self-learning from review gates
The reasoning side (learning standing preferences/quality models from review-gate activity) is **reserved**, gated on DOC8/the memory flatten. The **signal layer is already wired**: V3.3.1 §14.8 emits `finding_marked_wrong`, `revision_instruction_useful`, `evaluator_plan_user_edited`, etc., to DOC72/BDSM consumers (§14.8.4). This unit emits those signals from Review Studio actions (including per-tracked-change rejections, §3.2) but does not build the learning reasoner.

---

## 12. OP-A obligations (interim pre-flatten tracker rows)

Recorded in the interim cross-doc tracker (not canonical OP-A, reconciled at flatten completion). None of these are flatten-blocking.

```
OBL-RS-01  §G UI rows -> DOC20 migration
OBL-RS-02  Review Studio review-surface UI (Appendix A) -> DOC20
OBL-RS-03  Reconcile HumanReviewResult ⊇ DocumentReviewRequest (request shape is DOC20-owned, §3.2)
OBL-RS-04  AttachmentSchema.parent_type extension: add comment / finding / review_result (DOC20 §7.18)
OBL-RS-05  plan_review room kind dependency -> DOC12 (B-15; OBL-DOC12-FORUM-01)
OBL-RS-06  NoVerdictReason full consolidation -> when next in Addenda A
OBL-RS-07  Unified cross-module lifecycle substrate ownership (DOC23<->DOC20) — ordinary owner-boundary
           decision + OP-A row; NOT a flatten/DOC80 gate, NOT a blocker
OBL-RS-08  Fold the ADOPTED ModuleActivationChat surface (reprompt/chat/continuation addendum) into DOC20/DOC23 -> the §6.4/§6.5 checkpoint chat UI
OBL-RS-09  RevisionOperationKind += human_authored_version_created; add to §11.21 trigger set (V3.3.1 owner)
OBL-RS-10  ui_source += review_studio_card / document_viewer / email_reply (DOC20 + V3.3.1 §14.2)
```

---

## Appendix A — DOC20 additions / obligations (liftable, mockup-ready)

Clearly-labeled DOC20-owned work, liftable to DOC20 when next revised. Specified to mockup-ready depth.

- **Review mode for the Document Viewer** (§6.16): a `doc` tab opened by the gate, with findings loaded into the Comments panel as a **`finding` comment kind** (extends `NoteCommentStatus`/comment-kind set). Click-finding->highlight reuses §6.6.7.
- **Per-finding actions** in the Comments panel: Accept / Reject / Reject-with-modification + comment (Word-comment ergonomics).
- **Interaction-mode toggle** (revise | advise) on the review surface; advise hides mutation actions.
- **Result-format selector** — already present (§6.16.8 `result_format`); surface it in review mode and bind to the assist output contract.
- **Context-scope control** — already present (§6.16.8 `context_scope`).
- **Assist-target picker** — producing-agent default; candidate list = "agents involved in this task" (from the run graph) + Task Agent + forum; maps `agent_id`/`chat_id` (§6.2). Chat surface = ModuleActivationChat (proposal, OBL-RS-08).
- **Attachment `parent_type` extension** to cover `comment` / `finding` / `review_result` (§7.18; OBL-RS-04).
- **Comment-status <-> finding-state reconciliation**: `orphaned` <-> `superseded_by_revision`; carry `thread_root_id` on dispositions so threads link, not duplicate (§3.6).
- **`ui_source` values** for review surfaces (OBL-RS-10).
- **Plan-review layout**: Revisor plan steps as side-panel items with approve / drop / modify (consumes `plan_in`).

---

## Appendix B — Verification log (operative vs net-new)

**Operative (reused, cited):**
- `step.user_review_gate` spine, Review Card, email-reply actions, ports, `on_reject_action`, `max_revisions`, `revision_delivery`, Loop Controller Pattern B — DOC23 R3.1 §3.2.3 / §6.5.4 / §3.3.4 / §6.2 / §13.9.
- Document Viewer, anchored comments + threading, tracked changes, Convert-to-Note, Send-to-Agent + `DocumentReviewRequest`/`DocumentReviewResultEvent`, comment event-store, attachments — DOC20 R4.3 §6.6.2 / §6.6.3 / §6.10 / §6.16.6 / §6.16.8 / §6.16.9 / §6.16.11 / §7.16–§7.18.
- Finding lifecycle + `superseded_by_revision`, revalidation cascade + declared-dependency closure, `RevisionOperationKind`, `HumanOutcomeFeedbackEvent` (un-pinned supported), Feedback Interpreter + routing, authority classes, `DirectInstructionCandidate`, signals + consumers, Plan Review Forum, `RevisionRequest`, `TypedRevisionInstruction`, repair strategy/target taxonomies, Task Agent escalation, Outcome Compiler/Criterion, export/governance + default-deny + matter governance, derived-read-model "derived, not invented" — V3.3.1 §5.7 / §11.21 / §3.1.7 / §0.4.7 / §14.2 / §14.3 / §14.4 / §14.6 / §14.7 / §14.8 / §14.9 / §7.1 / §7.6 / §6.3 / §6.4 / §6.9 / §5.1.1 / §16.3 / §16.5 / §16.6 / §11.1 / §4.9.2.
- Module session continuation, module follow-up, Task Agent side-panel chat, `TaskRunFork`, `TaskModuleSessionRef` — Addenda B Core R0.7.1 §3170 / §3449 / §261 / §9397 / §10363 / §8622; Reprompt §7.1 -> Addenda A §A9.

**Net-new this unit (and its trace):**
- `interaction_mode` revise|advise — closes a gap vs DOC20 `output_mode` respond_in_chat / `result_format` respond_in_comments (§3.1/§3.3).
- `HumanReviewResult` as a superset of `DocumentReviewRequest` (§3.2) — reconciliation OBL-RS-03.
- Materialization of comments -> human-authored findings / run-scoped criteria; `InterpretedOutcomeFeedback` output extension (§3.5) — built on §5.1.1 + §5.7 + §14.3.
- Hybrid placeable + intrinsic gate (§4) — extends §3.2.3; intrinsic timing after Evaluator/before Revisor.
- `human_authored_version_created` revalidation trigger (§8.2) — OBL-RS-09.
- `LifecycleActorEnvelope`, `LifecycleReadQuery`/`LifecycleEventSubscription`, gated `LifecycleWriteCapability` (§9) — extend GovernanceEnvelope + §4.9.2/§11.1/§16.

**`OPEN_FOR_ARCHITECT_REVIEW`:** none outstanding. Resolved this revision: ModuleActivationChat — **adopted** (§6.4); `human_resolved` provenance — **adopted** (§8.3); Tier-1 Human-Review->Revisor — **in scope** (§7.2/§11.1). The Tier-3 orchestrator (§11.1) is **reserved by decision** (not an open question), to revisit after the other pieces land.

---

## Revision log

**Rev 2 (this pass)** — folded in architect decisions + audit findings:
- Adopted the ModuleActivationChat checkpoint chat UI (§6.4, OBL-RS-08).
- Adopted a distinct `human_resolved` provenance (§8.3).
- Confirmed Tier-1 Human-Review->Revisor as in scope; named the Tier-2 evaluator-bridge; reserved the Tier-3 orchestrator with building-block framing (§7.2, §11.1).
- Added the three-layer action model and disambiguated "Revise"; refined the `decision` enum to approve/send_for_revision/reject and removed `advise_only` as a routing kind (§5.4, §7.1).
- Added assist-result handling + iteration (§6.5), no-producing-agent fallback (§6.2), relationship to agent_review_gate / panel / the human_review_gate disposition (§1.3), email-channel limits (§3.4), two action-model lints, and GS-RS-10.

*End of design unit. Draft pending architect review and multi-LLM red-team.*
````