@cosyte/synth 0.0.1 → 0.0.3
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 +130 -0
- package/README.md +7 -2
- package/package.json +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -14,6 +14,13 @@ its public history at `0.0.x`, per the cosyte version ladder (`0.0.x` until firs
|
|
|
14
14
|
|
|
15
15
|
### Added
|
|
16
16
|
|
|
17
|
+
- **A brand image at the top of `README.md`.** The page opens with the Cosyte lockup, served as a
|
|
18
|
+
`<picture>` with a light and a dark source so it follows the reader's theme, and carrying alt text
|
|
19
|
+
that describes the mark for anyone reading with images off or a screen reader on. The block is
|
|
20
|
+
copied byte for byte out of the `hl7` README, which is the reference the suite mirrors, so the
|
|
21
|
+
repos that carry it stay one string rather than drifting into as many hand-typed variants. The
|
|
22
|
+
first 353 bytes of this README are now byte-identical to that file's, with the first divergence
|
|
23
|
+
inside the H1.
|
|
17
24
|
- Project scaffold from the shared `@cosyte/*` parser template: the canonical toolchain (TypeScript
|
|
18
25
|
ES2023 + strict rigor via `@cosyte/tsconfig`, ESLint 10 + type-checked `typescript-eslint` via
|
|
19
26
|
`@cosyte/eslint-config`, Prettier via `@cosyte/prettier-config`, Vitest 4 + v8 coverage via
|
|
@@ -369,6 +376,87 @@ its public history at `0.0.x`, per the cosyte version ladder (`0.0.x` until firs
|
|
|
369
376
|
instead of silently reopening the hole. `CHANGELOG.md` is excluded on purpose, as in every sibling
|
|
370
377
|
copy: it ships inside the npm tarball, yet the same convention names it as a place identifiers
|
|
371
378
|
belong. That contradiction is ecosystem-wide and is recorded, not decided here.
|
|
379
|
+
- **CI-REQUIRED-CHECKS: a gate on what the required test job SELECTS, not just that it ran.**
|
|
380
|
+
`scripts/check-test-selection.ts` (`pnpm check:test-selection`, also reached by `pnpm check`) plus
|
|
381
|
+
`.github/workflows/test-selection.yml` (job id, and therefore future check-run context,
|
|
382
|
+
`test-selection`). It compares the tracked test files that EXIST against the files
|
|
383
|
+
`vitest list --filesOnly` says vitest would RUN, and reds on any shortfall in its subject. Ported
|
|
384
|
+
in shape from `ncpdp` `27f9e89`; the **invocation rule ports verbatim** (this repo's `test` /
|
|
385
|
+
`test:coverage` bodies are spelled identically, confirmed before reuse, so
|
|
386
|
+
`ALLOWED_TEST_SCRIPT_BODIES` is the same closed exact-match set rather than a re-derivation), and
|
|
387
|
+
the **derived subjects are re-derived here**, because `ncpdp`'s ground its fuzz subject in a
|
|
388
|
+
workflow that hands a path straight to `vitest run` and **no workflow in this repo contains that
|
|
389
|
+
string at all** (ported verbatim it refuses). Three subjects instead:
|
|
390
|
+
1. **The published surface**, from `package.json` `exports`. Each of the eight subpaths resolves to
|
|
391
|
+
a `dist/[<dir>/]index.<ext>` emitted from `src/[<dir>/]index.ts`; every tracked module under
|
|
392
|
+
scope naming one of those entry points must be selected, and every entry point must have at
|
|
393
|
+
least one selected module naming it. Keyed on a **resolved module path**, not a filename and not
|
|
394
|
+
a bare substring, so a rename moves nothing out of the subject; scope is a **deny-list** of
|
|
395
|
+
`src/`, `scripts/` and the repo root, so a move anywhere else does not either. **This is the
|
|
396
|
+
rule that reaches the synthetic-safety property layer**, which was named by nothing.
|
|
397
|
+
**The scope was an allow-list (`test/`) in the first version and the refuter broke it**:
|
|
398
|
+
relocating all six `synthetic-safety.property.test.ts` files into `internal/` took the whole
|
|
399
|
+
safety layer out of CI, `vitest list` selected zero of them, and the gate printed OK exit 0.
|
|
400
|
+
A move into one of the three denied locations still escapes and is stated in three places
|
|
401
|
+
rather than denied.
|
|
402
|
+
2. **The fuzz path**, derived in two steps because that is how this repo spells it: the nightly
|
|
403
|
+
`Fuzz` workflow runs `pnpm test:fuzz`, whose body is a `vitest run <path>`. Redundant today
|
|
404
|
+
(that module also imports a published entry) and kept for its empty-set refusal, which is a
|
|
405
|
+
tripwire on the fuzz job disappearing **only if no other literal path is left behind anywhere in
|
|
406
|
+
a workflow**. The extraction is text and cannot tell a real `run:` from prose quoting one, so a
|
|
407
|
+
commented `vitest run test/hl7` suppresses the refusal; calling it unconditional would overstate
|
|
408
|
+
it.
|
|
409
|
+
3. **The PHI scanner**, ported directly (`phi-scan` script plus `run-phi-scan: true` in `ci.yml`).
|
|
410
|
+
|
|
411
|
+
It prints a **denominator** on every run instead of a bare OK: of 39 tracked in-scope code modules,
|
|
412
|
+
**38 are watched by a name-independent rule, 1 by the `.test.`/`.spec.` filename shape alone
|
|
413
|
+
(`test/docs-content.test.ts`), and 0 by no rule at all**. The like-for-like figure in `ncpdp` is **4
|
|
414
|
+
of 27** in-scope modules; its own header quotes "4 of 24", counting only name-shaped files, which
|
|
415
|
+
flatters the ratio. Cite the comparable number, not the friendlier one.
|
|
416
|
+
Three self-tests re-prove it on every run, one resolving a genuinely narrowed config through real
|
|
417
|
+
vitest; **self-test A ignores the filename floor and requires a DERIVED rule to name each dropped
|
|
418
|
+
file**. Both A's drop targets one at a time, so the colliding direction is exercised in each; the
|
|
419
|
+
single difference is that `ncpdp`'s verdict counts the filename floor, which is why that one passed
|
|
420
|
+
with its derived rules neutered. (An earlier draft of this entry said `ncpdp`'s A "does not do" the
|
|
421
|
+
one-at-a-time part; a refuter corrected it, and A is not the backstop for the derived rules in either
|
|
422
|
+
repo, because emptying a subject empties A's targets with it. Self-test C is.)
|
|
423
|
+
**`test-selection` is deliberately NOT added to ruleset `19913330`**: a required context no
|
|
424
|
+
workflow has emitted on `main` leaves every future PR pending and unmergeable. Wire first, require
|
|
425
|
+
later.
|
|
426
|
+
|
|
427
|
+
**Every quantity above is re-derivable, not asserted.** The script header lists the command that
|
|
428
|
+
produces each one, because two of the three refuter passes found a false number or a false claim of
|
|
429
|
+
reach rather than a hole in the mechanism, both times from a sentence ported out of a sibling repo
|
|
430
|
+
and never re-measured here. All of them were re-measured against this repo, on the tree that ships.
|
|
431
|
+
|
|
432
|
+
Demonstrated red by seeding, one route at a time: a narrowed `include`; an `exclude` targeting
|
|
433
|
+
`**/synthetic-safety.property.test.ts`; an `exclude` dropping `test/property/`; positional filters
|
|
434
|
+
written both `vitest run <p>` and `vitest --run <p>`; `--shard=`, `--config=`; a body naming no
|
|
435
|
+
vitest at all (`pnpm run test:unit`, `node node_modules/vitest/vitest.mjs run`) **and a delegation
|
|
436
|
+
to this repo's own narrowing script, `pnpm run test:fuzz`**; renaming a safety suite to `.ts`,
|
|
437
|
+
`.spec.ts` and `_safety.ts`; **the colliding renames that were measured GREEN on `ncpdp`'s earlier
|
|
438
|
+
versions** (`_helpers.ts`, `test/_helpers/load-fixture.ts`, `test/_x/parse.ts`, and the cross-format
|
|
439
|
+
safety suite moved into `test/_helpers/fuzz-config.ts`); the PHI suite renamed to
|
|
440
|
+
`phi-scan-suite.ts`; the fuzz subject renamed out of shape; `run-phi-scan: false`; and
|
|
441
|
+
un-exporting `./astm` together with a narrowed include. Deleting the `Fuzz` workflow, deleting the
|
|
442
|
+
`test:fuzz` script, or deleting the `exports` map each make it **REFUSE to report** rather than pass
|
|
443
|
+
vacuously.
|
|
444
|
+
|
|
445
|
+
Red after the refuter pass, having been **green before it**: any suite relocated out of `test/`
|
|
446
|
+
(one safety suite, then all six at once, then the PHI suite, each into `internal/`), and a suite
|
|
447
|
+
renamed to `_safety.ts` whose import specifiers were rewritten to unicode escapes so the raw text
|
|
448
|
+
no longer looked like the path while the imports still resolved.
|
|
449
|
+
|
|
450
|
+
Green and stated as limits rather than denied: a config branching on `process.argv` (**2 of 39**
|
|
451
|
+
suites would have run); un-exporting `./astm` alone (**2** `test/astm` suites drop to the filename
|
|
452
|
+
floor, denominator 38 to 36); a suite moved into `src/`, `scripts/` or the repo root; and renaming
|
|
453
|
+
`test/docs-content.test.ts` out of shape.
|
|
454
|
+
|
|
455
|
+
- **The dual ESM/CJS release smoke now runs in a job.** `.github/workflows/smoke.yml` (job id `smoke`,
|
|
456
|
+
matrix contexts `smoke (22)` / `smoke (24)`), with `build` and `smoke` as steps of **one** job so a
|
|
457
|
+
future required context covers both. Same wiring `deid` used for the same defect, which is what
|
|
458
|
+
makes this a class rather than an incident. These contexts are also deliberately **not** added to
|
|
459
|
+
the ruleset yet.
|
|
372
460
|
|
|
373
461
|
### Changed
|
|
374
462
|
|
|
@@ -409,6 +497,48 @@ its public history at `0.0.x`, per the cosyte version ladder (`0.0.x` until firs
|
|
|
409
497
|
|
|
410
498
|
### Fixed
|
|
411
499
|
|
|
500
|
+
- **`README.md` said the package was not published to npm. It is.** The summary blockquote opened
|
|
501
|
+
with "pre-alpha (`0.0.x`), not yet published to npm", so the npm package page asserted that the
|
|
502
|
+
package did not exist on npm, directly under the version npm renders in its own header. A reader
|
|
503
|
+
could not tell which half was current. The line now says the package is published and points at
|
|
504
|
+
the npm package page for the version that is live. **No version number is written into the
|
|
505
|
+
correction, deliberately**: the registry is the source of truth, and a number copied onto a page
|
|
506
|
+
is a number that goes stale there (`npm view @cosyte/synth version` is the check).
|
|
507
|
+
- The closing line of the same blockquote, "the two remaining founder gates are the actual
|
|
508
|
+
`npm publish` and the repo public-flip", was **cut rather than reworded**. Both halves are now
|
|
509
|
+
false: the publish happened, and `cosyte/synth` is already a public repository (read back from
|
|
510
|
+
`gh repo view`). Rewording it would have left a measured falsehood standing in cleaner clothes.
|
|
511
|
+
- **Still standing, and deliberately not touched here.** `CLAUDE.md` carries the same "not yet
|
|
512
|
+
published" claim, and the `[Unreleased]` preamble in this file still says the first pre-alpha
|
|
513
|
+
release "will ship" the initial API surface, in the future tense, about a version that shipped.
|
|
514
|
+
Both belong to a cross-repo item spanning eight repos; fixing one repo's copy inside this change
|
|
515
|
+
would fragment it. `docs-content/intro.md` and `docs-content/installation.md` carry the "not yet
|
|
516
|
+
published to npm" claim too, and are left for the same sweep.
|
|
517
|
+
- **`scripts/smoke.mjs` ran in NO CI job.** It only ever ran on the meta-repo's local
|
|
518
|
+
`scripts/verify.sh` ladder, which a contributor is not obliged to run and CI never invokes, so no
|
|
519
|
+
required check covered the eight published subpaths and a green PR said nothing about whether they
|
|
520
|
+
load. Now wired (`.github/workflows/smoke.yml`).
|
|
521
|
+
|
|
522
|
+
**A correction, recorded rather than quietly dropped.** Earlier drafts of this entry and of two
|
|
523
|
+
other surfaces said the file had been _documented as a CI gate_, so that the docs asserted a
|
|
524
|
+
protection nothing provided. **That was false here**, and the third refuter pass caught it: every
|
|
525
|
+
surface describing this file said `run by verify.sh` (this file, `CLAUDE.md`, and the
|
|
526
|
+
release-hardening changeset), and its header said only "Run after `build`". The docs were accurate.
|
|
527
|
+
The sentence was **ported from `deid`, where it is true** (its own changelog records the line that
|
|
528
|
+
claimed CI and never ran), and it was ported without re-measuring it against this repo, which is
|
|
529
|
+
precisely the failure the test-selection gate's header warns about two entries up. The defect is
|
|
530
|
+
real and unchanged; only the indictment of the prior docs was wrong.
|
|
531
|
+
|
|
532
|
+
- **The smoke's subpath set was a hand-written array.** `SUBPATHS` listed the eight subpaths inline,
|
|
533
|
+
so dropping one would have left the gate printing OK over a subset. It is now derived from
|
|
534
|
+
`package.json` `exports` at run time, loads the export targets themselves rather than
|
|
535
|
+
reconstructing `dist/<name>/index.mjs` by hand (so an `exports` entry pointing at a path the build
|
|
536
|
+
does not emit fails here rather than in a consumer's install), and **REFUSES to report** if its
|
|
537
|
+
per-subpath probe map and that `exports` map disagree in either direction. There is no exclusion
|
|
538
|
+
list either: `./package.json` drops out because its target is structurally data, not because a key
|
|
539
|
+
was named. Demonstrated: deleting `"./astm"` from `exports` makes the smoke refuse. That refusal is
|
|
540
|
+
the interlock under `check:test-selection`, whose headline subject is derived from the same map.
|
|
541
|
+
|
|
412
542
|
### Security
|
|
413
543
|
|
|
414
544
|
[Unreleased]: https://github.com/cosyte/synth/commits/main
|
package/README.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
<picture>
|
|
2
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://cosyte.com/tile/cosyte-lockup-tile-on-dark-1200x300.png">
|
|
3
|
+
<img alt="Cosyte: a plus mark set in two overlapping rounded squares, one solid and one outlined, beside the Cosyte wordmark" src="https://cosyte.com/tile/cosyte-lockup-tile-on-light-1200x300.png">
|
|
4
|
+
</picture>
|
|
5
|
+
|
|
1
6
|
# @cosyte/synth
|
|
2
7
|
|
|
3
8
|
> Deterministic, seedable **synthetic healthcare-fixture generator** for Node.js and TypeScript —
|
|
@@ -11,7 +16,8 @@ date, phone, and address from a **guaranteed-non-colliding synthetic source**. I
|
|
|
11
16
|
**format/conformance generator, not a clinical simulator** — it does not model disease progression
|
|
12
17
|
(that is Synthea).
|
|
13
18
|
|
|
14
|
-
> **Status:** pre-alpha (`0.0.x`),
|
|
19
|
+
> **Status:** pre-alpha (`0.0.x`), published to npm. The version shown on the npm package page is the
|
|
20
|
+
> one that is live; this page never repeats it. The generator is **feature-complete**: the
|
|
15
21
|
> seeded-PRNG core, the synthetic-safety providers, and the round-trip harness; **spec-clean generation
|
|
16
22
|
> across all six formats** — HL7 v2 (`ADT`/`ORU`/`ORM`/`SIU`/`VXU`), FHIR R4 / US Core (the full clinical
|
|
17
23
|
> set + `collection`/`transaction`/`document` Bundles), C-CDA R2.1 (CCD + Referral Note), X12 005010
|
|
@@ -26,7 +32,6 @@ date, phone, and address from a **guaranteed-non-colliding synthetic source**. I
|
|
|
26
32
|
> needing a private vendor corpus); the X12 **270** eligibility _request_ and NCPDP SCRIPT lifecycle
|
|
27
33
|
> **responses** (both track the parsers' builder surfaces); **NCPDP SCRIPT / ASTM / DICOM** de-identify
|
|
28
34
|
> pairing (no `@cosyte/deid` adapter, or not generated); and optional **Synthea** clinical-content ingestion.
|
|
29
|
-
> The two remaining founder gates are the actual `npm publish` and the repo public-flip.
|
|
30
35
|
|
|
31
36
|
## Install
|
|
32
37
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosyte/synth",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Deterministic, seedable synthetic healthcare-fixture generator for Node.js and TypeScript — spec-clean by construction, never real PHI.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"synth",
|
|
@@ -191,6 +191,8 @@
|
|
|
191
191
|
"changeset": "changeset",
|
|
192
192
|
"typecheck": "tsc --noEmit",
|
|
193
193
|
"phi-scan": "tsx scripts/phi-scan.ts",
|
|
194
|
+
"check": "pnpm run check:test-selection",
|
|
195
|
+
"check:test-selection": "tsx scripts/check-test-selection.ts",
|
|
194
196
|
"check:no-internal-refs": "bash scripts/check-no-internal-refs.sh",
|
|
195
197
|
"lint": "eslint \"src/**/*.ts\" \"scripts/**/*.ts\" \"test/**/*.ts\" --max-warnings=0 --no-error-on-unmatched-pattern",
|
|
196
198
|
"lint:fix": "eslint \"src/**/*.ts\" \"scripts/**/*.ts\" \"test/**/*.ts\" --fix --no-error-on-unmatched-pattern",
|