Skip to content

feat(evidence): add live FHIR tutorial support - #703

Open
jeremi wants to merge 12 commits into
mainfrom
agent/fhir-evidence-tutorial
Open

feat(evidence): add live FHIR tutorial support#703
jeremi wants to merge 12 commits into
mainfrom
agent/fhir-evidence-tutorial

Conversation

@jeremi

@jeremi jeremi commented Aug 10, 2026

Copy link
Copy Markdown
Member

Summary

  • add a tutorial that derives patient coverage and healthcare-establishment SD-JWT VCs from the public SMART Health IT R4 server
  • keep formal FHIR media handling in a bounded read-through adapter so the frozen Evidence v1 JSON source contract is unchanged
  • distinguish source-bound and derivation-only subject roles, including roles that share one selector field
  • add --subjects-file so sensitive selectors can be supplied from an owner-only file instead of process arguments

Why

The existing synthetic-server path did not prove that adopters could build against a real FHIR server. This tutorial uses a public R4 demo endpoint, treats its records as changeable synthetic data, discovers suitable records at run time, and derives only claims that the returned resources support. It deliberately does not reinterpret a Practitioner qualification as a professional licence.

The tutorial connects to the real public server through a minimal loopback-only read-through adapter for local authoring. The adapter has no fixtures or seeded responses. Every governed resource read is forwarded live to SMART. It requests and validates application/fhir+json upstream, then exposes the same JSON body as application/json to Evidence, preserving the frozen Version 1 source and bundle contracts.

Security and privacy

  • the frozen bundle v1 grammar and fixed-source response media types are unchanged
  • credential-free Evidence source access remains numeric-loopback-only and local-assurance-only
  • the tutorial adapter binds only to loopback, allows only the two reviewed FHIR resource paths, uses system TLS, denies redirects, validates returned resource identity, bounds responses, and suppresses request logging
  • source participation is role-aware; a derivation-only patient selector cannot widen the Coverage request
  • selector files must be regular, unsymlinked, single-link, owner-only 0600 files and are read with bounded, race-aware handling
  • selector values remain out of Git, command arguments, stdout, and stderr
  • the tutorial warns readers not to use real patient identifiers or personal data
  • the tutorial remains hidden as a draft pending human privacy and security review

Validation

  • rebased onto current origin/main at 9b0e3f3b0
  • replayed the complete tutorial against https://r4.smarthealthit.org: live discovery, both authored questions, both HTTP 200 credential requests, and offline verification of both SD-JWT VCs with true governed values
  • cargo fmt --all -- --check
  • cargo test --locked -p registry-evidencectl after the final rebase
  • cargo clippy --locked -p registry-evidencectl --all-targets -- -D warnings
  • Evidence contract, authoring schema, no-I/O, source-neutrality, verifier-portability, and config-key-path gates
  • full npm run check before the conflict-free rebase: passed, including 41,083 internal links
  • post-rebase docs generation reproduced exactly with no tracked drift
  • git diff --check origin/main...HEAD

@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: d3b9fc07d4

ℹ️ 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 docs/site/src/content/docs/tutorials/issue-fhir-evidence-as-vcs.mdx Outdated
@jeremi
jeremi force-pushed the agent/fhir-evidence-tutorial branch from d3b9fc0 to 0839d09 Compare August 11, 2026 02:01

@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: 0839d09088

ℹ️ 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 products/evidence/contracts/bundle.schema.yaml Outdated
Comment thread crates/registry-evidencectl/src/authoring.rs Outdated
@jeremi
jeremi force-pushed the agent/fhir-evidence-tutorial branch from 0839d09 to d8e4c62 Compare August 11, 2026 02:51

@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: d8e4c62f22

ℹ️ 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 products/evidence/contracts/source-contract.yaml Outdated
Comment thread crates/registry-evidencectl/src/authoring.rs
@jeremi
jeremi force-pushed the agent/fhir-evidence-tutorial branch from d8e4c62 to 165ada4 Compare August 11, 2026 03:42

@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: 165ada456c

