Loop is two things, and the one that matters is unreachable

Loop playback — the transport repeating the open symbol — is editor state and
the document has never heard of it. A looping INSTANCE is a node repeating the
symbol it places, which is the four-frame tire turning for the hundred and
twenty frames it is on screen, and it lives in the document as
`:playback {:end :loop}`. Same word, two scopes; named apart here before
anything is built on either.

The status of the second one is the surprise: it already works and cannot be
asked for. `node/placed-frame` does the modulo, `node/problems` already admits
`:end :loop`, `audio-tracks` already expands the periods — and no control sets
it anywhere in the UI. So the tire is three pieces of work, not one: somewhere
to edit an instance's playback, a block that draws its repeats rather than
only its first pass as the timeline's own docstring admits it does, and the
audio period guard.

This also pins down when the held cel can be torn out. Turning every drawing
into a one-frame looping instance is only safe once a looping instance can be
seen and edited; otherwise every drawing in the document quietly acquires a
property with no control on it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Your Name 2026-10-01 16:32:02 -04:00
parent d029908f0b
commit fb38990090

View file

@ -123,6 +123,37 @@ people, and it does not make the symbol a different kind of thing. The thing
to hold the line on is that nothing outside the timeline, and the commit
path's overlap check, is allowed to read it.
## Two things are called loop
Before any of this, name them apart, in the way the vocabulary table in
`lane-handoff.md` names a cel apart from an exposure.
- **Loop playback** is the transport repeating the open symbol while it plays.
It is `[:playback :loop?]` in app-db, the ⟳ button in the strip, and it is
EDITOR STATE. The document does not know about it.
- **A looping instance** is a node repeating the symbol it places: a four-frame
tire turning for the hundred and twenty frames the instance is on screen.
It is `:playback {:end :loop}` on the node, and it is in the DOCUMENT.
The car tire is the second one, and here is its actual status: it already
works in the evaluator and cannot be asked for. `node/placed-frame` does the
modulo, `node/problems` already admits `:end` of `:stop`, `:hold` or `:loop`,
`nest/audio-tracks` already expands a loop into its periods — and nothing in
the UI sets it. It is implemented and unreachable.
So three things are missing, and they are the work:
1. **A control.** Where an instance's playback is edited: `:in`, `:speed`, and
what happens at the end. One place, three fields, rather than a loop
checkbox somewhere else.
2. **Drawing the repeats.** `ui/timeline`'s docstring already admits that only
the first pass of a looping instance is drawn, so a tire turning thirty
times shows one turn's keys and then nothing. A looping block should show
its passes — at minimum the period boundaries, so the row says how many
times round it goes.
3. **The audio period guard** below, which a loop needs whether or not holds
become loops.
## Tear out the held cel
A held cel is a 1-frame symbol shown for many frames. A 1-frame symbol with
@ -132,9 +163,13 @@ keeping a special case for free.
**What is already true**, so that nothing has to move: `:span` is on the node,
in its own frames; `:time` (`:at`, `:rate`) is on the node; looping is on the
node. The SYMBOL owns only `:frames`, the authored window. So looping and span
are instance properties already, and this change is about deleting a mode, not
relocating a field.
node, as `:playback :end`. The SYMBOL owns only `:frames`, the authored
window. So looping and span are instance properties already, and this change
is about deleting a mode, not relocating a field.
It does mean the two changes are joined at one point: making every drawing a
looping instance is not safe until a looping instance can be seen and edited,
or every drawing in the document acquires a property with no control on it.
**What has to be decided and collapsed:**