xtc/docs/RECOVERY.md

145 lines
8.2 KiB
Markdown
Raw Permalink Normal View History

2026-11-06 15:20:20 +01:00
# Persistence and Failure Recovery
2026-11-06 15:20:20 +01:00
The project format is v12. Readers migrate v1–v11, validate bounded input and
atomically install a candidate only after complete success. Existing tests cover
exact migration/roundtrip, truncations, malformed references, counts, IDs,
nonfinite values and failed GUI/backend installation. Native processors are
session-only; saving their graph returns UNSUPPORTED rather than writing process
addresses or an unreadable project. See PROJECT_FORMAT.md.
Project Save writes a mode-0600 same-directory `NAME.tmp.XXXXXX`, flushes and
fsyncs it, closes and renames it over the destination. Before rename, handled
failures remove the temporary and retain the destination. POSIX rename gives
2026-11-06 15:20:20 +01:00
complete old-or-new destination contents during process failure. The containing
directory is fsynced after rename. If that sync fails, Save reports I/O failure
but the complete new file may already be present. Preserve and validate it
before retrying; filesystem/hardware durability still varies. Symlinks are
replaced rather than followed at rename; original file permissions are not kept.
Recording similarly writes/finalizes a same-directory temporary, then renames
it. Stop must synchronize callbacks before draining/finalizing. Ring overflow
returns an explicit error and may finalize a partial take for manual recovery;
I/O failure retains the previous destination. A killed recorder does not finish
2026-11-06 15:20:20 +01:00
its WAV header. Source WAV files remain external; references inside the project
folder are saved relative to it. Save As does not collect them. Back up the
project and assets together.
2026-11-06 15:20:20 +01:00
---
## After A Crash
1. Preserve the destination and any `.tmp.*` files before attempting repair.
2. Run `xtc-check --validate project.xtc` for metadata validation without a GUI,
2026-11-06 15:20:20 +01:00
display or audio server. Run `xtc-check --inspect project.xtc` to list
resolved media/module paths and plugin identities: status 2 means
missing/unreadable references, 1 means invalid metadata/I/O, 0 means files
are available. Neither command verifies file contents, plugin initialization
or realtime preparation.
3. A valid destination can be opened normally. If only a temporary contains
useful data, copy it to a separate candidate and validate that copy before
replacing anything. Partial project files are rejected; there is no salvage
parser.
4. An unfinished WAV temporary may have a zero/incorrect data length and needs a
separate recovery tool or manual header repair on a copy. xtc does not guess
its intended length or automatically rename orphan temporaries.
5. Missing assets preserve silent clips. Use Relink selected audio, then Play to
2026-11-06 15:20:20 +01:00
revalidate. For server loss/format changes, Stop/Reconnect and explicit
routing are required. Panic/F9 clears held notes. Failed close retains
ownership for retry.
There is no autosave, crash journal, automatic orphan recovery or persisted Undo
history. Existing finalized files are protected against the tested process-level
failures; unsaved edits/in-flight takes can still be lost.
2026-11-06 19:05:14 +01:00
`cmake --build build --target test-recovery` uses temporary directories and child processes only. It
forces an EFBIG-style write failure with a child-local file-size limit, kills
eight project writers while temporaries are visible, and kills a recorder after
draining but before finalization. Complete old/new destinations and explicit
orphan temporaries are verified. It does not cut power, terminate the shared
audio server, simulate a failing filesystem, or qualify disk/device endurance.
2026-11-06 15:20:20 +01:00
---
## Retained Recording Prefixes
Recording now defaults to no-clobber publication; the GUI requires an unused
path. Failed nonempty temporary recordings survive destruction. Query the
recorder recovery path before destruction, or use the GUI's reported path.
`xtc-check --recover-recording TEMP NEW.wav` reconstructs a canonical mono
2026-11-06 15:20:20 +01:00
float32 WAV from complete on-disk frames, ignoring a trailing partial frame. It
never changes the source or overwrites an existing destination. This supersedes
the earlier lack of a WAV recovery tool described above. See AUDIO_FILES.md for
2026-11-06 19:05:14 +01:00
format/ownership/size limits and `cmake --build build --target test-recording`.
2026-11-06 15:20:20 +01:00
---
## Plugin Load and Replacement Failures
GUI Open reports an unavailable/incompatible plugin's label and absolute module
path and retains the current document. Preserve the saved file; restore a
compatible module at its original path and retry Open. `xtc-check --validate`
checks metadata without executing plugins, so success does not certify that a
module exists or initializes. Metadata-only C load/save preserves unavailable
plugin records. There is no automatic missing-plugin substitution or GUI relink
for an unopened document.
For an already loaded project, Replace selected plugin preserves wires and node
ID only for the same audio layout. New defaults replace controls/automation;
Undo restores the original configuration. Failed discovery/compile/instantiate
retains the original graph, controls and history position. Cancel in the generic
parameter editor discards its temporary values. Reset defaults clears automation
2026-11-06 15:20:20 +01:00
only when applied. No host recovery can contain a crash or hang in trusted
native plugin code; LADSPA has no runtime error-return channel.
2026-11-06 15:20:20 +01:00
---
2026-11-06 15:20:20 +01:00
## Save Diagnostics
2026-11-06 19:05:14 +01:00
`cmake --build build --target test-project-diagnostics` deterministically injects flush, file-sync,
2026-11-06 15:20:20 +01:00
close, rename and directory-sync errors. Pre-rename failures retain the previous
bytes and clean temporary files. Post-rename sync errors leave a complete new
file and return failure; there is no rollback after replacement. Load
diagnostics identify the expected record and syntax line, or line zero for
whole-model/I/O stages. Unknown versions report the supported range (1–12);
unknown records/fields are rejected without partially changing the current
project.
Modern CLAP/VST2/VST3 module identity is preserved in v11 metadata even when the
binary is unavailable. Restore the compatible saved binary path and retry Open.
CLAP restart and VST2 I/O-change requests fail/silence subsequent blocks; stop
and rebuild/reload rather than attempting callback-time reconfiguration. Modern
2026-11-06 15:20:20 +01:00
instances restart at default configuration; no edited opaque state is exposed or
saved by the initial adapters. Trusted plugin crashes cannot be contained.
2026-11-06 15:20:20 +01:00
---
## Instrument Support
MIDI tracks can bind CLAP, VST2 and VST3 instruments. In the Track menu, select
**Load instrument plugin** for the selected sequencer track; **Use built-in
instrument** removes the binding. Assignment also selects the track for live
MIDI. **Live MIDI to selected instrument** changes that target; **Live MIDI to
built-in sine** restores the legacy live source. MIDI clip notes always go to
their own track's instrument. Independent instances feed track gain/pan,
mute/solo, bus routing and automation. Bindings/live target save in v12.
Supply the actual trusted Linux binary (including the inner .so of a VST3
2026-11-06 15:20:20 +01:00
bundle). Supported instruments have zero audio inputs, one mono output, float32
processing, zero latency and one note/event input. Default configuration only:
no custom editor, opaque state/preset restoration, modern parameter
editing/automation, stereo/multichannel instruments or MIDI output. No arbitrary
third-party instrument is qualified by the original ABI fixture tests.
CLAP accepts MIDI or native notes; VST2 uses MIDI events; VST3 uses IEventList
note events. Live CC reaches CLAP MIDI/VST2; native CLAP/VST3 have no controller
mapping (including sustain). Live MIDI goes to exactly one selected target.
Seeks/loops retrigger notes crossing the destination with fresh envelopes;
plugin oscillator/opaque DSP state cannot be reconstructed. Panic delivers
all-off (VST3 held-key note-offs); plugin release tails may remain. Processing
uses preallocated 256-frame chunks and 256 incoming events per instance/chunk;
overflow or processing failure silences the block and schedules reset events.
The existing 32 simultaneous scheduled-note and 4096 stored-note bounds remain.
Do not unload/replace modules during playback; candidate plans are prepared off
the callback and old instances are reclaimed on the control thread. Missing
references remain inspectable without loading; failed GUI preparation retains
the current project. Save a backup for applications limited to v11 or earlier.