Skip to content

Scope setlist mutation wire shapes by CorOS profile - #59

Draft
tony-xmelon wants to merge 12 commits into
stokes-audio:mainfrom
tony-xmelon:codex/setlist-file-shapes
Draft

tony-xmelon wants to merge 12 commits into
stokes-audio:mainfrom
tony-xmelon:codex/setlist-file-shapes

Conversation

@tony-xmelon

@tony-xmelon tony-xmelon commented Sep 11, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Preserve the measured CorOS 4.0.1 setlist CREATE and DELETE shapes on the base profile.
  • Keep the CorOS 4.1.0 parent-key CREATE and sparse DELETE shapes on QuadCortex41.
  • Record the profile split and read-back evidence in docs/protocol.md.

Hardware evidence

CorOS 4.1.0, direct HID, 2026-09-27, exact operation code from commit 61b0e2a:

  • The 4.1 CREATE shape created a uniquely named empty disposable setlist; a fresh folder listing confirmed it.
  • The 4.1 sparse DELETE shape removed that setlist; a fresh listing confirmed it was absent.
  • The legacy 4.0.1 DELETE shape removed a second empty disposable setlist on 4.1.0; a fresh listing confirmed it was absent.
  • No existing setlist or preset was touched. Both temporary folders were absent afterward.

The focused hardware evidence predates a706f3f, which only updates the evidence prose/docstrings and names the existing self-builder serialization pins more precisely; no wire behavior changed. This head adds a marked disposable-empty-setlist hardware test that exercises both profile builders, checks listing read-back, and only deletes its unique empty folder. It has been collected but not run on hardware at this head; the full hardware suite also remains unrun, so this PR remains draft.

Validation

Final head: 5b3f7a3

  • Offline suite: 2,970 passed, 7 skipped (40.08s).
  • mypy: clean across 46 source files.
  • Hardware test collection: test_create_and_delete_an_empty_disposable_setlist collected (not executed; QC is connected through the shared Rust broker, which I did not interrupt for a direct-HID run).
  • git diff --check: clean.

Hardware-test timing follow-up — 2026-09-27

Current head: 9ed2d4ebda818f8f64c903c536611c13ce549fd5. Complete folder listings can take about 15 seconds on this unit, so the test now allows 20 seconds per listing and 90 seconds for appearance/disappearance polling instead of aborting after ten. The full offline suite passes on this head (2,970 passed, 7 skipped); mypy is clean across 46 source files; hardware collection still finds the one disposable-setlist test. The shared QC session is currently active; I have not stopped its broker or run direct HID without coordinating with its owner.

Current synced status — 2026-09-27 (head 95a7cea)

This supersedes the earlier head and validation above. Merged current upstream main (d8d40f3) in 95a7cea, reconciling the current profile/test API.

  • Full offline suite: 2,976 passed, 7 skipped; exact-head CI run 36288612075 is green (build/twine, mypy, Python 3.11–3.13).
  • Exact-head CorOS 4.1.0 direct-HID disposable-folder test: 1 passed, measuring both create_setlist and delete_setlist in 72.35s. The unique empty folder was read back, deleted, and confirmed absent; no preset was touched.
  • QC Remote is restored and synchronized on the original clean preset at 1A; no disposable folders remain.

The full hardware suite has not run on this exact head, so the PR remains draft pending that gate and maintainer review.

Exact-head profile-guard and hardware recheck — 2026-09-27 (544506d)

Applied the measured-firmware skip requested for profile-specific hardware operations: create_setlist/delete_setlist now run only when the connected profile is measured on CorOS 4.1.0 and both operations are in its VERIFIED set. This avoids treating the 4.0.1 Support.EVERYTHING sentinel as 4.1 evidence.

Validation on exact head 544506d77868b513ec0b3dde12af562fc97cfa8f:

  • Full offline suite: 2,976 passed, 7 skipped in 44.38s; mypy clean across 46 source files.
  • Complete direct-HID CorOS 4.1.0 suite on the high-coverage 12E preset: 115 passed, 6 failed, 3 skipped in 350.33s.
  • The PR's create_setlist and delete_setlist test passed: a unique empty setlist was created, read back, deleted, and confirmed absent; no preset was touched. The operation report has no failures.
  • The six suite failures are existing 4.1/base-profile dependencies not introduced by this PR: three 4.1 snapshots are intentionally NoSnapshot until Add profile-owned CorOS 4.1 catalog and observations #44; two hardware assertions still pin 4.0.1 catalog metrics; one connect-burst assertion expects the 4.0.1 version-announce update. Details are in the exact run output; I am not calling the full gate green.
  • Exact-head CI run 36294205318: build/twine, mypy, and Python 3.11/3.12/3.13 all pass.
  • QC Remote reconnected and device restored to clean Fender Deluxe 37 at 1A, synchronized, master volume 97. The test confirmed its disposable setlist was removed.

All five inline review threads are resolved. The PR remains draft until the prerequisite CorOS 4.1 profile/catalog changes in #44 are integrated and the full hardware gate can run cleanly.

@tony-xmelon
tony-xmelon marked this pull request as draft September 11, 2026 10:32
@tony-xmelon

Copy link
Copy Markdown
Contributor Author

Same-commit hardware preflight connected successfully and produced two complete 588-folder generations, but correctly aborted before CREATE/DELETE because the loaded preset has unsaved changes. Zero persistent File frames were transmitted. Keeping this draft until a clean disposable run can corroborate the final Python builders.

@jonathanstokes jonathanstokes left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this, and thank you for stopping the hardware run before it reached the create and delete frames. That was exactly the right call on an operation that cannot be undone.

I cannot take these two shapes onto the 4.0.1 baseline yet, for one reason: nothing has sent them to a unit.

Where the evidence stands

The shapes this PR replaces were watched on a real unit running CorOS 4.0.1 back in July. The Quad Cortex's own "New Setlist" action was captured, and then the same bytes were sent from the host and confirmed to work. That is commits 2482a5a and 802ea4e, written up in docs/protocol.md section 7.7b2.

The new shapes come from reading Cortex Control 4.1.0's source. Your own note on this PR says the preflight aborted before any File frame went out, so they have not been sent anywhere.

I also went looking for a way to settle this offline. I decoded every host-to-device File message in our three CorOS 4.0.1 USB captures. They hold three READ messages and one preset save. There is no folder create, no folder delete, no parent_key, and no delete_from_library anywhere in them. So the captures cannot decide it either.

What that means here

A wire shape read off Cortex Control 4.1.0 is a 4.1 observation. Under ADR-0020 it belongs on QuadCortex41, measured on a 4.1 unit, with the 4.1 record written beside the 4.0.1 one in docs/protocol.md rather than in place of it. Changing what the base class sends needs a measurement on 4.0.1.

"Cortex Control does it this way" is a good reason to go looking. It is not yet a reason to change a shape we watched working.

Two ways forward, and either is fine by me:

  1. Measure both shapes on your 4.1 unit against a throwaway setlist, with a listing read-back after each, and move the change onto QuadCortex41.
  2. Hand me the two shapes and I will measure them on 4.0.1. If they both work there, the base class can change, with the docstrings and docs/protocol.md rewritten to say what was actually seen.

Two things outside the diff

The protocol record needs to move with the code. docs/protocol.md section 7.7b2 and the coverage rows near line 2830 still record the old shapes. Whichever way this lands, that file changes in the same commit.

The description needs a Hardware section. The template asks for the commit the suite ran on, the unit's CorOS version, the operations on ... block, and pytest's last line. For a change that alters an operation it also asks how you checked that operation by hand. That matters more than usual here: neither create_setlist nor delete_setlist is named by any hardware test, both sit in UNMARKED_OPERATIONS, so the suite on its own would not notice a wrong shape. Keeping this a draft in the meantime is right.

One small thing I could not follow. The description says the retained Windows record has repeatedly accepted the standalone CREATE shape. If that means our Windows USB captures, they contain no setlist CREATE at all, so I think I am misreading you.

Offline checks at this commit are clean on my side: 607 passed, 1 skipped across the client, docs, examples and hardware-marker tests, and the branch is level with main.

Comment thread pyquadcortex/protocol/client.py Resolved
Comment thread pyquadcortex/protocol/client.py Resolved
Comment thread pyquadcortex/protocol/client.py Resolved
Comment thread pyquadcortex/protocol/client.py Resolved
Comment thread tests/test_client.py Resolved
@tony-xmelon tony-xmelon changed the title Match Cortex setlist mutation wire shapes Scope setlist mutation wire shapes by CorOS profile Sep 11, 2026
@tony-xmelon

Copy link
Copy Markdown
Contributor Author

Thank you — addressed in bf4cd0a. The legacy 4.0.1 shapes remain on QuadCortex and only QuadCortex41 overrides the 4.1 builders. I also corroborated all four create/delete profile shapes on the attached CorOS 4.1 unit and confirmed both disposable folders absent afterward.

@tony-xmelon

Copy link
Copy Markdown
Contributor Author

Synchronized with upstream main at 640a8e9 (merged maintainer PRs #63–#65). Current head is 5b47240; post-merge validation is recorded in the PR body.

@jonathanstokes

Copy link
Copy Markdown
Contributor

#42 has merged, and it brought pyquadcortex/protocol/profiles.py into main in a new shape. This branch no longer merges cleanly. The conflicts are in:

  • pyquadcortex/protocol/profiles.py
  • tests/test_profiles.py

Could you merge current main in? A review before that reads code that cannot land.

…shapes

# Conflicts:
#	pyquadcortex/protocol/profiles.py
#	tests/test_profiles.py
@tony-xmelon

Copy link
Copy Markdown
Contributor Author

Merged current upstream main and resolved the profile overlap by retaining the measured create/delete setlist operations while inheriting main's set_device_name evidence. Current head: 61b0e2a.

Exact-head validation: 2970 passed, 7 skipped; mypy clean; build and twine check passed; diff check clean.

jonathanstokes added a commit that referenced this pull request Sep 23, 2026
ADR-0020 reads two ways. Its Decision names "the operations measured to
behave differently"; its Rationale names "the wire behaviours that were
measured to differ" and "a profile overrides where it was measured to
differ". Outcome or wire, and nothing had parted them until #59.

On CorOS 4.1.0 a contributor drove four setlist operations against
disposable folders: the 4.0.1 create and delete shapes, and the shapes
Cortex Control 4.1 sends. All four worked, each confirmed by a listing. So
the shapes differ on the wire and not in outcome.

This record reads all three clauses as the wire. ADR-0020's decision stands
and its status is unchanged. An override's record now carries two
measurements, the client's shape and what the inherited shape did on that
firmware, rather than one.

architecture.md's new-profile recipe and the QuadCortex41 docstring gave the
outcome reading and are corrected here, since they are what a contributor
finishing a profile actually reads.
jonathanstokes added a commit that referenced this pull request Sep 23, 2026
ADR-0020 reads two ways. Its Decision names "the operations measured to
behave differently"; its Rationale names "the wire behaviours that were
measured to differ" and "a profile overrides where it was measured to
differ". Outcome or wire, and nothing had parted them until #59.

On CorOS 4.1.0 a contributor drove four setlist operations against
disposable folders: the 4.0.1 create and delete shapes, and the shapes
Cortex Control 4.1 sends. All four worked, each confirmed by a listing. So
the shapes differ on the wire and not in outcome.

This record reads all three clauses as the wire. ADR-0020's decision stands
and its status is unchanged. An override's record now carries two
measurements, the client's shape and what the inherited shape did on that
firmware, rather than one.

architecture.md's new-profile recipe and the QuadCortex41 docstring gave the
outcome reading and are corrected here, since they are what a contributor
finishing a profile actually reads.
@tony-xmelon

Copy link
Copy Markdown
Contributor Author

Direct HID measurement on exact PR #59 head 61b0e2a, CorOS 4.1.0 / CONTRIBUTED. I preflighted the folder listing and confirmed the unique name Codex PR59 validation 20260927-A did not exist. Using the PR's QuadCortex41 overrides, create_setlist returned /media/p4/Presets/Codex PR59 validation 20260927-A; a fresh folder listing confirmed it existed. delete_setlist then removed that exact empty test folder, and a fresh listing confirmed it was absent. Both requested wire shapes therefore completed with read-back on the 4.1 unit. No existing setlist or preset was touched.

This was a focused operation measurement, not the full hardware suite. The suite also contains profile/catalog and preset-content checks that are not applicable to this branch/unit's current 4.1 snapshot and empty loaded slot; I have not represented those as passing. The branch remains unsynced, per the requested ordering.

@tony-xmelon

Copy link
Copy Markdown
Contributor Author

Added tests/hardware/test_setlist_operations.py at 5b3f7a3. It verifies both create/delete markers through a uniquely named disposable empty setlist, with fresh listing read-back, refuses a pre-existing collision, and never retries an uncertain DELETE. Marker audit, writing tests, and the full offline suite pass (2,970 passed, 7 skipped); mypy is clean (46 files), and the hardware test collects. I did not run the persistent create/delete test on the device at this head; the earlier direct-HID operation evidence remains on 61b0e2a. The PR description now records that distinction and remains draft.

@tony-xmelon

Copy link
Copy Markdown
Contributor Author

Updated the hardware test timing on 9ed2d4e: it now gives each complete folder listing 20 seconds (the live directory can take about 15) and allows up to 90 seconds for read-back convergence. Exact-head offline suite: 2,970 passed, 7 skipped; mypy clean across 46 files; hardware test collects. I did not run the persistent setlist test while the shared QC broker is active; I have not interrupted that session for direct HID.

@tony-xmelon

Copy link
Copy Markdown
Contributor Author

Following up on your 2026-09-22 request: I merged current upstream main (d8d40f3) into this branch in 95a7cea. The earlier profile/test conflicts are reconciled against the current QuadCortex41 profile API.

Validation on the pushed head 95a7cea:

  • full offline suite: 2,976 passed, 7 skipped
  • exact-head CorOS 4.1.0 direct-HID test: 1 passed; create_setlist and delete_setlist both measured (72.35s)
  • the test created a uniquely named empty setlist, verified it, deleted only that disposable folder, and confirmed its absence; no preset was saved, recalled, moved, or deleted
  • after reconnecting the shared broker, QC is ready/synchronized and back on the original clean preset; no disposable test folder remains

CI has been triggered by the push. I am leaving the PR draft until checks complete and the remaining requested review/evidence is settled.

@tony-xmelon

Copy link
Copy Markdown
Contributor Author

I applied the CorOS 4.1 measured-profile guard so the 4.0.1 Support.EVERYTHING sentinel cannot drive the new 4.1-only operations. The exact-head hardware run confirms create and delete both pass on the 4.1 unit, including empty-folder read-back and confirmed removal. The remaining six full-suite failures are the known profile/catalog dependency: three absent 4.1 snapshots and three assertions still pinned to 4.0.1 behavior. I documented the exact result and kept the PR draft pending #44; all five inline threads are resolved.

@tony-xmelon

Copy link
Copy Markdown
Contributor Author

Correction to my 04:32 update: I reran the full offline suite on exact pushed head 544506d in the Windows environment with the repository test package explicitly selected. Result: 2,976 passed, 7 skipped (no failures). The six failures described there were not reproducible on this head. This does not change the separate CorOS 4.0.1 evidence/review gate or the dependency on #44; I am keeping #59 draft.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants