Skip to content

feat(official): CMS138 onboarded — 0/47 → 47/47, and the gate learned a new kind of claim - #366

Merged
Taleef7 merged 6 commits into
mainfrom
feat/onboard-cms138
Jul 31, 2026
Merged

feat(official): CMS138 onboarded — 0/47 → 47/47, and the gate learned a new kind of claim#366
Taleef7 merged 6 commits into
mainfrom
feat/onboard-cms138

Conversation

@Taleef7

@Taleef7 Taleef7 commented Jul 31, 2026

Copy link
Copy Markdown
Owner

Result

CMS138: 0/47 with 47 errors → 47/47, 0 unexpected mismatches, 0 errors. The MADiE gate is now 278/278 across six measures.

Three things had to be true and only the first was: the value set had to be sourced, the artifact had to be complete, and the deck had to be able to see it.

1. Sourced

The credentialed workflow from #365 pulled …3.526.3.1278 ("Tobacco Use Screening") from VSAC at the pinned release — 4 codes, where upstream ships none. Its verification step confirmed truncated [] / absent [] before uploading, and refuses to upload anything less.

2. The deck still said 0/47 — which falsified ADR-053

Every case errored with Missing the following valuesets. ADR-053 had claimed "the real check on a sourced value set is the MADiE gate." The report explains why that's wrong in its own words:

"ValueSets are consumed directly from each official measure Bundle."

The gate runs on upstream's terminology. That is exactly what makes it a genuine external check for the other five — and exactly what makes it blind here, since the bundle is the thing lacking the set. A complete sidecar sat beside it the whole time, unread.

3. So the gate supplements — but only what upstream omits

runOfficialMeasureCases takes the artifact's runtime terminology and narrows it to the OIDs the bundle does not ship.

The narrowing lives next to the calculate call, not at the call site. The natural thing for a caller to do is pass the whole cache — which would quietly convert this gate from "upstream's terminology" into "ours" for every measure, deck still green, nothing to notice. With nothing missing, calculate takes three arguments exactly as before; the pre-existing assertion pinning that still passes, which is what makes the five complete measures provably unaffected.

What 47/47 licenses — and what it does not

For that one value set the codes are ours. What stays upstream's is the answer key — the expected population vectors. So agreement is real evidence the four sourced codes are right, and no evidence about upstream's terminology.

Everything here exists to stop that being rounded off to "47/47 like the others":

mechanism where
supplementedOids on the run in the data, so nothing downstream can drop it
mode measure-bundle+sourced-supplement distinguishes it from measure-bundle
stderr warning naming the OIDs a weaker claim shouldn't need a markdown diff to notice
a paragraph on the measure's own line in the report not a footnote

The report's controls paragraph no longer claims terminology comes only from the bundle — a supplemented run would have contradicted it two lines later.

Guards, mutation-checked

mutation result
supplementFor passes everything through unfiltered 5 tests fail
drop the |version OID normalization fails exactly the test written for it

Smaller things caught

  • A test comment still asserted cms138 "scores 0/47 because one value set will not expand" — the misdiagnosis ADR-053 corrected, living on where nobody looks.
  • Two CLI test doubles predated supplementedOids and threw on it, surfacing as the CLI returning exit 2 — reading as "the configuration was refused" rather than "the fixture is incomplete".
  • I re-ran the ADR-writing script by accident and duplicated ADR-053. Caught by grepping the heading count rather than by reading, which is the only reason it didn't ship.
  • official-artifacts.test.ts's vendored list is hardcoded on purpose ("a new artifact appearing unannounced is a review event"), so cms138 is a deliberate edit.

Still open

CMS130 and CMS165 are not vendored. Their blockers are capped expansions, which the gate handles today — no supplement needed. One workflow dispatch each.


Suite 1764 pass / 0 fail / 15 skipped; typecheck clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Q3BNWAJwJJ5QjP1X6JpHUo

Taleef and others added 5 commits July 31, 2026 12:12
…k verdict pending CI

