Problem
FCPKit.AnchoredItem has a .gap case, and the FCPXML DTD's %anchor_item; entity admits <gap>. But the DSL cannot produce one: anchoring a Gap throws BuildError.unsupportedContent.
After #43 the anchorable set is stated in exactly one place — Built.anchorable in Built+Anchoring.swift:
internal var anchorable: (any AnchorableItem)? {
switch self {
case .item(.title(let title)): return title
case .item(.assetClip(let clip)): return clip
case .item(.generator(let generator)): return generator
case .item(.video(let video)): return video
default: return nil // <- .gap lands here
}
}
Before #43 this same omission existed twice, in Anchor.applyLaneOffset and AnchoredItemBuilder.item, which is how it went unnoticed.
Fix
Conform FCPKit.Gap to AnchorableItem and add the case. The protocol requires lane, offset, asAnchoredItem, and asSpineItem — FCPKit.Gap has settable lane/offset and both enums have a .gap case, so the conformance is mechanical.
Why it was not done in #43
#43 was a pure refactor with byte-identical output as the acceptance criterion. Enabling anchored gaps is a behaviour change and deserves its own test — a gap anchored on a lane, verified through to the emitted XML, and ideally a Final Cut import check since an anchored empty gap is an unusual shape.
Problem
FCPKit.AnchoredItemhas a.gapcase, and the FCPXML DTD's%anchor_item;entity admits<gap>. But the DSL cannot produce one: anchoring aGapthrowsBuildError.unsupportedContent.After #43 the anchorable set is stated in exactly one place —
Built.anchorableinBuilt+Anchoring.swift:Before #43 this same omission existed twice, in
Anchor.applyLaneOffsetandAnchoredItemBuilder.item, which is how it went unnoticed.Fix
Conform
FCPKit.GaptoAnchorableItemand add the case. The protocol requireslane,offset,asAnchoredItem, andasSpineItem—FCPKit.Gaphas settablelane/offsetand both enums have a.gapcase, so the conformance is mechanical.Why it was not done in #43
#43 was a pure refactor with byte-identical output as the acceptance criterion. Enabling anchored gaps is a behaviour change and deserves its own test — a gap anchored on a lane, verified through to the emitted XML, and ideally a Final Cut import check since an anchored empty gap is an unusual shape.