Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
8266f88
VECTOR: a MIDI generator for the MIDI tracks (work in progress)
repeat98 Oct 21, 2026
a8b82e5
VECTOR 0.3.0-experimental: version, changelog and test record
repeat98 Oct 21, 2026
2970a7d
Merge branch 'claude/midi-generator-table' into claude/midi-generators
repeat98 Oct 21, 2026
0df82ea
VECTOR 0.3.0: import the source-built packages; the importer expects …
repeat98 Oct 21, 2026
d225700
VECTOR 0.3.0: an owner-approved update; drop the 0.2.4 qualification …
repeat98 Oct 21, 2026
6d9014d
Merge branch 'claude/midi-generator-table' into claude/midi-generators
repeat98 Oct 21, 2026
e85eee1
VECTOR 0.3.0: native comparison (48 matching images, 90 matching refu…
repeat98 Oct 21, 2026
04c3028
Merge branch 'claude/midi-generator-table' into claude/midi-generators
repeat98 Oct 24, 2026
3b56452
VECTOR 0.3.0: layout A on MIDI tracks (SRC and AMP pages, OCT/VEL/GAT…
repeat98 Oct 24, 2026
5aa0e32
Merge branch 'claude/midi-generator-table' into claude/midi-generators
repeat98 Oct 24, 2026
7c9af7c
VECTOR 0.3.0: manifest wording for layout A
repeat98 Oct 24, 2026
7d44b04
VECTOR 0.3.0: import the source-built packages for layout A
repeat98 Oct 24, 2026
df05e52
VECTOR 0.3.0: native comparison for layout A (54 matching images, 92 …
repeat98 Oct 24, 2026
47af5cf
Merge branch 'claude/midi-generator-table' into claude/midi-generators
repeat98 Oct 24, 2026
72faeba
VECTOR 0.2.6-experimental: SRC SETUP page 2 on VECTOR's own row, wher…
repeat98 Nov 1, 2026
bc36ae8
VECTOR 0.2.6: import the isolated toolchain's packages
repeat98 Nov 1, 2026
bfaa364
VECTOR 0.2.6: native comparison (54 images match, 108 refusals match,…
repeat98 Nov 1, 2026
cf55b5a
VECTOR 0.2.6: quick-test guide and source-test version pin
repeat98 Nov 1, 2026
1aade27
VECTOR 0.2.6: Analog BD proofs re-exported for the new module source …
repeat98 Nov 1, 2026
9080a87
VECTOR 0.2.6: Tape Echo and Euclid standalone recipes re-pin the impo…
repeat98 Nov 1, 2026
c8298ad
Merge remote-tracking branch 'origin/main' into claude/vector-026-set…
repeat98 Nov 1, 2026
76032d4
Merge remote-tracking branch 'origin/main' into claude/vector-026-set…
repeat98 Nov 6, 2026
9553163
VECTOR 0.2.6: import the isolated toolchain's packages after merging …
repeat98 Nov 6, 2026
dbe9728
VECTOR 0.2.6: bind the card captures to 0.2.4's native source by name…
repeat98 Nov 6, 2026
50d939e
VECTOR 0.2.6: Tape Echo and Euclid standalone recipes re-pin the impo…
repeat98 Nov 6, 2026
62c9aa7
VECTOR 0.2.6: Analog BD proofs re-exported for the merged module sour…
repeat98 Nov 6, 2026
c777dbb
Merge remote-tracking branch 'origin/main' into claude/vector-026-set…
repeat98 Nov 6, 2026
bf6b709
Merge remote-tracking branch 'origin/main' into claude/vector-026-set…
repeat98 Nov 6, 2026
672f9f7
Merge #1141's branch (VECTOR 0.2.6) into VECTOR 0.3.0; generated file…
repeat98 Nov 8, 2026
49cd653
Merge origin/main into VECTOR 0.3.0
repeat98 Nov 8, 2026
9be221a
VECTOR 0.3.0: on main with 0.2.6's setup-page fix; release notes, reg…
repeat98 Nov 8, 2026
1ea000a
VECTOR 0.3.0: import the source-built packages
repeat98 Nov 8, 2026
8ae180d
VECTOR 0.3.0: USB package with the MIDI generator; machine and standa…
repeat98 Nov 8, 2026
63a3dd2
VECTOR 0.3.0: firmware-free tests rerun, source fingerprint, resource…
repeat98 Nov 8, 2026
1129766
VECTOR 0.3.0: catalogue regenerated, Analog BD proofs re-exported (un…
repeat98 Nov 8, 2026
93417cf
VECTOR 0.3.0: native comparison (76 matching images, 110 matching ref…
repeat98 Nov 8, 2026
bd2af8c
Merge remote-tracking branch 'origin/main' into claude/midi-generators
repeat98 Nov 8, 2026
ebceb74
VECTOR 0.3.0: no .bss on a card (zero statics in .data), the hook reg…
repeat98 Nov 8, 2026
3f4b3d5
VECTOR 0.3.0: TESTING notes the card .bss fix
repeat98 Nov 8, 2026
1e2e8f5
VECTOR 0.3.0: rebuilt for the card .bss fix (packages, recipes, proof…
repeat98 Nov 8, 2026
febd681
Merge remote-tracking branch 'origin/main' into claude/midi-generators
repeat98 Nov 8, 2026
d66b4ed
VECTOR 0.3.0: emulator results for the MIDI generator (USB package an…
repeat98 Nov 8, 2026
2119fd6
VECTOR 0.3.0: named VECTOR MIDI on the site, its summary names MIDI t…
repeat98 Nov 8, 2026
a8cf758
Merge remote-tracking branch 'origin/main' into claude/midi-generators
repeat98 Nov 8, 2026
cd98871
VECTOR 0.3.0: on main with the MIDI generator list (#1332): control.s…
repeat98 Nov 8, 2026
e56d5dc
VECTOR 0.3.0: rebuilt on main with the MIDI generator list (package 4…
repeat98 Nov 8, 2026
17b0ca1
Merge remote-tracking branch 'origin/main' into claude/midi-generators
repeat98 Nov 8, 2026
973f948
VECTOR 0.3.0: the release announcement test names VECTOR MIDI
repeat98 Nov 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion scripts/module-source.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe('release package scope and reviewed source inventory', () => {
expect(versions['midi-scenes']).toBe('0.2.5-experimental')
expect(versions.miniverb).toBe('0.2.3-experimental')
for (const id of verifiedRequested) {
expect(versions[id]).toBe(id === 'analog-bassdrum' ? '0.1.6-experimental' : id === 'vector' ? '0.2.5-experimental' : id === 'quantizer' ? '0.1.4-experimental' : id === 'synth' ? '0.1.2-experimental' : id === 'usb-audio-out-tracks-main-cue' ? '0.2.0-experimental' : '0.1.2-experimental')
expect(versions[id]).toBe(id === 'analog-bassdrum' ? '0.1.6-experimental' : id === 'vector' ? '0.3.0-experimental' : id === 'quantizer' ? '0.1.4-experimental' : id === 'synth' ? '0.1.2-experimental' : id === 'usb-audio-out-tracks-main-cue' ? '0.2.0-experimental' : '0.1.2-experimental')
expect(paths).toContain('modules/' + id + '/manifest.py')
}
expect(paths).toContain('modules/midi-scenes/recipe.json')
Expand Down
7 changes: 4 additions & 3 deletions scripts/stock-copy-policy.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
// Which stock copies a requested card package may carry (scripts/import-module-build.mjs). A copy is a zero
// placeholder the builder fills from the user's verified OS at build time, matched by address, length and SHA-256,
// so no stock byte is in the package. Two kinds are admitted:
// - replay spans: the four of USB MIDI's descriptor package and of VECTOR's and POLY8's replaying units, each
// the guarded span of a detour of the same group (USB MIDI: its 23-byte descriptor);
// - replay spans: the four of USB MIDI's descriptor package and of VECTOR's and POLY8's replaying units (VECTOR's
// fifth: MIDI NOTE SETUP's drawer, its MIDI generator list on a card), each the guarded span of a detour of the
// same group (USB MIDI: its 23-byte descriptor);
// - data copies: any other package's copies, each a guard its module's import record declares under stockGuards
// with kind guarded-local-cpu-read, so a reviewer sees every span a module reads from the OS.

Expand All @@ -15,7 +16,7 @@ export function checkRequestedStockCopies(pkg, group, guards = []) {
const copies = pkg.stockCopies
if (!Array.isArray(copies)) throw new Error('Invalid inherited stock placeholder inventory')
if (REPLAY_LABELS.includes(pkg.label)) {
if (copies.length !== 4) throw new Error('Invalid inherited stock placeholder inventory')
if (copies.length !== (pkg.label === 'vector' ? 5 : 4)) throw new Error('Invalid inherited stock placeholder inventory')
for (const copy of copies) {
if (pkg.label === 'usbmidi_cfg') {
if (copy.bytes !== 23) throw new Error('Invalid inherited USB descriptor length')
Expand Down
6 changes: 6 additions & 0 deletions scripts/stock-copy-policy.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ describe('stock copies a requested card package may carry', () => {
it('refuses a replaying package without exactly four copies', () => {
expect(() => checkRequestedStockCopies({ label: 'vector', stockCopies: replay(3) }, detours)).toThrow('Invalid inherited stock placeholder inventory')
})
it("accepts VECTOR's fifth replay span (its MIDI generator list on a card) and no other package's", () => {
const five = { detours: [0, 1, 2, 3, 4].map(i => ({ address: 0x40001000 + 16 * i, guardLength: 6, guardSha256: A })) }
expect(() => checkRequestedStockCopies({ label: 'vector', stockCopies: replay(5) }, five)).not.toThrow()
expect(() => checkRequestedStockCopies({ label: 'vector', stockCopies: replay(4) }, five)).toThrow('Invalid inherited stock placeholder inventory')
expect(() => checkRequestedStockCopies({ label: 'polyui', stockCopies: replay(5) }, five)).toThrow('Invalid inherited stock placeholder inventory')
})
it('refuses a replay span that differs from its detour guard', () => {
const copies = replay(); copies[2] = copy(copies[2].source, 6, B, 16)
expect(() => checkRequestedStockCopies({ label: 'polyui', stockCopies: copies }, detours)).toThrow('Inherited replay span must match its declared native detour guard')
Expand Down
2 changes: 1 addition & 1 deletion sdk/catalog.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
},
{
"id": "vector",
"version": "0.2.5-experimental",
"version": "0.3.0-experimental",
"addedAt": "2026-10-06T08:02:00Z"
},
{
Expand Down
7 changes: 4 additions & 3 deletions sdk/machines/octatrack/module-adapters/machine-ports.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@
},
"vector": {
"sources": {
"sdk/octabam/modules/vector/control.s": "c4f829e437ffbde1275c00827031b694a86011013d37269077e4696818323471",
"sdk/octabam/modules/vector/manifest.py": "4d921f24256038797a99671534885b0bb9a27eaa79261b11136cf0a95a75af21"
"sdk/octabam/modules/vector/control.s": "e12b5f82744d14a5511a605fabc5ff0624387084164c59143f9ddccec1f207dd",
"sdk/octabam/modules/vector/manifest.py": "b9dec167f8bd4f1b691069cc89834f6c2a6717b874eb28629ef5c8c026d3d976"
},
"contribute": [
{
Expand Down Expand Up @@ -218,7 +218,8 @@
"st_name_replay",
"st_main_replay",
"st_edit_replay",
"st_draw_replay"
"st_draw_replay",
"mg_stock_note_draw"
],
"why": "VECTOR's st_* chooser hooks and their stock replays are unreachable in the package; its registry functions are the descriptor's, and its SRC SETUP page 2 (st_setup_page, st_setup_knob, which its card build's st_setup_draw6 and st_setup_edit6 call) the SETUP_PAGE record's"
},
Expand Down
74 changes: 51 additions & 23 deletions sdk/machines/octatrack/module-adapters/machine-recipes.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"schema": 1,
"imageSha256": "642d27796f5ee0100eed8477266a7aff77d8614b40da50b554218170a19d49c5",
"sources": {
"sdk/machines/octatrack/module-adapters/machine-ports.json": "59a501e0350538b626bfd38c24236bc1f9d3620e62c1dcef38f84d72d5b76b3e",
"sdk/machines/octatrack/module-adapters/machine-ports.json": "fc41b5ec896e452dd1b8d8db4afd04d1acb1f00ffbf331be036786360de71528",
"sdk/machines/octatrack/module-adapters/machine_ports.py": "bbb91f0c54c27043b54a9156cad01053531f2ef78fb13cc73e2b45f7fc7e8d6f",
"sdk/octabam/modules/poly8/manifest.py": "f8759dbcbb246b247c195e61f0c0464fd0cdc0dd40b68dd8f74c03b46c584afc",
"sdk/octabam/modules/poly8/polyphony.s": "c86a3a783c46ecdbb3b44341098f0c094c65b9a8d11716835c2d28c2d2d6ecee",
Expand Down Expand Up @@ -57,7 +57,7 @@
"schema": 1,
"imageSha256": "13047ca2595493c2389ad2265f39f8c04287f5c9021991197a5fded08faf75d0",
"sources": {
"sdk/machines/octatrack/module-adapters/machine-ports.json": "59a501e0350538b626bfd38c24236bc1f9d3620e62c1dcef38f84d72d5b76b3e",
"sdk/machines/octatrack/module-adapters/machine-ports.json": "fc41b5ec896e452dd1b8d8db4afd04d1acb1f00ffbf331be036786360de71528",
"sdk/machines/octatrack/module-adapters/machine_ports.py": "bbb91f0c54c27043b54a9156cad01053531f2ef78fb13cc73e2b45f7fc7e8d6f",
"sdk/machines/octatrack/module-adapters/quantizer_runtime.py": "61425221199f37adf4be1e8b9c5bb1346067c8f56540a9a15047b400ed84a1aa",
"sdk/octabam/modules/quantizer/manifest.py": "e0841437a471b000b448ce8417c8fd25cba1cf155aec488d08d2888f4c249394",
Expand Down Expand Up @@ -121,7 +121,7 @@
"imageSha256": "11afe489011aa243c5bc579a824635f7d1334b17f0a21d554d897ceec3d3fb1a",
"sources": {
"sdk/machines/octatrack/module-adapters/fm_runtime.py": "ecf39c395bd8231d1dda340e1c6bc26e8473ba548cfa422f9a4ae4ff2bd6807e",
"sdk/machines/octatrack/module-adapters/machine-ports.json": "59a501e0350538b626bfd38c24236bc1f9d3620e62c1dcef38f84d72d5b76b3e",
"sdk/machines/octatrack/module-adapters/machine-ports.json": "fc41b5ec896e452dd1b8d8db4afd04d1acb1f00ffbf331be036786360de71528",
"sdk/machines/octatrack/module-adapters/machine_ports.py": "bbb91f0c54c27043b54a9156cad01053531f2ef78fb13cc73e2b45f7fc7e8d6f",
"sdk/octabam/modules/synth/machine.s": "de9d849bf0b6e5d5ad747df32ae5806e7f9516674a14ac74b1c15d73d30d280a",
"sdk/octabam/modules/synth/manifest.py": "7854330aca001d2841de2fb384f0ca8adb7497db49dacc56da2815c1f444c0e6",
Expand Down Expand Up @@ -408,67 +408,95 @@
},
"vector": {
"schema": 1,
"imageSha256": "70187665697dd57baefc9b65480a564e7514c75bdbce9c3c6f5519d2953684ab",
"imageSha256": "33c2db1c6fd9e3d28d7bb5aa95119a36c354a5d2f060086927944cd58e42c974",
"sources": {
"sdk/machines/octatrack/module-adapters/machine-ports.json": "59a501e0350538b626bfd38c24236bc1f9d3620e62c1dcef38f84d72d5b76b3e",
"sdk/machines/octatrack/module-adapters/machine-ports.json": "fc41b5ec896e452dd1b8d8db4afd04d1acb1f00ffbf331be036786360de71528",
"sdk/machines/octatrack/module-adapters/machine_ports.py": "bbb91f0c54c27043b54a9156cad01053531f2ef78fb13cc73e2b45f7fc7e8d6f",
"sdk/machines/octatrack/module-adapters/vector_runtime.py": "e5e8351f4be954b1028a7b455a977c1460864c85ad10d781dfe4aef4876ad6e3",
"sdk/octabam/modules/vector/control.s": "c4f829e437ffbde1275c00827031b694a86011013d37269077e4696818323471",
"sdk/octabam/modules/vector/manifest.py": "4d921f24256038797a99671534885b0bb9a27eaa79261b11136cf0a95a75af21",
"sdk/machines/octatrack/module-adapters/vector_runtime.py": "25212235bdd5871fba2d2587ac215b2546a63bd1317b468c79c1582c27398eac",
"sdk/octabam/modules/vector/control.s": "e12b5f82744d14a5511a605fabc5ff0624387084164c59143f9ddccec1f207dd",
"sdk/octabam/modules/vector/manifest.py": "b9dec167f8bd4f1b691069cc89834f6c2a6717b874eb28629ef5c8c026d3d976",
"sdk/runtime/loader/build.py": "5131901224dcd037c07f0233cadabd67eec2a952878bef5a92274dd3d6236c7d"
},
"copies": [
{
"offset": 3410,
"offset": 34,
"length": 20,
"address": 1073802002,
"sha256": "4c14741dff5ce18a933b30875f7e3a0ac8d633db0096af8f7a7a31a88e1313b0",
"purpose": "vector: authored bytes coinciding with stock (strict scan), reconstructed from the identical bytes of the user's OS; review"
},
{
"offset": 2230,
"length": 13,
"address": 1073808978,
"sha256": "b8d6267fd976a1257142c8ba1ef20d072cc8a79fa80af4e402ec2cf85ce747b6",
"purpose": "vector: authored bytes coinciding with stock (strict scan), reconstructed from the identical bytes of the user's OS; review"
},
{
"offset": 5156,
"length": 14,
"address": 1074149512,
"sha256": "079db88a4b98775059e3e9b221b27a5436dfe7bfaaa30ec1d8a805faea0e9fd6",
"purpose": "vector: authored bytes coinciding with stock (strict scan), reconstructed from the identical bytes of the user's OS; review"
},
{
"offset": 5602,
"offset": 8256,
"length": 15,
"address": 1073934426,
"sha256": "532ccfdbeda1f24a92dff3bff914f0c178f143a4ba52c4c6f82a50696eabf852",
"purpose": "vector: authored bytes coinciding with stock (strict scan), reconstructed from the identical bytes of the user's OS; review"
},
{
"offset": 8724,
"length": 15,
"address": 1073934426,
"sha256": "532ccfdbeda1f24a92dff3bff914f0c178f143a4ba52c4c6f82a50696eabf852",
"purpose": "vector: authored bytes coinciding with stock (strict scan), reconstructed from the identical bytes of the user's OS; review"
},
{
"offset": 10220,
"length": 14,
"address": 1074073374,
"sha256": "5f460b9d4661db855641f1e3d7cb71cf2c6b0a6e8ad754886d283c9f1a3c5299",
"purpose": "vector: authored bytes coinciding with stock (strict scan), reconstructed from the identical bytes of the user's OS; review"
},
{
"offset": 7166,
"offset": 11868,
"length": 12,
"address": 1073882466,
"sha256": "f6838b012beac6d6395527d401c6eabefbded04cd643d14afbf356781cb4aeb6",
"purpose": "vector: authored bytes coinciding with stock (strict scan), reconstructed from the identical bytes of the user's OS; review"
},
{
"offset": 10032,
"offset": 14734,
"length": 14,
"address": 1074237950,
"sha256": "0939a4ca02b038ba72eec962b17c37d00c17ed240b08a4400cc3d071c8ebbe31",
"purpose": "vector: authored bytes coinciding with stock (strict scan), reconstructed from the identical bytes of the user's OS; review"
},
{
"offset": 11262,
"length": 14,
"address": 1074235542,
"sha256": "4be6e9d8ab86bfb63e91b242f2d2824f061a003fabd5eeea29fc4f33af158a54",
"offset": 16364,
"length": 16,
"address": 1074178428,
"sha256": "44d6e7638702c28959b44309e5f7c04a2d9dbd313666960cc1fa9036d028678c",
"purpose": "vector: authored bytes coinciding with stock (strict scan), reconstructed from the identical bytes of the user's OS; review"
},
{
"offset": 11484,
"length": 20,
"address": 1073802002,
"sha256": "4c14741dff5ce18a933b30875f7e3a0ac8d633db0096af8f7a7a31a88e1313b0",
"offset": 16432,
"length": 16,
"address": 1074178428,
"sha256": "44d6e7638702c28959b44309e5f7c04a2d9dbd313666960cc1fa9036d028678c",
"purpose": "vector: authored bytes coinciding with stock (strict scan), reconstructed from the identical bytes of the user's OS; review"
},
{
"offset": 12200,
"offset": 21492,
"length": 20,
"address": 1074428104,
"sha256": "96966986164a24f9ca5be84cca807a016a828da2bcc3167b831be52acad2a9a7",
"purpose": "vector: authored bytes coinciding with stock (strict scan), reconstructed from the identical bytes of the user's OS; review"
},
{
"offset": 12574,
"offset": 21866,
"length": 12,
"address": 1074100132,
"sha256": "fa4871f504c0f71c15f06b76536f127ec74d257852ce50a1b9f16b3d14e8688c",
Expand All @@ -483,7 +511,7 @@
"sources": {
"sdk/machines/octatrack/module-adapters/analog_bd_runtime.py": "b9c0e0f96632a0d0ab5283387edaae1b604e4e82e27e26b3fdc1666867d31daf",
"sdk/machines/octatrack/module-adapters/analog_bd_write_lease.py": "3e6a3766f32176e9be69627ef2b71272970f2d02a2088e77673946b640d365c7",
"sdk/machines/octatrack/module-adapters/machine-ports.json": "59a501e0350538b626bfd38c24236bc1f9d3620e62c1dcef38f84d72d5b76b3e",
"sdk/machines/octatrack/module-adapters/machine-ports.json": "fc41b5ec896e452dd1b8d8db4afd04d1acb1f00ffbf331be036786360de71528",
"sdk/machines/octatrack/module-adapters/machine_ports.py": "bbb91f0c54c27043b54a9156cad01053531f2ef78fb13cc73e2b45f7fc7e8d6f",
"sdk/machines/octatrack/module-adapters/stock_hook_write_lease.h": "ab14679a5faae84ef47d1ca37e46b3171da45252d12310e0b4458228be8334be",
"sdk/octabam/modules/analog-bassdrum/control.s": "463dacf528e4996c7f21e97533391583329a2e3aabda95c87b7cd020dee7adb6",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ def test_pair_has_one_owner_without_hidden_poly_or_unrelated_dedup(self):
claims += [(r.addr, r.addr + 4, m.name) for r in m.symbol_refs]
claims += [(p.addr, p.addr + len(p.write), m.name) for p in m.pokes]
claims += [(addr, addr + 4, m.name) for table in m.tables for addr, _ in table.refs]
self.assertEqual(len(claims), 96)
self.assertEqual(len(claims), 100) # VECTOR 0.3.0 adds its four MIDI generator detours
for previous, current in zip(sorted(claims), sorted(claims)[1:]):
self.assertLessEqual(previous[1], current[0], (previous, current))
self.assertEqual(sum(r.symbol == 'mr_pb_table' for r in bridge.symbol_refs), 5)
Expand Down
Loading
Loading