@cosyte/synth 0.0.1 → 0.0.2

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.
Files changed (2) hide show
  1. package/CHANGELOG.md +106 -0
  2. package/package.json +3 -1
package/CHANGELOG.md CHANGED
@@ -369,6 +369,87 @@ its public history at `0.0.x`, per the cosyte version ladder (`0.0.x` until firs
369
369
  instead of silently reopening the hole. `CHANGELOG.md` is excluded on purpose, as in every sibling
370
370
  copy: it ships inside the npm tarball, yet the same convention names it as a place identifiers
371
371
  belong. That contradiction is ecosystem-wide and is recorded, not decided here.
372
+ - **CI-REQUIRED-CHECKS: a gate on what the required test job SELECTS, not just that it ran.**
373
+ `scripts/check-test-selection.ts` (`pnpm check:test-selection`, also reached by `pnpm check`) plus
374
+ `.github/workflows/test-selection.yml` (job id, and therefore future check-run context,
375
+ `test-selection`). It compares the tracked test files that EXIST against the files
376
+ `vitest list --filesOnly` says vitest would RUN, and reds on any shortfall in its subject. Ported
377
+ in shape from `ncpdp` `27f9e89`; the **invocation rule ports verbatim** (this repo's `test` /
378
+ `test:coverage` bodies are spelled identically, confirmed before reuse, so
379
+ `ALLOWED_TEST_SCRIPT_BODIES` is the same closed exact-match set rather than a re-derivation), and
380
+ the **derived subjects are re-derived here**, because `ncpdp`'s ground its fuzz subject in a
381
+ workflow that hands a path straight to `vitest run` and **no workflow in this repo contains that
382
+ string at all** (ported verbatim it refuses). Three subjects instead:
383
+ 1. **The published surface**, from `package.json` `exports`. Each of the eight subpaths resolves to
384
+ a `dist/[<dir>/]index.<ext>` emitted from `src/[<dir>/]index.ts`; every tracked module under
385
+ scope naming one of those entry points must be selected, and every entry point must have at
386
+ least one selected module naming it. Keyed on a **resolved module path**, not a filename and not
387
+ a bare substring, so a rename moves nothing out of the subject; scope is a **deny-list** of
388
+ `src/`, `scripts/` and the repo root, so a move anywhere else does not either. **This is the
389
+ rule that reaches the synthetic-safety property layer**, which was named by nothing.
390
+ **The scope was an allow-list (`test/`) in the first version and the refuter broke it**:
391
+ relocating all six `synthetic-safety.property.test.ts` files into `internal/` took the whole
392
+ safety layer out of CI, `vitest list` selected zero of them, and the gate printed OK exit 0.
393
+ A move into one of the three denied locations still escapes and is stated in three places
394
+ rather than denied.
395
+ 2. **The fuzz path**, derived in two steps because that is how this repo spells it: the nightly
396
+ `Fuzz` workflow runs `pnpm test:fuzz`, whose body is a `vitest run <path>`. Redundant today
397
+ (that module also imports a published entry) and kept for its empty-set refusal, which is a
398
+ tripwire on the fuzz job disappearing **only if no other literal path is left behind anywhere in
399
+ a workflow**. The extraction is text and cannot tell a real `run:` from prose quoting one, so a
400
+ commented `vitest run test/hl7` suppresses the refusal; calling it unconditional would overstate
401
+ it.
402
+ 3. **The PHI scanner**, ported directly (`phi-scan` script plus `run-phi-scan: true` in `ci.yml`).
403
+
404
+ It prints a **denominator** on every run instead of a bare OK: of 39 tracked in-scope code modules,
405
+ **38 are watched by a name-independent rule, 1 by the `.test.`/`.spec.` filename shape alone
406
+ (`test/docs-content.test.ts`), and 0 by no rule at all**. The like-for-like figure in `ncpdp` is **4
407
+ of 27** in-scope modules; its own header quotes "4 of 24", counting only name-shaped files, which
408
+ flatters the ratio. Cite the comparable number, not the friendlier one.
409
+ Three self-tests re-prove it on every run, one resolving a genuinely narrowed config through real
410
+ vitest; **self-test A ignores the filename floor and requires a DERIVED rule to name each dropped
411
+ file**. Both A's drop targets one at a time, so the colliding direction is exercised in each; the
412
+ single difference is that `ncpdp`'s verdict counts the filename floor, which is why that one passed
413
+ with its derived rules neutered. (An earlier draft of this entry said `ncpdp`'s A "does not do" the
414
+ one-at-a-time part; a refuter corrected it, and A is not the backstop for the derived rules in either
415
+ repo, because emptying a subject empties A's targets with it. Self-test C is.)
416
+ **`test-selection` is deliberately NOT added to ruleset `19913330`**: a required context no
417
+ workflow has emitted on `main` leaves every future PR pending and unmergeable. Wire first, require
418
+ later.
419
+
420
+ **Every quantity above is re-derivable, not asserted.** The script header lists the command that
421
+ produces each one, because two of the three refuter passes found a false number or a false claim of
422
+ reach rather than a hole in the mechanism, both times from a sentence ported out of a sibling repo
423
+ and never re-measured here. All of them were re-measured against this repo, on the tree that ships.
424
+
425
+ Demonstrated red by seeding, one route at a time: a narrowed `include`; an `exclude` targeting
426
+ `**/synthetic-safety.property.test.ts`; an `exclude` dropping `test/property/`; positional filters
427
+ written both `vitest run <p>` and `vitest --run <p>`; `--shard=`, `--config=`; a body naming no
428
+ vitest at all (`pnpm run test:unit`, `node node_modules/vitest/vitest.mjs run`) **and a delegation
429
+ to this repo's own narrowing script, `pnpm run test:fuzz`**; renaming a safety suite to `.ts`,
430
+ `.spec.ts` and `_safety.ts`; **the colliding renames that were measured GREEN on `ncpdp`'s earlier
431
+ versions** (`_helpers.ts`, `test/_helpers/load-fixture.ts`, `test/_x/parse.ts`, and the cross-format
432
+ safety suite moved into `test/_helpers/fuzz-config.ts`); the PHI suite renamed to
433
+ `phi-scan-suite.ts`; the fuzz subject renamed out of shape; `run-phi-scan: false`; and
434
+ un-exporting `./astm` together with a narrowed include. Deleting the `Fuzz` workflow, deleting the
435
+ `test:fuzz` script, or deleting the `exports` map each make it **REFUSE to report** rather than pass
436
+ vacuously.
437
+
438
+ Red after the refuter pass, having been **green before it**: any suite relocated out of `test/`
439
+ (one safety suite, then all six at once, then the PHI suite, each into `internal/`), and a suite
440
+ renamed to `_safety.ts` whose import specifiers were rewritten to unicode escapes so the raw text
441
+ no longer looked like the path while the imports still resolved.
442
+
443
+ Green and stated as limits rather than denied: a config branching on `process.argv` (**2 of 39**
444
+ suites would have run); un-exporting `./astm` alone (**2** `test/astm` suites drop to the filename
445
+ floor, denominator 38 to 36); a suite moved into `src/`, `scripts/` or the repo root; and renaming
446
+ `test/docs-content.test.ts` out of shape.
447
+
448
+ - **The dual ESM/CJS release smoke now runs in a job.** `.github/workflows/smoke.yml` (job id `smoke`,
449
+ matrix contexts `smoke (22)` / `smoke (24)`), with `build` and `smoke` as steps of **one** job so a
450
+ future required context covers both. Same wiring `deid` used for the same defect, which is what
451
+ makes this a class rather than an incident. These contexts are also deliberately **not** added to
452
+ the ruleset yet.
372
453
 
373
454
  ### Changed
374
455
 
@@ -409,6 +490,31 @@ its public history at `0.0.x`, per the cosyte version ladder (`0.0.x` until firs
409
490
 
410
491
  ### Fixed
411
492
 
493
+ - **`scripts/smoke.mjs` ran in NO CI job.** It only ever ran on the meta-repo's local
494
+ `scripts/verify.sh` ladder, which a contributor is not obliged to run and CI never invokes, so no
495
+ required check covered the eight published subpaths and a green PR said nothing about whether they
496
+ load. Now wired (`.github/workflows/smoke.yml`).
497
+
498
+ **A correction, recorded rather than quietly dropped.** Earlier drafts of this entry and of two
499
+ other surfaces said the file had been _documented as a CI gate_, so that the docs asserted a
500
+ protection nothing provided. **That was false here**, and the third refuter pass caught it: every
501
+ surface describing this file said `run by verify.sh` (this file, `CLAUDE.md`, and the
502
+ release-hardening changeset), and its header said only "Run after `build`". The docs were accurate.
503
+ The sentence was **ported from `deid`, where it is true** (its own changelog records the line that
504
+ claimed CI and never ran), and it was ported without re-measuring it against this repo, which is
505
+ precisely the failure the test-selection gate's header warns about two entries up. The defect is
506
+ real and unchanged; only the indictment of the prior docs was wrong.
507
+
508
+ - **The smoke's subpath set was a hand-written array.** `SUBPATHS` listed the eight subpaths inline,
509
+ so dropping one would have left the gate printing OK over a subset. It is now derived from
510
+ `package.json` `exports` at run time, loads the export targets themselves rather than
511
+ reconstructing `dist/<name>/index.mjs` by hand (so an `exports` entry pointing at a path the build
512
+ does not emit fails here rather than in a consumer's install), and **REFUSES to report** if its
513
+ per-subpath probe map and that `exports` map disagree in either direction. There is no exclusion
514
+ list either: `./package.json` drops out because its target is structurally data, not because a key
515
+ was named. Demonstrated: deleting `"./astm"` from `exports` makes the smoke refuse. That refusal is
516
+ the interlock under `check:test-selection`, whose headline subject is derived from the same map.
517
+
412
518
  ### Security
413
519
 
414
520
  [Unreleased]: https://github.com/cosyte/synth/commits/main
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosyte/synth",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
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",