Skip to content

Make the Work Column dockable and transactionally detachable #977

Open
0 of 8 issues completed
Open

Description

@jeonghun-jj-lee

Important

Problem -- The Work Column is fixed on the right side of Chat. Researchers cannot move supporting surfaces to match their task, nor place the fully functional column in a separate VS Code editor tab while keeping it connected to the same Amicode Chat and session. Preview, inspectors, and context either compete for horizontal space or risk becoming stale copies when moved across webviews.

Approach -- Make the desktop Work Column dockable right, left, or bottom, and make a neutral drag release create a paired panel-only VS Code editor tab. Attached and detached presentations are exclusive hosts for one durable Work Column record. Every committed mutation is journaled and acknowledged before ownership moves, so Preview editing, inspector streams, Context, Files Changed, Home, widgets, commands, selections, scroll, and save state remain connected and do not drift.

Approaches considered -- (1) Purpose-built durable Work Column record with generation-fenced host leases and a narrow native-tab bridge (chosen): it gives full functional parity without duplicate mutable state. (2) One-shot snapshot or renderer reparenting: rejected because another webview cannot retain DOM or renderer identity, and late close/reload events lose state. (3) Extension-owned standalone renderer: rejected because it duplicates app behavior and session ownership. (4) Generic docking framework: rejected because no second proven client establishes a reuse boundary.

Scope -- in: desktop right/left/bottom docking, neutral-drop paired editor tab, full bidirectional state transfer, durable journal and recovery, Preview editing parity, inspector replay, widget suspend/resume, keyboard commands, lifecycle fencing, ADR and glossary amendments. out: mobile and legacy-layout changes, a separate VS Code application window, more than one detached panel per source editor, and a generic docking framework.

Assumptions -- The Work Column is the canonical auxiliary surface. Side Panel is a visible drag and command label only. A separate webview cannot preserve physical DOM or renderer identity; parity means the same logical state, features, commands, and outcomes after a transactional handoff.

Acceptance Criteria

  • In the desktop Work Column experience, the column can dock on the right, left, or bottom of Chat.
  • The unused trailing area of the outer surface-tab rail starts a drag after a small movement threshold and shows a Side Panel pill under the pointer.
  • Left, right, and bottom show Preview-style target highlights only when their geometry is feasible.
  • Releasing over a valid edge moves the same attached host without reconstructing Preview renderers or live inspector state.
  • Releasing outside the three edge targets shows Place in new window and starts a transactional move to a paired panel-only VS Code editor tab.
  • A constrained edge behaves as neutral detachment territory rather than presenting a false dock target.
  • Escape or a cancelled drag leaves the current layout unchanged; a completed neutral release either reaches the detached host or leaves the source host writable after a reported transfer failure.
  • Attached and detached hosts expose the same Work Column features, including Preview editing, save/close behavior, Home, Context, Files Changed, Pulse Inspector, and every supported command.
  • At most one host holds the mutable lease for a Work Column record. Every non-suspended record has exactly one mutable owner; a suspended record has none and rejects mutations. Stale, duplicate, or out-of-order mutations cannot alter the record.
  • Every committed mutation is durably journaled before the owner reports it complete, including Preview drafts, selections, undo/redo history, scroll anchors, pane-tree changes, save outcomes, inspector buffers, and context state.
  • Preview editing survives attached-to-detached and detached-to-attached handoff with the same logical document, dirty state, selection, undo/redo behavior, pane layout, zoom, and scroll position.
  • Inspector run and device updates received during transfer or reload are replayed to the current owner without gaps or duplicated effects.
  • Widgets preserve functional state across transfer through a suspend/resume protocol; a widget cannot claim detached parity without that protocol.
  • The source Chat is chat-only while detached. Its Side Panel titlebar control reports the external state and reveals or focuses the paired editor tab.
  • Closing the detached native tab reattaches the Work Column from the latest acknowledged record when its source Chat is live.
  • Closing the source Chat while detached closes the external panel only after its final checkpoint and retains the record in a suspended, recoverable state.
  • A source or detached-host reload, VS Code window restore, or extension restart recovers the latest acknowledged record without state drift.
  • Left and right share one remembered width; bottom has an independent remembered height. Geometry is scoped to an Amicode editor tab and survives reload.
  • The app exposes configurable commands for Dock Left, Dock Right, Dock Bottom, Detach, Dock Back, and Reset Side Panel Layout, with non-conflicting defaults and Command Palette entries.
  • Reset Side Panel Layout restores the default right dock and dimensions without changing the Work Column record or discarding state.
  • Mobile and legacy layouts remain unchanged.

Testing Decisions

Add state-codec tests that round-trip every Work Column record field, including recursive Preview panes, drafts, selections, undo/redo, scroll anchors, dirty-close state, inspector buffers, subscriptions, and widget snapshots. Add journal tests for write-ahead acknowledgement, canonical checksums, compaction, duplicate operations, stale generations, lease compare-and-swap, hydrate retry, and lease exclusivity. Extend existing Work Column and Preview browser suites to prove in-window renderer identity, then add cross-webview parity suites that execute the same mutation sequence in both directions. Add extension-host tests for panel creation, hydrate acknowledgement, native disposal, source disposal, suspended recovery, reload, window restoration, extension restart, and every close-order permutation. Validate all commands and focus behavior in a Dev Host because VS Code may intercept webview chords.

Key Decisions

  • One logical Work Column record -- attached and detached presentations are hosts, never independent copies. The record is the only source of truth for mutable Work Column state.
  • Durable acknowledgement before lease transfer -- the current owner flushes ordered operations to the extension-owned journal, the destination hydrates a checkpoint, and only its acknowledgement moves the generation-fenced lease.
  • Functional parity, not physical renderer identity -- retained DOM identity remains mandatory for ordinary in-document moves. Cross-webview transfer rehydrates equivalent logical state because physical DOM, editor, PDF, and iframe instances cannot cross documents.
  • Neutral drop means detached editor tab -- only three edge rails are dock destinations. Every other release requests the paired editor-tab host and communicates that intent under the pointer.
  • Chat-only source while detached -- the source does not show a second mutable or read-only copy. Its titlebar control exposes external status and focuses the canonical host.
  • Suspended recovery over discard -- source closure checkpoints and suspends the record. A matching Chat can later recover it; data is never destroyed merely because a host closes.
  • Keyboard commands replace persistent layout buttons -- drag is the direct-manipulation path. Commands are the configurable keyboard path and remain discoverable through existing shortcut and palette surfaces.

Data Contracts

Contract Owner Required fields and invariant
Work Column record Extension-owned durable journal Work Column ID, bound session identity, schema and codec version, journal revision, SHA-256 checksum of canonical serialized state, active outer surface, outer-tab state, versioned Preview document state, inspector stream state, context state, widget snapshots, and host presentation preferences.
Ordered mutation Current host Work Column ID, surface instance ID, generation, operation ID, base revision, write-ahead payload, resulting revision, checksum, and acknowledgement. Duplicate operation IDs are idempotent; stale generations, owners, and base revisions are rejected.
Transfer checkpoint Current host and extension Transfer ID, source host, destination host, generation, checkpoint revision, codec version, checksum, and quiescence result. The destination stays read-only until it acknowledges hydration of the exact checkpoint.
Host lease Extension Work Column ID, state, mutable owner host ID, monotonically increasing generation, lease revision, active transfer ID, and compare-and-swap predecessor. A suspended record has no mutable owner and rejects every mutation.
Preview document state App codec Resource identity, base content revision, dirty content or patch, pane and tab placement, selections, scroll anchors, serialized undo/redo history, pending save or close operation IDs, save outcome, and conflict state. Save and close results apply only when their operation ID and lease generation match.
Inspector and widget continuity Bridges Inspector identity, authoritative snapshot, last contiguous event sequence, replay cursor, and subscription intent; widget instance ID, type, schema version, serialized state, subscription descriptors, and resume token.

