Story: Implement the operations journeys in ores.web

Table of Contents

This page documents a story in Sprint 27. It captures the goal, current status, acceptance criteria, and the tasks that compose it.

1. Goal

The five Operations journeys – the running services, the compute grid, the message bus, the telemetry logs, and the versions and database – run as screens in ores.web against the real server.

2. Status

Field Value
State DONE
Parent sprint Sprint 27
Now Nothing.
Waiting on Nothing.
Next Nothing.
Last touched 2026-10-13

3. Acceptance

  • The five journeys run in ores.web against the real server on the journey runtime the Setup group landed, and no journey entity is added.
  • The whole grid is read under the permission the journey records, and the heartbeat carries its host.
  • The services roster keeps every expected instance with its state word, and the login answer carries the database row.
  • The Operations area carries the five screens with the footer, the system-administration menu carries the Operations entry, and the versions screen is offered in every mode.

4. Tasks

Task State Start End Description
Scaffold story: Implement the operations journeys in ores.web DONE 2026-10-04 2026-10-04 Story scaffolding rides this task: documents, sprint wiring, and the scaffold PR. Close it before merging that PR.
Carry the host on the heartbeat DONE 2026-10-04 2026-10-04 Initial task for: Implement the operations journeys in ores.web
Serve the services roster DONE 2026-10-06 2026-10-06 Serve the installation's expected services and their replica counts, and the last report of every instance at any age, so the roster keeps every expected row with a state: running, stopped or missing.
Carry the database on the login answer DONE   2026-10-07 Read the database row at login and carry it on the login answer beside the build it states already: fingerprint, environment, commit and created. No subject of its own.
Read the whole grid DONE   2026-10-07 Drop the session-tenant filter from the grid reads, keep the stored tenant id as attribution, and guard the read with the permission the journey records, so the whole grid comes back.
Keep the failure fields on the node summary DONE   2026-10-07 Carry the failed task count and the longest task into the node summary, so a node failing every task stops reading as idle.
Build the operations screens in ores.web DONE   2026-10-08 The five journeys as screens on the journey runtime, against the real server: services, grid, bus, logs and versions, with the Operations area, the BFF routes and the footer.
State who reaches the operations screens DONE 2026-10-05 2026-10-06 The documents state who reaches each operations screen: the four installation screens are the system administrator's in the Operations area, and the versions screen is any signed-in person's in every mode.

5. Plan

# Step What it leaves behind
1 Scaffold the story and wire it into the programme The story, its tasks, the sprint row and the programme's order table.
2 State who reaches the screens The access model on the group page, the five journeys, the story and the screens task: the four installation screens in the system-administration menu's area, the versions screen in every mode.
3 Close the data-model linkages The four fixes, each with its evidence, and each capture moved out of the inbox.
4 Build the operations screens The five screens, the Operations area and the footer in ores.web, on the runtime the Setup group landed.
5 Line up the shell side The grid stats command follows the changed read, and the story records where the shell carries no operations journey.

6. Decisions

