@clossys/writer 0.3.2

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 (115) hide show
  1. package/CHANGELOG.md +196 -0
  2. package/LICENSE +21 -0
  3. package/README.md +593 -0
  4. package/dist/addressability.d.ts +245 -0
  5. package/dist/addressability.d.ts.map +1 -0
  6. package/dist/addressability.js +567 -0
  7. package/dist/addressability.js.map +1 -0
  8. package/dist/checker.d.ts +159 -0
  9. package/dist/checker.d.ts.map +1 -0
  10. package/dist/checker.js +177 -0
  11. package/dist/checker.js.map +1 -0
  12. package/dist/cli.d.ts +149 -0
  13. package/dist/cli.d.ts.map +1 -0
  14. package/dist/cli.js +1049 -0
  15. package/dist/cli.js.map +1 -0
  16. package/dist/copy-gate.d.ts +107 -0
  17. package/dist/copy-gate.d.ts.map +1 -0
  18. package/dist/copy-gate.js +132 -0
  19. package/dist/copy-gate.js.map +1 -0
  20. package/dist/fingerprint.d.ts +61 -0
  21. package/dist/fingerprint.d.ts.map +1 -0
  22. package/dist/fingerprint.js +64 -0
  23. package/dist/fingerprint.js.map +1 -0
  24. package/dist/index.d.ts +47 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +63 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/locale-coverage.d.ts +227 -0
  29. package/dist/locale-coverage.d.ts.map +1 -0
  30. package/dist/locale-coverage.js +414 -0
  31. package/dist/locale-coverage.js.map +1 -0
  32. package/dist/passage.d.ts +294 -0
  33. package/dist/passage.d.ts.map +1 -0
  34. package/dist/passage.js +463 -0
  35. package/dist/passage.js.map +1 -0
  36. package/dist/path-exclusions.d.ts +114 -0
  37. package/dist/path-exclusions.d.ts.map +1 -0
  38. package/dist/path-exclusions.js +213 -0
  39. package/dist/path-exclusions.js.map +1 -0
  40. package/dist/registry.d.ts +61 -0
  41. package/dist/registry.d.ts.map +1 -0
  42. package/dist/registry.js +64 -0
  43. package/dist/registry.js.map +1 -0
  44. package/dist/resolve.d.ts +33 -0
  45. package/dist/resolve.d.ts.map +1 -0
  46. package/dist/resolve.js +133 -0
  47. package/dist/resolve.js.map +1 -0
  48. package/dist/scan.d.ts +457 -0
  49. package/dist/scan.d.ts.map +1 -0
  50. package/dist/scan.js +1698 -0
  51. package/dist/scan.js.map +1 -0
  52. package/dist/schema.d.ts +81 -0
  53. package/dist/schema.d.ts.map +1 -0
  54. package/dist/schema.js +482 -0
  55. package/dist/schema.js.map +1 -0
  56. package/dist/types.d.ts +268 -0
  57. package/dist/types.d.ts.map +1 -0
  58. package/dist/types.js +40 -0
  59. package/dist/types.js.map +1 -0
  60. package/dist/voice/checker.d.ts +186 -0
  61. package/dist/voice/checker.d.ts.map +1 -0
  62. package/dist/voice/checker.js +483 -0
  63. package/dist/voice/checker.js.map +1 -0
  64. package/dist/voice/derivation-coverage.d.ts +168 -0
  65. package/dist/voice/derivation-coverage.d.ts.map +1 -0
  66. package/dist/voice/derivation-coverage.js +181 -0
  67. package/dist/voice/derivation-coverage.js.map +1 -0
  68. package/dist/voice/fields.d.ts +107 -0
  69. package/dist/voice/fields.d.ts.map +1 -0
  70. package/dist/voice/fields.js +144 -0
  71. package/dist/voice/fields.js.map +1 -0
  72. package/dist/voice/index.d.ts +19 -0
  73. package/dist/voice/index.d.ts.map +1 -0
  74. package/dist/voice/index.js +24 -0
  75. package/dist/voice/index.js.map +1 -0
  76. package/dist/voice/internal/parse-template.d.ts +27 -0
  77. package/dist/voice/internal/parse-template.d.ts.map +1 -0
  78. package/dist/voice/internal/parse-template.js +111 -0
  79. package/dist/voice/internal/parse-template.js.map +1 -0
  80. package/dist/voice/internal/pattern-safety.d.ts +111 -0
  81. package/dist/voice/internal/pattern-safety.d.ts.map +1 -0
  82. package/dist/voice/internal/pattern-safety.js +278 -0
  83. package/dist/voice/internal/pattern-safety.js.map +1 -0
  84. package/dist/voice/schema.d.ts +65 -0
  85. package/dist/voice/schema.d.ts.map +1 -0
  86. package/dist/voice/schema.js +535 -0
  87. package/dist/voice/schema.js.map +1 -0
  88. package/dist/voice/types.d.ts +282 -0
  89. package/dist/voice/types.d.ts.map +1 -0
  90. package/dist/voice/types.js +37 -0
  91. package/dist/voice/types.js.map +1 -0
  92. package/package.json +72 -0
  93. package/src/addressability.ts +664 -0
  94. package/src/checker.ts +293 -0
  95. package/src/cli.ts +1166 -0
  96. package/src/copy-gate.ts +197 -0
  97. package/src/fingerprint.ts +66 -0
  98. package/src/index.ts +163 -0
  99. package/src/locale-coverage.ts +512 -0
  100. package/src/passage.ts +644 -0
  101. package/src/path-exclusions.ts +265 -0
  102. package/src/registry.ts +103 -0
  103. package/src/resolve.ts +172 -0
  104. package/src/scan.ts +1959 -0
  105. package/src/schema.ts +528 -0
  106. package/src/types.ts +301 -0
  107. package/src/voice/checker.ts +590 -0
  108. package/src/voice/derivation-coverage.ts +217 -0
  109. package/src/voice/fields.ts +160 -0
  110. package/src/voice/index.ts +55 -0
  111. package/src/voice/internal/parse-template.ts +114 -0
  112. package/src/voice/internal/pattern-safety.ts +336 -0
  113. package/src/voice/schema.ts +585 -0
  114. package/src/voice/types.ts +329 -0
  115. package/templates/voice-record.template.jsonc +135 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,268 @@
1
+ /**
2
+ * Plain TypeScript types for @clossys/writer's contract: one
3
+ * addressable, reviewable piece of copy (`CopyEntry`) and the record that
4
+ * groups a consumer's whole set of them (`CopyRecord`). Pure data — no
5
+ * validation logic lives here (see `schema.ts`) and no I/O (see
6
+ * `registry.ts`).
7
+ *
8
+ * This is the FROZEN CONTRACT this package and its sibling scanner/gate
9
+ * half (built in parallel, against the exact same shape) were both
10
+ * compiled against. Do not add, remove, rename, or reshape a field here
11
+ * without updating both halves in lockstep — a silent drift here breaks
12
+ * the other half's compile, not this package's own tests.
13
+ *
14
+ * No runtime schema library. That follows this repository's own
15
+ * precedent, restated once more because it matters more here than
16
+ * anywhere else: `@example/catalog`, `@example/policy`,
17
+ * `@example/ui/tokens`, and `@clossys/writer/voice` all ship zero
18
+ * runtime dependencies; only `@example/ui` carries any, and only
19
+ * because it wraps React primitives it genuinely cannot hand-roll. This
20
+ * package's entire job is dependency-free data shape validation — the
21
+ * same job `@example/strategy`'s `validation.ts` and
22
+ * `@clossys/writer/voice`'s `schema.ts` already do, in plain type
23
+ * guards, for their own shapes. `schema.ts` follows that pattern closely
24
+ * rather than pulling in a schema library (and its own major-version
25
+ * churn, a real cost for a *public* package's consumers) for what one
26
+ * file of type guards already covers.
27
+ *
28
+ * This file ships no example content of anyone's real copy. Every field
29
+ * here is either required-and-generic or a structural placeholder —
30
+ * filling in an actual product's actual sentences is a consumer's job.
31
+ * See "The single most important constraint" in the README: this package
32
+ * is to `@clossys/writer/voice` what `@example/ui` is to
33
+ * `@example/ui/tokens` — a vocabulary layer over a contract layer,
34
+ * never a source of real words. If a doc comment, a test fixture, or a
35
+ * README example in this package ever reads like something a product
36
+ * would actually show a user, that is a bug in this package, not a
37
+ * feature of it.
38
+ */
39
+ /**
40
+ * A stable address for one `CopyEntry`, unique within its `CopyRecord`.
41
+ * Dot-separated, lowercase, kebab-case within each segment — e.g.
42
+ * `"pagination.no-results"`, `"onboarding.step-2.title"`. At least one
43
+ * dot is required: a bare, unnamespaced id like `"title"` is exactly the
44
+ * kind of id that collides the moment a second feature also needs a
45
+ * `"title"` entry, which is the whole reason this package asks for a
46
+ * namespaced, dot-separated address rather than an arbitrary free-text
47
+ * string. See `schema.ts`'s `COPY_ENTRY_ID_RE` for the exact pattern this
48
+ * shape is validated against.
49
+ *
50
+ * A plain `string` alias, not a branded/nominal type: this package has no
51
+ * runtime mechanism to keep a caller from constructing one by hand
52
+ * outside `validateCopyRecordShape`/`parseCopyRecord`, so pretending
53
+ * otherwise at the type level would be a false promise. The alias exists
54
+ * purely to make every signature below say what kind of string it means.
55
+ */
56
+ export type CopyEntryId = string;
57
+ /**
58
+ * A locale tag supplied by the consumer (normally a BCP 47 tag such as
59
+ * `en` or `fr-CA`). It remains a plain string because locale support is a
60
+ * consumer policy: copy must not bundle a second internationalisation stack.
61
+ */
62
+ export type CopyLocale = string;
63
+ /** Values permitted when a `CopyRef` fills a registered `{placeholder}`. */
64
+ export type CopyValue = string | number | boolean;
65
+ /**
66
+ * The stable, serialisable way another package asks copy for audience-facing
67
+ * text. Surface documents carry this value instead of a prose literal.
68
+ *
69
+ * `locale` is a request, not a fallback algorithm. The resolver owns the
70
+ * fallback policy and fails closed when no compatible registry is available.
71
+ */
72
+ export interface CopyRef {
73
+ id: CopyEntryId;
74
+ locale?: CopyLocale;
75
+ values?: Readonly<Record<string, CopyValue>>;
76
+ }
77
+ /** Lifecycle state of a registry entry. Only approved entries can resolve. */
78
+ export type CopyEntryStatus = "draft" | "approved" | "retired";
79
+ /**
80
+ * Consumer-supplied provenance for a resolvable copy registry. `reference`
81
+ * is deliberately opaque: it may be a revision-control object, CMS revision,
82
+ * or editorial record, without Foundry importing that system.
83
+ */
84
+ export interface CopySource {
85
+ kind: "consumer" | "generated" | "imported";
86
+ reference: string;
87
+ }
88
+ /**
89
+ * One piece of copy a consumer's product shows a user, made addressable,
90
+ * reviewable, and checkable. This package never populates `text` with
91
+ * anything real — every `CopyEntry` a consumer's own repository registers
92
+ * is that repository's own words, the same way a `VoiceRecord`'s
93
+ * `glossary` and `claims` are never this package's words either (see
94
+ * `@clossys/writer/voice`'s README, "The single most important
95
+ * constraint").
96
+ */
97
+ export interface CopyEntry {
98
+ /** Stable address. Unique within the `CopyRecord` it belongs to — see `CopyEntryId`. */
99
+ id: CopyEntryId;
100
+ /** The copy itself — a consumer's own words, never this package's. */
101
+ text: string;
102
+ /**
103
+ * Where this copy appears — a screen name, a component, a route, a
104
+ * notification type. Required, and deliberately not optional: an entry
105
+ * with no stated location cannot be found by a human reviewer skimming
106
+ * a report, which makes it unreviewable in practice even though it is
107
+ * structurally present. "Unlocatable copy is not reviewable copy" is
108
+ * the one-line version of why this field exists at all.
109
+ */
110
+ context: string;
111
+ /**
112
+ * Named interpolations `text` must contain, e.g. `["start", "end",
113
+ * "total"]` for copy like `"Showing {start}–{end} of {total}
114
+ * results"`. Each name in this list is checked against `text` using the
115
+ * literal `{name}` convention — the same brace-delimited placeholder
116
+ * syntax already familiar from ICU MessageFormat and most i18n
117
+ * libraries — by `schema.ts`'s shape validation: a name declared here
118
+ * but not found as `{name}` in `text` is treated as a real bug (the
119
+ * copy was edited and the interpolation was dropped, or the
120
+ * placeholder list drifted from the actual sentence), not decoration.
121
+ * See `schema.ts` for exactly how this is checked, and this package's
122
+ * README for why this is presence-detection over an already-authored
123
+ * string, not a formatting engine: `Intl.PluralRules`,
124
+ * `Intl.ListFormat`, `Intl.RelativeTimeFormat`, and
125
+ * `Intl.NumberFormat.prototype.formatRange` already exist natively in
126
+ * Node 20+ for the actual formatting work, and this package does not
127
+ * re-wrap any of them.
128
+ *
129
+ * Optional — an entry with no interpolations at all (most copy) simply
130
+ * omits this field; `parseCopyRecord` defaults it to `[]`.
131
+ */
132
+ placeholders?: string[];
133
+ /**
134
+ * A plain string into a consumer's own facts registry — never a typed
135
+ * import, never a runtime dependency on `@example/strategy`.
136
+ * This mirrors exactly how `@clossys/writer/voice`'s `Claim.factRef`
137
+ * refers to a `strategy` package's facts without importing it: the
138
+ * coupling is an opaque string convention, not a code import, so this
139
+ * package works today, before `strategy` (or a consumer's own facts
140
+ * registry) exists at all, and keeps working unchanged after it does.
141
+ * Resolving a `factRef` against a real facts registry is a later gate's
142
+ * job, one with visibility into both this package's entries and that
143
+ * registry — deliberately not this package's, and not
144
+ * `@clossys/writer/voice`'s either. See the README, "The `factRef`
145
+ * seam", for the fuller argument (borrowed near-verbatim from that
146
+ * package's own README section of the same name, because it is the
147
+ * same seam, one layer over).
148
+ */
149
+ factRef?: string;
150
+ }
151
+ /**
152
+ * Content-derived provenance for one target-locale translation. Present only
153
+ * on a target-locale `CopyRegistryEntry` — a source-locale entry has nothing
154
+ * to be "translated from" and never carries this field. See
155
+ * `computeCopyFingerprint` below and `locale-coverage.ts`'s doc comment for
156
+ * why this is a fingerprint of the source text, never a human-maintained
157
+ * revision number: a hand-bumped counter requires someone to remember to
158
+ * bump it every time source copy changes, and nothing enforces that
159
+ * discipline, so it silently drifts out of sync. A content hash cannot drift
160
+ * the same way — it changes if and only if the text it was computed from
161
+ * changed.
162
+ */
163
+ export interface CopyTranslationProvenance {
164
+ /**
165
+ * A fingerprint of the SOURCE entry's `text`, computed with
166
+ * `fingerprintAlgorithm`, at the moment this translation was produced.
167
+ * Compared against a fresh `computeCopyFingerprint(sourceEntry.text)` by
168
+ * `checkLocaleCoverage` to detect staleness — see that file's doc
169
+ * comment for the full comparison.
170
+ */
171
+ sourceFingerprint: string;
172
+ /**
173
+ * The algorithm `sourceFingerprint` was computed with, e.g. `"sha256"` —
174
+ * matches `COPY_FINGERPRINT_ALGORITHM`, the constant `computeCopyFingerprint`
175
+ * (`fingerprint.ts`) is documented to use. Declared explicitly, per entry,
176
+ * so a future algorithm change is a detectable mismatch rather than a
177
+ * silent comparison between two fingerprints computed two different ways.
178
+ */
179
+ fingerprintAlgorithm: string;
180
+ /** ISO-8601 timestamp of when this translation was produced. */
181
+ translatedAt: string;
182
+ /**
183
+ * Opaque translator/vendor-job identifier — never a personal name. This
184
+ * package ships no real identity data, per its own "no real product
185
+ * sentences" constraint (see this file's top-of-file doc comment).
186
+ */
187
+ translatedBy?: string;
188
+ /** ISO-8601 timestamp of when this translation was last reviewed, if it has been. */
189
+ reviewedAt?: string;
190
+ /** Opaque reviewer identifier, mirroring `translatedBy` — never a personal name. */
191
+ reviewedBy?: string;
192
+ }
193
+ /** A `CopyEntry` that is eligible to participate in a rendered registry. */
194
+ export interface CopyRegistryEntry extends CopyEntry {
195
+ status: CopyEntryStatus;
196
+ /**
197
+ * Content-derived translation provenance, present only on a target-locale
198
+ * entry that has recorded it. Optional: absent on every source-locale
199
+ * entry, and absent on any target-locale entry authored before this field
200
+ * existed or by a host that has not adopted it yet — an existing registry
201
+ * does not become invalid overnight. See `locale-coverage.ts` for how
202
+ * presence/absence of this field changes what `checkLocaleCoverage` can
203
+ * report: an entry with `translation` gets a real stale/not-stale
204
+ * verdict; an entry without it gets `"locale-coverage:provenance-missing"`
205
+ * instead, which is a DIFFERENT outcome from "checked and not stale" —
206
+ * never collapsed into one signal.
207
+ */
208
+ translation?: CopyTranslationProvenance;
209
+ }
210
+ /**
211
+ * One consumer's complete, registered set of copy entries. This is the
212
+ * "brand.css" of this package — foundry ships the schema this conforms
213
+ * to and the machinery to check it, never a real instance of it. See the
214
+ * README, "The single most important constraint".
215
+ */
216
+ export interface CopyRecord {
217
+ id: string;
218
+ entries: CopyEntry[];
219
+ }
220
+ /**
221
+ * A versioned, locale-specific `CopyRecord` that can safely resolve
222
+ * `CopyRef`s for an audience-facing surface. The older `CopyRecord` remains
223
+ * the deliberately minimal scanner/checker input; resolution requires this
224
+ * stronger contract so a manifest never pretends unversioned text is traced.
225
+ */
226
+ export interface CopyRegistry extends CopyRecord {
227
+ locale: CopyLocale;
228
+ revision: string;
229
+ source: CopySource;
230
+ entries: CopyRegistryEntry[];
231
+ }
232
+ /** A successful, fully traced resolution of one copy reference. */
233
+ export interface CopyResolution {
234
+ ref: CopyRef;
235
+ text: string;
236
+ recordId: string;
237
+ revision: string;
238
+ locale: CopyLocale;
239
+ source: CopySource;
240
+ entryId: CopyEntryId;
241
+ }
242
+ /** Resolver shape for callers that need rendered audience text. */
243
+ export type CopyResolver = (ref: CopyRef) => CopyResolution | undefined;
244
+ /**
245
+ * One thing `schema.ts`'s shape validation found wrong with a candidate
246
+ * `CopyRecord` or `CopyEntry`. Deliberately the same shape as
247
+ * `@clossys/writer/voice`'s `VoiceFinding` (itself deliberately the same
248
+ * shape as `@example/policy`'s `Finding`) — `rule` / `severity` /
249
+ * `message` / optional `path` — so a caller already handling one kind of
250
+ * finding in this repository's ecosystem does not need a second mental
251
+ * model for this package's. Defined fresh here, not imported: this
252
+ * file's own zero-runtime-dependency requirement applies to
253
+ * `@clossys/writer/voice` too — `types.ts` and `schema.ts` do not import
254
+ * from it. (`checker.ts` does depend on `@clossys/writer/voice`, for
255
+ * `checkCopy` itself — see that file's own doc comment for why that
256
+ * dependency is confined there.)
257
+ */
258
+ export interface CopyFinding {
259
+ /** Stable identifier for the rule that produced this finding, e.g. `"id-shape"`, `"placeholder-missing-from-text"`. */
260
+ rule: string;
261
+ /** Always `"error"` from `schema.ts` — a malformed `CopyRecord` is never merely a warning. */
262
+ severity: "error" | "warning";
263
+ /** Human-readable description of the problem. */
264
+ message: string;
265
+ /** The specific field, entry index, or placeholder name this finding is about, when there is a single clear one. */
266
+ path?: string;
267
+ }
268
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Plain TypeScript types for @clossys/writer's contract: one
3
+ * addressable, reviewable piece of copy (`CopyEntry`) and the record that
4
+ * groups a consumer's whole set of them (`CopyRecord`). Pure data — no
5
+ * validation logic lives here (see `schema.ts`) and no I/O (see
6
+ * `registry.ts`).
7
+ *
8
+ * This is the FROZEN CONTRACT this package and its sibling scanner/gate
9
+ * half (built in parallel, against the exact same shape) were both
10
+ * compiled against. Do not add, remove, rename, or reshape a field here
11
+ * without updating both halves in lockstep — a silent drift here breaks
12
+ * the other half's compile, not this package's own tests.
13
+ *
14
+ * No runtime schema library. That follows this repository's own
15
+ * precedent, restated once more because it matters more here than
16
+ * anywhere else: `@example/catalog`, `@example/policy`,
17
+ * `@example/ui/tokens`, and `@clossys/writer/voice` all ship zero
18
+ * runtime dependencies; only `@example/ui` carries any, and only
19
+ * because it wraps React primitives it genuinely cannot hand-roll. This
20
+ * package's entire job is dependency-free data shape validation — the
21
+ * same job `@example/strategy`'s `validation.ts` and
22
+ * `@clossys/writer/voice`'s `schema.ts` already do, in plain type
23
+ * guards, for their own shapes. `schema.ts` follows that pattern closely
24
+ * rather than pulling in a schema library (and its own major-version
25
+ * churn, a real cost for a *public* package's consumers) for what one
26
+ * file of type guards already covers.
27
+ *
28
+ * This file ships no example content of anyone's real copy. Every field
29
+ * here is either required-and-generic or a structural placeholder —
30
+ * filling in an actual product's actual sentences is a consumer's job.
31
+ * See "The single most important constraint" in the README: this package
32
+ * is to `@clossys/writer/voice` what `@example/ui` is to
33
+ * `@example/ui/tokens` — a vocabulary layer over a contract layer,
34
+ * never a source of real words. If a doc comment, a test fixture, or a
35
+ * README example in this package ever reads like something a product
36
+ * would actually show a user, that is a bug in this package, not a
37
+ * feature of it.
38
+ */
39
+ export {};
40
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG"}
@@ -0,0 +1,186 @@
1
+ /**
2
+ * `checkCopy` — the working voice checker. Given a `VoiceRecord` (already
3
+ * validated — see `schema.ts`) and a piece of copy, reports the subset of
4
+ * voice violations that are actually mechanically detectable: forbidden
5
+ * glossary terms, forbidden person/tense word-markers, claims made in the
6
+ * copy that lack a `factRef` while `requiresSupport` is true, and —
7
+ * unconditionally, whether or not `copy` is even given — whether `record`
8
+ * itself is still (partly) an unedited copy of `voice-record.template.jsonc`.
9
+ *
10
+ * Pure, no I/O: every input is already in memory, every output is plain
11
+ * data. `checkCopy` never reads a file, never calls `strategy` or any other
12
+ * package, and never resolves a `factRef` against anything — see the
13
+ * README's "The `factRef` seam" for why that resolution is deliberately not
14
+ * this package's job.
15
+ *
16
+ * FAILS CLOSED. Three situations that would otherwise look like "nothing
17
+ * was wrong" are instead surfaced as an explicit, visible incompleteness or
18
+ * an explicit, unmissable error — never as a silent, empty-findings pass:
19
+ *
20
+ * 1. `copy` is empty or whitespace-only: every dimension is recorded in
21
+ * `skipped`, not run, and `findings` is empty for a reason a caller
22
+ * can see, not because the copy was clean.
23
+ * 2. A dimension has nothing configured to check against (e.g. no
24
+ * forbidden pronouns in `rules.person`, or an empty glossary) is
25
+ * likewise recorded in `skipped` rather than silently contributing
26
+ * zero findings to what would otherwise read as a clean run.
27
+ * 3. `record` still carries `TEMPLATE_PLACEHOLDER` in one or more of its
28
+ * bindable string fields — this voice was never actually bound, only
29
+ * copied from the template. See "The unbound signal" below.
30
+ *
31
+ * `report.complete` is `true` exactly when `skipped` is empty — mirroring
32
+ * `@example/gates`' `FoundationReport.complete` — so a caller can
33
+ * ask "did this report actually check everything it could have" with one
34
+ * boolean read. `report.bound` is the analogous read for #3.
35
+ *
36
+ * THE UNBOUND SIGNAL
37
+ * -------------------
38
+ * `@example/ui/tokens` has a visual answer to "did anyone bind this
39
+ * yet": import only `tokens.css` and the page renders in visible grey, plus
40
+ * a literal dev-mode badge, until `data-brand-bound` is set. Text has no
41
+ * pixels to fall back to — there is no "render this copy in grey" — so the
42
+ * honest analog is not visual, it's TRUTHFUL DEFAULT DATA: every bindable
43
+ * slot in `voice-record.template.jsonc` is filled with one specific,
44
+ * exported, unmistakable sentinel (`TEMPLATE_PLACEHOLDER`, from
45
+ * `fields.ts`) instead of a plausible-looking example value. A plausible
46
+ * example (a real-sounding pronoun, a real-sounding claim) is exactly what
47
+ * would let an unbound voice "happen to pass" — it would look indistinguishable
48
+ * from a deliberately-authored record that just happens to match the
49
+ * example. A loud, structurally-unmistakable placeholder cannot be
50
+ * mistaken for real content, which is what makes detecting it a reliable
51
+ * signal rather than a heuristic.
52
+ *
53
+ * `findPlaceholderPaths` below scans every string `checkCopy` can reach in
54
+ * `record` — recursively, the same "leaf, not tree" walk `fields.ts`
55
+ * documents for the template itself — for exact equality with
56
+ * `TEMPLATE_PLACEHOLDER`. If it finds even one, `report.bound` is `false`
57
+ * AND, critically, an `"error"`-severity `"voice:unbound-placeholder"`
58
+ * finding is pushed into `report.findings` for each one — not merely a flag
59
+ * a caller has to remember to check. This is the deliberate design choice:
60
+ * this package's own README (see "Usage") already tells every caller to do
61
+ * `if (report.findings.some(f => f.severity === "error")) process.exitCode = 1;`.
62
+ * An unbound record fails that exact, already-idiomatic check on its own,
63
+ * with no second code path a caller has to add and no way for "still
64
+ * template" and "genuinely clean" to ever produce the same result shape —
65
+ * which is the whole point: an unbound voice must never look like a bound
66
+ * one that happens to pass.
67
+ */
68
+ import type { Claim, VoiceChannel, VoiceFinding, VoiceRecord, VoiceSeverity } from "./types.js";
69
+ /**
70
+ * Which checkable dimension a run can evaluate. `"pattern"` is CONDITIONAL
71
+ * on `record.patterns` — a `VoiceRecord` that never declares `patterns` at
72
+ * all (`record.patterns === undefined`, the exact shape of every existing
73
+ * `VoiceRecord` written before this feature existed) never sees `"pattern"`
74
+ * in `ran`/`skipped` at all, so `report.skipped`/`report.ran`/
75
+ * `report.complete` behave byte-for-byte as they did before this addition —
76
+ * see `checkCopy`'s own comment on `patternsDeclared` for the mechanism,
77
+ * and `checker.test.ts`'s "an existing VoiceRecord that never declares
78
+ * patterns" test for the pinned proof. A `VoiceRecord` that DOES declare
79
+ * `patterns` (even as `[]`) gets `"pattern"` in `skipped`/`ran` exactly like
80
+ * every other dimension already works.
81
+ */
82
+ export type VoiceCheckDimension = "glossary" | "person" | "tense" | "claims" | "pattern";
83
+ /** One dimension `checkCopy` did not evaluate this run, and why. */
84
+ export interface VoiceDimensionSkip {
85
+ dimension: VoiceCheckDimension;
86
+ /**
87
+ * Machine-readable reason: `"empty-copy"` (nothing to scan at all —
88
+ * every dimension gets this reason together), or one of
89
+ * `"no-forbidden-terms-configured"` / `"no-forbidden-pronouns-configured"`
90
+ * / `"no-forbidden-markers-configured"` / `"no-claims-configured"` /
91
+ * `"no-patterns-configured"` (the copy was real, but this dimension's own
92
+ * `VoiceRecord` list was empty).
93
+ */
94
+ reason: string;
95
+ }
96
+ /**
97
+ * `true` exactly for `"error"` — the tier this package's own documented CI
98
+ * idiom (`report.findings.some(f => f.severity === "error")`) treats as
99
+ * build-breaking. Exported so a caller does not have to hardcode the string
100
+ * `"error"` itself to implement that exact idiom — see `VoiceSeverity`'s own
101
+ * doc comment (`types.ts`) for the full three-value mapping this mirrors:
102
+ * `"error"` fails CI, `"warning"` fails only a narrower editorial gate this
103
+ * package does not implement, `"advisory"` never fails anything.
104
+ */
105
+ export declare function isCiBlockingSeverity(severity: VoiceSeverity): boolean;
106
+ /**
107
+ * An explicit, auditable exception for one specific finding. Scoped
108
+ * narrowly on purpose — a waiver matches exactly one `rule` plus the exact
109
+ * `path` of the finding it covers (a single term, pronoun, marker, or claim
110
+ * id), never a whole dimension or the whole run. `reason` is required and
111
+ * non-empty: a waiver with no stated reason is rejected (see
112
+ * `"waiver:invalid"` below), not silently honored.
113
+ */
114
+ export interface VoiceCheckWaiver {
115
+ /** Must equal the `rule` of the finding this waiver covers, e.g. `"glossary:forbidden-term"`. */
116
+ rule: string;
117
+ /** Must equal the `path` of the finding this waiver covers, e.g. the exact forbidden term. */
118
+ match: string;
119
+ /** Required. Why this specific instance is acceptable — this is the audit trail. */
120
+ reason: string;
121
+ }
122
+ /** A `VoiceFinding` that was waived, with the waiver that covered it attached for the audit trail. */
123
+ export interface WaivedVoiceFinding extends VoiceFinding {
124
+ waiver: VoiceCheckWaiver;
125
+ }
126
+ export interface VoiceCheckOptions {
127
+ /** Waivers to apply to this run's raw findings before returning. Defaults to none. */
128
+ waivers?: VoiceCheckWaiver[];
129
+ /**
130
+ * The channel THIS `copy` is being checked for, e.g. `"linkedin"`. A
131
+ * channel-scoped `glossary`/`patterns` entry (see `VoiceChannel` in
132
+ * `types.ts`) only fires when it matches this value exactly — see
133
+ * `ruleAppliesToChannel`'s own doc comment for the omitted-vs-mismatched
134
+ * distinction. Omitted (the default) is IDENTICAL to every prior release
135
+ * of this package: no rule has a `channel` unless its author added one,
136
+ * so an existing `VoiceRecord`/caller that never touches this option
137
+ * behaves exactly as before.
138
+ */
139
+ channel?: VoiceChannel;
140
+ }
141
+ export interface VoiceCheckReport {
142
+ /** Findings not covered by any waiver. Empty does not necessarily mean "clean" — check `complete` and `bound` too. */
143
+ findings: VoiceFinding[];
144
+ /** Findings that were covered by a waiver, each with the waiver that covered it. */
145
+ waived: WaivedVoiceFinding[];
146
+ /** Dimensions this run could not evaluate, and why. Empty means every dimension ran. */
147
+ skipped: VoiceDimensionSkip[];
148
+ /** Dimensions this run actually evaluated (produced zero or more raw findings from real input). */
149
+ ran: VoiceCheckDimension[];
150
+ /** `true` exactly when `skipped` is empty. `false` means this report cannot vouch for having checked everything it could have. */
151
+ complete: boolean;
152
+ /**
153
+ * `false` if `record` still carries `TEMPLATE_PLACEHOLDER` in one or more
154
+ * bindable fields — i.e. this is (at least partly) an unedited copy of
155
+ * `voice-record.template.jsonc`, not a real, bound voice. See this file's
156
+ * top-of-file doc comment, "The unbound signal". Computed unconditionally,
157
+ * independent of `copy` — an unbound `record` is reported as such even
158
+ * when `copy` is empty. Every unbound field also produces its own
159
+ * `"voice:unbound-placeholder"` **error** in `findings`, so `bound: false`
160
+ * is never a silent flag a caller has to remember to check separately.
161
+ */
162
+ bound: boolean;
163
+ }
164
+ /**
165
+ * Registry-level audit, independent of any copy: which claims in `claims`
166
+ * require support (`requiresSupport: true`, the default) but carry no
167
+ * `factRef`. Useful as a standalone "is this claims register itself
168
+ * complete" check, separate from `checkCopy`'s "did THIS copy use one of
169
+ * them" question. Pure, no I/O.
170
+ */
171
+ export declare function auditClaimsRegister(claims: Claim[]): VoiceFinding[];
172
+ /**
173
+ * Checks `copy` against `record`. See this file's top-of-file doc comment
174
+ * for the fail-closed behavior on empty copy and on unconfigured
175
+ * dimensions, and the package README for exactly what each dimension does
176
+ * and does not attempt.
177
+ *
178
+ * Throws a plain `Error` (not a finding) for caller-input problems that are
179
+ * not this function's job to interpret as data: `copy` not a string, or
180
+ * `record` not an object. This mirrors `@example/gates`'
181
+ * `runFoundationCheck`, which treats a malformed call the same way — a hard
182
+ * upfront rejection, not a soft finding that could be mistaken for
183
+ * something the checker discovered about the copy itself.
184
+ */
185
+ export declare function checkCopy(record: VoiceRecord, copy: string, options?: VoiceCheckOptions): VoiceCheckReport;
186
+ //# sourceMappingURL=checker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checker.d.ts","sourceRoot":"","sources":["../../src/voice/checker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AAIH,OAAO,KAAK,EAAE,KAAK,EAAe,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE7G;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEzF,oEAAoE;AACpE,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,mBAAmB,CAAC;IAC/B;;;;;;;OAOG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAErE;AAoBD;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,iGAAiG;IACjG,IAAI,EAAE,MAAM,CAAC;IACb,8FAA8F;IAC9F,KAAK,EAAE,MAAM,CAAC;IACd,oFAAoF;IACpF,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,sGAAsG;AACtG,MAAM,WAAW,kBAAmB,SAAQ,YAAY;IACtD,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,sFAAsF;IACtF,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC7B;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,sHAAsH;IACtH,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,oFAAoF;IACpF,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,wFAAwF;IACxF,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,mGAAmG;IACnG,GAAG,EAAE,mBAAmB,EAAE,CAAC;IAC3B,kIAAkI;IAClI,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;;;;;;OASG;IACH,KAAK,EAAE,OAAO,CAAC;CAChB;AA+ED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,YAAY,EAAE,CAanE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,gBAAgB,CA2R9G"}