Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Owner delta review of draft PR 535 at head `7c0df369`, lock `83293867247323c4...`

Review of draft PR #535 at the immutable head `7c0df369f6aaeb263fc25576dbedfbfada74b6ab` (13 commits on main `8fc86119`, the merge of #546), lane `lane:shared`: the OpenHands SDK 1.50.0 lock
`blueprints/runtime-workers/openhands/requirements.lock` with sha256 `83293867247323c4d8fc463096e8a9c01dbee2ada5898112bbbb7d1a62a8b47a`, Linux x86_64, CPython 3.13.15, relocked onto urllib3 2.8.0 and PyJWT 2.15.0. It is a **delta review**
of the lock reviewed in [`evidence/artifacts/openhands-oauthlib-review-535-head6a7b16-20260930/`](../openhands-oauthlib-review-535-head6a7b16-20260930/receipt.json) (lock `383ccc5b`, historical): the two locks differ in exactly two entries, which
the record shows by an independent prediction, by the package closure and by the line-level difference. Claims D1-D11, findings and residuals: `receipt.json`. This is a **scoped
statement for that exact head and lock**; it approves no merge, exception, pin, image, trusted observer or task quality.

Verdict: no blocking finding for the OAuthlib reachability scope. Two P2 findings (a stale workflow binding in the requested receipt, and the category of four excluded compile-input
captures) are in `receipt.json` and need no change to the lock.

| Files | What they are |
| --- | --- |
| `checks/pr535-identity.txt`, `checks/prediction.txt` | head, base, lock hashes, pins, the exact-lock row, the `.github` differences, the independent prediction of the lock |
| `checks/closure-diff-vs-reviewed-383ccc.txt`, `checks/closure-diff-vs-main.txt` | the package closure and the changed lines against the previously reviewed lock and against the lock on main |
| `checks/install-log.txt`, `checks/independent-scan.txt`, `checks/pyjwt-surface.txt`, `checks/pin-sources.txt` | the reproduced hashed installs, the OAuthlib sweep, the PyJWT importers and JWKS client callers, the four advisory files' hashes |
| `checks/osv-exit-codes-and-findings.txt`, `checks/osv-*.json` | OSV-Scanner 2.6.0 (the CI pin): ordinary config exit 0, the empty-config control, the previously reviewed lock (advisory `details` prose removed from the JSON) |
| `checks/osv-split-controls.txt`, `checks/osv-two-new-locks.txt`, `checks/excluded-compile-input-captures.txt` | the workflow's own scan step at the head, the native controls, the two new runtime-worker locks, the four excluded captures |
| `checks/receipt-bindings.txt`, `checks/external-hashes.txt`, `checks/repo-checks-at-head.txt` | the receipt's 62 artifact and 53 command bindings, hashes recomputed from PyPI and codeload, the repository's own checks at the head |
| `checks/commands-as-typed.txt` | how the outputs were produced |
| `scripts/` | the scripts as run (`.txt` copies); `run_delta_outputs.sh.txt` regenerates every output |

