Skip to content

pgw#1138 (th#1722 §C): the worker stops reconstructing an org the hub derives itself - #659

Merged
PaulFidika merged 2 commits into
masterfrom
1138-media-owner-deadweight
Aug 11, 2026
Merged

pgw#1138 (th#1722 §C): the worker stops reconstructing an org the hub derives itself#659
PaulFidika merged 2 commits into
masterfrom
1138-media-owner-deadweight

Conversation

@PaulFidika

Copy link
Copy Markdown
Contributor

tensorhub de30113d mounts the media-upload family org-less (POST /api/v1/media/uploads) — an upload addresses the caller's own namespace, so the org comes from the credential and never from a path segment — and keeps the org-addressed shape only as a transitional alias for wheels ≤0.106.0 (th#1799 deletes it).

This moves the worker onto the org-less route and deletes the client-side reconstruction:

  • RequestContext._media_upload_owner() — decoded the capability JWT's tenant claim for one purpose, a URL segment.
  • the X-Cozy-Owner header — nothing in tensorhub reads it, in any version (the only Cozy-Owner-ish header in that tree is the orchestrator-internal X-Cozy-Owner-Forwarded).
  • RuntimeError("file save failed (missing owner)") and the J19 run34 403 class it was written against. A client that does not supply the org cannot supply the wrong one.

_decode_unverified_jwt_claims stays — transport, lifecycle, worker_identity, fleet_cells, hardware_report, capability_renewal, executor and procsplit all call it.

th#1795's upload.create/put/complete phase split and the sha256-declare direct PUT are untouched; complete_url is derived from the create URL, so it follows the move automatically.

The test is a route table, not a string

tests/harness/upload_sink.py now ROUTES like the hub: a pattern table mirroring registerMediaUploadRoutes(v1, "/media"), 404 for anything else including the alias. tests/test_media_upload_orgless_pgw1138.py drives the real ctx.save_bytes codepath against it, so the assertion is "the upload succeeded against a server serving only tensorhub's canonical routes" rather than a path a stub pinned to itself.

RED on the pre-change source (git checkout origin/master -- request_context/{_stream.py,__init__.py}): 7 failed, 10 passed — the four new tests plus test_p9_result_upload_metrics, test_inline_envelope_pgw767 and test_th1111_stage_timing, all failing at the create leg with status=404. Green after: 40 passed across the seven upload-touching files.

Sequencing (strict)

Safe to merge now — the alias serves old wheels, the org-less route serves new ones. th#1799 (deleting the hub alias) must wait until a wheel carrying this change ships AND the fleet relocks. Reversing that order 404s every worker output upload. No release cut here: joins the batched 0.110.0 (pgw#1140 ledger).

… derives itself

tensorhub de30113d mounts the media-upload family org-less
(POST /api/v1/media/uploads) because an upload addresses the CALLER'S OWN
namespace — the org comes from the credential, never from a path segment — and
keeps the org-addressed shape only as a transitional alias for wheels <=0.106.0
(th#1799 deletes it once the fleet relocks onto a wheel carrying this change).

So this client stops rebuilding what the hub already knows:

- RequestContext._media_upload_owner() is deleted. It decoded the capability
  JWT's `tenant` claim for one purpose — a URL segment.
- The X-Cozy-Owner header is deleted. Nothing in tensorhub reads it, in any
  version; the only Cozy-Owner-ish header in that tree is the
  orchestrator-internal X-Cozy-Owner-Forwarded.
- With them goes RuntimeError("file save failed (missing owner)") and the whole
  J19 run34 403 class it was written against: a client that does not supply the
  org cannot supply the wrong one.

_decode_unverified_jwt_claims STAYS — transport, lifecycle, worker_identity,
fleet_cells, hardware_report, capability_renewal, executor and procsplit all
call it. th#1795's upload.create/put/complete phase split and the sha256-declare
direct PUT are untouched, and complete_url is derived from the create URL, so
it follows the move automatically.

The test harness now ROUTES like the hub. tests/harness/upload_sink.py carries a
pattern table mirroring registerMediaUploadRoutes(v1, "/media") and 404s
anything else, including the alias — so the URL is proven by driving the real
ctx.save_bytes codepath against a server that serves only tensorhub's canonical
routes, not by asserting a path string a stub pinned to itself. Seven tests
across four files go RED on the pre-change source (the four new ones, plus
pgw#767, P9 and th#1111, which fail at the create leg with status=404).
`tests_v2/conftest.py`'s UploadSink answered every path, so
`test_dispatch_load_serve_and_upload_walk` could only assert the URL by
repeating it — and it pinned the org-addressed shape. It now carries the same
org-less route table as the v1 harness (duplicated, not imported: a cross-suite
import would make the v1 harness load-bearing for v2) and 404s anything else,
including the alias th#1799 deletes. The refusal-row `status=` knob is
unaffected — routing is decided first, so a refusal row still returns its
status for a VALID route.

The assertion now reads `path == MEDIA_UPLOADS_PATH` and `ORG not in path`:
ORG is dispatched on the job and must not reach the URL.
@PaulFidika
PaulFidika merged commit 12ea6a2 into master Aug 11, 2026
2 checks passed
@PaulFidika
PaulFidika deleted the 1138-media-owner-deadweight branch August 11, 2026 20:45
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