agentfootprint 9.52.0 → 9.53.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 (88) hide show
  1. package/AGENTS.md +1 -1
  2. package/CLAUDE.md +4 -1
  3. package/ai-instructions/claude-code/SKILL.md +1 -1
  4. package/bin/agentfootprint-check-semantics.mjs +14 -0
  5. package/dist/core/agent/coverage/read.js +13 -0
  6. package/dist/core/agent/coverage/read.js.map +1 -1
  7. package/dist/core/agent/stages/toolCalls.js +95 -4
  8. package/dist/core/agent/stages/toolCalls.js.map +1 -1
  9. package/dist/core/tools.js +25 -1
  10. package/dist/core/tools.js.map +1 -1
  11. package/dist/debug.js +14 -3
  12. package/dist/debug.js.map +1 -1
  13. package/dist/esm/core/agent/coverage/read.js +13 -0
  14. package/dist/esm/core/agent/coverage/read.js.map +1 -1
  15. package/dist/esm/core/agent/stages/toolCalls.js +95 -4
  16. package/dist/esm/core/agent/stages/toolCalls.js.map +1 -1
  17. package/dist/esm/core/tools.d.ts +24 -0
  18. package/dist/esm/core/tools.js +23 -0
  19. package/dist/esm/core/tools.js.map +1 -1
  20. package/dist/esm/debug.d.ts +1 -0
  21. package/dist/esm/debug.js +7 -0
  22. package/dist/esm/debug.js.map +1 -1
  23. package/dist/esm/events/payloads.d.ts +20 -0
  24. package/dist/esm/events/registry.d.ts +3 -1
  25. package/dist/esm/events/registry.js +2 -0
  26. package/dist/esm/events/registry.js.map +1 -1
  27. package/dist/esm/index.d.ts +2 -1
  28. package/dist/esm/index.js +11 -1
  29. package/dist/esm/index.js.map +1 -1
  30. package/dist/esm/lib/semantics/check.d.ts +70 -0
  31. package/dist/esm/lib/semantics/check.js +154 -0
  32. package/dist/esm/lib/semantics/check.js.map +1 -0
  33. package/dist/esm/lib/semantics/cli.d.ts +40 -0
  34. package/dist/esm/lib/semantics/cli.js +148 -0
  35. package/dist/esm/lib/semantics/cli.js.map +1 -0
  36. package/dist/esm/lib/semantics/envelope.d.ts +139 -0
  37. package/dist/esm/lib/semantics/envelope.js +592 -0
  38. package/dist/esm/lib/semantics/envelope.js.map +1 -0
  39. package/dist/esm/lib/semantics/format.d.ts +11 -0
  40. package/dist/esm/lib/semantics/format.js +33 -0
  41. package/dist/esm/lib/semantics/format.js.map +1 -0
  42. package/dist/esm/lib/semantics/index.d.ts +14 -0
  43. package/dist/esm/lib/semantics/index.js +15 -0
  44. package/dist/esm/lib/semantics/index.js.map +1 -0
  45. package/dist/esm/lib/semantics/types.d.ts +230 -0
  46. package/dist/esm/lib/semantics/types.js +71 -0
  47. package/dist/esm/lib/semantics/types.js.map +1 -0
  48. package/dist/events/registry.js +2 -0
  49. package/dist/events/registry.js.map +1 -1
  50. package/dist/index.js +65 -44
  51. package/dist/index.js.map +1 -1
  52. package/dist/lib/semantics/check.js +158 -0
  53. package/dist/lib/semantics/check.js.map +1 -0
  54. package/dist/lib/semantics/cli.js +176 -0
  55. package/dist/lib/semantics/cli.js.map +1 -0
  56. package/dist/lib/semantics/envelope.js +603 -0
  57. package/dist/lib/semantics/envelope.js.map +1 -0
  58. package/dist/lib/semantics/format.js +37 -0
  59. package/dist/lib/semantics/format.js.map +1 -0
  60. package/dist/lib/semantics/index.js +34 -0
  61. package/dist/lib/semantics/index.js.map +1 -0
  62. package/dist/lib/semantics/types.js +74 -0
  63. package/dist/lib/semantics/types.js.map +1 -0
  64. package/dist/types/core/agent/coverage/read.d.ts.map +1 -1
  65. package/dist/types/core/agent/stages/toolCalls.d.ts.map +1 -1
  66. package/dist/types/core/tools.d.ts +24 -0
  67. package/dist/types/core/tools.d.ts.map +1 -1
  68. package/dist/types/debug.d.ts +1 -0
  69. package/dist/types/debug.d.ts.map +1 -1
  70. package/dist/types/events/payloads.d.ts +20 -0
  71. package/dist/types/events/payloads.d.ts.map +1 -1
  72. package/dist/types/events/registry.d.ts +3 -1
  73. package/dist/types/events/registry.d.ts.map +1 -1
  74. package/dist/types/index.d.ts +2 -1
  75. package/dist/types/index.d.ts.map +1 -1
  76. package/dist/types/lib/semantics/check.d.ts +71 -0
  77. package/dist/types/lib/semantics/check.d.ts.map +1 -0
  78. package/dist/types/lib/semantics/cli.d.ts +41 -0
  79. package/dist/types/lib/semantics/cli.d.ts.map +1 -0
  80. package/dist/types/lib/semantics/envelope.d.ts +140 -0
  81. package/dist/types/lib/semantics/envelope.d.ts.map +1 -0
  82. package/dist/types/lib/semantics/format.d.ts +12 -0
  83. package/dist/types/lib/semantics/format.d.ts.map +1 -0
  84. package/dist/types/lib/semantics/index.d.ts +15 -0
  85. package/dist/types/lib/semantics/index.d.ts.map +1 -0
  86. package/dist/types/lib/semantics/types.d.ts +231 -0
  87. package/dist/types/lib/semantics/types.d.ts.map +1 -0
  88. package/package.json +2 -1
@@ -0,0 +1,592 @@
1
+ /**
2
+ * semantics/envelope — minting, recognizing and projecting the semantic
3
+ * tool-result envelope (9.53.0).
4
+ *
5
+ * Pattern: minted by a helper, RECOGNIZED by the framework (the `absent()` /
6
+ * tool-effects precedent). A return shape the framework does not
7
+ * understand is a convention, and a convention cannot ride the
8
+ * record, feed a UI, or be refused by a build gate.
9
+ * Role: lib/ layer, pure. The dispatch loop calls `readSemantics` at the
10
+ * execute boundary; `semantic()` is what a tool author writes;
11
+ * `checkSemantics` (check.ts) judges the same shapes offline.
12
+ * Emits: N/A (the caller emits `agentfootprint.tools.semantics_declared`).
13
+ *
14
+ * ## Two views of one envelope — the design decision, stated
15
+ *
16
+ * The MODEL reads a compact, rendering-free projection
17
+ * ({@link semanticsForModel}): the data (`series`/`facts`/`edges`), the
18
+ * caveats that must travel with it (`grain`, `provenance`), the composed
19
+ * `not_covered` prose, a non-null `clarify`, and the static note. Dropped
20
+ * from the model's view: the `af_semantics` marker (machine-only), `render`
21
+ * (a UI hint — the tool never renders, and a model parroting rendering
22
+ * directives is noise), the three-list `coverage` detail (it rides the
23
+ * coverage channel and the record; the model reads the composed
24
+ * `not_covered` lines instead), and a `clarify: null` (a stated non-question
25
+ * is a fact for the record, not something the model acts on).
26
+ *
27
+ * The RECORD gets everything: the full envelope — render, coverage,
28
+ * marker and all — lands on the `tools.semantics_declared` event BEFORE the
29
+ * result ceiling is measured, so grain and provenance survive to recordings
30
+ * and UIs even when the content itself is refused as oversized. The
31
+ * `coverage` field is additionally declared through the SAME channel the
32
+ * `coverage()` primitive uses (`tools.coverage_declared`, tracked state, the
33
+ * final-answer limits block) — absorbed, never duplicated.
34
+ *
35
+ * ## One rule set, two doors
36
+ *
37
+ * `semantic()` refuses a declaration this vocabulary cannot honor at the
38
+ * CALL SITE (the `absent()` law) — so a minted envelope is honest by
39
+ * construction: series carry their grain, data carries its provenance,
40
+ * counter-looking aggregations state `is_counter`. `semanticIssues()` judges
41
+ * the RENDERED shape — the same rules over a value somebody may have built
42
+ * by hand — and is what recognition and the `check:semantics` gate both
43
+ * stand on. Recognition is STRICT (the zero-cost guarantee): a marker-
44
+ * bearing value with any issue is NOT recognized — it keeps its bytes on
45
+ * the data path (dev-warned, and named field-by-field by the gate), because
46
+ * this library does not half-apply a shape it cannot fully honor.
47
+ */
48
+ import { normalizeCoverageList } from '../../core/agent/coverage/items.js';
49
+ import { COUNTER_AGGREGATION_WORDS, SEMANTICS_MARKER, SEMANTICS_NOTE, } from './types.js';
50
+ const isNonEmptyString = (v) => typeof v === 'string' && v.trim().length > 0;
51
+ const isPlainObject = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
52
+ /** Whole-token match against {@link COUNTER_AGGREGATION_WORDS}, singular or
53
+ * plural, case-insensitive — 'sum' and 'Counts' look like counters,
54
+ * 'summary' does not. */
55
+ export function isCounterLookingAggregation(aggregation) {
56
+ const tokens = aggregation.toLowerCase().split(/[^a-z]+/);
57
+ return tokens.some((t) => COUNTER_AGGREGATION_WORDS.includes(t) ||
58
+ (t.endsWith('s') && COUNTER_AGGREGATION_WORDS.includes(t.slice(0, -1))));
59
+ }
60
+ const ENVELOPE_KEYS = new Set([
61
+ SEMANTICS_MARKER,
62
+ 'series',
63
+ 'facts',
64
+ 'edges',
65
+ 'grain',
66
+ 'provenance',
67
+ 'coverage',
68
+ 'not_covered',
69
+ 'clarify',
70
+ 'render',
71
+ 'note',
72
+ ]);
73
+ const GRAIN_KEYS = new Set(['interval', 'aggregation', 'is_counter', 'collapsed']);
74
+ const PROVENANCE_KEYS = new Set(['measured_at', 'age_seconds', 'source', 'source_export_date']);
75
+ const COVERAGE_KEYS = new Set(['checked', 'not_checked', 'cannot_cover']);
76
+ const CLARIFY_KEYS = new Set(['question', 'candidates']);
77
+ const RENDER_KEYS = new Set(['default', 'columns', 'sort', 'filter_note', 'chart_hint']);
78
+ /** Compose the `not_covered` prose lines FROM coverage — the one derivation,
79
+ * used by the mint and by the drift check, so the two can never disagree. */
80
+ export function composeNotCovered(coverage) {
81
+ const items = [...(coverage.not_checked ?? []), ...(coverage.cannot_cover ?? [])];
82
+ return items.map((i) => (i.why !== undefined ? `${i.what} — ${i.why}` : i.what));
83
+ }
84
+ function malformed(field, message) {
85
+ return { code: 'malformed-semantics', field, message };
86
+ }
87
+ /** Detach one clarify declaration for the candidate envelope. A non-object
88
+ * passes through untouched so the validator can name it. */
89
+ function copyClarify(clarify) {
90
+ if (!isPlainObject(clarify))
91
+ return clarify;
92
+ return {
93
+ question: clarify.question,
94
+ candidates: Array.isArray(clarify.candidates)
95
+ ? [...clarify.candidates]
96
+ : clarify.candidates ?? [],
97
+ };
98
+ }
99
+ function checkItemList(issues, field, list, requireWhy) {
100
+ if (list === undefined)
101
+ return [];
102
+ if (!Array.isArray(list)) {
103
+ issues.push(malformed(field, `\`${field}\` must be an array of { what, why? } items.`));
104
+ return [];
105
+ }
106
+ const items = [];
107
+ list.forEach((raw, i) => {
108
+ if (!isPlainObject(raw) || !isNonEmptyString(raw.what)) {
109
+ issues.push(malformed(`${field}[${i}]`, `\`${field}[${i}]\` names no ground — each item is { what, why? }.`));
110
+ return;
111
+ }
112
+ if (raw.why !== undefined && !isNonEmptyString(raw.why)) {
113
+ issues.push(malformed(`${field}[${i}].why`, `\`${field}[${i}]\` has a \`why\` that says nothing.`));
114
+ return;
115
+ }
116
+ if (requireWhy && raw.why === undefined) {
117
+ issues.push(malformed(`${field}[${i}].why`, `\`${field}[${i}]\` ('${raw.what.trim()}') has no \`why\` — a permanent blind spot is a ` +
118
+ `claim about capability, and a claim with no reason cannot be acted on or disproved.`));
119
+ return;
120
+ }
121
+ items.push({
122
+ what: raw.what,
123
+ ...(raw.why !== undefined && { why: raw.why }),
124
+ });
125
+ });
126
+ return items;
127
+ }
128
+ /**
129
+ * Judge one RENDERED envelope shape against the whole rule set. Empty = a
130
+ * well-formed envelope this library can honor. Non-empty = the faults, each
131
+ * naming its field.
132
+ *
133
+ * Called with values that carry the marker; on anything else it reports the
134
+ * missing marker rather than guessing.
135
+ */
136
+ export function semanticIssues(value) {
137
+ if (!isPlainObject(value)) {
138
+ return [malformed(SEMANTICS_MARKER, 'a semantic envelope is a plain object.')];
139
+ }
140
+ if (value[SEMANTICS_MARKER] !== true) {
141
+ return [
142
+ malformed(SEMANTICS_MARKER, `\`${SEMANTICS_MARKER}\` must be exactly \`true\` — the marker is the vocabulary.`),
143
+ ];
144
+ }
145
+ const issues = [];
146
+ for (const key of Object.keys(value)) {
147
+ if (!ENVELOPE_KEYS.has(key)) {
148
+ issues.push(malformed(key, `carries '${key}', which is not a field this vocabulary has. The fields are: series, ` +
149
+ `facts, edges, grain, provenance, coverage, clarify, render (not_covered and note ` +
150
+ `are derived).`));
151
+ }
152
+ }
153
+ // ── series ──
154
+ const series = value.series;
155
+ if (series !== undefined) {
156
+ if (!Array.isArray(series) || series.length === 0) {
157
+ issues.push(malformed('series', '`series` must be a non-empty array of { t, entity, metric, value } points — omit the field to say nothing.'));
158
+ }
159
+ else {
160
+ series.forEach((p, i) => {
161
+ if (!isPlainObject(p)) {
162
+ issues.push(malformed(`series[${i}]`, `\`series[${i}]\` is not a point object.`));
163
+ return;
164
+ }
165
+ if (typeof p.t !== 'string' && typeof p.t !== 'number') {
166
+ issues.push(malformed(`series[${i}].t`, `\`series[${i}].t\` must be the measurement time (an ISO string or an epoch number).`));
167
+ }
168
+ if (!isNonEmptyString(p.entity)) {
169
+ issues.push(malformed(`series[${i}].entity`, `\`series[${i}].entity\` must name what was measured.`));
170
+ }
171
+ if (!isNonEmptyString(p.metric)) {
172
+ issues.push(malformed(`series[${i}].metric`, `\`series[${i}].metric\` must name the measurement.`));
173
+ }
174
+ if (!('value' in p)) {
175
+ issues.push(malformed(`series[${i}].value`, `\`series[${i}]\` has no \`value\` — a point with no reading is not a point.`));
176
+ }
177
+ });
178
+ }
179
+ }
180
+ // ── facts ──
181
+ const facts = value.facts;
182
+ if (facts !== undefined) {
183
+ if (!Array.isArray(facts) || facts.length === 0) {
184
+ issues.push(malformed('facts', '`facts` must be a non-empty array of rows — omit the field to say nothing.'));
185
+ }
186
+ else {
187
+ facts.forEach((f, i) => {
188
+ if (!isPlainObject(f) || !isNonEmptyString(f.entity)) {
189
+ issues.push(malformed(`facts[${i}].entity`, `\`facts[${i}]\` must say WHAT it is about — every row needs a non-empty \`entity\`.`));
190
+ }
191
+ });
192
+ }
193
+ }
194
+ // ── edges ──
195
+ const edges = value.edges;
196
+ if (edges !== undefined) {
197
+ if (!Array.isArray(edges) || edges.length === 0) {
198
+ issues.push(malformed('edges', '`edges` must be a non-empty array of { from, to, kind } — omit the field to say nothing.'));
199
+ }
200
+ else {
201
+ edges.forEach((e, i) => {
202
+ if (!isPlainObject(e) ||
203
+ !isNonEmptyString(e.from) ||
204
+ !isNonEmptyString(e.to) ||
205
+ !isNonEmptyString(e.kind)) {
206
+ issues.push(malformed(`edges[${i}]`, `\`edges[${i}]\` must carry non-empty \`from\`, \`to\` and \`kind\`.`));
207
+ }
208
+ });
209
+ }
210
+ }
211
+ // ── grain ──
212
+ const grain = value.grain;
213
+ if (grain !== undefined) {
214
+ if (!isPlainObject(grain)) {
215
+ issues.push(malformed('grain', '`grain` must be an object ({ interval?, aggregation?, is_counter?, collapsed? }).'));
216
+ }
217
+ else {
218
+ for (const key of Object.keys(grain)) {
219
+ if (!GRAIN_KEYS.has(key))
220
+ issues.push(malformed(`grain.${key}`, `\`grain.${key}\` is not a grain field.`));
221
+ }
222
+ let says = false;
223
+ for (const key of ['interval', 'aggregation', 'collapsed']) {
224
+ if (grain[key] !== undefined) {
225
+ if (!isNonEmptyString(grain[key])) {
226
+ issues.push(malformed(`grain.${key}`, `\`grain.${key}\` must be a non-empty string or omitted.`));
227
+ }
228
+ else
229
+ says = true;
230
+ }
231
+ }
232
+ if (grain.is_counter !== undefined) {
233
+ if (typeof grain.is_counter !== 'boolean') {
234
+ issues.push(malformed('grain.is_counter', '`grain.is_counter` must be a boolean — "stated" means true or false, never prose.'));
235
+ }
236
+ else
237
+ says = true;
238
+ }
239
+ if (!says && issues.every((i) => !i.field.startsWith('grain'))) {
240
+ issues.push(malformed('grain', '`grain` says nothing — state at least one of interval, aggregation, is_counter, collapsed, or omit the field.'));
241
+ }
242
+ if (isNonEmptyString(grain.aggregation) &&
243
+ isCounterLookingAggregation(grain.aggregation) &&
244
+ typeof grain.is_counter !== 'boolean') {
245
+ issues.push({
246
+ code: 'counter-aggregation-unstated',
247
+ field: 'grain.is_counter',
248
+ message: `grain.aggregation is '${grain.aggregation.trim()}', which is counter-looking, and ` +
249
+ `\`is_counter\` is not stated. Summing counters double-counts, and a reader cannot ` +
250
+ `tell a counter from a gauge by looking at a number — state \`is_counter: true\` or ` +
251
+ `\`is_counter: false\`.`,
252
+ });
253
+ }
254
+ }
255
+ }
256
+ // ── provenance ──
257
+ const provenance = value.provenance;
258
+ const hasData = series !== undefined || facts !== undefined;
259
+ if (provenance !== undefined) {
260
+ if (!isPlainObject(provenance)) {
261
+ issues.push(malformed('provenance', '`provenance` must be an object ({ measured_at, source, age_seconds?, source_export_date? }).'));
262
+ }
263
+ else {
264
+ for (const key of Object.keys(provenance)) {
265
+ if (!PROVENANCE_KEYS.has(key))
266
+ issues.push(malformed(`provenance.${key}`, `\`provenance.${key}\` is not a provenance field.`));
267
+ }
268
+ if (!isNonEmptyString(provenance.measured_at)) {
269
+ issues.push({
270
+ code: 'data-without-provenance',
271
+ field: 'provenance.measured_at',
272
+ message: '`provenance.measured_at` must say when the WORLD was measured — a tool reading a ' +
273
+ 'nightly export and answering in 4ms is serving yesterday, and only this field says so.',
274
+ });
275
+ }
276
+ if (!isNonEmptyString(provenance.source)) {
277
+ issues.push({
278
+ code: 'data-without-provenance',
279
+ field: 'provenance.source',
280
+ message: '`provenance.source` must name the system of record the values were read from.',
281
+ });
282
+ }
283
+ if (provenance.age_seconds !== undefined &&
284
+ (typeof provenance.age_seconds !== 'number' ||
285
+ !Number.isFinite(provenance.age_seconds) ||
286
+ provenance.age_seconds < 0)) {
287
+ issues.push(malformed('provenance.age_seconds', '`provenance.age_seconds` must be a finite number ≥ 0 or omitted.'));
288
+ }
289
+ if (provenance.source_export_date !== undefined &&
290
+ !isNonEmptyString(provenance.source_export_date)) {
291
+ issues.push(malformed('provenance.source_export_date', '`provenance.source_export_date` must be a non-empty string or omitted.'));
292
+ }
293
+ }
294
+ }
295
+ else if (hasData) {
296
+ issues.push({
297
+ code: 'data-without-provenance',
298
+ field: 'provenance',
299
+ message: 'carries series/facts with no `provenance` — `provenance.measured_at` and ' +
300
+ '`provenance.source` are required whenever the envelope carries data: a number with ' +
301
+ 'no age and no source cannot be trusted or audited.',
302
+ });
303
+ }
304
+ // ── series ⇒ grain ──
305
+ if (series !== undefined && grain === undefined) {
306
+ issues.push({
307
+ code: 'series-without-grain',
308
+ field: 'grain',
309
+ message: 'carries `series` with no `grain` — a time-series with no stated interval/aggregation ' +
310
+ 'reads as whatever the reader assumes, which is how counters get summed and windows get ' +
311
+ 'compared across different intervals.',
312
+ });
313
+ }
314
+ // ── coverage (rendered) + not_covered derivation ──
315
+ const coverage = value.coverage;
316
+ let renderedCoverage;
317
+ if (coverage !== undefined) {
318
+ if (!isPlainObject(coverage)) {
319
+ issues.push(malformed('coverage', '`coverage` must be an object of { checked?, not_checked?, cannot_cover? } item lists.'));
320
+ }
321
+ else {
322
+ for (const key of Object.keys(coverage)) {
323
+ if (!COVERAGE_KEYS.has(key)) {
324
+ issues.push(malformed(`coverage.${key}`, `\`coverage.${key}\` is not a coverage list — the three are checked, not_checked, cannot_cover.`));
325
+ }
326
+ }
327
+ const checked = checkItemList(issues, 'coverage.checked', coverage.checked, false);
328
+ const notChecked = checkItemList(issues, 'coverage.not_checked', coverage.not_checked, false);
329
+ const cannotCover = checkItemList(issues, 'coverage.cannot_cover', coverage.cannot_cover, true);
330
+ if (checked.length + notChecked.length + cannotCover.length === 0) {
331
+ issues.push(malformed('coverage', '`coverage` names no ground at all — declare at least one item, or omit the field.'));
332
+ }
333
+ else {
334
+ renderedCoverage = {
335
+ ...(checked.length > 0 && { checked }),
336
+ ...(notChecked.length > 0 && { not_checked: notChecked }),
337
+ ...(cannotCover.length > 0 && { cannot_cover: cannotCover }),
338
+ };
339
+ }
340
+ }
341
+ }
342
+ const notCovered = value.not_covered;
343
+ if (notCovered !== undefined) {
344
+ if (coverage === undefined) {
345
+ issues.push(malformed('not_covered', '`not_covered` is DERIVED from `coverage` (not checked + cannot cover) — declare `coverage` instead of writing the prose by hand, so the two cannot disagree.'));
346
+ }
347
+ else if (!Array.isArray(notCovered) || !notCovered.every(isNonEmptyString)) {
348
+ issues.push(malformed('not_covered', '`not_covered` must be an array of non-empty strings.'));
349
+ }
350
+ else if (renderedCoverage !== undefined) {
351
+ const derived = composeNotCovered(renderedCoverage);
352
+ const same = derived.length === notCovered.length && derived.every((l, i) => l === notCovered[i]);
353
+ if (!same) {
354
+ issues.push(malformed('not_covered', '`not_covered` disagrees with what `coverage` derives — it is a derived field; drop it (the mint composes it) or fix the coverage lists.'));
355
+ }
356
+ }
357
+ }
358
+ // ── clarify ──
359
+ const clarify = value.clarify;
360
+ if (clarify !== undefined && clarify !== null) {
361
+ if (!isPlainObject(clarify)) {
362
+ issues.push(malformed('clarify', '`clarify` must be { question, candidates } or null (null states "ambiguity was considered; there is none").'));
363
+ }
364
+ else {
365
+ for (const key of Object.keys(clarify)) {
366
+ if (!CLARIFY_KEYS.has(key))
367
+ issues.push(malformed(`clarify.${key}`, `\`clarify.${key}\` is not a clarify field.`));
368
+ }
369
+ if (!isNonEmptyString(clarify.question)) {
370
+ issues.push(malformed('clarify.question', '`clarify.question` must ask something.'));
371
+ }
372
+ if (!Array.isArray(clarify.candidates)) {
373
+ issues.push(malformed('clarify.candidates', '`clarify.candidates` must be an array (empty is fine — an open question is still a question).'));
374
+ }
375
+ }
376
+ }
377
+ // ── render ──
378
+ const render = value.render;
379
+ if (render !== undefined) {
380
+ if (!isPlainObject(render)) {
381
+ issues.push(malformed('render', '`render` must be an object ({ default, columns?, sort?, filter_note?, chart_hint? }).'));
382
+ }
383
+ else {
384
+ for (const key of Object.keys(render)) {
385
+ if (!RENDER_KEYS.has(key))
386
+ issues.push(malformed(`render.${key}`, `\`render.${key}\` is not a render hint.`));
387
+ }
388
+ if (!isNonEmptyString(render.default)) {
389
+ issues.push(malformed('render.default', "`render.default` must name the default presentation ('table', 'chart', 'prose', …)."));
390
+ }
391
+ if (render.columns !== undefined &&
392
+ (!Array.isArray(render.columns) ||
393
+ render.columns.length === 0 ||
394
+ !render.columns.every(isNonEmptyString))) {
395
+ issues.push(malformed('render.columns', '`render.columns` must be a non-empty array of column names or omitted.'));
396
+ }
397
+ for (const key of ['sort', 'filter_note', 'chart_hint']) {
398
+ if (render[key] !== undefined && !isNonEmptyString(render[key])) {
399
+ issues.push(malformed(`render.${key}`, `\`render.${key}\` must be a non-empty string or omitted.`));
400
+ }
401
+ }
402
+ }
403
+ }
404
+ // ── note ──
405
+ if (value.note !== undefined && typeof value.note !== 'string') {
406
+ issues.push(malformed('note', "`note` is the library's static sentence — a string, or omitted."));
407
+ }
408
+ // ── the envelope must declare SOMETHING ──
409
+ if (series === undefined &&
410
+ facts === undefined &&
411
+ edges === undefined &&
412
+ (clarify === undefined || clarify === null)) {
413
+ issues.push(malformed(SEMANTICS_MARKER, 'declares nothing — an envelope needs data (series, facts or edges) or a question ' +
414
+ '(clarify). Caveats with nothing to caveat are not a result.'));
415
+ }
416
+ return issues;
417
+ }
418
+ /**
419
+ * Say "here is typed data, with the caveats that make it honest" in a shape
420
+ * the framework recognizes, the record keeps whole, and a build gate can
421
+ * refuse.
422
+ *
423
+ * Returns the value a tool's `execute` should return. The framework
424
+ * recognizes it at the dispatch boundary: the MODEL reads the compact
425
+ * projection ({@link semanticsForModel}), the FULL envelope rides the typed
426
+ * `agentfootprint.tools.semantics_declared` event, and a declared `coverage`
427
+ * flows through the same channel `coverage()` uses.
428
+ *
429
+ * Refuses (throws, at the call site — the `absent()` law) any declaration
430
+ * this vocabulary cannot honor: series without grain, data without
431
+ * provenance, a counter-looking aggregation with `is_counter` unstated, and
432
+ * every malformed shape — each refusal names the field and the fix.
433
+ *
434
+ * @example a per-port IOPS tool
435
+ * return semantic({
436
+ * series: rows.map((r) => ({ t: r.time, entity: r.port, metric: 'avg_iops', value: r.iops })),
437
+ * grain: { interval: '30m', aggregation: 'avg', is_counter: false },
438
+ * provenance: { measured_at: latestSampleTime, source: 'InfluxDB SwitchPortStats' },
439
+ * coverage: {
440
+ * checked: ['shq-fab-a: all 48 FC ports'],
441
+ * notChecked: [{ what: 'the peer fabric', why: 'this collector is scoped to one fabric' }],
442
+ * },
443
+ * render: { default: 'table', columns: ['entity', 'value'], sort: 'value desc' },
444
+ * });
445
+ */
446
+ export function semantic(decl) {
447
+ const fn = 'semantic';
448
+ // Deliberately not the isPlainObject guard: its predicate would REPLACE
449
+ // the declared field types with an index signature for the rest of the
450
+ // function (SemanticDeclaration is all-optional, hence assignable).
451
+ if (typeof decl !== 'object' || decl === null || Array.isArray(decl)) {
452
+ throw new Error(`${fn}: takes a declaration — { series?, facts?, edges?, grain?, provenance?, coverage?, ` +
453
+ `clarify?, render? } with at least one of series/facts/edges/clarify.`);
454
+ }
455
+ const DECL_KEYS = new Set([
456
+ 'series',
457
+ 'facts',
458
+ 'edges',
459
+ 'grain',
460
+ 'provenance',
461
+ 'coverage',
462
+ 'clarify',
463
+ 'render',
464
+ ]);
465
+ for (const key of Object.keys(decl)) {
466
+ if (DECL_KEYS.has(key))
467
+ continue;
468
+ if (key === 'not_covered') {
469
+ throw new Error(`${fn}: \`not_covered\` is derived, never declared — declare \`coverage\` ` +
470
+ `({ notChecked, cannotCover }) and the prose list is composed from it, so the two ` +
471
+ `can never disagree.`);
472
+ }
473
+ throw new Error(`${fn}: '${key}' is not a field this vocabulary has. The fields are: series, facts, ` +
474
+ `edges, grain, provenance, coverage, clarify, render.`);
475
+ }
476
+ // Coverage first — the coverage() vocabulary, normalized by the SAME
477
+ // validator the coverage()/absent() primitives use (one validator, three
478
+ // doors), then respelled snake_case for the rendered envelope.
479
+ let coverage;
480
+ if (decl.coverage !== undefined) {
481
+ if (!isPlainObject(decl.coverage)) {
482
+ throw new Error(`${fn}: \`coverage\` must be a { checked?, notChecked?, cannotCover? } declaration.`);
483
+ }
484
+ const cov = decl.coverage;
485
+ const checked = normalizeCoverageList(fn, 'checked', cov.checked, false);
486
+ const notChecked = normalizeCoverageList(fn, 'notChecked', cov.notChecked, false);
487
+ const cannotCover = normalizeCoverageList(fn, 'cannotCover', cov.cannotCover, true);
488
+ if (checked.length + notChecked.length + cannotCover.length === 0) {
489
+ throw new Error(`${fn}: \`coverage\` names no ground at all — declare at least one item across ` +
490
+ `checked/notChecked/cannotCover, or omit the field (absent means "not declared", ` +
491
+ `never "nothing there").`);
492
+ }
493
+ coverage = {
494
+ ...(checked.length > 0 && { checked }),
495
+ ...(notChecked.length > 0 && { not_checked: notChecked }),
496
+ ...(cannotCover.length > 0 && { cannot_cover: cannotCover }),
497
+ };
498
+ }
499
+ const notCovered = coverage !== undefined ? composeNotCovered(coverage) : [];
500
+ const candidate = {
501
+ [SEMANTICS_MARKER]: true,
502
+ ...(decl.series !== undefined && { series: [...decl.series] }),
503
+ ...(decl.facts !== undefined && { facts: [...decl.facts] }),
504
+ ...(decl.edges !== undefined && { edges: [...decl.edges] }),
505
+ ...(decl.grain !== undefined && { grain: { ...decl.grain } }),
506
+ ...(decl.provenance !== undefined && { provenance: { ...decl.provenance } }),
507
+ ...(coverage !== undefined && { coverage }),
508
+ ...(notCovered.length > 0 && { not_covered: notCovered }),
509
+ ...('clarify' in decl &&
510
+ decl.clarify !== undefined && {
511
+ clarify: decl.clarify === null ? null : copyClarify(decl.clarify),
512
+ }),
513
+ ...(decl.render !== undefined && { render: { ...decl.render } }),
514
+ note: SEMANTICS_NOTE,
515
+ };
516
+ // One rule set, one implementation: the mint judges its own candidate with
517
+ // the exact validator recognition and the gate use, and refuses the first
518
+ // fault at the call site.
519
+ const issues = semanticIssues(candidate);
520
+ if (issues.length > 0) {
521
+ const first = issues[0];
522
+ throw new Error(`${fn}: ${first.message} (field: ${first.field})`);
523
+ }
524
+ return candidate;
525
+ }
526
+ /**
527
+ * Recognize (or decline to recognize) a value as a semantic envelope —
528
+ * STRICT, and the strictness is the zero-cost guarantee. Only a plain object
529
+ * whose `af_semantics` is exactly `true` AND that passes the whole rule set
530
+ * qualifies; every other value any tool has ever returned takes the path it
531
+ * always took, byte for byte.
532
+ *
533
+ * `undefined` means "not an envelope this library can honor" — a marker-
534
+ * bearing value with faults stays DATA (never half-applied); the dispatch
535
+ * loop dev-warns it and `check:semantics` names every fault.
536
+ */
537
+ export function readSemantics(value) {
538
+ if (!isPlainObject(value) || value[SEMANTICS_MARKER] !== true)
539
+ return undefined;
540
+ if (semanticIssues(value).length > 0)
541
+ return undefined;
542
+ return value;
543
+ }
544
+ /**
545
+ * Name what is wrong with a value that CARRIES the marker but was not
546
+ * recognized. `undefined` for values without the marker (they are data, not
547
+ * near-misses) and for well-formed envelopes. Diagnosis only — never changes
548
+ * what any value does.
549
+ */
550
+ export function explainSemantics(value) {
551
+ if (!isPlainObject(value) || value[SEMANTICS_MARKER] !== true)
552
+ return undefined;
553
+ const issues = semanticIssues(value);
554
+ return issues.length > 0 ? issues : undefined;
555
+ }
556
+ /**
557
+ * The MODEL's view of one recognized envelope — compact and rendering-free.
558
+ *
559
+ * Keeps: the data (`series`/`facts`/`edges`), the caveats that must travel
560
+ * with it (`grain`, `provenance`), the composed `not_covered` prose, a
561
+ * non-null `clarify`, and the static note. Drops: the marker, `render`
562
+ * (UI hint), the three-list `coverage` detail (rides the coverage channel
563
+ * and the record), and a `clarify: null`. Shallow-copied so the history
564
+ * entry is not the object the tool still holds.
565
+ */
566
+ export function semanticsForModel(sem) {
567
+ return {
568
+ ...(sem.series !== undefined && { series: sem.series.map((p) => ({ ...p })) }),
569
+ ...(sem.facts !== undefined && { facts: sem.facts.map((f) => ({ ...f })) }),
570
+ ...(sem.edges !== undefined && { edges: sem.edges.map((e) => ({ ...e })) }),
571
+ ...(sem.grain !== undefined && { grain: { ...sem.grain } }),
572
+ ...(sem.provenance !== undefined && { provenance: { ...sem.provenance } }),
573
+ ...(sem.not_covered !== undefined &&
574
+ sem.not_covered.length > 0 && { not_covered: [...sem.not_covered] }),
575
+ ...(sem.clarify !== undefined &&
576
+ sem.clarify !== null && {
577
+ clarify: { question: sem.clarify.question, candidates: [...sem.clarify.candidates] },
578
+ }),
579
+ note: typeof sem.note === 'string' ? sem.note : SEMANTICS_NOTE,
580
+ };
581
+ }
582
+ /** The envelope's coverage in the normalized three-list shape the coverage
583
+ * machinery reads — how `readCoverageResult` absorbs a semantic envelope's
584
+ * boundary into the one coverage channel. */
585
+ export function coverageOfSemantics(sem) {
586
+ return {
587
+ checked: sem.coverage?.checked ?? [],
588
+ notChecked: sem.coverage?.not_checked ?? [],
589
+ cannotCover: sem.coverage?.cannot_cover ?? [],
590
+ };
591
+ }
592
+ //# sourceMappingURL=envelope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envelope.js","sourceRoot":"","sources":["../../../../src/lib/semantics/envelope.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * semantics/format — rendering one {@link SemanticsReport} for a terminal.
3
+ *
4
+ * Pattern: the tool-lint `format.ts` sibling — pure string building, no IO.
5
+ * Role: lib/ layer, pure.
6
+ * Emits: N/A.
7
+ */
8
+ import type { SemanticsReport } from './check.js';
9
+ /** Render the report. Every finding names its tool and its field — the two
10
+ * facts a build log must carry for the fix to be a one-line edit. */
11
+ export declare function formatSemanticsReport(report: SemanticsReport): string;