@clossys/writer 0.3.9 → 0.5.0

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.
Files changed (136) hide show
  1. package/README.md +647 -6
  2. package/dist/addressability.d.ts +11 -1
  3. package/dist/addressability.d.ts.map +1 -1
  4. package/dist/addressability.js +169 -3
  5. package/dist/addressability.js.map +1 -1
  6. package/dist/approval-bypass.d.ts +120 -0
  7. package/dist/approval-bypass.d.ts.map +1 -0
  8. package/dist/approval-bypass.js +2318 -0
  9. package/dist/approval-bypass.js.map +1 -0
  10. package/dist/approval.d.ts +62 -0
  11. package/dist/approval.d.ts.map +1 -0
  12. package/dist/approval.js +421 -0
  13. package/dist/approval.js.map +1 -0
  14. package/dist/approve-cli.d.ts +82 -0
  15. package/dist/approve-cli.d.ts.map +1 -0
  16. package/dist/approve-cli.js +430 -0
  17. package/dist/approve-cli.js.map +1 -0
  18. package/dist/cli.d.ts +15 -0
  19. package/dist/cli.d.ts.map +1 -1
  20. package/dist/cli.js +264 -22
  21. package/dist/cli.js.map +1 -1
  22. package/dist/field-options.d.ts +59 -0
  23. package/dist/field-options.d.ts.map +1 -0
  24. package/dist/field-options.js +109 -0
  25. package/dist/field-options.js.map +1 -0
  26. package/dist/fold-wallpaper-gate.d.ts +7 -0
  27. package/dist/fold-wallpaper-gate.d.ts.map +1 -0
  28. package/dist/fold-wallpaper-gate.js +29 -0
  29. package/dist/fold-wallpaper-gate.js.map +1 -0
  30. package/dist/front-door.check.d.ts +2 -0
  31. package/dist/front-door.check.d.ts.map +1 -0
  32. package/dist/front-door.check.js +8 -0
  33. package/dist/front-door.check.js.map +1 -0
  34. package/dist/front-door.d.ts +82 -0
  35. package/dist/front-door.d.ts.map +1 -0
  36. package/dist/front-door.js +271 -0
  37. package/dist/front-door.js.map +1 -0
  38. package/dist/generated/advisor-plan-contract.generated.d.ts +3 -0
  39. package/dist/generated/advisor-plan-contract.generated.d.ts.map +1 -0
  40. package/dist/generated/advisor-plan-contract.generated.js +430 -0
  41. package/dist/generated/advisor-plan-contract.generated.js.map +1 -0
  42. package/dist/generated/contract-schema.generated.d.ts +97 -0
  43. package/dist/generated/contract-schema.generated.d.ts.map +1 -0
  44. package/dist/generated/contract-schema.generated.js +496 -0
  45. package/dist/generated/contract-schema.generated.js.map +1 -0
  46. package/dist/index.d.ts +18 -2
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +26 -0
  49. package/dist/index.js.map +1 -1
  50. package/dist/live-copy-gate.d.ts +16 -0
  51. package/dist/live-copy-gate.d.ts.map +1 -0
  52. package/dist/live-copy-gate.js +135 -0
  53. package/dist/live-copy-gate.js.map +1 -0
  54. package/dist/messaging-kit.d.ts +113 -0
  55. package/dist/messaging-kit.d.ts.map +1 -0
  56. package/dist/messaging-kit.js +121 -0
  57. package/dist/messaging-kit.js.map +1 -0
  58. package/dist/passage.d.ts +2 -1
  59. package/dist/passage.d.ts.map +1 -1
  60. package/dist/passage.js +2 -1
  61. package/dist/passage.js.map +1 -1
  62. package/dist/plan-authority.d.ts +73 -0
  63. package/dist/plan-authority.d.ts.map +1 -0
  64. package/dist/plan-authority.js +126 -0
  65. package/dist/plan-authority.js.map +1 -0
  66. package/dist/plan-contract.d.ts +16 -0
  67. package/dist/plan-contract.d.ts.map +1 -0
  68. package/dist/plan-contract.js +33 -0
  69. package/dist/plan-contract.js.map +1 -0
  70. package/dist/plan-digest.d.ts +23 -0
  71. package/dist/plan-digest.d.ts.map +1 -0
  72. package/dist/plan-digest.js +82 -0
  73. package/dist/plan-digest.js.map +1 -0
  74. package/dist/plan-rules.d.ts +54 -0
  75. package/dist/plan-rules.d.ts.map +1 -0
  76. package/dist/plan-rules.js +145 -0
  77. package/dist/plan-rules.js.map +1 -0
  78. package/dist/render-registry-parity.d.ts +20 -0
  79. package/dist/render-registry-parity.d.ts.map +1 -0
  80. package/dist/render-registry-parity.js +45 -0
  81. package/dist/render-registry-parity.js.map +1 -0
  82. package/dist/resolve.d.ts +40 -6
  83. package/dist/resolve.d.ts.map +1 -1
  84. package/dist/resolve.js +144 -18
  85. package/dist/resolve.js.map +1 -1
  86. package/dist/scan.d.ts +32 -0
  87. package/dist/scan.d.ts.map +1 -1
  88. package/dist/scan.js +67 -6
  89. package/dist/scan.js.map +1 -1
  90. package/dist/schema.d.ts +1 -0
  91. package/dist/schema.d.ts.map +1 -1
  92. package/dist/schema.js +231 -5
  93. package/dist/schema.js.map +1 -1
  94. package/dist/site-identity.d.ts +88 -0
  95. package/dist/site-identity.d.ts.map +1 -0
  96. package/dist/site-identity.js +82 -0
  97. package/dist/site-identity.js.map +1 -0
  98. package/dist/treatment-word-budget.d.ts +31 -0
  99. package/dist/treatment-word-budget.d.ts.map +1 -0
  100. package/dist/treatment-word-budget.js +80 -0
  101. package/dist/treatment-word-budget.js.map +1 -0
  102. package/dist/types.d.ts +76 -7
  103. package/dist/types.d.ts.map +1 -1
  104. package/dist/types.js +9 -7
  105. package/dist/types.js.map +1 -1
  106. package/fit-signals.json +11 -0
  107. package/package.json +201 -11
  108. package/skill/SKILL.md +49 -0
  109. package/src/addressability.ts +186 -4
  110. package/src/approval-bypass.ts +2263 -0
  111. package/src/approval.ts +491 -0
  112. package/src/approve-cli.ts +474 -0
  113. package/src/cli.ts +274 -22
  114. package/src/field-options.ts +134 -0
  115. package/src/fold-wallpaper-gate.ts +29 -0
  116. package/src/front-door.check.ts +10 -0
  117. package/src/front-door.ts +312 -0
  118. package/src/generated/advisor-plan-contract.generated.ts +430 -0
  119. package/src/generated/contract-schema.generated.ts +520 -0
  120. package/src/index.ts +107 -1
  121. package/src/live-copy-gate.ts +150 -0
  122. package/src/messaging-kit.ts +195 -0
  123. package/src/passage.ts +2 -1
  124. package/src/plan-authority.ts +160 -0
  125. package/src/plan-contract.ts +45 -0
  126. package/src/plan-digest.ts +81 -0
  127. package/src/plan-rules.ts +179 -0
  128. package/src/render-registry-parity.ts +65 -0
  129. package/src/resolve.ts +185 -19
  130. package/src/scan.ts +97 -6
  131. package/src/schema.ts +247 -5
  132. package/src/site-identity.ts +125 -0
  133. package/src/treatment-word-budget.ts +100 -0
  134. package/src/types.ts +83 -7
  135. package/templates/front-door.en.json +426 -0
  136. package/CHANGELOG.md +0 -330
