Product Backlog

This document contains the product backlog for VisualOre.

Product Vision

Here we define what we consider to be the the vision for the product; what guides us when we think about the product and what can and cannot go into the product backlog.

Vision Statement

The vision for ORE Studio is to build on top of ORE with the aim of providing:

  • a persistent database storage for all of its inputs and outputs;
  • a graphical user interface both for data generation as well as data exploration;
  • the ability to configure and orchestrate ORE execution.

Vision Quotes

People think focus means saying yes to the thing you've got to focus on. But that's not what it means at all. It means saying no to the hundred other good ideas that there are. You have to pick carefully. I'm actually as proud of the things we haven't done as the things I have done. Innovation is saying no to 1,000 things. – Steve Jobs

Release Checklist

Steps to create a new release.

Close previous sprint

To be done on the last Sunday of the sprint.

  1. Make a copy of current sprint backlog and name it current sprint + 1.
  2. Move all untouched stories into product backlog.
  3. Close current sprint: close all open tasks, delete tasks we did not work on, update clocks.
  4. Push commit and wait for builds. This ensures that if there are any failures you can fix them before the release tag.
  5. Tag commit and sign it with key.
  6. Push tag. You can generate new builds overnight.
  7. When tag build is finished, unpack and copy binaries into release, announce twitter and linked in.

Open new sprint

Note: use Claude to do this via the New Sprint Skill.

  1. Open new sprint, updating CMake version, README, GitHub (packages), vcpkg.json. Build all and run tests. This should all be in one commit.
  2. Create a demo. Publish it on youtube.
  3. Write up release notes, publish them in github.

Stories

Near

Stories we may get two in the next two or three sprints.

ORE Sample Data   code

We added examples and XSDs from ORE. We should consider some improvements to this dataset:

  • remove unnecessary files (notebooks, pngs, pdfs, etc).

C++ Complexity Measurements   code

Since we are no longer taking a close look at the generated code and since Gemini code review does not catch all issues, we should try to find some automated tools to measure complexity and point to places where generated code is not ideal.

Links:

  • GH: metrixplusplus: "Metrix++ is an extendable tool for code metrics collection and analysis."

Create python script to split xsdcpp output   code

We are generating one very large file with all the types. This is not ideal. Also, this will probably not work for FPML as the schema is even larger.

Add a "is alive" message   code

We need to brainstorm this. At present we can only tell if a server is there or not by connecting. It would be nice to give some visual indicator to the user that the server is not up as soon as the user types the host. this may not be a good idea.

Notes:

  • could tell client if registration / sign-up is supported.

Change reason and categories need permissions   code

We need some very specific permissions as these are reg-sensitive.

Change reason not requested on delete   code

At present you can delete entities without providing a change reason.

Remember dialog sizes and positions   code

At present we need to resize dialogs frequently. We should write this to QSettings.

Accounts need to have a human or robot field   code

Look for correct terminology (actor type?).

Geo-location tests fail for some IP Addresses   code

Error is probably happening because the range is not supposed to be used.

<Catch2TestRun name="ores.geo.tests" rng-seed="3117545047" xml-format-version="3" catch2-version="3.12.0">
  <TestCase name="geolocation_result_default_construction" tags="[service][#geolocation_service_tests]" filename="/home/marco/Development/OreStudio/OreStudio.local1/projects/ores.geo/tests/geolocation_service_tests.cpp" line="38">
    <OverallResult success="true" skips="0" durationInSeconds="1.00031"/>
  </TestCase>
  <TestCase name="lookup_with_boost_asio_address" tags="[service][#geolocation_service_tests]" filename="/home/marco/Development/OreStudio/OreStudio.local1/projects/ores.geo/tests/geolocation_service_tests.cpp" line="90">
    <Expression success="false" type="CHECK" filename="/home/marco/Development/OreStudio/OreStudio.local1/projects/ores.geo/tests/geolocation_service_tests.cpp" line="102">
      <Original>
        result.error() == geolocation_error::address_not_found
      </Original>
      <Expanded>
        2 == 1
      </Expanded>
    </Expression>
    <OverallResult success="false" skips="0" durationInSeconds="1.00013"/>
  </TestCase>

We don't see anything in the logs:

2026-01-09 19:16:19.370327 [INFO] [ores.testing.test_database_manager] Database context created successfully
2026-01-09 19:16:19.370360 [DEBUG] [ores.geo.service.geolocation_service] Geolocation lookup for 10.0.0.1. SQL: SELECT country_code FROM ores.geoip_lookup('10.0.0.1'::inet)
2026-01-09 19:16:19.386331 [DEBUG] [ores.geo.service.geolocation_service] Geolocation lookup for 10.0.0.1. Total rows: 0
2026-01-09 19:16:19.386475 [INFO] [ores.geo.tests] Lookup result for boost::asio::ip::address
2026-01-09 19:16:19.386695 [DEBUG] [catch2] Section ended: lookup_with_boost_asio_address (assertions: 1)
2026-01-09 19:16:19.386741 [INFO] [catch2] Test case ended: lookup_with_boost_asio_address - PASSED
2026-01-09 19:16:19.386767 [INFO] [catch2]   Assertions: 1 passed, 0 failed, 1 total

We should write the assertions in the logs.

Add support for staging   code

  • on import, are we importing one currency at a time? should import the entire file.

Non-classified observations   analysis

Observations, snags and so forth that have not been analysed to form a proper story.

  • add configuration option not to confirm on quit.
  • no repository tests for change reason. We need to check all entities and the coverage.
  • qt code processing for network error messages is duplicated.
  • raw SQL in image repository, should be a function.
  • session should record if telemetry is enabled or not enabled.
  • bootstrap mode flag change does not generate new version.
  • it is possible to create a country without a name. likely a currency too.
  • should be possible to click on user and see user profile details. If the user is admin, show all details; if not, show only key ones like email, etc.
  • remove maximise button.
  • test suites need to log version at the start. info script needs to grep log for version for all suites.
  • no generators for roles and permissions it seems.
  • we still have the legacy password salt field.
  • should role permission tables have change reasons?
  • missing ores.analyser from system model.
  • add flag "is iso compliant" or some such for currencies and countries which are in the standard.
  • allow users displaying password in password boxes.
  • send and receive are empty in sessions.
  • next, can you explain the difference in window types between the main currency dialog and say currency history and currency details. we switched of minimise button on the currency history and currency details and that worked fine. we tried switching it off on the main currency window twice and that never seems to work. can we make all windows the same type? same as currency history / currency details.
  • merge common functionality between entities in ores.qt.
  • updating email from my account does not raise an event.
  • fictional countries should also have X prefixes
  • generate button should only exist in new, not edit.
  • no save button in currency list, need for generation
  • would be nice to be able to "locally modify" entity and then press save for the batch. in git we call this staging, what name should we use? and what icon?
  • server should peridically house keep sessions. if not connected, just mark it as orphan. also when connection is dropped mark session as finished.
  • shouldn't revert to version be a server side operation? e.g. current version, target version.
  • in the history diff, add a "from version" combo which shows either latest or previous.

Add a flag for human readable time   code

We should be able to use regular timestamps or human readable time.

Retrieve NAT'ed IP address from local IP   code

It would be nice to be able to resolve to the NAT'ed IP address. Gemini:

#include <iostream>
#include <string>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;

std::string get_public_ip() { try { boost::asio::io_context io_context;

    // 1. Resolve the address for api.ipify.org
    tcp::resolver resolver(io_context);
    tcp::resolver::results_type endpoints = resolver.resolve("api.ipify.org", "http");

    // 2. Connect to the server
    tcp::socket socket(io_context);
    boost::asio::connect(socket, endpoints);

    // 3. Formulate the HTTP GET request
    std::string request =
        "GET / HTTP/1.1\r\n"
        "Host: api.ipify.org\r\n"
        "Connection: close\r\n\r\n";

    // 4. Send the request
    boost::asio::write(socket, boost::asio::buffer(request));

    // 5. Read the response
    boost::asio::streambuf response;
    boost::asio::read_until(socket, response, "\r\n");

    // Check the status line (optional but recommended)
    std::istream response_stream(&response);
    std::string http_version;
    unsigned int status_code;
    response_stream >> http_version >> status_code;

    if (status_code != 200) {
        return "Error: HTTP Status " + std::to_string(status_code);
    }

    // Skip the HTTP headers
    boost::asio::read_until(socket, response, "\r\n\r\n");

    // The remaining data in the buffer (and what's left to read) is the IP
    std::string public_ip;
    while (boost::asio::read(socket, response, boost::asio::transfer_at_least(1), boost::system::error_code())) {
        // Keep reading until EOF
    }

    // Convert the body content to a string
    std::stringstream ss;
    ss << &response;
    public_ip = ss.str();

    // api.ipify.org returns only the IP as plain text in the body
    return public_ip;

} catch (std::exception& e) {
    return std::string("Exception: ") + e.what();
}
}

int main() {
        stdout::cout << "Fetching public IP..." << std::endl;
        std::string ip = get_public_ip();
        std::cout << "Your Public IP is: " << ip << std::endl;
        return 0;
}

Users should be able to add picture to profile   code

It would be useful to have avatars. We can then display those in other places.

Add support for protocol debugging in Qt   code

We should add a view of all messages sent and received like the comms champ tools. It should be possible to record a session to file (maybe all the requests?) and then replay that session. You should be able to do it from the UI.

Links:

  • GH: cctoolsqt: "This project contains tool application(s), which can be used to develop, monitor and debug custom binary communication protocols, that were developed using the COMMS Library. All the applications are plug-in based, i.e. plug-ins are used to define I/O socket, data filters, and the custom protocol itself. The tools use Qt framework for GUI interfaces as well as loading and managing plug-ins."
  • How to Use CommsChampion Tools: screenshots of the UI to explore the protocol.

Assorted UI polish work   code

Break these down into their own stories:

  • icons for CRUD are not enabling when on detached mode.
  • no status bar in dettached mode.
  • should we just have toolbars at the detached window level?
  • application should exit when main window is closed.
  • is it possible to dock windows like visual studio?
  • add a detach current window that just detaches that window.
  • disabled menu options are not properly greyed out. Done.

Instrument components with telemetry context   code

Now that logging has been integrated with telemetry, the next step is to instrument key components with the TLOG_SEV macro to enable trace correlation.

Tasks:

  • Instrument server_session with root span on connection, child spans per request.
  • Instrument client_session with spans for outgoing requests.
  • Pass telemetry_context through message handlers in ores.iam, ores.refdata, etc.
  • Add spans for database operations in ores.database.

Add modified since for all entities   code

We added support for this only for images. We need to update all types such as currencies etc with support for point in time gets.

Add widget to manage assets   code

We can't upload flags etc.

Merged stories:

Add an image browser

At present we can't add or remove images.

  • update existing image browser to show tags and allow switching them on and off.

Missing session properties   code

  • disconnect type: orphaned, client disconnect.
  • add version, commit, etc.

Update currency details to use tabs   code

We need a main tab with the currency related properties, then a "system" tab with temporal data which is read-only even on edit and a "image" tab with the image used to represent the currency. It could also contain some description or notes.

Locking an account should log user out   code

At present if you lock an account the user will remain logged in.

Review of Wt   code

Problems:

  • no icons in website for the tab.
  • no flags in currencies in wt.
  • no way of knowing about reload (eventing) in wt. we should make the reload button change colour?
  • currency edit window in wt is too large, can't see bottom of screen.
  • cannot edit account in wt.
  • iso code field too small, numeric code field too small
  • adding new account crashes wt. saving new currency crashes wt.
[2026-Jan-07 12:16:08.080] 1050920 - [access] "wthttp: 127.0.0.1   POST /?wtd=kh0IzYWIDev5vqgQ HTTP/1.1 200 271"
[2026-Jan-07 12:16:08.080] 1050920 - [info] "WebRequest: took 0.969 ms"
2026-01-07 12:16:15.578713 [TRACE] [ores.iam.repository.account_mapper] Mapping db entity: {"id":"019b9856-215c-7fd4-b139-11821e39d80a","version":1,"username":"newuser3","password_hash":"$scrypt$ln=14,r=8,p=1$wcZS3a7UEPEz8RBhIuOWIA==$vFYxagrQLQ1FXzMhP1u1D4xMJF2G4HMMsmoOxpRsdwYjSChBIsGiuA92cD8dPODlSYoG9uiX6SohLcUaZNUUUg==","password_salt":"","totp_secret":"","email":"newuser3@example.com","modified_by":"bootstrap","valid_from":"2026-01-07 12:02:20","valid_to":"9999-12-31 23:59:59"}
2026-01-07 12:16:15.578787 [TRACE] [ores.iam.repository.account_mapper] Mapped db entity. Result: {"version":1,"id":"019b9856-215c-7fd4-b139-11821e39d80a","recorded_by":"bootstrap","username":"newuser3","password_hash":"$scrypt$ln=14,r=8,p=1$wcZS3a7UEPEz8RBhIuOWIA==$vFYxagrQLQ1FXzMhP1u1D4xMJF2G4HMMsmoOxpRsdwYjSChBIsGiuA92cD8dPODlSYoG9uiX6SohLcUaZNUUUg==","password_salt":"","totp_secret":"","email":"newuser3@example.com","recorded_at":"2026-01-07 12:02:20.000000000Z"}
2026-01-07 12:16:15.578866 [DEBUG] [ores.iam.repository.account_mapper] Mapped db entities.
2026-01-07 12:16:15.578895 [DEBUG] [ores.iam.repository.login_info_repository] Reading all login_info.
2026-01-07 12:16:15.579395 [DEBUG] [ores.iam.repository.login_info_repository] Read all login_info. Total: 1
2026-01-07 12:16:15.579436 [DEBUG] [ores.iam.repository.login_info_mapper] Mapping db entities. Total: 1
2026-01-07 12:16:15.579465 [TRACE] [ores.iam.repository.login_info_mapper] Mapping db entity: {"account_id":"019b9856-215c-7fd4-b139-11821e39d80a","last_ip":"127.0.0.1","last_attempt_ip":"127.0.0.1","failed_logins":0,"locked":0,"last_login":"2026-01-07 12:14:01","online":1,"password_reset_required":0}
2026-01-07 12:16:15.579519 [TRACE] [ores.iam.repository.login_info_mapper] Mapped db entity. Result: {"last_login":"2026-01-07 12:14:01.000000000Z","account_id":"019b9856-215c-7fd4-b139-11821e39d80a","failed_logins":0,"locked":false,"online":true,"password_reset_required":false,"last_ip":"127.0.0.1","last_attempt_ip":"127.0.0.1"}
2026-01-07 12:16:15.579585 [DEBUG] [ores.iam.repository.login_info_mapper] Mapped db entities.

Add a dashboard for users   code

As per screenshots:

user_dashboard_core_ui.png

dashboard_ideas.png

dashboard_ideas_II.png

Notes:

  • add command to shell to list sessions.

Add sign-up approval workflow   code

Should also handle invite codes, etc.

We did most of the work except invite codes.

Listen for events in details dialog   code

At present we are only listening for details in the main dialogs (accounts, currencies). It would be nice to be able to listen to events in the details dialogs. however, it needs to listen to events only for that specific entity (e.g. currency pair, account etc). Not sure we are setup for this.

Review skills in claude code templates   code

Ready-to-use configurations for Anthropic's Claude Code. A comprehensive collection of AI agents, custom commands, settings, hooks, external integrations (MCPs), and project templates to enhance your development workflow.

Links:

Add claude continuous learning skill   code

Every time you use an AI coding agent, it starts from zero. You spend an hour debugging some obscure error, the agent figures it out, session ends. Next time you hit the same issue? Another hour.

This skill fixes that. When Claude Code discovers something non-obvious (a debugging technique, a workaround, some project-specific pattern), it saves that knowledge as a new skill. Next time a similar problem comes up, the skill gets loaded automatically.

Links:

Add a system clock   code

At present we are using "now". We should have a ores function for this so that we can time travel if required.

Implement entity history in shell   code

We need to add a command in shell to show entity history.

Notes:

  • for the history diff we could use a simple unified diff format.

Consider adding an "entity waterfall"   code

It would be nice to be able to see what entities have been added, deleted, modified, etc. This would work as a running commentary.

Notification of deletes   code

At present it is easy to see new rows or modified rows in an entity dialog. It is not possible to see deleted rows. One way to do this is to preserve state from before reload by key. Any entities which are not present after reload can be shown as red. History then allows users to re-instate deleted entities.

Add REPL to Qt   code

Users should be able to interact with the system directly via the REPL. Add a simple widget for this.

Add entity messages should not set modified by   code

At present you can supply any modified by you want in the protocol messages. It makes more sense to say the message must have the modified by as the user logged in from the session.

Add heat map of user sessions   code

Things to measure:

  • duration of sessions (once we have session table).
  • bytes sent/received per session (possibly 3-D plot?). Also good for anomaly detection.
  • mine github for ideas.

Add currencies update command to shell   code

At present we can only add new currencies. We also need to be able to update. Also, adding currencies requires supplying all parameters.

Subscribe on reconnect fails   code

Logs:

2025-12-13 01:14:35.108648 [DEBUG] [ores.comms.messaging.frame] Successfully deserialized frame subscribe_request (0x10)
2025-12-13 01:14:35.108680 [DEBUG] [ores.comms.net.connection] Successfully deserialized frame, type: subscribe_request (0x10) total size: 60
2025-12-13 01:14:35.108708 [DEBUG] [ores.comms.net.server_session] Received message type subscribe_request (0x10)
2025-12-13 01:14:35.108750 [DEBUG] [ores.comms.messaging.message_dispatcher] Dispatching message type subscribe_request (0x10)
2025-12-13 01:14:35.108811 [WARN] [ores.comms.service.auth_session_service] Authorization failed for subscribe_request (0x10) from 127.0.0.1:45498: not authenticated
2025-12-13 01:14:35.108842 [WARN] [ores.comms.messaging.message_dispatcher] Authorization denied for subscribe_request (0x10) from 127.0.0.1:45498
2025-12-13 01:14:35.108875 [ERROR] [ores.comms.net.server_session] Message dispatch failed: 10

Unsubscribe before logout   code

On logout we see the following:

2025-12-11 22:45:54.559906 [INFO] [ores.accounts.messaging.accounts_message_handler] Successfully logged out account: 019a5e49-476c-70ce-9909-3887cae700e9
2025-12-11 22:45:54.559940 [DEBUG] [ores.comms.messaging.message_dispatcher] Successfully dispatched message, response type logout_response (0x200e) correlation_id=763
2025-12-11 22:45:54.559978 [DEBUG] [ores.comms.messaging.frame] Serialised frame logout_response (0x200e), size: 58
2025-12-11 22:45:54.560005 [DEBUG] [ores.comms.net.connection] Writing frame of size 58 type: logout_response (0x200e) sequence: 767
2025-12-11 22:45:54.560083 [DEBUG] [ores.comms.net.connection] Successfully wrote frame
2025-12-11 22:45:54.560113 [DEBUG] [ores.comms.net.session] Sent response for message type logout_request (0x200d)
2025-12-11 22:45:54.560137 [INFO] [ores.comms.net.session] Logout completed, closing connection
2025-12-11 22:45:54.560200 [ERROR] [ores.comms.net.session] Exception in notification writer: co_await: Operation canceled [system:125]
2025-12-11 22:45:54.560233 [DEBUG] [ores.comms.net.session] Notification writer coroutine ended
2025-12-11 22:45:54.560281 [INFO] [ores.comms.net.session] Unregistering session '127.0.0.1:38366' from subscription manager

We should probably unsubscribe before we logout.

Use events in comms and accounts   code

Now we have an event bus, we should create events for:

  • connect, disconnect, retry
  • login, logout

Data in login info looks spurious   code

We see stuff like this:

oresdb=> select * from login_info;
              account_id              |     last_ip     | last_attempt_ip | failed_logins | locked |       last_login       | online
--------------------------------------+-----------------+-----------------+---------------+--------+------------------------+--------
 019a4439-be9e-798e-bf2f-927ca236f84c | 0.0.0.0         | 0.0.0.0         |             0 |      0 | 1969-12-31 23:00:00+01 |      0
 019a3ba6-bd11-709b-b93d-fea9403d3d39 | 127.0.0.1       | 127.0.0.1       |             0 |      0 | 2025-10-31 19:03:48+00 |      1
 019a4431-98f8-79ae-9fc8-f6a6e77a0490 | 192.168.1.100   | 192.168.1.100   |             0 |      0 | 2025-11-02 10:51:32+00 |      1
 019a4431-9a7d-7b3d-a1cb-b9e02d44c804 | 0.0.0.0         | 192.168.1.100   |             1 |      0 | 1969-12-31 23:00:00+01 |      0

Also, we need a login timestamp and a logout timestamp so we can measure session duration.

Currencies displays when not connected   code

At present we can display currencies even before we connect. This is probably ok but we should at least state we are not connected. Alternatively it should be disabled.

Add a delete all button which deletes all currencies   code

It is useful especially in test environments to be able to delete all entities before a re-import.

Notes:

  • purge button.

Add party role scheme entity   code

The following is the analysis for adding support to party schemes.

Contains a code representing a related party role. This can be extended to provide custom roles.

Code Description

  • Code: Accountant
  • Description: Organization responsible for preparing the accounting for the trade.
  • Code: Allocation
  • Description: Agent The organization responsible for supplying the allocations for a trade to be allocated to multiple accounts/organizations.
  • Code: Arranging
  • Description: Broker The organization that arranged the trade, i.e. brought together the counterparties. Synonyms/Alternatives: Inter-dealer broker, agent.
  • Code: Beneficiary
  • Description: Organization that suffers the economic benefit of the trade. The beneficiary may be distinct from the principal/counterparty - an example occurs when a hedge fund trades via a prime broker; in this case the principal is the prime broker, but the beneficiary is the hedge fund. This can be represented as a payer/receiver account in the name of the hedge fund, but it is also possible to add the party role of "Beneficiary" at the partyTradeInformation level.
  • Code: Booking
  • Description: Party The entity for which the organization supporting the trade's processing has booked/recorded the trade. This is used in non-reporting workflows situations in which the trade doesn't need to be reported but a firm still wants to specify their own side.
  • Code: Buyer
  • Description: Acquirer of the legal title to the financial instrument. In the case of an option, the buyer is the holder of the option. In the case of a swap or forward, the buyer will be determined by industry best practice. This does not refer to an investor or investment manager or other organization on what is typically called the "Buy side"; for that, see the "Client" role. Corresponds to "Buyer" as defined in certain regulations such as ESMA MiFID II/MIFIR RTS 22 field 9.
  • Code: Buyer
  • Description: DecisionMaker The party or person who, having legal authority to act on behalf of the trade counterparty acting as Buyer as defined in this coding scheme, made the decision to acquire the financial instrument. Corresponds to "buyer decision maker" as defined in ESMA's MIFIR RTS 23 report. This does not refer to the decision maker for what is traditionally called the "Buy side"; for that, see the "Client Decision Maker" role.
  • Code: Clearing
  • Description: Client An organization that clears trades through a clearing house, via a clearing broker (member of the clearing house) who acts as an agent on its behalf. The term "client" refers to the organization's role in the clearing process in relation to its clearing broker, and not whether it is a price maker or taker in the execution process.
  • Code: Clearing
  • Description: ExceptionParty A party to the trade that claims a clearing exception, such as an end-user exception under Dodd-Frank Act provisions.
  • Code: Clearing
  • Description: Firm Organization that submits the trade to a clearing house on behalf of the principal. Synonyms/alternates: Futures Commission Merchant (FCM), Clearing Broker, Clearing Member Firm. Some implementations use "Clearing Broker" as synonym.
  • Code: Clearing
  • Description: Organization The organization that acts as a central counterparty to clear a derivatives contract. This is used to represent the role of Central Counterparties (CCPs) or Derivative Clearing Organizations (DCOs). Sometimes called "ClearingService". Some implementations also use the term "Clearer".
  • Code: Client
  • Description: Client as defined under ESMA MIFIR. This is generally the investor or other client of an investment firm, and is synonymous with the Beneficiary in many circumstances.
  • Code: Client
  • Description: DecisionMaker The party or person who, having legal authority to act on behalf of a trade counterparty, made the decision to acquire or sell the financial instrument.
  • Code: Confirmation
  • Description: Platform Organization serving as a financial intermediary for the purposes of electronic confirmation or providing services for post-processing of transactional data.
  • Code: Contractual
  • Description: Party A party to a contractual document. If the intended usage relates to the context of the trade lifecycle, more specific annotations have been defined which might be more appropriate.
  • Code: Counterparty
  • Description: An economic counterparty to the trade. Synonym: principal.
  • Code: Counter
  • Description: PartyAffiliate Organization offiially attached to the counterparty. e.g. partner, branch, subsidiary.
  • Code: Counter
  • Description: PartyUltimateParent The topmost entity or organization, within the corporate hierarchy, responsible for the reporting party.
  • Code: Credit
  • Description: SupportProvider Organization that enhances the credit of another organization (similar to guarantor, but may not fully guarantee the obligation).
  • Code: Custodian
  • Description: Organization that maintains custody of the asset represented by the trade on behalf of the owner/principal.
  • Code: Data
  • Description: Submitter Entity submitting the transaction report to the competent authority.
  • Code: Disputing
  • Description: Party Organization that is disputing the trade or transaction.
  • Code: Document
  • Description: Repository A marketplace organization which purpose is to maintain document records. If the intended usage relates to the context of the trade lifecycle, more specific annotations have been defined which might be more appropriate.
  • Code: Executing
  • Description: Broker The (generally sell-side) organization that executed the trade; the price-making party.
  • Code: Executing
  • Description: Entity Entity executing the transaction. If the transaction is executed directly by the reporting party, it will be the reporting party. If it is executed by an execution agent or an affiliated party on behalf of the reporting party, it will be that affiliate or agent.
  • Code: Execution
  • Description: Agent The (generally buy-side) organization that acts to execute trades on behalf of an investor. Typically this is an investment manager or asset manager, and also makes the investment decisions for the investor. If required, a separate InvestmentDecision role can be specified to distinguish that the party making the investment decision is different.
  • Code: Execution
  • Description: Facility The facility, exchange, or market where the trade was executed. Synonym: Swap Execution Facility, Designated Contract Market, Execution Venue.
  • Code: Guarantor
  • Description: Organization that backs (guarantees) the credit risk of the trade.
  • Code: Margin
  • Description: Affiliate Margin affiliate as defined by U.S. margin and capital rules §23.151.
  • Code: Order
  • Description: Transmitter The entity transmitting the order to the reporting firm. Synonym: Transmitting Firm.
  • Code: Prime
  • Description: Broker The organization that takes on or took on the credit risk for this trade by stepping in between the two economic parties (without a central counterparty clearing mechanism).
  • Code: Prior
  • Description: TradeRepository The trade repository at which the trade was reported previous to the current trade repository.
  • Code: PTRR
  • Description: CompressionProvider A party providing a post trade risk reduction service in the form of compression.
  • Code: PTRR
  • Description: RebalancingProvider A party providing a post trade risk reduction service in the form of portfolio rebalancing.
  • Code: Publication
  • Description: Venue The reporting service (whether trade repository, market data service, or exchange/facility/venue data distribution service) that published the report of this trade.
  • Code: Reporting
  • Description: Party The party with the regulatory responsibility to report this trade.
  • Code: Reporting
  • Description: PartyAffiliate Organization offiially attached to the reporting party e.g. partner, branch, subsidiary.
  • Code: Reporting
  • Description: PartyUltimateParent The topmost entity or organization, within the corporate hierarchy, responsible for the reporting party.
  • Code: Seller
  • Description: A counterparty in a trade, which performs in one of the following capacities: 1) it transfers or agrees to transfer in the future an instrument or title to that instrument in exchange for payment, 2) it writes a derivatives instrument such as an option or a swap in which it provides risk protection to the buyer. This does not refer to the broker/dealer or other organization on what is typically called the "Sell side"; for that, see the "Executing Broker" role. Corresponds to "Seller" as defined in certain regulations such as ESMA MiFID II/MIFIR RTS 22 field 16.
  • Code: Seller
  • Description: DecisionMaker The party or person who, having legal authority to act on behalf of the trade counterparty acting as Seller as defined in this coding scheme, made the decision to sell the financial instrument. Corresponds to "seller decision maker" as defined in ESMA's MIFIR RTS 23 report. This does not refer to the decision maker for what is traditionally called the "Sell side"; for that, see the "Trader" person role.
  • Code: Settlement
  • Description: Agent The organization that makes or receives payments on behalf of the given principal party.
  • Code: Trade
  • Description: Repository An organization that maintains records of the trade for regulatory reporting purposes.
  • Code: Trade
  • Description: Source The organization that originally supplied the record of the trade. In the context of regulatory reporting, it is the submitter of the trade record to a regulator or TR.
  • Code: Trading
  • Description: Manager The entity responsible for managing the assets/investments of this party. Synonnym: Asset Manager, Investment Manager, Trading Advisory.
  • Code: Trading
  • Description: Partner An entity with which this party trades from time to time, ie. with which it acts as a counterparty on some transactions. This role is used for static reference data, not individual transactions.

Modes of operation   code

We need to discuss this with Lau. Intuitively it seems that different users have different "views" on the functions of the system. If you are operations you probably want a specific set of screens and icons on the toolbar to go with it. Trading will have a different set. The administrator of the system also, and so on. There should be a way to create "profiles" which change the toolbar. These are distinct from user profiles which remember which screens to open and their positions.

Make bootstrap operation atomic using SQL transactions   code

The bootstrap operation is currently not atomic. If an exception is thrown after the admin account is created but before the bootstrap mode feature flag is disabled, the system is left in an inconsistent state where:

  • An admin account exists in the database.
  • Bootstrap mode is still enabled (allowing creation of additional admin accounts).
  • Current Flow

    The bootstrap process in bootstrap_service.cpp performs these operations:

    1. Create account via account_service.
    2. Create logininfo via login_info_service.
    3. Assign admin role via authorization_service.
    4. Disable bootstrap mode via system_flags_service.

    Each operation auto-commits independently, creating windows for partial failures.

  • Solution

    Use sqlgen's Transaction class to wrap all bootstrap operations in a single database transaction. The class provides RAII semantics with automatic rollback on destructor if commit() was not called.

    // sqlgen's Transaction class pattern:
    ~Transaction() {
        if (!transaction_ended_) {
            rollback();  // Auto-rollback on exception
        }
    }
    
  • Challenges
    • Current architecture creates separate database::context connections per service.
    • Need to pass a shared connection/transaction across services.
    • May require refactoring services to accept an optional transaction parameter.
  • Mitigation

    The existing self-healing mechanism in bootstrap_mode_service::initialize_bootstrap_state() detects when bootstrap mode was not properly disabled after account creation and auto-corrects the state on server startup. This provides defence in depth but is not a substitute for proper transactional integrity.

  • Acceptance Criteria
    • Bootstrap operation completes fully or rolls back entirely.
    • No partial state if any step fails.
    • Self-healing mechanism remains as defence in depth.

Investigate claude-code-hook-templates   code

A comprehensive collection of production-ready hooks covering all 8 Claude Code lifecycle events. Includes safety guards, autonomous TDD workflows, PR approval gates, cost controls, and more.

Links:

Investigate Agent-Native Architecture Audit   code

Conduct a comprehensive review of the codebase against agent-native architecture principles, launching parallel sub-agents for each principle and producing a scored report.

Core Principles to Audit:

  • Action Parity - "Whatever the user can do, the agent can do"
  • Tools as Primitives - "Tools provide capability, not behavior"
  • Context Injection - "System prompt includes dynamic context about app state"
  • Shared Workspace - "Agent and user work in the same data space"
  • CRUD Completeness - "Every entity has full CRUD (Create, Read, Update, Delete)"
  • UI Integration - "Agent actions immediately reflected in UI"
  • Capability Discovery - "Users can discover what the agent can do"
  • Prompt-Native Features - "Features are prompts defining outcomes, not code"

Links:

Sign-up dialog should be disabled if feature is disabled   code

At present you can click on sign up and fill in all details but then you get a server error:

2025-12-24 10:46:48.212905 [DEBUG] [ores.iam.messaging.accounts_message_handler] Request: signup_request{username=newuser4, email=newuser4@example.com}
2025-12-24 10:46:48.213049 [INFO] [ores.iam.service.signup_service] Signup attempt for username: newuser4, email: newuser4@example.com
2025-12-24 10:46:48.213144 [WARN] [ores.iam.service.signup_service] Signup rejected: signups are disabled
2025-12-24 10:46:48.213186 [WARN] [ores.iam.messaging.accounts_message_handler] Signup failed for username: newuser4, reason: User registration is currently disabled
2025-12-24 10:46:48.213898 [DEBUG] [ores.comms.messaging.compression] Compressed 68 bytes to 60 bytes using zlib (0x)

Makes more sense for sign-up button to also be disabled in client. Trouble is, we do not know as we are not connected. This means the handshake has to provide some kind of flag saying sign-up is enabled or disabled.

Tests are logging to stdout in github   code

There is a lot of stdout output in CDash. We need to understand why that is.

Test output
[2025-12-16 20:31:44.600851] [0x00000001f1d1a200] [info]    Test run starting, creating test database
[2025-12-16 20:31:44.601397] [0x00000001f1d1a200] [info]    Generated test database name: oresdb_test_4816_1242
[2025-12-16 20:31:44.601401] [0x00000001f1d1a200] [info]    Creating test database: oresdb_test_4816_1242
[2025-12-16 20:31:44.601434] [0x00000001f1d1a200] [info]    Creating context. Configuration: {"database_options":{"user":"ores","host":"localhost","database":"postgres","port":5432},"pool_size":1,"num_attempts":10,"wait_time_in_seconds":1}
[2025-12-16 20:31:44.630284] [0x00000001f1d1a200] [info]    Finished creating context.
[2025-12-16 20:31:44.771670] [0x00000001f1d1a200] [info]    Successfully created test database: oresdb_test_4816_1242
[2025-12-16 20:31:44.771733] [0x00000001f1d1a200] [info]    Setting ORES_TEST_DB_DATABASE environment variable to: oresdb_test_4816_1242
[2025-12-16 20:31:44.771738] [0x00000001f1d1a200] [info]    Environment variable set successfully
[2025-12-16 20:31:44.771740] [0x00000001f1d1a200] [info]    Test database ready: oresdb_test_4816_1242
[2025-12-16 20:31:44.772151] [0x00000001f1d1a200] [info]    Test case starting: delete_account_response_failure
[2025-12-16 20:31:44.772158] [0x00000001f1d1a200] [info]      Tags: messaging #messaging_protocol_tests

User interface options   code

This story keeps track of configuration points in the UI which should be added at some point:

  • display time in human readable form - e.g. last month, 3 months ago, etc.
  • auto-reload. If a dialog receives new data, reload it automatically. Defaults to off.

Notes:

  • we need a UI to manage the UI options.
  • should be stored in the server and cached locally with a sqlite db.

New feature flags   code

  • allow sign-ups. If true, users can create their own accounts. Done.
  • auto-authorise sign-ups. If true, the account is automatically created. If false, admin user has to authorise it.

Notes:

  • we need a UI to manage the UI options.

Perform tests to check database connectivity   code

We added some basic database monitoring but did not perform a lot of testing.

We should also generalise this so that if the database goes down after start we still perform some kind of retry logic.

See also this point from Gemini:

The new broadcastall method appears to be unused in this pull request. The database status broadcast is implemented directly in ores::comms::net::server::broadcast_database_status without using the subscriptionmanager. If this method is not intended for future use, it could be removed to avoid dead code.

Add sound assets   code

We need to be able to associate sounds to certain events such as disconnect, connect etc. Users need to be able to choose their own sounds.

Cli clean-ups   code

  • we still seem to support --entity currencies. This should now be invalid. Done.
  • we are still exporting as JSON. We should instead allow CSV and XML exports only.
  • add recipes for all commands.
  • should be able to list all admin accounts.
  • list command should support table output.
  • is admin should be a bool: --is-admin arg (=0)
  • add account duplicates logic. We should have a single service for this.
  • split application into entities.

Add search to currencies   code

It should be possible to filter the open currencies by a string. This should be any field. The user needs to know when the list has been filtered. Ideally we should have buttons at the top per field and filter using those. It should go back to database rather than just filter what is available in UI.

Add support for FIX   code

Links:

  • GH: hffix: "The High Frequency FIX Parser library is an open source implementation of tagvalue FIX (classic FIX) intended for use by developers of high frequency, low latency financial software. The purpose of the library is to do fast, efficient encoding and decoding of FIX in place, at the location of the I/O buffer. The library does not use intermediate message objects, and it does no memory allocation on the free store (the “heap”)."

Consider adding "global search" via typesense   code

Typesense:

Typesense is a fast, typo-tolerant search engine for building delightful search experiences.

We could pump specially crafted documents into typesense with IDs and types and then let users search across any type of entity.

Links:

  • GH typesense
  • GH pgtextsearch: Modern ranked text search for Postgres.
    • Simple syntax: ORDER BY content <@> 'search terms'
    • BM25 ranking with configurable parameters (k1, b)
    • Works with Postgres text search configurations (english, french, german, etc.)
    • Supports partitioned tables
    • Goal: state-of-the-art performance and scalability

Add a generic tagging system   code

It should be possible to associate any entity with one or more tags and then do a search by tags on that entity type. For example, tag a set of currencies as emerging markets and then search by that.

Merged stories:

Currencies should have tags

Examples:

  • metals, emerging markets
  • continent as a tag
  • crypto

