@cosyte/mllp 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +76 -2
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,8 +9,12 @@ this file is maintained by hand (Changesets handles the version bump and publish
|
|
|
9
9
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
`@cosyte/mllp` is published on npm and stays on the `0.0.x`-until-first-alpha ladder, so the API can
|
|
13
|
+
change with no deprecation cycle. The sentence this replaces said the first pre-alpha release "will
|
|
14
|
+
ship" the surface below, which stopped being true the day the package first published and had been
|
|
15
|
+
false ever since. **No version literal is written here, on purpose**: what is published is a fact
|
|
16
|
+
about the registry (`npm view @cosyte/mllp version`) and about `package.json`, and a number copied
|
|
17
|
+
into prose here is a claim that goes stale on its own.
|
|
14
18
|
|
|
15
19
|
### Added
|
|
16
20
|
|
|
@@ -76,6 +80,76 @@ begins its public history at `0.0.x`, per the cosyte version ladder (`0.0.x` unt
|
|
|
76
80
|
|
|
77
81
|
### Security
|
|
78
82
|
|
|
83
|
+
- **The PHI scanner enumerates a staged rename, reads a blob that replaced a walk root, and
|
|
84
|
+
refuses a root that is not a directory (`PHI-SCAN-RENAME-BLIND-AT-PRECOMMIT`).** Three holes, two
|
|
85
|
+
of them on `--staged`, which is this repo's **pre-commit** gate. All three were reproduced on
|
|
86
|
+
`2252d33` before anything was touched, with a synthetic name-bearing payload kept outside both
|
|
87
|
+
walk roots.
|
|
88
|
+
|
|
89
|
+
**The rename hole.** `R` (rename) and `C` (copy) are the only `--raw` statuses carrying a second
|
|
90
|
+
path, and `--diff-filter=AMT` deletes such a record outright, so the route never saw one.
|
|
91
|
+
Measured: `git mv <link> test/<name>` staged as `:120000 120000 <sha> <sha> R100` and `--staged`
|
|
92
|
+
printed `OK, no hits` with a mode-`120000` entry sitting under a scan root; a rename that also
|
|
93
|
+
substituted a real name staged as a scored rename and passed the same way, over live `PID-5` / `PID-7` /
|
|
94
|
+
`PID-3` values in the destination blob. The remedy is **`--no-renames`**, and it needs no work on
|
|
95
|
+
the record shape at all: the destination arrives as an ordinary single-path `A` and the source as a
|
|
96
|
+
`D` the filter already drops. The enumeration is a strict **superset** of the previous one, and
|
|
97
|
+
that is pinned on the records rather than on an exit code: a stage with no rename in it hands the
|
|
98
|
+
scanner byte-identical raw output either way. The two-field
|
|
99
|
+
stride becomes **structural** rather than conditional, because with detection off git cannot emit
|
|
100
|
+
an `R` or a `C` at all. Verified under `diff.renames` set to `true`, `copies`, `false` and `1`,
|
|
101
|
+
and under `diff.renameLimit=1`, so the caller's own configuration cannot reopen it. **The earlier
|
|
102
|
+
disclosure that admitting these "needs the two-path record shape handled, which is a scope
|
|
103
|
+
decision" was wrong**, and it was wrong because it was carried in from a sibling rather than
|
|
104
|
+
measured here.
|
|
105
|
+
|
|
106
|
+
**The root-replacing blob.** The refusal path already matched a scan root's own name, because an
|
|
107
|
+
entry at exactly `test` REPLACES the root instead of sitting in it. The read filter did not: it
|
|
108
|
+
wanted the `test/` prefix. So a mode-`100644` blob staged at exactly `test` was in scope for one
|
|
109
|
+
and out of scope for the other, and `--staged` exited 0 over the same three fields. Both read
|
|
110
|
+
predicates now admit the root's own path. **Admitting it to the read set was only half of it**:
|
|
111
|
+
`looksLikeHl7` decides what scan a target earns and a path named `test` matches none of the
|
|
112
|
+
fixture-like extensions, so a draft read the blob and still reported clean over a `PID`. An entry
|
|
113
|
+
that replaces a root is judged with **that root's own limits**, so `test` earns the structured
|
|
114
|
+
HL7 scan while `src` keeps the conservative dashed-SSN + email pass, exactly as a file inside
|
|
115
|
+
either root would. Both directions are pinned.
|
|
116
|
+
|
|
117
|
+
**The non-directory root.** A walk root that resolves to a **file** (a regular file at `test`, or
|
|
118
|
+
a link to one) threw `ENOTDIR` straight out of `readdirSync`, uncaught. Node exits **1** on an
|
|
119
|
+
uncaught throw, which is the code this contract reserves for "hits found", so the gate published
|
|
120
|
+
a finding it had never made: a false positive that reads as actionable, which is a different and
|
|
121
|
+
worse failure than a crash. A **dangling** link at a root was the silent half of the same shape,
|
|
122
|
+
because `existsSync` follows: the walk returned and the sweep reported `OK` over the entire
|
|
123
|
+
corpus that root stands for, with the `observed === 0` backstop unable to fire while the other
|
|
124
|
+
root still had files. Both refuse now (exit 2), naming the root and its kind and **never the link
|
|
125
|
+
target**. Reading whatever sits there instead was refused as the remedy: what is missing in the
|
|
126
|
+
working tree is a **tree**, and one file read in its place is evidence about that file rather
|
|
127
|
+
than about the corpus it replaced. `staged` mode does read such a blob, because the index holds
|
|
128
|
+
no directories to lose. `walk()` also no longer lets any `readdir` failure leave the process:
|
|
129
|
+
everything but `ENOENT` is now a refusal that names the directory.
|
|
130
|
+
|
|
131
|
+
**Two more routes into the same false finding, both `PRE-EXISTING`, both closed here.** A
|
|
132
|
+
**missing** allow-list threw its refusal past every `catch` in `main`, and an **unreadable**
|
|
133
|
+
allow-list or override log threw a raw `EACCES`: both exited 1. Nothing ever passed the gate that
|
|
134
|
+
way, because non-zero still blocks the commit, but the code said the wrong thing. All three exit
|
|
135
|
+
2 now: the missing-allow-list route is answered where it arises, and the two unreadable ones reach
|
|
136
|
+
a process-level guard that turns anything still unaccounted for into exit 2. A bad root and an
|
|
137
|
+
unscannable entry under the other root also come out in one refusal now, rather than one per
|
|
138
|
+
run.
|
|
139
|
+
|
|
140
|
+
**What did not change, deliberately, and is pinned so it stays a decision.** A root that is a
|
|
141
|
+
link to a **directory** is still followed and is still link-neutral (the tree beyond it is
|
|
142
|
+
scanned as the root it replaced would have been, with that root's own limits). An **absent** root
|
|
143
|
+
is still legitimate and still exits 0, which is the control that separates it from a dangling
|
|
144
|
+
one. Explicit-path mode still reads through a link. And the `test/` walk still excludes `.ts`
|
|
145
|
+
sources, which is a separate open question about walk-root scope and is not touched here.
|
|
146
|
+
|
|
147
|
+
16 new cases; **12 of them run red against the base scanner** and the other four are deliberate
|
|
148
|
+
controls (an ordinary stage, an absent root, a linked-directory root, and the record-identity
|
|
149
|
+
comparison, which is a statement about git and holds on both trees). Negative-controlled across packages too: the identical stage reports
|
|
150
|
+
four HL7 field hits through this scanner and nothing through a sibling's, so the evidence is
|
|
151
|
+
about this package rather than about the harness.
|
|
152
|
+
|
|
79
153
|
- **The PHI scanner refuses a non-regular entry under a scan root, on both routes
|
|
80
154
|
(`PHI-SCAN-SYMLINK-BLIND-ON-BOTH-ROUTES`).** A symbolic link under `test/` or `src/` read CLEAN on
|
|
81
155
|
**both** enumerating routes, so a link pointing at a PHI-bearing file passed the gate twice over.
|
package/dist/index.cjs
CHANGED