CI: gate every PR on python-interop conformance#22
Conversation
Hook equivalent to reticulum-kt's :rns-test:test and reticulum-swift's Tests/Interop/. Each pyxis PR now runs the microReticulum conformance bridge against canonical Python RNS, so a submodule-pin bump or any change that breaks byte-equivalence with python is caught at PR time instead of only by the reticulum-conformance repo's own CI (which runs against pyxis main, not the PR branch). Mechanism: - Check out THIS pyxis branch + reticulum-conformance + markqvist/Reticulum + markqvist/LXMF - Build the microReticulumBridge with -DMICRORETICULUM_DIR pointing at this branch's deps/microReticulum - Run the same deselect set we lock in reticulum-conformance/.github/ workflows/microreticulum.yml so the two CI surfaces stay in sync Locked baseline: 52 passing against the pyxis fork submodule (feat/t-deck @ ca355e5). The conformance CI on the spike/graft branch will report a different number once the graft progresses — that's the intended signal.
Greptile SummaryThis PR adds a
Confidence Score: 3/5Safe to merge for short-term use, but the gate's reliability degrades over time due to floating upstream pins. One P1 (unpinned external checkouts make the gate non-deterministic) and one P2 (duplicated deselect-set drift). The P1 doesn't break anything immediately but undermines the gate's purpose — spurious failures or silent mismatches can occur whenever any of the three upstream repos advances. .github/workflows/test.yml — specifically the three external checkout steps and the pytest deselect block. Important Files Changed
Sequence DiagramsequenceDiagram
participant GH as GitHub Actions
participant Pyxis as pyxis (this PR branch)
participant RC as reticulum-conformance (HEAD)
participant MRK as markqvist/Reticulum (HEAD)
participant LXMF as markqvist/LXMF (HEAD)
GH->>Pyxis: checkout (path: pyxis, submodules: recursive)
GH->>RC: checkout (no ref pin ⚠️)
GH->>MRK: checkout (no ref pin ⚠️)
GH->>LXMF: checkout (no ref pin ⚠️)
GH->>GH: cmake configure bridge -DMICRORETICULUM_DIR=pyxis/deps/microReticulum
GH->>GH: cmake --build bridge
GH->>GH: pytest tests/ --impl microreticulum --ignore/--deselect (copied list ⚠️)
GH-->>GH: 52 tests expected to pass
Prompt To Fix All With AIFix the following 2 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 2
.github/workflows/test.yml:97-113
**Unpinned external repo checkouts make the gate non-deterministic**
`reticulum-conformance`, `markqvist/Reticulum`, and `markqvist/LXMF` are all checked out at their default-branch HEAD with no `ref:` pin. This means the set of tests that actually run (and the Python RNS semantics they test against) is determined by whatever those repos' main branches contain at job execution time, not by anything in this PR. A new commit on `markqvist/Reticulum` could shift the "canonical" byte-equivalence target mid-PR, producing spurious failures or silently masking regressions; a new test added to `reticulum-conformance` (not yet deselected here) could block all pyxis PRs until this workflow is updated manually.
### Issue 2 of 2
.github/workflows/test.yml:144-172
**Duplicated deselect-set will drift from the canonical source**
The comment says this list matches `reticulum-conformance/.github/workflows/microreticulum.yml`, but since it's a manual copy it can silently diverge. When `reticulum-conformance` adds or removes a deselect entry, this workflow must be updated separately. A newly-added test in `reticulum-conformance` that isn't yet deselected here will block all pyxis PRs; a removed deselect will mean this gate is stricter than the reference, making the two CI surfaces inconsistent.
Reviews (1): Last reviewed commit: "CI: gate every PR on python-interop conf..." | Re-trigger Greptile |
| - name: Checkout reticulum-conformance | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| repository: torlando-tech/reticulum-conformance | ||
| path: reticulum-conformance | ||
|
|
||
| - name: Checkout Reticulum (markqvist) | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| repository: markqvist/Reticulum | ||
| path: Reticulum | ||
|
|
||
| - name: Checkout LXMF (markqvist) | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| repository: markqvist/LXMF | ||
| path: LXMF |
There was a problem hiding this comment.
Unpinned external repo checkouts make the gate non-deterministic
reticulum-conformance, markqvist/Reticulum, and markqvist/LXMF are all checked out at their default-branch HEAD with no ref: pin. This means the set of tests that actually run (and the Python RNS semantics they test against) is determined by whatever those repos' main branches contain at job execution time, not by anything in this PR. A new commit on markqvist/Reticulum could shift the "canonical" byte-equivalence target mid-PR, producing spurious failures or silently masking regressions; a new test added to reticulum-conformance (not yet deselected here) could block all pyxis PRs until this workflow is updated manually.
Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/test.yml
Line: 97-113
Comment:
**Unpinned external repo checkouts make the gate non-deterministic**
`reticulum-conformance`, `markqvist/Reticulum`, and `markqvist/LXMF` are all checked out at their default-branch HEAD with no `ref:` pin. This means the set of tests that actually run (and the Python RNS semantics they test against) is determined by whatever those repos' main branches contain at job execution time, not by anything in this PR. A new commit on `markqvist/Reticulum` could shift the "canonical" byte-equivalence target mid-PR, producing spurious failures or silently masking regressions; a new test added to `reticulum-conformance` (not yet deselected here) could block all pyxis PRs until this workflow is updated manually.
How can I resolve this? If you propose a fix, please make it concise.| # Same deselect set as reticulum-conformance/.github/workflows/microreticulum.yml | ||
| pytest tests/ \ | ||
| --impl microreticulum \ | ||
| --ignore=tests/wire \ | ||
| --ignore=tests/behavioral \ | ||
| --ignore=tests/lxmf \ | ||
| --ignore=tests/test_lxmf.py \ | ||
| --ignore=tests/test_ratchet.py \ | ||
| --ignore=tests/test_ratchet_lifecycle.py \ | ||
| --ignore=tests/test_compression.py \ | ||
| --ignore=tests/test_channel.py \ | ||
| --deselect tests/test_crypto.py::test_hkdf_with_info \ | ||
| --deselect tests/test_crypto.py::test_aes_encrypt_decrypt \ | ||
| --deselect tests/test_identity.py::test_identity_encrypt_decrypt \ | ||
| --deselect tests/test_token.py::test_token_cross_decrypt \ | ||
| --deselect tests/test_announce.py::test_announce_pack_unpack \ | ||
| --deselect tests/test_announce.py::test_announce_verify \ | ||
| --deselect tests/test_link.py::test_link_encrypt_decrypt \ | ||
| --deselect tests/test_link.py::test_link_request_pack_unpack \ | ||
| --deselect tests/test_link.py::test_link_rtt_pack_unpack \ | ||
| --deselect tests/test_transport.py::test_path_request_pack_unpack \ | ||
| --deselect tests/test_transport.py::test_packet_hashlist_pack_unpack \ | ||
| --deselect tests/test_ifac.py::test_ifac_mask_packet \ | ||
| --deselect tests/test_transport.py::test_ifac_mask_packet \ | ||
| --deselect tests/test_transport.py::test_ifac_unmask_packet \ | ||
| --deselect tests/test_transport.py::test_ifac_cross_mask_unmask \ | ||
| --deselect tests/test_transport.py::test_ifac_wrong_key_rejected \ | ||
| --deselect tests/test_transport.py::test_ifac_mask_small_ifac_size \ | ||
| -v |
There was a problem hiding this comment.
Duplicated deselect-set will drift from the canonical source
The comment says this list matches reticulum-conformance/.github/workflows/microreticulum.yml, but since it's a manual copy it can silently diverge. When reticulum-conformance adds or removes a deselect entry, this workflow must be updated separately. A newly-added test in reticulum-conformance that isn't yet deselected here will block all pyxis PRs; a removed deselect will mean this gate is stricter than the reference, making the two CI surfaces inconsistent.
Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/test.yml
Line: 144-172
Comment:
**Duplicated deselect-set will drift from the canonical source**
The comment says this list matches `reticulum-conformance/.github/workflows/microreticulum.yml`, but since it's a manual copy it can silently diverge. When `reticulum-conformance` adds or removes a deselect entry, this workflow must be updated separately. A newly-added test in `reticulum-conformance` that isn't yet deselected here will block all pyxis PRs; a removed deselect will mean this gate is stricter than the reference, making the two CI surfaces inconsistent.
How can I resolve this? If you propose a fix, please make it concise.
Summary
Hook equivalent to reticulum-kt's
:rns-test:testand reticulum-swift'sTests/Interop/. Every pyxis PR now runs the microReticulum conformance bridge against canonical Python RNS — submodule-pin bumps or any pyxis change that breaks byte-equivalence with python is caught at PR time, not only by reticulum-conformance's own CI (which runs against pyxis main).Why
Without this, a PR that bumps
deps/microReticulum(or modifies any code that's exercised by the conformance bridge) only gets python-interop validation after it lands on main and the reticulum-conformance repo's CI fires. With this, the same 52-test baseline is enforced inline on every pyxis PR.What runs
The
python-interopjob:reticulum-conformance+markqvist/Reticulum+markqvist/LXMFmicroReticulumBridgewith-DMICRORETICULUM_DIR=$(pwd)/pyxis/deps/microReticulumso the bridge is built against THIS branch's submodulereticulum-conformance/.github/workflows/microreticulum.ymlso both CI surfaces stay in syncCurrent baseline: 52 passing against pyxis main's submodule (fork
feat/t-deck @ ca355e5).Test plan
🤖 Generated with Claude Code