Task: Carry the database on the login answer

Table of Contents

This page documents a task in the Implement the operations journeys in ores.web story. It captures the goal, current status, acceptance, and any notes or results.

1. Goal

The versions screen states the database under the deployment: the fingerprint of the schema it was built from, the build environment, the commit and the created time. All four live in ores_database_info_tbl, and one reader touches the row today: each service's startup check, which compares the stored fingerprint with the one compiled into the code. No subject serves the row to a person. This task gives it its second reader (The login answer does not carry the database): the login_response states the database row beside the build it already states, read once per login, and the versions panel needs no request of its own.

2. Status

Field Value
State DONE
Parent story Implement the operations journeys in ores.web
Now Nothing.
Waiting on Nothing.
Next Nothing.
Last touched 2026-10-07

3. Acceptance

  • login_response carries a nested database_info with four fields — fingerprint, environment, commit and created — read once per login from the newest row of ores_database_info_tbl.
  • The iam service fills the struct on every reply path: the one-party success, the multi-party answer that opens the party picker, and both refusals (the login_error catch and the catch for any other exception). A read that fails leaves the struct empty and the login answers as it did before, because build forensics must not fail a sign-in.
  • No new subject, no new permission, no new BFF route and no second table read appear: the login answer states the deployment's build already, and the row rides beside it.
  • The row reaches the browser the way the build it states already travels: the BFF keeps it on the session record, GET /api/session states it beside version, and a party-choice login carries it into the session when the person picks a party.
  • The row's audience is the server build's audience, so no separate audience is defined for it.
  • The read is a hand-authored repository helper, tested against the real table so the test fails when the helper stops returning the row; the header-only login handler itself has no seam and is not unit-tested.
  • The capture The login answer does not carry the database moves out of the inbox with this task's evidence.

4. Plan

  1. Declare a nested database_info in the iam login model and give login_response a database field of it, with the doc comment that says why the row travels with the build.
  2. Regenerate the iam component, so the C++ and TypeScript protocol types carry the struct; the component file lists follow from the new hand-authored repository and test sources.
  3. Add a hand-authored read_database_info helper in ores.iam.core, a second reader beside the startup fingerprint check, and a repository test that fails when it stops returning the row.
  4. Read the row once at the top of auth_handler::login and place it on all four reply paths.
  5. Carry the row through the BFF session store and the wire-protocol session view, the same way version already travels, and test that the login answer and GET /api/session both state it.
  6. File the capture as discarded with this task's evidence, and correct the journey's * What is missing to say the answer carries the row now.

5. Measurements

Every number this task claims about a tree, with the command that produced it and the commit it was measured at. A number without both is not a measurement, because a clean-up record describes a tree and trunk moves under a branch: a consumer count, a gate's component count and a suite's size all change with no code changing, and the reader of a bare number cannot tell which tree it came from. Where the raw output matters, put it in an evidence/ file beside the task and name that file in the Command column.

What Value Command Commit
Build exit 0 ./compass.sh build 9d12f82b8c
Full suite 94/94 targets passed, 0 failed ./compass.sh test run 9d12f82b8c
Codegen unit tests 2 failed, 1288 passed (both pre-existing: the storage_capability_messages.org subject-conformance failures) projects/ores.codegen/venv/bin/python -m pytest projects/ores.codegen/tests -q 9d12f82b8c
Web workspace typecheck exit 0; 716 tests passed (bff 243, web 333, wire-protocol 140) npm run typecheck; npm run test 9d12f82b8c
Component drift clean (dry run) projects/ores.codegen/scripts/check_component_drift.py --all --dry-run 9d12f82b8c
Documentation 42/42 components pass ./projects/ores.codegen/validate_docs.sh 9d12f82b8c

6. Notes

The row travels with the build the answer already states, so the audience is the server build's audience and no subject of its own is needed. Exactly one row exists, written when the database is created or recreated.

7. 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
     

8. PRs

PR Title
#2778 [iam,web] Carry the database on the login answer

9. Review

Comment summary File Decision Notes
       

10. Result

The login answer carries the database row. login_response gained a nested database_info — fingerprint, environment, commit and created — declared in ores.iam.login_messages.org beside the version field it already states. auth_handler::login reads the newest row of ores_database_info_tbl once per login, through a hand-authored read_database_info helper, and places it on all four reply paths: the one-party success, the multi-party answer that opens the party picker, and both refusals. A read that fails leaves the struct empty and the sign-in still answers, because build forensics must not fail a sign-in. No new subject, permission or BFF route appears.

The row reaches the browser the way the build already travels. The wire protocol's loginResponseSchema parses it, the BFF keeps it on the session record, GET /api/session states it beside version, and a party-choice login carries it into the session when the person picks a party. The versions panel now reads it from the answer that opened the session.

The read is tested against the real table (ores.iam.core.tests: read_database_info_carries_the_recorded_build), and the session carry is tested through the BFF routes (login-database.test.ts). The header-only login handler has no seam, so the placement of the row on the four reply paths is proved on the built binary and the live fleet, not by a unit test that would pass with the field unfilled.

Gates: build exit 0; compass test run 94/94 targets pass; codegen pytest 2 failed / 1288 passed, the 2 unchanged pre-existing storage_capability_messages.org subject-conformance failures; ores.web typecheck exit 0 and 716 tests pass; component drift clean; validate_docs.sh 42/42; prototype inventory clean. The fleet was restarted afterwards.

Emacs 29.3 (Org mode 9.6.15)