The credentialed vendor workflow from #365 did its job. Run 30645615371:

  audit    CMS138FHIRTobaccoScrnCessation  32 retrieved  31 shipped  1 ABSENT
  vendor   sourced 2.16.840.1.113883.3.526.3.1278 from VSAC:
           absent from the upstream bundle → 4 codes @ Library/ecqm-fhir-update-2025
  verify   32 value sets, 549 codes, truncated [] absent []
           cms138: terminology complete — nothing capped, nothing absent

So the artifact is complete and `scoring=proportion`, `populationBasis=boolean` — no
episode-of-care problem like CMS68. Committed here with cms138 added to the gate map,
to the case-count floor (47, counted from the sparse checkout: 47 case DIRECTORIES,
the three non-directory entries are not cases), and to the CI + both deploy vendor
lists.

DELIBERATELY PUSHED WITH A STALE EVIDENCE REPORT. `docs/OFFICIAL_TESTCASE_REPORT` is
regenerated by `pnpm test:official-cases`, which needs the gitignored terminology
sidecar — and cms138's sidecar cannot be produced locally, because it needs the VSAC
secret. Two guards in `official-gate.test.ts` fail locally for exactly that reason and
they are RIGHT to: they say the report does not yet prove this artifact. CI runs the
deck with the credential, and the report artifact it uploads is what gets committed
next.

That means this push is the measurement, not a claim. The completion is the weaker
ADR-053 kind — upstream shipped no codes to check containment against and declared no
total to check length against — so nothing in the vendoring can tell a correct
expansion from a wrong one of the right size. 47 cases carrying the measure steward's
own expected population vectors can. It was 0/47 with 47 errors.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q3BNWAJwJJ5QjP1X6JpHUo
… an absent value set

Measured by running it: with cms138 in the gate and a COMPLETE sidecar beside it, the
deck scores 0/47 with 47 errors, every one 'Missing the following valuesets:
…3.526.3.1278'. Byte-for-byte the pre-ADR-053 result.

The cause is structural and the report states it plainly: 'ValueSets are consumed
directly from each official measure Bundle; no VSAC network call or key is used.' The
gate runs on UPSTREAM's terminology — which is what makes it an external check for the
other five measures, and what makes it blind for this one, since the bundle is exactly
what lacks the value set.

So a sourced-absent value set is validated by NEITHER the vendoring (no containment or
declared-total baseline) NOR the gate. ADR-053 said the gate covered it. It does not.

What would: run the deck with the vendored sidecar as fqm's value-set cache — the mode
the reduction check already models as `vendored-terminology-sidecar`. The codes are
then ours while the EXPECTED VECTORS stay upstream's, which is real evidence about the
codes and a weaker claim than the other five carry. Not built; must be labelled
per-measure in the report when it is.

CMS138 stays un-onboarded until then.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q3BNWAJwJJ5QjP1X6JpHUo
…s not ship (ADR-053)

Closes the gap the CMS138 run exposed: the MADiE gate executes each measure against the
upstream bundle's own ValueSet resources, so a value set upstream omits cannot be
resolved however complete our sidecar is. cms138 scored 0/47 with 47 errors, every one
"Missing the following valuesets".

"runOfficialMeasureCases" now accepts the artifact's runtime terminology and NARROWS it
to the OIDs the bundle does not ship. The narrowing lives next to the calculate call it
protects, not at the call site, because the natural thing for a caller to do is pass the
whole cache — which would silently convert this gate from "upstream's terminology" into
"ours" for every measure, with the deck still green and nothing to notice it.

- The default path is unchanged and provably so: with nothing missing, calculate is
  invoked with THREE arguments exactly as before (the pre-existing assertion still
  passes) and the mode stays "measure-bundle".
- A supplemented run records "supplementedOids", sets mode
  "measure-bundle+sourced-supplement", prints a console warning, and renders a
  per-measure paragraph in the report saying plainly that for those value sets the CODES
  are ours while the ANSWER KEY — the expected population vectors — stays upstream's.
- The controls paragraph no longer claims terminology comes only from the bundle, which
  a supplemented run would have contradicted two lines later.

Mutation-checked: unfiltered passthrough fails 5 tests; dropping the version-suffix
normalization fails exactly the test written for it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q3BNWAJwJJ5QjP1X6JpHUo
…lists conscious edits

- The CLI loads the artifact's runtime terminology BEFORE the gate run (it only did so
  for the reduction check) and hands it to `runOfficialMeasureCases`, which narrows it.
  A supplemented run is announced on stderr the same way a downgraded reduction check
  already is — a weaker claim should not require diffing a markdown file to notice.
- `official-artifacts.test.ts`'s vendored list is hardcoded on purpose ("a new artifact
  appearing unannounced is a review event"), so cms138 is a deliberate edit. Its comment
  said cms138 "scores 0/47 because one value set will not expand" — that was the
  misdiagnosis ADR-053 corrected, and it was still sitting in a test comment.
- Two CLI test doubles predated `supplementedOids` and threw on it, which surfaced as
  the CLI returning exit 2 — reading as "the configuration was refused" rather than
  "the fixture is incomplete".

Two failures remain locally and are CORRECT: the committed evidence report does not yet
cover cms138. It is regenerated by `pnpm test:official-cases`, which needs the
gitignored sidecar — producible only with the VSAC secret, i.e. only in CI. The next
push commits the report CI renders, and that report is where the CMS138 verdict appears.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q3BNWAJwJJ5QjP1X6JpHUo
…across six measures

The committed evidence report, rendered by the credentialed CI run. CMS138 scores
47/47 with 0 unexpected mismatches and 0 errors, up from 0/47 with 47 errors.

ADR-053 updated with the measured outcome, replacing the paragraph that said the
supplement was "not yet built" and CMS138 "stays un-onboarded" — both true when
written this morning and false now.

WHAT 47/47 LICENSES, AND WHAT IT DOES NOT. For one value set the codes are OURS,
sourced from VSAC at the pinned release, because upstream's bundle ships none. What
stays upstream's is the ANSWER KEY — the expected population vectors. So agreement is
real evidence the four sourced codes are right, and no evidence at all about upstream's
terminology. Everything here exists to stop that being rounded off to "47/47 like the
others": `supplementedOids` carries it in the data, the mode reads
`measure-bundle+sourced-supplement`, the CLI says so on stderr, and the report prints
it on the measure's own line rather than in a footnote.

Also caught in this pass: I re-ran the ADR-writing script by accident and duplicated
ADR-053. Found by grepping the heading count rather than by reading it, which is the
only reason it did not ship — restored from HEAD and re-applied the edit cleanly.

Suite 1764 pass / 0 fail / 15 skipped; typecheck clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q3BNWAJwJJ5QjP1X6JpHUo
@Taleef7
Taleef7 marked this pull request as ready for review July 31, 2026 18:36
@Taleef7 Taleef7 changed the title DRAFT feat(official): CMS138 vendored and sourced — but the MADiE gate cannot validate it feat(official): CMS138 onboarded — 0/47 → 47/47, and the gate learned a new kind of claim Jul 31, 2026

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

ℹ️ 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 .github/workflows/ci.yml
pnpm vendor:official --measure CMS2FHIRPCSDepScreenAndFollowUp --catalog-id cms2 --strip-elm-annotations $COMPLETE
pnpm vendor:official --measure CMS68FHIRDocumentationCurrentMeds --catalog-id cms68 --strip-elm-annotations $COMPLETE
pnpm vendor:official --measure CMS951FHIRKidneyHealthEval --catalog-id cms951 --strip-elm-annotations $COMPLETE
pnpm vendor:official --measure CMS138FHIRTobaccoScrnCessation --catalog-id cms138 --strip-elm-annotations $COMPLETE

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep uncredentialed fork CI from running CMS138 incomplete

