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_responsecarries a nesteddatabase_infowith four fields —fingerprint,environment,commitandcreated— read once per login from the newest row ofores_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_errorcatch 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/sessionstates it besideversion, 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
- Declare a nested
database_infoin theiamlogin model and givelogin_responseadatabasefield of it, with the doc comment that says why the row travels with the build. - Regenerate the
iamcomponent, so the C++ and TypeScript protocol types carry the struct; the component file lists follow from the new hand-authored repository and test sources. - Add a hand-authored
read_database_infohelper inores.iam.core, a second reader beside the startup fingerprint check, and a repository test that fails when it stops returning the row. - Read the row once at the top of
auth_handler::loginand place it on all four reply paths. - Carry the row through the BFF session store and the wire-protocol session
view, the same way
versionalready travels, and test that the login answer andGET /api/sessionboth state it. - 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.