Task: Carry the book purpose through the publisher
Table of Contents
This page documents a task in the Clear the local-check failures on main story. It captures the goal, current status, acceptance, and any notes or results.
1. Goal
book_purpose_type and ledger_feed_type became non-nullable on the book, the artefact that feeds it, and the trigger that validates it. The publish function that reads the artefact and writes the book was not updated, so it inserts neither: every tenant setup fails at its books step with 'missing_field: book_purpose_type' and no tenant can be provisioned.
2. Status
| Field | Value |
|---|---|
| State | DONE |
| Parent story | Clear the local-check failures on main |
| Now | Nothing. |
| Waiting on | Nothing. |
| Next | Nothing. |
| Last touched | 2026-10-09 |
3. Acceptance
- A tenant setup publishes its books and completes.
- The books carry a purpose and a ledger feed.
4. Plan
The failure names its own column, so the work is to find every writer of it rather than to read the error again. That column arrived on three things at once — the book, the artefact that feeds it, and the trigger that validates it — and the loaders were brought to it while the publisher between them was not.
Reproduce by retrying the run that failed, which is the only path that reaches the publisher, then hold the published table against the artefact to see whether the values crossed.
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 |
|---|---|---|---|
| Columns the publisher dropped | 2, of the 20 it names | the function's INSERT list | 2c6b5bcbf1 |
| Books in the tenant before | 0, with the setup failed at step 3 | select count(*) from ores_refdata_books_tbl |
2c6b5bcbf1 |
| Books after the retry | 110: 100 Trading, 10 SweepTarget | the same query | 2c6b5bcbf1 |
| Tenant setup steps at hand-over | publish_bundle, import_lei_hierarchy, provision_party and start_market_feeds completed, load_staff running | the step table | 2c6b5bcbf1 |
6. Notes
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 |
|---|---|
| #3013 | [refdata] Carry the book's purpose and ledger feed through the publisher |
9. Review
| Comment summary | File | Decision | Notes |
|---|---|---|---|
10. Result
A tenant can be provisioned again. The publisher reads book_purpose_type and ledger_feed_type out of the artefact and writes them on, so the trigger that validates them has something to validate, and the tenant setup walks its steps instead of failing at the third.
Three changes in a row moved the same two columns across three tables and each one left the next reader behind: the columns went onto the book, the loaders learnt to write the artefact, and nobody told the publisher that reads it. The lesson is not that the publisher was missed. It is that nothing compares a publish function's INSERT list against the table it writes — the same gap a loader census would close, and the third defect this session that a check looking at column lists would have caught.
The error also reaches the browser as the whole PL/pgSQL body, several hundred words of it, laid out in the step panel. That is a presentation defect of its own and is not fixed here.