DOC12_INTER_AGENT_COMMUNICATION_R7_1.md
Current Specs/DOC12/DOC12_INTER_AGENT_COMMUNICATION_R7_1.md
# DOC12 — Inter-Agent Communication, Multi-Agent Rooms, Shared Conversation Substrate, ACP-Aware Delegation, Red-Team Integration, and Dynamic Room Orchestration
**Version:** R7.1 Draft 1
**Date:** 2026-03-12
**Status:** Draft — companion-closure revision after DOC14 Cross-Document Delta Companion R1
**Build Assumption:** Fresh rebuild from finalized specs; coding agents must not invent behavior.
## IMPORTANT: Fresh Build Assumption
This document assumes a fresh rebuild of the ELNOR room substrate. R7 does not carry forward permissive migration shortcuts that were acceptable in R6 during active red-team iteration. If a behavior is visible, stateful, or safety-relevant, R7 must define:
- canonical owner
- request and response contract
- durable mutation path or explicit refusal
- read-model refresh path
- telemetry / SSE behavior
- idempotency and optimistic concurrency rules where applicable
- degraded / unavailable behavior
- tests that prove the behavior is real
If any DOC12 text conflicts with shared contracts in `packages/contracts`, the shared contract registry wins. If any R6 behavior conflicts with this R7 text, R7 wins.
## Minimum Reading Set
Read these before implementing DOC12 R7.1:
1. DOC10 Orchestration Integration Ledger R10
2. DOC11 OpenClaw Gateway / runtime truth R12.2
3. DOC14 CANDOR integration architecture v5.1
4. DOC14 Cross-Document Delta Companion R1
5. DOC15 Cognitive Infrastructure Layer R6
6. DOC15 Cross-Document Integration Contract R2
7. DOC16 Deferred Additions R5.1
8. DOC17 Overlay / Prompt Advisor / Prompt Recipes / Prompt Lab R4.2
9. Q Dashboard Master UI Specification R4.1
## Revision History
- **R7.1** — companion-closure revision. Adds canonical red-team command families, cache-promotion and adjudication paths, lineage upsert/query support, review-target materialization truth, room overlay state and participant prompt-plan precedence views, child-room prompt-artifact selection and minimal import-back, explicit red-team degraded/error state contracts, execution-turn-mode derivation for `room_mode = red_team`, minimum-viable-completion reserve support, complete red-team SSE normalization, and DOC14 companion UI / telemetry closure.
- **R7** — hardening revision. Adds durable room-turn execution journal, close-session lifecycle, prompt-artifact family truth, child-room launch compatibility, action-capability reporting, active review-target pinning, approval checkpoints, DOC14 batch judgment alignment, draft-room upload flow, correction queue semantics, and DOC15-compatible outcome / prompt-lineage emission.
- **R6** — central room pipeline, ghost agents, room cloning, document workspace, bootstrap budget enforcement, AsyncMutex locking, SSE behavioral contract, close lifecycle, correction follow-through, decision-basis hard fail, STOP/abort propagation, and related fixes.
## R7 Change Summary (Delta from R6)
R7 does five things:
1. Converts the R6 room-turn pipeline into a replay-safe, DOC11-aligned execution state machine.
2. Converts close from a one-pass lifecycle into a durable close session with warning-vs-failure semantics.
3. Promotes prompt-artifact truth, review-target truth, and child-room launch compatibility from advisory to required companion compatibility.
4. Adds room-level control honesty: action-capability reporting, approval checkpoints, draft-room flow, capability-aware document handling, and no clickable no-op controls.
5. Normalizes room-to-CIL signals: outcome signal, prompt observation, decision basis, review-target pin state, suppression events, and room health.
## R7.1 Change Summary (Delta from R7)
R7.1 adds or tightens:
1. canonical red-team command names and request/response schemas,
2. durable cached-finding promotion,
3. adjudication and lineage command/query paths,
4. review-target materialization truth,
5. room-level overlay state and participant prompt-plan precedence views,
6. child-room prompt-artifact selection and minimal import-back support,
7. red-team degraded/error state contracts,
8. explicit execution-turn-mode derivation for `room_mode = red_team`,
9. minimum viable completion / scheduler reserve support,
10. complete red-team SSE event normalization,
11. route-trace / idempotency / expected-version requirements for all red-team mutations,
12. Q read-model and UI surface closure for DOC14 companion requirements.
## Why This Document Exists
DOC12 defines the visible multi-agent room substrate inside ELNOR. It is the spec that answers:
- what a room is
- what a room participant is
- how visible turns are scheduled, dispatched, streamed, completed, failed, or aborted
- how room-local documents, findings, prompt truth, and review targets are represented
- how room policy mutations are applied honestly
- how the room integrates with DOC11 runtime truth, DOC14 review semantics, DOC15 learning capture, DOC16 future linked-room expansion, and DOC17 prompt artifacts
DOC12 does **not** replace OpenClaw. DOC12 orchestrates **around** OpenClaw and Gateway truth. DOC12 is the owner of room state, room lifecycle, room-local artifacts, room-local projections, and room UI semantics.
---
## §0 Guiding Principles
### §0.1 Three communication layers, not one blob
ELNOR has three distinct communication layers:
- **Layer A:** hidden bounded inter-agent consultation and runtime-internal work
- **Layer B:** visible multi-agent room with canonical visible transcript
- **Layer C:** async artifacts, exports, and follow-on review surfaces
DOC12 is primarily responsible for Layer B and its room-owned bridges to A and C.
### §0.2 Preserve OpenClaw autonomy
OpenClaw remains the native runtime. DOC12 must not override native session management, native memory, or SOUL-level behavior. DOC12 may request, observe, and reconcile runtime truth. DOC12 may not pretend to be the runtime.
### §0.3 Visible room participants are top-level participants
Every visible room participant is a first-class roster entry with stable participant identity, role configuration, state, turn history, and runtime binding truth.
### §0.4 Hidden system agents remain hidden by default
Internal workers, tool calls, native runtime helpers, and hidden red-team support processes remain non-visible unless a companion spec explicitly surfaces them.
### §0.5 Native sub-agents remain available
DOC12 does not ban native sub-agents. It bans only fake visible participants that have no truthful execution or message identity.
### §0.6 ACP is optional
ACP-aware delegation remains optional. DOC12 must degrade truthfully when ACP-specific capabilities are unavailable.
### §0.7 One room artifact, one canonical visible transcript
A room has one canonical visible transcript. Transcript truth lives in DOC12 artifacts and is refreshed through room events, not UI optimism.
### §0.8 Shared context should be passed by ref, summary, and bounded brief
Rooms must move context by references, compact summaries, and bounded manifests. They must not silently stuff unlimited history into prompts.
### §0.9 Memory and learning policy must be explicit
Room-local retention, promotion, purge, suppression, and export rules must be explicit. Silence is not a learning policy.
### §0.10 Turn policies must be bounded
Every room turn mode must have bounded activation, bounded participant eligibility, bounded ordering, and bounded failure handling.
### §0.11 Room/session isolation is required
Room state is isolated from unrelated rooms by default. Session truth is room-local unless a companion spec explicitly bridges it.
### §0.12 External channel projection is capability-driven
Projection to external channels must be driven by real capability truth, not hopeful UI affordances.
### §0.13 Falsification principle
In red-team or critique-oriented rooms, the system must preserve dissent, evidence discipline, review-target integrity, and prompt-truth visibility. Optimistic collapse is prohibited where it would hide disagreement or misstate evidence.
### §0.14 Human as conductor
The human user is a first-class room participant and policy authority. Human intent is structural, not decorative.
### §0.15 No room theater
No visible control may be clickable unless it has a route, a handler, and either a durable mutation or an explicit refusal. No visible room participant may emit messages without real participant identity and runtime truth.
### §0.16 Context honesty
If a document, prompt artifact, or instruction was not loaded, the room must not imply that it was loaded.
### §0.17 Memory isolation by default
Room-local findings, prompt observations, and corrections do not become durable global authority or heuristic memory unless a companion-authorized promotion path is used.
### §0.18 Substrate distinction
Rooms, panels, and forums share some substrate pieces but are not interchangeable. DOC12 owns rooms, not panel governance and not forum archival discussion logic.
### §0.19 Agents must know each other
Visible room participants must receive a truthful roster and role summary in bootstrap.
### §0.20 Structural human authority
Human corrections, directorial turns, pause requests, batch judgments, and close decisions are structural policy inputs, not incidental transcript text.
### §0.21 Core room vs red-team overlay
DOC12 owns the room substrate. DOC14 owns red-team semantics layered on top of that substrate. Room mode must map explicitly to red-team policy where required; mismatch is a contract error.
### §0.22 Prompt-artifact family truth is required
If prompt artifacts influence visible room behavior, the room must expose enough truth for users and companion systems to know what was active, what was proposed only, and what was unavailable.
### §0.23 Active review targets are special
Active review targets and current-round submissions are treated as pinned room documents. They may not be silently compressed away from the effective bootstrap.
### §0.24 Approval checkpoints are structural blocks
If a room requires approval before phase transition, export, child launch, or close, the scheduler must block. The UI may not pretend the room can proceed.
### §0.25 Action capability honesty
Room policy actions must advertise availability truthfully through a capability report. Unsupported actions are shown as read-only with explanation or omitted entirely.
---
## §1 Concepts and Architecture
### §1.1 Core concepts
Key nouns in DOC12:
- **Room:** a visible multi-participant conversation substrate with durable state and canonical transcript.
- **Participant:** visible room actor with role, state, runtime binding, and eligibility.
- **Room turn:** a scheduled visible contribution attempt by one participant.
- **Room turn execution:** durable record of queued → dispatching → accepted/running → terminal state.
- **Document binding:** room-local binding between a document and the room’s review or workspace semantics.
- **Review target:** currently active target of structured review or critique.
- **Prompt identity:** effective prompt-artifact family truth relevant to a participant or room turn.
- **Approval checkpoint:** scheduler block that requires a human decision before the room may proceed.
- **Child room:** launched review successor or companion room with linked prompt / target / import-back truth.
### §1.2 Communication layers
#### Layer A — hidden bounded consultation
Used for runtime-private work, tool use, internal scaffolding, and hidden quality support.
#### Layer B — visible multi-agent room
Used for all visible room messages, visible findings, visible judgments, visible control surfaces, and room-owned state transitions.
#### Layer C — async artifacts and exports
Used for follow-up review, export, child-room launch, forum/panel bridges, and room-close outcome bundles.
### §1.3 Room versus forum versus panel
- **Room:** live multi-agent execution substrate.
- **Forum:** asynchronous artifact/comment surface.
- **Panel:** governance or review shell that may open or observe rooms but does not replace room execution.
### §1.4 What the room is not
A room is not:
- a hidden runtime thread
- a panel execution surrogate
- a fake chat transcript assembled without turn truth
- a place where child-room or review-target truth may be guessed
### §1.5 Ownership split
- **DOC12:** room truth, room state, participant truth, room actions, room UI/read-model semantics, room documents, room-close lifecycle, room-local prompt truth surfaces.
- **DOC11:** runtime truth, Gateway room-turn transport payloads, prompt-plan truth generation, streaming / abort semantics.
- **DOC14:** findings, judgments, adjudications, lineage, room health, review-target binding semantics, child-room launch policy semantics, prompt observations, topology outcome semantics.
- **DOC15:** learning capture, authority / transient-instruction interpretation, CIL intake.
- **DOC17:** overlay, prompt recipe, prompt advisor artifact semantics.
- **DOC10:** shared orchestration contracts, route/correlation/telemetry obligations.
---
## §2 Scope Boundaries and Relationship to OpenClaw
### §2.1 Safe relationship to native OpenClaw behavior
DOC12 may request room-turn execution from Gateway, receive runtime truth, stream deltas, and issue aborts. DOC12 may not modify native OpenClaw memory, SOUL, or native session files.
### §2.2 Visible participants should be session-bound
A visible room participant must have a room-owned runtime binding record that points to the runtime session truth used for visible turns.
### §2.3 Visible participants versus internal workers
If a behavior is visible to the user, it must be attributed to a visible participant or explicit system event, not to an unnamed worker.
### §2.4 ACP posture
ACP-aware delegation remains optional. If a participant or action depends on ACP-specific affordances, the room must advertise the capability state honestly.
### §2.5 Agent Registry Interface
DOC12 depends on a minimal agent registry contract sufficient to resolve:
- logical agent id
- display name
- model/routing defaults
- supported capabilities
- room participation eligibility
- tool / file access posture
DOC12 does not own the registry; it consumes it.
---
## §3 Canonical Artifacts and Storage
### §3.1 Canonical room paths
DOC12 owns canonical room artifacts under `ELNOR_MEMORY/system/rooms/`.
Required baseline artifacts:
```text
ELNOR_MEMORY/system/rooms/<room_id>/room_state_current.json
ELNOR_MEMORY/system/rooms/<room_id>/commands.jsonl
ELNOR_MEMORY/system/rooms/<room_id>/idempotency_index.json
ELNOR_MEMORY/system/rooms/<room_id>/participants_current.json
ELNOR_MEMORY/system/rooms/<room_id>/messages.jsonl
ELNOR_MEMORY/system/rooms/<room_id>/turns.jsonl
ELNOR_MEMORY/system/rooms/<room_id>/runtime_bindings_current.json
ELNOR_MEMORY/system/rooms/<room_id>/summary_current.json
ELNOR_MEMORY/system/rooms/<room_id>/cost_aggregate_current.json
ELNOR_MEMORY/system/rooms/<room_id>/policy_current.json
```
R7 adds:
```text
ELNOR_MEMORY/system/rooms/<room_id>/turn_execution_current.json
ELNOR_MEMORY/system/rooms/<room_id>/turn_execution_events.jsonl
ELNOR_MEMORY/system/rooms/<room_id>/close_session_current.json
ELNOR_MEMORY/system/rooms/<room_id>/approval_checkpoints_current.json
ELNOR_MEMORY/system/rooms/<room_id>/approval_events.jsonl
ELNOR_MEMORY/system/rooms/<room_id>/document_bindings_current.json
ELNOR_MEMORY/system/rooms/<room_id>/ghost_outputs.jsonl
ELNOR_MEMORY/system/rooms/<room_id>/child_links_current.json
ELNOR_MEMORY/system/rooms/<room_id>/transfer_packets.jsonl
ELNOR_MEMORY/system/rooms/<room_id>/action_capabilities_current.json
ELNOR_MEMORY/system/rooms/<room_id>/findings_current.json
ELNOR_MEMORY/system/rooms/<room_id>/findings_judgments.jsonl
ELNOR_MEMORY/system/rooms/<room_id>/findings_adjudications.jsonl
ELNOR_MEMORY/system/rooms/<room_id>/findings_lineage_current.json
ELNOR_MEMORY/system/rooms/<room_id>/findings_cache_current.json
ELNOR_MEMORY/system/rooms/<room_id>/batch_review_progress_current.json
ELNOR_MEMORY/system/rooms/<room_id>/room_health_current.json
ELNOR_MEMORY/system/rooms/<room_id>/review_target_current.json
ELNOR_MEMORY/system/rooms/<room_id>/prompt_plan_current.json
ELNOR_MEMORY/system/rooms/<room_id>/prompt_plan_events.jsonl
ELNOR_MEMORY/system/rooms/<room_id>/child_room_links_current.json
ELNOR_MEMORY/system/rooms/<room_id>/child_import_events.jsonl
ELNOR_MEMORY/system/rooms/drafts/<draft_room_id>/draft_state.json
ELNOR_MEMORY/system/rooms/drafts/<draft_room_id>/draft_docs_manifest.json
```
R7.1 also clarifies the following room-owned projections:
- `findings_current.json` is a room projection owned by DOC12. It may embed or project DOC14-owned canonical finding records, but DOC12 owns the room-local storage path, versioning, and mutation-envelope semantics.
- `review_target_current.json` stores the active review-target binding and materialization truth used by the room. The review-target binding schema is shared with DOC14. DOC12 owns the room-local projection and pin transitions.
- `child_import_events.jsonl` records minimal import-back from child rooms. R7.1 supports the import seam and status projections, not the full DOC16 matter-workbench graph.
### §3.2 Append-only rule
Event logs remain append-only JSONL. Current-state snapshots use write-temp-then-rename atomic JSON writes.
### §3.3 Transcript truth
Visible transcript truth is the append-only message/event log plus derived current-state projections. UI must never invent transcript rows optimistically.
### §3.3A Locking strategy
DOC12 uses an in-process `AsyncMutex` per room for short mutation windows. The lock is held while:
- selecting an eligible queued head
- verifying current room revision / participant eligibility
- persisting pre-dispatch execution state
- applying terminal results
- mutating room-owned artifacts
The lock is **not** held across the Gateway network call or stream wait. Replay safety comes from durable execution state, not long mutex holds.
### §3.4 Room state concurrency and idempotency
Every mutable room command must support:
- `Idempotency-Key`
- `expected_version` or `_version`
- explicit conflict error if the room mutated incompatibly since the caller’s last read
### §3.5 Cost tracking artifacts
Room cost truth has two layers:
- **live subtotal truth** used for gating and dispatch budgets
- **durable aggregate files** used for read models and restart continuity
Budget checks must not rely solely on debounced file writes.
### §3.5A File I/O debouncing rules
Checkpoint and aggregate projections may be debounced for write efficiency. Execution truth, terminal state, close state, approval state, and idempotency truth may not be deferred in a way that compromises restart reconciliation.
### §3.6 Schema version migration rule
All durable DOC12 artifacts carry `schema_version`. Migrations must be explicit, monotonic, and idempotent.
### §3.7 Startup recovery
At startup DOC12 must reconcile:
- nonterminal turn execution records
- rooms in `closing` with incomplete close sessions
- pending approval checkpoints with expired deadlines or stale room refs
- stale engagement leases
- draft rooms beyond TTL
### §3.8 Room action capability reporting
Action availability is a durable read model, not just UI heuristics.
```ts
export const RoomActionCapabilitySchema = z.object({
action: z.enum([
"add_participant",
"remove_participant",
"mute_participant",
"unmute_participant",
"pause_room",
"resume_room",
"launch_child_redteam",
"bind_document",
"change_projection_mode",
"approve_checkpoint",
"judge_finding",
"batch_judge_findings",
"promote_cached_finding",
"adjudicate_finding",
"upsert_lineage",
"import_child_output",
]),
availability: z.enum([
"available",
"read_only",
"unsupported",
"degraded",
"blocked_by_policy",
]),
reason_code: z.string().optional(),
detail: z.string().optional(),
});
export const RoomActionCapabilityReportSchema = z.object({
room_id: z.string(),
generated_at: z.string().datetime(),
actions: z.array(RoomActionCapabilitySchema),
schema_version: z.literal(1),
});
```
## §4 Contracts and Schemas
### §4.1 Shared imports
DOC12 must import, not fork, shared contracts.
```ts
import {
GatewayRoomTurnDispatchRequest,
GatewayRoomTurnDispatchResult,
GatewayRoomTurnStreamDelta,
RoomTurnCompletedResult,
AbortRequest,
AbortReceipt,
} from "@elnor/contracts/gateway";
import {
RedTeamPolicySchema,
RoomFindingSchema,
FindingJudgmentSchema,
FindingAdjudicationRecordSchema,
FindingLineageSchema,
RoomHealthSnapshotSchema,
PromptObservationEmitSchema,
TopologyOutcomeSignalSchema,
ReviewTargetBindingRefSchema,
ReviewTargetMaterializationPlanSchema,
RoomHealthViewModelSchema,
FindingsPanelViewModelSchema,
BatchReviewProgressSchema,
ChildRedTeamLaunchPolicySchema,
ChildRoomPromptArtifactSelectionSchema,
LaunchChildRedTeamRoomRequestSchema,
PromptIdentityRefSchema,
PromptArtifactKindSchema,
ParticipantPromptPlanViewModelSchema,
RedTeamDegradedStateSchema,
RedTeamErrorCodeSchema,
} from "@elnor/contracts/red-team";
import {
OverlayIdSchema,
PromptRecipeIdSchema,
} from "@elnor/contracts/prompts";
import {
TransientInstructionSchema,
AuthorityCreationPathSchema,
AuthorityScopeSchema,
AuthorityAppliesToSchema,
} from "@elnor/contracts/cil";
```
DOC12 imports these shared red-team contracts. DOC12 does not create local lookalike schemas when the canonical owner schema already exists.
DOC12 may keep a room-side adapter seam, but its method signatures must use shared payloads only.
```ts
export interface RoomGatewayAdapter {
dispatchRoomTurn(req: GatewayRoomTurnDispatchRequest): Promise<GatewayRoomTurnDispatchResult>;
abortRun(req: AbortRequest): Promise<AbortReceipt>;
}
```
### §4.2 Core room enums
```ts
export const RoomStatusSchema = z.enum([
"configuring",
"active",
"paused",
"closing",
"closed",
"closed_with_warnings",
"close_failed",
"archived",
]);
export const RoomBlockStateSchema = z.enum([
"none",
"awaiting_human_approval",
"policy_blocked",
"runtime_degraded",
]);
export const UserGoalMetSchema = z.enum(["fully", "partially", "not_at_all"]);
export const RoomCloseReasonSchema = z.enum([
"user_close",
"convergence",
"turn_limit",
"cost_limit",
"system",
"all_muted",
"timeout",
"error",
"parent_close",
"director_deliver",
]);
```
### §4.3 Room artifact schema
The full room artifact is large; the fields below are the normative additions or normalizations introduced in R7.
```ts
export const RoomArtifactSchema = z.object({
room_id: z.string(),
title: z.string(),
room_mode: z.string(),
status: RoomStatusSchema,
room_revision: z.number().int().nonnegative(),
room_close_epoch: z.number().int().nonnegative().default(0),
last_activity_at: z.string().datetime(),
block_state: RoomBlockStateSchema.default("none"),
blocking_checkpoint_id: z.string().optional(),
linked_room_group_id: z.string().optional(),
active_review_target_ref: ReviewTargetBindingRefSchema.optional(),
active_prompt_plan_ref: z.string().optional(),
room_action_capability_ref: z.string().optional(),
close_session_ref: z.string().optional(),
turn_execution_ref: z.string().optional(),
human_correction_pending: z.array(HumanCorrectionItemSchema).default([]),
schema_version: z.literal(1),
});
```
### §4.4 Participant record
A visible participant must carry enough truth for room scheduling, runtime binding, and UI rendering.
```ts
export const ParticipantStateSchema = z.enum([
"active",
"muted",
"paused",
"blocked",
"degraded",
"ghost",
"removed",
]);
export const RoomParticipantSchema = z.object({
participant_id: z.string(),
logical_agent_id: z.string().optional(),
display_name: z.string(),
role_label: z.string(),
participant_kind: z.enum(["human", "agent", "ghost"]),
state: ParticipantStateSchema,
ghost_parent_participant_id: z.string().optional(),
runtime_binding_ref: z.string().optional(),
lease_ref: z.string().optional(),
max_output_tokens: z.number().int().positive().optional(),
prompt_plan_ref: z.string().optional(),
schema_version: z.literal(1),
});
```
### §4.5 Human participant schema
The human is a first-class participant.
```ts
export const HumanParticipantSchema = z.object({
participant_id: z.string(),
display_name: z.string(),
role_label: z.literal("human"),
participant_kind: z.literal("human"),
state: z.literal("active"),
schema_version: z.literal(1),
});
```
### §4.6 Shared conversation message
All visible room transcript entries are messages or explicit room/system events, never implicit UI assumptions.
```ts
export const RoomMessageSchema = z.object({
message_id: z.string(),
room_id: z.string(),
participant_id: z.string(),
seq: z.number().int().nonnegative(),
origin_class: z.enum(["human", "participant", "moderator", "system", "ghost_advisory"]),
content: z.string(),
created_at: z.string().datetime(),
correlation_id: z.string().optional(),
prompt_identity: PromptIdentitySnapshotSchema.optional(),
review_target_binding_ref: ReviewTargetBindingRefSchema.optional(),
schema_version: z.literal(1),
});
```
### §4.7 Turn execution journal
This is the most important R7 schema addition.
```ts
export const RoomTurnExecutionStateSchema = z.object({
room_id: z.string(),
room_turn_id: z.string(),
participant_id: z.string(),
room_revision_at_dispatch: z.number().int().nonnegative(),
room_close_epoch_at_dispatch: z.number().int().nonnegative().default(0),
state: z.enum([
"queued",
"dispatching",
"accepted",
"running",
"applying_result",
"completed",
"failed",
"aborted",
]),
run_id: z.string().optional(),
gateway_session_key: z.string().optional(),
dispatched_at: z.string().datetime().optional(),
accepted_at: z.string().datetime().optional(),
completed_at: z.string().datetime().optional(),
terminal_status: z.enum(["completed", "failed", "aborted"]).optional(),
reason_codes: z.array(z.string()).default([]),
usage_sample_ref: z.string().optional(),
execution_watermark_ref: z.string().optional(),
schema_version: z.literal(1),
});
```
### §4.8 Close-session durability
```ts
export const RoomCloseSessionSchema = z.object({
close_session_id: z.string().uuid(),
room_id: z.string(),
phase: z.enum([
"freeze_scheduler",
"drain_or_abort_turns",
"merge_subrooms",
"emit_outcome",
"release_leases",
"archive",
"finalize",
]),
status: z.enum(["running", "failed", "completed"]),
error_code: z.string().optional(),
warning_codes: z.array(z.string()).default([]),
schema_version: z.literal(1),
});
```
### §4.9 Human correction queue
```ts
export const HumanCorrectionItemSchema = z.object({
correction_id: z.string().uuid(),
room_id: z.string(),
finding_id: z.string().optional(),
human_message_id: z.string().optional(),
correction_text: z.string().min(1),
issued_at: z.string().datetime(),
status: z.enum(["pending", "addressed", "dismissed"]).default("pending"),
addressed_by_turn_id: z.string().optional(),
addressed_at: z.string().datetime().optional(),
durable_save_requested: z.boolean().default(false),
durable_authority_ref: z.string().optional(),
schema_version: z.literal(1),
});
```
Migration rule: if R6 room state contains a single `human_correction_pending` object, migrate it to a one-element `human_correction_pending[]` array.
### §4.10 Round plan and loop constraints
Round plans remain R6-shaped with the following normalization: loop end index may not precede loop start index.
```ts
export const LoopConfigSchema = z.object({
loop_start_phase_index: z.number().int().nonnegative(),
loop_end_phase_index: z.number().int().nonnegative(),
max_iterations: z.number().int().positive(),
}).refine(v => v.loop_end_phase_index >= v.loop_start_phase_index);
```
### §4.11 Target instruction segments
R7 replaces the monolithic `target_instruction` assumption with typed segments.
```ts
export const TargetInstructionSegmentSchema = z.object({
kind: z.enum([
"phase_overlay",
"role_overlay",
"director_directive",
"human_correction",
"ghost_advisory",
"system_notice",
]),
required: z.boolean().default(false),
priority: z.number().int().min(1).max(100),
max_tokens: z.number().int().positive(),
text: z.string(),
});
```
### §4.12 Document manifest and binding schemas
```ts
export const RoomDocumentPinStateSchema = z.enum([
"unpinned",
"pinned_reference",
"pinned_active",
]);
export const SharedDocManifestEntrySchema = z.object({
doc_id: z.string(),
original_filename: z.string(),
storage_key: z.string(),
content_hash: z.string(),
byte_size: z.number().int().nonnegative(),
materialization_mode: z.enum([
"file_tool",
"chunk_map",
"search_tool",
"inline_excerpt",
]),
pinned_as_review_target: z.boolean().default(false),
added_at: z.string().datetime(),
schema_version: z.literal(1),
});
export const RoomDocumentBindingSchema = z.object({
binding_id: z.string().uuid(),
room_id: z.string(),
doc_id: z.string(),
doc_role: z.string().optional(),
visibility_scope: z.enum(["all", "subset", "moderator_only", "human_only"]),
phase_scope: z.array(z.string()).default([]),
pin_state: RoomDocumentPinStateSchema.default("unpinned"),
materialization_mode: z.enum([
"full_if_budget",
"summary_default",
"chunk_map",
"search_tool",
"chunk_on_demand",
]),
linked_packet_ref: z.string().optional(),
schema_version: z.literal(1),
});
```
### §4.13 Ghost delivery state
```ts
export const GhostSessionScopeSchema = z.enum([
"fresh",
"room_bound_persistent",
"surface_bound_persistent",
]);
export const GhostAdvisoryDeliverySchema = z.object({
advisory_id: z.string().uuid(),
room_id: z.string(),
ghost_participant_id: z.string(),
parent_participant_id: z.string(),
routing_target: z.enum([
"director_ui",
"parent_bootstrap",
"moderator",
"phase_reveal",
"ledger_only",
]),
delivery_state: z.enum([
"pending_parent",
"delivered_parent",
"delivered_moderator",
"escalated_director",
"expired",
]),
expires_after_room_turns: z.number().int().positive().default(3),
created_at: z.string().datetime(),
delivered_at: z.string().datetime().optional(),
schema_version: z.literal(1),
});
```
### §4.14 Approval-checkpoint substrate
```ts
export const RoomApprovalCheckpointSchema = z.object({
checkpoint_id: z.string().uuid(),
room_id: z.string(),
label: z.string(),
checkpoint_kind: z.enum([
"pre_phase_transition",
"pre_export",
"pre_child_launch",
"pre_close",
"custom",
]),
required_before: z.enum([
"advance_phase",
"export_output",
"launch_child_room",
"close_room",
]),
status: z.enum([
"pending",
"approved",
"rejected",
"returned_with_edits",
"expired",
]).default("pending"),
resume_mode: z.enum(["manual_only", "auto_after_approval"]).default("manual_only"),
requested_at: z.string().datetime(),
resolved_at: z.string().datetime().optional(),
schema_version: z.literal(1),
});
```
### §4.15 Prompt-artifact family snapshot
DOC12 may use a room-local projection in addition to imported refs.
```ts
export const PromptIdentitySnapshotSchema = z.object({
prompt_artifact_kind: z.enum([
"room_role_prompt",
"overlay_template",
"prompt_recipe",
"prompt_advisor_rewrite",
]),
prompt_variant_id: z.string().optional(),
prompt_text_hash: z.string().min(16),
prompt_assignment_id: z.string().optional(),
active_overlay_ids: z.array(z.string()).default([]),
prompt_recipe_id: z.string().uuid().optional(),
prompt_artifact_ids: z.array(z.string()).default([]),
});
export const RoomPromptPlanSnapshotSchema = z.object({
room_id: z.string(),
participant_id: z.string(),
prompt_identity: PromptIdentitySnapshotSchema.optional(),
truth_state: z.enum(["available", "degraded", "unavailable"]),
recommendation_state: z.enum([
"none",
"proposal_only",
"apply_allowed",
"applied",
]).default("none"),
why_applied: z.array(z.string()).default([]),
why_dropped: z.array(z.string()).default([]),
trimmed_artifact_ids: z.array(z.string()).default([]),
schema_version: z.literal(1),
});
```
### §4.16 Room outcome signal
```ts
export const RoomOutcomeSignalSchema = z.object({
room_id: z.string(),
room_mode: z.string(),
close_reason: RoomCloseReasonSchema,
goal_type: z.string(),
user_goal_met: UserGoalMetSchema,
satisfaction_rating: z.number().int().min(1).max(5).optional(),
tags: z.array(z.string()).default([]),
findings_starred: z.number().int().nonnegative(),
findings_by_severity: z.record(z.string(), z.number().int().nonnegative()),
participant_count: z.number().int().positive(),
total_turns: z.number().int().nonnegative(),
total_cost_usd: z.number().min(0),
cil_signal_category: z.string(),
review_target_kind: z.string().optional(),
schema_version: z.literal(1),
});
```
### §4.17 Learning-signal suppression event
```ts
export const LearningSignalSuppressionEventSchema = z.object({
event_name: z.literal("room.learning_signal.suppressed"),
room_id: z.string(),
signal_family: z.enum([
"content_findings",
"decision_basis",
"outcome_signal",
"ghost_advisory",
"prompt_artifact",
]),
suppression_reason: z.enum([
"policy_disabled",
"judgment_coverage_missing",
"review_target_missing",
"prompt_truth_unavailable",
"degraded_execution",
]),
created_at: z.string().datetime(),
schema_version: z.literal(1),
});
```
### §4.18 Contribution grades and decision basis
```ts
export const ContributionGradeSchema = z.object({
argument_quality: z.number().min(1).max(5),
novelty: z.number().min(1).max(5),
evidence_strength: z.number().min(1).max(5),
relevance: z.number().min(1).max(5),
});
export const DecisionBasisArtifactSchema = z.object({
artifact_id: z.string(),
room_id: z.string(),
contribution_grades: z.record(z.string(), ContributionGradeSchema).default({}),
cited_finding_ids: z.array(z.string()).default([]),
missing_basis_count: z.number().int().nonnegative().default(0),
decision_type: z.string().optional(),
schema_version: z.literal(1),
});
```
### §4.19 Room clone request
```ts
export const RoomCloneRequestSchema = z.object({
clone_attachments: z.boolean().default(true),
clone_ghost_configs: z.boolean().default(true),
clone_findings: z.boolean().default(false),
clone_plan_state: z.boolean().default(false),
clone_document_bindings: z.boolean().default(true),
title_override: z.string().max(200).optional(),
detached_copy: z.boolean().default(false),
config_overrides: z.record(z.string(), z.unknown()).default({}),
});
```
### §4.20 Room browser response
```ts
export const RoomBrowserListResponseSchema = z.object({
items: z.array(z.object({
room_id: z.string(),
title: z.string(),
status: RoomStatusSchema,
turn_count: z.number().int().nonnegative(),
participant_count: z.number().int().positive(),
current_phase_label: z.string().optional(),
health_status: z.enum(["green", "amber", "red"]).optional(),
last_activity_at: z.string().datetime(),
linked_room_group_id: z.string().optional(),
active_review_target_title: z.string().optional(),
})),
page: z.number().int().positive(),
page_size: z.number().int().positive(),
total: z.number().int().nonnegative(),
sort: z.enum(["last_activity_desc", "created_desc", "cost_desc", "title_asc"]),
query: z.string().optional(),
});
```
### §4.21 Room turn chunk event
```ts
export const RoomTurnChunkEventSchema = z.object({
event_name: z.literal("room.turn.chunk"),
room_id: z.string(),
room_turn_id: z.string(),
participant_id: z.string(),
run_id: z.string(),
chunk_index: z.number().int().nonnegative(),
stream_event_kind: z.enum(["delta", "heartbeat", "metadata"]),
chunk_text: z.string().default(""),
is_final: z.boolean().default(false),
schema_version: z.literal(1),
});
```
### §4.22 Room gateway adapter
DOC12 may define a room-facing adapter interface but it must use shared payload shapes exclusively.
### §4.23 Schema normalization notes
R7 also normalizes:
- `close_reason` across room state, close modal, outcome signal, and telemetry
- `review_target_kind` and prompt-lineage fields in room exports
- projection-only room finding shapes must be explicitly marked non-canonical if kept for early-phase scaffolding
### §4.24 Canonical red-team mutation request/response schemas
```ts
export const RoomJudgeFindingRequestSchema = z.object({
room_id: z.string(),
finding_id: z.string(),
idempotency_key: z.string().min(8),
expected_version: z.number().int().nonnegative(),
route_trace_id: z.string().optional(),
operation_id: z.string().optional(),
origin_surface_kind: z.string().optional(),
origin_surface_id: z.string().optional(),
judgment: FindingJudgmentSchema.omit({
room_id: true,
finding_id: true,
}),
});
export const RoomJudgeFindingResponseSchema = z.object({
status: z.enum(["ok", "conflict", "duplicate", "blocked"]),
finding_id: z.string(),
new_version: z.number().int().nonnegative().optional(),
degraded_state: RedTeamDegradedStateSchema.optional(),
});
export const RoomBatchJudgeFindingsRequestSchema = z.object({
room_id: z.string(),
batch_id: z.string().uuid(),
idempotency_key: z.string().min(8),
expected_version: z.number().int().nonnegative(),
route_trace_id: z.string().optional(),
operation_id: z.string().optional(),
judgments: z.array(
z.object({
finding_id: z.string(),
judgment: FindingJudgmentSchema.omit({ room_id: true, finding_id: true }),
})
).min(1),
});
export const RoomBatchJudgeFindingsResponseSchema = z.object({
status: z.enum(["ok", "partial", "failed"]),
batch_id: z.string().uuid(),
processed_count: z.number().int().nonnegative(),
success_count: z.number().int().nonnegative(),
error_rows: z.array(
z.object({
finding_id: z.string(),
error_code: RedTeamErrorCodeSchema,
message: z.string(),
})
).default([]),
});
export const RoomPromoteCachedFindingRequestSchema = z.object({
room_id: z.string(),
cache_entry_id: z.string(),
idempotency_key: z.string().min(8),
expected_version: z.number().int().nonnegative(),
route_trace_id: z.string().optional(),
operation_id: z.string().optional(),
});
export const RoomAdjudicateFindingRequestSchema = z.object({
room_id: z.string(),
finding_id: z.string(),
idempotency_key: z.string().min(8),
expected_version: z.number().int().nonnegative(),
route_trace_id: z.string().optional(),
operation_id: z.string().optional(),
decision: z.enum([
"resolve_accept",
"resolve_reject",
"park_disputed",
"escalate_to_human",
]),
decision_basis_refs: z.array(z.string()).default([]),
confidence: z.number().min(0).max(1).optional(),
notes: z.string().optional(),
});
export const RoomUpsertLineageRequestSchema = z.object({
room_id: z.string(),
finding_id: z.string(),
idempotency_key: z.string().min(8),
expected_version: z.number().int().nonnegative(),
route_trace_id: z.string().optional(),
operation_id: z.string().optional(),
lineage: FindingLineageSchema,
});
```
### §4.25 Findings detail, panel, and room-health projections
```ts
export const FindingsPanelProjectionSchema = z.object({
room_id: z.string(),
findings: z.array(RoomFindingSchema),
grouped_counts: z.record(z.string(), z.number().int().nonnegative()),
batch_progress: BatchReviewProgressSchema.optional(),
cache_available: z.boolean().default(false),
stale: z.boolean().default(false),
degraded_state: RedTeamDegradedStateSchema.optional(),
});
export const FindingDetailViewModelSchema = z.object({
room_id: z.string(),
finding: RoomFindingSchema,
judgments: z.array(FindingJudgmentSchema).default([]),
adjudication: FindingAdjudicationRecordSchema.optional(),
lineage: FindingLineageSchema.optional(),
review_target_binding_ref: ReviewTargetBindingRefSchema.optional(),
prompt_identity: PromptIdentityRefSchema.optional(),
degraded_state: RedTeamDegradedStateSchema.optional(),
});
export const RoomHealthProjectionSchema = z.object({
room_id: z.string(),
health_state: z.enum(["healthy", "warning", "degraded", "blocked"]),
convergence_state: z.enum(["running", "reached", "overridden"]).optional(),
summary: z.string().optional(),
degraded_state: RedTeamDegradedStateSchema.optional(),
});
```
### §4.26 Review-target binding and materialization truth
```ts
export const ReviewTargetBindingSchema = z.object({
binding_ref: ReviewTargetBindingRefSchema,
room_id: z.string(),
doc_id: z.string(),
version_group_id: z.string().optional(),
active: z.boolean().default(false),
schema_version: z.literal(1),
});
export const ReviewTargetMaterializationProjectionSchema = z.object({
binding_ref: ReviewTargetBindingRefSchema,
materialization_mode: z.enum([
"direct",
"chunked",
"search_assisted",
"unavailable",
]),
included_in_bootstrap: z.boolean(),
chunk_refs: z.array(z.string()).default([]),
dropped_reason: RedTeamErrorCodeSchema.optional(),
anchorability: z.enum(["full", "chunk", "search_only", "none"]),
schema_version: z.literal(1),
});
```
Exactly one active review-target binding may exist per room. The room projection must disclose whether the target was directly materialized, chunked, search-assisted, or unavailable.
### §4.27 Room overlay state and participant prompt-plan precedence views
```ts
export const RoomOverlayStateSchema = z.object({
room_id: z.string(),
active_overlay_ids: z.array(z.string()).default([]),
prompt_recipe_id: z.string().uuid().optional(),
prompt_artifact_ids: z.array(z.string()).default([]),
truth_state: z.enum(["available", "degraded", "unavailable"]),
schema_version: z.literal(1),
});
export const ParticipantOverlayPrecedenceViewSchema = z.object({
participant_id: z.string(),
inherited_overlay_ids: z.array(z.string()).default([]),
room_default_overlay_ids: z.array(z.string()).default([]),
participant_overlay_ids: z.array(z.string()).default([]),
effective_overlay_ids: z.array(z.string()).default([]),
dropped_overlay_ids: z.array(z.string()).default([]),
trim_reasons: z.record(z.string(), z.string()).default({}),
schema_version: z.literal(1),
});
export const ParticipantPromptPlanProjectionSchema = z.object({
room_id: z.string(),
participant_id: z.string(),
prompt_identity: PromptIdentityRefSchema.optional(),
overlay_state: RoomOverlayStateSchema.optional(),
precedence: ParticipantOverlayPrecedenceViewSchema.optional(),
truth_state: z.enum(["available", "degraded", "unavailable"]),
recommendation_state: z.enum([
"none",
"proposal_only",
"apply_allowed",
"applied",
]),
why_applied: z.array(z.string()).default([]),
why_dropped: z.array(z.string()).default([]),
schema_version: z.literal(1),
});
```
### §4.28 Child-room prompt-artifact selection and import-back schemas
```ts
export const ChildRoomPromptArtifactSelectionProjectionSchema = z.object({
overlay_application_mode: z.enum([
"inherit_none",
"inherit_room_default",
"inherit_parent_effective",
"inherit_then_append_explicit",
"explicit_only",
"explicit_select",
]),
explicit_overlay_ids: z.array(z.string()).default([]),
prompt_recipe_mode: z.enum([
"inherit_none",
"carry_context_only",
"inherit_effective_recipe",
"explicit_select",
]),
explicit_prompt_recipe_id: z.string().uuid().optional(),
});
export const RoomLaunchChildRedteamRequestSchema =
LaunchChildRedTeamRoomRequestSchema.extend({
prompt_selection: ChildRoomPromptArtifactSelectionProjectionSchema,
idempotency_key: z.string().min(8),
expected_version: z.number().int().nonnegative(),
route_trace_id: z.string().optional(),
operation_id: z.string().optional(),
});
export const RoomLaunchChildRedteamResponseSchema = z.object({
status: z.enum(["ok", "blocked", "unsupported"]),
child_room_id: z.string().optional(),
linked_room_group_id: z.string().optional(),
bootstrap_preview_ref: z.string().optional(),
effective_overlay_ids: z.array(z.string()).default([]),
effective_prompt_recipe_id: z.string().uuid().optional(),
degraded_state: RedTeamDegradedStateSchema.optional(),
});
export const RoomImportChildRedteamOutputRequestSchema = z.object({
room_id: z.string(),
child_room_id: z.string(),
linked_room_group_id: z.string(),
import_back_strategy: z.enum([
"finding_subset",
"finding_subset_plus_summary",
"full_redteam_output_ref",
]),
packet_ref: z.string(),
idempotency_key: z.string().min(8),
expected_version: z.number().int().nonnegative(),
route_trace_id: z.string().optional(),
operation_id: z.string().optional(),
});
export const ChildImportBackStatusSchema = z.object({
room_id: z.string(),
child_room_id: z.string(),
linked_room_group_id: z.string(),
status: z.enum(["pending", "imported", "skipped", "failed"]),
imported_at: z.string().datetime().optional(),
packet_ref: z.string().optional(),
schema_version: z.literal(1),
});
```
### §4.29 Red-team execution-turn-mode and reserve policy
```ts
export const RedTeamExecutionTurnModeSchema = z.enum([
"moderator_led",
"round_plan_driven",
"structured_review_loop",
]);
export const RoomReservePolicySchema = z.object({
enabled: z.boolean().default(false),
reserve_kind: z.enum([
"synthesis",
"export",
"judgment_close",
]),
min_reserved_cost_usd: z.number().min(0).default(0),
min_reserved_output_tokens: z.number().int().nonnegative().default(0),
});
export const MinimumViableCompletionSchema = z.object({
requires_synthesis: z.boolean().default(true),
requires_exportable_summary: z.boolean().default(false),
requires_close_bundle: z.boolean().default(true),
});
```
### §4.30 Red-team degraded/error state projection
```ts
export const RedTeamSurfaceDegradedStateSchema = z.object({
code: RedTeamErrorCodeSchema,
message: z.string(),
blocking: z.boolean().default(false),
affected_surface: z.string(),
});
```
### §4.31 Complete red-team event payload schemas
```ts
export const RoomFindingJudgedEventSchema = z.object({
event_name: z.literal("room.finding.judged"),
room_id: z.string(),
finding_id: z.string(),
judgment: FindingJudgmentSchema,
});
export const RoomFindingStatusChangedEventSchema = z.object({
event_name: z.literal("room.finding.status_changed"),
room_id: z.string(),
finding_id: z.string(),
status: z.string(),
});
export const RoomBatchJudgmentProgressEventSchema = z.object({
event_name: z.literal("room.batch_judgment.progress"),
room_id: z.string(),
batch_progress: BatchReviewProgressSchema,
});
export const RoomFindingPromotedEventSchema = z.object({
event_name: z.literal("room.finding.promoted_from_cache"),
room_id: z.string(),
cache_entry_id: z.string(),
finding_id: z.string(),
});
export const RoomFindingAdjudicatedEventSchema = z.object({
event_name: z.literal("room.finding.adjudicated"),
room_id: z.string(),
finding_id: z.string(),
adjudication: FindingAdjudicationRecordSchema,
});
export const RoomFindingLineageUpdatedEventSchema = z.object({
event_name: z.literal("room.finding.lineage_updated"),
room_id: z.string(),
finding_id: z.string(),
lineage: FindingLineageSchema,
});
export const RoomReviewTargetBindingMissingEventSchema = z.object({
event_name: z.literal("room.review_target.binding_missing"),
room_id: z.string(),
degraded_state: RedTeamDegradedStateSchema,
});
export const RoomReviewTargetMaterializationChangedEventSchema = z.object({
event_name: z.literal("room.review_target.materialization_changed"),
room_id: z.string(),
plan: ReviewTargetMaterializationProjectionSchema,
});
export const RoomPromptArtifactInheritedEventSchema = z.object({
event_name: z.literal("room.prompt_artifact.inherited"),
room_id: z.string(),
participant_id: z.string().optional(),
active_overlay_ids: z.array(z.string()).default([]),
prompt_recipe_id: z.string().uuid().optional(),
});
export const RoomPromptArtifactTrimmedEventSchema = z.object({
event_name: z.literal("room.prompt_artifact.trimmed"),
room_id: z.string(),
participant_id: z.string().optional(),
trimmed_artifact_ids: z.array(z.string()).default([]),
});
export const RoomPromptArtifactRecommendationAppliedEventSchema = z.object({
event_name: z.literal("room.prompt_artifact.recommendation_applied"),
room_id: z.string(),
participant_id: z.string().optional(),
prompt_identity: PromptIdentityRefSchema.optional(),
});
export const RoomPromptArtifactProposalOnlyEventSchema = z.object({
event_name: z.literal("room.prompt_artifact.proposal_only"),
room_id: z.string(),
participant_id: z.string().optional(),
degraded_state: RedTeamDegradedStateSchema.optional(),
});
export const RoomChildCreatedEventSchema = z.object({
event_name: z.literal("room.child.created"),
room_id: z.string(),
child_room_id: z.string(),
linked_room_group_id: z.string(),
});
export const RoomChildImportedBackEventSchema = z.object({
event_name: z.literal("room.child.imported_back"),
room_id: z.string(),
child_room_id: z.string(),
linked_room_group_id: z.string(),
packet_ref: z.string(),
});
export const RoomChildLaunchFailedEventSchema = z.object({
event_name: z.literal("room.child.launch_failed"),
room_id: z.string(),
degraded_state: RedTeamDegradedStateSchema,
});
export const RoomConvergenceReachedEventSchema = z.object({
event_name: z.literal("room.convergence.reached"),
room_id: z.string(),
summary: z.string().optional(),
});
export const RoomConvergenceOverriddenEventSchema = z.object({
event_name: z.literal("room.convergence.overridden"),
room_id: z.string(),
actor_participant_id: z.string().optional(),
reason: z.string().optional(),
});
```
---
## §5 Human Participant Model and Message Origin Attribution
### §5.1 Problem this solves
R6 established structural human authority. R7 completes the model by separating transient room instructions from durable authority and by replacing single-pending correction logic with an ordered queue.
### §5.2 Human participant as first-class roster entry
The human is always a visible participant in the roster and bootstrap unless a companion surface explicitly suppresses display for a view-only room. Human messages are not anonymous room events.
### §5.3 Message origin attribution
Every visible transcript item must identify:
- participant id
- origin class
- timestamp
- message sequence
- correlation id when available
Moderator-only ghost advisories are not generic moderator messages; they must be marked `ghost_advisory`.
### §5.4 DOC11 Gateway transport requirement
Free-text room turns and room-origin human messages must not bypass runtime truth when they produce visible participant turns.
### §5.5 Bootstrap participant roster
Bootstrap must include truthful participant ids, role labels, display names, and model/runtime labels when available.
### §5.6 Structural authority and transient instructions
DOC12 must say explicitly:
- room-local directives and corrections are **not** automatically durable authority
- broader-than-session persistence is approval-gated and belongs to DOC1/Core/DOC15 flows
- the room compiler passes current-turn instructions as `transient_instructions`
### §5.7 Human correction queue and follow-through
Use queued semantics, not overwrite semantics.
```ts
function hasAddressedCorrection(
completed: RoomTurnCompletedResult,
pending: HumanCorrectionItem
): boolean {
return Boolean(
completed.output_artifacts?.some(
a => a.artifact_type === "moderator_correction_ack" && a.correction_id === pending.correction_id
)
);
}
```
Rules:
- clear only the acknowledged correction item
- preserve unresolved items
- store `addressed_by_turn_id`
- do not silently clear the queue on unrelated moderator text
### §5.8 Save-to-authority path
A room UI may mark a correction as a candidate for broader persistence. DOC12 records only:
- `durable_save_requested: true`
- optional `durable_authority_ref` when a companion flow accepts the save
DOC12 must not silently promote the correction to durable authority.
---
## §6 Agent Engagement States: Solo / Mute / Pause / Capability
### §6.1 Problem this solves
Room participation interacts with global agent engagement truth, room-local mute state, runtime availability, approval blocking, and projection capability. R7 unifies those surfaces.
### §6.2 Engagement lease model
Engagement leases remain the mechanism that protects single-participant exclusivity or room-scoped isolation rules.
### §6.3 Lease acquisition and release
Leases are acquired when participation begins or when a room-mode/policy requires exclusivity. Leases are released on room close, participant removal, or specific pause/auto-pause policies.
### §6.4 Enforcement at dispatch time
Before dispatching a turn, DOC12 verifies:
- participant still exists
- participant not muted/removed
- lease and runtime binding still valid
- room not blocked by approval, close, or policy state
- room-action capabilities do not prohibit the action
### §6.5 Startup engagement lease reconciliation
Startup reconciliation should scan the active lease set and open rooms, not blindly read all historical rooms.
### §6.6 Canonical pause semantics
`pauseRoom()` is the normative lifecycle. `stopRoom()` may remain as a backward-compatible command alias.
```ts
async function pauseRoom(room_id: string, reason: string): Promise<void> {
// mark pausing / blocked
// cancel queued turns
// issue aborts for running turns
// wait for terminal truth or reconcile after timeout
// release or retain leases according to policy
// set paused and emit activity
}
```
### §6.7 Inactivity timeout
R7 adds an idle threshold. Exceeding it triggers auto-pause and stale lease release according to policy.
### §6.8 Configuring-room cleanup
Abandoned draft/configuring rooms receive TTL-based cleanup unless pinned or recently edited.
### §6.9 Room action capability report
DOC12 must expose capability truth for room actions. UI uses it to render controls as available, read-only with explanation, or unsupported.
## §7 Room Presets and Configuration Templates
### §7.1 Purpose
Presets provide safe starting configurations without hiding critical room truth.
### §7.2 Preset artifact
A preset may define:
- title template
- participant roster template
- turn mode / policy
- round plan
- document policy
- red-team policy reference
- default output template
- context pressure policy
- ghost defaults
- approval-checkpoint defaults
### §7.3 Preset versioning
Preset version must be explicit. Applying a preset produces an immutable room configuration snapshot at room creation time.
### §7.4 Quick-start vs advanced configuration
R7 requires a quick-start path and an `Advanced` toggle in Q. Advanced controls remain available; they are not required for basic room creation.
### §7.5 Preset selection semantics
Preset application is pure merge, followed by explicit override resolution. Preset application must not silently create unsupported actions or runtime assumptions.
---
## §8 Fresh-Room Bootstrap and Session Isolation
### §8.1 Default rule
Every room starts with a fresh room-owned bootstrap packet and explicit reset notice semantics.
### §8.2 Reset notice
Reset notice is required metadata in bootstrap, but it is not allowed to crowd out all other required instructions. It participates in segmented instruction fitting.
### §8.3 Human in bootstrap
The human participant and any current transient instructions must be represented truthfully.
### §8.4 Model identification in roster
Model/runtime labels are included when available from DOC11 runtime truth.
### §8.5 Forbidden default
DOC12 may not inherit hidden room history into a fresh room bootstrap unless a documented predecessor/import path is invoked.
---
## §9 Room Creation, Lifecycle, and Commands
### §9.1 Core command families
DOC12 owns room commands for:
- create / update / clone / close / archive / pause / resume
- add / remove / mute / unmute participant
- insert human turn / director action
- bind / unbind / pin room documents
- request / resolve approval checkpoints
- launch child red-team room
- finding judgment batch commands where DOC14 delegates the room-owned route surface
Every mutable command supports `Idempotency-Key` and optimistic concurrency when applicable.
#### R7.1 red-team command family
In addition to the generic room command groups above, R7.1 requires the following canonical command names in the command registry and route matrix:
- `room_judge_finding`
- `room_batch_judge_findings`
- `room_promote_cached_finding`
- `room_adjudicate_finding`
- `room_upsert_lineage`
- `room_launch_child_redteam`
- `room_import_child_redteam_output`
All red-team mutations must carry:
- `idempotency_key`
- `expected_version`
- `route_trace_id` when invoked from a route surface
- `operation_id`
- `origin_surface_kind` / `origin_surface_id` where the UI initiated the mutation
Batch routes must support partial-success row errors and must never pretend all rows succeeded when some rows failed.
### §9.2 Room create request
Room creation includes:
- title
- mode
- participant roster
- round plan or mode policy
- document bindings or draft-room ref
- red-team policy ref / object when required
- review-target binding ref when required
- prompt artifact selection refs when explicitly chosen
- ghost config(s)
- approval-checkpoint defaults
- expected config version when editing existing drafts
### §9.2A Pre-launch cost estimate
Pre-launch estimate remains advisory and must not be confused with live cost gating.
### §9.3 Draft-room flow
R7 formalizes pre-launch upload.
Required routes:
- `POST /api/rooms/drafts`
- `POST /api/rooms/drafts/:draftRoomId/documents`
- `DELETE /api/rooms/drafts/:draftRoomId`
- `POST /api/rooms` with `draft_room_id`
Draft documents are stored by manifest/content hash. The room is finalized only once the create command succeeds.
### §9.4 Room create flow
1. validate request and preset merge
2. create draft or finalize existing draft
3. preflight participant capabilities and document materialization modes
4. persist room state and participants
5. persist document bindings and draft manifest adoption
6. persist review-target binding if present
7. compute room action capability report
8. emit room created event and initial read models
### §9.5 Human turn insertion
Human turns are durable room events. They may create transient instructions and pending corrections; they do not automatically create durable authority.
### §9.6 Director mode commands
Director commands remain room policy mutations, not UI-only toggles. Every director control must have a route, mutation/refusal, and read-model refresh.
### §9.7 Room editing mutability matrix
R7 keeps the mutability matrix and refines it:
- safe mode changes may be allowed while `paused`
- topology-heavy or policy-heavy transformations still require clone/recreate
- any change that invalidates active run eligibility increments `room_revision`
### §9.8 Close lifecycle
R7 replaces one-shot close with a durable close session.
`closeRoom()` must:
1. set room status to `closing`
2. freeze scheduler
3. drain or abort running turns
4. merge subrooms / child links as applicable
5. emit outcome signal bundle
6. emit prompt observation / topology signals
7. release leases and session bindings
8. archive outputs
9. finalize to `closed`, `closed_with_warnings`, or `close_failed`
Warning close:
- optional archive/telemetry failure -> `closed_with_warnings`
Integrity failure:
- unresolved mandatory outcome bundle
- unresolved running turn
- broken child merge
- failed lease release
-> `close_failed`
### §9.9 Attachment materialization and document workspace
The document workspace is a room-owned document binding system, not a raw directory listing.
Rules:
- capability-aware preflight is required before upload, launch, or participant add
- if file-read is unsupported, fallback to `chunk_map`, `search_tool`, or `inline_excerpt`
- active review target auto-pins to `pinned_active`
- current-round submission auto-pins where review policy requires it
- active pinned docs may not be compressed away from the effective bootstrap
### §9.10 Room cloning
Clone by manifest and binding reference, not by byte-copy, unless `detached_copy: true` is explicitly requested.
### §9.11 Child-room launch compatibility
DOC12 R7 includes minimal child-room launch compatibility:
- `POST /api/rooms/:roomId/child-redteam-launch`
- preserve `linked_room_group_id`
- preserve review-target binding ref
- preserve import-back strategy
- preserve inherited vs explicit overlay / prompt-recipe truth
Full matter workflow, logical actor graph, and transfer-packet-heavy orchestration remain outside baseline R7.
### §9.11A Child-room import-back
R7.1 adds a minimal import-back seam:
- route: `POST /api/rooms/:roomId/child-redteam-imports`
- durable write: child import event + linked summary / findings projection update
- read model: `ChildImportBackStatusSchema`
- SSE: `room.child.imported_back`
This is intentionally narrower than the later DOC16 transfer-packet / matter-workbench model.
### §9.12 Approval checkpoints
DOC12 R7 includes a minimal generic checkpoint substrate. If a checkpoint is pending, the scheduler must block until resolution according to `resume_mode`.
---
## §10 Turn Modes and Scheduling
### §10.1 General rule
Every turn mode must define:
- participant eligibility
- activation criteria
- ordering
- stop/interrupt behavior
- phase interaction
- failure/degrade handling
### §10.2 Mention / directed participation modes
Mention-only and moderator-led modes remain supported with truthful participant eligibility checks.
### §10.3 Round-robin and plan-driven modes
Round-robin remains simple sequencing. Plan-driven mode uses room phase and round-plan state.
### §10.4 Concurrency rule
Only one visible room turn may be in active nonterminal execution per room unless a future spec explicitly introduces multi-turn room concurrency.
### §10.5 User interruption rule
Human/director actions may interrupt scheduling but must do so through durable state transitions, not direct UI mutation.
### §10.6 All-muted deadlock
If every eligible participant is muted or blocked, the room must emit a real deadlock event and stop auto-scheduling until state changes.
### §10.7 Approval and pause blocks
Scheduling is suspended while:
- room status is `paused`, `closing`, `close_failed`
- room block state is `awaiting_human_approval`
- room action capability report says the required next action is blocked by policy or unsupported
---
## §11 Round Plans and Dynamic Phase Orchestration
### §11.1 Purpose
Round plans provide bounded, explicit orchestration for critique, synthesis, rebuttal, and review flows.
### §11.2 Phase types
The phase system remains extensible. R7 adds required phase metadata for UI and telemetry:
- label
- iteration index
- turn count in phase
- findings produced in phase
- active participants
- transition reason
- loop badge state
### §11.3 Unified phase-advance logic
R7 deconflicts `checkPhaseTransition()` and `checkPhaseConvergence()` by requiring one normative phase-advance decision path. Implementations may split helpers internally, but the spec must define one unambiguous responsibility boundary.
### §11.3A Explicit execution-turn-mode derivation for `room_mode = red_team`
R7.1 requires an explicit derivation step from red-team room policy to execution behavior. `room_mode = red_team` may not leave actual turn-mode semantics implicit.
```ts
function deriveExecutionTurnMode(input: {
room_mode: string;
turn_policy_mode: string;
red_team_policy?: z.infer<typeof RedTeamPolicySchema>;
round_plan_present: boolean;
}): z.infer<typeof RedTeamExecutionTurnModeSchema> {
if (input.room_mode !== "red_team") {
throw new Error("deriveExecutionTurnMode called for non-red-team room");
}
if (input.round_plan_present) return "round_plan_driven";
if (input.red_team_policy) return "moderator_led";
throw new Error("red_team room missing required execution policy");
}
```
If the turn mode cannot be derived truthfully, room creation, clone finalization, and launch must block with an explicit degraded/error state rather than guessing.
### §11.3B Scheduler reserve and minimum viable completion
R7.1 adds a minimal reserve policy so a room can still synthesize, export, or close honestly under budget pressure.
Rules:
- do not start a discretionary turn if it would consume the room's reserved synthesis/export/close budget,
- emit a blocked or warning state instead,
- allow explicit human override only if policy permits it,
- surface reserve status in the room header, close modal, and launch/config surfaces where estimates are shown.
### §11.4 Loop support
Loop start/end indices must validate; loop state must appear in room read models and phase timeline surfaces.
### §11.5 Decision-basis gating
The “second miss hard fail” rule is **policy-gated**, not universal. It applies when:
- room mode is `red_team_bounded`
- room policy is `ship` or `high_stakes`
- an explicit strict decision-basis flag is enabled
### §11.6 Room health snapshots
DOC12 must refresh room-health snapshots for:
- room header chip
- findings panel
- close modal
- CIL outcome bundle
---
## §12 Director Mode: Human-as-Conductor Controls
### §12.1 Purpose
Director mode exists to give the human bounded control over room flow without collapsing room truth.
### §12.2 Director controls
Core controls include:
- insert human turn
- force next participant
- skip participant
- pause room
- request approval checkpoint
- launch child room where applicable
- inject one-time directive
### §12.3 Director control rules
Every visible control must have:
- command route
- request schema
- durable mutation or explicit refusal
- pending/success/failure UI state
- SSE/read-model refresh
- action-capability gating
### §12.4 Onboarding
R7 requires a first-run Director Bar hint so new users know what the bar does.
### §12.5 Ghost advisory display
Ghost advisories shown to the director must be explicitly marked as synthetic/advisory and must identify the ghost role and parent participant.
---
## §13 Transcript Window Manager and Context Pressure
### §13.1 Problem
Large rooms need bounded active windows and compression without lying about what remains active.
### §13.2 Two-level architecture
Transcript handling remains:
- active window
- compressed/archive summaries with provenance
### §13.3 Compression flow
Compression may summarize secondary context, but not the active pinned review target. R7 explicitly prohibits compressing out a `pinned_active` document from the effective bootstrap.
### §13.4 Context pressure
Context pressure policy remains explicit and model-aware.
### §13.5 Summary coverage
Anchor-based coverage remains the required summary validation mechanism.
### §13.6 Active window summary helper
Ghosts and child-room previews may use bounded `getActiveWindowSummary()` outputs, but those summaries are advisory and do not replace room transcript truth.
### §13.7 Prompt / review-target disclosure under pressure
When trimming occurs, room read models must expose:
- trimmed artifact ids
- dropped document bindings
- degraded prompt truth state
- chunk-map or search-tool fallback for trimmed materials
---
## §14 DOC14 Red-Team Integration Seams
### §14.1 Ownership boundary
DOC14 owns finding, judgment, adjudication, lineage, review-target binding, room health, prompt observation, and topology outcome semantics. DOC12 owns the room surface that hosts or emits those artifacts.
### §14.2 Hook interface
DOC12 consumes `RedTeamHookCallback` and related room red-team contracts from shared contracts. DOC12 must not invent alternative hook payload shapes.
### §14.3 Hook dispatch points
DOC12 provides hook points at:
- pre-turn bootstrap assembly
- post-turn terminal apply
- phase transition
- close bundle emission
- child-room launch preview / execution
### §14.4 Ordering
DOC14 owns semantic ordering. DOC12 only owns slot timing.
### §14.5 Red-team route surface
R7.1 aligns room routes to the full DOC14 companion-closure set:
| Method | Path | Purpose |
|---|---|---|
| GET | `/api/rooms/:roomId/findings` | findings panel model |
| GET | `/api/rooms/:roomId/findings/:findingId` | finding detail model |
| GET | `/api/rooms/:roomId/findings/cache` | critique cache model |
| GET | `/api/rooms/:roomId/health` | room health model |
| GET | `/api/rooms/:roomId/review-target` | active review-target model |
| GET | `/api/rooms/:roomId/prompt-plan` | participant prompt-plan model |
| POST | `/api/rooms/:roomId/findings/:findingId/judgments` | single judgment |
| POST | `/api/rooms/:roomId/findings/judgments:batch` | batch judgment |
| POST | `/api/rooms/:roomId/findings/cache/:cacheEntryId/promote` | promote cached finding |
| POST | `/api/rooms/:roomId/findings/:findingId/adjudications` | adjudicate finding |
| POST | `/api/rooms/:roomId/findings/:findingId/lineage` | upsert lineage |
| POST | `/api/rooms/:roomId/child-redteam-launch` | launch child room |
| POST | `/api/rooms/:roomId/child-redteam-imports` | import child-room output |
Route rules:
- every mutation route requires `Idempotency-Key`,
- every mutation route requires `expected_version`,
- batch routes may return partial-success row errors,
- degraded or blocked states must be explicit, never silent,
- the old `/judge` route is non-canonical and must not appear in canonical route tables.
---
## §15 Child-Room Launch and Linked-Room Compatibility
### §15.1 Scope for R7.1
R7.1 supports real child-room launch, prompt-artifact inheritance/selection, bootstrap preview, linked-room grouping, minimal import-back, and degraded-state honesty.
R7.1 does not yet implement the full DOC16 matter workbench, full transfer-packet tray, logical-actor registry, or panel-backed linked-room control plane.
### §15.2 Child-room launch request
Use DOC14-owned request semantics. R7.1 requires a request/response pair that supports truthful prompt-artifact selection and bootstrap preview.
Launch request requirements:
- parent `room_id`
- `review_target_binding_ref`
- `import_back_strategy`
- `prompt_selection` using `ChildRoomPromptArtifactSelectionProjectionSchema`
- optional human approval before launch
- `idempotency_key`
- `expected_version`
Minimum launch response must include:
- `status`
- `child_room_id`
- `linked_room_group_id`
- `bootstrap_preview_ref`
- `effective_overlay_ids`
- `effective_prompt_recipe_id`
- explicit `degraded_state` when truth is partial or blocked
### §15.3 Overlay and prompt-recipe modes
Overlay application modes supported by R7:
- `inherit_none`
- `inherit_room_default`
- `inherit_parent_effective`
- `inherit_then_append_explicit`
- `explicit_only`
- `explicit_select`
Prompt-recipe inheritance modes supported by R7:
- `inherit_none`
- `carry_context_only`
- `inherit_effective_recipe`
- `explicit_select`
### §15.4 Child-room prompt truth
Child-room preview and room-state read models must disclose:
- inherited vs explicit overlays
- inherited vs explicit prompt recipe
- degraded or unavailable prompt truth state
- import-back strategy
- human-approval-before-launch state
### §15.5 Linked-room refs
Parent and child rooms persist `linked_room_group_id` and lightweight linkage artifacts so lineage and import-back flows remain truthful.
### §15.6 Child-room import-back
R7.1 adds a minimal import-back seam:
- route: `POST /api/rooms/:roomId/child-redteam-imports`
- durable write: child import event plus linked summary / findings projection update
- read model: `ChildImportBackStatusSchema`
- SSE: `room.child.imported_back`
### §15.7 Prompt-truth note
Child-room launch preview must truthfully disclose inherited overlays, explicitly selected overlays, inherited prompt recipe, explicitly selected prompt recipe, and any trimmed artifacts when DOC11 truth is available. If prompt truth is degraded or unavailable, the launch modal must say so explicitly.
---
## §16 Room Output Contracts, Approval Checkpoints, and Structured Export
### §16.1 Output templates
Output templates remain room-owned and may be validated against room mode and review policy.
### §16.2 Approval checkpoint commands
R7 introduces a generic approval-checkpoint substrate.
Required commands/routes:
- `room_request_approval`
- `room_approve_checkpoint`
- `room_reject_checkpoint`
- `room_return_with_edits`
- `POST /api/rooms/:roomId/approval-checkpoints`
- `POST /api/rooms/:roomId/approval-checkpoints/:checkpointId/approve`
- `POST /api/rooms/:roomId/approval-checkpoints/:checkpointId/reject`
- `POST /api/rooms/:roomId/approval-checkpoints/:checkpointId/return-with-edits`
- `GET /api/rooms/:roomId/approval-checkpoints`
### §16.3 Scheduler blocking semantics
While a checkpoint is pending:
- room scheduler must stop progression
- room header/director bar must display blocked state
- resume follows `resume_mode`
### §16.4 Export flow
Export or close flows may require approval checkpoints before proceeding.
### §16.5 Format conversion ownership
DOC12 owns room export orchestration. Format-specific conversion may be delegated elsewhere, but DOC12 owns the room-side command, blocking, and success/failure truth.
## §17 Runtime Mapping and Gateway Integration
### §17.1 Room coordinator flow
The room coordinator owns:
- queue selection
- policy and eligibility checks
- bootstrap assembly
- runtime dispatch request formation
- stream relay
- terminal result apply
- ghost sidecar enqueue
- post-turn hook dispatch
- room-health / prompt-observation / learning bridge emission
### §17.2 Gateway dispatch contract
DOC12 uses DOC11-owned transport payloads. DOC12 must not invent local room-turn result or delta shapes.
### §17.3 Runtime binding
Every visible participant has a room-owned runtime binding record that references the runtime session truth used for room execution.
### §17.4 Prompt-plan truth and bootstrap metadata
Bootstrap and related manifests must carry, whether or not all fields are shown to the model:
- prompt identity ref
- active overlays
- prompt recipe ref
- prompt artifact ids
- review target binding ref
- document binding refs
- pending approval checkpoint ref
- linked-room refs where present
### §17.4A R7.1 bootstrap truth extensions
Prompt-plan truth and bootstrap metadata must now include, when available:
- prompt identity snapshot or ref,
- active overlay ids,
- prompt recipe id,
- prompt artifact ids,
- review-target binding ref,
- review-target materialization plan,
- reserve-policy summary and minimum-viable-completion metadata where applicable.
### §17.4B Bootstrap packet shape extensions
`buildRoomBootstrapPacket()` must support the following additional fields:
```ts
active_review_target_ref?: ReviewTargetBindingRefSchema
review_target_materialization_plan?: ReviewTargetMaterializationProjectionSchema
room_overlay_state?: RoomOverlayStateSchema
participant_prompt_plan?: ParticipantPromptPlanProjectionSchema
reserve_policy?: RoomReservePolicySchema
minimum_viable_completion?: MinimumViableCompletionSchema
```
### §17A `buildRoomBootstrapPacket()`
R7 changes bootstrap assembly in three ways:
1. instruction segments replace monolithic `target_instruction`
2. prompt-artifact family truth is attached to the packet / manifest
3. active pinned review targets may not be silently trimmed out of the effective bootstrap
Required helpers:
- `estimateTokens()`
- `getModelContextBudget()`
- `peekOneTimeInstructionOverlay()`
- `popOneTimeInstructionOverlay()`
- `getGhostAdvisoryForParent()`
- `buildRoomBootstrapPacket()`
- `truncateBootstrapToFit()`
Algorithm:
1. assemble required instruction segments
2. attach room/participant/prompt/review-target/document metadata
3. estimate packet cost against model budget
4. trim lowest-priority optional segments first
5. if required segments alone exceed budget, block dispatch honestly
### §17B `dispatchRoomTurn()` — the central pipeline
R7 replaces the R6 optimistic gap with a replay-safe sequence.
Normative sequence:
1. lock room
2. reload room + participant + queued head
3. verify action capability, current version, eligibility, and not blocked/closing
4. persist `RoomTurnExecutionState(state = "dispatching")`
5. unlock
6. call DOC11 room-turn dispatch
7. persist `accepted + run_id`
8. relay stream deltas via `room.turn.chunk`
9. await terminal completion
10. re-lock
11. reload room + participant + execution record
12. if invalidated (room closed, participant removed, revision mismatch, close epoch changed), reconcile explicitly
13. otherwise apply terminal status faithfully
14. unlock
15. enqueue post-turn ghost sidecars / hooks / room-health updates
Faithful terminal mapping:
```ts
switch (terminal.status) {
case "completed":
appendAgentMessage(...);
markTurnCompleted(...);
break;
case "failed":
markTurnFailed(...);
emitRoomEvent("room.turn.failed", ...);
break;
case "aborted":
markTurnAborted(...);
emitRoomEvent("room.turn.aborted", ...);
break;
}
```
Important prohibitions:
- no fake completion after dispatch accept
- no blind result apply after room close or participant removal
- no transcript append for failed or aborted turns unless the event explicitly says so
- no ghost execution while the room lock is held
#### R7.1 revalidation checks before terminal apply
Before applying a completed, failed, or aborted terminal result, DOC12 must additionally verify:
- the review-target binding is still valid if the turn required one,
- participant prompt-plan truth is still eligible for any claimed applied artifacts,
- `room_close_epoch` is unchanged,
- `room_revision` is still compatible,
- the participant is still present,
- the execution turn mode is still derivable.
If any of those checks fail, DOC12 must enter explicit reconcile/degrade behavior rather than blindly applying the terminal result as if nothing changed.
#### R7.1 telemetry additions
The dispatch pipeline must also emit/record telemetry for:
- review-target materialization changes,
- prompt-artifact proposal-only state,
- child-room launch and import-back operations that are triggered from room actions,
- batch judgment operations initiated inside the room surface.
### §17C Dispatch failure handler
DOC12 must define `handleDispatchFailure()` with:
- retry/strike limit
- participant degrade/skip behavior
- room event emission
- preserved reason codes
- no fake terminal success
---
## §18 Context Inspection, Prompt Plans, and DOC11 Wiring
### §18.1 DOC11 coverage
DOC11 owns final prompt-plan truth, room-turn transport truth, stream/abort semantics, runtime capability checks, and effective prompt disclosure.
### §18.2 DOC12 requirements on DOC11
DOC12 requires from DOC11:
- room-turn request/result/stream/abort payloads
- runtime capability / health checks
- prompt-plan truth sufficient for room prompt-plan read models
- room-bound session/runtime binding truth
### §18.3 Room prompt-plan read models
R7 requires:
- `GET /api/rooms/:roomId/prompt-plan`
- participant-level prompt-plan rows
- room-local snapshot refs in room state
- explicit `truth_state`
- recommendation state: `none | proposal_only | apply_allowed | applied`
### §18.3A Room overlay state and prompt-plan precedence
R7.1 requires room query surfaces to expose:
- room-level active overlay state,
- per-participant overlay precedence,
- truth-state triad: `available / degraded / unavailable`,
- recommendation-state quadrants: `none / proposal_only / apply_allowed / applied`.
DOC11 remains the owner of effective prompt-plan truth, overlay packet truth, trim reasons, review-target inclusion truth, candidate apply gate truth, and runtime packet inspection. DOC12 owns the room projections and query surfaces that expose those truths to Q and companion docs.
### §18.4 Context inspector semantics
The context inspector must show:
- effective room bootstrap manifest
- prompt identity snapshot
- document bindings and active pin states
- review-target binding truth
- trimmed/dropped artifacts and why
- approval checkpoint refs
### §18.5 Proposal-only and degraded states
Without companion support from DOC11 prompt truth, DOC15 recommendation retrieval, and DOC8 optimizer gates, DOC12 must expose `proposal_only` or `unavailable` instead of implying applyable prompt-artifact recommendations.
Where prompt recommendations appear, the room must distinguish:
- no recommendation
- proposal-only because truth/apply gates are not satisfied
- degraded/unavailable because prompt truth is missing
- applied because all owner-doc gates allowed it
---
## §19 Ghost Agents — Configurable Shadow Participants
### §19.1 What ghost agents are
Ghost agents are hidden advisory sidecar participants attached to visible parents or room surfaces. They are not top-level visible room participants in the canonical transcript.
### §19.2 Default execution lane
R7 moves ghosts to an async advisory lane.
Default rule:
- parent visible turn reaches terminal state first
- room lock is released
- ghost sidecar work begins asynchronously
- ghost failure does not corrupt parent status
- only immediate-delivery modes may block the next **eligible parent turn**, never the whole room
### §19.3 Ghost config and quotas
Recommended defaults:
```ts
const ROOM_MAX_GHOST_AGENTS_TOTAL = 12;
const DEFAULT_GHOST_BUDGET_QUOTA = 0.30;
```
Default session scope:
- `ghost_session_scope = "surface_bound_persistent"`
### §19.4 Routing modes
Supported routing modes:
- `director_ui`
- `parent_bootstrap`
- `moderator`
- `phase_reveal`
- `ledger_only`
### §19.5 Delivery semantics
`parent_bootstrap` advisories have TTL-based delivery semantics. If undelivered after the configured room-turn horizon, they expire or escalate.
Moderator/director delivery must display:
- ghost role label
- parent participant
- synthetic/advisory status
### §19.6 Ghost prompt-packet validation
Ghost dispatch must validate:
- context window cap
- routing wrapper overhead
- overlay/prompt-advisor interaction overhead
- selected ghost model capability
### §19.7 Ghost helper functions
R7 requires explicit definitions for:
- `dispatchGhostTurn()`
- `buildGhostBootstrap()`
- `routeGhostOutputs()`
- `storeGhostAdvisory()`
- `writeGhostScratchpad()`
- `applyGhostLedgerAnnotations()`
- `getActiveWindowSummary()`
### §19.8 Ghost UI/read-model surfaces
DOC12 must expose ghost advisory read models for:
- director bar / drawer
- moderator-only surfaces
- parent advisory queue
- phase reveal state where configured
---
## §20 Memory, Retention, Self-Learning, and DOC15/CIL Bridge
### §20.1 Policy bundle
Room policy defines retention, export, suppression, promotion eligibility, and review-mode-specific signal behavior.
### §20.2 Room-close CIL bundle
On close, DOC12 emits a CIL-compatible bundle containing:
- room outcome signal
- participant roster snapshot
- room health snapshot ref
- prompt observation refs
- topology outcome ref
- decision basis artifact ref
- review target kind
- active target pin state
- suppression event when any capture path was intentionally withheld
### §20.3 Decision basis export
Turn and close paths must emit or reference:
- cited finding refs
- `decision_type`
- `decision_without_basis` where relevant
- prompt-lineage fields
- review-target kind
### §20.4 Finding-to-action tracking
Room-side emissions should include when a finding:
- is exported
- becomes a proposal
- survives dedup
### §20.5 Prompt-artifact family observation
Room observations and prompt observation events must preserve:
- `prompt_variant_id`
- `prompt_text_hash`
- `prompt_assignment_id`
- `active_overlay_ids`
- `prompt_recipe_id`
- `prompt_artifact_ids`
- `review_target_binding_ref`
### §20.5A Review-target and prompt-artifact export truth
When findings, judgments, adjudications, lineage updates, or outcome signals are exported to DOC15, DOC12 should preserve:
- `review_target_binding_ref`,
- active-target truth,
- prompt identity refs,
- room overlay / prompt-recipe truth,
- recommendation-state summary.
This allows downstream novelty, review-outcome, and recommendation models to distinguish review-target-bound critique from generic discussion.
### §20.6 Transient instruction vs durable authority
Room observations must distinguish:
- transient current-turn instructions
- durable authority actually applied
- durable authority skipped because scope/approval/precedence prevented it
### §20.7 Learning suppression
When learning signals are intentionally withheld, DOC12 must emit `room.learning_signal.suppressed`. Silence is not enough.
---
## §21 Moderator Role
### §21.1 Moderator options
A room may have an explicit moderator participant or moderator responsibilities may be assigned to a role-bearing participant depending on room mode.
### §21.2 Responsibilities
Moderator responsibilities may include:
- phase transition authority
- correction acknowledgement
- structured synthesis
- batch judgment review guidance
- approval checkpoint request
- child-room launch suggestion
### §21.3 Constraints
A moderator may not lie about runtime, findings provenance, review-target truth, prompt truth, or child-room inheritance.
### §21.4 Decision basis requirement
Where decision-basis policy is active, moderator outputs must carry or point to a real `DecisionBasisArtifact`.
### §21.5 Moderator failure
If moderator execution degrades or aborts, the room must either retry, skip, pause, or request human action according to policy—never silently proceed as though moderation occurred.
---
## §22 Forums and Panels
### §22.1 Shared substrate
Rooms may surface artifacts into panels and forums, but those shells do not become the canonical execution runtime.
### §22.2 Bridge actions
Room-origin actions surfaced elsewhere must preserve room ids, room-turn refs, correlation ids, review-target refs, prompt identity refs, and other provenance required by companion specs.
### §22.3 Child-room launch affordance
Panels or document views may expose “Red-team this draft” or related launch affordances, but the actual child-room launch remains a DOC12-owned room command.
### §22.4 Read-only degradation
If a panel or forum view lacks room-action capability, it must render read-only truthfully rather than exposing clickable no-op controls.
---
## §23 UI Design in Q
### §23.1 Canonical room surface
The room view remains the canonical surface for visible room execution, findings, review-target viewing, prompt-plan truth, and control state.
### §23.1A Additional R7.1 room surfaces
R7.1 additionally requires truthful room support for:
- Findings Batch Review
- Finding Detail Modal
- Critique Cache Drawer
- Review Target Viewer
- Prompt Plan Drawer / participant prompt tab
- Child-Room Launch Modal
- Child Import Status indicator
- Convergence banner / override state
- degraded / blocked / stale state rendering per surface
### §23.2 Room header
The room header must show:
- title
- room status
- phase label
- health status
- blocked/approval state
- prompt-truth state when relevant
- active review-target title/badge when relevant
### §23.3 Director bar
R7 adds:
- onboarding hint
- explicit pause state
- explicit approval-blocked state
- action-capability gating
- ghost advisory provenance
### §23.4 Participant drawer
The participant drawer must include a prompt-plan tab that can show:
- prompt artifact kind,
- active overlays,
- prompt recipe,
- artifact ids,
- why applied / why dropped,
- `proposal_only` / `apply_allowed` / `applied` / `unavailable`,
- degraded-state explanation when truth is partial.
R7 requires:
- prompt-plan tab
- runtime truth lines
- action-capability gating
- room-health chip
- prompt recommendation card with `proposal_only / apply_allowed / applied / unavailable`
### §23.5 Findings panel
R7.1 extends the findings surface to require:
- single judgments,
- batch review,
- row-level batch errors,
- adjudication action,
- lineage action,
- finding detail modal,
- cache promotion,
- degraded and blocked states.
R7 requires:
- updated DOC14 dispositions and rejection reasons
- `idempotency_key`
- `expected_version`
- batch review
- adjudication
- lineage view
- review-target anchor and document jump support
### §23.6 Transcript view
Transcript view must render streamed chunks, terminal status events, prompt/review-target provenance where visible, and correction/approval activity without inventing state.
### §23.7 Composer
Composer must support human turns, file attach where the room allows it, and explicit capability/degrade messaging if the room cannot accept the requested action.
### §23.8 Room close / export modal
R7.1 extends the close/export surface to show:
- batch-review completeness,
- adjudication/dispute summary,
- prompt artifacts actually used,
- active review-target summary,
- recommendation state summary,
- child-room launch shortcut when relevant,
- learning-signal suppressed notices where applicable.
R7 close modal must surface:
- unresolved findings and batch-review completeness
- prompt artifacts actually used
- active review target truth
- findings starred count
- room health summary
- goal type / goal outcome / tags / satisfaction
- prompt recommendation and learning-signal state (`proposal_only`, degraded, etc.)
### §23.9 Configure room modal
R7 configurator must support:
- quick-start flow
- Advanced toggle hiding deeper tabs by default
- draft-room document upload chips
- explicit review-target binding
- evidence domain / review-target kind
- prompt recommendation preview with degraded/proposal-only states
- explicit overlay and prompt recipe selection when feature-gated
- ghost discoverability in Participants tab and presets
- action capability warnings
### §23.10 Review-target viewer and document viewer
R7.1 requires the review-target/document surface to disclose:
- materialization mode,
- anchorability state,
- dropped/degraded reason,
- active pin state,
- child-room launch CTA,
- child import-back status where relevant.
The room view must provide a dedicated review-target/document viewer surface showing:
- title
- materialization mode
- dropped/degraded reason
- chunk-map/search-tool disclosure
- active pin badge
- child-room launch CTA where allowed
The document viewer should either support split view with findings or a floating evidence overlay.
### §23.11 Room browser
R7 requires real pagination, sort, filter, and room card content wired to the browser response schema.
### §23.12 Agents page
Engagement polling must be visibility-aware.
---
## §24 ACP Posture
ACP-specific execution remains optional. If ACP-only actions are not available:
- the room action capability report must say so
- UI must degrade to read-only or unsupported with explanation
- no ACP-specific button may remain clickable without a real route/mutation path
---
## §25 External Channel Projection
R7 reserves room for channel/topic/thread projection truth but does not make full external projection a baseline requirement. Any implemented projection must preserve capability truth, room/channel binding truth, and attachment/media handling truth.
## §26 Telemetry and Provenance
### §26.1 Required telemetry families
R7.1 requires telemetry for:
- room turn dispatch / stream / terminal apply
- approval checkpoint requested / resolved
- close-session phase transitions
- cost and reserve watermarks
- cache promotion
- adjudication
- lineage upsert
- review-target materialization change
- prompt artifact inherited / trimmed / proposal-only / applied
- child-room launch failed
- child-room import-back
- convergence reached / overridden
- prompt observation emitted
- learning signal suppressed
### §26.2 Minimum event payload
Every event must preserve, where applicable:
- room id
- participant id
- room turn id
- correlation id
- route trace id
- usage sample ref
- execution watermark ref
- dispatch max output token cap
- prompt identity snapshot or ref
- review target binding ref
### §26.3 SSE event mapping
The normalized room event list for R7.1 is:
- `room.turn.chunk`
- `room.turn.failed`
- `room.turn.aborted`
- `room.finding.judged`
- `room.finding.status_changed`
- `room.batch_judgment.progress`
- `room.finding.promoted_from_cache`
- `room.finding.adjudicated`
- `room.finding.lineage_updated`
- `room.health.updated`
- `room.prompt_observation.emitted`
- `room.prompt_artifact.updated`
- `room.prompt_artifact.inherited`
- `room.prompt_artifact.trimmed`
- `room.prompt_artifact.recommendation_applied`
- `room.prompt_artifact.proposal_only`
- `room.review_target.updated`
- `room.review_target.binding_missing`
- `room.review_target.materialization_changed`
- `room.document_binding.updated`
- `room.close.state_changed`
- `room.child.created`
- `room.child.imported_back`
- `room.child.launch_failed`
- `room.approval_checkpoint.requested`
- `room.approval_checkpoint.resolved`
- `room.action_capability.updated`
- `room.learning_signal.suppressed`
- `room.clone.created`
- `room.convergence.reached`
- `room.convergence.overridden`
### §26.3A `room.turn.chunk` semantics
Only DOC11 stream deltas with visible text contribute to `chunk_text`. Heartbeats are keepalive only. Metadata events are not transcript text.
### §26.4 Provenance requirements
Findings, judgments, adjudications, lineage, prompt observations, room-close bundles, review-target plans, and child-room launch/import previews must preserve prompt identity refs and review-target binding refs whenever those refs exist.
Findings, judgments, decision-basis exports, prompt observations, room-close bundles, and child-room launch previews must preserve prompt identity and review-target provenance.
### §26.5 Usage and cost telemetry
Usage/cost telemetry must preserve room and participant subtotal seams and must not conflate UI-target token desires with runtime `dispatch_max_output_tokens_cap` truth.
---
## §27 Participant Failure and Graceful Degradation
### §27.1 Three-strike escalation
Repeated participant dispatch failure may degrade or temporarily skip a participant according to policy, but must not silently erase the participant from the room.
### §27.2 Snapshot on every failure
Before applying degrade/skip/abort consequences, capture failure snapshot truth sufficient for replay, debugging, and review.
### §27.3 Runtime degradation
When DOC11 or underlying runtime capability is degraded:
- room action capability report updates
- relevant actions become read-only / unsupported / degraded
- prompt recommendation surfaces fall back to proposal-only or unavailable where required
### §27.4 Room hard limits
Hard limits remain on:
- cost
- active turns
- participant count
- ghost count
- loop iterations
- retry count
### §27.5 STOP/abort propagation
Abort flows must preserve DOC11 abort truth. Room stop/pause must not fake success if runtime abort is unknown or pending.
### §27.6 Forbidden patterns
Forbidden:
- clickable no-op controls
- fake completed room turns after runtime failure
- silent child-room inheritance changes
- silent review-target truncation
- silent prompt recommendation application without prompt-plan truth
- silent conversion of room-local corrections into durable authority
---
## §28 Implementation Surfaces
### §28.1 EC modules
Suggested room-owned EC modules:
- `RoomCommandService`
- `RoomStateStore`
- `RoomExecutionCoordinator`
- `RoomGatewayAdapter`
- `RoomDocumentBindingService`
- `RoomCloseService`
- `RoomApprovalService`
- `RoomPromptPlanProjectionService`
- `RoomActionCapabilityService`
- `RoomSSEManager`
### §28.2 Q Backend routes
Canonical route families include:
- room browser/list/detail/state
- room create/edit/clone/close/pause/resume
- participant actions
- findings/judgment/adjudication/lineage
- health / prompt-plan / review-target / document bindings
- child-room launch
- approval checkpoints
- draft-room lifecycle
- action-capability read route
### §28.3 Q Frontend components
Core R7 room components:
- `RoomPage`
- `RoomHeader`
- `DirectorBar`
- `ParticipantDrawer`
- `PromptPlanTab`
- `FindingsPanel`
- `ReviewTargetViewer`
- `DocumentViewer`
- `ApprovalCheckpointBanner`
- `ChildRoomLaunchModal`
- `RoomCloseModal`
- `RoomConfigurator`
- `RoomBrowserPage`
### §28.4 Helper functions that must be defined
R7 requires concrete definitions for the helper names used in pseudocode, including:
- `estimateTokens()`
- `getModelContextBudget()`
- `peekOneTimeInstructionOverlay()`
- `popOneTimeInstructionOverlay()`
- `getGhostAdvisoryForParent()`
- `buildRoomBootstrapPacket()`
- `truncateBootstrapToFit()`
- `handleDispatchFailure()`
- `dispatchGhostTurn()`
- `buildGhostBootstrap()`
- `routeGhostOutputs()`
- `storeGhostAdvisory()`
- `writeGhostScratchpad()`
- `applyGhostLedgerAnnotations()`
- `getActiveWindowSummary()`
- `buildOutcomeSignal()`
- `pauseRoom()`
### §28.5 Acceptance tests
R7 requires explicit acceptance tests for:
- crash after dispatch accept but before apply
- crash during stream
- room closes during run
- participant removed during run
- aborted terminal state mapping
- merge failure -> `close_failed`
- noncritical archive failure -> `closed_with_warnings`
- ghost async does not block main loop
- parent bootstrap TTL escalation
- active target auto-pins and remains uncompressed
- capability fallback for document materialization
- child-room preview shows inherited vs explicit prompt artifacts
- checkpoint blocks scheduler
- stale `/judge` path removed
- draft-room upload works pre-create
- every visible control has route + mutation/refusal + refresh
---
## §29 Phasing
### Phase 0 — Foundational
Required for build-safe handoff:
- durable turn execution journal
- faithful DOC11 room-turn transport usage
- close-session lifecycle
- action capability reporting
- draft-room flow
- active review-target pinning
- capability-aware document bindings
- prompt-plan truth surfaces and proposal-only states
- findings route alignment to DOC14 v5.1
- correction queue
- approval-checkpoint substrate
### Phase 1 — Core intelligence and companion compatibility
- richer child-room launch flows
- deeper prompt recommendation surfaces
- richer review-target materialization and large-doc flows
- prompt observation families and analytics depth beyond minimum capture
### Phase 2 — Advanced linked-room expansion
- transfer packets
- matter shell
- logical actor graph
- richer linked-room constellation orchestration
### Phase 3 — Research
- channel projection expansion
- advanced ACP-specific orchestration
- experimental multi-room routing logic
---
### §29.X R7.1 scope boundary
R7.1 includes:
- red-team command/read-model/event closure,
- review-target truth,
- prompt-plan room projections,
- child-room launch plus minimal import-back,
- minimum viable completion reserve,
- degraded-state honesty.
R7.1 does not include:
- full DOC16 matter workbench,
- full linked-room transfer tray,
- logical-actor registry,
- DOC8 optimizer lifecycle implementation,
- DOC15 recommendation-node ownership logic,
- full delta-since refresh as a Phase 0 ship gate.
## §30 Minimum Viable Room — End-to-End Walkthrough
### Step 1: Create draft and upload docs
The user opens the configurator, creates a draft room, uploads candidate documents, and optionally marks a review target.
### Step 2: Finalize room creation
DOC12 validates participant capabilities, materialization modes, preset merge, action capability report, and room policy. The room becomes `active` or `configuring` with truthful reasons.
### Step 3: User sends human turn
The human turn enters the transcript, may add transient instructions, and may add queued correction items.
### Step 4: Room dispatches participant turn
DOC12 locks room state, records `dispatching`, unlocks for Gateway dispatch, persists `accepted` and `run_id`, streams `room.turn.chunk`, and on completion re-locks and applies terminal truth faithfully.
### Step 5: Ghost sidecar runs
If configured, ghost advisories run asynchronously after the parent turn and are routed according to configured delivery semantics.
### Step 6: Findings and review target surfaces update
Findings, review-target viewer, room health, prompt plan, and capability surfaces update through SSE/read-model refresh.
### Step 7: Approval checkpoint blocks progress when needed
If the room reaches a checkpoint, scheduling stops until the checkpoint is resolved.
### Step 8: Child room launches when requested
If launched, the child room carries inherited or explicit prompt artifacts, review-target binding truth, and linked-room group refs.
### Step 9: Close
Close enters `closing`, drains/aborts turns, emits outcome/prompt/topology bundles, releases leases, archives, and lands in `closed`, `closed_with_warnings`, or `close_failed`.
---
## §31 Final Rule
If a DOC12 behavior affects visible room truth, it must be specified all the way through:
- payload shape
- mutation or refusal path
- read-model refresh
- SSE/telemetry behavior
- degraded/unavailable behavior
- tests
Anything less is room theater and is forbidden.
---
## §32 Notes for Companion Document Updates
### §32.1 DOC10 ledger updates required after R7 lands
Add or update ledger rows for:
- room execution journal / close-session artifacts
- room action capability reporting
- prompt-artifact family truth across DOC11/DOC12/DOC14/DOC15/DOC17/Q
- child-room launch preview / overlay mode / prompt recipe selection
- document binding / active review-target pinning
- approval checkpoints
- draft-room upload flow
### §32.2 DOC15 contract follow-up
After DOC12 R7 lands, update DOC15 integration contract status rows for:
- room-close CIL signal bundle
- prompt lineage on room turns
- decision basis export
- active review-target pin state export
- transient instruction and applied/skipped authority trace coverage
### §32.3 Q UI companion updates
Q R4 must remain aligned with:
- updated findings routes and batch flows
- prompt-plan drawer and degraded/proposal-only prompt truth states
- child-room launch preview
- review-target viewer
- draft-room upload flow
- approval checkpoint surfaces
- action capability gating
### §32.4 Companion version references
DOC12 R7 assumes:
- DOC10 Ledger R10
- DOC11 R12.2
- DOC14 v5.1
- DOC15 R6 + integration contract R2
- DOC16 R5.1
- DOC17 R4.2
- Q UI R4
---
R7.1 companion coordination list:
- DOC10 ledger rows for red-team commands, route traces, prompt-artifact lifecycle, telemetry registration, and action-capability tests,
- DOC11 alignment on prompt-plan truth, overlay packet truth, review-target inclusion truth, degraded truth, and runtime packet inspector,
- DOC15 follow-up on recommendation retrieval, recommendation node, reverse-path fields, and review-outcome ingestion,
- DOC8 follow-up on prompt-variant artifacts, prompt-assignment artifacts, and replay/canary lifecycles,
- DOC13 alignment on room/participant cost tagging and supervision-cost snapshots,
- DOC17 alignment on prompt-artifact family ids and observation emission,
- DOC16 cross-reference update after acceptance of child-room launch/import-back and approval checkpoints,
- Q UI R4.1 adoption.
## Appendix A — Canonical route matrix
### Room lifecycle and browser
- `GET /api/rooms`
- `GET /api/rooms/:roomId`
- `GET /api/rooms/:roomId/state?since_revision=...`
- `POST /api/rooms`
- `PATCH /api/rooms/:roomId`
- `POST /api/rooms/:roomId/clone`
- `POST /api/rooms/:roomId/pause`
- `POST /api/rooms/:roomId/resume`
- `POST /api/rooms/:roomId/close`
### Draft rooms
- `POST /api/rooms/drafts`
- `POST /api/rooms/drafts/:draftRoomId/documents`
- `DELETE /api/rooms/drafts/:draftRoomId`
### Participants and actions
- `POST /api/rooms/:roomId/participants`
- `POST /api/rooms/:roomId/participants/:participantId/mute`
- `POST /api/rooms/:roomId/participants/:participantId/unmute`
- `DELETE /api/rooms/:roomId/participants/:participantId`
- `GET /api/rooms/:roomId/action-capabilities`
### Findings / review / health
- `GET /api/rooms/:roomId/findings`
- `GET /api/rooms/:roomId/findings/cache`
- `POST /api/rooms/:roomId/findings/:findingId/judgments`
- `POST /api/rooms/:roomId/findings/judgments:batch`
- `POST /api/rooms/:roomId/findings/:findingId/adjudications`
- `POST /api/rooms/:roomId/findings/:findingId/lineage`
- `GET /api/rooms/:roomId/health`
### Documents / review target / prompt plan
- `GET /api/rooms/:roomId/document-bindings`
- `GET /api/rooms/:roomId/review-target`
- `GET /api/rooms/:roomId/prompt-plan`
### Approval checkpoints and child rooms
- `GET /api/rooms/:roomId/approval-checkpoints`
- `POST /api/rooms/:roomId/approval-checkpoints`
- `POST /api/rooms/:roomId/approval-checkpoints/:checkpointId/approve`
- `POST /api/rooms/:roomId/approval-checkpoints/:checkpointId/reject`
- `POST /api/rooms/:roomId/approval-checkpoints/:checkpointId/return-with-edits`
- `POST /api/rooms/:roomId/child-redteam-launch`
### R7.1 red-team additions
- `GET /api/rooms/:roomId/findings/:findingId`
- `POST /api/rooms/:roomId/findings/cache/:cacheEntryId/promote`
- `POST /api/rooms/:roomId/child-redteam-imports`
## Appendix B — Required read-models
DOC12 R7 requires durable or derivable read-models for:
- room current state
- participant roster and runtime truth
- turn execution current state
- room browser list items
- action-capability report
- document binding list + active pin state
- review-target view model
- prompt-plan room model
- prompt-plan participant rows
- findings list + cache projection
- room health snapshot
- approval checkpoint list/history
- close session current state
- child-link/current linkage projection
- ghost advisory projections
### R7.1 required additions
- `FindingDetailViewModelSchema`
- `BatchReviewProgressSchema`
- `ReviewTargetMaterializationProjectionSchema`
- `RoomOverlayStateSchema`
- `ParticipantPromptPlanProjectionSchema`
- `ChildImportBackStatusSchema`
## Appendix C — Helper signatures that must exist
```ts
function estimateTokens(input: unknown, modelId: string): number;
function getModelContextBudget(modelId: string): number;
function peekOneTimeInstructionOverlay(room_id: string): unknown | null;
function popOneTimeInstructionOverlay(room_id: string): void;
function getGhostAdvisoryForParent(room_id: string, participant_id: string): GhostAdvisoryDelivery | null;
function buildGatewayRequest(args: unknown): GatewayRoomTurnDispatchRequest;
function buildRoomBootstrapPacket(args: unknown): unknown;
function truncateBootstrapToFit(args: unknown): unknown;
function emitRoomTurnChunk(args: unknown): void;
function checkTranscriptWindowPressure(room_id: string): unknown;
function handleDispatchFailure(args: unknown): Promise<void>;
function dispatchGhostTurn(args: unknown): Promise<unknown>;
function buildGhostBootstrap(args: unknown): unknown;
function routeGhostOutputs(args: unknown): Promise<void>;
function storeGhostAdvisory(args: unknown): Promise<void>;
function writeGhostScratchpad(args: unknown): Promise<void>;
function applyGhostLedgerAnnotations(args: unknown): Promise<void>;
function getActiveWindowSummary(room_id: string): unknown;
function buildOutcomeSignal(args: unknown): RoomOutcomeSignal;
async function pauseRoom(room_id: string, reason: string): Promise<void>;
function deriveExecutionTurnMode(input: {
room_mode: string;
turn_policy_mode: string;
red_team_policy?: z.infer<typeof RedTeamPolicySchema>;
round_plan_present: boolean;
}): z.infer<typeof RedTeamExecutionTurnModeSchema>;
function buildReviewTargetMaterializationPlan(args: {
room: RoomArtifact;
binding: ReviewTargetBindingSchema;
context_budget: number;
}): z.infer<typeof ReviewTargetMaterializationProjectionSchema>;
function applyBatchJudgment(args: {
room_id: string;
request: z.infer<typeof RoomBatchJudgeFindingsRequestSchema>;
}): Promise<z.infer<typeof RoomBatchJudgeFindingsResponseSchema>>;
function promoteCachedFinding(args: {
room_id: string;
cache_entry_id: string;
idempotency_key: string;
expected_version: number;
}): Promise<void>;
function importChildRedteamOutput(args: {
request: z.infer<typeof RoomImportChildRedteamOutputRequestSchema>;
}): Promise<z.infer<typeof ChildImportBackStatusSchema>>;
```
## Appendix D — Anti-ghost control rule
For every visible room control, implementers must be able to point to:
- the command route
- the request schema
- the mutation or refusal path
- the SSE/read-model refresh path
- the optimistic concurrency/idempotency rule
- the disabled/degraded reason path
- the acceptance test
If any of those are missing, the control does not belong in the UI.
R7.1 extends the anti-ghost rule to these additional controls:
- batch judgment,
- Promote cached finding,
- adjudicate,
- lineage upsert,
- launch child red-team,
- import child output,
- approval checkpoint resolution,
- apply prompt recommendation.
## Appendix E — Normative pseudocode kernels
### `buildOutcomeSignal()`
```ts
function buildOutcomeSignal(
room: RoomArtifact,
closeInput: {
goal_type: string;
user_goal_met: "fully" | "partially" | "not_at_all";
satisfaction_rating?: number;
tags?: string[];
},
findings: RoomFinding[],
cost: { total_cost_usd: number },
): RoomOutcomeSignal {
return {
room_id: room.room_id,
room_mode: room.room_mode,
close_reason: room.close_reason,
goal_type: closeInput.goal_type,
user_goal_met: closeInput.user_goal_met,
satisfaction_rating: closeInput.satisfaction_rating,
tags: closeInput.tags ?? [],
findings_starred: findings.filter(f => f.starred).length,
findings_by_severity: countBySeverity(findings),
participant_count: room.participant_count,
total_turns: room.total_turn_count,
total_cost_usd: cost.total_cost_usd,
cil_signal_category: deriveCilSignalCategory(room, findings, closeInput),
review_target_kind: room.review_target_kind,
schema_version: 1,
};
}
```
### `closeRoom()`
```ts
async function closeRoom(room_id: string, closeInput: CloseInput): Promise<void> {
lock(room_id);
const room = loadRoom(room_id);
assertCloseEligible(room);
const session = createCloseSession(room_id, "freeze_scheduler");
room.status = "closing";
persist(room, session);
unlock(room_id);
try {
advanceCloseSession(session, "drain_or_abort_turns");
await drainOrAbortTurns(room_id);
advanceCloseSession(session, "merge_subrooms");
await mergeChildLinks(room_id);
advanceCloseSession(session, "emit_outcome");
emitOutcomeBundle(room_id, closeInput);
advanceCloseSession(session, "release_leases");
releaseLeases(room_id);
advanceCloseSession(session, "archive");
archiveRoomArtifacts(room_id);
advanceCloseSession(session, "finalize");
finalizeClosed(room_id, session);
} catch (err) {
classifyCloseFailure(room_id, session, err);
throw err;
}
}
```
### `dispatchRoomTurn()`
```ts
async function dispatchRoomTurn(room_id: string): Promise<void> {
lock(room_id);
const room = loadRoom(room_id);
const turn = selectEligibleQueuedHead(room);
const participant = loadParticipant(room_id, turn.participant_id);
verifyDispatchEligibility(room, turn, participant);
const exec = createTurnExecutionState({
room_id,
room_turn_id: turn.room_turn_id,
participant_id: participant.participant_id,
room_revision_at_dispatch: room.room_revision,
room_close_epoch_at_dispatch: room.room_close_epoch,
state: "dispatching",
});
persist(exec);
unlock(room_id);
const request = buildGatewayRequest(room, turn, participant);
const accepted = await roomGatewayAdapter.dispatchRoomTurn(request);
persistAccepted(exec, accepted);
relayStream(accepted.stream, evt => emitRoomTurnChunk(evt));
const terminal = await accepted.onComplete();
lock(room_id);
const freshRoom = loadRoom(room_id);
const freshParticipant = loadParticipant(room_id, participant.participant_id);
const freshExec = loadTurnExecution(room_id, turn.room_turn_id);
if (isInvalidated(freshRoom, freshParticipant, freshExec)) {
reconcileInvalidatedTurn(freshRoom, freshParticipant, freshExec, terminal);
unlock(room_id);
return;
}
applyTerminalResult(freshRoom, freshParticipant, freshExec, terminal);
unlock(room_id);
enqueueGhostSidecars(room_id, turn.room_turn_id);
}
```
## Appendix F — R7.1 Acceptance Checklist
R7.1 is not complete until all of the following are true:
- single-judgment route exists and is typed,
- batch-judgment route exists and is typed,
- cache-promotion route exists and is typed,
- adjudication route exists and finding-detail view exists,
- lineage route exists and detail view exposes lineage,
- review-target query exists and exposes materialization truth,
- prompt-plan query exists and exposes room overlay state plus per-participant precedence,
- child-room launch exists with prompt-artifact selection and preview,
- minimal import-back exists,
- red-team SSE events are typed,
- execution-turn-mode derivation is explicit,
- reserve policy / minimum viable completion are modeled,
- degraded and blocked states are explicit,
- Q R4.1 is updated to match,
- anti-ghost tests cover every DOC14 surface.