Host paths are masks (`<REVIEW-SCRATCH>`, `<REPO>`, `<OSV-BIN>`, `<HOME>`); colour codes are removed; nothing else in an output is edited.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
observed_utc=2026-09-30T19:28:31Z
== candidate versus the lock on main after #546 (1d11bae3): package closure
old: 335 packages, new: 176; added 0, removed 159, changed 2
ADDED: -
REMOVED: pyobjc==11.1, pyobjc-core==11.1, pyobjc-framework-accessibility==11.1, pyobjc-framework-accounts==11.1, pyobjc-framework-addressbook==11.1, pyobjc-framework-adservices==11.1, pyobjc-framework-adsupport==11.1, pyobjc-framework-applescriptkit==11.1, pyobjc-framework-applescriptobjc==11.1, pyobjc-framework-applicationservices==11.1, pyobjc-framework-apptrackingtransparency==11.1, pyobjc-framework-audiovideobridging==11.1, pyobjc-framework-authenticationservices==11.1, pyobjc-framework-automaticassessmentconfiguration==11.1, pyobjc-framework-automator==11.1, pyobjc-framework-avfoundation==11.1, pyobjc-framework-avkit==11.1, pyobjc-framework-avrouting==11.1, pyobjc-framework-backgroundassets==11.1, pyobjc-framework-browserenginekit==11.1, pyobjc-framework-businesschat==11.1, pyobjc-framework-calendarstore==11.1, pyobjc-framework-callkit==11.1, pyobjc-framework-carbon==11.1, pyobjc-framework-cfnetwork==11.1, pyobjc-framework-cinematic==11.1, pyobjc-framework-classkit==11.1, pyobjc-framework-cloudkit==11.1, pyobjc-framework-cocoa==11.1, pyobjc-framework-collaboration==11.1, pyobjc-framework-colorsync==11.1, pyobjc-framework-contacts==11.1, pyobjc-framework-contactsui==11.1, pyobjc-framework-coreaudio==11.1, pyobjc-framework-coreaudiokit==11.1, pyobjc-framework-corebluetooth==11.1, pyobjc-framework-coredata==11.1, pyobjc-framework-corehaptics==11.1, pyobjc-framework-corelocation==11.1, pyobjc-framework-coremedia==11.1, pyobjc-framework-coremediaio==11.1, pyobjc-framework-coremidi==11.1, pyobjc-framework-coreml==11.1, pyobjc-framework-coremotion==11.1, pyobjc-framework-coreservices==11.1, pyobjc-framework-corespotlight==11.1, pyobjc-framework-coretext==11.1, pyobjc-framework-corewlan==11.1, pyobjc-framework-cryptotokenkit==11.1, pyobjc-framework-datadetection==11.1, pyobjc-framework-devicecheck==11.1, pyobjc-framework-devicediscoveryextension==11.1, pyobjc-framework-dictionaryservices==11.1, pyobjc-framework-discrecording==11.1, pyobjc-framework-discrecordingui==11.1, pyobjc-framework-diskarbitration==11.1, pyobjc-framework-dvdplayback==11.1, pyobjc-framework-eventkit==11.1, pyobjc-framework-exceptionhandling==11.1, pyobjc-framework-executionpolicy==11.1, pyobjc-framework-extensionkit==11.1, pyobjc-framework-externalaccessory==11.1, pyobjc-framework-fileprovider==11.1, pyobjc-framework-fileproviderui==11.1, pyobjc-framework-findersync==11.1, pyobjc-framework-fsevents==11.1, pyobjc-framework-fskit==11.1, pyobjc-framework-gamecenter==11.1, pyobjc-framework-gamecontroller==11.1, pyobjc-framework-gamekit==11.1, pyobjc-framework-gameplaykit==11.1, pyobjc-framework-healthkit==11.1, pyobjc-framework-imagecapturecore==11.1, pyobjc-framework-inputmethodkit==11.1, pyobjc-framework-installerplugins==11.1, pyobjc-framework-instantmessage==11.1, pyobjc-framework-intents==11.1, pyobjc-framework-intentsui==11.1, pyobjc-framework-iobluetooth==11.1, pyobjc-framework-iobluetoothui==11.1, pyobjc-framework-iosurface==11.1, pyobjc-framework-ituneslibrary==11.1, pyobjc-framework-kernelmanagement==11.1, pyobjc-framework-latentsemanticmapping==11.1, pyobjc-framework-launchservices==11.1, pyobjc-framework-libdispatch==11.1, pyobjc-framework-libxpc==11.1, pyobjc-framework-linkpresentation==11.1, pyobjc-framework-localauthentication==11.1, pyobjc-framework-localauthenticationembeddedui==11.1, pyobjc-framework-mailkit==11.1, pyobjc-framework-mapkit==11.1, pyobjc-framework-mediaaccessibility==11.1, pyobjc-framework-mediaextension==11.1, pyobjc-framework-medialibrary==11.1, pyobjc-framework-mediaplayer==11.1, pyobjc-framework-mediatoolbox==11.1, pyobjc-framework-metal==11.1, pyobjc-framework-metalfx==11.1, pyobjc-framework-metalkit==11.1, pyobjc-framework-metalperformanceshaders==11.1, pyobjc-framework-metalperformanceshadersgraph==11.1, pyobjc-framework-metrickit==11.1, pyobjc-framework-mlcompute==11.1, pyobjc-framework-modelio==11.1, pyobjc-framework-multipeerconnectivity==11.1, pyobjc-framework-naturallanguage==11.1, pyobjc-framework-netfs==11.1, pyobjc-framework-network==11.1, pyobjc-framework-networkextension==11.1, pyobjc-framework-notificationcenter==11.1, pyobjc-framework-opendirectory==11.1, pyobjc-framework-osakit==11.1, pyobjc-framework-oslog==11.1, pyobjc-framework-passkit==11.1, pyobjc-framework-pencilkit==11.1, pyobjc-framework-phase==11.1, pyobjc-framework-photos==11.1, pyobjc-framework-photosui==11.1, pyobjc-framework-preferencepanes==11.1, pyobjc-framework-pushkit==11.1, pyobjc-framework-quartz==11.1, pyobjc-framework-quicklookthumbnailing==11.1, pyobjc-framework-replaykit==11.1, pyobjc-framework-safariservices==11.1, pyobjc-framework-safetykit==11.1, pyobjc-framework-scenekit==11.1, pyobjc-framework-screencapturekit==11.1, pyobjc-framework-screensaver==11.1, pyobjc-framework-screentime==11.1, pyobjc-framework-scriptingbridge==11.1, pyobjc-framework-searchkit==11.1, pyobjc-framework-security==11.1, pyobjc-framework-securityfoundation==11.1, pyobjc-framework-securityinterface==11.1, pyobjc-framework-securityui==11.1, pyobjc-framework-sensitivecontentanalysis==11.1, pyobjc-framework-servicemanagement==11.1, pyobjc-framework-sharedwithyou==11.1, pyobjc-framework-sharedwithyoucore==11.1, pyobjc-framework-shazamkit==11.1, pyobjc-framework-social==11.1, pyobjc-framework-soundanalysis==11.1, pyobjc-framework-speech==11.1, pyobjc-framework-spritekit==11.1, pyobjc-framework-storekit==11.1, pyobjc-framework-symbols==11.1, pyobjc-framework-syncservices==11.1, pyobjc-framework-systemconfiguration==11.1, pyobjc-framework-systemextensions==11.1, pyobjc-framework-threadnetwork==11.1, pyobjc-framework-uniformtypeidentifiers==11.1, pyobjc-framework-usernotifications==11.1, pyobjc-framework-usernotificationsui==11.1, pyobjc-framework-videosubscriberaccount==11.1, pyobjc-framework-videotoolbox==11.1, pyobjc-framework-virtualization==11.1, pyobjc-framework-vision==11.1, pyobjc-framework-webkit==11.1
CHANGED: openhands-sdk @openhands_sdk-1.49.6-py3-none-any.whl -> @openhands_sdk-1.50.0-py3-none-any.whl, openhands-tools @openhands_tools-1.49.6-py3-none-any.whl -> @openhands_tools-1.50.0-py3-none-any.whl
oauthlib: old 3.3.1, new 3.3.1
pyjwt: old 2.15.0, new 2.15.0
requests-oauthlib: old 2.0.0, new 2.0.0
google-auth-oauthlib: old 1.2.2, new 1.2.2
authlib: old 1.6.12, new 1.6.12
mcp: old 1.28.1, new 1.28.1
litellm: old 1.93.0, new 1.93.0
google-auth: old 2.53.0, new 2.53.0
openhands-sdk: old @openhands_sdk-1.49.6-py3-none-any.whl, new @openhands_sdk-1.50.0-py3-none-any.whl
openhands-tools: old @openhands_tools-1.49.6-py3-none-any.whl, new @openhands_tools-1.50.0-py3-none-any.whl
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
observed_utc=2026-09-30T19:28:31Z
== candidate versus the previously reviewed lock (383ccc5b, #537's subject): package closure
old: 176 packages, new: 176; added 0, removed 0, changed 2
ADDED: -
REMOVED: -
CHANGED: pyjwt 2.14.0 -> 2.15.0, urllib3 2.7.0 -> 2.8.0
oauthlib: old 3.3.1, new 3.3.1
pyjwt: old 2.14.0, new 2.15.0
requests-oauthlib: old 2.0.0, new 2.0.0
google-auth-oauthlib: old 1.2.2, new 1.2.2
authlib: old 1.6.12, new 1.6.12
mcp: old 1.28.1, new 1.28.1
litellm: old 1.93.0, new 1.93.0
google-auth: old 2.53.0, new 2.53.0
openhands-sdk: old @openhands_sdk-1.50.0-py3-none-any.whl, new @openhands_sdk-1.50.0-py3-none-any.whl
openhands-tools: old @openhands_tools-1.50.0-py3-none-any.whl, new @openhands_tools-1.50.0-py3-none-any.whl

== the same two locks, line level (hashes abbreviated to 8 hex): every changed line
< pyjwt==2.14.0 \
< --hash=sha256:77283c83... \
< --hash=sha256:ad0cef71...
> pyjwt==2.15.0 \
> --hash=sha256:7a3742de... \
> --hash=sha256:b11c5f97...
< urllib3==2.7.0 \
< --hash=sha256:231e0ec3... \
< --hash=sha256:9fb4c81e...
> urllib3==2.8.0 \
> --hash=sha256:0cf3cae5... \
> --hash=sha256:63bf2ead...
(line counts: reviewed 3054, candidate 3054)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Every output of this record was produced by one run of scripts/run_delta_outputs.sh (run_delta_outputs.sh.txt here), started as
bash run_delta_outputs.sh
after `git fetch origin '+pull/535/head:refs/remotes/origin/pr535'` had printed the head 7c0df369f6aaeb263fc25576dbedfbfada74b6ab; the script refuses to run on any other head. The run
began about 19:28Z on 2026-09-30 and ended at the time printed by its last line:
[2026-09-30T19:29:37Z] outputs regenerated in <REVIEW-SCRATCH>/out2
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
observed_utc=2026-09-30T19:28:59Z
== the four compile-input captures the PR lists under 'excluded', and what the pinned scanner reports about each as a requirements file (empty config)
pyjwt-relock-20260930-constraints.txt: 334 pinned lines, sha256 9be46e2d3628a47e
scan exit 1 | pyjwt-relock-20260930-constraints.txt.raw -> {"oauthlib==3.3.1": ["GHSA-hj66-6f7g-4r5v", "GHSA-xpv3-w29h-x7cv"]}
urllib3-relock-20260930-constraints.txt: 334 pinned lines, sha256 935e34547853b50e
scan exit 1 | urllib3-relock-20260930-constraints.txt.raw -> {"oauthlib==3.3.1": ["GHSA-hj66-6f7g-4r5v", "GHSA-xpv3-w29h-x7cv"], "pyjwt==2.14.0": ["GHSA-42vr-xj54-vc7v"]}
main-reconcile-20260930-constraints.txt: 334 pinned lines, sha256 b4e06f725855214b
scan exit 1 | main-reconcile-20260930-constraints.txt.raw -> {"oauthlib==3.3.1": ["GHSA-hj66-6f7g-4r5v", "GHSA-xpv3-w29h-x7cv"], "pyjwt==2.14.0": ["GHSA-42vr-xj54-vc7v"], "urllib3==2.7.0": ["GHSA-8988-9cw3-xx77", "GHSA-gh4c-6fx4-qh6g", "GHSA-vxq7-64xx-v4gw"]}
wheel-relock-20260930-constraints.txt: 334 pinned lines, sha256 bfdcbb60d2ed1819
scan exit 1 | wheel-relock-20260930-constraints.txt.raw -> {"oauthlib==3.3.1": ["GHSA-hj66-6f7g-4r5v", "GHSA-xpv3-w29h-x7cv"], "urllib3==2.7.0": ["GHSA-8988-9cw3-xx77", "GHSA-gh4c-6fx4-qh6g", "GHSA-vxq7-64xx-v4gw"]}
== references to these files outside evidence directories, receipts, manifests and the inventory (git grep at the head):
(end of matches)
== the inventory description's rule for the excluded list:
An excluded entry is a tracked lockfile deliberately left out of the scan; it needs a reason and an evidence path, and only a deliberately vulnerable test fixture qualifies. A lockfile entry
== the four entries' reasons (first 330 characters each):
pyjwt-relock-20260930-constraints.txt | Frozen native compile-input reproducibility fixture for the PyJWT 2.15.0 relock, retaining original bytes, command and target-specific selection in its receipt. It includes unused platform branches and is not an installable runtime closure. No recipe installer consumes it. The selected Linux x86_64/CPython 3.13.15 closure remain
urllib3-relock-20260930-constraints.txt | Frozen native compile-input reproducibility fixture for the intermediate urllib3 2.8.0 relock, retaining original bytes, command and target-specific selection in its receipt. It includes unused platform branches and is not an installable runtime closure. No recipe installer consumes it. The selected Linux x86_64/CPython 3.13.15
main-reconcile-20260930-constraints.txt | Frozen native compile-input reproducibility fixture copied from the reviewed main lock, with original bytes, baseline SHA, command and target-specific selection retained in the reconciliation receipt. It includes unused platform branches and is not an installable runtime closure. No recipe installer consumes this captured eviden
wheel-relock-20260930-constraints.txt | Frozen native compile-input reproducibility fixture, retained with its original hash and command in the relock receipt. It constrains the qualification resolver and includes unused Windows/macOS branches from the prior multi-platform export; it is not an installable runtime closure. No recipe installer consumes this captured evi
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
observed_utc=2026-09-30T19:29:02Z
receipt binds .github/workflows/security-scan.yml: sha256 88a47e2cf7c16078331a4052c08bf88bc10ed9c70c167d863cd8e581c1a0ef14, 9268 bytes
at the pre-merge base 11227bfd: sha256 88a47e2cf7c16078331a4052c08bf88bc10ed9c70c167d863cd8e581c1a0ef14, 9268 bytes
on main 8fc86119: sha256 1df67c92865aa16f53cbb9b451fa3fa82a83a50950dc20a8efeea227f93f6240, 11346 bytes
in the checkout (the PR head): sha256 1df67c92865aa16f53cbb9b451fa3fa82a83a50950dc20a8efeea227f93f6240, 11346 bytes
the PR head's workflow equals main's: True | the receipt's binding equals the pre-merge base's: True
PyJWT sdist pyjwt-2.15.0.tar.gz: sha256 b11c5f9791d7bf51c2b39a81ed669f6b2dbbd669df2942f6c60167e9e3d1abe4, equals the PyPI digest: True; uploaded 2026-09-23T16:56:00.689307Z
tests/test_api_jwt.py: sdist 8331ec496b0df6f7 | receipt 8331ec496b0df6f7 | EQUAL
tests/test_jwks_client.py: sdist f1f5e0076061c393 | receipt f1f5e0076061c393 | EQUAL
tests/utils.py: sdist b5b937a60999a63d | receipt b5b937a60999a63d | EQUAL
tox.ini: sdist 1674dc3f7b5747e1 | receipt 1674dc3f7b5747e1 | EQUAL
pyproject.toml: sdist a89f0097abe7a485 | receipt a89f0097abe7a485 | EQUAL
SDK archive dcf401af7a9a: 4108923 bytes, sha256 643e171b9de5b55f948cf22ea698af4b0b05d2cb3e27867960ae9a0e47a9819c | pins.json 643e171b9de5b55f948cf22ea698af4b0b05d2cb3e27867960ae9a0e47a9819c | receipt 643e171b9de5b55f948cf22ea698af4b0b05d2cb3e27867960ae9a0e47a9819c
uv.lock inside: sha256 9ee1944f08b39760cbf502b546ec420fad84ed65caed5eb08fc9cceb68074801 | receipt 9ee1944f08b39760cbf502b546ec420fad84ed65caed5eb08fc9cceb68074801
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
observed_utc=2026-09-30T19:28:41Z
== versions: {'oauthlib': '3.3.1', 'PyJWT': '2.15.0', 'requests-oauthlib': '2.0.0', 'google-auth-oauthlib': '1.2.2', 'authlib': '1.6.12', 'openhands-sdk': '1.50.0', 'openhands-tools': '1.50.0'}
== reverse dependencies (Requires-Dist names oauthlib):
requests-oauthlib 2.0.0 <- oauthlib >=3.0.0
requests-oauthlib 2.0.0 <- oauthlib[signedtoken] >=3.0.0 ; extra == 'rsa'
== raw-text sweep: 17793 files outside oauthlib; files mentioning 'oauthlib': 22 in 6 top-level entries
browser_use: 1 files {'.py': 1}
browser_use-0.11.9.dist-info: 1 files {'(none)': 1}
google_auth_oauthlib: 5 files {'.py': 5}
google_auth_oauthlib-1.2.2.dist-info: 4 files {'.txt': 2, '(none)': 2}
requests_oauthlib: 8 files {'.py': 8}
requests_oauthlib-2.0.0.dist-info: 3 files {'.txt': 1, '(none)': 2}
== import-shaped and dynamic lines (text files), outside requests_oauthlib's plain client imports:
browser_use/integrations/gmail/service.py:16: from google_auth_oauthlib.flow import InstalledAppFlow
[binary or other] browser_use-0.11.9.dist-info/METADATA
google_auth_oauthlib/helpers.py:29: import requests_oauthlib
google_auth_oauthlib/flow.py:24: from google_auth_oauthlib.flow import InstalledAppFlow
google_auth_oauthlib/flow.py:68: import google_auth_oauthlib.helpers
google_auth_oauthlib/flow.py:331: from google_auth_oauthlib.flow import InstalledAppFlow
google_auth_oauthlib/interactive.py:27: import google_auth_oauthlib.flow
google_auth_oauthlib/interactive.py:129: import google_auth_oauthlib
google_auth_oauthlib/tool/__main__.py:39: import google_auth_oauthlib.flow
[binary or other] google_auth_oauthlib-1.2.2.dist-info/RECORD
[binary or other] google_auth_oauthlib-1.2.2.dist-info/METADATA
[binary or other] requests_oauthlib-2.0.0.dist-info/RECORD
[binary or other] requests_oauthlib-2.0.0.dist-info/METADATA
== server-side or advisory names in files that mention oauthlib (outside oauthlib):
(0 lines)
== advisory source files:
oauthlib/oauth2/rfc6749/endpoints/revocation.py ebc5248a9cfb50e75e04298ee4a4d1a34bf06d415df2d4c6db60a4d21165ba6c
oauthlib/oauth2/rfc6749/grant_types/authorization_code.py 0d6931601c4e88a078fb3ccf5f052c035ad6a4bb2171efb9c218e088a7272dc6
oauthlib/oauth2/rfc6749/endpoints/pre_configured.py 6fe072e29e94f0bb6fa65bf8a223893b2702e8d77c52494b389f75bb3ebc6316
oauthlib/openid/connect/core/endpoints/pre_configured.py bc6ff1a5fa23c2dcc3a782125e13d93355e73abf2e4fadc406b86ebce121e7ee
Loading
Loading