@cosyte/astm 0.1.0 → 0.1.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.
package/CHANGELOG.md CHANGED
@@ -1,13 +1,180 @@
1
1
  # Changelog
2
2
 
3
- All notable changes to this project will be documented in this file.
3
+ ## 0.1.2
4
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).
5
+ ### Patch Changes
9
6
 
10
- ## [Unreleased]
7
+ - 93c5774: The README follows our shared layout, with Support and Security sections and the Node.js versions CI tests (22, 24, and 26), and at a fifth of its former length it fits well inside npm's README limit. Its API tour and its coverage and compatibility notes moved, unchanged, to two pages on docs.cosyte.com/astm: "The API, layer by layer" and "Coverage and compatibility". No code, API, or behavior changes.
8
+
9
+ ## 0.1.1
10
+
11
+ ### Patch Changes
12
+
13
+ - Published through npm trusted publishing, with provenance.
14
+
15
+ ## 0.1.0
16
+
17
+ ### Minor Changes
18
+
19
+ - **One date conversion surface across the @cosyte parsers.** `toObject`, `toISO` and `toDate` read a
20
+ parsed ASTM date the same way the sibling parsers do. `toObject` returns only the components the
21
+ value stated, and `toISO` appends no offset, because ASTM states none. `toDate` returns a `Date` only
22
+ when you pass `assumeOffsetMinutes`: an analyzer's timestamp is local to the analyzer.
23
+ - **A LIVD catalog records where it came from.** `defineLivdCatalog` takes an optional second argument
24
+ (publisher, publication version, LOINC version, LOINC copyright), and every annotation carries the
25
+ catalog's LOINC version, so a mapping can be reproduced. A catalog with no LOINC version still
26
+ builds and raises one `ASTM_LIVD_CATALOG_NO_LOINC_VERSION` warning.
27
+ - **Reported units can choose between candidate LOINCs.** A LIVD entry can carry
28
+ `representativeUnit`, `vendorSpecimenDescription` and `vendorResultDescription`. When one vendor
29
+ code maps to several LOINCs, the candidate whose unit exactly equals the reported unit is answered
30
+ `mapped`. The comparison is verbatim and case sensitive, not UCUM, and every unit-selected answer
31
+ says so. No match, or more than one, is still `ambiguous`.
32
+ - **Flags and statuses name the vocabulary they were graded against.** An abnormal flag carries the
33
+ code system and version it was compared with, and `HU` and `LU` are now recognized. A result status
34
+ says that no citable published source binds its letters, rather than implying one.
35
+ - **One deliberate break from 0.0.x**, in the LIVD mapping and in what `primaryCode()` returns:
36
+ a populated first component of the Universal Test ID is no longer reported as a LOINC, and
37
+ `primaryCode()` returns the vendor local code and nothing else. The hand-written entries below and
38
+ the [0.1.0 release notes](https://github.com/cosyte/astm/releases/tag/v0.1.0) give the migration.
39
+
40
+ ## 0.0.22
41
+
42
+ ### Patch Changes
43
+
44
+ - Gate the two-file contract between `CLAUDE.md` and the agent notes.
45
+ - Read the bytes git carries in the PHI sweep, as a union with the working-tree walk.
46
+
47
+ ## 0.0.21
48
+
49
+ ### Patch Changes
50
+
51
+ - Correct two false claims the contested-alignment codes rested on, both on consumer surfaces.
52
+ - Close the three measurement holes the contested-alignment claim corrections left behind.
53
+
54
+ ## 0.0.20
55
+
56
+ ### Patch Changes
57
+
58
+ - Read a stream embedded as a source string literal in the PHI commit-gate, and refuse a sweep that did not observe its corpus.
59
+
60
+ ## 0.0.19
61
+
62
+ ### Patch Changes
63
+
64
+ - Report a contested escape alignment whose tail this reader cannot read, not only one it cannot consume.
65
+ - The README lockup now links to cosyte.com.
66
+ - Report components a competing escape alignment moved one slot along.
67
+ - Development tooling only: the repository's own pre-commit PHI scanner no longer lets a caller's git configuration decide which staged entries it looks at.
68
+
69
+ ## 0.0.18
70
+
71
+ ### Patch Changes
72
+
73
+ - Report a field a competing escape alignment read short.
74
+
75
+ ## 0.0.17
76
+
77
+ ### Patch Changes
78
+
79
+ - Report a competing escape alignment that shifted a result's units and status into slots the sender did not write them in.
80
+
81
+ ## 0.0.15
82
+
83
+ ### Patch Changes
84
+
85
+ - Stop a delimiter set that names one of the escape mnemonics from altering the values it emits, and state what a header's delimiter-declaration surplus costs on emit.
86
+
87
+ ## 0.0.14
88
+
89
+ ### Patch Changes
90
+
91
+ - Refuse a `startFrameNumber` that cannot be written as a frame number, which used to go out as whatever byte the arithmetic truncated to and could cost a framed stream every one of its records.
92
+
93
+ ## 0.0.13
94
+
95
+ ### Patch Changes
96
+
97
+ - Refuse to emit a record whose own type letter the delimiter set would escape away, which used to produce a stream that read back as different records and, in its silent branch, fabricated a final lab result out of patient identifiers.
98
+
99
+ ## 0.0.11
100
+
101
+ ### Patch Changes
102
+
103
+ - A symbolic link under a scan root read clean on both of the PHI scanner's enumerating routes, so a link pointing at a file full of real identifiers passed the gate twice over.
104
+ - Make the package's own publish gate fail when a build would ship without its type declarations.
105
+
106
+ ## 0.0.10
107
+
108
+ ### Patch Changes
109
+
110
+ - Stop the frame encoder from silently writing a different character than the one it was given.
111
+
112
+ ## 0.0.9
113
+
114
+ ### Patch Changes
115
+
116
+ - Report a record whose fields did not separate, instead of reading it back with no value, no units and no status, and stop calling a message a result set when a record's type letter is unreadable.
117
+ - Stop one unescaped `&` in a value from swallowing every following field.
118
+
119
+ ## 0.0.8
120
+
121
+ ### Patch Changes
122
+
123
+ - Remove `ASTM_RECORD_UNKNOWN_TYPE` from the profile safety gate's tolerable allow-list.
124
+
125
+ ## 0.0.7
126
+
127
+ ### Patch Changes
128
+
129
+ - The alt text on the README's Cosyte mark now says how its two overlapping rounded squares differ, one solid and one outlined.
130
+
131
+ ## 0.0.6
132
+
133
+ ### Patch Changes
134
+
135
+ - The Cosyte mark now opens the README, and follows the reader's color scheme.
136
+
137
+ ## 0.0.5
138
+
139
+ ### Patch Changes
140
+
141
+ Internal tooling and CI only. No change to the published package surface.
142
+
143
+ ## 0.0.4
144
+
145
+ ### Patch Changes
146
+
147
+ - Correct the API documentation shipped in the type declarations, and stop it going stale.
148
+ - Stop pairing one patient's results with another's, and add `messages()` to read a stream as the sequence of messages it actually is.
149
+ - Read the delimiters from every header, not just the first, so a stream carrying more than one message no longer silently loses fields.
150
+ - Emit one delimiter set for the whole stream, so a round-trip no longer silently loses fields.
151
+ - Close the two emit-side gaps where a stream went out that could not be read back.
152
+
153
+ ## 0.0.3
154
+
155
+ ### Patch Changes
156
+
157
+ - Documentation: the page describing what the library does and does not do moves from an "About" category into **Troubleshooting**, matching the section order every other `@cosyte/*` package uses.
158
+ - The status note on the README, the overview page and the install page no longer names a version number, because a release made that number wrong every time.
159
+
160
+ ## Released before this file was generated
161
+
162
+ Every release section above this heading is written by
163
+ [Changesets](https://github.com/changesets/changesets) from the changesets in `.changeset/`, newest
164
+ release first. The release writes its own version heading, so nothing above this line is maintained
165
+ by hand, and a change is recorded by adding a changeset rather than by editing this file. The
166
+ sections for 0.0.3 to 0.1.1 were filled in from the GitHub release notes when generation was turned
167
+ on, because those releases shipped while this file was kept by hand and its last version heading was
168
+ 0.0.2. Each repeats the "What changed" list from that release's notes, and 0.1.0 adds one line on
169
+ its deliberate break.
170
+
171
+ Everything below this heading was maintained by hand, in the
172
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) format, and is left as it was written. The
173
+ entries from the start down to `[0.0.2]` sat under an `[Unreleased]` heading that no release rolled
174
+ over, so they record what 0.0.3 to 0.1.1 changed, written as the work landed rather than sorted by
175
+ release. Three things were dropped: the preamble above them (it said the file was kept by hand), the
176
+ `[Unreleased]` heading itself, and its link definition at the foot of the file. No entry was
177
+ reworded.
11
178
 
12
179
  **What 0.1 means for you.** This release is the first whose public API we treat as settled: the
13
180
  exported names, options, return shapes and warning codes are the surface we keep stable. What it
@@ -53,6 +220,9 @@ exists for.
53
220
 
54
221
  ### Changed
55
222
 
223
+ - **Published through npm trusted publishing, with provenance.** The code, API and behavior are
224
+ unchanged from 0.1.0. Only the README and some doc comments differ: a few doc comments now write
225
+ number ranges with "to".
56
226
  - **Every published release now carries a machine-readable dependency inventory as a downloadable
57
227
  asset.** No published value, type, warning code or emitted byte moves: this entry is release
58
228
  infrastructure only, and nothing under `src/` is touched. The inventory is a CycloneDX document
@@ -387,7 +557,7 @@ exists for.
387
557
  adding a workflow that would have to be made a required context separately. It asserts that every
388
558
  pointer resolves, that no section a pointer reaches is empty, that the record stays reachable from
389
559
  the always-read file, and that the always-read file still links the record by path. It asserts
390
- **no** ecosystem-wide contract: several cosyte repos carry no such record at all, and a gate
560
+ **no** ecosystem-wide contract: several Cosyte repos carry no such record at all, and a gate
391
561
  phrased as though every repo did would be an overclaim.
392
562
  - **The matcher was re-derived against this tree rather than ported, and that was the whole job.**
393
563
  Both sibling spellings score **zero** here: the path-qualified form used by `ccda` and `mllp`,
@@ -1430,7 +1600,7 @@ exists for.
1430
1600
  **The refusal removes no capability.** `composeAstmFrames` already accepted `Uint8Array`, so a
1431
1601
  consumer who knows their instrument's code page encodes with their own encoder and passes bytes,
1432
1602
  which are written through untouched. A stream whose every character is Latin-1 is byte-identical
1433
- to before, the full `0x00`–`0xFF` range included. The **record** layer is deliberately unchanged:
1603
+ to before, the full `0x00` to `0xFF` range included. The **record** layer is deliberately unchanged:
1434
1604
  `serializeAstmRecords` returns a `string`, which is not yet bytes, so the caller keeps the choice.
1435
1605
 
1436
1606
  **Stated no wider than it was measured.** This closes the string-to-bytes step only. It is not a
@@ -1907,7 +2077,7 @@ phase 8` passes while `Phase 8` reds). An arm keyed on a following digit was wri
1907
2077
  acceptance under a tolerating profile) is _measured_, on the tree before and after the change.
1908
2078
 
1909
2079
  - **The em dash (U+2014) is gone from every tracked file, and a CI gate keeps it out**
1910
- (`EMDASH-CONFORMANCE`). The brand rule bans the character outright across every cosyte surface
2080
+ (`EMDASH-CONFORMANCE`). The brand rule bans the character outright across every Cosyte surface
1911
2081
  and names commit messages explicitly; this package was the last one it had not reached, and the
1912
2082
  only one where it did not arrive on a clean tree. **1,129 occurrences across 108 of the 142
1913
2083
  tracked files** were rewritten with a comma, a colon, or a period. The sweep and the gate are one
@@ -2371,7 +2541,7 @@ phase 8` passes while `Phase 8` reds). An arm keyed on a following digit was wri
2371
2541
 
