Task: Edit the run document through the projection
Table of Contents
This page documents a task in the Make ores.ore the only owner of ORE formats story. It captures the goal, current status, acceptance, and any notes or results.
1. Goal
The package handler states a date change as a document change and asks the codec for the facts it needs, so no caller depends on how ORE spells an element.
2. Status
| Field | Value |
|---|---|
| State | DONE |
| Parent story | Make ores.ore the only owner of ORE formats |
| Now | Nothing. |
| Waiting on | Nothing. |
| Next | Nothing. |
| Last touched | 2026-10-29 |
3. Acceptance
- No code searches for an ORE element name or attribute spelling.
- The as-of date is read and set through the run document projection.
- The latest market data date comes from the market data reader.
- Tests cover a document whose marker sits in a comment, and one that writes its attributes in another order.
4. Plan
Both facts the handler needs are operations the codec can state, so they become operations on the two readers rather than searches inside the handler:
run_document_projection::as_of_datereads the document and maps it, so the parameter is found by name and the projection decides what an as-of date is.with_as_of_datemaps the document, sets the date, and writes it back through the projection, which is also how the export built it.market::latest_market_data_datereads the body with the market data parser and takes the last date it states, so a comment, a second date spelling or a repeated key are the parser's business.
The handler keeps what it alone knows: that a run prices at the data's last date when the data ends before the date the run asked for.
The tests live with the owners: a document that mentions the parameter in a comment and again inside an analytic, one that spells the attribute with other spacing and quote characters, one that states no date, and a body with comments, two date spellings and a line the tokeniser refuses.
ORE's schema gives Parameter one attribute, so "another attribute order" cannot
be written for the element this task reads. The spellings XML does allow, and the
decoy in an analytic's parameter list, are the cases a text search reads wrong.
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 |
|---|---|---|---|
| Searches for an ORE spelling outside the projection | 0 (both hits are in the projection) | grep -rn 'name"' projects/ –include=*.cpp –include=*.hpp= |
016f15a55e |
| Cases added for the two readers | 6 | git diff origin/main -- '*_tests.cpp' |
016f15a55e |
ores.ore.core.tests |
passed, 22.37s | compass test run -- -R ores.ore.core.tests |
016f15a55e |
ores.ore.service.tests |
passed, 0.91s, but the target holds no case | compass test run -- -R ores.ore.service.tests |
016f15a55e |
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
9. Review
| # | Comment summary | File | Decision | Notes |
|---|---|---|---|---|
| 1 | A pipeline with a line the tokeniser refuses read as a body with no date, so the run failed, where the old scan ignored the line | market_data_parser.cpp | Accepted | The newest date is read line by line through the tokeniser and a refused line is skipped. A case states it. |
| 2 | `@throws` named one exception, but a valid document the model cannot hold throws another | run_document_projection.hpp | Accepted | The docs name `std::invalid_argument` for text that is not XML and `std::runtime_error` for XML the model cannot read. |
| 3 | `with_as_of_date` promised not to invent parameters, but the projection always writes the ones the model always states | run_document_projection.hpp | Accepted | The doc says what it writes and when a value is empty; the task's Result says the same. |
| 4 | The new cases are named as sentences where their neighbours are snake_case, and the projection's cases carry no logger | both test files | Accepted | Renamed, and each case logs what it read. |
| 5 | The "attributes in another order" case re-spaced the attribute rather than reordering anything | xml_ore_run_document_projection_roundtrip_tests.cpp | Accepted in part | ORE's schema gives `Parameter` one attribute, so no order exists to vary. The case states the spellings XML allows, and a decoy in an analytic's parameters states the other failure of a text search. Recorded in the Plan. |
| 6 | The rewrite's "keeps every parameter" claim had no test | xml_ore_run_document_projection_roundtrip_tests.cpp | Accepted | The comment case now checks that an unrelated parameter and the analytic's own parameter survive the rewrite. |
| 7 | `ores.ore.service.tests` was cited as evidence but holds no case | task doc | Accepted | The measurement says so, and the limitation says the handler itself is untested. |
| — | The review bot did not run: the same infrastructure error, at no cost, before reading anything. The round was run as two parallel reviews, standards and spec | — | — | Both are in the rows above. |
10. Result
The package handler states a date change as a document change and asks the codec for the facts it needs. Its three text helpers are gone: no code outside the projection searches for an ORE element name or attribute spelling.
as_of_date and with_as_of_date are operations on the run document
projection, and latest_market_data_date is an operation on the market data
parser. The rewrite goes through the same reverse the export used, so the
document it writes is the one the export would have written with the other date:
the parameters the model always states are written with the values the document
gave them, and no parameter outside the model is invented.
A line the market data tokeniser cannot read is not a date line and is skipped, so a body with junk in it still states the newest date the lines around it carry. That mattered: reading a refused line as "no date" failed a run whose data did carry dates.
The handler keeps one rule of its own, which is about runs and not about ORE: a run whose gathered data ends before the date it asked for prices at the data's last date, and says so.