Transfer Commit Protocol

  1. The current lease holder writes a checkpoint and remains the only mutable host while draining write-ahead operations.
  2. The destination hydrates read-only and acknowledges the transfer ID, checkpoint revision, codec version, and canonical checksum.
  3. The durable lease compare-and-swaps to the destination with the next generation.
  4. Only after that compare-and-swap may the destination accept mutations; the source rejects them.
  5. Retries reuse the transfer ID and are idempotent. After a timeout or restart, every host re-reads the durable lease; an acknowledgement alone never grants write authority.

Lifecycle Resolution

Event Required postcondition
Detached host closes while source is live Reattach through the transfer protocol; attached mode becomes mutable only after the lease transfer.
Detached host closes while source is unavailable Persist the latest durable revision, clear the mutable owner, and enter suspended recovery.
Source closes while detached is active or reattach is pending Drain the current owner, checkpoint, revoke mutable authority, close the detached panel, and enter suspended recovery.
Destination boot or hydrate fails The source retains or regains its lease; the destination remains read-only and is discarded or retried by transfer ID.
Extension restart, reload, or native-host failure Restore only from the durable lease and journal; remain suspended when no matching source session is live.
Second detach request or restored duplicate tab Resolve by Work Column ID, reveal the canonical existing tab, and never create a second mutable detached host.

Parity Oracle

Maintain a normative feature matrix listing every supported surface, command, shortcut, mutable state field, codec, and expected outcome. Attached and detached hosts must match every supported entry. Preview renderer identity is an opaque instance ID: right, left, and bottom in-document moves preserve it; a cross-webview move creates a new physical ID only after canonical-state hydration succeeds. Each parity test injects failure after every transfer phase and compares canonical revision, checksum, command outcome, inspector sequence, and feature-matrix result.

Constraints & Invariants

  • The Work Column remains the only implementation of Home, Files Changed, Context, Pulse Inspector, and Preview. Detached mode is another host, not another renderer implementation.
  • No user-visible state may drift between attached and detached modes, including active content, drafts, save outcome, selections, scroll, inspector data, and command availability.
  • Native disposal is post-close; correctness therefore comes from acknowledged journal checkpoints, never from extracting state during disposal.
  • Every transfer-relevant user-visible mutation is write-ahead journaled before the host treats it as committed.
  • Before a normal close, reload, or transfer, the mutable host drains new mutations, waits for acknowledgements, checkpoints, and only then disposes or releases its lease. Recovery replays acknowledged journal entries rather than substituting an older checkpoint for pending state.
  • A checksum is SHA-256 of the versioned canonical serialized record at its named revision. Codec or checksum mismatch fails closed, leaves the source lease unchanged, and requires a fresh checkpoint.
  • Raw DOM, pointer capture, IME composition, and renderer instances cannot cross webviews. A transfer must quiesce transient interactions at their latest durable state before changing ownership.
  • Source disposal takes precedence over a pending reattach. A detached panel is closed after checkpoint, and its record enters suspended recovery rather than being discarded.
  • Docking targets must preserve usable minimum geometry for Chat and Work Column. Resizing clamps geometry but never silently detaches a panel.
  • All interaction states must work in light and dark themes with visible focus feedback and keyboard access.

Prior Art

  • The Work Column decisions for inspectors, Home, and Preview.
  • Preview's retained-renderer workspace and nested drag behavior.
  • Existing in-app session handoff and split-pane ownership patterns.
  • Existing native Amicode chat and deck editor-tab hosts.
  • Existing command, Command Palette, shortcut settings, and extension-to-app bridge infrastructure.

Source

ADR 0014, Dockable Work Column · Documentation PR #978. Amends the cross-webview boundary of the Preview retention decision. Glossary update: Work Column and Detached Work Column.

Notes

The parent must be implemented in dependency order: durable record and lease protocol first; state codecs, inspector replay, and widget suspend/resume second; in-window docking third; guarded detached-host UI and commands fourth; recovery, accessibility, and parity testing last. Detach UI must not ship ahead of the durable host protocol.

Review status: schema validation passed. The built-in review's mechanical checks passed with no findings, but its critic layer is degraded because critic children did not report model metadata. Independent artifact-only adversarial review resolved one blocking lease contradiction and approved the final contract.

Metadata

Metadata

Labels

hitlNeeds human review before merge

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions