4.5 KiB
#region ScenarioEditor.DataModel [C:4] [TYPE ADR] [SEMANTICS data-model,scenario,editor,edit,revision] @BRIEF Edit-session, edit-operation, constrained-assertion, and visual-dependency edit models for the Scenario Editor (043). @RELATION DEPENDS_ON -> [ScenarioEditor.Research] @RATIONALE Editing a persisted scenario must produce typed, validatable edit operations that translate into new immutable revisions without violating 038 safety invariants. @REJECTED Free-form graph mutation — rejected because it would allow SQL/raw baselines/paths into the graph; edits are constrained and validator-gated.
EditSession
Fields: session_id, scenario_id, base_revision_id, owner_id, opened_at, dirty (bool), active (bool). One active session per scenario per user; opening an edit pins base_revision_id for conflict detection.
EditOperation
Typed discriminant union:
- op=set_parameter_definition {param_name, default?, validation?, source?}
- op=set_assertion {logical_step_id, comparison: enum, threshold, baseline_ref}
- op=add_step {template, after_logical_step_id?}
- op=remove_step {logical_step_id}
- op=set_dependency {logical_step_id, add|remove, target_logical_step_id}
Invariant: op payloads only reference registered templates/operators/baseline refs; extra="forbid" on all edit ops (no SQL/code/path smuggling). Metadata uses PATCH /metadata with If-Match: metadata_version and never enters WorkingDraft. Every WorkingDraft operation is executable and creates a revision only on policy-authorized save. Parameter operations edit 038 ParameterDefinition, never a runtime value. Each durable step op carries a logical_step_id (immutable) for stable analytics.
WorkingDraft — server-stored, no client-draft bypass (#7)
apply persists a WorkingDraft server-side and returns {draft_id, digest}. save(draft_id, digest) reloads it server-side, re-validates the Verification Program (including SqlEvidenceSpec compilation), canonicalizes, re-hashes, and compares the base revision. The client NEVER returns the full graph; save cannot accept an arbitrary draft object. A WorkingDraft is bound to a base revision and expires on conflict/staleness.
Fields: draft_id, scenario_id, base_revision_id, ops[], applied_graph, digest, created_by, delegated_by?, agent_run_id?, investigation_case_id?, created_at, status (open|saved|awaiting_approval|expired).
ConstrainedAssertionEdit
Fields: logical_step_id, operator (enum from 037 comparison: exact, absolute, relative, range, row_set), threshold (typed), baseline_ref (approved baseline or candidate), evidence_required (bool). Free-form expected value forbidden.
VisualDependencyEdit
Fields: logical_step_id, target_logical_step_id, action (add|remove). Validated against 038 DAG rules (cycles, duplicate producers).
EditRevisionResult
Fields: new_revision_id, parent_revision_id, content_hash, activation_status=candidate, server_derived_change_summary {added, changed, removed, verification_program_diff}, validation (AuthoringValidation), diff_payload, policy_decision, agent_action_id?. Returned by save; never mutates prior revisions or advances current_revision. The caller submits only {draft_id, digest} plus its authenticated/delegated action identity; it never supplies audit/provenance summary. Promotion is the distinct 042 ActivateCurrentRevision operation, with its own deterministic eligibility and delegated-authority/gate decision.
EditProposal and ScenarioMigration
EditProposal { proposal_id, scenario_id, base_revision_id, proposed_graph, diff, validation, expires_at, agent_run_id?, investigation_case_id? } is server-stored. acceptProposal(proposal_id) validates its base revision and produces a WorkingDraft, which then uses normal save(draft_id,digest). A delegated agent may invoke that save after deterministic validation; if policy requires approval, the draft moves to awaiting_approval and an inline ActionApprovalGate is linked. revalidate creates a migration proposal with mappings/conflicts; conflicts must be resolved before accept. There is no client-side graph handoff.
Conflict & Safety
- Save requires
base_revision_idmatch → 409 STALE_REVISION on mismatch. - Every edit operation validated by 038 validator before revision creation.
- Agent proposals carry a full proposed graph which passes validation before display; an agent-saved revision retains AgentAction/InvestigationCase provenance. A save is not permission to activate it or change an automation target.
#endregion ScenarioEditor.DataModel