Skip to content

fix(OMN-19056): derive the futility verdict instead of putting it on a wire the release refuses - #2758

Merged
jonahgabriel merged 3 commits into
devfrom
jonah/omn-19056-wire-emission-floor
Sep 21, 2026
Merged

jonahgabriel merged 3 commits into
devfrom
jonah/omn-19056-wire-emission-floor

Conversation

@jonahgabriel

@jonahgabriel jonahgabriel commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

A field that no released consumer can decode

OMN-19016 (#2755, squash 1d957613d, dev 0.4.175) added no_rung_can_satisfy as a pydantic field on ModelQualityGateResult. That model declares extra="forbid". The last released omnimarket is v0.4.166 and its copy of the model has no such field, so a deployed consumer at the release refuses the payload outright at its decode boundary:

no_rung_can_satisfy: Extra inputs are not permitted

The OMN-18868 wire-compatibility gate caught it on its first day, on #2751, in its own words:

WIRE_COMPAT_REFUSED: the last released consumer (v0.4.166, version 0.4.166)
cannot decode this tree's wire payloads.
  src/omnimarket/models/delegation/wire/model_quality_gate.py: the released
  consumer ModelQualityGateResult at v0.4.166 REFUSES the key
  'no_rung_can_satisfy': Extra inputs are not permitted

This is OMN-18852 one field later, and worse in one respect. published_at was None by default and could be excluded while unset, which bought a quiet window. This field defaults to False, False serialises, so it went on the wire on every dump from the moment it merged. There was no quiet window at all.

Blast radius, measured rather than asserted

The break is latent, not realised, and saying so precisely is the point of measuring it.

what was measured reading
dead-letter scan, 5 lab topics, 900 messages 0 occurrences of the key, 0 refusal strings
lab dev lane, 4 containers, 18:44Z omnimarket 0.4.172
same lane after the 18:47:53Z force-recreate omnimarket 0.4.175
whole-tree gate replay, 10 wire modules exactly 1 finding

Both sides of the lab now carry the field, so neither refuses it there, and a peer lane separately established that the 18:50Z delegation outage was a container health race rather than this break. What the field breaks is a consumer pinned at 0.4.166 or older, which is every consumer the next release reaches. So the urgency comes from what a release does, not from what is dead-lettering now.

One correction to the reported picture, since it changes where the gate is red: the gate script exists only on #2751, so the Wire Compatibility Gate check-run appears on that PR alone and on no other open head. It becomes fleet-wide the moment #2751 merges, which is an argument for landing this first.

Why the OMN-18852 mechanism is not the mechanism here

The OMN-18852 remedy is a serialisation predicate that omits a field while it is unset (model_delegate_skill_request.py:261). It does not transfer, and the gate says so in its own docstring: it grades the maximal shape a producer can emit, so a new optional field is a finding even when the producer excludes it while unset, and there is no waiver list. It reads the model's declared fields rather than a dump, so such a predicate is invisible to it by construction.

The gate is right on both counts. An excluded-while-unset field is refused the moment anything sets it, and setting this one is the entire reason it exists. Forcing the older pattern here would have produced a change that reads like a fix and leaves the break in place.

What lands instead

The value was never independent information. The producer computed it as a predicate over failure_reasons — is every reason refusing this response a SHAPE_REFUSED one — and failure_reasons is a plain tuple[str, ...] that v0.4.166 already declares, already accepts, and carries the prefix through untouched.

So the field is withdrawn and the verdict is derived by a property on the model (model_quality_gate.py). Both consumer read sites keep their attribute access unchanged — port_local_delegation_dispatch.py:1385 and :1511, handler_delegation_workflow.py:2841 — and a consumer too old to know either keeps the pre-OMN-19016 climb-always behaviour, exactly as the withdrawn field's own description promised.

A property, deliberately not a computed_field. A computed field would put the key back on the wire and be invisible to the gate, which reads declared fields and never computed ones. A re-break the gate cannot see is worse than the original defect, so the shape is pinned by a test rather than by a comment.

The model also tolerates the withdrawn key on input and drops it. That half is what unblocks step 2: a producer sitting on dev 0.4.175 exactly keeps working, and the next release becomes the consumer that accepts the key, so when step 2 re-adds it as a real emitted field the released consumer's own validator no longer raises and the gate passes. Withdrawing the field without this validator would leave step 2 blocked by the same gate forever.

OMN-19016 is not reverted

The all-not-any derivation invariant, the zeroed score, the SHAPE_REFUSED verdict, the TERMINATE decision and both read sites are unchanged. Only the serialisation moved. Its two behavioural modules stay green beside the new one, and this was checked rather than assumed.

A plain revert was considered and rejected: it would have thrown away a correct behavioural fix to solve a carriage problem, and the carriage problem has a remedy that costs nothing.

The gate's own whole-tree control, run off CI against this worktree over all ten wire modules, returns WIRE_COMPAT_REFUSED with the single finding quoted above before the change and WIRE_COMPAT_PASS after it.

The new module reproduces that refusal byte for byte against a replica of the released decode boundary. The replica's accepted key set is pinned from the released source rather than derived from the model under test, because a set computed from the model agrees with any change that model makes, including the one that caused the break. It carries both controls a replica needs: it refuses the key, and it accepts the same payload without it, so a replica that accepted everything could not read as a pass.

Its two constants are spelled as literals rather than imported, so the module still collects against the parent commit. The red is behavioural — the released consumer refuses a real emitted payload — not an import error proving only that a symbol is missing.

tests/unit/delegation plus the delegate-skill, call-effect, routing-projection and delegation-projection node suites: 1647 passed, 6 skipped. mypy --strict clean over 3326 source files.

Delegation through the deployed dev lane, for the record: run 78fb8a90-7a93-4d1e-9b9b-cfb63ccf82e1, correlation 74e4eae8-3a55-4bae-b25b-ffdc4e817cdd, status completed, one attempt, quality_score 1.000, escalation_count 0. Summarization subtask run 76c35447-88ab-4c75-a94f-e0bd2b5233ee, correlation 2eba5d94-ac21-4d31-8b94-5dea1458d5ca, status completed.

Not in this PR

Re-emitting the key as a real field once a tolerant release is deployed is step 2, filed as a child of OMN-19056 with the floor version named. It is deliberately not built here, because building it now would reintroduce exactly the defect this PR removes.

A note for the adjacent work, recorded because the gate does not cover it: this gate grades two validation error types only, extra-key and missing-key, and replays each field with one placeholder string. A new enum member on a wire-reachable field produces neither of those error types, so it passes the gate green and still breaks a released consumer at the same boundary. OMN-19004 is in that class.

Version

0.4.182, re-enumerated live across every open head at the moment of the resolution rather than reused from the first push.

The first push went out at 0.4.180. #2744 then merged, taking dev to 0.4.178, which conflicted this branch on the version line alone and is why no workflow ran on the first head — GitHub does not run pull-request checks on a branch it cannot merge. While that was being resolved a peer took 0.4.180 on #2757 and another took 0.4.181 on #2756, so the resolution moved to 0.4.182.

State at the resolution: dev 0.4.178, #2753 0.4.179, #2757 0.4.180, #2756 0.4.181, and every remaining open head below dev. The merge commit resolves pyproject.toml and uv.lock and touches nothing else; the delegation suites and the gate control were both re-run against the new base, 1647 passed, 6 skipped and WIRE_COMPAT_PASS.

Ticket: OMN-19056. Parent: OMN-19016. Caught by: OMN-18868.

Evidence-Ticket: OMN-19056
Evidence-Source: OCC#10724

…a wire the release refuses

OMN-19016 (#2755, squash 1d95761, dev 0.4.175) added no_rung_can_satisfy as a
pydantic FIELD on ModelQualityGateResult. That model declares extra="forbid",
the last released omnimarket is v0.4.166 and its copy of the model has no such
field, so a deployed consumer at the release refuses the payload at its decode
boundary: "no_rung_can_satisfy: Extra inputs are not permitted". The OMN-18868
wire-compatibility gate caught it on its first day.

This is OMN-18852 one field later, and worse in one respect. published_at was
None by default and could be excluded while unset, which bought a quiet window.
This field defaults to False, False serialises, so it went on the wire on every
dump from the moment it merged. There was no quiet window at all.

WHY THE OMN-18852 MECHANISM IS NOT THE MECHANISM HERE.

exclude_if (model_delegate_skill_request.py:261) does not answer this, and the
gate says so in its own words: it grades the MAXIMAL shape a producer can emit,
so a new optional field is a finding even when the producer excludes it while
unset, and it has no waiver list. It reads model_fields, not a dump, so an
exclude_if predicate is invisible to it by construction. It is right on both
counts: an excluded-while-unset field is refused the moment anything sets it,
and setting this one is the entire reason it exists.

WHAT LANDS INSTEAD, AND WHY NOTHING IS LOST.

The value was never independent information. The producer computed it as a
predicate over failure_reasons -- is every reason refusing this response a
SHAPE_REFUSED one -- and failure_reasons is a plain tuple[str, ...] that
v0.4.166 already declares, already accepts, and carries the prefix through
untouched. So the field is withdrawn and the verdict is derived by a property
on the model. Both consumer read sites keep their attribute access unchanged
(port_local_delegation_dispatch.py:1385 and :1511,
handler_delegation_workflow.py:2841), and a consumer too old to know either
keeps the pre-OMN-19016 climb-always behaviour, exactly as the withdrawn
field's own description promised.

A property, deliberately not a computed_field. A computed_field would put the
key back on the wire AND be invisible to the gate, which reads model_fields and
never model_computed_fields. A re-break the gate cannot see is worse than the
original defect, so the shape is pinned by a test rather than by a comment.

The model also TOLERATES the withdrawn key on input and drops it, which is the
half that unblocks step 2. A producer sitting on dev 0.4.175 exactly keeps
working, and the next release becomes the consumer that accepts the key -- so
when step 2 re-adds it as a real emitted field, the released consumer's own
model_validate no longer raises and the gate passes. Withdrawing the field
without this validator would leave step 2 blocked by the same gate forever.

OMN-19016 IS NOT REVERTED. The all-not-any derivation invariant, the zeroed
score, the SHAPE_REFUSED verdict, the TERMINATE decision and both read sites
are unchanged; only the serialisation moved. Its two behavioural modules stay
green beside the new one.

EVIDENCE, MEASURED.

The gate's own whole-tree control, run off CI against this worktree before the
fix, over all ten wire modules: WIRE_COMPAT_REFUSED with exactly one finding,
"the released consumer ModelQualityGateResult at v0.4.166 REFUSES the key
'no_rung_can_satisfy': Extra inputs are not permitted". After the fix the same
command returns WIRE_COMPAT_PASS.

The new module reproduces that refusal byte for byte against a replica of the
released decode boundary, pinned from git show v0.4.166 rather than derived
from the model under test, with both controls a replica needs: it refuses the
key, and it accepts the same payload without it. Its constants are spelled as
literals so the module still COLLECTS against the parent commit -- the red is
behavioural, not an ImportError proving only that a symbol is missing.

Blast radius is latent, not realised. The lab dev lane on .201 read 0.4.172
across four containers and was force-recreated to 0.4.175 at 18:47:53Z, so both
sides there now carry the field and neither refuses it. A scan of 900 messages
across five onex.dlq.omnibase-infra topics found zero occurrences of the key
and zero "Extra inputs are not permitted". The break bites a consumer pinned at
0.4.166 or older, which is every consumer the next release reaches.

1647 passed, 6 skipped across tests/unit/delegation and the delegate-skill,
call-effect, routing-compute and delegation-projection node suites. mypy
--strict clean over 3326 source files.

Step 2, re-emitting the key once a tolerant release is deployed, is a child
ticket of OMN-19056 with the floor version named. It is deliberately not built
here.
@jonahgabriel

Copy link
Copy Markdown
Contributor Author

Pre-PR proof: surface=105 receipt=$OMNI_HOME/.onex_state/prepr-proof/omn19056-105-20260921T193025Z/receipt.txt sha256=2c08cabcfe122effcd3f60c78d12b2db3e9daa4927ac9c475363bca573a0dae5 result=PASS

22 assertions, 0 failures, 1 negative control. Lease 19:24:56Z .. 20:54:56Z, executed 19:25Z .. 19:30Z, surface restored and released.

The surface is better than a replica for this change. The dogfood runtime runs omnimarket 0.4.155 with extra="forbid" and no such field — below the v0.4.166 release floor — so it is a genuine pre-field deployed consumer. The negative control was measured on that live process before the patch, so it cannot be an artifact of it:

A2  extra_forbidden: Extra inputs are not permitted
A3  the same payload WITHOUT the key decodes  (so A2 is about the key, not the payload)

The branch's module was then copied over site-packages in both runtime containers and both were restarted, so every assertion below describes a process that actually loaded it. Identical results in omninode-dogfood-runtime and omninode-dogfood-runtime-effects:

assertion evidence
B2 the patched consumer accepts the gated key decoded, key dropped — the same call that raised at A2
B3 the key is not emitted model_dump 20 keys, json 20 keys, key absent
B4 the derived verdict agrees with what the producer sent sent True, derived True
B6 OMN-19016 all-not-any survives one climbable reason beside a shape refusal still climbs
B7 a passing result is never unsatisfiable derived False
B8 not a computed field either computed_fields=[]
B9 the tolerated key is not re-emitted the consumer does not become a producer of the break it absorbed

Both containers were restored from in-container backups, re-verified by sha256 against the original 113d6acf…, the module's __pycache__ entries deleted, both restarted, and the restored shape independently re-read rather than assumed. Nine of nine dogfood containers healthy before, during and after. No image rebuilt, no deployment, no database written, no compose file changed.

Not proven, recorded rather than omitted. No in-container gate evaluation was run and it would have been wrong to claim one: the 0.4.155 tree carries a failure_disposition field that both v0.4.166 and dev have since dropped and that its own handler still assigns, so the branch's model is deliberately not a superset of that surface's. That is an artifact of proving two releases behind the tree, not a property of this change, and the decode boundary — where the defect actually lives — is what was exercised. No model-calling delegation ran here either; the ladder behaviour stays covered by OMN-19016's own two modules.

Receipt path deviation: written to durable local state rather than a .recovery-evidence path inside a canonical clone, which the workspace guard refuses. Same deviation and same reason as the routing-fix-2 receipt recorded at docs/tracking/ROLLING_WORK_LEDGER.md:3759.

dev advanced to 0.4.178 with #2744 while this branch was in review, so the
only conflict is the version line in pyproject.toml and uv.lock.

Resolved to 0.4.182, re-enumerated live across every open head at the moment
of the resolution rather than reused from the first push: dev holds 0.4.178,
#2753 holds 0.4.179, #2757 holds 0.4.180 and #2756 holds 0.4.181, so the
0.4.180 this branch pushed with had been taken by a peer in the interim.
@github-actions

Copy link
Copy Markdown

✅ Architectural Review — PASSED

Errors: 0
Warnings: 0

What this checks

Rule Description
ARCH-TOPIC-001 No hardcoded Kafka topic strings in handler code
ARCH-DI-001 No event_bus=None bypass
ARCH-DI-002 No direct Handler instantiation outside workflow_runner/adapters
ARCH-DI-003 No reinvented DI containers
ARCH-TOPIC-002 contract.yaml topics follow `onex.{cmd

No architectural violations found.

Static architectural lint — no model inference (OMN-14176).

@jonahgabriel
jonahgabriel enabled auto-merge (squash) September 21, 2026 19:40
onexbot-occ-writer Bot added a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 21, 2026
…nimarket#2758

The declared checks were executed for real in the OmniNode-ai/omnimarket checkout at the PR head by the product-repo OCC receipt runner, and the results written append-only into this companion. Producer-minted PENDING receipts are superseded by a net-new record; no existing receipt was edited.

Ticket: OMN-16859 (AC3b)
Onex-Workflow: OCC Receipt Runner
Onex-Run: https://github.com/OmniNode-ai/omnimarket/actions/runs/35646184269
@github-actions

Copy link
Copy Markdown

✅ Hostile Reviewer — PASSED

Blocking findings (critical/error): 0
Total findings: 16
Models succeeded: qwen3-review,qwen3-review-b


Gate semantics

Verdict Meaning Blocks merge?
passed >=2 models succeeded, no critical/error findings No
blocked CRITICAL or ERROR findings found Yes
degraded Fewer than 2 models succeeded (infra unavailable/timeout) Yes (OMN-15110)

Powered by omniintelligence.review_pairing.cli_review — node-based adversarial review via HandlerLlmCliSubprocess (OMN-8524)

dev advanced to 0.4.181 with #2756. The version line in pyproject.toml and
uv.lock is again the only conflict.

Held at 0.4.182, re-enumerated live: dev 0.4.181, #2757 0.4.180, #2753 0.4.179,
and every remaining open head below dev, so 0.4.182 is still the first free
slot and needed no move this time.
onexbot-occ-writer Bot pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 21, 2026
…2758

OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head 3d700b30bb8275d1fab6f70489408418b42c197b.
onexbot-occ-writer Bot added a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 21, 2026
…nimarket#2758

The declared checks were executed for real in the OmniNode-ai/omnimarket checkout at the PR head by the product-repo OCC receipt runner, and the results written append-only into this companion. Producer-minted PENDING receipts are superseded by a net-new record; no existing receipt was edited.

Ticket: OMN-16859 (AC3b)
Onex-Workflow: OCC Receipt Runner
Onex-Run: https://github.com/OmniNode-ai/omnimarket/actions/runs/35647387831
jonahgabriel pushed a commit to OmniNode-ai/onex_change_control that referenced this pull request Sep 21, 2026
…imarket#2758 (#10724)

* evidence(OMN-19056): author OCC companion for OmniNode-ai/omnimarket#2758

OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head 3d700b30bb8275d1fab6f70489408418b42c197b.

* evidence(OMN-19056): self-bind OCC#10724 + rebind contract_sha256

* evidence(OMN-16859): executed test_passes receipts for OmniNode-ai/omnimarket#2758

The declared checks were executed for real in the OmniNode-ai/omnimarket checkout at the PR head by the product-repo OCC receipt runner, and the results written append-only into this companion. Producer-minted PENDING receipts are superseded by a net-new record; no existing receipt was edited.

Ticket: OMN-16859 (AC3b)
Onex-Workflow: OCC Receipt Runner
Onex-Run: https://github.com/OmniNode-ai/omnimarket/actions/runs/35647387831

---------

Co-authored-by: omnimarket-bot <bot@omninode.ai>
Co-authored-by: onexbot-occ-writer[bot] <307849072+onexbot-occ-writer[bot]@users.noreply.github.com>
@jonahgabriel
jonahgabriel merged commit 0ba8ace into dev Sep 21, 2026
145 of 147 checks passed
@jonahgabriel
jonahgabriel deleted the jonah/omn-19056-wire-emission-floor branch September 21, 2026 20:13
@jonahgabriel

Copy link
Copy Markdown
Contributor Author

Pre-PR proof: surface=mac-scratch:omn19056 receipt=$OMNI_HOME/.onex_state/prepr-proof/OMN-19056-mac-scratch-omn19056-20260921T203844Z/receipt.txt sha256=d102ca9b1d4843a35b4a1e12a395636ed10cabb75d45f1ef3b512ff09237b30d result=PASS

Standing, stated first. This arm ran after this PR merged. It is not the proof that gated the merge; that was the .105 arm in the earlier comment. It exists because it answers a question the earlier arm could not.

The gap it closes. Every released-consumer check so far, here and in the OMN-18868 gate itself, resolved v0.4.166 from the git tag by materialising that tree with git archive. None read the published wheel. Had the artifact on the index ever diverged from its tag, the whole proof would have been about a tree nobody installs.

It had not diverged, and that is the finding:

published wheel   sha256 6f6ccbf3c7bfdf6b7f45ea3571dbc1076f0063730b1008dd1ed14e0984f589dd
git tag v0.4.166  sha256 6f6ccbf3c7bfdf6b7f45ea3571dbc1076f0063730b1008dd1ed14e0984f589dd

Method. Three processes, because two versions of one package cannot share an interpreter. omnimarket==0.4.166 installed from the index into a scratch environment, confirmed to be the published artifact rather than a checkout by the absence of direct_url.json. Two detached worktrees as producers, each emitting the maximal shape through its real model_dump_json(by_alias=True) path, with the populated set derived from the model rather than from the script.

arm producer result
PASS merged dev 0ba8acee9, 0.4.182 accepted, 0 extra-key errors, 20 keys emitted against the release's 20
REFUSED (negative control) dev head 1d957613d, 0.4.175 no_rung_can_satisfy: Extra inputs are not permitted, the only error type raised, 21 keys emitted

Same script, same maximal shape, same published wheel. Only the producer commit differs, which is what makes the pass mean something.

End to end through the real gate. The lab dev lane runs 0.4.175, so a delegation there would exercise the pre-fix code and prove nothing about this change. Recorded as a limitation rather than run and presented as evidence; it becomes a real test once the lab carries 0.4.182 or later. The gate evaluation was driven in the merged tree instead: the shape rule returns its SHAPE_REFUSED verdict, the handler uses the prefix imported from the wire model and no longer defines its own helper, the derived verdict reads True, the score is zeroed, the key is absent from both dump forms, and a climbable reason beside the shape refusal still climbs. Eight of eight.

Incidental finding, unrelated to this change and not fixed here. A full dependency resolution of the dev producer against the published index fails today: published omnibase-infra>=0.38.36 depends on omnibase-core==0.47.18 while omnimarket dev requires >=0.47.20, so installing dev omnimarket from the index is unsatisfiable. The producer environments here used --no-deps plus the two packages the wire model needs, which is sufficient for a wire-model exercise and is not a workaround for the skew. Whoever cuts the next omnimarket release will hit it.

Scratch environments and both detached worktrees are lane-named and removed. No container, cluster, database, image or deployment was touched.

@jonahgabriel

Copy link
Copy Markdown
Contributor Author

Pre-PR proof countersign: receipt sha256=2c08cabcfe122effcd3f60c78d12b2db3e9daa4927ac9c475363bca573a0dae5 actor=prepr-countersign verdict=COUNTERSIGNED-WITH-LIMITS

I recomputed the receipt digest and it matches the value quoted above and in the ledger RELEASE row. The receipt names a commit that is not the one that merged: two merges of dev landed after the proof and the merged head is a later commit. I did not take the author's word that this is harmless. I read the proven module at both commits and it is byte-identical, content digest a86ef28a990bb6d067a9c5756a9094be335dd30c84ee67016fa4a8079f1198ca, and the seventy files that differ between those two commits include no quality-gate path at all. The drift is therefore real but inert for the seam that was proven.

I also reproduced the central claim myself, on a different released version than the receipt used, in a scratch virtual environment holding the wheel the index serves today. That released model is declared to forbid extra keys, carries no such field, dumps exactly twenty keys, and refuses the gated key with an extra-forbidden error while the identical payload without the key decodes cleanly. Same variable, opposite outcomes, and it agrees with the receipt's own count.

One thing to fix rather than repeat: the receipt prints the patched digest truncated to sixteen characters. A truncated digest cannot be checked, and it only checked out here because I could recover the full value from the repository.

@jonahgabriel

Copy link
Copy Markdown
Contributor Author

Pre-PR proof countersign: receipt sha256=d102ca9b1d4843a35b4a1e12a395636ed10cabb75d45f1ef3b512ff09237b30d actor=prepr-countersign verdict=COUNTERSIGNED

I recomputed the receipt digest and it matches the value quoted above and the ledger RELEASE row. This arm closes a gap I had independently flagged when countersigning the earlier one, and it closes it the right way: every released-consumer check in the earlier arm and in the compatibility gate resolves the released version from the git tag, and none of them read the artifact the index actually serves. Showing that the published wheel and the tag are byte-identical is a negative finding, and it is worth as much as a positive one, because every other gate in the fleet assumes that equivalence without measuring it.

The negative control is correctly isolated. The same script, the same maximal emitted shape and the same published wheel are held fixed while only the producer commit changes, and the pre-fix commit is refused with an extra-forbidden error naming the field while the merged commit is accepted at exactly twenty keys.

I reproduced the consumer side myself, before reading this receipt, in a separate scratch environment holding the same wheel from the index. I measured the same three properties independently: extra keys forbidden, no such field declared, and exactly twenty fields. My reading agrees with this receipt on all three. The standing paragraph is also accurate, since this arm ran after the merge and says so first rather than presenting itself as the gate.

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