The remainder is carried in Record service lifecycle events and surface them in system health.

  • The accepted design is the build's input. The five journeys were written and walked against a clickable prototype in sprint 26, and the user accepted the walk on 2026-10-04. The prototype branch is the design record; this build ports its screens onto the journey runtime rather than merging them, and each task re-checks its own claims against the tree as it works.
  • The data-model linkages are the story's first tasks. The walk found five linkages between the accepted screens and the models, and each one sits in the inbox as a capture. They are the story's first tasks, so the build sizes from them instead of finding them mid-screen.
  • The grid belongs to the installation. The grid reads drop the session tenant's filter, and the stored tenant id stays on the sample as attribution. The read grows the permission the journey records, so the whole grid and who may see it stay two separate decisions.
  • The heartbeat carries one new field, not a new entity. A host id on the service heartbeat answers both questions the record found — which node runs a wrapper, and which host runs an instance — and the publishing process already holds the id.
  • The database rides the login answer. The versions panel needs no read of its own: the login answer states the deployment's build already, and it gains the database row beside it. The row's audience is the server build's audience.
  • The roster keeps every expected row. A services screen drawn from samples alone fails worst when the list is short: the operator cannot tell what is missing. The screen draws the installation's expected services and their replicas, and the read that serves them is the roster task.
  • The estate's state is a small subset of the old controller. Heartbeats tell only whether an instance went quiet. The roster also needs what should run, which the registry gives through a generated expected-services table, and what each instance said about itself: every process announces started and a graceful stopped through the shared service lifecycle, and telemetry stores the events and raises a service_restarted notification to the super administrators. Supervision stays systemd's, as it would be Kubernetes'; the decommissioned controller's pid, stderr and restart policy are not brought back. Settled with the operator on 2026-10-06 (Record service starts and stops, Notify super administrators of service restarts).
  • Both clients reach one operation. Where the shell carries an operations journey today — the grid stats command and its recipe — it follows the same subject when the read changes. Where it carries none, this story records that rather than inventing a shell surface.
  • A journey a person cannot reach from a screen is not finished. Each journey's Related journeys list is links on the screen; a screen that omits them has not implemented the journey.
  • The Operations area is offered in system administration alone. The four installation journeys' actor is the super administrator acting from the system tenant, so the system-administration menu carries the Operations entry and no other menu does: a tenant administrator and a regular user reach none of the four screens. The versions screen is the exception. Its actor is any signed-in person, so the shell offers it in every mode, beside the footer. The accepted walk ran the prototype in that mode.
  • The screens follow the accepted contracts. The UX language, the UI design principles and the TypeScript Clean Standard bind the work.
  • A cross-sprint group closes DONE and gets a successor. The programme's rule applies here: if the group does not close in sprint 26, what lands is recorded and the rest continues in a successor story.
  • The node summary states the failures beside the completions. The node sample already stored tasks_failed and max_task_duration_ms, and the summary dropped both, so a node failing every task read as a node doing nothing. The summary carries both, mapped from the node's newest sample, and the shell's compute grid-stats node table prints them under a header row. The handler has no test seam — a header-only class with an injected NATS client and repositories built inline — so the mapping is proved on the live fleet, not by an automated test, and the task says so.
  • The database row rides the login answer, refusals included. The answer already states the deployment's build, so it gains a nested database_info beside it — fingerprint, environment, commit and created — read once per login from ores_database_info_tbl. The handler fills it on every reply path, both successes and both refusals, because the row rides with the build and a refusal still says what it talked to; a read that fails leaves the row empty rather than failing the sign-in. No subject, permission, BFF route or second read appears. The BFF keeps the row on the session record and GET /api/session repeats it, so the versions panel adds no request. The read is a hand-authored repository helper so it can be tested against the real table; the header-only login handler has no seam and is not unit-tested.

7. Out of scope

  • The journey documents, which the extraction pass and their stories own — where this build proves one wrong, the correction goes to the document and is recorded here.
  • Host, workunit and app management — the pages behind the grid's read-only view — deferred by the record to Extract the ores.compute user journeys.
  • The charts over the stored telemetry aggregates, which the logs journey records as a gap of its own (Expose the telemetry stats surface) — this group states the gap on the screen rather than building the charts.
  • The system-wide permission gap for hand-written operation handlers (Nothing gates a hand-written operation handler) — this group gates the reads it adds or changes and links the capture for the rest.

8. Documents

Document Kind Purpose
Operations journeys knowledge The group page: five journeys, who reaches each screen, and where the legacy screens went.
See the running services user_journey The roster, its state words and its version skew.
Watch the compute grid user_journey The nodes, the wrappers, and the failures.
Watch the message bus user_journey The server's vitals and the streams.
Read the telemetry logs user_journey The filter bar, the entries and the page count.
Check the versions and the database user_journey The three builds and the footer.
Document the operations journeys story The story that wrote the journeys and accepted the walk.
Prototype the operations journeys task The accepted prototype: branch prototype/operations-journeys at 285519db99.
The service heartbeat carries no host capture The grid's wrapper-to-node join and the services screen's instance-to-host question.
The services roster has no read capture The expected roster, the replica counts, and the states beyond running.
The login answer does not carry the database capture The versions panel's database row, on the login answer.
The grid read is scoped to the session tenant capture The filter the grid's ownership removes.
The node summary drops the failure fields capture The failures a node row must state.
Implement the user journeys in ores.web story The programme this group belongs to, and the order it keeps.
The journey runtime knowledge The step and the rail the screens use.
TypeScript Clean Standard knowledge The standard the screens are held to.
Journey execution knowledge The composition classes, and why no journey entity is added.

Emacs 29.3 (Org mode 9.6.15)