Changelog¶
All notable changes to the feedpak format specification are documented here.
The format is licensed under CC0-1.0 (prose) and MIT (schemas, examples, code). This file follows Keep a Changelog, and the specification is versioned per Semantic Versioning — see spec §4 for how format, side-file, and document versions relate.
[1.19.0] - 2026-07-22¶
Additive (MINOR) release: a pickup measure can finally carry its conventional number. Defect #64.
§7.6 defined a pickup (anacrusis) measure flag, but notation.schema.json required
idx >= 1 — so a pickup measure had no valid conventional number. The standard 0 was
rejected by the schema, and the only schema-valid option, 1, collided with the first full
measure and shifted every later measure off by one against the printed score. Using the flag
thus forced a renumbering; the pairing shipped with no example and no test, which is how the
contradiction survived every release since 1.0.0.
Fixed¶
measures[].idxnow allows0(§7.6) —notation.schema.jsonrelaxesminimumfrom1to0. The value0is RESERVED for an opening pickup measure and a measure withidx: 0MUST also setpickup: true, enforced by a schema conditional. The rule is one-directional:idx: 0impliespickup: true, but a pickup measure MAY instead carry the number its source gives it, sopickup: truedoes not requireidx: 0. This matches standard engraving practice and the usual MusicXML emission for an anacrusis (<measure number="0" implicit="yes">).- §7.6 now defines the surrounding semantics the flag needed: a pickup measure's
tis its first sounded beat (it has no downbeat), and insong_timeline.jsonits beats are upbeats —measure: -1— withmeasure: 1on the first full measure's downbeat, so the timeline needs no0. Also stated: mid-score implicit or partial measures (a measure split across a repeat, "7a"/"7b" publisher numbering) remain out of scope for v1's integeridx, and0MUST NOT be reused for them — a Writer rule, recorded so the reserved value doesn't get overloaded later. examples/extended.feedpaknow opens with a keys pickup measure, exercised across the whole pack: every sibling time stream shifts with the grid (apply-until-next maps keep their0.0anchor so the pickup region stays covered), and the timeline shows the upbeat-then-downbeat shape. The reference test suite covers the accepted shapes and the rejected ones.
Compatibility¶
Two directions, stated separately. Existing packages — purely a relaxation: every package
valid under 1.18.0 remains valid, and no conformant package could ever have used idx: 0, so
no corpus exists to break. New packages that use idx: 0 — a pre-1.19 Reader that
re-validates notation against its own bundled copy of the old schema rejects the file rather
than degrading gracefully; a Reader that consumes idx numerically (or ignores it) is
unaffected. This is the §4.2 opt-in carve-out
boundary (entry 3 there), the first value-domain widening in that list. A Writer that needs
the broadest Reader range can keep a source-given number on the pickup (pickup: true with
idx: 1 remains valid) and adopt 0 once 1.19-aware Readers are common. Writers gain the
first way to encode an anacrusis without renumbering it against the printed score.
[1.18.0] - 2026-07-20¶
Additive (MINOR) release: MIDI-voiced sound sources in the rig model — a chart can now declare what a MIDI part (piano, keys, drums) should sound like, with a guaranteed General-MIDI floor. FEP #61.
- New reserved realization
engine:soundfont(sourceblocks only;format: "sf2"reserved,formatopen), addressed as library (ref) + voice (bank/program). - New reserved block
role:source— a generator at the head of the signal chain whose input is the Reader-supplied MIDI event stream (pack note data or live controller input alike). - New OPTIONAL
intent.gmon source blocks — a normative-when-present General-MIDI floor ({program}melodic;{percussion, kit}kits, kit numbers 0-based wire/SF2 values, absent ⇒0) so a GM-only Reader still voices the part. - Arrangement-entry
tones(manifest, §5.2): bind a sound to any arrangement — including notation-only and drum-part entries — with manifest-wins-wholesale precedence over in-JSONtones(Writers SHOULD NOT emit both). New top-leveldrum_tonesbinds the song-level (primary) drum part; ontype: drumsarrangements (1.17.0) the entrytonestakes precedence,drum_tonesremaining the fallback for packs without drum arrangements. - §7.9 conformance: realization selection now stated as gating on
engineandformat(general clarification, already implicitly true forplugin); source blocks SHOULD fall back tointent.gmrather than skip; control events are honoured by whatever voices the part. - Prose: rigs are instrument-neutral signal chains (§5.1, §6.9, §7.9 framing).
[1.17.0] - 2026-07-20¶
Additive (MINOR) release: drum charts become first-class arrangements, so a pack can carry
more than one — two drummers recorded separately, a programmed layer beside an acoustic kit, or
an aux-percussion part. Until now drums were a single song-level drum_tab sidecar, the one part
that was not an arrangements[] entry.
Added¶
type: "drums"arrangement value + an optional per-arrangementdrum_tabpointer (§5.2, §7.5). A drum part is now an arrangement entry withtype: drumsand adrum_tabpath (nofile, nonotation) — mirroring how a keys part is an entry with anotationpointer. It is purely additive over the song-leveldrum_tabkey, which stays the primary drum part and its back-compat alias: a Reader without per-arrangementdrum_tabsupport reads that one drum chart and ignores the extratype: drumsentries (they carry nofileto render), degrading gracefully to one drummer; a Reader with support takes its drum parts from the arrangements and does not double-load the song-level key. A single-drum pack is unchanged — it keeps emitting only the song-leveldrum_tab. Normative: atype: drumsarrangement MUST NOT be selected or scored as a pitched/fretted arrangement.schemas/manifest.schema.jsonaddsdrum_tabtoarrangementEntry(and to itsfile/notationanyOf);examples/extended.feedpakcarries a primaryDrumsarrangement (aliasing the song-leveldrum_tab) and a secondDrums (Live)arrangement with its owndrum_tab_live.json.
[1.16.0] - 2026-07-19¶
Additive (MINOR) release: optional per-stem display metadata, and the retention of the
full mixdown after separation is promoted from a SHOULD to a version-scoped MUST.
Packs increasingly carry stems beyond the classic separation set — a rhythm guitar layer, a
click track, an alternate backing track — and a Reader had nothing to show for them but the
raw id. Stems were the only user-facing list in the manifest without a display label
(arrangements[] and lyric_tracks[] both have name).
Added¶
- Optional per-stem
nameanddescription(§5.3) — purely presentational fields on astems[]entry.nameis a short display label for mixers and stem lists; absent ⇒ a Reader falls back to theid, the same rule asarrangements[].name.descriptionis free-form text saying what the stem is (e.g. a click track's count-in); a Reader MAY surface it and MAY ignore it. Neither carries semantics:idremains the stable reference key, and anameonfullchanges none of §5.3's mixdown rules.schemas/manifest.schema.jsondocuments both onstemEntry;examples/extended.feedpakcarries a labelledguitarstem and an authoredclickstem exercising both fields.
Changed¶
- Retaining the
fullmixdown after separation is now a MUST (§5.3), gated to the pack's own version: a Writer producing a pack atfeedpak_version≥ 1.16.0 that separates a mixdown into per-instrument stems MUST keepfull(withdefault: false). It was aSHOULD. Separation is lossy and the mixdown is unrecoverable once dropped, and consumers now depend on it — a Reader that playsfullat unity gain to avoid the separation loss degrades to a lossy recombination on any pack that discarded it. The change is version-scoped, so no existing pack becomes non-conformant: a pack authored before 1.16.0 is still judged by theSHOULDthat was in force when it was written. The obligation binds only the act of separating a mixdown — a pack of real recorded multitrack stems, never separated, is unaffected. Additive in effect (MINOR); no new keys and no structural change. - Docs (no format change): the §6.9
tones.definitionsexample now uses a neutral opaque placeholder instead of a source-specific field name.definitionsis unchanged — still defined as raw, source-copied passthrough that Readers MUST preserve verbatim; only the illustrative field names in the example were genericised.
Compatibility¶
- Purely additive. An older Reader ignores
name/descriptionand keeps displaying the stemid; nothing is removed, renamed, or repurposed. Thefull-retention MUST binds only packs declaringfeedpak_version≥ 1.16.0 — every earlier pack is still judged by the SHOULD in force when it was written.
[1.15.0] - 2026-07-13¶
Additive (MINOR) release: the stem id full is now reserved for the complete mixdown, and a
separated pack is asked to keep it rather than throw it away.
The format always had a home for the pre-separation mixdown — a stem — but §5.3 described full
as being "commonly replaced" by the per-instrument entries once a pack is split, which left the
mixdown nowhere to live. Source separation is lossy, so that lost audio is unrecoverable: summing
guitar + bass + drums + vocals does not reproduce the file they came from. In practice
implementations worked around this by inventing a second location for audio outside stems
(a top-level key pointing at an original/ directory), which is exactly the redundancy an open
format should not have. Reserving full closes the gap with no new manifest surface at all.
Added¶
- §5.3 — the stem id
fullis RESERVED for the song's complete mixdown, and a Writer MUST NOT use it for anything else. A Writer that separates a pack into per-instrument stems SHOULD retain thefullentry alongside them withdefault: false. - Normative Reader rules for a pack that carries
fulland per-instrument stems: a Reader that sums stems MUST NOT includefullin the sum (it already contains every instrument — summing it doubles the whole song), a per-stem mixer SHOULD NOT offerfullas an instrument channel, and a Reader SHOULD preferfullover the summed stems when every instrument stem is at unity gain, since it is the same mix without the separation loss. schemas/manifest.schema.jsondocuments the reserved id onstemEntry.id.examples/extended.feedpakis now a separated pack that retainsfullalongsideguitar,drumsandvocals(plus astem_separationprovenance block), exercising the new rule.
Compatibility¶
- No manifest key is added, removed, renamed, or repurposed; a pack that predates this release
stays valid, and
stemssemantics are unchanged for every id other thanfull. - Safe for an older Reader that honours
default— normative since 1.0.0 — which is exactly why the retained entry is specified asdefault: false: such a Reader does not playfullon open, whatever else it does with the list. A Reader that sums every stem regardless ofdefaultwas already mis-reading the format; thedefault: falserequirement onfullis what keeps even that Reader from doubling the mix on open.
[1.14.0] - 2026-07-02¶
Additive (MINOR) release: optional recording-identity keys, so a pack can carry a stable, open, exact identity for the recording it transcribes.
Added¶
- New optional top-level manifest keys
mbid— the MusicBrainz Recording MBID of the recording the pack transcribes (lowercase canonical UUID) — andisrc— its International Standard Recording Code. Both are author-set exact identity keys: a consumer SHOULD prefer them over free-textartist/titlematching when grouping charts of the same recording or looking up external metadata, and SHOULD trustmbidwhen the two disagree. The stored ISRC is the bare 12-character code — the hyphens in the common display form are presentation only, stripped when writing and before comparing.schemas/manifest.schema.jsonvalidates both formats.
Compatibility¶
- Purely additive. Older Readers ignore both keys and still load. Nothing is removed, renamed, or repurposed.
[1.13.0] - 2026-07-01¶
Additive (MINOR) release: an engine-agnostic rig model so a feedpak can carry tone information
natively — a structured, portable alternative to the opaque tones.definitions passthrough.
Added¶
- New optional side-file
rigs.json(§7.9) and manifestrigskey: a pack-level library of rigs, each an ordered set of effect blocks. Every block splits what it is (intent, engine-independent) from how to render it (realizations— an ordered preference list overnam/ir/plugin/builtinengines, extensible to future ones). Openrole/kind/enginevocabularies, an open normalizedparamsmap with optional timeautomation, and an optionalgraphfor non-serial topology (parallel amps, wet/dry, stereo).schemas/rigs.schema.json. - Arrangement
tones(§6.9) gainsbase_rigandchanges[].rig, referencing a rigidinrigs.json. The legacy opaquetones.definitionspassthrough is unchanged; a rig-aware Reader prefers the structured references. examples/extended.feedpaknow ships arigs.jsonand atonesblock that exercises it.
Compatibility¶
- Purely additive. Older Readers ignore the
rigskey,rigs.json, and the newbase_rig/rigfields, and still load. Nothing is removed, renamed, or repurposed.
[1.12.0] - 2026-07-01¶
Additive (MINOR) release: album-grouping and genre metadata. Backward-compatible — a 1.0.0 (or 1.11.0) pack is also a valid 1.12.0 pack, and an older reader ignores the new optional keys.
Added¶
- Album grouping + genre metadata (spec §5.1): four OPTIONAL, author-set top-level keys —
album_artist(string) — album artist for the release, so multi-artist / compilation albums group under one album identity; absent ⇒ falls back toartist.track(int, 1-based) — track number within the album, for album playback order.disc(int, 1-based, default 1) — disc number for multi-disc releases.genres(list of strings, most specific first;genres[0]is primary) — genre labels.
A reader predating 1.12.0 ignores all four.
1.11.0 - 2026-06-23¶
Additive (MINOR) release: multi-lingual lyric tracks, language tags, and language-tagged vocal
stems. Backward-compatible — a 1.0.0 pack is also a valid 1.11.0 pack, and an older reader ignores
the new optional keys and still loads the single lyrics pointer + stems as before.
Added¶
- Multi-lingual packs (spec §5.5, §5.1, §5.3): three OPTIONAL additive keys so a pack can express language and carry more than one lyric representation —
- a top-level
language(BCP 47) naming the song's primary sung language; - a per-stem
languagehint tagging a language-specific vocal stem (e.g.vocals_ja/vocals_enfor a song with two sung-language recordings); - a
lyric_trackslist of additional lyric files, each withid,file,language, and akindoforiginal/transliteration/translation, plus OPTIONALlyrics_source,lyric_transcriptionprovenance, and astempointer pairing a sung original with its vocal recording.
Each track is an ordinary lyrics.json-shaped flat array, so
no new side-file schema is introduced — only schemas/manifest.schema.json grows (a bcp47
$def, a lyricTrack $def, the lyric_tracks array, and language on the manifest and on
$defs/stemEntry). The legacy single lyrics pointer is unchanged: when lyric_tracks is absent
a reader behaves exactly as before, and when present a writer SHOULD still point lyrics at the
primary-language original track's file for pre-1.11.0 readers. Exercised by the extended example
(an English original + a Japanese translation + a romaji transliteration, and a language-tagged
full stem).
Changed¶
- CI (no format change): the version-consistency guard (
tools/check_versions.py) now covers every place the current version is written — the spec header, the §4.1feedpak_versionexample + writer-SHOULD line, the README table and citation, and the extended example manifest, in addition to the newestCHANGELOG.mdversion. A missed spot during a bump now fails CI with a precise diff instead of drifting silently. - Docs (no format change): the hand-editing guide's
.jsoncsection now spells out the two caveats — comments are the only relaxation (no trailing commas / JSON5), and a comment-bearing.jsoncneeds a JSONC-aware reader, so keep distributed packs as comment-free.json.
1.10.0 - 2026-06-21¶
Additive (MINOR) release: a song-level harmony track. Backward-compatible — a 1.0.0 pack is also a valid 1.10.0 pack, and older readers ignore the new optional manifest key + side-file.
Added¶
- Song-level harmony track —
harmony.json(spec §7.8, manifestharmonykey): the song's intended chord progression (the chords the song is, independent of what any arrangement plays) — reference/teaching data for fretboard-theory overlays, chord lyric lines, and practice-alongs. Time-ordered events applying until the next (same shape askeys.json):t(required),root(absolute note name;nullmarks a no-chord/N.C. event),quality,rn(Roman numeral relative to the activekeys.jsonkey, omitted when no key is active), andbass(slash-chord bass). Voicing-free (does not index arrangement chord templates) and honesty-ruled — a grader MUST NOT score against it. Defined as distinct from per-chordfn(as-played function): a Reader MAY derive one from the other, but neither is authoritative.quality/fn.qnow reference a shared (recommended, not closed) chord-quality vocabulary so they stay interoperable. Schema:schemas/harmony.schema.json; exercised by the extended example (an Em→C→G→D7/F#→N.C. progression aligned to its Em/Gkeys.json). Implements #28.
1.9.0 - 2026-06-21¶
Additive (MINOR) release: audio stem formats beyond OGG. Backward-compatible — every existing OGG-only pack stays valid, and a Reader that only decodes the baseline keeps working on any portable pack.
Added¶
- Audio stem formats beyond OGG (spec §5.3.2,
§1): stems are now dispatched by file extension, with a
normative decoder baseline — a Reader MUST decode OGG (
.ogg) and WAV (.wav) and SHOULD decode MP3 / FLAC / Opus. A new OPTIONALcodechint on eachstems[]entry disambiguates when an extension doesn't determine the codec (schema:codecon$defs/stemEntryinschemas/manifest.schema.json; exercised by the extended example'sfullstem ascodec: vorbis). A portability rule requires a distributable pack to carry at least one baseline-format stem, so non-baseline stems are opportunistic enhancements rather than hard dependencies; a Reader MUST raise a clear error or fall back rather than fail silently on a format it can't decode. Proprietary/game formats (e.g. Wwise.wem) are explicitly not in the baseline, get no reference decoder, and MUST NOT be a distributable pack's only stem.
Changed¶
- §4.2 compatibility carve-out now lists two opt-in file-format relaxations — the existing
.jsoncextension and (new) audio stem formats beyond OGG (1.9.0 widens the baseline OGG→OGG+WAV and allows formats above it; since OGG was the only pre-1.9.0 guarantee, even a baseline WAV-only pack needs a 1.9.0 Reader) — both kept MINOR on the same "strictly opt-in, per-file; only a pack that actually uses it needs a supporting Reader" justification.
1.8.0 - 2026-06-21¶
Additive (MINOR) release: the two deferred per-chord harmony descriptors from the §6.3.1 FEP. Backward-compatible — a 1.0.0 pack is also a valid 1.8.0 pack, and older readers ignore the new optional fields.
Added¶
- Chord-template harmony descriptors (spec §6.6): two
OPTIONAL template fields that annotate the chord shape for teaching/display, never grading (the
honesty rule — a grader MUST NOT score them) —
caged(the CAGED-system shape the fingering derives from: one ofC/A/G/E/D) andguideTones(chromatic semitone offsets0–11above the chord root marking the quality-defining tones, typically the 3rd and 7th, e.g. a dominant-7 →[4, 10]). Both are key-independent shape properties, so they ride the template alongsidevoicing. Schema:caged(enum) +guideTones(int array) on$defs/templateinschemas/arrangement.schema.json; exercised by the extended example (the Em template →caged: "E",guideTones: [3]). Completes the §6.3.1 FEP, whosecaged/guideToneswere deferred in 1.7.0.
1.7.0 - 2026-06-21¶
Additive (MINOR) release: per-chord harmony annotations. Backward-compatible — a 1.0.0 pack is also a valid 1.7.0 pack, and older readers ignore the new optional fields.
Added¶
- Per-chord harmony annotations (spec §6.3.1,
§6.6): two OPTIONAL fields that annotate a chord's
harmony for teaching/display, never grading (the honesty rule — a grader MUST NOT score
them) —
fnon the chord instance ({rn, q, deg}: Roman-numeral label, quality token, and the chord root's chromatic offset0–11above the activekeys.jsontonic, mirroringsd; the chord's as-played function, derivable so a Reader MAY compute it), andvoicingon the chord template (a key-independent voicing-type string, e.g.open/shell/drop2). Function rides the instance and voicing the template because the same shape recurs across keys.fn's prose notes its boundary with a future song-level harmony track (the intended progression). Schema:fnon$defs/chordandvoicingon$defs/templateinschemas/arrangement.schema.json; exercised by the extended example (an Em chord asviin G major).cagedandguideTonesfrom the FEP are deferred.
1.6.0 - 2026-06-21¶
MINOR release under the new §4.2 opt-in file-format relaxation carve-out: the .jsonc
data-file extension (comment-annotated JSON), plus a docs-site version banner. No existing pack is
affected, and a comment-free .jsonc file is plain JSON — but a .jsonc file that actually
contains comments is not readable by a strict-JSON-only Reader; it requires a JSONC-aware
Reader. This is why .jsonc ships under an explicit, bounded carve-out rather than the ordinary
"older Readers keep working" minor rule (see the JSONC bullet below and spec §4.2 / §8).
Added¶
- Docs site (no format change): a build-time version banner. The site now stamps the newest
released
CHANGELOG.mdversion (SPEC_VERSIONenv →mkdocs.ymlextra.spec_version→overrides/main.html) into a top announcement bar, so the displayed version is deterministic and no longer depends on Material's client-side GitHub-release widget (which is cached in the browser's localStorage and could lag a release). - JSONC support (§2.2,
§3,
§8):
.jsoncfiles (C-style-commented JSON) are now accepted anywhere.jsonfiles are specified. Hand-edited data files MAY use the.jsoncextension to signal that they contain comments; Readers strip comments before parsing, and Writers SHOULD preserve them on round-trip. Only comments are permitted — trailing commas and other JSON5-style relaxations are not; after comment removal a.jsoncfile MUST be strict JSON. The reference validator (tools/validate.py) parses.jsoncfiles accordingly. Shipped as a MINOR bump under the §4.2 opt-in-relaxation carve-out: no existing pack is affected, and a comment-free.jsoncfile is plain JSON, but a.jsoncfile that contains comments is readable only by Readers that implement the comment-stripping step (a plain JSON parser errors on//), so a Writer needing maximum reader compatibility SHOULD keep data files as comment-free.json.
1.5.0 - 2026-06-21¶
Additive (MINOR) release: per-note teaching marks. Backward-compatible — a 1.0.0 pack is also a valid 1.5.0 pack, and older readers ignore the new optional note fields.
Added¶
- Per-note teaching marks (spec §6.2.2):
three OPTIONAL note fields that annotate how a note is taught or displayed, never whether it was
played correctly (the honesty rule — graders MUST NOT score them) —
fg(fret-hand finger,-1unset /0thumb /1–4index→pinky, same convention astemplate.fingers),ch(strum-group key: notes sharing a value≥ 0are one strum/rake gesture, withpkdgiving direction), andsd(scale degree as a chromatic offset0–11above the activekeys.jsontonic; derivable, so a Reader MAY compute it). Schema:fg/ch/sdon$defs/noteinschemas/arrangement.schema.json; exercised by the extended example pack (an Em-triad rake grouped bych).
1.4.0 - 2026-06-20¶
Additive (MINOR) release: per-note bend shape. Backward-compatible — a 1.0.0 pack is also a valid 1.4.0 pack, and older readers ignore the new optional note fields.
Added¶
- Per-note bend shape (spec §6.2.1): two OPTIONAL
note fields complementing the scalar
bnpeak —bt(bend intent: up / release / pre-bend / pre-bend-release / round-trip) andbnv(a time-stamped[{t, v}]bend curve). Lets renderers draw the bend arc and graders judge the right pitch over the note. Schema:bt+bnvon$defs/noteinschemas/arrangement.schema.json; exercised by the extended example pack.
Fixed¶
- §5.2
tuning: corrected the accepted-length range from "4–7 (4 = bass)" to 4–8 (4–6 = bass, 6–8 = extended-range guitar). 6-string bass and 7/8-string guitar were already permitted by the schema (tuninghas nomaxItems, noteshas no maximum) and by the "Readers MUST NOT hard-code length 6" rule, but the prose under-stated the upper bound. Editorial clarification only — no on-disk format change.
1.3.0 - 2026-06-20¶
Tooling, docs, and example release — no on-disk format change (a 1.2.0 pack is also a valid 1.3.0 pack). Bundles the repository's testing/CI, the documentation site, release automation, and a worked keyboard-notation example.
Added¶
- Repository CI/CD (no format change): a
pytesttest suite for the reference validator (tests/), a Python 3.10–3.13 matrix and arufflint job in the validate workflow, and a GitHub Pages workflow that publishes the JSON Schemas so their$idURLs resolve. (Release automation is described in its own bullet below.) - Docs site (no format change): the GitHub Pages site is now built with MkDocs Material
(light/dark theme, search, rendered spec/hand-editing/changelog).
tools/gen_docs.pyassembles the site from the canonical sources and copies the schemas in verbatim so their hosted URLs are unchanged. - Example (no format change): the extended pack now includes a notation-only
keysarrangement (type: piano) with a two-stavenotation_<id>.jsonpart, so the §7.6 standard-notation / keyboard-arrangement path is exercised by the validator and CI. - Release automation (no format change): a reviewed version bump now cuts its GitHub Release
automatically on merge to
main(idempotent release-on-merge), replacing the manual tag-triggered flow. Atools/check_versions.pyCI guard enforces that the spec header, the README table, and the newest releasedCHANGELOG.mdversion stay in lockstep.
1.2.0 - 2026-06-20¶
Additive (MINOR) release: new optional song-level and per-arrangement timing data, all backward-compatible with 1.0.0/1.1.0 readers.
Added¶
- Song-level
temposandtime_signaturesinsong_timeline.json(spec §7.4): two OPTIONAL time-ordered event arrays giving the song-wide tempo ({time, bpm}) and meter ({time, ts: [num, den]}) maps. Each event applies until the next, likekeys.json. This gives guitar/game consumers a song-wide BPM and meter that previously existed only per-measure inside notation files. The file'sversionstays1. - Per-arrangement
temposoverride (spec §6.10): an arrangement JSON MAY carry its owntemposmap; when present a Reader uses it for that chart and ignores the song-level tempo. Mirrors the §7.4 side-file-priority rule. keys.jsondisambiguation note (spec §7.7): clarifies that the key/scale track is instrument-independent and unrelated to a keyboard arrangement — a guitar-only pack can signal key changes with no keyboard part. No schema change.- Schema and example updates:
tempos/time_signaturesinschemas/song-timeline.schema.json, a$defs/tempoEventandtemposproperty inschemas/arrangement.schema.json, exercised by the extended example pack (song timeline + a per-chart bass override).
1.1.0 - 2026-06-20¶
Additive (MINOR) release: a new optional manifest field, backward-compatible with 1.0.0 readers.
Added¶
- Manifest
authorslist (spec §5.4): an OPTIONAL top-level array crediting the people who authored or edited a feedpak — each entry carries a requirednameplus optionalrole,email, andurl. Distinct fromartist(the recording artist). Released as a MINOR bump (feedpak_version1.1.0); older readers ignore the unknown key. Schema: a new$defs/authorinschemas/manifest.schema.json; exercised by the extended example pack. hand-editing.md— a practical, vendor-neutral hand-editing guide (record/replace stems, edit metadata/cover/lyrics/tuning, re-zip for distribution), adapted from the feedback project's user guide with application-specifics removed. Linked from the README.
1.0.0 - 2026-06-19¶
Initial public release of the feedpak format specification.
Added¶
- Normative specification:
feedpak-v1.md, with a Conformance section (RFC 2119 / RFC 8174), Reader/Writer roles, and a "this document is authoritative" stance independent of any implementation. - Built-in versioning: top-level
feedpak_versionsemver field in the manifest, a MAJOR/MINOR/PATCH compatibility policy, and explicit rules separating the format version, per-file side-fileversionintegers, and the specification-document version. - Manifest reference (§5), arrangement wire format (§6), and side-file schemas (§7): lyrics, vocal pitch, vocal pitch contour, song timeline, drum tab, notation, and key/scale annotations.
- JSON Schemas (Draft 2020-12) for the manifest and all structured files, in
schemas/. - Worked examples in
examples/: a minimal pack and an extended pack exercising the optional side-files. - Reference validator
tools/validate.py, doubling as the CI gate. - Repository governance: README, CONTRIBUTING (DCO + enhancement-proposal process), GOVERNANCE, CODE_OF_CONDUCT, and dual CC0/MIT licensing.