At present we are overloading the currency type field.

  • Analysis Labels versus tags
    That is an **excellent question** that gets to the heart of cloud governance and
    system design. You are correct that the underlying structure is fundamentally
    the same—a **key-value pair attached to a resource**—but the distinction is
    necessary because of the **context, governance, and enforcement mechanisms**
    applied to each one.
    
    The distinction between GCP Labels and Tags boils down to **Annotation vs.
    Policy**.
    
    ---
    
    ## ⚖️ Why the Distinction is Necessary
    
    | Feature              | GCP **Labels** (Annotation)                                                                          | GCP **Tags** (Policy/Governance)                                                                                                                                               |
    |:---------------------|:-----------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
    | **Primary Goal**     | **Organization, filtering, cost allocation, and reporting.**                                         | **Policy enforcement, access control, and hierarchical governance.**                                                                                                           |
    | **Structure**        | **Flexible/Arbitrary.** Key-Value pair set directly on the resource.                                 | **Structured/Centralized.** Key and Value are defined *centrally* as separate resources (at the Organization/Project level) and then *bound* to the resource.                  |
    | **Hierarchy**        | **Flat.** A resource does not inherit labels from its parent folder.                                 | **Hierarchical.** Tags are inherited by child resources (like a VM inheriting a tag from its containing project).                                                              |
    | **Access Control**   | **Low Control.** Any user with permissions to modify the resource can typically modify its labels.   | **High Control.** Dedicated **IAM Roles** are required to create, manage, and even attach Tag Keys and Values. This prevents users from "tagging" their way out of a policy.   |
    | **Enforcement**      | **None.** Labels are metadata and cannot be used directly in IAM conditions to grant or deny access. | **High.** Tags are the *only* mechanism designed for **conditional IAM policies** and Organization Policies (e.g., "deny deletion unless resource has tag `environment:dev`"). |
    | **Use Case Example** | Filtering the console: "Show me all resources labeled `owner:john_doe`."                             | Security: "Only allow network traffic from resources tagged `security_zone:trusted`."                                                                                          |
    
    ### Analogy: The Whiteboard vs. The Building Code
    
    1.  **Labels are like a sticky note on a whiteboard:**
        * They are **flexible**, quickly written, and easy to change.
        * They are used for **informal organization** (cost center, app name, etc.).
        * Changing the note has **no impact on the resource's function** or security.
    
    2.  **Tags are like a building code requirement:**
        * They are **highly structured** and defined by a central authority (the city/organization).
        * They are used to **enforce policy** (safety, compliance).
        * If a resource (a building) doesn't have the correct tag (e.g., a **fire-rating tag**), an automated system (the policy engine) will **deny an action** (e.g., deny occupation or modification).
    
    ---
    
    ## How This Relates to Your SVG System
    
    Your current **three-table model** is structurally a **GCP Label** system—it's
    excellent for annotation and filtering (e.g., "Give me all icons with the tag
    'currency'").
    
    If you wanted to implement a **GCP Tag** concept, you would need to:
    
    1.  **Formalize the Tags:** Create certain tags as *official resources* (like
        `Status` with official values `Draft`, `Approved`, `Production`).
    2.  **Add Permissions:** Implement **application logic** that checks a user's
        role against the tag. For example: "A user needs the `Approver` role to
        apply the `Status:Production` tag to an icon."
    
    The need to distinguish them comes down to providing one system that is
    **flexible for organization (Labels)** and another that is **rigid for security
    and compliance (Tags)**.
    

    Examples:

    • majors, minors, EM, latam, etc are tags we can have on currencies. On currency pairs, We could also have USD crosses, which is inferred by having USD as one of the pair. However these are not labels because we do not want everyone to start using them. When defining a report, you could associate currencies and currency pairs to the report via the tags.
    • labels are things we could associate with images for example. Flags could have both "countries" and "currencies" labels so that when we want to select a flag as the image for a currency, we could ask for all images labelled "currencies". The labelling can be done by pretty much anyone.

Add "uptime" screen   code

See the claude page for ideas:

anthropic_uptime_page.jpeg

Mine dexter for ideas   code

Dexter is an autonomous financial research agent that thinks, plans, and learns as it works. It performs analysis using task planning, self-reflection, and real-time market data. Think Claude Code, but built specifically for financial research.

Links:

Add support for PDF generation   code

A lot of legal documents require PDF support. This story keeps track of useful PDF libraries.

Links:

  • GH libharu: "Haru is a free, cross platform, open-sourced software library for generating PDF. It supports the following features."

Automated SQL generation   code

At present we are manually creating the SQL. We should be able to do it from sqlgen.

Missing shell functionality   code

The job of the client is to exercise the entirety of the comms protocol, and to provide a way to perform CRUD operations via command line. Note:

  • client never access the repositories directly, it should do exactly the same as the qt client would do.
  • client's only interface is the REPL.
  • client will eventually be used by AI agents.

Client needs to have messages at the entity level:

  • currencies:
    • import currencies from ORE Format. Given a path in the filesystem, it performs the import using the importer and appropriate comms messages.
    • export currencies to ORE format. Uses comms to obtain the currencies, then the exporter to convert, then dumps them into the terminal as ORE XML.
    • list existing currencies as a table or as JSON. We need support for latest, "at time point" and "all" (meaning every single version). It should be possible to supply some filtering by the entity's ID (e.g. --iso-code).
    • delete one or more currencies. User supplies a number of entity IDs (e.g. --iso-code ABC --iso-code CDE --iso-code FGH and so on).
    • add a currency supplying arguments (e.g. --iso-code and so forth).
    • add currencies from JSON.
  • accounts:
    • list existing currencies as a table or as JSON. We need support for latest, "at time point" and "all" (meaning every single version). It should be possible to supply filtering by the entity's ID.
    • delete one or more accounts. User supplies a list of entity IDs.
    • add an account supplying arguments.
    • add accounts from JSON.
  • feature flags:
    • list existing feature flags as a table or as JSON. We need support for latest, "at time point" and "all" (meaning every single version). It should be possible to supply some filtering by the entity's ID
    • delete one or more feature flags. User supplies a list of entity IDs.
    • add feature flags supplying arguments.
    • add feature flags from JSON.

Notes:

  • update recipes with the new client commands.

Invalid password should not throw   code

At present in the unlock test we have:

BOOST_LOG_SEV(lg, info) << "Locking account by failing 5 login attempts";
auto ip = internet::ipv4();
for (int i = 0; i < 5; ++i) {
    try {
        sut.login(account.username, "wrong_password", ip);
    } catch (...) {}
}

This is very suspicious; a failed login should just return false or the modern c++ equivalent (std::expected?).

Faker with seeds   code

As suggested by phi4:

Faker Usage:

Randomness: Ensure that the use of faker data is appropriate for testing. Consider seeding the random generator for reproducibility in tests.

Notes:

#include "faker-cxx/generator.h" void setSeed(std::mt1993764::resulttype seed) Catch::rngSeed()

Improve handling of error responses   code

As per Gemini code review:

Certainly. Point #2 from the review of `CurrencyHistoryDialog.cpp` addressed
the potential complexity of error checking by suggesting that relying on the
specific response message type is **fragile**.

The goal is to move from:

1.  Client sends **Request A**.
2.  Server returns **Response A** (Success) OR **Error Response** (Failure) OR
    **Response B** (Unexpected success type).
3.  Client checks: *Is the message type exactly **Response A**?*

to a more robust pattern where the client checks for a generic failure response
first.

-----

## 🐞 Fragile Error Check (Current Code)

The current code in `loadHistory` checks for success by expecting *only* the
specific success message type:

```cpp
// Current Fragile Logic
if (result->header().type != comms::protocol::message_type::get_currency_history_response) {
    onHistoryLoadError(QString("Server does not support currency history (received message type %1)")
        .arg(static_cast<int>(result->header().type)));
    return;
}
```

This logic has two main problems:

1.  **Hiding Server Errors:** If the server returns a generic protocol error
    (`message_type::error_response`) because, for example, the client's session
    timed out, the client logs a misleading message: "Server does not support
    currency history." It should be reporting the actual error message sent by
    the server.
2.  **Lack of Standardization:** Every client method needs to implement its own
    logic to handle unexpected types.

-----

## 🛠️ Suggested Improvement: Standardized Error Handling

The improvement is to check for a generic **`error_response`** message type
first, and report its payload/message, before attempting to deserialize the
successful response.

Assuming your system has a standard `error_response` message:

```cpp
void CurrencyHistoryDialog::handleHistoryResponse(const HistoryResult& result) {
    if (!result) {
        onHistoryLoadError(QString::fromStdString(result.error()));
        return;
    }

    // 1. Check for a generic server-side error response
    if (result->header().type == comms::protocol::message_type::error_response) {
        // Assume error_response contains a readable message payload
        auto error_response = risk::messaging::error_response::deserialize(result->payload());
        if (error_response) {
            onHistoryLoadError(QString::fromStdString(error_response->message));
        } else {
            onHistoryLoadError("Server returned a malformed error response.");
        }
        return;
    }

    // 2. Check for the specific SUCCESS response type
    if (result->header().type == comms::protocol::message_type::get_currency_history_response) {
        auto response = risk::messaging::get_currency_history_response::deserialize(result->payload());

        if (!response || !response->success) {
            // Handle success=false within the expected response type
            onHistoryLoadError(QString::fromStdString(response ? response->message : "Invalid or failed history response."));
            return;
        }

        history_ = std::move(response->history);
        onHistoryLoaded();
        return;
    }

    // 3. Handle truly unexpected message type
    onHistoryLoadError(QString("Received unexpected message type %1 from server.")
        .arg(static_cast<int>(result->header().type)));
}
```

By standardizing the **`error_response`** type, the client can always extract
and display the relevant server-side failure reason, leading to much clearer
logging and user feedback.

Do not disable cert verification   code

At present we've hacked cert verify to false. We should not do this. Gemini:

You cannot use Let's Encrypt for development purposes because it requires a public domain name that Let's Encrypt can verify, and your local development server is not publicly accessible. The recommended approach is to create a local certificate authority (CA) using a tool like mkcert to sign your certificates, which allows you to bypass browser warnings for local domains like localhost.

Option 1: Use mkcert for local development

  • Install mkcert: Follow the instructions to install the mkcert tool on your system.
  • Install the local CA: Run the command to install the local CA root certificate into your system's trust store. This is a one-time setup.
  • Generate a local certificate: Use mkcert to generate certificates for your local development domains (e.g., localhost, my-app.local). The generated certificates will be signed by your trusted local CA and will not cause browser warnings.

Option 2: Use Let's Encrypt with a real public domain

Purchase a domain: Buy a public domain name (e.g., mydomain.dev).

  • Use an ACME client: Use an ACME client like Certbot to automate the certificate process. You can run certbot on a server that is accessible to the public internet.
  • Complete the validation: The client will need to verify your ownership of the domain through a DNS or HTTP challenge, which requires the domain to be publicly reachable.
  • Deploy the certificate: Let's Encrypt will issue a certificate that you can then deploy to your development server.

Why Let's Encrypt doesn't work for local development

  • Let's Encrypt's primary purpose is to secure public-facing websites by automatically verifying domain ownership.
  • They use ACME protocol challenges (DNS or HTTP) that require the public internet to access your server at the specified domain.
  • Since your local server is not on the public internet, it cannot respond to these challenges, and Let's Encrypt cannot verify your ownership of the domain.

Add [[nodiscard]] to repository operations returning data   code

At present we can create an account and ignore the result, etc. We should be forced to look at the result.

CLI Importing needs to read from database   code

After we do the import into the database, we need to read the currencies again to get the valid from/to.

Add output option to repl   code

It should be possible to set the "output type" or format in the shell, from json to table. Find the correct terminology for this.

Add more account commands   code

See the azeroth account commands for inspiration.

Links:

Improve error message when server is not running   code

At present we get:

Failed to connect to server: Failed to connect to server

If we try again after the error, "authenticating…" shows up in red.

Consider adding log command line options to qt   code

At present we have hard-coded logging options. However, maybe users should be able to change the logging settings from the UI rather than having to restart the app and supply command line options.

Troubleshoot skills in claude   infra

Add entity related charts   code

Have a think on things that could benefit from a graphical display at the entity level. Some ideas:

  • entity history: number of additions, edits, deletions over time. Bar chart. Makes it easier to pick up weird system problems. This is overall across all instances.
  • single entity history. In the history tab for that entity, graph showing the changes to the entity over time.

In addition, we need to be able to support charts in ASCII so that we can see them in the REPL. This will be used by the AI agents.

Links:

Add skill to review product backlog   infra

We could get claude to review the stories, add more details, etc. Needs more thinking.

Add skill to update vcpkg   infra

As per instructions in readme.

Ensure applications work under OSX using github images   code

We need to install the DMG and run the app.

We think the package does not have all of the dependencies, but this did not work:

if(APPLE)
    install(CODE "
        # make sure the bundle is already on disk
        set(BU_CHMOD_BUNDLE_ITEMS TRUE)
        include(BundleUtilities)

        # full path to the real executable inside the bundle
        set(app_exe \"\${CMAKE_INSTALL_PREFIX}/OreStudio.app/Contents/MacOS/OreStudio\")

        # directory where 3rd-party libraries will be copied
        set(libs_dir \"\${CMAKE_INSTALL_PREFIX}/OreStudio.app/Contents/Frameworks\")

        # discover all prerequisites and copy/fix them
        fixup_bundle(\"\${app_exe}\" \"\" \"\${libs_dir}\")
    " COMPONENT Runtime)
endif()

We should ask someone with an OSX machine to test this.

Links:

Make UI/UX look more professional   code

Links:

Analysis from Gemini:

To make your Qt application look like an advanced trading system—even for a
simple CRUD operation screen—requires moving beyond basic desktop application
styles toward the dense, high-contrast, data-rich aesthetic of platforms like
Bloomberg or professional broker terminals.

The current look (a dark table with simple data rows) is a great foundation.
Here are targeted suggestions for your Qt UI to elevate it to a professional,
advanced trading system aesthetic:

## I. Color and Contrast (The Dark Theme)

Your current dark gray background is good, but trading systems use specific
contrast to highlight data significance.

1.  **Define a Palette:** Adopt a limited, functional color palette:

      * **Primary Background:** A very dark, near-black charcoal (`#1A1A1A` or
        `#1E1E1E`). This is the foundation.
      * **Foreground/Text:** Clean white or light gray (`#F0F0F0`).
      * **Accent Color (Neutral):** A subdued corporate blue/cyan (`#007ACC` or
        a subtle green/gold from your branding) for selected rows, borders, and
        input focus.
      * **Data Status Colors:**
          * **Positive (Gains):** Bright, high-contrast green (`#00C853`).
          * **Negative (Losses):** High-contrast red (`#FF3333`).
          * *(While CRUD isn't about gains/losses, you can use these colors for
            status, like 'Active' vs. 'Inactive' currencies).*

2.  **Subtle Depth:** Avoid flat black. Use a slightly lighter shade of gray
    (`#2A2A2A`) for embedded panels, sidebars, and control areas to create
    visual segmentation, giving the impression of modularity.

## II. Typography and Data Presentation

Trading UIs prioritize density and scannability.

1.  **Monospace Font:** For the currency codes and numerical columns, switch to
    a clear, legible **monospace font** (like Consolas, Fira Code, or a custom
    font in Qt). Monospace fonts ensure that all numbers align perfectly in
    columns, which is essential for rapid data comparison.
2.  **Font Sizing:** Use a small, consistent font size (e.g., 10pt or 11pt) to
    fit more data on screen. Use bolding sparingly, primarily for the Currency
    Code (e.g., USD, EUR).
3.  **Visual Alignment:**
      * **Text Columns** (Currency Name): Left-aligned.
      * **Code Columns** (ISO Code, Symbol): Center-aligned.
      * **Numerical Columns** (Rounding, Precision): Right-aligned. **This is
        critical** for financial UIs, as it allows users to compare magnitude
        instantly.

## III. Advanced Table View Enhancements (QTableView/QTableWidget)

Since the core of this screen is a table, focus on making the table look
high-tech.

1.  **Header Styling:**

      * Make column headers slightly stand out with a subtle dark gradient or a
        distinct, slightly brighter background color (e.g., `#282828`).
      * Ensure the header font is crisp (perhaps slightly bolder than the row
        data).
      * Add tiny, clear **sort indicators** to show the current sort direction.

2.  **Row Selection:**

      * The selected row should use your accent color (e.g., a thin blue left
        border or a light blue background fill) with white or light gray text
        for high visibility.
      * Introduce **subtle, faint horizontal rules** (1px in a color like
        `#333333`) to separate rows, which aids readability in dense tables.

3.  **Interactive Elements (Hover):** Implement a very subtle change on row
    hover (e.g., the background darkens by 5%) to indicate interactivity, even
    if clicking doesn't change the view.

## IV. UI Layout and Modularity

Advanced UIs are rarely monolithic; they are built from modular panels.

1.  **Toolbar (Top):** Create a clean, dedicated toolbar area at the top for
    your CRUD operations (`Add`, `Edit`, `Delete`) and your system icons
    (Connection, Reference Data).

      * Use the Fluent UI System Icons you researched (`globe-32-regular`,
        `money-32-regular`).
      * Buttons should be flat, high-contrast text or icons only. On hover, they
        should reveal a subtle gray background or a thin accent border.

2.  **Side Panel (Right or Left):** Instead of a simple dialog for *editing*,
    use a dedicated side panel that slides out or appears next to the table when
    a row is selected.

      * This panel would house the detail view for the selected currency. This
        makes the UI feel like a single workspace rather than navigating modal
        windows.
      * Give this panel a slightly different background shade (`#2A2A2A`).

3.  **Status Bar (Bottom):** Add a sleek, minimal status bar at the bottom. This
    is where you would place your connection status icon (using your proposed
    `globe-32-regular` or `plug-connected-32-regular` icon). It reinforces the
    "system is live" feel.

## V. Qt-Specific Implementation via Stylesheets

In Qt, you achieve this professional look primarily through **QSS (Qt Style
Sheets)**. You will be targeting specific widgets (like `QTableView`,
`QPushButton`, `QLineEdit`) with CSS-like rules.

```css
/* Example QSS Snippets for the Trading Look */

QTableView {
    /* Base style for the data area */
    background-color: #1A1A1A; /* Primary Background */
    gridline-color: #333333; /* Faint row separators */
    color: #F0F0F0;
    border: 1px solid #007ACC; /* Subtle border using accent color */
    selection-background-color: #007ACC; /* Accent Color for selection */
    selection-color: white;
}

QHeaderView::section {
    /* Style for Column Headers */
    background-color: #282828; /* Slightly lighter shade for headers */
    color: #FFFFFF;
    border: none;
    padding: 6px;
    font-size: 11pt;
    font-weight: bold;
}

QLineEdit {
    /* Style for input fields (e.g., in the side panel or search) */
    background-color: #1A1A1A;
    border: 1px solid #444444;
    color: #F0F0F0;
    padding: 5px;
}

QPushButton {
    /* Flat button style for toolbar */
    background-color: transparent;
    border: none;
    color: #F0F0F0;
    padding: 8px 12px;
}

QPushButton:hover {
    /* Hover effect */
    background-color: #2A2A2A;
    border: 1px solid #007ACC;
}
```

Current issues with package install in debian   code

At present we have several issues with packaging:

  • debs are built on ubuntu so they cannot install on latest debian testing as the t64 migration has been completed. Error:
root@lovelace:~# apt install /home/marco/Downloads/orestudio_0.0.4_amd64.deb
You might want to run 'apt --fix-broken install' to correct these.
Unsatisfied dependencies:
 orestudio : Depends: libqt6gui6t64 (>= 6.1.2) but it is not installable
             Depends: libqt6widgets6t64 (>= 6.1.2) but it is not installable
Error: Unmet dependencies. Try 'apt --fix-broken install' with no packages (or specify a solution).
root@lovelace:~# apt install libqt6widgets6t64 libqt6gui6t64
Package libqt6gui6t64 is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
However the following packages replace it:
  libqt6gui6:i386  libqt6gui6


Package libqt6widgets6t64 is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
However the following packages replace it:
  libqt6widgets6:i386  libqt6widgets6


Error: Package 'libqt6widgets6t64' has no installation candidate
Error: Package 'libqt6gui6t64' has no installation candidate
  • when starting the package from a directory, it tries to create the log relative to that directory:
[marco@lovelace ~]$ /opt/OreStudio/0.0.4/bin/ores.qt
terminate called after throwing an instance of 'boost::filesystem::filesystem_error'
  what():  boost::filesystem::create_directories: Permission denied [system:13]: "/home/marco/../log", "/home/marco/../log"
Aborted                    /opt/OreStudio/0.0.4/bin/ores.qt

When investigating a crash we noticed the app is not exiting cleanly. Fix all of these crashes before we go any further.

Add skill to improve UI design   code

Create basic manual   code

We should start populating the manual from the start. Ensure there is a claude skill that updates the manual as we add new entities. Create a PDF build for it. We can use templates from thesis. Link it to site so that yuo can browse it.

Do not return sensitive fields   code

As per code review:

Major Security Flaw (listaccountsresponse): The serialization format explicitly includes highly sensitive fields (passwordhash, passwordsalt, totpsecret) for every domain::account returned. This is a severe security risk. These fields must not be exposed over any messaging protocol, even internal ones, unless it is a dedicated, highly protected replication channel.

Proposed Change: Create a protocol-safe subset structure, e.g., domain::accountsummary, which contains only non-sensitive data (id, username, email, isadmin, version, modifiedby). Update listaccountsresponse to use std::vector<domain::accountsummary>.

Change listaccountsresponse::accounts to use a non-sensitive type like std::vector<domain::accountsummary>.

Local versus remote connectivity   code

In some cases it makes sense to use the UI directly against the database - for example, users may just want to create a simple setup to play around and the complexity of having to have a server is not helpful. In addition, they may not even require a full blown postgres - sqlite is enough. It should be possible to setup a connection to a database in this manner. Ideally the client should support both at the same time.

Allow in place editing of currencies   code

For expediency users should be able to edit multiple currencies and save them in one go directly in the grid. Shift enter to edit a field seems interesting.

Users need to be made aware when there are changes in CRUD objects, and there needs to be a reload button to reload data from the database in that case. This could be done by making the reload button a different colour when data is available.

Make the reload button blue when there are changes.

Notes:

  • history windows should also have the notification.

Light system theme results in mix of dark and light   code

We need to ensure we can have both light and dark themes and they work consistently.

Setup Qt properly on Windows   code

Seems like our package is still missing Qt DLLs. Use the windows tool to determine what is missing. Consider installing Qt in the build machine via the built packages.

Add SC script on windows to install ores.service   code

We should package a trivial batch file that sets up the service on windows. We should also consider adding a simple script to setup the service on Linux. Ideally it should be done via the packaging step.

Package SQL scripts   code

We need to initialise the database on installation. The package should contain all of the necessary SQL as well as a script to do it.

Or maybe we should do everything from within sqlgen and generate the scripts for the cases where we need manual work in database.

Remove postgres passwords from github workflows   code

As a quick hack we added the dev passwords to the workflows. We should really generate these on the fly and supply them to the tests.

Allow supplying the postgres connection URI   code

At present we are supplying all of the components for the connection. It may be easier to allow the entire URI:

  • connection-uri: The connection URI to connect to PostgreSQL. Example: postgresql://postgres:postgres@localhost/postgres.

Consider adding MCP support   code

From Kaggle course:

Model Context Protocol (MCP) is an open standard that lets agents use community-built integrations. Instead of writing your own integrations and API clients, just connect to an existing MCP server.

MCP enables agents to:

  • Access live, external data from databases, APIs, and services without custom integration code
  • Leverage community-built tools with standardized interfaces
  • Scale capabilities by connecting to multiple specialized servers

2.1: How MCP Works

MCP connects your agent (the client) to external MCP servers that provide tools:

  • MCP Server: Provides specific tools (like image generation, database access)
  • MCP Client: Your agent that uses those tools

All servers work the same way - standardized interface Architecture:

┌──────────────────┐ │ Your Agent │ │ (MCP Client) │ └────────┬─────────┘ │ │ Standard MCP Protocol │ ┌────┴────┬────────┬────────┐ │ │ │ │ ▼ ▼ ▼ ▼ ┌────────┐ ┌─────┐ ┌──────┐ ┌─────┐ │ GitHub │ │Slack│ │ Maps │ │ … │ │ Server │ │ MCP │ │ MCP │ │ │ └────────┘ └─────┘ └──────┘ └─────┘

Links:

Add country support   code

We will probably need country support at some point. We should link the country to the currencies, where applicable.

Log file location for Qt application is non-standard on Linux   code

At present we need to manually create the log directory for the gui to fix this error:

[marco@lovelace bin]$ ./ores.qt terminate called after throwing an instance of 'boost::filesystem::filesystemerror' what(): boost::filesystem::createdirectories: Permission denied [system:13]: "opt/OreStudio/0.0.3/bin../log", "opt/OreStudio/0.0.3/bin../log" Aborted ./ores.qt

We should really output the log file in a standard location such as /var/log or something.

Create shared object interfaces   code

At present we are building shared objects / DLLs for the ores components, but we did not bother defining proper interfaces, exporting symbols etc. This causes problems on windows:

LINK : fatal error LNK1104: cannot open file 'projects\ores.utility\ores.utility.lib'

This is happening because we are not exporting explicitly any symbols. To fix this we did a hack:

if(WIN32 AND MSVC)
    # Export all symbols on windows for now. Bit of a hack.
    set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
endif()

The right solution for this is to annotate all the public types of each SO correctly, exporting symbols for all platforms:

Deep seek analysis:

Yes, Boost provides a cross-platform wrapper for exporting symbols using the
`BOOST_SYMBOL_EXPORT` macro from the **Boost.DLL** library. This macro abstracts
away the compiler-specific keywords required for different platforms.

### 🗂️ Boost's Cross-Platform Symbol Exporting

To export a symbol, you use the `BOOST_SYMBOL_EXPORT` macro in your code. Under
the hood, it expands to the correct compiler-specific attribute:

- On **Windows** with MSVC, it becomes `__declspec(dllexport)`
- On **macOS** and **Linux** with GCC/Clang, it becomes `__attribute__((visibility("default")))`

Here is a basic example of how to use it to export a global variable:

```cpp
#include <boost/config.hpp> // For BOOST_SYMBOL_EXPORT

class my_plugin_api {
    // Your interface definition
};

namespace my_namespace {
    class my_plugin_sum : public my_plugin_api {
        // Implementation
    };

    // Export the 'plugin' variable
    extern "C" BOOST_SYMBOL_EXPORT my_plugin_sum plugin;
    my_plugin_sum plugin;
}
```
*Note: The `extern "C"` is used here to prevent C++ name mangling, making the symbol name
predictable for tools that use C linkage. This is often crucial for a library's public API.*

For exporting factory functions, Boost offers the `BOOST_DLL_ALIAS` macro, which
is often more convenient:

```cpp
#include <boost/dll/alias.hpp> // For BOOST_DLL_ALIAS

namespace my_namespace {
    class my_plugin_aggregator : public my_plugin_api {
        // Implementation
    };

    // Factory function
    boost::shared_ptr<my_plugin_api> create() {
        return boost::shared_ptr<my_plugin_aggregator>(new my_plugin_aggregator());
    }

    // Export the factory function with the alias "create_plugin"
    BOOST_DLL_ALIAS(my_namespace::create, create_plugin)
}
```

### 💡 A Complementary Approach: Controlling Visibility

While Boost's macro solves the declaration problem, for finer control and to
minimize your shared library's public API, combine it with compiler flags that
hide all symbols by default.

- **On Linux and other ELF platforms**, use the `-fvisibility=hidden` flag. You
  can then use a **linker version script** to explicitly list the symbols you
  want to export.
- **On macOS**, use the `-fvisibility=hidden` flag and an **exported symbols
  list** with `-exported_symbols_list` during linking.
- **On Windows**, symbol visibility is typically controlled explicitly via
  `__declspec(dllexport)` or a module definition (.def) file, which
  `BOOST_SYMBOL_EXPORT` already handles.

Setting default visibility to hidden helps create a cleaner, more efficient
library by reducing its footprint, improving load times, and avoiding potential
symbol conflicts.

### 🔧 Summary

For a complete cross-platform solution:

1. **Use Boost.DLL macros**: Incorporate `BOOST_SYMBOL_EXPORT` or
   `BOOST_DLL_ALIAS` in your code to handle platform-specific export keywords.
2. **Hide symbols by default**: Compile your shared library with
   `-fvisibility=hidden` on Linux and macOS. This works in conjunction with the
   Boost macros.
3. **Use version scripts (optional)**: For maximum control on ELF platforms
   (Linux) or via an exported symbols list on macOS, use these linker features
   to define a precise public API.

I hope this helps you build your cross-platform shared library! If you have more
questions about using the Boost.DLL library for loading these symbols at
runtime, feel free to ask.

Links:

Update timestamps to use timezone   code

Read up on ECS   analysis

Links:

Consider adding otel support   code

Links:

Add trace context propagation to messaging protocol   code

To enable distributed tracing across client and server, trace context needs to be propagated in the messaging protocol.

Tasks:

  • Extend frame header to include optional traceid and spanid fields.
  • Update frame serialization/deserialization.
  • Client includes trace context in outgoing request frames.
  • Server extracts trace context and creates child spans linked to client's trace.

Create span collection and export infrastructure   code

The telemetry component has span types defined but no infrastructure to collect and export completed spans.

Tasks:

  • Create span_collector interface for accumulating completed spans.
  • Implement span_exporter interface (similar to log_exporter).
  • Create file_span_exporter that writes spans as JSON Lines.
  • Integrate span export with lifecycle_manager or create telemetry_provider.

Add OTLP exporter for OpenTelemetry collector   code

For production observability, export telemetry data to an OpenTelemetry collector using the OTLP protocol.

Tasks:

  • Add OTLP protocol buffer definitions or use existing C++ OTLP library.
  • Implement otlp_log_exporter for log records.
  • Implement otlp_span_exporter for traces.
  • Add configuration for collector endpoint.
  • Consider gRPC vs HTTP transport.

Links:

Add chat support   code

Links:

Consider using getML to integrate ML   code

Links:

  • GH: getml: "getML is a tool for automating feature engineering on relational data and time series. It includes a specifically customized database Engine for this very purpose."
  • user guide quick start

Configure postgres with async IO   code

Consider using sqls for LSP   code

We are presently testing postgrestools. If that does not work well, we should consider sqls.

Links:

Add workspace as a container   code

Core needs to have a container for all of the data stored within a context.

Actually, according to Data Priented Principles, we may not need it. This may be a UI concept but not a code concept.

Add portfolio support   code

Setup code quality actions   infra

We added a test password to the repo on purpose to see if it was going to be detected by the github actions:

std::string connection_string("postgresql://ores:ores@localhost:5433/oresdb");

It wasn't. We need to figure out which actions need to be setup for this. Add any other actions we may be missing.

The build seems to be failing:

-- SCCache NOT found.
 CMake Error at /usr/local/share/cmake-3.30/Modules/CMakeDetermineSystem.cmake:152 (message):
   Could not find toolchain file:
   /home/runner/work/OreStudio/OreStudio/vcpkg/scripts/buildsystems/vcpkg.cmake
 Call Stack (most recent call first):
 CMakeLists.txt:61 (project)


 CMake Error: CMake was unable to find a build program corresponding to "Unix Makefiles".  CMAKE_MAKE_PROGRAM is not set.  You probably need to select a different build tool.
 CMake Error: CMAKE_CXX_COMPILER not set, after EnableLanguage
 -- Configuring incomplete, errors occurred!
 ~/work/OreStudio/OreStudio ~/work/OreStudio/OreStudio
 ~/work/OreStudio/OreStudio
 cpp/autobuilder: No supported build command succeeded.
 cpp/autobuilder: autobuild summary.
 Error: We were unable to automatically build your code. Please replace the call to the autobuild action with your custom build steps. Encountered a fatal error while running "/opt/hostedtoolcache/CodeQL/2.18.0/x64/codeql/cpp/tools/autobuild.sh". Exit code was 1 and last log line was: cpp/autobuilder: autobuild summary. See the logs for more details.

This may be due to a missing sub-module for vcpkg.

Starting UI from file manager does not work   infra

At present we can't start the Qt UI because the file manager thinks its a video. Maybe we need a desktop file.

Example desktop file:

[Desktop Entry]
Comment=
Terminal=true
Name=fixvideo
Exec=/home/user/fixvideo.sh %f
Type=Application
Icon=/usr/share/icons/gnome/48x48/apps/gnome-settings-theme.png
Encoding=UTF-8
Hidden=false
NoDisplay=false
Categories=AudioVideo;Player;Recorder;
MimeType=video/dv;v

Source: Is there a standard mode for .ini files?

Tasks:

  • create a desktop file for the application.
  • add an icon.

Consider adding the update copyrights action from quantlib   infra

We should remove copyrights from each file and instead have it only at the top-level to make maintenance easier.

See copyrights.yml in QuantLib repo.

Investigate git UIs for history display   infra

Links:

  • Gittyup: "Gittyup is a graphical Git client designed to help you understand and manage your source code history. "

Investigate GoldenCheetah for ideas on graph displays   code

Seems particularly useful for report overviews and headline positions.

Links:

  • GH GoldenCheetah: "GoldenCheetah is a desktop application for cyclists and triathletes and coaches."

Investigate the toolbar icon style in serial studio   code

Investigate the graphs used in dirstat   code

Seems like a good way of showing deal contribution to position.

Links:

Consider adding clang-tidy build   infra

As per QuantLib build: tidy.yml.

Consider adding test times build   infra

As per QuantLib build: test-times.yml.

Consider adding sanitizer build   infra

As per QuantLib build: sanitizer.yml.

Use string views for static strings   infra

We are creating std::strings where we don't need them, use string views instead.

This is not trivial, when we tried a lot of things were borked.

Add discord support to app   infra

It would be nice if we could post messages from the app into discord.

Links:

Recipes do not show variables in org-babel   infra

At present when we look at a recipe in the site, we cannot tell what the environment variables are:

./ores.console import ${log_args} --currency-configuration ${currency_config_dir}/currencies.xml

It would be nice if log_args etc showed up in the recipe.

Links:

Install OSX package on OSX machine   infra

We need to install and run the windows package and make sure it works. Check console and GUI start.

Work through all types required for Example 1   code

We want to be able to visualise all the data types needed in order to be able to run the most basic example of ORE. For each of these types, create a stories.

The files are as follows. First, there are the files in the Input directory:

Specifically:

  • currencies.xml
  • netting.xml
  • ore.xml
  • ore_swaption.xml
  • plot.gp
  • portfolio.xml
  • portfolio_swap.xml
  • portfolio_swap_20151023.xml
  • portfolio_swaption.xml
  • portfolio_swaption_20151023.xml
  • simulation.xml

In addition, we need all of the common inputs under:

These are:

  • calendaradjustment.xml
  • conventions.xml
  • currencies.xml
  • curveconfig.xml
  • fixings_20160205.txt
  • market_20160205.txt
  • market_20160205_flat.txt
  • pricingengine.xml
  • todaysmarket.xml

Finally, we need support for the outputs. We can grab these from the expected outputs:

These are:

  • colva_nettingset_CPTY_A.csv
  • curves.csv
  • exposure_nettingset_CPTY_A.csv
  • exposure_trade_Swap_20y.csv
  • flows.csv
  • log_progress.json
  • netcube.csv
  • npv.csv
  • swaption_npv.csv
  • xva.csv

Consider adding support for A/B testing   code

At present feature flags are global. However, we may want to enable a feature for a subset of the population. Analysis:

To support **gradual rollout (ramping)** of features—e.g., enabling a feature
for 10% of users, then 50%, then 100%—you need to extend your feature flag
system beyond a simple boolean toggle. The current temporal table design
(`feature_flags` with validity periods) is great for time-based control, but
**not sufficient for user-based targeting**.

Here’s a practical, scalable approach that integrates well with your C++23/Qt/PostgreSQL stack:

---

### 🎯 Goal
Enable a feature **conditionally** based on:
- User identity (e.g., user ID, tenant ID, or client ID)
- A **rollout percentage** (e.g., 10%)
- Optional: user attributes (role, region, etc.)

---

### ✅ Step 1: Enhance the Feature Flag Schema

Add **rollout strategy metadata** to your `feature_flags` table:

```sql
ALTER TABLE oresdb.feature_flags
ADD COLUMN rollout_percentage INTEGER CHECK (rollout_percentage BETWEEN 0 AND 100) DEFAULT 100,
ADD COLUMN targeting_criteria JSONB; -- optional, for advanced rules
```

Now each flag version can specify:
- `rollout_percentage = 10` → enable for ~10% of users
- `targeting_criteria = '{"role": "beta_tester"}'` → (future extensibility)

> Keep your temporal primary key and exclusion constraint — they still apply.

---

### ✅ Step 2: Determine a Stable User Identifier

Your client must provide a **consistent, hashable ID** per user or session, such as:
- User ID (if authenticated)
- Device ID / client UUID (if anonymous)
- Tenant ID (for multi-tenant apps)

This ID must be **stable** across sessions so the same user doesn’t see the feature flicker on/off.

> 💡 In your Qt client, generate or retrieve this ID at startup and pass it to the feature flag service.

---

### ✅ Step 3: Implement Consistent Hash-Based Sampling in C++

Use a **deterministic hash** to map user IDs into a 0–99 bucket:

```cpp
#include <functional>
#include <string>

bool should_enable_for_user(std::string_view feature_name,
                            std::string_view user_id,
                            int rollout_percentage) {
    if (rollout_percentage <= 0) return false;
    if (rollout_percentage >= 100) return true;

    // Combine feature name + user ID to avoid correlation across features
    std::string key = std::string(feature_name) + ":" + std::string(user_id);

    // Use a stable hash (e.g., std::hash, but note: not guaranteed consistent across runs)
    // For production, prefer a consistent hash like FNV-1a or CityHash
    auto hash = std::hash<std::string>{}(key);
    int bucket = static_cast<int>(hash % 100);
    return bucket < rollout_percentage;
}
```

> ⚠️ **Warning**: `std::hash` is **not guaranteed to be stable across program runs or platforms**.
> For reliable rollout, use a **stable hashing algorithm** like **FNV-1a**, **MurmurHash3**, or **xxHash**.

Example with a simple FNV-1a (C++23-friendly):

```cpp
constexpr uint32_t fnv1a_32(std::string_view s) {
    uint32_t hash = 2166136261u; // FNV offset basis
    for (char c : s) {
        hash ^= static_cast<uint8_t>(c);
        hash *= 16777619u; // FNV prime
    }
    return hash;
}

bool should_enable_for_user(std::string_view feature_name,
                            std::string_view user_id,
                            int rollout_percentage) {
    if (rollout_percentage <= 0) return false;
    if (rollout_percentage >= 100) return true;

    std::string key{feature_name};
    key += ':';
    key += user_id;

    uint32_t hash = fnv1a_32(key);
    return (hash % 100) < static_cast<uint32_t>(rollout_percentage);
}
```

This ensures:
- Same user → same decision
- Uniform distribution across users
- Independent per-feature rollout

---

### ✅ Step 4: Update Your Feature Flag Service

Modify your C++ `FeatureFlagService`:

```cpp
class FeatureFlagService {
public:
    // Returns true if the feature is enabled AND user qualifies
    bool is_enabled_for_user(Feature f, std::string_view user_id) const;

private:
    struct FlagConfig {
        bool enabled;
        int rollout_percentage; // 0–100
        // add targeting_criteria later if needed
    };
    std::unordered_map<Feature, FlagConfig> cache_;
};
```

Implementation:

```cpp
bool FeatureFlagService::is_enabled_for_user(Feature f, std::string_view user_id) const {
    auto it = cache_.find(f);
    if (it == cache_.end() || !it->second.enabled) {
        return false;
    }
    return should_enable_for_user(to_string(f), user_id, it->second.rollout_percentage);
}
```

---

### ✅ Step 5: Integrate in Qt UI

```cpp
QString userId = getCurrentUserId(); // from auth, settings, etc.

if (featureFlagService.is_enabled_for_user(Feature::ExperimentalUI, userId.toStdString())) {
    ui->experimentalPanel->show();
}
```

---

### ✅ Optional: Advanced Targeting (Future-Proofing)

Use the `targeting_criteria JSONB` column to store rules like:
```json
{
  "min_version": "2.1.0",
  "regions": ["EU", "NA"],
  "roles": ["admin", "beta"]
}
```

Then evaluate these in C++ (or push filtering to DB with JSONB queries if you fetch per-user flags).

But for **simple ramp-up**, percentage-based hashing is sufficient and efficient.

---

### ✅ Operational Benefits

- **No client-side config changes** needed to ramp from 10% → 50% → 100% — just update the DB.
- **Auditability**: Every rollout change is versioned in your temporal table.
- **Safety**: You can instantly roll back by setting `rollout_percentage = 0`.

---

### Summary

| Component           | Change |
|---------------------|--------|
| **Database**        | Add `rollout_percentage INT` to `feature_flags` |
| **C++ Service**     | Add `is_enabled_for_user(feature, user_id)` |
| **Hashing**         | Use stable hash (e.g., FNV-1a) over `feature:user_id` |
| **Qt UI**           | Pass user ID to flag checks |

This gives you **safe, gradual, observable rollouts** while keeping your architecture clean and performant.

Event Viewer advanced features   code

Advanced features for the Event Viewer dialog that are not part of the initial implementation.

  • Filtering and Search
    • Filter by event type (dropdown with checkboxes).
    • Filter by source (local/remote/all).
    • Text search across all fields.
    • Time range filter.
  • Real-time vs Paused Mode
    • Pause/Resume button to stop event capture temporarily.
    • Max events spin box to limit history (e.g., last 1000 events).
  • Event Statistics Panel

    Collapsible panel showing:

    • Events per second (rolling average).
    • Event type breakdown (pie chart).
    • Most active event types.
  • Export Functionality
    • Export to JSON file.
    • Export to CSV.
    • Copy selected events to clipboard.
  • Event Replay

    Store captured events and allow replay to test widget behavior:

    void replayEvent(const EventRecord& record) {
        // Re-publish the event to the bus
        eventBus_->publish(record.reconstruct());
    }
    
  • Subscription Visualisation

    A secondary tab showing a graph/table of:

    • All known event types.
    • Which widgets are subscribed to each.
    • Subscription counts over time.
  • Breakpoints / Alerts

    Set conditions to pause or highlight specific events:

    • "Break when currencychanged with isocode='USD'".
    • "Highlight all events with more than 10ms processing time".

Far

Stories that we want to capture, but won't work on for a while.

LLM Integration   code

LLMs can be useful when learning a new subject as they can provide additional context to the information displayed in the screen. For example, a user can ask the LLM to explain a graph or a table. It would probably be fairly straight forward to allow dumping some of the information in a format that is friendly to LLMs (.e.g./ PNG, Markdown, plain text) and then make an API call to a local or remote LLM. We could probably create a set of useful canned prompts (explain this report, explain this chart).

On a more blue skies approach, one could conceive asking the LLM for suggestions on how to act, on the basis of the analysis. This could result in suggestions for action the user could implement, or even on actions directly taken based on the LLM's suggestions. This is conceptually straightforward: the LLM could for example generate a well defined JSON with the proposed action, and the system would look for some predefined markers in the LLM output:

----- ACTION START
<JSON>
----- ACTION END

The JSON payload would describe the action:

{
    "action": "some_action_type",
    "key1": "value1",
    ....

A trivial lookup table could de-serialise the JSON and execute the action. All that is required is for the LLM to "learn" how to generate JSON compliant with the desired format, which should be quite straightforward (perhaps with the help of fine-tuning). Agents probably provide most of this infrastructure already. The key thing is to ensure all functionality in the core becomes UI agnostic such that one could bolt an NLP UI around it.

Links:

Support multiple ORE "toolchains"   code

Much like with an IDE, where one can have multiple toolchains configured, we need to also support multiple versions of ORE. Unlike with IDEs, it may be desirable to run computations with more than one version of ORE for comparison purposes. This means we need a way to associate outputs with their ORE version. This approach does not necessarily fit the existing example code, because these have a single "output directory". However, we just need way to associate N toolchains with a given workspace or possibly component; when present, the output directory starts to reflect the toolchain configuration. For example, with CMake we use presets:

  • linux-clang-debug
  • linux-clang-release
  • linux-gcc-debug
  • linux-gcc-release

For ORE the only dimension under which variability is possible is the version. We can then have pricing engine configurations that are either the same, or possibly different:

  • for a workspace;
  • for a component;
  • for a toolchain version.

Footer

Previous: Agile

Emacs 29.1 (Org mode 9.6.6)