Repository navigation
Conversation
…13ed8) The engine, page and the author's FM SYNTH chooser are vendored byte for byte from timhastie/octatrick-modules v2.12 (ca13ed8): the 2.10 engine with 6 dB of headroom, the 2.11 machine list (a row table, six row-count detours in place of the 2.10 pokes, five row-clamp detours, the SELECT MACHINE TYPE scroll) and the two 2.12 changes: the metronome click no longer cuts a held note (the engine's hook on the click word is removed), and a machine change to or from FM SYNTH resets the track's machine parameters to init, step and scene locks kept as in stock (one new detour, po_unload). With FM Synth alone the list keeps its six rows. Modwerk's machine.s / registration.s are dropped; the bundled quantizer keeps 0.1.2's drawer fix (repeat98#264). Every stock expectation is a stock_guard (73). The author's native Analog BD conflict is cleared in the wrapper (Modwerk declares it in octamod.module.json). Emulator evidence on the image built from this source (MAIN OS 00fa6caa): cycles (one VOIC 4 track 81,422 of 95,779 cycles/block, the largest of five runs), exact memory (43,812 module-owned bytes), stack bound 352 B, two-instance Part/project save and reload, the metronome case and the machine-change init, captures, Part smoke, odd-address check. Hardware fields are placeholders for the author's report. The native/browser record is not refreshed: POLY8's bridge is bound to 0.1.2's chooser hooks (TESTING.md).
…rt inventory refreshed on main 3151975
…racks) The bundled quantizer moves to timhastie/octatrick-modules 48b89e7 (tag v2.13; its synth/ files are the same bytes as v2.12 ca13ed8, so the engine, chooser and page are 0.1.4's). With a scale on, a MIDI track's NOTE knob and NOTE locks step through the scale from ROOT and its CHROMATIC keys play the scale from ROOT (three new detours: 0x40055382 qz_mknob, 0x40050b98 qz_mplock, 0x400436a8 qz_mkey); NOT2..4, TRAN, the arpeggiator, MIDI IN and SCALE OFF are unchanged. 2.13 takes Modwerk's repeat98#264 form of the CHROMATIC drawer hook (0x400449be), so quantizer.s, core.s, keys.s, scale.s and README.md are the author's files byte for byte; the quantizer manifest is his 2.13 manifest in stock_guard form (23 guards). The module LICENSE carries his 2.13 LICENSE (one sentence crediting Modwerk's form). Inventory sdk/imports/synth-48b89e7.json, following 0.1.4's synth-ca13ed8.json. Emulator evidence on the image built from this source (MAIN OS 37661aee): the FM objects are byte-identical to 0.1.4's at the same addresses; NOTE knob / locks 409 of 409 and CHROMATIC keys 245 of 245 against a model of the rules, SCALE OFF as stock, the sequencer unchanged, the quantizer's added cost per call; Part smoke, two-instance persistence, machine-change init; exact memory (44,404 module-owned bytes), stack bound 352 B; 0.1.4's cycle table with its bounding cards rerun here; seven captures (a MIDI track's CHROMATIC page new; two 0.1.4 captures dropped for the eight-media limit). Hardware fields are placeholders for the author's report.
…nly); Analog BD record re-verified and rebound build-module-packages.py --include-requested on this source, imported with --development: only the Synth objects and the Synth version change against main's 0.1.2 packages (Modwerk's fmregistration object is gone, the author's poly and fmmachine objects come in, the bundled quantizer objects change; 0.1.4 has no package commit of its own on this branch). The Analog BD record's moduleSourceTreeSha256 is rebound after verify-analog-bd-native.mjs passed against the new packages (162 native OS and GNU bootloader comparisons, 50 matching refusals, 6 firmware round trips).
…rt inventory refreshed on main 263aa1b
… scale, and a per-track exemption, are planned; a drum track is programmed with SCALE OFF until then
…e it alone, as native octabam does (its manifest requires SYNTH MACHINE); FM Synth's per-remix units gain a SY DRUM variant; the core logger yields a hook site a selected module owns; module:doctor accepts a module refused alone by design
…module (stock_guard form, README, TESTING, captures, smoke, emulator qualification) upstream/sy-drum/ is timhastie/octatrick-modules v2.14 (39dc5d8) sy-drum/ byte for byte except manifest.py, whose 53 stock expectations are stock_guard(address, length, sha256) of the user's 1.40C (410 bytes, each recomputed and checked against the literal it replaces); upstream/synth/engine_abi.inc and upstream/LICENSE are the same tag's. SY DRUM needs FM Synth 0.1.5, which stays pinned to v2.13 (48b89e7): v2.14 changes only sy-drum/ and the author's README, so synth/ is the same bytes at both tags. 2.14 is the author's fix of his hardware finding on the previous test image of this package (MAIN OS d0dab5fe, the 2.12 SY DRUM): PLAYBACK SETUP step locks edited while the pattern played were lost by a power-off without SAVE PROJECT, while the stock locks came back. The step locks' WORK file is now written while the sequencer plays too (one more hook, the UI tick's transport test at 0x4005224a: at most one write every 60 UI ticks while a lock edit is unwritten), and the lock files load whatever the stock bank load returned. The SY DRUM unit differs from the previous build's only in the code assembled from locks_io.inc.s (+346 B). Emulator evidence on the image built from this source with FM Synth 0.1.5 (MAIN OS 27c213b2): cycles (2 tracks 84,213 of 95,779 cycles/block, the maximum over five runs of each load), exact memory, stack bound, the machine change SY DRUM -> FM SYNTH -> SY DRUM, two-instance Part / project-load checks with the sylock files, the power-off without SAVE (while playing, 0.6 s after pressing STOP, stopped) with the power-on load and the battery-backed memory carried over (an emulator build that keeps it; the previous image as the failing control), a removed / cut / damaged stock bank file at that load, the machine-list walk, seven renders identical to the author's, captures, Part smoke, odd-address check. Hardware fields are placeholders for the author's report of this image.
…main 263aa1b (beside FM Synth 0.1.5); Analog BD's matrix re-verified and rebound
…t inventory refreshed
…he records as committed (main 263aa1b), and main's Tape Echo retained-evidence gate, also on the current main; the comparison with the previous image names the larger run-to-run spread
9 of 15 tasks
Owner
|
Hey Tim, Modwerk can't have cross-dependency between modules. |
Contributor
Author
|
Ok, thanks for letting me know. I'm at work now, will have to look into the
fix later.
…On Wed, Oct 14, 2026 at 11:06 AM Jannik Aßfalg ***@***.***> wrote:
*repeat98* left a comment (repeat98/modwerk#558)
<#558 (comment)>
Hey Tim, Modwerk can't have cross-dependency between modules.
—
Reply to this email directly, view it on GitHub
<#558?email_source=notifications&email_token=ANTUMBDJUCVXNKBNCIPF6M35T66DPA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTMMJXGUYDCMBYGUZ2M4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2KYZTPN52GK4S7MNWGSY3L#issuecomment-6175010853>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ANTUMBFZFEXIPILYCHVBOPL5T66DPAVCNFSNUABGKJSXA33TNF2G64TZHMYTGOJZGM2DSMZTHA5US43TOVSTWNJYGM2DEOBSGYZTLILWAI>
.
Triage notifications, keep track of coding agent tasks and review pull
requests on the go with GitHub Mobile for iOS
<https://github.com/notifications/mobile/ios/ANTUMBEXGVBZQ4CW3IDJVSD5T66DPA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTMMJXGUYDCMBYGUZ2M4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2KUZTPN52GK4S7NFXXG>
and Android
<https://github.com/notifications/mobile/android/ANTUMBENXU3KI6KW25JCOJT5T66DPA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTMMJXGUYDCMBYGUZ2M4TFMFZW63VGMF2XI2DPOKSWK5TFNZ2K4ZTPN52GK4S7MFXGI4TPNFSA>.
Download it today!
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Owner
|
Thanks for SY DRUM. I can't take it in its current form:
If SY DRUM stands on its own, most of the shared-code changes in the description go away: the "needs FM Synth" rule, the Please don't spend time rebasing it for now. FM Synth 0.1.5 (#555) is blocked by its own checks; see my comment there. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft, stacked on the FM Synth 0.1.5 PR: #555. Until that PR is merged this branch also carries its commits; please review only the SY DRUM commits listed below.
SY DRUM 0.1.0: a new machine module (needs FM Synth)
SY DRUM is a new Octatrack module: a drum machine for audio tracks, chosen in the track machine list in the row after FM SYNTH. Each SY DRUM track is one voice — two oscillators, a pitch sweep, a two-pole low-pass filter opened by the decay envelope, six modes (A–F) and a dedicated LFO with sample-and-hold. It plays without a sample. It is my octatrick 2.14 module,
timhastie/octatrick-modulesat39dc5d8ca285c14674b66a452f58a5a0364efb96(tagv2.14), packaged for Modwerk assy-drum0.1.0-experimental.SY DRUM is modelled on the 1979 Pearl Syncussion SY-1, written from a study of that unit's circuit. It is not affiliated with or endorsed by Pearl or Behringer. Syncussion is a trademark of its owner.
This PR is stacked on the FM Synth 0.1.5 PR (#555), the one FM Synth PR (it carries 0.1.4's two commits and 0.1.5's five). SY DRUM runs on FM Synth's engine, so the first seven commits of this branch are that PR's, up to its head
8798df4; please review only the six SY DRUM commits on top:fded9ed(shared code),341b779(the module),6dc3a5b(packages and records),6fb4adb(the evidence revision),2e6e69d(TESTING, documentation only) and71d9da9(my hardware report, the evidence revision pointed at341b779, the README and TESTING wording). The FM Synth branch is rebased onto Modwerk mainc181b76; SY DRUM's first five commits were made on main263aa1band replay onto the FM Synth head without a conflict. (6fb4adb's message names7a135ff, the measured source before an earlier rewrite of the branch; the module folder at341b779is byte-identical to it, and the record now names341b779.) Modwerk main at the time I opened this PR:4c0dda3(fetched 13 Oct 2026, 09:50 PDT). Sincec181b76it has changed documentation, the elekloader USB link (src/engine/elekloader/octatrack-link.ts,src/components/LoadDialog.tsxand their tests) and Tape Echo's preservation binding, none of them a file this branch touches; a trial merge of this branch into4c0dda3has no conflict.The pins. SY DRUM pins my
v2.14; FM Synth 0.1.5 stays on myv2.13(48b89e7).v2.14changes onlysy-drum/(and my top-level README), so FM Synth'ssynth/is the same bytes at both tags, and the FM Synth PR is unchanged by this one. FM Synth 0.1.5's change, my 2.13 scale quantizer on MIDI tracks, does not touch SY DRUM, a machine for audio tracks; in the test image FM Synth's engine and chooser objects are the same bytes as in the previous SY DRUM build.What it does
S,Y, 1 in unused NEIGHBOR PLAYBACK bytes, the FM Synth mechanism (F,M, 1).sylock01–sylock16.work/.strdfiles (my development builds' format, so a project moves between them and this module with its locks).What 2.14 changes: my hardware finding on the previous test image, and the fix
On the previous test image of this package (MAIN OS
d0dab5fe…, my octatrick 2.12 SY DRUM beside FM Synth 0.1.5) I found on my MKI that PLAYBACK SETUP step locks edited while the pattern played came back without those edits after a power-off with no SAVE PROJECT, in about half of my runs, while the stock PLAYBACK locks always came back; with SAVE PROJECT both came back. The cause: stock keeps the current bank, and so its own locks, in battery-backed memory and writes its working files only while the sequencer is stopped; SY DRUM's working filesylockNN.workwas written by that same stopped-only background save, so a power-off while playing, or within about a second of STOP, found it behind. A second cause gives the same symptom: when one stock bank file of the project is missing or unreadable at load, the SY DRUM files were not read at all.2.14 (
v2.14, SY DRUM only):0x4005224a), counts stock's 60-tick save cadence while a lock edit is unwritten and posts one job of the module's own (at most one write every 60 UI ticks, 1.2 s on the emulator; none while nothing is unwritten; the card write is an engine-task job like stock's own save);A lock edited less than about 1.2 s before a power-off can still come back without that edit; SAVE PROJECT closes that.
Measured on the test image of this PR (MAIN OS
27c213b2…) with my previous image (d0dab5fe…) as the control, on an emulator build that carries the battery-backed memory over a power-off and loads the project at power-on as the unit does (ot_emu07a7c08e…; everything else in this PR used the pinned9dc31d12…). A project with Flex samples and three SY DRUM tracks; four PLAYBACK locks and five PLAYBACK SETUP locks recorded in GRID RECORDING, no SAVE:And with
bank05.workof the project removed, cut short or damaged before that power-on (stock's own message, answered NO): this image loads every bank's step locks (ready mask0000ffff); the previous image loads none (00000000). Details: TESTING.md, "Power-off without SAVE".On my MKI I also ran the play-time write in my own octatrick build on 12 October (not a Modwerk image, without the bank-load change): the locks came back after a power-off while playing, and I heard no crackling on a STATIC track streaming from the card while the lock file was written. On 13 October the test sheet of my octatrick 2.14 build (MAIN OS
c367d8bc…) worked as well. Neither is a report of this image; the report under Hardware is.What 2.12 changes (against my 2.11 SY DRUM)
The dependency on FM Synth, and the six shared-code changes (for your decision)
My manifest says
requires=("SYNTH MACHINE",): SY DRUM's engine is called from FM Synth's engine paths (start, frame, render, the sample-free voice, the AMP envelope, keys, MIDI) and its row lives in FM Synth's machine list. Native octabam refuses SY DRUM without FM Synth. Octatrack modules in contract v2 have norequires, so each change below is the smallest I could find; each comes with the smallest alternative I see, so you can take it, change it or turn it down. The fallback for all six together is SY DRUM folded into the FM Synth package as an option of that module. The move to 2.14 changes none of them.src/catalog/selection-conflicts.ts: one rule,sy-drum-needs-synth("SY DRUM needs FM Synth", fix: remove SY DRUM), with a test.Smallest alternative: leave the rule out and let change 3 refuse the build; the configurator then explains the refusal only when the image is built, not while choosing.
scripts/build-module-packages.py:sy-drumjoinsREQUESTED. FM Synth's three units written per remix (poly,fmmachine, the bundled quantizerfm_qz; myHAVE_SYDRUMflag) are built for FM Synth alone as their ordinary objects, plus one variant each,whenModules: ["sy-drum"],withoutModules: ["poly8"], assembled with SY DRUM in the remix: the mechanism the POLY8 / sidechain variants already use. The requested packages carry, at their root, the nativerequiresof the modules that have one ("requires": {"sy-drum": ["SYNTH MACHINE"]}); no group or object of another module changes.Smallest alternative: keep the variants (FM Synth alone must stay byte-for-byte as it is) but drop the
requiresfield at the package root, and hard-code the one pair in change 3 instead.src/engine/requested-modules.ts: a selection holding a module whose native manifest requires a key that no selected module has is refused as a declaration collision ("SY DRUM requires SYNTH MACHINE"), the class native reports, somodule:verifysees matching refusals. Test inrequested-modules.test.ts.Smallest alternative: the same refusal as a hard-coded
sy-drum/synthpair (one line, no package field; see 2).src/engine/core-logger.ts/static-compose.ts: SY DRUM's card-file code hooks the stock engine-job dispatch at0x4008485e(its lock files must follow every load / save / reload / sync job, and since 2.14 it also runs its own play-time job there), the same 6 bytes the core logger'sjobhook takes. Native has no logger, so native builds; the browser refused with overlapping guards. The logger now leaves out a hook whose site a selected module owns and names it (yielded: ["job"]) in its configuration identity. For every selection that builds today nothing changes (a module writing inside a logger hook's span was refused with overlapping guards until now, so none does). A build with SY DRUM therefore logs no engine jobs. Test incore-logger.test.ts.Smallest alternative: none on Modwerk's side short of dropping the logger's
jobhook for everyone; on mine, I move SY DRUM's hook off that site in a later version of my source. Tell me which you prefer.src/engine/compose-os.ts:sy-drumjoins the loader-free list.Smallest alternative: none smaller; it is one list entry, as for every requested ColdFire module (Output Matrix was added the same way).
scripts/module-doctor.mjsandsrc/catalog/availability.test.ts: a module the selection rules refuse alone has no declaration record alone; the doctor says "refused alone by design" instead of failing, and the availability test builds SY DRUM beside FM Synth.Smallest alternative: leave the doctor unchanged and accept one red
declaration checksrow for SY DRUM (explained in TESTING.md); the availability test still needs its one companion entry, or SY DRUM listed as an exception there.Besides these six: the scope tests (
module-release-scope.test.mjs,module-source.test.mjs) and the licence inventory (SY DRUM's upstream LICENSE under the existingocta-panelcomponent) name the new module, and the catalogue and package assets are regenerated.One more item for your decision: Tape Echo's retained evidence. Tape Echo 0.1.3 keeps 0.1.2's evidence (since
fdabc28e), andscripts/retained-evidence.mjsrequires the build inputs it protects (src/enginewith its assets,scripts/build-module-packages.py,scripts/module-source.mjsand the SDK's platform, DSP and build tools) to stay as they were at its evidence commit32ac46b, unless a preservation binding covers the change. On current main that binding is the Tape Echo browser preservation record (sdk/browser-infrastructure-preservation/tapeecho-usb-integration.json, added in62cf7ab0, read throughscripts/browser-infrastructure-preservation.mjs): it lists by hash the protected files main itself has changed, and any other change to a protected input fails it. This branch changes four of those engine files (changes 3 to 5), the package builder (change 2) and the package assets (SY DRUM's units, with the firstmemoryRegionsentry incoldfire-packages.json: the 2 MiB lock table, the first module with a DRAM region). What ran, 13 October 2026: on this branch as pushed (FM Synth's head on mainc181b76),npm run modules:generateandnpm run modules:check -- --base origin/mainboth stop with "Invalid or stale Tape Echo browser preservation binding; full qualification is required"; on a local trial merge of this branch into current main4c0dda3(whose commit7d6d173erefreshed that binding),modules:generatestops with the same message. What it stops:modules:generate(sosrc/catalog/module-documents.json,compatibility-checks.jsonandpublic/module-media/are not regenerated in this PR, and the catalogue does not list SY DRUM yet),modules:check, and thereforenpm run check -- --base origin/mainafter its licence and machine checks, andnpm run module:doctor -- sy-drum, which does not find SY DRUM in the catalogue ("Unknown module: sy-drum"). FM Synth 0.1.5's PR stops at the same gate, so this is not SY DRUM's alone. I cannot clear it from my side: it needs your binding for these changes, as you did for VECTOR and for Tape Echo's USB work, or a fresh Tape Echo qualification. Amodules:generateafter that produces the catalogue files; I am glad to push that commit once the gate passes.A second item for your decision: main's Octatrack base.
src/engine/elekloader/octatrack-base.test.ts(new on main since this branch's packages were made) reports the committed Octatrack base stale, because the base recordssrc/engine/assets/chooser-metadata.jsonamong its inputs and this branch's packages add SY DRUM's row to it. The test's own fix isnpm run octatrack:base -- --write; I have not run it, since it rewrites the shared base package (octatrack-base.elemodand its fills) that you generate. Tell me if you want that commit in this PR.Conflicts and limits
octamod.module.jsonlists them.sylockNNcompanion files on save / reload / sync / save-to-new / export / delete — a file format of mine, which the module guide asks contributors not to invent, so this one needs your decision — and, since 2.14, a write of the working file while the sequencer plays (at most every 1.2 s while a lock edit is unwritten) and their load beside a missing stock bank file; the sequence edits that carry the companion locks; the trig LEDs.Qualification (emulator, exact image)
Image: MAIN OS
27c213b2dca96e071200d97441de821c900bf9f87556af0918da200ef623aed9, FM Synth 0.1.5-experimental + SY DRUM 0.1.0-experimental with all stock effects, built byscripts/export-composition-proofs.py --vendored-sdk --static-stock --modules synth,sy-drum --select synth+sy-drum:truefrom this branch (rebuilt from this branch's head after the restack onto the FM Synth PR: the same MAIN OS and the same update file). Update file1644e5fa…(OCTAMOD79). Pinnedot_emu9dc31d12…for everything but the power-off walks (07a7c08e…, above). Mytools/align_check.py(2.14) finds no instruction and no hook target at an odd address in it. Details:TESTING.md.maxInstancesis 2: 2 tracks peak at most 33,419, 33,791 with FM Synth's 372-instruction allowance, 84,213 of 95,779 cycles/block.sd_tickis 606 emulator instructions a frame with the module in the image and no SY DRUM track. The 2.14 hook is on the UI tick, outside the audio interrupt: 34 instructions a UI tick while playing, 2 while stopped (static count).d0dab5fe…): the peak blocks moved by s1 -16, s2 +14, s3 -154, s4 -14, s8 -344 instructions, inside the larger run-to-run spread (418; 208 here); the frame interrupt runs the same code on both images; maxConfiguration 84,178 -> 84,213, maxInstances 2 -> 2.Load, plainly
FM SYNTH and SY DRUM tracks are heavy on processor load, and track freezes with many instances of either are expected. SY DRUM runs on the ColdFire inside the audio interrupt. Two SY DRUM tracks take about 88 % of an audio block on the emulator (84,213 of 95,779 cycles, this record's maxConfiguration); the record qualifies two instances and not three. FM SYNTH tracks in the same project add their own load (one at VOIC 4 is about 85 % by itself). Beyond that the block overruns, and then the unit can stall or freeze. That is expected with many instances of SY DRUM or FM SYNTH; it is not a defect of a particular project. The figures are emulator cycle counts at the record's calibration, not hardware times; the Processor Load module (submitted separately) shows the headroom on the unit.
Hardware
I tested the exact image above (MAIN OS
27c213b2…, FM Synth 0.1.5-experimental + SY DRUM 0.1.0-experimental, the update file1644e5fa…) on my Octatrack, working through every item of its test sheet. The same facts are intests.qualification.hardware(hardwareStatusreported, my own report) and inTESTING.md:manifest.py'sproof_notestill says the hardware report is pending: that file is part of the native source fingerprint the measurements are bound to, so I left it as measured;README.md,TESTING.md,docs/VERIFICATION.mdand the record carry the report.History, not evidence for this image: the previous test image of this package (
d0dab5fe…) gave the finding above; the play-time write ran on my MKI in my own octatrick build (above); on 10 October 2026 I tested the 2.11 build of this package (b9b65cd9…) on my MKI and saw no issues other than the machine change not resetting a track's parameters, which 2.12 changes. Those builds are superseded and their reports are not carried over; the report above is for this image.Verification
verify.pypasses on the image (evidence/native-smoke.json): SY DRUM chosen on all eight tracks, the Part and battery-RAM shadow signatureS,Y, 1 and the seeds, sample slots untouched, reselection keeps an edit, FM SYNTH one row up still writesF,M, 1, FLEX clears it. A walk of both windows on a project card reads the same bytes back as on the previous image.sylock01.strd/.workbeside the stock files, a project load from the card brings the working locks, PROJECT > RELOAD the saved ones; audio after each step. (The previous record called that project load a cold boot; it is the menu's load. The power-on path is the power-off section above.)npm run module:verify -- sy-drumon the host toolchain (no Docker here; run on main263aa1b, before the restack): 126 selections, 4 builds matching outside the platform writes, 122 matching refusals, 0 mismatches. POLY8 is left out of that pool locally (the FM Synth PR's open POLY8 question). Analog BD's matrix re-verified before rebinding its source identity (162 native OS and bootloader comparisons, 50 matching refusals, 6 firmware round trips).media/capture.json), byte-identical to the previous image's: 2.14 changes no page.licenses:check,machines:check,elekloader:check,sdk:imports:check,typecheckandlint(0 errors; 7 warnings, all in files this branch does not touch) pass. SDK tests (python3 -m unittest discover -s sdk/tests, as insdk:check): 231 run, 7 skipped, one failure,test_measured_release_keeps_hardware_attribution_separate(FM Synth's POLY8 item, as on its branch alone);sdk/tests/test_sy_drum_import.pypasses.modules:check,modules:generateandmodule:doctor -- sy-drumstop as described under the Tape Echo item.npx vitest run: 2,249 of 2,286 pass. The 37 failures: 18 are the ones FM Synth 0.1.5's branch shows for the cataloguemodules:generatecould not regenerate (compiled versions and changelog against the old catalogue:module-build,compose-os,core-logger,sessionx4,build-supportx2,module-changelogs,downloaded-module-guide,src/tooling/check.test.tsx7); 8 more for the same reason with SY DRUM, which is not in that catalogue yet (selection-conflicts,requested-modules"SY DRUM on FM Synth" x2,availability,compatibility-checksx2,module-contract,resource-indicators); 4 are FM Synth's POLY8 item (requested-modulesx2,native-comparisons,synth-release); 2 are the gate itself (module-qualification"preserves tapeecho qualification",scripts/module-doctor.test.mjs); 4 arescripts/module-pages.test.mjs, which needspublic/module-media/(written only bymodules:generate; these also fail on main in the same environment); and 1 is the Octatrack base item above. In a throwaway clone of this head,npm run licenses:generate, the packages built from source (scripts/build-module-packages.py --include-requested, host toolchain) and their--developmentimport change no committed file, and--check-only --verify-existingpasses; Modwerk's exporter rebuilds MAIN OS27c213b2…and update file1644e5fa…. The native comparison (module:verify) was not rerun after the restack; since its run on263aa1bmain has changed nothing insdk/octabam/or the package builder.tools/stock_scan.py(2.14) finds no run of 16 or more stock bytes in any data file of the module folder; overupstream/assembled it finds the same 4 runs as my reviewed 2.14 scan ofsy-drum/(displaced-instruction replays and assembler idioms, at most 19 bytes); over every other file this branch changes, the runs added against the FM Synth head are all in the package assets and every one is among the reviewed runs of my 2.14 scan, the SY DRUM scan above and FM Synth's reviewed 2.13 scan.263aa1b, before the restack (a scratch copy with test values in both hardware fields and that one Tape Echo comparison switched off, two lines ofscripts/retained-evidence.mjs, never committed): the import--check-only --verify-existing,modules:generateandmodules:checkpassed;module:doctor -- sy-drumwas green except SY DRUM's performance row (no static per-frame bound, no MIDI flood);npm run check -- --base origin/mainpassed licenses:check, machines:check, modules:check, elekloader:check, licenses:generate, machines:generate, modules:generate, typecheck, build:bundle; 1,768 of 1,786 tests passed, the failures explained in TESTING.md.src/catalog/add-blocks.test.ts("flags every other module beside standalone MIDI Scenes and MIDI Scenes beside anything") fails with SY DRUM in the catalogue. The add-warning reads the selection rules, andsy-drum-needs-synthis a "needs" rule whose only fix removes SY DRUM itself: beside MIDI Scenes the warning finds no swap that keeps SY DRUM, and with FM Synth not selected the chip says "Conflicts with" and names no module. I have not changed the warning; the smallest fix I see is for it to treat a rule whose fixes all remove the candidate as "Needs FM Synth" (or for the rule to offer "Add FM Synth", theaddIdsfield I left out of change 1). Your call.Review scope
New module: the owner reviews the first release. Besides the module folder this changes the shared code listed above,
docs/VERIFICATION.md, the release notes and the regenerated assets. The two automatic-publication boxes are left unticked.Checklist
Ticked only where the facts above show it for this branch as it stands; the rest are open for the reasons under the Tape Echo item, Verification and the POLY8 note, or are your decisions.
Automatically merge and publish my module update after checks pass.
I verified the source, licences, UI and qualification reports, including instance isolation and Part/project/reboot persistence where applicable; no required acceptance check is failed or untested.
New or changed module: I read the guide for its category in
docs/module-guides/(andsequencing.mdif it acts in time), walked its checklists, and TESTING.md lists what I did not test.npm run module:doctor -- <id>is green.Every code change to a module has a greater semantic version and exact catalog pin (documentation and media edits need none).
Source and media are original or properly licensed; authors and full licence texts are preserved.
No Elektron firmware, extracted routines/tables, upgrade files or other infringing material is included.
Every new/changed module with OT UI has real screenshots of its location and relevant control pages, manifest
accessinstructions, andmedia[].otUiversion/build/setup provenance. Automatic USB modules without OT UI use the narrowaccess.noUiReasondeclaration for reviewer verification.I verified the captions, button/menu steps, screenshot authenticity and page coverage against the current module UI.
TESTING.md records commands, results, exact source, conditions and limitations; emulator and hardware evidence are separate.
CPU, DSP core and memory gauges are populated in
resources.impactwith rough load tiers, workload, rationale and source records. Reviewer: I checked the estimates; they do not imply exact hardware headroom percentages.Runtime/resource changes and new modules:
tests.qualificationcontains worst-case cycle counts for every processor used, under parameter extremes, simultaneous modulation, mode changes and maximum load, within the declared real-time budget.Runtime/resource changes and new modules: exact memory regions include code, state, tables, buffers, stack/heap, padding and shared allocations; words, word widths, bytes and maximum-instance totals agree with the native allocation/build report.
Runtime/resource changes and new modules: this version/source/build has attributed real-hardware test evidence verified by the reviewer (the owner for first releases; the registered author for scoped updates). Record tester, date, source/build identity, observed behavior, workload and limitations. A reported functional test must stay labelled as reported; unknown model, duration and maximum load must stay explicit.
Reviewer: for new modules and runtime/resource changes, I verified the actual cycle/memory reports, coverage of modulation and maximum load, and attributed hardware evidence and its actual coverage against the submitted source/build. A declaration or emulator-only result is insufficient.
Complete README/TESTING/licence/control/compatibility documentation, at least three practical tutorial steps and real black-and-white PNG screenshots document the current behavior with honest version/build provenance; README and the applicable qualification/retained-evidence documentation record are synchronized. Yellow captures do not qualify.
Reviewer: I verified tutorial usefulness, all relevant control/page coverage, screenshot authenticity, exact access instructions and full documentation completeness.
I rebased onto current main and ran module/version checks on this revision.
Credits
LICENSE, the original inupstream/LICENSE.How to test
npm ci, thennpm run check -- --base origin/mainandnpm run module:doctor -- sy-drum(until the Tape Echo gate is bound, the first stops atmodules:checkand the second does not find SY DRUM in the catalogue; see the Tape Echo item).npm run module:verify -- sy-drum --os <your OCTATRACK_OS1.40C.bin>(see the POLY8 note above).sylock01.strdbesidesylock01.workin the project folder.