From a2183b8b6f601f12aaae8c56867972c33aa1779e Mon Sep 17 00:00:00 2001 From: Pedro Sakuma Travi <39205549+pedrosakuma@users.noreply.github.com> Date: Mon, 27 Jul 2026 21:41:56 +0000 Subject: [PATCH 1/2] ci: per-file companion repo mapping for schema cross-check SbeB3UmdfConsumer is a dead/renamed name for B3MarketDataPlatform (GitHub silently redirects it), which happened to still work here since this repo is genuinely independent of B3MarketDataPlatform, but relying on a rename-redirect for a security-relevant check is fragile (the name could later be reclaimed by an unrelated repo). This repo vendors two schema files with two different companions, so map by filename instead of hardcoding one target: b3-market-data-messages-*.xml -> B3MarketDataPlatform b3-entrypoint-messages-*.xml -> B3EntryPointClient An unrecognized filename only warns, same fail-open-on-unknown behavior as a fetch failure. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/ci.yml | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d342ef9..148b240 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,17 +42,20 @@ jobs: echo "$changed" fi - # Best-effort cross-check against the companion SbeB3UmdfConsumer - # repo, which vendors the same UMDF market-data schema and is kept - # in lock-step per README.md/CONTRIBUTING.md. Network/availability - # issues here only warn (they must not make an unrelated outage - # block every PR); an entrypoint-only file that isn't vendored - # there also just warns. An actual content mismatch on a shared - # file is treated the same as a local edit. + # Best-effort cross-check against the companion repo that vendors + # the same schema file, kept in lock-step per README.md/ + # CONTRIBUTING.md: b3-market-data-messages-*.xml against + # B3MarketDataPlatform, b3-entrypoint-messages-*.xml against + # B3EntryPointClient. Network/availability issues here only warn + # (they must not make an unrelated outage block every PR); a + # file with no known companion also just warns. An actual + # content mismatch on a shared file is treated the same as a + # local edit. # Scoped to files this PR actually touched under schemas/ — PRs # that don't touch schemas/ must not be blocked by pre-existing # drift between the two repos that predates this PR. Iterated - # line-by-line (not word-split) so filenames with spaces survive. + # line-by-line (not word-split) so filenames with spaces + # survive. # # NOTE: because this only runs for files already in $changed, it # can never independently flip flagged from 0 to 1 — flagged is @@ -72,12 +75,21 @@ jobs: continue fi name="$(basename "$f")" - url="https://raw.githubusercontent.com/pedrosakuma/SbeB3UmdfConsumer/main/schemas/$name" + case "$name" in + b3-market-data-messages-*.xml) companion_repo="B3MarketDataPlatform" ;; + b3-entrypoint-messages-*.xml) companion_repo="B3EntryPointClient" ;; + *) companion_repo="" ;; + esac + if [ -z "$companion_repo" ]; then + echo "::warning::No known companion repo for $name; skipping cross-repo check." + continue + fi + url="https://raw.githubusercontent.com/pedrosakuma/$companion_repo/main/schemas/$name" if remote_sha="$(curl -fsSL --connect-timeout 5 --max-time 15 "$url" 2>/dev/null | sha256sum | awk '{print $1}')"; then local_sha="$(sha256sum "$f" | awk '{print $1}')" if [ "$remote_sha" != "$local_sha" ]; then flagged=1 - echo "$f (sha256 $local_sha) diverges from SbeB3UmdfConsumer's vendored copy (sha256 $remote_sha)." + echo "$f (sha256 $local_sha) diverges from $companion_repo's vendored copy (sha256 $remote_sha)." fi else echo "::warning::Could not fetch $url to cross-check vendored schema fidelity; skipping cross-repo check for $name." From 5235bb05d076098a7295bc1db993019b556f0c0d Mon Sep 17 00:00:00 2001 From: Pedro Sakuma Travi <39205549+pedrosakuma@users.noreply.github.com> Date: Mon, 27 Jul 2026 21:47:46 +0000 Subject: [PATCH 2/2] docs: retire stale SbeB3UmdfConsumer references SbeB3UmdfConsumer is a dead/renamed name (now B3MarketDataPlatform); replace all remaining doc/code/config references with the correct current repo names (B3MarketDataPlatform for the UMDF/market-data consumer, B3EntryPointClient for the entrypoint client), consistent with the ci.yml companion-repo fix in this branch. Also fixes an unrelated stale build command in docs/EXCHANGE-SIMULATOR.md that referenced a solution file (SbeB3UmdfConsumer.slnx) that has never existed in this repo; the real file is SbeB3Exchange.slnx. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/copilot-instructions.md | 8 +++++--- .vscode/mcp.json | 2 +- CONTRIBUTING.md | 5 +++-- README.md | 3 ++- docs/B3-ENTRYPOINT-ARCHITECTURE.md | 6 +++--- docs/EXCHANGE-SIMULATOR.md | 2 +- docs/RUNBOOK.md | 2 +- docs/adr/0013-options-channel-topology.md | 6 +++--- docs/rfc/0002-equity-options-support.md | 2 +- src/B3.Exchange.Core/ChaosUdpPacketSinkDecorator.cs | 2 +- 10 files changed, 21 insertions(+), 17 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 2091e40..3ef8824 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -2,7 +2,8 @@ Stateful B3 exchange simulator. Inbound: B3 EntryPoint SBE over TCP. Outbound: B3 UMDF wire format over UDP multicast, plus SBE ExecutionReports back to the -TCP client. Companion to the external `SbeB3UmdfConsumer` repo. +TCP client. Companion to the external `B3MarketDataPlatform` (UMDF +consumer) and `B3EntryPointClient` (EntryPoint client) repos. ## Toolchain @@ -70,7 +71,8 @@ Layered projects under `src/` (build order roughly bottom-up): 1. `B3.EntryPoint.Sbe` / `B3.Umdf.Sbe` — generated SBE bindings from `schemas/b3-entrypoint-messages-8.4.2.xml` and `schemas/b3-market-data-messages-2.2.0.xml`. Vendored copies; keep in sync - with `SbeB3UmdfConsumer` when upgrading. + with `B3EntryPointClient` and `B3MarketDataPlatform` respectively when + upgrading. 2. `B3.Umdf.WireEncoder` — stateless byte-level encoders for UMDF MBO / Trade / Snapshot frames (V16 schema). 3. `B3.Exchange.Instruments` — JSON instrument loader. @@ -115,7 +117,7 @@ Layered projects under `src/` (build order roughly bottom-up): per-session firm assignment is not implemented. - **Schemas are vendored.** Do not hand-edit files under `schemas/`; regenerate the SBE bindings in `B3.*.Sbe` when upgrading and mirror the change in - `SbeB3UmdfConsumer`. + `B3MarketDataPlatform` (UMDF) / `B3EntryPointClient` (EntryPoint). ## Configuration diff --git a/.vscode/mcp.json b/.vscode/mcp.json index 11e2a92..e980ff9 100644 --- a/.vscode/mcp.json +++ b/.vscode/mcp.json @@ -2,7 +2,7 @@ "servers": { "github": { "type": "copilot", - "description": "GitHub MCP — repos, issues, PRs, Actions, code search (companion repo SbeB3UmdfConsumer)" + "description": "GitHub MCP — repos, issues, PRs, Actions, code search (companion repos B3MarketDataPlatform, B3EntryPointClient)" }, "filesystem": { "command": "npx", diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c20d4ce..7622e00 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -107,5 +107,6 @@ Both must pass before merge. Do not hand-edit files under `schemas/`. When upgrading B3 EntryPoint or UMDF, regenerate the SBE bindings in `B3.*.Sbe` and mirror the -change in the companion `SbeB3UmdfConsumer` repo. The two repos must -agree on the schema version. +change in the companion repo (`B3MarketDataPlatform` for UMDF, +`B3EntryPointClient` for EntryPoint). The repos must agree on the +schema version. diff --git a/README.md b/README.md index 703c9fe..364f24f 100644 --- a/README.md +++ b/README.md @@ -144,7 +144,8 @@ EntryPoint TCP listener (default port 9876). `schemas/b3-market-data-messages-2.2.0.xml` and `schemas/b3-entrypoint-messages-8.4.2.xml` are vendored copies of the -official B3 SBE schemas. The same files exist in `SbeB3UmdfConsumer`; keep +official B3 SBE schemas. The same files exist in `B3MarketDataPlatform` +(market-data schema) and `B3EntryPointClient` (entrypoint schema); keep them in sync when upgrading. ### Inbound EntryPoint compatibility matrix diff --git a/docs/B3-ENTRYPOINT-ARCHITECTURE.md b/docs/B3-ENTRYPOINT-ARCHITECTURE.md index ff54b9f..5ddf8b0 100644 --- a/docs/B3-ENTRYPOINT-ARCHITECTURE.md +++ b/docs/B3-ENTRYPOINT-ARCHITECTURE.md @@ -714,7 +714,7 @@ Three test surfaces, mirroring the component split. client speaking SBE + SOFH against it. - Scenarios: full session lifecycle, gap recovery, CoD trigger, daily reset mid-session, throttle reject. -- Use `SbeB3UmdfConsumer` style decoder to verify multicast output. +- Use a `B3MarketDataPlatform` style decoder to verify multicast output. --- @@ -806,7 +806,7 @@ is on so they are inspectable). **EntryPoint and UMDF version independently.** Each schema is bumped on its own cadence; you do not need to upgrade both at once. The companion -[`SbeB3UmdfConsumer`](https://github.com/pedrosakuma/SbeB3UmdfConsumer) +[`B3MarketDataPlatform`](https://github.com/pedrosakuma/B3MarketDataPlatform) repo vendors the same UMDF schema and must be kept in lock-step when the UMDF version moves. @@ -843,7 +843,7 @@ UMDF version moves. the version we target and per-template gap status; bump the version and audit any newly added or removed templates. 8. **Mirror UMDF changes** in - [`SbeB3UmdfConsumer`](https://github.com/pedrosakuma/SbeB3UmdfConsumer) + [`B3MarketDataPlatform`](https://github.com/pedrosakuma/B3MarketDataPlatform) when bumping the market-data schema; the consumer is what proves the wire is end-to-end correct. diff --git a/docs/EXCHANGE-SIMULATOR.md b/docs/EXCHANGE-SIMULATOR.md index 8e4de2d..0c1f2f5 100644 --- a/docs/EXCHANGE-SIMULATOR.md +++ b/docs/EXCHANGE-SIMULATOR.md @@ -40,7 +40,7 @@ TCP client ──► EntryPointSession ──► HostRouter ──► ChannelDis ```bash # 1. Build -dotnet build SbeB3UmdfConsumer.slnx +dotnet build SbeB3Exchange.slnx # 2. Run with the sample config dotnet run --project src/B3.Exchange.Host -- config/exchange-simulator.json diff --git a/docs/RUNBOOK.md b/docs/RUNBOOK.md index 2db1abb..048514d 100644 --- a/docs/RUNBOOK.md +++ b/docs/RUNBOOK.md @@ -568,7 +568,7 @@ umdf_chaos_duplicated_total{channel="1"} umdf_chaos_reordered_total{channel="1"} ``` -Recovery scenario (companion `SbeB3UmdfConsumer`): +Recovery scenario (companion `B3MarketDataPlatform`): 1. Start the host with `dropProbability: 0.01` on a channel of interest. 2. Drive load with a synthetic trader. diff --git a/docs/adr/0013-options-channel-topology.md b/docs/adr/0013-options-channel-topology.md index f229550..17bce6f 100644 --- a/docs/adr/0013-options-channel-topology.md +++ b/docs/adr/0013-options-channel-topology.md @@ -18,9 +18,9 @@ Real B3 publishes equity options on a UMDF channel distinct from cash equities and from derivatives. The simulator must reflect that -topology so consumers (e.g. `B3MarketDataPlatform`, the -`SbeB3UmdfConsumer` companion repo) can validate per-group ring -and cross-group fan-in against a shape that matches production. +topology so consumers (e.g. the `B3MarketDataPlatform` companion repo) +can validate per-group ring and cross-group fan-in against a shape +that matches production. Two designs were considered while drafting RFC 0002: diff --git a/docs/rfc/0002-equity-options-support.md b/docs/rfc/0002-equity-options-support.md index 2e4958b..a0c5640 100644 --- a/docs/rfc/0002-equity-options-support.md +++ b/docs/rfc/0002-equity-options-support.md @@ -428,7 +428,7 @@ as ADRs are written. ## 8. Risks and consequences -- **Schema coupling with `SbeB3UmdfConsumer`.** No schema is +- **Schema coupling with `B3MarketDataPlatform`.** No schema is modified — only encoder output. Consumers compatible with UMDF v2.2.0 receive the new fields transparently. **Action:** no-op, but confirm in the encoder PR that the companion repo's parser diff --git a/src/B3.Exchange.Core/ChaosUdpPacketSinkDecorator.cs b/src/B3.Exchange.Core/ChaosUdpPacketSinkDecorator.cs index bb642a7..bd9df9b 100644 --- a/src/B3.Exchange.Core/ChaosUdpPacketSinkDecorator.cs +++ b/src/B3.Exchange.Core/ChaosUdpPacketSinkDecorator.cs @@ -5,7 +5,7 @@ namespace B3.Exchange.Core; /// /// decorator that injects controlled packet loss, /// duplication, and reordering into an inner sink. Designed for testing the -/// companion SbeB3UmdfConsumer's recovery paths (snapshot bootstrap, +/// companion B3MarketDataPlatform's recovery paths (snapshot bootstrap, /// gap detection) without external network-shaping tools. /// /// NOT thread-safe; like the inner sinks it expects to be called from a