Task: Close the money-column gate over the FX deviations
Table of Contents
+#+blocked_on: +#+blocked_since: +#+created: 2026-10-16 +#+updated: 2026-10-16 +#+environment: +#+todo: DISCOVERED BACKLOG STARTED BLOCKED | DONE ABANDONED
This page documents a task in the Rework the FX instruments to the instrument table rule story. It captures the goal, current status, acceptance, and any notes or results.
1. Goal
Make the money gate able to see the shapes the FX review found. The check reads the models and classifies each column by name, so three deviations pass it: a continuous quantity whose name reads as money, a money value read through a binary float, and money typed text. Both of its baselines are a single blank line, so the gate asserts nothing for this family in either direction.
2. Status
| Field | Value |
|---|---|
| State | DONE |
| Parent story | Rework the FX instruments to the instrument table rule |
| Now | Nothing. |
| Waiting on | Nothing. |
| Next | Nothing. |
| Last touched | 2026-10-18 |
3. Acceptance
- A column whose name reads as money but whose economics are continuous is checked as continuous, and the exclusion list is not the only thing that hides it.
- A money column typed
textis reported. - The check is not extended to read the ORE binding unless that is the chosen mechanism; if it is, the check names what it reads.
- Both baselines are seeded with the offenders that remain, so the debt is visible and cannot grow.
- The exact-numbers page stops restating the baselines in prose, as its own rule asks.
- A pytest case covers each new direction, including one that the old check missed.
4. Plan
- Reproduce the three blind spots with the family's own columns.
- Decide the mechanism for each, and write it into the check with a test.
- Run the check over the whole tree, seed the baselines, and read the new entries.
- Correct
exact_numbers_and_economic_change.orgso it points at the baselines rather than repeating a count.
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 |
|---|---|---|---|
| Money offenders recorded | 5, all money typed text in other components | python3 build/scripts/check_money_decimal_columns.py, in evidence/money-gate.txt |
the PR head |
| Continuous offenders recorded | 0 | the same command | the PR head |
| Columns read | 7523 | the same command | the PR head |
| Money-gate pytest cases | 24 | projects/ores.codegen/venv/bin/python -m pytest projects/ores.codegen/tests/test_check_money_decimal_columns.py |
the PR head |
| Money column typed numeric with a float in the domain | reported | test_money_exact_in_sql_but_a_float_in_the_domain_is_reported |
the PR head |
| Missing baseline | an error, not an empty list | test_a_missing_baseline_is_an_error |
the PR head |
6. Notes
- The evidence for this task is Investigation: FX family data model review, the enforcement gap section and finding 10.
- The two shapes the name rule still cannot see are stated in the check's docstring: a continuous quantity spelled as text, which is a code in these models, and a continuous column with no continuous token in its name and no
CONTINUOUS_COLUMNSentry.
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
9. Review
| Comment summary | File | Decision | Notes |
|---|---|---|---|
10. Result
The three shapes the review named were closed across two units, and this one makes the gate say what it covers.
The continuous shape, a quantity whose name reads as money, was closed when the
variance strike landed (a08b693bed): CONTINUOUS_COLUMNS names the column
and its reason, so the entity that states it decides, and the exclusion list no
longer hides it. Money typed text was already reported; the money baseline
records the five that remain, all in other components. This unit closes the
remaining hole in the binary-float direction: the match read the literal word
double, so a money column typed numeric with a float in the domain passed.
It now matches either binary float, a field group's money member typed string
or float is reported too, and a missing baseline is an error rather than an
empty debt list.
Both baselines carry a header that states the format and what an empty list means. The continuous baseline holds only its header, so the direction records no debt and the next offender fails the check. The money baseline holds the five text columns.
The exact-numbers page already forbids a prose copy of the baselines and points
at the check. It was corrected in a07cbba44f, before this unit, so it needed
no change here; the claim that it still counts ten columns was stale when the
task was written. The stale count did live in the codegen test's docstring, and
that is corrected.
11. Decisions
- The check stays on the models. It does not read the ORE binding. A money
value is lost at the binding only when a leaf is not a
moneyFloat, and the digit tests and the goldens cover that seam directly; teaching this check a second input language would duplicate the binding's own drift guard. - An empty baseline is a statement, not an absence. The header says so, and a test holds the reader to it, so the next offender in a clean direction fails rather than being absorbed.
- The exclusion list stays for columns the name rule cannot classify. It is not the mechanism for a continuous quantity any more; it remains for a money word that names a code or a quote, and each entry still needs its reason in the model prose.