@cosyte/astm 0.0.21 → 0.0.22
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 +75 -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 +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -11,6 +11,81 @@ this file is maintained by hand (Changesets handles the version bump and publish
|
|
|
11
11
|
|
|
12
12
|
### Added
|
|
13
13
|
|
|
14
|
+
- **The PHI sweep now reads the bytes git carries, as a union with the working-tree walk.** All mode
|
|
15
|
+
reconciled the paths it walked against the paths git tracks, and a comparison of path _sets_ is
|
|
16
|
+
satisfied by a working tree that carries different content at those paths. Four states were
|
|
17
|
+
reproduced on the previous release, each printing `[phi-scan] OK: no hits` and exiting `0` over a
|
|
18
|
+
synthetic stream carrying a patient name, a mother's maiden name, a birthdate and a dashed SSN:
|
|
19
|
+
decoy content at a tracked path; a tracked path outside every walk root; a tracked symbolic link
|
|
20
|
+
or nested repository outside every walk root; and an empty index, against which every check passes
|
|
21
|
+
vacuously. All four now report or refuse. The mechanism is written down in exactly one place,
|
|
22
|
+
`buildTargetsForIndex` in `scripts/phi-scan.ts`, and every other surface states only what a green
|
|
23
|
+
means.
|
|
24
|
+
- **It is a union, never a replacement.** No scan root was narrowed and no clause dropped; a file
|
|
25
|
+
the walk reads is still read from disk with exactly the views it had, and a blob whose bytes the
|
|
26
|
+
walk has provably already scanned is skipped, so nothing is reported twice. The skip is a byte
|
|
27
|
+
comparison rather than a timestamp, a size or a hash, because those are exactly what a decoy
|
|
28
|
+
defeats.
|
|
29
|
+
- **The scan reported eighteen tracked files outside every walk root that no route had opened.**
|
|
30
|
+
One carried this package's own published contact address, which is already public in every
|
|
31
|
+
release's registry metadata and is not patient data; it is declared in
|
|
32
|
+
`scripts/phi-allow-list.txt` with the cost of that declaration written beside it, because an
|
|
33
|
+
allowed email domain is global and applies on every route.
|
|
34
|
+
- **A positive control proves the sweep opens the corpus it clears.** This package's own manifest
|
|
35
|
+
is placed at the same out-of-root path in a throwaway tree and the declaration is then struck:
|
|
36
|
+
the same corpus reports the address at exit `1`. A green over an unopened corpus is
|
|
37
|
+
indistinguishable from a green over a corpus that was read, so a case showing the scanner
|
|
38
|
+
passing proves nothing on its own.
|
|
39
|
+
- **What it deliberately does not do**, so a green is not read as wider than it is: it does not
|
|
40
|
+
credit a scan root (a root emptied on disk still refuses, though the index carries its files);
|
|
41
|
+
it does not reach `--staged`, whose scope decides what a _commit_ is blocked on; and markdown
|
|
42
|
+
stays excluded, which is the walk's own rule rather than a new one. Working-tree bytes at a path
|
|
43
|
+
outside every scan root are still read by neither route, unchanged from before and now stated.
|
|
44
|
+
- **Line endings are deliberately not normalized before the byte comparison.** Doing so would
|
|
45
|
+
compare a derived form of the two byte strings, and content differing only in what the
|
|
46
|
+
normalizer erases would then be skipped.
|
|
47
|
+
|
|
48
|
+
- **The two-file contract between `CLAUDE.md` and `documentation/agent-notes.md` is now gated**
|
|
49
|
+
(`pnpm check:agent-notes`, `scripts/check-agent-notes.ts`), with the teeth in
|
|
50
|
+
`test/scripts/agent-notes.test.ts` so it rides the required `ci / verify` matrix rather than
|
|
51
|
+
adding a workflow that would have to be made a required context separately. It asserts that every
|
|
52
|
+
pointer resolves, that no section a pointer reaches is empty, that the record stays reachable from
|
|
53
|
+
the always-read file, and that the always-read file still links the record by path. It asserts
|
|
54
|
+
**no** ecosystem-wide contract: several cosyte repos carry no such record at all, and a gate
|
|
55
|
+
phrased as though every repo did would be an overclaim.
|
|
56
|
+
- **The matcher was re-derived against this tree rather than ported, and that was the whole job.**
|
|
57
|
+
Both sibling spellings score **zero** here: the path-qualified form used by `ccda` and `mllp`,
|
|
58
|
+
and the basename-qualified form used by `terminology`. Every pointer in this repository is a
|
|
59
|
+
third spelling neither sibling gate matches, a backtick-quoted anchor with no filename at all. A
|
|
60
|
+
verbatim port would have reported "all resolving" over a corpus it never opened. Both sibling
|
|
61
|
+
forms are matched anyway so a pasted pointer is never invisible, and the live form falling to
|
|
62
|
+
zero is a refusal rather than a pass.
|
|
63
|
+
- **The anchor space is this record's explicit `<a id>` tags, not GitHub heading slugs.** Not one
|
|
64
|
+
pointer here resolves to a heading slug, because the headings carry long titles with dates and
|
|
65
|
+
status in them. A gate checking only slugs, which is what the siblings check, would have
|
|
66
|
+
reported every pointer in the repository as dangling.
|
|
67
|
+
- **An early draft was vacuous rather than wrong, and only a positive control found it.** Treating
|
|
68
|
+
an explicit anchor and the heading it precedes as separate sections made the empty-section
|
|
69
|
+
assertion cover nothing: the anchor looked empty and the heading looked unreferenced, so both
|
|
70
|
+
were skipped and a deliberately emptied section still printed `OK`. Anchors are now bound to the
|
|
71
|
+
heading they name.
|
|
72
|
+
- **The one declared non-pointer is pinned to the single sentence it describes**, and refuses both
|
|
73
|
+
when it matches nothing (a phantom skip) and when it matches more than once. The second case
|
|
74
|
+
fired during this change's own build.
|
|
75
|
+
- The corpus is `git ls-files` reconciled as sets, with **no exclusion list, no binary skip and no
|
|
76
|
+
NUL skip**; this repository tracks NUL-bearing TypeScript sources, most of them tests, that a NUL
|
|
77
|
+
partition would drop in silence. A pointer is matched if and only if the file spells it in ASCII
|
|
78
|
+
bytes, pinned in both directions by test. Every tracked file is scanned, so a backticked anchor
|
|
79
|
+
is a live pointer wherever it is written, **including `README.md` and `docs-content/`, which
|
|
80
|
+
ships in an immutable release asset**: reference a section by title on any surface that ships.
|
|
81
|
+
- **CI caught a defect the local run structurally could not, and the gate was right.** Because the
|
|
82
|
+
corpus is the index, a new file is invisible until staged: `verify.sh` ran green while both new
|
|
83
|
+
files were untracked, and CI went red once they were tracked, because the gate's own test file
|
|
84
|
+
spelled pointers in its fixtures that were then scanned against the real record. Both the checker
|
|
85
|
+
and its test now **build** pointer strings at run time rather than spelling them, pinned by a
|
|
86
|
+
test; exempting those paths would have been the exclusion list the gate refuses to have. **Re-run
|
|
87
|
+
a corpus-scanning gate after staging, never only before.**
|
|
88
|
+
|
|
14
89
|
- **The PHI commit-gate now reads a stream written as a source string literal, and refuses a sweep
|
|
15
90
|
that did not observe its corpus.** Two separate holes, closed together because closing one alone
|
|
16
91
|
buys only the cross-cutting SSN/email floor.
|
package/dist/index.cjs
CHANGED