@cosyte/synth 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +414 -0
- package/LICENSE +21 -0
- package/README.md +325 -0
- package/dist/astm/index.cjs +847 -0
- package/dist/astm/index.cjs.map +1 -0
- package/dist/astm/index.d.cts +418 -0
- package/dist/astm/index.d.ts +418 -0
- package/dist/astm/index.mjs +828 -0
- package/dist/astm/index.mjs.map +1 -0
- package/dist/ccda/index.cjs +1103 -0
- package/dist/ccda/index.cjs.map +1 -0
- package/dist/ccda/index.d.cts +380 -0
- package/dist/ccda/index.d.ts +380 -0
- package/dist/ccda/index.mjs +1077 -0
- package/dist/ccda/index.mjs.map +1 -0
- package/dist/deid/index.cjs +2809 -0
- package/dist/deid/index.cjs.map +1 -0
- package/dist/deid/index.d.cts +464 -0
- package/dist/deid/index.d.ts +464 -0
- package/dist/deid/index.mjs +2793 -0
- package/dist/deid/index.mjs.map +1 -0
- package/dist/example-codes-DeXcnCSK.d.cts +105 -0
- package/dist/example-codes-DeXcnCSK.d.ts +105 -0
- package/dist/fhir/index.cjs +1429 -0
- package/dist/fhir/index.cjs.map +1 -0
- package/dist/fhir/index.d.cts +772 -0
- package/dist/fhir/index.d.ts +772 -0
- package/dist/fhir/index.mjs +1384 -0
- package/dist/fhir/index.mjs.map +1 -0
- package/dist/hl7/index.cjs +1012 -0
- package/dist/hl7/index.cjs.map +1 -0
- package/dist/hl7/index.d.cts +548 -0
- package/dist/hl7/index.d.ts +548 -0
- package/dist/hl7/index.mjs +990 -0
- package/dist/hl7/index.mjs.map +1 -0
- package/dist/index.cjs +535 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +407 -0
- package/dist/index.d.ts +407 -0
- package/dist/index.mjs +488 -0
- package/dist/index.mjs.map +1 -0
- package/dist/ncpdp/index.cjs +714 -0
- package/dist/ncpdp/index.cjs.map +1 -0
- package/dist/ncpdp/index.d.cts +432 -0
- package/dist/ncpdp/index.d.ts +432 -0
- package/dist/ncpdp/index.mjs +695 -0
- package/dist/ncpdp/index.mjs.map +1 -0
- package/dist/providers-OLz3zAc-.d.cts +343 -0
- package/dist/providers-OLz3zAc-.d.ts +343 -0
- package/dist/quirk-DmkgoZdh.d.cts +239 -0
- package/dist/quirk-JLyO1Ncj.d.ts +239 -0
- package/dist/x12/index.cjs +920 -0
- package/dist/x12/index.cjs.map +1 -0
- package/dist/x12/index.d.cts +484 -0
- package/dist/x12/index.d.ts +484 -0
- package/dist/x12/index.mjs +892 -0
- package/dist/x12/index.mjs.map +1 -0
- package/package.json +210 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
Versions and publishing are managed with [Changesets](https://github.com/changesets/changesets);
|
|
8
|
+
this file is maintained by hand (Changesets handles the version bump and publish only).
|
|
9
|
+
|
|
10
|
+
## [Unreleased]
|
|
11
|
+
|
|
12
|
+
The first pre-alpha release (`0.0.1`) will ship the initial public API surface. The package begins
|
|
13
|
+
its public history at `0.0.x`, per the cosyte version ladder (`0.0.x` until first alpha).
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- Project scaffold from the shared `@cosyte/*` parser template: the canonical toolchain (TypeScript
|
|
18
|
+
ES2023 + strict rigor via `@cosyte/tsconfig`, ESLint 10 + type-checked `typescript-eslint` via
|
|
19
|
+
`@cosyte/eslint-config`, Prettier via `@cosyte/prettier-config`, Vitest 4 + v8 coverage via
|
|
20
|
+
`@cosyte/vitest-config`, dual ESM + CJS build via `tsup` + `@cosyte/tsup-config`, `attw` publish
|
|
21
|
+
gate), thin callers of the reusable `cosyte/.github` CI/release workflows, Changesets on the
|
|
22
|
+
`0.0.x` ladder, and the property-based conformance harness from `@cosyte/test-utils`.
|
|
23
|
+
- **Phase 1 — the generator core (SYNTH-1).** The seeded-PRNG + synthetic-safety + round-trip
|
|
24
|
+
foundation every format plugs into, proven end-to-end on HL7 v2:
|
|
25
|
+
- **Seeded, deterministic PRNG** — a hand-rolled, zero-dep `sfc32` seeded by `splitmix32`
|
|
26
|
+
(`createRng`, `splitmix32`, `sfc32Next`). `Math.random` is **lint-banned** in `src/` (it is not
|
|
27
|
+
seedable). Same seed → byte-identical output, a tested invariant.
|
|
28
|
+
- **The synthetic-safety provider layer** (`safe` + `ssn`/`phone`/`email`/`ipv4`/`ipv6`/`uuid`/
|
|
29
|
+
`identifier`/`address`/`dateYmd`/`name`) — every value drawn from a guaranteed-non-colliding
|
|
30
|
+
source: SSA never-issued (`900–999`) + advertising (`987-65-432x`) SSNs, NANP `555-01xx` phones,
|
|
31
|
+
RFC 2606/6761 `example.*` domains, RFC 5737/3849 TEST-NET IPs, a synthetic assigning authority
|
|
32
|
+
(`COSYTE-SYNTH`) for MRNs, and a shipped clearly-fake name pool. Reserved-range predicates
|
|
33
|
+
(`isSyntheticSsn`/`isSyntheticPhone`/`isSyntheticEmail`/`isSyntheticIp`).
|
|
34
|
+
- **The `Corpus` abstraction** (`makeCorpus`) — a deep-frozen, self-describing seed + manifest.
|
|
35
|
+
- **`defineSynthProfile`** — the profile growth-loop skeleton.
|
|
36
|
+
- **Stable fatal codes** (`SYNTH_FATAL_CODES`: `SYNTH_UNSUPPORTED_FORMAT`, `SYNTH_UNSUPPORTED_QUIRK`)
|
|
37
|
+
- the typed `SynthError`.
|
|
38
|
+
- **HL7 v2 generation** at the `@cosyte/synth/hl7` subpath (`generateAdt`, `roundTrip`, `hl7Corpus`,
|
|
39
|
+
`componentsField`) — builds `ADT^A01/A04/A08` **through `@cosyte/hl7`'s `buildMessage`**, so output
|
|
40
|
+
is spec-clean by construction and round-trips with zero warnings.
|
|
41
|
+
- **Phase 2 — the rest of the HL7 v2 set (SYNTH-2).** Extends HL7 v2 generation from `ADT` alone to
|
|
42
|
+
the full Phase 2 family, all built **through `@cosyte/hl7`'s `buildMessage`** and all round-tripping
|
|
43
|
+
through the parser with **zero warnings**, seed-deterministic, and synthetic-safe:
|
|
44
|
+
- **New generators** at the `@cosyte/synth/hl7` subpath: `generateOru` (`ORU^R01`, an OBR/OBX result
|
|
45
|
+
group), `generateOrm` (`ORM^O01`, an ORC/OBR order), `generateSiu` (`SIU^S12`, an SCH schedule
|
|
46
|
+
activity), and `generateVxu` (`VXU^V04`, a PID + ORC/RXA/RXR immunization). Each emits exactly the
|
|
47
|
+
segments the parser's structure net requires for its trigger, so nothing warns.
|
|
48
|
+
- **`generateHl7(kind, seed)`** — a dispatch over every `Hl7MessageKind`
|
|
49
|
+
(`ADT^A01`/`A04`/`A08`, `ORU^R01`, `ORM^O01`, `SIU^S12`, `VXU^V04`).
|
|
50
|
+
- **`hl7Corpus` now generates a mixed corpus** across every family by default (`mix?` to choose,
|
|
51
|
+
`triggers?` kept for SYNTH-1 ADT-only back-compat).
|
|
52
|
+
- **Shared HL7 building blocks** (`mshScaffold`, `patientIdentity`, `pidSegment`, `seededTimestamp`)
|
|
53
|
+
so every family mints identity from the same synthetic-safety providers in the same draw order;
|
|
54
|
+
`ADT` now uses them (byte-identical output preserved).
|
|
55
|
+
- **A small, license-clean example-code pool** (`EXAMPLE_LAB_OBSERVATIONS`, `EXAMPLE_ORDER_SERVICES`,
|
|
56
|
+
`EXAMPLE_VACCINES` — public LOINC/CVX code facts) to fill coded fields. **No** terminology is
|
|
57
|
+
bundled; codes are illustrative structural fillers only.
|
|
58
|
+
- **Tier-1 fixtures** for the new families and the synthetic-safety + seed-determinism property tests
|
|
59
|
+
extended to sweep every family (PID loci provably synthetic; whole-message real-data sweep zero).
|
|
60
|
+
- **The round-trip harness + synthetic-safety CI gate** — property tests prove seed-determinism,
|
|
61
|
+
zero-warning round-trips, and that no generated value escapes a reserved/synthetic source; the
|
|
62
|
+
repo `phi-scan` gains HL7-PID structured detection (synthetic-SSN-range aware).
|
|
63
|
+
- **Vendored `@cosyte/hl7`** as an optional peer dep via the `mllp` pattern (`file:vendor/*.tgz`
|
|
64
|
+
devDependency) — third-party runtime deps stay at **zero**.
|
|
65
|
+
- **Phase 3 — FHIR R4 / US Core (SYNTH-3).** A new `@cosyte/synth/fhir` subpath generating the US Core
|
|
66
|
+
clinical spine **through `@cosyte/fhir`'s own model constructors and serializer**, so every resource
|
|
67
|
+
is spec-clean by construction — validating under `@cosyte/fhir.validateResource` and, against the
|
|
68
|
+
**real, published US Core 6.1.0 `StructureDefinition`s** (BYO — none bundled), conformant to US Core:
|
|
69
|
+
- **New generators** at the `@cosyte/synth/fhir` subpath: `generatePatient` (base + `profile:"us-core"`
|
|
70
|
+
with the race/ethnicity/birthsex must-support extensions), `generateCondition` (US Core
|
|
71
|
+
problem-list item), `generateObservationLab` (US Core Laboratory Result), `generateVitalSign` (US
|
|
72
|
+
Core Vital Signs), `generateMedicationRequest` (US Core, satisfying the `us-core-21` requester
|
|
73
|
+
invariant), and `generateBundle` (`collection` + `transaction`, wired by `urn:uuid:` references).
|
|
74
|
+
- **`fhirCorpus(seed, count?, mix?)`** — a reproducible mixed corpus across the spine; **`roundTrip`**
|
|
75
|
+
— the FHIR round-trip/validate harness (serialize → parse → validate(strict) → serialize), which
|
|
76
|
+
accepts caller-supplied (BYO) US Core / vendor profiles. For FHIR, **spec-clean means zero
|
|
77
|
+
`error`/`fatal` findings + byte-stable** (the harness exposes both `errors` and `warnings`);
|
|
78
|
+
advisory findings a valid resource may legally carry — `REFERENCE_UNRESOLVED` on a collection
|
|
79
|
+
Bundle's external reference, `MUST_SUPPORT_ABSENT`, `INVARIANT_UNCHECKED`, base `dom-6` — are **not**
|
|
80
|
+
spec-cleanliness violations, unlike the HL7-side "zero warnings" contract (FHIR warnings are not all
|
|
81
|
+
conformance failures).
|
|
82
|
+
- **Model-construction helpers** (`prop`/`str`/`dec`/`bool`/`coding`/`codeableConcept`/`reference`/
|
|
83
|
+
`narrative`/`meta`/`mrnIdentifier`/`fhirPatientIdentity`/`toFhirDate`) that build through
|
|
84
|
+
`@cosyte/fhir`; US Core canonical URLs + code-system identifiers (`US_CORE_PROFILE`, `SYSTEM`, the
|
|
85
|
+
race/ethnicity/birthsex extension URLs) as **facts only**; and a small **license-clean** FHIR
|
|
86
|
+
example-code pool (`EXAMPLE_LAB_OBSERVATIONS`, `EXAMPLE_VITAL_SIGNS`, `EXAMPLE_CONDITIONS`,
|
|
87
|
+
`EXAMPLE_MEDICATIONS`, `EXAMPLE_RACE_CATEGORIES`, `EXAMPLE_ETHNICITY_CATEGORIES` — public LOINC/
|
|
88
|
+
SNOMED/RxNorm/OMB code facts). **No** US Core IG or terminology content is bundled.
|
|
89
|
+
- **US Core conformance is validated firsthand** against the committed real US Core 6.1.0 profiles
|
|
90
|
+
(`test/us-core-profiles/`, BYO reference inputs) — every US-Core generator validates with **zero
|
|
91
|
+
errors** across a 200-seed sweep; plus FHIR seed-determinism, synthetic-safety, and golden-fixture
|
|
92
|
+
property/regression suites, and FHIR-aware structured detection (HumanName + phone `ContactPoint`)
|
|
93
|
+
in the repo `phi-scan`.
|
|
94
|
+
- **Vendored `@cosyte/fhir`** as an optional peer dep via the same `file:vendor/*.tgz` pattern —
|
|
95
|
+
third-party runtime deps stay at **zero**. Deferred to SYNTH-4: `Encounter`, `DiagnosticReport`,
|
|
96
|
+
`Immunization`, `AllergyIntolerance`, `Procedure`, the `document` Bundle shape, and quirk mode.
|
|
97
|
+
- **Phase 4 — the rest of the US Core clinical set (SYNTH-4).** Extends the `@cosyte/synth/fhir` subpath
|
|
98
|
+
from the SYNTH-3 clinical spine to the full US Core clinical set, each built **through `@cosyte/fhir`'s
|
|
99
|
+
own model constructors** and validated firsthand against the **real, published US Core 6.1.0
|
|
100
|
+
`StructureDefinition`s** (BYO — none bundled):
|
|
101
|
+
- **New generators:** `generateEncounter` (US Core Encounter), `generateDiagnosticReport` (US Core
|
|
102
|
+
Laboratory DiagnosticReport — carries the mandated `LAB` category slice and `effectiveDateTime` +
|
|
103
|
+
`issued` for the `us-core-8`/`us-core-9` invariants, with optional `result` wiring),
|
|
104
|
+
`generateImmunization` (US Core Immunization), `generateAllergyIntolerance` (US Core
|
|
105
|
+
AllergyIntolerance — `clinicalStatus` + `verificationStatus` emitted together for `ait-1`/`ait-2`),
|
|
106
|
+
and `generateProcedure` (US Core Procedure). Each takes a `subject`/`patient` reference and claims US
|
|
107
|
+
Core via `meta.profile` by default (`usCore:false` opts out).
|
|
108
|
+
- **The `document` Bundle shape:** `generateBundle({ type: "document" })` leads with the FHIR-mandated
|
|
109
|
+
`Composition` (`bdl-11`) plus a synthetic `Organization` author/custodian, and carries the required
|
|
110
|
+
`identifier` (`bdl-9`) and `timestamp` (`bdl-10`). `buildComposition` is exported. The shared Bundle
|
|
111
|
+
spine now assembles the **full clinical set** wired by `urn:uuid:` `fullUrl`s so **every reference
|
|
112
|
+
resolves in-bundle** (the `DiagnosticReport.result` points at the in-bundle lab `Observation`).
|
|
113
|
+
- **New license-clean example-code pools** (public code facts, no terminology bundled): `EXAMPLE_VACCINES`
|
|
114
|
+
(CVX), `EXAMPLE_ALLERGENS` + `EXAMPLE_ALLERGY_MANIFESTATIONS` (RxNorm/SNOMED), `EXAMPLE_PROCEDURES`
|
|
115
|
+
(SNOMED — never CPT), `EXAMPLE_DIAGNOSTIC_REPORTS` (LOINC panels), `EXAMPLE_ENCOUNTER_TYPES` (SNOMED),
|
|
116
|
+
`EXAMPLE_ENCOUNTER_CLASSES` (v3 ActCode); plus the matching `SYSTEM`/`US_CORE_PROFILE` identifiers.
|
|
117
|
+
- **`fhirCorpus`** now cycles the full clinical set by default; every new generator is covered by the
|
|
118
|
+
round-trip (zero-error, byte-stable), US-Core-conformance (zero-error over a 200-seed sweep),
|
|
119
|
+
seed-determinism, synthetic-safety, and golden-fixture suites. The five new US Core 6.1.0 profiles
|
|
120
|
+
(`us-core-encounter`, `us-core-diagnosticreport-lab`, `us-core-immunization`,
|
|
121
|
+
`us-core-allergyintolerance`, `us-core-procedure`) are committed under `test/us-core-profiles/`.
|
|
122
|
+
Deferred to SYNTH-5: C-CDA generation; quirk mode remains Phase 7.
|
|
123
|
+
- **Phase 4 / C-CDA — spec-clean C-CDA generation (SYNTH-5).** A new `@cosyte/synth/ccda` subpath
|
|
124
|
+
generating Consolidated CDA R2.1 documents **through `@cosyte/ccda`'s `buildCcda`**, so every document
|
|
125
|
+
is spec-clean by construction — it round-trips through `parseCcda` with **zero warnings**, is
|
|
126
|
+
seed-deterministic (byte-identical for a seed), and is synthetic by construction:
|
|
127
|
+
- **New generators:** `generateCcd` (Continuity of Care Document), `generateReferralNote` (the second
|
|
128
|
+
document type `buildCcda` supports, with its Reason-for-Referral + Assessment narrative sections),
|
|
129
|
+
and the generic `generateCcda({ documentType })`. Each populates the CCD SHALL sections (Problems,
|
|
130
|
+
Allergies, Medications, Results, Vital Signs) plus Immunizations, Procedures, and Social History
|
|
131
|
+
(Smoking Status).
|
|
132
|
+
- **`ccdaCorpus`** builds a reproducible mixed corpus (CCD + Referral Note by default); `roundTrip`
|
|
133
|
+
is the C-CDA round-trip-through-the-parser harness (serialize → parse → serialize, judged by the
|
|
134
|
+
parser). `ccdaPatientIdentity` mints the synthetic `recordTarget`.
|
|
135
|
+
- **Reuses the license-clean example-code pools** (the same public LOINC/RxNorm/SNOMED/CVX facts the
|
|
136
|
+
FHIR generators ship, adapted to `@cosyte/ccda`'s OID-coded `BuildCode`) plus a small Social-History
|
|
137
|
+
(SNOMED smoking status) and NCI-route pool. No terminology content is bundled.
|
|
138
|
+
- **Synthetic-by-construction:** the patient name is from the shipped fake-name pool, the MRN lives
|
|
139
|
+
under the synthetic assigning-authority OID (never a real facility namespace), and every date comes
|
|
140
|
+
from the seeded generator — `buildCcda`'s default `effectiveTime: new Date()` is always overridden
|
|
141
|
+
with a synthetic date so the reproducibility contract holds. Seed-determinism and synthetic-safety
|
|
142
|
+
property suites (250-seed sweeps) + golden fixtures added; the repo `phi-scan` gains C-CDA-aware
|
|
143
|
+
structured detection (recordTarget `name` + `telecom`).
|
|
144
|
+
- **`@cosyte/ccda` vendored as an optional peer dep** (`file:vendor/cosyte-ccda-0.0.1.tgz`), lazily
|
|
145
|
+
loaded per format — importing the package root never pulls it; third-party runtime deps stay at
|
|
146
|
+
zero. Deferred to SYNTH-6: X12 generation; quirk mode remains Phase 7.
|
|
147
|
+
- **Phase 5 / X12 — spec-clean HIPAA 005010 generation (SYNTH-6).** A new `@cosyte/synth/x12` subpath
|
|
148
|
+
generating X12 EDI transactions **through `@cosyte/x12`'s domain builders**, so every interchange is
|
|
149
|
+
spec-clean by construction — it round-trips through `@cosyte/x12` with **zero warnings**, is
|
|
150
|
+
byte-stable, seed-deterministic, and synthetic by construction:
|
|
151
|
+
- **New generators:** `generate837P` / `generate837I` / `generate837D` (Professional / Institutional /
|
|
152
|
+
Dental claims via `build837P/I/D`), `generate835` (Health Care Claim Payment/Advice via `build835`,
|
|
153
|
+
**balance-checked by construction** — line, claim, and remit balance identities are satisfied before
|
|
154
|
+
the builder is called), and `generate271` (Health Care Eligibility Benefit Response via `build271`).
|
|
155
|
+
A shared `generate837(variant, …)` selects the claim variant. The builder computes the HL spine and
|
|
156
|
+
the ISA/GS/ST…SE/GE/IEA envelope + control numbers, so `synth` never hand-writes a byte.
|
|
157
|
+
- **`x12Corpus`** builds a reproducible mixed corpus (one of each of 837P/I/D + 835 + 271 by default);
|
|
158
|
+
`roundTrip` is the X12 round-trip-through-the-parser harness (serialize → parse → serialize, judged
|
|
159
|
+
by the parser). `x12Person` / `x12Organization` / `x12ProviderPerson` / `x12Payer` /
|
|
160
|
+
`x12TradingPartners` / `x12EnvelopeTiming` mint the synthetic identity; `dec` / `money` are the
|
|
161
|
+
shared `X12Decimal` money helpers.
|
|
162
|
+
- **Synthetic-safety is the hardest-attacked invariant here** (an 837/271 is identity-dense). New
|
|
163
|
+
provider **`safe.npi`** emits a 10-digit NPI with a **deliberately-invalid Luhn check digit** — a real
|
|
164
|
+
NPI must satisfy the CMS `80840`-prefixed Luhn check, so a `synth` NPI can **never** be a NPPES-issued
|
|
165
|
+
provider (new `isSyntheticNpi` / `npiCheckDigit` / `luhnMod10` + `NPI_LUHN_PREFIX`). Provider tax ids
|
|
166
|
+
are SSA never-issued (900-range) SSNs at `REF*SY`; member ids are synthetic-assigning-authority
|
|
167
|
+
scoped; person names are from the shipped fake-name pool; DOBs/dates come from the seeded generator.
|
|
168
|
+
- The repo **`phi-scan` gains X12-aware structured detection** (NM1 person names + member ids + NPIs,
|
|
169
|
+
PER contact names + phones, `REF*SY` provider SSNs, and a hard refusal of `NM1*34` raw SSNs). A
|
|
170
|
+
Luhn-**valid** XX-qualified NPI is a hard hit — it could denote a real provider. Seed-determinism and
|
|
171
|
+
synthetic-safety property suites (120-seed sweeps) + committed `.edi` golden fixtures added.
|
|
172
|
+
- **`@cosyte/x12` vendored as an optional peer dep** (`file:vendor/cosyte-x12-0.0.1.tgz`), lazily loaded
|
|
173
|
+
per format — importing the package root never pulls it; third-party runtime deps stay at zero.
|
|
174
|
+
- **Deferred:** the **270** eligibility _request_ (`@cosyte/x12` ships `build271` but no `build270`, and
|
|
175
|
+
`synth` never hand-writes bytes around a missing builder — coverage tracks the builder); vendor-quirk
|
|
176
|
+
mode remains Phase 7 / SYNTH-7.
|
|
177
|
+
- **Phase 6 / NCPDP — spec-clean SCRIPT + Telecom generation (SYNTH-7).** A new `@cosyte/synth/ncpdp`
|
|
178
|
+
subpath generating both NCPDP standards **through `@cosyte/ncpdp`'s own emit surface**, so every
|
|
179
|
+
message is spec-clean by construction — it round-trips through the parser with **zero warnings**, is
|
|
180
|
+
byte-stable, seed-deterministic, and synthetic by construction:
|
|
181
|
+
- **New SCRIPT (XML ePrescribing) generators:** `generateNewRx` (via the validated `buildNewRx`
|
|
182
|
+
builder) and `generateRxRenewalRequest` / `generateRxChangeRequest` (built as `@cosyte/ncpdp`'s
|
|
183
|
+
**public typed `ScriptMessage` model** + `serializeScript` — the same typed-model→serializer path
|
|
184
|
+
the X12 arm uses, never a hand-written byte). Each round-trips through `parseScript` cleanly.
|
|
185
|
+
- **New Telecom (vD.0 pharmacy claim) generators:** `generateB1` (billing), `generateB2` (reversal),
|
|
186
|
+
and `generateB3` (rebill) via `buildTelecomRequest` + `serializeTelecom` — the fixed Transaction
|
|
187
|
+
Header, the FS/GS/RS framing, and every field id are the parser's own emit. A shared
|
|
188
|
+
`generateTelecom(code, …)` selects the transaction.
|
|
189
|
+
- **`ncpdpCorpus`** builds a reproducible mixed corpus (one of each of NewRx + RxRenewalRequest +
|
|
190
|
+
RxChangeRequest + B1 + B2 + B3 by default); `scriptRoundTrip` / `telecomRoundTrip` are the NCPDP
|
|
191
|
+
round-trip-through-the-parser harnesses. `ncpdpPatient` / `ncpdpPrescriber` / `ncpdpPharmacy` /
|
|
192
|
+
`ncpdpCardholder` / `ncpdpScriptRouting` mint the synthetic identity; a small license-clean
|
|
193
|
+
example-drug pool (`EXAMPLE_DRUGS`, invented `00000`-labeler NDCs) supplies drug content — **no
|
|
194
|
+
NCPDP-copyrighted text is bundled**.
|
|
195
|
+
- **Synthetic-safety carries a new identity locus X12 did not have — the prescriber DEA.** New
|
|
196
|
+
provider **`safe.dea`** emits a `XX`+7-digit DEA number with a **deliberately-invalid checksum** — a
|
|
197
|
+
real DEA number's 7th digit satisfies the published `(d1+d3+d5)+2·(d2+d4+d6)` checksum, so a `synth`
|
|
198
|
+
DEA can **never** be a validly-issued registration (new `isSyntheticDea` / `deaCheckDigit` +
|
|
199
|
+
`DEA_REGISTRANT_TYPES`). Prescriber NPIs remain invalid-Luhn; patient / cardholder / member ids are
|
|
200
|
+
synthetic-assigning-authority scoped (`MBR`-prefixed); names from the fake-name pool; DOBs and dates
|
|
201
|
+
(including SCRIPT `SentTime`) from the seeded generator (never wall-clock).
|
|
202
|
+
- The repo **`phi-scan` gains an NCPDP arm** — SCRIPT (`<FirstName>`/`<LastName>`/`<MiddleName>`
|
|
203
|
+
names, `<NPI>` Luhn, `<DEANumber>` checksum) and Telecom (field-id-keyed CA/CB/CC/CD names, CQ
|
|
204
|
+
phone, CY/C2 ids, DB prescriber NPI). A Luhn-**valid** NPI or a checksum-**valid** DEA is a hard hit
|
|
205
|
+
— it could denote a real provider. Seed-determinism + synthetic-safety property suites (120-seed
|
|
206
|
+
sweeps) and committed `.xml` (SCRIPT) + `.ncpdp` (Telecom) golden fixtures added.
|
|
207
|
+
- **`@cosyte/ncpdp` vendored as an optional peer dep** (`file:vendor/cosyte-ncpdp-0.0.1.tgz`), lazily
|
|
208
|
+
loaded per format — importing the package root never pulls it; third-party runtime deps stay at zero.
|
|
209
|
+
- **Deferred:** SCRIPT coverage tracks the parser's builder surface — the renewal/change **responses**
|
|
210
|
+
and other lifecycle transactions land as `@cosyte/ncpdp` grows its builders (`synth` never
|
|
211
|
+
hand-writes bytes around a missing builder). Vendor-quirk mode remains Phase 7.
|
|
212
|
+
- **Phase 6 / ASTM — spec-clean E1394 + E1381 generation (SYNTH-8).** A new `@cosyte/synth/astm` subpath
|
|
213
|
+
generating ASTM/CLSI-LIS laboratory messages **through `@cosyte/astm`'s own emit surface**, so every
|
|
214
|
+
message is spec-clean by construction — it round-trips through the parser with **zero warnings**, is
|
|
215
|
+
byte-stable, seed-deterministic, and synthetic by construction. This **completes the spec-clean
|
|
216
|
+
generation core across all six formats** (ASTM was gated on `@cosyte/astm`'s serializer/builder,
|
|
217
|
+
`ASTM-7`, now shipped):
|
|
218
|
+
- **New record generators (E1394):** `generateAstmResult` (a full `H`/`P`/`O`/`R`…/`C`/`L` result
|
|
219
|
+
report) and `generateAstmOrder` (`H`/`P`/`O`/`L`), built through `buildAstmMessage` — the `H|\^&`
|
|
220
|
+
delimiter declaration, record type letters, per-type sequence counters, and `L` terminator are the
|
|
221
|
+
parser's own conservative emit, never a hand-written byte. Each round-trips through
|
|
222
|
+
`parseAstmRecords` cleanly and re-serializes byte-identically.
|
|
223
|
+
- **New framing generator (E1381):** `generateAstmResultFramed` frames the same records via
|
|
224
|
+
`composeAstmFrames` into `<STX> FN text <ETB|ETX> CS <CR><LF>` — the **modulo-256 checksum and the
|
|
225
|
+
`0`–`7` frame number are computed by `@cosyte/astm`, never faked** — round-tripping through
|
|
226
|
+
`parseFramedAstm` with **zero frame and zero record warnings**.
|
|
227
|
+
- **`astmCorpus`** builds a reproducible mixed corpus (a result report + an order by default);
|
|
228
|
+
`astmRoundTrip` / `astmFramedRoundTrip` are the ASTM round-trip-through-the-parser harnesses.
|
|
229
|
+
`astmPatient` / `astmOrder` / `astmHeaderIdentity` mint the synthetic identity; a small license-clean
|
|
230
|
+
`EXAMPLE_ASTM_TESTS` pool (public LOINC codes + invented local analyzer codes) supplies test content
|
|
231
|
+
— **no terminology prose is bundled**.
|
|
232
|
+
- **Synthetic-safety at ASTM's PHI-dense `P` (patient) record:** the patient name comes from the
|
|
233
|
+
shipped fake-name pool, the birthdate is seeded (never wall-clock), and the **practice-assigned**
|
|
234
|
+
and **laboratory-assigned** patient IDs are minted **independently** under the synthetic assigning
|
|
235
|
+
authority (`PRA` / `LAB`-prefixed) so they stay **distinct** — exactly as `@cosyte/astm` keeps them
|
|
236
|
+
distinct on parse. The order accession is `ACC`-prefixed synthetic.
|
|
237
|
+
- The repo **`phi-scan` gains an ASTM arm** — the `P`-record name (field 6, `Last^First^Middle`) and
|
|
238
|
+
the practice/lab patient IDs (fields 3/4), tolerating an E1381 frame prefix so a framed fixture is
|
|
239
|
+
swept identically to a bare record stream. A name not declared synthetic, or a patient ID not
|
|
240
|
+
recognized as synthetic-AA-scoped, is a hard hit. Seed-determinism + synthetic-safety + spec-clean
|
|
241
|
+
round-trip property suites (150-seed sweeps, record and framed) and committed `.astm` (record) +
|
|
242
|
+
`.frame` (framed) golden fixtures added.
|
|
243
|
+
- **`@cosyte/astm` vendored as an optional peer dep** (`file:vendor/cosyte-astm-0.0.0.tgz`), lazily
|
|
244
|
+
loaded per format — importing the package root never pulls it; third-party runtime deps stay at zero.
|
|
245
|
+
- **Deferred:** vendor-quirk mode (lowercase ASTM checksums, framing dropped over TCP, and the other
|
|
246
|
+
tolerances `@cosyte/astm`'s profile system advertises, each round-tripping to exactly the intended
|
|
247
|
+
warning) remains Phase 7.
|
|
248
|
+
- **Phase 7 — vendor-quirk generation, the differentiator (SYNTH-9).** Profile-driven **off-spec**
|
|
249
|
+
fixtures whose vocabulary **is the parsers' own profile systems** — a quirk deviates message
|
|
250
|
+
_structure_ so it round-trips to **exactly one intended, stable parser warning** (the
|
|
251
|
+
**intended-warning contract**), and where a **public** built-in parser profile claims the deviation it
|
|
252
|
+
round-trips cleanly under it (suppressed, or re-badged to `PROFILE_QUIRK_APPLIED`). Shipped for the
|
|
253
|
+
three richest profile systems — **HL7 v2, C-CDA, ASTM**:
|
|
254
|
+
- **Format-agnostic quirk core** (`src/quirk.ts`, root subpath): `QuirkDescriptor` / `QuirkArtifact` /
|
|
255
|
+
`QuirkRoundTripResult` / `QuirkProfiledVerdict` / `QuirkProfileDisposition`, `resolveQuirk` (fail-closed
|
|
256
|
+
`SYNTH_UNSUPPORTED_QUIRK`), `sameCodeSet`, `profileTolerated`, `validateProfileQuirks`,
|
|
257
|
+
`assertIntendedWarnings`, and the `PROFILE_QUIRK_APPLIED` marker. Quirks are applied **post-serialize**
|
|
258
|
+
(roadmap §10 Q4: profile tolerance is parse-side) as a deterministic transform of the parser's own
|
|
259
|
+
emit, and every `generate*Quirk` **self-checks the intended-warning contract at generation time**
|
|
260
|
+
(`assertIntendedWarnings`) — a fixture whose bare parse does not produce exactly the declared code is a
|
|
261
|
+
fatal error, never a silently-mislabeled golden file.
|
|
262
|
+
- **HL7 v2** (`@cosyte/synth/hl7`): `generateHl7Quirk` / `hl7QuirkRoundTrip` / `hl7QuirkCorpus` /
|
|
263
|
+
`hl7QuirkProfile` / `HL7_QUIRKS`. `unknown-zsegment` → `UNKNOWN_SEGMENT` (suppressed by the public
|
|
264
|
+
`visage` PACS profile's `ZDS` claim); `unknown-escape` → `UNKNOWN_ESCAPE_SEQUENCE`.
|
|
265
|
+
- **C-CDA** (`@cosyte/synth/ccda`): `generateCcdaQuirk` / `injectCcdaQuirk` / `ccdaQuirkRoundTrip` /
|
|
266
|
+
`ccdaQuirkCorpus` / `ccdaQuirkProfile` / `CCDA_QUIRKS`. `template-extension-absent` →
|
|
267
|
+
`TEMPLATE_EXTENSION_ABSENT` (re-badged by the public `legacyR11` profile); `deprecated-loinc` →
|
|
268
|
+
`DEPRECATED_LOINC` and `deprecated-code-system` → `DEPRECATED_CODE_SYSTEM` (re-badged by the public
|
|
269
|
+
`smartScorecard` profile). Structural (seed-robust) XML anchors that hold for **every generable
|
|
270
|
+
document type** (CCD **and** Referral Note — the `template-extension-absent` quirk drops the R2.1
|
|
271
|
+
stamp on each document-type template root).
|
|
272
|
+
- **ASTM** (`@cosyte/synth/astm`): `generateAstmQuirk` / `astmQuirkRoundTrip` / `astmQuirkCorpus` /
|
|
273
|
+
`astmQuirkProfile` / `ASTM_QUIRKS`. `unknown-escape` → `ASTM_UNKNOWN_ESCAPE_SEQUENCE` (re-badged by the
|
|
274
|
+
public `referenceCorpus` OSS profile); `unknown-record-type` → `ASTM_RECORD_UNKNOWN_TYPE`.
|
|
275
|
+
- **Synthetic-safety holds in quirk mode** — a quirk changes shape, never provenance, so the `phi-scan`
|
|
276
|
+
gate stays zero over quirk output (proven by scanner tests + committed quirk fixtures under
|
|
277
|
+
`test/fixtures/{hl7,ccda,astm}/quirk/`). Mandatory property suites: intended-warning (every quirk ×
|
|
278
|
+
seed × kind → exactly the intended code), seed-determinism (byte-identical), synthetic-safety.
|
|
279
|
+
- **Grounding:** every quirk is **publicly grounded** (ADR 0018 — a published IG, a vendor interface
|
|
280
|
+
spec, or a redistributable OSS corpus), never a private vendor corpus. **Deferred:** quirk recipes for
|
|
281
|
+
**FHIR / X12 / NCPDP**, and any quirk that would need a private, vendor-attributed corpus
|
|
282
|
+
(`REAL-CORPUS`-gated). New `@cosyte/synth/ccda` export `injectCcdaQuirk`; a new **quirk guide** in
|
|
283
|
+
`docs-content/`.
|
|
284
|
+
- **Phase 8 — the `@cosyte/deid` pairing loop (SYNTH-10).** A new `@cosyte/synth/deid` subpath — a
|
|
285
|
+
deterministic, seeded **closed-loop co-validation harness** for the `synth` ⇄ `deid` pair: **generate**
|
|
286
|
+
a spec-clean synthetic artifact → **enumerate** the distinctive synthetic PHI sentinels `synth` planted
|
|
287
|
+
at its patient loci → **de-identify** through `@cosyte/deid` → **verify** every sentinel is gone from
|
|
288
|
+
the de-identified output (a surviving sentinel is a hard failure) **and** that the clinical payload
|
|
289
|
+
survives (the over-scrub guard). It consumes the shipped generators unchanged — a harness capability,
|
|
290
|
+
not a generator change.
|
|
291
|
+
- **Per-format loops:** `hl7DeidLoop` (ADT/ORU/ORM/SIU/VXU), `fhirDeidLoop` (a US-Core `Bundle`, so
|
|
292
|
+
there is clinical content to prove is not over-scrubbed), `x12DeidLoop` (837P/837I/837D/271/835),
|
|
293
|
+
`ncpdpTelecomDeidLoop` (B1/B2/B3), and `ccdaDeidLoop` (CCD + Referral Note). Each returns an immutable
|
|
294
|
+
`DeidLoopResult` (`planted` / `survivors` / `clinicalProbed` / `clinicalScrubbed` / `pass`).
|
|
295
|
+
- **Removal check, locus-scoped and collision-proof.** Sentinels are enumerated from the patient PHI
|
|
296
|
+
loci — via `@cosyte/deid`'s own extractors for HL7/FHIR/X12/NCPDP, and a `<recordTarget>`-scoped scan
|
|
297
|
+
for C-CDA — then decomposed to **literal, distinctive** synthetic tokens (`identifierSentinels`,
|
|
298
|
+
`recordTargetSentinels`). Removal is verified by sweeping only the **de-identified values that remain
|
|
299
|
+
at those former PHI loci** (`sweepSurvivors`), re-read from the de-identifier's own output — so
|
|
300
|
+
provider/organization identity a de-identifier legitimately retains (drawn from the same synthetic
|
|
301
|
+
pools) never reads as a false survivor.
|
|
302
|
+
- **Removal-oriented policy** (`deidLoopPolicy`, `DEID_LOOP_POLICY_NAME`): HIPAA Safe Harbor with the
|
|
303
|
+
keyed-by-default identifier categories (MRN / beneficiary / account) switched to `redact`, so the loop
|
|
304
|
+
needs **no key context** and is a pure function of the seed.
|
|
305
|
+
- **Over-scrub guard** (`clinicalRetention`): distinctive (≥ 4-char) structured clinical codes present
|
|
306
|
+
before de-identification must survive after — short codes are not probed (they collide inside removed
|
|
307
|
+
PHI). Plus a `summarizeDeidCoverage` per-format coverage report.
|
|
308
|
+
- **Honest scope (roadmap §Phase 8, §7):** this is a **co-validation harness**, not an independent audit
|
|
309
|
+
of `@cosyte/deid` against real-world data — it proves the pair works on `synth`'s own output; a
|
|
310
|
+
sentinel `deid` **blocks** rather than redacts still passes (blocked = gone). Covers the five formats
|
|
311
|
+
both packages support; **NCPDP SCRIPT** and **ASTM** (no `@cosyte/deid` adapter) and **DICOM** (not
|
|
312
|
+
generated by `synth`) are **skipped and named** (`DEID_LOOP_SKIPPED`), never silently.
|
|
313
|
+
- `@cosyte/deid` is an **optional peer dependency**, vendored for dev/test via the `mllp`/`ncpdp`
|
|
314
|
+
pattern (`vendor/cosyte-deid-0.0.0.tgz`); **third-party runtime deps stay at 0**. Property suites:
|
|
315
|
+
seed-determinism (byte-identical artifact + de-identified output + sentinels), removal (0 survivors
|
|
316
|
+
across every format × seed), over-scrub (0 clinical loss), non-vacuity (the loop genuinely fails when
|
|
317
|
+
a sentinel survives — proven by tampering), and synthetic-safety of every planted sentinel.
|
|
318
|
+
**Deferred:** NCPDP SCRIPT / ASTM / DICOM pairing (blocked on `@cosyte/deid` adapters), optional
|
|
319
|
+
Synthea clinical-content ingestion (roadmap §Phase 8 — documented future concern), and SYNTH-11
|
|
320
|
+
release hardening.
|
|
321
|
+
- **Phase 9 — release hardening (SYNTH-11), the final roadmap phase.** No new runtime API; this phase
|
|
322
|
+
is the property/fuzz suite, coverage, publish dry-run, and honesty docs that make the package
|
|
323
|
+
release-shaped. The generator is feature-complete across all six formats.
|
|
324
|
+
- **Consolidated conformance property suite** (`test/property/all-formats.property.test.ts`) — every
|
|
325
|
+
one of the six spec-clean format generators is driven through the **same three mandatory
|
|
326
|
+
properties** (round-trip spec-clean · seed-determinism · synthetic-safety) so no format can silently
|
|
327
|
+
ship without one; plus an **intended-warning** arm proving each quirk corpus (HL7 v2 / C-CDA / ASTM)
|
|
328
|
+
is non-vacuous and stays synthetic-safe. Non-vacuity is asserted directly (the registry is proved to
|
|
329
|
+
cover every `SynthFormat`; every corpus is proved non-empty with non-trivial content).
|
|
330
|
+
- **Seed-sweep generation fuzz** (`test/property/seed-sweep.fuzz.property.test.ts`, the inverted fuzz
|
|
331
|
+
of roadmap §6) — sweeps seed × count × format across the six spec-clean corpora and the three quirk
|
|
332
|
+
corpora, asserting generation is **total**: it never throws outside the sanctioned `SYNTH_FATAL_CODES`
|
|
333
|
+
set, never hangs, and every output still passes the round-trip + synthetic-safety gates. Scales via
|
|
334
|
+
`SYNTH_FUZZ_RUNS`; new `test:fuzz` script + a nightly `Fuzz` workflow (`.github/workflows/fuzz.yml`).
|
|
335
|
+
- **Dual ESM/CJS release-shape smoke** (`scripts/smoke.mjs`, new `smoke` script, run by `verify.sh`) —
|
|
336
|
+
for **every published subpath** (`.`/`hl7`/`fhir`/`ccda`/`x12`/`ncpdp`/`astm`/`deid`) it imports the
|
|
337
|
+
ESM entry and requires the CJS entry from `dist/`, generates synthetic output through each, and
|
|
338
|
+
asserts ESM/CJS agree byte-for-byte for the same seed — catching a broken dual build a source-only
|
|
339
|
+
suite would not.
|
|
340
|
+
- **Publish dry-run proven:** `attw` green (per-condition types across all eight subpaths) and an
|
|
341
|
+
`npm publish --dry-run` clean 58-file tarball carrying every subpath's `.d.ts`/`.mjs`/`.cjs` plus
|
|
342
|
+
`README`/`LICENSE`/`CHANGELOG`. Per-dir **≥90 coverage** continues to gate.
|
|
343
|
+
- **Honesty docs** — `docs-content/limitations.md` (registered in the sidebar and gated by the
|
|
344
|
+
doc/code-agreement runner) leads with the governing sentence (_format/conformance generator, not a
|
|
345
|
+
clinical simulator; synthetic-by-construction; deterministic per seed within a version window; no
|
|
346
|
+
bundled terminology; no DICOM in v1_) and states the full **synthetic-safety posture** (the
|
|
347
|
+
900-range SSN, invalid-Luhn NPI, invalid-checksum DEA, `555-01xx` phone, `example.*` domain,
|
|
348
|
+
TEST-NET IP, and synthetic-assigning-authority MRN floors), the structural-not-clinical / not-Synthea
|
|
349
|
+
scoping, and the deferred surfaces (FHIR/X12/NCPDP quirks, NCPDP SCRIPT responses, X12 270 request,
|
|
350
|
+
DICOM, Synthea ingestion). **Founder-gated tail (not crossed):** the actual `npm publish` and the
|
|
351
|
+
repo public-flip remain the two standing human stops.
|
|
352
|
+
- `VERSION` export.
|
|
353
|
+
- **Public-surface gate: `scripts/check-no-internal-refs.sh` + `pnpm check:no-internal-refs` + the
|
|
354
|
+
`no-internal-refs` workflow.** Ported from `hl7`'s reference implementation via `ncpdp`'s copy (which
|
|
355
|
+
added the fourth pass), keeping the cross-repo parts verbatim: the prefix list, the paragraph-join
|
|
356
|
+
second pass, the doc-comment third pass, the string-literal fourth pass, the silent-green route
|
|
357
|
+
closures and the NEGATIVE self-tests. Four passes: the public markdown + npm metadata, the same rules
|
|
358
|
+
over paragraph-joined text (so a violation straddling a line wrap cannot hide), `src/` doc comments,
|
|
359
|
+
and `src/` string literals. It self-tests both directions on every run and refuses to print OK from a
|
|
360
|
+
scan that did not read all of its input.
|
|
361
|
+
Two deliberate divergences from the sibling copies, both recorded in the script header:
|
|
362
|
+
**`SYNTH` is in the prefix list here and absent from `ncpdp`'s** (it is this repo's own item prefix,
|
|
363
|
+
and was the whole of the identifier backlog), with the collision it creates handled by an explicit
|
|
364
|
+
`SYNTHETIC_FIXTURE_TOKEN` exclusion for the three provenance markers this package stamps into
|
|
365
|
+
generated output (`SYNTH-FAC`, `SYNTH-LIS`, `SYNTH-ANALYZER`) rather than by dropping the prefix; and
|
|
366
|
+
**rule 5 gained a `roadmap §` arm**, the same widening `ncpdp` made to rule 3 for ADR paths, because
|
|
367
|
+
this repo cites its roadmap by section and 169 such citations were structurally invisible without it.
|
|
368
|
+
Both widenings carry their own standalone self-test so a later "resync with a sibling copy" reds
|
|
369
|
+
instead of silently reopening the hole. `CHANGELOG.md` is excluded on purpose, as in every sibling
|
|
370
|
+
copy: it ships inside the npm tarball, yet the same convention names it as a place identifiers
|
|
371
|
+
belong. That contradiction is ecosystem-wide and is recorded, not decided here.
|
|
372
|
+
|
|
373
|
+
### Changed
|
|
374
|
+
|
|
375
|
+
- Replaced the parser-archetype scaffold stubs (`parseSynth`, `WARNING_CODES`, `FATAL_CODES`) with the
|
|
376
|
+
generator surface — `@cosyte/synth` is a synthetic-fixture **generator**, not a parser.
|
|
377
|
+
- **Docs:** refreshed the `README.md` status block to describe the **feature-complete** generator surface
|
|
378
|
+
(all six spec-clean formats + quirk mode for HL7 v2/C-CDA/ASTM + the `@cosyte/deid` pairing loop) with
|
|
379
|
+
its honest deferrals, replacing the stale forward-looking Phase 1–7 roadmap narrative. Status remains
|
|
380
|
+
pre-alpha (`0.0.x`), not yet published to npm.
|
|
381
|
+
- **PUBLIC-SURFACE-HYGIENE (founder directive, 2026-07-27): no internal project bookkeeping on a public
|
|
382
|
+
surface.** Swept every surface a consumer reads — `README.md`, `docs-content/`, the npm `description`
|
|
383
|
+
and `keywords`, the `src/` JSDoc that compiles into `dist/*.d.ts` and renders on hover, and the `src/`
|
|
384
|
+
string literals this package emits into what it generates. Measured on the base commit `cdfcdd9` by
|
|
385
|
+
running the gate exactly as it ships, with its refusal suppressed so every pass reports rather than
|
|
386
|
+
stopping at the first: **21 rows over 19 distinct locations on the public markdown and npm metadata**;
|
|
387
|
+
**416 rows over 227 distinct lines in `src/` doc comments** (288 found line by line, 128 more found
|
|
388
|
+
only by the paragraph-reflow pass); **1 in `src/` string literals**, with a second found by hand that
|
|
389
|
+
no rule here can see; and **562 rows over 442 distinct lines in the built declaration files**, 281
|
|
390
|
+
rows per module condition. All
|
|
391
|
+
are now zero. The backlog recorded "11+6"; a count is a function of the rule set, so these were taken
|
|
392
|
+
with the final one and are quoted with the tree they were taken on. Item identifiers (`SYNTH-4`),
|
|
393
|
+
`Phase N` language, ADR numbers, meta-repo paths and `roadmap §N` citations are gone from those
|
|
394
|
+
surfaces; they remain where the convention puts them — the changeset, this file, the commit, the PR
|
|
395
|
+
and the roadmap.
|
|
396
|
+
- **Stale deferral claims deleted rather than reworded.** `src/ccda/index.ts` and `src/astm/index.ts`
|
|
397
|
+
each documented quirk generation as still to come, lines above the export that ships it;
|
|
398
|
+
`src/ncpdp/index.ts` and `docs-content/guides-ncpdp.md` said ASTM generation was not yet shipped when
|
|
399
|
+
the ASTM subpath ships. Stripping the phase number would have left
|
|
400
|
+
a false claim standing in cleaner clothes, so the sentences were cut.
|
|
401
|
+
- **`DEID_LOOP_SKIPPED[].reason` text changed for the `ncpdp-script` and `dicom` entries.** The reasons
|
|
402
|
+
are unchanged in substance; the internal citation trailing each was removed. These strings are part of
|
|
403
|
+
a frozen exported constant, so a consumer asserting them verbatim is affected. The `format` values and
|
|
404
|
+
the shape of the constant are unchanged, and no generated byte changes.
|
|
405
|
+
|
|
406
|
+
### Deprecated
|
|
407
|
+
|
|
408
|
+
### Removed
|
|
409
|
+
|
|
410
|
+
### Fixed
|
|
411
|
+
|
|
412
|
+
### Security
|
|
413
|
+
|
|
414
|
+
[Unreleased]: https://github.com/cosyte/synth/commits/main
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Cosyte
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|