Actors join channels and declare skills. Examples: browser user (human-*), AI agents (agent-1, agent-2). Each actor owns a canonical deck slice (per-track or per-line stream). The effective project is a merge of actor canonicals plus optional UI overlay.
- Track ownership: each channel
idhasownerActorId+authorIdin sidecar (AUTHOR_TAGGING.md). - Merge order: for each track, body lines come from owner lane’s last applied
deck.line/deck.blockfor that track; if master has taken the track, master wins. - Overlay:
{ channelId, field, value, untilTs?, authorId }— applied on top for playback/UI only until cleared or promoted.
- Human moves a fader on an AI-owned track → stored as overlay (temporary).
- Promote: write overlay value into target actor deck (if permitted) and clear overlay.
- Master clear overlay: drop all overlays in scope.
- Designated
authorId(usually human session id) withisMaster: true. - May emit
controlmessages:take_track,release_track,clear_overlay,set_master,master_overwrite(see STREAM_PROTOCOL.md §4). Of these onlyclear_overlayis implemented today;take_track/release_track/set_master/master_overwriteare Planned. - AI actors cannot modify tracks the master has taken until
release_track. - Master lock has a UI: a per-track LOCK/OPEN toggle in the channel rack (src/ui/ChannelRack.tish) calls
setMasterLock, settingcoDjMeta.tracks[channelId].masterLock. The merge read path honors it —actorMayEditTrack(src/codj/Merge.tish) refuses edits to a locked track regardless of ownership.
- Split panels: Stream A | Stream B | Human — each with stream textarea + lane color.
- Unified: single rack; tracks show actor chip (color); overlays show dashed border.
- Song deck = optional full export of merged state.
- Per-actor buffers = what each actor typed; merge engine produces
projectfor audio engine.