Skip to content

feat(adapter): add the Adapter live translation facade - #2529

Merged
jeremi merged 2 commits into
mainfrom
jeremi/live-adapter
Oct 31, 2026
Merged

jeremi merged 2 commits into
mainfrom
jeremi/live-adapter

Conversation

@jeremi

@jeremi jeremi commented Oct 31, 2026 •

Copy link
Copy Markdown
Member

Pull Request

Summary

Adds the Adapter product: a live translation facade that serves a standard registry API over systems that already hold the data (DHIS2, FHIR servers, OpenCRVS, bespoke REST services) without changing their native APIs. It holds no records and decides nothing; it translates each request and response live.

The engine is a bounded Rust port of Apache Camel's core (Exchange and Message, routes in Camel's YAML DSL shape, enterprise integration patterns under their Camel names, the contract-first REST facade, error handling and redelivery), restricted for a minimum-disclosure stack. Source interpretation lives in reviewed pack scripts and artifacts, not in source-specific Rust.

What it serves at this checkpoint:

  • The breg-records read surface (search, get, read-only POST reads) with OIDC, client admission, operation and record-type scopes, closed request and response schemas, bounded source access, profile-owned problems, opaque continuations, and a value-free PostgreSQL journal.
  • Synchronous POST create and PUT update, with exact response replay, body-mismatch refusal without a second send, and no repeat of an uncertain effect.
  • Credential-free public HTTPS only behind an explicit operator acknowledgement; TLS verification and facade authentication still apply.

New crates: registry-adapter, registry-adapter-core, registry-adapterctl. Packs and examples for DHIS2 tracker, DHIS2 on GovStack, and OpenCRVS (offline fixtures only), five source-shape fixtures (FHIR R4 read and conditional create, GraphQL cursor paging, REST offset paging over mTLS, a second target profile), and a refusal corpus. products/adapter/README.md is the entry point; CONCEPT.md holds the contract and its decisions.

Shared changes outside the Adapter:

  • registry-platform-httputil: destination policy and OAuth client support used by the Adapter.
  • registry-platform-resilience (circuit breaker, redelivery) and a rolling window in registry-platform-ratelimit.
  • registry-platform-script: Rhai additions for pack scripts.
  • Platform config formats, conventions exceptions and conformance cases for the Adapter formats; CLI docs catalog; CI change detection for the Adapter lane.
  • Docs site: the Adapter's formats and CLI reference are gated behind a registry-adapter docset product that no docset publishes yet, and both binaries are listed as unreviewed and source-build-only. Nothing about the Adapter appears on the docs site until it has reviewed pages.

This is a first checkpoint, not the full Adapter programme. What remains: the Idempotent Consumer and GraphQL port rows, asynchronous write modes (202 status link, bounded wait), multi-step write resume, a real OpenCRVS proof, and personal delegation and MCP writes, which stay behind their own contracts.

Evidence

Run locally after rebasing onto current main:

Gate Result
cargo fmt --check, workspace cargo check and cargo clippy (all targets, warnings denied) pass
products/adapter/scripts/check-contracts.sh 960 passed
products/adapter/scripts/test-postgres.sh 645 passed
Platform crates 1,460 passed, 3 ignored
Test authorization server 27 passed
registry-mcp (Adapter goldens repinned to the in-tree producer) 64 passed, 7 ignored; MCP schema tests 8 passed
registry-adapter-core, registry-adapterctl (including tls-test verify) pass after the identifier fixes
Adapter corpus (check-corpus.py) 127 members refuse with their own code; base control clean
CLI docs catalog pass
cargo deny check clean
13 Python suites, --check-generated, conventions lint, gates inventory pass
Identifier catalog (check.sh, --check-references) pass; catalog regenerated with the six Adapter schemas
CI change detection tests 186 passed
Strict configuration conformance 5,657 cells: 4,227 pass, 2 expected failures, 0 fail
gitleaks over the branch no findings

Not run locally: the full cargo test --workspace, the ignored native_adapter tests, the docs site build, client bindings, tutorials, other products' lanes, and the merge-queue assurance lanes. CI covers those.

Live journeys run against one immutable build of this branch before the rebase:

  • DHIS2 read: 264 of 264 checks.
  • DHIS2 synchronous create and attribute update: 25 of 25 checks, including exact replay, body mismatch without a resend, readback and cleanup.
  • HAPI FHIR: 18 checks for one synthetic Patient (conditional create, read, search, replay, mismatch, delete, readback).
  • MCP gateway read pairing: 6 native Adapter and PostgreSQL cases.

These prove the named paths only, and they were not rerun after rebasing onto current main.

Notes

  • Security: the Adapter authenticates and authorizes before any body or source access; source credentials, caller tokens and forbidden headers never reach the source; a failed credential never falls back to anonymous access.
  • Compatibility: additive. No existing product's behavior changes; shared platform crates gain functions, and the platform conformance runner gains Adapter formats.
  • Strict conformance: two unique-list-sweep cells (evidence/bundle, coordinator/runtime) are recorded in expected-failures.yaml. This branch adds the case, and those two readers report a duplicate set item as a domain diagnostic instead of config.duplicate-item. No Adapter cell fails. Evidence and Coordinator readers report duplicate set items as config.duplicate-item #2530 covers the two readers.
  • Identifier catalog: the six Adapter schemas are active catalog entries. The Adapter problem base problems/registry-adapter/ is reserved by one planned-resolution exclusion until the inventory has titles, descriptions and a settled URI form; Publish the Adapter problem inventory in the identifier catalog #2531 covers it.
  • MCP: the Adapter MCP goldens that feat(mcp): add configurable native and adapter providers #2516 pinned to an off-main producer commit are repinned to the in-tree producer.
  • Timing: oauth_served_route::token_acquisition_obeys_the_route_deadline_before_any_data_send (a 10 ms route deadline) failed twice in full local contract-gate runs on a loaded machine and passed 5 of 5 alone. Worth watching in CI; not changed here.
  • CodeQL: the rust/hard-coded-cryptographic-value alerts in auth/material.rs are the HTTP Basic encoding test vectors in basic_values_encode_and_refuse (test-only, same class as the Scheduling alerts dismissed as "used in tests"). The two rust/cleartext-logging alerts in auth/token.rs are fixed by no longer echoing the rendered Debug output in assertion messages.
  • Review fixes (after the Codex review): an upstream 202 marks the write incomplete whatever the configured ok range; a redelivered send resends its original request body; one profile operation bound to several record types loads, serves and replays (path conflicts compare path shape, including partial-segment parameters); journal retention runs on a cadence in bounded oldest-first batches, a failed batch is logged and retried at the next tick rather than stopping the server, and startup refuses a runtime role without INSERT, SELECT and DELETE on adapter_journal_events; each migration commits in one transaction with its ledger row. Gates rerun on the combined tree: fmt, workspace and Adapter (postgres-test) clippy, check-contracts.sh, test-postgres.sh, all pass.
  • History: squashed to one commit so the internal delivery records that lived on the branch never reach main.
  • Release: nothing is released by this PR.

DCO

  • Every commit includes a Signed-off-by trailer.
  • I reviewed the submitted changes and am responsible for the contribution.

@jeremi jeremi added the ci:full Run the heavy integration tier on this pull request label Oct 31, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-31T20:27:39.487302Z b885e3e New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c8aaee46d4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/registry-adapter/src/load.rs Resolved
Comment thread crates/registry-adapter/src/route.rs Resolved
Comment thread crates/registry-adapter/src/serve.rs Resolved
Comment thread crates/registry-adapter/src/journal.rs Resolved
Comment thread crates/registry-adapter/src/route.rs Resolved
Serve a standard registry API over systems that already hold the data,
translating each request and response live, with no record store and no
decisions. Adds the registry-adapter, registry-adapter-core and
registry-adapterctl crates, packs and offline fixtures, the refusal
corpus, and the shared platform support they need (destination policy,
OAuth client, resilience, rolling rate window, script additions,
config conformance cases).

Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
@jeremi
jeremi force-pushed the jeremi/live-adapter branch from 6244336 to b885e3e Compare October 31, 2026 20:26
@jeremi
jeremi added this pull request to the merge queue Oct 31, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 31, 2026
…ify cannot race it

Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
@jeremi
jeremi added this pull request to the merge queue Oct 31, 2026
Merged via the queue into main with commit e6533c2 Oct 31, 2026
78 checks passed
@jeremi
jeremi deleted the jeremi/live-adapter branch October 31, 2026 23:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:full Run the heavy integration tier on this pull request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants