Skip to content

Commit 1669c57

Browse files
author
records-bot
committed
sync: monorepo @ validator 0.4.0 / validation-types 0.1.5
Snapshot of medvertical/records monorepo state, exported via oss:export-validator. Tracks the npm publication of: @records-fhir/validator@0.4.0 @records-fhir/validation-types@0.1.5 Run npm i @records-fhir/validator@0.4.0 for the matching distribution. The conformance evidence in conformance-results/ matches the published tarball.
1 parent fae59ab commit 1669c57

72 files changed

Lines changed: 5033 additions & 620 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ jobs:
4646
For production CI, pin an immutable patch tag:
4747
4848
```yaml
49-
- uses: medvertical/records-fhir-validator@v0.3.0
49+
- uses: medvertical/records-fhir-validator@v0.4.0
5050
with:
5151
paths: resources/**/*.json
5252
profile-url: http://hl7.org/fhir/StructureDefinition/Patient
@@ -59,7 +59,7 @@ Action pinning:
5959
| Goal | Pin in `uses:` | Notes |
6060
|---|---|---|
6161
| Latest stable in current major | `medvertical/records-fhir-validator@v0` | Floating tag, force-moved on stable releases only |
62-
| Exact released version | `medvertical/records-fhir-validator@v0.3.0` | Immutable consumer tag |
62+
| Exact released version | `medvertical/records-fhir-validator@v0.4.0` | Immutable consumer tag |
6363
| Bit-exact reproducibility | `medvertical/records-fhir-validator@<commit-sha>` | Best for audit and forensics |
6464

6565
The `validator-v<semver>` tag is the npm mirror/release-page tag. Use
@@ -68,7 +68,7 @@ The `validator-v<semver>` tag is the npm mirror/release-page tag. Use
6868
### npm Package
6969

7070
```sh
71-
npm install @records-fhir/validator@0.3.0 @records-fhir/validation-types@0.1.5
71+
npm install @records-fhir/validator@0.4.0 @records-fhir/validation-types@0.1.5
7272
```
7373

7474
Run the CLI against one file or a folder:
@@ -138,7 +138,7 @@ includes `file`, `resourceType`, `profileUrl`, and `issues`. With
138138

139139
## What Is Included
140140

141-
- `@records-fhir/validator` 0.3.0 - Apache-2.0 validation engine.
141+
- `@records-fhir/validator` 0.4.0 - Apache-2.0 validation engine.
142142
- `@records-fhir/validation-types` 0.1.5 - Apache-2.0 validation-domain types.
143143
- Composite GitHub Action at repository root.
144144
- Standalone examples under `packages/validator/examples/`.
@@ -257,10 +257,13 @@ Spec dispatch coverage for the measured R4 base package constraints is 100%.
257257

258258
MII conformance is measured in a separate lane from the HL7
259259
`FHIR/fhir-test-cases` score. The current scoped MII-2026 reference run
260-
matches the official MII FHIR Validator on 241/241 measured resources from the
261-
refreshed MII 2026 corpus under the `mii-2026-reference` profile scope and
260+
was generated on 2026-05-19 against the official MII FHIR Validator container
261+
`mii-fhir-validator:0.0.1-alpha.7` at `http://localhost:8081`. It matches
262+
the reference validator on 241/241 measured resources from the refreshed MII
263+
2026 corpus under the `mii-2026-reference` profile scope and
262264
`mii-local-blaze` terminology mode, with 12 classified corpus/profile-drift
263-
skips.
265+
skips. The source-repository report is
266+
`conformance-results/mii-triangulation-alpha7-2026-05-19.json`.
264267

265268
This is a scoped parity claim for the measured package-example corpus. It is
266269
not an MII certification claim and does not imply full site-level MII

packages/validation-types/src/validation/__tests__/settings-defaults.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,15 @@ describe('validation settings defaults', () => {
1515
expect(getDefaultValidationSettingsForVersion('R4').resourceTypes.includedTypes).toContain('Bundle');
1616
expect(getDefaultValidationSettingsForVersion('R5').resourceTypes.includedTypes).toContain('Bundle');
1717
});
18+
19+
it('disables imposed profile policies by default', () => {
20+
expect(getDefaultValidationSettingsForVersion('R4').imposedProfiles).toEqual({
21+
enabled: false,
22+
policies: [],
23+
});
24+
expect(getDefaultValidationSettingsForVersion('R5').imposedProfiles).toEqual({
25+
enabled: false,
26+
policies: [],
27+
});
28+
});
1829
});

packages/validation-types/src/validation/__tests__/type-integrity.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,23 @@ describe('Type Integrity - DTO Serialization', () => {
252252
expect(result.success).toBe(false);
253253
});
254254

255+
it('accepts imposed profile policy settings updates', () => {
256+
const result = safeParseSettingsUpdate({
257+
imposedProfiles: {
258+
enabled: true,
259+
policies: [{
260+
id: 'mii-patient',
261+
resourceType: 'Patient',
262+
profileUrl: 'https://www.medizininformatik-initiative.de/fhir/core/StructureDefinition/Patient|2025.0.1',
263+
packageId: 'de.medizininformatikinitiative.kerndatensatz.person',
264+
packageVersion: '2025.0.1',
265+
}],
266+
},
267+
});
268+
269+
expect(result.success).toBe(true);
270+
});
271+
255272
it('does not normalize business rule aliases to custom_rule', () => {
256273
expect(normalizeValidationAspect('businessRule')).toBe('businessRule');
257274
expect(normalizeValidationAspect('business-rules')).toBe('business-rules');

packages/validation-types/src/validation/defaults/base-settings.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ export const DEFAULT_VALIDATION_SETTINGS_R4: ValidationSettings = {
114114
simplifier: true,
115115
packageRegistry: true
116116
},
117+
imposedProfiles: {
118+
enabled: false,
119+
policies: []
120+
},
117121
advancedTerminology: DEFAULT_ADVANCED_TERMINOLOGY,
118122
packageDownload: {
119123
versionPolicy: 'prefer-stable',
@@ -225,6 +229,10 @@ export const DEFAULT_VALIDATION_SETTINGS_R5: ValidationSettings = {
225229
simplifier: true,
226230
packageRegistry: true
227231
},
232+
imposedProfiles: {
233+
enabled: false,
234+
policies: []
235+
},
228236
advancedTerminology: DEFAULT_ADVANCED_TERMINOLOGY,
229237
packageDownload: {
230238
versionPolicy: 'prefer-stable',

packages/validation-types/src/validation/dtos.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ export interface ValidationMessageGroupDTO {
144144
serverId?: number; // Server ID (for single-server queries, or first seen for multi-server)
145145
resourceType?: string; // Primary resource type for this issue group
146146
resourceTypeCounts?: Record<string, number>; // Per-type resource counts (e.g. { Patient: 5, Encounter: 3 })
147+
validatorPackageVersion?: string; // Validator package version observed for the affected resource/aspect results
147148
validationRulesetVersion?: string; // Ruleset version observed for the affected resource/aspect results
148149
}
149150

@@ -181,6 +182,7 @@ export interface ResourceMessagesDTO {
181182
text: string;
182183
signature: string;
183184
createdAt: Date;
185+
validatorPackageVersion?: string;
184186
validationRulesetVersion?: string;
185187
}[];
186188
}[];

packages/validation-types/src/validation/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ export type {
111111
ValidationSettingsValidationResult,
112112
FHIRResourceTypeConfig,
113113
AdvancedTerminologyConfig,
114+
ProfileApplicationSource,
115+
ImposedProfilePolicy,
116+
ImposedProfilesConfig,
114117
AdvisorRule,
115118
AdvisorRuleMatch,
116119
AdvisorRuleTransform

packages/validation-types/src/validation/settings-schema.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,22 @@ export const HapiConfigSchema = z.object({
231231
enableBestPractice: z.boolean().optional(),
232232
});
233233

234+
export const ImposedProfilePolicySchema = z.object({
235+
id: z.string().optional(),
236+
enabled: z.boolean().optional(),
237+
resourceType: z.string().min(1),
238+
profileUrl: z.string().min(1),
239+
label: z.string().optional(),
240+
packageId: z.string().optional(),
241+
packageVersion: z.string().optional(),
242+
reason: z.string().optional(),
243+
});
244+
245+
export const ImposedProfilesConfigSchema = z.object({
246+
enabled: z.boolean(),
247+
policies: z.array(ImposedProfilePolicySchema),
248+
});
249+
234250
// ============================================================================
235251
// Main ValidationSettings Schema
236252
// ============================================================================
@@ -277,6 +293,7 @@ export const ValidationSettingsSchema = z.object({
277293
profileCachePath: z.string().optional(),
278294
}).optional(),
279295
profileSources: ProfileSourcesConfigSchema.optional(),
296+
imposedProfiles: ImposedProfilesConfigSchema.optional(),
280297
advancedTerminology: AdvancedTerminologyConfigSchema.optional(),
281298
packageDownload: PackageDownloadConfigSchema.optional(),
282299
autoRevalidateAfterEdit: z.boolean().optional(),

packages/validation-types/src/validation/settings.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,36 @@ export interface AdvisorRule {
105105
enabled?: boolean;
106106
}
107107

108+
export type ProfileApplicationSource =
109+
| 'resource-meta'
110+
| 'explicit-run'
111+
| 'imposed-policy'
112+
| 'structuredefinition-imposeProfile'
113+
| 'base-fallback';
114+
115+
export interface ImposedProfilePolicy {
116+
/** Stable identifier used in reports and audit evidence. */
117+
id?: string;
118+
/** Disabled policies are kept for draft/customer-specific configurations. */
119+
enabled?: boolean;
120+
/** FHIR resource type to which the profile is applied. Use "*" for all. */
121+
resourceType: string;
122+
/** Canonical URL of the profile to validate against. */
123+
profileUrl: string;
124+
/** Optional human-readable label shown in UI/report contexts. */
125+
label?: string;
126+
/** Optional package evidence when the policy is tied to a pinned IG package. */
127+
packageId?: string;
128+
packageVersion?: string;
129+
/** Optional explanation for why this profile is imposed. */
130+
reason?: string;
131+
}
132+
133+
export interface ImposedProfilesConfig {
134+
enabled: boolean;
135+
policies: ImposedProfilePolicy[];
136+
}
137+
108138
// ============================================================================
109139
// Validation Settings
110140
// ============================================================================
@@ -231,6 +261,12 @@ export interface ValidationSettings {
231261
*/
232262
profileSources?: ProfileSourcesConfig;
233263

264+
/**
265+
* Profiles that Records should apply as validation policy even when a
266+
* resource does not declare them in meta.profile.
267+
*/
268+
imposedProfiles?: ImposedProfilesConfig;
269+
234270
/**
235271
* Advanced Terminology Validation
236272
* Optional checks that require additional terminology server calls.
@@ -359,6 +395,7 @@ export interface ValidationSettingsUpdate {
359395
profileCachePath?: string;
360396
};
361397
profileSources?: ProfileSourcesConfig;
398+
imposedProfiles?: Partial<ImposedProfilesConfig>;
362399
packageDownload?: Partial<ValidationSettings['packageDownload']>;
363400
autoRevalidateAfterEdit?: boolean;
364401
autoRevalidateOnVersionChange?: boolean;

packages/validator/CHANGELOG.md

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,44 @@ ship together; package-only changes are noted under each release.
1212

1313
No unreleased changes yet.
1414

15+
## [0.4.0] — 2026-06-30
16+
17+
Runtime slicing and evidence-gate update for the standalone validator and
18+
GitHub Action. Released with `@records-fhir/validation-types` 0.1.5.
19+
20+
### Added
21+
22+
- Added runtime support for differential-only slices that inherit slicing from
23+
their base or snapshot when slice elements do not redeclare slicing locally.
24+
- Added local-first FHIR Schema dual-path evidence reporting with exported
25+
normalization helpers for comparing Records, graph-derived validation, and
26+
Java OperationOutcome baselines.
27+
- Added focused regression coverage for required slices, closed slicing,
28+
`memberOf` prechecks, and FHIR Schema StructureDefinition merge behavior.
29+
30+
### Changed
31+
32+
- Merge differential and base StructureDefinition elements by slice-aware
33+
identity instead of path alone, keeping same-path slices from sharing
34+
cardinality or metadata by accident.
35+
- Normalize known equivalent closed-slicing diagnostics in the evidence lane so
36+
Java pattern differences are measured without hiding real parity gaps.
37+
- Refresh README evidence around the current MII/ISiK triangulation signal and
38+
scoped FHIR Schema dual-path status.
39+
40+
### Fixed
41+
42+
- Fixed required-slice detection for profiled differential-only slices where
43+
the slice exists in the differential but the slicing declaration is inherited.
44+
- Fixed local terminology/memberOf precheck diagnostics so missing local
45+
expansions produce stable validation signals without depending on remote TX
46+
availability.
47+
48+
### Verification
49+
50+
- Verified locally with validator typecheck/build, targeted Vitest suites, MII
51+
reference gate, validator performance gate, and repository lint.
52+
1553
## [0.3.0] — 2026-06-23
1654

1755
Release-hardening update for the standalone validator and GitHub Action.
@@ -602,7 +640,8 @@ extracted from the Records DataOps Control Plane.
602640
are explicitly out of scope for this package and are not blended
603641
into the headline conformance score.
604642

605-
[Unreleased]: https://github.com/medvertical/records-fhir-validator/compare/validator-v0.3.0...HEAD
643+
[Unreleased]: https://github.com/medvertical/records-fhir-validator/compare/validator-v0.4.0...HEAD
644+
[0.4.0]: https://github.com/medvertical/records-fhir-validator/compare/validator-v0.3.0...validator-v0.4.0
606645
[0.3.0]: https://github.com/medvertical/records-fhir-validator/compare/validator-v0.2.0...validator-v0.3.0
607646
[0.2.0]: https://github.com/medvertical/records-fhir-validator/compare/validator-v0.1.14...validator-v0.2.0
608647
[0.1.0]: https://github.com/medvertical/records-fhir-validator/releases/tag/validator-v0.1.0

packages/validator/README.md

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ depending on your trade-off between freshness and stability:
8989
| Goal | Pin in `uses:` | Notes |
9090
|---|---|---|
9191
| Always-latest within current major | `medvertical/records-fhir-validator@v0` | Force-moved on every stable release; never advances onto a prerelease |
92-
| Specific minor/patch (recommended for production CI) | `medvertical/records-fhir-validator@v0.3.0` | Immutable once published |
92+
| Specific minor/patch (recommended for production CI) | `medvertical/records-fhir-validator@v0.4.0` | Immutable once published |
9393
| Bit-exact reproducibility | `medvertical/records-fhir-validator@<commit-sha>` | For audit / forensic builds |
9494

9595
The `validator-v<semver>` tag you may see on the public repo's release
@@ -494,12 +494,13 @@ constraints measured by `quality:spec-coverage`.
494494

495495
MII conformance is measured in a separate lane from the HL7
496496
`FHIR/fhir-test-cases` score. The current scoped MII-2026 reference run was
497-
generated on 2026-05-09 against the official MII FHIR Validator container at
498-
`http://localhost:8080`. It matches the reference validator on 241/241 measured
499-
resources from the refreshed MII 2026 corpus under the `mii-2026-reference`
500-
profile scope and `mii-local-blaze` terminology mode, with 12 classified
501-
corpus/profile-drift skips. The source-repository report is
502-
`conformance-results/mii-triangulation-2026-05-09.json`.
497+
generated on 2026-05-19 against the official MII FHIR Validator container
498+
`mii-fhir-validator:0.0.1-alpha.7` at `http://localhost:8081`. It matches the
499+
reference validator on 241/241 measured resources from the refreshed MII 2026
500+
corpus under the `mii-2026-reference` profile scope and `mii-local-blaze`
501+
terminology mode, with 12 classified corpus/profile-drift skips. The
502+
source-repository report is
503+
`conformance-results/mii-triangulation-alpha7-2026-05-19.json`.
503504

504505
This is a scoped parity claim for the measured package-example corpus. It is
505506
not an MII certification claim and does not imply full site-level MII
@@ -510,6 +511,57 @@ The full scope-expansion plan is tracked in
510511
The public `medvertical/records-fhir-validator` export includes the same
511512
roadmap under `docs/conformance-scope-roadmap.md`.
512513

514+
### FHIR Schema Dual-Path Scope
515+
516+
FHIR Schema is being evaluated as a cleaner intermediate representation for
517+
the same StructureDefinition semantics, not as a replacement for conformance
518+
evidence. The current engine remains StructureDefinition-first. The FHIR Schema
519+
graph path runs in parallel and is compared against both Records' current
520+
StructureDefinition path and Java/reference `OperationOutcome` evidence where a
521+
reference report exists.
522+
523+
The current MII Observation dual-path lane covers 261 real fixtures. Of those,
524+
131 have Java/reference coverage and 90 reference-comparable issues after
525+
excluding Java informational open-slice hints and Java-implied core Observation
526+
profiles (`bp`, `resprate`, `vitalsigns`) that are not part of the explicit MII
527+
profile contract for the lane. In that scoped lane, the graph path matches 73
528+
normalized Java/reference issue keys and the current Records comparable issue
529+
lane now also matches 73 after the slice-aware FHIR Schema merge and
530+
closed-slicing equivalence normalization loop.
531+
532+
Reference coverage is reported separately from graph-vs-Records correctness. The
533+
current attached MII HTTP reference report covers 131 fixtures and leaves 130
534+
reference-coverage gaps: 77 Onkologie fixtures outside the current report scope,
535+
47 Gematik ISiK/ICU fixtures outside that scope, 2 Person/Base fixtures outside
536+
that scope, and 4 fixtures without an explicit `meta.profile`. A separate local
537+
HL7 Java validator CLI supplement can cover the 126 profiled gaps and reduces
538+
the remaining reference-coverage gaps to the 4 no-profile fixtures. That CLI
539+
supplement is Java OperationOutcome evidence, not a replacement for the official
540+
MII HTTP reference validator container.
541+
542+
The report classifies the remaining cases instead of hiding them in one score:
543+
46 three-way-match cases, no one-sided Graph/Java-vs-Records or
544+
Records/Java-vs-Graph confirmed gaps, 13 graph-only-unconfirmed cases, 13
545+
Records-only-unconfirmed cases, 1 both-miss-reference case, 12 intentionally
546+
unmapped profile-missing cases, and 4 no-profile fixture cases.
547+
The intentionally excluded classes are part of the evidence model: unsupported
548+
or unmapped corpus profiles, fixtures without an explicit profile, Java
549+
informational hints, and Java behavior from implicit core Observation profiles
550+
outside the measured MII profile contract.
551+
552+
The graph-vs-Records delta keys are also classified into decision buckets:
553+
forbidden or required `code.coding` slice cardinality, Coding identity versus
554+
full-pattern differences, component-slice expression granularity, and one
555+
Records-only `focus` rule. These remain visible until Java/reference coverage
556+
or an explicit product decision promotes them into runtime behavior. The single
557+
Java-covered both-miss case is the MII spontaneous respiratory-rate fixture,
558+
where Java reports a required `sct` `code.coding` slice as missing while both
559+
TypeScript paths accept the explicit child `system`/`code` pattern.
560+
561+
This lane is therefore an implementation-reduction and convergence signal. It
562+
does not broaden the public headline parity claim beyond the explicitly measured
563+
FHIR JSON comparison lanes.
564+
513565
## License
514566

515567
Apache-2.0 for this package. The surrounding Records application remains proprietary and is licensed separately.

0 commit comments

Comments
 (0)