2372
2542
  ## [0.0.1] - 2026-07-22
2373
2543
 
2374
- The first pre-alpha release. The package begins its public history at `0.0.x`, per the cosyte version
2544
+ The first pre-alpha release. The package begins its public history at `0.0.x`, per the Cosyte version
2375
2545
  ladder (`0.0.x` until first alpha).
2376
2546
 
2377
2547
  ### Added
@@ -2499,7 +2669,7 @@ warnings: readonly AstmFrameWarning[] }`. A frame is `<STX> FN text <ETB|ETX> CS
2499
2669
  - **Modulo-256 checksum** over the bytes after `STX` up to and **including** the `ETB`/`ETX`
2500
2670
  terminator, two hex chars: **verified on decode, emitted uppercase, accepted lowercase** (a real
2501
2671
  vendor quirk). `computeChecksum` / `toChecksumHex` / `parseChecksumHex` exported.
2502
- - **Frame-number `0`–`7` sequencing** (rolls over `7 → 0 → 1`, starts at `1`) and **multi-frame record
2672
+ - **Frame-number `0` to `7` sequencing** (rolls over `7 → 0 → 1`, starts at `1`) and **multi-frame record
2503
2673
  reassembly**: text is capped at **240 bytes** (the seven control bytes are **not** counted), `ETB`
