@cosyte/mllp 0.0.5 → 0.0.6
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 +83 -0
- 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
|
@@ -185,6 +185,89 @@ begins its public history at `0.0.x`, per the cosyte version ladder (`0.0.x` unt
|
|
|
185
185
|
|
|
186
186
|
### Fixed
|
|
187
187
|
|
|
188
|
+
- **The PHI scanner no longer refuses an entire sweep because a transient file went away while it
|
|
189
|
+
was reading.** `all` mode lists `test/` + `src/`, then reads each file; anything created and
|
|
190
|
+
removed inside that window made a read throw `ENOENT` and took the whole scan down with it
|
|
191
|
+
(exit 2, the invocation-error code). The refusal was never wrong, the **enumeration** was, so the
|
|
192
|
+
enumeration is what changed. `PHI-SCAN-ENUMERATE-THEN-READ-CLASS`, porting the remedy that
|
|
193
|
+
shipped in `ccda#80`.
|
|
194
|
+
|
|
195
|
+
**This repo is genuinely reachable, and that was measured rather than read off the code.** With a
|
|
196
|
+
`git` shim first on `PATH` (the scanner runs `git` between the walk and the first read, so the
|
|
197
|
+
shim is a deterministic hook into exactly that gap), a `test/phi-scan-cap-*/capture.txt` removed
|
|
198
|
+
in the window made `pnpm phi-scan` on this checkout exit 2. Those directories are not
|
|
199
|
+
hypothetical: `test/scripts/phi-scan.test.ts` `mkdtemp`s two of them inside `test/`, which IS a
|
|
200
|
+
walk root, and polling the tree during a suite run measured each existing for about **510 ms**
|
|
201
|
+
(about 1.03 s of exposure per `pnpm test`). The siblings are spared only because their walk roots
|
|
202
|
+
are not the repo root, which is where a build transient lands. **The exposure is real but not
|
|
203
|
+
self-triggering:** nothing in this repo runs an `all`-mode sweep beside the suite (CI runs
|
|
204
|
+
`pnpm phi-scan` as a step strictly before `pnpm test` in one sequential job, the pre-commit hook
|
|
205
|
+
runs `--staged` and reads blobs from the index, and inside the test file the sweep is ordered
|
|
206
|
+
before both capture tests), so what is live is a hand-run or agent-run sweep during a test run.
|
|
207
|
+
Racing 88 sweeps against 6 suite runs produced 0 refusals, which is consistent with the measured
|
|
208
|
+
duty cycle: walk 2-4 ms, `git check-ignore` 6-9 ms, reads 11-19 ms, inside a ~4 s process.
|
|
209
|
+
|
|
210
|
+
**Exactly one case is now tolerated:** a file the walk enumerated **itself**, that **git does not
|
|
211
|
+
track**, failing with **`ENOENT`**. It is reported on stderr as skipped, naming the path, and is
|
|
212
|
+
never silent. **Still refusing:** a tracked file that cannot be read, any non-`ENOENT` failure, a
|
|
213
|
+
tolerated file back on disk at sweep end, a `git` that cannot report the tracked set, and an
|
|
214
|
+
**empty** tracked set (a removed `.git/index` exits 0 with no output, which would make every file
|
|
215
|
+
untracked and quietly delete the tracked-file bound; a corrupt one exits 128 and was already
|
|
216
|
+
caught). `all` mode additionally refuses when it observed **no** files, so the tolerance can never
|
|
217
|
+
decay into a clean report of nothing.
|
|
218
|
+
|
|
219
|
+
**Which bounds are pinned, and which are only disclosed.** Pinned by eight tests in
|
|
220
|
+
`test/scripts/phi-scan.test.ts`, each against a throwaway tree under `tmpdir()` (seven of them a
|
|
221
|
+
git repo, one deliberately not) and **five** of them driven by the `git`-shim technique, with no
|
|
222
|
+
sleep and no real build: the tolerance itself; the tracked-file bound; the `ENOENT`-only bound
|
|
223
|
+
(`EISDIR` via a decoy replaced by a directory); git unable to answer; the empty tracked set;
|
|
224
|
+
`observed no files`; a violator in an untracked file that does not vanish; and a violator inside a
|
|
225
|
+
transient that is still there when the read arrives. Each bound was **mutation-tested**: widening
|
|
226
|
+
`tolerateVanish` to `true` fails three of them, dropping the `ENOENT` check fails one, dropping
|
|
227
|
+
the `size > 0` guard fails one, and dropping the `observed === 0` refusal fails one. **Not pinned,
|
|
228
|
+
and measured as not pinned:** the back-on-disk re-check. Stubbing it out leaves all 40 tests
|
|
229
|
+
green. Reaching it needs a timed re-create against a deliberately slowed sweep, and a
|
|
230
|
+
load-sensitive sleep guarding a load-dependent race is the failure mode this defect itself
|
|
231
|
+
teaches; losing that branch loses the re-check, never the tolerance's bounds. **The gate drove
|
|
232
|
+
that branch by hand** (shim anchored on the second git call, `git ls-files`, against a 20,000-file
|
|
233
|
+
read loop with a tuned re-create delay) and confirmed the code right at all three delays, so the
|
|
234
|
+
branch is measured-correct and unpinned rather than unknown.
|
|
235
|
+
|
|
236
|
+
**Two residuals carried, not closed.** The post-sweep re-check is keyed on the enumerated PATH,
|
|
237
|
+
not on content, so an untracked file RENAMED inside the window goes unscanned under a clean
|
|
238
|
+
report; it is bounded (committing the file means `git add`, after which it is tracked and
|
|
239
|
+
untolerable) and closing it needs a content-addressed sweep, a different design rather than a
|
|
240
|
+
wider bound. And `walk()`'s own `existsSync` -> `readdirSync` race, one phase earlier, is
|
|
241
|
+
untouched: a directory removed in that window throws a plain `SystemError` `main()` does not
|
|
242
|
+
convert, so Node exits **1**, the code the contract reserves for "hits found". It matters more
|
|
243
|
+
here than in the siblings because this repo's transient is a **directory**, removed wholesale, and
|
|
244
|
+
it is unpinnable by the same technique because nothing runs before the walk.
|
|
245
|
+
|
|
246
|
+
**The suite keeps writing inside the walk root, deliberately.** The two capture tests exist to
|
|
247
|
+
prove that a file whose repo-relative path starts with `test/` earns the structured scan, so the
|
|
248
|
+
path is the fixture and moving them would delete what they test.
|
|
249
|
+
|
|
250
|
+
**Three things the gate checked hardest and could not break, recorded so they are not re-derived.**
|
|
251
|
+
The tracked-set spelling comparison holds: instrumented against this checkout, **zero** files come
|
|
252
|
+
out `tolerateVanish: true`, so the tolerance is inert on a clean tree, and a purpose-built repo of
|
|
253
|
+
15 adversarial tracked filenames (space, tab, newline, quote, backslash, `$`, `*`, `;`, non-ASCII,
|
|
254
|
+
CJK, emoji, plus an invalid-UTF-8 name) never marked a tracked file untracked, because `-z`
|
|
255
|
+
suppresses `core.quotePath` on both sides. The tolerance cannot reach `paths` or `staged` mode,
|
|
256
|
+
and `--allow-fixture` forces `mode = "paths"`, so an allow-list subtraction can never be used to
|
|
257
|
+
drive `all` mode to zero observed files. And in `all` mode `report()` is unreachable while
|
|
258
|
+
`observed === 0`, while in every mode a sweep that observed nothing has no hits to publish.
|
|
259
|
+
(`staged` legitimately reaches `report()` at `observed === 0` and prints `OK, no hits` when a
|
|
260
|
+
commit stages nothing in scope, which is why the refusal is scoped to `all`.)
|
|
261
|
+
|
|
262
|
+
**Two scope notes surfaced by the same review, one pre-existing and one introduced here.**
|
|
263
|
+
PRE-EXISTING: `walk()` tests `e.isFile()`, which is false for a symlink Dirent, so a symlinked
|
|
264
|
+
file under `test/` or `src/` is never swept in `all` mode; it is bounded, because git cannot
|
|
265
|
+
commit content through a symlink and `--staged` reads the index. INTRODUCED by this change: a
|
|
266
|
+
tolerated skip exits **0** with only a stderr line, including in CI, where the tree is at rest and
|
|
267
|
+
a skip is therefore anomalous by definition. On the base commit that same input exited 2. Both are
|
|
268
|
+
stated rather than changed: the first is not this defect, and the second **is** the shipped design
|
|
269
|
+
under review.
|
|
270
|
+
|
|
188
271
|
- **Three doc comments that had outlived the code they described**, all of which shipped into the
|
|
189
272
|
published type declarations. The `'reconnecting'` payload was documented as carrying
|
|
190
273
|
`connectionId` only, while `MllpClient` populates `attempt` and `delayMs` when it schedules a
|
package/dist/index.cjs
CHANGED