@cosyte/terminology 0.0.9 → 0.0.11
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 +333 -8
- package/README.md +6 -4
- 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 +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,13 +1,335 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## 0.0.11
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
-
Versions and publishing are managed with [Changesets](https://github.com/changesets/changesets);
|
|
8
|
-
this file is maintained by hand (Changesets handles the version bump and publish only).
|
|
5
|
+
### Patch Changes
|
|
9
6
|
|
|
10
|
-
|
|
7
|
+
- 9b5b390: The npm `description` no longer carries an em dash (`EMDASH-CONFORMANCE`).
|
|
8
|
+
|
|
9
|
+
The brand rule bans U+2014 on every cosyte surface, and this string is the most visible one the
|
|
10
|
+
package has: it is the subtitle on the npm package page and the one line shown in every npm search
|
|
11
|
+
result. It now reads with a colon, which is what the rule's own remedy list names first.
|
|
12
|
+
|
|
13
|
+
Scoped deliberately to the description alone. The full tree sweep for this repo is a separate unit,
|
|
14
|
+
still queued, and lands with the CI gate that keeps it swept: a gate without the sweep reds CI on
|
|
15
|
+
arrival, and a sweep without the gate grows the character back.
|
|
16
|
+
|
|
17
|
+
- 1374d15: `CHANGELOG.md` is now written by the release rather than by hand, so the copy inside every published tarball stops presenting already-shipped work as unreleased.
|
|
18
|
+
|
|
19
|
+
The file is listed in `package.json#files`, so it ships with the package. For the whole of this package's published history `.changeset/config.json` disabled Changesets' own changelog generation, which meant no release ever wrote a version heading into it and nothing ever rolled its single hand-maintained `[Unreleased]` heading over. Entries that had gone out sat under that heading beside entries that had not, with nothing to tell a reader which was which, while the package published its way to `0.0.10` on top of them. A later note in the same file described the changelog generator as off, which is a maintenance instruction pointing the wrong way inside a document a consumer reads.
|
|
20
|
+
|
|
21
|
+
The mechanism changed rather than the sentences: `changelog` now names the default Changesets generator, so each release writes its own version heading and the changeset summary becomes the entry a reader sees. Correcting the headings by hand would have left in place the mechanism that produced them, to produce them again on the next release.
|
|
22
|
+
|
|
23
|
+
The hand-written history is preserved verbatim, moved under a new `Released before this file was generated` heading with generated sections above it. No entry was reworded, re-ordered, re-wrapped or re-sorted, and this was measured against the registry rather than against the repository: every entry is byte identical to its copy inside the published `0.0.10` tarball, which is what an installed copy holds. What was dropped was scaffolding for the workflow that no longer runs, together with the prose it belonged to: the `[Unreleased]` heading, its link definition at the foot of the file, the preamble calling the file hand-maintained, and the note that described the generator as off. What release attribution the file had is kept rather than flattened: the heading that note sat under is retitled to name the versions its entries went out in, so a reader can still separate the entries that shipped in `0.0.10` from those that shipped across `0.0.2` through `0.0.9`, and from the dated `0.0.1` section below them. Two facts that note carried are kept because they remain true: no version between `0.0.2` and `0.0.10` has a section of its own, and `0.0.3` never reached npm.
|
|
24
|
+
|
|
25
|
+
The release's Prettier pass is left on, derived from this package having no `.prettierignore` and a format check that covers root markdown, so the archived history is already Prettier-canonical and comes through a release unchanged.
|
|
26
|
+
|
|
27
|
+
No runtime code, public API, type, diagnostic code or result changed.
|
|
28
|
+
|
|
29
|
+
- 7ae2c1b: The README lockup now links to cosyte.com (`ASSETS`).
|
|
30
|
+
|
|
31
|
+
The `<picture>` block above the H1 is wrapped in an anchor to https://cosyte.com, per the founder
|
|
32
|
+
requirement of 2026-08-06. Nothing inside the block moved: the `<source>`, the `<img>`, the alt text
|
|
33
|
+
and both tile URLs are byte-identical.
|
|
34
|
+
|
|
35
|
+
What the anchor does was measured on both surfaces by `fhir`, not assumed, because fourteen READMEs
|
|
36
|
+
carry this shape. On GitHub the anchor works and the colour-scheme switch keeps working, because the
|
|
37
|
+
`<img>` stays a direct child of `<picture>`, which is the condition the HTML spec puts on `<source>`
|
|
38
|
+
applying at all. On an npm package page the anchor is lost: npm wraps a README image in its own
|
|
39
|
+
anchor to the image file, a nested anchor is not representable, so the parser closes ours early and
|
|
40
|
+
the image ends up linked to the image file rather than to cosyte.com. Shipped anyway by founder
|
|
41
|
+
decision of 2026-08-07: on npm that is no worse than the unlinked lockup it replaces, and GitHub is
|
|
42
|
+
where these READMEs are read.
|
|
43
|
+
|
|
44
|
+
## Released before this file was generated
|
|
45
|
+
|
|
46
|
+
Every release section above this heading is written by
|
|
47
|
+
[Changesets](https://github.com/changesets/changesets) from the changesets in `.changeset/`, newest
|
|
48
|
+
release first. The release writes its own version heading, so nothing above this line is maintained
|
|
49
|
+
by hand: a change is recorded by adding a changeset, and that changeset's summary is the entry a
|
|
50
|
+
reader sees here.
|
|
51
|
+
|
|
52
|
+
Everything from here down to `## [0.0.1]` was maintained by hand, and all of it has shipped. It
|
|
53
|
+
accumulated under a single `[Unreleased]` heading that no release ever rolled over, so the file mixed
|
|
54
|
+
released work in with work that had not gone out and gave a reader no way to tell them apart, while
|
|
55
|
+
the package published its way to `0.0.10` on top of it. What release attribution the file does have
|
|
56
|
+
is carried by headings, and both of them are kept: the entries between here and the next heading went
|
|
57
|
+
out in `0.0.10`, the entries under `Released in 0.0.2 through 0.0.9` went out across those versions
|
|
58
|
+
without ever being split any finer, and `## [0.0.1]` below has a dated section and a release link of
|
|
59
|
+
its own.
|
|
60
|
+
|
|
61
|
+
The entries are left exactly as they were written rather than re-sorted into version sections:
|
|
62
|
+
re-sorting would rewrite text that published tarballs already carry, and no version from `0.0.2` to
|
|
63
|
+
`0.0.10` has a section of its own or a compare link. Measured against the registry rather than against
|
|
64
|
+
this repository, because the registry is what an installed copy holds: every entry below is byte
|
|
65
|
+
identical to its copy inside the published `0.0.10` tarball. Nothing below was reworded, re-ordered
|
|
66
|
+
or re-wrapped; neither what was removed nor what was added is an entry.
|
|
67
|
+
|
|
68
|
+
What was removed was scaffolding for the hand-written workflow that no longer runs, together with the
|
|
69
|
+
prose that scaffolding belonged to: the `[Unreleased]` heading itself, its link definition at the foot
|
|
70
|
+
of the file, the preamble that described this file as maintained by hand, and the note under the next
|
|
71
|
+
heading, which described the generator as off and pointed at the work this change performs. That
|
|
72
|
+
heading is kept and retitled to say which releases its entries went out in.
|
|
73
|
+
|
|
74
|
+
One consequence is left standing rather than edited, because editing it would rewrite published text:
|
|
75
|
+
an entry in the `0.0.2` through `0.0.9` block refers to "the `[Unreleased]` entry above", and no such
|
|
76
|
+
heading exists any more.
|
|
77
|
+
|
|
78
|
+
`0.0.3` never reaching npm is deliberate now, though it began as a consequence rather than a choice:
|
|
79
|
+
a leftover changeset meant that release run only opened the next version PR, and the content shipped
|
|
80
|
+
in `0.0.4`. It is not a hole to be filled, because publishing a `0.0.3` now would place it after
|
|
81
|
+
`0.0.4` in registry order.
|
|
82
|
+
|
|
83
|
+
The entries below follow [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); the generated
|
|
84
|
+
sections above use the format Changesets writes, which is a version heading and a list of the
|
|
85
|
+
changes that release consumed. Versions follow the cosyte pre-alpha ladder, `0.0.x` until first
|
|
86
|
+
alpha, rather than [Semantic Versioning](https://semver.org/spec/v2.0.0.html) alone.
|
|
87
|
+
|
|
88
|
+
### Fixed
|
|
89
|
+
|
|
90
|
+
- **The PHI scan had NO observation rule at all, so the all-mode sweep reported clean over a scan
|
|
91
|
+
root it never opened (`PHI-SCAN-OBSERVED-NOTHING-IS-GLOBAL`).** Development tooling only:
|
|
92
|
+
`scripts/phi-scan.ts` ships in no tarball, and the public surface, build output and runtime
|
|
93
|
+
behaviour are unchanged. `pnpm phi-scan` with no arguments is what CI runs. It walked two roots,
|
|
94
|
+
`test/fixtures` and `src`, and refused nothing on the strength of what it had read — not the
|
|
95
|
+
global "observed zero files in total" rule the siblings carried, but no rule of any kind.
|
|
96
|
+
|
|
97
|
+
**The starved state was LIVE here, not hypothetical.** `test/fixtures` has never existed in this
|
|
98
|
+
repository (`git log -- test/fixtures` is empty; every test is inline TypeScript and
|
|
99
|
+
`find test -type f -not -name '*.ts'` returns nothing; the throwaway-repo helper in
|
|
100
|
+
`test/scripts/phi-scan.test.ts` has only ever created `scripts/` and `src/`), so one of the two
|
|
101
|
+
declared roots was unopened on every run this gate has ever made. **Reproduced on `0fe4b84` on a
|
|
102
|
+
clone, three ways**, each printing `[phi-scan] OK — no hits` and exiting **0**: `src` moved aside,
|
|
103
|
+
`src` replaced by a **dangling symlink** — each leaving all 39 source files unread — and the
|
|
104
|
+
fixture root, which needed no manipulation at all.
|
|
105
|
+
|
|
106
|
+
**The dangling case is the sharpest, and nothing else in the scanner can see it.** `existsSync`
|
|
107
|
+
**follows** the link and answers false, so `walk()` returns before `readdirSync` and the
|
|
108
|
+
not-a-regular-file refusal never fires: that rule only classifies entries found **inside** a root,
|
|
109
|
+
and this is the root itself. Absent, dangling and empty are one state to the walk. **This reporter
|
|
110
|
+
prints no denominator either** — `report` writes `OK — no hits` and no file count — so nothing on
|
|
111
|
+
stdout looked wrong. Adding a count would be a real improvement and is **not** part of this
|
|
112
|
+
change.
|
|
113
|
+
|
|
114
|
+
**The rule is now per-root.** All-mode refuses (exit **2**) unless **every** declared root yielded
|
|
115
|
+
at least one file that was actually read, and the refusal names the starved roots. It is written
|
|
116
|
+
per-root rather than in the global form the siblings started from, so that shape — one surviving
|
|
117
|
+
file vouching for every other root — cannot arrive along with the second root.
|
|
118
|
+
|
|
119
|
+
**`test/fixtures` is no longer declared as a walk root, and its removal is not a narrowing.** If
|
|
120
|
+
readable, non-ignored content arrives there, all-mode **refuses** (exit 2) and names the
|
|
121
|
+
declaration rather than reporting clean over content nothing walks. **That refusal fires only
|
|
122
|
+
where the remedy it prints would help.** It uses the two predicates the walk already has:
|
|
123
|
+
`rootOf`, so declaring the path silences it by construction, and a content test mirroring the
|
|
124
|
+
walk's own rules, so an **empty** `test/fixtures`, a **markdown-only** one (the walk skips
|
|
125
|
+
markdown) and a **gitignored** one are all left alone at exit 0, exactly as before this change. An
|
|
126
|
+
`existsSync`-only guard refused over all three and kept refusing after the printed remedy was
|
|
127
|
+
followed — a gate that cannot be satisfied — and it invented a second, stricter gitignore boundary
|
|
128
|
+
beside the single one this file keeps. **Two exceptions are recorded rather than papered over**,
|
|
129
|
+
both counting as content because a scan that cannot account for something must not report clean: a
|
|
130
|
+
path the walk cannot list, where declaring it exits 1; and a path holding only a non-regular
|
|
131
|
+
entry, where declaring it lands on the not-a-regular-entry refusal at exit 2. Both behave the same
|
|
132
|
+
before this change, so neither is a regression. The `--staged` predicate is deliberately
|
|
133
|
+
untouched and still enumerates `test/fixtures/**` and that path's own name, so the pre-commit
|
|
134
|
+
route is unchanged in both directions.
|
|
135
|
+
|
|
136
|
+
**The STARVATION refusal never swallows a finding.** Hits from the roots that DID yield are
|
|
137
|
+
printed before it, and the exit code is still 2. That is scoped to the starvation branch and no
|
|
138
|
+
wider: the reappearing-corpus refusal, like the not-a-regular-entry and unmerged refusals beside
|
|
139
|
+
it, throws out of `buildTargetsForAll` before anything is scanned and so reports nothing found on
|
|
140
|
+
the way — fail-closed, and unchanged in that respect. With one root declared, starved means an empty target list, so that
|
|
141
|
+
line is unreachable from this repository's own configuration — it is therefore exercised against a
|
|
142
|
+
copy of the scanner with a second root declared, rather than shipped as an untested promise, which
|
|
143
|
+
is exactly how the defect being fixed here survived.
|
|
144
|
+
|
|
145
|
+
**Deliberately unchanged:** `--staged` and named-path mode make no per-root promise, because
|
|
146
|
+
neither enumerates a root. Both boundaries are pinned, and widening the rule to them was run as a
|
|
147
|
+
mutation rather than argued — dropping the mode guard reds 10 cases; removing the per-root rule
|
|
148
|
+
reds 4; removing the reappearing-corpus refusal reds 3; removing the print-hits-first line reds 1;
|
|
149
|
+
emptying `SCAN_ROOTS` reds 14.
|
|
150
|
+
|
|
151
|
+
**The granularity is the declared root and nothing finer, which is a real bound, not a slogan.**
|
|
152
|
+
Four states are still not refused, each measured **with** the rule in place, each now in the
|
|
153
|
+
scanner's own limits list with the command that produced it and each pinned by a characterization
|
|
154
|
+
test: a directory missing from **inside** a root (`mv src/ucum ..` still prints `OK — no hits`
|
|
155
|
+
with 6 sources unread, while a planted violator in it exits 1 with it present); a root that is
|
|
156
|
+
**itself a symlink** to a directory, which is followed, so the rule is satisfied by whatever is on
|
|
157
|
+
the other side; the floor is **one** file, whatever the root used to hold; and **any directory the
|
|
158
|
+
walk cannot list** exits **1** — the code this gate reserves for hits — because `walk()` does not
|
|
159
|
+
wrap `readdirSync` and the error reaches node's default handler with a v8 stack trace in place of
|
|
160
|
+
the scanner's own diagnostic. That last one is **not only about roots**: measured as `ENOTDIR` on
|
|
161
|
+
a root that is a regular file and on a root linking to one, and as `EACCES` on a `chmod 000`
|
|
162
|
+
directory at depth with the per-root rule otherwise satisfied. **It is CLOSED in the sibling this
|
|
163
|
+
rule was ported from and OPEN here**, and it is recorded so it is not ported back out as though it
|
|
164
|
+
were fixed; it belongs to the separate exit-code work.
|
|
165
|
+
|
|
166
|
+
**Two more bounds are recorded so none of the above reads as completeness, and both are
|
|
167
|
+
`PRE-EXISTING`.** The reappearing-corpus refusal sees only what `existsSync` can resolve: silent
|
|
168
|
+
on a dangling link, which is deliberate because a dangling link holds no corpus, but also silent
|
|
169
|
+
when a real corpus sits behind a directory that cannot be traversed (`chmod 000 test` with
|
|
170
|
+
`test/fixtures/leak.txt` present — measured, and identical before this change). And **all-mode
|
|
171
|
+
walks `src` and nothing else**, so the observation rule can be fully satisfied while every tracked
|
|
172
|
+
file under `test/` goes unread: measured back to back, `pnpm phi-scan` clean at exit 0 while
|
|
173
|
+
naming a file under `test/` directly returns hits at exit 1 over the same bytes
|
|
174
|
+
(`PHI-SCAN-WALK-ROOT-SCOPE`). Widening the walk is separate work with its own two-sided trap,
|
|
175
|
+
because this floor is SSN/email only.
|
|
176
|
+
|
|
177
|
+
Tests were added on throwaway repositories only, so no starved root, no dangling link and no
|
|
178
|
+
violator is ever written into the committed corpus. **No count of them is recorded here**: one
|
|
179
|
+
was, it was correct when written, two more cases were added in the same slice, and it was then
|
|
180
|
+
wrong. Several are red against the superseded scanner — every case asserting one of the new
|
|
181
|
+
refusals — and one is an explicit **anti-vacuity** control asserting the starved corpus really did
|
|
182
|
+
hold a detectable hit, because a starvation test over an empty corpus proves exactly nothing,
|
|
183
|
+
which is the defect itself.
|
|
184
|
+
|
|
185
|
+
- **The PHI commit-gate's `--staged` route was blind to a staged RENAME or COPY, so an ordinary
|
|
186
|
+
`git mv` into a scan root printed its clean line and exited 0 at pre-commit**
|
|
187
|
+
(`PHI-SCAN-RENAME-BLIND-AT-PRECOMMIT`). Development tooling only: `scripts/phi-scan.ts` ships in
|
|
188
|
+
no tarball, and the public surface, build output and runtime behaviour are unchanged.
|
|
189
|
+
|
|
190
|
+
**The hole.** Rename detection is on by git's default, and `git diff --cached --raw
|
|
191
|
+
--diff-filter=AMT` returns neither `R` (rename) nor `C` (copy). So `git mv <tracked link>
|
|
192
|
+
test/fixtures/<name>` staged as `:120000 120000 <sha> <sha> R100` with **two** paths and the
|
|
193
|
+
status filter deleted the record outright: measured on git 2.39.5 in a throwaway repository, the
|
|
194
|
+
index held a mode-120000 entry under a scan root and `pnpm phi-scan --staged` reported clean. It
|
|
195
|
+
was never only a **mode** gap. A rename that also SUBSTITUTES a real-looking value into the moved
|
|
196
|
+
file passed identically, measured at mode 100644, while naming the same destination
|
|
197
|
+
directly returned a hit. The gap was at **pre-commit**, where `simple-git-hooks` runs
|
|
198
|
+
`pnpm phi-scan --staged`; the all-mode sweep is the backstop and saw both.
|
|
199
|
+
|
|
200
|
+
**The remedy is `--no-renames`, with no record-stride work.** With detection off git emits no `R`
|
|
201
|
+
and no `C` at all: the destination arrives as an ordinary single-path `A` and the source as a `D`
|
|
202
|
+
the filter already drops. **This route's own previous disclosure — that admitting `R`/`C` needed
|
|
203
|
+
the two-path record shape handled, "which is a scope decision" — was measured FALSE and is
|
|
204
|
+
withdrawn in place rather than deleted, because it shipped.** Verified under
|
|
205
|
+
`diff.renames=true|copies|false|1` with `diff.renameLimit=1`: every one yields the same
|
|
206
|
+
single-path records, so the two-field stride is STRUCTURAL rather than conditional on the caller's
|
|
207
|
+
configuration. **State the relation exactly, and SCOPE it. Of `--no-renames` alone, holding the
|
|
208
|
+
rest of the argv fixed: the new enumeration CONTAINS the old one — EQUAL whenever git emitted no
|
|
209
|
+
`R` and no `C`, larger only when it did.** It is a superset, not a strictly larger set. **That
|
|
210
|
+
equality is NOT a claim about the route as a whole** — the whole-argv change also adds the
|
|
211
|
+
unmerged and gitlink records below, so on an index holding an unmerged path the two enumerations
|
|
212
|
+
differ while git emitted no `R` and no `C` at all. The corollary, because it is easy to misread as "nobody was affected": a
|
|
213
|
+
caller who had already set `diff.renames=false` was covered before this, and everybody on git's
|
|
214
|
+
default was not.
|
|
215
|
+
|
|
216
|
+
**The `C` half is real and no rename fixture reaches it.** Under `diff.renames=copies`, copying an
|
|
217
|
+
out-of-scope file carrying the same payload INTO a scan root stages as a genuine `C100` two-path
|
|
218
|
+
record and was dropped identically: exit 0 before, exit 1 after. One precondition, recorded because
|
|
219
|
+
it is easy to state too broadly: configuration-only copy detection also needs the copy SOURCE
|
|
220
|
+
modified in the same staged diff, or git finds no copy source, the record arrives as an ordinary
|
|
221
|
+
`A` that even the previous argv enumerated, and the fixture proves nothing.
|
|
222
|
+
|
|
223
|
+
**Three further enumeration holes in the same route, each measured open here rather than assumed.**
|
|
224
|
+
An index entry at exactly `test/fixtures` or exactly `src` escaped a prefix test that required the
|
|
225
|
+
trailing slash (exit 0 over a staged mode-120000 entry at each), so a whole scan root replaced by a
|
|
226
|
+
link went unjudged — **the one ADDITION to this route's path scope in this change, named as an
|
|
227
|
+
addition rather than filed under narrowing.** `diff.ignoreSubmodules=all` ERASED a staged gitlink
|
|
228
|
+
from the enumeration entirely, so a refusal the route already had never fired (exit 2 on the
|
|
229
|
+
default, exit 0 with that config, same index); closed by `--ignore-submodules=none`, the same
|
|
230
|
+
remedy family. And an UNMERGED path was returned by neither `AM` nor `AMT`, so a conflicted
|
|
231
|
+
in-scope path made the route report clean over an index it structurally cannot read; it is now
|
|
232
|
+
enumerated so it can be REFUSED. **`U` is closed by a DIFFERENT mechanism and the two must not be
|
|
233
|
+
conflated: by being in `--diff-filter=AMTU`, not by `--no-renames`.** Git itself refuses to commit
|
|
234
|
+
while a path is unmerged, so that one was never a route to a committed leak; what it was is the
|
|
235
|
+
gate attesting clean over a state it never observed.
|
|
236
|
+
|
|
237
|
+
**One refusal message was false and is corrected, not softened.** It asserted that `git show
|
|
238
|
+
:<path>` "hands back its target path rather than any content", which holds only for mode 120000;
|
|
239
|
+
on a staged gitlink it fails outright, and the same sentence was emitted for gitlinks and for the
|
|
240
|
+
mode fallback. It now says what the INDEX holds instead of what `git show` would answer.
|
|
241
|
+
|
|
242
|
+
**Twelve cases added**, most of them asserting git's own premise before the scanner's behaviour,
|
|
243
|
+
because the remedy rests on what git emits. Eight run red against the previous scanner; the other four
|
|
244
|
+
are the configuration sweep, two flag-coupling premises and an out-of-scope control, green on both
|
|
245
|
+
by design. **The argv coupling is pinned, and a first draft of this entry had half of it BACKWARDS.**
|
|
246
|
+
`-M`, `-C` and `--find-copies-harder` each turn detection back on over the top of `--no-renames`
|
|
247
|
+
and empty the route again; `--find-copies-harder` does so in EITHER order, so nothing here says a
|
|
248
|
+
later `--no-renames` undoes them. **`-B` IS NOT INERT, AND CALLING IT SO WAS THE PERMISSIVE HALF OF
|
|
249
|
+
A STANDING DIRECTIVE.** That reading came from a rename stage, the one stage where `-B` does
|
|
250
|
+
nothing. On a COMPLETE REWRITE `-B` breaks the pairing, the `--diff-filter` letter is `B` and not
|
|
251
|
+
`M`, `AMTU` drops the record outright, and the gate reports clean over a staged dashed SSN
|
|
252
|
+
(measured, same index: exit 1 without the flag, exit 0 with it). It empties this route through the
|
|
253
|
+
status FILTER rather than by re-enabling detection — a different mechanism, the same answer: do not
|
|
254
|
+
add it. Corrected in place rather than deleted, because an "inert" reading is exactly what gets
|
|
255
|
+
ported onward, and a case now pins it. That case guards GIT's premise rather than the scanner's argv, so it does not by
|
|
256
|
+
itself fail if someone adds `-M` to the scanner; the suite as a whole does. **Every flag is
|
|
257
|
+
counterfactually measured against the final suite of 34:** injecting `-M` reds 2 cases, `-C` reds
|
|
258
|
+
3, `--find-copies-harder` reds 3 and `-B` reds 1; removing `--ignore-submodules=none` reds 1, and
|
|
259
|
+
dropping `U` from the filter reds 1. Before the `-B` case was added, injecting `-B` red nothing,
|
|
260
|
+
which is how the false "inert" claim survived a first pass. Every case builds a
|
|
261
|
+
throwaway git repository, so no rename, copy, conflict or violator enters the committed corpus.
|
|
262
|
+
**No case runs `git merge`:** it resolves the COMMITTER IDENTITY up front and exits 128 before
|
|
263
|
+
merging anything when it cannot find one, which passes on a developer's box and fails on a runner,
|
|
264
|
+
so the unmerged fixtures are built with `git update-index --index-info` against an index state —
|
|
265
|
+
what this route actually reads, and `git status` still reports `UU`. The suite was re-run under
|
|
266
|
+
`env -i` with no discoverable git identity: 34 pass.
|
|
267
|
+
|
|
268
|
+
**Measured and deliberately NOT closed here, both PRE-EXISTING and identical before this change.**
|
|
269
|
+
With a scan root replaced by a link to a regular file the all-mode walk raises an uncaught
|
|
270
|
+
`ENOTDIR` and exits **1**, a code this contract reserves for HITS, with a stack trace in place of
|
|
271
|
+
the scanner's own diagnostic; a missing allow-list throws out of the same route the same way. Both
|
|
272
|
+
are fail-closed rather than silent, and belong to the separate exit-code work. And one property
|
|
273
|
+
that is newly true rather than unchanged, because such a blob was previously out of scope
|
|
274
|
+
entirely: a
|
|
275
|
+
regular blob staged at exactly a scan root is scanned at the SAME tier as one under it, which is
|
|
276
|
+
true **here** only because `scanTarget` has one tier — the SSN/email floor — and keys on nothing
|
|
277
|
+
about the path. Implementing the fenced TODO section with a path-keyed dispatch would break that,
|
|
278
|
+
and a case now says so.
|
|
279
|
+
|
|
280
|
+
- **Nothing pinned that the publish gate FORWARDS `--no-definitely-typed`, so a gate that accepted
|
|
281
|
+
the flag and then dropped it would have looked exactly like one that forwards it**
|
|
282
|
+
(`TERMINOLOGY-ATTW-FORWARDING-UNPINNED`). Development tooling only: `scripts/attw.mjs` ships in no
|
|
283
|
+
tarball, and the public surface, build output and runtime behaviour are unchanged. No executable
|
|
284
|
+
line of the gate moved; the only edit to that file is one docblock paragraph.
|
|
285
|
+
|
|
286
|
+
**The gap was structural, not one forgotten assertion.** Every case in
|
|
287
|
+
`test/scripts/attw-gate.test.ts` passes `--no-definitely-typed`, to keep the gate off the network,
|
|
288
|
+
so the flag rode along on every run and no assertion ever depended on it arriving. The allow-list
|
|
289
|
+
covered the acceptance half incidentally, since removing the flag from it kills every other case at
|
|
290
|
+
the argument guard; the forwarding half was covered by nothing at all. The one test whose name said
|
|
291
|
+
otherwise, `"forwards the two arguments it does accept"`, measured `--profile` alone, and its name
|
|
292
|
+
is corrected here rather than left overclaiming.
|
|
293
|
+
|
|
294
|
+
**`attw` itself cannot settle it, which is why the answer is a shim.** The CLI reports on a packed
|
|
295
|
+
tarball, never on its own arguments, and on the `--pack` path this gate always takes the flag
|
|
296
|
+
suppresses a DefinitelyTyped lookup that is never made. Inert means unobservable: accepting the
|
|
297
|
+
flag and dropping it produces byte-identical output to forwarding it. The pin therefore runs this
|
|
298
|
+
repo's own `scripts/attw.mjs` against a fixture package whose `node_modules/.bin/attw` prints the
|
|
299
|
+
argv it was handed. The wrapper resolves its binary beside its own file rather than from the
|
|
300
|
+
working directory, so the probe needs its own copy of the script, and the suite asserts that copy
|
|
301
|
+
is byte-identical to the real one instead of trusting it.
|
|
302
|
+
|
|
303
|
+
**The negative controls are the load-bearing half, and they are committed rather than merely run.**
|
|
304
|
+
A test that would pass whether or not the flag is forwarded proves nothing. Given no arguments the
|
|
305
|
+
shim must see `--pack .` and nothing else, which reds a gate that hard-codes the flag into its own
|
|
306
|
+
spawn, which a positive assertion alone cannot tell apart. A second control
|
|
307
|
+
asserts that a refused argument never reaches the shim at all; that one sharpens the existing
|
|
308
|
+
refusal cases rather than catching anything they miss.
|
|
309
|
+
|
|
310
|
+
**Three counterfactuals were run against the real script, over the whole of
|
|
311
|
+
`test/scripts/attw-gate.test.ts` rather than the new block alone.** Dropping the forwarding reds
|
|
312
|
+
three cases, the new positive pin among them, and leaves both new controls green. Hard-coding the
|
|
313
|
+
flag into the spawn and discarding the argv also reds three, but the pairing is what matters: the
|
|
314
|
+
positive pin stays GREEN while the bare-`--pack .` control reds. That is the precise failure this
|
|
315
|
+
change exists to make visible.
|
|
316
|
+
Bypassing the allow-list so the whole argv is forwarded reds eighteen, of which seventeen are
|
|
317
|
+
refusal cases that were here already; the new refusal control is the eighteenth and adds only "and
|
|
318
|
+
`attw` never saw it". **So that control sharpens an existing guard rather than being what stops a
|
|
319
|
+
forward-everything gate from passing**, and it is recorded that way instead of being credited with
|
|
320
|
+
the catch.
|
|
321
|
+
|
|
322
|
+
**Unchanged, and not claimed to be closed: the `.attw.json` route.** `readConfig()` applies a
|
|
323
|
+
committed config file after argv and sets an option value for every key it carries, so a config
|
|
324
|
+
file wins regardless of the argument allow-list and no argv-level pin can reach it. This change
|
|
325
|
+
narrows nothing there, and the gate's docblock keeps stating it as the known limit it is.
|
|
326
|
+
|
|
327
|
+
## Released in 0.0.2 through 0.0.9
|
|
328
|
+
|
|
329
|
+
These entries accumulated under `[Unreleased]` across those versions and were never split per
|
|
330
|
+
version; none of them has a section of its own or a compare link. One entry below carries a
|
|
331
|
+
`[Superseded]` annotation that was added during the `0.0.10` cycle, so that annotation shipped later
|
|
332
|
+
than the entry it annotates.
|
|
11
333
|
|
|
12
334
|
### Changed
|
|
13
335
|
|
|
@@ -177,7 +499,11 @@ this file is maintained by hand (Changesets handles the version bump and publish
|
|
|
177
499
|
still **not** enumerated by `--staged` at all, so a staged rename that also appends PHI passes that
|
|
178
500
|
route — pre-existing, unchanged here, and admitting it needs the two-path record shape handled,
|
|
179
501
|
which is a scope decision rather than this one; CI's all-mode sweep does read the resulting
|
|
180
|
-
worktree file.
|
|
502
|
+
worktree file. **[Superseded — see the `[Unreleased]` entry above. `R`/`C` ARE now enumerated, and
|
|
503
|
+
the reason given here for deferring them — that it needs the two-path record shape handled, "which
|
|
504
|
+
is a scope decision" — was MEASURED FALSE: `--no-renames` closes it with no stride work. This
|
|
505
|
+
sentence is left standing rather than rewritten because it shipped, and because it is the sentence
|
|
506
|
+
this repo exported to the ecosystem backlog and to sibling repos.]** A tracked file **absent from the worktree** is still caught at `git add` time only.
|
|
181
507
|
And the scanner still has no tolerance for a file that vanishes between enumeration and read, so an
|
|
182
508
|
untracked transient appearing under a walk root can still refuse a whole sweep; that is a different
|
|
183
509
|
defect, it fails closed, and it is not addressed here.
|
|
@@ -1058,5 +1384,4 @@ ladder (`0.0.x` until first alpha).
|
|
|
1058
1384
|
`WARNING_CODES` entry, and the parse-oriented option/warning types). This package is an engine, not
|
|
1059
1385
|
a parser; that placeholder surface never shipped.
|
|
1060
1386
|
|
|
1061
|
-
[Unreleased]: https://github.com/cosyte/terminology/compare/v0.0.1...HEAD
|
|
1062
1387
|
[0.0.1]: https://github.com/cosyte/terminology/releases/tag/v0.0.1
|
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/terminology
|
|
7
9
|
|
package/dist/index.cjs
CHANGED
|
@@ -4776,7 +4776,7 @@ function approximateMatch(graph, query, options = {}) {
|
|
|
4776
4776
|
}
|
|
4777
4777
|
|
|
4778
4778
|
// src/index.ts
|
|
4779
|
-
var VERSION = "0.0.
|
|
4779
|
+
var VERSION = "0.0.11";
|
|
4780
4780
|
|
|
4781
4781
|
exports.COMPLEX_MAP_SOURCE_SYSTEM = COMPLEX_MAP_SOURCE_SYSTEM;
|
|
4782
4782
|
exports.DIAGNOSTIC_CODES = DIAGNOSTIC_CODES;
|