Story: Hotfix: Restore every red build on main
Table of Contents
This page documents a story in Sprint 26. It captures the goal, current status, acceptance criteria, and the tasks that compose it.
1. Goal
Every continuous build on main is red. Each red job stops on a different defect, and each defect is independent of the others:
| Job | Where it stops | Root cause |
|---|---|---|
| Continuous Linux (4 of 4 jobs) | validate_schemas.sh |
Four regenerated ores.workspace SQL files define the same table, indexes and insert function as the hand-written, wired schema, and no aggregator includes them, so the strict wire check refuses the tree. |
| Continuous macOS (2 of 2 jobs) | compile of ores.iam |
Both iam handlers declare std::atomic<std::shared_ptr<const token_settings>>. libc++ has no such specialisation, so the name resolves to the generic std::atomic<T> primary template, which static_asserts that T is trivially copyable. |
| Continuous Windows (4 of 4 jobs) | compass db recreate, Phase 2 |
populate/iam/iam_service_account_roles_populate.sql uses :'storage_service_user', which the psql invocation did not define. |
| Nightly Linux (2 of 2 jobs) | compass db recreate, Phase 2 |
The same undefined storage_service_user. |
| Product website and CDash site | org-publish of one page |
The dq artefact task carried [[file:...org_loader.py::943]]. Org cannot resolve a line-number search inside a Python file. |
The storage defect and the site defect are already fixed on main: the
storage service was added to service_registry.org, to the generated
service_vars.sh and to the env configure output, and the dq page now
links through the proj: link type, which renders a GitHub URL and
searches nothing. The Linux and macOS defects are still red, and this
hotfix carries those two.
The macOS defect is the one with a design decision behind it. The estate
already met it once, in crm_ingest_bridge, and chose a mutex-guarded
shared_ptr there, recording the reasoning in
Revisit std::atomic<std::shared_ptr<T>> once macOS libc++ supports it.
The iam handlers were written with the atomic form afterwards and never
met a macOS compiler, because the macOS build had been red on other
grounds for long enough that nobody saw the failure. The fix puts the
portable form in ores.platform, so the decision is made once and the
callers carry no preprocessor branch.
The workspace defect is wiring debt that one commit created. It is not a defect in the workspace feature itself.
2. Status
| Field | Value |
|---|---|
| State | DONE |
| Parent sprint | Sprint 26 |
| Now | Nothing. |
| Waiting on | Nothing. |
| Next | Nothing. |
| Last touched | 2026-09-27 |
3. Acceptance
validate_schemas.shpasses with no warnings, and no generated file underprojects/ores.sqlduplicates a wired, hand-written schema file.- Both iam handlers compile against a standard library with no
std::atomic<std::shared_ptr<T>>specialisation, and no header in the estate names that specialisation. - The portable snapshot is tested, and the test fails on a torn read.
compass db recreatecompletes on this tree.- The site build publishes every page, the dq artefact page included.
- Every codegen gate, the codegen test suite and the full build pass.
ores.refdata.core.testsis the one ctest target still red on this tree. It fails because the checked-in refdata C++ and its eventing tests are stale while the SQL is current, so the event's key record does not decode. The capture Five test binaries fail on main, and four of them share one … owns it, four of its five targets are green now, and its fix is a refdata migration rather than a hotfix line.- The only build left red is the Windows one, on the
ores.shell.tradingtranslation unit. That is a separate, known defect and this story does not own it.
4. Tasks
| Task | State | Start | End | Description |
|---|---|---|---|---|
| Implement Hotfix: Restore every red build on main | DONE | 2026-09-27 | 2026-09-27 | Turn off the workspace entity's SQL facet and delete the four generated files that duplicate the hand-written schema, add the portable atomic snapshot to ores.platform and move both iam handlers onto it, confirm the storage service variable reaches psql, and confirm the site link resolves. Verify every gate, then raise the PR. |
5. Decisions
- The workspace entity's SQL facet is switched off in its model rather
than silenced in
validation_ignore.txt. The generated schema cannot be wired while the model is stale, because it dropsparty_idandname, which the hand-written schema and the hand-written repository both use. A disabled facet is reversible in one line and the generator enforces it; an ignore entry leaves two competing definitions of the same table in the tree for the next reader to wire by mistake. - The portable snapshot joins
ores.platform, notores.utility. The choice it encodes is a standard-library gap, which is what that component exists for, and both iam handlers already link it. - The portable snapshot is mutex-backed on every platform, not atomic-backed on the platforms that support it. One code path ships everywhere and the tests exercise it everywhere; a conditional would leave the macOS path compiled only on macOS.
6. Out of scope
- The
ores.shell.tradingtranslation unit that MSVC and clang-cl cannot compile. Continuous Windows stays red on it, by agreement. - The refdata migration: regenerate the component onto its current
models, reconcile the hand-written tenant-isolation filter in the
generated
party_cache.hpp, and migrate the twoores.orecall sites the regenerated removal type breaks. That is what makesores.refdata.core.testsgreen, and it also wants refdata added to the codegen drift gate so the next 499 files cannot accumulate unnoticed. - The workspace model migration itself, which moves
nameinto* Columnsas a flagged natural key, statesparty_idthe way the other models state it, and reconciles the generated schema with the hand-written one. Fix workspace entity model drift owns it; re-enabling the facet is part of that work. - Moving
crm_ingest_bridgeonto the platform snapshot. It keeps its own mutex for now; the capture that records the switch-back now names the shim as the place the switch-back happens.