ℹ️ 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-evidence-authoring/src/model.rs
Comment thread docs/site/src/content/docs/tutorials/issue-fhir-evidence-as-vcs.mdx
Comment thread crates/registry-evidencectl/src/authoring.rs Outdated
Comment thread docs/site/scripts/check-evidence-tutorials.sh Outdated
jeremi added 7 commits August 11, 2026 18:40
Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
render_parameters_schema() emitted a bare empty-object schema with no
comment, unlike the other must-edit placeholders in the same draft
(posture, authentication). An author had no way to know the file
needed replacing until the bundle validator's opaque "schema objects
must declare bounded properties" surfaced at compile time, since the
closed Version 1 schema subset admits no empty-object schema and a
transport: http-json source must declare at least one adapter
parameter.

Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
…osture

The inline route already refuses to guess an authentication posture. The
referenced route did not: a sources/<id>.yaml that never stated one
compiled cleanly and reached the bundle with the posture undecided, so the
author only learned of it when the evidence runtime rejected the bundle, or
at production build time through the general "every production source must
use authenticated HTTPS" refusal. evidencectl now refuses at compile time
and names the source file and the question.

Two shapes are refused, each with its own message so the author can tell
them apart: an absent or null `authentication`, and an `authentication`
that states no usable `kind` (not a mapping, or a mapping whose `kind` is
missing, null, non-string, or blank). `authentication: {}` is the first
absence wearing a mapping, and it previously failed only inside serde's
untagged-enum rejection at runtime.

Security review notes:

- This narrows, never widens, what evidencectl accepts. It refuses only
  the two shapes above on an `http-json` referenced source; every stated
  kind compiles exactly as before, so no posture becomes acceptable that
  was not acceptable already.
- The check settles that a decision was stated, never which one. An
  unrecognized but non-blank kind string still passes through to the
  runtime, which owns the closed enumeration and the assurance-profile
  rules that admit `none` only at a numeric-loopback HTTP origin under
  local assurance. No authorization decision moves out of the runtime.
- `sqlite-extract` sources open no network channel and carry no
  credential field in the runtime contract, so the check is scoped to the
  HTTP transport and leaves them untouched.
- The runtime keeps its own check, and `validate_production_sources` keeps
  its production gate. This is an earlier, more actionable refusal beside
  them, not a replacement, and nothing under crates/registry-evidence/ or
  products/evidence/contracts/ changed.
- Both messages name only the source file, the question id, and the
  `authentication:`/`kind:` field names. Neither echoes a stated kind,
  a secret reference, or any other credential material.

Tests: absent and null `authentication` are refused with the absent
message; `{}`, a null kind, a non-string kind, a blank kind, and a
non-mapping value are refused with the unnamed-kind message; each leaves
staging empty. `{kind: none}`, `{kind: static-authorization}`, and a kind
this tool does not enumerate all still compile and land in the bundle,
pinning the boundary with the runtime's enum.

Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
…orts

The standards register said Evidence Gateway accepts FHIR JSON from fixed
governed HTTP operations. The frozen fixed-source contract accepts
`application/json` and `application/graphql-response+json`, not
`application/fhir+json`, and the FHIR request and validation happen in a
local read-through adapter the operator writes. The register now says that,
matching the limitations page it links to.

Adoption metadata follows the same correction. An adapter that is project
code is not a Registry Stack surface, so the entry returns to `referenced`
and `compares_against` with no owning crate, rather than claiming
`registry-evidence` implements a profiled FHIR surface.

Generated standards.json reproduced with docs/site/scripts/generate-data.mjs.

Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
@jeremi
jeremi force-pushed the agent/fhir-evidence-tutorial branch from 165ada4 to 074024a Compare August 11, 2026 13:00

@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: 074024a13c

ℹ️ 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 docs/site/src/content/docs/tutorials/issue-fhir-evidence-as-vcs.mdx Outdated
jeremi added 3 commits August 11, 2026 20:52
Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>

@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: f93f7f93e2

ℹ️ 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 docs/site/scripts/check-evidence-tutorials.sh
Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
@jeremi
jeremi enabled auto-merge (squash) August 11, 2026 14:20

@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: cb6d6e6559

ℹ️ 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-evidencectl/src/authoring.rs
Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant