| Agreement | Bonds posted | Cash posted | Total posted | Exposure | Excess / (deficit) | Coverage |
|---|
| Metric | Current | Day / Day | Week / Week | Year / Year |
|---|
| Agreement | Asset | Type | Holding | Post (mv) | Haircut | Collateral value | Cost (bps) | Annual cost | Action |
|---|
Upload your own production data files, map each demo (dummy) field to a field in your file, then flip the toggle to run the whole app on your real data. Uploads and mappings are saved in this browser, so they stay put across reloads and future visits — this is not a one-time import. With the toggle on Dummy data every screen is exactly the built-in demo. On Production data, each data set that has both an uploaded file and a usable mapping serves your data; any set without them falls back to the demo data. Each card below shows which source it is actually serving. Use Download mappings to save every field mapping to a small file, and Import mappings to restore them later — so if you overwrite the app you re-upload your data files and re-import this one file instead of re-mapping every column by hand.
There are two ways to feed this screen, and today it uses the first. The five views — approval blotter, benefits scorecard, scenario board, movement map and shortfall board — present the answer a run already worked out. Today that run is worked out inside the app, so the screen reads nothing of its own and is fed by the same three master data sets the optimiser reads. If your own optimiser works the run out instead, you upload what it produced: data set 12 Optimization outputs (one row per proposed movement) and data set 13 Optimization exclusions & exceptions (one row per record held out or obligation left short). Both now carry a full field list on their own card below and are mapped exactly like every other set. The two tables that lead the screen have their own sets as well — 12.1 Bond sources (internal) and 12.2 Bond destinations (postings out) — and those two are wired: map them and the tables serve your rows instead of the ones the run derived, each falling back on its own. The rules behind a run — data set 11 Optimization rules — are never a file: you set them on the Rules engine tab, and what you set there is the data.
| What the screen shows | Which of your files it comes from |
|---|---|
| The instrument to deliver, its type, where it is held, its market value and its funding cost | Bond inventory |
| The agreement, its counterparty, what it accepts, its haircut, its rating floor and its concentration limit | Agreements static |
| How much each agreement owes, which is what the run has to cover | Margin obligations |
| Haircut applied, collateral value, annual cost, coverage, saving, shortfall | Worked out from the three files above when the app runs the optimiser — or read straight from Optimization outputs when your own optimiser worked the run out |
| What the run held out, and every obligation it could not fill | Worked out by the app’s own run — or read straight from Optimization exclusions & exceptions |
| The rules the run applied, and the run’s own settings | Optimization rules — set on the Rules engine tab, never uploaded |
| Accepted / On hold / Rejected on a movement | None — this is the decision the user takes on the screen, not a value from a file |
The goal is that every figure on every screen either comes from a file you supply, or is worked out from figures that do. This card is read straight out of the application, so it cannot flatter itself. Anything that does not trace back is listed below with the reason it broke, a real value read off the screen so you can see exactly which box is meant, and the answer that clears it — so this is a list of decisions to make, not a list of problems to worry about.
Every value you can see today is demo data — no file has been loaded yet, so the app fills all of it in. That is not what this card counts. It counts whether a box exists for the value to arrive in: a field is green when a card offers a column your file can carry, even though the demo is writing what you see today; it is amber when nothing you upload can change it, because no column feeds it at all.
159 fields on the screens. 157 have a column your file fills — nothing to do. None are left without one — every value the screens read now has somewhere in your file to come from. 2 have no column feeding them — the app writes those itself, so loading your file leaves them exactly as they are.
Your call: nothing to do — you named the file each of these comes from and the field is on that card, so the made-up id is replaced by your column. Say “it is issued on our side after all” for any of them and it goes back to being the demo’s own reference.
trade, and your file supplies it on the Collateral used data card.isin, and your file supplies it on the Bond / securities static, G7 by bond, Optimization outputs, Bond sources (internal), Bond destinations (postings out), Collateral used data, Inventory data cards.tid, and your file supplies it on the MX Trades Data card.Your call: each rule is printed under the field it produces. Check it reads the way your business does it. If one is wrong, tell me the rule and it is changed; if it should come from a file instead, say which card carries it.
The rule to build to: the identifier travels on every file, the description is held once. A holdings row carries the security’s code so the app can find it; everything else about that security — its issuer, coupon, maturity, rating — is read from the one file that owns securities. Each file below shows the label it uses and whether the field is that file’s own key.
Waiting on you (5)
Your call: name the file that is the master list for it — every other file then carries it only to point at the record; or say “different things” and it drops to the settled list below and stops being asked about.
end, on 3 files: Agreements static (as “Agreement end date”) · Bond sources (internal) (as “End Date”) · Bond destinations (postings out) (as “End Date”)start, on 3 files: Bond sources (internal) (as “Start Date”) · Bond destinations (postings out) (as “Start Date”) · Inventory data (as “Trade Start”)g7, on 2 files: G7 industry group (as “G7 industry group”) · G7 by bond (as “G7 industry group”)interestRate, on 2 files: Agreements static (as “Interest / rebate rate”) · Agreement eligibility schedule (as “Interest / rebate rate”)portfolio, on 2 files: Bond sources (internal) (as “Portfolio (Source)”, its own key) · Inventory data (as “Portfolio”)Partly answered — one file still open (1) — what you have already said is recorded below and is not being asked again; only the line marked Still with you needs an answer
maturity, on 4 files: the date a bond redeems and the date a trade ends are two different datesSettled — master named (5) — shown in bold below; every other file carries it only to say which record the row is about
isin, on 7 files: Bond / securities static (as “ISIN”, its own key) · G7 by bond (as “ISIN”) · Optimization outputs (as “ISIN”, its own key) · Bond sources (internal) (as “ISIN”, its own key) · Bond destinations (postings out) (as “ISIN”, its own key) · Collateral used data (as “ISIN / Currency”, its own key) · Inventory data (as “ISIN”, its own key) — master: Bond / securities staticcoupon, on 2 files: Bond / securities static (as “Coupon”) · Inventory data (as “Coupon”) — master: Bond / securities staticissuer, on 2 files: Bond / securities static (as “Issuer”) · Inventory data (as “Issuer Name”) — master: Bond / securities static — the agreement file holds a SELECTION of these values — the issuers it accepts as collateral — not one issuer of its ownlabel, on 2 files: Bond / securities static (as “Instrument Name”) · Inventory data (as “Instrument Name”) — master: Bond / securities staticseniority, on 2 files: Bond / securities static (as “Seniority”) · Inventory data (as “Seniority of Bond”) — master: Inventory data — the securities file does not carry seniority today, so the bond's own seniority is only on the inventory file; say the word and it moves onto the securities file with coupon, sector and maturitySettled — several different things (2) — you have said the files carrying this name do not all mean the same value. Each meaning is listed below with the files that carry it; where a meaning is on more than one file, its master is in bold. Nothing to decide
ccy, on 4 files: a bond's currency, an FX rate's currency and a trade's currency are three different valuesnotional, on 2 files: the size of a bond we hold and the size of a trade are two different amountsSettled — one value for the whole entity (1) — you have said this is set once for the entity, not carried record by record, so every file shows the same value and there is no master to name. Nothing to decide
repccy, on 2 files: Agreements static (as “Reporting currency”) · Collateral used data (as “Reporting Currency”) — one reporting currency for the whole Singapore entity, set once for the entity rather than carried record by record, so every file shows the same value and there is no master to name. The screens already state it in words: the Bond postings table heads its amount columns Posted (USD), Allocated (USD) and Unallocated (USD), and every money figure in the app prints a dollar sign. Those are typed into the app rather than read from this column — left as is on your instruction of 26 Aug 2026Nothing to decide yet — no screen reads it (6) — the files offer this column but no chart, table or pop-up in the app reads it, and no heading states it either, so there is no place two answers could disagree. It becomes a question the day something displays it
rate, on 3 files: Market data — FX rates (as “Rate (USD per 1 unit)”, its own key) · Bond sources (internal) (as “Rate”) · Bond destinations (postings out) (as “Rate”) — no screen reads it todayagKey, on 2 files: Agreements static (as “Type code”, its own key) · Agreement eligibility schedule (as “Type code”, its own key) — no screen reads it todayagname, on 2 files: Optimization outputs (as “Agreement Name”, its own key) · Collateral used data (as “Agreement Name”, its own key) — no screen reads it todayamount, on 2 files: Bond sources (internal) (as “Amount”) · Bond destinations (postings out) (as “Amount”) — no screen reads it todaydirection, on 2 files: Bond sources (internal) (as “Direction”) · Bond destinations (postings out) (as “Direction”) — no screen reads it todayrunId, on 2 files: Optimization outputs (as “Run reference”, its own key) · Optimization exclusions & exceptions (as “Run reference”, its own key) — no screen reads it todaySettled — not one field (1) — two different things that happen to share a name. Nothing to decide; listed so nobody joins them by mistake
code, on 2 files: Counterparty static (as “Counterparty code”) · Currency static (as “Currency code”, its own key) — a counterparty's code and a currency's code are not the same valueaccount on the Show all agreements view of the Trade contributions drill-down (Overview) and name on the Agreement summary table (Overview).issuerCountry on the Concentration risk strip in the agreement pop-up (Overview) and issuerCtry on the security pop-up you get by clicking an ISIN (Inventory Manager).btype on the Bond postings table (Overview) and type on the security pop-up you get by clicking an ISIN (Inventory Manager) and the security pop-up you get by clicking an ISIN (Overview).Waiting on you (11)
Your call: pick the one wording for it, or say leave them and the screens keep their own words.
account appears as Agreement on the Show all agreements view of the Trade contributions drill-down (Overview) · Agreement Name on the Bond postings table (Overview)industry appears as Industry Classification on the Column display view of the Bond inventory table (Inventory Manager) · Industry classification on the security pop-up you get by clicking an ISIN (Inventory Manager) and the security pop-up you get by clicking an ISIN (Overview)issuer appears as Issuer on the Eligibility schedule in the agreement pop-up (Overview) and the security pop-up you get by clicking an ISIN (Inventory Manager) · Issuer Name on the Column display view of the Bond inventory table (Inventory Manager)issuerCtry appears as Country of Issuer on the Time series of inventory table (Inventory Manager) · Issuer Country on the Column display view of the Bond inventory table (Inventory Manager) · Issuer country on the security pop-up you get by clicking an ISIN (Inventory Manager)label appears as Instrument Name on the Column display view of the Bond inventory table (Inventory Manager) and the Time series of inventory table (Inventory Manager) · Security on the Bond postings table (Overview)maturity appears as Maturity on the Bond postings table (Overview) and the Trade contributions drill-down (Overview) · Maturity date on the security pop-up you get by clicking an ISIN (Inventory Manager) and the security pop-up you get by clicking an ISIN (Overview)name appears as Agreement on the Agreement summary table (Overview) · Instrument name on the security pop-up you get by clicking an ISIN (Inventory Manager) and the security pop-up you get by clicking an ISIN (Overview)sector appears as Sector on the Bond postings table (Overview) · Sector of Issuer on the Column display view of the Bond inventory table (Inventory Manager) · Sector of issuer on the security pop-up you get by clicking an ISIN (Inventory Manager) and the security pop-up you get by clicking an ISIN (Overview)seniority appears as Seniority on the Eligibility schedule in the agreement pop-up (Overview) and the security pop-up you get by clicking an ISIN (Inventory Manager) · Seniority of Bond on the Column display view of the Bond inventory table (Inventory Manager)start appears as Start date on the Dates & Status card in the agreement pop-up (Overview) · Trade start on the security pop-up you get by clicking an ISIN (Inventory Manager) and the security pop-up you get by clicking an ISIN (Overview)type appears as Agreement type on the Agreement Admin card in the agreement pop-up (Overview) · Type on the security pop-up you get by clicking an ISIN (Inventory Manager) and the security pop-up you get by clicking an ISIN (Overview)Settled — different labels are right (2) — you have already said this name covers more than one value, so the screens must not be made to read the same. Nothing to decide
ccy appears as Bond Ccy on the Time series of inventory table (Inventory Manager) · Ccy on the Trade contributions drill-down (Overview) · Instrument Ccy on the Column display view of the Bond inventory table (Inventory Manager) · Instrument currency on the security pop-up you get by clicking an ISIN (Inventory Manager) and the security pop-up you get by clicking an ISIN (Overview) — a bond's currency, an FX rate's currency and a trade's currency are three different valuesnotional appears as Bond Notional (mm) on the Column display view of the Bond inventory table (Inventory Manager) · Notional (USD) on the Trade contributions drill-down (Overview) — the size of a bond we hold and the size of a trade are two different amounts| Label on screen | Stored as | Card field to map it to | Which chart or table shows it | Direct or computed | How it is worked out | What it shows today | Traces to your data? |
|---|---|---|---|---|---|---|---|
| Agreement Name | account | none yet | the Bond postings table Overview | Computed | Worked out before it is shown: Label, with the wording around it. | CSG_Amberlaine Bank_RIM↗ | yes |
| Trade # | trade | trade | the Bond postings table Overview | Computed | Worked out before it is shown: Worked out from more than one stored value. | TRD-600001 | yes |
| ISIN | isin | isin | the Bond postings table Overview | Computed | Worked out before it is shown: Built by the app's genISIN rule. | USV8J7IDADZ2 | yes |
| Security | label | label | the Bond postings table Overview | Computed | Worked out before it is shown: Taken straight from name. | US TREASURY N/B 3.125% 06/26 | yes |
| Type | btype | btype | the Bond postings table Overview | Direct | Taken straight from type. | UST | yes |
| Sector | sector | sector | the Bond postings table Overview | Direct | Taken straight from sector. | Sovereign | yes |
| Counterparty | cpty | cpty | the Bond postings table Overview | Direct | Taken straight from counterparty. | Amberlaine Bank | yes |
| Agreement Type | — | n/a — worked out | the Bond postings table Overview | Computed | Worked out from more than one stored value. | Bilateral CSA IM | yes |
| Custodian | custodian | custodian | the Bond postings table Overview | Direct | Taken straight from custodian (shown by its display name). | Euroclear | yes |
| Source | source | source | the Bond postings table Overview | Direct | Taken straight from source. | CT | yes |
| Maturity | maturity | maturity | the Bond postings table Overview | Direct | Taken straight from maturity. | 24 Jun 2026 | yes |
| Product | prod | prod | the Trade contributions drill-down Overview | Direct | Taken straight from product. | Cleared OIS | yes |
| Trade ID | tid | tid | the Trade contributions drill-down Overview | Computed | Worked out before it is shown: Worked out from more than one stored value. | MX163952437 | yes |
| Trade date | tradeDate | tradeDate | the Trade contributions drill-down Overview | Direct | Taken straight from trade date. | 07 Jan 2023 | yes |
| Maturity | maturity | maturity | the Trade contributions drill-down Overview | Direct | Taken straight from maturity. | 24 Jun 2026 | yes |
| Notional (USD) | notional | notional | the Trade contributions drill-down Overview | Direct | Taken straight from notional (usd). | $15.05B | yes |
| Ccy | ccy | ccy | the Trade contributions drill-down Overview | Direct | Taken straight from ccy. | JPY | yes |
| MtM (USD) | mtmUsd | mtmUsd | the Trade contributions drill-down Overview | Direct | Taken straight from mtm (usd). | $60.2M | yes |
| Agreement | account | none yet | the Show all agreements view of the Trade contributions drill-down Overview | Computed | Worked out before it is shown: Label, with the wording around it. | GMRA | yes |
| Agreement | name | name | the Agreement summary table Overview | Computed | Worked out before it is shown: Taken straight from name. | GMRA | yes |
| Total exposure | exposure | none yet | the Agreement summary table Overview | Computed | Worked out before it is shown: Total exposure multiplied by the app's own w value. | $647.9M | yes |
| Call / obligation | obligation | obligation | the Agreement summary table Overview | Computed | Worked out before it is shown: Call / obligation multiplied by the app's own w value. | $635.9M | yes |
| Received (in) | received | received | the Agreement summary table Overview | Computed | Worked out before it is shown: Received (in) multiplied by the app's own w value. | $672.4M | yes |
| Margin call | marginCall | marginCall | the Agreement summary table Overview | Computed | Worked out before it is shown: Margin call multiplied by the app's own w value. | $37.0M | yes |
| Total | — | n/a — worked out | the Agreement summary table Overview | Computed | Bonds (posted) plus cash (posted). | $598.9M | yes |
| Bonds (Posted) | bond | bondRating (different name, same thing) | the Agreement summary table Overview | Computed | Worked out before it is shown: Bonds (posted) multiplied by the app's own w value. | $587.9M | yes |
| Cash (Posted) | cash | cash | the Agreement summary table Overview | Computed | Worked out before it is shown: Cash (posted) multiplied by the app's own w value. | $11.1M | yes |
| Total | used | none yet | the Agreement summary table Overview | Computed | Worked out before it is shown: Total multiplied by the app's own w value. | $598.9M | yes |
| Bonds (Allocated) | bondUsed | none yet | the Agreement summary table Overview | Computed | Worked out before it is shown: Bonds (allocated) multiplied by the app's own w value. | $587.9M | yes |
| Cash (Allocated) | cashUsed | cash (different name, same thing) | the Agreement summary table Overview | Computed | Worked out before it is shown: Cash (allocated) multiplied by the app's own w value. | $11.1M | yes |
| Unallocated | unalloc | none yet | the Agreement summary table Overview | Computed | Worked out before it is shown: Built by the app's unallocOf rule. | $0K | yes |
| Surplus | surplus | none yet | the Agreement summary table Overview | Computed | Worked out before it is shown: Built by the app's surplusOf rule. | $562.0M | yes |
| DoD (total allocated) | dod | none yet | the Agreement summary table Overview | Computed | Worked out before it is shown: Total minus the app's own u1 value. | ▼ -$21.9M (-3.5%) | yes |
| WoW (total allocated) | wow | none yet | the Agreement summary table Overview | Computed | Worked out before it is shown: Total minus the app's own u7 value. | ▼ -$39.4M (-6.2%) | yes |
| MoM (total allocated) | mom | none yet | the Agreement summary table Overview | Computed | Worked out before it is shown: Total minus the app's own u30 value. | ▲ $112.7M (23.2%) | yes |
| Threshold | threshold | threshold | the Agreement summary table Overview | Computed | Worked out before it is shown: Threshold multiplied by the app's own w value. | $12.0M | yes |
| Expected post | expPost | none yet | the Agreement summary table Overview | Computed | Worked out before it is shown: Depends on the app's own mc value — one of two values, chosen by a condition. | $37.0M | no column feeds it |
| Expected collect | — | n/a — worked out | the Agreement summary table Overview | Computed | Depends on exp collect — one of two values, chosen by a condition. | $0K | no column feeds it |
| ITM Exposure | itmExp | none yet | the Agreement summary table Overview | Computed | Worked out before it is shown: Itm exposure multiplied by the app's own w value. | $228.2M | yes |
| OTM Exposure | otmExp | none yet | the Agreement summary table Overview | Computed | Worked out before it is shown: Otm exposure multiplied by the app's own w value. | -$145.9M | yes |
| Dispute Value | disputeVal | none yet | the Agreement summary table Overview | Computed | Worked out before it is shown: Dispute value multiplied by the app's own w value. | $427K | yes |
| Dispute Age | disputeAge | disputeAge | the Agreement summary table Overview | Direct | Taken straight from dispute age (zero if it is not supplied). | 1d | yes |
| Base CCY | baseCcy | baseCcy | the Agreement summary table Overview | Direct | Taken straight from base ccy (a dash if it is not supplied). | USD | yes |
| Base Total Exp. | baseTotalExp | none yet | the Agreement summary table Overview | Computed | Worked out before it is shown: Base total exp. multiplied by the app's own w value. | $374.0M | yes |
| Base Call Amt | baseCallAmt | none yet | the Agreement summary table Overview | Computed | Worked out before it is shown: Base call amt multiplied by the app's own w value. | $21.3M | yes |
| Concentration limits group name | group | group | the Concentration risk strip in the agreement pop-up Overview | Direct | Taken straight from group. | — | yes |
| Limit type | limitType | limitType | the Concentration risk strip in the agreement pop-up Overview | Direct | Taken straight from limit type. | Max | yes |
| Limit type granularity | granularity | granularity | the Concentration risk strip in the agreement pop-up Overview | Direct | Taken straight from granularity. | — | yes |
| Limit | limit | limit | the Concentration risk strip in the agreement pop-up Overview | Direct | Taken straight from limit. | 20% | yes |
| Limit unit | unit | unit | the Concentration risk strip in the agreement pop-up Overview | Direct | Taken straight from unit. | — | yes |
| Asset class | assetClass | assetClass | the Concentration risk strip in the agreement pop-up Overview | Direct | Taken straight from asset class. | Sovereign | yes |
| Asset type | assetType | assetType | the Concentration risk strip in the agreement pop-up Overview | Direct | Taken straight from asset type. | Government Bond | yes |
| Issuer sector | issuerSector | issuerSector | the Concentration risk strip in the agreement pop-up Overview | Direct | Taken straight from issuer sector. | Sovereign | yes |
| Issuer country | issuerCountry | issuerCountry | the Concentration risk strip in the agreement pop-up Overview | Direct | Taken straight from issuer country. | US, AU, CA, FR, DE, GB, SG | yes |
| Basis | basis | basis | the Concentration risk strip in the agreement pop-up Overview | Direct | Taken straight from basis. | Contract Collateral Basis | yes |
| MTM | — | n/a — worked out | the Exposure card in the agreement pop-up Overview | Computed | Mtm (shown formatted). | $150.4M | yes |
| Independent Amount (IA) | — | n/a — worked out | the Exposure card in the agreement pop-up Overview | Computed | Obligation minus mtm (shown formatted). | $50.1M | yes |
| Agreement type | type | none yet | the Agreement Admin card in the agreement pop-up Overview | Computed | Worked out before it is shown: Depends on the row — one of two values, chosen by a condition. | Bilateral CSA IM | yes |
| Margin type | marginType | marginType | the Agreement Admin card in the agreement pop-up Overview | Direct | Taken straight from margin type (a dash if it is not supplied). | Initial Margin (IM) | yes |
| Valuation frequency | valuationFreq | valuationFreq | the Agreement Admin card in the agreement pop-up Overview | Direct | Taken straight from valuation freq (a dash if it is not supplied). | Daily (T+0) | yes |
| Reciprocity | reciprocal | reciprocal | the Agreement Admin card in the agreement pop-up Overview | Direct | Taken straight from reciprocal (a dash if it is not supplied). | Yes | yes |
| Benchmark rate | benchmarkRate | benchmarkRate | the Agreement Admin card in the agreement pop-up Overview | Direct | Taken straight from benchmark rate (a dash if it is not supplied). | SOFR | yes |
| Start date | start | start | the Dates & Status card in the agreement pop-up Overview | Direct | Taken straight from start (a dash if it is not supplied). | 10 Apr 2026 | yes |
| End date | end | end | the Dates & Status card in the agreement pop-up Overview | Direct | Taken straight from end (a dash if it is not supplied). | 14 Mar 2031 | yes |
| ABC MTA | — | n/a — worked out | the Margin Call Summary card in the agreement pop-up Overview | Computed | Abc mta when the record carries one, otherwise the app's own mta value. | $500K | yes |
| Counterparty MTA | — | n/a — worked out | the Margin Call Summary card in the agreement pop-up Overview | Computed | Cpty mta when the record carries one, otherwise the app's own mta value. | $500K | yes |
| Rounding (delivery) | roundingDelivery | roundingDelivery | the Margin Call Summary card in the agreement pop-up Overview | Direct | Taken straight from rounding delivery (a dash if it is not supplied). | DOWN | yes |
| Rounding (return) | roundingReturn | roundingReturn | the Margin Call Summary card in the agreement pop-up Overview | Direct | Taken straight from rounding return (a dash if it is not supplied). | DOWN | yes |
| Collateral balance (posted) | — | n/a — worked out | the Margin Call Calculation card in the agreement pop-up Overview | Computed | Posted (shown formatted). | $174.0M | yes |
| Margin call / surplus | — | n/a — worked out | the Margin Call Calculation card in the agreement pop-up Overview | Computed | Margin call multiplied by the app's own wt value, with the plus or minus sign dropped (shown formatted). | $26.5M | yes |
| Direction | — | n/a — worked out | the Margin Call Calculation card in the agreement pop-up Overview | Computed | Depends on the row — one of two values, chosen by a condition (shown formatted). | Call — deliver collateral | yes |
| Total exposure | — | n/a — worked out | the Margin Call Calculation card in the agreement pop-up Overview | Computed | Obligation multiplied by the app's own wt value (shown formatted). | $647.9M | yes |
| ABC threshold | abcThreshold | abcThreshold | the Margin Call Calculation card in the agreement pop-up Overview | Direct | Taken straight from abc threshold (a dash if it is not supplied). | $0 | yes |
| Cpty threshold | cptyThreshold | cptyThreshold | the Margin Call Calculation card in the agreement pop-up Overview | Direct | Taken straight from cpty threshold (a dash if it is not supplied). | $0 | yes |
| Notification time | — | n/a — worked out | the Call Schedule card in the agreement pop-up Overview | Computed | The agreement's own notif time when it carries one, otherwise the standard one. | 08:00 SGT | yes |
| Resolution time | — | n/a — worked out | the Call Schedule card in the agreement pop-up Overview | Computed | Resolution time when the record carries one, otherwise notif by. | T+1 14:00 NY | yes |
| Time zone | timezone | timezone | the Call Schedule card in the agreement pop-up Overview | Direct | Taken straight from timezone (a dash if it is not supplied). | America/New_York | yes |
| Holiday centre(s) | holidayCentres | holidayCentres | the Call Schedule card in the agreement pop-up Overview | Direct | Taken straight from holiday centres (a dash if it is not supplied). | New York, London | yes |
| Settlement delay | settlementDelay | settlementDelay | the Call Schedule card in the agreement pop-up Overview | Direct | Taken straight from settlement delay (a dash if it is not supplied). | 0d | yes |
| Interest calc method | interestCalc | interestCalc | the Collateral Rules card in the agreement pop-up Overview | Direct | Taken straight from interest calc (a dash if it is not supplied). | SOFR | yes |
| Calculation rule | calculationRule | calculationRule | the Collateral Rules card in the agreement pop-up Overview | Direct | Taken straight from calculation rule (a dash if it is not supplied). | Simple | yes |
| Interest settlement date | interestSettlementDate | interestSettlementDate | the Collateral Rules card in the agreement pop-up Overview | Direct | Taken straight from interest settlement date (a dash if it is not supplied). | First of the Month | yes |
| Allow negative rate | allowNegRate | allowNegRate | the Collateral Rules card in the agreement pop-up Overview | Direct | Taken straight from allow neg rate (a dash if it is not supplied). | No | yes |
| Group | — | n/a — worked out | the Concentration risk strip in the agreement pop-up Overview | Computed | Built by the app's cGet rule. | IM Standard Concentration Limits | yes |
| Granularity | — | n/a — worked out | the Concentration risk strip in the agreement pop-up Overview | Computed | Built by the app's cGet rule. | Per Issuer Country | yes |
| Currency | currency | currency | the Eligibility schedule in the agreement pop-up Overview | Direct | Taken straight from currency (a dash if it is not supplied). | AUD, CAD, EUR, GBP, JPY, SGD, USD | yes |
| Interest / rebate rate | interestRate | interestRate | the Eligibility schedule in the agreement pop-up Overview | Direct | Taken straight from interest rate (a dash if it is not supplied). | SOFR | yes |
| Issuer | issuer | issuer | the Eligibility schedule in the agreement pop-up Overview | Direct | Taken straight from issuer (a dash if it is not supplied). | US Treasury, Agency, Supra-National | yes |
| Seniority | seniority | seniority | the Eligibility schedule in the agreement pop-up Overview | Direct | Taken straight from seniority (a dash if it is not supplied). | Unsubordinated | yes |
| Security rating | — | n/a — worked out | the Eligibility schedule in the agreement pop-up Overview | Computed | Security rating when the record carries one, otherwise rating floor2. | >= A- / A3 / A- (S&P/Moody/Fitch) | yes |
| Time to maturity | timeToMaturity | timeToMaturity | the Eligibility schedule in the agreement pop-up Overview | Direct | Taken straight from time to maturity (a dash if it is not supplied). | <= 25 years | yes |
| Haircut schedule | haircutSchedule | haircutSchedule | the Eligibility schedule in the agreement pop-up Overview | Direct | Taken straight from haircut schedule (a dash if it is not supplied). | 0% — no haircut | yes |
| Exclusions | exclusions | exclusions | the Eligibility schedule in the agreement pop-up Overview | Direct | Taken straight from exclusions (a dash if it is not supplied). | Convertibles; subordinated debt; own-issue & affiliate paper | yes |
| Currency code | — | n/a — worked out | the Static Data reference screens Overview | Computed | Worked out from more than one stored value. | — | yes |
| Curve / index name | — | n/a — worked out | the Static Data reference screens Overview | Computed | Worked out from more than one stored value. | — | yes |
| Day count | — | n/a — worked out | the placeholder block at the foot of the security pop-up Overview | Computed | Worked out from more than one stored value. | — to be provided — | yes |
| Instrument name | name | name | the security pop-up you get by clicking an ISIN Overview | Computed | Worked out before it is shown: Taken straight from name (shown formatted). | US TREASURY N/B 3.125% 06/26 | yes |
| ISIN | isin | isin | the security pop-up you get by clicking an ISIN Overview | Computed | Worked out before it is shown: Built by the app's genISIN rule (shown formatted). | USV8J7IDADZ2 | yes |
| Type | type | none yet | the security pop-up you get by clicking an ISIN Overview | Computed | Worked out before it is shown: Depends on the row — one of two values, chosen by a condition (shown formatted). | UST | yes |
| Industry classification | industry | industry | the security pop-up you get by clicking an ISIN Overview | Direct | Taken straight from industry (shown formatted). | Sovereign | yes |
| Sector of issuer | sector | sector | the security pop-up you get by clicking an ISIN Overview | Direct | Taken straight from sector (shown formatted). | Government | yes |
| Classification Level 4 name | l4 | l4 | the security pop-up you get by clicking an ISIN Overview | Direct | Taken straight from l4 (shown formatted). | Others | yes |
| BICS Level 2 Industry Group Name | bics | bics | the security pop-up you get by clicking an ISIN Overview | Direct | Taken straight from bics (shown formatted). | Others | yes |
| Issuer Industry | issuerIndustry | issuerIndustry | the security pop-up you get by clicking an ISIN Overview | Direct | Taken straight from issuer industry (shown formatted). | GOVT NATIONAL | yes |
| G7 Industry group | g7 | g7 | the security pop-up you get by clicking an ISIN Overview | Direct | Taken straight from g7 (shown formatted). | Others | yes |
| Instrument currency | ccy | ccy | the security pop-up you get by clicking an ISIN Overview | Direct | Taken straight from ccy (shown formatted). | USD | yes |
| Coupon | — | n/a — worked out | the security pop-up you get by clicking an ISIN Overview | Computed | Coupon, with the wording around it (shown formatted). | 3.125% · Bullet | yes |
| Clearer | clearer | clearer | the security pop-up you get by clicking an ISIN Overview | Direct | Taken straight from clearer (shown formatted). | Euroclear | yes |
| Issuer rating | — | n/a — worked out | the security pop-up you get by clicking an ISIN Overview | Computed | Issuer rating, with the wording around it (shown formatted). | AAA | yes |
| Bond rating | — | n/a — worked out | the security pop-up you get by clicking an ISIN Overview | Computed | Bond rating, with the wording around it (shown formatted). | AAA | yes |
| Bond notional | — | n/a — worked out | the security pop-up you get by clicking an ISIN Overview | Computed | Notional (usd) and ccy, with the wording around it (shown formatted). | 46.7 mm USD | yes |
| MTM of notional | — | n/a — worked out | the security pop-up you get by clicking an ISIN Overview | Computed | Mtm and ccy, with the wording around it (shown formatted). | 42.7 mm USD (price 91.48) | yes |
| Issue date | issueDate | none yet | the security pop-up you get by clicking an ISIN Overview | Computed | Worked out before it is shown: Built by the app's instrIssueDate rule (shown formatted). | 24 Jun 2020 | yes |
| Trade start | start | start | the security pop-up you get by clicking an ISIN Overview | Direct | Taken straight from start (shown formatted). | 10 Apr 2026 | yes |
| Maturity date | maturity | maturity | the security pop-up you get by clicking an ISIN Overview | Direct | Taken straight from maturity (shown formatted). | 24 Jun 2026 | yes |
| Portfolio | portfolio | portfolio | the Column display view of the Bond inventory table Inventory Manager | Direct | Taken straight from portfolio. | Treasury ALM | yes |
| Business Line | bizline | bizline | the Column display view of the Bond inventory table Inventory Manager | Direct | Taken straight from business line. | Repo & Collateral | yes |
| Holding | holding | holding | the Column display view of the Bond inventory table Inventory Manager | Direct | Taken straight from holding (shown by its display name). | Internal | yes |
| Instrument Name | label | label | the Column display view of the Bond inventory table Inventory Manager | Direct | Taken straight from label. | US TREASURY N/B 3.625% 03/32 | yes |
| ISIN | isin | isin | the Column display view of the Bond inventory table Inventory Manager | Direct | Taken straight from isin. | USJN7J29IZS7 | yes |
| Instrument Ccy | ccy | ccy | the Column display view of the Bond inventory table Inventory Manager | Direct | Taken straight from ccy. | USD | yes |
| Bond Notional (mm) | notional | notional | the Column display view of the Bond inventory table Inventory Manager | Direct | Taken straight from bond notional (mm). | 2,136.7 | yes |
| Issuer Name | issuer | issuer | the Column display view of the Bond inventory table Inventory Manager | Direct | Taken straight from issuer name. | US TREASURY N/B | yes |
| Issuer Country | issuerCtry | issuerCtry | the Column display view of the Bond inventory table Inventory Manager | Direct | Taken straight from issuer ctry. | United States | yes |
| Seniority of Bond | seniority | seniority | the Column display view of the Bond inventory table Inventory Manager | Direct | Taken straight from seniority of bond. | Senior Unsecured | yes |
| Callable / Coupon | — | n/a — worked out | the Column display view of the Bond inventory table Inventory Manager | Computed | Coupon, with the wording around it. | Bullet · 3.625% | yes |
| Clearer | clearer | clearer | the Column display view of the Bond inventory table Inventory Manager | Direct | Taken straight from clearer. | Fedwire | yes |
| Sector of Issuer | sector | sector | the Column display view of the Bond inventory table Inventory Manager | Direct | Taken straight from sector of issuer. | Government | yes |
| Industry Classification | industry | industry | the Column display view of the Bond inventory table Inventory Manager | Direct | Taken straight from industry classification. | Sovereign | yes |
| Issuer Rating | issuerRating | issuerRating | the Column display view of the Bond inventory table Inventory Manager | Direct | Taken straight from issuer rating. | AA+ | yes |
| Bond Rating | bondRating | bondRating | the Column display view of the Bond inventory table Inventory Manager | Direct | Taken straight from bond rating. | AA+ | yes |
| MTM of Notional (mm) | mtm | mtm | the Column display view of the Bond inventory table Inventory Manager | Direct | Taken straight from mtm of notional (mm). | 2,104.4 | yes |
| ISIN | isin | isin | the Time series of inventory table Inventory Manager | Direct | Taken straight from isin. | USJN7J29IZS7 | yes |
| Instrument Name | label | label | the Time series of inventory table Inventory Manager | Direct | Taken straight from label. | US TREASURY N/B 3.625% 03/32 | yes |
| Country of Issuer | issuerCtry | issuerCtry | the Time series of inventory table Inventory Manager | Direct | Taken straight from issuer ctry. | United States | yes |
| Bond Ccy | ccy | ccy | the Time series of inventory table Inventory Manager | Direct | Taken straight from ccy. | USD | yes |
| Day count | — | n/a — worked out | the placeholder block at the foot of the security pop-up Inventory Manager | Computed | Worked out from more than one stored value. | — to be provided — | yes |
| Instrument name | name | name | the security pop-up you get by clicking an ISIN Inventory Manager | Direct | Taken straight from name (shown formatted). | US TREASURY N/B 3.625% 03/32 | yes |
| ISIN | isin | isin | the security pop-up you get by clicking an ISIN Inventory Manager | Direct | Taken straight from isin (shown formatted). | USJN7J29IZS7 | yes |
| Issuer | issuer | issuer | the security pop-up you get by clicking an ISIN Inventory Manager | Direct | Taken straight from issuer name (shown formatted). | SINGAPORE GOVT | yes |
| Type | type | none yet | the security pop-up you get by clicking an ISIN Inventory Manager | Computed | Worked out before it is shown: Depends on the app's own cat value — one of two values, chosen by a condition (shown formatted). | Govies | yes |
| Issuer country | issuerCtry | issuerCtry | the security pop-up you get by clicking an ISIN Inventory Manager | Direct | Taken straight from issuer ctry (shown formatted). | United States | yes |
| Industry classification | industry | industry | the security pop-up you get by clicking an ISIN Inventory Manager | Direct | Taken straight from industry classification (shown formatted). | Sovereign | yes |
| Sector of issuer | sector | sector | the security pop-up you get by clicking an ISIN Inventory Manager | Direct | Taken straight from sector of issuer (shown formatted). | Government | yes |
| Classification Level 4 name | l4 | l4 | the security pop-up you get by clicking an ISIN Inventory Manager | Direct | Taken straight from l4 (shown formatted). | Others | yes |
| BICS Level 2 Industry Group Name | bics | bics | the security pop-up you get by clicking an ISIN Inventory Manager | Direct | Taken straight from bics (shown formatted). | Others | yes |
| Issuer Industry | issuerIndustry | issuerIndustry | the security pop-up you get by clicking an ISIN Inventory Manager | Direct | Taken straight from issuer industry (shown formatted). | GOVT NATIONAL | yes |
| G7 Industry group | g7 | g7 | the security pop-up you get by clicking an ISIN Inventory Manager | Direct | Taken straight from g7 (shown formatted). | Others | yes |
| Instrument currency | ccy | ccy | the security pop-up you get by clicking an ISIN Inventory Manager | Direct | Taken straight from ccy (shown formatted). | SGD | yes |
| Coupon | — | n/a — worked out | the security pop-up you get by clicking an ISIN Inventory Manager | Computed | Coupon, with the wording around it (shown formatted). | 3% · Bullet | yes |
| Seniority | seniority | seniority | the security pop-up you get by clicking an ISIN Inventory Manager | Direct | Taken straight from seniority of bond (shown formatted). | Senior Unsecured | yes |
| Clearer | clearer | clearer | the security pop-up you get by clicking an ISIN Inventory Manager | Direct | Taken straight from clearer (shown formatted). | Fedwire | yes |
| Issuer rating | — | n/a — worked out | the security pop-up you get by clicking an ISIN Inventory Manager | Computed | Issuer rating, with the wording around it (shown formatted). | AA+ | yes |
| Bond rating | — | n/a — worked out | the security pop-up you get by clicking an ISIN Inventory Manager | Computed | Bond rating, with the wording around it (shown formatted). | AA+ | yes |
| Bond notional | — | n/a — worked out | the security pop-up you get by clicking an ISIN Inventory Manager | Computed | Bond notional (mm) and ccy, with the wording around it (shown formatted). | 837.5 mm SGD | yes |
| MTM of notional | — | n/a — worked out | the security pop-up you get by clicking an ISIN Inventory Manager | Computed | Mtm of notional (mm) and ccy, with the wording around it (shown formatted). | 826.7 mm SGD (price 98.71) | yes |
| Issue date | issueDate | none yet | the security pop-up you get by clicking an ISIN Inventory Manager | Computed | Worked out before it is shown: Built by the app's instrIssueDate rule (shown formatted). | 12 Feb 2027 | yes |
| Trade start | start | start | the security pop-up you get by clicking an ISIN Inventory Manager | Direct | Taken straight from start (shown formatted). | 25 Sept 2025 | yes |
| Maturity date | maturity | maturity | the security pop-up you get by clicking an ISIN Inventory Manager | Direct | Taken straight from maturity (shown formatted). | 12 Feb 2030 | yes |
The cards follow the canonical data catalog (the same master list documented on Requirements 2) — the 15 top-level sets, with the user-maintained set (7) broken out into its eight datasets (7.1–7.8), each its own card. Sets tagged LIVE are wired into the screens today, so uploading + mapping them changes the app immediately. The other sets accept an upload and a saved mapping now; their live wiring is delivered as each set is connected.
A build & test specification detailed enough to rebuild a replica of the whole app from scratch. It covers the underlying data, the logic and the interactive behaviour. It is organised into Epics — one per feature area. Each epic opens with a collapsed “About” write-up: expand it for context and key terms. Under that sits a set of User stories — “As a user, I can …”. Every user story is a fold — click its title to open it. Inside a story you get its requirements: the exact fields, formulas, defaults and persistence keys the build must reproduce. At the end of every story is a second fold, 🧪 Test cases. It holds the scenarios that prove that story. Each scenario is a Do step and a Verify step. Use ⊕ Expand all / ⊖ Collapse all above to open or close everything at once. Jump to any epic from the Contents below. Overview 2 (the workspace builder, Epic 9) has its own tab, “Requirements 2 · Overview 2”. This tab (Requirements 1) covers everything else. No prior knowledge of the system is needed.
Reference library (build appendices, not epics): A · Data model & conventions · B · Glossary & data sources · C · Table controls · D · Tooltips, hovers & dynamic text · E · Field → data model lineage
Standing log: Open questions & decisions. It holds what is still to be confirmed, and the decisions already made.
Every open question and pending decision now lives on its own tab. It is ❓ Open questions, one register of everything still to be confirmed. It gathers questions from everyone who raised one. The product owner raises business setup: roles, volumes, service levels and connected systems. The testers raise figures that do not yet reconcile, from the test pack’s Gap Log. The data-model review raises fields with no agreed data source, from §E.14. Each row states the question in plain English. It names who raised it, who must answer it, and its status. Rows are never deleted — only moved from open to decided.
Open the ❓ Open questions tab for the full list.
To get here: open the app. This epic applies to the whole screen. That means the top row of tabs, and the top-right controls.
/j-collateral?embed=1 for Overview. It loads /j-collateral?embed=1&widgets=1 for Overview 2 — the same page in workspace-builder mode. That mode adds the palette, close buttons, multiple workspaces, multi-instance widgets and emitter/receiver linking, and persists to collat-workspaces-v1. When embedded, each page hides its own top bar (the host owns the title + theme toggle)./j-inventory, inside its own screen, when the sidebar entry is opened. The Overview 2 Inventory Manager widget loads the same address the same way.{type:"theme", mode:"light"|"dark"} to both iframes. The Overview page passes the same message on to the Inventory Manager it holds. So the theme travels two hops. The Layout selector posts {type:"setLayout", lay:"tabs"|"split"|"drawer"|"single"} to the Overview iframe. Each iframe applies the message on receipt. The Layout selector is hidden while Overview 2 is active (widget mode has no fixed layouts).?only=<tab>). Opening the shell with a query like /j-collateraldemo?embed=1&only=rules renders only that one tab. The top bar and the tab strip are hidden. The other tab panels stay hidden. The heavy Overview iframes are not loaded at all. This is how the Rules engine widget in Overview 2 reuses the real Rules engine. That widget lives in /j-collateral?widgets=1 and embeds /j-collateraldemo?only=rules. So there is one source of truth. Runs and rules edited in the widget, and through the Overview sidebar’s Optimization Rules entry, are the same records. (There is no longer a top-level Rules engine tab — see the 01 Oct 2026 change log entry.)collat-theme-ds2 (values "light" / "dark"). If the key is absent the page is light. No data-theme attribute means light.To get here: click the Overview tab (it is the default). The dashboard has four parts. A left sidebar of agreement types. A row of KPI cards. The charts. And a bond-postings panel docked at the bottom.
These same nine figures are also used in: 1) US2.4 — the docked Agreement summary table. That table shows them a row at a time, instead of book-wide. Where each one comes from, and how to check it, is written up once. It is in Appendix E.1 · the Figure check sheet. Do not repeat those rules here.
Some agreements are watched more closely than the rest. The user names them on User maintenance → Special agreements, and tags each one Zero-interest CSA or Korean CSA. A tagged agreement is a special agreement, of any agreement type. This filter cuts the blotter down to the postings booked to those agreements. It offers the tags that select agreements; Korean CSA drops its agreements from the app instead, so it is never a filter option here.
The Postings view lists every posting across everything selected. Say the same bond was posted to the same agreement on several dates. It then appears once per posting date. Clicking an individual agreement name narrows this view to that agreement’s own postings. It then shows that agreement’s share of each amount. See US2.6 below. Postings by bonds answers a narrower question about a single agreement. That question is: “which bonds have we posted to this agreement, or to this triparty repo agent?” And: “how much of each is posted, allocated and unallocated?” It answers with one row per bond. That bond’s postings are added together.
Summary is per agreement type. Detailed is per individual agreement. Under Triparty the individual rows are the counterparties the agents handle, because there are no triparty agreement codes. So switching an agent off in the sidebar takes its counterparties out of the list. Sortable/filterable; “Call / obligation” & exposure cells drill (§7), posting cells open Postings. The two levels show different columns. The exposure, dispute and base-currency columns appear only at the Detailed level. They are not on the type-level Summary.
Where these figures come from, and how to check each one is written up once. See Appendix E.1 · the Figure check sheet. It works each rule through with the app’s own live numbers. The same figures are also used in: 1) US2.3 — the KPI banner, which totals them across the whole book. 2) US3.2 — the Daily Exposure Report. That report repeats these seven detailed-level columns, and adds its own call-handling ones.
How these columns are headed. The posting and allocated figures are not six separate headings in one row. The header is two rows deep. The upper row carries a single centred heading, Total Posting, across the three columns it owns. Beside it sits Total Allocated, across its own three. The lower row names the three columns under each heading. Under the first: Total, Bonds (Posted), Cash (Posted). Under the second: Total, Bonds (Allocated), Cash (Allocated). The first column under each heading is called just Total. The heading above it already says which total it is. Sometimes a column has to be named on its own. That happens in the column chooser, the filter title, and this document. It is then written as the heading and the column together, e.g. Total Posting · Total. Every other column has no heading above it, so its name occupies both rows. That covers Agreement, Total exposure, Margin call, Unallocated, Surplus and the rest. Sorting, filtering, hiding, reordering and pinning work on the lower-row columns exactly as before. The heading is a label only, and is never clickable. The column chooser may hide or move part of a group. The heading then shrinks to span only the columns still sitting together. It never spans a column that does not belong to it.
Posting vs Allocated columns: Total Posting · Total = the collateral posted (Bonds (Posted) + Cash (Posted)). Total allocated is how much of that posting is actually consumed covering the exposure. It is capped at what was posted — the smaller of Total posting and Total exposure. Bonds (Allocated) / Cash (Allocated) split Total allocated in the same proportion as the posting. So they add back to Total allocated. Unallocated = Total posting − Total allocated (the collateral posted but not consumed; never negative). Surplus = Total allocated − Margin call. DoD / WoW / MoM show the change in Total allocated. They compare with the reference date 1, 7 and 30 days earlier, as an amount and a percentage.
These same 18 columns are also used in: 1) US7.2 — the exposure drill's Collateral Posted mode. Change a column here and it must change there too.
The five amount fields on a bond posting (they sit together at the end of the table, in this order). Original Ccy = the currency the bond is denominated in. Original Amount = how much of that bond was posted, counted in its own currency. Posted (USD) = that same posted amount converted into US dollars at the exchange rate. Allocated (USD) = the part of it the collateral team actually used to cover this agreement’s margin requirement. Unallocated (USD) is Posted (USD) minus Allocated (USD). It is collateral posted into the long box but not consumed. It is never below zero, and a fully-used posting leaves nothing unallocated. The “(USD)” in those three headings is the reporting currency — one setting for the whole Singapore entity (confirmed 26 Aug 2026), not something each posting carries its own answer for. The demo writes it into the headings and into the dollar sign on every amount; the real system should take both from that one setting, so changing it re-labels every screen. Worked example: Original Ccy SGD, Original Amount 1,000,000 → Posted (USD) 700,000 → Allocated (USD) 500,000 → Unallocated (USD) 200,000.
Several lists show individual agreements. They are the docked table at Detailed level, and the Margin Calls list at individual level. They also include the Postings, Bonds Maturing and Postings by bonds blotters. In all of them each agreement name is a selector, with a small ↗ arrow beside it. Clicking the name selects the agreement; clicking the arrow opens the agreement detail popup. Agreement type names are unchanged. Those are the coloured type rows on the Summary view. They still drill into that type’s individual agreements.
To get here: Overview → left sidebar → “Rules Engine → Optimization Rules”. Or open an in-call agreement popup and click “▶ Optimize posting”.
What it is: this entry has no screen of its own. It shows the Rules engine — the same screen as the Rules engine tab. It fills the Overview’s working area, with the sidebar still beside it. It is written up in full in §11 Rules engine. Nothing about it is repeated here. Every control behaves exactly as §11 says, because it is that screen.
Developers: build ONE Rules engine and show it in three places. Never build a second look-alike. Two builds of one screen drift apart. The user is then shown two answers to the same question.
To get here: Overview → left sidebar → “Maintenance → User Maintenance”.
What it is: this entry has no screen of its own. It shows User maintenance — the same screen as the User maintenance tab. It fills the Overview’s working area, and the sidebar stays beside it.
Why it is here: the six datasets on that screen decide figures the Overview shows. A cost-of-funds rate, an industry-group mapping, a collateral source, an excluded agreement, an exposure adjustment, an added inventory row. Noticing a wrong figure and fixing its data should not mean leaving the Overview.
Developers: build ONE User maintenance screen and show it in two places. Never build a second look-alike. Two builds of one screen drift apart. The user is then shown two answers to the same question.
To get here: Overview → left sidebar → “Rules Engine → Optimization Results”. Or press ▶ Run on Optimization Rules. Or press “Optimise to cover” on Triparty AOE. All three land here.
To get here: Overview tab → the docked panel at the bottom → click the “Margin Calls” button. (This is the Daily Exposure Report view.)
Eleven of these columns are shared with the docked agreement table. Those eleven are Total Exposure, ITM Exposure, OTM Exposure, Call / Obligation and Margin Call. Plus Threshold, Dispute Value, Dispute Age, Base CCY, Base Total Exp. and Base Call Amt. They are written up once in US2.4, and their source and check are in Appendix E.1. The rest of the list is specific to this report. The call-handling columns are Call Status, Action, LRP, STD Amount and Cpty Amount. Then Agreed Amount, Net Alternative, Notification Time, Resolve By and Statement Status. The row also carries Category, Credit Rating and Region.
max(baseNow × 0.35, seasonal/weekday/quarter-end adjusted value). So exposure never collapses to zero in the demo. baseNow is the agreement's normal size, grown by its yearly trend. It is defined in plain English in Requirements 2, US9.8.To get here: Overview tab → docked panel → “Bonds Maturing”. The Triparty AOE button appears only when Triparty is selected in the sidebar. (It was called “T+N Ladder” until 01 Oct 2026.)
/aoe/. See the preamble: the three designed screens are served as files, not built from this spec.due-soon). Amber when days are 30 or fewer (CSS due-mid). No colour beyond 30 days.To get here: Overview tab → left sidebar → the “Static Data” group → click any item. Each opens a reference-data modal (fields are placeholders “to be provided”).
This is the reference record for a bond. The live attributes a user sees for one bond are also used in two places. 1) US8.2 — the instrument detail modal, in both its field sets. 2) US10.3 — the Inventory Manager's Column display fields.
To get here: go to the Overview tab and find any list of individual agreements. Click the small ↗ arrow beside an individual agreement name. A full-screen detail popup opens. (Clicking the name itself selects the agreement instead — see US2.6. Inside an Overview 2 workspace widget the name still opens this popup directly.)
Header row: “📋 Eligibility schedule — [schedule name] · each eligible type below shows how much of it is currently posted”. Below it sits one bordered card per accepted type in the agreement's accept-list. The order is Cash · Govt · Corp. Each has a colour-coded left border and heading: Cash green, Govt blue, Corp amber. Each card has a header bar where the posted amount is the main focus — a large bold figure (e.g. $8.8M) with a smaller “posted · N% of collateral” beside it. When nothing of that type is posted it reads a muted “$0 · eligible — none posted” instead. A full-width colour-coded share bar sits directly under the header. Below the header is the attribute grid. Posted amounts tie to the authoritative postings. Govt is Sovereign plus Public-sector and Agency bonds. Corp is Corporate bonds. Cash is the cash posting. Every agreement posts a realistic mix across the types it accepts (and only those types) — e.g. GMRA shows Govt and Corp. BVM, CCP and TRI show Govt, Corp and Cash. Agreements that do not accept Corp — BIM, GMSLA and FUT — hold no corporate bonds. GMRA takes no cash, so it holds none. Attributes differ by type; Interest / rebate rate belongs to Cash only — never to a bond. Values are illustrative demo data.
Data source — Collateral used data (set 14). The Asset Holdings Summary table and the Collateral Posted drill both read that set. It holds the line-level collateral records. They are defined in full on the Requirements 2 · Overview 2 tab. Look under Data source catalog #14, in the collateral-used column dictionary. The columns shown here map onto that set. Asset Class is each line's G7 industry group. The Held and Delivery columns come from lines whose Position is Held or Delivered. Mkt Val is the line's Market Value in USD. Coll Val is the line's Collateral Value in USD — the Market Value after the line's Haircut. Both are converted from the booking currency using each line's FX Rate (Market data — FX, set 8). The Collateral Posted drill's ISIN / Security / Maturity / Counterparty / Ccy columns are the same set's per-line fields. Feature labels here are unchanged; only the underlying data set is now named and traced.
MtM = obligation × (0.75 + (hash%20)/100). That lands between 75% and 95% of the total exposure. hash is a stable number derived from the agreement's name. So each agreement always gets the same split, and it is not random. The remainder is the Independent Amount (IA). Total Exposure = MtM + IA. The Trades tab is synthesised so its rows net back to this MtM.CONC_LIMITS, keyed by agreement key (bim/bvm/gmra/gmsla/ccp/fut/tri). Its fields are {group, limitType, granularity, limit, unit, assetClass, assetType, issuerSector, issuerCountry, basis}. The pop-up reads it via concLimitFor(key). The Rules engine in j-collateraldemo.html mirrors the identical catalog, so the limit shown there is the same value.To get here: on the Overview tab, click a “Call / obligation” or “Total exposure” amount in a table. Those amounts carry a dotted underline. A full-screen drill overlay opens with a “← Back” button and a “Trade contributions / Collateral Posted” toggle.
Same 18 columns as the docked postings table. They are written up once, in US2.4 → “docked Postings / Postings by bonds / Bonds Maturing table columns”. Nothing is added or dropped here. Sorting, filtering and column show/hide behave the same way in both places.
To get here: click any ISIN or instrument name — they carry a dotted underline. They appear in the Overview bond postings tables and in the Inventory Manager table.
One window, wherever you open it from. The instrument window is the same window on both screens. The Overview shows it, and so does every Overview 2 widget that embeds the Overview. The Inventory Manager shows the same one. Same fields, same order, same “to be provided” block. Only the source of the values differs. The two screens hold different books. The Overview knows the bond as collateral it has posted. The Inventory Manager knows it as a trade it holds.
The four classification fields (numbers 8–11) are worked out in US8.3. That story is where the matching rule lives. Ratings are shown as small rounded labels. Deal status is green when the position runs to maturity, red when it ends earlier.
These bond attributes are also used in three other stories. 1) US10.3 — the Inventory Manager's Column display fields. That is the row this modal expands. 2) US5.1 — the Instrument reference screen, the static record they come from. 3) US2.4 — the docked postings tables. There ISIN, Security, Type and Sector appear as columns.
| Bond | Bond notional | Price | Notional × price ÷ 100 | MTM of notional on the card |
|---|---|---|---|---|
| SINGAPORE GOVT 3.125% 06/26 (Overview) | 48.1 mm SGD | 108.49 | 52.2 | 52.2 mm SGD ✓ |
| MAS BILL 0.625% 06/26 (Overview) | 50.2 mm SGD | 89.28 | 44.8 | 44.8 mm SGD ✓ |
| ASIAN DEV BANK 3.625% 08/28 (Inventory) | 3,250.1 mm USD | 87.52 | 2,844.5 | 2,844.5 mm USD ✓ |
To get here: open the Overview tab. In its left sidebar, under the Inventory heading, click Inventory Manager. The charts and the postings table are replaced by the Inventory Manager, filling the screen. Click any agreement, or any other sidebar entry, to go back. Or add the Inventory Manager widget inside Overview 2. Both show this same page. See Requirements 2 · Overview 2. It shows a summary bar of holdings by category. Top-right sits a “Snapshot as-at” date picker and a View toggle. Below them is a table of bond trades. The View toggle has three settings: the trade list (Column display), the same trades day by day (Time series of inventory), and those same trades added up into a two-attribute grid (Pivot table).
To get here: in the Inventory Manager, set the View toggle to Pivot table — the third option, after Column display and Time series of inventory.
These same fields are also used in two other stories. 1) US18.1 — Adjusting inventory, where the user types new rows in. Every field except Holding is captured there. 2) US8.2 — the Inventory instrument detail modal, which shows the same attributes for one bond. Change a field here and it must change in both.
collat-inventory.js. Both the Inventory Manager and the Rules engine load it. So the two screens show the same book. The Rules engine no longer keeps its own separate list. Rows the user adds under User maintenance → Adjusting inventory flow into that same shared book. So does any uploaded production Inventory data, set 15. Both therefore appear on both screens.The pivot adds no new field to the book. It is built from the Column display list above: its two grouping pickers offer the fifteen text fields of that list, and its Value picker offers the two amount fields — Bond Notional (mm) and MTM of Notional (mm). Add a field to the Column display view and it appears in the pivot automatically. See US10.4.
To get here: click the top-level Rules engine tab. Or add the Rules engine widget inside Overview 2. That widget embeds this same studio. See Requirements 2 · widget lineage. It is an allocation-optimisation studio. At the top is a hero bar, with the run selector and Run. Below it is a rule library, shown as a Visual flow or a List. At the bottom is a drawer holding Inputs and Run-order. The run’s Output is not here: the Optimisation Results view sits at the bottom of the Optimization Results tab, under the rest of that run’s answers, and “▶ Run” takes you straight to it. This is NOT the Overview's Optimization panel (§2). This one is richer, with its own named runs, drawer and parameters.
CONC_LIMITS in j-collateraldemo.html, read via concLimitFor(agKey). Each entry in the engine's AGREEMENTS array gets two fields. conc is the full record, for display. concLimit is its numeric value, used by optimise().expr. A group is {op:"and"|"or", not:bool, kids:[node…]}. A condition is {field, cop, value}. cop is the condition operator. Its values are in/notin, gte/lte/gt/lt/eq/ne/between, and equals/contains/startswith/endswith/notcontains. It is evaluated by evalExprOn(record, source, node); a rule with no expr falls back to the legacy single-condition evaluation. Rules persist to aoe-re-rules.This is the rule the engine follows for every margin call, in this order. Nothing about price or cost is considered until eligibility has already been settled.
Agreement 1 has a $100mm margin call. Its eligibility schedule accepts supranational issuers only. Inventory holds $100mm of corporate bond A, $50mm of supranational bond 2 and $80mm of supranational bond 3.
Two things that change the split, and only these two. (a) Haircuts. The agreement may value that paper at less than face. The engine then delivers more than the figures above, so the collateral value still adds up to $100mm. The run log shows both numbers, as “post $X → $Y cover”. (b) The concentration boundary. Say the agreement's concentration limit caps any one holding at 20% of the call. The same $100mm is then spread across more holdings, instead of two. With no concentration limit biting and no haircut, the answer is exactly $50mm + $50mm.
it.g7, its issuer's G7 group. lineG7(it) looks the line's industry up in the user's mapping. That mapping is localStorage collat-g7-map, holding rows of {issuer, g7} keyed on Issuer Industry, upper-cased. It falls back to it.industry, then to "Unclassified".AGREEMENTS array carries eligG7. It lists the groups its eligibility schedule accepts, transcribed from the schedule's Issuer line. The values are as follows. bvm and fut are ["Sovereign"]. bim, gmra and tri are ["Sovereign","Agency","Supranational"]. gmsla is ["Corporates","Financial Institutions","Supranational","Agency"]. ccp is ["Sovereign","Agency"]. An empty or absent list means no issuer-group restriction.g7Ok(it, ag) is the test. optimise() applies it as a pool filter before ranking. It sits alongside the existing call.accepts.includes(it.type) and ratingRank(it.rating) <= ratingRank(floor) filters.takeColl = min(need, cap, avail[it.id]·(1−hc)) per line. Here cap = call.req · min(run concentration cap, ag.concLimit)/100. It then grosses up to a delivered market value, postMv = roundTo(takeColl/(1−hc), P.round), bounded by avail[it.id]. A line whose postMv rounds to zero is skipped. A residual under half the rounding increment counts as covered, via doneTol = max(0.01, P.round/2). That is what stops a queue of $0.0mm postings and a spurious “short $0.0mm”.The ⚠ Exceptions view is the fourth setting of the view toggle, next to ☰ List, ◈ Visual and ▦ Overview. It answers one question: what did this run NOT use, and why? Nothing on it is stored or typed in. Every row is worked out afresh from the run you have selected, each time you open the view, so it can never disagree with the run itself.
Sweep the deck is a run parameter, set in the Run parameters panel next to the concentration cap, minimum transfer amount, rounding and haircut buffer. It is saved with the run, so each run remembers its own setting. It has two settings.
On is the default, for new runs and for the three runs the app starts with.
They come from the Collateral used data set — data set 14 in the master list — using only its Delivered rows, which are the lines we have posted out and have not had back. Two figures are read from it:
This data set is not loaded yet. Data set 14 is catalogued but not yet connected to a live source, so the app holds no existing-postings rows today. Nothing is invented to fill the gap. Until real rows are loaded, a Sweep-off run has nothing to retain and produces exactly the same proposal as a Sweep-on run — and it says so, in the run log and as a “Missing or invalid values” exception, rather than letting the two settings look identical for no visible reason.
Take GMRA, which owes $567mm across its two sub-agreements, in a book owing $1,757mm in total. Suppose one Delivered row is loaded against GMRA: an Asian Development Bank bond, $105mm of market value posted, worth $100mm of collateral value after its haircut.
| Figure | Rule | Sweep the deck ON | Sweep the deck OFF |
|---|---|---|---|
| GMRA already covered | Add up the collateral value of GMRA’s Delivered rows; on is always nothing | $0mm | $100mm |
| GMRA still to cover | What it owes, less what it already has covered | $567mm | $467mm (567 − 100) |
| Whole book still to cover | Add up every obligation’s still-to-cover figure | $1,757mm | $1,657mm (1,757 − 100) |
| Inventory not available | Market value of instruments already delivered out | $0mm | $105mm |
| Asian Development Bank line left to give | Its market value, less the $105mm already delivered out | its full market value | its market value − $105mm |
To check any of these on screen: press ▶ Run and read the run log. Its third line states the setting, the collateral value retained and the market value unavailable. Its fourth line states the still-to-cover total against the total owed. Each obligation’s own line states what it still needs.
Eligibility is not a user-set rule group. What a counterparty accepts is fixed by that agreement's own eligibility schedule. It sets the accepted asset types, the accepted issuer groups in the G7 industry grouping, and the rating floor. The optimiser applies all three automatically to every posting. See US11.6. Users restrict only their own inventory pool, via the Scoping group.
aoe-re-runs / active run aoe-re-active):
aoe-re-rules, aoe-re-runs, aoe-re-active). This is a separate parameter set from the Overview dock Optimization panel (§2). That panel's demo defaults are MTA $250K, Rounding $10K and Substitution buffer 5%.aoe-re-seedver. It records which version of the built-in default rules your browser last saved. Suppose the app’s built-in defaults have since changed, so your saved marker is older than the current one. Then the next page load clears your saved rules and runs, and rebuilds them from the current defaults. In plain terms: rules and runs are saved in your browser, and normally kept as-is between visits. Without this marker, an old default set could stay on your screen forever after we changed the defaults. The marker makes the app notice, and refresh to the current default rules automatically. It does not wipe anything on an ordinary reload. It only acts when the default set itself has moved on. Developer note: the current marker value is "2026-07-24"; bump it whenever the default rule library or seed runs change.Where to find it. Rules engine tab → any rule in the Ranking group. Open it from the ✎ on its box in Visual, or from its row in List. A new one is made with + New Rule on an input box, then setting Group to Ranking.
The problem this solves. A desk’s preference has two halves and the screen used to hold only the first. The first half is an ORDER OF KINDS — take corporate paper before supranational paper. The second half is what to do once the engine is inside one of those kinds and several lines qualify — take the biggest line, so the call is covered in the fewest movements. Written as two separate rules the second half reads as if it applied to the whole book, which is not what was meant. So it is carried on the ranking rule, nested under the order it belongs to.
sub, holding one key from the two choices above; the empty key means no sub-rule. A rule saved before sub-rules existed has no key and behaves as “none”.aoe-re-seedver), so a browser holding the older set is re-seeded on its next load — see US11.4.Where to find it. The Optimisation Results view sits at the bottom of the Optimization Results tab, under the flow tables and the five views. It used to sit in a drawer at the bottom of the Rules engine tab. It is the same one screen, moved — so everything below it still applies, and pressing ▶ Run on the Rules engine takes you here.
The demo runs on a handful of agreements, so every result fits on one screen. The real book will not. This story is the contract for what the results view must do when it does not fit — and it is a build requirement, not a demo convenience. A results screen that draws one card per agreement is fine at seven and unusable at several thousand.
| Figure | Where it comes from | How to check it |
|---|---|---|
| The count beside the search box | How many proposed postings match what you typed, and how many different agreements those postings belong to. | Clear the search — it must read the same number of postings as the total row at the foot of the table, and the same number of agreements as the card count under the cards. |
| “Showing 8 of 214 agreements” | The cards drawn on this page, and the number of agreements with at least one matching posting. | Count the cards on screen. Page to the last page and check the last page's count is the remainder. |
| “Showing 25 of 36 postings” | The rows drawn on this page, and the number of postings matching the search. | Count the rows on screen; add up the rows across every page and the answer must be the second number. |
| Total row — market value posted, collateral value, annual cost | Each column added up across every matching posting that has not been switched off with Ignore, on all pages. | Click Next to page through the table: the total row must not move. Then add the column up by hand across the pages — it must equal the row. |
| “1 of 4 postings match” on a card | How many of that agreement's proposed postings match the search, out of all of them. | Clear the search: the card returns to a coverage percentage, and the number of postings listed on it must equal the second number. |
Where to find it. Two doors, one screen. The top-level Optimization Results tab, next to Rules engine. And the Optimization Results entry in the Overview's left-hand menu, under the Rules Engine heading, beside Optimization Rules. The Overview entry does not rebuild the screen — it shows that same tab, framed full width, exactly the way Optimization Rules shows the Rules engine tab. Anything true of one door is true of the other, always.
What sits at the bottom of this tab. Under the flow tables and the five views is the Optimisation Results view — the run log, the summary figures, the one search box, the per-agreement cards, the two charts and the Full posting detail table. It moved here from the Rules engine tab's bottom drawer, so every run answer now reads on one tab. It is one screen, not a copy: US11.9 governs its search, its paging and which population each total covers.
Switching view clears the search and returns to page one, so you never arrive on a view already filtered by something you typed somewhere else.
01 · Approval blotter is the working list. One row per proposed posting, every row decided.
| Figure | Where it comes from | How to check it |
|---|---|---|
| Market value, Haircut, Collateral value, Cost on a row | The posting the optimiser proposed: the instrument it chose, the discount that agreement applies, and the funding cost carried on that holding. | Open the Rules engine's own “Full posting detail” table and find the same agreement and instrument — the four figures must match to the penny. |
| Total row — market value and collateral value | Each column added up across every accepted posting matching the search, on all pages. | Click Next: the totals must not change. With nothing typed and nothing rejected they read $1,782.6mm and $1,756.9mm. |
| Total row — Cost | The cost of the accepted set as a whole, weighted by how much market value each posting sends out, so a large cheap posting counts for more than a small dear one. | With everything accepted it reads 7.8 bps, which sits between the cheapest holding used (7 bps) and the dearest (11 bps). |
| “$1,756.9mm to release” | The collateral value of every posting still marked Accepted, across the whole run. | Reject one line and it must fall by that line's own collateral value — rejecting the $41.4mm posting takes it to $1,375.4mm. |
02 · Benefits scorecard. Six tiles and one comparison bar. Every tile counts only the postings still marked Accepted on the blotter, so the case being made is the case being released.
| Figure | Where it comes from | How to check it |
|---|---|---|
| Saved this year — $6.52mm | The all-cash cost less what the proposed mix costs. | $7.91mm − $1.38mm = $6.52mm. Both are printed on the tile beside it. |
| ▼ 82% cheaper | The saving as a share of the all-cash cost. | $6.52mm out of $7.91mm is 82%. |
| Requirement covered — 100.0% | The collateral value of the accepted postings, out of what the run's obligations add up to. | $1,756.9mm out of $1,757.0mm. The first figure is the blotter's own total row. |
| Left uncovered — $0.1mm | The requirement less the collateral value covered. | $1,757.0mm − $1,756.9mm. Every obligation is met in full on this run, so the shortfall board has nothing to list and says so. |
| The two bars | The all-cash cost is the full-width bar; the run's cost is drawn as its share of it. | $1.38mm is about a sixth of $7.91mm, and the green bar is about a sixth of the red one. |
03 · Scenario board. One column per saved run, one row per measure, and a Do nothing column so every run is measured against the current book rather than only against each other.
| Measure | Do nothing | Baseline (all GFM) | CSG agreements only | USD margin calls only |
|---|---|---|---|---|
| Annual carry cost | $7.91mm | $1.38mm | $1.39mm | $1.38mm |
| Saved vs doing nothing | — | $6.52mm | $6.52mm | $6.52mm |
| Requirement covered | — | 100.0% | 100.0% | 100.0% |
| Market value posted | — | $1,783mm | $1,783mm | $1,783mm |
| Movements to make | — | 36 | 37 | 36 |
| Blended funding cost | — | 7.8 bps | 7.8 bps | 7.8 bps |
| Left uncovered | — | $0.1mm | $0.2mm | $0.1mm |
Read that table before building it: the cheapest run is not the best run. “CSG agreements only” costs a hair less and saves a hair more, yet leaves $9.2mm more uncovered and covers half a point less. That trade-off is the whole reason this screen exists, and it is why no single row may be presented as the winner.
04 · Movement map. Inventory lines on the left, agreements on the right, ribbons between them.
| From inventory | Collateral value | To agreement | Collateral value |
|---|---|---|---|
| FRANCE OAT 1.25% 06/27 | $301.7mm | GMRA · Dunmore Bank | $567.0mm |
| SINGAPORE GOVT 3% 02/30 | $301.2mm | Bilateral CSA IM · Brackwater Bank | $206.9mm |
| KFW 1.25% 02/27 | $267.8mm | GMSLA · Ironvale Bank | $190.7mm |
| IBRD WORLD BANK 2% 06/26 | $230.8mm | CCP · LCH | $148.1mm |
| ASIAN DEV BANK 3.625% 08/28 | $230.7mm | Triparty · Halvard Bank | $141.0mm |
| KFW 1.5% 10/27 | $84.7mm | Bilateral CSA VM · Caldera Bank | $98.8mm |
| Futures · CME | $64.4mm |
Both sides add up to the same total — $1,756.9mm — because every posting leaves an inventory line and arrives at an agreement. That is the check: if the two columns disagree, a posting has been counted on one side and not the other.
05 · Shortfall board. Only the obligations the run could not fill, each with the constraint that stopped it.
Searchable by agreement or counterparty, twenty rows to a page, and the total row adds up every agreement listed, not the page. When a run covers everything, the board says so rather than showing an empty table.
| Agreement | Needed | Covered | Short | Coverage | Eligible lines |
|---|---|---|---|---|---|
| Nothing to list on today's run. Every obligation is covered in full, so the board says “Every obligation in this run was covered in full.” instead of drawing an empty table. The columns above are what it draws when a run cannot fill something — narrow an agreement's eligibility, lower its concentration limit or take lines out of scope, and the rows come back. | |||||
Every column adds up: Needed less Covered is Short on each row, and the rows add to the total, each shown to the nearest $0.1mm.
What makes a row appear is almost never that the firm is out of collateral. It is that too few of its holdings pass the agreement's own eligibility test (accepted types, rating floor, issuer groups), and that each one that does pass may only carry a share of the call — that agreement's concentration limit. Cover a $247.0mm call from two eligible lines at a 20% limit and $98.8mm is all that can be delivered, whatever the optimiser does. That is the sentence a collateral manager needs, and it is why the eligible-line count and the blocking constraint sit on every row. On today's book the firm holds enough eligible paper that every obligation clears both tests, so the board reports a covered run instead.
To get here: the Optimization Results tab, or the Optimization Results entry in the Overview’s left sidebar. Both open the same screen.
What it is: one movement has two legs. The bond leaves a desk inside the firm, and it arrives at an agreement outside it. The screen leads with one table per leg. Everything the screen used to open with sits underneath them, in a fold headed “UI suggested by AI based on what is available from vendors in the market”, open by default.
One row per line the run draws on. Where the same bond is drawn for several agreements, it is one row here and several rows on the second table.
Collateral does not only come from a desk. A call can be met by borrowing a bond that is free at the desk, or by recalling one the firm already has posted out somewhere else. A Sweep-ON run assumes the second has happened — it re-optimises as if nothing were posted — so the recall is not a detail, it is half the supply, and somebody has to make those calls.
Worked example, from the figures on screen today. XSBIY8G8VPB6 posts $308.55mm, so the pool must source $311.00mm. $158.03mm of that bond is already posted out — $89.63mm against Bilateral CSA VM (Caldera Bank), $41.93mm against CCP (LCH) and $26.47mm against Futures (CME) — and all of it is recalled. The desk therefore lends only the remaining $152.97mm fresh. XSFAIBBDJEA8 is the other shape: $288.97mm comes back against a draw of $273.00mm, so the desk lends nothing. XS9Z40G1NNE9 is the third: none of it is posted out, so all $87.00mm is a fresh borrow.
The pool does not source the exact amount it posts. It sources a little more, for two reasons a collateral desk will recognise, and both are read off the run rather than typed in:
Worked example, from the figures on screen today. The run posts $86.55mm of XS9Z40G1NNE9 — $48.75mm to GMSLA and $37.80mm to CCP. The active run carries a 0.5% haircut buffer, so the pool needs $86.55mm × 1.005 = $86.98mm, which rounds up to a whole $87.00mm borrowed from SG Credit Trading. $0.45mm stays in the pool. The line holds far more than that, so the cap does not bite. Across the whole run the summary reads $1,290.70mm borrowed against $1,782.60mm posted.
One row per proposed movement. This is the leg that leaves the firm.
“Bilateral CSA IM” is a KIND of contract, not a contract. The firm signs many of them, and each one is its own paperwork with its own end date and its own settlement terms. So one posting of a bond to Bilateral CSA IM does not all settle on the same day or run to the same end date — it is spread over the individual agreements that are covering it.
Worked example, from the figures on screen today. The run posts $50.40mm of XSBIY8G8VPB6 to Bilateral CSA VM. That is one row, reading $50.40mm of collateral against an Expected Margin Call of $247.00mm — what the whole type owes. Open it and the two agreements behind it appear: ISDA/CSA-VM-MS-001, which expects $148.00mm and therefore takes $30.20mm, settling 20/06/2026 and running to 01/07/2030; and ISDA/CSA-VM-MS-002, which expects $99.00mm and takes $20.20mm, settling 19/06/2026 and running to 01/07/2029. They add back to $50.40mm against $247.00mm. Because their dates differ, the row above reports the span — 19/06/2026 – 20/06/2026 and 01/07/2029 – 01/07/2030. CCP’s two agreements happen to share a date, so its row prints the one date.
Why this screen exists. Sweep the deck ON is an assumption with a consequence. The run re-optimises as if nothing had ever been posted — which means every line already out with a counterparty has to be recalled first. Somebody has to pick up the phone. A run that silently assumes the recall, on a screen that never says what is being recalled or from whom, is not something anyone can act on. This table says it.
It is the state of the book, not a proposal. It is read from the existing-postings data (catalogue set 14, Collateral used data), not from the run, so changing a rule does not change it. What the run changes is what happens to it, and the line under the heading says which.
The two totals must tie to the run, and that is how you check this screen. Press ▶ Run with Sweep the deck OFF and read the run log: the collateral value retained and the inventory market value already pledged are the same two figures as this table’s totals. Today that is $1,158.83mm retained against the Collateral value total, and $1,173.48mm pledged against the Market value total, over 19 lines. If they ever disagree, one of the two is reading a different book.
What it is: the engine proposes; a person decides. Any row on either table can be proposed for removal, edited, or added from scratch. Every row therefore says where it came from, so the engine’s answer and a person’s amendment are never confused.
What it is: the two tables below it are one row per movement, which answers “what is moving” but not “what is happening to this bond”. This table is one row per bond. It puts the amount borrowed and the amount posted side by side, and opens to show the lines behind both.
A bond goes to several agreements, and an agreement is met by several bonds. Neither grouping can answer the other’s question: read down the bond view and no single row ever tells you whether an agreement is actually covered. So the summary carries a toggle — By bond and By agreement — and the user picks which question they are asking.
The two views tie to the run, and that is how you check them. Today By agreement lists 14 agreements expecting $1,757.00mm — the run’s whole requirement — against $1,782.60mm of collateral posted, worth $1,756.89mm after haircut — met in full, with $0.22mm of rounding left over. That posted figure is the same total By bond shows, and that collateral value is the run’s own “requirement covered”.
Production holds thousands of movements. This is where the user actually works: they find the bond, open it, and amend the lines under it — rather than hunting the same row down a flat table of thousands. Two rules shape how that works.
An amendment can leave an agreement without enough collateral against it. The screen says so rather than letting it pass.
Borrowed is higher than Posted on every bond, and that is the point of the table. The pool borrows the postings plus the run’s haircut buffer, rounded up to a whole million and capped at what the line holds — the rule is written out under US11.16, “How much the pool borrows”. What is borrowed and not posted is headroom left in the pool, never a shortfall. Today the totals read $1,290.70mm borrowed against $1,782.60mm posted. The gap moves on its own when the run does: change the haircut buffer, or change what the run posts, and both columns follow. It widens differently again once the two legs come from your own files — catalog sets 12.1 and 12.2 are separate uploads, so a bond borrowed at 100 and posted at 90 reads as 100 and 90 here.
What it is: every figure on this screen belongs to one run. The picker sits at the very top, above the summary, because it governs everything below it.
What it is: the same run, grouped both ways at once, on one screen. It leads the tab, directly under the run picker — it is the first thing a user sees, because it answers whichever of the two questions they arrived with. Everything it replaced is still there: Summary by bond, Where the bonds are posted today and the two flow tables are folded away under ▸ The long form, one click below it, unchanged.
The two questions are asked together, not one tab at a time. A bond goes to several agreements and an agreement is met by several bonds, so whichever grouping is on screen, the other half of the answer is on the tab you are not looking at. Here both are up at once: bonds on the left, agreements on the right. Pick a row on either side and the other side becomes just the records related to it. Pick the same row again and both go back to the whole run. Nothing is hidden behind a toggle, and nothing has to be remembered across a click.
Before either grouping, the question a desk asks first is how the run is doing against each kind of paper — Bilateral CSA IM, Bilateral CSA VM, GMRA, GMSLA, CCP, Futures, Triparty. That is the headline, and it leads the panel.
Today’s headline. GMRA expects $567.00mm and the run proposes $579.15mm — more than the call, on purpose; GMSLA $318.00mm against $194.10mm; Bilateral CSA VM $247.00mm against $100.80mm; Bilateral CSA IM $207.00mm against $210.30mm; CCP $185.00mm against $150.75mm; Triparty $141.00mm against $144.00mm; Futures $92.00mm against $65.70mm. Seven kinds, $1,757.00mm expected and $1,782.60mm proposed — the run’s own two totals. Opening Bilateral CSA VM shows 4 postings across 2 agreements adding to the $100.80mm on the row above it.
Production holds thousands of bonds and hundreds of agreements, so the user arrives knowing a name, not a row number. Three boxes sit above both panes, one for each name they might know.
A user can only choose what exists. Collateral is not conjured: a borrow is a draw on an inventory line the firm actually holds, a recall is a call on collateral that is actually posted out, and a posting can only go to an agreement that would accept the bond. So all three are chosen from a list of what is there rather than typed in free hand, and what can be borrowed or called back is capped by what is there. The one figure left open is what goes OUT, because a desk may deliberately post more than the call.
The worked example, in today’s run. With nothing picked the strip reads Sourced $2,464.08mm · Posted $1,782.60mm · Value $1,756.89mm · Short $0.22mm; the left pane closes on 15 bonds at those first two figures and the right pane on 14 agreements expecting $1,757.00mm, covered to $1,756.89mm — met in full, the $0.22mm being rounding rather than a shortfall. Pick XSV2KLI4P6V3 and the strip reads “XSV2KLI4P6V3 → 12 of 14 agreements”: the right pane shows 1 line borrowed from SG Credit Trading for $308.00mm — the Sourced figure on the row still highlighted on the left — nothing to recall, because none of that bond is posted out today, and 12 postings totalling $305.55mm, which is that row’s Posted. Click GMRA/BRC-SGP-001 in that list and the sides swap roles: the strip reads “GMRA/BRC-SGP-001 ← 6 of 15 bonds” and the left pane shows those 6 postings for $345.22mm, worth $340.04mm — the same Value printed against that agreement on the right, against its $340.00mm call. Every figure on this panel is one of the run’s own figures read a different way round.
What it is: a panel at the bottom of the Optimization Results tab. It sits under Optimisation Results, separated by a rule. A dropdown picks an optimisation model. The screen then shows what that model would propose for the run on screen.
The engine is one way of deciding, not the only way. Today it fills the fussiest obligation first. Inside each one it posts the cheapest eligible bond. It never revisits a decision. That is a heuristic: a sensible shortcut, with no claim to be the cheapest answer. Other algorithms make the same decision differently. Some solve the whole book at once. Some improve an answer they already have. This panel runs them over the same run and shows what each proposes.
Picking a model here does not change the run. Every screen above this panel still shows the engine's answer. This panel answers a different question. It asks what a different algorithm would have proposed. Choosing which model the engine itself uses is a separate decision, raised as OQ-46.
It is read the way the Rules engine is read. The Rules engine draws a run as input → process → output. So does this panel, and for the same reason. Those three columns are what a reader compares when choosing between two algorithms. The input column is identical whichever model is picked. That is deliberate: every model is handed the same scoped obligations, the same eligible pool, the same holdings and the same limits. The process column is the model's own way of deciding. That is the only thing that differs. The output column is what it proposes, and what carrying it costs.
Building the greedy model? Its exact logic — every step, every formula, every tie-break and every edge case — is written out in the Developer build detail fold at the end of this story. It is the only place on this tab that carries verbatim formulas.
Six models are built and can be picked. This table describes each in plain words, without its industry name. The Model column here says what the model does; the name in the dropdown is in the “Name on screen” column. It carries no formulas. The rules each one obeys are the run's own rules, unchanged.
| Model | Name on screen | Family | How it decides | What it is good for |
|---|---|---|---|---|
| Shortcut, cheapest holding first | Greedy · cheapest-to-deliver | A sensible shortcut | Serves the obligation with the narrowest eligibility schedule first. Inside each one it posts the cheapest eligible holding until it is covered. It never goes back on a decision. | Instant, and every posting has a reason a person can repeat. This is what the app runs today. |
| Shortcut, tightest obligation first | Greedy · most-constrained obligation first | A sensible shortcut | The same filling, but the queue is ordered differently. It measures how thin each obligation's own eligible pool is against what that obligation owes. The tightest one is served first. | Cutting shortfalls that are caused only by the order obligations were served in. |
| Shortcut, cheapest posting anywhere first | Global cost-ranked pair sweep | A sensible shortcut | There is no queue of obligations. It prices every holding-to-obligation combination in the book, sorts that one list cheapest first, and works down it. | Making the cheapest posting in the book first, wherever it happens to belong. |
| Solved in one go, any amount | Linear programming (exact optimum) | Worked out exactly, amounts unrestricted | It decides every posting at once rather than one at a time. A posting may be any amount, including one that could not actually be settled. Leaving an obligation uncovered is priced far above the dearest holding in the book. So it finds cover first, and argues about cost second. | The cheapest answer that exists under these rules. It is the floor every other model is measured against. |
| Solved in one go, whole lots only | MILP · lot-constrained | Worked out exactly, amounts must be whole lots | The same problem, with every posting forced into whole settlement lots. It works out the best answer with that rule lifted. It then rounds every posting down to a whole lot. Finally it buys the remainder back, one cheapest lot at a time. | An answer that could be settled exactly as it stands. It also states what having to deal in whole lots cost. |
| Shortcut, then keep improving it | Heuristic + local search | Improves an answer it already has | It starts from the engine's own answer. It then looks at every posting for a cheaper eligible holding with room for it. It takes the best swap it finds, and looks again. It stops when no single swap improves anything. | Improving an answer you already have. It can be stopped at any point and still hand back a valid answer. |
The worked example, in today’s run. Open Optimization Results on Baseline (all GFM) and scroll to Optimization Model Research by AI. The input cards read 27 of 30 lines eligible, 7 obligations · $1,757mm, 14 of 14 margin calls in scope, 7 of 7 agreements and 84 feasible combinations, under a 35% cap, a 0.15mm minimum transfer, $0.2mm lots and a 0.5% haircut buffer. Those four cards do not move whichever model is picked. Every model covers the whole requirement on this book — 100.0%, $1,756.9mm of cover — so what separates them is what that cover costs to carry. Greedy · cheapest-to-deliver, the engine’s own procedure, proposes 36 postings from 14 lines, $1,782.6mm posted, at $1.38mm a year and 8 bps. Linear programming (exact optimum) lands the same cover for $1.33mm a year: the greedy shortcut costs about $0.05mm a year, which is the price of deciding one obligation at a time and never going back. Greedy · most-constrained obligation first recovers roughly $0.02mm of it by changing nothing but the queue, and the Global cost-ranked pair sweep about $0.04mm. MILP · lot-constrained reaches the same carry as the linear programme in 50 whole-lot postings rather than 37, which is what a settleable answer costs in movements. Heuristic + local search reads level: it only looks for cheaper lines, and the greedy it starts from already took the cheapest, so it finds 0 improving swaps.
What the panel is really for. The verdict under the table is chosen by what separates the models, not by whether everything was covered. Where they differ on cover it prices the gap to the linear programme and credits what re-ordering the queue alone recovers. Where they cover the same and differ on carry — today’s reading — it names the linear programme as the floor and says what the shortcut costs a year. And where they cannot be told apart at all, it says so and names the limit that is binding instead, because that is the run where the algorithm is not the thing to fix. A book with several times more eligible collateral than it owes, or obligations that are all capped out, will produce that third reading — six identical rows are a fact about the rules, not a fault in the models.
Skip this section unless you are building the engine. Everything above says what the greedy model does in words. This says it exactly, with every formula, every tie-break and every edge case, so a developer can build it without reading the demo’s source. It is the logic for Greedy · cheapest-to-deliver — the model the engine runs today. The other five models reuse steps 0, 2, 3 and 5 unchanged and differ only where noted in their own rows of the models table above.
One builder produces the whole run context, once, before any allocation happens. Every model is handed the same object. Nothing downstream re-derives any of it.
| Name | What it holds | How it is worked out |
|---|---|---|
concPct | Run concentration cap, per cent | Run parameter. Falls back to 100 when unset. |
mta | Minimum transfer amount, $mm | Run parameter. Falls back to 0. |
round | Settlement lot size, $mm | Run parameter. 0 means no rounding. |
buffer | Extra haircut added to every posting, per cent | Run parameter. Falls back to 0. |
strat | Ranking strategy for the pool | The value of the run’s single active match rule. Defaults to cheapest when the run has none. |
fr | The run’s active filter rules | Every rule that is enabled AND selected into this run, of kind filter. |
sweep | Sweep the deck, on or off | Run parameter. ON is the default — only an explicit false turns it off. |
avail[lineId] | Market value of each line still free to post, $mm | Sweep ON: the line’s whole market value. Sweep OFF: market value less what is already pledged out, floored at 0. |
elig | Inventory lines that survive the run’s filter rules | Every line for which every filter rule passes. Book-wide; the per-obligation test comes later. |
calls | The obligations this run must cover | See D2. |
Why gross and retained are both kept. A screen has to be able to say “$567mm owed, $0mm already posted, $567mm to find”. Storing only the difference loses two thirds of that sentence.
⚠ Two known weaknesses in this step, both real and both worth a decision before you build it. First, it measures the wrong kind of fussiness. The count is of accepted asset classes only. It ignores the issuer-group list and the rating floor, which are usually what actually thins a pool. Read the eligible-line counts off today’s run in the order this step serves them: 17, 17, 12, 5, 5, 10, 16. The two thinnest pools are served fourth and fifth, behind two obligations with seventeen lines each. A genuinely most-constrained order would have been 5, 5, 10, 12, 16, 17, 17. Bilateral CSA VM is the clearest case: it accepts three asset classes, so it sorts late, but its schedule accepts Sovereign issuers only, leaving it 5 eligible lines against a $247.0mm call. At a 20% cap those five lines can deliver exactly what it needs and not a dollar more, so it covers with zero slack. It is not short today only because the book is deep enough to absorb the mistake. Second, the tie-break is arbitrary. Four obligations accept two classes each, so their order is simply the order they sit in the source data. Whichever sits last is the one that pays when the book is thin. Neither weakness is a bug — the code does what this step says — but both are why the most-constrained-obligation-first model exists, and both belong to OQ-46.
Start from the run’s eligible lines and apply four tests. All four run before any cost ranking. A cheaper line that fails any of them is never a candidate, however cheap.
Walk the ranked pool from the top. Two figures are carried: need, the cover still to find, which starts at the requirement; and availability, per line, shared across every obligation.
⚠ The rounding is the subtle part. Rounding to nearest, then clamping, means the cover actually delivered can be slightly more or slightly less than the cover asked for. So the cover must be recomputed from the final market value. Deriving it from the pre-rounding figure is the single easiest way to build this wrong: totals stop tying and the error compounds down the pool. The same rule applies on the way out — round once, when a figure is printed, never when it is stored.
Amounts are $mm. Costs are basis points a year. bps means one hundredth of one per cent.
| Figure | Formula | Note |
|---|---|---|
| Effective haircut | min(0.95, line.haircut + agreement.haircutAddon/100 + run.buffer/100) | Capped at 95%. Three parts: the schedule’s base, the agreement’s add-on, the run’s buffer. |
| Effective cost | line.fundingBps / (1 − effectiveHaircut) | bps per $1 of cover delivered. The only figure any ranking uses. |
| Concentration cap | requirement × min(run.concPct, agreement.concLimit) / 100 | In collateral value. Agreement limit absent → use the run’s. |
| Done tolerance | max(0.01, run.round / 2) | Half a lot. Below this, the obligation counts as covered. |
| Cover to take | min(need, cap, avail × (1 − effectiveHaircut)) | Skip the line if this is ≤ 0.01. |
| Market value to post | min(avail, roundToNearest(coverToTake / (1 − effectiveHaircut), run.round)) | Round then clamp, in that order. Skip if ≤ 0.001. |
| Cover delivered | postMv × (1 − effectiveHaircut) | Recomputed from the final market value, after rounding and clamping. |
| Annual cost of a posting | postMv × line.fundingBps / 10000 | Priced on market value posted, not on cover delivered. |
| Blended cost | totalAnnual / totalPostMv × 10000 | 0 when nothing was posted. |
| Uncovered total | totalRequirement − totalCoverDelivered | Never the sum of the shortfall rows. |
The worked trace, in today’s run. Run Baseline (all GFM): cap 35%, MTA 0.15mm, lots $0.15mm, buffer 0.5%, strategy cheapest, Sweep ON. 27 of 30 lines survive the run’s 5 filter rules, leaving 84 workable line-and-obligation combinations. Seven obligations total $1,757mm. Step 1 settles the order as Bilateral CSA IM, GMRA, GMSLA, Futures (two accepted classes each), then Bilateral CSA VM, CCP, Triparty (three each). Bilateral CSA IM goes first: it needs $207mm, accepts Cash and Govt from Sovereign, Agency or Supranational issuers rated AA or better, and its own 20% limit beats the run’s 35%, so no line may deliver more than $41.4mm of cover. 17 of the 27 lines pass the four eligibility tests. The cheapest is FRANCE OAT 0.875% 01/27 at 7bps; the cap binds before the need does, so it posts $41.9mm of market value for $41.4mm of cover. Four more capped postings follow and the fifth takes need below half a lot — fully covered on 5 postings, five times $41.4mm being exactly the $207mm owed. Bilateral CSA VM, served fifth, shows the fill loop with no room in it: 5 eligible lines, each capped at 20% of a $247.0mm call, so all five are needed and all five are used. Across the run: 36 postings, $1,782.6mm of market value posted, $1,756.88mm of cover against $1,757mm owed. Note what that leaves. No obligation recorded a shortfall — every one finished within half a lot — yet $0.12mm is still uncovered. That is D9’s rule made visible: the sum of the shortfall rows is zero here, and the uncovered total is not. Build the uncovered figure as requirement less cover delivered, never by adding the shortfall rows up.
To get here: click the User maintenance tab. A sub-tab strip selects one of eight datasets. They are 💰 Cost of funds, 🏭 G7 industry group and 🔖 G7 by bond. Then 🎯 Source of collateral, ⭐ Special agreements, 📈 Adjusting exposures, 📦 Adjusting inventory and 🏷 Tags & highlights.
collat-um-updated.To get here: User maintenance → 💰 Cost of funds.
| Figure on screen | Where it comes from | How it is worked out | How to check it |
|---|---|---|---|
| Security Type cell | The G7 industry group mapping (§14) — data set 7.2 — plus the built-in Others catch-all. | List the different G7 Industry group values on that screen, keeping the order they were first seen in. Add Others if it is not already among them. | Open §14, read down its G7 Industry group column, and write out the different values you see. That list, plus Others, must be exactly the Security Types here. |
| Currency cell | The currency static list — data set 5. | Every Security Type is repeated once for each currency in the list, in the order AUD, CAD, CHF, USD, SGD. | Count the currencies on any one Security Type: there must be 5, and the same 5 against every Security Type. |
| Rate (internal) / Rate (external) | Typed in by the user, or loaded from the user's uploaded file — data set 7.1. | Shown exactly as entered; nothing is calculated, rounded or converted. | Download the file and compare it with the screen line by line. They must be identical, because the download is the screen. |
| Row count in the line under the table (“10 row(s)”) | The rows on screen. | Number of Security Types multiplied by number of currencies. | Count the rows in the table; and check the multiplication against the two counts quoted next to it. |
| “N complete” | The rows on screen. | Count of rows where both rates are filled in and both are numbers. | Count the rows with no amber outline — it must match. |
| “N still missing a mandatory rate” | The rows on screen. | Total rows minus the complete count. When it is zero the text is replaced by “all 4 fields complete on every row”. | Count the rows that carry an amber outline; complete + missing must always add back to the row count. |
| “N problem(s) found” on a rejected upload | The uploaded file, checked against the rows on screen. | Count the messages listed in the red box. There is one per bad line, plus one covering all the rows the file left out. | Count the bullet points in the red box — it must equal the number in the status strip. |
collat-cost-of-funds, shaped {rates:{"<Security Type>|<CCY>":{ri:"1.20",re:"1.45"}}}. Values are stored as the strings the user typed. The last-updated stamp lives in collat-um-updated under the key cof.cofTypes() is g7Groups() with "Others" appended. g7Groups() gives the distinct non-blank G7 values from collat-g7-map, in first-seen order. "Others" is only appended when no case-insensitive match is already present. The grid is cofTypes() × CCYS where CCYS = ["AUD","CAD","CHF","USD","SGD"].cofRate(v) trims, drops one trailing %, rejects empty, then requires isFinite(Number(s)). Blank and non-numeric are reported differently but both fail.Security Type, Currency, Rate (internal), Rate (external). Security Type and Currency are matched case-insensitively (currency is upper-cased). Validation is all-or-nothing: the parse collects every problem, and if any exist nothing is written. There are seven problem classes. A blank key field. An unknown Security Type. An unknown Currency. The same Security Type and Currency twice. A blank rate. A non-numeric rate. And keys on screen that the file does not carry.UM.costOfFunds(securityType, currency) is the single implementation of the exception handling and returns {securityType, ccy, internal, external, fallback}. No case-insensitive match on securityType → "Others"; currency not in CCYS → both rates 0. Any consumer must call this rather than reading the store directly, so the rule exists once.renderCof(), so adding or renaming a group reshapes this grid immediately.To get here: User maintenance → 🏭 G7 industry group.
Finance / XYZ_IND_GRP / GOVT NATIONAL / United States → Government, Government Owned, No Guarantee / Airlines / TRANS - NON RAIL / Singapore → Transport, Sovereign / Sovereigns / GOVT NATIONAL / Germany → Government, Supranational / Supranationals / PUBLIC SECTOR / Luxembourg → Supranational, Banking / Banks / BANKS / United Kingdom → Financials and Industrial / Aerospace & Defense / CORPORATE / United States → Credit – Non-financial. The last row is a catch-all, reading Others / Others / Others. It covers anything not mapped. Its G7 group defaults to Others, and is editable.collat-g7-map.| Bond type | Issuer Industry the bond carries |
|---|---|
| Singapore Government Securities (SGS), US Treasuries (UST) | GOVT NATIONAL |
| Supranational, Agency | PUBLIC SECTOR |
| Corporates | CORPORATE |
To get here: User maintenance → 🔖 G7 by bond.
| Column | Read-only or editable | Where the value comes from |
|---|---|---|
| ISIN | read-only | the bond’s own static data |
| Bond Name | read-only | the bond’s own static data (its instrument name) |
| Issuer Name | read-only | the bond’s own static data |
| Issuer Country | read-only | the bond’s own static data |
| Classification Level 4 name | read-only | the mapping row this bond falls on |
| BICS Level 2 Industry Group Name | read-only | the mapping row this bond falls on |
| Issuer Industry | read-only | the bond’s own static data — it is what the mapping row is matched on |
| G7 industry group | editable | the value set on this bond, or the mapping row’s value where none is set |
collat-g7-bond. Only bonds with a value set are stored. The Overview and the Inventory Manager read the same key.g7_by_bond.csv.To get here: User maintenance → 🎯 Source of collateral.
collat-source-rules (stores {sources, rules}); the Overview reads sources to set the chart's source list.To get here: User maintenance → ⭐ Special agreements. This was the 🚫 Exclude CSA screen until 17 Sep 2026, and ⭐ Special CSA until 18 Sep 2026.
CSG_Amberlaine Bank_RIM or GSG_JPM_VM. These are what the Special agreement filter matches.BVM-001, plus Triparty’s counterparty names. These are what “Zero-interest only” and the exclusions match.CSG_Amberlaine Bank_RIM tells the user it is a Bilateral CSA IM with Amberlaine Bank. Where the app does not name a counterparty for an agreement, the counterparty shows as a dash; the generated individual-agreement codes are the case in point.collat-agreement-names. Until the Overview has loaded once there are no names to offer. The finder and the list then both read “The agreement names come from the Overview screen. Open the Overview tab once, then come back.” Both fill themselves in the moment the names arrive, with no refresh.collat-csa-list as one agreement name and one tag per row, and shared with the Overview on the same origin. The Overview picks a change up live, and after a refresh. Anything already maintained arrives tagged Korean CSA if it was on the old collat-exclude-csa list, or had Exclude from the app ticked while that tick box existed — because that tag is now what excluding an agreement means.special_agreements.csv, two columns: Agreement name and Tag. An older file with a third Exclude column still uploads: a Yes in it means what the Korean CSA tag means now, so it is read as that tag. Download and upload carry the list, never the finder — the finder is a way of looking, not a dataset.To get here: User maintenance → 📈 Adjusting exposures.
collat-exposure-adjust.To get here: User maintenance → 📦 Adjusting inventory.
collat-inventory-adjust.The same fields as the Inventory Manager's Bond Inventory table. They are written up once, in US10.3 → “Column display fields”. One difference: Holding is not captured here. It is worked out by the app, not typed in. Everything else on that list is a field the user can fill in on this screen.
To get here: User maintenance → 🏷 Tags & highlights.
collat-tags. It is shared, so the screen where the tag is maintained and the screen where it is painted read the same list.tags_and_highlights.csv and its four columns are the four above.To get here: top tabs → Data (between “User maintenance” and “Requirements 1”).
How to read this table. It has one row per thing the Data tab shows. The middle columns say where it comes from and how it is worked out. The last column says how to prove it is right.
| Figure on screen | Where it comes from | How it is worked out | How to check it |
|---|---|---|---|
| Row count on a set’s card (“777 rows”) | The file you uploaded to that set. | The number of data rows read from your file. For a CSV that is the number of lines after the header row. For JSON it is the number of objects. | Open your file and count the data rows (all lines except the header). It must equal the number on the card. |
| Upload date & time | Your browser’s clock at the moment you uploaded. | Stamped when the upload succeeds; refreshed when you Replace the file. | It should match when you clicked Upload; re-upload and confirm it updates. |
| File name | The file you picked. | Shown exactly as your file was named. | Compare with the file on your computer. |
| Sample value beside a mapped column | Your uploaded file (its first data row). | The value in the first data row of the column you mapped. | Look at the first data row of that column in your file — it must match. |
| Serving: Dummy / Production badge | Worked out from the master switch, whether the set has an upload, and whether its required fields are mapped. | Reads Production only when four things hold at once. The switch is on Production. The set is LIVE. It has an upload. And every required field is mapped. Otherwise it reads Dummy, with the reason. | Flip the switch and add / remove the mapping — the badge must follow the rule above. |
| “N sets served from your uploads” note | The set of cards currently serving Production. | A count of the LIVE sets whose Serving badge reads Production. | Count the green “Serving: Production data” badges — it must equal N. |
#tab-data panel in j-collateraldemo.html; the controller is the DataTab module. The Overview / Overview 2 / Inventory Manager iframes are same-origin, so they share the browser storage below.collatData, object store sets, keyed by set id. They survive reloads. Alongside it, a synchronous read-model is written to localStorage, so the iframes read it without waiting. collat-data-mirror-<id> holds only the mapped columns, re-projected whenever the mapping changes. collat-data-meta-<id> holds the file name, row count, upload date, headers and a first-row sample. The iframes only ever read the mapped columns. Storing just those keeps a wide file well under the browser’s localStorage quota. The mirror is skipped only if even the mapped columns overflow the quota. The card then flags it “too large for live serving — stored durably”. The durable IndexedDB copy is always kept. Reducing the number of mapped fields lets it serve live again.collat-data-mode is the raw string "dummy" or "production". collat-data-map-<id> is a small object of { demoFieldKey: yourColumnHeader }.collat-data-map-<id>, plus the current mode, to collateral-data-mappings.json. Its shape is { app, version, exportedAt, mode, sets:[{id,name,map,file}] }. Import mappings reads such a file and writes each collat-data-map-<id> back. It restores the mode. It re-projects the mirror for any set whose rows are already in IndexedDB. Then it reloads the iframes. The data files themselves are not in this export — the user re-uploads those; only the mappings are restored.CollatData helper reads collat-data-mode + the stored upload/mapping. In Dummy mode every getter returns the built-in demo data unchanged, byte-for-byte. In Production mode a set with an upload and a usable mapping is served from the uploaded rows. Its columns are translated to the demo field names. Only the source rows swap. Every worked-out figure keeps computing exactly as before, on top of whichever source is active. That covers Used, Unallocated, the margin call and the chart aggregations.*) for that set maps to a header the uploaded file actually has.{USD:1,EUR:1.08,GBP:1.27,SGD:0.74,JPY:0.0064}. They are merged over the demo defaults, so unsupplied currencies keep their demo rate. The second is set 15 · Inventory data. It is the shared bond-inventory book behind both the Inventory Manager and the Rules engine, via collat-inventory.js. Unmapped fields fall back to sensible defaults, so every uploaded row still renders. An uploaded Holding column of Internal, External-held or Received is honoured. The other mappable sets are 1, 2, 5, 6, 10 and 14. They accept an upload and a saved mapping now. Each is wired as it is connected.For developers: reference values the app is built on. All data is deterministic demo data, generated in the browser. It uses a random-number generator started from a fixed “seed”. So every load produces exactly the same sample numbers. There is no backend and no live feed. Exact numbers are reproducible but illustrative.
| Ccy | USD | EUR | GBP | SGD | JPY |
|---|---|---|---|---|---|
| Rate | 1.00 | 1.08 | 1.27 | 0.74 | 0.0064 |
| Code | Full name | Base ccy | Sub-books |
|---|---|---|---|
| BVM | ISDA / CSA — Variation Margin | USD | — |
| BIM | ISDA / CSA — Initial Margin | USD | — |
| GMRA | GMRA — Repurchase | USD | VM only |
| GMSLA | GMSLA — Securities Lending | EUR | VM only |
| CCP | CCP — Cleared | USD | IM / VM |
| Futures | Futures / Cleared Derivatives | USD | — |
| Triparty | Triparty Collateral | SGD | Custodians (Euroclear / Clearstream / BNY) |
AAA · AA+ · AA · AA- · A+ · A · A- · BBB+ · BBB · BBB- · BB+ · BB
collat-theme-ds2 (light/dark); aoe-cols:<view> per-table column layout (e.g. tblBonds:summary, tblBonds:postings, tblDrill:trades, tblDrill:postings, tblInv:columns, tblInv:series); collat-inv-pivot, the Inventory Manager pivot view's chosen groupings and amount ({group,row,value}, defaulting to clearer × issuerCtry, notional). Then aoe-re-rules, aoe-re-runs and aoe-re-active for the Rules-engine tab's rules, runs and active run. Then the User-maintenance datasets. collat-cost-of-funds. collat-g7-map, which drives the bond-type and G7 chart. collat-source-rules, which drives the sources chart. collat-csa-list, the Special agreements list — one row per agreement, holding its tag and its exclude flag. Alongside it collat-agreement-names holds the agreement catalog the Overview publishes for it, grouped by screen — each name with the agreement type it is booked under and its counterparty, which is what the finder searches and shows. collat-exposure-adjust. And collat-inventory-adjust. And last collat-um-updated, holding the last-updated stamps.For testers and developers. This lists every finance term and abbreviation used in the app. Each gets a plain definition. Where the term is a number, it also says where that number comes from. All values are deterministic in-browser demo data. They are invented sample numbers that come out identical on every load, with no live feed. The “production source” notes say where the real data would come from.
Applies to the Overview docked tables — Summary/Detailed, Postings and Margin Calls. Also the exposure drill, in both modes, and the Inventory Manager table. They all share the same behaviour, so it is documented once here.
Build detail: every hover tooltip (the exact title= text), hover-cursor behaviour, chart tooltip, and status text that changes at runtime. Reproduce these strings verbatim.
What this is. A complete, screen-by-screen list of every field the application shows. Each is traced back to the exact data it comes from. That means the numbered data set, from the 15-set Data source catalog. Where relevant it also names the entity and field in the Data model & data dictionary. This is the field-level companion to the widget-level “Widget → data & logic lineage” on Requirements 2.
How the links work. Each coloured data-set or entity name is a link. Click it to jump to that set in the catalog, or that entity in the data dictionary. It opens the Requirements 2 tab and scrolls to the definition. How to read the “Comes from” column. A value is one of three things. Referenced means looked up from one of the 15 sets, and it always matches that set. Held on the record itself means the screen’s own stored data. Worked out means calculated from other fields. Those plain-English formulas live in the dictionary’s derived figures. Everything on these screens is deterministic in-browser demo data. It is the same on every load, with no live feed. The mappings say where the real data would come from.
Standing rule (data lineage): every field must trace to a set in the 15-set catalog. Some fields below do not yet trace to a catalogued set. They are gathered in §E.14 · Off-catalogue & to-confirm, and flagged with a ⚑. They are raised, not invented. A source must be agreed and added to the catalog before the field is built for real.
The docked per-agreement table (§2, Epic 2). One row per agreement type (Summary) or per individual agreement (Detailed). Every money figure is worked out from the daily book record (data models 10 & 14) at the reference date. The two levels show different columns. Three groups appear only at the Detailed level, and never on the type-level Summary. They are the exposure split (ITM / OTM). The dispute pair (Value / Age). And the base-currency set (Base CCY / Total Exp. / Call Amt).
| Field (column) | Data set | Entity · field | Comes from (plain English) |
|---|---|---|---|
| Agreement | Agreements static · 6 (Triparty also Counterparty static · 1) | data model 6 · name, colour | Referenced — the type’s name and colour dot. At Detailed level it is the individual agreement’s account code, from data model 6. Under Triparty there are no agreement codes. There it is the counterparty’s name — the counterparty whose collateral that agent holds. |
| Total exposure | Exposures & margin calls · 10 + Agreements static · 6 | derived figures (Exposure) | Worked out — what’s owed that day plus the type’s threshold cushion. |
| Call / obligation | Exposures & margin calls · 10 | data models 10 & 14 · obligation | Referenced — the day’s obligation (what needs covering). |
| Received (in) | Collateral used data · 14 | data models 10 & 14 · received | Referenced — inbound collateral received that day. Information only: it is displayed and totalled, and it never feeds Unallocated, the margin call, or any other worked-out figure. |
| Margin call | Exposures & margin calls · 10 | Exposures & margin calls · 10 | Read straight from the margin-call record for that agreement and date — not worked out from anything on the screen. Positive means collateral must be delivered; negative means there is more posted than owed and it can be collected back. To check it, read the same figure back from the margin-call data. The Margin Calls view shows it. Do not recompute it from the other columns. |
| Total posting | Collateral used data · 14 | data models 10 & 14 · total posting | Referenced — the collateral posted that day (bonds + cash). |
| Bonds (Posted) | Collateral used data · 14 | data models 10 & 14 · bonds posted | Referenced — the bond part of the posting. |
| Cash (Posted) | Collateral used data · 14 | data models 10 & 14 · cash posted | Referenced — the cash part of the posting. |
| Total allocated | Worked out | derived figures (Allocated) | Worked out — the smaller of Total posting and Total exposure. |
| Bonds (Allocated) | Worked out | derived figures | Worked out — Total allocated split into bonds in the same proportion as the posting. |
| Cash (Allocated) | Worked out | derived figures | Worked out — the cash part of Total allocated. |
| Unallocated | Worked out | derived figures (Unallocated) | Worked out — Total posting minus Total allocated. To check it: read that row’s Total posting and Total allocated and subtract; it must equal this cell. |
| Surplus | Worked out | derived figures (Surplus) | Worked out — Total allocated minus Margin call. To check it: read that row’s Total allocated and Margin call and subtract; it must equal this cell. Watch the sign: where Margin call is negative, subtracting it adds to the surplus. |
| DoD / WoW / MoM (total allocated) | Worked out | derived figures | Worked out — the change in Total allocated versus the same figure 1 / 7 / 30 days earlier. |
| Threshold | Agreements static · 6 | data model 6 · threshold cushion | Referenced — the type’s threshold cushion. |
| Expected post / Expected collect | Worked out | derived figures | Worked out — the deliver amount when short (post) or the recall amount when in unallocated (collect). |
| ITM / OTM Exposure (Detailed level only) | Exposures & margin calls · 10 ⚑ | derived figures | Worked out — the in-your-favour / against-you split of exposure. Shown only at the individual-agreement (Detailed) level. ⚑ The split is a modelled proportion, not a real mark-to-market feed (see §E.14). |
| Dispute Value, Dispute Age (Detailed level only) | Exposures & margin calls · 10 | derived figures | Referenced/worked out — the size and age of any dispute between your figure and the counterparty’s. Shown only at the Detailed level; modelled close to the call amount in the demo (see §E.14). |
| Base CCY, Base Total Exp., Base Call Amt (Detailed level only) | Agreements static · 6 + Market data FX · 8 | derived figures | Referenced/worked out — the agreement’s own reporting currency, and the exposure / call amount converted into it using the FX rate. Shown only at the Detailed level. |
Individual-agreement rows take each type figure and scale it down. The scale is that agreement’s share of the type, from data model 6. Rows can also be dropped by the user’s Exclude-CSA list (Exclude CSA · 7.4), and by the zero-interest filter.
This sheet is generated from the running application, not typed by hand. The numbers below are read straight off the Agreement summary table at /j-collateral (Summary by agreement type, as at 2026-06-18). Every worked-out figure is then re-calculated from the other figures on the same row. It is then compared with what the screen shows. So the rules written here and the figures the application produces cannot disagree. If they ever did, this sheet would flag the row in red and the build would fail its checks. Open the screen beside this page and follow the "How to check it" column. Every figure can be confirmed with a subtraction you can do in your head.
| Figure | What it means / how it is worked out | How to check it | Worked example — live figures |
|---|---|---|---|
| Call / obligation | What the agreement's trades owe on the reference date, before any collateral is taken into account. | It is the starting figure on the row — everything else on the row is built from it. Click the cell to list the trades that make it up; their amounts add up to this figure. | GMRA reads $635.9M. |
| Threshold | The unsecured cushion written into the agreement — the amount that may go uncovered before collateral is required. | Fixed per agreement type (GMRA $12.0M, GMSLA $18.0M, all others zero). Compare with the agreement's own terms. | GMRA reads $12.0M. |
| Total exposure | Everything the agreement has to cover: what is owed plus its threshold cushion. | Add the row's Call / obligation and Threshold. The answer must equal this cell. | GMRA: $635.9M + $12.0M = $647.9M |
| Total Posting · Total | All the collateral posted against the agreement — bonds and cash together. It is the Total column of the Total Posting group. | Add the row's Bonds (Posted) and Cash (Posted) — the other two columns under Total Posting. Click the cell to list the individual postings; they add up to this figure. | GMRA: $587.9M + $11.1M = $598.9M |
| Margin call | The call struck against the agreement on the reference date. A positive figure means collateral must be delivered. A negative figure means more is posted than owed, and it can be collected back. It is an INBOUND figure, read from the Exposures & margin calls data, catalog set 10. It is not worked out from anything else on the row. | Do not recompute it from this row. Read it back from the margin-call record for that agreement and date. The Margin Calls view shows the same figure. In the sample data the call is struck as the day's position. So it currently also equals Call / obligation minus Total Posting · Total. But that is a property of the sample, not the rule. The build must READ the figure; if the data and that subtraction ever disagree, the margin-call data wins. | GMRA reads $37.0M. |
| Total Allocated · Total | How much of the posted collateral is actually consumed covering the exposure. It is never more than was posted, and never more than the exposure needs. It is the Total column of the Total Allocated group. | Take the smaller of the row's Total Posting · Total and its Total exposure. The answer must equal this cell. | GMRA: the smaller of $598.9M and $647.9M = $598.9M |
| Total Allocated · Bonds (Allocated) + Cash (Allocated) | The allocated total split between bonds and cash in the same proportion as the collateral was posted. | Add the other two columns under Total Allocated: Bonds (Allocated) and Cash (Allocated). The answer must equal Total Allocated · Total. | GMRA: $587.9M + $11.1M, which must equal Total Allocated · Total = $598.9M |
| Unallocated | The collateral posted but not consumed — what is sitting there spare. Never negative, because nothing can use more than was posted. | Subtract the row's Total Allocated · Total from its Total Posting · Total. The answer must equal this cell. | GMRA: $598.9M − $598.9M = $0.0M |
| Surplus | What is left of the collateral allocated once the margin call has been met. The margin call is positive when we have to post. Allocate $100M against a call of $50M, and $50M is spare. A negative call means nothing has to go out. It can be collected back, so it adds to the surplus. | Subtract the row's Margin call from its Total Allocated · Total. The answer must equal this cell. Watch the sign: where Margin call is negative, subtracting it ADDS to the surplus. | GMRA: $598.9M − $37.0M = $562.0M |
| Expected post | The collateral expected to go out: the margin call when it is positive, otherwise nothing. | Read the row's Margin call. If it is positive this cell repeats it; if it is negative or zero this cell reads zero. | GMRA: Margin call is $37.0M, so this cell = $37.0M |
| Expected collect | The collateral expected to come back: the margin call when it is negative, shown without the minus sign, otherwise nothing. | Read the row's Margin call. If it is negative, this cell shows the same amount without the minus sign. If it is positive or zero, this cell reads zero. Bilateral CSA IM shows a dash, because initial margin is not collected back. | GMRA: Margin call is $37.0M, so this cell = $0.0M |
| Received (in) | Collateral counterparties have posted TO us on the reference date. It is INFORMATION ONLY. | There is nothing on this row to reconcile it against, and that is deliberate. Received (in) never feeds the margin call, Unallocated, Surplus or any other worked-out figure. If a change ever makes another figure move when Received moves, that is a defect. | GMRA reads $672.4M. |
| Agreement | Total exposure | Call / obligation | Received (in) | Margin call | Total Posting · Total | Total Posting · Bonds (Posted) | Total Posting · Cash (Posted) | Total Allocated · Total | Total Allocated · Bonds (Allocated) | Total Allocated · Cash (Allocated) | Unallocated | Surplus | Threshold | Expected post | Expected collect |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| GMRA | $647.9M | $635.9M | $672.4M | $37.0M | $598.9M | $587.9M | $11.1M | $598.9M | $587.9M | $11.1M | $0K | $562.0M | $12.0M | $37.0M | $0K |
| CCP | $485.1M | $485.1M | $513.9M | -$28.4M | $513.5M | $263.7M | $249.8M | $485.1M | $249.1M | $236.0M | $28.4M | $513.5M | $0K | $0K | $28.4M |
| GMSLA | $394.9M | $376.9M | $404.2M | -$32.0M | $408.9M | $373.8M | $35.1M | $394.9M | $361.0M | $33.9M | $14.0M | $426.9M | $18.0M | $0K | $32.0M |
| Bilateral CSA VM | $225.2M | $225.2M | $254.5M | -$34.1M | $259.4M | $79.7M | $179.7M | $225.2M | $69.2M | $156.0M | $34.1M | $259.4M | $0K | $0K | $34.1M |
| Bilateral CSA IM | $200.5M | $200.5M | $209.1M | $26.5M | $174.0M | $139.6M | $34.4M | $174.0M | $139.6M | $34.4M | $0K | $147.4M | $0K | $26.5M | — |
| Futures | $141.8M | $141.8M | $148.2M | $77.2M | $64.7M | $13.3M | $51.3M | $64.7M | $13.3M | $51.3M | $0K | -$12.5M | $0K | $77.2M | $0K |
| Total (6) | $2.1B | $2.07B | $2.2B | $46.2M | $2.02B | $1.46B | $561.3M | $1.94B | $1.42B | $522.6M | $76.5M | $1.9B | $30.0M | $140.7M | $94.5M |
The cards above the table and the table’s own total row are two views of the same figures. Read one against the other — they must agree, allowing for rounding. The cards are rounded to whole millions or billions. The table is rounded to one decimal place. This is the quickest check that the screen is internally consistent.
| Key-figures card | Card shows | Table total row column | Total row shows | Agree? |
|---|---|---|---|---|
| Total exposure | $2.1B | Total exposure | $2.1B | ✓ agree |
| Total posting | $2B | Total Posting · Total | $2.02B | ✓ agree |
| Bonds posted | $1.5B | Total Posting · Bonds (Posted) | $1.46B | ✓ agree |
| Cash posted | $561M | Total Posting · Cash (Posted) | $561.3M | ✓ agree |
| Total allocated | $1.9B | Total Allocated · Total | $1.94B | ✓ agree |
| Bonds allocated | $1.4B | Total Allocated · Bonds (Allocated) | $1.42B | ✓ agree |
| Cash allocated | $523M | Total Allocated · Cash (Allocated) | $522.6M | ✓ agree |
| Unallocated | $76.5M | Unallocated | $76.5M | ✓ agree |
| Received (inbound) | $2.2B | Received (in) | $2.2B | ✓ agree |
Result of this run: every figure ties — no mismatches.
What this is. A generated check that every field the Data tab lets you map is actually read by a screen. It is the field-level companion to the Figure check sheet: that one stops the numbers in this document drifting from the app, this one stops the fields drifting. It is written by a script and re-checked by the standing test run, so a field that quietly stops being read cannot sit here unnoticed.
How to read it. Read means mapping that field changes what a screen shows. Not read means the box is there and nothing looks at it — a field you could fill in for no effect. Set not wired means no screen asks for that data set at all yet, so every one of its fields is in that position today.
Summary. 14 data sets accept a mapping. 4 are wired into the screens (8, 15, 121, 122). 10 are not: 1 · Counterparty static, 2 · Bond / securities static, 5 · Currency static, 6 · Agreements static, 6.1 · Agreement eligibility schedule, 10 · Exposures & margin calls, 12 · Optimization outputs, 13 · Optimization exclusions & exceptions, 14 · Collateral used data, 16 · MX Trades Data. Of the fields on wired sets, 0 are never read.
| Set | Field you can map | Status | Read by |
|---|---|---|---|
| 1 · Counterparty static | Counterparty name * | not wired | — |
| 1 · Counterparty static | Counterparty code | not wired | — |
| 2 · Bond / securities static | ISIN * | not wired | — |
| 2 · Bond / securities static | Instrument Name | not wired | — |
| 2 · Bond / securities static | Issuer | not wired | — |
| 2 · Bond / securities static | Coupon | not wired | — |
| 2 · Bond / securities static | Maturity | not wired | — |
| 2 · Bond / securities static | Bond Currency | not wired | — |
| 2 · Bond / securities static | Bond type | not wired | — |
| 2 · Bond / securities static | Asset class | not wired | — |
| 2 · Bond / securities static | Asset type | not wired | — |
| 2 · Bond / securities static | Issuer type | not wired | — |
| 2 · Bond / securities static | Issuer country | not wired | — |
| 2 · Bond / securities static | Seniority | not wired | — |
| 2 · Bond / securities static | Rating1 | not wired | — |
| 2 · Bond / securities static | Rating2 | not wired | — |
| 2 · Bond / securities static | Rating3 | not wired | — |
| 5 · Currency static | Currency code * | not wired | — |
| 5 · Currency static | Base currency | not wired | — |
| 6 · Agreements static | Type code * | not wired | — |
| 6 · Agreements static | Short name | not wired | — |
| 6 · Agreements static | Full name | not wired | — |
| 6 · Agreements static | Reporting currency | not wired | — |
| 6 · Agreements static | Colour | not wired | — |
| 6 · Agreements static | Sub-accounts | not wired | — |
| 6 · Agreements static | Custodian | not wired | — |
| 6 · Agreements static | Threshold cushion ($mm) | not wired | — |
| 6 · Agreements static | Agreement end date | not wired | — |
| 6 · Agreements static | Benchmark rate | not wired | — |
| 6 · Agreements static | Rounding (delivery) | not wired | — |
| 6 · Agreements static | Rounding (return) | not wired | — |
| 6 · Agreements static | Holiday centre(s) | not wired | — |
| 6 · Agreements static | Settlement delay | not wired | — |
| 6 · Agreements static | Calculation rule | not wired | — |
| 6 · Agreements static | Interest settlement date | not wired | — |
| 6 · Agreements static | Allow negative rate | not wired | — |
| 6 · Agreements static | Concentration limits group name | not wired | — |
| 6 · Agreements static | Limit type | not wired | — |
| 6 · Agreements static | Limit type granularity | not wired | — |
| 6 · Agreements static | Limit | not wired | — |
| 6 · Agreements static | Limit unit | not wired | — |
| 6 · Agreements static | Basis | not wired | — |
| 6 · Agreements static | Margin type | not wired | — |
| 6 · Agreements static | Valuation frequency | not wired | — |
| 6 · Agreements static | Reciprocity | not wired | — |
| 6 · Agreements static | ABC MTA | not wired | — |
| 6 · Agreements static | Counterparty MTA | not wired | — |
| 6 · Agreements static | Notification time | not wired | — |
| 6 · Agreements static | Resolution time | not wired | — |
| 6 · Agreements static | Time zone | not wired | — |
| 6 · Agreements static | Interest calc method | not wired | — |
| 6 · Agreements static | Interest / rebate rate | not wired | — |
| 6 · Agreements static | Issuer sector | not wired | — |
| 6 · Agreements static | ABC threshold | not wired | — |
| 6 · Agreements static | Counterparty threshold | not wired | — |
| 6 · Agreements static | Minimum rating accepted | not wired | — |
| 6 · Agreements static | Collateral types accepted | not wired | — |
| 6 · Agreements static | Counterparty | not wired | — |
| 6.1 · Agreement eligibility schedule | Type code * | not wired | — |
| 6.1 · Agreement eligibility schedule | Eligibility schedule name | not wired | — |
| 6.1 · Agreement eligibility schedule | Collateral type | not wired | — |
| 6.1 · Agreement eligibility schedule | Eligible currencies | not wired | — |
| 6.1 · Agreement eligibility schedule | Minimum security rating | not wired | — |
| 6.1 · Agreement eligibility schedule | Time to maturity | not wired | — |
| 6.1 · Agreement eligibility schedule | Haircut schedule | not wired | — |
| 6.1 · Agreement eligibility schedule | Exclusions | not wired | — |
| 6.1 · Agreement eligibility schedule | Interest / rebate rate | not wired | — |
| 7.2 · G7 industry group | Issuer Industry | not wired | — |
| 7.2 · G7 industry group | Classification Level 4 name | not wired | — |
| 7.2 · G7 industry group | BICS Level 2 Industry Group Name | not wired | — |
| 7.2 · G7 industry group | G7 industry group | not wired | — |
| 7.3 · Source of collateral | Collateral source | not wired | — |
| 7.8 · G7 by bond | ISIN | not wired | — |
| 7.8 · G7 by bond | G7 industry group | not wired | — |
| 8 · Market data — FX rates | FX Currency * | read | collat-inventory.js, j-collateral.html |
| 8 · Market data — FX rates | Rate (USD per 1 unit) * | read | collat-inventory.js, j-collateral.html |
| 10 · Exposures & margin calls | Agreement type * | not wired | — |
| 10 · Exposures & margin calls | Date * | not wired | — |
| 10 · Exposures & margin calls | Obligation (what’s owed) * | not wired | — |
| 10 · Exposures & margin calls | Total posting | not wired | — |
| 10 · Exposures & margin calls | Bonds posted | not wired | — |
| 10 · Exposures & margin calls | Cash posted | not wired | — |
| 10 · Exposures & margin calls | Received (inbound) | not wired | — |
| 10 · Exposures & margin calls | Bond share for the day | not wired | — |
| 10 · Exposures & margin calls | Margin call | not wired | — |
| 10 · Exposures & margin calls | Dispute age | not wired | — |
| 12 · Optimization outputs | Run reference * | not wired | — |
| 12 · Optimization outputs | Run name | not wired | — |
| 12 · Optimization outputs | Agreement Name * | not wired | — |
| 12 · Optimization outputs | ISIN * | not wired | — |
| 12 · Optimization outputs | Market value posted ($mm) | not wired | — |
| 12 · Optimization outputs | Haircut applied | not wired | — |
| 12 · Optimization outputs | Collateral value ($mm) | not wired | — |
| 12 · Optimization outputs | Funding cost (bps) | not wired | — |
| 12 · Optimization outputs | Annual carry cost ($mm) | not wired | — |
| 12.1 · Bond sources (internal) | ISIN * | read | j-collateraldemo.html |
| 12.1 · Bond sources (internal) | Desk (Source) | read | j-collateraldemo.html |
| 12.1 · Bond sources (internal) | Portfolio (Source) * | read | j-collateraldemo.html |
| 12.1 · Bond sources (internal) | Direction | read | j-collateraldemo.html |
| 12.1 · Bond sources (internal) | Amount | read | j-collateraldemo.html |
| 12.1 · Bond sources (internal) | Start Date | read | j-collateraldemo.html |
| 12.1 · Bond sources (internal) | End Date | read | j-collateraldemo.html |
| 12.1 · Bond sources (internal) | Rate | read | j-collateraldemo.html |
| 12.2 · Bond destinations (postings out) | ISIN * | read | j-collateraldemo.html |
| 12.2 · Bond destinations (postings out) | Agreement (Destination) * | read | j-collateraldemo.html |
| 12.2 · Bond destinations (postings out) | Destination | read | j-collateraldemo.html |
| 12.2 · Bond destinations (postings out) | Direction | read | j-collateraldemo.html |
| 12.2 · Bond destinations (postings out) | Amount | read | j-collateraldemo.html |
| 12.2 · Bond destinations (postings out) | Start Date | read | j-collateraldemo.html |
| 12.2 · Bond destinations (postings out) | End Date | read | j-collateraldemo.html |
| 12.2 · Bond destinations (postings out) | Rate | read | j-collateraldemo.html |
| 13 · Optimization exclusions & exceptions | Run reference * | not wired | — |
| 13 · Optimization exclusions & exceptions | Exception category * | not wired | — |
| 13 · Optimization exclusions & exceptions | Record reference * | not wired | — |
| 13 · Optimization exclusions & exceptions | Record name | not wired | — |
| 13 · Optimization exclusions & exceptions | Record detail | not wired | — |
| 13 · Optimization exclusions & exceptions | Why it was held out | not wired | — |
| 13 · Optimization exclusions & exceptions | Records affected | not wired | — |
| 13 · Optimization exclusions & exceptions | Amount needed ($mm) | not wired | — |
| 13 · Optimization exclusions & exceptions | Amount covered ($mm) | not wired | — |
| 13 · Optimization exclusions & exceptions | Amount short ($mm) | not wired | — |
| 13 · Optimization exclusions & exceptions | Collateral types accepted | not wired | — |
| 13 · Optimization exclusions & exceptions | Minimum rating accepted | not wired | — |
| 13 · Optimization exclusions & exceptions | Eligible issuer groups | not wired | — |
| 13 · Optimization exclusions & exceptions | Eligible lines that qualify | not wired | — |
| 14 · Collateral used data | Agreement Name * | not wired | — |
| 14 · Collateral used data | Trade # | not wired | — |
| 14 · Collateral used data | Position | not wired | — |
| 14 · Collateral used data | Counterparty | not wired | — |
| 14 · Collateral used data | Asset Class | not wired | — |
| 14 · Collateral used data | Agreement Category | not wired | — |
| 14 · Collateral used data | ISIN / Currency * | not wired | — |
| 14 · Collateral used data | Maturity Date | not wired | — |
| 14 · Collateral used data | Date of Posting | not wired | — |
| 14 · Collateral used data | Valuation Date | not wired | — |
| 14 · Collateral used data | Booking Currency | not wired | — |
| 14 · Collateral used data | Par Amount | not wired | — |
| 14 · Collateral used data | Booking Market Value | not wired | — |
| 14 · Collateral used data | Booking Collateral Value | not wired | — |
| 14 · Collateral used data | Haircut | not wired | — |
| 14 · Collateral used data | Reporting Currency | not wired | — |
| 14 · Collateral used data | Market Value (USD) | not wired | — |
| 14 · Collateral used data | Collateral Value (USD) | not wired | — |
| 14 · Collateral used data | FX Rate | not wired | — |
| 15 · Inventory data | Portfolio | read | collat-inventory.js |
| 15 · Inventory data | Business Line | read | collat-inventory.js |
| 15 · Inventory data | Holding | read | collat-inventory.js |
| 15 · Inventory data | Instrument Name | read | collat-inventory.js |
| 15 · Inventory data | ISIN * | read | collat-inventory.js |
| 15 · Inventory data | Bond Currency | read | collat-inventory.js |
| 15 · Inventory data | Bond Notional (mm) | read | collat-inventory.js |
| 15 · Inventory data | Issuer Name | read | collat-inventory.js |
| 15 · Inventory data | Issuer Country | read | collat-inventory.js |
| 15 · Inventory data | Seniority of Bond | read | collat-inventory.js |
| 15 · Inventory data | Coupon | read | collat-inventory.js |
| 15 · Inventory data | Callable | read | collat-inventory.js |
| 15 · Inventory data | Clearer | read | collat-inventory.js |
| 15 · Inventory data | Sector of Issuer | read | collat-inventory.js |
| 15 · Inventory data | Industry Classification | read | collat-inventory.js |
| 15 · Inventory data | Issuer Rating | read | collat-inventory.js |
| 15 · Inventory data | Bond Rating | read | collat-inventory.js |
| 15 · Inventory data | MTM of Notional (mm) | read | collat-inventory.js |
| 15 · Inventory data | Trade Start | read | collat-inventory.js |
| 15 · Inventory data | Maturity Date | read | collat-inventory.js |
| 16 · MX Trades Data | Product | not wired | — |
| 16 · MX Trades Data | Trade ID * | not wired | — |
| 16 · MX Trades Data | Trade date | not wired | — |
| 16 · MX Trades Data | Maturity | not wired | — |
| 16 · MX Trades Data | Notional | not wired | — |
| 16 · MX Trades Data | Trade Currency | not wired | — |
| 16 · MX Trades Data | MtM (USD) | not wired | — |
| Card | Data set | Entity · field | Comes from (plain English) |
|---|---|---|---|
| Total exposure | 10 + 6 | derived figures | Worked out — obligation across the selection plus each threshold cushion. |
| Total posting · Bonds posted · Cash posted · Received (inbound) | Collateral used data · 14 | data models 10 & 14 · posting / bonds / cash / received | Referenced — the day’s posting figures and inbound collateral, added across the selection. |
| Total allocated · Bonds allocated · Cash allocated · Unallocated | Worked out | derived figures | Worked out. Allocated is the smaller of posting and exposure. It is split into bonds and cash by the posting mix. Unallocated is posting minus allocated. Each card’s sub-line compares versus one week earlier. |
| Element | Data set | Comes from (plain English) |
|---|---|---|
| Utilisation history — Bonds / Cash bars | Collateral used data · 14 | The period-average bonds and cash posted (data models 10 & 14), bucketed to the chosen granularity. |
| Utilisation history — Exposure line | 10 + 6 | Worked out — obligation plus threshold across the selection. |
| Utilisation history — Total-posted line | Worked out | The posted total itself, read straight off the record — the same figure as the Total posting card and the Agreement summary table. It lands exactly on top of the Bonds + Cash bars. The fixed 10% demo buffer that used to lift it was removed on 08 Aug 2026 (OQ-10, closed). |
| By agreement — stacked posting mix | 14 + 6 | Posted per agreement (colours from Agreements static). |
| Sources of collateral — bars | 14 + Source of collateral · 7.3 | Posted value grouped by funding source; the source of each posting follows the user’s Source-of-collateral rules. |
| Bond collateral by G7 group — doughnut | 14 + 2 + G7 industry group · 7.2 | Posted bond value grouped by G7 industry group — each bond’s sector (Bond static) mapped through the user’s G7 map. |
| Cross-filter chips (As at / Active in / Agreement / Type / Source / breakdown / postings) | follows the filtered dimension | Each chip is a filter over the dimension it names. Those are agreement (6), bond type (2), source (7.3/14), or a date or period from screen state. |
Same underlying figures as the Agreement summary table (§E.1). Every column is either an Agreements static · 6 attribute or an Exposures & margin calls · 10 figure.
| Field | Data set | Comes from (plain English) |
|---|---|---|
| Agreement · Category · LRP · Threshold · Base CCY · Notification time · Resolve by · Credit Rating · Statement Status · Region | Agreements static · 6 | Referenced — attributes carried on the agreement / its type. |
| Total Exposure · Call / Obligation · Margin Call | Exposures & margin calls · 10 | The day’s obligation (+ threshold for exposure); Margin Call = owed minus posted. |
| Call Status · Action | 10 | The call’s review status; Action = Delivery or Call. |
| ITM / OTM Exposure · Net Alternative ⚑ | 10 ⚑ | Modelled split of exposure — no real mark-to-market feed (see §E.14). |
| STD Amount · Cpty Amount · Agreed Amount · Dispute Value · Dispute Age | 10 | Your figure, the counterparty’s, the agreed one, and any dispute; modelled close to the call amount in the demo. |
| Base Total Exp. · Base Call Amt | 10 + FX · 8 | Exposure / call amount converted into the agreement’s base currency. |
| KPI tiles: Total Margin Call · Pending Review · Confirmed · No Call · Disputes | 10 | Totals / counts of the rows by call status and dispute. |
| Column | Data set | Entity · field | Comes from (plain English) |
|---|---|---|---|
| Agreement Name | 6 + 1 | data model 14 | The individual agreement’s account code (agreement + counterparty + sub-book). |
| Trade # | Collateral used data · 14 | data model 14 | Held on the posting line — its posting/trade reference. |
| ISIN · Security · Type · Sector · Original Ccy · Maturity | Bond / securities static · 2 | data model 14 (instrument attributes) | Referenced — the security’s reference details. |
| Counterparty | Counterparty static · 1 | data model 14 | Referenced — who the collateral is with. |
| Agreement Type | Agreements static · 6 | data model 6 · name | Referenced — the type this posting sits under. |
| Custodian | 6 / 14 | data model 14 | The custody agent (the type’s sub-account, or the settlement agent held on the line). On a Triparty line this is the triparty repo agent — Euroclear, Clearstream or BNY Mellon. |
| Source | Source of collateral · 7.3 | data model 14 | The funding source, per the user’s Source-of-collateral rules. |
| Start date | Collateral used data · 14 | data model 14 | Held on the line — when the posting started. |
| Maturing in Days | Worked out | derived figures | Worked out — days from the reference date to maturity. |
| Original Amount | Collateral used data · 14 + FX · 8 | data model 14 | Worked out — how much of the bond was posted on this line. It is counted in the instrument’s own currency. Take the posted value in US dollars and convert it back at the line’s exchange rate. |
| Posted (USD) | Collateral used data · 14 + FX · 8 | data model 14 | What G7 posted on this line, in US dollars — the Original Amount multiplied by the line’s exchange rate. The posted lines of an agreement add back to that agreement’s “Bonds (Posted)” figure in the summary. |
| Allocated (USD) | Collateral used data · 14 + Exposures & margin calls · 10 | data model 14 | Worked out — what TMO allocated on this posting, not what G7 posted. Take the Posted (USD) figure and scale it down by the agreement’s allocated-versus-posted coverage. That coverage is the smaller of one, and the exposure divided by the total posting. So the postings add back to the agreement’s “Bonds (Allocated)” in the summary. |
| Unallocated (USD) | Worked out | data model 14 | Worked out — Posted (USD) minus Allocated (USD). It is what was posted into the long box, but not consumed by the agreement’s margin requirement. Never below zero; a fully-used posting shows nothing unallocated. |
| Field | Data set | Comes from (plain English) |
|---|---|---|
| Triparty agent (section) | 6 / 14 | The triparty custody agent (Euroclear / Clearstream / BNY Mellon). |
| Country (row) ⚑ | ⚑ none | ⚑ The country breakdown has no catalogued source — a fixed demo list (see §E.14). |
| T+0 … T+5 amounts & total ⚑ | ⚑ none | ⚑ The settlement-availability amounts are demo placeholder numbers. They are not drawn from Collateral used (14) or Inventory (15). A source must be agreed — see §E.14. |
Most of the popup is the agreement’s term sheet — all Agreements static · 6. The live money figures re-use the Overview book (§E.1).
| Card · field | Data set | Comes from (plain English) |
|---|---|---|
| Exposure card — MTM & Independent Amount (IA) ⚑ | 10 ⚑ | Worked out — the obligation split into a market-value part and an independent-amount buffer. ⚑ The split is modelled, not a real valuation feed (see §E.14). |
| Required / Posted / Shortfall / % covered | 10 + 14 | Worked out — obligation vs posting at the reference date. |
| Agreement Admin — type, margin type, valuation frequency, reciprocity | Agreements static · 6 | Referenced — the agreement’s legal / mechanics terms. |
| Agreement Admin — Benchmark rate ⚑ | 6 (name) / 9 | The reference-rate name only (e.g. SOFR). ⚑ Benchmark rate levels (set 9) are a placeholder — no rate value is modelled. |
| Dates & Status — Start / End date; Agreement status | 6 / Worked out | Start/End referenced; status worked out from whether there is a call. |
| Eligibility schedule — Cash / Govt blocks (asset class, currency, interest/rebate rate, issuer, seniority, rating floor, maturity limit, haircut schedule, exclusions) | Agreements static · 6 | Referenced — the agreement’s eligible-collateral schedule (per collateral type). |
| Eligibility schedule — Corp block ⚑ | 6 ⚑ | ⚑ Several Corp schedule rows carry the same fixed wording for every agreement, rather than per-agreement data. They should be sourced from each agreement’s schedule. See §E.14. |
| Eligibility — “$X posted · Y%” per type | 14 + 2 | Worked out — the agreement’s postings grouped into Cash / Govt / Corp. |
| Concentration risk — limit meta (group, limit type, granularity, limit, unit, basis) | Agreements static · 6 | Referenced — the agreement’s concentration limits. |
| Concentration risk — by-asset-type & by-issuer bars, breach flag | 14 + 2 | Worked out — each asset type’s / issuer’s share of the posting, compared to the limit. |
| Asset Holdings Summary — sector rows, Total bonds / Cash / Total posted ⚑ | 14 + 2 | Worked out — the agreement’s postings by sector. ⚑ The Delivery / Market-Value / Collateral-Value columns use fixed demo factors rather than real per-line values (see §E.14). |
| Margin Call Summary — ABC / Cpty MTA, rounding | Agreements static · 6 | Referenced — minimum transfer amounts and rounding terms. |
| Margin Call Calculation — balance, call/unallocated, thresholds, total exposure | 10 + 14 + 6 | Worked out — posted vs owed and the resulting call, against the thresholds. |
| Call Schedule — notification / resolution time, time zone, settlement delay | Agreements static · 6 | Referenced — the agreement’s call-timing terms. |
| Call Schedule — Holiday centre(s) ⚑ | 6 (text) / 3 | Free-text on the agreement. ⚑ A real holiday calendar (set 3) is a placeholder. |
| Collateral Rules — interest calc method, calc rule, interest settlement, allow negative rate | Agreements static · 6 | Referenced — the agreement’s interest/collateral terms. |
| Trades tab (Product, Trade ID, Trade date, Maturity, Notional, Ccy, MtM) ⚑ | ⚑ none (MtM ties to 10) | ⚑ The individual derivative trades have no catalogued source — only their total mark-to-market ties back to the exposure (see §E.14). |
| Postings tab | 14 + 2 | The same postings blotter (§E.5), filtered to this agreement. |
| Column | Data set | Comes from (plain English) |
|---|---|---|
| Agreement | 6 / 1 | Referenced — the agreement the trade belongs to. |
| MtM (USD) | Exposures & margin calls · 10 | Worked out — the per-trade mark-to-market; the total ties to the agreement’s exposure. |
| Product, Trade ID, Trade date, Maturity, Notional (USD), Ccy ⚑ | ⚑ none | ⚑ The individual trade attributes have no catalogued source — a derivative-trade feed is needed (see §E.14). |
| (Collateral-Posted mode) | 14 + 2 | The same postings blotter (§E.5). |
| Field | Data set | Comes from (plain English) |
|---|---|---|
| Instrument name, ISIN, Issuer, Issuer country, Industry classification, Sector of issuer, Instrument currency, Coupon (and whether it is callable), Seniority, Maturity date | Bond / securities static · 2 | Referenced — the security’s reference details. On the Overview the country and the sector come from the issuer reference list. The industry classification comes from the bond’s type. In the real system all of them are held once, on the security. |
| Clearer ⚑ | 2 / 14 ⚑ | Where the collateral settles and sits. On the Overview it is the posting’s custodian or triparty agent. ⚑ Confirm whether it belongs to the security’s settlement instructions or to the position (see §E.14). |
| Bond rating, Issuer rating ⚑ | 2 ⚑ | Worked out from the bond type. The bond’s own rating is then moved off the issuer’s by its seniority. Subordinated paper rates lower; secured and covered paper rates higher. ⚑ Not a stored per-security rating (see §E.14). |
| Classification Level 4 name, BICS Level 2 Industry Group Name, Issuer Industry, G7 Industry group | G7 industry group · 7.2 | Every bond maps to one row of the G7 industry group mapping table (§14). All four are that row’s values. That is the row whose Issuer Industry matches the bond’s, and that has a G7 group filled in. When nothing matches, it is the table’s last row — the catch-all, where every column is the default. To check, open User maintenance → G7 industry group and read that row. |
| Bond notional, MTM of notional, price ⚑ | Collateral postings · 14 + 2 ⚑ | Worked out. The market value is every posting of this bond added up, in the bond’s own currency. The face notional is that value divided by the price, out of 100. ⚑ The price needs a security-price source, which is not on the catalogue (see §E.14). Full trace and worked example: US8.4. |
| Type ⚑ | Bond / securities static · 2 ⚑ | The security bucket each screen already groups its own book by. On the Overview it is the bond type (SGS, UST, Supra, Agency, Corporates). In the Inventory Manager it is the holdings category on the summary cards (Govies, Supra, Agency, Financials, Corporates). ⚑ Confirm the one list of types the real system should hold on the security (see §E.14). |
| Issue date ⚑ | 2 ⚑ | Worked out back from maturity — a whole number of years, three to ten, fixed by the ISIN. ⚑ Not a stored field yet (see §E.14). |
| Trade start, Deal status | Collateral postings · 14 | Worked out from the pledge window. Trade start is the earliest date this bond was posted. Deal status reads “Live to maturity” when the pledge runs to maturity. It reads “Terminates” with that date when the pledge ends earlier. |
| Day count, Settlement (T+), Haircut, Accrued interest, Country of risk ⚑ | 2 (placeholder) ⚑ | ⚑ Shown as “to be provided”, on both screens. These are Bond static (set 2) fields not yet surfaced here. See §E.14. |
The whole page is fed by the holdings pool — Inventory data · 15. Each holding carries reference attributes and its own economics. The reference attributes come from Bond static · 2, Portfolios · 4 and Currency · 5. USD figures convert via FX · 8. User-added rows come from Adjusting inventory · 7.6.
| Field | Data set | Comes from (plain English) |
|---|---|---|
| Summary tiles (Total holdings, N trades, face; Govies / Supra / Agency / Financials / Corporates) | Worked out over 15 + 8 | Worked out — holding values added up (and grouped by industry), converted to USD. |
| ISIN, Instrument Name, Issuer Name, Issuer Country, Sector, Industry Classification, Seniority, Callable / Coupon, Instrument Ccy, Issuer Rating, Bond Rating | Bond / securities static · 2 | Referenced — the instrument’s reference details (Bond Rating is notched from the issuer rating). |
| Portfolio | Portfolios static · 4 | Referenced — the owning portfolio the holding points to. |
| Business Line ⚑ | 4 ⚑ | The owning desk / business line. ⚑ Confirm this is a Portfolios-static attribute (see §E.14). |
| Bond Notional (mm), MTM of Notional (mm) ⚑ | Inventory data · 15 ⚑ | Held on the holding — face amount and market value. ⚑ The market value needs a security-price source, which is not on the catalogue (see §E.14). |
| Clearer ⚑ | 15 / 2 ⚑ | The settlement / custody location. ⚑ Confirm whether it belongs to the holding (15) or the security’s settlement instructions (2) — see §E.14. |
| Time-series view — per-day notional | Inventory data · 15 | Worked out — each holding’s notional as at each business day (nil when not live). |
| Snapshot as-at date, filters, column show/hide | screen state | Presentation controls; the date bounds come from the holdings’ start / maturity dates. |
| Instrument modal “Further fields” (Issue date, Day count, Settlement T+, Haircut, Accrued interest, Country of risk) ⚑ | placeholder ⚑ | ⚑ Declared “to be provided”. They would map to Bond static (2), Currency / Holiday (5 / 3), and Collateral used (14, haircut). None is sourced yet. |
| Field | Data set | Comes from (plain English) |
|---|---|---|
| Rule library — name, group, input source, filter field, condition, value, note, enabled | Optimization rules · 11 | The rule configuration the user builds, plus the built-in starter rules already loaded when the app opens. |
| Run parameters (concentration cap, MTA, rounding, buffer, allow partial) | Optimization rules · 11 | The run’s parameters. |
| Input tables (Inventory / Margin calls / Agreements) with in-scope / out flags | 15 / 10 / 6 + 13 | The input rows come from those sets; the in-scope / out decision is an exclusion (set 13). |
| Agreements input drawer — Eligible issuer groups (G7) | Agreements static · 6 + User-maintained data · 7 | Referenced — the issuer groups named on that agreement’s own eligibility schedule (its Issuer / Issuer type lines). The groups themselves are the ones the user maintains in the G7 industry group table. |
| Output drawer — allocation cards, coverage, carry saving, full posting detail | Optimization outputs · 12 | What a rules run produces. |
| Output drawer — the issuer group shown against each recommended posting | Inventory data · 15 + User-maintained data · 7 | Referenced — the holding’s issuer industry, from the bond inventory. The user’s G7 industry group mapping table translates it into a G7 group. Until that table is filled in, it is left as the issuer industry itself. |
| Screen | Data set | Status |
|---|---|---|
| Counterparty | Counterparty static · 1 | Placeholder — schema only (“— to be provided —”). |
| Instrument | Bond / securities static · 2 | Placeholder — schema only. |
| Holiday Calendar | Holiday calendars · 3 | Placeholder — schema only. |
| Portfolio | Portfolios static · 4 | Placeholder — schema only. |
| Currency | Currency static · 5 | Placeholder — schema only. |
| FX Rate | Market data FX · 8 | Placeholder — schema only (only conversion factors modelled). |
| Interest Rate | Benchmark rates · 9 | Placeholder — schema only. |
Each dataset mixes system-provided columns (referenced read-only from another set) and user-entered columns. All persist to the browser and stamp a “Last updated”.
| Dataset · column | Data set (source) | Who fills it |
|---|---|---|
| Cost of funds — Security Type | G7 industry group · 7.2 | System (read-only) — the distinct G7 groups from set 7.2, always including the Others catch-all. |
| Cost of funds — Currency | Currency static · 5 | System (read-only). |
| Cost of funds — Rate (internal) / Rate (external) | Cost of funds · 7.1 | User-entered. |
| G7 industry group — Classification L4 / BICS L2 / Issuer Industry | 2 + 7.2 | System (read-only). Confirmed 24 Aug 2026: the bond carries its Issuer Industry on Bond / securities static (2); the app matches on it to find the bond’s row of the G7 industry group mapping table (7.2), and reads Classification L4 and BICS L2 off that row. |
| G7 industry group — G7 group (+ Others) | G7 industry group · 7.2 | User-entered. Drives the Overview “By bond type” chart. It also drives the four classification fields on the instrument detail card (§8). Every bond is matched back to a row of this table. Anything unmatched takes the catch-all row. |
| Source of collateral — Field (portfolio dimensions) | Portfolios static · 4 | System (dropdown list). |
| Source of collateral — Match / Value / Collateral Source | Source of collateral · 7.3 | User-entered. Drives the Overview “Sources” chart. |
| Special agreements — Agreement name | Agreements static · 6 | System (found on screen, not typed) — the agreement names the app puts on screen, each shown with the agreement type it is booked under and its counterparty. |
| Special agreements — Tag | Special agreements · 7.4 | User-entered, and the only thing the user sets here. One of Zero-interest CSA, which makes the agreement filterable on the dashboards, or Korean CSA, which drops the agreement from the app, or none, which leaves it ordinary. |
| Adjusting exposures — Agreement name | Agreements static · 6 | System (dropdown). |
| Adjusting exposures — Adjusted Exposure (USD / orig), Original Ccy, Date | Adjusting exposures · 7.5 (applied onto 10); Ccy from 5 | User-entered. Adjusts an agreement’s exposure on the given date. |
| Adjusting inventory — 16 Bond-Inventory fields | Adjusting inventory · 7.6 (structure mirrors Inventory · 15) | User-entered. Appended into the Inventory Manager. |
These displayed fields do not yet trace cleanly to one of the 15 catalogued data sets. Or their source needs the product owner’s confirmation. Per the standing lineage rule, they are listed here for a decision. A source must be agreed and added to the catalog before the field is built for real. Nothing has been invented to fill the gap.
| # | Where | Gap | Suggested resolution |
|---|---|---|---|
| 1 | Exposure drill (§E.8) & Agreement detail → Trades tab (§E.7) | No derivative-trade data set. Six trade fields have no source among the 15 sets. They are Trade ID, Product, Notional, Trade date, Maturity and Ccy. Only the trades’ total mark-to-market ties to Exposures · 10. | Add a “Trades / derivative positions” data set to the catalog (the trade-level feed exposure is calculated from). |
| 2 | Inventory Manager (§E.10); Agreement Exposure card MTM/IA (§E.7); ITM/OTM split (§E.1/§E.4) | No security-price / valuation data set. Market value (MTM) needs a per-security price. The catalog has FX (8) and benchmark rates (9) only. There is no security-price feed. | Add a “Market data — security prices / valuations” data set (or extend Bond static · 2 with a price). |
| 3 | T+N settlement ladder (§E.6) | No source for the ladder. The T+0 to T+5 settlement-availability amounts are demo placeholder numbers, and so is the country breakdown. Neither is drawn from Collateral used (14) or Inventory (15). | Confirm the source: a settlement-availability view over Inventory (15) / Collateral used (14) by agent, country and settlement horizon. |
| 4 | Inventory “Clearer” (§E.10) | Ambiguous set. The settlement/custody location could be a holding attribute (Inventory · 15) or the security’s settlement instructions (Bond static · 2). | Confirm which set owns the clearer / SSI attribute. |
| 5 | Inventory “Business Line” (§E.10) | To confirm. Mapped to Portfolios static (4), but the set’s description doesn’t name business line explicitly. | Confirm business line is a Portfolios-static attribute. |
| 6 | G7 industry-group system columns (§E.13) | Answered — 24 Aug 2026. Issuer Industry is a security attribute and lives on Bond / securities static (2), where it is now a field you can map. It is the value each bond is matched on when the app looks up its row of the G7 industry group mapping table; Classification Level 4 name, BICS Level 2 Industry Group Name and G7 Industry group are that row’s own columns and stay on G7 industry group (7.2). | Closed. Issuer Industry sits on Bond / securities static (2); nothing about issuer classification is held on Counterparty static (1). |
| 7 | Various demo-modelled figures | Modelled, not fed. Four items are modelled rather than sourced. The History chart’s Total-posted line, being posted lifted by a fixed 10% buffer. The ITM, OTM, Net-Alternative, STD, Cpty and Dispute amounts, modelled close to the call. The Agreement Holdings Delivery, Market and Collateral factors. And the hard-coded Corp eligibility rows. | Not off-catalogue data — flagged so a developer replaces the demo assumption with the real per-agreement / per-line value when building. |
| 8 | Instrument modal placeholders (§E.9, §E.10) | Placeholder fields. Six fields are shown as “to be provided”. They are Coupon frequency, Country of risk, Day count, Settlement (T+), Haircut and Accrued interest. Coupon and Sector already exist on the record. | Surface the existing Bond-static fields; add the remaining ones to Bond static (2) / Collateral used (14, haircut). |
Decided 20 August 2026. The screen stays in the demo so it can still be opened and clicked through. It is not part of the system being built.
This tab describes Overview 2 — the workspace builder (the 2nd tab in the app) — from your point of view as the person using it: what you can see, what you can do, and how to tell every figure is right. It is written in plain English so you can read it without any technical background. It was detailed enough for developers to build the real thing from it — that is no longer its purpose, see the notice above. It is kept as the record of how the screen works, so the decision can be reversed without rewriting it. It contains: a short About note, a Data model & data dictionary (what information the screen holds and where each number comes from), a guide to verifying the on-screen figures, and then the things you can do (“As a user, I can …”). The exact rebuild formulas a programmer needs are tucked into a single collapsed Developer build detail section at the end — you never need to open it. The step-by-step test scripts live on their own tab, “UAT test cases · Overview 2”. Finance terms and the shared table controls are explained in the appendices on the Requirements 1 tab.
The reference sections come first (what the screen holds and how to check it), then the things you can do, and finally an optional developer-only section you can skip.
To get here: click the Overview 2 tab (2nd tab).
Overview 2 is a workspace builder: a left palette lists every available widget; the user adds widgets onto a collision-aware grid, closes them, pins them, and drags / resizes them (widgets never overlap — moving or resizing one pushes the others out of the way and the set compacts upward).
The user can keep several workspaces (top tabs), each with its own independent set of widgets and layout, and can add the same widget many times (each instance is independent).
Everything inside each widget behaves the same way as on the Overview (§2–§8): clicking a chart drills in or cross-filters, the postings panel’s view toggles and column ⚙ work, and drill-downs open as full-screen overlays above the canvas.
Nothing on this page is left undocumented — the exact rebuild formulas a programmer needs (how the sample numbers are made, how each figure is worked out, how the layout is saved) are all here, gathered into the single collapsed Developer build detail section at the end so they don’t clutter the read; a business reader never needs to open it.
The three shared full-screen overlays that can open above the canvas — the agreement-detail popup, the exposure drill and the instrument modal — look and behave exactly as they do on the Overview, so they are specified once on the Requirements 1 tab (Epics 6 / 7 / 8) rather than repeated here.
For the BA / developer: this single reference lists all the data Overview 2 needs — every entity, each of its fields (name · type · format/example · how it is derived), the reference/look-up tables, the derived figures shown on screen, and the exact persisted data structure.
Nothing here is a new field — it is the same data described in context under US9.15–US9.17, gathered in one place so you can see the whole model at a glance.
All figures are generated in-browser from fixed seeds (no backend); user-maintenance overrides are read from localStorage.
For every figure the screen shows, this spec documents not just where it comes from and how it is worked out, but how to confirm it is correct and where to look — if a card reads $10.0mm, a business analyst or tester must be able to prove that number rather than take it on trust.
The figure-by-figure checks are gathered under 🔎 Verifying the on-screen figures below (and the one fully worked collateral line in the collateral-used column dictionary is the template for checking a single line end to end).
What this is, in plain terms: a collateral-management system is fed by a fixed set of source data sets — reference lists it looks things up in (who the counterparties are, what a bond is, which currencies exist), market data (exchange rates, interest rates), the day-to-day activity (exposures, margin calls, what collateral is posted), and the optimisation layer (the rules and what they produce).
The data sets below are the canonical master list for this whole application — the 15 top-level sets, with the user-maintained set (7) broken out into its eight datasets (7.1–7.8), each a set in its own right. Every widget on Overview 2 must draw its data from one of these sets — see the “Widget → data & logic lineage” table further down for which widget reads which set.
Status tells the developer how much of each set actually exists in the demo today:
| Status | What it means |
|---|---|
| Modeled | The data set is fully generated / present and drives the screens. |
| Partial | Only a slice exists (e.g. a single exchange-rate number rather than a full market-data feed); the rest is still to be provided. |
| Placeholder — to be detailed | Not built yet. It is listed here on purpose as a reserved slot so nothing is forgotten; the field-level detail will be supplied later, and until then no field structure is invented for it. |
| # | Data set | What it holds (plain English) | Status | Where it lives today / maps to |
|---|---|---|---|---|
| 1 | Counterparty static | The reference list of who we face (names, codes; and later legal entity, LEI, rating, country, netting status). | Partial | A live name/code list drives selections and, under Triparty, the counterparties each triparty agent handles; the full Counterparty reference screen (Requirements 1 · Epic 5) is a schema-only placeholder (“— to be provided —”). |
| 2 | Bond / securities static | Reference details of each security (ISIN, issuer, issuer industry, coupon, maturity, currency, bond type, sector, rating). | Modeled | Instrument-level data behind the postings (data model 14) and the Inventory Manager; feeds the blotter and the “By bond type” chart. Also surfaced as the Rules engine widget’s Bond static data input (reference attributes per eligible collateral class). |
| 3 | Holiday calendars | Business-day / settlement calendars per market or currency (which dates are non-working). | Placeholder — to be detailed | Not built as data. Only a placeholder reference screen and free-text “holiday centres” exist. No Overview 2 widget consumes it yet. |
| 4 | Portfolios static | The reference list of portfolios / books / trading desks and their owning entity. | Partial | Live portfolio dimensions exist in the Inventory Manager and Rules engine; a portfolio reference screen (Requirements 1 · Epic 5) is a placeholder. Now read by the Rules engine widget via its Portfolio static input (Portfolio name, Close entity, PC Code, Desk, Book, Product Lines, Product Franchise). |
| 5 | Currency static | The reference list of currencies (code, name, decimal places, settlement lag, holiday calendar). | Partial | Only the FX conversion factors exist (see set 8); the full Currency reference screen is a placeholder. |
| 6 | Agreements static (CSA IM, CSA VM, Triparty Repo, Futures Clearing, GMSLA, GMRA, CCP — incl. eligibility schedule & concentration limits) | The term-sheet data for each agreement type: margin mechanics, thresholds/MTA, legal terms, the eligible-collateral (eligibility) schedule and the concentration limits. | Modeled | All 7 types present (data model 6); full per-type term sheets incl. eligibility schedule + concentration limits (agreement-detail popup, Requirements 1 · Epic 6). The concentration limit is one stored record per agreement (group, limit type, granularity, limit value/unit, scope, basis) held in a single canonical store, read by both the agreement-detail popup and the Rules engine widget’s Agreements input — one source of truth, so the limit shown in the two places is always the same value. |
| 7 | User-maintained data — the eight datasets the user edits/uploads themselves. Each is listed below as its own set (7.1–7.8), maintained on the User-maintenance tab and read by Overview 2 each time it loads. (The exact browser storage-key names are in the Developer build detail.) | |||
| 7.1 | Cost of funds | The internal and external cost-of-funds rate for every Security Type × currency (AUD / CAD / CHF / USD / SGD). Security Type is the G7 industry group from set 7.2, and an Others catch-all row is always present for anything the mapping does not recognise. All four fields are mandatory. | Modeled | User-maintenance tab → Cost of funds (the exact saved-data name is in the Developer build detail). |
| 7.2 | G7 industry group | The mapping from each issuer’s classification (Classification Level 4 name / BICS Level 2 Industry Group name / Issuer Industry) to a user-defined G7 industry group, with an Others catch-all. | Modeled | User-maintenance tab → G7 industry group. Drives the Overview “By bond type” chart and seeds the Cost-of-funds grid. |
| 7.3 | Source of collateral | User rules over portfolio fields (Product Lines / Book / Product Franchise / Attribute ID / Portfolio Description) with Include / Exclude values that assign each posting a Collateral Source. | Modeled | User-maintenance tab → Source of collateral. Drives the Overview “By source” chart. |
| 7.4 | Special agreements | One user list of agreement names. Per agreement it holds one tag, and the tag is the whole instruction: Korean CSA drops the agreement from the app, Zero-interest CSA leaves it in and makes it filterable on the dashboards. | Modeled | User-maintenance tab → Special agreements. |
| 7.5 | Adjusting exposures | User exposure adjustments (Agreement name, Original Exposure, Adjusted Exposure in USD, Adjusted Exposure in original currency, Original currency, Date) that add on to an agreement’s exposure on a given date. | Modeled | User-maintenance tab → Adjusting exposures. |
| 7.6 | Adjusting inventory | User-added inventory rows (using the Inventory Manager “Bond Inventory” fields) appended into the Inventory Manager. | Modeled | User-maintenance tab → Adjusting inventory. |
| 7.7 | Tags & highlights | The user’s own labels on the book. One row per tag: which attribute of the book it keys on (bond ISIN, instrument name, portfolio, business line, holding, issuer name, issuer country, instrument currency, clearer, sector of issuer or industry classification), the value it applies to, the name the user gives it, and its colour. Every trade carrying that value is highlighted in that colour in the Inventory Manager. | Modeled | User-maintenance tab → Tags & highlights; read by the Inventory Manager. |
| 7.8 | G7 by bond | The bonds whose G7 industry group the user has set by hand, one row per ISIN. It holds only the exceptions to set 7.2: a bond that is not listed here follows the mapping in 7.2. Where a bond is listed, its value is the G7 industry group used for that bond everywhere. | Modeled | User-maintenance tab → G7 by bond. Read by the instrument pop-up and the “By bond type” chart, and its distinct values are Security Types on the Cost-of-funds grid. |
| 8 | Market data — FX rates | Exchange rates used to convert every currency to the reporting currency (and later spot / bid-ask / as-of time / source). | Partial | A single conversion factor per currency (the FX exchange-rate look-up table in the reference / look-up tables); a full FX market-data feed is a placeholder. |
| 9 | Market data — benchmark interest rates | The reference interest rates / curves (e.g. SOFR, €STR, SORA) with levels, tenor, as-of date, day count. | Placeholder — to be detailed | Only rate names appear as text on agreement term sheets; no rate levels are modeled. No Overview 2 widget consumes it yet. |
| 10 | Exposures & margin calls (all agreements) | Each agreement’s daily exposure (what needs covering), its margin calls (requests to post more collateral), and the collateral received in from counterparties each day (the inbound side, which is what the Received (inbound) figure is drawn from). | Modeled | Daily book records (data models 10 & 14’s “Obligation (what’s owed)” field) + the margin-call flag / call statuses (data model 6); drives the Margin Calls view and the Exposure figures. |
| 11 | Optimization rules | The scoping, limit and ranking rules that decide how collateral is allocated, the runs they are grouped into, and each run’s own settings (concentration cap, minimum transfer amount, rounding increment, haircut buffer, Sweep the deck). | Modeled | Rules engine tab — the same screen the Overview sidebar entry and the Overview 2 widget show. This set is never a file. The user sets the rules and runs on that screen and what they set is the data, so the Data tab offers no upload or mapping for it. Lives outside Overview 2 — no Overview 2 widget consumes it yet. |
| 12 | Optimization outputs | What a rules run produces — one row per proposed movement: the run it belongs to, the agreement being covered, the security to deliver, the market value posted, the haircut applied, the collateral value that gives, and what the line costs to fund. The run’s headline figures (annual carry, saving against posting all cash, requirement covered, blended funding cost) are added up from these rows, not stored on them. | Modeled | The Optimisation Results view and all five Optimization Results views — every one of them on the Optimization Results tab. Field-by-field breakdown at Data model 12 in detail; uploadable and mappable on the Data tab since 9 Sep 2026. Lives outside Overview 2 — no Overview 2 widget consumes it yet. |
| 12.1 | Bond sources (internal) | Where each bond in a run comes from inside the firm — one row per sourced line: the desk and portfolio it is drawn from, whether it is moving into the collateral pool or back out to the desk, how much, the window it is held for, and what that funding costs. | Modeled | The Internal sources of bonds table that leads the Optimization Results screen (US11.16). Uploadable and mappable on the Data tab; when mapped it replaces the rows the run derived. |
| 12.2 | Bond destinations (postings out) | Where each bond in a run is posted to — one row per movement window: the agreement type it covers, where it settles, whether it is going out or being recalled, how much, the settlement date and end date the agreements in that window share, and what it costs there. One agreement type can appear on several rows for one bond, because the firm’s agreements of that type were not all papered together. | Modeled | The Where the bonds are posted to table that leads the Optimization Results screen (US11.16). Uploadable and mappable on the Data tab; when mapped it replaces the rows the run derived. |
| 13 | Optimization exclusions & exceptions | Everything a run held out and every data problem behind it — one row per exception, in four categories: inventory lines the run’s rules removed from the pool, margin calls and agreements its scoping rules kept out, obligations it could not fully cover, and missing or invalid values in what it read. Shortfall rows also carry what was needed, what was covered, what is short, and the eligibility terms that blocked it. | Modeled | Live on the Rules engine’s ⚠ Exceptions view (see US11.7) and on the Optimization Results 05 Shortfall board. Field-by-field breakdown at Data model 13 in detail; uploadable and mappable on the Data tab since 9 Sep 2026. Lives outside Overview 2 — no Overview 2 widget consumes it yet. |
| 14 | Collateral used data | The individual collateral lines posted out (Delivered) or received and held (Held) against each agreement — for each line: the instrument (its ISIN, or for cash the currency), the amounts in the original booking currency (par, market value, and collateral value after the haircut), the dates (posting, valuation, maturity), the agreement and counterparty, the haircut, and the reporting-currency (USD) conversion. This same line-level data also underpins the bonds-vs-cash split and the available / allocated / unallocated views. | Modeled | Also read by the Rules engine when Sweep the deck is off (US11.8): its Delivered rows are what a top-up run keeps in place and nets off each obligation, and what a Sweep-ON run has to recall — which is what Where the bonds are posted today lists (US11.16a). The line-level records behind the Bond postings blotter and the Overview Asset Holdings Summary — the full column dictionary is the collateral-used column dictionary below. Also rolled up into daily book records (data models 10 & 14 — the day's total posting amount and its bonds-vs-cash split) plus each posting's available / allocated / unallocated amounts (data model 14), to drive Posted / Allocated / Unallocated and the Key figures. |
| 15 | Inventory data | The pool of collateral we hold and can post — each line's identity, economics, portfolio, business line, clearer, Holding (Internal / External-held / Received) and its held window (a start date and end date, with the amount held varying day-to-day in between). One shared book (one shared inventory data file that feeds both this screen and the Inventory Manager) feeds both screens, so they never differ. | Modeled | Inventory Manager (Requirements 1 · Epic 10) + the Rules-engine inventory (both load the shared module); the postings blotter (data model 14) is the Overview 2 view onto it. |
| 16 | MX Trades Data | The individual trades that add up to an agreement's mark-to-market. One row per trade: its reference, the product traded, when it was traded and when it matures, the notional and the currency it is in, and what it is marked at in US dollars. | Partial | The agreement detail pop-up's Trades tab (Requirements 1 · Epic 6). Added 21 Aug 2026 — the pop-up was showing trade figures that traced to no data set. |
Gap highlight (declared but not yet consumed by any Overview 2 widget): sets 3 Holiday calendars and 9 Benchmark interest rates are on the master list but no current Overview 2 widget reads them (both are placeholder reference data). They stay listed so the slot is reserved. (Sets 2 Bond/securities static, 4 Portfolios static, 11 Optimization rules, 12 Optimization outputs and 13 Optimization exclusions & exceptions are now read by the Rules engine widget — via its Bond static data, Portfolio static, scoping-rules, output and exclusions inputs.)
Standing lineage rule: every Overview 2 widget must draw its data from a set in this catalog.
Whenever a widget is added or changed, its data must trace back to one of the 15 sets — if a widget would need data that is not on this list, that gap must be raised with the product owner and added to the catalog before it is built, rather than introducing an off-catalogue data source silently.
The “Widget → data & logic lineage” table below and the matching matrix on the UAT test cases · Overview 2 tab are kept in step with this list.
Uploading your own data (the Data tab). Every set in this catalog can now be fed with real production data from the Data tab: upload a file for the set, map each demo field to a column in your file, and switch the app to Production data (see Requirements 1 · Epic 19). This does not change any set’s Status above — Status describes what the built-in demo models; your upload replaces the demo source rows for that set at run time without changing how any figure is worked out. Two sets are wired live today (8 · Market data FX rates and 15 · Inventory data); the other mappable sets accept an upload + mapping now and are connected as each is wired.
The 15 data models above are the master list. Eight of them are big enough to need a record-by-record breakdown, and those breakdowns follow below — each one says which data model it belongs to, so there is only ever one set of numbers to keep track of.
| Data model | What its detail section covers |
|---|---|
| 6 · Agreements static | Two breakdowns: the 7 agreement types (the rows in the Agreements widget, with the dials that generate each one), and the individual agreements beneath each type — 100 numbered agreements for each of the six coded types, and for Triparty the counterparties handled by each agent. |
| 10 · Exposures & margin calls and 14 · Collateral used data | The daily book record — one point per type per day across the 1,100-day history. This is what drives every chart and every dollar figure on the screen. |
| 14 · Collateral used data | Two breakdowns: the posting row behind the Bond postings blotter, and the column-by-column dictionary of a collateral line, with a worked example that ties out end to end. |
| 12 · Optimization outputs | The proposed movement a run produces, column by column — one row per movement, with what is on the file, what is read from the other files by reference, and what the screens add up for themselves. |
| 13 · Optimization exclusions & exceptions | The exception row, column by column — the four categories, the reason column the set exists for, and the seven shortfall columns that are filled in on the not-fully-covered rows only. |
| 1, 2, 5 & 8 | The reference / look-up tables — exchange rates, threshold cushions, funding sources, bond types to sector, and the G7 industry groups. |
Two things that are not data models, so they are documented elsewhere: the figures the screen works out for itself (Posted / Exposure / Allocated / Unallocated and the nine Key-figures cards) are nothing to do with stored data and live under Checks that span more than one widget; and the saved workspace layout (your widgets, links and filters, kept in your browser) is a storage detail, covered in the Developer build detail at the end.
How to read this table: the Field column names each piece of data in plain words; the last column explains what it means.
A few of the fields are “generation dials” — the settings that decide how this type’s sample numbers are made up for the demo (there is no live feed).
The Typical values column shows the range those settings sit in.
| Field | Type | Typical values | What it means (plain English) |
|---|---|---|---|
| Type code | text (unique) | bim · bvm · gmra · gmsla · ccp · fut · tri | The short code that identifies the type. |
| Short name | text | “GMRA”, “Bilateral CSA IM” | The short name shown as the row label in the Agreements widget. |
| Full name | text | “GMRA — Repurchase” | The longer descriptive name. |
| Reporting currency | a currency | USD · EUR · SGD | The currency this type reports in; every figure is converted into it using the FX rates. |
| Colour | a colour | green, blue… | The colour of the dot shown beside the name. |
| Sub-accounts | a list | Euroclear & Clearstream · or a single book | The sub-accounts a type is split into (e.g. two custodians). Only the ones switched on are added into the totals. |
| Threshold cushion | $ millions | 0 · 12 · 18 · 25 | A cushion amount (in $ millions) that is added on top of what’s owed when working out Exposure. |
| Starting size | $ millions | about $150m–$520m | Generation dial. How big this type is at the start of the ~3-year history. |
| Day-to-day jiggle | small setting | low … high | Generation dial. How much the daily amount moves up and down from one day to the next — a bigger setting means a choppier line. |
| Yearly growth trend | a percentage | about 1%–10% a year | Generation dial. The steady yearly growth trend — how much the type grows over a year. |
| How well covered | a ratio | 0.42 … 1.22 | Generation dial. How much collateral is posted compared with what’s owed: 1.00 = exactly covered, 1.22 = 22% over-posted, 0.93 = 7% short, 0.42 = less than half of it posted. The agreements are spread across that range on purpose, so every situation appears somewhere. Those are: over-posted with collateral left over; exactly covered; a small call outstanding; and a call so large that everything posted still does not meet it. |
| Target bond share | a percentage | 20% … 100% | Generation dial. The target share of the posting that is bonds rather than cash (20% = aim for one-fifth bonds). |
| Seasonal cycle (timing & strength) | two settings | peak month · swing size | Generation dials for the yearly cycle: one sets which month of the year the cycle peaks; the other sets how strong that up-and-down seasonal swing is. |
| Received vs owed | a ratio | 1.05 … 1.13 | Generation dial. How much inbound collateral is received compared with what’s owed (1.10 = 10% more received than owed). |
The full per-type value tables are listed under US9.15 (the agreement book) and US9.16 (the generation dials). Triparty is left out of the combined “All agreements” total.
Each type is made up of individual agreements — the rows you see when you drill into a type. Each field below is described in plain words.
Six of the seven types are made up of 100 numbered agreements. Triparty is different, and deliberately so: triparty business is not booked under standalone agreement codes. The collateral sits with a triparty agent — Euroclear, Clearstream or BNY Mellon — and each agent administers the counterparties whose collateral it holds. So the rows under Triparty are those counterparty names (111 of them, each belonging to exactly one agent), never “TRI-001 / TRI-002” style codes. Which agent handles a given counterparty is fixed and the same on every load.
“Decided by a fixed rule based on the agreement name” means the demo always makes the same choice for the same agreement on every load — it is worked out from the name, not re-rolled each time.
| Field | Type | What it means & how it is set (plain English) |
|---|---|---|
| Agreement name | text (unique) | For the six coded types: the agreement’s account code, numbered 001–100 within its type — for example BIM-001 to BIM-100. For Triparty: the counterparty’s name — for example Brackwater Bank, Upperby Bank, Verdance Capital. |
| Triparty agent | text (Triparty only) | Which of the three triparty agents — Euroclear, Clearstream or BNY Mellon — administers this counterparty. Every Triparty counterparty belongs to exactly one agent; the six other types leave this blank. Roughly a third of the counterparties sit with each agent, decided by a fixed rule based on the counterparty name. |
| Share of the type | a percentage | How big this one agreement is within its type. For the six coded types: each of the 100 agreements is given an amount, and then all 100 are scaled so that together they add up to 100%. For Triparty: a counterparty’s share is measured inside its own agent’s book — the counterparties of one agent add up to 100% of that agent — and to place it in the whole Triparty book that share is multiplied by the agent’s share of the book. Either way, that share is what shrinks the agreement’s Posted / Allocated / Unallocated down from the whole type’s figures. |
| Zero-interest? | yes / no | Marks the agreement as zero-interest. It is not held on the agreement. It is true when the user has tagged that agreement Zero-interest CSA on the Special agreements screen. Nothing is zero-interest until somebody says so. |
| Had a margin call in the last 14 days? | yes / no | Marks that the agreement had a margin call in the last 14 days. About 30% (3 in 10) do, again decided by a fixed rule based on the agreement name. The number of these within a type is the orange (N) badge. |
| Call status | one of three fixed labels | Where this agreement has got to in the margin-call process, and what the Margin Calls view’s count tiles count. Every agreement carries exactly one of three: Pending Review (about 2 in 10 agreements), Margin Request Confirmed (about 4 in 10) and No Call Required (the remaining 4 in 10). Which one an agreement gets is decided by a fixed rule based on its name, so the same agreement always shows the same status on every load. When a whole agreement type is shown as one row, it takes the most urgent status found among its agreements — Pending Review outranks Margin Request Confirmed, which outranks No Call Required. To check the tiles: count the rows in each status on the Margin Calls table; each count tile must equal its own status’s row count, and the three counts must add up to the number of rows shown. |
For each type there is one record per day for the last ~3 years, and these day-by-day records drive every chart and every dollar figure. Each row below is described in plain words.
A “small random wobble” just means the value is nudged up or down by a small random amount each day so the line isn’t unnaturally smooth.
| Field | Type | How it is worked out each day (plain English) |
|---|---|---|
| Date | a calendar date | One row per day for the last 1,100 days (about 3 years), from the start date up to the anchor “today” (18 Jun 2026). |
| Obligation (what’s owed) | US$ amount | What the type owes / needs covering that day. It starts from the type’s normal size grown by its yearly trend, then is nudged by the season, a slow multi-year wave, the day of the week, and month-end / quarter-end spikes; it is never allowed to fall below 35% of normal. |
| Total posting | US$ amount | The collateral posted that day: what’s owed multiplied by the cover ratio, then nudged up or down by up to 3%. |
| Bonds posted | US$ amount | The bond part of the posting: the day’s total posting multiplied by that day’s bond share. |
| Cash posted | US$ amount | The cash part of the posting: whatever is left after the bonds. |
| Received (inbound) | US$ amount | Inbound collateral received that day: what’s owed multiplied by the received factor, then nudged up or down by up to 2%. |
| Bond share for the day | a percentage (5%–99%) | The share of the posting that is bonds on that day; it gradually drifts toward the type’s target bond share. |
| Column group | Columns it contains |
|---|---|
| Postings / Bonds-Maturing columns | Agreement Name, Trade #, ISIN, Security, Type (bond type), Sector, Counterparty, Agreement Type, Custodian, Source (funding source), Start date, Maturity, Maturing in Days, then the five amount fields — Original Ccy, Original Amount (what was posted, in the instrument’s own currency), Posted (USD) (the same posted amount in US dollars), Allocated (USD) (the part of it TMO used), Unallocated (USD) (Posted minus Allocated). |
| Summary / Detailed (per-agreement) columns | Agreement, Total exposure, Call/obligation, Received (in), Margin call, Total posting, Bonds (Posted), Cash (Posted), Total allocated, Bonds (Allocated), Cash (Allocated), Unallocated (= Total posting − Total allocated), Surplus (= Total allocated − Margin call), DoD/WoW/MoM total allocated, Threshold, Expected post, Expected collect. Detailed (individual-agreement) level only, in addition: ITM/OTM Exposure, Dispute Value, Dispute Age, Base CCY, Base Total Exp., Base Call Amt. |
| Margin Calls columns | The Daily Exposure Report fields + 5 KPI tiles (Total Margin Call, Pending Review, Confirmed, No Call, Disputes). |
These column sets are identical to the Overview dock — full definitions live on the Requirements 1 tab (Epic 2). They are listed here so the data inventory is complete.
What this is, in plain terms: the Collateral used data set is the list of individual collateral lines — each bond or cash amount that has been posted out to (Delivered) or received and held from (Held) a counterparty under an agreement. One row = one collateral line.
The same bond can be posted to the same agreement (or the same triparty agent) more than once — on different dates and for different amounts. Each of those is its own collateral line with its own Trade # and Start date, and the Postings view lists them all. The Postings by bonds view is the pivot of exactly this: it aggregates by bond, so those lines become one row whose Original Amount, Posted (USD) and Allocated (USD) are the sums of the lines and whose Start date is the earliest of them. In the demo book 5 of the 38 bond postings are second postings of a bond already posted to the same agreement, so the aggregation is visible on screen — for example bond SGTAEZ1GFSY0 (MAS BILL 4% 05/27) under Triparty · BNY Mellon: two lines, $19.7M posted from 29 Sept 2025 and $16.0M from 19 Mar 2026, which Postings by bonds shows as one row of $35.7M starting 29 Sept 2025.
The Where it comes from column tags every field as one of three things: referenced from one of the other 16 data sets (and it always matches that set), captured on the collateral line itself (this set's own data), or worked out from the other columns on the same line.
The right-hand column carries one fully worked example line so every figure can be checked end to end. A ⚑ marks a field the product owner still needs to confirm.
Values are illustrative demo data.
| Column | What it means (plain English) | Where it comes from | Worked example line |
|---|---|---|---|
| Agreement Name | The individual agreement this collateral line belongs to. | Referenced from Agreements static (set 6) — the individual agreement's name. | GMRA-001 |
| Trade # | The reference your system issues for this collateral line — the number you would quote to look the posting up. Every line has its own; where one posting is settled in two parts, each part carries its own Trade #. | Captured on the collateral line itself (this set's own data). The demo makes one up so the screen has something to show; in the real system it comes from your file. | TRD-600001 |
| Position | Whether we delivered this collateral out to the counterparty, or hold collateral we received from them. | Captured on the collateral line itself (this set's own data). Just two possible values: Delivered or Held. | Delivered |
| Counterparty | Who the collateral is posted to, or received from. | Referenced from Counterparty static (set 1). | Fernhollow Bank |
| Asset Class | The G7 industry-group classification of the collateral — for a bond, the group its issuer falls in; for a cash line, simply “Cash”. | Referenced from the user-maintained G7 industry group map (set 7.2), applied to the security's bond type from Bond / securities static (set 2). | Government |
| Agreement Category | The agreement type this line sits under — for example GMRA, GMSLA, Bilateral IM. | Referenced from Agreements static (set 6) — the agreement's category / type. | GMRA |
| ISIN / Currency | For a security, its ISIN code; for a cash line, the cash currency instead. | The ISIN is referenced from Bond / securities static (set 2); for a cash line, the currency is referenced from Currency static (set 5). | KR103502GA34 |
| Maturity Date | The security's maturity date. Left blank for a cash line. | Referenced from Bond / securities static (set 2). | 20/09/2029 |
| Date of Posting | The date this collateral line was posted or received (day / month / year). | Captured on the collateral line itself (this set's own data). | 12/06/2026 |
| Valuation Date ⚑ | The date the line's values are struck as at — set a few business days after the posting date. ⚑ The exact business meaning is still to be confirmed by the product owner; treated as a placeholder for now. | Captured on the collateral line itself (this set's own data); for now, the posting date plus a few business days. | 16/06/2026 |
| Booking Currency | The original currency the collateral is posted in — the instrument's own currency (for example a Korean government bond is posted in KRW). The Par Amount, Booking Market Value and Booking Collateral Value are all in this currency. | Referenced from Bond / securities static (set 2) — the security's denomination currency; for a cash line it is the cash currency itself (Currency static, set 5), the same as the ISIN / Currency column. | KRW |
| Par Amount | The face (nominal) amount of the security posted, in its Booking Currency. | Captured on the collateral line itself (this set's own data). | 2,643,000,000 |
| Booking Market Value | The market value of the line in its booking (instrument) currency. | Captured on the collateral line itself (this set's own data). | 2,626,523,538 |
| Booking Collateral Value | The value the collateral is credited at after the haircut, still in the booking currency — the market value reduced by the haircut. | Worked out from this line: the Booking Market Value taken down to the Haircut percentage of itself (here 92, i.e. 92% of the market value). | 2,416,401,655 |
| Haircut | The percentage of market value the collateral is allowed to count for. 100 means no haircut; less than 100 means a discount (92 = an 8% haircut). | Referenced from Agreements static (set 6) — the agreement's eligible-collateral / haircut schedule. | 92 |
| Reporting Currency | The single currency every line is reported in, so lines in different Booking Currencies can be compared and added together. Confirmed = USD, set once for the whole Singapore entity rather than carried record by record. | A fixed system reporting setting for the Singapore entity — US dollars (USD); the currency code itself is one of Currency static (set 5). | USD |
| Market Value (USD) | The Booking Market Value converted from the Booking Currency into the reporting currency (US dollars). | Worked out from this line: the Booking Market Value converted using this line's FX Rate. | 1,917,362 |
| Collateral Value (USD) | The Booking Collateral Value converted from the Booking Currency into the reporting currency (US dollars). | Worked out from this line: the Booking Collateral Value converted using this line's FX Rate. | 1,763,973 |
| FX Rate | The exchange rate used to convert this line's Booking Currency into the reporting currency — US dollars per 1 unit of the Booking Currency. | Referenced from Market data — FX rates (set 8). | 0.00073 (KRW → USD) |
Reading the worked example: the line is a Korean-won (KRW) government bond delivered to Fernhollow Bank under GMRA-001 — its Booking Currency is KRW, so the Par Amount and both Booking values are in won.
Its haircut of 92 turns a Booking Market Value of 2,626,523,538 into a Booking Collateral Value of 2,416,401,655 (92% of it). Converting both at the won FX rate of 0.00073 US dollars per won gives a Market Value (USD) of 1,917,362 and a Collateral Value (USD) of 1,763,973.
Every referenced column ties to its source data set; every worked-out column can be re-derived from the other columns on the same line — so a developer can check the whole row without any hidden inputs.
Every column maps to a source (the standing lineage rule): Agreement Name, Agreement Category and Haircut come from Agreements static (set 6); Counterparty from Counterparty static (set 1); Asset Class from the user's G7 map (set 7.2) over Bond / securities static (set 2); ISIN, Maturity Date and the Booking Currency from Bond / securities static (set 2); the cash Currency and the Reporting Currency (a fixed setting = USD) from Currency static (set 5); FX Rate from Market data FX (set 8).
Trade #, Position, Date of Posting, Valuation Date, Par Amount and Booking Market Value are captured on the line itself (this set, #14). Booking Collateral Value, Market Value (USD) and Collateral Value (USD) are worked out from the other columns.
Reporting Currency = USD and Booking Currency = the instrument's original posting currency are confirmed (the reporting currency is one setting for the whole Singapore entity, re-confirmed 26 Aug 2026); one item stays flagged (⚑) for the product owner: the exact business meaning of Valuation Date.
How the bond-postings blotter's five amount fields map onto this dictionary: Original Ccy is the Booking Currency; Original Amount is the Booking Collateral Value (the posted, after-haircut amount in that currency); Posted (USD) is the Collateral Value (USD) — the same amount converted at the line's FX Rate; Allocated (USD) is the part of Posted (USD) the collateral team used against the agreement's margin requirement; Unallocated (USD) is Posted (USD) minus Allocated (USD).
What this is, in plain terms: when the rules are run, the answer is a list of movements — “deliver this security against that agreement”. This data set is that list. One row = one proposed movement. It is what the Optimisation Results view and all five Optimization Results views read — every one of them on the Optimization Results tab.
Where the rows come from. Today the app works the run out itself from three files it already has — the securities and inventory it can post (data sets 2 and 15), the agreements and what each will accept (data set 6 and its eligibility schedule 6.1), and what each agreement owes (data set 10). If your own optimiser works the run out instead, you upload its answer as this data set on the Data tab and map each column, exactly as for any other set.
What this file deliberately does not carry. The row names the security by its code only. What that security is — its name, issuer, coupon, rating — is read from the securities file, and which portfolio and holding it sits in is read from the inventory file. Who the counterparty is comes from the agreement. The rule is the standing one for this whole application: the identifier travels on every file, the description is held once.
The run’s headline figures are not on the file either. Annual carry, the saving against posting all cash, how much of the requirement is covered and the blended funding cost are all added up from these rows against what the agreements owe. They are worked out when the screen is drawn, so no run can ever show two different answers for the same total.
Values are illustrative demo data.
| Column | What it means (plain English) | Where it comes from | Worked example row |
|---|---|---|---|
| Run ID | The reference of the run this movement belongs to. Every row of a run carries the same one, which is how a proposal is filed, re-opened and argued against later. | The run itself. The Optimization Results run bar prints it. | Modeled |
| Run date & time | The moment the run was put through the optimiser. A proposal is only as good as the book it was worked out on, so this says which. | Stamped when the run is run; printed beside the Run ID. | Modeled |
| Agreement | The individual agreement this movement covers — its own reference, not the kind of contract it is. Triparty is named by its counterparty, because it is never booked under a standalone agreement code. | The margin obligations one level down (data set 10). | Modeled |
| Expected margin call | What that individual agreement expects to be called for. It belongs to the agreement, so it reads the same on every bond posted to it and is never added up down the file. | The obligation’s own requirement. | Modeled |
| Settlement date | When the margin call has to be settled — the day the collateral must be with the counterparty. Today plus that agreement’s own settlement days. | Worked out from the agreement’s settlement terms. | Modeled |
| ISIN | The code of the security to deliver. For a cash line this is the currency instead. | Referenced from Bond static (data set 2). | Modeled |
| Collateral amount | How much of that security is being delivered, at today’s market price, in millions of US dollars. | What the run proposed for that agreement. | Modeled |
| Start date | When the proposed repo of the collateral begins — the day it goes out. It is the settlement date, because the repo starts when the collateral is delivered. | Derived from the settlement date. | Modeled |
| End date | When that repo ends and the collateral is due back. It is the earlier of the agreement’s own end date and the day the firm’s holding of the bond itself ends — a bond cannot be committed for longer than it is held, nor to an agreement after it has expired. | Derived from the agreement terms and the inventory line. | Modeled |
| Source | Where this collateral is coming from, so the movement can actually be instructed. Either Desk and the portfolio it is borrowed fresh from, or Recall and the agreement it has to be called back from. A movement that takes from both names both. What is already posted out comes back first; the desk lends only the rest. | Worked out from the inventory line and the existing postings (data set 14). | Modeled |
| Cost of funds | What it costs to fund this security for a year, in basis points, after the agreement’s haircut is taken off it. | Cost of funds (data set 7.1) grossed up by the haircut. | Modeled |
Accepted / On hold / Rejected is not on this file. That is the decision a person takes on the Approval blotter after reading the proposal, so it is never uploaded. It lives only for as long as the screen is open, and re-prices the release the moment it changes.
What is left out of the totals. A movement marked Rejected is dropped from every figure on the results screens; one marked On hold is dropped from the accepted totals but still counted in the on-hold tally. Nothing is deleted from the file.
Still with the product owner: the run reference appears on this file and on the exceptions file (data set 13) and both call it the same thing. Which of the two is the master list for a run needs naming, so every other file carries it only to point back at that run.
What this is, in plain terms: a run does not use everything it is given. It leaves inventory out because a rule says so, it leaves agreements and margin calls out because they fall outside what the run was scoped to, it runs out of eligible collateral before some obligations are filled, and it meets data it cannot use. This data set is the list of all four. One row = one exception. It is what the Rules engine ⚠ Exceptions view and the Optimization Results 05 Shortfall board read.
Four categories, one file. Every row says which category it belongs to, and the four are: inventory held out by the run’s rules; margin calls and agreements held out by the same rules; obligations the run could not fully cover; and missing or invalid values in what the run read.
A data problem is one row, not one row per record. A book with five thousand lines missing the same thing is one exception affecting five thousand records, not five thousand exceptions. The Records affected column carries that count. The other three categories are one row per record, because each record was held out for its own reason.
The last seven columns are filled in on the not fully covered rows only, because they describe an obligation. On the other three categories they are blank.
Values are illustrative demo data.
| Column | What it means (plain English) | Where it comes from | Worked example row |
|---|---|---|---|
| Run reference | The run that raised this exception. The same reference the proposed movements carry, so a run and everything it held out stay together. | Captured on the run itself (this set’s own data). Required. | RUN-01 |
| Exception category | Which of the four kinds of exception this row is. Exactly four values: Inventory held out · Calls and agreements held out · Not fully covered · Missing or invalid values. | Captured on the exception itself (this set’s own data). Required. | Inventory held out |
| Record reference | What the exception is about, named the way that kind of record is named: a trade reference for an inventory line, a margin-call reference or an agreement name for a held-out obligation, the agreement name for something not fully covered, and the field name for a data problem. | Referenced from whichever file owns that record — the inventory, the margin calls, the agreement book. Required. | TRD-600001 |
| Record name | The record in words, so a reader recognises it without looking it up: the instrument for an inventory line, the counterparty for an obligation, or what is missing for a data problem. | Referenced from the file that owns the record. | FRANCE OAT 1.25% 06/27 |
| Record detail | A one-line description of the record as it stood when the run held it out — enough to tell two similar records apart on the screen. | Referenced from the file that owns the record, read at the moment of the run. | Govt · AA · SG Rates Trading · $41.2M |
| Why it was held out | The reason, in plain words: which rule removed it, or what is wrong with the value. This is the column the whole data set exists for. | Worked out by the run, from the rule that fired. | Portfolio is not in the run’s included list |
| Records affected | How many records this one problem affects. Filled in on the missing-or-invalid-values rows; blank on the others, where each row is already one record. | Worked out by the run. | 12 |
| Amount needed | What the agreement had to cover, in millions of US dollars. Not fully covered rows only. | Referenced from Exposures & margin calls (data set 10). | 312.0 |
| Amount covered | How much of it the run managed to cover, in millions of US dollars. Not fully covered rows only. | Worked out by the run, adding up the collateral value of the movements it proposed for that agreement. | 286.4 |
| Amount short | What was left uncovered — the needed amount less the covered amount, in millions of US dollars. Not fully covered rows only. | Worked out by the run, from the two columns above. | 25.6 |
| Collateral types accepted | What that agreement will take as collateral. Shown on the shortfall row because it is usually the reason the pool was too small. Not fully covered rows only. | Referenced from the agreement eligibility schedule (data set 6.1). | Cash/Govt |
| Minimum rating accepted | The lowest credit rating that agreement will accept. Not fully covered rows only. | Referenced from the agreement eligibility schedule (data set 6.1), taken together with the margin call’s own rating floor — whichever is stricter. | A |
| Eligible issuer groups | The kinds of issuer whose paper that agreement will accept — sovereigns, supranationals, agencies, financial institutions, corporates. Not fully covered rows only. | Referenced from the agreement eligibility schedule (data set 6.1), read against the user-maintained G7 industry group map (data set 7.2). | Sovereign/Supranational |
| Eligible lines that qualify | How many inventory lines survive that agreement’s own eligibility test, out of the ones the run’s rules left in play. The smaller this number, the harder the obligation is to fill. Not fully covered rows only. | Worked out by the run. | 2 |
The three exclusion lists are not this data set. The rules that hold records out live in Optimization rules (data set 11, set on the Rules engine tab); the Special-agreements list lives in the user-maintained data (data set 7.4); the per-line Ignore switch is a choice made on the results screen. This data set is what those three produced on a given run — the record of what was actually left out, and why.
Where it is shown. The Rules engine ⚠ Exceptions view shows all four categories, one section each, with a count on every section and the first hundred rows of each listed (the true total is always stated). The Optimization Results 05 Shortfall board shows the not-fully-covered category on its own, sorted with the largest shortfall first.
| Look-up table | What it holds |
|---|---|
| FX (USD per 1 unit) | USD 1 · EUR 1.08 · GBP 1.27 · SGD 0.74 · JPY 0.0064. |
| Thresholds ($mm, per type) | bim 0 · bvm 0 · gmra 12 · gmsla 18 · ccp 0 · fut 0 · tri 25. |
| Funding sources (7) | Interbank Repo · Flow Reports · HQLA · MI · CT · LMM · LRP (overridable by the user’s Source-of-collateral rules). |
| Bond types (5) → sector | SGS/UST → SOVGN (sovereign / government) · Supra/Agency → PBSEC (public-sector & agency) · Corporates → CORPO (corporate). |
| G7 industry groups | From the user’s G7 industry-group map; every bond is matched to a row of it on Issuer Industry, and a bond that matches no row takes the last row — the catch-all where every column is the default; drives “By bond type”. (The exact override keys are in the Developer build detail.) |
localStorage["collat-workspaces-v2"]{
active: "<wsId>", // currently open workspace
order: ["ws-1", "ws-2", …], // tab order
ws: {
"ws-1": {
name: "Workspace 1",
seq: 3, // instance counter
instances: [ // one per widget on the canvas
{ iid:"agreements-1", type:"agreements|charts|dock|rules|inventory",
x:0, y:0, w:4, h:14, // grid rect (12-col grid)
pinned:false,
soloDim:"time|agreement|source|type", // charts widget only
link:{ color:"blue|green|amber|purple|pink|teal|null",
role:"emitter|receiver" } // role is FIXED by type
}
],
groupSel: { "<color>": { level:"all|type|indiv", key, account, weight } }, // each emitter's pick
groupFilter: { "<color>": { gran:"daily|monthly|yearly", fromMs, toMs, refMs } } // each emitter's filters
}
}
}
{iid, type, x, y, w, h, pinned, soloDim, link:{color, role}}. role is always coerced to the type’s role on load (coerceRolesByType()); orphaned receiver colours are cleared (pruneOrphanReceivers()).#3b82f6 · green #22c55e · amber #f59e0b · purple #a855f7 · pink #ec4899 · teal #14b8a6.collat-source-rules · collat-g7-map · collat-csa-list · collat-agreement-names · collat-exposure-adjust · collat-inventory-adjust.TODAY = 18 Jun 2026 UTC · START = TODAY − 1100 days · MS_DAY = 86400000.424242 · bond inventory 20260618 · per-agreement weights 2000 + ai·131 · individual agreements 8800 + ai·1337.COLS=12 · ROW=34 · GAP=6 · MINW=2 · MINH=2; row pitch 40px; column width = canvas width ÷ 12.Each story below is one thing you can do, told in your own words (“As a user, I can …”), followed by the plain rules the app follows so it behaves that way. Read straight down — there is no technical detail here; the formulas are all kept in the collapsed Developer build detail section at the very end.
The stories are grouped: first the canvas itself (adding, arranging, linking widgets), then one section per widget — Agreements, Collateral charts, Bond postings — and finally the Key figures strip that rides on two of them.
There are five widget types (Agreements, Collateral charts, Bond postings, Rules engine, Inventory Manager) plus a Key figures strip that rides on top of two of them. The Rules engine and the Inventory Manager are both Standalone, single-instance widgets — each embeds a whole existing tool (the Rules engine embeds the Rules engine tab, §11; the Inventory Manager embeds the Inventory Manager tab, §10) and takes part in every canvas behaviour below (add, move, resize, pin, close, persist), but neither joins a colour group, so neither has a chain icon and neither drives nor follows the Agreements emitter.
Every widget carries the same handles: a ⋮⋮ grip to drag it, a chain icon to link it into a colour group, a 📌 to pin it, a ✕ to close it, and a bottom-right corner to resize.
Each widget section ends with a “What this widget shows” table: for every field it gives what it shows, how it is worked out, and which numbered Data source catalog set it draws from.
Fields marked “control” are things you operate rather than figures, so they have no data source. The one-row-per-widget Widget → data & logic lineage table above is the at-a-glance summary of the same mapping.
These four things are about the canvas itself: adding the widgets you want, arranging them on the grid, keeping several workspaces, and wiring widgets together into colour groups so one drives the others.
Each widget’s role is FIXED by its type — it is never a user choice. Agreements is always an Emitter (⬆), the Collateral charts and Bond postings widgets are always Receivers (⬇), and the Rules engine and Inventory Manager are always Standalone (they neither emit nor receive, so they have no chain icon at all).
The top-right chain icon therefore does not let you pick a role — it only sets which colour group the widget joins (under its fixed role), or Standalone (unlink).
A widget’s chain popover shows its role as a read-only label (“Emitter ⬆” / “Receiver ⬇”), then the colour swatches, then Standalone.
Emitters broadcast the agreement they show and their filter panel to every Receiver on the same colour group. This is one Emitter per colour, with any number of Receivers on that same colour; two Emitters can never share a colour, and different colour groups are independent.
A colour group only exists while an Emitter is present on it — see the two rules below.
Rule A — a Receiver only follows a colour that has a live Emitter. A receiver renders group data only when an Emitter widget is currently present on its colour.
If a receiver is linked to a colour with no emitter in the workspace (or its emitter is later closed / moved to another colour), the receiver reverts to no data: the Collateral charts widget shows its placeholder; other receivers fall back to the workspace’s global default.
There is no “phantom” group data from a colour that has no emitter. The receiver also stops showing as linked: its coloured outline and chain icon revert to the standalone look (🔗) and the now-orphaned colour is dropped from its link — a widget only ever displays a link to an emitter that actually exists on the workspace.
Rule B — Emitters auto-take a distinct colour; roles are set by type. Because the role follows the widget type, no role step exists.
Adding an Agreements widget makes it an Emitter on the next unused colour automatically (blue is taken by the default workspace, so the 2nd Agreements becomes green, the 3rd amber, …), so two emitters never share a colour; in its chain popover an emitter’s colour swatches are the colours not already used by another emitter (plus its own).
A Receiver (Collateral charts, Bond postings) starts standalone and only renders group data once you link it to a colour; in a Receiver’s colour picker the only swatches shown are colours that currently have an Emitter — a receiver can only bind to an emitter that is actually there.
Layouts saved by an older version (which used to let you pick roles) are corrected automatically when they load, so the roles are always right.
The Agreements widget is Overview 2’s control panel and its role is fixed as an Emitter (⬆): it holds the shared filters and the agreement selector, and broadcasts both to every same-colour Receiver.
It does two jobs at once: it holds the shared filters, and it is the agreement selector you drill through.
Below the filter panel is the agreement list. A single column legend labels the money columns once — Agreement · Posted · Allocated · Unallocated — then the list shows All agreements (the grand totals) and one row per agreement type.
Each row has: a colour dot, the type name, an orange (N) badge (the number of that type’s agreements with a margin call in the last 14 days), the three values Posted, Allocated and Unallocated lined up under the legend, and a › drill arrow. The labels appear only in the legend, not on every row.
How Allocated and Unallocated read: Allocated is the smaller of Posted and the type’s exposure (what’s owed plus its threshold cushion); Unallocated is Posted minus Allocated, shown green when zero or more and red when negative.
Click a type to drill into its individual agreements (e.g. GMRA-001, GMRA-002 …), each showing its share in the same columns; ← Summary returns to the type list. Drilling Triparty lists the counterparties handled by the selected triparty agent(s) (e.g. Brackwater Bank, Upperby Bank …) instead of agreement codes.
What you pick is what the Receivers show, right down to the individual agreement: pick Fernhollow Bank under Triparty and the linked Bond postings widget lists Fernhollow Bank alone — its Agreement column reads the very counterparty you picked — and the Key figures above it are Fernhollow Bank’s. Pick the type row again (or ← Summary, All agreements, ✕ Clear) and the Receivers widen back to the whole type.
Some agreement types are kept as more than one book, and some carry a flag you may want to narrow by. When you pick a type, its own sub-filter buttons appear immediately underneath that row (they are the same sub-filters the Overview sidebar offers). They are specific to the type — a type that has none shows none:
The custodian / agent / IM-VM buttons all start switched on (you are seeing the whole book). Click one to leave it out; click it again to bring it back — you can never switch the last one off, so at least one book is always showing. “Zero-interest only” starts off.
What changes when you use one: the type’s own Posted, Allocated and Unallocated figures on that row are re-worked from only the books you left on, its individual agreements are re-worked the same way, and — because this widget is the control panel — every same-colour Receiver (charts, Key figures, Bond postings) re-draws on that narrower book too. Switching “Zero-interest only” on narrows the individual CSA VM list to the flagged agreements only (about one in three). The sub-filter belongs to the agreement type you picked: the other rows keep their whole-book totals, and picking a different type starts that type fresh with every book on and zero-interest off.
(Static Data is not on Overview 2. The Rules engine and the Inventory Manager are now Overview 2 widgets in their own right — they sit in the palette and are covered in this document.)
The Agreements widget is the control panel for Overview 2. (In widget mode the standard Overview’s top filter bar is hidden, so its controls live here instead.)
At the top sits the filter panel:
When this widget is linked as an Emitter, its agreement pick and its filters drive every same-colour Receiver; when standalone, its filters drive the workspace’s global default instead.
As a user, when I add the Agreements widget and pick All agreements, a type, or an individual agreement, then it drives every same-colour Receiver and shows me each agreement’s posted / allocated / unallocated position.
It is the control panel: it broadcasts its agreement pick and its whole filter panel to every same-colour Receiver.
| Field | What it shows | How it is worked out | Data set it draws from |
|---|---|---|---|
| Granularity (Daily / Monthly / Yearly) | The time bucket receivers draw at. | Your choice, broadcast to same-colour receivers. | Control (no data set). |
| Quick range (1M / 3M / 6M / 1Y / 2Y) | A shortcut that sets the From/To window. | Your choice; sets the date window sent to receivers. | Control (no data set). |
| From / To date pickers | The start and end of the date window. | You set them; they bound every receiver’s figures. | Control (no data set). |
| Reference-date chip | The as-at date, tagged green “● latest” (newest day) or amber “historical” (stepped back in time). | The newest day in the history unless you step back; drives every “as at” figure and the Week/Week pills. | Data set 10 · Exposures & margin calls (the dated book). |
| ✕ Clear | A reset for this colour group. | Resets the group’s pick to All and the reference date to latest. | Control (no data set). |
| ⟲ Reset layout | A re-tile control (it lives here, not the toolbar). | Unpins and re-tiles the workspace’s widgets to default sizes; keeps widgets + links. | Control (no data set). |
| Column legend (Agreement · Posted · Allocated · Unallocated) | Labels the three money columns once, above the rows. | Static labels; the rows line up under them. | Control (label only). |
| Colour dot | The type’s colour beside its name. | The type’s assigned colour. | Data set 6 · Agreements static. |
| Row label (All agreements + one row per type) | The grand-total row, then the 7 type names. | The 7 type names, plus an All-agreements roll-up that deliberately excludes Triparty. | Data set 6 · Agreements static. |
| (N) margin-call badge | The orange count beside a type. | The number of that type’s individual agreements that had a margin call in the last 14 days; fixed on every load. For Triparty that is counted over its counterparties. | Data set 10 · Exposures & margin calls. |
| Posted | Collateral posted for the row. | Add up the collateral posted across the row’s selection; an individual agreement is scaled down by its share of the type. | Data set 14 · Collateral used data. |
| Allocated | Collateral actually used. | The smaller of Posted and Exposure (Exposure = what’s owed plus the type’s threshold cushion). | Data sets 14 + 10 + 6. |
| Unallocated | Spare collateral (green) or shortfall (red). | Posted minus Allocated. | Derived from the two rows above. |
| Sub-filter buttons (under the selected type only) | The sub-filters that belong to the type you picked: Bilateral CSA IM → Euroclear / Clearstream; Bilateral CSA VM → Zero-interest only; CCP → IM / VM; Triparty → Euroclear / Clearstream / BNY Mellon; GMRA, GMSLA, Futures → none. | Book buttons start on and can be switched off one at a time (never the last one); the type’s Posted / Allocated / Unallocated, its individual agreements and every same-colour Receiver are then re-worked from the books left on, and the parts always add back to the whole book. Zero-interest only starts off; switching it on narrows the individual CSA VM list to the flagged agreements. | Data set 6 · Agreements static (the sub-books and the zero-interest flag) — the money is re-worked from data set 14 · Collateral used data. |
| Drill chevron › / individual-agreement rows | Opens the type’s individual agreements (e.g. GMRA-001…), each with its own Posted / Allocated / Unallocated; “← Summary” returns. Under Triparty the rows are the counterparties handled by the agent(s) left on (e.g. Brackwater Bank…). | Each individual row is the type figure scaled by that agreement’s share of the type (the shares shown add to 100%). For a Triparty counterparty the share is its share inside its own agent’s book multiplied by that agent’s share of the books on show, so the counterparty’s figure stays the same however the other agents are toggled. | Data set 6 · Agreements static (the individual agreement, its triparty agent where it has one, and its share). |
The Collateral charts widget’s role is fixed as a Receiver (⬇). Unlinked — or linked to a colour that has no Emitter present — it shows a placeholder and no data, and its Key figures strip is hidden.
A segmented toggle at the top of the widget picks which of the four charts is displayed; the choice is remembered per widget instance.
Each chart and how it is worked out is set out in the “What the Collateral charts widget shows” table below.
Chart clicks drill / cross-filter (source, G7 group, agreement) or set the reference date, with one important limit that applies only on Overview 2. Clicking a By source bar or a By bond type slice switches that cross-filter on or off, and it does so for every widget on the page — these two cross-filters are shared page-wide rather than being confined to one colour group. Clicking an Over time bar or a By agreement bar has no visible effect on a linked chart: a linked widget always redraws from what its Agreements control panel is broadcasting, and that broadcast overrides the click. Known limitation (open, raised 31 Jul 2026): there is currently no way for a chart click to move its own colour group’s reference date or agreement pick — use the Agreements panel for that. Whether bar clicks ought to drive the colour group is an open question for the product owner.
As a user, when I add the Collateral charts widget and link it to an Emitter’s colour, then it shows the collateral position of whatever that Emitter has selected, drawn as one of four charts I switch between.
Its role is fixed as a Receiver. Unlinked — or linked to a colour that has no Emitter present — it shows a placeholder and no data, and its Key figures strip is hidden.
| Field | What it shows | How it is worked out | Data set it draws from |
|---|---|---|---|
| Key figures strip (across the top) | The nine summary cards. | Computed for this widget’s scope (the agreement + filters it receives from its Emitter). | See the Key figures strip widget below. |
| Segmented toggle (Over time / By agreement / By source / By bond type) | Which of the four charts is displayed. | Your choice; it persists per widget instance. | Control (no data set). |
| Over time — Bonds (allocated) + Cash (allocated) bars | The collateral actually allocated in each period, stacked into its bond and cash parts. The two bars together are that period’s Total allocated. | Worked out one agreement at a time, then added up: for each agreement in the selection take the smaller of what it posted and what it owes (its obligation plus its threshold cushion) — that is its used amount, and it can never be more than that agreement posted. Split each agreement’s used amount into bonds and cash in the same proportion as that agreement posted them, and add the bond parts together for the blue bar and the cash parts for the orange bar. A unallocated on one agreement is never allowed to cover a shortfall on another. When the period covers more than one day (monthly or yearly), each bar is the average of that period’s daily figures. Verify: set granularity to Daily and click the bar at the reference date — the blue bar must equal Bonds (Allocated), the orange bar Cash (Allocated), and the two together Total allocated, on the Bond postings table’s footer and on the Total allocated / Bonds allocated / Cash allocated key-figures cards. | Data set 14 · Collateral used data + data sets 10 & 6 (the exposure and threshold that cap it). |
| Over time — Total-posted line | A line in the ordinary text colour (white on the dark theme) running above the stacked bars, showing everything that was posted — used and unused together. | Add up the total posting (bonds plus cash) of every agreement in the selection, for the same period as the bars; on monthly or yearly granularity it is the average of that period’s daily figures. Because the bars show only the part that is used, the gap between this line and the top of the bars is the unallocated — collateral posted but not consumed. The line sits on or above the bars, never below. Verify: read the line at the reference date against the Total posting key-figures card; the gap to the bar tops must equal the Unallocated card. | Data set 14. |
| Over time — Exposure line | A line above the obligation. | What’s owed plus the type’s threshold cushion. | Data sets 10 + 6. |
| By agreement | The posting mix stacked per agreement. | Posted value per agreement, coloured by type. | Data sets 14 + 6. |
| By source | Bonds posted grouped by funding source (bars). | Each posting’s funding source, taken from the list of source categories; bonds only, no cash. The user’s Source-of-collateral rules supply the list of categories shown here; in the demo each posting is then given one of those categories by a fixed repeatable rule, rather than by testing that posting against the rules’ include/exclude criteria one at a time. | Data sets 14 + 7.3. |
| By bond type (doughnut) | Posted bond value grouped by G7 industry group; each slice labelled with its value and its % of the whole. | Each bond’s sector mapped through the user’s G7 map; the slices add to 100%. | Data sets 14 + 2 + 7.2. |
The Bond postings widget’s role is fixed as a Receiver (⬇). It is a single-instance widget — at most one per workspace — and is never an Emitter, so it never broadcasts.
A view toggle picks which set of columns the blotter shows; each view and its columns are set out in the “What the Bond postings widget shows” table below.
The Summary view is one row per agreement type; the Detailed view is one row per individual agreement. When the Agreements widget it follows has picked one individual agreement, Detailed shows that agreement only — its Agreement column reads the counterparty (or agreement code) picked there — and the heading underneath the title names it, e.g. “Summary by individual agreement — Fernhollow Bank, as at 18 Jun 2026”. Margin Calls narrows the same way when it is listing individual agreements. Switching views keeps the pick; it is the Agreements widget that widens it again.
The Postings view carries the Unallocated (USD) figure itself — what is posted minus what is allocated — so the bonds sitting in the longbox that the agreement’s margin requirement did not consume are visible on the posting line. (There is no separate Unallocated view; it was removed once the figure moved onto the Postings view.) A fully-used agreement leaves nothing unallocated.
The Postings by bonds view answers “which bonds have we posted to this agreement — or to this triparty repo agent — and how much of each is posted, allocated and unallocated?”. It is a pivot of the Postings view, aggregated by bond: the same bond can be posted to the same agreement (or agent) several times — different dates, different amounts, each its own line on Postings — and here they become one row whose amounts are the sums and whose Start date is the earliest of them, so no bond is listed twice. Because the row is the bond and not a posting, it drops two of the Postings columns — Agreement Name (every row is the one agreement or agent selected) and Trade # (a bond can have several postings, so no one trade number describes the row) — and starts at ISIN, whose footer counts the rows as “N bonds”. Same date window and cross-filters as Postings; it opens sorted by Posted (USD), biggest first.
Its button is always there — never hidden, so anyone using the blotter can see the view exists. It fills in once the selection names the one thing it answers for: either (a) the Agreements widget has picked one individual agreement of a non-Triparty type — for example GMRA-002 — or (b) Triparty is selected with only one agent left switched on (Euroclear, Clearstream or BNY Mellon).
Until then it shows no rows and asks for the pick. All agreements, a whole type, several types, or Triparty with more than one agent on all leave it waiting, because “which bonds are posted to this one agreement” has no answer for a group. In place of the table it reads “Select an agreement to see the bonds posted to it”, then “Click an agreement name in the Summary or Postings list — for example GMRA-002 — and this view lists every bond posted to it.” and “For Triparty, pick one agent instead — Euroclear, Clearstream or BNY Mellon — because triparty collateral is held with the agent, not under an agreement code.” It deliberately does not fall back to listing everything — that would answer a different question. The title says which state you are in: “Postings by bonds — GMRA-002”, “Postings by bonds — Triparty Clearstream”, or plain “Postings by bonds” while it waits.
Triparty is scoped by agent, not by an agreement code, because triparty collateral is not booked under a standalone agreement code — it sits with the agent, who administers the counterparties whose collateral it holds. Those rows are one per bond held with that agent, the Custodian column repeats the agent and the Counterparty column keeps whose collateral each bond is; because the same postings are only being grouped, the column totals match the Postings totals for that same one-agent selection. For one individual agreement every row is that agreement’s (which is why the column naming it is not repeated on every line), and the amounts are that agreement’s share of its type’s book — the same share the Summary/Detailed rows, the key figures strip and the agreement detail screen give it — so its totals are the type’s Postings totals multiplied by that share, not equal to them.
The “Maturing ≤ N days” filter limits Bonds Maturing to lines maturing within N days, and the column ⚙ shows/hides, reorders and pins columns — both are detailed in the field table below.
As a user, when I add the Bond postings widget, then a blotter of individual collateral lines appears.
If it is linked to an Emitter it filters to that agreement / type; standalone, it shows all postings. Its role is fixed as a Receiver — it is never an emitter and does not broadcast. Only one per workspace.
When the Emitter has picked one individual agreement, the views whose rows are individual agreements — Detailed, and Margin Calls at individual level — list that agreement alone, so the Agreement column ties to what is highlighted in the Agreements widget. The bond-level views Postings and Bonds Maturing still show the whole type; Postings by bonds is the one bond-level view that follows the pick — its button is always available, it lists that agreement’s (or that triparty agent’s) bonds alone once one is picked, and until then it shows no rows and asks for the pick.
| Field | What it shows | How it is worked out | Data set it draws from |
|---|---|---|---|
| Key figures strip (across the top) | The nine summary cards. | Computed for whatever the table currently shows (the widget’s selection + filters). | See the Key figures strip widget below. |
| View toggle (Summary / Detailed / Postings / Postings by bonds / Bonds Maturing / Margin Calls / T+N Ladder) | Which set of columns the blotter shows, and at what level of detail each row sits. | Your choice. Every view’s button is always on offer; Postings by bonds additionally needs one individual agreement (non-Triparty) or one triparty agent to be selected before it has rows to show. | Control (no data set). |
| “Maturing ≤ N days” filter | Limits Bonds Maturing to lines maturing within N days. | Your day count checked against each line’s maturity date. | Data set 2 · Bond / securities static (maturity). |
| Postings by bonds view (the Postings columns except Agreement Name and Trade #) | One row per bond posted to the one agreement — or the one triparty repo agent — currently selected, each with its posted / allocated / unallocated amounts and the rest of the bond’s details. The button is always available; until one agreement or one agent is selected it shows no rows and asks for that pick. | Takes the same postings as the Postings view, keeps only those of the selected agreement (or agent) and adds together the postings of the same bond: Original Amount, Posted (USD) and Allocated (USD) are the sums, Unallocated (USD) is Posted minus Allocated and Start date is the earliest posting’s. The agreement code and the Trade # belong to a posting, not to the rolled-up bond, so neither column is shown; the ISIN footer counts the rows as “N bonds”. For a triparty agent the Custodian column repeats the agent, so the totals match the Postings view for the same one-agent selection. For one individual agreement every amount is its share of its type’s book (the same share the Summary rows and the key figures use), so the totals are the Postings totals multiplied by that share. Opens sorted by Posted (USD), biggest first. | Data sets 14 · Collateral used data (the postings and their amounts) · 2 · Bond / securities static (the bond’s details) · 6 · Agreements static (the agreement / triparty agent it was posted to). |
| Column ⚙ | Show/hide, reorder and pin columns. | Your layout control. | Control (no data set). |
| Postings columns (Agreement Name, Trade #, ISIN, Security, Type, Sector, Counterparty, Agreement Type, Custodian, Source, Start date, Maturity, Maturing in Days, then the five amount fields: Original Ccy, Original Amount, Posted (USD), Allocated (USD), Unallocated (USD)) | One row per collateral line. | Every column’s what/computation/source is the column dictionary in the collateral-used column dictionary — instrument reference from set 2, counterparty from set 1, funding source from set 7.3, FX from set 8. | Data set 14 · Collateral used data (+ sets 1, 2, 7.3, 8). |
| The five amount fields on every postings row (Original Ccy · Original Amount · Posted (USD) · Allocated (USD) · Unallocated (USD)) | Original Ccy the currency the bond is denominated in. Original Amount how much of the bond was posted, counted in that currency. Posted (USD) the same posted amount in US dollars. Allocated (USD) the part of it the collateral team used to cover this agreement’s margin requirement. Unallocated (USD) what is posted but not consumed — it sits in the longbox. Worked example: Original Ccy SGD, Original Amount 1,000,000, Posted (USD) 700,000, Allocated (USD) 500,000, Unallocated (USD) 200,000. | Posted (USD) = Original Amount multiplied by the line’s exchange rate. Allocated (USD) = Posted (USD) scaled down by the agreement’s used-versus-posted coverage (the smaller of: one, and the exposure divided by the total posting). Unallocated (USD) = Posted (USD) minus Allocated (USD), never below zero. Verify: pick any row — Original Amount times the currency’s rate must give Posted (USD); Posted (USD) minus Allocated (USD) must give Unallocated (USD); the Allocated column’s footer total must equal that agreement’s “Bonds (Allocated)” figure on the Summary view, and the Posted column’s footer total its “Bonds (Posted)” figure. Known defect (open, raised 31 Jul 2026): the build currently normalises every posting of a book — including postings that have already matured — up to the day’s bond figure, and only then hides the ones not live at the reference date. The result is that the postings on screen add up to less than the Bonds posted card whenever a selection holds matured postings: at the latest reference date GMRA shows about $448m of postings against a $588m card, and GMSLA about $296m against $374m. Bilateral CSA IM and VM, CCP, Futures and Triparty happen to tie out because all of their postings are still live. The tie-out described here is the intended behaviour and the build is to be corrected to match it — until then, expect GMRA and GMSLA to fall short and do not raise it as a new defect. A fully-used agreement (total posting at or below exposure) shows nothing unallocated on any line. | Data set 14 · Collateral used data (posted & used amounts) + set 8 · FX (the rate) + sets 10 & 6 (the coverage). |
| Summary / Detailed (per-agreement) columns | The same money figures as the Agreements table, per agreement. Summary is one row per agreement type; Detailed is one row per individual agreement — and when the Agreements widget has picked one individual agreement, that one row only. | Exposure / Call / Margin call from set 10 (+ 6 for thresholds); Posting / Bonds / Cash / Received from set 14. An individual agreement’s figures are the type’s figures scaled by that agreement’s share of the type — the same share the Agreements widget shows it at, so the two screens agree. Full definitions in data model 14 and the Overview field table (Requirements 1 · Epic 2). | Data sets 10 + 14 + 6. |
| T+N Ladder view (Triparty only — Country · T+0 · T+1 · T+2 · T+3 · T+4 · T+5) | How much triparty bond collateral could be settled on each of the next six business days. The button appears only while Triparty is the selection and disappears when any other type is picked. It shows three separate tables, one per triparty agent — Euroclear, Clearstream and BNY Mellon. Each table has one row per settlement location — GB, FR, HK, EA, AU, US and Corp — and one column per settlement horizon, from T+0 (settles today) out to T+5 (settles in five business days). Every cell is an amount in US$ millions: the unallocated bond collateral sitting in that agent’s longbox that could settle in that location at that horizon. Amounts of half a million or less are shown as a dash rather than a number. A Total row closes each table. | Each agent’s ladder starts from that agent’s own book size shared across the seven locations, and then falls away as the horizon lengthens — roughly 15% less at each step out, so T+0 is always the largest column and T+5 the smallest. The Total row is simply the seven location rows for that column added together. Verify: add up the seven country figures in any column — the result must equal that column’s Total. Read across any row and the amounts must fall as the horizon lengthens. The same figures appear on every fresh load, so two testers on two machines must read identical numbers. Lineage note (open, raised 31 Jul 2026): unlike every other figure in this document, these amounts are a fixed illustrative table in the demo — they are not worked out from the collateral lines behind the Postings view, so they will not reconcile to the Unallocated column or to any other figure on the screen. Before this view is built for real it needs its source data set confirmed and added to the data model list above. | Not yet traced to a data model — see the lineage note. |
| Margin Calls view + 5 KPI tiles (Total Margin Call, Pending Review, Confirmed, No Call, Disputes) | The Daily Exposure Report rows and their roll-up tiles. When it is listing individual agreements and the Agreements widget has picked one, it lists that agreement alone and the five tiles count only it. | Totals and counts of the rows by call status and dispute. | Data set 10 · Exposures & margin calls. |
The Key figures strip is not a standalone palette widget; it rides on top of the Collateral charts and Bond postings widgets, each strip scoped to its own widget.
As a user, when I add a Collateral charts or Bond postings widget, then a strip of nine summary cards appears across its top, each scoped to that widget — so two strips can show different numbers at once.
The Bond postings strip always describes the table underneath it: when that table is narrowed to one individual agreement (the Agreements widget picked it and the view is Detailed, Postings by bonds, or Margin Calls at individual level), every card is that agreement’s share — so Total exposure equals the row’s Total exposure, Total posting equals its Total posting, and so on down the row. The cards scale the same way on Postings by bonds once that view has an agreement to show. On the remaining bond-level views (Postings, Bonds Maturing) the table is still the whole type, so the cards are the whole type’s.
It is not a standalone palette widget; it only ever rides on those two widgets.
| Field | What it shows | How it is worked out | Data set it draws from |
|---|---|---|---|
| Total exposure | What’s owed plus the threshold cushion across the selection. | Add up each obligation plus its threshold. | Data sets 10 + 6. |
| Total posting | Collateral posted across the selection. | Add up the day’s posting across the selection. | Data set 14. |
| Bonds posted | The bond part of the posting. | The posting times the bond share. | Data set 14. |
| Cash posted | The cash part of the posting. | Total posting minus Bonds posted. | Data set 14. |
| Total allocated | Collateral actually used. | Worked out one agreement at a time and then added up: for each agreement in the selection take the smaller of what it posted and what it owes (obligation plus threshold), and add those amounts together. A unallocated on one agreement never covers a shortfall on another, so this can be less than simply taking the smaller of the two grand totals. | Data sets 14 + 10. |
| Bonds allocated | The bond part of Allocated. | Each agreement’s used amount split in the same bonds-to-cash proportion as that agreement posted, then added up across the selection. | Data set 14. |
| Cash allocated | The cash part of Allocated. | Total allocated minus Bonds allocated. | Data set 14. |
| Unallocated | Spare collateral (green “unallocated”) or shortfall (red “deficit”). | Total posting minus Total allocated; no Week/Week pill. | Derived from the two rows above. |
| Received (inbound) | Collateral counterparties posted to us. | An independent inbound figure — not derived from Posted / Allocated / Unallocated; it moves with the selection and date window. | Data set 10 · Exposures & margin calls. |
| Week/Week pill (on every card except Unallocated) | The change versus a week earlier. | The figure now compared with the same figure seven days before the reference date; the percentage is the change divided by that earlier figure. | The same set as the card it sits on. |
Everything above described one widget at a time: what it is for, what you can do with it, and where each of its figures comes from. This last section is the opposite view — the checks that only make sense when you look at two or more widgets together, plus the one-line summary of which widget reads which data model.
If you are verifying a single number, you will find it in that widget’s own “what this widget shows” table further up. Come here when you want to prove that two widgets agree with each other.
These are not stored anywhere — they are added up from the daily records whenever a screen is drawn. “The selection” means whatever the user has picked (all agreements, one type, or one individual agreement).
| Figure | How it is worked out (plain English) | How to check it is correct (what to compare it against, on screen) |
|---|---|---|
| Posted (Total posting) | Add up the collateral posted across everything selected. For a whole type use it as-is; for one individual agreement, scale it down by that agreement’s share. | On a Key-figures strip, the Total posting card must equal Bonds posted plus Cash posted (its two halves added together). In the Agreements widget, the All agreements Posted must equal the sum of the individual type-row Posted figures except Triparty (left out of the All-agreements total) — add the visible type rows and compare. |
| Exposure | Add up what’s owed across the selection, plus each one’s threshold cushion. | On the Over time chart the Exposure line sits above the obligation by the type’s threshold cushion — for a type with a $12mm threshold, Total exposure minus what’s owed should be $12mm. A type with a zero threshold (e.g. Bilateral IM/VM) shows Exposure equal to what’s owed. |
| Allocated (Total allocated) | For each agreement, the smaller of what it Posted and its own Exposure — you can’t use more collateral than you posted, or more than you owe. The card is those per-agreement amounts added up, so a unallocated on one agreement never covers a shortfall on another. | Open the Agreements panel and read each type row’s Posted and Allocated: every row’s Allocated must be the smaller of its own Posted and its own Exposure, and adding the rows up (skipping Triparty) must give the Total allocated card. Do not check it by taking the smaller of the two grand-total cards — that only agrees when every agreement leans the same way. Where a type posted less than it owes, its Allocated equals its Posted and it contributes no unallocated. |
| Unallocated | Total Posted minus Total Allocated. It is shown green with the word “unallocated” when it is zero or positive, and red with the word “deficit” when it is negative. | Read the Total posting and Total allocated cards and subtract — the Unallocated card must equal Posted minus Allocated (to the displayed rounding). |
| Bonds / Cash allocated | Split each agreement’s Allocated figure into bonds and cash in the same proportion as that agreement posted them, then add up across the selection. | Bonds allocated plus Cash allocated must add back to Total allocated. The bonds share of Allocated will be close to, but need not exactly equal, the bonds share of the posting — each agreement is split by its own mix, so agreements that are more bond-heavy or more cash-heavy than average shift the blend. Check it agreement by agreement instead: on any single type row, Bonds (Allocated) ÷ Total allocated must equal Bonds (Posted) ÷ Total posting. |
| Received (inbound) | The collateral that counterparties have posted to us for the selection — the inbound side, the opposite direction to Posted (what we post out). It is drawn from the Exposures & margin calls data (set 10) and is an independent figure: it is not worked out from Posted, Allocated or Unallocated. | Received has no partner card to add or subtract against on the same strip (it is inbound, the others are outbound), so check it two other ways: (1) scope — it must move when you change the agreement selection or the date window, matching whatever the strip is scoped to; (2) its Week/Week pill — set the To date back 7 days on the Agreements panel and the Received you then read must equal what the pill was comparing against. On fresh loads it is always the same number — the demo’s sample data is fixed, so reloading the page never changes it. |
| Key-figures cards (9) | The nine summary cards: Total exposure · Total posting · Bonds posted · Cash posted · Total allocated · Bonds allocated · Cash allocated · Unallocated · Received (inbound collateral). | The cards cross-check each other by the rows above (Bonds added to Cash gives the total; Allocated is the Agreements panel’s type rows added up; Unallocated is posting minus used). Each strip must also match its own scope — the Collateral charts strip follows the agreement and dates the Agreements control panel broadcasts, the Bond postings strip follows whatever the blotter currently shows. Allow for the displayed rounding ($ millions to one decimal). |
Why this section exists (for the BA and the tester): every figure Overview 2 shows must be checkable — if a card reads $10.0mm Total posting, we have to be able to say where that number came from and prove it is right, not take it on trust.
Overview 2 shows no figure that cannot be re-derived from the data documented above and cross-checked against another figure on the same screen.
Below, figure by figure, is the check to run and where to look.
(The underlying build formulas are in US9.15–US9.17 and the developer folds; these are the same checks in plain words, so a non-technical reviewer can confirm any number by comparison alone. Allow for the displayed rounding — the Key-figures cards and the Agreements widget’s Posted / Allocated / Unallocated figures are shown in whole $ millions, while the table cells and the Unallocated card show one decimal place. So when you add displayed figures together, allow up to about $1m of rounding difference for each figure you add — adding three sub-book readings can legitimately be about $3m off the total.)
| Figure / check | How to verify it | Where to look |
|---|---|---|
| The nine Key-figures cards add up among themselves. | On either strip: Bonds posted plus Cash posted must equal Total posting; Bonds allocated plus Cash allocated must equal Total allocated; Total allocated is the Agreements panel’s type rows added up (each capped at its own posting), not the smaller of the two grand totals; Unallocated is Total posting minus Total allocated. Read the cards and do the arithmetic — they must tie out. Unallocated shows green (“unallocated”) when it is zero or positive and red (“deficit”) when it is negative. | The Key-figures strip across the top of the Collateral charts widget and the one across the top of the Bond postings widget. |
| Received (inbound) is an independent figure — check it by scope, not by arithmetic. | Received is collateral counterparties posted to us, so unlike the other cards it does not add up with them. Confirm it moves with the selection (change the Agreements pick or date window and it changes) and that its Week/Week pill is checkable (set the To date back 7 days on the Agreements panel — the Received you then read equals what the pill compared against). | The Received (inbound) card at the right-hand end of each Key-figures strip. |
| Each strip matches its own scope. | The Collateral charts strip must equal the agreement selection and date window the Agreements control panel is broadcasting to that colour group — change the Agreements pick and the strip must move with it. The Bond postings strip must equal whatever the blotter is currently showing (its view and filters). A strip that does not follow its scope is a defect. | Compare each strip with its host widget’s current selection. |
| The Agreements rows reconcile to the grand total. | In the Agreements widget the All agreements row’s Posted / Allocated / Unallocated must equal the sum of the individual type rows below it — except Triparty, which is deliberately excluded from the All-agreements total (see data model 6). Add the visible type-row figures (skip Triparty) and compare with the All-agreements row. Each type row’s Allocated must be the smaller of its Posted and its Exposure, and its Unallocated is Posted minus Allocated. Fixed 04 Aug 2026 (was raised 31 Jul 2026): the All agreements row used to work its Allocated out as the smaller of the two grand totals rather than by adding the type rows up, so it read about $2,095m Allocated / $25m Unallocated where the type rows added to about $2,040m / $80m. It now adds the type rows, and the row reconciles. | The Agreements control-panel widget’s row list. |
| Drill down and the parts add back to the whole. | Click a type to drill into its individual agreements: each shows its share of the type, and the shares add up to the whole type (they total 100%). So the individual Posted figures sum back to the type’s Posted total — spot-check by adding a few and confirming the proportion. This holds for Triparty too, where the rows are the counterparties the agents handle: with all three agents on, all the counterparties’ Posted figures add back to All Triparty; with one agent on, only that agent’s counterparties are listed and they add back to the agent’s own Posted. | The individual-agreement drill list (the “← Summary” button returns). |
| A Triparty counterparty’s figure does not move when you change agents. | Drill into Triparty with all three agents on and write down one counterparty’s Posted. Switch off the two agents that do not handle it — the counterparty must still be listed and still show the same Posted, because its size is measured inside its own agent’s book. Switch off its own agent instead and the counterparty must disappear from the list altogether (it is handled by that agent only). | The Triparty drill list and the Euroclear / Clearstream / BNY Mellon buttons above it. |
| A sub-filter’s parts add back to the whole book. | Pick a type that has sub-filter buttons (Bilateral CSA IM, CCP or Triparty) and write down its Posted with every button on. Switch all but one book off and write that Posted down; repeat for each of the other books. The separate readings must add back to the figure you started with (allow 0.1 for rounding) — e.g. CCP with IM only plus CCP with VM only equals CCP with both on. Check the same holds for the same-colour Receivers: the charts’ Total posting card must equal the Agreements row you are filtering to. For Bilateral CSA VM, switching “Zero-interest only” on must narrow the individual list to about a third of the agreements and leave the money figures on the full CSA VM book. | The Agreements widget’s sub-filter buttons, under the type you selected; then the linked Collateral charts widget’s Key-figures strip. |
| The blotter’s Agreement column ties to the agreement picked in the Agreements widget. | Drill into a type in the Agreements widget and click one individual agreement — say Fernhollow Bank under Triparty; note its Posted, Allocated and Unallocated there. On the linked Bond postings widget switch to Detailed: it must list exactly one row, its Agreement column must read Fernhollow Bank, and that row’s Total posting must equal the Posted you noted (allow the displayed rounding). The Key figures cards above it must equal that single row figure for figure — Total posting to Total posting, Total exposure to Total exposure. Then check it widens back: click the type row again and the table returns to all of that type’s agreements with the cards back at the type totals. Switch to Margin Calls and it is the same one agreement; switch to Postings and the bond lines are the whole type’s, which is expected — collateral is posted at agreement-type level. | The Agreements widget’s drill list, and the Detailed / Margin Calls / Postings views of the Bond postings widget with its Key figures strip. |
| Rolling one agent’s postings up by bond moves no money. | Select Triparty with only one agent switched on (say Clearstream). Read the Posted (USD), Allocated (USD) and Unallocated (USD) totals in the footer of the Postings view, then switch to Postings by bonds and read them again — they must be the same (allow the displayed rounding), because the view only groups those same postings by agreement and bond. Spot-check one row: its Unallocated must equal its Posted minus its Allocated, and no agreement may list the same ISIN twice. (For one individual agreement the two views do not match, and should not: Postings by bonds shows that agreement’s share of the type’s postings, so its total is the Postings total multiplied by the agreement’s share of its type.) | The Bond postings widget — the Postings and Postings by bonds buttons, and the totals row at the foot of the table. |
| The (N) margin-call badge is a fixed count. | The orange (N) beside a type is the number of that type’s agreements that had a margin call in the last 14 days; it is the same on every fresh load (not random). Known limitation (a gap to raise): the individual-agreement drill rows do not display a per-agreement margin-call flag, so N cannot be independently re-counted on screen — verify it by its tooltip and its consistency across reloads, and flag the un-recomputable count to the Business Analyst. | The badge on each type row. |
| The charts reconcile to the strip. | On Over time, the height of each stacked bar (Bonds (allocated) and Cash (allocated) together) equals that period’s Total allocated — set granularity to Daily, click the bar at the reference date, and compare it with the Total allocated card and with the Bond postings table’s Total allocated footer; the two bar segments must equal Bonds (Allocated) and Cash (Allocated). The Total posted line runs above the bars, and the gap between the line and the bar tops is the Unallocated card — a line sitting below the bar tops is a defect (you cannot use more than you posted). It is drawn in the ordinary text colour (white on the dark theme), not green. The Exposure line sits above the obligation by the type’s threshold cushion, and the bars sit at or below it. On By source, the funding-source bars add up to Bonds posted (see the known defect note below) (this chart shows bonds only, not cash). On By bond type, the doughnut slices add up to Bonds posted Known defect (open, raised 31 Jul 2026): the build currently normalises every posting of a book — including postings that have already matured — up to the day’s bond figure, and only then hides the ones not live at the reference date. The result is that the postings on screen add up to less than the Bonds posted card whenever a selection holds matured postings: at the latest reference date GMRA shows about $448m of postings against a $588m card, and GMSLA about $296m against $374m. Bilateral CSA IM and VM, CCP, Futures and Triparty happen to tie out because all of their postings are still live. The tie-out described here is the intended behaviour and the build is to be corrected to match it — until then, expect GMRA and GMSLA to fall short and do not raise it as a new defect. and each slice’s label shows its value and its % of the whole — the percentages add to 100%. | The Collateral charts widget’s segmented toggle (Over time / By agreement / By source / By bond type). |
| The Week/Week pill is checkable. | Each card’s W/W pill compares the figure now with the same figure seven days before the reference date; the percentage is the change divided by that earlier figure. To check it, set the To date back 7 days on the Agreements panel (the reference-date chip itself is a read-out, not a control — the To date is what moves it); the figure you then read must equal what the pill was comparing against. | The pill under each Key-figures card (Unallocated has no pill). |
| A single collateral line ties out end to end. | The fully worked line in the collateral-used column dictionary shows the whole chain — booking amount → value after the haircut → converted to US dollars — and every referenced field points back to its source data set, so a developer can re-derive the row with no hidden inputs. Use it as the template for checking any line in the Bond postings blotter. | the collateral-used column dictionary above, and the Postings view of the Bond postings widget. |
This traces every Overview 2 widget back to the Data source catalog above: the numbered data sets it reads and the logic it applies to them.
Overview 2 ships five widget types (Agreements, Collateral charts, Bond postings, Rules engine, Inventory Manager) plus the Key-figures strips that ride on two of them. Read the numbers against the 15-set catalog.
This table is the one-row-per-widget summary. The field-by-field breakdown — every field a widget shows, what it shows, how it is worked out, and which data set it draws from — is in each widget’s “What this widget shows” table, starting with US9.7 · what the Agreements widget shows.
| Widget | Role | Data sets it reads (catalog #) | Logic it applies |
|---|---|---|---|
| Agreements (control panel) | Emitter ⬆ | 6 Agreements static (the 7 types, names, colours, thresholds; each individual agreement and, for Triparty, the agent that handles it) · 1 Counterparty static (the counterparty names listed when Triparty is drilled) · 10 Exposures & margin calls (obligation; the 14-day margin-call flag) · 14 Collateral used data (Posted — the Collateral Value of its lines; see the collateral-used column dictionary) · 8 FX (base-currency → USD) | Per type/selection: Exposure = add up each one’s obligation plus its threshold cushion; Allocated = the smaller of Posted and Exposure; Unallocated = Posted minus Allocated (green if zero or positive, red if negative). The (N) badge = count of that type’s individual agreements that had a margin call in the last 14 days. Drilling a type lists its individual agreements, each scaled by its share of the type (the shares add up to 100%). Drilling Triparty lists counterparties, not agreement codes — triparty collateral is held by an agent, so the rows are the counterparties the selected agent(s) handle, and switching an agent off removes its counterparties from the list. The selected type’s own sub-filters (Bilateral CSA IM → Euroclear / Clearstream · Bilateral CSA VM → Zero-interest only · CCP → IM / VM · Triparty → Euroclear / Clearstream / BNY Mellon) re-work that type’s figures from only the books left on, and travel with the selection to the colour group’s receivers. Broadcasts the agreement pick + filter panel to same-colour receivers. |
| Collateral charts | Receiver ⬇ | 14 Collateral used data (bonds/cash posted — Booking / USD values of its lines; see the collateral-used column dictionary) · 10 Exposures (the exposure line) · 6 Agreements static (By agreement mix) · 7 User-maintained — Source of collateral (By source) & G7 map (By bond type = the line's Asset Class) · 2 Bond/securities static (bond type → sector/G7) · 8 FX (FX Rate per line) | Buckets the daily book records to the emitter’s granularity (Daily/Monthly/Yearly) & date window, then draws one of four dimensions: Over time (stacked Bonds (allocated) + Cash (allocated) bars, which add up to Total allocated, with a Total-posted line above them and an Exposure line), By agreement (stacked mix), By source (funding-source bars, using the user’s Source-of-collateral rules), By bond type (doughnut by G7 group, using the user’s G7 mapping — the line’s Asset Class). Chart clicks cross-filter (source / G7 / agreement) or set the reference date. Shows a placeholder + hides its Key-figures strip when it has no live emitter. |
| Bond postings (single) | Receiver ⬇ | 15 Inventory data & 2 Bond/securities static (each posting: ISIN, Security, Type, coupon, maturity) · 1 Counterparty static (Counterparty column) · 7 User-maintained — Source of collateral (Source column) & G7/sector · 14 Collateral used data (the posting line itself: Position, Par Amount, Booking & USD Market/Collateral Value, the five amount fields — Original Ccy, Original Amount, Posted (USD), Allocated (USD) (what TMO used, scaled by the used-versus-posted coverage) and Unallocated (USD) (Posted minus Allocated); see the collateral-used column dictionary) · 10 Exposures & margin calls (Margin Calls view + 5 KPI tiles) · 6 Agreements static (Agreement Category / Custodian, Haircut; the agreement filter) · 5/8 Currency / FX (Ccy, Base CCY, FX Rate columns) | Filters the postings to the emitter’s broadcast agreement/type (or shows all postings when standalone). When the emitter has broadcast one individual agreement, the views whose rows are individual agreements — Detailed, and Margin Calls at individual level — list that agreement alone (its figures being the type’s scaled by that agreement’s share of the type), so the Agreement column matches the emitter’s pick; the bond-level views stay on the whole type, as postings are held at agreement-type level. Toggles Summary / Detailed / Postings / Postings by bonds / Bonds Maturing / Margin Calls views; the Postings by bonds view rolls the postings of a single agreement (non-Triparty) or a single triparty agent up to one row per bond, adding that bond’s postings together, and shows no rows — just an ask-for-a-pick message — until the selection names one; the “Maturing ≤ N days” filter; the column ⚙ (show/hide, reorder, pin). The Unallocated (USD) column on the Postings view shows posted-minus-allocated per line (what is posted to the longbox but not consumed by the margin requirement). Its Key-figures strip scopes to whatever the table currently shows. Never an emitter — it does not broadcast. |
| Rules engine (single) | Standalone — (neither emits nor receives) | 15 Inventory data (the collateral pool to allocate) · 10 Exposures & margin calls (the requirements to cover — one per agreement type) · 6 Agreements static (eligibility schedule, rating floor, haircut add-on, concentration limit, minimum transfer amount, settlement delay) · 2 Bond/securities static (the Bond static data input — reference attributes per collateral class: asset class/type, issuer, issuer type/country, currency, seniority, security rating, time to maturity, haircut schedule, exclusions) · 4 Portfolios static (the Portfolio static input — Portfolio name, Close entity, PC Code, Desk, Book, Product Lines, Product Franchise) · 14 Collateral used data (its Delivered rows — what is already posted; read only when the run’s Sweep the deck setting is off, so the run tops up instead of starting from a clean deck) · 13 Optimization exclusions & exceptions (what the ⚠ Exceptions view reports) · 11 Optimization rules (the active run’s scoping & ranking rules) · 12 Optimization outputs (the resulting postings) · 13 Optimization exclusions & exceptions (lines the user ignores / excludes) | Embeds the standalone Rules engine as a widget — it is the very same allocation-optimisation studio documented in full on Requirements 1 · §11 Rules engine, shown here through /j-collateraldemo?only=rules so the two stay one source of truth. In short: it scopes the inputs by the active run’s rules, then for each agreement picks the cheapest eligible collateral that satisfies eligibility, haircut, concentration and minimum-transfer limits, and reports the per-agreement postings plus the carry-cost saved versus posting all cash. Standalone: it never joins a colour group, so it neither follows nor drives the Agreements emitter. This is one of two Overview 2 widgets whose internals are specified on Requirements 1 rather than in full here, because it is an embed of that existing tool, not a native re-build. |
| Inventory Manager (single) | Standalone — (neither emits nor receives) | 15 Inventory data (the transaction-level bond holdings — every trade row: Portfolio, ISIN, Security, Notional/Par, Market & Collateral Value, category, dates) · 2 Bond/securities static (each holding’s reference details: type, coupon, maturity, sector, rating) · 8 FX (base-currency → USD for the value columns) | Embeds the standalone Inventory Manager as a widget — it is the very same inventory tool documented in full on Requirements 1 · §10 Inventory Manager, shown here through the /j-inventory page (it hides its own top bar when framed) so the two stay one source of truth. In short: it shows the holdings summary bar by category, a “Snapshot as-at” date picker, a View toggle, and the transaction-level table of bond trades. Standalone: it never joins a colour group, so it neither follows nor drives the Agreements emitter. This is the second of two Overview 2 widgets whose internals are specified on Requirements 1 rather than in full here, because it is an embed of that existing tool, not a native re-build. |
| Key figures strips (ride on Collateral charts & Bond postings) | — (part of the host widget) | 14 Collateral used data · 10 Exposures · 2 Bond/securities static (bonds-vs-cash split) | Computes the nine derived cards (derived figures) — Total exposure, Total posting, Bonds/Cash posted, Total/Bonds/Cash allocated, Unallocated, Received — each for its host widget’s own scope (the charts strip follows the charts widget’s emitter; the postings strip follows what the table shows — including scaling down to a single individual agreement when the table is narrowed to one). |
No current Overview 2 widget reads sets 3 or 9 — see the Gap highlight under the catalog. (Sets 11, 12 and 13 — the optimization rules, outputs and exclusions — plus sets 2 Bond/securities static and 4 Portfolios static are now read by the Rules engine widget, via its Bond static data and Portfolio static inputs.) If a future widget needs any of them (or any data not on the 15-set list), raise it and add it to the catalog before building.
Everything inside this fold is the exact, verbatim technical detail a programmer needs to recreate Overview 2 number-for-number — code names, seeds, formulas, grid constants and storage schemas. It is kept here, collapsed, so the rest of the page reads in plain English; you never need to open it to use or check the screen.
COLS=12, ROW=34, GAP=6, MINW=2, MINH=2 (px / cells). Column width = canvas clientWidth ÷ 12 (responsive; colW()). Row pitch = ROW+GAP = 40px. A widget at grid {x,y,w,h} is positioned by applyLayout() as left = x·colW, top = y·40, width = max(1, w·colW − 6), height = max(1, h·40 − 6) (the −6 is the GAP gutter — a 3px margin each side of a widget, per the design system). Minimum size 2×2 cells; moves/resizes snap to whole cells via Math.round and clamp to x∈[0, 12−w], y≥0, w∈[2, 12−x], h≥2. A drag starts immediately on header pointerdown (left button) — no pixel threshold — and is suppressed if the pointer is on a button/input/select/a/[contenteditable] or the widget is pinned. Canvas min-height = max(viewportH−47, bottom-most widget +20)px; a ResizeObserver re-applies the layout on width change.singleton:true in the catalog) allow only one instance per workspace; their row disables while one is present.pinned flag (accent border, drag & resize disabled, acts as a fixed obstacle in the reflow).link:{color, role} where color ∈ {blue, green, amber, purple, pink, teal} (or none = standalone) and role ∈ {emitter, receiver}. The role is fixed by the widget type — typeRole() returns emitter for Agreements and receiver for Collateral charts & Bond postings — so the UI never lets you change it; only the colour (or Standalone) is user-set. An emitter’s current agreement selection is stored per colour on the workspace (groupSel[color]) and its filter panel per colour (groupFilter[color] = {gran, fromMs, toMs, refMs}); every receiver on that colour re-renders with both (All → all agreements; a type → that type; an individual agreement → that agreement, scaled by the agreement’s share/weight; a receiver blotter filters to the type) at the emitter’s granularity / date window. Standalone widgets follow the workspace’s global selection + the global default filter. The chain icon shows the group colour + ⬆/⬇ (matching the fixed role); the popover shows the role as a read-only label and only sets the colour or Standalone.
role:"emitter" holds that colour (helper emitterColors()). Receiver gating (recvSel, effFilter, and the Collateral charts empty-state) all require hasEmitter(link.color) — a receiver on a colour with no emitter reads as unlinked (charts → placeholder; other receivers → global default). Closing or recolouring an emitter re-renders its old colour group, then pruneOrphanReceivers() clears the now-orphaned link.color of any receiver left on that colour and refreshes its chrome via chainChrome(), so the coloured outline + ⬇ icon revert to the standalone 🔗 look — the widget never shows as linked to an emitter that isn’t there. The same pruning runs on load (so a persisted phantom link self-heals) and whenever a widget’s role/colour is changed in the chain popover. chainChrome() also independently treats a receiver whose colour has no emitter as unlinked.link:{color:freeEmitterColor(), role:"emitter"} — the first colour not already used by an emitter (null if all six are taken). A Receiver widget (Collateral charts, Bond postings) is added as link:{color:null, role:"receiver"} = standalone until linked. On load, coerceRolesByType() forces every persisted instance’s role back to its type’s role (and re-frees any duplicate emitter colour), so older saved layouts that let the user pick roles are healed. No two emitters share a colour.migrate()): one workspace ws-1 named “Workspace 1” with three instances at these exact grid rects: Agreements {x:0,y:0,w:4,h:14} link {blue, emitter}; Collateral charts {x:4,y:0,w:8,h:14} link {blue, receiver}; Bond postings {x:0,y:14,w:12,h:9} link {null, receiver} (standalone). Workspace-level groupSel:{}, groupFilter:{blue: defaultFilter()}; every instance carries soloDim:"time" and pinned:false. So it ships pre-linked on blue (Agreements Emitter + Collateral-charts Receiver) and renders immediately, while the Bond-postings dock starts standalone (all postings). Note: these first-load sizes differ from the per-type catalog defaults used by Reset layout (CATALOG.def): Agreements 4×10, Collateral charts 9×11, Bond postings 12×9 — Reset unpins and re-tiles each type stacked at x=0 in the order Agreements → Collateral charts → Bond postings → Rules engine → Inventory Manager.collat-workspaces-v2 — {active, order:[wsId…], ws:{wsId:{name, seq, instances:[{iid, type, x, y, w, h, pinned, soloDim, link:{color, role}}], groupSel:{color:{level, key, account, weight}}, groupFilter:{color:{gran, fromMs, toMs, refMs}}}}}. The Collateral charts instance also stores soloDim (time | agreement | source | type) — which of its four charts is shown; groupFilter holds each emitter colour group’s granularity + date window + reference date. Any layout saved under an earlier key is replaced by the default on first load./j-collateral page. The host iframes it as /j-collateral?embed=1&widgets=1. On load the page runs its normal init (buildNav(); setTheme(localStorage["collat-theme-ds2"] || "light"); setLayout("tabs"); renderAll()); because it is embedded (window.self !== window.top) it hides its own top bar and listens for the host’s postMessage — {type:"theme", mode:"light"|"dark"} re-themes, {type:"setLayout", lay} is ignored in widget mode. Then, because ?widgets=1, the workspace-builder IIFE adds body.wmode (which hides the standard <main> and the Overview <aside> sidebar) and builds the toolbar + palette + canvas. The four-layout selector, the Split drag-handle/maximize/collapse and the Drawer/Single behaviours do not apply in Overview 2.role:null, singleton:true): Rules engine (kind:"rules", def w:12 h:22) frames /j-collateraldemo?embed=1&only=rules (frame class wrules-frame, widget class wframe-rules); Inventory Manager (kind:"inventory", def w:12 h:20) frames /j-inventory (frame class winventory-frame, widget class wframe-inventory). The framed page hides its own top bar because window.self !== window.top, and follows the host’s {type:"theme"} messages. Because each is role:null its chain icon is removed (no colour group), and drawFn is a no-op — the embedded page draws itself, so edits made in the widget and in the corresponding top-level tab are the same data (one source of truth). In the offline standalone export both routes to the Inventory Manager — this widget and the Overview sidebar entry — have their iframe src rewritten to ./j-inventory.html, the copy of that page the bundle carries as its third file.mulberry32, a “seeded PRNG” (pseudo-random number generator). Because the seed never changes, the “random” data comes out identical on every load — that is all “deterministic and reproducible” means. Time anchor: TODAY = 18 Jun 2026 UTC (Date.UTC(2026,5,18)), history START = TODAY − 1100 days, MS_DAY = 86400000 (the number of milliseconds in one day).mulberry32(424242); the bond inventory uses mulberry32(20260618); each agreement’s source/type weights use mulberry32(2000 + ai·131); the individual agreements of each type use mulberry32(8800 + ai·1337). Same seeds → same numbers every load.collat-source-rules replaces the funding-source list that drives “By source”; collat-g7-map drives the G7 grouping of “By bond type”; collat-csa-list, collat-exposure-adjust, collat-inventory-adjust apply the same way they do on Overview.| Key | Name (sidebar) | Full name | Base ccy | Dot colour | Sub-books | Threshold $mm |
|---|---|---|---|---|---|---|
| bim | Bilateral CSA IM | ISDA / CSA — Initial Margin | USD | #2563eb | Euroclear · Clearstream (custodian) | 0 |
| bvm | Bilateral CSA VM | ISDA / CSA — Variation Margin | USD | #60a5fa | — single book | 0 |
| gmra | GMRA | GMRA — Repurchase | USD | #10b981 | — VM-only, single book | 12 |
| gmsla | GMSLA | GMSLA — Securities Lending | EUR | #34d399 | — VM-only, single book | 18 |
| ccp | CCP | CCP — Cleared | USD | #8b5cf6 | IM · VM | 0 |
| fut | Futures | Futures / Cleared Derivatives | USD | #22d3ee | — single book | 0 |
| tri | Triparty | Triparty Collateral | SGD | #6366f1 | Euroclear · Clearstream · BNY Mellon | 25 |
tri) is its own world — excluded from cross-category “All agreements” totals. agVals() for a sub-book type sums only the enabled sub-books (subEff()).bim, bvm, gmra, gmsla, ccp, fut — not tri, see the next bullet). Account code = <LABEL>-NNN zero-padded (e.g. BIM-001, BIM-002). Each agreement gets a weight — its share of the type's total (a bigger weight = a bigger agreement): a raw size w = 0.3 + rng() is drawn, then all 100 are scaled so they add up to exactly 100% of the type (“normalised”): weight = w / Σw. Two yes/no flags are derived from each agreement's account code rather than at random, so the same agreements are always flagged: a zeroInterest flag = hashStr(account+"zi") % 3 === 0 (~1 in 3) and the margin-call-in-14-days flag = hashStr(account) % 10 < 3 (~30%); the per-type count of flagged agreements is MC_COUNT[type] = the orange (N) badge. hashStr(s) turns a piece of text into a stable number (the same text always gives the same number): h=0; for each char h=(h·31 + charCode) >>> 0.TRI-NNN codes. Build AGINDIV.tri by keeping the first INDIV_PER_TYPE counterparties that land on each triparty agent (2 per agent × 3 agents = 6 of the 111, so every agent keeps its own book — this is the one type that carries more than INDIV_PER_TYPE rows, by design): account = cpty = cp.name, and agent = subKeys("tri")[hashStr(cp.name+"triagent") % 3] (one of euroclear / clearstream / bny) — the agent rule is unchanged; the review-sized book simply stops at the first 2 counterparties that map to each agent, currently Euroclear: Brackwater Bank, Caldera Bank · Clearstream: Fernhollow Bank, Halvard Bank · BNY Mellon: Aldmoor Bank, Dunmore Bank. Raw size w = 0.3 + rng() from the same mulberry32(8800 + ai·1337) stream, then normalise within the agent: wAgent = w / Σw over that agent's counterparties (so each agent's counterparties total 100% of that agent). A static whole-book share is also kept for fallbacks: weight = wAgent · TRI_AGENTS[agent].base / Σ base, where the Σ runs over the agents that actually hold one of these counterparties, so the individual rows always add back to the Triparty total. zeroInterest is always false for triparty.indivList(agKey, subsOn) is the single accessor every consumer uses. For non-tri types it returns AGINDIV[agKey] untouched. For tri it keeps only the counterparties whose agent is in subsOn (defaulting to all three) and re-weights each to its share of the books on show — weight = wAgent · posted(agent) / Σ posted(agents on show), reading refRec().ag.tri[agent].posted. That gives two guarantees: the listed rows always sum back to the sub-filtered type total, and a counterparty's own figure (typeTotal · weight) is invariant to which OTHER agents are toggled. Consumers: agSummaryRows() and renderMarginCalls() pass subEff("tri"); the Overview 2 Agreements widget passes new Set(selSubs(sel,"tri")); indivWeight(agKey,account) wraps it for openAgModal() and the Rules-engine context banner. Toggling a triparty agent OFF while one of its counterparties is the current selection drops the selection back to the type level. INDIV_IX maps every individual agreement name → {key, indiv} so agDetails() resolves a counterparty name to tri, fills Counterparty name from it, and shows Triparty / custodian as that counterparty's ONE agent rather than all three.USD 1 · EUR 1.08 · GBP 1.27 · SGD 0.74 · JPY 0.0064.bim 0 · bvm 0 · gmra 12 · gmsla 18 · ccp 0 · fut 0 · tri 25.collat-source-rules).INDIV_PER_TYPE (in j-collateral.html) = individual agreements per agreement type, currently 2 (Triparty takes that many counterparties per triparty agent, so it shows 6 rows). PER_INDUSTRY (in collat-inventory.js) = bond trades per issuer industry, currently 2 — with SIZE_SCALE = 130 / (PER_INDUSTRY × 5) multiplying each trade’s notional so the book’s total value stays in the range of the original 130-trade book (it becomes 1.0 at 26 per industry). POSTINGS_PER_BOOK (in j-collateral.html) = bond postings per agreement sub-book, currently 3, splitting the same unchanged money target across fewer postings. This one is not a free dial like the other two: it is the length of POSTED_TYPES, the fixed list ["UST","SGS","Corporates"]. Each book gets one posting of each type in that list, in that order. To repopulate with more postings per book, lengthen that list rather than the number.SGS/UST→SOVGN, Supra/Agency→PBSEC, Corporates→CORPO.PROFILE) — the sample-data dials, verbatimIn plain English: the demo invents its own daily history — there is no real feed. Each agreement type has eight dials that shape its made-up numbers so they move like a real book. The table below is copied exactly from the code (a rebuild must use these exact values); what each dial means:
base — the book's normal size, in $mm (e.g. gmra sits around $520mm). Every other number is generated around this.vol — day-to-day randomness: how much the number jumps from one day to the next (0.027 = choppy line, 0.011 = smooth line).drift — slow growth across the year (0.06 ≈ the book grows ~6% over a year).cover — how much collateral gets posted relative to what is owed (1.15 = posts ~115% of the obligation, so it runs a healthy unallocated; 0.93 = posts only ~93%, so it tends to show a deficit). This one dial decides which of the four situations a book is in, because Total posting = obligation × cover and every other figure follows from it: above 1 + threshold÷obligation the book leaves collateral unallocated; above 1 its margin call is negative and can be collected back; below 1 a call is due; and below 0.5 the call is bigger than everything the book has posted, so Surplus goes negative.bondShare — the split of the posted collateral: the fraction that is bonds, the rest is cash (0.30 = 30% bonds / 70% cash).phase — where in the calendar this book's seasonal peak lands, so the types don't all peak in the same month.amp — how strongly this book swings with the seasons (1.40 = big seasonal swings, 0.85 = fairly flat).rf — the received factor: how much collateral comes back in from counterparties, relative to the obligation (1.05 = receives ~105% of it).| Type | base | vol | drift | cover | bondShare | phase | amp | rf |
|---|---|---|---|---|---|---|---|---|
| bvm | 240 | 0.022 | 0.02 | 1.15 | 0.30 | 4 | 1.30 | 1.13 |
| bim | 180 | 0.012 | 0.10 | 0.93 | 0.80 | 1 | 1.15 | 1.06 |
| gmra | 520 | 0.014 | 0.06 | 0.97 | 1.0 | 7 | 0.85 | 1.05 |
| gmsla | 300 | 0.016 | 0.04 | 1.10 | 0.90 | 10 | 1.10 | 1.06 |
| ccp | 410 | 0.018 | 0.09 | 1.06 | 0.55 | 2 | 1.25 | 1.07 |
| fut | 150 | 0.027 | 0.01 | 0.45 | 0.20 | 5 | 1.40 | 1.05 |
| tri | 360 | 0.011 | 0.07 | 1.04 | 0.92 | 8 | 0.95 | 1.05 |
BIM_CUST, TRI_AGENTS, SUBPROF) — required to reproduce three of the seven typesRead this before using the PROFILE table above. Three types are not walked directly from their PROFILE row. Bilateral CSA IM, CCP and Triparty are generated one book per sub-filter, each from its own profile below, and the sub-books then add back to the type total. For these three, the PROFILE row seeds the sub-books rather than being walked itself; a rebuild that walks PROFILE directly will produce the wrong figures for them. The other four types (Bilateral CSA VM, GMRA, GMSLA, Futures) are single-book and do come straight from PROFILE. Note also that data models 10 & 14’s “one record per type per day” becomes one record per sub-book per day for these three.
// Bilateral CSA IM — one book per custodian (they sum to the IM total)
BIM_CUST = {
euroclear: {base:110, vol:0.013, drift:0.11, cover:1.06, bondShare:0.82, phase:0, amp:1.10, rf:1.06},
clearstream: {base:70, vol:0.018, drift:0.05, cover:0.42, bondShare:0.74, phase:6, amp:1.35, rf:1.06},
}
// Triparty — one book per agent (they sum to the Triparty total, base 360)
TRI_AGENTS = {
euroclear: {base:150, vol:0.012, drift:0.09, cover:1.22, bondShare:0.95, phase:7, amp:0.90, rf:1.05},
clearstream: {base:130, vol:0.014, drift:0.06, cover:0.93, bondShare:0.93, phase:11, amp:1.00, rf:1.05},
bny: {base:80, vol:0.016, drift:0.07, cover:1.03, bondShare:0.90, phase:3, amp:1.05, rf:1.06},
}
// CCP only — IM / VM derived from the CCP PROFILE row p (GMRA & GMSLA are VM-only, single book)
SUBPROF.ccp = {
im: {base:p.base*0.40, vol:p.vol*0.8, drift:p.drift*0.9, cover:CCP_COVER.im, rf:p.rf,
bondShare: noCash ? 1.0 : Math.min(0.98, p.bondShare+0.05), phase:(p.phase||0)+1, amp:(p.amp||1)*0.8},
vm: {base:p.base*0.60, vol:p.vol*1.25, drift:p.drift, cover:CCP_COVER.vm, rf:p.rf,
bondShare: noCash ? 1.0 : Math.max(0.10, p.bondShare-0.10), phase:(p.phase||0)+4, amp:(p.amp||1)*1.2},
}
// CCP_COVER = {im: 1.1872, vm: 0.9805} — each sub-book carries its own cover, the same
// way every book in BIM_CUST and TRI_AGENTS does, either side of the parent 1.06
// noCash = the agreement type does not accept Cash, so its sub-books stay all-bonds
SUBPROF.bim = {euroclear: BIM_CUST.euroclear, clearstream: BIM_CUST.clearstream}
SUBPROF.tri = {euroclear: TRI_AGENTS.euroclear, clearstream: TRI_AGENTS.clearstream, bny: TRI_AGENTS.bny}
Note the covers differ from the parent PROFILE row, deliberately: Bilateral CSA IM’s sub-books use 1.06 / 0.42 (not PROFILE’s 0.93), Triparty’s use 1.22 / 0.93 / 1.03 (not 1.04), and CCP’s sub-books carry their own 1.1872 / 0.9805 in CCP_COVER (not PROFILE’s 1.06). Each sub-book is placed on a different side of full cover so the custodian, agent and IM/VM toggles each move between different situations rather than showing the same one twice. The Triparty weight formula in US9.15 that cites TRI_AGENTS[agent].base reads its values from the table above.
evolveBook) — how obligation / posting / received are madeIn plain English: each day the demo rolls every book forward one step — start from the book's trend size, let it wobble randomly, apply calendar effects (seasons, weekends, month-end, quarter-end), floor it so it never hits zero, then split the result into posted bonds/cash and collateral received. The exact formulas a rebuild must reproduce (rng = the seeded random-number generator, giving a value between 0 and 1):
baseNow = base·(1 + drift·yearFrac) where yearFrac = dayIndex/365.ob) is pulled 4.5% of the way back toward the trend (so it drifts but never runs away) and then nudged by a random daily shock sized by the book's randomness dial: ob += (baseNow − ob)·0.045 + (rng−0.5)·2·(vol·2.6)·baseNow.seas = 1 + amp·(0.22·sin((m+phase)/12·2π) + 0.10·sin((2m+phase)/12·2π)); a slow ~14-month cycle slow = 1 + amp·0.13·sin(i/430·2π + phase); a weekday wiggle (quieter weekends: 0.97 on Sat/Sun, else 1 + 0.013·sin((dow+1)·1.7)); a month-end build-up (dom≥26 → 1 + 0.10·(dom−25)/6) and a quarter-end bump (month%3===2 && dom≥24 → ×1.10).max(baseNow·0.35, ob·seas·slow·weekday·monthEnd·quarterEnd).mix) drifts gently toward the book's bondShare dial, with a little noise: mix = clamp(0.05…0.99, mix + (bondShare−mix)·0.025 + (rng−0.5)·0.02).cover dial, with ≈ ±3% noise: obligation·(cover + (rng−0.5)·0.060). Bonds = posted·mix; Cash = posted − bonds.rf dial, with ≈ ±2% noise: obligation·(rf + (rng−0.5)·0.04).agVals(refRec, key).posted (with WLINK=null so it is the full, unscaled type total).obligation + THRESH[key].min(Posted, Exposure) — collateral utilised to cover exposure, capped at what is posted.Posted − Allocated (green when ≥ 0, red when negative; the over-collateralisation remaining).typePosted · weight; Exposure = typeExposure · weight; Allocated = min(Posted, Exposure) — both already scaled once by the weight above; do not apply the weight a second time . Mechanically, WLINK is set to the agreement’s weight and agVals() multiplies oblig / posted / bonds / cash / received / unallocated by it — so a Receiver linked to an Emitter showing one individual agreement renders that agreement’s share of the type.tri — for Allocated too: allUsed = Σ min(agPosted(k), agExposure(k)) over the non-Triparty types, never min(Σposted, Σexposure), so the row equals the rows beneath it.renderCards) — 9 cards in this order, with formulasThe strip is not a standalone widget — one copy rides across the top of the Collateral charts widget (scoped to the agreement + filters it receives from its Emitter; hidden when the charts widget is unlinked) and one across the top of the Bond postings widget (scoped to what that table currently shows). Each card except Unallocated shows a Week/Week delta pill (prior = the same aggregate at reference − 7 days, rendered like ▼ -$14.0mm (-1.5%)).
selThreshold() (Σ THRESH of the selection)usedSel(rec).u = Σa ∈ selection min(posteda, obliga + THRESH[a]) — per agreement, then summed. Not min(Σposted, Σexposure): the aggregate form lets one agreement’s unallocated cover another’s deficit and breaks the tie-out with the summary table (it read $2,095m where the rows added to $2,040m).usedSel(rec).bu = Σa (posteda ? useda · bondsa ÷ posteda : 0) — each agreement split by its own posting mixusedSel(rec).cu, the same per-agreement split on cash (Bonds allocated + Cash allocated = Total allocated). Note the blended bonds share of Allocated need not equal the bonds share of the posting.Total posting − Total allocated — green + word “unallocated” when ≥ 0, red + “deficit” when negative; no W/W pillsoloConfig) — segmented #soloDim toggle: Over time / By agreement / By source / By bond typetime) — a stacked bar chart: Bonds (allocated) (colour --bond = #0567f7) + Cash (allocated) (colour --cash) stacked, so the bars add up to Total allocated (usedSel(rec).bu / .cu — per agreement, capped at its own posting, each split by its own posting mix), plus two lines: Total posted (--txt, = aggSel(rec).po, which therefore runs on or above the bar tops — the gap is the unallocated) and Exposure (--exp, = obligation + selThreshold()). Buckets are the time series averaged per period at the current granularity. Y-axis beginAtZero, ticks "$"+value.toLocaleString(); tooltip " <series>: $Xmm". Click a bar → set the reference date to that bucket’s end (setRefAt). Matches the Overview history chart (no “Received” line).agreement) — a stacked bar, one dataset per selected agreement, each coloured with the agreement’s dot colour. Click a bar → toggle that agreement’s filter and reveal the postings table.source) — a horizontal bar, one bar per funding source, sorted descending, coloured from SRCCOLORS (a bar dims to --line when a source cross-filter excludes it); value labels on; x-axis grace 12% (12% of empty headroom is added past the longest bar so its value label fits). Click a bar → toggle that source cross-filter (xfSource).type) — a doughnut by G7 industry group (each posting classified via bondG7 against the collat-g7-map table — matched on Issuer Industry, and anything unmatched takes the table’s last row, the catch-all where every column is the default), colours G7_COLORS (an Unclassified slice uses --line), cutout 52% (the “cutout” is the empty hole in the middle of the doughnut — just over half the chart's diameter). The right legend shows each slice’s label + $value + %; slice tooltip " <label>: $X (pct%)". Click a slice → toggle that G7 cross-filter (xfG7). This is by G7 group, not raw bond type. The widget caps this chart’s width at 720px.The selected chart persists per instance as soloDim ∈ {time, agreement, source, type}. A Collateral-charts widget renders its strip + chart under the agreement & filters of its Emitter; unlinked (or on an emitter-less colour) it shows the placeholder “This is a Receiver — link it to an Agreements Emitter: open the chain icon (🔗, top-right) and pick a colour group that has an Emitter. Without one, it shows no data.” and the Key-figures strip is hidden.
#dock DOM is moved into the widget body, and moved back when the widget is closed). It therefore exposes every dock view via its own segmented controls: Summary / Detailed, Postings / Bonds Maturing (T+N Ladder appears only when Triparty is selected), and Margin Calls, plus the “Maturing only ≤ N days” toggle with presets 7d / 30d / 90d / 180d / 1Y and the column ⚙ (show/hide, reorder, pin).WLINK is forced null, so the weight is not applied the way the charts apply it. The individual-agreement pick instead travels as a row filter: the Detailed and Margin-Calls rows carry that agreement’s share of the type, and the Key-figures cards above the table scale to the same share, while the bond-level Postings rows stay at whole-type amounts. Standalone / unlinked → the workspace’s global selection = all postings. Its Key-figures strip scopes to whatever the table currently shows.blue #3b82f6 · green #22c55e · amber #f59e0b · purple #a855f7 · pink #ec4899 · teal #14b8a6. A widget’s link = {color, role} where color ∈ those keys (or null = standalone) and role ∈ {emitter, receiver} is fixed by type via typeRole() (Agreements → emitter; Collateral charts, Bond postings → receiver).groupSel[color] = {level:"all"|"type"|"indiv", key, account, weight}; its filter per colour in groupFilter[color] = {gran, fromMs, toMs, refMs}. A Receiver on a colour resolves its selection with recvSel() and its filter with effFilter() — both require hasEmitter(color), so a colour with no live Emitter yields no group data.emitterColors() = the set of colours that currently have an emitter; hasEmitter(c); freeEmitterColor() = first colour not used by an emitter (adding an Agreements widget auto-claims it); pruneOrphanReceivers() clears a receiver’s colour once its emitter is gone; coerceRolesByType() (run on load) forces each stored role back to its type’s role and re-frees any duplicate emitter colour. redrawGroup(color) re-renders every widget on a colour after the emitter changes.color is set and (emitter, or receiver with a live emitter). Live → the widget gets a coloured outline (--wlink) and the chain button shows ⬆ (emitter) / ⬇ (receiver) with title "<Role> · <color> group"; otherwise the button shows 🔗 with title "Link — emitter / receiver"."Emitter ⬆" / "Receiver ⬇"), a Group swatch row, and a Standalone (unlink) button. Receiver swatches = only colours that have an emitter; Emitter swatches = colours not used by another emitter (plus its own). Empty states: receiver → “No emitter groups yet — add an Agreements widget (it becomes an Emitter) first.”; emitter → “All colours are already in use by emitters.”collat-workspaces-v2) — schema, healing & save triggers{active, order:[wsId…], ws:{ wsId:{ name, seq, instances:[{iid, type, x, y, w, h, pinned, link:{color, role}, soloDim}], groupSel:{color:{level,key,account,weight}}, groupFilter:{color:{gran,fromMs,toMs,refMs}} } }}.type ∉ CATALOG; ensure groupFilter exists; run coerceRolesByType() then pruneOrphanReceivers(); if the stored DB is missing/invalid, build the default via migrate(). The old keys collat-widgets-v2 / collat-widget-links-v1 are not migrated — an older layout simply falls back to the fresh default.soloDim change; workspace rename / new / switch / close.title “Add to workspace”; singleton row suffix “ (single)”.title “Link — emitter / receiver”; pin “Pin — lock this widget’s position & size” / when pinned “Unpin — allow this widget to move & resize”; close “Close — remove from this workspace”; resize handle “Drag to resize”; header grip glyph “⋮⋮”.title “New workspace”); per-tab close “✕” (title “Close workspace”); double-click a tab name to rename inline (Enter commits, Escape cancels).title “Reset the agreement selection and reference date for this group”); “⟲ Reset layout” (title “Reset this workspace’s layout”); Reference chip shows the date + “● latest” (green) or “historical” (amber); column-header titles “Total posting” / “Total allocated” / “Unallocated = Total posting − Total allocated” / “Surplus = Total allocated − Margin call”; drill note “<Agreement> — individual agreements · posting / allocated / unallocated shown” with a “← Summary” back button; the (N) badge title “N agreement(s) with margin calls in the last 14 days”.linkNote): emitter → “Emitter · <color> group — receivers linked to this colour follow the agreement you pick here.”; receiver → “Receiver · <color> group — following its emitter’s selection.”; standalone → “Pick an agreement. This is an Emitter — open the chain icon (🔗, top-right) to give it a colour group so receivers can follow. Click a type to drill into its individual agreements.”Decided 20 August 2026. Every test on this tab exercises the Overview 2 workspace builder, which is not being built. The screen is still in the demo, so the tests would still pass — passing them proves nothing about the system being delivered.
A User Acceptance Testing (UAT) pack for Overview 2 only — the widget workspace builder. It is written for a tester with no prior knowledge of the system: every test can be run by following the words alone. Each test case traces to exactly one user story on the Requirements 2 · Overview 2 tab, whose stories are now grouped by widget and numbered US9.1–US9.17 (US9.1–US9.4 canvas & workspaces · US9.5–US9.7 Agreements widget · US9.8–US9.10 Collateral charts widget · US9.11–US9.13 Bond postings widget · US9.14 Key figures strip · US9.15–US9.17 developer build detail). The test IDs keep the form TC-9.<n>.<n> (they were not renumbered); the Traceability matrix at the bottom shows which current story each case verifies. Read the “How to use this pack” box first, then work top-to-bottom, running each case’s Steps and comparing what you see to the Expected result.
What this application is: Overview 2 is a build-your-own dashboard for a collateral-management team. You add movable boxes called widgets onto a canvas, arrange them (they never overlap), link some together so one controls the others, and keep several saved workspaces. The data (agreements, postings, charts) is realistic sample data generated in the browser — there is no live feed.
Repo desk.Repo desk and press Enter.Repo desk.Repo desk.collat-workspaces-v2.)Overview 2 is fed by a fixed master list of data sets (the “Data source catalog” on the Requirements 2 · Overview 2 tab) — the 15 top-level sets, with the user-maintained set (7) broken out into its eight datasets 7.1 Cost of funds · 7.2 G7 industry group · 7.3 Source of collateral · 7.4 Exclude CSA · 7.5 Adjusting exposures · 7.6 Adjusting inventory · 7.7 Tags & highlights · 7.8 G7 by bond. This matrix shows, for a tester, which widget uses which data set and what it does with it, so you can trace any number on screen back to its source. Numbers in the Data sets column refer to that catalog. A tester does not need to verify the catalog itself — use this to understand where each widget’s figures come from, and to run the lineage checks below. The two lineage cases trace to the “what this widget shows” stories on Requirements 2: TC-DL.1 → US9.10 (Collateral charts) and TC-DL.2 → US9.13 (Bond postings).
| Widget | Data sets used (catalog #) | What the widget does with them |
|---|---|---|
| Agreements (control panel, Emitter) | 6 Agreements static · 1 Counterparty static (Triparty drill) · 10 Exposures & margin calls · 14 Collateral used data · 8 FX | Lists the 7 agreement types + drill to individual agreements; shows Posted / Allocated / Unallocated and the (N) margin-call badge; broadcasts its pick + filters to linked widgets. Drilling Triparty lists the counterparties the selected triparty agent(s) handle (Counterparty static, set 1) rather than agreement codes, because triparty collateral is held by an agent on a counterparty’s behalf. |
| Collateral charts (Receiver) | 14 Collateral used data · 10 Exposures · 6 Agreements static · 7.3 Source of collateral · 7.2 G7 industry group · 2 Bond/securities static · 8 FX | Draws Over time / By agreement / By source / By bond type. On Over time the bars are the collateral allocated (set 14 capped, agreement by agreement, by that agreement’s exposure from sets 10 + 6) and the Total-posted line is the posting from set 14 uncapped, so the gap between them is the unallocated. The By-source bars use the user’s Source-of-collateral rules and the By-bond-type doughnut uses the user’s G7 mapping (the collateral line's Asset Class) — every bond is matched to a row of that mapping table on its Issuer Industry, and a bond that matches no row is grouped under the table's last row, the catch-all where every column is the default, so no slice ever carries a group that is not in the table. |
| Bond postings (Receiver, single) | 15 Inventory data · 2 Bond/securities static · 1 Counterparty static · 7.3 Source of collateral · 14 Collateral used data · 10 Exposures & margin calls · 6 Agreements static · 5/8 Currency / FX | The postings blotter (Summary / Detailed / Postings / Postings by bonds / Bonds Maturing / Margin Calls); the Counterparty column comes from counterparty data, the Source column from the user’s rules, the Margin Calls view from exposures & calls, and each posting line's own fields (Position, Par, Market/Collateral Value, FX Rate) from Collateral used data (set 14 · the collateral-used column dictionary). The Unallocated (USD) column derives posted-minus-used per line entirely from set 14 (posted & used amounts; coverage from sets 10 + 6), and the Postings by bonds view only narrows those same lines to one agreement (or one triparty agent) and groups them by bond — neither introduces a new data source. When the Agreements widget broadcasts one individual agreement, the per-agreement views (Detailed, and Margin Calls at individual level) list that agreement alone — its figures being the type’s figures scaled by that agreement’s share of the type (sets 10 + 14 + 6); the bond-level views Postings and Bonds Maturing stay on the whole type, since set 14 holds the postings at agreement-type level, while Postings by bonds shows that agreement’s share of them. |
| Rules engine (standalone) | 15 Inventory data · 10 Exposures & margin calls · 6 Agreements static · 2 Bond / securities static · 4 Portfolios static · 11 Optimization rules · 12 Optimization outputs · 13 Optimization exclusions & exceptions · 14 Collateral used data (Delivered rows — only when Sweep the deck is off) | Embeds the full rules studio as a widget. It neither emits nor receives an agreement selection, so it never joins a colour group and never follows the Agreements widget. One copy per workspace. |
| Optimization Results (standalone screen, five views) | None of its own — it reads the Rules engine’s published result, which is built from 15 Inventory data · 10 Exposures & margin calls · 6 Agreements static | Presents ONE run five ways — approval blotter, benefits scorecard, scenario board, movement map, shortfall board. It never recomputes a figure: every number is read from the answer the optimiser published, so a view cannot disagree with the run that produced it. The scenario board is the one exception to “one run”: it runs each OTHER saved run through the same optimiser to fill its columns, then restores the active run. |
| Inventory Manager (Standalone, single) | 15 Inventory data · 2 Bond/securities static · 8 FX | Embeds the standalone Inventory Manager (the /j-inventory page) as a widget — the holdings summary bar by category, the “Snapshot as-at” date picker, the View toggle and the transaction-level bond-trade table. It is the same tool as the top-level Inventory Manager tab; it never joins a colour group. |
| Key figures strips (on charts & postings) | 14 Collateral used data · 10 Exposures · 2 Bond/securities static | The nine KPI cards (Total exposure, Total/Bonds/Cash posted, Total/Bonds/Cash allocated, Unallocated, Received), each computed for the host widget’s own scope. The three allocated cards are worked out one agreement at a time (each capped at its own posting) and then added up, so they tie to the Bond postings table’s used columns and to the Over time chart’s bars. |
Not used by any widget yet (a deliberate gap): data sets 3 Holiday calendars and 9 Benchmark interest rates only. (Sets 4, 11, 12 and 13 were on this list until the Rules engine became an Overview 2 widget — it reads all four, so they are now consumed. This list must match the “Gap highlight” line in the Requirements 2 data model section.) If a new widget appears that shows data outside the 15-set list, that is a defect — raise it.
Every test case traces to exactly one user story on the Requirements 2 · Overview 2 tab, whose stories are now grouped by widget and numbered US9.1–US9.17. The left column is the current Requirements 2 story; the right column lists the cases that verify it. Coverage is complete when every user-facing story (US9.1–US9.14) has at least one Passed case. This is a pure re-alignment to the re-grouped spec — no test’s steps, data or expected result changed, and no TC id was renumbered.
| Gap | Req 2 story | What’s missing | Impact if shipped | Raised to |
|---|---|---|---|---|
| G1 | US9.7 What the Agreements widget shows (field table) | No standalone field-inventory case. This is a “what this widget shows” reference story; its individual fields/figures are exercised by TC-9.4.1 (row content, legend & drill), TC-9.4.2 (Unallocated = Posted − Allocated) and TC-9.4.3 ((N) badge), which trace to US9.5. There is no case that walks the full field table row by row. | Low — the displayed fields are covered by the US9.5 operate cases; only the exhaustive field-by-field inventory is unwritten. | BA — confirm whether the field-table stories need their own UAT case or are considered covered by the operate-story cases. |
| G2 | US9.12 Filter maturing & configure columns | No dedicated case. The behaviours (Maturing ≤ N days presets 7d / 30d / 90d / 180d / 1Y, and the column ⚙ show/hide / reorder / pin) are exercised as steps 2–3 of TC-9.9.6, which is mapped primarily to US9.11 (switch the blotter view). US9.12 therefore has no case of its own. | Low — the behaviour is tested inside TC-9.9.6; only the traceability is bundled, not the coverage. | BA — consider splitting a dedicated TC for the maturing filter + column configuration so US9.12 has its own case. |
| G3 | US9.5 — the (N) margin-call badge (carried forward) | Not a coverage gap but an app/spec gap already flagged in TC-9.4.3: the individual-agreement drill rows do not show a per-agreement margin-call flag, so the orange (N) count cannot be independently re-counted anywhere on screen. | Medium — a tester/auditor cannot prove (N) from the screen; it can only be checked by tooltip + consistency across reloads. | BA — surface the per-agreement margin-call flag in the drill, or accept (N) as un-recomputable. |
| G4 | US9.5 — the All-agreements row (Allocated & Unallocated) | Closed 04 Aug 2026. Was a spec-versus-build disagreement: the requirements say the All-agreements row’s Allocated and Unallocated are the type rows added together; the build worked Allocated out as the smaller of the two grand totals. The build now adds the type rows, and the same per-agreement basis was applied to the Allocated key figures and to the Over time chart’s bars. Covered by TC-9.8.3, which now passes. | Was: the grand-total row understated Unallocated and overstated Allocated — about $2,095m / $25m against the $2,040m / $80m the parts add to. It now reads $2,040m / $80m and reconciles to the parts. | BA · 31 Jul 2026 — product owner ruled the requirement correct; build corrected 04 Aug 2026. |
| G5 | US9.13 — postings do not tie back to the Bonds figures | Another spec-versus-build disagreement. The requirements say a book’s Posted and Allocated footer totals equal its Bonds (Posted) and Bonds (Allocated). The build scales matured postings into the total and then hides them, so books holding matured postings fall short. Now covered by TC-DL.3 step 7, expected to fail for GMRA and GMSLA. | The blotter and the summary appear to describe different amounts of money for the same agreement — GMRA about $448m against $588m. Testers cannot reconcile the two views, and a real reconciliation control built on this would break. | BA · 31 Jul 2026 — product owner ruled the requirement correct; the build is to be changed. |
| G6 | US9.9 — chart clicks on a linked widget | Clicking an Over time or By agreement bar has no visible effect on a linked chart, because the control panel’s broadcast overrides it. The two cross-filter charts (By source, By bond type) do work, but apply page-wide rather than to one colour group. | A documented interaction does nothing, so users may believe a filter has been applied when it has not. | BA · 31 Jul 2026 — open question: should a bar click drive its own colour group? |
| G7 | US9.13 — the T+N Ladder’s figures have no data source | The T+N Ladder is now documented and covered, but its amounts are a fixed illustrative table in the demo rather than being worked out from the collateral lines, so they reconcile to nothing else on the screen. | The view cannot be built for real until its source data set is named and added to the data model list. | BA · 31 Jul 2026 — needs a data set on the master list. |
No orphan cases: every test case below (including TC-DL.1, TC-DL.2 and TC-DL.3) traces to exactly one current story. TC-9.9.11 is listed under US9.11 (switching the blotter view); it also exercises US9.13’s Agreement-column rule, which US9.13’s own cases cover. The developer stories US9.15–US9.17 are not required to carry UAT cases, but do — the deterministic-data and computation checks live there.
| User story (Requirements 2, current) | Test cases |
|---|---|
| US9.1 Add, add again & close widgets | TC-9.1.1, TC-9.1.2, TC-9.1.3, TC-9.1.4, TC-9.1.5, TC-9.6.1, TC-9.6.2 |
| US9.2 Move, resize, pin & reflow | TC-9.2.1, TC-9.2.2, TC-9.2.3, TC-9.2.4 |
| US9.3 Keep multiple workspaces — persist & reset | TC-9.3.1, TC-9.3.2, TC-9.3.3, TC-9.3.4, TC-9.3.5 |
| US9.4 Link widgets into colour groups | TC-9.5.1, TC-9.5.2, TC-9.5.3, TC-9.5.4, TC-9.5.5, TC-9.5.6, TC-9.6.3 |
| US9.5 Select & drill agreements | TC-9.4.1, TC-9.4.2, TC-9.4.3, TC-9.4.6, TC-9.4.7, TC-9.4.8 |
| US9.6 Set the shared filters & broadcast them | TC-9.4.4, TC-9.4.5 |
| US9.7 What the Agreements widget shows | — no dedicated case (see Gap Log G1); fields exercised by TC-9.4.1 / 9.4.2 / 9.4.3 under US9.5 |
| US9.8 Switch between the four charts | TC-9.9.3 |
| US9.9 Click a chart to drill / cross-filter | TC-9.9.4 |
| US9.10 What the Collateral charts widget shows | TC-9.9.5, TC-DL.1 |
| US9.11 Switch the blotter view | TC-9.9.6, TC-9.9.10, TC-9.9.11 |
| US9.12 Filter maturing & configure columns | — no dedicated case (see Gap Log G2); exercised within TC-9.9.6 |
| US9.13 What the Bond postings widget shows | TC-9.9.7, TC-9.9.11, TC-DL.2, TC-DL.3 |
| US9.14 What the Key figures strip shows | TC-9.9.1, TC-9.9.2, TC-9.9.12 |
| US9.15 (developer) Data model, loading & determinism | TC-9.7.1, TC-9.7.2 |
| US9.16 (developer) Generation & core computations | TC-9.8.1, TC-9.8.2, TC-9.8.3, TC-9.8.5, TC-9.8.6 |
| US9.17 (developer) Key-figures strip, four charts & blotter | TC-9.9.2, TC-9.9.8, TC-9.9.9 |
Fill one row per test case as you run it. Mark Pass or Fail; for any Fail, write what you saw and attach a screenshot. Select-all → copy this whole pack into your spreadsheet to fill it in there.
| Test ID | Title | Pass / Fail | Notes (what you saw if Fail) |
|---|---|---|---|
| TC-9.1.1 | Add a widget from the palette | ||
| TC-9.1.2 | Add the same widget several times | ||
| TC-9.1.3 | Bond postings is single | ||
| TC-9.1.4 | Close a widget — others compact up | ||
| TC-9.2.1 | Move a widget — no overlap | ||
| TC-9.2.2 | Header button does not start a drag | ||
| TC-9.2.3 | Resize a widget — minimum size | ||
| TC-9.2.4 | Pin locks a widget; unpin | ||
| TC-9.3.1 | Create / switch / rename / close workspace | ||
| TC-9.3.2 | New workspace opens empty | ||
| TC-9.3.3 | Always at least one workspace | ||
| TC-9.3.4 | Everything persists across refresh | ||
| TC-9.3.5 | Reset layout on the Agreements widget | ||
| TC-9.4.1 | Row content, legend & drill | ||
| TC-9.4.2 | Unallocated = Posted − Allocated | ||
| TC-9.4.3 | The (N) badge | ||
| TC-9.4.4 | Filter panel drives receivers | ||
| TC-9.4.5 | ✕ Clear resets selection & reference | ||
| TC-9.4.6 | Per-type sub-filter buttons | ||
| TC-9.4.7 | Sub-filter re-works figures; parts add back | ||
| TC-9.4.8 | Zero-interest only; new type starts fresh | ||
| TC-9.5.1 | Chain popover — role read-only | ||
| TC-9.5.2 | Emitter broadcasts to receivers | ||
| TC-9.5.3 | Emitter-less receiver shows no data | ||
| TC-9.5.4 | New Agreements auto-takes a colour | ||
| TC-9.5.5 | Receiver picker offers only emitter colours | ||
| TC-9.5.6 | Independent colour groups | ||
| TC-9.6.1 | Palette lists exactly five widgets | ||
| TC-9.6.2 | Toolbar hint text | ||
| TC-9.6.3 | Default workspace on first load | ||
| TC-9.7.1 | Figures are deterministic | ||
| TC-9.7.2 | Seven agreement types present | ||
| TC-9.8.1 | Allocated = min(Posting, Exposure); Unallocated | ||
| TC-9.8.2 | Individual agreement is a share; shares add back to the whole | ||
| TC-9.8.3 | Type rows reconcile to “All agreements” (grand total) | ||
| TC-9.9.1 | Two KPI strips, nine cards in order | ||
| TC-9.9.2 | KPI arithmetic identities | ||
| TC-9.9.3 | Chart toggle — four dimensions | ||
| TC-9.9.4 | Chart clicks drill / cross-filter | ||
| TC-9.9.5 | Unlinked charts → placeholder | ||
| TC-9.9.6 | Blotter views, maturing presets, ⚙ | ||
| TC-9.9.7 | Bond postings scoping | ||
| TC-9.9.8 | Charts reconcile to the KPI strip | ||
| TC-9.9.9 | Week/Week delta pill is checkable | ||
| TC-9.9.10 | Postings by bonds — always visible, prompts until one agreement / agent is picked | ||
| TC-9.9.11 | Blotter Agreement column follows the picked agreement | ||
| TC-9.1.5 | Rules engine & Inventory Manager — single-copy standalone widgets | ||
| TC-9.8.5 | Exposure = what’s owed plus the threshold cushion | ||
| TC-9.8.6 | Bonds (Allocated) on the GMRA row, traced end to end | ||
| TC-9.9.12 | Received (inbound) is scoped and repeatable | ||
| TC-DL.1 | “By source” chart follows the Source-of-collateral rules | ||
| TC-DL.2 | Bond postings blotter columns trace to their data sets | ||
| TC-DL.3 | The five amount fields on the Postings view tie out |
One consolidated register of every open question across the collateral demo — items still waiting on a decision or an answer from the Business Analyst, the Product Owner, a Developer or the Tester. Anyone can raise a question here. Each row says what is unclear, where it shows up, who raised it, who it is pending on, and its status. This is the single place to see everything outstanding; the underlying detail lives in Requirements 1 · §E.14 (data-lineage gaps) and the UAT test cases for Overview 2.
How an item closes: the owner it is pending on makes the decision or supplies the data → the source is added to the Data source catalog or the spec is updated → the row is marked Resolved (with the answer) and drops off the open list. Nothing here has been invented — every item is a real gap already flagged in the spec or found during testing. Status key: Open = needs a source / a build decision · To confirm = a mapping or an intended behaviour to sign off · Placeholder = a data set that is named but not yet detailed (a reserved slot).
These figures are shown, but there is no catalogued data set they can honestly be drawn from. A source must be agreed and added to the catalog before the field is built for real. See §E.14 for the field-level detail.
| # | Open question | Where it shows up | Raised by | Pending on | Status |
|---|---|---|---|---|---|
| OQ-1 | There is no derivative-trade data set. The individual trades behind an exposure (Trade ID, Product, Notional, Trade date, Maturity, Currency) have nowhere to come from — only their combined mark-to-market ties back to Exposures & margin calls (set 10). Which data set feeds the trades? | Exposure drill; Agreement detail → Trades tab | Data-lineage audit | Product Owner | Open — add a “Trades / derivative positions” set to the catalog |
| OQ-2 | There is no security-price / valuation data set. Market value (mark-to-market) needs a price per security, but the catalog only has FX rates (8) and benchmark rates (9). Where do security prices come from? | Inventory Manager; Agreement Exposure card (MTM / IA); the ITM / OTM split | Data-lineage audit | Product Owner | Open — add a security-price data set (or add a price to Bond static · 2) |
| OQ-3 | The T+N settlement ladder has no source. The T+0…T+5 settlement-availability amounts and the country breakdown are demo placeholder numbers, not drawn from Collateral used (14) or Inventory (15). | Triparty T+N ladder | Data-lineage audit | Product Owner / BA | Open — confirm a settlement-availability source (by agent, country and settlement horizon) |
| # | Open question | Where it shows up | Raised by | Pending on | Status |
|---|---|---|---|---|---|
| OQ-4 | The “Clearer” (settlement / custody location) could be a holding attribute (Inventory · 15) or the security’s settlement instructions (Bond static · 2). Which set owns it? | Inventory Manager | Data-lineage audit | BA | To confirm |
| OQ-5 | “Business Line” is mapped to Portfolios static (4), but that set’s description does not name business line explicitly. Confirm it is a Portfolios-static attribute. | Inventory Manager | Data-lineage audit | BA | To confirm |
| OQ-6 | The issuer-classification columns (Classification Level 4 / BICS Level 2 Industry Group / Issuer Industry) are mapped to Bond static (2) but could belong to Counterparty / issuer static (1). Which set owns issuer classification? | User maintenance → G7 industry group | Data-lineage audit | BA | To confirm |
Two kinds of item here. Genuine placeholders (Holiday calendars · 3 and Benchmark rates · 9) are named in the 15-set catalog with Status = Placeholder and no invented fields — they need the Product Owner / BA to supply the detail before the feature that uses them is built. Separately, a few sets are catalogued and (partly or fully) built elsewhere but not yet surfaced on Overview 2 — the only open question there is whether they should appear on Overview 2 at all.
| # | Open question | Where it shows up | Raised by | Pending on | Status |
|---|---|---|---|---|---|
| OQ-7 | Holiday calendars (set 3) are not yet built — today the holiday centre shows as free text on the agreement. What are the calendars, and how do they drive call-date working days? | Agreement detail → Call schedule | Data catalog | Product Owner / BA | Placeholder — supply the calendar detail |
| OQ-8 | Benchmark interest rates (set 9) are a placeholder — only the rate name (e.g. SOFR) is shown; no rate value is modelled. What is the rate feed? | Agreement detail → Benchmark rate | Data catalog | Product Owner | Placeholder — supply the rate feed |
| OQ-9 | Some catalogued sets are not yet shown in any Overview 2 widget: Optimization rules (11) and outputs (12) are already built on the Rules-engine tab (catalog Status = Modeled), and Portfolios static (4) and exclusions & exceptions (13) are partly built (Status = Partial). They are catalogued, not undetailed — the only open question is whether any of them should also surface on Overview 2. | Data source catalog; Rules engine | Data-lineage audit | BA | To confirm — Overview 2 coverage |
| # | Open question | Where it shows up | Raised by | Pending on | Status |
|---|---|---|---|---|---|
| OQ-10 | Resolved (08 Aug 2026): the green “Total posted” line on the utilisation-over-time chart used to be the posted total lifted by a fixed 10% over-collateralisation buffer — a demo modelling choice, not a data feed. The buffer has been removed. The line is now the posted total itself, read straight off the record. It therefore lands exactly on top of the Bonds + Cash bars, and agrees with the Total posting card and the Agreement summary table. A line drawn above the bars is now a defect. | Overview / Overview 2 → utilisation-over-time chart | Data-lineage audit / Tester | Developer | Closed (08 Aug 2026) |
| OQ-41 | On the agreement detail pop-up, Remaining Posting Capacity → “Headroom to capacity limit (est.)” assumes the capacity limit is 130% of the obligation, for every agreement type. No agreement carries that term, and nothing in the agreement data sets it. The figure is shown in green or red, so it tells a user they are near a limit that cannot be checked against anything. What is the posting capacity limit, and where does it come from? | Agreement detail → Remaining Posting Capacity | Hard-coded-figure audit (08 Aug 2026) | Product Owner / BA | Closed (21 Aug 2026) — the line is gone. The Remaining Posting Capacity card was built in the code but never put on screen, so nothing ever showed the 130% figure. The whole card was deleted; if a real posting capacity limit exists, it comes back as a new request with its source named. |
| OQ-11 | The ITM / OTM / Net-Alternative split and the STD / Counterparty / Agreed / Dispute amounts are modelled close to the call amount, not fed from a real mark-to-market or a real dispute record. | Agreement summary; Margin Calls (Daily Exposure Report) | Data-lineage audit | Developer | Open — wire to the real feeds (depends on OQ-2) |
| OQ-12 | On the Agreement detail, the Asset-Holdings Delivery / Market-Value / Collateral-Value factors and several Corp eligibility rows are the same fixed demo wording for every agreement, rather than per-agreement / per-line values. | Agreement detail → Asset Holdings & Eligibility schedule | Data-lineage audit | Developer | Open — source per-agreement / per-line values |
| OQ-13 | The Instrument modal shows several fields as “to be provided” — Coupon frequency, Country of risk, Day count, Settlement (T+), Haircut, Accrued interest. Which of these come from Bond static (2) / Collateral used (14), and which need a new source? | Instrument modal (Inventory / postings) | Data-lineage audit | BA / Developer | Open — surface the existing fields; source the rest |
| # | Open question | Where it shows up | Raised by | Pending on | Status |
|---|---|---|---|---|---|
| OQ-39 | The optimiser's funding cost does not come from the maintained Cost of funds table. This now reaches further: the Cost column on the Optimization Results approval blotter, and the annual carry, blended funding cost and saved this year figures on the benefits scorecard, are all priced off that same built-in table, so the saving the screen reports is only as right as those buckets are. The Cost (bps) figure on every Rules-engine holding — and the Annual cost and posting-cost figures worked out from it — comes from a small built-in table of four buckets by asset class and credit rating (government AAA/AA, government A, investment-grade corporate, high-yield corporate), each with a fixed internal and external number. Meanwhile the team maintains a real cost of funds table by Security Type × currency (§13) that nothing reads, and the agreed exception handling (no matching security type → the Others row; currency not found → 0) is implemented but not yet called by the optimiser. So the number on screen does not move when the maintained rates change, which the “never hard-code a displayed figure” rule forbids. Wiring it up is a real behaviour change and needs a decision: the demo's Security Types are not priced out of the box, so on today's data every holding would fall to the Others row and price at 0, and the “cheapest first” ranking rule would stop discriminating until the table is populated. Should the optimiser be switched to the maintained table (and the demo table seeded with starting rates), or should the built-in buckets stay until real rates are loaded? | Rules engine → Inventory input, Allocation table (Cost (bps), Annual cost), run log; User maintenance → Cost of funds | BA — cost-of-funds file requirement, 07 Aug 2026 | Product Owner / BA | Open — decide whether to wire the optimiser to the maintained rates |
| OQ-40 | What should happen if the same row appears twice in an uploaded cost-of-funds file? The agreed file rules cover a row on screen that the file leaves out, and a row in the file the system does not recognise — but not a file that carries the same Security Type and Currency on two lines with different rates. Today the later line simply wins and nothing is said, which means a user can load a rate they did not intend without being told. Decided (user, 07 Aug 2026): reject it and flag it out. A file carrying the same Security Type and Currency twice is now rejected outright and the repeat is named line by line, so neither rate pair is saved and the user fixes the file instead of loading a rate they did not intend. Built the same day — test case COF-12. | User maintenance → Cost of funds (upload) | BA — cost-of-funds file requirement, 07 Aug 2026 | — | Closed (07 Aug 2026) — reject and flag out; built. |
| # | Open question | Where it shows up | Raised by | Pending on | Status |
|---|---|---|---|---|---|
| OQ-42 | What does “Release” actually do? The approval blotter lets a user accept, hold or reject each proposed movement and then press Release. In the demo that only confirms on screen. For the real system: where do accepted movements go (a settlement instruction, the triparty agent, a file to operations)? Who is allowed to release, and does it need a second pair of eyes? Can a released set be recalled before it settles, and what is the cut-off? | Optimization Results → 01 Approval blotter | BA (build of the new screen) | Product Owner | Open |
| OQ-43 | Are the accept / hold / reject decisions kept, and is an audit trail required? Today they live in the browser for the run on screen and are lost when the optimiser is re-run, because a re-run proposes a different set of postings. Does the real system need to record who decided what, when, and why a line was rejected? And does a line put on hold carry forward to the next run, or start again? | Optimization Results → 01 Approval blotter | BA (build of the new screen) | Product Owner | Open |
| OQ-44 | The movement map can show where collateral goes, but not what MOVED. A before-and-after view needs what is already posted — Collateral used data (set 14, Delivered rows) — and no such data is loaded, so a run with Sweep the deck OFF currently retains $0.0mm and behaves exactly like a sweep-on run. Confirm set 14 will be supplied, and whether the map should then show recalls and substitutions alongside new postings. | Optimization Results → 04 Movement map; Rules engine → Sweep the deck | BA (build of the new screen) | Product Owner / BA | Open |
| OQ-45 | The generated field check does not cover the Rules engine or the Optimization Results screens. The Data tab’s “Every field on the screens” card is produced from the Overview and Inventory Manager screens only, so no field on either Rules-engine screen is checked against the data you can supply. This is a pre-existing gap the new screen inherits, not a regression. Should both screens be added to the check? Expect the field count to rise well above 159 and to raise new call-outs to work through. | Data tab → Every field on the screens | BA (build of the new screen) | Product Owner | Open |
| OQ-14 | The exact business meaning of “Valuation Date” is not yet defined (flagged ⚑ on 20 Jul). What does it represent, and how does it differ from Date of Posting? | Collateral used data (set 14) → the collateral-used column dictionary column dictionary | BA | Product Owner | Open |
| OQ-46 | Which optimisation model should the engine itself run? The Optimization Model Research by AI panel now runs the same run through six different algorithms and shows what each proposes. The engine itself still runs the first one — a greedy, cheapest-to-deliver heuristic that never revisits a decision. That was never a decision anybody took; it is simply what was built first. The panel makes the alternatives comparable, and on today’s demo book it also shows that the choice does not yet matter: every model lands within a cent of the others, because the concentration cap and the eligibility schedules bind long before cost does. Two things need deciding. First, whether the engine should keep the greedy heuristic, or move to the lot-constrained optimisation, which is the only model that carries a provable bound and still settles in whole lots. Second, if it moves, whether the desk accepts an answer it cannot explain one posting at a time — an optimiser’s answer is justified by the model, not by a reason per row, and that is a governance question rather than a technical one. Building the chosen model for real also means a solver (open-source or commercial) to licence, host and support, with a time limit and a fallback for a book that will not solve in time. | Optimization Results → Optimisation model; the Rules engine’s own run | BA — optimisation model review, 16 Sep 2026 | Product Owner / BA | Open — decide whether the engine keeps the greedy heuristic or moves to the lot-constrained optimisation |
| OQ-15 | Feature relabelling — several existing feature labels are being kept as-is until the product owner supplies the agreed relabelling list. Which labels change, and to what? | Whole app (feature labels) | BA | Product Owner | Open — awaiting the relabelling list |
| # | Open question | Where it shows up | Raised by | Pending on | Status |
|---|---|---|---|---|---|
| OQ-16 | The orange (N) margin-call badge is a count of a type’s agreements with a recent margin call, but N cannot be re-counted on screen — the individual-agreement drill rows do not show a per-agreement margin-call flag. Should the per-agreement flag be surfaced so a tester can verify N? | Overview 2 Agreements widget; Overview Margin Calls | Tester — UAT review | BA / Developer | Open — decide whether to surface the per-agreement flag |
| OQ-17 | Unallocated definition. Decided (Product Owner, 21 Jul 2026): Unallocated is simply Total Posted minus Total Allocated — shown green (“unallocated”) when zero or positive and red (“deficit”) when negative. There is no “always zero-or-positive / always green” rule; the earlier claim that a red Unallocated could not occur on Overview 2 was never a stated requirement and has been removed. (The app already has a live red/deficit render path.) (Test pack Gap Log · GAP-03.) | Overview 2 Key figures; Agreements widget | Tester — UAT review | — | Decided — this figure = Total Posted − Total Allocated. Renamed 07 Aug 2026: it is now called Unallocated; “Surplus” is a different figure (Total allocated − Margin call). |
| OQ-18 | “Unallocated” is defined two different ways in our own documents. The on-screen note says unallocated is the posted collateral left over after covering what is used; an older appendix says it is what was received minus what was utilised — two definitions, two different numbers. Which one is correct to build? | Overview / Overview 2 — Agreement summary → Unallocated | Tester — figure-traceability (Gap Log GAP-01) | BA | Closed (07 Aug 2026) — the posted-minus-used definition wins, and the figure is renamed Unallocated = Total posting − Total allocated, on Overview and Overview 2 alike. The received-based definition is retired: Received (in) is information only and never feeds any worked-out figure. Surplus is now a separate figure — Total allocated − Margin call (see OQ-26, closed 07 Aug 2026). |
| OQ-19 | The “collateral value after haircut” estimate and the detailed haircut schedule don’t match up. The headline estimate trims every bond by a flat three percent, but each agreement also shows a detailed haircut table that varies the trim by credit rating and time to maturity. Should the headline figure use the flat three percent, or be driven by the detailed schedule? | Overview → collateral value after haircut; Agreement detail → haircut schedule | Tester — figure-traceability (Gap Log GAP-02) | BA | Open |
| OQ-20 | The “change since” indicators don’t mean the same thing on every screen. The day-on-day, week-on-week and month-on-month change pills compare against different look-back periods and are shown in different units on different screens. Should these be made consistent across screens, or clearly labelled on each screen so a reader knows which comparison they are looking at? | Overview KPI pills; Agreement summary; Overview 2 | Tester — figure-traceability (Gap Log GAP-04) | BA | To confirm |
| OQ-29 | The Asset Holdings Summary card works its values out from fixed percentages, not from the agreement’s own haircut schedule. On the agreement detail popup, Market value (est.) is the bonds figure cut by a flat 1.5%, Collateral value after haircut (est.) by a flat 3%, and the mini-table’s Delivery column is a flat 28% of the amount held — the same three percentages for every agreement, every rating and every maturity. Meanwhile each agreement already carries a real haircut schedule in its own terms (for example “AAA / up to 1 year: 0.5% · AAA / 1–5 years: 1.5% · AA / 1–5 years: 2% · A / 1–5 years: 4%”), which is what those figures ought to be worked out from, bond by bond, using each holding’s credit rating and time to maturity. The Delivery column has no source at all — it is not clear what business figure it is meant to be. These numbers therefore do not move when the book changes, which the 04 Aug standing rule (“never hard-code a displayed figure”) forbids. What should each of the three be derived from? | Overview & Overview 2 → agreement detail popup, Asset Holdings Summary | Hard-coded-figure audit, 04 Aug 2026 | Product Owner / BA | Open |
| OQ-28 | The “Base Total Exp.” and “Base Call Amt” totals add different currencies together. Both columns are stated in each agreement’s own base currency, and the demo book holds three (US dollars for most types, euros for GMSLA, Singapore dollars for Triparty). On any selection spanning more than one, the total row adds those amounts as if they were the same currency. The total row now shows an amber “Mixed” under Base CCY so the reader is warned, but the two amount totals are still shown as single numbers. Should they be suppressed on a mixed selection, split per currency, or converted to a reporting currency first? | Overview & Overview 2 → agreement summary table, Detailed view | Raised while filling in the blank totals, 04 Aug 2026 | Product Owner | Open |
| OQ-25 | The “All agreements” row does not add up for Allocated and Unallocated. The requirements say that row is the agreement-type rows added together. The build worked its Allocated out as the smaller of the two grand totals, so the row read about $2,095m Allocated / $25m Unallocated while the six type rows added to about $2,040m / $80m. Posted always added up correctly. Decided (Product Owner, 31 Jul 2026): the requirement is correct — the build to be changed so the row adds the type rows. Fixed 04 Aug 2026: the row now adds the type rows, and the same per-agreement basis was carried into the Allocated key figures and the Over time chart’s bars, so all four surfaces now agree at $2,040m / $80m. TC-9.8.3 passes. | Overview 2 → Agreements widget, the All agreements row | UAT figure-traceability review | Developer (build fix) | Closed — fixed 04 Aug 2026 |
| OQ-26 | The Surplus figure came out large and negative on every agreement. It had been specified the wrong way round, as Margin call minus Total allocated, which gave every row that agreement’s own posting with a minus sign in front of it — GMRA read −$562.0m and Bilateral CSA VM −$259.4m, on a row where $34.1m was in fact spare. | Overview / Overview 2 — Agreement summary and Agreement summary — detailed → Surplus | BA — figure provenance check, 07 Aug 2026 | Product Owner | Closed (07 Aug 2026) — the two figures were the wrong way round. Surplus is Total allocated minus Margin call: what is left of the collateral allocated once the call has been met. The margin call is signed positive when we have to post, so allocating $100m against a call of $50m to post leaves $50m spare. A negative margin call means nothing has to go out and it can be collected back, so subtracting it adds to the surplus — Bilateral CSA VM now reads $225.2m − (−$34.1m) = $259.3m. |
| OQ-26 | The bond postings on screen add up to less than the Bonds posted figure. The build scales every posting of a book — including ones that have already matured — up to the day’s bond figure, and only then hides the matured ones, so a book holding matured postings falls short. At the latest reference date GMRA shows about $448m of postings against a $588m Bonds (Posted) figure, and GMSLA about $296m against $374m; the other five types tie out because none of their postings have matured. Decided (Product Owner, 31 Jul 2026): the postings are meant to tie out — the build is to be changed. Until then TC-DL.3 step 7 is expected to fail for GMRA and GMSLA. | Overview 2 → Bond postings (Postings view footer totals), the By source and By bond type charts | UAT figure-traceability review | Developer (build fix) | Open — decision made, fix pending |
| OQ-27 | Clicking an Over time or By agreement bar does nothing on a linked chart. A linked widget always redraws from what its Agreements control panel is broadcasting, and that broadcast overrides the click. The two cross-filter charts (By source, By bond type) do respond, but they apply page-wide rather than to the one colour group. Should a bar click be able to drive its own colour group’s reference date or agreement pick? | Overview 2 → Collateral charts widget | UAT figure-traceability review | Product Owner | Open |
| OQ-34 | Test coverage still missing after the 31 Jul review. The review found these gaps but they were not closed in that change, so they remain untested: (a) sub-filter memory per colour group — that a book choice such as CCP → VM-only is remembered per colour group, survives a reload, and does not leak into another group; (b) what a Bond postings widget does when its emitter disappears — closing or recolouring the Agreements widget it followed should drop it back to showing everything; (c) the column sets of the Summary, Detailed and Margin Calls views — no test reads the header row against the documented list, or checks that Detailed adds exactly the six extra columns, or hand-counts the five Margin-Calls tiles against the rows; (d) the Collateral charts strip when one individual agreement is picked — only the blotter strip is covered; (e) boundary cases — running out of emitter colours, cancelling a workspace rename with Escape, and the saved column layout. Decide whether these should be written up as test cases now or deliberately accepted as untested. | UAT test cases · Overview 2 | UAT figure-traceability review | BA / Product Owner | Open — known gap, not yet closed |
| OQ-35 | Does clicking a bar on the “By agreement” chart do anything inside a widget? On the top-level Overview this click reveals the postings table, but on Overview 2 the postings table is a separate widget. The review could not confirm what, if anything, happens without running the page, so the expected result cannot be written yet. Someone needs to click it and record what actually happens. | Overview 2 → Collateral charts widget → By agreement | UAT figure-traceability review | Tester (observe), then BA | Open — behaviour unconfirmed |
| OQ-36 | Dates are shown in two different formats. The Detailed view heading writes the as-at date as 2026-06-18, while the requirements use 18 Jun 2026 throughout. One of the two should win. This is a presentation choice, not a calculation, so it is being raised rather than changed. | Overview 2 → Bond postings → Detailed heading (and the chart hints) | UAT figure-traceability review | Product Owner | Open |
| OQ-37 | Is the T+N Ladder meant to be an Overview 2 view at all? It has now been documented because it is on screen, but it was never specified as an Overview 2 feature — it may have been intended only for the Triparty view on the top-level Overview. Confirm whether it stays as a seventh blotter view (in which case it also needs the data source in OQ-3 resolved) or is removed from the widget. | Overview 2 → Bond postings → T+N Ladder | UAT figure-traceability review | Product Owner | Open |
| OQ-38 | Should each figure carry its “how to check it” right beside it? Every widget section lists its figures with what they show, how they are worked out and which data model they come from; the independent verification step for each currently sits in the “Checks that span more than one widget” section instead of next to the figure. Confirm whether to move each check up beside its own figure (a fifth column on every widget table) or leave the checks gathered together. | Requirements 2 · Overview 2 — every widget table | Requirements review | Product Owner / BA | Open — presentation decision |
Overview 2 field-lineage completeness audit (22 Jul 2026). Every field, column, KPI card, chart series and label shown anywhere in Overview 2 — the Agreements control panel, the four Collateral charts (Over time / By agreement / By source / By bond type), the Bond-postings blotter in all five views (Summary / Detailed / Postings / Bonds Maturing / Margin Calls), and the Key-figures strips — was traced field-by-field to the data catalog. Result: every Overview 2 figure either traces to a modeled data set (6 Agreements static · 10 Exposures & margin calls · 14 Collateral used data, plus 1 · 2 · 5 · 7.2 · 7.3 · 8 for the blotter’s reference columns) or is already listed as an open question above — the modelled Total-posted buffer (OQ-10), the ITM/OTM/STD/Cpty split (OQ-11), the meaning of Valuation Date (OQ-14), and the (N) margin-call-badge verifiability (OQ-16). No new off-catalogue Overview 2 field was found. Category / Region / Credit Rating in the Detailed view were checked and trace to Agreements static · 6 (per §E.1), so they are not a gap. This applies the standing rule that everything shown in Overview 2 must be documented against an existing data model, else raised here as an outstanding question.
The everyday questions a Business Analyst asks at the very start of a project that were never settled for this app. Until they are answered, the demo’s own shortcuts (a single user, no login, data made up in the browser) stand in — and those are demo-only, not how the real system should be built.
| # | Open question | Where it shows up | Raised by | Pending on | Status |
|---|---|---|---|---|---|
| OQ-21 | Who will use the real system, and is there more than one type of user? For example, is there a person who enters and confirms margin calls and a separate person who only reviews or approves them, and are there read-only viewers? The demo runs as a single user with no login, so the real roles — and what each is allowed to see and do — need to be confirmed. | Whole app — sign-in & roles | BA — discovery | Product Owner | Open — decides whether the build needs sign-in, separate roles and “who may do what” rules |
| OQ-22 | Roughly how much data will the real system hold and change each day? About how many agreements, margin calls, collateral postings and inventory rows, and how often do they update? An order of magnitude is enough (hundreds, thousands, tens of thousands). | Whole app — tables, filters, totals, charts | BA — discovery | Product Owner | Open — changes how screens must be built to stay fast and readable |
| OQ-23 | What are the expectations for how the real system must behave? Specifically: how fast screens should load, what security is required, whether there must be an audit trail (a record of who changed what and when), how long data must be kept, and which devices and browsers must be supported. None of these have been specified yet. | Whole app — non-functional requirements | BA — discovery | Product Owner | Open — the demo’s single-user, in-browser, no-login setup is demo-only |
| OQ-24 | Which systems feed this app, and which systems use what it produces? Where do the agreements, exposures, margin calls, collateral postings and inventory actually come from (the systems upstream), and which teams or systems consume the results downstream? The demo makes up its own sample data in the browser, so the real sources and consumers need to be named. | Whole app — data in / data out | BA — discovery | Product Owner | Open — names the real sources behind every figure and completes the data-source catalog |
The Rules engine lets you filter and rank your collateral, margin calls and agreements on a set of fields. Tracing each of those fields back to the data catalog shows that several of them have nowhere to be stored yet — the data set the engine reads doesn’t hold that attribute, so it cannot be uploaded and mapped on the Data tab. Each needs a source decision before it is built for real. (Detail: the “Field → data model → Data tab” trace, Rules-engine screen.)
| # | Open question | Where it shows up | Raised by | Pending on | Status |
|---|---|---|---|---|---|
| OQ-25 | The engine can filter inventory by Asset type (Cash / Govt / Corp), but the Inventory data set (15) does not hold an asset-type field — it holds Sector, Industry and Bond type instead. Should Asset type be worked out from those, or added as its own field? | Rules engine → Inventory scoping | Field → data-model trace (Rules engine) | BA | Open |
| OQ-26 | The engine can filter inventory by Holding (our own holdings / held elsewhere / collateral we have received), but the Inventory data set (15) has no holding-status field. The nearest is the Delivered / Held marker on Collateral used (14). Add a holding-status field to inventory, or read it from Collateral used? | Rules engine → Inventory scoping | Field → data-model trace (Rules engine) | BA | Open |
| OQ-27 | The engine can filter inventory by Haircut %, but the Inventory data set (15) carries no haircut. A haircut normally comes from the eligibility / haircut schedule (Bond static · 2 / Agreement · 6) or is captured on the posted line (Collateral used · 14). Where should the per-line haircut come from? (Relates to OQ-19.) | Rules engine → Inventory scoping | Field → data-model trace (Rules engine) | BA | Open |
| OQ-28 | The engine can filter inventory by Book (the desk / book that owns the line), which is a Portfolios-static (4) attribute — but Portfolios static is still a placeholder with no fields defined, so Book cannot be uploaded / mapped yet. Detail Portfolios static and join Book to each inventory line. | Rules engine → Inventory scoping | Field → data-model trace (Rules engine) | Product Owner / BA | Placeholder |
| OQ-29 | The engine ranks (and can filter) inventory by Cost of funds (bps), which is not held on the inventory line — it comes from the user-maintained Cost of funds table (7), matched to each line by G7 industry group × currency. Confirm those are the correct match keys. | Rules engine → Ranking / Inventory scoping | Field → data-model trace (Rules engine) | BA | To confirm |
| OQ-30 | The engine filters on a single Rating, but each inventory line holds two ratings — Issuer Rating and Bond Rating. Which one should the rating rule use? | Rules engine → Inventory scoping | Field → data-model trace (Rules engine) | BA | To confirm |
| OQ-31 | The engine filters on Custodian (e.g. Euroclear, an internal custody account), while the Inventory data set (15) calls its settlement / custody location Clearer. Are “Custodian” and “Clearer” the same attribute? (Ties to OQ-4.) | Rules engine → Inventory scoping | Field → data-model trace (Rules engine) | BA | To confirm |
| OQ-32 | The engine scopes on individual margin calls (by Currency, Call size and MTA), but the catalogued “Exposures & margin calls” set (10) is modelled per agreement type per day, not per individual call — so those call-level fields have no home. Add call-level fields to set 10, or add a separate individual-margin-calls set. | Rules engine → Margin-obligations scoping | Field → data-model trace (Rules engine) | Product Owner / BA | Open |
| OQ-33 | Resolved (23 Jul 2026): Agreements static (6) now carries the full set of agreement-level terms shown on the agreement detail pop-up — identity/admin, margin-call summary, valuation & call schedule and collateral rules — and the Rules engine can scope agreements on any of them (plus the eligibility Rating floor and Settlement delay it already had). Concentration limits and the eligibility rating floor remain modelled as optimisation boundaries, not scoping rules (a deliberate business decision), so they are not offered as agreement scoping conditions. | Rules engine → Agreement scoping / Limits | Field → data-model trace (Rules engine) | Product Owner / BA | Closed |
Copy or download everything needed to stand up Overview 2 and the Data screen as a standalone application, and hand it to another Claude (or any developer). The source-file cards fetch the currently-deployed pages live from this site when you open this tab, so they are never a stale copy. This is the same export that used to live on /j-tool — kept here so you can grab it straight from the demo.
Packs the whole prototype into collateral-optimisation-prototype.zip, fetched live from this site so it is always the currently-deployed source. Unzip it and keep the folders it creates — the zip mirrors the paths this site serves, with the three designed screens and their runtime under aoe/ and the libraries under vendor/, because that is exactly where the app asks for them. Then serve the unzipped folder at a web server's root and open j-collateraldemo.html — any plain static server will do, because the packed copies spell out the .html on their own routes (this site resolves them without it; a plain server does not). Flattening the files into one folder, or opening them off disk, leaves the app looking for /aoe/… and /collat-inventory.js where nothing is — the Overview loses its tab strip and the three designed screens come up blank, even though every file is present. Charts come from the Chart.js CDN; if that is blocked where you serve it, point the cdn.jsdelivr.net script tag at the vendor/chart.umd.js in the pack. If you cannot run a web server, use the offline bundle below instead — that one is built flat on purpose, with every path rewritten to sit beside the file asking for it, and it opens by double-clicking.
Builds a fully self-contained copy of Overview, Overview 2, the Data screen and the three designed screens (Optimization Rules, Optimization Results and the Triparty AOE dashboard) — the charting library and the inventory data file are baked in, the designed screens and their runtime travel beside them, and every link is made relative, so it runs by double-clicking a file, with no web server and no internet. Use this when you cannot download files, or cannot reach this site, from the target laptop. It is generated live from the currently-deployed pages, so it is never a stale copy.
Hands Overview 2 (the workspace-builder dashboard) and the Data screen (upload your own files, map fields, flip the whole app between the built-in demo and your production data) to another Claude as its OWN standalone application — same data and interactions as the live tabs. Paste this message first, then give the 2 files from the card below. It tells the receiving Claude to serve the files as-is, byte-for-byte, then run the verification checks and report pass/fail.
The 2 files behind the handoff above, fetched live from this site as you open this tab — so they are ALWAYS the currently-deployed version, never a stale copy. j-collateral.html is the Overview 2 app (open at /j-collateral?widgets=1) and carries the data-reading layer; j-collateraldemo.html carries the Data screen (its “Data” tab) plus the full build spec. Save each as its matching filename and serve both under the same origin so they share browser storage.
j-collateral.html opened at /j-collateral?widgets=1 (top-level, not in an iframe) — that query string turns the file into the standalone workspace builder with its own top bar & theme toggle. To make the app open straight into it, add a one-line landing page that redirects to that URL; do not edit j-collateral.html.j-collateraldemo.html — serve it at /j-collateraldemo and open that tab. Because both files are same-origin, an upload + mapping saved there is read by Overview 2 automatically (they share browser storage).