@cosyte/astm 0.0.4 → 0.0.5

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/dist/index.d.cts CHANGED
@@ -3,8 +3,8 @@
3
3
  * record layer.
4
4
  *
5
5
  * **PHI discipline (the whole point).** A position identifies *where* a
6
- * deviation occurred — the record's ordinal index, its type letter, and the
7
- * 1-based field / component indices — and **never** carries a field value. A
6
+ * deviation occurred (the record's ordinal index, its type letter, and the
7
+ * 1-based field / component indices) and **never** carries a field value. A
8
8
  * warning or error may be logged verbatim without leaking a patient name, an
9
9
  * identifier, or a result value.
10
10
  */
@@ -51,21 +51,21 @@ interface AstmPosition {
51
51
  * ```
52
52
  */
53
53
  declare const WARNING_CODES: {
54
- /** A record's type letter is not one of the modeled types — surfaced as an unsupported record. */
54
+ /** A record's type letter is not one of the modeled types: surfaced as an unsupported record. */
55
55
  readonly ASTM_RECORD_UNKNOWN_TYPE: "ASTM_RECORD_UNKNOWN_TYPE";
56
- /** The header declared delimiters other than the canonical `H|\^&` — tolerated, noted. */
56
+ /** The header declared delimiters other than the canonical `H|\^&`: tolerated, noted. */
57
57
  readonly ASTM_NONSTANDARD_DELIMITERS: "ASTM_NONSTANDARD_DELIMITERS";
58
- /** An escape sequence body was not one of `&F&`/`&S&`/`&R&`/`&E&` — preserved verbatim. */
58
+ /** An escape sequence body was not one of `&F&`/`&S&`/`&R&`/`&E&`: preserved verbatim. */
59
59
  readonly ASTM_UNKNOWN_ESCAPE_SEQUENCE: "ASTM_UNKNOWN_ESCAPE_SEQUENCE";
60
60
  /**
61
61
  * A result value field carried an *unescaped* component delimiter, so it split into more than one
62
- * component. Both the full raw value and the split are surfaced and this warning fires — the
62
+ * component. Both the full raw value and the split are surfaced and this warning fires: the
63
63
  * ambiguity is never resolved silently into a truncated value.
64
64
  */
65
65
  readonly ASTM_RECORD_AMBIGUOUS_VALUE_SPLIT: "ASTM_RECORD_AMBIGUOUS_VALUE_SPLIT";
66
66
  /**
67
67
  * A result's abnormal-flag field (`R` field 7) carried a letter outside HL7 Table 0078. The flag is
68
- * surfaced as `undefined` — never dropped, and **never coerced to `normal`** (a clinical error).
68
+ * surfaced as `undefined`: never dropped, and **never coerced to `normal`** (a clinical error).
69
69
  */
70
70
  readonly ASTM_RECORD_UNDEFINED_ABNORMAL_FLAG: "ASTM_RECORD_UNDEFINED_ABNORMAL_FLAG";
71
71
  /**
@@ -75,7 +75,7 @@ declare const WARNING_CODES: {
75
75
  readonly ASTM_RECORD_UNDEFINED_RESULT_STATUS: "ASTM_RECORD_UNDEFINED_RESULT_STATUS";
76
76
  /**
77
77
  * A result's reference-range field (`R` field 6) did not match a recognized form (`low-high`,
78
- * `<high`, `>low`). The text is surfaced verbatim as `unparsed` — a bound is **never fabricated**.
78
+ * `<high`, `>low`). The text is surfaced verbatim as `unparsed`: a bound is **never fabricated**.
79
79
  */
80
80
  readonly ASTM_RECORD_UNPARSEABLE_REFERENCE_RANGE: "ASTM_RECORD_UNPARSEABLE_REFERENCE_RANGE";
81
81
  /**
@@ -84,25 +84,25 @@ declare const WARNING_CODES: {
84
84
  */
85
85
  readonly ASTM_RECORD_UNITS_ABSENT: "ASTM_RECORD_UNITS_ABSENT";
86
86
  /**
87
- * A `C` (comment) record had no valid preceding `H`/`P`/`O`/`R` parent — an **orphan**. The comment
87
+ * A `C` (comment) record had no valid preceding `H`/`P`/`O`/`R` parent: an **orphan**. The comment
88
88
  * is attached to the message root (`attachedToRoot: true`) and surfaced, **never dropped**.
89
89
  */
90
90
  readonly ASTM_RECORD_ORPHAN_COMMENT: "ASTM_RECORD_ORPHAN_COMMENT";
91
91
  /**
92
92
  * A `YYYYMMDDHHMMSS` timestamp had an odd digit run that truncates a two-digit component in half
93
93
  * (e.g. a partial day/hour). The raw run is preserved and the structured value stops at the last
94
- * **complete** component — the dangling digit is **never zero-filled into a fabricated time**.
94
+ * **complete** component: the dangling digit is **never zero-filled into a fabricated time**.
95
95
  */
96
96
  readonly ASTM_RECORD_PARTIAL_TIMESTAMP: "ASTM_RECORD_PARTIAL_TIMESTAMP";
97
97
  /**
98
98
  * A `Q` (request-information) record carried a request-information status code (field 13). The code
99
99
  * *set* is `[OSS-derived / paywalled]` with no publicly-groundable enumeration, so the parser
100
100
  * interprets **none** of them: the status is surfaced verbatim and this value-free warning flags that
101
- * it was passed through **uninterpreted** — never mapped to a guessed meaning.
101
+ * it was passed through **uninterpreted**, never mapped to a guessed meaning.
102
102
  */
103
103
  readonly ASTM_RECORD_UNINTERPRETED_QUERY_STATUS: "ASTM_RECORD_UNINTERPRETED_QUERY_STATUS";
104
104
  /**
105
- * A message carried **both** a `Q` (request) and an `R` (result) record — a contradictory shape. The
105
+ * A message carried **both** a `Q` (request) and an `R` (result) record: a contradictory shape. The
106
106
  * message is classified `host-query` (the `Q` **dominates**, so it is never read as a result set) and
107
107
  * this warning flags the anomaly. Positional context only; no field value.
108
108
  */
@@ -111,7 +111,7 @@ declare const WARNING_CODES: {
111
111
  * A later `H` (header) record declared a **different** delimiter set from the one in force, and the
112
112
  * parser **followed it**: that header and every record after it are read with the newly-declared
113
113
  * delimiters, until the next `H`. Records already read keep the set that was in force when they were
114
- * read — a redeclaration never reinterprets bytes that have already been consumed.
114
+ * read: a redeclaration never reinterprets bytes that have already been consumed.
115
115
  *
116
116
  * A stream carrying several messages back to back is ordinary, and a header that simply **repeats**
117
117
  * the delimiters already in force is a no-op that warns nothing. This code fires only when the set
@@ -120,13 +120,13 @@ declare const WARNING_CODES: {
120
120
  */
121
121
  readonly ASTM_RECORD_DELIMITERS_REDECLARED: "ASTM_RECORD_DELIMITERS_REDECLARED";
122
122
  /**
123
- * A later `H` (header) record could not declare a usable delimiter set — it was too short, or the
123
+ * A later `H` (header) record could not declare a usable delimiter set: it was too short, or the
124
124
  * field separator it named also appeared among the other three, leaving the four roles
125
125
  * indistinguishable. The delimiters **already in force are kept** and every record is still surfaced;
126
126
  * a set is never guessed and no record is dropped.
127
127
  *
128
128
  * The same condition on the *first* header is unrecoverable and remains the
129
- * `ASTM_RECORD_UNDECLARED_DELIMITERS` fatal — there is no earlier set to fall back to.
129
+ * `ASTM_RECORD_UNDECLARED_DELIMITERS` fatal: there is no earlier set to fall back to.
130
130
  */
131
131
  readonly ASTM_RECORD_UNREADABLE_REDECLARATION: "ASTM_RECORD_UNREADABLE_REDECLARATION";
132
132
  /**
@@ -134,7 +134,7 @@ declare const WARNING_CODES: {
134
134
  * (see `src/profiles/`). The original warning is **never dropped**: its code moves to
135
135
  * {@link AstmRecordWarning.toleratedCode}, the warning is re-badged `PROFILE_QUIRK_APPLIED` with
136
136
  * `expected: true` and the tolerating profile named, so a consumer can filter known, grounded noise
137
- * while the fact of the deviation — and where it was — survives. A profile can only ever reach this
137
+ * while the fact of the deviation, and where it was, survives. A profile can only ever reach this
138
138
  * path for a **non-safety-critical** code (enforced at profile-definition time); a safety-critical
139
139
  * deviation (a result value, flag, status, patient identifier, code system, or a frame-integrity
140
140
  * warning) can **never** be tolerated, so it can never be re-badged here.
@@ -170,14 +170,14 @@ interface AstmRecordWarning {
170
170
  * `true` when an active vendor {@link AstmProfile} *expected* this deviation and re-badged it as a
171
171
  * {@link WARNING_CODES.PROFILE_QUIRK_APPLIED}. An `expected` warning does **not** escalate to a
172
172
  * thrown `AstmStrictError` in strict mode (the whole point of the profile is that this deviation is
173
- * known and benign) — it is still recorded, so nothing is hidden. Absent on an untolerated warning.
173
+ * known and benign): it is still recorded, so nothing is hidden. Absent on an untolerated warning.
174
174
  */
175
175
  readonly expected?: boolean;
176
176
  /** The name of the {@link AstmProfile} that tolerated this warning, when `expected`. */
177
177
  readonly profile?: string;
178
178
  /**
179
179
  * When `code` is {@link WARNING_CODES.PROFILE_QUIRK_APPLIED}, the original warning code the profile
180
- * tolerated — so a consumer can still see *which* deviation was re-badged as expected.
180
+ * tolerated, so a consumer can still see *which* deviation was re-badged as expected.
181
181
  */
182
182
  readonly toleratedCode?: WarningCode;
183
183
  }
@@ -206,7 +206,7 @@ declare function nonStandardDelimiters(position: AstmPosition): AstmRecordWarnin
206
206
  /**
207
207
  * Build an `ASTM_RECORD_DELIMITERS_REDECLARED` warning. Emitted when a later `H`
208
208
  * record declares a delimiter set different from the one in force; the new set is
209
- * honored from that header onward. Positional context only — never the delimiters
209
+ * honored from that header onward. Positional context only: never the delimiters
210
210
  * themselves.
211
211
  *
212
212
  * @example
@@ -242,7 +242,7 @@ declare function unreadableRedeclaration(position: AstmPosition): AstmRecordWarn
242
242
  declare function unknownEscapeSequence(position: AstmPosition): AstmRecordWarning;
243
243
  /**
244
244
  * Build an `ASTM_RECORD_AMBIGUOUS_VALUE_SPLIT` warning. Emitted when a result
245
- * value field split on an unescaped component delimiter — the full raw value and
245
+ * value field split on an unescaped component delimiter: the full raw value and
246
246
  * the split are both surfaced, never a silent truncation.
247
247
  *
248
248
  * @example
@@ -346,7 +346,7 @@ declare function uninterpretedQueryStatus(position: AstmPosition): AstmRecordWar
346
346
  */
347
347
  declare function ambiguousMessageKind(position: AstmPosition): AstmRecordWarning;
348
348
  /**
349
- * Build a `PROFILE_QUIRK_APPLIED` warning — the downgraded form an active vendor profile produces from
349
+ * Build a `PROFILE_QUIRK_APPLIED` warning: the downgraded form an active vendor profile produces from
350
350
  * a deviation it *expects*. The original warning is **not dropped**: its `code` moves to
351
351
  * `toleratedCode`, the warning is re-badged `PROFILE_QUIRK_APPLIED`, `expected` is set, and the
352
352
  * tolerating profile is named. The original `position` and `message` are preserved (both PHI-free by
@@ -373,7 +373,7 @@ declare function profileQuirkApplied(original: AstmRecordWarning, profileName: s
373
373
  *
374
374
  * ASTM/CLSI-LIS02 messages are **self-describing**: every `H` (header) record
375
375
  * declares the four delimiters it uses, in the bytes immediately after the `H`.
376
- * A parser MUST read them from the record and MUST NOT hardcode them — a vendor
376
+ * A parser MUST read them from the record and MUST NOT hardcode them: a vendor
377
377
  * is free to declare non-standard delimiters and a conformant reader follows.
378
378
  *
379
379
  * The canonical declaration is `H|\^&`:
@@ -405,18 +405,18 @@ declare function profileQuirkApplied(original: AstmRecordWarning, profileName: s
405
405
  * ```
406
406
  */
407
407
  interface Delimiters {
408
- /** Field separator — the char immediately after `H` in the header. */
408
+ /** Field separator: the char immediately after `H` in the header. */
409
409
  readonly field: string;
410
- /** Repeat (repetition) separator — ASTM `\` by default. */
410
+ /** Repeat (repetition) separator: ASTM `\` by default. */
411
411
  readonly repeat: string;
412
- /** Component separator — ASTM `^` by default. */
412
+ /** Component separator: ASTM `^` by default. */
413
413
  readonly component: string;
414
- /** Escape character — ASTM `&` by default (introduces `&F&`/`&S&`/`&R&`/`&E&`). */
414
+ /** Escape character: ASTM `&` by default (introduces `&F&`/`&S&`/`&R&`/`&E&`). */
415
415
  readonly escape: string;
416
416
  }
417
417
  /**
418
418
  * The canonical ASTM delimiter set (`H|\^&`). Used only as documentation and as
419
- * a comparison baseline for the non-standard-delimiter warning — never as a
419
+ * a comparison baseline for the non-standard-delimiter warning: never as a
420
420
  * parse-time default (delimiters are always read from the header).
421
421
  *
422
422
  * @example
@@ -430,14 +430,14 @@ declare const CANONICAL_DELIMITERS: Delimiters;
430
430
  * Read the four delimiters from a header record's raw text (a single `H`
431
431
  * record, its terminator already stripped).
432
432
  *
433
- * Returns `undefined` when the record cannot declare all four delimiters — it is
433
+ * Returns `undefined` when the record cannot declare all four delimiters: it is
434
434
  * shorter than `H` + a field separator + a 3-char delimiter definition, or the
435
435
  * field separator it names also appears among the other three.
436
436
  *
437
437
  * What the caller does with that depends on **which** header it is. On the first
438
438
  * header it is the `ASTM_RECORD_UNDECLARED_DELIMITERS` fatal, because there is no
439
- * earlier set to fall back to. On any later header — a stream may carry several
440
- * messages, each declaring its own set — the delimiters already in force are kept
439
+ * earlier set to fall back to. On any later header (a stream may carry several
440
+ * messages, each declaring its own set) the delimiters already in force are kept
441
441
  * and an `ASTM_RECORD_UNREADABLE_REDECLARATION` warning is raised instead; a set is
442
442
  * never guessed and no record is dropped.
443
443
  *
@@ -468,12 +468,12 @@ declare function readDelimiters(headerRecord: string): Delimiters | undefined;
468
468
  declare function isNonStandard(d: Delimiters): boolean;
469
469
 
470
470
  /**
471
- * The ASTM date/time value — `YYYYMMDDHHMMSS`, precision-preserving, no timezone.
471
+ * The ASTM date/time value: `YYYYMMDDHHMMSS`, precision-preserving, no timezone.
472
472
  *
473
473
  * ASTM timestamps are a run of digits, most-significant first, truncated at
474
474
  * whatever precision the instrument reports. There is **no timezone field**:
475
475
  * the value is local to the instrument and this parser never assumes UTC. A
476
- * date-only value (`YYYYMMDD`) is a normal, complete value at day precision —
476
+ * date-only value (`YYYYMMDD`) is a normal, complete value at day precision:
477
477
  * **not** an error and never zero-filled into a fake time.
478
478
  */
479
479
  /** The precision to which an {@link AstmDate} is populated. */
@@ -482,7 +482,7 @@ type AstmDatePrecision = "year" | "month" | "day" | "hour" | "minute" | "second"
482
482
  * A parsed ASTM date/time. Immutable plain data; the populated fields extend
483
483
  * exactly as far as {@link AstmDate.precision}. Absent components are left
484
484
  * `undefined` rather than defaulted, so a consumer can tell "midnight" from
485
- * "no time given". No timezone is modeled — the value is instrument-local.
485
+ * "no time given". No timezone is modeled: the value is instrument-local.
486
486
  *
487
487
  * @example
488
488
  * ```ts
@@ -504,10 +504,10 @@ interface AstmDate {
504
504
  /** How far the components are populated. */
505
505
  readonly precision: AstmDatePrecision;
506
506
  /**
507
- * `true` when the digit run does **not** align to a whole-component boundary — an odd number of
507
+ * `true` when the digit run does **not** align to a whole-component boundary: an odd number of
508
508
  * digits that cuts a two-digit component (month/day/hour/minute/second) in half (lengths 5, 7, 9,
509
509
  * 11, 13). The full run is preserved in {@link AstmDate.raw} and the structured value is truncated
510
- * to the last **complete** component — the dangling digit is **never zero-filled into a fabricated
510
+ * to the last **complete** component: the dangling digit is **never zero-filled into a fabricated
511
511
  * time**. Absent (never `false`) for a clean value. A caller surfaces this as a value-free
512
512
  * `ASTM_RECORD_PARTIAL_TIMESTAMP` warning.
513
513
  */
@@ -516,7 +516,7 @@ interface AstmDate {
516
516
  /**
517
517
  * Parse an ASTM `YYYYMMDDHHMMSS` value, preserving whatever precision is
518
518
  * present. Returns `undefined` for a value that is not a usable timestamp (fewer
519
- * than four leading digits for the year, or non-digit content) — a caller keeps
519
+ * than four leading digits for the year, or non-digit content): a caller keeps
520
520
  * the raw field text either way, so nothing is lost. A partial value is parsed,
521
521
  * never rejected.
522
522
  *
@@ -535,7 +535,7 @@ interface AstmDate {
535
535
  declare function parseAstmDate(raw: string): AstmDate | undefined;
536
536
  /**
537
537
  * Render an {@link AstmDate} as an ISO-8601-*like* string truncated to its
538
- * precision, with **no** `Z` and **no** offset — because ASTM carries no
538
+ * precision, with **no** `Z` and **no** offset: because ASTM carries no
539
539
  * timezone and appending one would fabricate information. A consumer that knows
540
540
  * the instrument's zone can attach it; this function never assumes UTC.
541
541
  *
@@ -556,9 +556,9 @@ declare function astmDateToLocalISO(d: AstmDate): string;
556
556
  * spec's component order is LOINC-slot / test-name / coding-scheme / local-code.
557
557
  * In the field the way real analyzers emit it:
558
558
  *
559
- * - **component 1** is a LOINC slot — *almost always empty*; a few vendors place
559
+ * - **component 1** is a LOINC slot: *almost always empty*; a few vendors place
560
560
  * an inline LOINC when one exists;
561
- * - **component 4** is the vendor/local code — the identifier that is actually
561
+ * - **component 4** is the vendor/local code: the identifier that is actually
562
562
  * present, and therefore the **primary** identifier here.
563
563
  *
564
564
  * Following the sibling parsers' conservative posture, this module is a
@@ -568,11 +568,11 @@ declare function astmDateToLocalISO(d: AstmDate): string;
568
568
  */
569
569
  /** Where a Universal Test ID's usable identifier came from. */
570
570
  type UniversalTestIdProvenance =
571
- /** Component 1 (the LOINC slot) is populated — a candidate LOINC, recognized not validated. */
571
+ /** Component 1 (the LOINC slot) is populated: a candidate LOINC, recognized not validated. */
572
572
  "inline-loinc-candidate"
573
573
  /** Component 4 (the vendor/local code) carries the identifier. */
574
574
  | "local-code"
575
- /** Only the test name (component 2) is present — no code. */
575
+ /** Only the test name (component 2) is present: no code. */
576
576
  | "name-only"
577
577
  /** Nothing usable in the field. */
578
578
  | "empty";
@@ -591,13 +591,13 @@ type UniversalTestIdProvenance =
591
591
  interface UniversalTestId {
592
592
  /** The field's components, verbatim and in order. */
593
593
  readonly components: readonly string[];
594
- /** Component 1 when populated — a *candidate* LOINC (provenance only, never validated). */
594
+ /** Component 1 when populated: a *candidate* LOINC (provenance only, never validated). */
595
595
  readonly loincCandidate?: string;
596
- /** Component 2 — the test / battery name, when present. */
596
+ /** Component 2: the test / battery name, when present. */
597
597
  readonly testName?: string;
598
- /** Component 3 — the coding-scheme selector, when present. */
598
+ /** Component 3: the coding-scheme selector, when present. */
599
599
  readonly codingScheme?: string;
600
- /** Component 4 — the vendor/local code: the primary identifier when no inline LOINC is given. */
600
+ /** Component 4, the vendor/local code: the primary identifier when no inline LOINC is given. */
601
601
  readonly localCode?: string;
602
602
  /** Where the primary identifier came from. */
603
603
  readonly provenance: UniversalTestIdProvenance;
@@ -617,7 +617,7 @@ declare function recognizeUniversalTestId(components: readonly string[]): Univer
617
617
  /**
618
618
  * The primary code to key a result on: the inline LOINC candidate when a vendor
619
619
  * supplied one, otherwise the local (vendor) code. Returns `undefined` when the
620
- * field carries no code at all (name-only or empty) — never a guess.
620
+ * field carries no code at all (name-only or empty): never a guess.
621
621
  *
622
622
  * @param u - A recognized Universal Test ID.
623
623
  * @returns The primary code, or `undefined`.
@@ -633,7 +633,7 @@ declare function primaryCode(u: UniversalTestId): string | undefined;
633
633
  * Positional context for frame-codec warnings and errors.
634
634
  *
635
635
  * **PHI discipline (the whole point).** A frame deviation is located by **frame
636
- * number + byte offset** and nothing else — never the record text a frame
636
+ * number + byte offset** and nothing else: never the record text a frame
637
637
  * carries. A frame warning or error may be logged verbatim without ever leaking a
638
638
  * result value, a patient identifier, or any other field the reassembled record
639
639
  * bytes contain.
@@ -659,12 +659,12 @@ interface AstmFramePosition {
659
659
  }
660
660
 
661
661
  /**
662
- * The **frame** warning registry (`ASTM_FRAME_*`) for the ASTM/CLSI-LIS01 codec —
662
+ * The **frame** warning registry (`ASTM_FRAME_*`) for the ASTM/CLSI-LIS01 codec:
663
663
  * the second of the package's two registries, alongside the record layer's
664
664
  * `ASTM_RECORD_*` (both share only the `EMPTY_INPUT` fatal).
665
665
  *
666
666
  * A frame warning is the lenient codec's record of a tolerated byte-level
667
- * deviation: it never crashes, never invents a value, and — critically — never
667
+ * deviation: it never crashes, never invents a value, and, critically, never
668
668
  * lets an untrusted frame be silently merged into a record. Every warning carries
669
669
  * a stable code plus an {@link AstmFramePosition} (frame number + byte offset) and
670
670
  * **never** the record bytes a frame carries (PHI discipline). Consumers compare
@@ -689,12 +689,12 @@ declare const FRAME_WARNING_CODES: {
689
689
  * A frame's two-hex-char checksum did not match the modulo-256 sum recomputed over its bytes. The
690
690
  * frame is surfaced with `trusted: false` and its text is **never merged** into a reassembled
691
691
  * record (default **warn** in lenient mode, escalated to a thrown error in `strict`). Corruption is
692
- * never silently trusted — the "checksums are routinely not validated" claim was refuted; we
692
+ * never silently trusted: the "checksums are routinely not validated" claim was refuted; we
693
693
  * validate.
694
694
  */
695
695
  readonly ASTM_FRAME_BAD_CHECKSUM: "ASTM_FRAME_BAD_CHECKSUM";
696
696
  /**
697
- * A frame's sequence number was not the expected next value (`1 → … → 7 → 0 → …`) — a frame was
697
+ * A frame's sequence number was not the expected next value (`1 → … → 7 → 0 → …`): a frame was
698
698
  * possibly dropped. The stream is **never silently concatenated across the gap** as if contiguous;
699
699
  * the in-progress record is tainted and not emitted as a clean reassembly.
700
700
  */
@@ -708,7 +708,7 @@ declare const FRAME_WARNING_CODES: {
708
708
  readonly ASTM_FRAME_UNTERMINATED: "ASTM_FRAME_UNTERMINATED";
709
709
  /**
710
710
  * A frame's record text exceeded the 240-byte limit without a split. The frame is still surfaced
711
- * (and, if its checksum validates, reassembled) — the deviation is flagged, not silently dropped
711
+ * (and, if its checksum validates, reassembled): the deviation is flagged, not silently dropped
712
712
  * (warn in lenient, thrown in `strict`).
713
713
  */
714
714
  readonly ASTM_FRAME_OVERSIZE: "ASTM_FRAME_OVERSIZE";
@@ -785,14 +785,14 @@ declare function frameOversize(position: AstmFramePosition): AstmFrameWarning;
785
785
 
786
786
  /**
787
787
  * The **LTP** warning registry (`ASTM_LTP_*`) for the ASTM/CLSI-LIS01 protocol
788
- * layer — the third of the package's registries, alongside the record layer's
788
+ * layer: the third of the package's registries, alongside the record layer's
789
789
  * `ASTM_RECORD_*` and the frame codec's `ASTM_FRAME_*`.
790
790
  *
791
791
  * An LTP warning is the protocol reducer's (or the transport detector's) record
792
792
  * of a tolerated session-level deviation: an ambiguous framed/raw stream, a
793
793
  * control event that arrived in a state that did not expect it, or a frame the
794
794
  * receiver had to reject (`NAK`) rather than accept. Every warning carries a
795
- * stable code plus, at most, a **frame number** — never the record bytes a frame
795
+ * stable code plus, at most, a **frame number**: never the record bytes a frame
796
796
  * carries (PHI discipline). Consumers compare `warning.code ===
797
797
  * LTP_WARNING_CODES.<CODE>`; renaming a code is a **breaking change**.
798
798
  */
@@ -809,21 +809,21 @@ declare function frameOversize(position: AstmFramePosition): AstmFrameWarning;
809
809
  declare const LTP_WARNING_CODES: {
810
810
  /**
811
811
  * The transport detector could not tell a framed stream from a raw (unframed) one from its leading
812
- * byte — it was neither `STX`/`ENQ` nor a bare record letter. It **defaults to framed** and warns,
812
+ * byte: it was neither `STX`/`ENQ` nor a bare record letter. It **defaults to framed** and warns,
813
813
  * never guessing silently into data loss; a profile override forces the mode. (cobas b121 drops
814
- * framing over TCP; cobas 4800 / Iguana retain it — both realities exist, so an unrecognizable lead
814
+ * framing over TCP; cobas 4800 / Iguana retain it, both realities exist, so an unrecognizable lead
815
815
  * is defaulted, not assumed.)
816
816
  */
817
817
  readonly ASTM_LTP_AMBIGUOUS_TRANSPORT: "ASTM_LTP_AMBIGUOUS_TRANSPORT";
818
818
  /**
819
- * A control event arrived in a protocol state that did not expect it — e.g. an inbound `ACK`/`NAK`
819
+ * A control event arrived in a protocol state that did not expect it: e.g. an inbound `ACK`/`NAK`
820
820
  * at a receiver (which sends, never receives, those), or an `ENQ` mid-transfer. The event is
821
821
  * surfaced and handled defensively (an unexpected `ACK`/`NAK` is **never** read as acceptance of
822
822
  * data); it never advances the transfer as if valid.
823
823
  */
824
824
  readonly ASTM_LTP_UNEXPECTED_EVENT: "ASTM_LTP_UNEXPECTED_EVENT";
825
825
  /**
826
- * The receiver rejected a received frame with a `NAK` instead of accepting it — because its
826
+ * The receiver rejected a received frame with a `NAK` instead of accepting it: because its
827
827
  * checksum failed, it was unterminated, or its frame number was out of sequence. The frame's text
828
828
  * is **never** appended to the record and the transfer does **not** advance; the receiver awaits the
829
829
  * sender's retransmit. This is the protocol-level face of the frame codec's fail-safe: a bad frame
@@ -838,7 +838,7 @@ declare const LTP_WARNING_CODES: {
838
838
  type LtpWarningCode = (typeof LTP_WARNING_CODES)[keyof typeof LTP_WARNING_CODES];
839
839
  /**
840
840
  * A single LTP protocol / transport warning: a stable code, a value-free
841
- * human-readable message, and — for a frame-scoped deviation — the frame number
841
+ * human-readable message, and, for a frame-scoped deviation, the frame number
842
842
  * only. Never carries a frame's record bytes.
843
843
  *
844
844
  * @example
@@ -846,7 +846,7 @@ type LtpWarningCode = (typeof LTP_WARNING_CODES)[keyof typeof LTP_WARNING_CODES]
846
846
  * import type { AstmLtpWarning } from "@cosyte/astm";
847
847
  * const w: AstmLtpWarning = {
848
848
  * code: "ASTM_LTP_FRAME_REJECTED",
849
- * message: "Frame rejected — NAK sent, retransmit expected.",
849
+ * message: "Frame rejected, NAK sent, retransmit expected.",
850
850
  * frameNumber: 2,
851
851
  * };
852
852
  * ```
@@ -901,22 +901,22 @@ declare function ltpFrameRejected(frameNumber?: number): AstmLtpWarning;
901
901
  * (RS-232) always uses full E1381 framing. Over **TCP it varies within a single
902
902
  * vendor**: the Roche cobas 4800 and iNTERFACEWARE Iguana retain the full
903
903
  * `ENQ`/`ACK` + `STX`/checksum framing over TCP (**framed-TCP**), while the cobas
904
- * b121 drops all low-level framing — "TCP itself ensures correctness" — and streams
904
+ * b121 drops all low-level framing, "TCP itself ensures correctness", and streams
905
905
  * de-framed record bytes directly (**raw-TCP**). A reader must handle both and must
906
906
  * not assume the handshake is present.
907
907
  *
908
908
  * {@link detectFraming} decides which it is from the stream's leading byte: `STX`
909
909
  * or `ENQ` ⇒ framed (feed it to the frame codec + {@link ltpReduce}); a bare record
910
910
  * letter ⇒ raw (feed it straight to `parseAstmRecords`). Anything else is
911
- * **ambiguous**, and the fail-safe is to **default to framed** and warn — never to
912
- * guess silently into data loss — with an explicit override for a profile that
911
+ * **ambiguous**, and the fail-safe is to **default to framed** and warn, never to
912
+ * guess silently into data loss, with an explicit override for a profile that
913
913
  * knows better.
914
914
  */
915
915
 
916
916
  /**
917
917
  * The transport framing of an ASTM byte stream: `"framed"` (E1381 `STX`/checksum
918
918
  * frames, the serial and framed-TCP realities) or `"raw"` (framing dropped,
919
- * de-framed record bytes streamed directly — the raw-TCP reality).
919
+ * de-framed record bytes streamed directly, the raw-TCP reality).
920
920
  */
921
921
  type AstmFraming = "framed" | "raw";
922
922
  /**
@@ -925,7 +925,7 @@ type AstmFraming = "framed" | "raw";
925
925
  interface DetectFramingOptions {
926
926
  /**
927
927
  * A profile-supplied override. When set, detection is bypassed entirely and this
928
- * value is returned with no warning — the way a vendor profile forces raw for
928
+ * value is returned with no warning: the way a vendor profile forces raw for
929
929
  * a cobas b121 or framed for a cobas 4800 regardless of the leading byte.
930
930
  */
931
931
  readonly override?: AstmFraming;
@@ -975,7 +975,7 @@ declare function detectFraming(bytes: Uint8Array, options?: DetectFramingOptions
975
975
  * plus an optional **transport override** (the raw-vs-framed-TCP knob). It mirrors
976
976
  * the sibling `@cosyte/hl7` `defineProfile` and `@cosyte/ccda` `defineCcdaProfile`
977
977
  * shape (`name` / `lineage` / `describe()` / `extends`-merge) but models ASTM's
978
- * quirks — a warning code the stream is expected to trip, and its framing reality —
978
+ * quirks (a warning code the stream is expected to trip, and its framing reality)
979
979
  * rather than HL7 v2 Z-segments or C-CDA template deviations.
980
980
  *
981
981
  * A profile **never changes an extracted value**. It operates purely at the
@@ -984,29 +984,29 @@ declare function detectFraming(bytes: Uint8Array, options?: DetectFramingOptions
984
984
  * layer (forcing framed/raw before a single byte is parsed). The two load-bearing
985
985
  * safety rules, enforced by `defineAstmProfile`:
986
986
  *
987
- * 1. **A profile can never tolerate a safety-critical warning code** — a result
987
+ * 1. **A profile can never tolerate a safety-critical warning code**: a result
988
988
  * value, abnormal flag, result status, reference range, units, patient/comment
989
989
  * context, message-kind ambiguity, code system, or any frame/LTP integrity
990
990
  * warning (see `src/profiles/safety.ts`). Naming one is a *definition-time
991
- * throw*, not a silent relaxation — so a profile can never make a bad checksum
991
+ * throw*, not a silent relaxation, so a profile can never make a bad checksum
992
992
  * "ok" or a cancelled result read "final."
993
993
  * 2. **A tolerated deviation is downgraded, never dropped.** The parser still
994
994
  * records it (re-coded {@link WARNING_CODES.PROFILE_QUIRK_APPLIED}, flagged
995
995
  * `expected: true`, carrying the original `toleratedCode`) so nothing is
996
- * silently hidden — Postel's Law with a receipt.
996
+ * silently hidden, Postel's Law with a receipt.
997
997
  */
998
998
 
999
999
  /**
1000
- * Any warning code from any of the three registries — the record layer
1000
+ * Any warning code from any of the three registries: the record layer
1001
1001
  * (`ASTM_RECORD_*` / `ASTM_NONSTANDARD_DELIMITERS` / `ASTM_UNKNOWN_ESCAPE_SEQUENCE`),
1002
1002
  * the frame codec (`ASTM_FRAME_*`), or the LTP protocol layer (`ASTM_LTP_*`). A
1003
1003
  * {@link QuirkTolerance} may *name* any of them, but the safety gate refuses all
1004
- * but the small, benign, record-layer subset — so the union exists mainly to let
1004
+ * but the small, benign, record-layer subset, so the union exists mainly to let
1005
1005
  * the gate reject a frame/LTP code with a precise, typed message.
1006
1006
  */
1007
1007
  type AnyAstmWarningCode = WarningCode | FrameWarningCode | LtpWarningCode;
1008
1008
  /**
1009
- * Provenance for an {@link AstmProfile} — the **real, cited public artifact** a
1009
+ * Provenance for an {@link AstmProfile}: the **real, cited public artifact** a
1010
1010
  * profile's quirks are grounded in. A quirk is encoded only when a real
1011
1011
  * (de-identified) document or a redistributable reference corpus grounds it; this
1012
1012
  * record is where that grounding is stated, so a reviewer can trace every
@@ -1025,7 +1025,7 @@ type AnyAstmWarningCode = WarningCode | FrameWarningCode | LtpWarningCode;
1025
1025
  interface AstmProfileProvenance {
1026
1026
  /** Short human-readable name of the grounding source (corpus, transcript, or spec). */
1027
1027
  readonly source: string;
1028
- /** A citation the grounding can be traced to — a URL, DOI, or repo+path. */
1028
+ /** A citation the grounding can be traced to: a URL, DOI, or repo+path. */
1029
1029
  readonly reference: string;
1030
1030
  /** When the grounding was last verified (ISO date) or the pinned commit SHA. */
1031
1031
  readonly retrieved?: string;
@@ -1035,7 +1035,7 @@ interface AstmProfileProvenance {
1035
1035
  /**
1036
1036
  * Optional structural narrowing for a {@link QuirkTolerance}. When present, the
1037
1037
  * tolerance applies only to warnings whose PHI-free {@link AstmPosition} matches
1038
- * every provided field — so a profile can expect a deviation on one record type
1038
+ * every provided field, so a profile can expect a deviation on one record type
1039
1039
  * (e.g. an unknown escape only inside `R` result values) without blanket-tolerating
1040
1040
  * it everywhere. Matching is on **structural identifiers only** (record-type
1041
1041
  * letter, 1-based field index); there is no matching on any field *value*, by
@@ -1072,7 +1072,7 @@ interface AstmQuirkMatch {
1072
1072
  interface AstmQuirkTolerance {
1073
1073
  /** The existing, non-safety-critical warning code this profile expects. */
1074
1074
  readonly code: AnyAstmWarningCode;
1075
- /** Why the profile expects this deviation — grounded in its provenance. */
1075
+ /** Why the profile expects this deviation: grounded in its provenance. */
1076
1076
  readonly rationale: string;
1077
1077
  /** Optional structural narrowing (record type / field index). */
1078
1078
  readonly match?: AstmQuirkMatch;
@@ -1082,7 +1082,7 @@ interface AstmQuirkTolerance {
1082
1082
  * {@link defineAstmProfile}; consumers pass it to `parseAstmRecords(raw, { profile })`
1083
1083
  * (or register it as the process default), and feed its {@link AstmProfile.transport}
1084
1084
  * to `detectFraming(bytes, { override })`. Hand-authoring the object literal is
1085
- * supported but discouraged — the factory validates the safety rules and attaches
1085
+ * supported but discouraged: the factory validates the safety rules and attaches
1086
1086
  * `describe()`.
1087
1087
  *
1088
1088
  * @example
@@ -1097,13 +1097,13 @@ interface AstmProfile {
1097
1097
  readonly name: string;
1098
1098
  /** Optional human-readable description. */
1099
1099
  readonly description?: string;
1100
- /** Resolved lineage — `[...parents, name]`, first-occurrence deduped. */
1100
+ /** Resolved lineage: `[...parents, name]`, first-occurrence deduped. */
1101
1101
  readonly lineage: readonly string[];
1102
1102
  /** The expected, non-safety-critical deviations this profile tolerates. */
1103
1103
  readonly tolerate: readonly AstmQuirkTolerance[];
1104
1104
  /**
1105
1105
  * The raw-vs-framed-TCP override. When set, a consumer forces this framing via
1106
- * `detectFraming(bytes, { override: profile.transport })` — the way a profile
1106
+ * `detectFraming(bytes, { override: profile.transport })`, the way a profile
1107
1107
  * that knows a vendor's transport reality (e.g. framing dropped over raw TCP)
1108
1108
  * bypasses leading-byte auto-detection. Absent means "let detection decide."
1109
1109
  */
@@ -1150,33 +1150,33 @@ interface DefineAstmProfileOptions {
1150
1150
  * coerced to `normal`**.
1151
1151
  * - A **result status** (field 9) is modeled so a **correction (`C`)** or a
1152
1152
  * **cancellation (`X`)** can never read as an active-final result, and an
1153
- * **absent** status is a typed `unspecified` — **never assumed `F` (final)**.
1153
+ * **absent** status is a typed `unspecified`: **never assumed `F` (final)**.
1154
1154
  * - A **reference range** (field 6) is parsed into a low/high (or open-ended)
1155
- * pair; an unparseable range is surfaced **verbatim** — a bound is **never
1155
+ * pair; an unparseable range is surfaced **verbatim**, a bound is **never
1156
1156
  * fabricated**.
1157
1157
  *
1158
1158
  * Every bound and code is surfaced verbatim; nothing is collapsed, reconciled,
1159
1159
  * or converted. Units are handled at the record layer (a numeric value without
1160
- * units warns; units are never defaulted, guessed, or converted — see
1160
+ * units warns; units are never defaulted, guessed, or converted, see
1161
1161
  * `./parse.ts`).
1162
1162
  */
1163
1163
  /**
1164
1164
  * The recognized abnormal-flag letters, from **HL7 v2.2 Table 0078** (the flag
1165
- * *value* set — a published fact set, not CLSI prose). Read in the context of an
1165
+ * *value* set, a published fact set, not CLSI prose). Read in the context of an
1166
1166
  * `R` record's field 7: here `S`/`R`/`I` are the microbiology susceptibility
1167
1167
  * codes and `R` is **not** the repeat delimiter.
1168
1168
  */
1169
1169
  type AbnormalFlagCode = "L" | "H" | "LL" | "HH" | "<" | ">" | "N" | "A" | "AA" | "U" | "D" | "B" | "W" | "S" | "R" | "I";
1170
1170
  /**
1171
1171
  * The modeled meaning of a recognized {@link AbnormalFlagCode}, plus the two
1172
- * fail-safe sentinels: `undefined` (a flag was present but is not in Table 0078)
1173
- * — which is **never** collapsed to `normal`.
1172
+ * fail-safe sentinels: `undefined` (a flag was present but is not in Table 0078),
1173
+ * which is **never** collapsed to `normal`.
1174
1174
  */
1175
1175
  type AbnormalFlagMeaning = "below-normal" | "above-normal" | "critically-below-normal" | "critically-above-normal" | "below-scale" | "above-scale" | "normal" | "abnormal" | "very-abnormal" | "significant-change-up" | "significant-change-down" | "better" | "worse" | "susceptible" | "resistant" | "intermediate" | "undefined";
1176
1176
  /**
1177
1177
  * A recognized (or explicitly *un*recognized) abnormal flag. The raw field text
1178
1178
  * is always preserved; `recognized` is `false` and `meaning` is `"undefined"`
1179
- * for any letter outside Table 0078 — the flag is surfaced, never dropped, and
1179
+ * for any letter outside Table 0078, the flag is surfaced, never dropped, and
1180
1180
  * **never coerced to `normal`**.
1181
1181
  *
1182
1182
  * @example
@@ -1202,7 +1202,7 @@ interface AbnormalFlag {
1202
1202
  *
1203
1203
  * Leading/trailing whitespace is ignored for the lookup but the `raw` text is
1204
1204
  * preserved verbatim. An unrecognized flag yields `{ recognized: false, meaning:
1205
- * "undefined" }` — surfaced, never dropped, and **never `"normal"`**.
1205
+ * "undefined" }`, surfaced, never dropped, and **never `"normal"`**.
1206
1206
  *
1207
1207
  * @param raw - The verbatim field-7 text.
1208
1208
  * @returns The interpreted flag.
@@ -1216,13 +1216,13 @@ interface AbnormalFlag {
1216
1216
  declare function interpretAbnormalFlag(raw: string): AbnormalFlag;
1217
1217
  /**
1218
1218
  * The recognized result-status letters (`R`-record field 9). The clinically
1219
- * load-bearing members are **`C` (correction — supersedes a previously
1219
+ * load-bearing members are **`C` (correction, supersedes a previously
1220
1220
  * transmitted value)** and **`X` (cannot be done / cancelled)**.
1221
1221
  */
1222
1222
  type ResultStatusCode = "F" | "C" | "P" | "R" | "S" | "I" | "X";
1223
1223
  /**
1224
1224
  * The modeled meaning of a result status, plus two fail-safe sentinels:
1225
- * `unspecified` (the field was absent — **never assumed `final`**) and
1225
+ * `unspecified` (the field was absent, **never assumed `final`**) and
1226
1226
  * `undefined` (a letter was present but is not a recognized status).
1227
1227
  */
1228
1228
  type ResultStatusMeaning = "final" | "correction" | "preliminary" | "previously-transmitted" | "partial" | "pending" | "cancelled" | "unspecified" | "undefined";
@@ -1232,11 +1232,11 @@ type ResultStatusMeaning = "final" | "correction" | "preliminary" | "previously-
1232
1232
  *
1233
1233
  * - **`isActiveFinal`** is `true` **only** for a plain `F` (final). It is `false`
1234
1234
  * for a correction (`C`), a cancellation (`X`), a preliminary/partial/pending
1235
- * result, an absent status, and an unrecognized one — so a superseded or
1235
+ * result, an absent status, and an unrecognized one, so a superseded or
1236
1236
  * cancelled result can **never** read as current/final.
1237
- * - **`supersedes`** is `true` for `C` — this value replaces a previously
1237
+ * - **`supersedes`** is `true` for `C`: this value replaces a previously
1238
1238
  * transmitted one.
1239
- * - **`cancelled`** is `true` for `X` — the result cannot be done / was cancelled.
1239
+ * - **`cancelled`** is `true` for `X`: the result cannot be done / was cancelled.
1240
1240
  *
1241
1241
  * @example
1242
1242
  * ```ts
@@ -1255,17 +1255,17 @@ interface ResultStatus {
1255
1255
  readonly meaning: ResultStatusMeaning;
1256
1256
  /** Whether the raw text matched a recognized status letter. */
1257
1257
  readonly recognized: boolean;
1258
- /** `true` **only** for a plain `F` (final) — never for `C`, `X`, absent, or unrecognized. */
1258
+ /** `true` **only** for a plain `F` (final): never for `C`, `X`, absent, or unrecognized. */
1259
1259
  readonly isActiveFinal: boolean;
1260
- /** `true` for `C` — this value supersedes a previously transmitted result. */
1260
+ /** `true` for `C`: this value supersedes a previously transmitted result. */
1261
1261
  readonly supersedes: boolean;
1262
- /** `true` for `X` — the result cannot be done / was cancelled. */
1262
+ /** `true` for `X`: the result cannot be done / was cancelled. */
1263
1263
  readonly cancelled: boolean;
1264
1264
  }
1265
1265
  /**
1266
1266
  * Interpret an `R`-record result-status field (field 9).
1267
1267
  *
1268
- * An **absent** status (`undefined` or empty) is typed `unspecified` — **never
1268
+ * An **absent** status (`undefined` or empty) is typed `unspecified`: **never
1269
1269
  * assumed `final`**. A **present but unrecognized** letter is `undefined`
1270
1270
  * (recognized `false`). In every non-`F` case `isActiveFinal` is `false`, so a
1271
1271
  * correction, a cancellation, or an unknown status can never read as current.
@@ -1284,10 +1284,10 @@ declare function interpretResultStatus(raw: string | undefined): ResultStatus;
1284
1284
  /**
1285
1285
  * The shape of a parsed reference range.
1286
1286
  *
1287
- * - `closed` — both a low and a high bound (`3.5-5.0`).
1288
- * - `open-low` — an upper bound only (`<5`): everything at or below `high`.
1289
- * - `open-high` — a lower bound only (`>10`): everything at or above `low`.
1290
- * - `unparsed` — the text did not match a recognized form; both bounds are
1287
+ * - `closed`: both a low and a high bound (`3.5-5.0`).
1288
+ * - `open-low`: an upper bound only (`<5`), so everything at or below `high`.
1289
+ * - `open-high`: a lower bound only (`>10`), so everything at or above `low`.
1290
+ * - `unparsed`: the text did not match a recognized form; both bounds are
1291
1291
  * absent and the raw text is surfaced. **A bound is never fabricated.**
1292
1292
  */
1293
1293
  type ReferenceRangeKind = "closed" | "open-low" | "open-high" | "unparsed";
@@ -1296,7 +1296,7 @@ type ReferenceRangeKind = "closed" | "open-low" | "open-high" | "unparsed";
1296
1296
  * (never coerced to a float, never rounded, never converted) so nothing is lost
1297
1297
  * or fabricated.
1298
1298
  *
1299
- * **`[OSS-derived]` — the exact lower/upper delimiter (`-`) and the open-ended
1299
+ * **`[OSS-derived]`: the exact lower/upper delimiter (`-`) and the open-ended
1300
1300
  * `<x`/`>x` forms are taken from the permissively-licensed OSS reference parsers
1301
1301
  * and cross-verified vendor transcripts; they are not confirmed against the
1302
1302
  * purchased CLSI LIS02-A2. Anything that does not match these
@@ -1326,8 +1326,8 @@ interface ReferenceRange {
1326
1326
  * open-ended) pair.
1327
1327
  *
1328
1328
  * Recognized forms are `low-high` (closed), `<high` (open-low), and `>low`
1329
- * (open-high). Anything else — including an ambiguous multi-dash string or a
1330
- * bare non-numeric token — is returned as `kind: "unparsed"` with the raw text
1329
+ * (open-high). Anything else, including an ambiguous multi-dash string or a
1330
+ * bare non-numeric token, is returned as `kind: "unparsed"` with the raw text
1331
1331
  * preserved and **no bound invented**. Bounds are surfaced as verbatim text, not
1332
1332
  * coerced to numbers.
1333
1333
  *
@@ -1349,7 +1349,7 @@ declare function parseReferenceRange(raw: string): ReferenceRange;
1349
1349
  * A message is a header (which carries the resolved delimiters as provenance), an
1350
1350
  * ordered list of typed records, and the Tier-2 warnings the lenient parser
1351
1351
  * accumulated. Every record keeps its raw {@link AstmField}s **and** the typed
1352
- * accessors relevant to its type — the raw tree is always present so nothing the
1352
+ * accessors relevant to its type: the raw tree is always present so nothing the
1353
1353
  * parser did not model is lost.
1354
1354
  *
1355
1355
  * `H`/`P`/`O`/`R`/`C`/`Q`/`M`/`S`/`L` are modeled; every other type letter is an
@@ -1388,7 +1388,7 @@ interface RecordBase {
1388
1388
  interface HeaderRecord extends RecordBase {
1389
1389
  readonly type: "H";
1390
1390
  /**
1391
- * The four delimiters **this** header put into force — the set its own fields, and every record
1391
+ * The four delimiters **this** header put into force: the set its own fields, and every record
1392
1392
  * after it, were read with.
1393
1393
  *
1394
1394
  * A stream may carry several messages (`H` … `L`) and each header declares its own set, so on a
@@ -1403,7 +1403,7 @@ interface HeaderRecord extends RecordBase {
1403
1403
  * delimiters are read from this raw text, never from {@link RecordBase.fields}.
1404
1404
  *
1405
1405
  * It is **not** what the serializer emits from. To change a header field, edit
1406
- * {@link RecordBase.fields} — `fields[0]` is the type letter, `fields[1]` is the
1406
+ * {@link RecordBase.fields}: `fields[0]` is the type letter, `fields[1]` is the
1407
1407
  * delimiter declaration, and the header's ASTM data fields follow from `fields[2]`.
1408
1408
  * Editing this string instead has no effect on emit.
1409
1409
  */
@@ -1422,63 +1422,63 @@ interface PatientName {
1422
1422
  * The `P` (patient) record.
1423
1423
  *
1424
1424
  * **Safety:** the practice-assigned ID (field 3) and the laboratory-assigned ID
1425
- * (field 4) are modeled as **distinct** fields and never collapsed — conflating
1425
+ * (field 4) are modeled as **distinct** fields and never collapsed, conflating
1426
1426
  * them is the primary result-misfiling path.
1427
1427
  */
1428
1428
  interface PatientRecord extends RecordBase {
1429
1429
  readonly type: "P";
1430
- /** Field 2 — sequence number. */
1430
+ /** Field 2: sequence number. */
1431
1431
  readonly seq?: string;
1432
- /** Field 3 — practice-assigned patient ID. Distinct from {@link PatientRecord.laboratoryAssignedId}. */
1432
+ /** Field 3: practice-assigned patient ID. Distinct from {@link PatientRecord.laboratoryAssignedId}. */
1433
1433
  readonly practiceAssignedId?: string;
1434
- /** Field 4 — laboratory-assigned patient ID. Distinct from {@link PatientRecord.practiceAssignedId}. */
1434
+ /** Field 4: laboratory-assigned patient ID. Distinct from {@link PatientRecord.practiceAssignedId}. */
1435
1435
  readonly laboratoryAssignedId?: string;
1436
1436
  /**
1437
- * Field 5 — a third patient identifier (e.g. a national/alternate ID), surfaced verbatim. Kept
1438
- * separate from the practice- and laboratory-assigned IDs — the three never collapse into one.
1437
+ * Field 5: a third patient identifier (e.g. a national/alternate ID), surfaced verbatim. Kept
1438
+ * separate from the practice- and laboratory-assigned IDs: the three never collapse into one.
1439
1439
  */
1440
1440
  readonly patientIdThree?: string;
1441
- /** Field 6 — patient name (`Last^First^Middle`). */
1441
+ /** Field 6: patient name (`Last^First^Middle`). */
1442
1442
  readonly name?: PatientName;
1443
- /** Field 7 — mother's maiden name, surfaced verbatim (a surname component; PHI). */
1443
+ /** Field 7: mother's maiden name, surfaced verbatim (a surname component; PHI). */
1444
1444
  readonly mothersMaidenName?: string;
1445
- /** Field 8 — birthdate (`YYYYMMDDHHMMSS`, precision-preserving; a truncated run sets `truncated`). */
1445
+ /** Field 8: birthdate (`YYYYMMDDHHMMSS`, precision-preserving; a truncated run sets `truncated`). */
1446
1446
  readonly birthDate?: AstmDate;
1447
- /** Field 9 — sex, surfaced raw (`M`/`F`/`U`/vendor value). */
1447
+ /** Field 9: sex, surfaced raw (`M`/`F`/`U`/vendor value). */
1448
1448
  readonly sex?: string;
1449
1449
  }
1450
1450
  /**
1451
- * The `O` (order) record — binds a result to a specimen.
1451
+ * The `O` (order) record: binds a result to a specimen.
1452
1452
  */
1453
1453
  interface OrderRecord extends RecordBase {
1454
1454
  readonly type: "O";
1455
- /** Field 2 — sequence number. */
1455
+ /** Field 2: sequence number. */
1456
1456
  readonly seq?: string;
1457
- /** Field 3 — specimen / accession ID. */
1457
+ /** Field 3: specimen / accession ID. */
1458
1458
  readonly specimenId?: string;
1459
- /** Field 4 — instrument specimen ID. */
1459
+ /** Field 4: instrument specimen ID. */
1460
1460
  readonly instrumentSpecimenId?: string;
1461
- /** Field 5 — Universal Test ID (same caret structure as a result's). */
1461
+ /** Field 5: Universal Test ID (same caret structure as a result's). */
1462
1462
  readonly universalTestId?: UniversalTestId;
1463
1463
  /**
1464
- * Field 6 — priority, surfaced raw (e.g. `S` STAT, `R` routine, `A` ASAP). Vendor letters vary;
1464
+ * Field 6: priority, surfaced raw (e.g. `S` STAT, `R` routine, `A` ASAP). Vendor letters vary;
1465
1465
  * the code set is `[OSS-derived]` (the exact enumeration is in the paywalled CLSI LIS02-A2), so the
1466
1466
  * value is surfaced verbatim and **never mapped to a guessed meaning**.
1467
1467
  */
1468
1468
  readonly priority?: string;
1469
1469
  /**
1470
- * Field 12 — action code, surfaced raw (e.g. `C` cancel, `A` add, `N` new). The exact field index
1471
- * (`~12`) and the code set are `[OSS-derived]` (paywalled) — surfaced verbatim, never interpreted.
1470
+ * Field 12: action code, surfaced raw (e.g. `C` cancel, `A` add, `N` new). The exact field index
1471
+ * (`~12`) and the code set are `[OSS-derived]` (paywalled): surfaced verbatim, never interpreted.
1472
1472
  */
1473
1473
  readonly actionCode?: string;
1474
1474
  /**
1475
- * Field 26 — report type, surfaced raw (e.g. `F` final, `P` preliminary, `X` cancel). The exact
1476
- * field index (`~26`) and the code set are `[OSS-derived]` (paywalled) — surfaced verbatim.
1475
+ * Field 26: report type, surfaced raw (e.g. `F` final, `P` preliminary, `X` cancel). The exact
1476
+ * field index (`~26`) and the code set are `[OSS-derived]` (paywalled): surfaced verbatim.
1477
1477
  */
1478
1478
  readonly reportType?: string;
1479
1479
  }
1480
1480
  /**
1481
- * The `R` (result) record — the value itself.
1481
+ * The `R` (result) record: the value itself.
1482
1482
  *
1483
1483
  * The raw safety-critical fields (value, `units`, `referenceRange`,
1484
1484
  * `abnormalFlags`, `resultStatus`) are always surfaced exactly as received.
@@ -1486,94 +1486,94 @@ interface OrderRecord extends RecordBase {
1486
1486
  * (Table 0078, `undefined` never coerced to normal), `status` (a `C`/`X` never
1487
1487
  * reads as active-final; an absent status is `unspecified`, never `final`), and
1488
1488
  * `range` (open/closed bounds surfaced verbatim, never fabricated). The raw
1489
- * strings and the modeled views coexist — nothing is collapsed or reconciled.
1489
+ * strings and the modeled views coexist: nothing is collapsed or reconciled.
1490
1490
  */
1491
1491
  interface ResultRecord extends RecordBase {
1492
1492
  readonly type: "R";
1493
- /** Field 2 — sequence number. */
1493
+ /** Field 2: sequence number. */
1494
1494
  readonly seq?: string;
1495
- /** Field 3 — Universal Test ID (local code in component 4 is the primary identifier). */
1495
+ /** Field 3: Universal Test ID (local code in component 4 is the primary identifier). */
1496
1496
  readonly universalTestId?: UniversalTestId;
1497
1497
  /**
1498
- * Field 4 — the measured value. In the ordinary single-component case this is the decoded scalar.
1498
+ * Field 4: the measured value. In the ordinary single-component case this is the decoded scalar.
1499
1499
  * When the value field carried an *unescaped* component delimiter (an ambiguity), this is the
1500
- * **full raw field text** — never a truncated component — and {@link ResultRecord.valueComponents}
1500
+ * **full raw field text**, never a truncated component, and {@link ResultRecord.valueComponents}
1501
1501
  * plus an `ASTM_RECORD_AMBIGUOUS_VALUE_SPLIT` warning are also present.
1502
1502
  */
1503
1503
  readonly value?: string;
1504
1504
  /**
1505
1505
  * Field 4 split into components, present only when the value field carried an *unescaped* component
1506
- * delimiter — i.e. it read as more than one component. Surfaced alongside the full raw value (and a
1506
+ * delimiter: i.e. it read as more than one component. Surfaced alongside the full raw value (and a
1507
1507
  * warning) so an ambiguous split is visible, never resolved silently.
1508
1508
  */
1509
1509
  readonly valueComponents?: readonly string[];
1510
- /** Field 5 — units (vendor free text; a missing unit is not defaulted). */
1510
+ /** Field 5: units (vendor free text; a missing unit is not defaulted). */
1511
1511
  readonly units?: string;
1512
- /** Field 6 — reference range, surfaced raw. */
1512
+ /** Field 6: reference range, surfaced raw. */
1513
1513
  readonly referenceRange?: string;
1514
1514
  /**
1515
- * Field 6 — the reference range parsed into low/high (or open-ended) bounds, present only when the
1515
+ * Field 6: the reference range parsed into low/high (or open-ended) bounds, present only when the
1516
1516
  * field carried a value. An unparseable range is `kind: "unparsed"` with the raw text preserved and
1517
1517
  * **no bound fabricated**. Bounds are verbatim numeric text, never coerced to floats.
1518
1518
  */
1519
1519
  readonly range?: ReferenceRange;
1520
- /** Field 7 — abnormal flags, surfaced raw (HL7 Table 0078 values). */
1520
+ /** Field 7: abnormal flags, surfaced raw (HL7 Table 0078 values). */
1521
1521
  readonly abnormalFlags?: string;
1522
1522
  /**
1523
- * Field 7 — the abnormal flag interpreted against HL7 Table 0078, present only when the field
1524
- * carried a value. An unrecognized flag is `{ recognized: false, meaning: "undefined" }` — surfaced,
1523
+ * Field 7: the abnormal flag interpreted against HL7 Table 0078, present only when the field
1524
+ * carried a value. An unrecognized flag is `{ recognized: false, meaning: "undefined" }`, surfaced,
1525
1525
  * never dropped, and **never coerced to `normal`**.
1526
1526
  */
1527
1527
  readonly flag?: AbnormalFlag;
1528
- /** Field 9 — result status, surfaced raw (`F`/`C`/`X`/…). */
1528
+ /** Field 9: result status, surfaced raw (`F`/`C`/`X`/…). */
1529
1529
  readonly resultStatus?: string;
1530
1530
  /**
1531
- * Field 9 — the modeled result status. **Always present** (an absent field yields a typed
1531
+ * Field 9: the modeled result status. **Always present** (an absent field yields a typed
1532
1532
  * `unspecified`, never assumed `final`), so `status.isActiveFinal` is always a reliable boolean: it
1533
1533
  * is `true` only for a plain `F`, and `false` for a correction (`C`), a cancellation (`X`), a
1534
1534
  * partial/preliminary/pending, an absent, or an unrecognized status.
1535
1535
  */
1536
1536
  readonly status: ResultStatus;
1537
- /** Field 11 — operator. */
1537
+ /** Field 11: operator. */
1538
1538
  readonly operator?: string;
1539
- /** Field 12 — test started timestamp. */
1539
+ /** Field 12: test started timestamp. */
1540
1540
  readonly startedAt?: AstmDate;
1541
- /** Field 13 — test completed timestamp. */
1541
+ /** Field 13: test completed timestamp. */
1542
1542
  readonly completedAt?: AstmDate;
1543
- /** Field 14 — instrument identifier. */
1543
+ /** Field 14: instrument identifier. */
1544
1544
  readonly instrument?: string;
1545
1545
  }
1546
1546
  /**
1547
- * The `C` (comment) record — free-text context attached to a parent record.
1547
+ * The `C` (comment) record: free-text context attached to a parent record.
1548
1548
  *
1549
1549
  * A comment is **attached by position** to the immediately-preceding `H`/`P`/`O`/`R` record
1550
1550
  * ({@link CommentRecord.parentIndex}); consecutive comments share that parent. **Fail-safe:** a
1551
- * comment with no valid preceding parent is an **orphan** — it is attached to the message root
1551
+ * comment with no valid preceding parent is an **orphan**: it is attached to the message root
1552
1552
  * ({@link CommentRecord.attachedToRoot} `true`) and a value-free `ASTM_RECORD_ORPHAN_COMMENT` warning
1553
- * fires — **never silently dropped**, so a comment carrying (e.g.) "QC / non-compliant" context can
1553
+ * fires, **never silently dropped**, so a comment carrying (e.g.) "QC / non-compliant" context can
1554
1554
  * never float away unnoticed.
1555
1555
  */
1556
1556
  interface CommentRecord extends RecordBase {
1557
1557
  readonly type: "C";
1558
- /** Field 2 — sequence number. */
1558
+ /** Field 2: sequence number. */
1559
1559
  readonly seq?: string;
1560
- /** Field 3 — comment source (who/what produced it), surfaced verbatim. */
1560
+ /** Field 3: comment source (who/what produced it), surfaced verbatim. */
1561
1561
  readonly source?: string;
1562
1562
  /**
1563
- * Field 4 — the comment text, surfaced as the **full** field text (all components), never
1563
+ * Field 4: the comment text, surfaced as the **full** field text (all components), never
1564
1564
  * truncated to the first component. The component structure is in {@link CommentRecord.textComponents}.
1565
1565
  */
1566
1566
  readonly text?: string;
1567
1567
  /**
1568
- * Field 4 — the comment text split into its decoded components (comment text is component-capable;
1568
+ * Field 4: the comment text split into its decoded components (comment text is component-capable;
1569
1569
  * multiple components are a normal structured comment, **not** an ambiguity). Present only when the
1570
1570
  * field carried more than one component.
1571
1571
  */
1572
1572
  readonly textComponents?: readonly string[];
1573
1573
  /**
1574
- * Field 5 — comment type code, surfaced verbatim. **`[OSS-derived]`:** `I` (instrument) is the only
1574
+ * Field 5: comment type code, surfaced verbatim. **`[OSS-derived]`:** `I` (instrument) is the only
1575
1575
  * value seen in the permissively-licensed real transcripts; other values (e.g. `G`/`T`/`P`) are
1576
- * defined only in the paywalled CLSI LIS02-A2 and are **not** interpreted here — the raw code is
1576
+ * defined only in the paywalled CLSI LIS02-A2 and are **not** interpreted here: the raw code is
1577
1577
  * surfaced, never mapped to a guessed meaning.
1578
1578
  */
1579
1579
  readonly commentType?: string;
@@ -1582,57 +1582,57 @@ interface CommentRecord extends RecordBase {
1582
1582
  * the comment is an orphan attached to the message root (see {@link CommentRecord.attachedToRoot}).
1583
1583
  */
1584
1584
  readonly parentIndex?: number;
1585
- /** `true` when no valid parent preceded — the comment is attached to the message root (and warned). */
1585
+ /** `true` when no valid parent preceded: the comment is attached to the message root (and warned). */
1586
1586
  readonly attachedToRoot: boolean;
1587
1587
  }
1588
1588
  /**
1589
- * The `Q` (Request Information) record — the host-query request.
1589
+ * The `Q` (Request Information) record: the host-query request.
1590
1590
  *
1591
1591
  * A `Q` record asks the LIS for information (e.g. outstanding orders for a
1592
1592
  * specimen); its **presence classifies the whole message as a request, never a
1593
1593
  * result set** (see {@link AstmMessage.classification}). Its safety-relevant
1594
- * fields — the starting/ending range ID and the request-information status — are
1594
+ * fields, the starting/ending range ID and the request-information status, are
1595
1595
  * surfaced **verbatim**; the field *positions* are the public ASTM E1394 layout,
1596
1596
  * but their internal structure and code meanings are **`[OSS-derived / paywalled]`**
1597
1597
  * and are therefore **never interpreted or guessed**.
1598
1598
  */
1599
1599
  interface QueryRecord extends RecordBase {
1600
- /** Field 2 — sequence number. */
1600
+ /** Field 2: sequence number. */
1601
1601
  readonly seq?: string;
1602
1602
  readonly type: "Q";
1603
1603
  /**
1604
- * Field 3 — starting range ID number, surfaced as the **full** verbatim field text (never truncated
1604
+ * Field 3: starting range ID number, surfaced as the **full** verbatim field text (never truncated
1605
1605
  * to a component). Its caret component structure (e.g. patient ID ^ specimen ID) is
1606
- * **`[OSS-derived / paywalled]`** — the raw split is available via {@link RecordBase.fields}, but the
1606
+ * **`[OSS-derived / paywalled]`**: the raw split is available via {@link RecordBase.fields}, but the
1607
1607
  * *meaning* of each component is **never** assigned here.
1608
1608
  */
1609
1609
  readonly startingRangeId?: string;
1610
- /** Field 4 — ending range ID number, surfaced verbatim (same `[OSS-derived]` caveat as field 3). */
1610
+ /** Field 4: ending range ID number, surfaced verbatim (same `[OSS-derived]` caveat as field 3). */
1611
1611
  readonly endingRangeId?: string;
1612
1612
  /**
1613
- * Field 5 — Universal Test ID (the same caret structure as an `O`/`R` record's), recognized by
1613
+ * Field 5: Universal Test ID (the same caret structure as an `O`/`R` record's), recognized by
1614
1614
  * provenance only. When the field is the literal universal-query keyword, {@link QueryRecord.queriesAllTests}
1615
- * is set instead — see its caveat.
1615
+ * is set instead: see its caveat.
1616
1616
  */
1617
1617
  readonly universalTestId?: UniversalTestId;
1618
1618
  /**
1619
1619
  * `true` when field 5 is the literal `ALL` universal-query keyword (case-insensitive). **`[OSS-derived
1620
1620
  * / paywalled]`:** the token is surfaced because it appears in the OSS references, but its exact
1621
1621
  * host-query *behavior* (which tests a bare `ALL` selects, and whether the vendor answers with a full
1622
- * `H/P/O/L` or a `P/O`-only response) is paywalled and vendor-specific — **not decided here**.
1622
+ * `H/P/O/L` or a `P/O`-only response) is paywalled and vendor-specific, **not decided here**.
1623
1623
  */
1624
1624
  readonly queriesAllTests: boolean;
1625
1625
  /**
1626
- * Field 13 — request-information status code(s), surfaced **verbatim**. The status code *set* is
1626
+ * Field 13: request-information status code(s), surfaced **verbatim**. The status code *set* is
1627
1627
  * **`[OSS-derived / paywalled]`**: with no publicly-groundable enumeration, this
1628
- * parser recognizes **none** of them and interprets nothing — every present status is surfaced raw
1628
+ * parser recognizes **none** of them and interprets nothing, every present status is surfaced raw
1629
1629
  * and flagged with a value-free `ASTM_RECORD_UNINTERPRETED_QUERY_STATUS` warning. Never mapped to a
1630
1630
  * guessed meaning.
1631
1631
  */
1632
1632
  readonly requestInformationStatus?: string;
1633
1633
  }
1634
1634
  /**
1635
- * The `M` (manufacturer) record — vendor-defined free-form data
1635
+ * The `M` (manufacturer) record: vendor-defined free-form data
1636
1636
  * (QC / calibration / maintenance), surfaced **VERBATIM** and **never interpreted
1637
1637
  * into typed clinical fields**.
1638
1638
  *
@@ -1647,7 +1647,7 @@ interface ManufacturerRecord extends RecordBase {
1647
1647
  * The record's exact wire text (terminator excluded), preserved byte-for-byte.
1648
1648
  *
1649
1649
  * Emit reproduces these bytes exactly whenever a reader using the delimiters being
1650
- * emitted against would recover the fields this record models — always the case when
1650
+ * emitted against would recover the fields this record models: always the case when
1651
1651
  * the record is already in those delimiters, and also when it carries no delimiter
1652
1652
  * either set would split on. Otherwise the record is re-encoded from
1653
1653
  * {@link RecordBase.fields}, so the row can never go out in delimiters the header does
@@ -1656,7 +1656,7 @@ interface ManufacturerRecord extends RecordBase {
1656
1656
  readonly rawLine: string;
1657
1657
  }
1658
1658
  /**
1659
- * The `S` (scientific) record — vendor-defined free-form data, surfaced
1659
+ * The `S` (scientific) record: vendor-defined free-form data, surfaced
1660
1660
  * **VERBATIM** and **never interpreted into typed clinical fields** (same posture
1661
1661
  * as {@link ManufacturerRecord}).
1662
1662
  */
@@ -1666,7 +1666,7 @@ interface ScientificRecord extends RecordBase {
1666
1666
  * The record's exact wire text (terminator excluded), preserved byte-for-byte.
1667
1667
  *
1668
1668
  * Emit reproduces these bytes exactly whenever a reader using the delimiters being
1669
- * emitted against would recover the fields this record models — always the case when
1669
+ * emitted against would recover the fields this record models: always the case when
1670
1670
  * the record is already in those delimiters, and also when it carries no delimiter
1671
1671
  * either set would split on. Otherwise the record is re-encoded from
1672
1672
  * {@link RecordBase.fields}, so the row can never go out in delimiters the header does
@@ -1675,7 +1675,7 @@ interface ScientificRecord extends RecordBase {
1675
1675
  readonly rawLine: string;
1676
1676
  }
1677
1677
  /**
1678
- * The `L` (terminator) record — closes a message.
1678
+ * The `L` (terminator) record: closes a message.
1679
1679
  */
1680
1680
  interface TerminatorRecord extends RecordBase {
1681
1681
  readonly type: "L";
@@ -1684,7 +1684,7 @@ interface TerminatorRecord extends RecordBase {
1684
1684
  * Any record whose type letter is not modeled (a genuinely unknown letter).
1685
1685
  * `H`/`P`/`O`/`R`/`C`/`Q`/`M`/`S`/`L` are all modeled; anything else is surfaced
1686
1686
  * with its raw fields intact and flagged with an
1687
- * `ASTM_RECORD_UNKNOWN_TYPE` warning — never dropped.
1687
+ * `ASTM_RECORD_UNKNOWN_TYPE` warning, never dropped.
1688
1688
  */
1689
1689
  interface UnsupportedRecord extends RecordBase {
1690
1690
  readonly type: "unsupported";
@@ -1696,30 +1696,30 @@ type AstmRecord = HeaderRecord | PatientRecord | OrderRecord | ResultRecord | Co
1696
1696
  /**
1697
1697
  * How a message is classified by the host-query flow.
1698
1698
  *
1699
- * - `host-query` — the message carries at least one `Q` record: it is a **request
1699
+ * - `host-query` (the message carries at least one `Q` record): it is a **request
1700
1700
  * for information**, and **must never be read as a result set** (the load-bearing
1701
1701
  * safety distinction of this layer). `Q` **dominates**: a `Q` present classifies
1702
1702
  * the message as a request even if a result record is also present (an anomaly,
1703
- * separately warned) — so a `Q`-bearing message is never silently treated as a
1703
+ * separately warned), so a `Q`-bearing message is never silently treated as a
1704
1704
  * result upload.
1705
- * - `results` — no `Q`, at least one `R` (result) record: a result upload / response.
1706
- * - `orders` — no `Q`, no `R`, at least one `O` (order) record: an order download,
1705
+ * - `results` (no `Q`, at least one `R` result record): a result upload / response.
1706
+ * - `orders` (no `Q`, no `R`, at least one `O` order record): an order download,
1707
1707
  * or a query response before results are attached.
1708
- * - `indeterminate` — none of the above (e.g. header + terminator only). Not
1708
+ * - `indeterminate`: none of the above (e.g. header + terminator only). Not
1709
1709
  * guessed into one of the other kinds.
1710
1710
  */
1711
1711
  type AstmMessageKind = "host-query" | "results" | "orders" | "indeterminate";
1712
1712
  /**
1713
1713
  * The message-level classification from the host-query flow. `isHostQueryRequest`
1714
1714
  * is the single boolean a consumer should gate on before treating records as
1715
- * results — it is `true` **iff** a `Q` record is present.
1715
+ * results: it is `true` **iff** a `Q` record is present.
1716
1716
  *
1717
1717
  * @example
1718
1718
  * ```ts
1719
1719
  * import { parseAstmRecords } from "@cosyte/astm";
1720
1720
  * const req = parseAstmRecords("H|\\^&\rP|1\rQ|1|^SPEC-7||ALL\rL|1\r");
1721
1721
  * req.classification.kind; // "host-query"
1722
- * req.classification.isHostQueryRequest; // true — never read its records as results
1722
+ * req.classification.isHostQueryRequest; // true, never read its records as results
1723
1723
  * ```
1724
1724
  */
1725
1725
  interface AstmMessageClassification {
@@ -1732,7 +1732,7 @@ interface AstmMessageClassification {
1732
1732
  /** At least one `O` (order) record is present. */
1733
1733
  readonly hasOrders: boolean;
1734
1734
  /**
1735
- * `true` **iff** `kind === "host-query"` (a `Q` record is present) — the safety surface: gate on this
1735
+ * `true` **iff** `kind === "host-query"` (a `Q` record is present), the safety surface: gate on this
1736
1736
  * before treating records as results, so a query is never misread as a result upload.
1737
1737
  */
1738
1738
  readonly isHostQueryRequest: boolean;
@@ -1758,12 +1758,12 @@ interface AstmMessage {
1758
1758
  *
1759
1759
  * A stream may carry several messages (`H` … `L`), and a later header may declare a different set,
1760
1760
  * which is honored from that header onward. So this is not necessarily the set every record was
1761
- * read with — each header reports its own on {@link HeaderRecord.delimiters}, and a change is
1761
+ * read with: each header reports its own on {@link HeaderRecord.delimiters}, and a change is
1762
1762
  * flagged `ASTM_RECORD_DELIMITERS_REDECLARED`.
1763
1763
  */
1764
1764
  readonly delimiters: Delimiters;
1765
1765
  /**
1766
- * The host-query classification of this message — whether it is a request (`Q`
1766
+ * The host-query classification of this message: whether it is a request (`Q`
1767
1767
  * present), a result upload, an order download, or indeterminate. Gate on
1768
1768
  * {@link AstmMessageClassification.isHostQueryRequest} before reading records as
1769
1769
  * results.
@@ -1771,7 +1771,7 @@ interface AstmMessage {
1771
1771
  readonly classification: AstmMessageClassification;
1772
1772
  readonly warnings: readonly AstmRecordWarning[];
1773
1773
  /**
1774
- * The vendor profile that was active for this parse, when one applied — its
1774
+ * The vendor profile that was active for this parse, when one applied: its
1775
1775
  * `name` and resolved `lineage` (attribution only; the profile object itself is
1776
1776
  * not embedded). Absent when no profile applied. A profile that tolerated a
1777
1777
  * deviation shows up as a `PROFILE_QUIRK_APPLIED` entry in {@link warnings}, not
@@ -1789,7 +1789,7 @@ interface AstmParseOptions {
1789
1789
  /**
1790
1790
  * When `true`, escalate any Tier-2 deviation to a thrown {@link AstmStrictError}
1791
1791
  * instead of accumulating a warning. Off by default. A deviation a profile
1792
- * *expected* (a `PROFILE_QUIRK_APPLIED`) does **not** escalate — it is known,
1792
+ * *expected* (a `PROFILE_QUIRK_APPLIED`) does **not** escalate: it is known,
1793
1793
  * benign, and still recorded.
1794
1794
  */
1795
1795
  readonly strict?: boolean;
@@ -1809,7 +1809,7 @@ interface AstmParseOptions {
1809
1809
  * It assumes **already-de-framed** record bytes; {@link parseFramedAstm} composes
1810
1810
  * the E1381/LIS01 framing layer with this one. It reads the four delimiters from each
1811
1811
  * `H` record, tokenizes every record escape-aware, and builds the immutable
1812
- * {@link AstmMessage} — lenient by default: vendor quirks become typed warnings, and
1812
+ * {@link AstmMessage}, lenient by default: vendor quirks become typed warnings, and
1813
1813
  * only three unrecoverable structural conditions are fatal.
1814
1814
  */
1815
1815
 
@@ -1838,7 +1838,7 @@ declare class AstmStrictError extends Error {
1838
1838
  *
1839
1839
  * The stream is a sequence of records separated by `CR` (with `LF`/`CRLF`
1840
1840
  * tolerated); the first record must be an `H` header, which declares the
1841
- * delimiters. Lenient by default — set `strict` to reject any tolerated deviation.
1841
+ * delimiters. Lenient by default: set `strict` to reject any tolerated deviation.
1842
1842
  *
1843
1843
  * **Several messages in one stream.** A message runs `H` … `L`, so a stream may carry
1844
1844
  * more than one, and each `H` declares the delimiters for the records that follow it.
@@ -1847,7 +1847,7 @@ declare class AstmStrictError extends Error {
1847
1847
  * they were read with, so a redeclaration never reinterprets earlier bytes. A header
1848
1848
  * that merely restates the set in force is a no-op and warns nothing. A later header
1849
1849
  * that cannot declare a usable set keeps the delimiters already in force and warns
1850
- * `ASTM_RECORD_UNREADABLE_REDECLARATION` — a set is never guessed, and no record is
1850
+ * `ASTM_RECORD_UNREADABLE_REDECLARATION`: a set is never guessed, and no record is
1851
1851
  * dropped. Per-header sets are on each {@link HeaderRecord.delimiters};
1852
1852
  * {@link AstmMessage.delimiters} is the first header's.
1853
1853
  *
@@ -1867,9 +1867,9 @@ declare class AstmStrictError extends Error {
1867
1867
  */
1868
1868
  declare function parseAstmRecords(raw: string | Uint8Array, options?: AstmParseOptions): AstmMessage;
1869
1869
  /**
1870
- * Attach every `C` (comment) record to its parent by position — the immediately-preceding
1870
+ * Attach every `C` (comment) record to its parent by position: the immediately-preceding
1871
1871
  * `H`/`P`/`O`/`R` record; consecutive comments share that parent. **Fail-safe:** a comment with no
1872
- * valid preceding parent is an **orphan** — it is attached to the message root (`attachedToRoot:
1872
+ * valid preceding parent is an **orphan**, it is attached to the message root (`attachedToRoot:
1873
1873
  * true`) with an `ASTM_RECORD_ORPHAN_COMMENT` warning, **never dropped**. Returns a new array; the
1874
1874
  * non-comment records pass through unchanged.
1875
1875
  *
@@ -1901,19 +1901,19 @@ declare function attachComments(records: readonly AstmRecord[], warnings: AstmRe
1901
1901
  * each record with a `CR`.
1902
1902
  *
1903
1903
  * **Round-trip.** `parseAstmRecords(serializeAstmRecords(msg))` reproduces the modeled
1904
- * records — the same components, the same typed accessors, and the canonical delimiter
1904
+ * records: the same components, the same typed accessors, and the canonical delimiter
1905
1905
  * set (a non-canonical source is normalized to `H|\^&` by default). Normalizing sets the
1906
1906
  * four delimiter **roles**; it does not delete a declaration's surplus characters, so a
1907
1907
  * canonically-declared header that arrived carrying surplus keeps it on the default path
1908
1908
  * too.
1909
1909
  *
1910
- * **One delimiter set for the whole stream.** Every record — including `H`, `M` and `S` —
1910
+ * **One delimiter set for the whole stream.** Every record (including `H`, `M` and `S`)
1911
1911
  * is emitted against the delimiters being emitted with, and the header declares that same
1912
1912
  * set. `M` and `S` carry vendor free-form data and are reproduced **byte-for-byte** from
1913
1913
  * their preserved `rawLine` whenever a reader using those delimiters would recover exactly
1914
1914
  * the fields they model, which is the case for any stream already in the emit delimiter
1915
- * set. When it is not — the record arrived under one delimiter set and is being emitted
1916
- * under another — the record is re-encoded from its decoded tree instead, so its fields
1915
+ * set. When it is not, the record arrived under one delimiter set and is being emitted
1916
+ * under another, the record is re-encoded from its decoded tree instead, so its fields
1917
1917
  * survive as fields rather than collapsing into one on the next read.
1918
1918
  *
1919
1919
  * **Emit follows the model.** Every record type, `H` included, is emitted from its decoded
@@ -1921,7 +1921,7 @@ declare function attachComments(records: readonly AstmRecord[], warnings: AstmRe
1921
1921
  * part of a record that is never taken from the model is the header's delimiter
1922
1922
  * declaration, and only in the three positions that carry a role: those always state the
1923
1923
  * repeat, component and escape characters actually in use, whatever the model says. Any
1924
- * further characters the declaration carried — a reader assigns them no role — come from
1924
+ * further characters the declaration carried, a reader assigns them no role, come from
1925
1925
  * the model like everything else, so a header that arrived as `H|\^&#` goes back out as
1926
1926
  * `H|\^&#` rather than losing the `#`. That holds on the **default** canonical path as
1927
1927
  * well as when a set is passed explicitly: the surplus of a canonically-declared header
@@ -1935,19 +1935,19 @@ declare function attachComments(records: readonly AstmRecord[], warnings: AstmRe
1935
1935
  * never emitted raw.
1936
1936
  *
1937
1937
  * **Check the delimiter set before writing.** Three conditions are required for the
1938
- * emitted bytes to read back as the records that produced them — each separator exactly
1939
- * one character, no separator a `CR`/`LF`, no two separators the same character — and a
1938
+ * emitted bytes to read back as the records that produced them (each separator exactly
1939
+ * one character, no separator a `CR`/`LF`, no two separators the same character) and a
1940
1940
  * set failing any of them is a typed {@link AstmSerializeError}
1941
1941
  * (`ASTM_EMIT_INVALID_DELIMITERS`) rather than output this library's own parser would
1942
1942
  * reject or silently re-read with a different field tree. These are **necessary**
1943
1943
  * conditions, not a guarantee of readback: a set can pass all three and still produce a
1944
- * stream that reads back wrong — a separator that collides with a record's type letter
1944
+ * stream that reads back wrong, a separator that collides with a record's type letter
1945
1945
  * is the known case, and it corrupts identically with or without this check.
1946
1946
  */
1947
1947
 
1948
1948
  /**
1949
1949
  * Thrown by the record/frame emit side when a value cannot be serialized into a
1950
- * spec-clean stream — specifically when a component contains a record terminator
1950
+ * spec-clean stream: specifically when a component contains a record terminator
1951
1951
  * (`CR`/`LF`), which the ASTM escape codec cannot encode and which would break
1952
1952
  * framing if emitted raw. Carries a stable code + positional context, never the
1953
1953
  * offending value (PHI discipline).
@@ -1978,9 +1978,9 @@ declare class AstmSerializeError extends Error {
1978
1978
  /**
1979
1979
  * The reasons emit refuses rather than writing a stream that cannot be read back.
1980
1980
  *
1981
- * - `ASTM_EMIT_UNENCODABLE_VALUE` — a component holds a record terminator
1981
+ * - `ASTM_EMIT_UNENCODABLE_VALUE`: a component holds a record terminator
1982
1982
  * (`CR`/`LF`), which the escape codec has no mnemonic for.
1983
- * - `ASTM_EMIT_INVALID_DELIMITERS` — the delimiter set to emit against failed one
1983
+ * - `ASTM_EMIT_INVALID_DELIMITERS`: the delimiter set to emit against failed one
1984
1984
  * of the three conditions readback requires (see {@link serializeAstmRecords}).
1985
1985
  * Those conditions are necessary rather than sufficient, so this code means a
1986
1986
  * set was rejected, not that every unreversible set is.
@@ -1993,7 +1993,7 @@ declare class AstmSerializeError extends Error {
1993
1993
  */
1994
1994
  type AstmSerializeErrorCode = "ASTM_EMIT_UNENCODABLE_VALUE" | "ASTM_EMIT_INVALID_DELIMITERS";
1995
1995
  /**
1996
- * Escape-encode one component leaf for spec-clean emit — the inverse of
1996
+ * Escape-encode one component leaf for spec-clean emit: the inverse of
1997
1997
  * `decodeEscapes`. The **escape character itself is encoded first** (`&` → `&E&`)
1998
1998
  * so a later delimiter substitution can never double-encode the `&` it just
1999
1999
  * introduced; then the field / component / repeat delimiters map to their
@@ -2009,7 +2009,7 @@ type AstmSerializeErrorCode = "ASTM_EMIT_UNENCODABLE_VALUE" | "ASTM_EMIT_INVALID
2009
2009
  * @returns The escaped component text.
2010
2010
  * @throws {@link AstmSerializeError} for a `CR`/`LF` in the leaf
2011
2011
  * (`ASTM_EMIT_UNENCODABLE_VALUE`), or for a delimiter set failing one of the
2012
- * three conditions readback requires (`ASTM_EMIT_INVALID_DELIMITERS`) — which
2012
+ * three conditions readback requires (`ASTM_EMIT_INVALID_DELIMITERS`), which
2013
2013
  * are necessary, not sufficient, so a set can pass them and still not reverse.
2014
2014
  * @example
2015
2015
  * ```ts
@@ -2023,8 +2023,8 @@ declare function encodeComponent(leaf: string, d: Delimiters, recordIndex?: numb
2023
2023
  * terminator). Emits with the given delimiters, defaulting to the canonical set.
2024
2024
  *
2025
2025
  * The header (`H`) is special-cased: its delimiter-definition field is emitted as
2026
- * the **literal** declaration of `d`, never escaped — escaping it would corrupt the
2027
- * very declaration a reader depends on — followed by any characters the modeled
2026
+ * the **literal** declaration of `d`, never escaped, escaping it would corrupt the
2027
+ * very declaration a reader depends on, followed by any characters the modeled
2028
2028
  * declaration carried beyond the three a reader takes its roles from. Manufacturer
2029
2029
  * (`M`) and scientific (`S`) records are reproduced **byte-identically** from their
2030
2030
  * preserved `rawLine` when they are already in `d`, and re-encoded from their fields
@@ -2035,7 +2035,7 @@ declare function encodeComponent(leaf: string, d: Delimiters, recordIndex?: numb
2035
2035
  * @returns The record's wire text, terminator excluded.
2036
2036
  * @throws {@link AstmSerializeError} when a component contains an unencodable `CR`/`LF`
2037
2037
  * (`ASTM_EMIT_UNENCODABLE_VALUE`), or when `d` fails one of the three conditions
2038
- * readback requires (`ASTM_EMIT_INVALID_DELIMITERS`) — necessary conditions, not
2038
+ * readback requires (`ASTM_EMIT_INVALID_DELIMITERS`): necessary conditions, not
2039
2039
  * sufficient ones, so a set can pass them and still not reverse.
2040
2040
  * @example
2041
2041
  * ```ts
@@ -2047,11 +2047,11 @@ declare function encodeComponent(leaf: string, d: Delimiters, recordIndex?: numb
2047
2047
  declare function serializeAstmRecord(record: AstmRecord, d?: Delimiters): string;
2048
2048
  /**
2049
2049
  * Serialize a whole ASTM message (or a bare record list) to a spec-clean,
2050
- * `CR`-terminated record stream — the inverse of `parseAstmRecords`.
2050
+ * `CR`-terminated record stream: the inverse of `parseAstmRecords`.
2051
2051
  *
2052
2052
  * Emit is **conservative**: the canonical `H|\^&` delimiters, every embedded
2053
2053
  * delimiter re-escaped, each record closed with a `CR`. A message parsed with
2054
- * non-canonical delimiters is **normalized** to the canonical set on emit — every
2054
+ * non-canonical delimiters is **normalized** to the canonical set on emit: every
2055
2055
  * record, `M` and `S` included, so the emitted stream is in one delimiter set and
2056
2056
  * re-parsing it recovers every field. Passing `d` explicitly emits against that set
2057
2057
  * instead, and the header declares it. Normalization replaces the four delimiter
@@ -2060,11 +2060,11 @@ declare function serializeAstmRecord(record: AstmRecord, d?: Delimiters): string
2060
2060
  *
2061
2061
  * **`d` is checked before anything is written.** Each of the four separators must be
2062
2062
  * exactly one character, none may be a record terminator, and no two may share a
2063
- * character — otherwise the emitted bytes cannot be read back as the records that
2063
+ * character: otherwise the emitted bytes cannot be read back as the records that
2064
2064
  * produced them, and emit has no warning channel with which to say so. A set that
2065
2065
  * fails is an {@link AstmSerializeError} with code `ASTM_EMIT_INVALID_DELIMITERS`.
2066
2066
  * This is stricter than the parser, which reads some sets it cannot reverse, so
2067
- * `serializeAstmRecords(msg, msg.delimiters)` can refuse a message that parsed —
2067
+ * `serializeAstmRecords(msg, msg.delimiters)` can refuse a message that parsed:
2068
2068
  * in exactly the cases where it used to emit a stream that read back wrong. The
2069
2069
  * three conditions are necessary rather than sufficient: a set that passes them can
2070
2070
  * still read back wrong if a separator collides with a record's type letter, which
@@ -2075,7 +2075,7 @@ declare function serializeAstmRecord(record: AstmRecord, d?: Delimiters): string
2075
2075
  * @returns The serialized record stream (`CR` after every record).
2076
2076
  * @throws {@link AstmSerializeError} when a component contains an unencodable `CR`/`LF`
2077
2077
  * (`ASTM_EMIT_UNENCODABLE_VALUE`), or when `d` fails one of the three conditions
2078
- * readback requires (`ASTM_EMIT_INVALID_DELIMITERS`) — necessary conditions, not
2078
+ * readback requires (`ASTM_EMIT_INVALID_DELIMITERS`): necessary conditions, not
2079
2079
  * sufficient ones, so a set can pass them and still not reverse.
2080
2080
  * @example
2081
2081
  * ```ts
@@ -2095,7 +2095,7 @@ declare function serializeAstmRecords(input: AstmMessage | readonly AstmRecord[]
2095
2095
  * @returns The escaped field text.
2096
2096
  * @throws {@link AstmSerializeError} when a component contains an unencodable `CR`/`LF`
2097
2097
  * (`ASTM_EMIT_UNENCODABLE_VALUE`), or when `d` fails one of the three conditions
2098
- * readback requires (`ASTM_EMIT_INVALID_DELIMITERS`) — necessary conditions, not
2098
+ * readback requires (`ASTM_EMIT_INVALID_DELIMITERS`): necessary conditions, not
2099
2099
  * sufficient ones, so a set can pass them and still not reverse.
2100
2100
  * @example
2101
2101
  * ```ts
@@ -2114,13 +2114,13 @@ declare function serializeField(field: AstmField, d?: Delimiters): string;
2114
2114
  *
2115
2115
  * - **Never fabricate.** A builder emits **only** the values the caller supplied.
2116
2116
  * An unsupplied field is left **empty**, never filled with a default clinical
2117
- * value — no defaulted result status, abnormal flag, units, value, or patient
2117
+ * value: no defaulted result status, abnormal flag, units, value, or patient
2118
2118
  * identifier. (Leaving a field empty is not a guess; inventing an `F` status or
2119
2119
  * an `N` flag would be.) A consumer that parses a built result whose status the
2120
2120
  * caller omitted reads `status.meaning === "unspecified"`, never `"final"`.
2121
2121
  * - **Compute, don't guess, the structure.** The record type letters, the
2122
2122
  * delimiter declaration (canonical `H|\^&`), the message terminator (`L`), and
2123
- * the per-record sequence counters are **structural** — computed by the builder,
2123
+ * the per-record sequence counters are **structural**: computed by the builder,
2124
2124
  * not clinical values. The caller may override any sequence number.
2125
2125
  *
2126
2126
  * Every value is escape-encoded on emit (via the serializer), so an embedded
@@ -2133,98 +2133,98 @@ interface PatientNameInput {
2133
2133
  readonly first?: string;
2134
2134
  readonly middle?: string;
2135
2135
  }
2136
- /** Input for a `P` (patient) record. The three IDs stay distinct — none defaults from another. */
2136
+ /** Input for a `P` (patient) record. The three IDs stay distinct: none defaults from another. */
2137
2137
  interface PatientInput {
2138
2138
  readonly type: "P";
2139
2139
  /** Structural sequence number; auto-computed when omitted. */
2140
2140
  readonly seq?: string;
2141
- /** Field 3 — practice-assigned patient ID. */
2141
+ /** Field 3: practice-assigned patient ID. */
2142
2142
  readonly practiceAssignedId?: string;
2143
- /** Field 4 — laboratory-assigned patient ID. */
2143
+ /** Field 4: laboratory-assigned patient ID. */
2144
2144
  readonly laboratoryAssignedId?: string;
2145
- /** Field 5 — a third patient identifier. */
2145
+ /** Field 5: a third patient identifier. */
2146
2146
  readonly patientIdThree?: string;
2147
- /** Field 6 — patient name (`Last^First^Middle`). */
2147
+ /** Field 6: patient name (`Last^First^Middle`). */
2148
2148
  readonly name?: PatientNameInput;
2149
- /** Field 7 — mother's maiden name. */
2149
+ /** Field 7: mother's maiden name. */
2150
2150
  readonly mothersMaidenName?: string;
2151
- /** Field 8 — birthdate (`YYYYMMDDHHMMSS`), emitted verbatim, never reformatted. */
2151
+ /** Field 8: birthdate (`YYYYMMDDHHMMSS`), emitted verbatim, never reformatted. */
2152
2152
  readonly birthDate?: string;
2153
- /** Field 9 — sex, emitted verbatim (never defaulted). */
2153
+ /** Field 9: sex, emitted verbatim (never defaulted). */
2154
2154
  readonly sex?: string;
2155
2155
  }
2156
2156
  /** Input for an `O` (order) record. */
2157
2157
  interface OrderInput {
2158
2158
  readonly type: "O";
2159
2159
  readonly seq?: string;
2160
- /** Field 3 — specimen / accession ID. */
2160
+ /** Field 3: specimen / accession ID. */
2161
2161
  readonly specimenId?: string;
2162
- /** Field 4 — instrument specimen ID. */
2162
+ /** Field 4: instrument specimen ID. */
2163
2163
  readonly instrumentSpecimenId?: string;
2164
- /** Field 5 — Universal Test ID components (verbatim, in order; e.g. `["", "", "", "687"]`). */
2164
+ /** Field 5: Universal Test ID components (verbatim, in order; e.g. `["", "", "", "687"]`). */
2165
2165
  readonly universalTestId?: readonly string[];
2166
- /** Field 6 — priority, emitted verbatim. */
2166
+ /** Field 6: priority, emitted verbatim. */
2167
2167
  readonly priority?: string;
2168
- /** Field 12 — action code, emitted verbatim. */
2168
+ /** Field 12: action code, emitted verbatim. */
2169
2169
  readonly actionCode?: string;
2170
- /** Field 26 — report type, emitted verbatim. */
2170
+ /** Field 26: report type, emitted verbatim. */
2171
2171
  readonly reportType?: string;
2172
2172
  }
2173
2173
  /** Input for an `R` (result) record. No clinical field is defaulted; unsupplied ⇒ empty. */
2174
2174
  interface ResultInput {
2175
2175
  readonly type: "R";
2176
2176
  readonly seq?: string;
2177
- /** Field 3 — Universal Test ID components (verbatim). */
2177
+ /** Field 3: Universal Test ID components (verbatim). */
2178
2178
  readonly universalTestId?: readonly string[];
2179
- /** Field 4 — the measured value, emitted verbatim (never defaulted). */
2179
+ /** Field 4: the measured value, emitted verbatim (never defaulted). */
2180
2180
  readonly value?: string;
2181
- /** Field 5 — units (vendor free text; never defaulted, guessed, or converted). */
2181
+ /** Field 5: units (vendor free text; never defaulted, guessed, or converted). */
2182
2182
  readonly units?: string;
2183
- /** Field 6 — reference range, emitted verbatim. */
2183
+ /** Field 6: reference range, emitted verbatim. */
2184
2184
  readonly referenceRange?: string;
2185
- /** Field 7 — abnormal flags, emitted verbatim (never defaulted to `N`). */
2185
+ /** Field 7: abnormal flags, emitted verbatim (never defaulted to `N`). */
2186
2186
  readonly abnormalFlags?: string;
2187
- /** Field 9 — result status, emitted verbatim (never defaulted to `F`). */
2187
+ /** Field 9: result status, emitted verbatim (never defaulted to `F`). */
2188
2188
  readonly resultStatus?: string;
2189
- /** Field 11 — operator. */
2189
+ /** Field 11: operator. */
2190
2190
  readonly operator?: string;
2191
- /** Field 12 — test-started timestamp (`YYYYMMDDHHMMSS`), verbatim. */
2191
+ /** Field 12: test-started timestamp (`YYYYMMDDHHMMSS`), verbatim. */
2192
2192
  readonly startedAt?: string;
2193
- /** Field 13 — test-completed timestamp, verbatim. */
2193
+ /** Field 13: test-completed timestamp, verbatim. */
2194
2194
  readonly completedAt?: string;
2195
- /** Field 14 — instrument identifier. */
2195
+ /** Field 14: instrument identifier. */
2196
2196
  readonly instrument?: string;
2197
2197
  }
2198
2198
  /** Input for a `C` (comment) record. */
2199
2199
  interface CommentInput {
2200
2200
  readonly type: "C";
2201
2201
  readonly seq?: string;
2202
- /** Field 3 — comment source. */
2202
+ /** Field 3: comment source. */
2203
2203
  readonly source?: string;
2204
- /** Field 4 — comment text (a single component). Use {@link CommentInput.textComponents} for a structured comment. */
2204
+ /** Field 4: comment text (a single component). Use {@link CommentInput.textComponents} for a structured comment. */
2205
2205
  readonly text?: string;
2206
- /** Field 4 — comment text as explicit components (takes precedence over `text` when set). */
2206
+ /** Field 4: comment text as explicit components (takes precedence over `text` when set). */
2207
2207
  readonly textComponents?: readonly string[];
2208
- /** Field 5 — comment type code, emitted verbatim. */
2208
+ /** Field 5: comment type code, emitted verbatim. */
2209
2209
  readonly commentType?: string;
2210
2210
  }
2211
2211
  /** Input for a `Q` (request-information) record. */
2212
2212
  interface QueryInput {
2213
2213
  readonly type: "Q";
2214
2214
  readonly seq?: string;
2215
- /** Field 3 — starting range ID, emitted verbatim. */
2215
+ /** Field 3: starting range ID, emitted verbatim. */
2216
2216
  readonly startingRangeId?: string;
2217
- /** Field 4 — ending range ID, emitted verbatim. */
2217
+ /** Field 4: ending range ID, emitted verbatim. */
2218
2218
  readonly endingRangeId?: string;
2219
- /** Field 5 — Universal Test ID components; ignored when {@link QueryInput.queriesAllTests} is set. */
2219
+ /** Field 5: Universal Test ID components; ignored when {@link QueryInput.queriesAllTests} is set. */
2220
2220
  readonly universalTestId?: readonly string[];
2221
- /** Field 5 — emit the literal `ALL` universal-query keyword instead of a Universal Test ID. */
2221
+ /** Field 5: emit the literal `ALL` universal-query keyword instead of a Universal Test ID. */
2222
2222
  readonly queriesAllTests?: boolean;
2223
- /** Field 13 — request-information status, emitted verbatim. */
2223
+ /** Field 13: request-information status, emitted verbatim. */
2224
2224
  readonly requestInformationStatus?: string;
2225
2225
  }
2226
2226
  /**
2227
- * Input for an `M` (manufacturer) or `S` (scientific) record — vendor-defined
2227
+ * Input for an `M` (manufacturer) or `S` (scientific) record: vendor-defined
2228
2228
  * free-form data. Emitted verbatim from the caller's fields; never interpreted.
2229
2229
  */
2230
2230
  interface VerbatimInput {
@@ -2246,7 +2246,7 @@ interface MessageInput {
2246
2246
  /** The body records, in order. `H` and `L` are supplied by the builder. */
2247
2247
  readonly records: readonly AstmRecordInput[];
2248
2248
  /**
2249
- * Field 3 of the auto-appended `L` (terminator) record — the termination code
2249
+ * Field 3 of the auto-appended `L` (terminator) record: the termination code
2250
2250
  * (e.g. `N` normal). Omitted by default (not defaulted to a value the caller
2251
2251
  * did not choose); the `L` seq is always emitted.
2252
2252
  */
@@ -2258,7 +2258,7 @@ interface MessageInput {
2258
2258
  * The builder emits the canonical `H|\^&` header (plus any header fields), then
2259
2259
  * every body record with each supplied field at its correct 1-based position and
2260
2260
  * every value escape-encoded, then an `L` terminator. **Nothing clinical is
2261
- * defaulted** — an unsupplied field is empty, never a guessed value — and the
2261
+ * defaulted** (an unsupplied field is empty, never a guessed value) and the
2262
2262
  * structural pieces (delimiters, record types, sequence counters, terminator) are
2263
2263
  * computed. The result parses back to an equal message: build → parse fidelity by
2264
2264
  * construction.
@@ -2278,7 +2278,7 @@ interface MessageInput {
2278
2278
  declare function buildAstmMessage(input: MessageInput): string;
2279
2279
 
2280
2280
  /**
2281
- * Typed extractors over an {@link AstmMessage} — the one-line "pull the value out"
2281
+ * Typed extractors over an {@link AstmMessage}: the one-line "pull the value out"
2282
2282
  * surface that is the package's north star.
2283
2283
  *
2284
2284
  * They are thin and immutable: they read the already-parsed model and never re-parse,
@@ -2287,7 +2287,7 @@ declare function buildAstmMessage(input: MessageInput): string;
2287
2287
  * **They are scoped to a single message, and they enforce it.** An `AstmMessage` models a
2288
2288
  * whole record **stream**, which may carry several `H` … `L` messages back to back. These
2289
2289
  * extractors read across the whole stream, so on a multi-message stream `patient()` used to
2290
- * answer with the first `P` in the stream while `results()` answered with every `R` in it —
2290
+ * answer with the first `P` in the stream while `results()` answered with every `R` in it:
2291
2291
  * pairing the two attributed one patient's results to another, silently and with no warning.
2292
2292
  * They now **refuse** that stream: an {@link AstmAmbiguousStreamError} instead of a confident
2293
2293
  * wrong answer, which is the same rule the rest of this parser follows. {@link messages} is
@@ -2303,7 +2303,7 @@ declare function buildAstmMessage(input: MessageInput): string;
2303
2303
  * @param msg - A parsed **single-message** stream.
2304
2304
  * @returns The result records (possibly empty).
2305
2305
  * @throws {@link AstmAmbiguousStreamError} (`ASTM_AMBIGUOUS_MULTI_MESSAGE`) when the stream
2306
- * carries more than one message — see {@link messages}.
2306
+ * carries more than one message: see {@link messages}.
2307
2307
  * @example
2308
2308
  * ```ts
2309
2309
  * import { parseAstmRecords, results } from "@cosyte/astm";
@@ -2318,7 +2318,7 @@ declare function results(msg: AstmMessage): readonly ResultRecord[];
2318
2318
  * This is the identity a result files against, so it is answered only when the stream
2319
2319
  * determines exactly one. It **refuses** the two shapes where "the patient" is a guess: a
2320
2320
  * stream carrying several messages, and a single message carrying several `P` records. In
2321
- * both, the old behaviour — the first `P` in the stream — is the wrong-patient path itself.
2321
+ * both, the old behaviour, the first `P` in the stream, is the wrong-patient path itself.
2322
2322
  *
2323
2323
  * @param msg - A parsed single-message stream carrying at most one patient.
2324
2324
  * @returns The patient record, or `undefined` when the message carries none.
@@ -2339,7 +2339,7 @@ declare function patient(msg: AstmMessage): PatientRecord | undefined;
2339
2339
  * @param msg - A parsed **single-message** stream.
2340
2340
  * @returns The order records (possibly empty).
2341
2341
  * @throws {@link AstmAmbiguousStreamError} (`ASTM_AMBIGUOUS_MULTI_MESSAGE`) when the stream
2342
- * carries more than one message — see {@link messages}.
2342
+ * carries more than one message: see {@link messages}.
2343
2343
  * @example
2344
2344
  * ```ts
2345
2345
  * import { parseAstmRecords, orders } from "@cosyte/astm";
@@ -2351,12 +2351,12 @@ declare function orders(msg: AstmMessage): readonly OrderRecord[];
2351
2351
  /**
2352
2352
  * Every comment (`C`) record in the message, in wire order. Each carries the
2353
2353
  * `parentIndex` of the `H`/`P`/`O`/`R` it attaches to (or `attachedToRoot` when
2354
- * it is an orphan) — use {@link commentsFor} to get the comments of one record.
2354
+ * it is an orphan): use {@link commentsFor} to get the comments of one record.
2355
2355
  *
2356
2356
  * @param msg - A parsed **single-message** stream.
2357
2357
  * @returns The comment records (possibly empty).
2358
2358
  * @throws {@link AstmAmbiguousStreamError} (`ASTM_AMBIGUOUS_MULTI_MESSAGE`) when the stream
2359
- * carries more than one message — see {@link messages}.
2359
+ * carries more than one message: see {@link messages}.
2360
2360
  * @example
2361
2361
  * ```ts
2362
2362
  * import { parseAstmRecords, comments } from "@cosyte/astm";
@@ -2371,7 +2371,7 @@ declare function comments(msg: AstmMessage): readonly CommentRecord[];
2371
2371
  * Unlike the other extractors this works on **any** stream, single- or multi-message: the
2372
2372
  * parent record it is handed already names the message, so there is nothing to disambiguate.
2373
2373
  * Returns the comments whose `parentIndex` is that record's `recordIndex`, so a
2374
- * comment carrying (e.g.) QC context is read against the record it modifies —
2374
+ * comment carrying (e.g.) QC context is read against the record it modifies:
2375
2375
  * never floated to the wrong one.
2376
2376
  *
2377
2377
  * @param msg - A parsed message.
@@ -2387,13 +2387,13 @@ declare function comments(msg: AstmMessage): readonly CommentRecord[];
2387
2387
  declare function commentsFor(msg: AstmMessage, parent: AstmRecord): readonly CommentRecord[];
2388
2388
  /**
2389
2389
  * Every request-information (`Q`) record in the message, in wire order. A non-empty
2390
- * result means the message is a **host-query request**, not a result set — see
2390
+ * result means the message is a **host-query request**, not a result set: see
2391
2391
  * {@link AstmMessage.classification} (`isHostQueryRequest`).
2392
2392
  *
2393
2393
  * @param msg - A parsed **single-message** stream.
2394
2394
  * @returns The query records (possibly empty).
2395
2395
  * @throws {@link AstmAmbiguousStreamError} (`ASTM_AMBIGUOUS_MULTI_MESSAGE`) when the stream
2396
- * carries more than one message — see {@link messages}.
2396
+ * carries more than one message: see {@link messages}.
2397
2397
  * @example
2398
2398
  * ```ts
2399
2399
  * import { parseAstmRecords, query } from "@cosyte/astm";
@@ -2404,13 +2404,13 @@ declare function commentsFor(msg: AstmMessage, parent: AstmRecord): readonly Com
2404
2404
  declare function query(msg: AstmMessage): readonly QueryRecord[];
2405
2405
 
2406
2406
  /**
2407
- * Message grouping — the safe replacement for the stream-scoped extractors.
2407
+ * Message grouping: the safe replacement for the stream-scoped extractors.
2408
2408
  *
2409
2409
  * A parsed {@link AstmMessage} models a whole **record stream**, and a stream may carry
2410
2410
  * several messages back to back: a message runs from an `H` header to its `L` terminator.
2411
2411
  * The flat extractors in `./extractors.js` read the whole stream, so on a multi-message
2412
2412
  * stream `patient(msg)` answered with the first `P` in the stream while `results(msg)`
2413
- * answered with every `R` in it — pairing the two, which is exactly what the package's
2413
+ * answered with every `R` in it: pairing the two, which is exactly what the package's
2414
2414
  * one-line north star does, attributed one patient's results to another. It needed no
2415
2415
  * redeclaration and no unusual delimiters, and it warned about nothing.
2416
2416
  *
@@ -2431,20 +2431,20 @@ declare function query(msg: AstmMessage): readonly QueryRecord[];
2431
2431
  * about the unit itself: a message is bounded by the `H` record at one end and the `L`
2432
2432
  * record at the other. That clause is in CLSI's free sample and is the whole of what is
2433
2433
  * claimed from the standard here. It does **not** settle which record *opens* a new scope
2434
- * partway through a stream, so treating a second `H` as the start of the next message —
2435
- * rather than, say, requiring an intervening `L` — is a reasoned choice, not a citation. It
2434
+ * partway through a stream, so treating a second `H` as the start of the next message
2435
+ * (rather than, say, requiring an intervening `L`) is a reasoned choice, not a citation. It
2436
2436
  * is made this way because it is the boundary this parser already enforces for delimiters,
2437
2437
  * and because it never drops a record.
2438
2438
  *
2439
- * **What is deliberately not modeled.** ASTM's within-message record hierarchy — which `P`
2440
- * a given `R` files against when one message carries several patients — is not modeled
2439
+ * **What is deliberately not modeled.** ASTM's within-message record hierarchy, which `P`
2440
+ * a given `R` files against when one message carries several patients, is not modeled
2441
2441
  * here. The clauses that would ground it (the message-level structure diagram, and the `P`
2442
2442
  * sequence-number rule) are withheld from the free sample and are paywalled, so rather than
2443
2443
  * guess a scoping rule this layer refuses to answer: a message carrying more than one `P`
2444
2444
  * leaves {@link AstmStreamMessage.patient} `undefined` and surfaces all of them on
2445
- * {@link AstmStreamMessage.patients}. Multi-patient messages are real — at least one
2445
+ * {@link AstmStreamMessage.patients}. Multi-patient messages are real, at least one
2446
2446
  * openly-published vendor interface grammar makes the patient group repeatable on the
2447
- * download direction — so this is a deferral with a known shape, not a claim that the case
2447
+ * download direction, so this is a deferral with a known shape, not a claim that the case
2448
2448
  * does not arise, and not a claim that the standard is silent about it.
2449
2449
  *
2450
2450
  * **The OSS corpus was checked and offers no prior art.** It is informative here, unlike
@@ -2478,11 +2478,11 @@ declare const AMBIGUOUS_CODES: {
2478
2478
  /** The one message in the stream carries more than one `P`, so "the patient" is not determined. */
2479
2479
  readonly ASTM_AMBIGUOUS_MULTI_PATIENT: "ASTM_AMBIGUOUS_MULTI_PATIENT";
2480
2480
  };
2481
- /** A value from {@link AMBIGUOUS_CODES} — the discriminant on {@link AstmAmbiguousStreamError}. */
2481
+ /** A value from {@link AMBIGUOUS_CODES}: the discriminant on {@link AstmAmbiguousStreamError}. */
2482
2482
  type AmbiguousCode = (typeof AMBIGUOUS_CODES)[keyof typeof AMBIGUOUS_CODES];
2483
2483
  /**
2484
2484
  * Thrown by a flat extractor when the stream it was handed does not determine a single
2485
- * answer — either because it carries several messages, or because its one message carries
2485
+ * answer: either because it carries several messages, or because its one message carries
2486
2486
  * several patients.
2487
2487
  *
2488
2488
  * The throw **is** the fix. A caller who gets this error is strictly better off than one
@@ -2506,7 +2506,7 @@ type AmbiguousCode = (typeof AMBIGUOUS_CODES)[keyof typeof AMBIGUOUS_CODES];
2506
2506
  * ```
2507
2507
  */
2508
2508
  declare class AstmAmbiguousStreamError extends Error {
2509
- /** The stable discriminant — see {@link AMBIGUOUS_CODES}. */
2509
+ /** The stable discriminant: see {@link AMBIGUOUS_CODES}. */
2510
2510
  readonly code: AmbiguousCode;
2511
2511
  /** Where the ambiguity became visible: the second header, or the second `P`. Value-free. */
2512
2512
  readonly position: AstmPosition;
@@ -2532,7 +2532,7 @@ interface AstmStreamMessage {
2532
2532
  /** This message's header record. */
2533
2533
  readonly header: HeaderRecord;
2534
2534
  /**
2535
- * The delimiter set in force for this message — the header's own resolved set, which is
2535
+ * The delimiter set in force for this message: the header's own resolved set, which is
2536
2536
  * the set its records were actually read with. When a later header's declaration was
2537
2537
  * unusable, this is the set that stayed in force, never a guessed one.
2538
2538
  */
@@ -2540,7 +2540,7 @@ interface AstmStreamMessage {
2540
2540
  /** Every record of this message in wire order, the header first. */
2541
2541
  readonly records: readonly AstmRecord[];
2542
2542
  /**
2543
- * This message's patient — but **only when the message determines one**: the single `P`
2543
+ * This message's patient, but **only when the message determines one**: the single `P`
2544
2544
  * when it carries exactly one, and `undefined` when it carries none **or** several.
2545
2545
  * `patients.length` distinguishes those two cases; there is no third meaning.
2546
2546
  *
@@ -2600,14 +2600,14 @@ declare function messages(msg: AstmMessage): readonly AstmStreamMessage[];
2600
2600
  * order flow, so this module makes the distinction **explicit**:
2601
2601
  *
2602
2602
  * **The `Q` record dominates.** Any message carrying a `Q` (request-information)
2603
- * record is classified `host-query` — a request — and is **never** treated as a
2603
+ * record is classified `host-query`, a request, and is **never** treated as a
2604
2604
  * result set, even if a result record is also present (an anomaly, which the
2605
2605
  * parser flags separately with `ASTM_RECORD_AMBIGUOUS_MESSAGE_KIND`). This is the
2606
2606
  * whole point: a `Q`-bearing message can never silently read as a result upload.
2607
2607
  */
2608
2608
 
2609
2609
  /**
2610
- * Classify a record stream by the host-query flow. Pure and total — it only reads
2610
+ * Classify a record stream by the host-query flow. Pure and total: it only reads
2611
2611
  * the record type letters, never a field value.
2612
2612
  *
2613
2613
  * `Q` dominates: a message with any `Q` record is a `host-query` request even when
@@ -2686,7 +2686,7 @@ declare function tokenizeHeader(record: string, d: Delimiters, onUnknownEscape?:
2686
2686
  /**
2687
2687
  * The primary scalar of a field: its first repeat's first component, decoded.
2688
2688
  * Returns `undefined` for a truly empty field so callers can distinguish
2689
- * "absent" from a value — never defaulting a missing value.
2689
+ * "absent" from a value: never defaulting a missing value.
2690
2690
  *
2691
2691
  * @example
2692
2692
  * ```ts
@@ -2705,7 +2705,7 @@ declare function fieldScalar(field: AstmField | undefined): string | undefined;
2705
2705
  * `AstmParseError` is thrown directly and consumers narrow via the `code`
2706
2706
  * discriminant. {@link FatalCode} is **closed**: these three are all of it. The frame
2707
2707
  * codec reuses `EMPTY_INPUT` (an empty stream is fatal in both its lenient and strict
2708
- * modes) but does not widen the union — its own thrown errors are separate types with
2708
+ * modes) but does not widen the union, its own thrown errors are separate types with
2709
2709
  * their own discriminants: {@link AstmFrameEncodeError} carries
2710
2710
  * `ASTM_FRAME_EMPTY_RECORD`, and {@link AstmFrameStrictError} carries the rejected
2711
2711
  * warnings rather than a `code`. So narrowing an `AstmParseError` on `code` will only
@@ -2730,15 +2730,15 @@ declare function fieldScalar(field: AstmField | undefined): string | undefined;
2730
2730
  * ```
2731
2731
  */
2732
2732
  declare const FATAL_CODES: {
2733
- /** Input was empty or whitespace-only — there is nothing to parse. Shared across layers. */
2733
+ /** Input was empty or whitespace-only: there is nothing to parse. Shared across layers. */
2734
2734
  readonly EMPTY_INPUT: "EMPTY_INPUT";
2735
- /** The first record is not an `H` (header) record — an ASTM message must lead with `H`. */
2735
+ /** The first record is not an `H` (header) record: an ASTM message must lead with `H`. */
2736
2736
  readonly ASTM_RECORD_NO_HEADER: "ASTM_RECORD_NO_HEADER";
2737
2737
  /** The `H` record is too short to declare the four delimiters (field/repeat/component/escape). */
2738
2738
  readonly ASTM_RECORD_UNDECLARED_DELIMITERS: "ASTM_RECORD_UNDECLARED_DELIMITERS";
2739
2739
  };
2740
2740
  /**
2741
- * A value from {@link FATAL_CODES} — the type carried by a thrown {@link AstmParseError}.
2741
+ * A value from {@link FATAL_CODES}: the type carried by a thrown {@link AstmParseError}.
2742
2742
  */
2743
2743
  type FatalCode = (typeof FATAL_CODES)[keyof typeof FATAL_CODES];
2744
2744
  /**
@@ -2774,7 +2774,7 @@ declare class AstmParseError extends Error {
2774
2774
  }
2775
2775
 
2776
2776
  /**
2777
- * The ASTM escape codec — the fix for a documented silent-misread class.
2777
+ * The ASTM escape codec: the fix for a documented silent-misread class.
2778
2778
  *
2779
2779
  * ASTM escapes an embedded delimiter with the escape character on both sides of
2780
2780
  * a single mnemonic letter (the InterSystems mnemonics, cross-verified against
@@ -2788,12 +2788,12 @@ declare class AstmParseError extends Error {
2788
2788
  * ```
2789
2789
  *
2790
2790
  * **Why this is a requirement, not a nicety.** A result value can legitimately
2791
- * contain a component delimiter — e.g. a titre written `1^40`. On the wire that
2791
+ * contain a component delimiter: e.g. a titre written `1^40`. On the wire that
2792
2792
  * is escaped as `1&S&40`. A parser that splits a field into components on the
2793
2793
  * raw component delimiter and *never decodes the escape* is safe here (the
2794
2794
  * escape body `&S&` contains no literal `^`), but a parser that **decodes first
2795
2795
  * and splits second** turns `1&S&40` into `1^40` and then mis-splits it into two
2796
- * components — the silent misread `python-astm` / `Chistousov` exhibit. The
2796
+ * components: the silent misread `python-astm` / `Chistousov` exhibit. The
2797
2797
  * correct order, implemented here, is **escape-aware split, then decode each
2798
2798
  * leaf**: the escape sequence survives the split intact and only then decodes to
2799
2799
  * a single literal, so `1&S&40` reads as exactly one component.
@@ -2832,7 +2832,7 @@ declare function decodeEscapes(leaf: string, d: Delimiters, onUnknown?: UnknownE
2832
2832
  /**
2833
2833
  * Split `text` on `delimiter`, treating any escape sequence (`escape …
2834
2834
  * escape`) as an opaque atom so a delimiter that appears *inside* an escape body
2835
- * never causes a split. Returns the raw (still-encoded) segments — decoding is
2835
+ * never causes a split. Returns the raw (still-encoded) segments: decoding is
2836
2836
  * the caller's next step, per the escape-aware-split-then-decode contract.
2837
2837
  *
2838
2838
  * For the four canonical mnemonics this is belt-and-suspenders (their bodies are
@@ -2877,12 +2877,12 @@ declare function splitEscapeAware(text: string, delimiter: string, escape: strin
2877
2877
  declare function deepFreeze<T>(value: T): T;
2878
2878
 
2879
2879
  /**
2880
- * `defineAstmProfile()` — the public factory for building immutable
2880
+ * `defineAstmProfile()`: the public factory for building immutable
2881
2881
  * {@link AstmProfile} objects with the safety rules enforced and `describe()`
2882
2882
  * attached. Mirrors the sibling `@cosyte/hl7` `defineProfile()` / `@cosyte/ccda`
2883
2883
  * `defineCcdaProfile()` shape (name / lineage / `extends`-merge / `describe`) while
2884
- * modelling ASTM quirks — a tolerated warning code with provenance, plus the
2885
- * optional raw-vs-framed transport override — rather than HL7 v2 Z-segments or
2884
+ * modelling ASTM quirks (a tolerated warning code with provenance, plus the
2885
+ * optional raw-vs-framed transport override) rather than HL7 v2 Z-segments or
2886
2886
  * C-CDA template deviations.
2887
2887
  *
2888
2888
  * Zero runtime deps. No `any`; immutability at the return boundary via
@@ -2892,7 +2892,7 @@ declare function deepFreeze<T>(value: T): T;
2892
2892
  /**
2893
2893
  * Build a frozen {@link AstmProfile} from a validated options object. Throws
2894
2894
  * {@link AstmProfileDefinitionError} on a bad name, an unknown option key, an
2895
- * invalid `transport`, or an invalid `tolerate` entry — including the **safety
2895
+ * invalid `transport`, or an invalid `tolerate` entry, including the **safety
2896
2896
  * rule**: a profile may never tolerate a safety-critical warning code (default-deny
2897
2897
  * across all three registries).
2898
2898
  *
@@ -2925,18 +2925,18 @@ declare function defineAstmProfile(opts: DefineAstmProfileOptions): AstmProfile;
2925
2925
  /**
2926
2926
  * The definition-time error for the `@cosyte/astm` vendor-profile subsystem.
2927
2927
  *
2928
- * A profile is validated when it is *defined*, not when it is applied — so a
2928
+ * A profile is validated when it is *defined*, not when it is applied, so a
2929
2929
  * misconfigured profile (a bad name, an unknown option key, a tolerated code that
2930
2930
  * is unknown or **safety-critical**) fails loudly at construction, long before it
2931
2931
  * could quiet a real deviation. This is the class that failure throws. It is a
2932
2932
  * programming error (a bad profile literal), distinct from `AstmParseError` (bad
2933
- * input) — so consumers narrow on it separately.
2933
+ * input), so consumers narrow on it separately.
2934
2934
  */
2935
2935
  /**
2936
2936
  * Thrown by `defineAstmProfile` when a profile definition is invalid: a missing or
2937
2937
  * empty `name`, an unknown option key, an invalid `transport` value, or a
2938
- * `tolerate` entry whose code is unknown, whose `rationale` is empty, or — the
2939
- * load-bearing safety rule — whose code is **safety-critical** (a result value,
2938
+ * `tolerate` entry whose code is unknown, whose `rationale` is empty, or, the
2939
+ * load-bearing safety rule, whose code is **safety-critical** (a result value,
2940
2940
  * abnormal flag, result status, reference range, units, patient/comment context,
2941
2941
  * message-kind, code system, or any frame/LTP integrity warning). Carries the
2942
2942
  * offending profile's `name` when it is known, so a multi-profile build names the
@@ -2976,14 +2976,14 @@ declare class AstmProfileDefinitionError extends Error {
2976
2976
  * option always wins, and `profile: null` opts out of the default for a single call.
2977
2977
  *
2978
2978
  * The single mutable module-scoped `let` is the only such state in the profile
2979
- * subsystem — an intentional, documented trade-off (identical to the siblings).
2979
+ * subsystem: an intentional, documented trade-off (identical to the siblings).
2980
2980
  * Tests that set a default MUST clear it in teardown (`setDefaultAstmProfile(null)`)
2981
2981
  * to avoid cross-test bleed.
2982
2982
  */
2983
2983
 
2984
2984
  /**
2985
2985
  * Look up a built-in profile by name. Returns `undefined` when no built-in has that
2986
- * name (a user-defined profile is not in this registry — pass it directly).
2986
+ * name (a user-defined profile is not in this registry, pass it directly).
2987
2987
  *
2988
2988
  * @param name - The built-in profile name.
2989
2989
  * @returns The profile, or `undefined`.
@@ -3011,7 +3011,7 @@ declare function listAstmProfiles(): readonly string[];
3011
3011
  * clear. An explicit `parseAstmRecords(raw, { profile })` always wins;
3012
3012
  * `{ profile: null }` opts out of the default for a single call.
3013
3013
  *
3014
- * **Test hygiene:** the only mutable module-scoped state here — tests that call this
3014
+ * **Test hygiene:** the only mutable module-scoped state here, tests that call this
3015
3015
  * MUST clear it in teardown or default-profile bleed infects later tests.
3016
3016
  *
3017
3017
  * @param profile - The profile to register as default, or `null` to clear.
@@ -3044,7 +3044,7 @@ declare function getDefaultAstmProfile(): AstmProfile | undefined;
3044
3044
  * plus the transport-override accessor the framing detector consumes.
3045
3045
  *
3046
3046
  * A profile **never touches an extracted value**. The warning transform operates
3047
- * purely at the warning layer — downgrading a deviation it *expects* into a
3047
+ * purely at the warning layer: downgrading a deviation it *expects* into a
3048
3048
  * `PROFILE_QUIRK_APPLIED` warning (flagged `expected`, carrying the original
3049
3049
  * `toleratedCode`) while leaving every un-expected warning untouched. Because the
3050
3050
  * transform only ever rewrites a warning object (never a record, field, or value),
@@ -3076,7 +3076,7 @@ declare function applyAstmProfile(profile: AstmProfile, warning: AstmRecordWarni
3076
3076
  * Apply a profile across a whole warning list, returning a NEW array (the input is
3077
3077
  * never mutated). Returned unchanged (same reference contents, a shallow copy) when
3078
3078
  * `profile` is `undefined`, so the no-profile path pays only a copy. Every tolerated
3079
- * warning is re-badged; every other warning passes through by identity — nothing is
3079
+ * warning is re-badged; every other warning passes through by identity, nothing is
3080
3080
  * dropped, reordered, or reallocated beyond the re-badge.
3081
3081
  *
3082
3082
  * @param warnings - The accumulated record warnings.
@@ -3090,7 +3090,7 @@ declare function applyAstmProfile(profile: AstmProfile, warning: AstmRecordWarni
3090
3090
  */
3091
3091
  declare function applyAstmProfileToWarnings(warnings: readonly AstmRecordWarning[], profile: AstmProfile | undefined): AstmRecordWarning[];
3092
3092
  /**
3093
- * The profile's transport override, if any — the value a consumer feeds to
3093
+ * The profile's transport override, if any: the value a consumer feeds to
3094
3094
  * `detectFraming(bytes, { override })` to force framed/raw and bypass leading-byte
3095
3095
  * auto-detection. `undefined` means "let detection decide."
3096
3096
  *
@@ -3108,11 +3108,11 @@ declare function resolveProfileTransport(profile: AstmProfile | undefined): Astm
3108
3108
  /**
3109
3109
  * The safety spine of the profile subsystem: the set of warning codes a profile is
3110
3110
  * **forbidden** to tolerate. A vendor profile exists to quiet known, benign
3111
- * structural noise — never to hide a deviation that could change a clinical
3111
+ * structural noise: never to hide a deviation that could change a clinical
3112
3112
  * reading or corrupt the wire.
3113
3113
  *
3114
3114
  * **Design: default-deny.** Rather than enumerate the *forbidden* codes (a list you
3115
- * can forget to extend when a new warning ships — the exact incompleteness a
3115
+ * can forget to extend when a new warning ships, the exact incompleteness a
3116
3116
  * safety gate must not have), this module enumerates the tiny set of **explicitly
3117
3117
  * tolerable** codes and treats *every other* code, across all three registries
3118
3118
  * (record `ASTM_RECORD_*`, frame `ASTM_FRAME_*`, protocol `ASTM_LTP_*`), as
@@ -3123,32 +3123,32 @@ declare function resolveProfileTransport(profile: AstmProfile | undefined): Astm
3123
3123
  *
3124
3124
  * The four tolerable codes are the only deviations that (a) are structural/
3125
3125
  * syntactic vendor noise and (b) **cannot alter, drop, or fabricate an extracted
3126
- * value** — because a profile only ever re-badges a *warning*, never re-parses. In
3126
+ * value**: because a profile only ever re-badges a *warning*, never re-parses. In
3127
3127
  * every one, the underlying datum is already surfaced verbatim regardless of the
3128
3128
  * profile:
3129
3129
  *
3130
- * - `ASTM_RECORD_UNKNOWN_TYPE` — an unmodeled record type, surfaced verbatim as an
3130
+ * - `ASTM_RECORD_UNKNOWN_TYPE`: an unmodeled record type, surfaced verbatim as an
3131
3131
  * `unsupported` record carrying no interpreted clinical field.
3132
- * - `ASTM_NONSTANDARD_DELIMITERS` — the header's own declared delimiters are read
3132
+ * - `ASTM_NONSTANDARD_DELIMITERS`: the header's own declared delimiters are read
3133
3133
  * and honored either way; this only notes they differ from the canonical set.
3134
- * - `ASTM_UNKNOWN_ESCAPE_SEQUENCE` — an unrecognized `&…&` body is **preserved
3134
+ * - `ASTM_UNKNOWN_ESCAPE_SEQUENCE`: an unrecognized `&…&` body is **preserved
3135
3135
  * byte-for-byte** in the decoded value (the escape codec never guesses); the
3136
3136
  * warning is a purely syntactic advisory, the value is identical with or without
3137
3137
  * the profile.
3138
- * - `ASTM_RECORD_UNINTERPRETED_QUERY_STATUS` — a `Q`-record request-information
3138
+ * - `ASTM_RECORD_UNINTERPRETED_QUERY_STATUS`: a `Q`-record request-information
3139
3139
  * status surfaced verbatim on a *request* record; the code set is paywalled and
3140
3140
  * is never interpreted, profile or not.
3141
3141
  *
3142
- * Everything a wrong value could hide from — a result value split ambiguity, an
3142
+ * Everything a wrong value could hide from: a result value split ambiguity, an
3143
3143
  * undefined abnormal flag or result status, an unparseable reference range, absent
3144
3144
  * units, a mis-attached comment, a partial timestamp, a query-vs-result ambiguity,
3145
3145
  * a bad frame checksum / sequence gap / unterminated / oversize frame, an
3146
- * ambiguous transport, an unexpected protocol event, or a rejected frame — is
3146
+ * ambiguous transport, an unexpected protocol event, or a rejected frame: is
3147
3147
  * forbidden.
3148
3148
  */
3149
3149
 
3150
3150
  /**
3151
- * The **only** warning codes a profile may list in its `tolerate` set — benign,
3151
+ * The **only** warning codes a profile may list in its `tolerate` set: benign,
3152
3152
  * structural/syntactic vendor noise that cannot alter, drop, or fabricate an
3153
3153
  * extracted value. Frozen so it cannot be mutated at runtime to smuggle a code in.
3154
3154
  * Adding to this set is a deliberate, reviewable act (and each addition must be an
@@ -3174,7 +3174,7 @@ declare const TOLERABLE_CODES: ReadonlySet<AnyAstmWarningCode>;
3174
3174
  */
3175
3175
  declare const ALL_ASTM_WARNING_CODES: ReadonlySet<AnyAstmWarningCode>;
3176
3176
  /**
3177
- * The forbidden set — computed as **every known code minus the tolerable
3177
+ * The forbidden set: computed as **every known code minus the tolerable
3178
3178
  * allow-list**, so it is complete by construction. Frozen. A code appears here iff
3179
3179
  * it is a real warning code that is not in {@link TOLERABLE_CODES}.
3180
3180
  *
@@ -3187,7 +3187,7 @@ declare const ALL_ASTM_WARNING_CODES: ReadonlySet<AnyAstmWarningCode>;
3187
3187
  */
3188
3188
  declare const SAFETY_CRITICAL_CODES: ReadonlySet<AnyAstmWarningCode>;
3189
3189
  /**
3190
- * True when `code` is a known warning code that is **not** tolerable — i.e. a
3190
+ * True when `code` is a known warning code that is **not** tolerable: i.e. a
3191
3191
  * profile may never list it. A code that is not a real warning code at all returns
3192
3192
  * `false` here (the validator reports "unknown code" separately, a distinct
3193
3193
  * failure with a distinct message).
@@ -3205,14 +3205,14 @@ declare function isSafetyCriticalCode(code: string): boolean;
3205
3205
 
3206
3206
  /**
3207
3207
  * The `default` conservative baseline profile. Tolerates **nothing** and forces no
3208
- * transport — every deviation surfaces as its own warning, unmodified, and framing
3208
+ * transport: every deviation surfaces as its own warning, unmodified, and framing
3209
3209
  * is auto-detected. It exists so "no profile" and "the default profile" are the
3210
3210
  * same, explicit behaviour, and so a consumer can name the baseline when composing
3211
3211
  * (`extends: astmProfiles.default`) without importing a special sentinel. Absence of
3212
- * a profile means this conservative default applied — not that a stream was fully
3212
+ * a profile means this conservative default applied: not that a stream was fully
3213
3213
  * understood.
3214
3214
  *
3215
- * Authored through the public `defineAstmProfile()` API — zero privileged coupling;
3215
+ * Authored through the public `defineAstmProfile()` API: zero privileged coupling;
3216
3216
  * it is exactly what a user would write.
3217
3217
  */
3218
3218
 
@@ -3229,13 +3229,13 @@ declare function isSafetyCriticalCode(code: string): boolean;
3229
3229
  declare const defaultProfile: AstmProfile;
3230
3230
 
3231
3231
  /**
3232
- * The `referenceCorpus` profile — a **non-vendor**, evidence-backed tolerance
3232
+ * The `referenceCorpus` profile: a **non-vendor**, evidence-backed tolerance
3233
3233
  * grounded firsthand in the **redistributable OSS reference corpus**, not an
3234
3234
  * invented per-vendor deviation matrix.
3235
3235
  *
3236
3236
  * Grounding (firsthand-verified 2026-07-21; the corpus is permissively licensed):
3237
3237
  *
3238
- * - **`kxepal/python-astm` `codec.py`** (BSD) — its `decode_record` /
3238
+ * - **`kxepal/python-astm` `codec.py`** (BSD), its `decode_record` /
3239
3239
  * `decode_component` / `decode_repeated_component` split fields, components, and
3240
3240
  * repeats on the raw delimiters and **never un-escape** ASTM escape sequences: the
3241
3241
  * source contains zero handling of `&F&`/`&S&`/`&R&`/`&E&`, and the escape
@@ -3247,15 +3247,15 @@ declare const defaultProfile: AstmProfile;
3247
3247
  * names) that our **escape-aware** tokenizer flags as
3248
3248
  * `ASTM_UNKNOWN_ESCAPE_SEQUENCE`. We are deliberately stricter than the OSS
3249
3249
  * references here, so the warning is *expected*
3250
- * noise when talking to that ecosystem — recognizable and non-clinical.
3250
+ * noise when talking to that ecosystem: recognizable and non-clinical.
3251
3251
  *
3252
3252
  * **Why this is safe.** The escape codec **preserves an unrecognized `&…&` body
3253
3253
  * byte-for-byte** in the decoded value (`decodeEscapes` never guesses); the value a
3254
3254
  * consumer reads is identical whether or not this profile is active. The profile
3255
- * only re-badges the *warning* — no value, flag, status, or identifier is altered
3255
+ * only re-badges the *warning*: no value, flag, status, or identifier is altered
3256
3256
  * or dropped. And by the safety gate in `defineAstmProfile`, it **cannot** tolerate
3257
3257
  * a result value / flag / status / range / units, a patient or comment context, a
3258
- * message-kind ambiguity, or any frame / LTP integrity warning — those always
3258
+ * message-kind ambiguity, or any frame / LTP integrity warning: those always
3259
3259
  * surface, profile or not.
3260
3260
  *
3261
3261
  * **Honesty.** This is a *reference-corpus* profile, not a claim about any named
@@ -3265,7 +3265,7 @@ declare const defaultProfile: AstmProfile;
3265
3265
 
3266
3266
  /**
3267
3267
  * Tolerates the non-standard-escape noise that streams from the escape-agnostic OSS
3268
- * reference stack (`python-astm` / `senaite`) carry — the value is preserved
3268
+ * reference stack (`python-astm` / `senaite`) carry: the value is preserved
3269
3269
  * verbatim; only the syntactic warning is expected.
3270
3270
  *
3271
3271
  * @example
@@ -3285,7 +3285,7 @@ declare const referenceCorpus: AstmProfile;
3285
3285
  * set, the definition-time error, and the profile types.
3286
3286
  *
3287
3287
  * The individual built-ins are reached via `astmProfiles.referenceCorpus` etc., not
3288
- * as top-level named exports — mirrors the sibling `profiles` namespace convention
3288
+ * as top-level named exports: mirrors the sibling `profiles` namespace convention
3289
3289
  * ("default" is too generic for a top-level export).
3290
3290
  */
3291
3291
 
@@ -3295,7 +3295,7 @@ declare const referenceCorpus: AstmProfile;
3295
3295
  * redistributable OSS reference corpus), each authored via the public
3296
3296
  * `defineAstmProfile()` API and carrying its cited provenance. Named per-vendor
3297
3297
  * profiles (cobas / Sysmex / …) are **deferred** pending a firsthand
3298
- * vendor-attributed quirk document — the engine fully supports them; we do not ship
3298
+ * vendor-attributed quirk document: the engine fully supports them; we do not ship
3299
3299
  * ungrounded ones.
3300
3300
  *
3301
3301
  * @example
@@ -3315,17 +3315,17 @@ declare const astmProfiles: {
3315
3315
  * from an IICC LIVD ("LOINC to Vendor IVD") mapping the consumer provides.
3316
3316
  *
3317
3317
  * **Bring-your-own, by design.** `@cosyte/astm` bundles
3318
- * **no** LOINC, SNOMED, or LIVD data — LOINC is © Regenstrief (redistributable
3318
+ * **no** LOINC, SNOMED, or LIVD data: LOINC is © Regenstrief (redistributable
3319
3319
  * only with its attribution notice) and the public CDC LIVD publication is a
3320
3320
  * SARS-CoV-2-specific file that also carries SNOMED CT (separately licensed), not
3321
3321
  * a general-analyte, public-domain catalog. So the package stays a **structural
3322
3322
  * recognizer, not a dictionary**: it recognizes the Universal Test ID's LOINC slot
3323
3323
  * and surfaces vendor codes verbatim, and this module lets a consumer
3324
- * *supply* their own LIVD file to map those codes — the terminology data, and its
3324
+ * *supply* their own LIVD file to map those codes, the terminology data, and its
3325
3325
  * license obligations, are the consumer's.
3326
3326
  *
3327
3327
  * **Grounded firsthand on the IICC LIVD digital format / HL7 LIVD IG.** The
3328
- * mapping key is the **Vendor Analyte Code** — the vendor *transmission code* the
3328
+ * mapping key is the **Vendor Analyte Code**: the vendor *transmission code* the
3329
3329
  * instrument sends for an automated test, which is exactly the local code an ASTM
3330
3330
  * analyzer puts in the Universal Test ID (`R`/`O` field, component 4). The mapping
3331
3331
  * target is the **LOINC Code** (with the LOINC Long Common Name as an optional
@@ -3342,7 +3342,7 @@ declare const astmProfiles: {
3342
3342
  * a catalog-hygiene concern the consumer owns.
3343
3343
  */
3344
3344
  /**
3345
- * One LIVD mapping row a consumer supplies — a vendor test code and the LOINC it
3345
+ * One LIVD mapping row a consumer supplies: a vendor test code and the LOINC it
3346
3346
  * maps to, plus optional human-readable / provenance fields. Modeled on the IICC
3347
3347
  * LIVD digital format's data elements.
3348
3348
  *
@@ -3354,20 +3354,20 @@ declare const astmProfiles: {
3354
3354
  */
3355
3355
  interface LivdEntry {
3356
3356
  /**
3357
- * The **Vendor Analyte Code** — the vendor transmission code the instrument sends (the local code
3357
+ * The **Vendor Analyte Code**: the vendor transmission code the instrument sends (the local code
3358
3358
  * in an ASTM Universal Test ID, component 4). The mapping key; compared **verbatim** (exact,
3359
- * case-sensitive) against the reported code — never normalized or fuzzy-matched.
3359
+ * case-sensitive) against the reported code, never normalized or fuzzy-matched.
3360
3360
  */
3361
3361
  readonly vendorCode: string;
3362
3362
  /**
3363
3363
  * The **LOINC Code** this vendor code maps to (e.g. `"1920-8"`). Taken from the consumer's catalog
3364
- * as-is and **never validated, altered, or invented** — the parser does not ship a LOINC table and
3364
+ * as-is and **never validated, altered, or invented**: the parser does not ship a LOINC table and
3365
3365
  * cannot check it; it only carries what the catalog says.
3366
3366
  */
3367
3367
  readonly loinc: string;
3368
- /** The **LOINC Long Common Name**, when the catalog supplies it — an optional human-readable label. */
3368
+ /** The **LOINC Long Common Name**, when the catalog supplies it: an optional human-readable label. */
3369
3369
  readonly loincLongName?: string;
3370
- /** The **Vendor Analyte Name** — the vendor's human-readable analyte label, when supplied. */
3370
+ /** The **Vendor Analyte Name**: the vendor's human-readable analyte label, when supplied. */
3371
3371
  readonly vendorAnalyteName?: string;
3372
3372
  /** The device **Manufacturer**, when the catalog scopes the mapping to a device (optional provenance). */
3373
3373
  readonly manufacturer?: string;
@@ -3376,7 +3376,7 @@ interface LivdEntry {
3376
3376
  }
3377
3377
  /**
3378
3378
  * The outcome of looking a vendor code up in a {@link LivdCatalog}. A distinct
3379
- * value per safe disposition — a hit is `mapped`; a miss is `unmapped`; a code that
3379
+ * value per safe disposition: a hit is `mapped`; a miss is `unmapped`; a code that
3380
3380
  * matched more than one **distinct** LOINC is `ambiguous` with the candidates
3381
3381
  * surfaced but **none chosen**. There is deliberately no "guessed" case.
3382
3382
  */
@@ -3387,11 +3387,11 @@ type LivdLookup =
3387
3387
  readonly loinc: string;
3388
3388
  readonly loincLongName?: string;
3389
3389
  }
3390
- /** No entry for this code — a miss. The code stays verbatim; no LOINC is invented. */
3390
+ /** No entry for this code: a miss. The code stays verbatim; no LOINC is invented. */
3391
3391
  | {
3392
3392
  readonly status: "unmapped";
3393
3393
  }
3394
- /** More than one distinct LOINC — surfaced for inspection, never resolved to one. */
3394
+ /** More than one distinct LOINC: surfaced for inspection, never resolved to one. */
3395
3395
  | {
3396
3396
  readonly status: "ambiguous";
3397
3397
  readonly candidates: readonly string[];
@@ -3407,7 +3407,7 @@ interface LivdCatalog {
3407
3407
  /**
3408
3408
  * Look a vendor code up, verbatim (exact, case-sensitive). Returns `mapped` on a
3409
3409
  * single-LOINC hit, `unmapped` on a miss, and `ambiguous` when the code carries
3410
- * more than one distinct LOINC — never a guess.
3410
+ * more than one distinct LOINC: never a guess.
3411
3411
  *
3412
3412
  * @param vendorCode - The reported vendor/local test code.
3413
3413
  * @returns The lookup outcome.
@@ -3443,13 +3443,13 @@ declare function defineLivdCatalog(entries: readonly LivdEntry[]): LivdCatalog;
3443
3443
 
3444
3444
  /**
3445
3445
  * The **terminology** warning registry (`ASTM_LIVD_*`) for the LIVD-aware LOINC
3446
- * recognition layer — the fourth of the package's registries,
3446
+ * recognition layer: the fourth of the package's registries,
3447
3447
  * alongside the record layer's `ASTM_RECORD_*`, the frame codec's `ASTM_FRAME_*`,
3448
3448
  * and the protocol reducer's `ASTM_LTP_*`.
3449
3449
  *
3450
3450
  * A terminology warning is the record of a **safe non-mapping**: a reported
3451
3451
  * vendor test code that a consumer-supplied LIVD catalog did not map to a single
3452
- * LOINC. It never carries a LOINC the catalog did not vouch for — the whole point
3452
+ * LOINC. It never carries a LOINC the catalog did not vouch for: the whole point
3453
3453
  * of the layer is that an unmapped or ambiguous code is surfaced as *unmapped*,
3454
3454
  * **never a guessed LOINC** (mis-identifying a test is safety-critical). Every
3455
3455
  * warning carries a stable code plus positional context ({@link AstmPosition}) and
@@ -3460,7 +3460,7 @@ declare function defineLivdCatalog(entries: readonly LivdEntry[]): LivdCatalog;
3460
3460
  * profile safety gate's universe (`ALL_ASTM_WARNING_CODES`): a LIVD non-mapping is
3461
3461
  * a post-parse advisory produced by the opt-in {@link applyLivd} helper, not a
3462
3462
  * parse-time deviation a vendor profile could ever "tolerate". A profile referencing
3463
- * one is rejected as an unknown code — correctly, since there is nothing here to
3463
+ * one is rejected as an unknown code: correctly, since there is nothing here to
3464
3464
  * quiet.
3465
3465
  */
3466
3466
 
@@ -3477,14 +3477,14 @@ declare function defineLivdCatalog(entries: readonly LivdEntry[]): LivdCatalog;
3477
3477
  declare const LIVD_WARNING_CODES: {
3478
3478
  /**
3479
3479
  * A record carried a vendor/local test code, but the consumer-supplied LIVD catalog held **no**
3480
- * entry for it. The code stays surfaced verbatim and the mapping is `unmapped` — a LOINC is
3480
+ * entry for it. The code stays surfaced verbatim and the mapping is `unmapped`: a LOINC is
3481
3481
  * **never** guessed. Purely advisory: the raw code and value are untouched.
3482
3482
  */
3483
3483
  readonly ASTM_LIVD_UNMAPPED_CODE: "ASTM_LIVD_UNMAPPED_CODE";
3484
3484
  /**
3485
3485
  * A vendor/local test code matched **more than one distinct LOINC** in the catalog (e.g. the same
3486
3486
  * transmission code used by two devices for different analytes). The mapping is `ambiguous` and the
3487
- * candidate LOINCs are surfaced for inspection, but **none is chosen** — refusing to pick is the
3487
+ * candidate LOINCs are surfaced for inspection, but **none is chosen**: refusing to pick is the
3488
3488
  * fail-safe, since guessing wrong mis-identifies the test.
3489
3489
  */
3490
3490
  readonly ASTM_LIVD_AMBIGUOUS_MAPPING: "ASTM_LIVD_AMBIGUOUS_MAPPING";
@@ -3503,7 +3503,7 @@ type LivdWarningCode = (typeof LIVD_WARNING_CODES)[keyof typeof LIVD_WARNING_COD
3503
3503
  * import type { AstmLivdWarning } from "@cosyte/astm";
3504
3504
  * const w: AstmLivdWarning = {
3505
3505
  * code: "ASTM_LIVD_UNMAPPED_CODE",
3506
- * message: "Reported test code had no LIVD mapping — surfaced unmapped, never a guessed LOINC.",
3506
+ * message: "Reported test code had no LIVD mapping, surfaced unmapped, never a guessed LOINC.",
3507
3507
  * position: { recordIndex: 3, recordType: "R" },
3508
3508
  * };
3509
3509
  * ```
@@ -3544,13 +3544,13 @@ declare function livdAmbiguousMapping(position: AstmPosition): AstmLivdWarning;
3544
3544
  /**
3545
3545
  * The **additive, advisory** LIVD annotation layer. {@link applyLivd}
3546
3546
  * reads a parsed {@link AstmMessage} and a consumer-supplied {@link LivdCatalog}
3547
- * and returns a **separate** layer of per-record LOINC annotations — it **never
3547
+ * and returns a **separate** layer of per-record LOINC annotations: it **never
3548
3548
  * mutates, alters, or drops** the raw reported code or value. Recognition is an
3549
3549
  * annotation, not a rewrite: the wire stays exactly as parsed.
3550
3550
  *
3551
3551
  * **The never-fabricate rule (the safety-critical point).** A vendor code with no
3552
3552
  * single LIVD mapping surfaces as a typed `unmapped`/`ambiguous`/`no-code`
3553
- * annotation — **never** a guessed LOINC. A wrong LOINC mis-identifies a test, so
3553
+ * annotation: **never** a guessed LOINC. A wrong LOINC mis-identifies a test, so
3554
3554
  * the layer only ever reports a LOINC the wire itself carried (an inline LOINC
3555
3555
  * candidate) or one the consumer's catalog vouched for (labeled `derived`), and
3556
3556
  * otherwise reports nothing but the miss.
@@ -3560,14 +3560,14 @@ declare function livdAmbiguousMapping(position: AstmPosition): AstmLivdWarning;
3560
3560
  * The outcome of annotating one record's Universal Test ID against a LIVD catalog.
3561
3561
  * A distinct case per disposition; there is no case in which a LOINC is guessed.
3562
3562
  *
3563
- * - `mapped` — the vendor/local code resolved to a single LOINC **via the catalog**
3563
+ * - `mapped`, the vendor/local code resolved to a single LOINC **via the catalog**
3564
3564
  * (labeled `derived: true`, `source: "livd"`).
3565
- * - `inline-loinc` — the wire itself carried a LOINC in the Universal Test ID's slot
3565
+ * - `inline-loinc`, the wire itself carried a LOINC in the Universal Test ID's slot
3566
3566
  * (component 1); surfaced `source: "wire"`, **not** derived and **not** validated.
3567
- * - `unmapped` — a vendor/local code with no catalog entry.
3568
- * - `ambiguous` — a vendor/local code matching more than one distinct LOINC; the
3567
+ * - `unmapped`: a vendor/local code with no catalog entry.
3568
+ * - `ambiguous`: a vendor/local code matching more than one distinct LOINC; the
3569
3569
  * candidates are surfaced but **none is chosen**.
3570
- * - `no-code` — the record carried no usable test code at all (name-only/empty), so
3570
+ * - `no-code`: the record carried no usable test code at all (name-only/empty), so
3571
3571
  * there was nothing to map.
3572
3572
  */
3573
3573
  type LivdMapping = {
@@ -3589,7 +3589,7 @@ type LivdMapping = {
3589
3589
  readonly status: "no-code";
3590
3590
  };
3591
3591
  /**
3592
- * One record's LIVD annotation — which record, the code that was looked up
3592
+ * One record's LIVD annotation, which record, the code that was looked up
3593
3593
  * (verbatim), how it was recognized, and the mapping outcome. Additive: it points
3594
3594
  * at the record by index and never replaces it.
3595
3595
  *
@@ -3614,7 +3614,7 @@ interface LivdAnnotation {
3614
3614
  readonly reportedCode?: string;
3615
3615
  /** How the reported code was recognized in the Universal Test ID (provenance only, never a lookup). */
3616
3616
  readonly provenance: UniversalTestIdProvenance;
3617
- /** The mapping outcome — never a guessed LOINC. */
3617
+ /** The mapping outcome: never a guessed LOINC. */
3618
3618
  readonly mapping: LivdMapping;
3619
3619
  }
3620
3620
  /**
@@ -3625,7 +3625,7 @@ interface LivdAnnotation {
3625
3625
  interface LivdResult {
3626
3626
  /** One annotation per `R`/`O` record, in wire order. */
3627
3627
  readonly annotations: readonly LivdAnnotation[];
3628
- /** A value-free warning per `unmapped`/`ambiguous` code — never per `mapped`/`inline-loinc`/`no-code`. */
3628
+ /** A value-free warning per `unmapped`/`ambiguous` code: never per `mapped`/`inline-loinc`/`no-code`. */
3629
3629
  readonly warnings: readonly AstmLivdWarning[];
3630
3630
  }
3631
3631
  /**
@@ -3701,7 +3701,7 @@ interface FrameChecksum {
3701
3701
  }
3702
3702
  /**
3703
3703
  * One decoded ASTM frame. `text` is the frame's record-byte payload (the bytes
3704
- * between the frame number and the terminator, escapes untouched — this is the
3704
+ * between the frame number and the terminator, escapes untouched, this is the
3705
3705
  * framing layer, not the record layer). `trusted` is the single flag a consumer
3706
3706
  * gates on: it is `true` only for a fully-terminated frame whose checksum
3707
3707
  * validated, and such frames are the only ones reassembled into `records`.
@@ -3739,7 +3739,7 @@ interface AstmFrame {
3739
3739
  */
3740
3740
  interface DecodeAstmFramesResult {
3741
3741
  /**
3742
- * The reassembled record byte-strings — one entry per complete record (a run of
3742
+ * The reassembled record byte-strings: one entry per complete record (a run of
3743
3743
  * frames closed by an `ETX`), in wire order. **Only** clean reassemblies appear:
3744
3744
  * a record whose frames included a bad checksum, a sequence gap, or an
3745
3745
  * unterminated frame is **omitted** (its frames are still in {@link DecodeAstmFramesResult.frames},
@@ -3767,16 +3767,16 @@ interface FrameOptions {
3767
3767
  * The value model for the pure LTP protocol reducer ({@link ltpReduce}).
3768
3768
  *
3769
3769
  * The reducer models the **receiver** side of an ASTM/CLSI-LIS01 (LIS01-A2)
3770
- * session — the host/LIS receiving an upload — because that is where the one
3770
+ * session, the host/LIS receiving an upload, because that is where the one
3771
3771
  * safety decision lives: whether to `ACK` (accept) or `NAK` (reject) a frame that
3772
3772
  * just arrived. It is a **pure function** of the current {@link LtpState} and one
3773
3773
  * inbound {@link LtpEvent}, returning an {@link LtpTransition} (the next state plus
3774
3774
  * the actions the consumer should take and any warnings). No sockets, no timers,
3775
- * no I/O — the consumer owns the wire and the clock; the reducer owns the logic.
3775
+ * no I/O: the consumer owns the wire and the clock; the reducer owns the logic.
3776
3776
  */
3777
3777
 
3778
3778
  /**
3779
- * The protocol phase. The line is either **neutral** (idle — awaiting an `ENQ` to
3779
+ * The protocol phase. The line is either **neutral** (idle, awaiting an `ENQ` to
3780
3780
  * establish, or reset there after an `EOT`) or in **transfer** (establishment
3781
3781
  * accepted; frames and their per-frame `ACK`/`NAK` flow until the sender's `EOT`).
3782
3782
  * The classic three-phase LIS01 model (establishment → transfer → termination)
@@ -3814,7 +3814,7 @@ interface LtpState {
3814
3814
  /** `true` when a record is mid-reassembly (an `ETB` frame was accepted, awaiting its `ETX`). */
3815
3815
  readonly recordOpen: boolean;
3816
3816
  /**
3817
- * The bytes accumulated so far for the in-progress record — the concatenation of
3817
+ * The bytes accumulated so far for the in-progress record: the concatenation of
3818
3818
  * the `ETB` frames accepted since the last `ETX`. Empty when no record is open.
3819
3819
  * These bytes are **never** delivered on their own: only an `ETX` completes a
3820
3820
  * record, at which point they (plus the final frame's text) become one entry in
@@ -3826,7 +3826,7 @@ interface LtpState {
3826
3826
  * An inbound protocol event the consumer feeds the reducer: one of the four LTP
3827
3827
  * control signals (`ENQ`/`ACK`/`NAK`/`EOT`) read off the wire, or a `frame` the
3828
3828
  * consumer already decoded with `decodeAstmFrames` (the reducer reuses the codec's
3829
- * `trusted`/`checksum` verdict — it never re-derives it).
3829
+ * `trusted`/`checksum` verdict, it never re-derives it).
3830
3830
  */
3831
3831
  type LtpEvent = {
3832
3832
  readonly type: "enq";
@@ -3873,14 +3873,14 @@ interface LtpTransition {
3873
3873
  * The pure LTP protocol reducer: {@link ltpReduce} and {@link ltpInitialState}.
3874
3874
  *
3875
3875
  * A deterministic, socket-free receiver-side state machine for ASTM/CLSI-LIS01
3876
- * (LIS01-A2). The consumer owns the wire — it reads bytes, decodes frames with
3877
- * `decodeAstmFrames`, and drives this reducer one {@link LtpEvent} at a time — and
3876
+ * (LIS01-A2). The consumer owns the wire (it reads bytes, decodes frames with
3877
+ * `decodeAstmFrames`, and drives this reducer one {@link LtpEvent} at a time) and
3878
3878
  * the reducer decides, purely, what happens next: whether to `ACK` or `NAK`, when a
3879
3879
  * record is complete, and when the session returns to neutral.
3880
3880
  *
3881
3881
  * **The one inviolable rule (borrowed from `mllp`'s ACK-failsafe discipline):** a
3882
- * frame the codec did not vouch for — a bad checksum, an unterminated frame, or one
3883
- * out of sequence — is answered with `NAK`, **never** a fabricated positive `ACK`,
3882
+ * frame the codec did not vouch for (a bad checksum, an unterminated frame, or one
3883
+ * out of sequence) is answered with `NAK`, **never** a fabricated positive `ACK`,
3884
3884
  * and its bytes are **never** appended to a record or delivered. A `NAK` drives
3885
3885
  * retransmit, not acceptance. This is the protocol-level twin of the frame codec's
3886
3886
  * "a bad-checksum frame is never merged into a record."
@@ -3903,14 +3903,14 @@ interface LtpTransition {
3903
3903
  */
3904
3904
  declare function ltpInitialState(): LtpState;
3905
3905
  /**
3906
- * Advance the LTP session by one inbound event — a pure function, no I/O.
3906
+ * Advance the LTP session by one inbound event: a pure function, no I/O.
3907
3907
  *
3908
3908
  * Behaviour by phase:
3909
- * - **neutral** — `enq` accepts establishment (`sendAck`, enter transfer); `eot` is
3909
+ * - **neutral**: `enq` accepts establishment (`sendAck`, enter transfer); `eot` is
3910
3910
  * a benign line reset (no-op); `ack`/`nak` are unexpected at a receiver (surfaced,
3911
3911
  * never read as acceptance); a `frame` before establishment is tolerated
3912
- * (Postel's Law) — the session auto-establishes and processes it, with a warning.
3913
- * - **transfer** — a `frame` is accepted (`sendAck`, appended, sequence advanced) only
3912
+ * (Postel's Law), the session auto-establishes and processes it, with a warning.
3913
+ * - **transfer**: a `frame` is accepted (`sendAck`, appended, sequence advanced) only
3914
3914
  * when it is trusted *and* carries the expected number; a duplicate of the last
3915
3915
  * accepted frame is idempotently re-`ACK`ed without re-appending; a bad or
3916
3916
  * out-of-sequence frame is `NAK`ed and dropped. `eot` terminates the transfer and
@@ -3936,18 +3936,18 @@ declare function ltpReduce(state: LtpState, event: LtpEvent): LtpTransition;
3936
3936
  * (was E1381), plus the bare-record-letter set the transport detector keys on.
3937
3937
  *
3938
3938
  * The frame codec (`../frames`) owns the *inside* of a frame (`STX FN text
3939
- * ETB/ETX CS CRLF`); this module owns the *handshake around* frames — the
3939
+ * ETB/ETX CS CRLF`); this module owns the *handshake around* frames, the
3940
3940
  * establishment/transfer/termination signalling that the {@link ltpReduce}
3941
3941
  * reducer consumes. These are the raw byte values; the reducer and the transport
3942
3942
  * detector are the only consumers.
3943
3943
  */
3944
- /** Enquiry (`0x05`) — the sender's request to establish a transfer. */
3944
+ /** Enquiry (`0x05`): the sender's request to establish a transfer. */
3945
3945
  declare const ENQ = 5;
3946
- /** Acknowledge (`0x06`) — the receiver accepted the last establishment or frame. */
3946
+ /** Acknowledge (`0x06`): the receiver accepted the last establishment or frame. */
3947
3947
  declare const ACK = 6;
3948
- /** Negative acknowledge (`0x15`) — the receiver rejected the last frame; retransmit, do not accept. */
3948
+ /** Negative acknowledge (`0x15`): the receiver rejected the last frame; retransmit, do not accept. */
3949
3949
  declare const NAK = 21;
3950
- /** End of transmission (`0x04`) — the sender terminated the transfer; the line returns to neutral. */
3950
+ /** End of transmission (`0x04`): the sender terminated the transfer; the line returns to neutral. */
3951
3951
  declare const EOT = 4;
3952
3952
 
3953
3953
  /**
@@ -3961,7 +3961,7 @@ declare const EOT = 4;
3961
3961
  * **both** modes: a bad-checksum frame is surfaced flagged untrusted and **never**
3962
3962
  * merged into a record, and a sequence gap is **never** silently bridged.
3963
3963
  *
3964
- * This is the framing layer only — it does not parse record grammar. Hand a
3964
+ * This is the framing layer only: it does not parse record grammar. Hand a
3965
3965
  * reassembled record to `parseAstmRecords`, or use `parseFramedAstm` to compose
3966
3966
  * both layers at the edge.
3967
3967
  */
@@ -3982,7 +3982,7 @@ declare const EOT = 4;
3982
3982
  * @example
3983
3983
  * ```ts
3984
3984
  * import { decodeAstmFrames } from "@cosyte/astm";
3985
- * // One final frame carrying the record text "R|1|" — checksum "AF" over FN..ETX (mod 256).
3985
+ * // One final frame carrying the record text "R|1|": checksum "AF" over FN..ETX (mod 256).
3986
3986
  * const bytes = new Uint8Array([0x02, 0x31, 0x52, 0x7c, 0x31, 0x7c, 0x03, 0x41, 0x46, 0x0d, 0x0a]);
3987
3987
  * const { records, frames } = decodeAstmFrames(bytes);
3988
3988
  * frames[0]?.frameNumber; // 1
@@ -3995,7 +3995,7 @@ declare function decodeAstmFrames(bytes: Uint8Array, options?: FrameOptions): De
3995
3995
  * The frame-layer **emit** side: {@link composeAstmFrames}.
3996
3996
  *
3997
3997
  * The exact inverse of {@link decodeAstmFrames}. Given the reassembled record
3998
- * byte-strings (one entry per complete record — the same shape `decodeAstmFrames`
3998
+ * byte-strings (one entry per complete record, the same shape `decodeAstmFrames`
3999
3999
  * *produces*), it wraps each into one or more `<STX> FN text <ETB|ETX> CS <CR><LF>`
4000
4000
  * frames, so `decodeAstmFrames(composeAstmFrames(records)).records` reproduces the
4001
4001
  * input records exactly.
@@ -4007,7 +4007,7 @@ declare function decodeAstmFrames(bytes: Uint8Array, options?: FrameOptions): De
4007
4007
  * - the **frame number** `0`–`7`, starting at `1` and rolling over `7 → 0 → 1`,
4008
4008
  * continuous across every frame in the stream (as the decoder's sequence check
4009
4009
  * expects);
4010
- * - the **240-byte text split** — a record longer than 240 bytes is split across
4010
+ * - the **240-byte text split**: a record longer than 240 bytes is split across
4011
4011
  * frames closed by `ETB` (intermediate) with a final `ETX`; the seven framing
4012
4012
  * control bytes are never counted toward the 240.
4013
4013
  *
@@ -4016,7 +4016,7 @@ declare function decodeAstmFrames(bytes: Uint8Array, options?: FrameOptions): De
4016
4016
  */
4017
4017
  /**
4018
4018
  * Thrown by {@link composeAstmFrames} when the input cannot be framed into a
4019
- * spec-clean stream — an empty record list, or a record with no bytes (a frame
4019
+ * spec-clean stream: an empty record list, or a record with no bytes (a frame
4020
4020
  * must carry a record; an empty one is a structural error, never an empty frame).
4021
4021
  * Carries a stable code + the offending record index, never record bytes.
4022
4022
  *
@@ -4042,12 +4042,12 @@ declare class AstmFrameEncodeError extends Error {
4042
4042
  interface ComposeFramesOptions {
4043
4043
  /**
4044
4044
  * The frame number to start the sequence at (`0`–`7`). Defaults to
4045
- * {@link FIRST_FRAME_NUMBER} (`1`) — the ASTM convention.
4045
+ * {@link FIRST_FRAME_NUMBER} (`1`): the ASTM convention.
4046
4046
  */
4047
4047
  readonly startFrameNumber?: number;
4048
4048
  }
4049
4049
  /**
4050
- * Frame reassembled record bytes into a spec-clean ASTM/CLSI-LIS01 byte stream —
4050
+ * Frame reassembled record bytes into a spec-clean ASTM/CLSI-LIS01 byte stream:
4051
4051
  * the inverse of {@link decodeAstmFrames}.
4052
4052
  *
4053
4053
  * Each record is split at 240 text bytes into `ETB`-closed intermediate frames
@@ -4074,11 +4074,11 @@ declare function composeAstmFrames(records: readonly (Uint8Array | string)[], op
4074
4074
  * Composing the two layers at the edge: {@link parseFramedAstm}.
4075
4075
  *
4076
4076
  * The framing layer ({@link decodeAstmFrames}) and the record layer
4077
- * (`parseAstmRecords`) share nothing but the payload boundary — a frame carries
4077
+ * (`parseAstmRecords`) share nothing but the payload boundary: a frame carries
4078
4078
  * record bytes; a record knows nothing about frames. This helper joins them at the
4079
4079
  * one point they meet: decode a framed stream into trusted, reassembled record
4080
4080
  * bytes, then parse those bytes into an {@link AstmMessage}. It is deliberately
4081
- * thin — a consumer that already holds de-framed record bytes calls
4081
+ * thin: a consumer that already holds de-framed record bytes calls
4082
4082
  * `parseAstmRecords` directly, and a consumer that only wants frames calls
4083
4083
  * `decodeAstmFrames` directly.
4084
4084
  */
@@ -4115,7 +4115,7 @@ interface FramedAstmResult {
4115
4115
  * @example
4116
4116
  * ```ts
4117
4117
  * import { parseFramedAstm } from "@cosyte/astm";
4118
- * // A single final frame carrying "H|\^&\r" — checksum "E5" over FN..ETX (mod 256).
4118
+ * // A single final frame carrying "H|\^&\r": checksum "E5" over FN..ETX (mod 256).
4119
4119
  * const bytes = new Uint8Array([
4120
4120
  * 0x02, 0x31, 0x48, 0x7c, 0x5c, 0x5e, 0x26, 0x0d, 0x03, 0x45, 0x35, 0x0d, 0x0a,
4121
4121
  * ]);
@@ -4127,7 +4127,7 @@ interface FramedAstmResult {
4127
4127
  declare function parseFramedAstm(bytes: Uint8Array, options?: FrameOptions & AstmParseOptions): FramedAstmResult;
4128
4128
  /**
4129
4129
  * Serialize an ASTM message (or a bare record list) and frame it into a spec-clean
4130
- * byte stream in one call — the inverse of {@link parseFramedAstm}, composing the
4130
+ * byte stream in one call: the inverse of {@link parseFramedAstm}, composing the
4131
4131
  * two emit layers at the edge.
4132
4132
  *
4133
4133
  * Each record is serialized to spec-clean, `CR`-terminated wire text (canonical
@@ -4155,15 +4155,15 @@ declare function serializeFramedAstm(input: AstmMessage | readonly AstmRecord[],
4155
4155
  * The ASTM/CLSI-LIS01 modulo-256 frame checksum.
4156
4156
  *
4157
4157
  * The checksum is the sum, modulo 256, of every byte **after** the `STX` up to
4158
- * and **including** the `ETB`/`ETX` terminator — i.e. the frame number, the record
4158
+ * and **including** the `ETB`/`ETX` terminator: i.e. the frame number, the record
4159
4159
  * text, and the terminator byte. It is carried on the wire as **two hexadecimal
4160
4160
  * characters**. This module computes it (`computeChecksum`), formats it for emit
4161
- * (`toChecksumHex` — always **uppercase**), and reads it back leniently
4162
- * (`parseChecksumHex` — **accepts lowercase**), matching the real-vendor quirk that
4161
+ * (`toChecksumHex`, always **uppercase**), and reads it back leniently
4162
+ * (`parseChecksumHex`, **accepts lowercase**), matching the real-vendor quirk that
4163
4163
  * some analyzers emit a lowercase checksum.
4164
4164
  */
4165
4165
  /**
4166
- * Sum bytes `[start, endInclusive]` of `bytes` modulo 256 — the ASTM frame
4166
+ * Sum bytes `[start, endInclusive]` of `bytes` modulo 256: the ASTM frame
4167
4167
  * checksum span (frame number through the terminator, inclusive).
4168
4168
  *
4169
4169
  * @param bytes - The full decoded byte stream.
@@ -4194,7 +4194,7 @@ declare function toChecksumHex(checksum: number): string;
4194
4194
  /**
4195
4195
  * Read the two-hex-char checksum at `bytes[i0]`/`bytes[i1]`, **case-insensitively**
4196
4196
  * (a lowercase checksum is a tolerated real-vendor quirk). Returns `undefined` when
4197
- * either position is out of range or not a hex digit — the caller then treats the
4197
+ * either position is out of range or not a hex digit: the caller then treats the
4198
4198
  * frame as having no readable declared checksum, never as a match.
4199
4199
  *
4200
4200
  * @param bytes - The full decoded byte stream.
@@ -4211,7 +4211,7 @@ declare function toChecksumHex(checksum: number): string;
4211
4211
  declare function parseChecksumHex(bytes: Uint8Array, i0: number, i1: number): number | undefined;
4212
4212
 
4213
4213
  /**
4214
- * The frame codec's thrown error — the `strict`-mode counterpart to its lenient
4214
+ * The frame codec's thrown error: the `strict`-mode counterpart to its lenient
4215
4215
  * warnings.
4216
4216
  *
4217
4217
  * The frame layer is lenient by default (byte-level deviations become
@@ -4246,19 +4246,19 @@ declare class AstmFrameStrictError extends Error {
4246
4246
  }
4247
4247
 
4248
4248
  /**
4249
- * Public entry point for the `@cosyte/astm` package — the ASTM/CLSI-LIS02
4249
+ * Public entry point for the `@cosyte/astm` package: the ASTM/CLSI-LIS02
4250
4250
  * **record** layer.
4251
4251
  *
4252
4252
  * The north star: hand a de-framed ASTM record stream to {@link parseAstmRecords}
4253
- * and pull a result's value, units, and flag out in one line — lenient on parse
4254
- * (vendor quirks become typed warnings, never silent loss), and — the whole point
4255
- * — **never a confident wrong value**. Delimiters are read from each header,
4253
+ * and pull a result's value, units, and flag out in one line. Parsing is lenient
4254
+ * (vendor quirks become typed warnings, never silent loss) and, the whole point,
4255
+ * **never returns a confident wrong value**. Delimiters are read from each header,
4256
4256
  * embedded escapes are decoded before a value is split, the practice- and
4257
4257
  * laboratory-assigned patient IDs stay distinct, and every deviation is a stable,
4258
4258
  * value-free warning. Result flag/status semantics, patient/order identity
4259
4259
  * depth + the `C` comment record + partial-timestamp hardening, and the
4260
4260
  * request-information (`Q`) record + host-query classification + verbatim `M`/`S`
4261
- * records are all modeled — the **record-content layer is now feature-complete**.
4261
+ * records are all modeled: the **record-content layer is now feature-complete**.
4262
4262
  *
4263
4263
  * A parsed model is a whole record **stream**, and a stream may carry several `H` … `L`
4264
4264
  * messages. {@link messages} splits it into them, so a patient and a result are only ever
@@ -4269,19 +4269,19 @@ declare class AstmFrameStrictError extends Error {
4269
4269
  * The E1381/CLSI-LIS01 **framing** layer lives alongside the record layer and
4270
4270
  * shares nothing but the payload boundary: {@link decodeAstmFrames} decodes a framed
4271
4271
  * byte stream (`<STX> FN text <ETB|ETX> CS <CR><LF>`) into frames + reassembled
4272
- * record bytes — verifying the modulo-256 checksum (a bad frame is surfaced
4272
+ * record bytes: verifying the modulo-256 checksum (a bad frame is surfaced
4273
4273
  * untrusted, never merged), tracking frame-number sequencing (a gap is never
4274
4274
  * silently bridged), and reassembling the 240-byte-limited multi-frame records.
4275
4275
  * {@link parseFramedAstm} composes the two layers at the edge.
4276
4276
  *
4277
4277
  * The LTP **protocol** layer sits above the frame codec: {@link detectFraming}
4278
- * auto-detects the transport reality — framed (serial / cobas 4800 / Iguana) vs raw
4279
- * (cobas b121, framing dropped) — from the stream's leading byte, and
4278
+ * auto-detects the transport reality from the stream's leading byte, framed
4279
+ * (serial / cobas 4800 / Iguana) vs raw (cobas b121, framing dropped).
4280
4280
  * {@link ltpReduce} is a **pure, socket-free** receiver-side state machine over
4281
4281
  * `ENQ`/`ACK`/`NAK`/`EOT` + frame-received events. The consumer owns the wire; the
4282
4282
  * reducer decides. Its inviolable rule mirrors `mllp`'s ACK-failsafe: a frame the
4283
4283
  * codec did not vouch for is answered with `NAK`, **never** a fabricated positive
4284
- * `ACK`, and never merged into a record — a `NAK` drives retransmit, not acceptance.
4284
+ * `ACK`, and never merged into a record, a `NAK` drives retransmit, not acceptance.
4285
4285
  *
4286
4286
  * The **emit** half is the conservative inverse of the record and framing layers.
4287
4287
  * {@link buildAstmMessage} constructs records from typed caller input, emitting only