Sprint 28
Table of Contents
This page documents a sprint (Sprint 28) of ORE Studio. It captures the sprint's mission, current status, and the stories that compose it. For the surrounding context — version goals, sprint order, and product identity — see Version 0.
1. Mission
Finish the work carried out of sprint 27 — the record screens, the remaining journeys, and the rest of its remainders — before drawing anything new from the product backlog.
Sprint 28 opens with 41 stories carried from sprint 27, across nine themes: the record screens and the web UX standard, the journeys in ores.web, four-eyes approvals, market-data feeds and bindings, security and tenancy, the grid and telemetry, reporting and ACME data, trading-model integrity, and codegen and data-quality debt. The sprint commits to finishing those stories rather than adding scope. Sprint 27's retrospective asked for fewer stories in flight, so nothing new is pulled from the product backlog this sprint.
2. Status
| Field | Value |
|---|---|
| State | STARTED |
| Parent version | Version 0 |
| Previous | Sprint 27 |
| Start | 2026-10-13 |
| End (expected) | 2026-10-20 |
| Now | Sprint 28 in flight: finishing the work carried from sprint 27. |
| Waiting on | Nothing. |
| Next | Pick the first story. |
| Release Notes | ORE Studio Sprint 28 – Release Notes |
| Last touched | 2026-10-13 |
3. Stories
For the definitions of the themes see Themes.
3.1. Product
| Story | State | Start | End | Description |
|---|---|---|---|---|
| Sprint health review — System 2 analysis | DONE | 2026-10-24 | 2026-10-24 | Recurring System 2 health reviews of sprint 28, covering goal alignment, load, PR velocity, story and task balance, focus signal, and bookkeeping hygiene. |
| Open sprint 28 | DONE | 2026-10-13 | 2026-10-13 | Scaffold sprint 28, wire the version manifest and the agile index, bump the project version to 0.0.28, and update the vcpkg submodule. |
| Populate sprint 28 with the carried stories | DONE | 2026-10-13 | 2026-10-13 | Move sprint 27's carried stories and their successors from the product backlog inbox into sprint 28, and wire them into the sprint table. |
| Trigger a report run on demand or on a schedule | DONE | 2026-10-14 | 2026-10-15 | Make a trigger the only way a run is admitted, so a person can run a report without a schedule and both paths share one handler. |
| Populate the ACME books with a realistic trade population | DONE | 2026-10-15 | 2026-10-24 | Generate a stable, present-relative trade population into ACME books from ores.synthetic, referencing its own books, counterparties and staff, starting with bonds. |
| Bring the FX spot conventions onto the market standard | ABANDONED | 2026-10-24 | Correct the FX spot conventions where they disagree with the market: the pair's spot lag, the quote precision, the spot tick size and the end-of-month roll, and record the evidence behind each. | |
| Rework the FX instruments to the instrument table rule | DONE | 2026-10-18 | Bring the FX family onto the data-oriented design guidelines, from the 2026-10-16 review. Seven units: carry the ORE money digits, give the accumulator's range bounds a child table, agree the continuous columns, batch the service reads, key the soft references, close the money gate, and settle the discriminators. | |
| Rework the equity instruments to the instrument table rule | DONE | 2026-10-18 | Apply the bond pattern to the equity family: a family header holding exactly its codes, product fact tables, shared children with role codes, and securities keyed by their reference datum. | |
| Provision the streams services durably consume | DONE | 2026-10-17 | 2026-10-18 | Nothing creates the JetStream streams that services durably consume, so provisioning aborts on a five second publish timeout, and stale overlapping streams stop a service starting. Apply the documented stream provisioning pattern where it is missing, and add the check that keeps the next service from repeating it. |
| Carry the rates family's fields across the ORE boundary | DONE | 2026-10-18 | 2026-10-24 | The rates family's structure is right and its boundary disagrees with it: a short forward rate agreement stores as a long, an inflation swap cannot be stored, a floor returns as a cap, and four more fields are dropped or degraded. Close the review's Critical and Important findings, other than the one recorded as the component's, in units that each prove their finding, then add the check that would have caught them. |
| Refactor conventions onto families and bundles | DONE | 2026-10-24 | Conventions fail to build on MSVC because one aggregate carries every family. Refactor them onto the classification: one family per convention, a bundle per import applied in one unit of work, and the ORE file demoted to a package at the boundary. | |
| A trader screen that resolves a tenor to a date, before any editing | DONE | 2026-10-18 | 2026-10-18 | A trader asks what date a tenor gives on a horizon, and the authoring journey cannot answer it because it has no horizon or calendar field. A read-only resolve page asks for the four things resolution needs and reads the date, the anchor it counted from and the schedule it rolled on. |
| Trade Blotter | DONE | 2026-10-19 | 2026-10-24 | Build the Trade Blotter: the primary front-office screen for viewing, booking, amending, and routing trades through their lifecycle. First, check that the trade prototypes still follow the entity screen specification. |
3.2. Hotfixes
| Story | State | Start | End | Description |
|---|---|---|---|---|
| Account for the grid's usage | ABANDONED | 2026-10-24 | A super administrator needs to know which tenant is using the grid, and the work that answers it is tenant-owned, so reading it across tenants is the widening the guard forbids. The installation records what it did instead: the compute service, already inside each tenant as it dispatches that tenant's work and takes the result back, writes a usage row. This story builds that ledger and the global view it feeds. | |
| Fix the defects the bond family review found | ABANDONED | 2026-10-24 | Bonds were the data-oriented design pilot, reworked across sprints 25 to 27. Review the family's current data model against the Regime 2 checklist and record what holds and what does not. | |
| Audit the FX instrument family against the data-oriented design guidelines | DONE | 2026-10-16 | 2026-10-16 | Review the seven FX instrument models and their generated artefacts against the Regime 2 checklist, and record what holds and what does not. The family was never reworked to the method, so the review asks whether it was ever built to the rules. |
| Audit the rates instrument family against the data-oriented design guidelines | DONE | 2026-10-18 | 2026-10-18 | Review the rates family header, its nine product fact tables, its shared children and their generated artefacts against the Regime 2 and Regime 3 checklists, and record what holds and what does not. The family was reworked to the instrument table rule in sprint 27, so the review asks whether the reworked tree meets the guidelines rather than whether it was ever built to them. |
| Approve a reporting line change by the proposed manager | ABANDONED | 2026-10-24 | A change to someone's reporting line becomes a four-eyes decision: it is proposed, and the person it would make their manager approves or declines it, like a role request. | |
| Bring the existing screens to the entity screen specification | ABANDONED | 2026-10-24 | Check the currency screens and every other existing screen against the entity screen specification and the record screen standard, and fix each difference in one PR. | |
| Build the retire or reset tenant journey | DONE | 2026-10-24 | The Retire or reset a tenant journey has a document and no implementation: suspend has no operation, terminate, deprovision and purge have SQL functions but no subjects, and a party-level reset has no subject. The roster's row menu shows Retire or reset as not built until these exist. | |
| Clean ores.synthetic to the component clean standard | ABANDONED | 2026-10-24 | Bring ores.synthetic to the Component Clean Standard (Entity items): tier 3, domain component. | |
| Close the credit loose ends | DONE | 2026-10-21 | The three gaps the credit rework left open: the ORE export drops a required element from 17 example documents, the IMM_ROLL algorithm behind the credit and CDS tenor convention throws, and the netting sets wait for a credit-limit entity. | |
| Codegen facet: generate the DQ publish-from-dq pattern | ABANDONED | 2026-10-24 | Add an ores.codegen facet that generates the SECURITY DEFINER publish-from-dq SQL function for the homogeneous family — about 29 of the 57 hand-written copies — from a declaration on the entity's codegen model, and unify the eight per-service publish_from_dq handlers rather than generating 57 of them. | |
| Decide the XML strategy for ORE documents | DONE | 2026-10-17 | 2026-10-21 | Choose how ORE XML becomes ORE Studio records. A measured prototype points at a zero-copy scanner driven by tables generated from the XSD, in place of the generated xsdcpp binding. |
| Edit a party on a standard entity page | ABANDONED | 2026-10-24 | Replace the party wizards with a standard entity page for a party: a list, a page with cards and tabs, and dialogs, built from the shared record parts. A save writes directly for now. The four-eyes approval of party changes belongs to the story Build the four-eyes framework. | |
| End a session when its window closes, not when it is unattended | ABANDONED | 2026-10-24 | A session ends when the browser window that held it is gone, and never because a screen sat unattended for a while, so traders can leave their screens open. Presence, not activity, decides. | |
| Finish moving the hand-written SQL onto models | ABANDONED | 2026-10-24 | Bring the last hand-written SQL under codegen: the four populate pipelines that predate the dataset archetypes, and the tables that have a codegen shape but no model. Both are the defect the DQ artefact migration fixed for staging tables — schema and its loader written by hand, and checked by nothing. | |
| Hotfix: the debug builds never finish | DONE | 2026-10-19 | 2026-10-19 | Every debug leg of Continuous and Nightly times out because the compiler cache it would warm never gets stored. |
| Hotfix: the services die on shutdown | DONE | 2026-10-18 | 2026-10-18 | A service can destroy the state a NATS handler is still writing to, and dies on a core dump. |
| Hotfix: the site stops on a link it cannot resolve | DONE | 2026-10-18 | 2026-10-18 | A full site build aborts on an org id no page defines, because two links spell it in upper case. |
| Keep counting failed attempts on a locked account | ABANDONED | 2026-10-24 | A locked account still counts its failed sign-in attempts and records the address of each, so a run of attempts against a locked account shows as an attack. | |
| Keep the record screens up to date | DONE | 2026-10-24 | The web screens read once and never learn that a record changed elsewhere. Add live updates from the change events to the browser, a Refresh button on the record page and the list, and a stated behaviour when the record under edit changed: tell the person, show what changed, and let them keep their edit or take the new values. Complete the 'Updates and refresh' section of the entity screen specification and the Change notification page. | |
| Link every reference to its record | ABANDONED | 2026-10-24 | Replace the per-screen address functions with one system-wide mechanism, so every foreign key a web screen shows is a link to the page of the record it names. | |
| Move the installation's remaining reads onto its own class | ABANDONED | 2026-10-24 | The roster, the logs, the bus and the versions are facts about the deployment, not about a tenant. Story 58F3FC7C named that class and gave it a policy shape; this story moves the remaining reads onto it. The design is doc/knowledge/architecture/tenant_ownership_and_the_information_flow.org (id 5A5D6490-AF64-4AAF-8B3D-48EF3EDAF3D2). | |
| Name the record in a change event | ABANDONED | 2026-10-24 | A change event says that an entity changed and names no record, so a record screen cannot tell whether the change concerns the record it shows. Carry the key of the changed row on every entity event, pass it to the browser, and let a record screen go stale only for its own record. | |
| Paint every web badge from the catalogue | ABANDONED | 2026-10-24 | Replace the hand-picked Tag tones on state and type values in ores.web with one shared Badge component that paints from the badge catalogue. | |
| Raise a notification for a scenario waiting for a tester | ABANDONED | 2026-10-24 | Story 3 of the QA runner arc. A scenario that waits for a tester raises an inbox notification and the bell shows it. Add a tester role and an assignment, and a permission for the Development module. Today any signed-in user may call the QA routes. Also settle whether the module runs in production, since a deployed BFF has no work tree. | |
| Record system events in a central event log | ABANDONED | 2026-10-24 | Extend ores.telemetry with a central log of key system events, apart from the logs: a catalogue of event types, a publish API every service calls, a collector that stores them with their subject, an Operations Events screen, and events in each record's History. Feed runs are the first client. | |
| Session activity: record the size of every NATS message per server | ABANDONED | 2026-10-24 | Count the bytes of every NATS message each server receives and sends, and write the totals to the database at a fixed interval, so the session activity has samples to draw. | |
| Restore the trading guards the versioned model dropped | ABANDONED | 2026-10-24 | Making every trading entity versioned removed the immutable profiles, and two guarantees went with them without a replacement: a trade's reported portfolio no longer has to belong to the trade's party, and a raw update rewrites every version of a row instead of opening a new one. | |
| Seed a relative-time trade population with the market data it needs | ABANDONED | 2026-10-24 | A new ACME system has no time horizon and no deal population, so nothing says which historical fixings or market data it needs. Hold a sample ACME trade corpus in DQ whose dates are relative to the install date, then derive the market data that corpus requires and generate it, including historical fixings, in ores.synthetic. | |
| Sort every list by when it was updated | ABANDONED | 2026-10-24 | Every list can be ordered by the time of the latest save, so the newest changes come first. | |
| Trace a process run and the trade groups it creates | ABANDONED | 2026-10-24 | A process that acts on a set of trades must be traceable, so it can be undone or repeated. Record each run with an identity and a state machine, name the process it is a run of, and let the trade groups its inputs and outputs carry the run's key. Waits on one process with a real client. | |
| Validate a curve pillar's tenor codes | ABANDONED | 2026-10-24 | ir_curve_bootstrap_pillar.start_tenor_code and end_tenor_code are undeclared soft references to refdata_tenors. The only database check validates curve_role_code, so a typo in a tenor code saves and then throws at bootstrap time inside curve_republish_resolver, where the end tenor doubles as the quote point id. | |
| Prove the report grid run end to end | DONE | 2026-10-08 | 2026-10-24 | The ACME report definition runs to completion against the compute grid from an input bundle that already exists, the compute results are retrieved, and the run is reproducible from a freshly recreated database. |
| Move the lookup artefact tables and settle the remaining DQ artefact models | DONE | 2026-10-13 | 2026-10-14 | Move the fifteen lookup-template artefact tables onto domain models and retire the lookup artefact template, settle the owner of the DQ-only models including the GLEIF tables, and model the geo ip2country store so its staging table is generated from a model. |
| Bring the role screens to the standard | ABANDONED | 2026-10-24 | Move the roles list and role page onto the shared record parts, with paged server reads for roles and for the people who hold a role. | |
| Raise approval requests from the remaining gated write paths | ABANDONED | 2026-10-24 | The party, convention and tenor screens, the ORE import and the shell counterparty commands raise approval requests instead of writing gated data directly. | |
| Add entity groups and finish the remaining codegen work | DONE | 2026-07-29 | 2026-10-24 | Add an entity group annotation to the model and a group flag to codegen, and finish the remaining codegen work: the model drift fixes, the counterparty logo picker and the tenor convention messaging layer under codegen, and the literate template split. |
| Find a trade by its identifiers, state, book and date from one list | ABANDONED | 2026-10-24 | A person finds a trade by its identifier, state, book, date, counterparty, trade type or enum column from one list. | |
| Gather each trade set and its market data | DONE | 2026-10-24 | Partition a report's trade population into trade sets and record them against the run, export one trade set as an archive and map it into the ORE portfolio, resolve and export each set's market data at its as-of, hand each configuration to its owner by id at an as-of, and assemble the package only w | |
| Give the other prototype groups their design notes | ABANDONED | 2026-10-24 | Give the eighteen remaining prototypes across eight groups their design notes, make every group page state the rule, and make the check refuse a prototype without a note. | |
| Record service lifecycle events and surface them in system health | ABANDONED | 2026-10-24 | Services announce their starts and graceful stops, telemetry records the events and raises restart notices, a service logs out on shutdown, and the system-health home shows the services. | |
| Build the synthetic collection and model catalogue journeys | ABANDONED | 2026-10-24 | A person runs a synthetic collection and keeps the yield curve model catalogue in ores.web, on the subjects the journeys name. | |
| Close the tenor journey and the remaining refdata gaps | DONE | 2026-10-15 | 2026-10-24 | The tenor resolution journey and the remaining refdata gaps are built: the tenor resolve operation and its screen, party membership versions, the convention family mapping and term rules, the portfolio right key, the Acme book-control actors, and the party list and history reads. |
| Draw every coded value as its badge | DONE | 2026-10-17 | A value that is a catalogue code is drawn through one shared renderer, so a screen shows the badge the code domain paints and never a bare code. Census the screens that still print codes as text, give the domains that have no badge their definitions, and hold the rule with a gate. | |
| Prove the credit round trip over the corpus | DONE | 2026-10-15 | Run the ORE round trip over the credit corpus at the new shape and prove that every trade survives import, export and re-import. | |
| Give each tenant its own buckets and scope the reaper | ABANDONED | 2026-10-24 | A tenant owns a bucket per data class, the storage service derives the tenant from the bucket, a step service reaches its tenant's buckets with its run token, a run's inputs and outputs are removed at run end with a 24-hour backstop, and the compute reaper acts inside each tenant. | |
| Design and seed the reports, configurations and portfolio trees each ACME party runs | ABANDONED | 2026-10-24 | Each ACME party gets the reports it would really run, with the configuration those reports need and a realistic portfolio tree, root portfolio and currencies. | |
| Build the bindings screen and clear the oresmd snags | DONE | 2026-10-16 | 2026-10-24 | A person lists bindings, says what each source writes and when it last ticked, binds and rebinds a party to a source, enables and disables a binding, and starts or stops the feed behind it, with the oresmd snags cleared. |
| Rework the market data feeds into a market data service with adapters | DONE | 2026-10-22 | 2026-10-24 | Move the simulated feeds behind a market data service: vendor ids and a mapping, sources with a kind, subscriptions and routes, adapters on NATS, metering and cost, and the simulator as one adapter, so the system treats live and simulated data in the same way. |
| Subscribe tenants to provider feeds and prove the browser at scale | ABANDONED | 2026-10-24 | A tenant or party subscribes to a provider's feeds through feed bindings, the feed screen standard states the browser, the two scopes and the subscription, and the feed browser is proved with tens of thousands of feeds. | |
| Complete the ACME report inputs and prove they run | ABANDONED | 2026-10-13 | 2026-10-24 | Add the analytic and exposure input documents the reports read through DQ, add a readiness check, give the platform reports their own report type, split an ORE file by a key, resolve the curve quote names against the feeds, and prove the exported packages run in ORE. |
| Audit the policies that let the system tenant read every tenant | ABANDONED | 2026-10-24 | Each policy that lets the system tenant read every tenant is either replaced by acting inside the tenant or listed as a reviewed exception with its reason, and a check fails the build on an unlisted one. | |
| Draw the node heatmap and carry the engine run statistics | ABANDONED | 2026-10-24 | The grid screen draws the node heatmap and state ribbon, a node sample states the engine's run time and peak memory, and the run statistics are measured, recorded and aggregated for the grid. | |
| Gate every ER diagram | ABANDONED | 2026-10-24 | Make the er-diagram check compare every generated group diagram and the index, discovered from the model rather than a hard-coded list. | |
| Fix the tenor basis swap convention model and the document TU | DONE | 2026-10-14 | 2026-10-24 | Split the tenor basis swap convention onto the data-oriented field groups its access patterns need, and find out why the configuration document protocol builds such a large MSVC translation unit, so the Windows build stops failing with C1202. |
| Cut the feed ingest round trips | DONE | 2026-10-14 | The market data ingest stores one observation per tick, and every database acquisition pays a session-context round trip before the insert. Collapse the session context to a single statement and measure the cost per stored tick. | |
| Investigate the broken Linux and macOS CI | DONE | 2026-10-14 | 2026-10-14 | Continuous Linux and Continuous macOS are red on main. The Linux clang jobs and the macOS release job exceed the six-hour runner limit, and the macOS debug job stops with 'No space left on device'. |
| Atomise every convention onto the central entity | DONE | 2026-10-14 | 2026-10-24 | Pilot the atomised entity shape with tenor basis swap, then convert every remaining convention onto one central convention row plus its kind-specific parts, one convention per PR. |
| Rebalance the CI tiers: Linux clang continuous, macOS and Windows nightly | DONE | 2026-10-14 | 2026-10-14 | No continuous job fits GitHub's six-hour limit. On the last green run linux-clang ran in about 2h50m, linux-gcc in about 4h10m, and macOS in 4h40m to 5h40m. Make linux-clang debug and release the only continuous builds and schedule them from their measured run time, and move macOS and Windows to nightly. |
| Cut the work the continuous CI jobs carry | DONE | 2026-10-14 | 2026-10-14 | Continuous Linux exists to prove the tree builds and the suites pass. It does not need coverage instrumentation or a package: the Nightly Build already runs coverage and memcheck, and the nightly and tag runs publish the packages. Take both off the continuous run and leave them where the archive is the deliverable. |
| Keep the compiler cache warm when a continuous job is cancelled | DONE | 2026-10-14 | 2026-10-14 | The continuous clang jobs ran in about an hour at an 85.72 % sccache hit rate on 2026-10-03, and need more than six hours at the 3 to 10 per cent they see now. A job that hits the six-hour limit is cancelled, and the Save sccache step is gated on !cancelled(), so every object that run compiled is thrown away. The cache can therefore never warm and the job can never finish. Save the cache whenever the CTest step ran and the local cache grew past a floor. |
| Unblock the unity build by hoisting the small-kappa threshold | DONE | 2026-10-14 | 2026-10-14 | Six process files each defined their own small_kappa_threshold in an anonymous namespace. A unity build concatenates them into one translation unit, which merges the unnamed namespaces and rejects the repeated name, so a whole-tree unity build stopped after 19 seconds in ores.analytics.quant. Hoist the value into one public constant of the component and include it where it is used. |
| Give the cache save time to run after the build stops | DONE | 2026-10-14 | 2026-10-14 | The cache-save guard only helps if the save finishes. A job that hits the six-hour limit is cancelled and its always() steps get roughly thirty seconds before the job is torn down, which is nowhere near enough to upload a multi-gigabyte compiler cache. Cap the CTest step far below the job limit so the build stops with time to spare and the cache actually reaches the store. |
| Fix the failing local gate checks | DONE | 2026-10-14 | 2026-10-14 | Three checks are red on main. The compass suite chmods the user's persona cache, which a sandbox makes read-only. Four IAM pgTAP suites need a tenant that only a provisioned environment has. And a marketdata case keys a manual point it never clears, which the suite's own non-declaration order turns into a failure of the case before it. Each check is fixed where it runs. |
| Move the version stamp out of the binaries | DONE | 2026-10-14 | 2026-10-14 | The build's git hash is compiled into ores.utility.lib, a shared library that 179 targets link, so the stamp changes on every commit and relinks all of them. Move the commit out of every binary into a manifest read at runtime, so a commit changes no compiled file and relinks nothing. |
| Report the nightly platform builds under the CDash Nightly group | DONE | 2026-10-14 | 2026-10-14 | macOS and Windows moved off the continuous tier, but their workflows still pass build_group=Continuous to CTest.cmake, so CDash files every macOS and Windows build under Continuous. Nightly Build already reports under Nightly. Move both to Nightly so CDash matches the schedule the workflows now run on. |
| Stop deleting the compiler cache before saving it | DONE | 2026-10-14 | 2026-10-14 | Both cache-saving workflows delete the sccache entry and then save it, because actions/cache/save cannot overwrite an existing key. When the save then fails, the entry is gone: the cache service does fail, with 400 responses and outages in the logs, and the two Linux clang entries have now disappeared. Save under a run-unique key with a restore-keys prefix instead, so a failed save can never destroy the cache, and drop the delete. |
| Remove the unused CodeQL workflow | DONE | 2026-10-14 | 2026-10-14 | CodeQL is not in use. The workflow triggers only on workflow_dispatch, its schedule is commented out, and nothing depends on it. Delete it and drop its row from the CI workflows page, which counts the workflows that keep their own triggers. |
| Free disk space on the macOS runner | DONE | 2026-10-14 | 2026-10-14 | The Linux workflow frees disk before its build, and the macOS workflow does not. The macOS debug job has already died with 'No space left on device' while linking, and the macOS runner image carries toolchains and simulator runtimes a C++ build never touches. Add the macOS equivalent, keeping the Xcode version the workflow selects. |
| Stop the workflow from losing steps to a transient storm | ABANDONED | 2026-10-14 | 2026-10-24 | A provisioning run lost its first step to a transient database connection storm. The command was dropped rather than retried, the pool storm left no explanation, and the handler has a path that discards a command in silence. Make delivery durable, retry intermittent faults, and make a failure name its cause. |
| Bring the service code onto the NATS patterns | DONE | 2026-10-24 | Audit every NATS call site against the NATS service pattern library, and fix each deviation from it. | |
| Fix the deprecated getenv in the build stamp | DONE | 2026-10-15 | 2026-10-15 | The build-stamp change reads ORES_VERSION_MANIFEST with std::getenv. The MSVC STL deprecates it in favour of _dupenv_s, so every Windows job fails under -Werror=deprecated-declarations and all four Nightly Windows configurations are red. The codebase provides an environment provider that wraps this for exactly that reason; use it, and keep the utility component free of raw std::getenv. |
| Cap the Nightly Build step below the six-hour job limit | DONE | 2026-10-15 | 2026-10-15 | The Nightly Build's linux-clang-debug job is the heaviest configuration in the repository, debug with coverage and memcheck, and on 2026-10-15 it hit exactly 6h0m0s and was killed. An uncapped step runs to the job limit, and the job is then torn down about thirty seconds later, which is not enough for the cache steps to finish. continuous-linux.yml has been capped at 320 minutes since the same thing happened there; nightly-linux.yml has no cap at all. |
| Restore the linux gcc release build | DONE | 2026-10-15 | 2026-10-15 | The tier rebalance made Continuous Linux clang-only and left the gcc configurations to the Nightly Build, but the nightly matrix carries debug alone. linux-gcc-release is therefore built nowhere: the repository no longer compiles its gcc release configuration in CI at all, and nothing reports it to CDash. Add release to the nightly matrix and keep coverage and memcheck on the debug jobs, where they belong. |
| Prune older cache entries after a successful save | DONE | 2026-10-15 | 2026-10-15 | Saves use a run-unique key so that a failed save can never destroy the cache, but the entries accumulate: two clang-debug runs already cost 5 GB of the 10 GB repository cap, the cache sits at 9.55 GB with 0.45 GB free, and the gcc cache has been evicted entirely, so the nightly gcc jobs run cold. Delete every older entry of the same variant once the new one is stored, which bounds each variant to one entry and frees roughly 5 GB. |
| Give the Nightly Build its own cache keys | DONE | 2026-10-15 | 2026-10-15 | The clang cache prefix is shared by continuous-linux.yml and nightly-linux.yml, but the two build the same variant with different flags: the nightly's debug jobs carry code coverage, so sccache keys those objects differently and the two caches hold objects the other cannot use. Restore takes the newest match, so whichever workflow ran last can hand the other a useless cache, and the prune step actively deletes the other's entry. Scope the compiler cache keys to the workflow, and lower the nightly ceiling so all six variants fit the 10 GB repository cap. |
| Run code coverage on the Continuous debug builds | DONE | 2026-10-15 | 2026-10-15 | Continuous Linux builds linux-clang-debug without code coverage, so the 3-hourly CI reports no coverage to CDash and the coverage trend has a sample once a day at best. The build is now fast enough to afford the instrumentation: after the compiler cache warmed, clang-debug fell from 5h03m30s to 4h08m39s and clang-release from 2h59m27s to 2h24m15s. Turn code_coverage on for the Continuous debug jobs, so that Continuous and Nightly measure the same thing on the same configuration. |
| Silence the GNUInstallDirs uninitialized warnings | DONE | 2026-10-15 | 2026-10-15 | CMake 4.4 prints ten (uninitialized) warnings on the Linux configure step, one for each CMAKE_INSTALL_<dir> variable. They come from CMake's own Modules/GNUInstallDirs.cmake, which dereferences each cache entry at line 306 before it creates it, and the repository's warnings.uninitialized and warnings.systemVars preset settings make CMake report that dereference. The module is not ours to patch, and the same file already silences this diagnostic around Modules/InstallRequiredSystemLibraries.cmake and Modules/CPack.cmake for the same reason. |
| Re-tangle the shell scripts the report trigger work left behind | DONE | 2026-10-15 | 2026-10-15 | Commit 96c4be8625 modelled the report trigger and regenerated the report_instances recipe, which added a trigger_id column and a new report_trigger_types recipe, but it never ran the shell tangle. Three committed scripts still render the old uuid placeholder for trigger_id as 0 instead of the empty uuid, and the whole report_trigger_types script library is absent from the repository. The tangle-shell check is therefore red on main, and it rewrites the three scripts as a side effect, which in turn makes component-drift fail because those rewritten files look like changed components. |
| Cut the continuous build time | DONE | 2026-10-14 | 2026-10-15 | The continuous clang jobs stopped fitting the six-hour limit: the 2026-10-14 linux-clang-release job reached only 5422 of 7187 build steps in 5h39m. The trials ruled the build itself out. The largest gap between build-step completions is 36.9 s and the median is 1.96 s, so there is no hotspot to split; linking is 53 of the 7187 steps; and a whole-tree unity build stops in 19 s on a name that four files repeat. The constraint was the compiler cache, which ran at an 85.72 per cent hit rate on 2026-10-03 when the whole build took about 49 minutes, and at 3 to 10 per cent after it went cold. Keeping the cache on a cancelled job, pruning it, and scoping its keys to each workflow fixed it: the continuous clang jobs now run in 4h08m39s and 2h24m15s. |
| Silence the configure warnings on the site and macOS builds | DONE | 2026-10-15 | 2026-10-15 | The doc-only site configure prints six unused-cli warnings, because the linux-doc-only preset inherits vcpkg and compiler variables that a configure with ORES_VCPKG_ENABLED=OFF never reads: without the toolchain there is no dependency discovery, and without the C++ build configuration there are no compile rules. The macOS configure prints six uninitialized warnings from build/cpack, because Info.plist.in reads PROJECT_MAJOR_VERSION, PROJECT_MINOR_VERSION and PROJECT_PATCH_VERSION, which nothing sets; the project() call sets PROJECT_VERSION_MAJOR and its siblings, so the bundle plist has rendered an empty version. Two further warnings come from vcpkg's own ports and are out of scope. |
| Overlay the libarchive port to silence its unused variable | DONE | 2026-10-16 | 2026-10-16 | The macOS vcpkg install prints a warning from libarchive's portfile: it passes -DCMAKE_REQUIRE_FIND_PACKAGE_MbedTLS=ON for the OSX crypto backend, but libarchive's CMakeLists.txt never reads that variable in this configuration, so vcpkg_cmake_configure reports a manually specified variable that went unused and asks for it to be listed in MAYBE_UNUSED_VARIABLES. Upstream still omits it, so the pinned submodule cannot be bumped to fix it. Add an overlay port that lists the variable, and record why the other vcpkg warning, boost-system's build-path length warning on Windows, does not get one. |
| Replace the deprecated sscanf calls | DONE | 2026-10-16 | 2026-10-16 | The Windows clang release job fails to compile projects/ores.reporting/core/src/service/run_document_generator.cpp, because MSVC's STL marks std::sscanf deprecated and the build passes -Werror. The function parses an ISO 8601 run date by hand, and the platform layer already provides time_utils::parse_date, which does the same job with std::from_chars and validates the result. A second site in the platform test suite parses the executable build timestamp the same way and would fail on the same flag. Replace both so the tree carries no deprecated C runtime call. |
| Save the compiler cache instead of silently dropping it | DONE | 2026-10-16 | 2026-10-16 | actions/cache tars the cache directory, and a tar that reads a file while sccache is still writing it exits non-zero. actions/cache reports that failure as a warning and still exits zero, so the Save step reports success while storing nothing. The debug job has therefore never stored a cache: the only linux-clang-debug entry is the legacy one built before coverage changed every compile line, so every run restores it, misses 79 per cent of its compiles, hits the 320-minute cap and saves nothing again. The prune step makes it worse, because it is gated on the cache being worth saving rather than on the save having landed, so it would delete the entry the failed save was meant to replace. Stop the sccache server before archiving so the directory is still, and prune only once the run's key is really in the cache. |
| Share one compiler cache between the Linux tiers | DONE | 2026-10-16 | 2026-10-16 | The continuous and nightly Linux jobs compile the same variants with the same settings: both pass code_coverage=1 on the two debug variants and neither passes anything extra on release, and the differences between the two workflows cannot change a compile line. The memory check adds valgrind to the test step, the build group only names the CDash track, and the package flag only picks between the all and package build targets. The cache keys were scoped per workflow when the flags did differ, and that now stores the same objects twice: the same four Linux variants cost up to eight entries, and the 10 GB cap pays for the duplicates instead of for the gcc variants. Remove the workflow scope so both tiers restore and replace one entry per variant. |
| Carry six-digit microseconds in every timestamp the platform writes | DONE | 2026-10-17 | The platform formatter drops the whole fractional second and the parser silently discards a fraction, so a market observation loses up to a second of its timestamp. | |
| Test the tenor rule before saving it | DONE | 2026-10-17 | 2026-10-17 | The tenor journey authors a rule and never shows its answer, so a wrong anchor or roll rule is discovered only after it is written. Add a test step that resolves the rule as it stands in the form and shows the date, its refusal, and how it got there. |
| Replace the credit fact variant with typed arrays | DONE | 2026-10-17 | 2026-10-24 | The credit carrier holds a std::variant field, credit_fact_variant, for the product fact row. The data-oriented design checklist forbids a polymorphic payload field and asks for one typed array per concrete type, joined by key. Replace it with per-type arrays and migrate its consumers. The rates, equity and fx variants are out of scope: other environments own them. |
| Follow the child run a workflow hands off | ABANDONED | 2026-10-24 | bootstrap setup and provision tenant report 'All 2 step(s) completed' and 'the tenant is ready to work in' as soon as the provision_tenant_workflow finishes, while the tenant is still being populated by the 9-step tenant_setup_workflow that start_tenant_setup creates. The child run's id is already in the final step's response as child_instance_id, so the shell can follow it; it simply never reads it. The follow loop has no notion of a child run. | |
| Name the convention sets a report chooses | ABANDONED | 2026-10-24 | Conventions become a small set of clearly named, clearly purposed sets that a report binds by choosing one. Authoring a set is its own UX, deferred, and the gaps that block the choice today are recorded as acceptance criteria. | |
| Prune the branches that are merged into origin/main | DONE | 2026-10-17 | compass branches prune selects branches merged into origin/main, then deletes them with git branch -d, which asks whether they are merged into HEAD. A branch merged into main but not into whatever is checked out is reported safe to prune and then survives the prune with a message that blames unmerged commits. | |
| Manage reports from the list a party runs | DONE | 2026-10-17 | 2026-10-24 | Report management gets its own UX, and its front door is the list of reports a party runs: what exists, when it last ran, whether it is healthy and when it runs next. Conventions and analytics authoring are reached by a link out, not carried here. |
| Run a report end to end on a synthetic bond population | DONE | 2026-10-21 | 2026-10-24 | Trigger the NPV report of an ACME party over its synthetic bonds, follow the run to a completed instance, and record every issue met on the way with its cause and its fix. |
| Give the web one way to handle time and timestamps | DONE | 2026-10-18 | ores.web has no single owner for time. The wire-protocol package validates only four timestamp fields with wireTimestampSchema; at least twelve timestamp-shaped fields are plain z.string(), including eventTime, three recordedAt, startTime, endTime, givenAt, assigned_at, occurred_at and two more recorded_at. Nothing checks those, so server drift reaches the browser silently. Worse, the server sometimes does not send the project's wire shape at all: auth_event.event_time is std::string in the operations protocol even though the domain holds a time_point, so it bypasses to_iso8601_utc and carries the database's textual rendering, '2026-10-17 15:27:23.511414+01' in a +01 session and '+00' in a UTC one. The same instant therefore serialises two ways depending on the reader's timezone. The accounts outage (GET /api/accounts 500, 'Not a wire timestamp' at every recorded_at) was this same class of drift caught loudly because that one field was validated; the unvalidated ones would have failed silently. | |
| Hotfix: gcc rejects member names that match their type in the generated xml headers | DONE | 2026-10-19 | 2026-10-19 | The gcc nightly builds fail with -Wchanges-meaning on credit_simulation.hpp because a member shares its name with its type; the debug builds also never finish. |
| Hotfix: the compiler cache is too small for the builds it serves | DONE | 2026-10-19 | 2026-10-19 | The action's max-size overrides the job cap, nightly and continuous cap the shared entries differently, and the four variants do not fit the 10 GB allowance. Give each variant a budget and stop the gcc debug build. |
| Hotfix: the Windows debug builds never pass | DONE | 2026-10-19 | 2026-10-19 | All four nightly Windows legs fail on compile errors and the debug legs add the longest runs. Switch off the Windows debug builds until the release builds pass. |
| Author the report configurations on guided screens | ABANDONED | 2026-10-19 | 2026-10-24 | A person creates and edits a report configuration on screens that guide each step. A configuration holds many related entities, so each entity gets a screen that helps the person choose, check and connect its parts. The configuration screens link later to the report definition screens. |
| Tenant auto-start feeds are not restored after a services restart | DONE | 2026-10-19 | 2026-10-19 | The boot walk read only the system tenant's feeds. It now visits every active tenant, so ACME's feeds run after a restart. |
| A feed runs as the tenant that owns it | DONE | 2026-10-19 | 2026-10-19 | A feed's vintage read runs under the run grant of its collection, so a restart starts every tenant's feeds. The caller of Start is checked once, at the command. |
| Feeds start and restart the same way every time | DONE | 2026-10-19 | 2026-10-20 | A restart starts every feed that should run, whatever order the services come up in. A provision starts the system feeds. A person's Start subscribes the person's party. A collection's grant ends with the collection. |
| Hotfix: fix the main CI failures | DONE | 2026-10-20 | Four CI failures on main: range-loop-construct error in xml_document_tests.cpp (gcc), incomplete component_trade type in deque on windows-msvc, workflow_engine_tests SIGABRT (std::system_error Invalid argument), and the site build broken link to ID 465ca244 in the time-series plot capture. | |
| Find why market data ticks lag the wall clock | DONE | 2026-10-20 | 2026-10-24 | A tick on the chart was stamped 71 minutes behind the wall clock and drained its backlog at only 1.16 times real time. Find where the backlog sits and fix it. |
| Fix the marketdata suite timeout | DONE | 2026-10-20 | The marketdata core suite outgrew the 600 s ctest default and lost its serial setting in a regeneration. | |
| Fix the site build id link | DONE | 2026-10-21 | The site build fails on an uppercase id link to a page that defines its id in lowercase. | |
| Prototype the management of conventions | DONE | 2026-10-21 | Design how a person manages conventions, as user journeys first and clickable prototypes second. | |
| Scope a report by regulatory book type | ABANDONED | 2026-10-21 | 2026-10-24 | A report states the regulatory book type of the books it may read, from the same vocabulary a book uses, so a trading book report never prices the banking book. |
| Preview a convention's term structure on a calendar | DONE | 2026-10-21 | 2026-10-24 | A person picks a tenor convention and a calendar in ores.web and sees every tenor of the convention resolved to its date at once. |
| Fix the macOS real parse | DONE | 2026-10-21 | libc++ deletes the floating-point from_chars, so the ORE XML binding and record readers fail to compile on macOS. | |
| See and change everything a report runs | DONE | 2026-10-21 | 2026-10-24 | A report page shows its definition, its configurations and its conventions on tabs, and a person can choose the conventions a report reads. |
| Hotfix: fix the Linux sccache save | DONE | 2026-10-21 | The debug saves fail on a tar race and the old cache is deleted before the save, so the next build starts cold. | |
| Browse and follow the grid's jobs | DONE | 2026-10-22 | 2026-10-24 | The grid screen counts batches, workunits and results and shows no row of any of them. The journeys Browse the grid's jobs and Follow a job are written and prototyped. This story builds the screens: the paged tree of batches, workunits and results, the details of each, the job page, and the file download, for the operator, the tenant administrator and the party member. |
| Build the conventions list screens | DONE | 2026-10-21 | 2026-10-24 | A person who reads conventions gets the plain entity screens the prototype draws: a list of kinds, grouped by asset class with the shared kinds in their own tab, and a list of one kind's documents. The guided run that authors a convention moves into the Workflows menu. |
4. Achievements
Milestones worth capturing as they happen, so the release notes at
sprint close have the evidence to hand. Add a dated ** subheading
per milestone, with any screenshot via [[proj:assets/images/<file>.png]].
5. Captures
Real captures filed during this sprint that have not been pulled into a
story as tasks — listed here purely for visibility into what the sprint
surfaced. Each is an inbox capture (compass capture); triage them at the
health review (promote to a story, move to next, or discard).
| Capture | Tags | Description |
|---|---|---|
6. Health Review
| # | Date | Day | Overall | Task |
|---|---|---|---|---|
| 1 | 2026-10-24 | day 12 | RED | Health review 1 — sprint 28 close analysis |
(Run compass-agile-review-sprint to add more rows.)
7. Charts
Charts generated via compass sprint charts. See Sprint health charts for what each chart measures, its purpose, and how to read it.
7.1. PRs & Commits per Day
Dual-axis bar chart. PRs (left axis) and commits (right axis) per day. A high commits-to-PR ratio may indicate scope creep.
7.2. Daily Line Churn
Lines added (green) and deleted (red) per day. Building work produces mostly additions; refactoring produces a mix. Days with no churn may indicate blockers.
7.3. PR Cycle Time
Hours from PR open to merge, one dot per PR for every PR merged in the sprint, on a log scale, with the median and the upper quartile as lines. High dots indicate review bottlenecks. Generated only when PR data is available.
7.4. Cumulative Stories Done
Line chart tracking stories marked DONE during the sprint. Steady upward slope is healthy; plateauing signals a stall.
8. Retrospective
(Filled at sprint close.)
9. Release Notes
See ORE Studio Sprint 28 – Release Notes for the full narrative.