Task: Add compute read verbs to the shell: list apps, app versions, platforms, hosts and batches

Table of Contents

This page documents a task in the Manage the compute grid from the shell story. It captures the goal, current status, acceptance, and any notes or results.

1. Goal

The shell's compute menu gains five read-only verbs: list-apps, list-app-versions, list-platforms, list-hosts and list-batches. Each verb renders the domain rows as a table with the fields a script needs — ids, names, versions, status — so the grid can be inspected from the shell with no UI.

2. Status

Field Value
State DONE
Parent story Manage the compute grid from the shell
Now Nothing.
Waiting on Nothing.
Next Nothing.
Last touched 2026-08-10

3. Acceptance

  • compute list-apps lists the app catalogue (id, name, description).
  • compute list-app-versions lists app versions (app id, wrapper and engine version, min RAM).
  • compute list-platforms lists platform triplets (id, code, display name, OS, CPU arch).
  • compute list-hosts lists grid nodes (id, external id, display name, hardware, last RPC time, credit).
  • compute list-batches lists batches (id, external ref, status).
  • Every verb works against a live serving environment; empty domains render a header-only table, not an error (list-platforms prints no rows until a platform exists).

4. Plan

All five verbs reuse existing NATS subjects and the codegen table renderers in ores.compute.api (*_table_io.hpp); no backend or codegen changes. Implementation lives in the existing compute_commands.{hpp,cpp} next to publish-package, following its shape: require a login, send the list request authenticated, log the row count, print the table. compute_platform has no table renderer (it is hand-written, not model-owned), so list-platforms renders raw rows until the drift story generates the renderer (see Notes).

5. Notes

  • Live proof (2026-08-10): scripted session against brave_hopper with all 23 services up. compute list-apps returned the ORE and hello apps; list-app-versions two versions; list-platforms six triplets (hand-rolled table at the time, replaced by raw rows later — see the provisional-output note below); list-hosts six registered nodes; list-batches the remote-compute-node-join-proof batch (closed).
  • The compute grid is controlled by the system super admin, not by a tenant; the .env auto-login defaults (tenant_admin@acme_corporation) fail against this environment ("Auto-login failed", empty message), so the recipes and the live proof log in as super_admin@localhost. All five library scripts run as authored against the current environment: connect, login, verb, logout — each renders its table with live data (2 apps, 2 app versions, 6 platforms, 6 hosts, 1 batch).
  • Recipes live in doc/recipes/shell/compute/ (one per verb), tangled into projects/ores.shell/scripts/library/compute/, indexed under the new Compute section of doc/recipes/shell/shell.org.
  • Provisional output (2026-08-10): compute_platform is the one hand-written island in an otherwise codegen-owned component — every other compute entity is generated from a model org (ores.compute.modeling: domain type, *_table_io, protocol, repository, SQL), but platform predates the model migration and has no org and no table renderer. Rather than block the verbs on that drift, list-platforms prints raw rows (one platform per line, space-separated fields, no table formatting) until the Entity classification and drift baseline: ores.compute story generates the renderer. The story's reconciliation task then swaps the loop for out << resp->platforms, matching the other four verbs.

6. Test Scenarios

Manual QA scenarios (scaffolded via compass add test_scenario, run through the QA Validation Runner panel) 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
#1992 [ores.shell] Add compute grid management verbs to the shell

8. Review

# Comment summary File Decision Notes
1 canonical_result_id left uninitialized in dispatched workunits (5410154095) compute_commands.cpp Fixed Set wu.canonical_result_id = uuid{}; mapper stores nil as NULL (dddb3ca710)
2 Batch marked dispatched before the workunit loop; partial failure strands it (5410154095, 5410154821, 5410160036) compute_commands.cpp Fixed Status save moved after the loop; a partial failure leaves the batch open, re-dispatchable (dddb3ca710)
3 limit = 1000 with no pagination on list requests (5410154095) compute_commands.cpp Declined Matches the existing convention in crm/provision/accounts commands; reviewer 2 checked and called it "Not a concern"
4 Hand-built input key bypasses the compute_storage helper (5410154095, 5410160036) compute_commands.cpp Partial Comment documents the batch-scoped convention and the download-input reverse; an input_key helper for batch bundles is a follow-up
5 Smoke online-host snapshot taken after the drain loop exits (5410154095) compute_commands.cpp Fixed Host set captured at the drain transition, not re-fetched (67406e0ea2)
6 PR traceability table points at the artifact-download task (5410154821) PR body Fixed gh pr edit; body now cites the read-verbs task (7FB32716-261C-45D9-A5C9-6A43FF2AD6F5)
7 list-platforms header comment says "as a table" (5410159838) compute_commands.hpp Fixed Comment now states provisional raw rows until the drift story lands table_io (01ad6a94e3)
8 is_online 90s window disagrees with the server's 5-minute grid-stats window (5410160036) compute_commands.cpp Fixed online_window{300} aligned with ores_compute_grid_stats_fn_create.sql (67406e0ea2)
9 O(n×m) match in results_of_batch (5410160036) compute_commands.cpp Fixed std::unordered_set<uuid> lookup, O(n+m) (01ad6a94e3)
10 dispatch-batch retry after a partial failure duplicates already-dispatched jobs (5411538471) compute_commands.cpp Declined Inherent to the leave-open-and-redispatch design: a re-run mints job_count new workunits; accepted risk, documented in the reply
11 limit = 1000 without pagination on batch-scoped lookups (5411538471) compute_commands.cpp Declined Same as row 3; tracked as follow-up (paginate_compute_list_requests.org)
12 delete-host docstring says 90s heartbeat window (5411538471) compute_commands.hpp Fixed Doc now states 300s, matching online_window{300} (0dc9f4a13b)
13 Stale 90s heartbeat text in the header doc and the delete-host recipe (5411583598) compute_commands.hpp, delete-host recipe Fixed Both now state 300 seconds (5 minutes), matching online_window{300} (0dc9f4a13b)
14 split_storage_uri hardcodes "api/v1/storage" (5412188603) compute_commands.cpp Fixed Prefix derived from storage_paths::prefix, in sync with make_object_path (58761e0ffa)
15 Stale 90s heartbeat in the monitoring task doc Acceptance/Plan (5412188603) task_grid-monitoring-verbs.org Fixed Aligned with the Result section's 5 minutes (0dc9f4a13b)
16 Smoke recipe variable INPUT_DIR stale for the tarball input (5418263168) recipes, .ores scripts Fixed Renamed to INPUT_TARBALL in the smoke and dispatch recipes, retangled (bb0b13bcd7)

9. Result

  • Five read-only verbs shipped in compute_commands.{hpp,cpp}: list-apps, list-app-versions, list-platforms, list-hosts, list-batches. All reuse existing NATS subjects and codegen table renderers; no backend or codegen changes.
  • All acceptance criteria met, verified live against brave_hopper: 2 apps, 2 app versions, 6 platforms, 6 hosts, 1 batch. Empty domains render a header-only table, not an error.
  • list-platforms prints provisional raw rows; the reconciliation task swaps the loop for the generated table_io once the drift story ships the platform renderer.
  • Five recipes added under doc/recipes/shell/compute/, tangled into projects/ores.shell/scripts/library/compute/ and indexed in the Compute section of doc/recipes/shell/shell.org.

Emacs 29.3 (Org mode 9.6.15)