Task: Make the reporting to compute handoff drive a job
Table of Contents
This page documents a task in the Run an example bundle through the compute grid from a report definition story. It captures the goal, current status, acceptance, and any notes or results.
1. Goal
Make the reporting path's workunit reach a wrapper and run. The original note listed three defects in the submit path; the run-token task moved submission onto the compute dispatcher and closed one of them, so two remain:
- The subject has no consumer. The dispatcher publishes each assignment on
compute.v1.work.assignments.{run_tenant}.{platform}, and every wrapper subscribes on its own configured tenant, the system tenant, so a tenant's run is published where nobody listens. The platform's wrapper fleet is the deployment's shared pool and must consume every tenant's work. - The input URI is the wrong shape.
prepare_ore_packageanswers withores/ore/packages/{instance}/ore_package.tar.gz, a bucket and key, and the wrapper fetches it over the storage HTTP interface, which speaks/api/v1/storage/{bucket}/{key}. The package and output URIs the dispatcher sets are already paths.
2. Status
| Field | Value |
|---|---|
| State | DONE |
| Parent story | Run an example bundle through the compute grid from a report definition |
| Now | Nothing. |
| Waiting on | Nothing. |
| Next | Nothing. |
| Last touched | 2026-10-07 |
3. Acceptance
- A workunit submitted through the reporting path is picked up by a wrapper and executes.
- The wrapper can download the package and the input, and has somewhere to put the output.
- The subject, the URI shape and the workunit fields match what the working dispatcher produces.
4. Plan
The subject fix belongs in the wrapper, not the dispatcher: the stream already
captures assignments.>, and the tenant segment is the routing key a tenant's
own pool will filter on later, so the shared fleet widens its consumer to
assignments.*.{platform} and keeps the tenant in the subject. The node's
--tenant-id stays its own identity for the host row and telemetry; it is no
longer a filter on the work it takes.
The URI fix belongs where the URI is built: prepare_ore_package builds it with
storage_paths::make_object_path, the same helper the compute dispatcher uses
for the package and the output.
5. Notes
Closed. The handoff drives a job end to end. Report instance
0b6d9908-d699-49ae-b633-cbc363d4b8e6 of the "Intercompany Exposure Matrix"
definition reached the terminal completed state, and its result
9fd17163-d2a4-43d8-83ef-0b25edb84069 came back Done with outcome 1 from host
ed10ef0f-ed48-5b3f-96ab-49e5eca325d7. The node downloaded the package and the
input and uploaded the output, each authorised by the assignment's capability;
the same URLs answer 401 without one. The mechanism is recorded in
give a worker node a capability to reach its assignment's objects, which
also records the two defects that had to be fixed first.
The live run reached the wrapper. Run f8275ac1-1ac5-4e2e-a485-97324ef3b13e,
tenant 51e855c0-ce99-4726-a590-7272c89cf8b1:
- The wrapper subscribes to
compute.v1.work.assignments.*.x64-linux(durablecompute_wrapper_shared_x64-linux), and at 14:24:57 it took the run's assignment. Defect 1 is closed. - The attempted package URL is
http://localhost:20600/api/v1/storage/ores/compute/packages/ORE-1.8.17.0/..., the path shape storage speaks. Defect 3 is closed for the package; the input is built by the same helper. - It then failed
HTTP 401.ores.compute.wrapperhas no storage credential at all:application.cpppasses aconstexpremptystorage_bearer_tokento every get and put. A node needs a credential before it can download, and the design says that credential is the per-assignment capability Storage policy describes, which the isolation story owns. This task waits on it rather than inventing a standing service token the policy would replace.
A second finding: the JetStream assignments stream survives a database
recreate. On the recreated environment the wrapper replayed assignments from
the previous one and answered results.submit failed: Result not found for
each, because the result rows were gone. The smoke-test story's "reproducible
from a freshly recreated database" acceptance will meet this; the stream wants
purging, or the handler wants to treat an unknown result as an expiry rather
than an error.
6. Test Scenarios
Manual QA scenarios (scaffolded via compass add test_scenario)
that verify this task. Link
new ones here as they're created; the scenario doc itself links back
via its "Verifies task" field.
| Scenario | State | Notes |
|---|---|---|
7. PRs
| PR | Title |
|---|---|
| #2740 | [compute] Let the shared wrapper fleet take a tenant's work |
8. Review
| Comment summary | File | Decision | Notes |
|---|---|---|---|
9. Result
Partial, and landed: the two defects this task owned are fixed and proven.
- The platform wrapper fleet consumes
compute.v1.work.assignments.*.{platform}, so the shared pool serves every tenant. Proven live: the wrapper took runf8275ac1's assignment. prepare_ore_packagebuilds its tarball URI withstorage_paths::make_object_path, so the wrapper's input URL is well formed.- The handoff's third defect was closed by the run-token task, which moved submission onto the compute dispatcher.
Still open, and why this task is BLOCKED rather than DONE: a wrapper cannot download, because a node holds no storage credential. That is the per-assignment capability the isolation story owns, not a handoff defect. The task closes when a node can authenticate to storage and a run executes.