Task: Close the approval model gaps
Table of Contents
This page documents a task in the Rework the market data feeds into a market data service with adapters — the remaining work story. It captures the goal, current status, acceptance, and any notes or results.
1. Goal
The approval model asks the checks the journeys describe and no open question is left in the demo notes.
2. Status
| Field | Value |
|---|---|
| State | DONE |
| Parent story | Rework the market data feeds into a market data service with adapters — the remaining work |
| Now | Nothing. |
| Waiting on | Nothing. |
| Next | Nothing. |
| Last touched | 2026-10-27 |
3. Acceptance
- An opening book asks for the controller part; an update does not.
- A market data publish has a kind, a raiser and a decider, and the publish waits on the decision.
- The journeys state which party's Market Risk decides a tenant-wide change.
- A hold takes a reason from a lookup, not free text.
4. Plan
(Implementation strategy. Written when work starts; key decisions
are distilled into the parent story's * Decisions at close, but the
plan itself stays — it is the historical record of what we did.)
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 |
|---|---|---|---|
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 |
|---|---|
9. Review
| Comment summary | File | Decision | Notes |
|---|---|---|---|
10. Measurements
| What | Value |
|---|---|
| Opening book parts | controller, finance, market_risk, operations |
| Controller answer order | 1, the only open part on an opening |
| Publish kind | marketdata.curve_publish, market risk decides, 14-day expiry |
| Hold reasons | 10 codes, system-tenant lookup |
| Suites | book proposal 43, curve publish 5, hold 3, inbox and shell 100%, BFF 1040 |
| Live | controller queue and decision, publish ask/approve/refuse, hold accept/refuse |
11. Result
The four approval gaps are closed.
- An opening book asks for the controller part. The policy model gained an operation value `create`, so an opening asks controller plus the field owners and an edit asks only the owners.
- A market data publish has a kind, a raiser and a decider. The trader asks through publish_curve, which raises marketdata.curve_publish for the market risk decider, and writes only with an approved request. republish_curve stays the ungated internal write and is named as the bypass.
- The tenant's Market Risk decides a tenant-wide convention change, never a party's, as a permission is held by an account in a tenant and the queue is tenant-scoped. The journeys and the demo note state it.
- A hold takes a code from a seeded lookup of ten reasons; a missing or unknown code is refused with the lookup's terms, and the shell and the decision panel offer the list.
Open by design: a publish request names no subject, so it authorises whatever config the publisher passes; a curve has no published marker or publisher; the Acme dataset has no curve config of its own; the shell needs a placeholder part token for a request with no parts; only TenantAdmin holds refdata::books:write, so a desk cannot raise a book change; and a put of a book id that no longer exists counts as an opening.