Skip to content

feat(timeline): DAWproject linear-subset XML importer#6467

Merged
shipyard-local[bot] merged 1 commit into
mainfrom
feature/timeline-dawproject-import
Jul 22, 2026
Merged

feat(timeline): DAWproject linear-subset XML importer#6467
shipyard-local[bot] merged 1 commit into
mainfrom
feature/timeline-dawproject-import

Conversation

@shipyard-local

@shipyard-local shipyard-local Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

What

Foundation of Phase-3 item #7 (DAWproject import): a DAWproject project.xml → timeline-model importer for a documented linear subset.

import_dawproject_xml() parses the XML with pugixml (DOM traversal) and assembles a Project through the timeline model's public construction API. It is a pure model consumer — no model-layout change.

Documented subset (the DoD "documented subset loads")

  • <Project version="1.x"> root
  • <Transport> single <Tempo unit="bpm"> + <TimeSignature> → single-point tempo/meter maps at bar one
  • flat <Structure> <Track> elements (no nested group tracks)
  • <Arrangement> <Lanes timeUnit="beats"> → per-track <Lanes track><Clips><Clip time duration> with <Notes> or <Audio><File> content

Beats are quarter notes → canonical ticks via kTicksPerQuarter. Audio clips reference a deduplicated MediaAsset; its durable ContentHash is provisionally derived from the package path (bytes live in the not-yet-unzipped container), with the path preserved as a PackageRelative AssetLocator hint.

Fails closed — no silent drops

Anything outside the subset (<Warps>, nested group tracks, timeUnit="seconds", unknown arrangement/lane timelines, missing required attributes, out-of-range note pitch/velocity, dangling track refs, duplicate track ids) is rejected with a descriptive DawProjectImportError, never partially imported.

Where it lives — and why not src/

The importer is in core/timeline/import/, not core/timeline/src/. The web-timeline-source-closure gate sweeps every core/timeline/src/*.cpp into the WAM/WebCLAP wasm DSP lanes, which deliberately do not link pulp-runtime. The importer's pugixml dependency has no place in a browser RT-DSP binary, so keeping it out of src/ keeps pugixml out of wasm. The timeline and web-plugins skills record this constraint.

Tests

test/test_timeline_dawproject_import.cpp (72 assertions, 4 cases):

  • committed fixture linear_subset.dawproject.xml → import → assert track count/order, clip placements (ticks), asset dedup, notes, tempo/meter, sequence duration
  • silent-drop guard: committed out_of_subset.dawproject.xml (a <Warps> clip) must be rejected, not imported as an empty clip
  • 11 malformed/out-of-subset sub-cases (parse error, wrong root, bad version, non-bpm tempo, seconds timing, nested group track, duplicate id, dangling ref, missing attr, bad pitch, missing <File>, unsupported arrangement timeline)
  • empty-project-with-defaults case

Deferred (follow-ups, out of scope here)

  • .dawproject ZIP unwrap + real-byte content hashing
  • non-linear / clip-launch arrangement mapping
  • the pulp import CLI verb (tools/cli)
  • full parity-suite integration

🤖 Generated with Claude Code

https://claude.ai/code/session_01TVQHcnbg3t6TvXsdv6gXhS


🔎 Provenance

Agent claude
Machine m3
Tab Timeline v3
Directory /Volumes/Workshop/Code/pulp-dawproject
Session c66f4a64-25ea-42e5-b184-d48611a066a2

Resume

claude --resume c66f4a64-25ea-42e5-b184-d48611a066a2

Jump to this tab

cmux surface focus C0B3DA54-39AF-4DAA-8089-AA08DAB71968

Relaunch (any agent)

cmux surface resume get --surface C0B3DA54-39AF-4DAA-8089-AA08DAB71968

Restore URLhttps://claude.ai/code/session_01TVQHcnbg3t6TvXsdv6gXhS

stamped 2026-07-22 13:02 UTC

Import the DAWproject interchange format's linear foundation — tracks,
clips, tempo, and time signature — into the timeline model. Parses a
project.xml document with pugixml (DOM only; the lib is -fno-exceptions)
and assembles a Project via the model's public construction API,
deduplicating audio assets by package path and deriving a provisional
ContentHash from that path (the bytes live in the not-yet-unzipped
container; unzip + the CLI import verb are follow-ups).

The documented subset is beats-timed <Notes>/<Audio> clips on flat
tracks with a single tempo and meter. Everything outside it fails closed
with a descriptive error rather than a silent partial import.

The importer lives in core/timeline/import/ rather than src/ because the
web timeline-source-closure gate sweeps every core/timeline/src/*.cpp
into the WAM/WebCLAP wasm DSP lanes, which do not link pulp-runtime; the
importer's pugixml dependency has no place in the browser RT-DSP binary.
The timeline and web-plugins skills record the constraint.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TVQHcnbg3t6TvXsdv6gXhS
@shipyard-local
shipyard-local Bot enabled auto-merge July 22, 2026 13:02
@shipyard-local
shipyard-local Bot added this pull request to the merge queue Jul 22, 2026
Merged via the queue into main with commit 2ccff74 Jul 22, 2026
31 of 38 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant