Skip to content

Bank workspace — full UI guide ​

INFO

Ported from docs/workspace-guide.md. Prefer the zone pages (Work, Analysis, …) for navigation; this page keeps the complete tour in one place.

Status: October 2026 (through slice 34).

This guide explains every page under bank /workspace (locus-web), plus a short map of the separate platform ops app (locus-ops). It is written for a software developer who does not work in finance. Each chapter says what the page is for, what it actually does in the product, what the words on the screen mean, why a bank or an arranger would open it, and a concrete way to use it.

Every claim comes from the page component, the data it reads, and the domain code it calls. Where a number is sample / test-reference copy rather than a live tenant calculation, the chapter says so.

The product UI mixes English and French. French labels are quoted and translated the first time they matter.


How to read this guide ​

Read What Locus is and How a page is chosen once. Then use the route map to jump to a page. For platform operators, read Platform ops (locus-ops) and regulatory-data.md. Terms are explained on the first page that uses them. The glossary repeats each term in one sentence so you can look it up later.

Ideas that will save you time:

  1. Almost every analysis page is about one open deal (a financing mandate). The deal is carried in the URL as ?project=. Fresh tenants have no open deal until they create one.
  2. No prefilled product data. CEMAC reference dossiers (SEEG, PAPN, Eneo, SNPC) exist only under tests/fixtures/cemac for unit/regression tests — never injected into a registered organization’s workspace. Chapters that still walk through SEEG figures are test-reference walkthroughs, not the empty-tenant product path.
  3. Persistence is a Postgres system of record (locus-backend) with a Next.js BFF under /api/locus/*. Deal lists hydrate from the API on SSR (TanStack Query on the client). Tenant document binaries live in Cloudflare R2 (AES-256-GCM at rest when DOCUMENT_ENCRYPTION_KEY_HEX is set). Platform statutes live in the legal vault (R2 or local LEGAL_VAULT_STORAGE_PATH) — see regulatory-data.md.
  4. Bank sign-in is institutional email/password plus a mandatory OTP on every login (and after register). Cookie: HMAC-signed locus_session (SESSION_SIGNING_KEY). There is no OIDC/SAML and no demo login bypass.
  5. Platform ops is a separate app (locus-ops, typically :3001, cookie locus_ops_session). It is not under /workspace. Legacy /workspace/regulatory-admin and /workspace/access-requests redirect via NEXT_PUBLIC_OPS_APP_URL.
  6. SoR writers (slice 29+). Upload → OCR → SYSCOHADA cells/ratios; analysis → contradictions, blockers, alerts; market ingest, portfolio CRUD, Q&A, precedents. R4: cells and contradiction alerts ground on real Citation rows; UI never invents bounding boxes. R5/R7: vault resolve + Watchtower + review publish. Analysis never falls back to a SEEG disk benchmark.

Related docs:

DocTopic
regulatory-data.mddata/regulatory/fixtures PDFs, vault vs catalog corpus
ocr-override-sop.mdWhen analysts must override OCR cells
copilot-analysis.mdCopilot architecture
../IMPLEMENTATION_TRACKER.mdAuthoritative checklist (slices 1–34)
../locus-ops/README.mdOps app runbook

For a product-level French overview see PRESENTATION.md. For architecture see TECHNICAL_PRESENTATION.md. For investor language see PITCH.md.


What Locus is ​

Locus is a workspace for people who arrange, lend, invest in, or legally review debt in the CEMAC zone.

CEMAC is the Economic and Monetary Community of Central Africa: Cameroon, the Central African Republic, Congo, Gabon, Equatorial Guinea, and Chad. They share a currency, the CFA franc, shown in the product as FCFA or XAF. In this app the euro conversion uses a fixed parity of 1 € = 655.957 XAF. That parity is a real feature of the currency peg, and the product hardcodes it (for example when you create a dossier, and as the badge Parité fixe BEAC 655,957 on the regulatory page).

The people who use the product, in plain language:

Role in the appTitle shownWhat they are trying to decide
investment_bankerInvestment Banker / Origination & DCM (Banquier d’Affaires)Should we structure this financing and take it to a credit committee? Lands on Deals.
credit_analystCredit Analyst (Analyste Risques)Can this borrower repay, and are the contractual ratios still safe? Lands on Financials.
compliance_officerCompliance Officer (Conformité & Juridique)Is the file legally ready for the market regulator? Lands on Regulatory.
research_analystResearch Analyst (Analyste Recherche)What are rates and issuers doing in the region? Lands on Market Radar.
portfolio_managerPortfolio Manager (Gérant de Portefeuille)Which bonds should the fund hold, and how do they move if rates move? Lands on Portfolio.
administratorAdministrateurFull access. Lands on Overview.

DCM means Debt Capital Markets: the team that helps a company or a government borrow by issuing bonds or arranging a loan. An arranger (in the product, often L'Archer Securities) is the bank that organizes that process. A syndicate is the group of banks that share the loan. A mandate (mandat) is the formal instruction from the borrower to that arranger: “raise this money for us.”

The product is organized as editions. An edition is a preset of modules and a home question for one kind of institution. You pick it in the organization modal. The seven primary editions:

EditionInstitutionThe question the home screen asksNorth-star measure
Securities IntelligenceBroker-dealer / bond arranger (BVMAC)Should we structure, price, or participate in this transaction?Time from mandate to an approved memo
Credit IntelligenceCommercial bank credit committeeShould we lend to or keep financing this borrower?How early we see a covenant breach coming
Asset ManagementFund, insurer, bond portfolioWhat should we own, at what risk and price?Time from a market event to a portfolio-impact view
DFI & Project FinanceDevelopment bank (BDEAC, AfDB, IFC, …)Should we finance this project, sponsor, or country?Time from pipeline entry to an investment-committee dossier
Sovereign DebtTreasury / debt officeHow should we fund and manage sovereign debt?How far ahead refinancing risk is visible
Legal & RegulatoryLaw firm or regulatory auditorIs this transaction legally and regulatorily ready?Issues caught before the regulator raises them
Enterprise Financial GroupBank group with several businessesGive each business unit its own workspace on one platformCross-unit exposure, without leaking confidential deals

BVMAC is the regional stock exchange (Central African securities exchange). BEAC is the regional central bank. COSUMAF is the regional capital-markets regulator (the body that authorizes a public bond offering). COBAC supervises banks. OHADA is the shared business-law system; its uniform acts cover companies, accounting (SYSCOHADA), and collateral (sûretés).


How a page is chosen ​

/workspace immediately redirects to /workspace/overview.

Every other screen is one URL:

text
/workspace/{section}?project={dealId}

Legal section ids live in locus-web/src/components/workbench/workspace-routes.ts. An unknown section is a Next.js 404. The page component is chosen by a switch in locus-web/src/components/workbench/WorkspaceSection.tsx. The layout wraps every page in WorkbenchView, which draws the sidebar, the top bar, and the copilot.

The open deal ​

There is no separate “current project” setting in storage. The open deal is React state plus the project query.

Seed deals in locus-web/src/engine/projects_data.ts:

IdBorrowerStatus shownMeaning
deal_seeg_refinancing_2026SEEG (Gabon water and power utility)Dossier actif (ACTIVE)The richest demo. Almost every analysis screen is written around this file.
deal_papn_expansion_2026PAPN (port of Pointe-Noire)En structuration (STRUCTURING)Default when the URL has no matching id (DEFAULT_PROJECT_ID).
deal_eneo_restructuring_2026Eneo (Cameroon power)En comité de crédit (COMMITTEE_REVIEW)In front of the credit committee.
deal_snpc_prefinancing_2026SNPC (Congo national oil company)En structurationEarly structuring.

If ?project= is set and no loaded deal matches it (case-insensitive), you see the blocked-mandate screen instead of the page:

  • Heading: Mandat Introuvable ou Non Autorisé (“Mandate not found or not authorized”).
  • Body: the dossier is outside the institution’s approved perimeter, or it is behind a strict Chinese wall.
  • Button: Revenir au dossier benchmark SEEG.

A Chinese wall (mur d’information) is an internal barrier so that one team (for example, the bankers arranging a deal) cannot show confidential information to another team (for example, the fund that might buy the bond). The Enterprise edition is the only preset that flags informationBarriersRequired.

The button calls selectProject('seeg'). The seed id is deal_seeg_refinancing_2026, not seeg, so that button does not select the SEEG deal. To open SEEG, use ?project=deal_seeg_refinancing_2026 or pick it from Deals or search.

Selecting a deal updates the URL with router.replace and keeps the current section. On load, deals come from SSR (getDeals → C# /api/deals) and refresh via TanStack Query. When the API payload omits financials, contradictions, or memo, the mapper merges the matching seed deal so analysis screens stay usable. Creating a deal should hit the SoR create endpoint; any remaining local cache is a fallback only.

Route map ​

The sidebar (OrganizedSidebar.tsx) groups routes into four zones. A fifth zone, INTELLIGENCE, is the copilot and the alerts drawer, which are overlays rather than routes.

text
WORK
  Overview                          /workspace/overview
  Deals & Pipeline                  /workspace/deals
    Nouveau dossier                 /workspace/new-dossier
    Data Room & VDR                 /workspace/deal-room
    Exhaustivité                    /workspace/dataroom-completeness
    Q&A Syndiqué                    /workspace/deal-qa
    Graphe Transaction              /workspace/deal-graph
    Agent Diligence                 /workspace/diligence-runner
  Issuers                           /workspace/issuers
  Instruments                       /workspace/instruments
  Portfolio                         /workspace/portfolio

ANALYSIS
  Sovereign Curves                  /workspace/sovereign-curves
                                    /workspace/fixed-income-terminal   (same screen)
  Financials                        /workspace/financial-tables
    Ratios                          /workspace/ratio-cockpit
  Debt & Covenants                  /workspace/credit-lab
    Review Grids                    /workspace/review-grids
  Risk                              /workspace/risk-register
    Contradictions                  /workspace/contradiction-radar
  Regulatory                        /workspace/regulatory
    Visa COSUMAF                    /workspace/cosumaf-auditor

MONITORING
  Market Radar                      /workspace/market-radar
  Auctions & Calendars              /workspace/sovereign-curves        (same screen as curves)

KNOWLEDGE
  Research                          /workspace/research                (same view as radar, different header)
  Institutional Memory              /workspace/institutional-memory
  Reports & Memos                   /workspace/memo-drafter

ADMIN (visible to institution admins)
  Membres & droits                  /workspace/org-members

Also a route, opened from the account menu:
  Profile                           /workspace/profile

Server-side exports (PDF / Excel) ​

Institutional downloads are generated by the C# API (POST /api/exports/*), proxied by Next at /api/locus/exports/*. The browser never builds committee PDFs with window.print().

ScreenButtonArtifact
MémoImprimer / PDFBranded diligence PDF (Locus logo)
SYSCOHADAExcelMulti-year financial workbook
RatiosExcel / PDFRatio table + one-page summary
ContradictionsPDFDual-citation findings
Risk registerPDFRisks & CPs
COSUMAF attestationExporter PDFPre-visa certificate

Each export is audited (MEMO_EXPORT, SYSCOHADA_EXPORT, …) with file name and SHA-256.

sovereign-curves and fixed-income-terminal render FixedIncomeTerminalView. market-radar and research render MarketIntelligenceView. Research only changes the header. Both open on the morning brief.


Shared shell ​

The shell is everything that stays on screen while you change pages: sidebar, top bar, search, alerts, copilot, account menu, and the organization modal.

Zone labels from NAVIGATION_ZONES, plus an ADMIN block for institution admins:

  • WORK — what you are actively working: pipeline, dossiers, mandates, portfolio.
  • ANALYSIS — engines applied to that work: curves, financial statements, covenants, stress lab, rules.
  • MONITORING — early signals, auction calendars, maturities.
  • KNOWLEDGE — comparables, research, precedents, memos.
  • ADMIN — Membres & droits (/workspace/org-members): invite members, assign institutional roles, view the derived module matrix, set sparse overrides, read the membership audit log. Access is gated to institution admins (and the local administrator profile role).

Badges on the sidebar are computed from the open deal:

  • Exhaustivité shows the count of fatal blockers (missing documents that stop a closing).
  • Risk shows the count of risks whose severity is CRITICAL or HIGH.
  • Contradictions shows contradiction_alerts.length.

The footer shows CEMAC ISO 9001:2015, a link Portail to /landing, and Packs (n), which opens the organization modal. ISO 9001 is a quality-management standard. Here it is a label for the audit trail the product claims to keep, not a certification check the code performs.

Clicking the organization name opens Profil Institutionnel & Éditions Métier.

Organization modal ​

Three tabs:

  1. Choix de l’Édition — pick a business preset. The card shows the edition name, tagline, the core question, the north-star KPI, how many modules are recommended, and the intelligence packs. Choosing an edition replaces the module checklist with that preset’s recommended modules. It is not saved until you press Appliquer la configuration.
  2. Modules & Packs Actifs — toggle the 13 analysis modules and a filter Filtre Édition Actif / Afficher Tous les Modules. The filter is stored as filterByEdition. The note on this tab says the shared engine still runs accounting identities and major legal risks even if a module is hidden.
  3. Institution & Juridiction — organization name and primary CEMAC country (CG, GA, CM, TD, CF, GQ). The country chooses the default national tax code in the regulatory story (CGI Congo or CGI Gabon) and the treasury the desk treats as home. Badges for OHADA, BEAC, COSUMAF, and COBAC are display-only.

Organization profile is loaded from the SoR on workspace SSR (getOrganizationProfile). If the SoR is unreachable, the UI shows an empty institution shell — never a branded demo firm. Edition, modules, and jurisdiction come from the authenticated organization record.

Roles are not editable in this modal. The signed-in role comes from the stored profile (administrator by default).

Top bar ​

ControlWhat it doesWhere the data comes from
Skip link Aller à l'espace d'analyseJumps to the page body—
Search Rechercher émetteurs, deals, documents, obligations... and ⌘KOpens global searchA fixed list of 22 rows, not the live deals
Status badgeShows status_label of the open dealThe deal. Tone: active = success, structuring = info, committee = warning
CompteAccount menuOrganization profile
Lancer l’analysePOST /api/pipeline. While running, the label is Calcul…Drawer title: deterministic Python pipeline (Nelson-Siegel and SYSCOHADA). Badges: En cours…, Succès, Erreur
CopilotOpens the copilot sheetThe open deal
Alerts bellOpens the alerts centerThe red dot is computed (fatal blockers or any contradiction). The six cards inside are a fixed list
Afficher les sources / Masquer les sourcesToggles the PDF viewer for the selected deal documentThe open deal’s data room, on deal-workspace sections

Deal-workspace sections (the ones that show the status badge and the sources toggle) are: data room, completeness, Q&A, financials, ratios, credit lab, review grids, contradictions, regulatory, deal graph, diligence runner, risk register, and memo.

Search hits come from tenant-scoped Postgres SearchDocuments via /api/locus/search (french tsvector/GIN), plus the institution’s authorized deal list. A fresh organization with no dossiers and no indexed documents sees an empty result set — there is no static CEMAC catalog in the product path.

Pills: Tout, Émetteurs, Deals, Instruments, Documents, Réglementation, Recherche, Mémoire.

Clicking a deal row navigates with the SoR deal_* id. Legacy aliases (e.g. proj_*) still resolve on the BFF for bookmarks, but new work should use canonical ids.

Alerts center ​

Title: Centre d’Alertes & Risques Institutionnels. Alerts load from SoR GET /api/locus/alerts. A fresh tenant has zero alerts until analysis/OCR writers emit them — the API never auto-seeds demo cards.

After dossier OCR + analysis, SoR writers create AlertItems from: open contradictions (CRITICAL/MAJOR), covenant breaches on RatioSnapshots, and fatal open Blockers. Severity badges: DIRIMANT, ATTENTION, MARCHÉ (when market ingest has written rows).

Lifecycle actions (assign / acknowledge / archive) remain on the same BFF routes and audit chain.

You will meet these alerts again as the running example. The short version, in developer language:

  • DSCR (debt service coverage ratio) asks “does cash available this year cover the loan payments due this year?” Below 1.0x means the cash does not cover the payments. A contract often requires something like 1.20x, meaning 20% spare cash.
  • A basis point (bp) is 0.01 percentage point. 45 bp is 0.45%. 100 bp is 1%.
  • A term sheet is the short commercial summary of a loan (amount, margin, maturity, covenants). The loan agreement is the long contract. If they disagree, somebody has to say which one wins before the committee.
  • A concession is a state contract that lets a company run a public service (here, water and electricity) until a date. If the bond is still outstanding after the concession ends, the company may no longer own the assets that were supposed to repay the bond.
  • Article 42 of the BEAC foreign-exchange regulation requires a cross-border loan to be declared to the central bank.

Copilot (Assistant d’analyse) ​

Opened from the navbar (no floating FAB). Sheet title Instruction (eyebrow Assistant d'analyse · Préparatoire). Every reply is framed as preparatory analysis, not a regulator’s decision, and carries a COSUMAF / legal disclaimer.

Architecture and Layers:

  1. Agentic Tool Orchestrator & Registry (copilot/agent.ts, copilot/tools/registry.ts, financials.ts) — agentic dispatcher with 16 certified deterministic tools:
    • Credit & Financials: get_syscohada_ratios (Net Debt, EBE, DSCR, ICR, cash), simulate_credit_stress (EBE shocks -10%, -20%, -30% with scenario comparison card), audit_covenants (contract ceilings and headroom). Fail closed if periods are missing (no invented constants).
    • BlackRock Aladdin Fixed Income & Relative Value: price_fixed_income_instrument (clean/dirty price, duration, convexity, DV01 sensitivity under +50 bp shock), compare_bond_to_curve (corporate yield vs Nelson-Siegel sovereign curve to compute sovereign credit spread in bps).
    • BlackRock Aladdin Portfolio Intelligence: get_portfolio_exposure (market value in XAF, book duration, DV01, top issuers), run_portfolio_stress (+50, +100, +150 bps parallel shifts with P&L and DV01 loss approximation), explain_portfolio_duration (OTA vs BTA factor decomposition), list_portfolio_exceptions (open limit breaches).
    • Diligence & Regulatory: audit_contradictions_radar (dual-citations), explain_concession_maturity_trap (2028 Concession vs 2031 Debt 35-month gap), get_risk_register, audit_dataroom_completeness (fatal blockers like Quitus Fiscal DGI and BEAC Art. 42 declaration), check_regulatory_compliance (OHADA AUS Art. 140 escrow pledge, BEAC R-2018/02, COSUMAF visa), compile_credit_memo, and investigate_360.
  2. Multi-Turn Conversation Memory (copilot/agent.ts, IntelligenceCopilot.tsx) — passes prior conversation history (history: CopilotMessage[]) on every call. Resolves contextual follow-ups ("Et si l'EBITDA baisse de 15% ?", "Quelle est la marge sur ce covenant ?") seamlessly.
  3. Retrieval (copilot/async.ts, retrieval.ts) — for ask / investigate / review / draft, calls GET /api/locus/search (Postgres SearchDocuments, including OCR pages) and merges spatial citations with bounding boxes. GET /api/locus/blockers enriches missing-piece answers.
  4. Optional LLM prose (copilot/llm.ts) — only for draft / investigate, only if COPILOT_LLM_PROVIDER is openai or anthropic. Default off. The model may rephrase French; it must not invent numbers.

Workbench passes organizationId on every call for tenant checks.

Scope (Périmètre d'analyse): current page (prefer active doc), whole dossier (default), whole data room, or CEMAC corpus (blocks deal financial calculations).

Mode strip: Question, Calcul, Investigation, Revue, Rédaction. Keywords can overwrite the selected mode.

CommandIntent
/calculateFormal ratios from live periods or fixed income bond pricing
/investigate360° synthesis (ratios + alerts + risks + dataroom)
/compareStructured contradiction_alerts or sovereign curve spread analysis
/stresstestShock EBE / leverage on live periods or portfolio yield shock
/reviewCovenant / clause review mode
/risksTop risks from the risk register
/draftMemo sections from project.memo (+ optional LLM polish)
/portfolioBook exposure, rate stress, exceptions, duration explainer
/blockersCompleteness + Postgres blockers

Evidence marks: Vérifié, Calculé, À examiner, Preuve insuffisante. Live Moteurs : badges display certified algorithms executed (e.g. [✓ LEVIER DETTE NETTE / EBE · 2.52x]). Blocks order Source → Calcul → Interprétation, then citations, actions, follow-ups. A scenario card shows metric, cap, audited base, after-shock value, and residual headroom.

explain() from a ratio, risk, or contradiction opens this sheet and sends that string as the user message. Empty-state suggestions depend on the active tab (portfolio, instruments, sovereign-curves, etc.).

Account menu ​

Profil goes to /workspace/profile. Déconnexion posts action=logout to /api/auth (revokes SoR AuthSessions and clears the signed cookie) and returns to /. The name and role shown come from the authenticated institutional session.

Pipeline button ​

Lancer l’analyse posts to /api/pipeline and names the open borrower in the log. The drawer is titled as a deterministic Python run of the Nelson-Siegel curve fit and the SYSCOHADA statements. Treat it as a job launcher attached to the shell, not as a page.


WORK ​

WORK is the desk: the deal you are on, the documents in it, and the issuers and bonds around it.

Overview ​

Route/workspace/overview
SidebarOverview
Default forAdministrator. Securities edition also treats this as a morning desk.

Purpose. A morning snapshot of the edition you selected: a few market or portfolio numbers, a short list of decisions, a news-style feed, and the deals or facilities you should open next.

What it does. The heading is always Vue d’ensemble. The detail line is Lecture du mandat en cours : marchés, points d’attention, pipeline et échéances. The eyebrow includes the edition name and a fixed session stamp, Lundi 05 octobre 2026 · 08:30 GMT+1.

Two buttons:

  • Synthèse du matin opens the copilot with that edition’s morning prompt (for securities: the three critical points that need attention this morning).
  • A primary action that depends on the edition (Nouveau dossier, Analyse financière, Instruments, Courbes souveraines, Revue réglementaire, Exposition agrégée, …).

The body is four blocks. Metric tiles and decision rows navigate to another section. The work list, for the securities and treasury editions, is the live project list (borrower, deal_code, country, status, and an amount in billions of FCFA). Clicking a live row selects that project and opens the data room. Other editions use hardcoded work items. The side list (auctions, watchlist, coverage) is not clickable.

The edition copy is selected by overviewForEdition. Unknown editions fall through to the securities desk (Bourse & DCM).

Edition labelQuestion on the pagePrimary button
Bourse & DCMShould we structure, price, or join this transaction?New dossier
Banque & RisquesWho is becoming risky, and how early, before a covenant breaks?Financials
Gestion d’actifsWhat should we hold, at what risk and price?Portfolio
Développement & PPPShould we finance this project, sponsor, or country?New dossier
Dette souveraineHow do we fund the debt, and how far out is refinancing risk visible?Sovereign curves
Juridique & règlesIs this deal legally and regulatorily ready?Regulatory
Groupe financierWhat is group exposure, within what each wall allows?Risk register
TrésorerieWhich maturities and which covenant headroom are still manageable?Financials

Data. Edition metrics, decisions, feed, and side lists are sample strings. They are not computed from financial_periods. When useProjects is true, only the work-list rows come from the deal array. Example securities tiles: CEMAC sovereign rates 6,45 %, Gabon spread +145 bp, BVMAC volume 14,2 Mds, treasury auctions 142,5 Mds. Example credit tile: SEEG DSCR headroom −12 bp with 1,08x observed against a 1,20x floor, linking to the credit lab.

Terms on this page.

  • Spread. The extra yield you demand above a reference rate. +145 bp on “Gabon versus the BEAC reference” means Gabon’s bonds yield 1.45 percentage points more than the reference, because lenders see more risk.
  • BTA / OTA. Treasury bills and treasury bonds issued through BEAC auctions. BTA are short (weeks). OTA are longer (years). Companies and funds buy them; the state uses them to fund itself.
  • Encours. Amount still outstanding (not yet repaid).
  • Créances douteuses. Loans the bank already doubts will be repaid in full. A rising share is an early warning.
  • Watchlist. Borrowers under closer monitoring, short of a formal default.
  • AUM / actifs sous gestion. Market value of the portfolios the firm manages.
  • YTD. Year to date.
  • Duration (modified). How many years of interest-rate sensitivity a bond portfolio has. A modified duration of 4.6 means a 1% rise in yields cuts the price by about 4.6%. The instruments page and the curve terminal compute this properly; the overview only prints a sample.
  • Yield. The annual return implied by the price, if you hold to maturity. Higher yield means the bond is cheaper, or the market thinks it is riskier.
  • Pipeline. The list of deals being worked, from first conversation to committee.
  • CI. Investment committee (comité d’investissement), the meeting that approves a development-bank financing.
  • Visa. The COSUMAF authorization to offer a bond to the public. Without it, a public offering does not proceed.
  • Quitus. A tax-clearance certificate. The product treats a missing Gabon DGI quitus as a hard stop.
  • DSRA. Debt service reserve account: cash locked aside to pay the next few months of debt if operating cash falls short.
  • Nantissement. A pledge. A compte séquestre is an escrow account. Pledging that account can collide with a promise not to pledge anything (negative pledge).
  • Livre d’ordres. The order book: the list of investors who have said they will buy the bond, and in what size.
  • Prêt-relais. A bridge loan: short-term money that is supposed to be replaced (taken out) by a later bond.
  • Mur d’information. The Chinese wall described above. The enterprise overview says aggregated figures stay visible and a confidential markets mandate does not appear in the asset-management view.

Business value. This is the only page that changes its question with the edition. A DCM banker sees “do we take this mandate?”. A credit officer sees “who is about to break a covenant?”. It is a router into the rest of the workspace, not the place where a number is proven.

Use case. You open the app on Monday as an arranger. The securities overview shows a DSCR problem on SEEG and a 45 bp rate gap. You click the live SEEG row, land in the data room, and start the file. Or you press Synthèse du matin and let the copilot list the three points before you pick a page.

Next. Deals, the data room, sovereign curves, or whatever tile you clicked.

Deals and pipeline ​

Route/workspace/deals
SidebarDeals & Pipeline
Default forInvestment banker

Purpose. The list of financing mandates the desk is responsible for. You filter it, sort it, and open one dossier.

What it does. Eyebrow L'Archer Securities · Direction des Engagements & Syndication. Title Portefeuille des Mandats de Financement. The detail line says you select a dossier to open the analysis workshop, audit SYSCOHADA documents, and check covenants.

Actions:

  • Nouveau dossier opens the new-dossier wizard.
  • Four shortcut chips jump to the curve terminal, the morning brief, the COSUMAF auditor, and institutional memory. Their labels still say POC and Layer 5; those are product nicknames, not separate apps.
  • Search matches deal name, borrower, deal code, country, and sector.
  • Status pills: Tous, Actifs (ACTIVE), Structuration (STRUCTURING), Comité (COMMITTEE_REVIEW). There is no pill for CLOSED, even though the status enum includes it.
  • Filters for country and sector, built from the deals you have.
  • Sort by amount (euros, descending), number of contradiction alerts, or updated_at.

Each card shows country, sector, status label, deal code, deal type, borrower, name, envelope in millions of euros, CEMAC equivalent in billions of FCFA, a summary, document count, a hardcoded SYSCOHADA 100 %, the contradiction count (Écarts / Risques or Conforme), and the review date. Continuer le travail / Travailler sur ce dossier selects that project. The parent then keeps you on the current route with the new ?project=.

Data. The four KPI tiles are computed from the projects array:

  • Mandates under management = projects.length, with a split of active versus structuring.
  • Target book = sum of total_amount_eur, shown in millions of euros, plus the FCFA sum in billions.
  • Documents audited = sum of data-room document counts.
  • Attention points = sum of contradiction alerts.

The SYSCOHADA 100 % badge on every card is not computed.

Terms.

  • Mandat de financement. The engagement to raise or refinance a stated amount.
  • Enveloppe. The target size of that financing.
  • Syndication. Sharing a loan across several banks so no single balance sheet holds all of it.
  • Comité de crédit. The internal meeting that approves or refuses the bank’s participation.
  • Écart / contradiction. Two documents in the same file disagree (rate, date, definition of profit, collateral).
  • SYSCOHADA. The OHADA accounting framework used by companies in this zone. “100%” on the card means the demo marks the accounts as present, not that a validator scored them.

Business value. This is the pipeline a head of origination manages: how many live mandates, how much money they represent, and which files already contain contradictions. It is the index. The judgment happens on the later pages.

Use case. Filter to Gabon, sort by number of risk alerts, and open SEEG because it has the contradiction count. Or press Nouveau dossier for a borrower that is not in the seed.

Next. New dossier, or the data room of the deal you selected.

New dossier ​

Route/workspace/new-dossier
SidebarNouveau dossier (under Deals)

Purpose. A four-step form that creates a financing mandate and, by default, drops you into its data room.

What it does. Steps, clickable only backwards: Mandat, Juridiction, Transaction, Montant.

  1. Mandate. Operation name, borrower, sector. Sectors are a fixed list (energy and water, ports, oil and gas, telecoms, industry, mining, transport, sovereign and local authorities).
  2. Jurisdiction. Primary country, default Congo (CG). Optional extra countries. Checking an extra country marks the file as cross-border. Checkbox Entité liée à l’État (state-linked entity), which later turns on concession and public-sector checks.
  3. Transaction. One nature, default Financement corporate. Currency of the profile: XAF, EUR, or USD. Checkbox Appel public à l’épargne (a public offering, which later requires a COSUMAF visa).
  4. Amount. Target in euros, default 45,000,000, minimum 500,000. The helper shows the FCFA equivalent at 655.957. Optional preliminary note. Checkbox Ouvrir le dossier dans l’atelier dès la création (default on).

Créer le dossier builds a project with status En structuration, risk MEDIUM, arranger L'Archer Securities (COSUMAF-SDB-01/2021), deal code DEAL-{4 letters}-2026-XAF, a single term-sheet document titled as a teaser, one synthetic 2023 SYSCOHADA period scaled from the amount (revenue = amount × 3.5, EBITDA = amount × 0.9, and similar), and a two-section memo. The chosen XAF/EUR/USD is stored on the jurisdiction profile. The project’s display currency field is always FCFA / EUR.

Terms.

  • Financement corporate. A loan or bond of an operating company, repaid from the whole company’s cash, not from one project.
  • Financement de projet. Debt repaid from one project’s or concession’s cash flows. Lenders care more about that project’s contracts than about the sponsor’s other businesses.
  • Souverain / sous-souverain. The borrower is the state, or a city, region, or public agency.
  • Émission obligataire. A bond issue. If it is a public offering on BVMAC, COSUMAF rules apply.
  • Refinancement. New debt whose job is to repay old debt.
  • Restructuration. Changing the terms of debt that is already in trouble (longer dates, a standstill, a waiver). A waiver is a formal agreement to forgive a breach for a period.
  • Financement d’acquisition / LBO. Debt used to buy a company. LBO means leveraged buyout: the purchased company’s cash is supposed to repay the debt.
  • Appel public à l’épargne. Offering securities to the public, as opposed to a private placement with a few professional investors. Public offerings need a prospectus and a visa.
  • Teaser / mémorandum d’information. The first short document sent to potential lenders. It is not the binding contract.

Business value. Origination starts here. The wizard forces the questions that later pages branch on: country, public offering or not, state-linked or not, project finance or corporate. Those flags change which regulatory findings appear.

Use case. A banker has a new Gabon telecom borrower. They enter the name, pick Gabon plus Congo (cross-border), choose Émission obligataire, tick the public-offering box, set 45 million euros, and create. The data room contains only the teaser. Completeness will then show almost everything as missing, which is the honest state of a new file.

Next. Data room if the checkbox stayed on, otherwise Deals.

Data room and VDR ​

Route/workspace/deal-room
SidebarData Room & VDR

Purpose. The index of evidence for the open deal: which files exist, how many pages they have, and a short fingerprint so you can see that a file was registered.

What it does. Title Pièces de la transaction. Detail: central index of evidential documents, extractions, and control fingerprints.

  • Importer une pièce posts multipart/form-data to POST /api/locus/documents/upload with the open dossierId.
  • Server path: SHA-256 → Cloudflare R2 PutObject (private key tenants/{org}/dossiers/{dossier}/…) → C# POST /api/documents → OCR / text extract (ocr-ingest.ts) → POST /api/documents/{id}/ocr-result which writes ExtractedPages, Citations, and SearchDocuments rows and sets OcrStatus = COMPLETED.
  • Without R2_* env vars the API returns 503 R2_NOT_CONFIGURED. Health: GET /api/locus/storage/health.
  • After upload, a short-lived presigned GET (≤ 15 min) is returned for download. Duplicate SHA-256 on the same dossier → 409.
  • Metrics: document count and pages (from seed + uploaded meta). Seed rows still show class, page count, SHA-256 prefix, and key pages for the PDF viewer.

Document classes include FINANCIAL_STATEMENT, LOAN_AGREEMENT, TERM_SHEET, CONCESSION_AGREEMENT, REGULATORY_FILING, OTHER. OCR status: PENDING | PROCESSING | COMPLETED | FAILED.

Data. Seed documents on currentProject.deal_room.documents, plus live Postgres document rows after upload. Copilot retrieval can cite OCR pages via search.

Terms.

  • Data room / VDR. Controlled folder where lenders read confidential documents. This page is the index; Q&A holds the permissions / watermark story.
  • SHA-256. Cryptographic content identity; used for dedup and vault keys.
  • R2. Cloudflare’s S3-compatible object store — the private binary vault. Postgres holds metadata and searchable text, not the PDF bytes.
  • Pièce probante. A document the committee may rely on, as opposed to an unsupported sentence in a slide.

Business value. Credit and legal work is only as good as the file. Upload now lands in a real vault and becomes searchable evidence for the copilot, not a UI-only filename.

Use case. On SEEG, open the seeded financial report, loan, term sheet, and concession. Upload a new PDF (with R2 configured), confirm OCR completed, then ask the copilot a free-form question that should pull a dataroom excerpt.

Next. Completeness, to see what is still missing. Q&A, when a lender asks a question about one of these files.

Data-room completeness ​

Route/workspace/dataroom-completeness
SidebarExhaustivité

Purpose. A closing checklist: which documents a CEMAC bond or loan file is expected to contain, which of them are in this data room, and which gaps are fatal.

What it does. Title Audit d’Exhaustivité de la Data-Room & Pièces Manquantes. The detail text names the transaction as a bridge refinancing and a BVMAC bond, and talks about fatal blockers. That sentence is fixed copy, even if the open deal is PAPN.

A verdict badge is computed:

  • COMMITTEE_READY → Dossier Prêt pour Comité when every fatal item is satisfied, no condition precedent is still open, and the score is at least 75.
  • CONDITIONAL_GAPS → Comité Sous Réserve (CPs) when fatals are clear but a CP is open or the score is under 75.
  • otherwise Bloqué : Pièces Dirimantes Manquantes.

The score is satisfied / total, rounded. Four tiles: global score, fatal blockers, conditions precedent, and indexed pieces. Category chips filter the list (Gouvernance & Statuts, Comptabilité & Commissariat, Fiscalité & Sécurité Sociale, Concession & Régulation, Sûretés & Garanties, Contrats Clés & BEAC). Status tabs: Tous, Bloquants, Manquants, Déficients, Conformes.

Each requirement shows an id, title, description, severity, category, a legal citation, an optional source file, an audit finding, and a recommended action. Voir Pièce opens the PDF. Générer Requête opens a letter modal addressed to the borrower’s management and counsel, with a subject line that includes the deal code. Copier le texte copies it. Enregistrer & Notifier only fires a browser alert; it does not send email.

Severity labels: Bloquant Dirimant (fatal), Condition Préalable (CP), Post-Closing. Statuses used by the engine: SATISFIED, DEFICIENT, MISSING, EXPIRED. There is no tab for expired.

Data. The checklist template lives in dataroom_completeness/engine.ts and scores against the open deal’s data-room documents. Server-side, analysis also upserts SoR Blockers for core classes (SYSCOHADA FS, loan agreement, term sheet, legal opinion, concession) and clears them when a matching document is attached. A brand-new dossier with no uploads scores empty / all open; there is no permanent SEEG-shaped forced finding set in the product path.

The 20 items, in the order a closing lawyer would recognize:

IdWhat it asks forWhy it exists
REQ-CORP-01OHADA-harmonized bylawsA company that issues or borrows must be validly incorporated.
REQ-CORP-02Shareholder minutes approving last year’s accountsLenders rely on accounts the shareholders have adopted.
REQ-CORP-03Board resolution authorizing the borrowingWithout it, the loan can be challenged as unauthorized.
REQ-CORP-04Recent commercial-register extract and a no-bankruptcy certificateProves the company exists and is not in insolvency.
REQ-CORP-05Legal opinion from independent local counselThe syndicate’s standard comfort that the contracts are binding.
REQ-FIN-01Certified SYSCOHADA statements, 2021–2023The numbers behind every ratio.
REQ-FIN-02Statutory auditor reports without qualificationA reserve (qualification) means the auditor refused to sign the accounts cleanly.
REQ-FIN-03Operating model and 24-month cash planBank-supervision practice (COBAC) wants a forward view, not only history.
REQ-TAX-01Tax clearance from the DGI, under 3 monthsCOSUMAF practice in this product: no clearance, no file. Always missing in the template.
REQ-TAX-02Social-security clearance (CNSS), under 90 daysUnpaid payroll taxes become a senior claim.
REQ-TAX-03List of ongoing tax disputesPost-closing item. Hidden tax claims change the credit.
REQ-CONC-01Concession aligned with the debt maturityForced deficient when a concession file exists.
REQ-CONC-02Ministry approval to grant securityYou often cannot pledge public-service assets without the state.
REQ-CONC-03Current tariff decreeRevenue depends on a regulated price.
REQ-SEC-01Escrow / DSRA agreement under the OHADA collateral actForced deficient via the Note 14 pledge.
REQ-SEC-02Proof the pledges were registered at the RCCMAn unregistered pledge can lose to another creditor.
REQ-SEC-03Valuation of the pledged assetsCOBAC wants collateral you can measure.
REQ-COMM-01The 53.4 million euro bridge agreementThe contract being refinanced.
REQ-COMM-02Syndication term sheet / issue termsThe commercial deal, and a COSUMAF document.
REQ-COMM-04BEAC foreign-loan declarationAlways missing in the template.

Terms.

  • Fatal blocker / dirimant. A gap that stops the credit committee or the closing. Not a “nice to have.”
  • Condition préalable (CP, condition precedent). Something that must happen before the first drawdown (money actually paid out), even if the committee has said yes. Example: a notary registration.
  • Post-closing undertaking. A promise to deliver something after signing. Weaker than a CP, because the money may already be gone.
  • Closing. The day the contracts are signed and, usually, the money moves.
  • RCCM. The OHADA trade and personal-property register. Security interests are filed there.
  • CAC (commissaire aux comptes). The statutory auditor.
  • DGI. The national tax directorate.
  • Legal opinion. A lawyer’s letter saying the company validly approved the deal and the contracts are enforceable.
  • Greffe. The court clerk’s office where filings are stamped.

Business value. Committees slip dates because one certificate is missing. This page turns that into a score, a blocker count, and a draft chase letter. The business decision is “can we convene the committee, or do we wait?”

Use case. On SEEG, open Bloquants. You should see the tax quitus and the BEAC declaration. Generate the request letter, copy it, and send it outside the app. Then open the concession item and read why a document that exists is still DEFICIENT: the dates do not cover the bond.

Next. Q&A (to ask the borrower), the deal graph (to see how the concession date connects to the bond), or the risk register (the same facts as committee risks).

Syndicated Q&A ​

Route/workspace/deal-qa
SidebarQ&A Syndiqué

Purpose. The question channel between lenders, the arranger, lawyers, and the borrower. Answers are drafted, revised, approved, and then published to the whole syndicate, with an audit log.

What it does. Title Gestion des Questions-Réponses (Q&A) & Matrice des Droits VDR.

Permissions follow the signed-in role (qa:read / qa:submit / dealroom:upload). The UI loads and creates tickets from SoR via /api/locus/deals/{id}/qa (QaThreads). A fresh dossier shows an empty list until someone submits a question.

KPIs (counts, average response time) are computed from the loaded threads — or show — when empty.

Tabs: the question list and a form to ask a question.

Data. Postgres QaThreads only. No in-memory demo ticket pack in the product path.

Terms.

  • Chef de file / lead arranger. The bank in charge of the syndicate. They decide when an answer is official.
  • Pool. The lenders as a group. “Published to the pool” means every lender sees the same answer, so nobody has a private side letter.
  • Filigrane. A watermark with the reader’s name, so a leaked PDF can be traced.
  • EBE / EBITDA. Earnings before interest, tax, and depreciation. SYSCOHADA’s name is excédent brut d’exploitation (EBE). Lenders use it as a proxy for cash generation. A file that shows one EBE in the accounts and a higher “normalized EBITDA” in a slideshow is a classic fight; the Q&A exists so the official number is the audited one.
  • Euribor. A euro interbank rate. EURIBOR 3M + 7.20% means the borrower pays the 3-month Euribor plus 7.20 percentage points. The 7.20 is the margin. If the term sheet says 6.75 and the contract says 7.20, the annual interest bill is higher. The product prices that gap at about 240,000 euros a year on this facility.
  • Confidence percentage. A label on the draft (“how sure the extractor is”). It is stored on the seed ticket. It is not a probability the engine recomputes when you type a new question.

Business value. In a real syndication, unlogged answers create liability: one bank was told the margin is 6.75, another was told 7.20. A published Q&A with an audit trail is the single official record. The rights matrix is the product’s sketch of who may see accounts, who may ask, and who may approve.

Use case. Switch to the BGFI lender. You can read published answers and you cannot approve. Switch back to the lead arranger, open the margin question, and publish it so the pool sees one number. Then ask a new question about the concession and watch the similarity warning if your wording overlaps ticket 3.

Next. The deal graph, which draws the same four conflicts as a map. Or the memo, which is where the official answer should end up.

Deal knowledge graph ​

Route/workspace/deal-graph
SidebarGraphe Transaction

Purpose. A map of how the borrower, the contracts, the covenants, the collateral, the regulations, and the risks connect. You use it to see a failure path, not to read a table.

What it does. Title Graphe de Connaissances de la Transaction. A badge shows node and edge counts, which are computed. The center node’s sector and country come from the open project. The node glyph prefers a parenthetical code in the borrower name (for example PAPN); otherwise it builds initials from the label.

The canvas uses the design-system palette: sovereign navy background, brass borrower node, warning/critical/compliant fills for status, and ink-faint edges with critical dashed risk paths. Selection uses a brass ring, not a neon glow.

Risk-path buttons:

  • Vue d’Ensemble 360°
  • Piège de Déchéance Concessive (2028 vs 2031) — critical
  • Violation Negative Pledge (Séquestre Turbine Note 14) — critical
  • Distorsion Tarifaire (7.20% Contrat vs 6.75% Term Sheet) — major
  • Sanction Réglementaire BEAC (Emprunt Extérieur Art. 42) — critical

Choosing a path highlights its nodes. Réinitialiser la vue returns to the full map. A segmented filter shows type codes: FACILITY, DOCUMENT, COVENANT, COLLATERAL, REGULATION, RISK. A red status disc means BREACH. The inspector shows the node label, properties, and direct links. Consulter Pièce Source opens the PDF when the node has a document id.

Data. The graph generator reads the open project’s SoR-hydrated fields (financial_periods, contradiction_alerts, data-room documents). A fresh dossier with no OCR/analysis yields a minimal or empty graph — not a hardcoded SEEG facility map.

Terms.

  • Facility. One contract of debt (the bridge, or the bond), as opposed to the whole relationship.
  • Take-out. The later instrument that repays the bridge. Here, the 2031 bond is supposed to take out the 2025 bridge.
  • Déchéance. Losing the concession. If the state takes the assets back in 2028, the 2031 bondholders are left with a claim and without the network.
  • Negative pledge. A promise not to give collateral to anyone else. It protects unsecured lenders. Note 14 of the accounts says turbines are already pledged, which contradicts that promise.
  • Note 14. A numbered note in the financial statements. Notes are where the real collateral and commitments hide. The face of the balance sheet often does not say “this cash is locked.”
  • Assiette de sûreté. The pool of assets the pledge actually covers.
  • Gearing and headroom. Shown on the leverage node: 2.52x versus a 3.50x ceiling leaves 0.98x of room. Headroom is that spare room before a breach.

Business value. Tables list problems one by one. The graph is how a structuring team explains a chain: concession expiry causes a collateral problem, which causes a refinancing problem, which causes a BEAC filing problem. DFI and sovereign editions even default their landing lens toward this page because project and country risk is about links.

Use case. Select the concession path. Read the edge Expire 3 ans avant. Open the concession PDF from the node. Then select the negative-pledge path and open Note 14. You now have the two structural issues the committee memo will lead with.

Next. Diligence runner, to execute the checklist that mentions these same paths. Risk register, to assign an owner.

Diligence agent ​

Route/workspace/diligence-runner
SidebarAgent Diligence

Purpose. One button that runs a playbook: a fixed sequence of checks (documents, covenants, contradictions, regulation, completeness, risks, stress) and prints a log.

What it does. Title Agent Diligence Runner (Playbooks Institutionnels). Lancer la Diligence waits 600 ms and reruns runDiligencePipeline. Choosing another playbook reruns immediately.

Playbooks:

NameBadgeStated durationSteps
Audit exhaustif de transaction360° Diligence4.2 s7
Revue covenants et capacité de remboursementCovenant Focus2.1 s3
Scrutin réglementaire et risque concessifRéglementaire2.5 s3
Détection des divergences inter-documentsContradictions1.8 s3

The banner counts are partly computed: risk-register length, contradiction-alert length, review-grid covenants in BREACH, fatal completeness items, and checklist items with status MISSING. The timeline shows each step name, an engine id (DeterministicRatioEngine, CrossDocumentContradictionRAG, and others), a one-line output, and a random duration between 120 and 369 ms. Expanding a step shows log lines. A separate terminal titled Journal d’Émission Déterministe is hardcoded, including DSCR: 1.02x and the three fatal blockers. It does not echo the step logs.

Links at the bottom go to the risk register, completeness, the credit lab, and the graph.

Data. Steps report real SoR counts: documents, financial_periods, contradiction alerts, review-grid covenants (from ratio formulas on extracted periods), and completeness fatals. When the dossier has no indexed data, steps log that nothing was available — they do not invent SEEG terminal text.

Terms.

  • Playbook. A named procedure, like a runbook. The product’s point is that diligence is a sequence, not a chat.
  • Déterministe. Same inputs, same outputs. The UI uses this word to contrast with a model that might invent a number. The ratio engine is deterministic. Several log lines are still fixed strings.
  • Capacité de remboursement. Ability to repay from cash, which is what DSCR measures.
  • RAG. Retrieval-augmented generation: answer from retrieved documents. The engine id CrossDocumentContradictionRAG is a label on the step. The contradictions themselves are seeded alerts, not a live retrieval over PDFs.

Business value. A head of diligence uses this as a single “run the file” action before a committee date, then jumps to the page that owns each failure. The value is orchestration and a reproducible log, not a new analysis.

Use case. Run the 360° playbook on SEEG. Read the banner: blockers, a DSCR breach, contradictions. Open the covenant step, then follow Stress-Test Lab to see how much room is left.

Next. Issuers, if you want the company rather than the deal. Or the credit lab.

Issuers ​

Route/workspace/issuers
SidebarIssuers

Purpose. A 360° card on the company or the treasury that issues the debt: what it earns, what it owes, which instruments it has, and the risks attached to it.

What it does. The H1 is the issuer’s legal name. Mémo 360° opens the copilot with a credit-memo prompt. Ouvrir le dossier goes to the data room.

The issuer switcher has three cards: SEEG Gabon, Eneo Cameroun, Trésor Gabon. The open project only picks the initial card: a borrower name containing “eneo” selects Eneo, “seeg” selects SEEG, anything else (including PAPN and SNPC) also selects SEEG.

Tabs: Vue d’ensemble, États financiers, Dette et covenants, Instruments, Dossiers, Risques. Metric tiles switch the local tab. Links jump to financial tables, the credit lab, the risk register, deals, the data room, and the instruments blotter.

Data. The entire ISSUERS array is hardcoded. No formula reads financial_periods here. Figures a developer should recognize, because every other SEEG screen repeats them:

SEEGEneoTrésor Gabon
TypeState concessionaire, utilitiesPower operatorCEMAC sovereign
Revenue198.45 billion FCFA342.10 billion2,150 billion (tax receipts)
EBE34.85 billion, margin 17.6%68.40 billion, 20.0%Shown as not applicable
Net debt87.90 billion145.20 billion5,420 billion
Leverage2.52x (cap 3.50x)2.12x58.2% of GDP
DSCR1.08x1.34x2.40x
RatingB / Stable (Bloomfield)B+ / Stable (GCR)B- / Negative (S&P)
Concession30 June 202831 December 2031Permanent

SEEG risks on the card: refinancing wall, concession 2028 versus bond 2031, negative DSCR headroom, and 15.2 billion FCFA sitting in escrow. Eneo’s distinctive risk is government payment arrears of 64 billion FCFA. The treasury card talks about short BTA auctions and a Nelson-Siegel curve.

Terms.

  • Issuer / émetteur. The legal entity that owes the money. For a corporate bond, the company. For an OTA, the state treasury.
  • Chiffre d’affaires. Revenue. Turnover from selling water and power, or port services, or (for a treasury) the tax take. A treasury is not a company, so EBE is the wrong concept; the page says so.
  • Dette nette. Gross financial debt minus cash. Lenders use net debt because cash could be used to repay. Formula on the ratio page: long-term debt + short-term debt − cash.
  • Levier (net debt / EBE). How many years of current EBE it would take to repay net debt, ignoring interest. 2.52x with a 3.50x cap means the company is inside the contract. A sovereign “58% of GDP” is a different ratio: debt compared with the economy, not with EBE.
  • Notation. A credit rating from an agency (S&P, Fitch, Moody’s, or regional agencies Bloomfield and GCR). B is speculative grade: the issuer can pay today, but a shock can change that. BBB- (on the BDEAC bond in the blotter) is the bottom of investment grade. Outlook Stable or Négative is the agency’s direction, not a second rating.
  • Taux moyen pondéré. The average interest rate, weighted by how much debt sits at each rate.
  • Maturité moyenne. The average time until principal is due.
  • PIB. GDP. Used only on the sovereign card.

Business value. Bankers and portfolio managers think in issuers, not only in deals. One issuer can have a bridge, a bond, and a concession. This page is the identity record those other pages should share. Today the record is a curated card, so treat it as the reference sheet for the demo, and treat Financials as the place where SEEG’s accounts are actually tabulated.

Use case. Start from the SEEG deal, open Issuers, confirm leverage 2.52x and DSCR 1.08x, then open Dette et covenants and jump to the stress lab to see what breaks first. Switch to Trésor Gabon when you want the sovereign, then jump to curves.

Next. Instruments, for the bonds themselves. Financials, for the statements behind the EBE.

Instruments ​

Route/workspace/instruments
SidebarInstruments
Default forPortfolio manager

Purpose. A blotter of tradable rate products: sovereign bonds, treasury bills, and listed corporate bonds. You filter it and jump to the curve of the same market.

What it does. Title Instruments de taux. Detail: sovereign bonds, treasury bills, and corporate debt listed on BVMAC. Courbes opens sovereign curves. Stress DV01 asks the copilot to simulate a +50 bp rate shock on the whole CEMAC blotter.

Filters: tabs Tous, OTA, BTA, Corporate; a country select (Gabon, Cameroon, Congo, Régional); a search on name, ticker, and ISIN.

Columns: instrument and ISIN, issuer, type, coupon, maturity, price, yield to maturity, spread versus BEAC, modified duration, rating, and a Courbe action.

KPIs: filtered count (Titres affichés), arithmetic mean of yields on screen (Rendement moyen), average modified duration (Duration moyenne), and an explicit provenance tag (Source du livre : SoR Book or Démonstration or Vide).

Data. Bound dynamically to the tenant's System of Record book via /api/locus/portfolio (using mapSorInstruments and mapSorIssuers). When connected to the live PostgreSQL database, the blotter displays the verified CEMAC book instruments and marks for the active institution. In isolated demo mode or fallback, representative benchmark rows include:

TickerWhat it isCouponYieldSpread vs BEACMod. duration
OTA-CMR-24/29Cameroon 5-year OTA6.25%6.91%0 bp3.95 years
OTA-GAB-23/28Gabon 5-year6.50%7.25%+34 bp3.65 years
OTA-COG-24/31Congo 7-year6.75%7.85%+94 bp4.80 years
BTA-CMR-52SCameroon 52-week billzero coupon5.82%−109 bp0.98 years
SEEG-6.50%-28SEEG 2023–2028 bond6.50%7.15%+24 bp3.52 years
BDEAC-5.60%-27BDEAC 2022–20275.60%5.95%−96 bp2.30 years

Terms.

  • Blotter. A trader’s list of positions or of the market’s lines. Here it is the market universe, not the firm’s holdings. The asset-management overview talks about a portfolio; this page does not weight the rows by a holding size.
  • ISIN. The international id of a security (or, in this demo, a BVMAC code such as BVMAC-SEEG-28).
  • Coupon. The stated annual interest, as a percent of face value. A zero-coupon bill pays no coupon; you buy it below 100 and the gain to 100 is your return.
  • Price. Quoted as a percent of par. Par is 100. A price of 97.20 means you pay 97.20 for a claim of 100 at maturity, so your yield is higher than the coupon.
  • Yield to maturity (taux actuariel). The single rate that equates the price you pay with the coupons and principal you will receive. This is the number you compare across bonds.
  • Spread BEAC. Yield minus a BEAC reference, in basis points. Positive means the bond yields more than the reference (more risk, or a longer maturity). The bills can show a negative spread because they are short and the reference used on the row is higher than bill yields.
  • Modified duration. Price sensitivity. SEEG at 3.52 years loses about 3.52% of price if yields rise 1%, approximately. The copilot prompt (+50 bp) would be about half of that, roughly 1.76% of price, if you applied the approximation yourself. This page does not compute that portfolio loss.
  • DV01. The money lost if the yield rises by 1 basis point. “Per million” means per 1,000,000 of face. The column is in the data model and hidden. The curve terminal computes a deal-level DV01 in the structuring tab.
  • Ticker. The short market code.

Business value. A portfolio manager asks two questions: what is the bond yielding versus the sovereign curve, and how much does the price move if BEAC hikes. This blotter is the inventory for the first question. The curve terminal is where the second question is actually calculated.

Use case. Filter to Corporate, find SEEG-6.50%-28 at a 7.15% yield and +24 bp, and open Courbe to see whether that yield is cheap or rich versus Gabon’s sovereign curve. Then run Stress DV01 only as a prompt into the copilot; the numerical stress of a new issue lives on the structuring tab of the curve page.

Next. Portfolio, for the firm’s holdings book. Sovereign curves, for the reference rates those instruments are priced against.

Portfolio ​

Route/workspace/portfolio
SidebarPortfolio
Default forPortfolio manager; asset-management edition
ComponentPortfolioWorkspaceView
Domainlocus-web/src/domains/portfolio/

Purpose. Treat the firm’s CEMAC fixed-income book as one object: holdings, exposures, rate stress, policy exceptions, performance versus a benchmark, and experimental construction candidates. This is the Aladdin-style book view; Instruments remains the market blotter of listed lines.

What it does. Workspace title around the CEMAC demo book. Tabs:

  1. Overview. Aggregate market value, modified duration, DV01, and an estimated loss for a parallel +50 bp move (estimateParallelLossFromDv01). Quick links into holdings, exceptions, and stress.
  2. Holdings. Position blotter: issuer, instrument type (BTA / OTA / corporate / loan), notional, clean price, yield, duration, DV01, and price source (OBSERVED, MODEL, or UNPRICED). Selecting an issuer can open the linked deal and jump to Issuers or Research.
  3. Exposures. Weight by issuer, country, and sector, plus a maturity ladder.
  4. Scenarios. Saved stress presets (parallel yield, steepener/flattener, issuer spread, liquidity haircut, delayed repayment). Runs produce P&L and risk deltas against the live snapshot.
  5. Exceptions. Unified inbox of open limit and market exceptions with severity and status (OPEN, UNDER_REVIEW, MITIGATED, CLOSED). Status can be updated in session.
  6. Attribution. FI performance attribution versus a benchmark (carry, rates, spread, residual) built from the seed book.
  7. Construction. Constraint-based candidate books (issuer ≤ 15%, country ≤ 35%, duration ≤ 4.5 years). Marked experimental — not investment advice.

Copilot tools under /portfolio call the same deterministic domain functions (exposure, stress, exceptions).

Data. Tenant book from GET /api/locus/portfolio (C# /api/portfolio/book). Fresh tenants start empty; positions are added via portfolio CRUD (POST holdings/instruments/issuers) or the add-position form. Valuation uses valuation.ts on SoR rows.

Terms.

  • Holding. One line the firm owns (or seeds as owned): instrument + quantity + mark.
  • Price source. OBSERVED is a market quote. MODEL is a curve- or engine-derived mark. UNPRICED means no usable mark yet.
  • DV01. Money value of a one-basis-point move; the overview’s +50 bp loss is a linear approximation from aggregate DV01.
  • Exception. A limit breach or market alert that needs an owner and a status, separate from deal-room Q&A.
  • Attribution. Decomposition of book return versus a benchmark into rate, spread, and residual pieces.
  • Construction. Soft-constraint reweighting that proposes candidate books after data trust is established; it does not execute trades.

Business value. A portfolio manager’s morning question is “what do we own, what breaks if rates jump 50 bp, and which exceptions are still open?” This page answers that without forcing them through deal-centric screens. Deal links remain one click away when an issuer ties to an open mandate.

Use case. Open Portfolio as a PM. Read the +50 bp loss on Overview. Open Exceptions and take anything CRITICAL under review. Run the parallel yield scenario, then check Attribution versus the seed benchmark. Only after the book looks trustworthy open Construction to compare candidate weights.

Next. Sovereign curves, to see the rate surface behind the stress. Instruments, to inspect a listed line that is not yet in the book. Market radar, for the auction that moved the marks.


ANALYSIS ​

ANALYSIS is where a number is either calculated or checked against a rule. The open deal still matters for financials, ratios, the credit lab, contradictions, regulatory findings, and the COSUMAF header. Curves and the COSUMAF rule engine also use their own market and checklist data.

Sovereign curves and the fixed-income terminal ​

Routes/workspace/sovereign-curves and /workspace/fixed-income-terminal
SidebarSovereign Curves. The monitoring item Auctions & Calendars opens the same URL.
Same componentFixedIncomeTerminalView

Purpose. Build a yield curve for CEMAC treasuries from auction results, then use that curve to price a new bond and to see which listed bonds look cheap or expensive.

What it does. Title Courbes souveraines. Detail: Nelson-Siegel and cubic splines for Cameroon, Gabon, Congo, and Chad. The spline model exists in code and is not what the screen draws. The fitted model is always Nelson-Siegel.

Header KPIs come from sample JSON, not from the fit: TIAO BEAC 5.00% (Taux d’intérêt des appels d’offres, the central bank’s main auction rate), Prêt marginal 6.75% (the rate banks pay for emergency central-bank cash), and a count of ingested auctions.

Four tabs:

  1. Courbes. Issuer and curve-mode filters sit in one compact toolbar on the chart card (segmented codes ALL / CMR / GAB / COG / TCD and modes Spot / Forward / DF). The chart plots the selected countries. Badges show R² and RMSE in basis points. A reference line is drawn at 5.00% and labeled TIAO. A HUD lists Nelson-Siegel parameters β₀, β₁, β₂, and λ, plus R², RMSE, and max residual. If the issuer is not Cameroon, it also shows the 5-year spread versus Cameroon. A table gives the model yield at standard tenors from 13 weeks to 10 years, and spreads of Gabon and Congo versus Cameroon.
  2. Structuration. A new-issue pricer. You set the name, amount (default 50 billion FCFA), tenor (default 5 years), coupon (default 6.5%), credit spread versus the curve (default +25 bp), and either linear amortization or bullet (In Fine), with an optional grace period. Outputs: market yield (curve yield + spread), theoretical price, modified duration, Macaulay duration, and DV01. A stress table shocks the rate from −100 bp to +100 bp and shows the arranger’s profit or loss if they underwrite the bond. A cash-flow schedule lists principal, coupon, discount factor, and present value by year.
  3. Valeur relative. Three banners and two tables. The 2-year versus 10-year slope for Cameroon is computed from the fitted curve. The Gabon-versus-Cameroon 5-year premium banner is hardcoded at +104 bps with badge SURVEILLANCE, and the “2 buy signals / +40 to +48 bp” banner is also hardcoded. The bond table recomputes cheap/fair/rich from sample secondary quotes against the fitted curve. A second table is the sovereign spread matrix versus Cameroon, with a z-score.
  4. Adjudications. Filter by issuer and by BTA or OTA. A paste box runs parseBEACBulletin on text you paste, with a demo button that loads four lines. The ledger itself is the sample auction file. Coverage (bid-to-cover) is colored against 1.20x in the UI only.

Data. Sample file locus-web/data/fixed_income/sample_data/cemac_sovereign_data.json, fitted by NelsonSiegelEngine inside CurveEvaluator.fitSovereignCurve. Curves are fitted for CMR, GAB, COG, and TCD only.

The spot yield at maturity t (in years) is the Nelson-Siegel function:

text
y(t) = β0 + β1 * ((1 - e^(-t/λ)) / (t/λ)) + β2 * (((1 - e^(-t/λ)) / (t/λ)) - e^(-t/λ))

If t is essentially zero, the code returns β0 + β1. Calibration searches λ from 0.2 to 5.0 in steps of 0.05 and solves β₀, β₁, β₂ by weighted least squares. Weights are the square root of the amount allotted, in billions of FCFA. Fits with a negative β₀ are skipped. Fewer than three points returns a hardcoded parameter set. R² is 1 - ssRes/ssTot, floored at 0. RMSE is the square root of the mean squared yield error.

Forward rate: f(t) = β0 + β1*e^(-t/λ) + β2*(t/λ)*e^(-t/λ).

Discount factor: P(t) = exp(-y(t)/100 * t). The chart shows that times 100.

Bond math in the pricer (one payment per year):

  • Clearing yield = curve yield at the tenor + credit spread.
  • Bullet debt pays all principal on the last date. Amortizing debt spreads principal over the years after the grace period.
  • Macaulay duration = the present-value-weighted average time until you receive cash.
  • Modified duration = Macaulay / (1 + yield).
  • DV01 = price in FCFA × modified duration × 0.0001.
  • Clean price is set equal to dirty price, with a comment that this assumes the issue date is today (no accrued coupon yet).
  • The “breakeven coupon” shown on the slider is set equal to the clearing yield. A comment says an amortizing bond should solve for the coupon; the code does not.
  • Underwriting fee suggestion = max(1.25%, modified duration × 0.35% + 0.5%).
  • Profit and loss of a rate move = change in price percent × nominal. The narrative also states the loss for a 25 bp widening as duration × 0.25% × nominal.

Relative value: fair yield is the issuer curve at the bond’s remaining tenor (Cameroon if that issuer has no curve). Spread in bp = (market yield − model yield) × 100. At least +30 bp is ACHAT ALPHA (cheap). At most −25 bp is SURÉVALUÉ (rich). Between those, JUSTE PRIX.

Z-score on the sovereign matrix is spreadBps / 35 - 2.5. That is a display scaling, not a statistical z-score from a history of spreads. The market-radar page has a separate, genuine z-score against a stated mean and standard deviation.

Terms.

  • Yield curve / courbe des taux. Yields of the same issuer’s debt plotted against maturity. Reading it tells you the market’s price of lending for 3 months versus 10 years.
  • Spot. The yield from today to that maturity. Forward. The rate the curve implies for a loan that starts later. Discount factor. The present value of 1 FCFA received at that date. If the 5-year discount factor is 0.70, a 100 FCFA payment in five years is worth 70 today at the curve’s rates.
  • Nelson-Siegel. A four-parameter curve used by central banks because it is smooth and needs only a handful of bonds. β₀ is the long-term level. β₁ drives the short end (the slope). β₂ drives the belly (curvature). λ sets how fast the short-end effect dies. Diebold-Li is the dynamic version of the same formula; the HUD mentions it because the calibration solves those three betas.
  • R². Share of auction-yield variation the curve explains. Close to 1 means the auctions sit near the curve. RMSE. Typical miss, here shown in basis points.
  • TIAO. BEAC’s tender rate, the policy rate banks bid against. The marginal lending rate is the penalty ceiling. A deposit facility at 0% (in the sample file, not on this header) is the floor banks earn on cash parked at the central bank.
  • Tenor. The length of the instrument. 52S means 52 weeks.
  • Primary versus secondary. Primary is the auction where the treasury sells new paper. Secondary is later trading on BVMAC. Alpha here means a secondary price that disagrees with the primary curve: you might buy the cheap one.
  • Bid-to-cover / taux de couverture. Demand divided by the amount offered. 1.10x means investors bid for only 10% more than the state wanted to sell. The product treats a low cover, together with a higher yield, as a weak auction. 2.15x is a strong one.
  • Souscription / prise ferme. Underwriting. The arranger promises to buy the bonds that investors do not take, and holds the price risk until they are sold. The stress table is that inventory risk. A commission d’arrangement is the fee charged for organizing the deal; the cockpit suggests a minimum fee that scales with duration so the fee covers a rate wobble during the selling period.
  • In fine / bullet. All principal at maturity. Amortissable. Principal paid down over time. Différé / grâce. A grace period during which principal is not yet repaid.
  • Prime / décote. Price above 100 is a premium (coupon higher than the required yield). Price below 100 is a discount.
  • Convexity. A second-order price effect stored in the math module. The terminal’s KPI strip shows duration and DV01, not convexity.
  • Steepener. A trade that profits if the curve gets steeper (long rates rise relative to short rates). The badge on the slope banner is hardcoded, not inferred from a position.
  • Z-score. How many standard deviations a point sits from a mean. On this tab the formula is the display scaling above. On Market Radar it is (observed − mean) / sigma.

Business value. An arranger prices a new CEMAC bond off the sovereign curve, then adds a credit spread. A portfolio manager uses the same curve to see which bonds are cheap. A treasury uses the auction ledger to see whether demand is there before they announce the next size. The business decision on the structuring tab is “what coupon clears, and how much money do we lose if yields move 25 bp before we place the bond?”

Use case. Leave the issuer on Gabon, tenor 5 years, spread +25 bp. Read the clearing yield (Gabon 5-year spot plus 0.25%). Read DV01: that is the FCFA loss per 1 bp if L’Archer holds the deal. Open the stress row at +25 bp and compare it with the suggested arrangement fee. Then open Valeur relative and see which BVMAC lines the engine marks ACHAT ALPHA.

What changes between the two URLs. Nothing on the page. fixed-income-terminal is the target of the portfolio shortcut, the alerts card, and the market-radar button. sovereign-curves is the sidebar entry. Auctions & Calendars is a second sidebar link to sovereign-curves.

Next. Market radar, for the auction that moved. Instruments, for the listed line you want to compare.

Financials (SYSCOHADA) ​

Route/workspace/financial-tables
SidebarFinancials
Default forCredit analyst

Purpose. Read the borrower’s official accounts in SYSCOHADA form, year by year, and open the page of the PDF each line came from.

What it does. Title Lecture SYSCOHADA. Detail: historical series tied out to the Central Africa Deloitte statements (that attribution is copy). Two badges always show success: Actif = Passif and VA − Personnel = EBE. Those identities are real checks inside computeSyscohadaRatios (absolute difference under 1 FCFA). This table does not recompute them; it displays the stored lines and paints the badges green.

Tabs: Compte de résultat (income statement), Bilan actif (assets), Bilan passif (liabilities and equity).

Columns: line label, a source button, one column per period, and TCAM (21-23). The growth figure is not a compound annual growth rate. It is (last − first) / abs(first). The column title stays TCAM (21-23) even if the periods you pass in are different. A missing source shows an em dash. When the period carries SoR source_citations, the source button opens that citation (page + optional bbox). Periods without SoR citations may still use legacy sheet defs; the UI does not invent coordinates when a SoR citation exists but has no bbox.

Income-statement lines, in the order a credit analyst reads them:

LineFieldPlain meaning
Chiffre d'affairesrevenueSales
Valeur ajoutéevalue_addedSales minus the goods and services consumed to produce them
Charges de personnelpersonnel_expensesWages and social charges
EBE / EBITDAebitdaValue added minus personnel, in a clean file. The badge claims this identity.
Dotations aux amortissementsdepreciation_amortizationThe year’s allocation of the cost of long-lived assets
Résultat d'exploitation (REX / EBIT)ebitOperating profit after that allocation
Charges financièresfinancial_expensesInterest and fees
Résultat netnet_incomeProfit after interest and tax

Asset lines: net fixed assets (dams, networks), inventories, trade receivables, cash, total assets.

Liability lines: equity, long-term financial debt, short-term financial debt, trade payables, tax and social payables, total liabilities.

Data. currentProject.financial_periods from SoR: after OCR on a financial PDF, DossierAnalyticsService writes FinancialStatements + ExtractedCells and the deal GET maps them into periods. A fresh dossier with no FS upload shows an empty table. Analyst cell overrides remain on /api/locus/deals/{id}/cells/{cellId}/override.

Terms.

  • Bilan. The balance sheet. Assets are what the company controls. Equity and liabilities are how those assets were financed. They total to the same number if the file is complete. Actif = Passif is that check.
  • Compte de résultat. The income statement for one year. It is a flow. The balance sheet is a stock at the closing date.
  • Valeur ajoutée. The value the company itself created. For a utility it is mostly the tariff minus purchased inputs.
  • Amortissement. Spreading the cost of a dam or a network over its life. It is an accounting charge. It is not cash leaving the bank this year. That is why lenders often look at EBE (before this charge) and then subtract real capital spending separately.
  • Capex. Cash spent to buy or renew fixed assets. On the ratio page it is subtracted when computing cash available for debt. It is not on this table.
  • Créances clients. Money customers owe the company. In this region a large slice can be the state paying late. That becomes the “receivables stretch” shock in the credit lab.
  • Dettes financières. Borrowed money, as opposed to supplier payables or tax payables. Only financial debt goes into leverage.
  • Capitaux propres. Equity: share capital, reserves, retained earnings. The residual after liabilities.
  • TCAM. Literally a compound growth rate. This column is a simple total change from the first year to the last. Read it as “how much did this line move from 2021 to 2023,” not as a per-year compound rate.
  • Deloitte Afrique Centrale. The copy attributes the series to audited statements. The numbers are the seed, and citations point at 01_seeg_etats_financiers_syscohada_2023.pdf.

Business value. Every covenant is a ratio of these lines. If the identity Actif == Passif fails, the regulatory and ratio engines flag UNRECONCILED and block automated covenant certification. In production, this balance sheet reconciliation identity is evaluated directly via the C# PostgreSQL SoR (GET /api/locus/deals/[id]/reconciliation), and any manual analyst adjustments require mandatory human justification and append to the immutable audit log (POST /api/locus/deals/[id]/cells/[cellId]/override). This screen is where a credit analyst sees the lines, the source citations, and overrides before trusting the cockpit.

Use case. Open SEEG, income statement, click the EBE source, and confirm 34.85 billion on the PDF citation. Then open the liability tab and read long-term debt 84.5 billion, of which the citation says 4.2 billion is pledged. That 4.2 billion is the negative-pledge fight on the later pages.

Next. Ratios.

Ratio cockpit ​

Route/workspace/ratio-cockpit
SidebarRatios (under Financials)

Purpose. Turn the latest SYSCOHADA year into the contractual credit ratios, and move three sliders to see those ratios change.

What it does. Title Capacité de dette & covenants. Badge Calcul traçable. The baseline period is the record whose period is 2023, otherwise the last period.

Four cards:

CardRule shown on the cardStatus rule
Levier net (dette / EBE)≤ 3.50xThe covenant flag from the engine: BREACH if above 3.50x, WARNING if above 90% of the cap, else COMPLIANT
Couverture intérêts (ICR)≥ 2.50xLocal: RUPTURE if under 2.50, else SÉCURISÉ. The engine itself has no warning band for ICR
Service dette (DSCR)Cible ≥ 1.30xLocal: ATTENTION if under 1.30, else CONFORME
Fonds de roulement (FRNG)Badge always PositifFoot shows BFR and BFR in days of sales

Expliquer on the leverage card sends a copilot prompt. Voir source opens the underlying SYSCOHADA line citation when SourceCitationId / period source_citations is present (R4). Réinitialiser appears only after a slider moves.

Sliders, applied before computeSyscohadaRatios:

  • Revenue shock −25% to +25%. Revenue is multiplied by 1 + shock/100. EBE is multiplied by 1 + shock × 1.5 / 100. EBIT by 1 + shock × 1.8 / 100. A revenue drop therefore hits profit harder than it hits sales.
  • Rate hike 0 to 400 bp. Interest expense is multiplied by 1 + (bps/100) × 0.15. A 100 bp hike adds 15% to the interest line. It does not reprice the debt from a base rate.
  • Capex overrun 0 to 50%. Capex is multiplied by 1 + overrun/100.

Below the cards, Audit des Covenants Contractuels lists each flag with threshold, actual, and a French detail sentence. The contract named in the subtitle is the bridge-loan agreement.

Formulas in computeSyscohadaRatios (defaults: max net debt/EBE 3.50, min ICR 2.50, min DSCR 1.30):

text
gross debt = long-term financial debt + short-term financial debt
net debt   = gross debt − cash
net debt / EBE = net debt / ebitda          (999 if ebitda ≤ 0)
ICR        = ebit / financial expenses      (999 if expenses ≤ 0)
debt service = scheduled principal + financial expenses
CFADS      = ebitda − corporate tax − capex
DSCR       = CFADS / debt service
FRNG       = (equity + long-term financial debt) − fixed assets
BFR        = (inventories + receivables + other current assets)
             − (trade payables + tax and social + other current liabilities)
BFR days   = (BFR / revenue) × 365

The same function also computes gearing (net debt / equity), EBITDA interest cover (EBE / interest, which is not the ICR card), current ratio, quick ratio, and margins. The cockpit cards do not show all of them. The credit lab uses a different DSCR floor, 1.20x, and a different shock model. If the two pages disagree, that is why.

On unstressed SEEG 2023 the engine’s inputs are the seed: EBE 34.85 billion, cash 14.8 billion, long-term debt 84.5 billion, short-term debt 18.2 billion, so net debt is 87.9 billion and leverage is 87.9 / 34.85 ≈ 2.52x. That matches the issuer card. The DSCR card uses CFADS = EBE − tax − capex, then divides by principal plus interest. The review grid and several narratives instead show DSCR at 1.08x or 1.02x from canned sentences. Read the cockpit number as the one this function produces after your sliders. Read 1.08x as the story number used on Overview, Issuers, the graph, the risk register, and the review grid.

Terms.

  • Covenant. A contractual promise that can be tested with a number. If you break it, the lender can accelerate the loan, raise the margin, or stop new drawings. Testing is usually twice a year.
  • ICR (interest coverage). EBIT divided by interest. 2.50x means operating profit covers the interest bill 2.5 times. The review grid’s ICR line is labeled “EBE / interest” and shows a hardcoded 3.20x. The cockpit uses EBIT / interest. Those are different numerators. EBE is before depreciation, so it is larger.
  • DSCR. CFADS divided by debt service. Debt service is principal plus interest, not interest alone. That is why a company can have a fine ICR and a weak DSCR: principal repayments are large.
  • CFADS. Cash flow available for debt service. This codebase defines it as EBE minus tax minus capex. Textbooks vary (some start from EBITDA and adjust working capital). When you read DSCR in Locus, this is the definition.
  • FRNG (fonds de roulement net global). Long-term financing minus long-term assets. If it is positive, long-term money more than covers the fixed assets, and the surplus funds the operating cycle. The badge does not turn red when the number is negative.
  • BFR (besoin en fonds de roulement). Cash trapped in the operating cycle: inventory and unpaid customer bills, minus what the company itself owes suppliers and the tax office. More BFR means more cash tied up. Days of revenue says how many days of sales that stock of cash represents.
  • Headroom / marge de manœuvre. Distance to the covenant. For a maximum leverage covenant it is cap − actual. For a minimum coverage covenant it is actual − floor.
  • Points de base on the rate slider. A market move in the interest rate. The cockpit’s mapping (100 bp → +15% interest expense) is a simplified sensitivity, not a full repricing of Euribor plus margin.

Business value. The credit committee’s question is “if revenue falls 10% and BEAC hikes, do we breach?” The sliders answer that in one screen, with the formula fixed in code so two analysts get the same output. The business decision is whether the headroom is wide enough to approve, or whether the structure needs a reserve account or a longer maturity.

Use case. Open SEEG, note leverage near 2.52x and the DSCR card against 1.30x. Push revenue to −10% and the rate slider to +100 bp. Watch which card flips first. Then open the credit lab, which applies a richer shock (receivables, foreign exchange) and uses the 1.20x DSCR floor written in the alerts.

Next. Credit lab for the committee scenarios. Review grids for the contractual clause the ratio is tested against.

Credit lab ​

Route/workspace/credit-lab
SidebarDebt & Covenants

Purpose. Stress the latest financial year with the shocks a CEMAC credit committee actually argues about (state arrears, a rate jump, a currency tranche), and produce an approve / conditional / reject verdict.

What it does. Title Laboratoire de Stress-Testing & Scénarios Crédit. Réinitialiser returns to the base preset.

Four presets plus a custom state if you move a slider:

PresetBadgeWhat it sets
Cas de base (audité 2023)BaselineAll shocks zero
Sensibilité comité de créditBanque CaseRevenue −10%, EBE margin −2.5 points, rates +100 bp, receivables +30 days, capex −10%
Choc arriérés État et retard BFRRisque CEMACRevenue −12%, margin −1.5 points, +50 bp, receivables +90 days, capex −25%
Choc sévère macro et taux BEACStress ExtrêmeRevenue −20%, margin −5 points, +300 bp, +60 days, capex −30%, FX +20%

A breach banner always uses destructive styling. It names the primary vulnerability: either DSCR already below 1.20x, or the revenue drop, margin compression, rate hike, or cash runway that would get you there. The trigger math holds every other shock at zero and solves one variable at a time.

Six sliders: revenue −30% to +20%, EBE margin compression −10 to +5 percentage points, interest-rate shock 0 to 500 bp, receivables delay 0 to 180 days, capex −50% to +30%, FX 0 to 40%.

Four result tiles: DSCR, net leverage, ICR, and cash absorbed by the receivables stretch. Status labels: Rupture, Alerte, Conforme. Each coverage tile shows base, stressed, threshold, and headroom.

The verdict:

  • More than one covenant at risk, or DSCR in breach → Refus / Restructuration and the headline that the debt must be restructured before syndication.
  • One covenant at risk, or DSCR only on warning → Favorable Sous Réserve and a 6-month DSRA.
  • Otherwise → Favorable and the headline that the file survives standard sensitivity.

Four mitigants are always listed: a 6-month DSRA, a tripartite compensation agreement with the Gabon treasury, subordination and a dividend block while DSCR is under 1.25x, and a margin ratchet on net leverage. A bridge table compares base and stressed revenue, EBE, EBIT, interest, debt service, CFADS, and adjusted net debt.

Data. runStressSimulation on project.financial_periods, last period. Overrides passed from the component: max leverage 3.50, min ICR 2.50, min DSCR 1.20. Amounts display in billions (Mrds).

Shock formulas that differ from the cockpit:

text
stressed revenue = revenue × (1 + revenue shock)
stressed EBE     = revenue × (base margin + margin shock)
stressed EBIT    = stressed EBE − depreciation
base rate        = interest / gross debt, or 5.5% if that cannot be computed
stressed rate    = base rate + bps/10000
FX multiplier    = 1 + fx shock
stressed interest and principal = base × stressed rate or base principal, × FX
tax rate         = tax / EBIT, or 25%
CFADS            = EBE − tax − capex
extra BFR        = (stressed revenue / 365) × extra days
stressed cash    = cash − extra BFR − any CFADS shortfall, floored at 0
stressed net debt = gross debt − stressed cash

Leverage breaches above the cap, and warns above 90% of the cap. Coverage breaches below the floor, and warns below 110% of the floor.

Terms.

  • Stress test. Recompute the ratios on purpose-built bad inputs. The point is the distance to breach, not the base case the company already published.
  • Arriérés. Overdue payments. “Arriérés de l’État” means the government has not paid the utility. The days slider is a DSO shock: days sales outstanding, how long cash sits in receivables.
  • Percentage points (pp). A margin move from 17.6% to 15.1% is −2.5 pp. That is not −2.5% of the margin.
  • FX tranche. Part of the debt is in euros or dollars. If the exchange rate moves against the FCFA, the local-currency cost of that debt rises. The peg makes a large move a political scenario; the slider still lets you impose one. The product’s own parity is fixed at 655.957, so this shock is hypothetical on top of that peg.
  • Ratchet. A clause that changes the margin, or tightens a covenant, when a ratio gets worse. It is listed as a mitigant; the lab does not apply a ratchet schedule to the interest line.
  • Subordination. An agreement that some debt or some dividends are paid only after senior lenders. A dividend block while DSCR is under 1.25x keeps cash inside the company.
  • DSRA 6 mois. Cash trapped at signing equal to six months of debt service.
  • Quasi-fonds propres. Money that behaves like equity (a subordinated shareholder loan, for example) so leverage falls without a full capital increase.
  • Comité de crédit verdict. Approve, approve with conditions, or send the structure back. The lab’s enum is APPROVE, CONDITIONAL_APPROVAL, REJECT_STRUCTURING_REQUIRED.

Business value. This is the page a credit analyst brings to committee. The presets match the stories in the file: a standard bank case, a CEMAC state-arrears case, and a severe BEAC hike. The decision is the verdict plus the conditions precedent the arranger must add to the term sheet.

Use case. Select Choc Arriérés État. Read the DSCR tile and the cash-absorption tile. If the verdict is conditional, the CP to write down is the 6-month DSRA. Switch to the severe preset and see the verdict flip toward restructuring. The same shocks are what the diligence runner’s stress step describes in canned log lines.

Next. Review grids, to attach these ratios to clauses. Risk register, to assign the DSCR issue to the credit risk committee.

Review grids ​

Route/workspace/review-grids
SidebarReview Grids (under Debt & Covenants)

Purpose. A clause-by-clause grid of the loan: commercial terms on one tab, financial covenants on the other, each with a source page and a human verification state.

What it does. Title Grilles de Revue d'Engagements & Covenants (Kira-Style). Kira is a known contract-extraction product; the label means “structured fields pulled out of contracts,” not a live Kira integration.

Badges: percent of fields a human has verified or modified, and the count of covenant breaches. KPIs repeat the certification rate, the count of facility fields, the count of financial covenants, and the count of breaches plus discrepancy flags.

Tabs:

  • Termes de la Facilité & Sûretés. Columns: clause, value extracted by the machine, value confirmed or overridden, source, verification status, actions. Valider sets HUMAN_VERIFIED by Analyste Crédit (L'Archer). Editing sets MODIFIED.
  • Engagements Financiers & Covenants. Columns: code, contractual threshold, “actual” from the cockpit, headroom, status, source, certification. Status text is Rupture de Covenant or Conforme. ✦ Expliquer opens the copilot. Validate here attributes the check to Directeur des Risques.

Verification labels: Vérifié par Analyste, Extrait par IA, Contesté / Litige, Modifié Manuellement.

Data. Review grids stay empty until SYSCOHADA extractions exist in the SoR for the open dossier. There is no hardcoded SEEG facility fallback.

Facility rows (source file 02_convention_pret_relais_53m_eur.pdf):

ClauseExtracted valueFlag
Principal53,400,000 € (about 35.03 billion FCFA)Normal, human-verified
MarginEuribor 3M + 7.20%, and the verified cell also records 6.75% in the term sheetDisputed. Note: 45 bp, about +240k€ a year
MaturityBridge due 30/06/2025, bond in 2031Breach. The bond outlasts the 2028 concession by 3 years
Negative pledgeAbsolute ban on any pledgeBreach. Conflicts with the 4.2 billion turbine escrow in Note 14
Cross-default500 million FCFAExtracted, not yet verified
LawOHADA, CCJA arbitration in Abidjan or the Libreville court—

Covenant rows:

CodeTestThresholdShown actualStatus
LEV_01Net debt / EBE≤ 3.50x2.52x, headroom +0.98xCompliant. Note says a slide-deck EBITDA of 42.1 billion is not enforceable; the certified EBE is 34.85
ICR_01Labeled EBE / net interest≥ 2.50x3.20xCompliant. This 3.20x is a literal, and the numerator in the label is EBE, not the cockpit’s EBIT
DSCR_01DSCR≥ 1.20x1.08x, headroom −0.12xBreach
CAPEX_01Annual capex cap≤ 15 billion FCFA12 billionCompliant
CASH_01Minimum cash≥ 8 billion FCFA14.80 billionCompliant. Note: 4.2 billion of that cash is trapped in the turbine escrow

Terms.

  • Cross-default. If the borrower defaults on some other debt above a threshold (here 500 million FCFA), this loan is also in default. It stops a borrower from quietly defaulting to one lender while staying current with another.
  • CCJA. The OHADA arbitration court in Abidjan. Choosing it means disputes may not be heard only in the local commercial court.
  • Headroom sain. Positive spare room. A negative headroom on DSCR is a breach, not a warning.
  • Pro forma / normalized EBITDA. A management number that adds back items the company says are one-off. Lenders in this product are told to ignore 42.1 billion and keep 34.85 billion, because only the audited EBE is opposable (enforceable against the borrower).
  • Certification. A person, not the model, has accepted the extracted cell. The rate on the badge is the share of cells in HUMAN_VERIFIED or MODIFIED. That rate is the operational control: uncertified cells should not go into a committee memo as facts.

Business value. Models compute ratios. Contracts decide which ratio, which threshold, and which definition. This grid is the bridge. The business decision is “which clauses are still disputed, and who has signed the cell?” A disputed margin must be resolved before the book of investors is opened, because the coupon in the prospectus has to match the contract.

Use case. After OCR + analysis, open the covenant tab: LEV/ICR/DSCR rows are computed from the dossier’s financial_periods. Facility margin/maturity hints appear when term-sheet OCR extracted them into review_grid_extract. A dossier without periods shows empty grids.

Next. Contradictions, which shows the two documents side by side. Risk register, which assigns an owner to each of these breaches.

Risk register ​

Route/workspace/risk-register
SidebarRisk

Purpose. The committee list of risks: severity, owner, evidence, a mitigant, and whether the mitigant is a condition precedent.

What it does. Title Registre Central des Risques & Conditions Suspensives. Badges show the borrower and the count of critical alerts (critical and high).

KPIs: risks being watched, critical risks, the count of CPs, and identified exposure in FCFA.

Filters: severity (Critique, Élevée, Moyenne; LOW exists on the type and has no option), status (Risque Ouvert, En Revue Comité, Mesure Validée, Accepté par Comité), and category (maturity and concession, contractual contradiction, collateral and negative pledge, BEAC regulation, financial covenants, sovereign legal security).

Each card shows id, raw severity, category, status, owner, and the scope. ✦ Expliquer opens the copilot. Two evidence columns: deal documents, and an opposable legal text (OHADA or CEMAC) when one exists. You can set the status with the French buttons. The footer stamps a local update time. Status is held in the page session; it is not written back to the project seed.

Data. Risk register is built from the open deal’s documents, contradictions, and findings — or stays empty for a fresh dossier. No hardcoded SEEG risk pack is injected.

SEEG risks:

TitleCategorySeverityStatusOwnerExposure
Maturity mismatch, concession 2028 vs bond 2031ConcessionCriticalOpenLegal counselThe deal amount. CP: a concession decree beyond 31/12/2031
Margin 6.75% vs 7.20%ContractHighOpenLead arranger157.6 million FCFA, stated as 240,300 euros
Negative pledge vs Note 14 escrowCollateralHighIn committee reviewLegal counsel4.2 billion FCFA. Cites OHADA article 140
BEAC Article 42 declaration missingRegulatoryHighOpenCompliance officer—
DSCR 1.08x vs 1.20xCovenantHighIn committee reviewCredit risk committee14.5 billion FCFA (a year of debt service)
Unverified national utility lawRegulatory gapMediumOpenLegal counselNone

Terms.

  • Condition suspensive. Same idea as a CP: the committee can say yes, and the money still does not move until this clause is satisfied. The card prints Clause CP Term Sheet when the risk carries one.
  • Mesure d'atténuation. The action that makes the risk acceptable: a longer concession, a waiver, a reserve account, a filing.
  • Accepté par comité. The committee saw the risk and took it with no further document. That is different from Mesure Validée, which means the mitigant is in place.
  • Exposition. A franc amount the card attaches to the issue (the disputed interest, the pledged cash, one year of debt service). It is not a probability-weighted loss. Probability and impact fields exist on the object and are not shown.
  • Texte opposable. A statute or contract clause you can show a judge or a regulator. The right-hand column is that text. A structuring risk with no statute says so explicitly.
  • PPP. Public-private partnership. The non-Gabon card is about Congo’s PPP statute, because a port or a utility financed with state support has to fit that law.

Business value. Committees do not approve a 40-page model. They approve a list of risks with owners and conditions. This page is that list. The decision is which risks stay open, which become CPs in the term sheet, and which are accepted.

Use case. Filter to Critique. There is one: the concession date. Leave it Ouvert until legal has a draft decree. Move the negative-pledge card only when a waiver is signed. The DSCR card stays with the credit risk committee and points at the 14.5 billion of annual debt service, which is the scheduled principal sitting on the financial period.

Next. Contradictions for the evidence pair. Memo drafter, where these CPs should be written as the recommendation.

Contradictions ​

Route/workspace/contradiction-radar
SidebarContradictions (under Risk)

Purpose. Show two documents that disagree, with the quoted sentences and the page numbers, so an analyst can resolve the gap instead of averaging it.

What it does. Title File de contradictions. Badges count CRITICAL and MAJOR alerts. There are no filters. Each card has an index, a title, a topic, a variance metric, a severity, and ✦ Expliquer. The body is Lecture analyste. Two columns, Document A and Document B, each with Voir sur le PDF, the quotation, and the file name. Alerts are hydrated from SoR Citation rows (real page/filename; bbox only when usable — never a hardcoded zero box).

Data. currentProject.contradiction_alerts. SEEG’s four seed alerts:

TopicWhat disagreesMetric
INTEREST_RATELoan, page 18: Euribor 3M + 7.20%. Term sheet, page 3: Euribor 3M + 6.75%45 bp, about 240,300 € a year
MATURITY_DATEConcession ends 31/12/2028. Take-out bond runs into 20313 years, the explanation says 35 months
EBITDA_DEFINITIONCertified EBE 34.85 billion. Presentation “normalized EBITDA” 42.1 billion+7.25 billion, +20.8%. The explanation says leverage would move from 2.08x to 2.52x if you switch numerator’s companion debt figure. That sentence is text, not a function
NEGATIVE_PLEDGEAbsolute negative pledge versus an existing 4.2 billion pledge in Note 14The pledged amount

Topics also include COVENANT in the enum. Severity MINOR has no separate color. A new wizard dossier does not copy this list unless the seed merge supplies it; SEEG’s project carries these four.

Terms.

  • Variance metric. The size of the gap in the unit that matters to money: basis points, years, or FCFA. It is the reason the row is on the page.
  • Document A / B. The two sources. Neither is automatically “the winner.” The Q&A sample says 7.20% prevails because it is in the signed loan. The radar does not encode that winner. A human does, by publishing the answer and editing the review-grid cell.
  • Normalized EBITDA. Already covered on the review grid. The radar is the evidence view of the same fight: the slideshow number versus the audited line.

Business value. A single wrong margin in a prospectus is a liability to investors and a reason for COSUMAF to refuse a visa. This page is the control that stops two teams from using two numbers. The decision is which document governs, and which sentence must be amended before the file is sent out.

Use case. Open the interest-rate card, view both PDFs, and write down that the signed loan says 7.20. Then open the EBITDA card and refuse the 42.1 billion figure for any covenant test. The regulatory dashboard repeats each of these alerts as a legal finding.

Next. Regulatory, which attaches a rule to each gap. The memo, which states the open questions.

Regulatory ​

Route/workspace/regulatory
SidebarRegulatory
Default forCompliance officer. Also the default landing tab of the legal edition.

Purpose. Ask which CEMAC and national rules apply to this deal, which findings the file triggers, and how trustworthy the legal corpus is.

What it does. Title Cadre Juridique & Rapprochement Réglementaire. Badges: evaluation date from project.created_at, and a hardcoded peg Parité fixe BEAC 655,957.

If the jurisdiction profile says so, chips show Appel public à l’épargne (BVMAC), Financement transfrontalier, and Entité liée à l’État.

KPIs, computed by analyzeDeal (client) or analyzeDealWithVault (server / jobs):

  • Regulatory coverage = catalogued sources / applicable sources.
  • Attention points = findings with status issue.
  • Open legal questions = status question.
  • Deterministic checks = how many boolean checks passed.

Vault overlay (slices 32–33). When a session can call the SoR, analyzeDealWithVault resolves each statutory cite to vault editionId / provisionId / artifactId / sha256 and may set openStatuteHref → bank BFF
/api/locus/legal-vault/artifacts/{id}/content (hash-verified PDF stream). Findings can be persisted on the dossier as DossierRegulatoryFindings for audit replay. Evaluation predicates still live in code/catalog.ts until provisions are legal_reviewed. Platform PDF attach and review happen in locus-ops, not on this page — see Platform ops and regulatory-data.md.

Heuristics (slice 34). BEAC Art. 42 also fires when the data room mentions EUR/USD / emprunt extérieur / devise (not only currency !== 'XAF'). COSUMAF APE vs private placement uses deal type + document tags + investor/listing keywords.

A warning appears when any involved country’s corpus curation is pending. The sentence says the engine never infers one member state’s national law from another member state’s law.

The curation panel shows five authorities with literal document counts, not a live count of files:

AuthorityWhat it isSample stockTrust shown
OHADACompany law and collateral3 acts, 5 articles, 100%Human-verified
COSUMAFCapital markets and public offerings2 acts, 3 articles, 85%Machine-validated
BEACForeign exchange2 acts, 1 article, 75%Official source verified
COBACBank supervision and large exposures1 act, 1 article, 60%Official source verified
CongoPPP law and local commercial code3 acts, 1 article, 35%Pending digitization

Search runs searchRegulatoryCorpus (limit 4) over the loaded articles. The placeholder examples are pledge of an account, COSUMAF visa, and BEAC currency declaration.

Findings are produced from the deal:

  • One finding per contradiction alert. Negative pledge is filed under OHADA collateral articles 138 and 140. The others are filed as term-sheet versus loan contradictions.
  • Missing audited financials, fewer than three historical years, or a broken balance-sheet or EBE identity.
  • Each covenant BREACH on the latest period, using the ratio engine defaults, so the DSCR floor here is 1.30x, not the 1.20x in the credit lab.
  • Public-offering questions: private-placement language in a public deal, a bond that was not formally classified, a missing visa or information note.
  • State-linked deals without a concession or a statute.
  • Cross-border deals (security must be coordinated across countries).
  • A non-XAF currency, which triggers the BEAC declaration story. The check text says the currency has no special FX formality when the currency is XAF.
  • A pending national corpus.

Each finding shows severity (HIGH, MEDIUM, LOW), a type label (documentary contradiction, financial inconsistency, contractual breach, regulatory point, regulatory gap, missing document, legal risk, calculation anomaly), a confidence word, the deal evidence, and the official text. If counsel review is required, the card says a formal legal opinion is mandatory before issue. When vault IDs are present, open-statute opens the platform PDF (not a tenant deal-room upload).

The bottom registry lists regional and national instruments with a SHA-256 prefix, page count, and articles. Pending national instruments say digitization is required. Catalog pdfPath placeholders are not the CI fixtures under data/regulatory/fixtures/ — those fixtures are for vault bootstrap tests only (see regulatory-data.md).

Terms.

  • Corpus. The library of statutes the engine is allowed to cite. A pending corpus means “we have not ingested this country’s law,” not “the country has no law.”
  • Curation. How far a text has been checked: catalogued, source verified, text extracted, machine validated, human verified, superseded, or pending. The percentage is a stored label.
  • Appel public / placement privé. Public offer versus a sale to qualified investors only. Mixing the words in the documents is a finding because the visa regime depends on the choice.
  • Note d’information. The disclosure document investors receive. For a public bond it is the prospectus-style document COSUMAF visas.
  • Change. Foreign-exchange control. A euro loan from outside the zone is not just a commercial contract; BEAC wants it declared.
  • Sûretés multi-juridictionnelles. Collateral that sits in more than one country. A pledge valid in Gabon is not automatically valid in Congo. The finding tells counsel to coordinate, and it does not draft the local filings.
  • Confiance High/Medium/Low. How direct the evidence is. A contradiction quoted from two deal documents is high. A gap because a national corpus is empty is a different kind of uncertainty.
  • CGI. The national general tax code, selected in spirit by the organization jurisdiction. The dashboard does not run a tax computation.

Business value. A deal can be financially fine and still be unlawful to market. This page is the compliance officer’s list of reasons COSUMAF, BEAC, or a court could stop it. The decision is which findings are issues to fix in the documents, and which are questions that need an external legal opinion before anyone signs.

Use case. Open SEEG and read the four contradiction findings first. Then check whether the public-offering chip is on. If you created a dossier with Appel public à l’épargne and no prospectus in the data room, the visa finding appears. Open the BEAC currency finding if the profile currency is not XAF. Use search for nantissement when you need the OHADA article the negative-pledge card cites.

Next. The COSUMAF auditor, which scores the prospectus text itself.

COSUMAF visa auditor ​

Route/workspace/cosumaf-auditor
SidebarVisa COSUMAF (under Regulatory)

Purpose. Run the bond-offering checklist against this deal’s information note, score how close the file is to a visa, and keep a record of each run.

What it does. The eyebrow is Visa COSUMAF plus the deal code. The title is the deal name. A score readout shows visa_readiness_score / 100 and a decision badge once a run has returned.

Readouts: dossier, issuer (country and sector), amount (billions of FCFA when large enough), and which text was audited (a note you pasted, or the data room plus the internal note).

Tabs:

  • Revue. Counts of blockers, reservations, and passes. A table of rule, legal basis, excerpt, finding, proposed clause, and status. Verser au registre posts the run into the history for this deal code.
  • Note. Paste or upload .pdf or .txt, then Contrôler cette note. You can return to the dossier text.
  • Corpus. Search the COSUMAF regulation. Default query compte séquestre. Calls GET /api/regulatory/search.
  • Historique. Past runs for this deal code: date, issuer, source (Note déposée or Dossier), score, decision.
  • Attestation. A printable A4-style pre-visa certificate (design-system sheet): formal title, operation identity matrix, conic readiness score, numbered material findings with status marks, technical opinion, control seal, and the preparatory disclaimer. Print CSS strips application chrome. It lists every result that is not compliant. The footer says the document is an internal decision aid and is not the COSUMAF visa.

The view posts /api/regulatory/audit with sections built from the open dossier.

Scoring. Start at 100. Subtract blockers × (70 / n) and warnings × (30 / n), where n is the number of checklist rules. Clamp to 0–100. Any blocker produces VISA_PRE_REJECTED (UI label Visa ajourné). Any warning and no blocker produces CONDITIONAL_APPROVAL (Accord conditionnel). All clear produces VISA_READY (Prêt au visa). A blocker is a NON_COMPLIANT result whose severity is BLOCKER. Status marks use Non conforme, Réserve, and Conforme.

The checklist CHK-BOND-2023 (Grille de Contrôle Réglementaire COSUMAF - Émissions Obligatoires):

RuleWhat must be in the noteBasisSeverity
CHK-01 Legal warningThe COSUMAF cover warning that the regulator does not guarantee the opportunity of the investmentArticle 138Blocker
CHK-02 EscrowA subscription escrow account that is blocked at a COBAC-licensed bank until the centralization reportArticle 142Blocker
CHK-03 Fee capArrangement and placement fees ≤ 3.50%Article 155Blocker. The auditor sums every percent it finds in the fee section
CHK-04 Risk factorsIssuer, credit, BVMAC liquidity, and currency/sovereign risksArticle 148Warning
CHK-05 Bondholders’ massA masse des obligataires and a named representativeArticle 162 and OHADABlocker
CHK-06 CustodianAn independent licensed depository and centralizing agentArticle 182Blocker
CHK-07 AmortizationA forecast amortization table and coupon scheduleArticle 150Warning
CHK-08 AuditorsA report from licensed statutory auditorsArticle 136Blocker

Special failures you will read in the finding text: the warning sentence is missing; subscription money is described as immediately available on the operating account; the fee sum exceeds 3.5%; the risk section misses credit or sovereign language; the bondholders’ representative is not named as a lawyer or firm under OHADA. A pass says the clause meets the general regulation and no change is required.

Precedent snippets are attached for a few clause types (a BDEAC visa, a Congo fee clause at 2.85%, a Gabon listing-delay clause). They are examples of language that passed before, not a ruling on this deal.

Terms.

  • Visa. COSUMAF’s authorization to proceed with a public offering. Pré-visa means “our internal score before we file,” which is what the attestation is.
  • Réserve. A point that does not by itself reject the file in this scorer, but keeps the decision at “conditional.” In audit language, a reserve is also the auditor’s qualification. CHK-04 and CHK-07 are that kind of softer failure here.
  • Masse des obligataires. The legal body of all bondholders. OHADA gives it a representative who can act for the group. Without that clause, investors have no collective mechanism.
  • Compte séquestre de souscription. The account where subscription money sits, blocked, until the offering is declared successful. Article 142, as encoded here, forbids dumping that money straight into the company’s operating account.
  • Plafond de frais. A cap on what the arranger and the placing banks may charge, so the issuer’s proceeds are not consumed by fees. 3.50% is the threshold in the checklist JSON.
  • Dépositaire / centralisateur. The institution that holds the securities and the one that collects the orders. Independence matters so the arranger is not also the only record-keeper.
  • DCU. The body that issues the centralization report (procès-verbal de centralisation) after which escrowed funds can be released. The rule text names it.
  • Attestation. The printable sheet. It is useful in a committee pack. It does not bind the regulator.

Business value. Filing a prospectus that misses the cover warning or the escrow clause wastes a regulatory cycle and delays the mandate. The score is a pre-flight. The decision is whether the note is ready to file, ready only after named edits, or must be rewritten.

Use case. Open the SEEG deal, run Revue, and read any Non conforme rows first. If the fee finding quotes a sum above 3.5%, that is CHK-03 adding every percent sign it found. Paste a revised note in the Note tab, rerun, and Verser au registre so Historique shows both scores. Print the attestation only after blockers are gone, and keep the footer in mind: it is not the visa.

Next. Institutional memory, to see how a previous SEEG committee treated the same covenants. The memo, to paste the remaining reservations as open questions.


MONITORING ​

MONITORING is the region, not the open deal. The open deal is still in the URL, and one button can jump back to the curve terminal.

Market radar and research ​

Routes/workspace/market-radar and /workspace/research
SidebarMarket Radar, and Research under KNOWLEDGE
Default forResearch analyst (market radar)
Same componentMarketIntelligenceView

Purpose. A morning note on BEAC, treasury auctions, and BVMAC, plus a short list of rate moves that sit far from their recent average.

What it does. Both routes open on the tab Brief du matin. Research does not switch to a hidden “briefs” tab. defaultSubTab="briefs" only flips a header flag.

Market radarResearch
EyebrowMarchés · CEMACRecherche · CEMAC
TitleRadar de marchéVeille et recherche
DetailOfficial surveillance of BEAC, BVMAC, and national treasuries. An anomaly is a move beyond two standard deviations.Same detail

The action Courbes souveraines goes to the fixed-income terminal.

Headline metrics and tabs hydrate from GET /api/locus/market (bulletins, observations, auctions, curves). Ingest writes via POST /api/market/ingest (financial:write or tenant:manage). A fresh tenant sees empty states until data is ingested — there is no permanent SEEG/demo radar pack in the product path.

Tabs:

  1. Brief du matin. Badge 08:00 AM SYNTHÈSE QUOTIDIENNE. The date is “generated at 08:00 UTC on today’s date,” formatted in French. The executive summary interpolates that date and the 5% policy rate, then states that Gabon’s 3-year OTA auction widened by +35 bp with cover of 1.10x. Three sections follow, each with one source button: BEAC monetary policy (TIAO 5%, marginal facility 6.75%, deposit facility 0%, surplus liquidity in Douala and Libreville), primary auctions (Cameroon 26-week BTA covered at 215% and a 4.78% average rate, Gabon 3-year at 6.65% marginal and 1.10x, Congo 5-year at 7.12%), and BVMAC (secondary turnover 485 million FCFA, plus the SEEG bridge of 53.4 million euros and the 2031 bond under COSUMAF review). Evidence buttons do nothing unless a document opener is passed in. This page does not pass one.

  2. Anomalies (2). Title says deviations beyond 2.0σ. The button opens the curve terminal. Cards are hardcoded, not the output of detectAnomaly():

    • Gabon 3-year auction yield, severity INVESTIGATION_SIGNAL, z-score +2.41σ, observed 6.65%, mean 6.12%, sigma 0.22%, cover 1.10x.
    • Cameroon bid-to-cover, severity WATCH, z-score +2.5σ, observed 2.15%, mean 1.45%, sigma 0.28%. The observed value is a cover ratio shown with a percent sign in the card.
  3. Mouvements de taux. Three auction rows, filterable by ALL, CMR, GAB, COG, TCD. Chad matches nothing.

    IssuerInstrumentTenorDateLimit rateAverage rateCoverMoveStatus
    CMRBTA0.5 year2026-04-014.85%4.78%2.15x+8 bpNormal
    GABOTA3 years2026-04-026.65%6.55%1.10x+35 bpAnomaly > 2σ
    COGOTA5 years2026-03-287.20%7.12%1.45x−10 bpNormal
  4. Sources officielles. Four ingested documents, each with a full SHA-256 and status INGESTÉ & VÉRIFIÉ: a BEAC auction bulletin, a BVMAC official list, a BEAC policy-rate decision, and a Cameroon official-journal decree on bond issues.

detectAnomaly(), if called, would mark |z| ≥ 3 as an investigation signal and |z| ≥ 2 as a watch. The page does not call it. The cards are the seed the service returns from getRecentAnomalies().

Terms.

  • Brief du matin. A one-page note a research desk publishes before the market is busy. The 08:00 badge is the product’s publishing slot.
  • Sigma (σ) and z-score. Sigma is the historical standard deviation of the series. Z = (today − average) / sigma. +2.41σ means this Gabon auction was 2.41 typical deviations above the 6.12% average. The page’s rule of thumb is that beyond 2σ you investigate. It is a screen, not a trading signal by itself.
  • Taux limite / taux marginal. The cutoff yield at which the auction stopped accepting bids. Taux moyen pondéré (TMP) is the average yield of the accepted bids, weighted by size. The marginal rate is usually worse than the average.
  • Couverture (B/C). Bid-to-cover, same idea as on the curve ledger.
  • Anomalie. On this page, a statistical outlier in an auction, not a document contradiction.
  • Veille. Monitoring of official sources. Research is the same screen with a research header, so a “research” workflow here means reading the brief and the sources, not a separate library.
  • SHA-256 on a source. The fingerprint of the official PDF the sentence claims to come from. The hashes in the seed are identifiers, not hashes computed in the browser from a downloaded bulletin.
  • Surliquidité. Banks holding more central-bank reserves than they need. The brief says that surplus is uneven and concentrated in Douala and Libreville, which is why Cameroon bill auctions can be heavily oversubscribed.
  • Inflation −40 bp. The macro card’s change in the inflation rate, in basis points, not a bond spread.

Business value. A research analyst and a portfolio manager need to know, before they price SEEG or bid a treasury auction, whether the sovereign curve just moved for a statistical reason. A weak Gabon cover (1.10x) and a +35 bp jump is a reason to demand more spread on any Gabon credit, including a utility. The decision is whether today’s move is noise or a change in the reference curve the structuring tab uses.

Use case. Read the brief’s Gabon bullet, open Anomalies, confirm +2.41σ and 1.10x cover, then Ouvrir dans le Terminal Taux and look at Gabon’s 3-year point on the curve. Use Sources if you need the bulletin name and hash to cite in a memo. The Research sidebar item is the same path with the title Veille et recherche, for people whose job is the note rather than the alert.

Next. Sovereign curves. Institutional memory, if you want the last time a Gabon credit was approved in a similar rate environment.


KNOWLEDGE ​

KNOWLEDGE is what the institution already learned: past deals, life after closing, and the committee memo for the deal that is open now.

Institutional memory ​

Route/workspace/institutional-memory
SidebarInstitutional Memory

Purpose. Look up how this institution structured similar deals, which covenants it imposed, and whether those deals later paid and complied.

What it does. Title Mémoire institutionnelle. Metrics and cards come from GET /api/locus/precedents (precedents + post-close outcomes). Promote a CLOSED dossier with POST /api/precedents/promote. Fresh tenants see an empty memory until something is promoted.

Tabs:

  • Comparables. Search/filter over SoR precedent rows (country filters built from loaded data).
  • Post-clôture. Outcomes linked to promoted deals when recorded at promote time.

Terms.

  • Comparable / précédent. A past deal similar enough that its spread, covenants, and conditions are evidence for the one you are structuring now. It is not a statistical sample. Three cards are a memory, not a market database.
  • Committee outcome. Approved, approved with conditions, or declined. Conditions are the CPs you already saw: BEAC filing, DSRA, concession extension.
  • Spread / courbe. The margin versus the sovereign curve at pricing, in basis points. SEEG at +220 bp over the curve is a much wider credit spread than BDEAC at +50 bp, which matches a development bank versus a utility.
  • Post-clôture. Monitoring after signing: did they pay, did a covenant break, was the bridge refinanced.
  • IRR (TRI, taux de rendement interne). The annual rate that sets the present value of the actual cash flows to zero. A realized 7.85% means the money the lender actually earned, which can differ from the coupon if fees, delays, or an early refinance changed the timing. The card prints the stored percent. It does not solve an IRR from a cash-flow table.
  • Technical default. A covenant or paperwork breach while payments are still being made. Payment default means a missed interest or principal payment. Performing means neither, in this enum.
  • Waiver. Mentioned in the tab subtitle as how breaches were managed. The SEEG outcome describes a cure (the ratio recovered), not a waiver document.
  • DSRA maintenu à 100%. The reserve account stayed full. That is the post-closing test of the mitigant the credit lab recommends.

Business value. Committees hate being shown a structure that ignores what the same institution accepted last time. Memory answers “what did we require of SEEG in 2022, and did it hold?” The decision is whether this new mandate’s covenants are tighter or looser than the precedent, and whether the old DSCR breach means the 1.20x floor was already too tight.

Use case. Filter to Gabon. Read the 2022 SEEG loan: the same three covenants (3.5x, 1.2x, 2.5x) and the same three risks as the live file. Open Post-clôture and read that DSCR did touch 1.02x and was cured, and that the bridge was refinanced. Take that into the memo as the precedent, not as a prediction.

Next. The memo.

Reports and memos ​

Route/workspace/memo-drafter
SidebarReports & Memos

Purpose. The committee paper for the open deal, written as sourced facts, calculated inferences, and open questions.

What it does. Title Mémorandum de diligence. Actions: Copier (briefly becomes Copié), download .md, and Imprimer.

A legend defines the reading method: Fait sourcé (a fact with a source), Déduction calculée (an inference), Question ouverte (unresolved). The letterhead is L’Archer Securities, Corporate Finance & Debt Syndication, then the operation name, the issuer, the draft date, and Interne / Comité d'Engagement.

Each statement is badged FAIT, DÉDUCTION, or QUESTION. A citation button opens the PDF. If the document id starts with ohada-, cosumaf-, beac-, cobac-, or cg-, the button is labeled as an official text. Deal PDFs show the file name and page. The downloadable markdown keeps the raw statement type (FACT, INFERENCE, OPEN_QUESTION) and quotes the citation.

Data. currentProject.memo. The default open deal is PAPN, so the first memo you see is the port memo, which has no citations. SEEG, Eneo, and SNPC have their own memos. Stored projects can override the memo.

PAPN (default): a 75 million euro container-terminal extension. Facts: 1.1 million TEU a year, 49.20 billion FCFA, a 250 meter quay extension, dredging to −16 m for New-Panamax ships. Inference: 2024 net debt / EBE at 1.19x, with EBE margin 32.6% on revenue of 108.4 billion. Open question: the BDEAC DSCR floor is 1.40x and the syndicated documents say 1.25x, and that gap can create a cross-default.

SEEG memo, dated 30 September 2026, is the one that matches the rest of this guide:

  1. Mandate of 53.4 million euros. Inference: net debt 87.90 billion, EBE 34.85 billion, leverage 2.52x versus a 3.50x cap. Fact: the bridge ends 30 June 2025 and must be repaid by a BVMAC bond.
  2. Concession ends 31 December 2028. Open question: the bond runs to November 2031, 35 months past the handback of assets. A sovereign comfort letter or a concession extension is an imperative CP.
  3. Revenue grew from 178.2 billion in 2021 to 198.45 billion in 2023, and the EBE margin from 16.6% to 17.6%. Inference: ICR 3.20x using EBIT 16.65 / interest 5.20, above 2.50x. Fact: cash 14.80 billion, of which 4.20 billion is escrowed, so free cash is 10.60 billion.
  4. Open questions: the 6.75% versus 7.20% margin, and the pledged escrow versus negative pledge article 12. A waiver or a specific carve-out is required.
  5. Inferences with no citations: favorable opinion subject to reserves, because of the concession monopoly and 2.52x leverage; CP 1 is a Gabon confirmation that the concession continues past 2028; CP 2 is a cleaned-up negative pledge and one syndicate coupon.

Eneo’s memo is a 62 million euro restructuring and solar facilities, with the open question of an escrow fed by large industrial customers. SNPC’s memo is a 110 million euro prefinancing, with the open question of an intercreditor agreement before the BVMAC order book opens.

Terms.

  • Fact versus inference versus question. A fact is something a document says. An inference is a ratio or a judgment built from facts. A question is not yet decided. The product’s claim is that a committee memo that blends these three is how errors enter the minutes. The badges are the control.
  • Comité d’engagement. The commitment committee, the meeting that binds the arranger or the lender. The memo is the paper for that meeting.
  • Lettre de confort. A letter from the state that is morally or politically supportive and often not a full guarantee. The SEEG memo asks for one, or for a real concession amendment. They are not the same legal strength.
  • Intercreditor agreement. A contract between lenders who have different pledges, deciding who gets paid first. SNPC’s memo says the cargo pledge is already granted to someone else, so the new bond cannot open an order book until that ranking is written down.
  • TEU and New-Panamax. The PAPN facts. A TEU is a twenty-foot container. New-Panamax is a ship size. They explain why the port is borrowing. They are not credit ratios.
  • Cross-default inside the memo. PAPN’s question is the practical version: two contracts with two DSCR floors means a breach of the tighter one (1.40x) can pull the other loan into default.

Business value. This is the deliverable the securities edition’s north star measures: time from mandate to an approved memo. Everything else in the workspace is evidence for or against the sentences on this page. The decision is the last section: favorable with CPs, or not ready.

Use case. Switch the URL to the SEEG deal. Read section 5 and check that each CP has a matching open question in sections 2 and 4 and a matching card on the risk register. Download the markdown if you want to diff it in git. Do not treat PAPN’s uncited inferences as sourced; the legend says a fact should carry a source, and that memo has none.

Next. Profile, if the name on the attestation and the audit log should be yours. Or back to the risk register to align statuses with the CPs you just read.


Profile ​

Route/workspace/profile
Opened fromAccount menu Profil, not the main sidebar

Purpose. The name, email, and role printed on visas, memos, and the audit log.

What it does. Title Profil. One panel. Initials come from the first two words of the name (seed IK). You can edit Nom and Adresse (email). Rôle and Institution are read-only. Enregistrer is disabled when either editable field is blank. Success text: Profil enregistré. Saving writes currentUserName and the current team member’s name and email through the organization profile. It does not change the role.

Defaults follow the authenticated session (full name, email, role, institution). Local seed/demo builds may still show the historical persona Inéfable Koumba / L’Archer Securities when demo mode is on.

Terms. There is no financial term that is special to this page. The role titles are the six jobs in the table at the top of this guide. The page shows the long title, not the short sidebar label.

Business value. An audit trail with a shared login is not an audit trail. The name on this page is what Q&A approvals and memo letterheads should be able to attribute. Today, Q&A still uses the persona switcher (Alexandre Mandji and the others) rather than this profile. The profile is the session identity the shell shows in the sidebar.

Use case. Set your name and email before you export a COSUMAF attestation or a memo, so the pack does not go out under the seed name.


A full pass on the SEEG file ​

Use this when you want to see how the pages depend on each other. Start at:

text
/workspace/deals?project=deal_seeg_refinancing_2026

The story, in one paragraph: L’Archer is arranging the refinancing of a 53.4 million euro bridge for SEEG, Gabon’s water and power concessionaire. The take-out is a BVMAC bond running to 2031. The concession ends in 2028. The signed loan margin is Euribor + 7.20% and the term sheet says + 6.75%. Audited EBE is 34.85 billion FCFA and a presentation uses 42.1 billion. Net leverage is about 2.52x against a 3.50x cap. Several screens say DSCR is about 1.08x against a 1.20x floor. A 4.2 billion FCFA escrow is already pledged, against a negative pledge. The tax clearance and the BEAC Article 42 filing are missing.

Walk it in the order a mandate actually moves:

  1. Deals. Confirm SEEG is the active dossier and note the contradiction count.
  2. Data room. Open the accounts, the loan, the term sheet, and the concession. Leave sources visible.
  3. Completeness. Read the fatal gaps (tax quitus, BEAC declaration) and the deficient concession and escrow items. Generate a chase letter.
  4. Q&A. Publish the margin answer as the lead arranger so the syndicate has one number.
  5. Graph. Select the concession path, then the negative-pledge path, and open the source documents from the nodes.
  6. Financials. Confirm EBE 34.85 billion and the pledged long-term debt note.
  7. Ratios. Read leverage near 2.52x. Move the revenue and rate sliders. Remember this DSCR uses a 1.30x floor and the CFADS formula.
  8. Credit lab. Run the state-arrears preset and the severe preset. Write down the verdict and the DSRA condition.
  9. Review grids. See the disputed margin and the DSCR row at 1.08x. Leave the disputed cell unverified.
  10. Contradictions. Read the four pairs, including the EBITDA definition.
  11. Risk register. Assign the concession issue as the critical CP. Leave the margin with the lead arranger.
  12. Regulatory. See the same contradictions as legal findings, and the BEAC currency point if the profile is not XAF.
  13. COSUMAF auditor. Score the note. Treat blockers as filing stops. Print the attestation only as an internal sheet.
  14. Curves. Price a 5-year Gabon-spread bond and read DV01 and the +25 bp underwriting loss.
  15. Portfolio. Open the book, confirm the SEEG holding, run a +50 bp rate stress, and note any open limit exceptions.
  16. Market radar. Check whether Gabon’s latest auction is the +2.41σ anomaly before you lock the spread.
  17. Memory. Compare with the 2022 SEEG bridge, which used the same covenant set and later cured a 1.02x DSCR.
  18. Memo. Read section 5. The two CPs should match the risk register. Export markdown for the committee pack.

PAPN is the default deal and a quieter file (a port expansion, a DSCR-floor conflict between 1.40x and 1.25x, no citations on the memo). Eneo is the committee-stage Cameroon credit with public-sector arrears. SNPC is the Congo oil prefinancing that needs an intercreditor agreement. Use them when you want to see what is project-specific (the memo, the data room, the financial periods, the contradiction list) and what stays SEEG-shaped anyway (the review grid, the graph labels, the completeness template, the issuer fallback).


Platform updates (October 2026) ​

This section summarizes capabilities that landed after the first workspace guide pass. Details live in the linked docs and trackers (IMPLEMENTATION_TRACKER.md, TECHNICAL_PRESENTATION.md).

Authentication (credentials + mandatory OTP) ​

  • No OIDC / SAML. Enterprise SSO routes and modules were removed.
  • Register (/register, BFF POST /api/auth action=register → SoR POST /api/auth/register): creates Organization + INSTITUTION_ADMIN membership, then requires OTP before any session is issued.
  • Login always returns mfaRequired. Password alone never sets a cookie. OTP (/auth/otp, action=otp → SoR LoginOtpService) issues AuthSessions and a browser cookie.
  • Session cookie is an HMAC-SHA256 ticket v1.<payload>.<sig> signed with SESSION_SIGNING_KEY (session-ticket.ts). Edge middleware rejects missing, forged, or expired tickets — cookie presence alone is not enough. There is no LOCUS_DEMO_MODE bypass.
  • Public auth routes: /login, /register, /auth/otp, /auth/forgot-password, /auth/reset-password.
  • Tests: tests/auth_otp_and_register.test.ts, tests/auth_screens_and_credentials.test.ts, tests/session_ticket_middleware.test.ts.

System of record (Postgres + C#) ​

  • ASP.NET Core API (locus-backend, port 5000) owns dossiers, documents, OCR pages, blockers, portfolio, market overview, precedents, access requests, members, search index, audit events (AuthSessions for identity).
  • Next.js BFF under /api/locus/* uses requireBffSession + Bearer forwarding; mutating routes pass Zod validation.
  • Fail-closed EF Core tenant query filters on all organization-scoped entities; audit events form a per-tenant SHA-256 hash chain.
  • Workspace SSR loads deals and organization profile; client refresh uses TanStack Query (not localStorage as SoR).
  • Canonical deal ids are SoR deal_* values (canonical-ids.ts); UI aliases (including legacy proj_* / short names) resolve on the BFF.

Document vault, OCR, and queues ​

  • Deal Room upload → R2 private object + Document row + OCR enqueue + search index.
  • AES-256-GCM at rest when DOCUMENT_ENCRYPTION_KEY_HEX is set (production fails closed without it). Downloads go through the BFF decrypt proxy /api/locus/documents/{id}/content.
  • Tesseract OCR (fra+eng) on locus-workers (POST /api/v1/ocr); BFF escalates unreadable harvests to the worker.
  • Redis / BullMQ when REDIS_URL is set (production fails closed); document OCR and analysis jobs are async. Analysis: POST /api/locus/deals/{id}/analysis → poll GET /api/locus/analysisjobs/{jobId}.

Deploy (Coolify / VPS) ​

  • One Dockerfile per tier: locus-web, locus-backend, locus-workers. Secrets are Coolify/Docker runtime env only (not baked into images). See .env.example files.

Copilot grounded path ​

  • Agentic tool router with certified quantitative tools (src/copilot/tools/registry.ts).
  • Multi-turn conversation memory with contextual pronoun and conditional follow-up resolution (src/copilot/agent.ts).
  • Fail-closed financials; live deal tools; tenant ids from Workbench; scope enforcement for regulatory_corpus.
  • Async path: engine → RAG (/api/locus/search) → optional LLM polish (COPILOT_LLM_PROVIDER=off by default).
  • Tests: tests/intelligence_copilot.test.ts, tests/copilot_retrieval_and_llm.test.ts, tests/copilot_agent_and_tools.test.ts.

Portfolio domain ​

  • Full book workspace (overview, holdings, exposures, scenarios, exceptions, attribution, construction) with deterministic /portfolio copilot tools.
  • Tenant book from Postgres: GET /api/locus/portfolio → SoR PortfolioController (financial:read). UI maps via mapSorBookToDomain then runs BondMath valuations. Empty tenant holdings → empty state (never injects another org’s demo book). SoR errors surface an error state — demo seed is never injected into the workspace.
  • Seeder upserts the full CEMAC book (8 holdings, masters, limits). Tests: tests/portfolio_sor_book.test.ts.

Landing & access ​

  • Public landing reframed around capabilities / journey (not a single SEEG case study as the hero story).
  • Access-request submit/verify remain on the bank BFF (/api/locus/access-requests*). Operator approve/reject/provision UI lives in locus-ops /access-requests (not under bank /workspace).
  • Self-serve register provisions a tenant when the corporate domain is free.

Fail-closed integration (slice 26) ​

  • SoR is the durable authority: deal mapping no longer overlays demo seed financials/contradictions; authenticated empty tenants stay empty.
  • BFF alerts, reconciliation, and cell override return 502 when Postgres is unavailable — no DOMAIN_MIRROR Map fallback.
  • Logout revokes AuthSessions in C# (POST /api/auth/logout); BFF resolves sessions via SoR only.
  • Analysis pipeline uses POST /api/locus/deals/{id}/analysis (legacy /api/pipeline → 410).
  • Portfolio workspace fails closed on SoR errors (no demo book injection). Precedents exposed at /api/locus/precedents.
  • Domain Map services start empty; CEMAC reference data is loaded only in tests via tests/fixtures/cemac.

Postgres RLS, FTS, SoR sessions (slice 27) ​

  • Native RLS (FORCE) on org-bearing and dossier-child tables via migration 20261012080000_PostgresRlsAndTsvectorSearch. Policies use GUCs app.current_tenant_id / app.is_platform_operator (locus_tenant_ok). Users / AuthSessions / AccessRequests stay outside FORCE RLS so pre-claim auth works.
  • GUC wiring: TenantRlsConnectionInterceptor applies set_config before every command; TenantRlsMiddleware copies claims after InstitutionalAuthMiddleware. Register/login/seed use explicit bypass.
  • SearchDocuments french tsvector (generated) + GIN; SearchController ranks with plainto_tsquery('french', …).
  • Sessions: BFF + workspace layout resolve only via SoR fetchSorSession — the in-memory Map is local/test cache only (empty authority in production).
  • Copilot stream: POST /api/copilot/polish-stream (SSE) via polishCopilotProseStream; fail-closed to deterministic draft when COPILOT_LLM_PROVIDER=off.
  • Tests: tests/rls_tsvector_session_stream.test.ts.

Fresh tenant / zero mock runtime (slice 28) ​

Product journey (only path): register organization → OTP → empty workspace → create dossier → upload documents → analysis/search/portfolio from SoR only.

  • Workbench never falls back to INITIAL_PROJECTS; empty tenants see an empty shell + CTA to create a dossier.
  • AlertsController does not auto-seed alerts; Alerts UI has no local SEEG catalog fallback.
  • Client generators (risk, review grids, deal graph, diligence, Q&A) and catalogs (global search, issuers, market, FI, blotter) return empty until SoR-backed data exists.
  • Org profile never merges a branded demo firm; Seed:RunOnStartup defaults to false; migrate-failure path never seeds.
  • LOCUS_DEMO_MODE and demo credential stores removed from runtime. CEMAC reference packs live under locus-web/tests/fixtures/cemac for tests only.
  • Manual smoke: register a real corporate domain → confirm empty deals/alerts/portfolio/search → create dossier → upload → search returns that tenant’s docs only (no SEEG strings).
  • Tests: tests/fresh_tenant_runtime_guard.test.ts, tests/fresh_tenant_services_empty.test.ts.

Citation grounding (slice 34 / R4) ​

  • SYSCOHADA extract sets ExtractedCell.SourceCitationId when OCR word boxes match the line; otherwise null (no fake bbox).
  • Contradiction alerts hydrate page / filename / bbox from SoR Citation rows; missing boxes are null.
  • Ratio cockpit shows Voir source when a citation exists; Financials / review grids / Contradiction radar open the PDF viewer. Highlight is skipped for missing or degenerate boxes.
  • Analyst override SOP: ocr-override-sop.md.
  • Platform tables: instruments, editions, provisions, artifacts, review items, amendments, provision applicability.
  • Ops pipeline: Source Registry → Fetch PDFs / Check listing → Extract → Review → VaultPublisher (never auto in-force).
  • Change detection: listing fingerprint + SHA mismatch on known URLs → HASH_CHANGE review.
  • Optional scheduler: LEGAL_VAULT_WATCHTOWER_INTERVAL_MINUTES on the SoR host.
  • CI fixtures and how PDFs are attached: regulatory-data.md.

Platform ops (locus-ops) ​

Not a bank workspace. Dedicated Next.js app (default http://localhost:3001), cookie locus_ops_session, SoR permission system:manage / role PLATFORM_OPERATOR.

RoutePurpose
/loginPlatform password + OTP (rejects non-PLATFORM_OPERATOR)
/regulatorySource Registry, Legal Vault, Review Queue, Applicability, Ingestion Logs
/access-requestsApprove/reject institutional onboarding; provision tenant + admin
/marketPaste/upload market ingest JSON for a target tenant org (PLATFORM_OPERATOR override)

Default seeded operator (only when Seed:RunOnStartup=true / LocusDbSeeder runs — off in production by default):

FieldValue
Emailops@locus.platform
PasswordLocus@2026!Seed
User idusr_platform_ops
MembershipDemo org org_larcher_securities (role PLATFORM_OPERATOR)

Production Coolify deploys must create or seed an ops user explicitly.

Legal vault PDF attach

  1. Prefer ops UI: Legal Vault → select edition → Upload PDF (R2 or local vault).
  2. Dev/CI: data/regulatory/fixtures/ + ./scripts/attach-vault-fixtures.sh — see regulatory-data.md.
  3. Review Queue → set instrument id → Approve & publish → LegalVaultPublisher creates/links edition; prior in_force becomes historical.

Bank analysts never write vault editions. They only read resolved statutes via open-statute when findings carry vault artifact ids.


data/regulatory — purpose of the PDFs ​

Short version (full detail in regulatory-data.md):

PathWhat the PDFs / files are
data/regulatory/fixtures/*.pdf (repo root)Tiny synthetic PDFs for CI/dev bootstrap of vault editions. Used by attach-vault-fixtures.sh and ops tests. Not official gazettes; digests must not be claimed as production source hashes.
locus-web/data/regulatory/Parsed JSON / SQLite corpus feeding catalog.ts and retrieval until vault provisions are legally reviewed. Not the R2 vault.

Flow for fixture PDFs: generate → attach as LegalSourceArtifact → extract → human approve → publish edition → analyzeDealWithVault can resolve artifact ids → open-statute streams the PDF.


Glossary ​

One sentence each. Pages above hold the formulas. Numeric examples in older chapters that mention SEEG are test-reference math, not product defaults.

Alpha. A price that disagrees with the model curve. On the curve terminal, a bond yielding at least 30 bp more than the curve is marked cheap.

Amortissement (accounting). Spreading the cost of a long-lived asset over its life. It reduces EBIT and is not the same as repaying a loan.

Amortissable. A bond or loan that repays principal in installments.

Appel public à l’épargne. Offering securities to the public. It requires a COSUMAF visa and an information note.

Arranger / chef de file. The bank that organizes the financing and speaks to the syndicate.

Arriérés. Payments that are overdue. In these files, often the state paying a utility late.

Assiette de sûreté. The assets a pledge actually covers.

Attestation. A signed statement. On the COSUMAF page, the printable pre-visa sheet.

AUM. Assets under management. The market value of portfolios the firm runs.

BEAC. The Bank of Central African States. It runs monetary policy and the treasury-auction system.

Basis point (bp). 0.01 percentage point. 45 bp is 0.45%.

Bid-to-cover. Amount bid divided by amount offered at an auction. Below about 1.2x is treated as a weak sale in this UI.

Bilan. The balance sheet. Assets equal equity plus liabilities.

Blotter. A list of bonds or loans. The instruments page is a market blotter, not a record of the firm’s holdings.

Bridge loan / prêt-relais. Short-term debt meant to be repaid by a later bond or loan (the take-out).

BTA. Short treasury bill, auctioned in weeks (13, 26, 52).

Bullet / in fine. All principal repaid on the final date.

BVMAC. The regional securities exchange where CEMAC bonds are listed.

BFR. Cash tied up in operations: inventory and receivables, minus payables. More BFR means less free cash.

CAC. The statutory auditor who certifies SYSCOHADA accounts.

Capex. Cash spent to acquire or renew fixed assets. Subtracted in this app’s CFADS definition.

CEMAC. The six-country central African monetary community that shares the CFA franc.

CFADS. Cash flow available for debt service. Here: EBE minus tax minus capex.

Chinese wall / mur d’information. An internal barrier so one team cannot see another team’s confidential deal.

Clean price. Bond price excluding accrued coupon. This pricer sets it equal to the dirty price on the issue date.

Closing. Signing and, usually, funding.

CNSS. The social-security body. A clearance certificate says payroll contributions are current.

COBAC. The regional banking supervisor.

Comité de crédit / comité d’engagement. The internal meeting that approves a loan or a mandate.

Commission d’arrangement. The fee for organizing the deal. The structuring tab suggests a floor that rises with duration.

Comparable. A past deal used as evidence for spread and covenants.

Compte séquestre. An escrow account. Subscription escrow holds investors’ money until the offer closes. A DSRA holds debt-service cash.

Concession. A state contract allowing a company to operate a public service until a date.

Condition préalable (CP). Something that must be true before money is drawn.

Contrat de prêt. The long-form loan agreement. It prevails over a term sheet once it is signed, unless the parties amend it.

Convexity. The curvature of a bond’s price as yields change. Computed in bond math and not shown as a terminal KPI.

Corpus. The library of statutes the regulatory engine may cite.

COSUMAF. The regional capital-markets regulator. It visas public offerings.

Coupon. The stated annual interest as a percent of face value.

Covenant. A contractual financial or legal promise that is tested on a schedule. A breach can accelerate the loan.

Créances douteuses. Loans a bank already doubts will be repaid in full.

Cross-default. A clause that puts this loan in default if the borrower defaults on other debt above a threshold.

Curation. How thoroughly a legal text has been checked before the engine cites it.

Debt service. Principal due plus interest due, over the test period.

Déchéance. Losing the concession and handing the assets back to the state.

Dépositaire. The institution that holds the securities for investors.

DGI. The national tax directorate. A quitus is its clearance certificate.

Diebold-Li. The Nelson-Siegel curve written so the three betas can be estimated from yields. The HUD names it.

Dirimant. Fatal for closing or for the committee. Not a follow-up item.

Dirty price. Clean price plus accrued coupon since the last payment date.

Discount factor. Today’s value of 1 unit of currency received in the future, at the curve’s rates.

Dividend block. A promise not to pay dividends while a ratio is below a floor.

Dossier. The deal file: documents, numbers, and the committee story.

DSCR. CFADS divided by debt service. Under 1.0x, cash does not cover this period’s debt payments.

DSRA. A reserve account holding several months of debt service.

DSO. Days sales outstanding. How long sales sit unpaid in receivables.

Duration, Macaulay. The weighted average time until the bond’s cash flows, weights being present values.

Duration, modified. Macaulay duration divided by (1 + yield). Approximate percent price fall for a 1% yield rise.

DV01. Money lost if the yield rises by one basis point.

EBE. SYSCOHADA operating surplus before interest, tax, and depreciation. The local name for the EBITDA lenders use.

EBIT / REX. Operating profit after depreciation.

Encours. Principal still outstanding.

Escrow. See compte séquestre.

Euribor. A euro interbank reference rate. Loans here are quoted as Euribor plus a margin.

Facility. One debt contract (the bridge, or the bond).

Fatal blocker. A missing or broken item that stops the closing checklist.

FCFA / XAF. The CFA franc used in CEMAC. The app converts euros at 655.957.

Forward rate. The future interest rate implied by today’s curve.

FRNG. Long-term financing minus fixed assets. Positive means long-term funds cover the fixed assets and help fund operations.

Gearing. Net debt divided by equity. Computed in the ratio engine and not shown on the cockpit cards.

Headroom. Distance between the actual ratio and the covenant limit.

ICR. Interest coverage. On the cockpit, EBIT divided by interest. On the review grid, a hardcoded figure labeled as EBE over interest.

In fine. See bullet.

Intercreditor agreement. A contract among lenders that sets who is paid first.

IRR / TRI. The annual rate earned on the actual cash flows of a deal.

ISIN. The standard identifier of a security.

Issuer / émetteur. The entity that owes the debt.

Levier. Net debt divided by EBE, unless the screen says percent of GDP for a sovereign.

Lettre de confort. A supportive letter, often from the state, that is weaker than a guarantee.

Livre d’ordres. The list of investor orders for a new bond.

LMA. The Loan Market Association, whose templates are a reference for syndicated-loan clauses. The product mentions the style; it does not ship the LMA documents.

Mandate / mandat. The borrower’s instruction to the arranger to raise the financing.

Marge. The spread over Euribor, or more generally the extra yield over a reference.

Masse des obligataires. The legal grouping of bondholders and their representative.

Maturité. The date principal is due, or the length of the instrument.

MNPI. Material non-public information. The reason a Chinese wall exists between arranging a deal and buying the bond.

Nantissement. A pledge over an asset or an account.

Negative pledge. A promise not to pledge assets to someone else.

Nelson-Siegel. A smooth yield-curve formula with a long-run level, a slope, a curvature, and a decay speed.

Note 14. A numbered note in the financial statements. In this file, the note that discloses the pledged escrow.

Note d’information. The disclosure document for investors. The COSUMAF auditor reads it as the prospectus.

OHADA. The treaty system of uniform business laws used in West and Central Africa.

OTP. One-time password emailed at every login (and after register). Required before Locus issues a session cookie.

OTA. A longer-dated treasury bond, as opposed to a BTA bill.

Par. A price of 100. Above par is a premium. Below par is a discount.

PIB. GDP. Used on the sovereign issuer card as debt divided by the size of the economy.

Pipeline. The set of mandates being worked, from first pitch to committee.

Placement privé. A sale to a limited set of professional investors, not a public offer.

Playbook. A named, ordered diligence procedure.

Post-closing. An obligation to deliver something after signing, or the monitoring period after closing.

Prêt marginal. BEAC’s emergency lending rate for banks.

Price (bond). Percent of face value you pay today.

Pro forma. A figure adjusted for a hypothetical event. A “normalized EBITDA” in a slideshow is not the audited EBE.

Prospectus. The public disclosure document. In this product the working name is often note d’information.

Quitus fiscal. A tax-clearance certificate.

Ratchet. A clause that changes the margin or a covenant when a ratio deteriorates.

Rating / notation. An agency’s grade of credit quality, plus an outlook.

RCCM. The OHADA register where companies and pledges are filed.

Refinancement. New debt raised to repay existing debt.

Réserve. A softer failure. For an auditor, a qualification of the accounts. For the COSUMAF scorer, a warning that does not by itself reject the visa score.

RMSE. Typical size of the curve’s miss versus the auctions it was fitted to.

R². Share of variation the curve explains. Near 1 means auctions sit close to the curve.

Session ticket. HMAC-signed locus_session cookie (v1.…) verified by Edge middleware with SESSION_SIGNING_KEY. Forged or expired tickets do not open /workspace.

SHA-256. A fingerprint of a file. Any change in the file changes the fingerprint.

Souverain. The state as borrower. A sovereign curve is the treasury’s yield curve.

Spread. Extra yield versus a reference (BEAC, or another sovereign).

Steepener. A position that gains if long-term yields rise relative to short-term yields.

Stress test. Recomputing ratios or prices under deliberate bad assumptions.

Subordination. Debt or dividends that rank behind senior lenders.

Syndication. Several banks sharing one loan under one arranger.

SYSCOHADA. The OHADA chart of accounts and financial statements.

Take-out. The later financing that repays a bridge.

TCAM. A compound growth rate. The financials column with this title shows a simple change from the first period to the last.

Teaser. A short introductory document for potential lenders, not the contract.

Tenor. The length of a bond or loan.

Term sheet. The short commercial summary that precedes the full contracts.

TIAO. BEAC’s main policy auction rate.

TMP. The weighted-average accepted yield at a treasury auction.

Underwriting / prise ferme. The arranger’s promise to buy bonds investors do not take, and therefore to hold price risk.

Valeur ajoutée. Sales minus consumed inputs. In a clean SYSCOHADA file, value added minus personnel equals EBE.

Variance. On the contradiction page, the size of a disagreement between two documents.

VDR. Virtual data room. The controlled document space for a deal.

Visa. COSUMAF’s authorization of a public offering.

Waiver. A lender’s agreement to forgive a breach for a stated period.

Watchlist. Borrowers under heightened monitoring, short of default.

Yield / taux actuariel. The single annual rate that equates a bond’s price to its future coupons and principal.

Yield curve. Yields of one issuer plotted against maturity.

YTD. From the start of the calendar year to today.

Z-score. How many standard deviations a point sits from its mean. On Market Radar this is a real distance from a stated mean and sigma. On the sovereign spread matrix it is the display formula spread in bp / 35 − 2.5.

Zero coupon. A bill that pays no coupon. You buy it below 100 and earn the pull to par.

Source of trust for Locus. If this conflicts with code, code + IMPLEMENTATION_TRACKER.md win.