When this job runs for a fork or Dependabot PR, GitHub withholds WORKWELL_VSAC_API_KEY_VENDOR, so lines 170–176 leave $COMPLETE empty. This new invocation then regenerates CMS138 with only the 31 upstream value sets; backend-ts/scripts/vendor-official-measure.mjs:507-515 explicitly says that the resulting artifact cannot run because the missing set requires --complete-terminology. The bundle-only reproducibility check still passes, but the workflow subsequently runs the default pnpm test:official-cases gate at lines 232–234, which now includes CMS138 and therefore reports all 47 cases as errors and exits nonzero. Condition the CMS138 invocation/gate for the uncredentialed path or otherwise provide a credentialless way to retain its validated supplement, so every external PR is not unconditionally red.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Correct and fixed in 895027d — thank you, this would have turned every external contributor's PR red on merge.

Your trace is exactly right: uncredentialed → $COMPLETE empty → cms138 re-vendored with only upstream's 31 value sets → the supplement has nothing to draw on → 47 errors → nonzero exit. And the bundle-only reproducibility check passes, so nothing upstream of the gate would have caught it.

--allow-missing-terminology skips a measure the CONTEXT cannot resolve, passed by CI only where steps.vendor.outputs.credentialed != 'true' — the same conditional the reproducibility check already splits on, and the same shape official-flip-config.test.ts uses to excuse the capped class.

The opt-OUT is the load-bearing half, so it is the one I pinned hardest: a credentialed run passes nothing and therefore skips nothing, because there an unresolvable value set means a broken artifact — which is the whole point of the gate. There is a test that supplies the SAME unresolvable OID without the flag and asserts the measure still runs, so the accommodation cannot quietly become the default.

Two consequences your comment did not have to reach, both handled:

  1. A skipped run is PARTIAL even though it asked for the full list, so it must not rewrite the committed report — otherwise CI's staleness check would read "current" on the very run that could not produce it. Extended the existing --measure guard rather than adding a second one.
  2. That staleness step is now credentialed-only, since an uncredentialed run deliberately leaves the report alone and the comparison would always differ.

The skip predicate is absentValueSets(artifact, requiredOids(artifact)) — the same one officialRoutingProblems refuses on — so "the gate skipped it" and "routing would refuse it" are one decision, not two that can drift.

Mutation-checked both ways: skipping regardless of the flag, and letting a partial run overwrite the report, each fail exactly one test.

…lly red (review, #366)

GitHub withholds WORKWELL_VSAC_API_KEY_VENDOR from fork and Dependabot PRs, so CI
re-vendors without --complete-terminology. For cms138 that regenerates a sidecar
missing the value set upstream does not ship — there is nothing to supplement from, the
deck cannot resolve it, and all 47 cases error. Every external contributor's PR would
have failed for a reason unrelated to their change. Codex caught it before merge.

`--allow-missing-terminology` skips a measure this CONTEXT cannot resolve, and CI passes
it only where `steps.vendor.outputs.credentialed != 'true'` — the same shape the
reproducibility check already uses, and the same shape official-flip-config.test.ts uses
to excuse the capped class.

THE OPT-OUT IS THE LOAD-BEARING HALF. A credentialed run passes nothing and therefore
skips nothing: there an unresolvable value set means a broken artifact, which is what
the gate exists to catch. Pinned by a test that supplies the SAME unresolvable OID
without the flag and asserts the measure still runs.

Two further consequences, both handled:
- A run that skipped a measure is PARTIAL even though it asked for the full list, so it
  must not rewrite the committed report — otherwise CI's staleness check reads "current"
  on the very run that could not produce it. Extended the existing `--measure` guard.
- That staleness step is now credentialed-only, since an uncredentialed run deliberately
  leaves the report alone and comparing against it would always differ.

The skip predicate is `absentValueSets(artifact, requiredOids(artifact))` — the same one
`officialRoutingProblems` refuses on — so "the gate skipped it" and "routing would refuse
it" are one decision rather than two that can disagree.

Mutation-checked: skipping regardless of the flag, and letting a partial run overwrite
the report, each fail exactly one test.

Suite 1767 pass / 0 fail / 15 skipped; typecheck clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q3BNWAJwJJ5QjP1X6JpHUo
@Taleef7
Taleef7 merged commit ca8df4c into main Jul 31, 2026
12 checks passed
@Taleef7
Taleef7 deleted the feat/onboard-cms138 branch July 31, 2026 19:10
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