@cosyte/cli 0.0.4 → 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 +124 -0
- package/README.md +6 -4
- package/dist/bin/cosyte-mcp.cjs +1 -1
- package/dist/bin/cosyte-mcp.cjs.map +1 -1
- package/dist/bin/cosyte-mcp.mjs +1 -1
- package/dist/bin/cosyte-mcp.mjs.map +1 -1
- package/dist/bin/cosyte.cjs +1 -1
- package/dist/bin/cosyte.cjs.map +1 -1
- package/dist/bin/cosyte.mjs +1 -1
- package/dist/bin/cosyte.mjs.map +1 -1
- 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/dist/mcp.cjs +1 -1
- package/dist/mcp.cjs.map +1 -1
- package/dist/mcp.mjs +1 -1
- package/dist/mcp.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -17,6 +17,130 @@ still do. Each entry was assigned to the release whose tag first contains it, re
|
|
|
17
17
|
|
|
18
18
|
### Fixed
|
|
19
19
|
|
|
20
|
+
- **`pnpm phi-scan`'s all-mode walk was rooted at `test/__fixtures__` and `src` only, so 89 of this
|
|
21
|
+
repository's 123 tracked files were scanned by NEITHER of its two routes
|
|
22
|
+
(PHI-SCAN-WALK-ROOT-SCOPE).** The walk now roots at **`src`, `test` and `scripts`**, which opens 72
|
|
23
|
+
tracked files instead of 34.
|
|
24
|
+
- **Measured back to back on the base commit, and re-derived for this repository rather than ported
|
|
25
|
+
from a sibling.** A dashed SSN and an off-domain address written into `test/planted.test.ts`, in
|
|
26
|
+
this repository's own inline-message shape (a whole HL7 message as one `.ts` string literal with
|
|
27
|
+
`\r` escapes between its segments), exited **0** with `OK, no hits` in all mode, while naming the
|
|
28
|
+
same file in paths mode reported both at **exit 1** over the same bytes. A file written under
|
|
29
|
+
`scripts/` behaved identically. Both routes now report both.
|
|
30
|
+
- **All 38 newly opened files were hand-read.** Every message literal is a placeholder and the only
|
|
31
|
+
SSN/email shapes anywhere are the scanner's own declared synthetic payload, so the gap was one of
|
|
32
|
+
**enumeration**, not a live exposure: the defect was that the gate could not see those files, so
|
|
33
|
+
nothing would have caught a real value if one appeared.
|
|
34
|
+
- **`test` REPLACES `test/__fixtures__` rather than joining it.** Roots must stay disjoint: each is
|
|
35
|
+
walked independently and the results concatenated, so a nested root would enumerate every file
|
|
36
|
+
beneath it twice and report each hit twice. The fixture directory is still watched, through the
|
|
37
|
+
observation rule's other condition, **wherever git tracks files under it** (here, seven); only the
|
|
38
|
+
root a refusal is filed under changed.
|
|
39
|
+
- **One cover was LOST, and it is stated rather than implied away:** where git tracks NOTHING under
|
|
40
|
+
`test/__fixtures__`, an empty one no longer refuses. As a declared root it refused by the
|
|
41
|
+
opened-nothing floor whatever git carried; as an ordinary directory it contributes no entry and the
|
|
42
|
+
reconciliation has no expected path to miss. A test pins it.
|
|
43
|
+
- **`scripts/` is a root because the scanner, its allow-list and its override log live there**, so
|
|
44
|
+
the one directory guaranteed to hold PHI-shaped text was the one nothing enumerated. All nine
|
|
45
|
+
files there were measured against the detector before the root was declared: no hits.
|
|
46
|
+
- **The cost of that root nobody would guess: the allow-list's own bytes.** The allow-list documents
|
|
47
|
+
`ID <value>` as a synthetic id "matching an SSN / MRN / member-id shape", and the dashed-SSN check
|
|
48
|
+
consults no allow-list, so an `ID` entry written in that dashed shape now reds the gate on the
|
|
49
|
+
allow-list itself. Latent today (the shipped file declares its only id in the `MRN-` form, and a
|
|
50
|
+
test pins that). **The remedy is to spell the id in a shape the check does not match**, never to
|
|
51
|
+
make that check consult the allow-list (which would delete a detection) and never to exempt the
|
|
52
|
+
file (which would leave the likeliest place for a real value unswept).
|
|
53
|
+
- **A narrowing that came with it:** `test/__fixtures__` is no longer a declared root, so a live or
|
|
54
|
+
dangling symbolic link at that path is now an enumerated entry and is refused outright, whatever
|
|
55
|
+
it points at. Only the three top-level roots can still be followed.
|
|
56
|
+
- **`test/scripts/phi-scan.test.ts` is exempt from the sweep, and is the only exempt path.** It
|
|
57
|
+
carries violator literals on purpose, as the positive half of the scanner's own tests. The
|
|
58
|
+
exemption is applied **after the read**, so the file still counts as observed and an unreadable
|
|
59
|
+
one still refuses; it is **scoped to the sweep**, so naming the file explicitly still reports
|
|
60
|
+
every hit; and it is **per path, never a pattern**.
|
|
61
|
+
- **What this does NOT buy, stated because a wider reading would be false:** the detector is still
|
|
62
|
+
the cross-cutting SSN + email floor, over 38 more files. Structured, field-level detection remains
|
|
63
|
+
unimplemented, and a test now pins that limit rather than leaving it as prose.
|
|
64
|
+
- **`--staged` is deliberately unchanged**, because widening it changes what a commit is blocked on.
|
|
65
|
+
The two routes therefore differ widely, and the scanner's own documentation says by how much.
|
|
66
|
+
- **Four claims about which directories are deliberately NOT scan roots are now checks rather than
|
|
67
|
+
prose**, after two of them were measured false: `docs-content/` and `.changeset/` each carry one
|
|
68
|
+
tracked non-markdown file, and the repository root is not clean under the detector (the `author`
|
|
69
|
+
field carries a real off-domain contact address). `documentation/` and `.github/` were correct.
|
|
70
|
+
|
|
71
|
+
- **`pnpm phi-scan` printed `OK, no hits` and exited 0 over a corpus it never opened
|
|
72
|
+
(PHI-SCAN-OBSERVED-NOTHING-IS-GLOBAL).** A declared scan root that the walk never observed is now
|
|
73
|
+
a refusal at **exit 2**, in the all-mode sweep CI runs. Each root's walk is reconciled against
|
|
74
|
+
`git ls-files`, and two independent conditions refuse: the root contributed **nothing**, or git
|
|
75
|
+
tracks an in-scope file under the root that the walk did not open.
|
|
76
|
+
- **Six states measured on this repository, every one of them previously exiting 0 with
|
|
77
|
+
`OK, no hits`:** the root missing; the root emptied; the root a **dangling** symbolic link; the
|
|
78
|
+
root a **live** symbolic link to a directory outside the repository; a single tracked fixture
|
|
79
|
+
removed from the working tree with the rest of the root still opened; and `src` moved away.
|
|
80
|
+
- **The dangling case is why a kind check cannot stand in for this rule.** `existsSync` follows
|
|
81
|
+
the link and answers false, so `walk()` returns before `readdirSync` and the existing
|
|
82
|
+
not-a-regular-file refusal never fires. Nothing about the entry is ever inspected, so no check
|
|
83
|
+
on its kind can reach it. Refusing on what was **observed** needs no opinion about the entry.
|
|
84
|
+
- **A denominator is deliberately not what this is.** A count counts the roots and the files that
|
|
85
|
+
did exist, so a healthy-looking total is exactly what a starved root produces. This scanner
|
|
86
|
+
prints no file count and one was not added.
|
|
87
|
+
- **Existence is not observation, which is why both conditions ship.** Refusing only a missing
|
|
88
|
+
root leaves the emptied one open; refusing only an empty result leaves the swapped one open,
|
|
89
|
+
because a root pointed at another directory opens plenty. Neither subsumes the other.
|
|
90
|
+
- **Exit 2 was derived from this scanner's own contract, not ported from a sibling.** `1` means
|
|
91
|
+
"hits found" here; `walk()` already raises an unreadable root as an invocation failure, and a
|
|
92
|
+
root replaced by a regular file already exits 2 through `readdirSync`. Sibling scanners disagree
|
|
93
|
+
on this code, and carrying one across would have been the defect.
|
|
94
|
+
- **`git ls-files` failing refuses rather than answering the empty set**, because an empty answer
|
|
95
|
+
is indistinguishable from "this root tracks nothing" and would switch the rule off in silence.
|
|
96
|
+
- **The rule is one-directional on purpose.** A tracked in-scope file the walk missed refuses; an
|
|
97
|
+
untracked working-tree file the walk found does not, because scanning more than git carries is
|
|
98
|
+
the safe direction.
|
|
99
|
+
- **Scope, stated rather than left to be inferred:** all-mode only. `--staged` is a diff and not a
|
|
100
|
+
corpus, and widening it would change what a **commit** is blocked on, which is a separate
|
|
101
|
+
decision. Naming paths explicitly is unchanged.
|
|
102
|
+
- **Narrowed, not closed, and still disclosed in the module header:** a scan root that is itself a
|
|
103
|
+
live link is still followed. It is now refused whenever git tracks an in-scope file under the
|
|
104
|
+
root that the link's target does not also carry **at the same relative path**, so a link to an
|
|
105
|
+
unrelated directory refuses; the reconciliation compares path **sets** rather than the bytes git
|
|
106
|
+
carries at those paths, so a target mirroring the tracked names still passes at exit 0, and a
|
|
107
|
+
root git tracks nothing under is the degenerate case of that rather than the whole of it. An
|
|
108
|
+
**ancestor** of a scan root remains out of the staged route's scope, and paths mode still follows
|
|
109
|
+
a link a caller names.
|
|
110
|
+
- **A present-but-unreadable `phi-scan-overrides.md` exited 1, the code reserved for "hits found".**
|
|
111
|
+
`loadOverrideLog` threw a raw filesystem error past every handler while its sibling reader,
|
|
112
|
+
`loadAllowList`, had already been wrapped. It now exits 2 with a diagnostic. A caller branching on
|
|
113
|
+
the exit code read a broken invocation as a PHI finding.
|
|
114
|
+
- **A red pre-publish gate showed a red X and merged anyway, because `ci / prepublish` was a
|
|
115
|
+
required check nowhere (CI-REQUIRED-CHECKS).** The shared pipeline this repo calls grew a
|
|
116
|
+
`prepublish` job on 2026-08-05 (`cosyte/.github#35`, `6142ac4`; its second layer defaulted on in
|
|
117
|
+
`#36`, `90936ea`), so `ci.yml` began emitting a `ci / prepublish` context on every pull request
|
|
118
|
+
here **with no commit landing in this repo**. Repository ruleset `19907924` did not name it, so
|
|
119
|
+
the job could fail and the merge still landed on `main`, which is the branch that publishes.
|
|
120
|
+
`ci / prepublish` is now a required context, `integration_id`-pinned like the other six.
|
|
121
|
+
- **What it gates is this package's own worst shipped defect.** The job is an offline manifest
|
|
122
|
+
lint that refuses a dependency specifier no registry can resolve, plus a probe that packs this
|
|
123
|
+
tree and installs the tarball into a clean directory. `@cosyte/cli@0.0.1` and `0.0.2` reached
|
|
124
|
+
the registry carrying `file:vendor/*.tgz` specifiers and are permanently uninstallable; the
|
|
125
|
+
manifest lint would have refused both. A gate that catches that and then cannot block the merge
|
|
126
|
+
reintroducing it is documentation.
|
|
127
|
+
- **The order was load-bearing and is recorded because it is easy to get backwards.** The context
|
|
128
|
+
name was read off a real `pull_request` check run before the ruleset was written, never off the
|
|
129
|
+
workflow's `name:` field. Requiring a context nothing emits does not fail a pull request, it
|
|
130
|
+
leaves it pending and unmergeable forever. A census of the eight most recent head shas here
|
|
131
|
+
(`#27` through `#34`) finds `ci / prepublish` **zero** times, because the newest of them merged
|
|
132
|
+
before the upstream job existed, so it could not have been required any earlier.
|
|
133
|
+
- **`ci.yml`'s banner now covers the hazard that actually bit.** Every previous wording of it was
|
|
134
|
+
scoped to splitting a step out of `verify` locally. The `uses:` reference is unpinned, so a job
|
|
135
|
+
added upstream emits a new `ci / <job>` context here with no commit in this repo, and it always
|
|
136
|
+
arrives unrequired.
|
|
137
|
+
- **Deliberately NOT in this change: `release.yml`'s version-PR trap note.** It carries a stale
|
|
138
|
+
required-context count and a claim about the "Version Packages" PR arriving with zero check runs
|
|
139
|
+
whose truth depends on whether `RELEASE_PR_TOKEN` is authoring that PR. Two attempts to correct
|
|
140
|
+
it inside this change each produced a fresh false claim: the first a false operational premise,
|
|
141
|
+
the second a false claim about the note's own history. So it is cut out to its own change rather
|
|
142
|
+
than rewritten a third time. Nothing about it is made worse here; it is left exactly as it was.
|
|
143
|
+
|
|
20
144
|
- **The shipped documentation sidebar was off the canonical IA spine, and it was holding up the
|
|
21
145
|
docs site's deploy (CLI-SIDEBAR-IA-NONCANONICAL).** `docs-content/sidebars.json` declared two
|
|
22
146
|
top-level categories that are not on the spine, **"MCP server"** and **"Reference"**. The docs
|
package/README.md
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
<
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
<a href="https://cosyte.com">
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://cosyte.com/tile/cosyte-lockup-tile-on-dark-1200x300.png">
|
|
4
|
+
<img alt="Cosyte: a plus mark set in two overlapping rounded squares, one solid and one outlined, beside the Cosyte wordmark" src="https://cosyte.com/tile/cosyte-lockup-tile-on-light-1200x300.png">
|
|
5
|
+
</picture>
|
|
6
|
+
</a>
|
|
5
7
|
|
|
6
8
|
# @cosyte/cli
|
|
7
9
|
|