2504
2674
  is intermediate / `ETX` final. `parseFramedAstm(bytes, opts?)` composes the framing and record layers
2505
2675
  at the edge (decode → reassemble trusted records → `parseAstmRecords`).
@@ -2535,7 +2705,7 @@ defaulted: boolean; warnings }`. A leading `STX`/`ENQ` ⇒ **framed** (serial, a
2535
2705
  by `ltpInitialState()`. Events are the four LTP control signals (`enq`/`ack`/`nak`/`eot`) plus a
2536
2706
  codec-decoded `frame`; actions are `sendAck` / `sendNak` / `sendEot` / `deliverRecord`. It models
2537
2707
  the LIS01-A2 establishment → transfer → termination phases as `neutral ⇄ transfer`, reassembling
2538
- `ETB…ETX` runs into delivered records and tracking the `0`–`7` frame sequence.
2708
+ `ETB…ETX` runs into delivered records and tracking the `0` to `7` frame sequence.
2539
2709
  - **ACK-failsafe (safety-critical, borrowed from `mllp`).** A frame the codec did not vouch for (a
2540
2710
  **bad checksum**, an **unterminated** frame, or one **out of sequence**) is answered with `NAK`,
2541
2711
  **never** a fabricated positive `ACK`, and its bytes are **never** appended to a record or
@@ -2572,7 +2742,7 @@ EOT` session **reassembles exactly the source records**; a **raw-TCP stream equa
2572
2742
  counters, the `L` terminator) is **computed, not guessed** (a sequence number may be overridden).
