Skip to content

CI: gate every PR on python-interop conformance#22

Open
torlando-tech wants to merge 1 commit into
mainfrom
feat/python-interop-ci-hook
Open

CI: gate every PR on python-interop conformance#22
torlando-tech wants to merge 1 commit into
mainfrom
feat/python-interop-ci-hook

Conversation

@torlando-tech

Copy link
Copy Markdown
Owner

Summary

Hook equivalent to reticulum-kt's :rns-test:test and reticulum-swift's Tests/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-interop job:

  1. Checks out THIS pyxis branch + reticulum-conformance + markqvist/Reticulum + markqvist/LXMF
  2. Builds microReticulumBridge with -DMICRORETICULUM_DIR=$(pwd)/pyxis/deps/microReticulum so the bridge is built against THIS branch's submodule
  3. Runs the same deselect set locked in reticulum-conformance/.github/workflows/microreticulum.yml so both CI surfaces stay in sync

Current baseline: 52 passing against pyxis main's submodule (fork feat/t-deck @ ca355e5).

Test plan

  • CI passes on first push (52 passed, 17 deselected)
  • Future submodule-pin changes will see this gate before merge

🤖 Generated with Claude Code

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-apps

greptile-apps Bot commented May 5, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a python-interop CI job that builds the microReticulum conformance bridge against the PR's own submodule pin and runs it against canonical Python RNS, closing the gap where submodule-pin bumps weren't validated against Python until after landing on main.

  • The three external repos (reticulum-conformance, markqvist/Reticulum, markqvist/LXMF) are checked out at their default-branch HEAD with no ref: pin, so the gate's behaviour shifts whenever those upstreams change — a new commit on Python RNS changes the byte-equivalence target without any change to pyxis.
  • The deselect list is a manual copy of reticulum-conformance/.github/workflows/microreticulum.yml's list; the two can drift silently, causing this gate to block all PRs if a new test is added upstream before the copy is updated.

Confidence Score: 3/5

Safe 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

Filename Overview
.github/workflows/test.yml Adds python-interop CI job running microReticulum conformance bridge against Python RNS; three external repos (reticulum-conformance, markqvist/Reticulum, markqvist/LXMF) are checked out without ref: pins, making gate results dependent on floating upstream HEAD states.

Sequence Diagram

sequenceDiagram
    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
Loading

Fix All in Claude Code

Prompt To Fix All With AI
Fix 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

Comment on lines +97 to +113
- 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

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.

P1 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.

Fix in Claude Code

Comment on lines +144 to +172
# 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

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.

P2 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.

Fix in Claude Code

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.

1 participant