package/CHANGELOG.md DELETED
@@ -1,330 +0,0 @@
1
- # Changelog
2
-
3
- All notable changes to this package are documented here. Format follows
4
- [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5
-
6
- ## [0.3.9] - 2026-09-18
7
-
8
- ### Added
9
-
10
- - Documented installation against the public npm registry
11
- (`https://registry.npmjs.org`) and that installing needs no authentication.
12
- - Stated the charter close condition in the README: independent consumer
13
- evidence of `approved copy coverage rate`, computed by
14
- `assessApprovedCopyCoverageRate()`. An empty evaluated set is
15
- indeterminate, never a perfect rate of 1. `checkCopyRecord` and
16
- `checkCopyTraceability` remain the gates they are; neither is this rate.
17
- - Declared `foundry.assessment` against a new mapped `writer-rate-check`
18
- bin with `invocation: "single-json-input"`. `writer-check` remains the
19
- multi-mode CLI and is not the assessment surface. Advisor remains the
20
- only required first-day role.
21
- - `writer-rate-check assessment.json`: prints the `approved copy coverage
22
- rate` report and exits on the `0` / `1` / `2` ternary.
23
-
24
- ### Notes
25
-
26
- - This does not claim the position is closed. Qualification of `0.3.9` is
27
- deferred under #833.
28
-
29
- ## [0.3.8] - 2026-09-16
30
-
31
- ### Added
32
-
33
- - README now documents the `writer-check --format json` contract added in
34
- 0.3.7: the exact object shape, and the guarantee that `verdict`, `findings`
35
- and `unchecked` are present together on every path — clean, findings, and
36
- total failure alike. The flag was documented in `--help` and in this
37
- changelog but not in the README, where this package documents its other
38
- CLI exit-code contracts (#880).
39
-
40
- ### Changed
41
-
42
- - Version bumped from 0.3.7 to 0.3.8 without a functional change to the
43
- shipped code. 0.3.7 was never published: its retained qualification record
44
- bound a tarball that could not be reproduced from the tree, because the
45
- record was generated against an incrementally-built `dist/` that carried
46
- stale artifacts. Qualification records are immutable — one introduction per
47
- path, hash-pinned — so the 0.3.7 record could not be corrected and 0.3.7
48
- could never be published. It is skipped deliberately rather than reused.
49
-
50
- The mechanism is filed as #893; this release's own record was generated
51
- from a clean build on the pinned release runtime specifically because of it.
52
-
53
- ## [0.3.7] - 2026-09-15
54
-
55
- ### Fixed
56
-
57
- - The default `writer-check` command's scanner could not classify a `//`
58
- line comment or a `/* */` block comment placed BETWEEN a JSX element's
59
- attributes — legal TSX every mainstream formatter produces for a
60
- commented-out or explained prop. The attribute-parsing loop inside
61
- `tryScanJsxElement` had no case for either comment form, so it fell
62
- through to the loop's own "not committed, silently not-JSX" backtrack;
63
- for a NESTED element (the realistic shape in a real component tree)
64
- that backtrack surfaced as an `"unrecognized-jsx-child"` `unchecked`
65
- entry, and this package's own indeterminate-fold ("one unreadable
66
- region must not let a scan report itself clean") turned that ONE
67
- construct into exit code 2 for the WHOLE run — discarding every real
68
- finding the same scan had already produced (issue #753: a 270-entry
69
- `CopyRecord` scan against a real application tree extracted 294
70
- candidates, produced 292 findings, and still exited 2 over this one
71
- construct). Comment trivia between attributes is now skipped exactly
72
- like the whitespace surrounding it, before any commit decision is
73
- made — the same "silent, pre-commit trivia" treatment this loop
74
- already gives TSX's generic-arrow-function syntax.
75
-
76
- ### Added
77
-
78
- - `writer-check --format json`: the default command's own structured,
79
- machine-readable report (`CopyTraceabilityReport`), matching the
80
- `--format json` shape `inspector`'s CLI already publishes. Exit code 2
81
- (indeterminate) is unchanged and still wins whenever any JSX construct
82
- is `unchecked` — an indeterminate result must never read as clean, and
83
- this does not touch that rule. What changes is that a consumer no
84
- longer has to choose between reading the exit code and discarding
85
- everything the run DID measure: `--format json` prints exactly one
86
- object to stdout, always carrying `verdict` (the same
87
- `"clean" | "findings" | "indeterminate"` states this package uses
88
- everywhere), `findings`, and `unchecked` together, regardless of which
89
- verdict resulted — so a real finding produced alongside a genuinely
90
- unclassifiable construct in the same run is still reachable by a
91
- consumer that reads past the exit code, exactly as #753 asked for,
92
- while a consumer that only checks `exitCode`/`verdict` still, correctly,
93
- never sees an indeterminate run reported as a pass.
94
-
95
- ## [0.3.6] - 2026-09-14
96
-
97
- ### Changed
98
-
99
- - Patch version bump only, to obtain a fresh, never-before-used
100
- `governance/release-qualifications/` record path. The 0.3.5 qualification
101
- record added by #811 was orphaned when that pull request was squash-merged
102
- (#821) and had to be removed (#834); the immutability gate that protects
103
- already-introduced record paths (`check-candidate-qualification.mjs`'s
104
- single-introduction-commit invariant) means a valid record can never again
105
- be introduced at the `0.3.5` path, so this package moves to `0.3.6`
106
- purely to regain one. No functional or behavioral change.
107
-
108
-
109
- ## [0.3.5] - 2026-09-09
110
-
111
- ### Changed
112
-
113
- - Historical entries below now describe the previous npm scope without naming
114
- the producer account this catalogue no longer publishes under, and links to
115
- this repository use its current `clossys/foundry` path. No date, version,
116
- or recorded fact changed — only the way the retired scope is referred to.
117
-
118
-
119
- ## [0.3.4] - 2026-09-02
120
-
121
- ### Fixed
122
-
123
- - Declared `bin` targets without a leading `./`. npm rejected the dotted
124
- form as an invalid script name and **removed the entry entirely** on
125
- publish, so `writer-check` would not have been installed
126
- by a consumer of the previous release.
127
-
128
- ### Changed
129
-
130
- - Named Clossys as copyright holder in `LICENSE` and as `author` in the
131
- package manifest, so every package in the catalogue attributes identically.
132
-
133
-
134
- ## [0.3.3] - 2026-08-31
135
-
136
- ### Changed
137
-
138
- - Prepared a bounded trusted-publisher patch source for provenance after the owner-present first publication and anonymous registry verification. This change does not publish the package or claim provenance.
139
-
140
- ## [0.3.2] - 2026-08-30
141
-
142
- ### Changed
143
-
144
- - Updated the package's public repository, issue-tracker, and homepage metadata to the canonical Foundry repository. This change is not a publication or qualification claim.
145
-
146
- ## [0.3.1] - 2026-08-24
147
-
148
- ### Fixed
149
-
150
- - Added a current lifecycle note to the historical donor availability record.
151
-
152
- ## [0.3.0] - 2026-08-21
153
-
154
- ### Added — the passage layer (issue #373)
155
-
156
- **A `Passage` composes `CopyEntry`/glossary-term REFERENCES the way a UI
157
- block composes atoms.** `@clossys/writer` already had terms (a
158
- glossary) and entries (single addressable strings) and nothing between
159
- them — in practice nobody reuses one string; they reuse a whole
160
- empty-state (title + body + action), a whole FAQ item (question + answer),
161
- a whole error (message + recovery). This release adds that missing
162
- middle: terms ≈ tokens, entries ≈ atoms, passages ≈ blocks. Documents
163
- (the composition layer, mirroring how a view composes blocks) remain out
164
- of scope for this release — see the issue.
165
-
166
- - **`PassageRecord`/`Passage`** (`passage.ts`): a `Passage` has a stable
167
- dot-separated `id`, a required `context` (an unlocatable passage is not
168
- reviewable, mirroring `CopyEntry.context`'s own rule), and `fields` — a
169
- set of named slots (`title`, `body`, `action`, ...) each of which should
170
- hold a `PassageReference`: `{ ref: "entry", id }` or `{ ref: "term",
171
- term }`.
172
- - **`validatePassageRecordShape`/`parsePassageRecord`** — structural
173
- validation, in the same dependency-free, accumulate-and-keep-going style
174
- every other schema in this package uses. Deliberately does NOT validate
175
- a field's own value shape (whether it's a literal or a reference) — see
176
- below.
177
- - **`readPassageRecord`** — the one place in `passage.ts` that touches a
178
- filesystem; never throws, mirrors `registry.ts`'s `readCopyRecord`
179
- exactly.
180
- - **`classifyPassageField`/`checkPassageComposition`** — the passage
181
- COMPOSITION gate, wired to a new CLI subcommand, `writer-check passages
182
- <registry-file>`, dispatched the identical way `writer-check
183
- addressability` already is (a fully separate top-level branch, its own
184
- exported `mainPassagesCheck`, never folded through `main()`). THE
185
- TERNARY:
186
- - **`0` (satisfied)** — every passage references only entries and
187
- terms, at least one passage evaluated.
188
- - **`1` (violated)** — a passage inlines a literal string instead of
189
- referencing an entry (the verbal equivalent of a hardcoded value
190
- instead of a token), or references another passage's own internals
191
- (`{ ref: "passage", ... }`) rather than composing entries/terms the
192
- way a block composes atoms. Wins over an incomplete picture in the
193
- same run — the identical "a real violation must outrank an incomplete
194
- scan" precedence this package's own `addressability` gate settled on
195
- for issue #407/#433, applied here from the start.
196
- - **`2` (indeterminate)** — the registry could not be
197
- read/parsed/validated, zero passages were registered, or a field's
198
- value could not be confidently classified, with zero violations found.
199
- Fails CLOSED with a machine-readable reason; never a silent pass.
200
- - **What this gate deliberately does not do**: verify a referenced entry
201
- id or term actually exists in a real `CopyRecord`/glossary. That is a
202
- different, weaker question than the one this gate answers (composition
203
- purity: is this field a reference at all, never mind whether it
204
- resolves) — the same split `addressability.ts` already draws from
205
- `copy-gate.ts`'s traceability check. See
206
- `passage.adversarial.test.ts` for the proof: a weaker
207
- "every referenced entry id exists" tool passes a passage built entirely
208
- from inline literals (it has zero references to check), while
209
- `writer-check passages`, spawned as the compiled CLI, correctly exits 1
210
- on the identical fixture.
211
- - Not ported from `@clossys/designer/tokens`: the `brandable` boolean.
212
- See `passage.ts`'s own top doc comment, "WHERE THE MIRROR STOPS", for
213
- why forcing that field into this layer would be false symmetry.
214
-
215
- `checkPassageComposition`, `classifyPassageField`, `parsePassageRecord`,
216
- `readPassageRecord`, `validatePassageRecordShape`, and every associated
217
- type are exported from this package's root entry point.
218
-
219
- ## [0.2.0] - 2026-08-21
220
-
221
- ### Changed — BEHAVIOURAL, read this before upgrading (issue #407)
222
-
223
- **`writer-check addressability`'s exit-code precedence flipped.** A run that
224
- finds at least one violation now exits `1` REGARDLESS of how many string
225
- positions are unclassified. Previously, any unclassified ("unchecked")
226
- position forced exit `2` ("indeterminate") even when the same run had
227
- already found and named real violations — and on any real tree, hundreds of
228
- positions are token data this gate cannot classify by design, so the old
229
- precedence made `1` unreachable outside a fixture: every real run had *some*
230
- unclassified positions and therefore always read `2`, silently discarding
231
- every violation it had actually found.
232
-
233
- - **`violated` (exit `1`)** — at least one violation, regardless of
234
- unclassified count. The coverage gap is not hidden by this: `unchecked`
235
- and `reasons` are still populated and `writer-check addressability`
236
- still prints them unconditionally; only the verdict changed.
237
- - **`indeterminate` (exit `2`)** — zero violations AND at least one
238
- unclassified position (or the tree could not be read, or zero components
239
- were scanned). The honest "found nothing, but did not see everything"
240
- case — unchanged, and still never a pass.
241
- - **`satisfied` (exit `0`)** — zero violations, zero unclassified, over at
242
- least one scanned file. Unchanged.
243
-
244
- **If your CI treats `writer-check addressability`'s exit `2` as
245
- non-blocking or "flaky, coverage is never complete, ignore it": stop.** A
246
- tree that used to report `2` will now correctly report `1` whenever it
247
- contains a real violation, and that is the point of this release, not a
248
- regression — those trees always had the violation, this exit code was
249
- previously the only thing hiding it.
250
-
251
- `checkAddressability`'s `AddressabilityGateResult.verdict`/`.reasons` and
252
- `mainAddressabilityCheck`'s exit code both changed together; no other
253
- export's shape changed. See `addressability.ts`'s top doc comment ("THE
254
- TERNARY") and `README.md`'s "Copy addressability" section for the full
255
- precedence.
256
-
257
- ## [0.1.0] - 2026-08-21
258
-
259
- First release. This package is the writer role, recut from the previous
260
- scope's `copy` per
261
- [decision 10](../../docs/DECISIONS.md#10-recutting-the-expression-surface-into-role-shaped-packages).
262
-
263
- This changelog starts here rather than carrying the donor's history, which
264
- cites decisions and issues that would mean nothing — or the wrong thing — to
265
- a reader who arrives at this package first.
266
-
267
- ### Added
268
-
269
- - A consumer-owned language system: voice rules (glossary terms and
270
- regex-safe pattern rules), claims validation, addressable and
271
- locale-aware copy records (`CopyRegistry`, `CopyRef`), source
272
- traceability scanning, and computed content fingerprints.
273
- - `readCopyRecord` and the `checkCopy` voice checker, unchanged from the
274
- donor.
275
- - Four gates, all reachable from the single `writer-check` bin: the
276
- default traceability command, `addressability`, `voice-derivation-coverage`,
277
- and `locale-coverage`. Each dispatches on `argv[0]` matching exactly —
278
- never on `basename(process.argv[1])`, which would see `cli.js` and
279
- silently run the wrong command wherever a gate is invoked by compiled
280
- path.
281
- - Zero runtime dependencies, unchanged from the donor.
282
- - The `voice-record.template.jsonc` template, still reachable at the
283
- `@clossys/writer/voice-record.template.jsonc` export subpath.
284
- - **The published tarball carries this changelog.** `files` includes
285
- `CHANGELOG.md`, following the convention the operation packages adopted in
286
- #417. A consumer reading the installed package should not have to leave it
287
- to find out what changed; a new package should be born with the current
288
- convention rather than inheriting its donor's gap.
289
-
290
- ### Changed from the previous scope's `copy`
291
-
292
- - **The package is named for the job, not the artifact.** The role's
293
- exclusive question is *is it well said?* A name that describes a thing
294
- rather than a doer is an artifact, and an artifact belongs inside a role.
295
- - **The bin is `writer-check`, not `copy-check`.** Same program, same four
296
- subcommands, renamed to match the package.
297
- - **Nothing else was renamed.** `CopyRegistry`, `CopyRef`, `checkCopyRecord`,
298
- `CopyEntry`, `checkCopyTraceability`, the `copy-record` vocabulary, and
299
- every voice/glossary/claim term keep their names. A role owns artifacts;
300
- renaming the role does not rename what it reasons about. A sweep that also
301
- renamed the vocabulary would have made the diff unreviewable while
302
- changing no behaviour.
303
- - Self-referential `copy` package-name mentions in doc
304
- comments — including the `/voice` subpath — were updated to
305
- `@clossys/writer`, the same treatment `strategist` gave its own
306
- self-references to its own donor, `strategy`.
307
-
308
- ### On the donor, and why it is not deprecated yet
309
-
310
- > **Current lifecycle note:** the previous scope's `copy` and
311
- > `surface` are now retired. This release note records their
312
- > state at 0.1.0; the lifecycle contract is the authority for current
313
- > availability.
314
-
315
- The previous scope's `copy` stays `published` for now. It cannot be marked
316
- deprecated while that scope's `surface` still declares it as a runtime
317
- dependency — `check:package-governance` reports a lifecycle finding for a live
318
- package depending on a deprecated one, and it is right to. The donors are
319
- deprecated once `publisher` replaces `surface` and depends on this package
320
- instead.
321
-
322
- This is a deferral with a trigger, not an omission.
323
-
324
- ### Not included
325
-
326
- - **No forwarding stub in the donor.** The previous scope's `copy` is
327
- deprecated-and-retained: still installable for a consumer already pinned
328
- to it, with no re-export pointing here. A stub would keep the old name
329
- importable, and a supersession check could then never reach zero — the
330
- forwarding layer would defeat the gate built to prove the swap completed.