fix(myuplink): make the signed artifact agree that myuplink is read-only - #83
Merged
Conversation
Not ready to merge. Two blockers found while building it, both external to this diff -- recorded here so the work is not lost. What this does: myuplink declares read_only = true and auth_post_path = "/oauth/token" in its DRIVER table. The channel then publishes it read_only with control_enabled false, and the generated guard permits host.http_post only for a URL whose path ends in the declared path, refusing it everywhere else. So the flag enforces "this POST is authentication" rather than asserting it. A path rather than a URL because base_url is config-overridable. Blocker 1 -- FTW rejects it. go/internal/driverrepo/sourceful.go, validateSourcefulReadOnlyContract, allows a read-only package only http.get, modbus.read, mqtt.subscribe, serial.read and returns "read-only package requests write-capable permission" for anything else. Publishing this without an FTW change first makes every host refuse myuplink at install. Blocker 2 -- editing the Lua forfeits the FTW-baseline exemption. drivers/tests/conftest.py exempts a driver byte-identical to baselines/ftw and says so explicitly: it "stops being exempt the moment someone edits it". Adding two metadata fields costs the exemption and lights up 7 catalog-convention checks this driver was never written to meet -- among them "should use 'http://' scheme" and "reference config.port" for an HTTPS cloud API, and "should call host.emit()" when emitting only metrics is the driver's stated design. The catalog half is already shippable and separate: see the branch fix/myuplink-read-only-catalog (#64), which is green. Signed-off-by: HuggeK <[email protected]> Co-authored-by: HuggeK <[email protected]>
Signed-off-by: Fredrik Ahlgren <[email protected]>
Signed-off-by: Hugo Karlsson <[email protected]>
Conflicts: CHANGELOG (kept both sides' Unreleased entries), SUPPORT_STATUS rows (myuplink 1.2.0 from this branch, nibe_local 1.1.2 from main), and test_driver_contract.py where main's test_calls_emit_in_poll supersedes this branch's simpler emit-or-metric rule with the DER-gated version. Co-authored-by: HuggeK <[email protected]> Signed-off-by: Hugo Karlsson <[email protected]>
Signed-off-by: Fredrik Ahlgren <[email protected]>
This was referenced Aug 16, 2026
frahlg
added a commit
that referenced
this pull request
Aug 16, 2026
…#84) Branch protection requires a pull request to be up to date with main before it merges, and the merge commit GitHub's "Update branch" button writes carries no Signed-off-by trailer. The check counted it, so bringing a stale pull request up to date was the act that made it unmergeable. There was no way out from inside the rule. Fixing it means force-pushing a trailer onto a commit the contributor did not write, and for a pull request from a fork this repository cannot push to, nobody who can merge can also do that. It deadlocked #65 -- relanded as #83 to carry a one-line trailer -- and a0d5d73 on that same branch before it. A sign-off certifies authored content. A merge commit from the update button carries none, so git rev-list gains --no-merges and the check asks for the trailer on the commits that do, the same line the upstream DCO app draws. A conflict resolved inside a merge commit becomes content the check no longer sees; the reviewable content still arrives on the authored commits either side. The failure message now also names the two commands that fix a genuine miss. Verified against the range that failed on #65 (4fb8608..01da267): it fails under the old rule and passes under the new one, while an authored commit with no trailer still fails. Signed-off-by: Fredrik Ahlgren <[email protected]>
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.
Carries #65 (@HuggeK) verbatim — same five commits, same authorship, same
tree. The only difference is a
Signed-off-bytrailer on the merge commit thatGitHub's "Update branch" button created without one, which failed the required
dcocheck on #65. That branch lives on a fork this session cannot push to, sothe fix is carried here instead. Credit for the change is HuggeK's; please close
#65 in favour of this.
Summary
myuplinkdeclaresread_only = trueandauth_post_path = "/oauth/token"inits
DRIVERtable. The signed channel infers control from the mere presence ofa
driver_commandentrypoint, so a driver whose entrypoint refuses everycommand was still published
control_enabled: true,read_only: false, with awrite permission. It now publishes read-only.
The read-only guard would otherwise deny
host.http_post, which this driverneeds to exchange its refresh token before it can read anything. The generated
guard confines that POST to the declared path rather than trusting it, so the
flag enforces "this POST is authentication" instead of asserting it. A path
rather than a URL, because
base_urlis config-overridable.The catalog-convention checks that lit up when this driver lost its
baselines/ftwbyte-identity exemption are already handled onmain: theconnectivity-aware test split stops holding cloud drivers to the local
config.host/config.port/http://rules, and the driver contract acceptshost.emit_metricfor metrics-only drivers.Driver evidence
myuplinkupstream_docsin the manifestnot_assessedfor both targets. This is a read-only labelling and artifactcorrection, not a hardware claim.
driver_commandstill refusesevery command it is handed.
Safety
The one write-capable permission this driver retains (
http.post) is scoped bythe generated guard to the declared auth path.
test_signing_in_is_declared_or_it_does_not_happenfails if any driver otherthan
myuplinkloses the blanket denial, and asserts every other read-onlydriver has neither
auth_post_pathnorhttp.post.Package or promotion evidence
6074b70eb2bbe49481fcc59551d65474cb8129ae5370e9c1844c23b08a5f6fd6myuplink1.1.1 → 1.2.0 (the Lua bytes moved;the
DRIVERblock's stale1.0.0version line is also corrected to match themanifest)
ftw-core,blixt-l1— bothnot_assessed, unchangedsigned channel accepts this treeconfirms the bump covers the changed bytesrequired: not applicable — no control pathfalseapplicable; this removes a control claim rather than adding one.
Checks
Signed-off-by. — all five verifiedmake check— 3616 passed, 1333 skipped, on this exact treeChannel note
A push to
mainpublishes to the beta driver channel only(
.github/workflows/ftw-drivers-release.yml); promotion todrivers-stablestays a manual
workflow_dispatch. Sites on the stable driver channel areunaffected, which is what makes this safe to land while ftw 1.16.x (carrying
RuntimePolicy.AuthPostPath) is still beta-only.Generated by Claude Code