2573
2743
  - **Frame encoder.** `composeAstmFrames(records, opts?)` is the exact inverse of `decodeAstmFrames`:
2574
2744
  it wraps reassembled record bytes into `<STX> FN text <ETB|ETX> CS <CR><LF>` frames with the
2575
- modulo-256 **checksum** and the `0`–`7` **frame number** **computed** (never accepted-as-given or
2745
+ modulo-256 **checksum** and the `0` to `7` **frame number** **computed** (never accepted-as-given or
2576
2746
  faked; emitted uppercase), numbered continuously across the stream (start `1`, roll over `7 → 0`),
2577
2747
  and every record over **240** text bytes **split** `ETB…ETX` (the seven control bytes never counted).
2578
2748
  `serializeFramedAstm(msg | records)` composes both emit layers at the edge: the mirror of
@@ -2709,6 +2879,5 @@ EOT` session **reassembles exactly the source records**; a **raw-TCP stream equa
2709
2879
  interactive contention/timeout/retransmit **timing**) is a thin consumer adapter, and the standard's
2710
2880
  exact numeric timeouts / retry counts are deferred (we model transitions, not timers).
2711
2881
 
2712
- [Unreleased]: https://github.com/cosyte/astm/commits/main
2713
2882
  [0.0.2]: https://github.com/cosyte/astm/releases/tag/v0.0.2
2714
2883
  [0.0.1]: https://github.com/cosyte/astm/releases/tag/v0.0.1
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Cosyte
3
+ Copyright (c) 2026 Cosyte LLC
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal