agentfootprint 6.16.0 → 6.18.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 (31) hide show
  1. package/dist/adapters/observability/audit.js +559 -0
  2. package/dist/adapters/observability/audit.js.map +1 -0
  3. package/dist/adapters/observability/otel.js +545 -56
  4. package/dist/adapters/observability/otel.js.map +1 -1
  5. package/dist/adapters/observability/xray.js +97 -13
  6. package/dist/adapters/observability/xray.js.map +1 -1
  7. package/dist/esm/adapters/observability/audit.js +554 -0
  8. package/dist/esm/adapters/observability/audit.js.map +1 -0
  9. package/dist/esm/adapters/observability/otel.js +545 -56
  10. package/dist/esm/adapters/observability/otel.js.map +1 -1
  11. package/dist/esm/adapters/observability/xray.js +97 -13
  12. package/dist/esm/adapters/observability/xray.js.map +1 -1
  13. package/dist/esm/lib/canonicalJson.js +125 -0
  14. package/dist/esm/lib/canonicalJson.js.map +1 -0
  15. package/dist/esm/observability-providers.js +5 -0
  16. package/dist/esm/observability-providers.js.map +1 -1
  17. package/dist/lib/canonicalJson.js +129 -0
  18. package/dist/lib/canonicalJson.js.map +1 -0
  19. package/dist/observability-providers.js +13 -1
  20. package/dist/observability-providers.js.map +1 -1
  21. package/dist/types/adapters/observability/audit.d.ts +255 -0
  22. package/dist/types/adapters/observability/audit.d.ts.map +1 -0
  23. package/dist/types/adapters/observability/otel.d.ts +143 -20
  24. package/dist/types/adapters/observability/otel.d.ts.map +1 -1
  25. package/dist/types/adapters/observability/xray.d.ts +7 -1
  26. package/dist/types/adapters/observability/xray.d.ts.map +1 -1
  27. package/dist/types/lib/canonicalJson.d.ts +57 -0
  28. package/dist/types/lib/canonicalJson.d.ts.map +1 -0
  29. package/dist/types/observability-providers.d.ts +3 -1
  30. package/dist/types/observability-providers.d.ts.map +1 -1
  31. package/package.json +3 -2
@@ -0,0 +1,255 @@
1
+ /**
2
+ * auditExport — tamper-evident audit bundle (backlog #20, compliance
3
+ * wedge item 2; pairs with #19's `otelObservability` GenAI spans).
4
+ *
5
+ * Consumes the typed `agentfootprint.*` event stream and accumulates an
6
+ * append-only, HASH-CHAINED record log: every record carries the SHA-256
7
+ * of its own canonical serialization plus the hash of the previous
8
+ * record. Flipping a single byte anywhere in an exported bundle makes
9
+ * `verifyAuditBundle` name the exact record that broke — the
10
+ * record-keeping shape EU AI Act Art. 12 asks for (events the system
11
+ * logged, in order, demonstrably unmodified since capture).
12
+ *
13
+ * Pattern: Observability strategy (one purpose — chain accumulation)
14
+ * + pure offline verifier.
15
+ * Role: Outer ring (Hexagonal). Attach via
16
+ * `agent.enable.observability({ strategy: auditExport() })`.
17
+ * Emits: nothing — terminal sink.
18
+ *
19
+ * ## What lands in the chain
20
+ *
21
+ * One record per typed event, in dispatch order: decisions
22
+ * (`agent.route_decided`, `composition.route_decided` incl. decide()
23
+ * evidence), tool calls (`stream.tool_start/_end`), validation
24
+ * rejections (#9), permission verdicts and halts, credential lifecycle,
25
+ * costs, errors, skill/memory/context activity. Each new `meta.runId`
26
+ * is anchored by a GENESIS record (`audit.genesis`) carrying the runId,
27
+ * the agent identity, and library versions — runs chain back-to-back in
28
+ * one log, so silently DROPPING a whole run breaks the chain too.
29
+ *
30
+ * High-volume content deltas (`stream.token`, `stream.thinking_delta`)
31
+ * are excluded by default (`includeTokenEvents: true` to include).
32
+ *
33
+ * ## Record / bundle schema
34
+ *
35
+ * ```
36
+ * AuditRecord = { seq, timestamp, eventType, payload, meta, prevHash, hash }
37
+ * hash = SHA-256 hex over canonicalJson(record minus `hash`)
38
+ * prevHash = previous record's `hash` (ZERO_HASH at chain start)
39
+ * AuditBundle = { header, records, finalHash }
40
+ * header = { format, hashAlgorithm, canonicalization, chainHead,
41
+ * firstSeq, recordCount, exportedAt, library }
42
+ * ```
43
+ *
44
+ * Canonicalization is `afp-cjson/1` (see `lib/canonicalJson.ts` — those
45
+ * rules ARE the contract; the header names them so independent
46
+ * verifiers can re-implement byte-exactly).
47
+ *
48
+ * ## Persistence + long runs
49
+ *
50
+ * Persistence is the CONSUMER's job — the bundle is plain JSON
51
+ * (`JSON.stringify(strategy.bundle())`, store anywhere). For long runs,
52
+ * `drain()` returns the records accumulated since the last drain while
53
+ * keeping the chain intact ACROSS drains: each segment's
54
+ * `header.chainHead` equals the previous segment's `finalHash`, so
55
+ * `verifyAuditBundle([seg1, seg2, ...])` re-verifies the concatenation
56
+ * end-to-end.
57
+ *
58
+ * ## PII discipline (mirrors #19's otelObservability)
59
+ *
60
+ * Payloads enter records through a bounding layer — by default
61
+ * (`payloadMode: 'bounded'`) record payloads NEVER carry raw runtime
62
+ * values that can echo PII:
63
+ *
64
+ * - tool args → `'[keys: …]'` (top-level key NAMES only)
65
+ * - tool results → `'[type: …]'` (typeof only)
66
+ * - userPrompt / LLM content / thinking blocks / history
67
+ * → `'[N chars]'` / `'[N messages]'` markers
68
+ * - content PREVIEWS (`contentSummary` on context/memory events,
69
+ * `rawContent`, `resultSummary`, `droppedSummaries`) → markers
70
+ * (for short content a preview IS the content; `contentHash`
71
+ * stays — it links identical content without echoing it)
72
+ * - error MESSAGE strings (`error`, `errorMessage`, `lastError`,
73
+ * `rawOutput`) → `'[N chars]'` (messages can echo values)
74
+ * - free-form Records (`questionPayload`, `resumeInput`, risk/eval
75
+ * `evidence`, memory `scoreEvidence`) → `'[keys: …]'`
76
+ *
77
+ * Everything else is embedded as the registry payload (sanitized:
78
+ * strings capped at 256 chars, lists at 32 items, cycles broken) —
79
+ * those payloads are bounded by construction: identifiers, counts,
80
+ * enums, decide() evidence (engine-bounded + redaction-aware),
81
+ * validation issues (paths/TYPES per #9), credential events (no
82
+ * secrets by contract).
83
+ *
84
+ * `payloadMode: 'verbatim'` embeds full payloads (still
85
+ * JSON-sanitized). For Art. 12 completeness on an access-controlled
86
+ * store that is often the point — but the bundle then carries prompts,
87
+ * tool args/results and model output. Treat it as PII-bearing, and
88
+ * remember the Agent sets NO footprintjs RedactionPolicy by default
89
+ * (policies you do set redact the emit channel UPSTREAM of this
90
+ * strategy, so redacted events arrive here already redacted).
91
+ *
92
+ * ## Tamper-EVIDENT, not tamper-PROOF (honest threat model)
93
+ *
94
+ * The chain proves INTERNAL consistency: any partial modification —
95
+ * edit, insert, delete, reorder, drop-a-run — is detected and named.
96
+ * It does NOT prove provenance: an adversary holding the only copy can
97
+ * recompute every hash from the mutation onward and present a
98
+ * self-consistent forgery. For non-repudiation, anchor `finalHash`
99
+ * externally as part of your retention process (write-once/WORM store,
100
+ * signed log, RFC 3161 timestamping, or simply a second party) — then
101
+ * a whole-suffix recomputation no longer matches the anchor.
102
+ *
103
+ * ## Runtime requirements
104
+ *
105
+ * Hashing uses `node:crypto` (`createHash('sha256')`) — zero new
106
+ * dependencies, imported lazily at first use (same gating as the
107
+ * optional vendor SDKs in this folder, so merely importing this module
108
+ * stays browser-safe). `auditExport` and `verifyAuditBundle` therefore
109
+ * run anywhere `node:crypto` exists: Node ≥ 20, Bun, Deno,
110
+ * edge runtimes with Node compat (e.g. Cloudflare `nodejs_compat`).
111
+ * In a browser there is no SYNC SHA-256 (WebCrypto is async-only), so
112
+ * both throw a descriptive error — verify server-side, or re-implement
113
+ * verification from the documented contract (it is pure: recompute
114
+ * SHA-256 over `afp-cjson/1` canonicalization and walk the chain).
115
+ *
116
+ * @example Capture → export → verify
117
+ * ```ts
118
+ * import { auditExport, verifyAuditBundle } from 'agentfootprint/observability-providers';
119
+ *
120
+ * const audit = auditExport({ agent: 'loan-officer' });
121
+ * const stop = agent.enable.observability({ strategy: audit });
122
+ * await agent.run({ message: 'assess application A-17' });
123
+ * stop();
124
+ *
125
+ * const bundle = audit.bundle(); // JSON-serializable
126
+ * await fs.writeFile('run.audit.json', JSON.stringify(bundle));
127
+ *
128
+ * const check = verifyAuditBundle(bundle); // offline — no agent needed
129
+ * // check.valid === true; tamper with one byte → { valid: false, brokenAt: <seq> }
130
+ * ```
131
+ */
132
+ import { CANONICAL_JSON_VERSION } from '../../lib/canonicalJson.js';
133
+ import type { ObservabilityStrategy } from '../../strategies/types.js';
134
+ /** SHA-256 of "nothing" — the `prevHash` of the first record in a
135
+ * chain and the `chainHead` of a chain's first segment. */
136
+ export declare const AUDIT_ZERO_HASH: string;
137
+ /** `eventType` of the per-run genesis record. Deliberately OUTSIDE the
138
+ * `agentfootprint.*` registry namespace — it is a chain-level record,
139
+ * not a dispatched event (#20 ships zero new typed events). */
140
+ export declare const AUDIT_GENESIS_EVENT_TYPE = "audit.genesis";
141
+ /** Format identifier carried on every bundle header. */
142
+ export declare const AUDIT_BUNDLE_FORMAT = "agentfootprint.audit/1";
143
+ /**
144
+ * One link of the hash chain.
145
+ *
146
+ * `hash` = SHA-256 hex over `canonicalJson` of the record WITHOUT the
147
+ * `hash` field (i.e. `{ seq, timestamp, eventType, payload, meta,
148
+ * prevHash }` — canonical key order makes field order irrelevant).
149
+ * Because the preimage is "everything but `hash`", ADDING a field to a
150
+ * record is detected exactly like mutating one.
151
+ */
152
+ export interface AuditRecord {
153
+ /** 0-based position in the chain (monotonic across drains). */
154
+ readonly seq: number;
155
+ /** Wall-clock ms of the source event (`meta.wallClockMs`). */
156
+ readonly timestamp: number;
157
+ /** Registry event name verbatim, or {@link AUDIT_GENESIS_EVENT_TYPE}. */
158
+ readonly eventType: string;
159
+ /** Bounded / sanitized event payload (see module PII docs). */
160
+ readonly payload: unknown;
161
+ /** Sanitized event meta (runId, runtimeStageId, paths, indices). */
162
+ readonly meta: {
163
+ readonly runId: string;
164
+ } & Readonly<Record<string, unknown>>;
165
+ /** `hash` of the previous record ({@link AUDIT_ZERO_HASH} at chain start). */
166
+ readonly prevHash: string;
167
+ /** SHA-256 hex of this record's canonical preimage. */
168
+ readonly hash: string;
169
+ }
170
+ export interface AuditBundleHeader {
171
+ readonly format: typeof AUDIT_BUNDLE_FORMAT;
172
+ readonly hashAlgorithm: 'sha-256';
173
+ readonly canonicalization: typeof CANONICAL_JSON_VERSION;
174
+ /** `prevHash` of `records[0]` — {@link AUDIT_ZERO_HASH} for the first
175
+ * segment, the previous segment's `finalHash` after a `drain()`. */
176
+ readonly chainHead: string;
177
+ /** `seq` of `records[0]` (continues across drains). */
178
+ readonly firstSeq: number;
179
+ readonly recordCount: number;
180
+ /** Wall-clock ms when `bundle()` / `drain()` produced this export. */
181
+ readonly exportedAt: number;
182
+ readonly library: {
183
+ readonly name: 'agentfootprint';
184
+ readonly version: string;
185
+ };
186
+ }
187
+ /** JSON-serializable export of the chain (or one drained segment). */
188
+ export interface AuditBundle {
189
+ readonly header: AuditBundleHeader;
190
+ readonly records: readonly AuditRecord[];
191
+ /** `hash` of the last record (= `chainHead` when `records` is empty).
192
+ * The next drained segment's `chainHead` equals this value. */
193
+ readonly finalHash: string;
194
+ }
195
+ export interface AuditVerifyResult {
196
+ readonly valid: boolean;
197
+ /** Records whose hashes were recomputed and matched. */
198
+ readonly recordsChecked: number;
199
+ /** `seq` of the first record that fails (or the expected seq at the
200
+ * failure point, when the stored seq itself was tampered). */
201
+ readonly brokenAt?: number;
202
+ /** Human-readable cause — names the failed check. */
203
+ readonly reason?: string;
204
+ }
205
+ export interface AuditExportOptions {
206
+ /** Agent identity recorded in every run's genesis record (service /
207
+ * agent name as your compliance review knows it). */
208
+ readonly agent?: string;
209
+ /**
210
+ * `'bounded'` (default) — payloads pass the PII bounding layer (see
211
+ * module docs). `'verbatim'` — full payloads, JSON-sanitized only.
212
+ *
213
+ * @remarks Verbatim bundles carry prompts, tool args/results and
214
+ * model output. Treat the store as PII-bearing; the Agent applies NO
215
+ * RedactionPolicy by default.
216
+ */
217
+ readonly payloadMode?: 'bounded' | 'verbatim';
218
+ /** Include `stream.token` / `stream.thinking_delta` events (high
219
+ * volume; content still bounded under `payloadMode: 'bounded'`).
220
+ * Default `false`. */
221
+ readonly includeTokenEvents?: boolean;
222
+ /** Extra version pins for the genesis record (your app, model
223
+ * config revision, policy bundle hash, …). */
224
+ readonly versions?: Readonly<Record<string, string>>;
225
+ }
226
+ /** The strategy returned by {@link auditExport}. */
227
+ export interface AuditExportStrategy extends ObservabilityStrategy {
228
+ /** Snapshot the retained records WITHOUT draining. Safe mid-run. */
229
+ bundle(): AuditBundle;
230
+ /** Return the records accumulated since the last drain and clear
231
+ * them from memory. Chain state persists — consecutive drained
232
+ * segments re-verify end-to-end via `verifyAuditBundle([...])`. */
233
+ drain(): AuditBundle;
234
+ /** Records currently retained (since last drain). */
235
+ recordCount(): number;
236
+ }
237
+ export declare function auditExport(opts?: AuditExportOptions): AuditExportStrategy;
238
+ /**
239
+ * Recompute the hash chain of a bundle (or of consecutive drained
240
+ * segments, in order) and report the exact record where integrity
241
+ * breaks. Pure function over JSON data — runs offline, long after the
242
+ * run, with no agent and no strategy instance.
243
+ *
244
+ * Checks, in order, per segment:
245
+ * 1. header format / algorithm / canonicalization are supported
246
+ * 2. `recordCount` matches `records.length`
247
+ * 3. segment continuity (`chainHead`/`firstSeq` extend the previous
248
+ * segment's `finalHash`/seq range)
249
+ * 4. per record: `seq` is contiguous, `prevHash` links the previous
250
+ * record, and SHA-256 over the canonical preimage (the record
251
+ * minus `hash` — so ADDED fields are caught too) matches `hash`
252
+ * 5. `finalHash` equals the last record's hash
253
+ */
254
+ export declare function verifyAuditBundle(input: AuditBundle | readonly AuditBundle[]): AuditVerifyResult;
255
+ //# sourceMappingURL=audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../../../src/adapters/observability/audit.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,12 @@
1
1
  /**
2
2
  * otelObservability — OpenTelemetry distributed-tracing adapter.
3
3
  *
4
- * Ships every agentfootprint event as OpenTelemetry spans + log
5
- * records via a consumer-supplied OTel API. Same hierarchical
6
- * mapping as the X-Ray adapter, but the destination is whichever
7
- * OTel-compat backend the consumer's SDK exports to:
4
+ * Ships every agentfootprint event as OpenTelemetry spans + span events
5
+ * via a consumer-supplied OTel API, following the OpenTelemetry **GenAI
6
+ * semantic conventions** (`gen_ai.*` attribute namespace) plus
7
+ * agentfootprint-specific explainability attributes (`agentfootprint.*`).
8
+ * Same hierarchical mapping as the X-Ray adapter, but the destination is
9
+ * whichever OTel-compat backend the consumer's SDK exports to:
8
10
  *
9
11
  * - **Honeycomb** (OTLP/HTTP)
10
12
  * - **Grafana Cloud / Tempo / Mimir** (OTLP)
@@ -27,24 +29,67 @@
27
29
  * configure the SDK + exporter once at app startup; we just speak
28
30
  * the typed OTel API.
29
31
  *
30
- * Mapping:
32
+ * ## Event → span/attribute mapping
31
33
  *
32
- * agent.turn_start ↦ start root span (one trace per turn)
33
- * agent.turn_end ↦ end root span
34
+ * agent.turn_start ↦ start root span (one trace per turn)
35
+ * `gen_ai.operation.name: 'invoke_agent'`
36
+ * agent.turn_end ↦ end root span (+ turn-total `gen_ai.usage.*`)
34
37
  * agent.iteration_start ↦ start child span under root
35
38
  * agent.iteration_end ↦ end iteration span
36
- * stream.llm_start ↦ start child span (model call)
37
- * stream.llm_end ↦ end llm span
38
- * stream.tool_start start child span (tool call)
39
- * stream.tool_end ↦ end tool span (with `error: true` if errored)
39
+ * stream.llm_start ↦ start child span (inference) — `gen_ai.*`
40
+ * request attrs (`chat` operation)
41
+ * stream.llm_end end llm span (+ `gen_ai.usage.*`,
42
+ * `gen_ai.response.*`)
43
+ * stream.tool_start ↦ start child span — `execute_tool` operation,
44
+ * `gen_ai.tool.name` / `gen_ai.tool.call.id`
45
+ * stream.tool_end ↦ end tool span (ERROR status + `error.type`
46
+ * if errored). Correlated by toolCallId so
47
+ * PARALLEL tool calls close the right span.
40
48
  * cost.tick ↦ setAttribute on topmost active span
49
+ * error.fatal ↦ ERROR status on root + defensive unwind
50
+ * context.evaluated ↦ N span events `agentfootprint.skill.routing`
51
+ * — SYNTHESIZED name (one per routing entry),
52
+ * not a registry-verbatim forward; all other
53
+ * span events use the registry name verbatim
54
+ *
55
+ * ## Decisions = SPAN EVENTS, not attributes (design decision)
56
+ *
57
+ * Explainability signals (route decisions, skill routing, validation
58
+ * rejections, permission checks, credential lifecycle) are emitted as
59
+ * **span events** on the currently-active span rather than attributes:
60
+ *
61
+ * 1. MULTIPLICITY — an iteration span can carry several decisions
62
+ * (route + N skill routings + M permission checks). Attributes are
63
+ * last-write-wins and would clobber; span events accumulate.
64
+ * 2. ORDERING — span events carry their own timestamps, preserving the
65
+ * decision sequence inside one span. Compliance review (EU AI Act
66
+ * Art. 12 record-keeping) needs the order decisions were made.
67
+ * 3. ROUND-TRIP — OTLP backends (and agentThinkingUI's `fromOTLP`
68
+ * ingestion) surface span events as first-class timeline entries.
69
+ *
70
+ * When the consumer-injected tracer's spans don't implement `addEvent`
71
+ * (minimal test doubles), the adapter falls back to flattened
72
+ * `${eventName}.${key}` attributes — degraded (last-write-wins) but
73
+ * never silently dropped.
74
+ *
75
+ * ## PII discipline
76
+ *
77
+ * Mirrors the #9 validation contract: attribute values NEVER echo
78
+ * runtime VALUES that can carry PII —
79
+ * - tool args → top-level key NAMES only (`agentfootprint.tool.args.keys`)
80
+ * - tool results → `typeof` only (`agentfootprint.tool.result.type`)
81
+ * - validation issues → path / expected / got TYPES (bounded upstream)
82
+ * - decide() evidence → rule labels, operators, thresholds (developer
83
+ * constants) and the engine's redaction-aware value SUMMARIES
84
+ * - userPrompt / llm content / thinking → never emitted
85
+ * - error.fatal → stage + scope only (error MESSAGES can echo values)
86
+ * - credential events carry no secrets by construction (registry contract)
41
87
  *
42
88
  * @example Basic — Honeycomb via OTLP
43
89
  * ```ts
44
90
  * import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
45
91
  * import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
46
92
  * import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
47
- * import { trace } from '@opentelemetry/api';
48
93
  * import { otelObservability } from 'agentfootprint/observability-providers';
49
94
  *
50
95
  * // Set up OTel ONCE at app startup.
@@ -55,12 +100,13 @@
55
100
  * })));
56
101
  * provider.register();
57
102
  *
58
- * agent.enable.observability({
59
- * strategy: otelObservability({
60
- * serviceName: 'my-agent',
61
- * // tracer optional — defaults to trace.getTracer('agentfootprint').
62
- * }),
103
+ * const otel = otelObservability({
104
+ * serviceName: 'my-agent',
105
+ * // genAiSpanNames: true, // opt-in spec span names ('chat gpt-4', …)
63
106
  * });
107
+ * agent.enable.observability({ strategy: otel });
108
+ * // Optional — operator-level decide()/select() evidence as span events:
109
+ * // Agent.create({...}).recorder(otel.decisionEvidenceRecorder())
64
110
  * ```
65
111
  *
66
112
  * @example Test injection
@@ -71,6 +117,7 @@
71
117
  * });
72
118
  * ```
73
119
  */
120
+ import type { FlowDecisionEvent, FlowSelectedEvent } from 'footprintjs';
74
121
  import type { ObservabilityStrategy } from '../../strategies/types.js';
75
122
  export interface OtelObservabilityOptions {
76
123
  /** Service name on every emitted span. Surfaces in your OTel
@@ -86,20 +133,45 @@ export interface OtelObservabilityOptions {
86
133
  * where the consumer wants agentfootprint to drop spans BEFORE
87
134
  * they reach the SDK (e.g., aggressive cost control). */
88
135
  readonly sampleRate?: number;
136
+ /**
137
+ * Opt-in OTel GenAI semconv SPAN NAMES (default `false`):
138
+ *
139
+ * root → `invoke_agent {serviceName}` (was `{serviceName}`)
140
+ * llm → `chat {model}` (was `llm`)
141
+ * tool → `execute_tool {toolName}` (was `tool:{toolName}`)
142
+ *
143
+ * Off by default because existing consumers' dashboards / alerts key
144
+ * on the legacy span names — renames would break them. All `gen_ai.*`
145
+ * ATTRIBUTES are emitted regardless of this flag (purely additive),
146
+ * so semconv-aware backends can already group by
147
+ * `gen_ai.operation.name` with the flag off.
148
+ */
149
+ readonly genAiSpanNames?: boolean;
150
+ /**
151
+ * Explainability span events (default `true`): route decisions, skill
152
+ * routing provenance, validation rejections, permission decisions,
153
+ * credential lifecycle. Set `false` to emit only the span tree +
154
+ * `gen_ai.*` attributes (e.g., aggressive per-byte vendor billing).
155
+ */
156
+ readonly explainability?: boolean;
89
157
  }
158
+ /** Attribute value union we emit. Matches OTel's `AttributeValue`
159
+ * subset: primitives + homogeneous string arrays
160
+ * (`gen_ai.response.finish_reasons`, issue lists, …). */
161
+ export type OtelAttributeValue = string | number | boolean | readonly string[];
90
162
  /** Subset of `@opentelemetry/api`'s `Tracer` we depend on. */
91
163
  export interface OtelTracerLike {
92
164
  startSpan(name: string, options?: OtelSpanOptions, context?: unknown): OtelSpanLike;
93
165
  }
94
166
  /** Subset of `@opentelemetry/api`'s `SpanOptions`. */
95
167
  export interface OtelSpanOptions {
96
- attributes?: Record<string, string | number | boolean>;
168
+ attributes?: Record<string, OtelAttributeValue>;
97
169
  startTime?: number;
98
170
  kind?: number;
99
171
  }
100
172
  /** Subset of `@opentelemetry/api`'s `Span` we depend on. */
101
173
  export interface OtelSpanLike {
102
- setAttribute(key: string, value: string | number | boolean): unknown;
174
+ setAttribute(key: string, value: OtelAttributeValue): unknown;
103
175
  setStatus(status: {
104
176
  code: number;
105
177
  message?: string;
@@ -110,6 +182,57 @@ export interface OtelSpanLike {
110
182
  spanId: string;
111
183
  traceFlags: number;
112
184
  };
185
+ /** OTel `Span.addEvent` — optional in the duck-typed surface so
186
+ * minimal test doubles still satisfy the interface. Explainability
187
+ * signals degrade to flattened attributes when absent. */
188
+ addEvent?(name: string, attributes?: Record<string, OtelAttributeValue>): unknown;
189
+ }
190
+ /**
191
+ * footprintjs CombinedRecorder (FlowRecorder channel) that forwards
192
+ * decide()/select() operator-level evidence into the paired
193
+ * otelObservability strategy as span events. Attach via
194
+ * `Agent.create({...}).recorder(...)` or
195
+ * `executor.attachCombinedRecorder(...)`.
196
+ */
197
+ export interface OtelDecisionEvidenceRecorder {
198
+ readonly id: string;
199
+ onDecision(event: FlowDecisionEvent): void;
200
+ onSelected(event: FlowSelectedEvent): void;
201
+ }
202
+ /** Return type of {@link otelObservability} — the base
203
+ * ObservabilityStrategy plus the decide()/select() evidence bridge. */
204
+ export interface OtelObservabilityStrategy extends ObservabilityStrategy {
205
+ /**
206
+ * Build the decide()/select() evidence bridge for this strategy.
207
+ *
208
+ * Operator-level decision evidence (which rule fired, the
209
+ * `key op threshold → actual` conditions) travels on footprintjs's
210
+ * FlowRecorder channel (`onDecision` / `onSelected`) — it never
211
+ * reaches the typed event dispatcher, so the strategy alone can't
212
+ * see it. This recorder is the bridge (same pattern as the #5
213
+ * causal-evidence bridge in `memory/causal/evidenceRecorder.ts`).
214
+ *
215
+ * Decisions WITHOUT structured evidence are skipped — they already
216
+ * arrive via the `agent.route_decided` / `composition.route_decided`
217
+ * typed events, so forwarding them here would double-report.
218
+ *
219
+ * @remarks PII: attaching this recorder EXPORTS bounded actual scope
220
+ * values to your OTel collector — each condition renders as
221
+ * `key op threshold → actualSummary (bool)`, where `actualSummary` is
222
+ * the engine's redaction-aware ≤80-char value summary (e.g.
223
+ * `creditScore gt 700 → 750 (true)`). Keys covered by a footprintjs
224
+ * `RedactionPolicy` render `[REDACTED]`; everything else leaves the
225
+ * process. For compliance record-keeping that disclosure is usually
226
+ * the point — but treat the collector as PII-bearing, or redact the
227
+ * relevant keys upstream, before attaching.
228
+ *
229
+ * @remarks Attach ONCE per executor. Every instance carries the
230
+ * well-known id `'otel-decision-evidence'`, so re-attaching is
231
+ * idempotent-by-ID (the replacement prevents double-reported span
232
+ * events); instances from the same strategy share its turn state by
233
+ * design.
234
+ */
235
+ decisionEvidenceRecorder(): OtelDecisionEvidenceRecorder;
113
236
  }
114
- export declare function otelObservability(opts: OtelObservabilityOptions): ObservabilityStrategy;
237
+ export declare function otelObservability(opts: OtelObservabilityOptions): OtelObservabilityStrategy;
115
238
  //# sourceMappingURL=otel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"otel.d.ts","sourceRoot":"","sources":["../../../../src/adapters/observability/otel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwEG;AAIH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAIvE,MAAM,WAAW,wBAAwB;IACvC;2CACuC;IACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;qEAEiE;IACjE,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,CAAC;IACjC;;;;8DAI0D;IAC1D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAID,8DAA8D;AAC9D,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,YAAY,CAAC;CACrF;AAED,sDAAsD;AACtD,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,4DAA4D;AAC5D,MAAM,WAAW,YAAY;IAC3B,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;IACrE,SAAS,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;IAC/D,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;CACxE;AAgBD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,wBAAwB,GAAG,qBAAqB,CA8OvF"}
1
+ {"version":3,"file":"otel.d.ts","sourceRoot":"","sources":["../../../../src/adapters/observability/otel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsHG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGxE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAIvE,MAAM,WAAW,wBAAwB;IACvC;2CACuC;IACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;qEAEiE;IACjE,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,CAAC;IACjC;;;;8DAI0D;IAC1D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;CACnC;AAID;;0DAE0D;AAC1D,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,MAAM,EAAE,CAAC;AAE/E,8DAA8D;AAC9D,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,YAAY,CAAC;CACrF;AAED,sDAAsD;AACtD,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,4DAA4D;AAC5D,MAAM,WAAW,YAAY;IAC3B,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC;IAC9D,SAAS,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;IAC/D,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IACvE;;+DAE2D;IAC3D,QAAQ,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,GAAG,OAAO,CAAC;CACnF;AAgBD;;;;;;GAMG;AACH,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC3C,UAAU,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAAC;CAC5C;AAED;wEACwE;AACxE,MAAM,WAAW,yBAA0B,SAAQ,qBAAqB;IACtE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,wBAAwB,IAAI,4BAA4B,CAAC;CAC1D;AA2GD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,wBAAwB,GAAG,yBAAyB,CA8rB3F"}
@@ -10,7 +10,13 @@
10
10
  * stream.llm_start ↦ push leaf subsegment (model call)
11
11
  * stream.llm_end ↦ close llm subsegment
12
12
  * stream.tool_start ↦ push leaf subsegment (tool call)
13
- * stream.tool_end ↦ close tool subsegment
13
+ * stream.tool_end ↦ close tool subsegment (correlated
14
+ * by toolCallId — parallel-safe)
15
+ * error.fatal ↦ fault on root + close the whole
16
+ * tree (turn_end never arrives)
17
+ *
18
+ * Events are anchored on `meta.runId` (the dispatcher envelope),
19
+ * with a `payload.runId` fallback for hand-built events.
14
20
  *
15
21
  * The result in the X-Ray Trace Map: a hierarchical timeline of every
16
22
  * agent run — turn → iteration → llm-call/tool-call — queryable in
@@ -1 +1 @@
1
- {"version":3,"file":"xray.d.ts","sourceRoot":"","sources":["../../../../src/adapters/observability/xray.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAIH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAIvE,MAAM,WAAW,wBAAwB;IACvC,qEAAqE;IACrE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;iCAC6B;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;oDAEgD;IAChD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;0CAEsC;IACtC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC;yCACqC;IACrC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,2DAA2D;IAC3D,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC;CACnC;AAID,MAAM,WAAW,cAAc;IAC7B,gBAAgB,CAAC,KAAK,EAAE;QAAE,qBAAqB,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC7F;AA6BD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,wBAAwB,GAAG,qBAAqB,CA2QvF"}
1
+ {"version":3,"file":"xray.d.ts","sourceRoot":"","sources":["../../../../src/adapters/observability/xray.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AAIH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAIvE,MAAM,WAAW,wBAAwB;IACvC,qEAAqE;IACrE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;iCAC6B;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;oDAEgD;IAChD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;0CAEsC;IACtC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC;yCACqC;IACrC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,2DAA2D;IAC3D,QAAQ,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC;CACnC;AAID,MAAM,WAAW,cAAc;IAC7B,gBAAgB,CAAC,KAAK,EAAE;QAAE,qBAAqB,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC7F;AA6BD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,wBAAwB,GAAG,qBAAqB,CA4WvF"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * canonicalJson — deterministic JSON serialization (`afp-cjson/1`).
3
+ *
4
+ * Pattern: Canonicalization function (RFC 8785 JCS-inspired, JS-native).
5
+ * Role: The byte contract under the tamper-evident audit chain
6
+ * (backlog #20). `AuditRecord.hash` = SHA-256 over the
7
+ * canonical serialization of the record — two parties that
8
+ * serialize the same VALUE must produce the same BYTES, or
9
+ * verification breaks. These rules ARE the contract; bump the
10
+ * identifier (`afp-cjson/2`) for ANY behavioral change.
11
+ *
12
+ * ## Canonicalization rules (`afp-cjson/1`)
13
+ *
14
+ * 1. **Objects** — own enumerable string-keyed properties only, keys
15
+ * sorted lexicographically by UTF-16 code unit (JavaScript's
16
+ * default `Array.prototype.sort()` comparison), serialized
17
+ * `{"k":v,...}` with no whitespace. Symbol keys are ignored.
18
+ * 2. **Arrays** — element order preserved, `[v,...]` no whitespace.
19
+ * 3. **Strings** — `JSON.stringify` escaping (deterministic per the
20
+ * ECMAScript spec: minimal escapes, lowercase `\uXXXX` hex).
21
+ * 4. **Numbers** — finite numbers via `JSON.stringify` (ECMAScript
22
+ * shortest round-trip formatting). `NaN` / `±Infinity` → `null`
23
+ * (JSON.stringify parity). `-0` serializes as `0`.
24
+ * 5. **`null`** → `null`. **`undefined`** — omitted as an object
25
+ * property, `null` as an array element or top-level value
26
+ * (JSON.stringify parity).
27
+ * 6. **Functions / symbols** — omitted as object properties, `null`
28
+ * in arrays (JSON.stringify parity).
29
+ * 7. **`toJSON`** — honored before serialization (so `Date` →
30
+ * ISO-8601 string, exactly like `JSON.stringify`).
31
+ * 8. **`bigint`** → `TypeError` (JSON.stringify parity). Sanitize
32
+ * upstream (the audit bounding layer converts bigint to string).
33
+ * 9. **Cycles** → `TypeError`. Canonicalization is defined over
34
+ * JSON-safe trees; the audit bounding layer breaks cycles first.
35
+ *
36
+ * The domain is "anything `JSON.parse` can produce" (the audit bundle
37
+ * is JSON); for other inputs the behavior mirrors `JSON.stringify`
38
+ * except that object keys are SORTED. Verification re-canonicalizes
39
+ * records that came through `JSON.parse(JSON.stringify(bundle))`, so
40
+ * round-tripping a bundle never changes its hashes.
41
+ *
42
+ * Browser-safe: no Node imports — pure computation.
43
+ */
44
+ /** Identifier of the canonicalization rules implemented by
45
+ * {@link canonicalJson}. Carried on `AuditBundleHeader.canonicalization`
46
+ * so offline verifiers can reject bundles produced under different
47
+ * rules instead of mis-verifying them. */
48
+ export declare const CANONICAL_JSON_VERSION = "afp-cjson/1";
49
+ /**
50
+ * Serialize `value` to canonical JSON (see module docs for the exact
51
+ * `afp-cjson/1` rules). Deterministic: equal values (after key
52
+ * reordering) always produce identical strings.
53
+ *
54
+ * @throws TypeError on circular references or bigint values.
55
+ */
56
+ export declare function canonicalJson(value: unknown): string;
57
+ //# sourceMappingURL=canonicalJson.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonicalJson.d.ts","sourceRoot":"","sources":["../../../src/lib/canonicalJson.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH;;;2CAG2C;AAC3C,eAAO,MAAM,sBAAsB,gBAAgB,CAAC;AAEpD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAMpD"}
@@ -41,5 +41,7 @@
41
41
  export { agentcoreObservability, type AgentcoreObservabilityOptions, } from './adapters/observability/agentcore.js';
42
42
  export { cloudwatchObservability, type CloudwatchObservabilityOptions, } from './adapters/observability/cloudwatch.js';
43
43
  export { xrayObservability, type XrayObservabilityOptions, type XRayLikeClient, } from './adapters/observability/xray.js';
44
- export { otelObservability, type OtelObservabilityOptions, type OtelTracerLike, type OtelSpanLike, type OtelSpanOptions, } from './adapters/observability/otel.js';
44
+ export { otelObservability, type OtelObservabilityOptions, type OtelObservabilityStrategy, type OtelDecisionEvidenceRecorder, type OtelTracerLike, type OtelSpanLike, type OtelSpanOptions, type OtelAttributeValue, } from './adapters/observability/otel.js';
45
+ export { auditExport, verifyAuditBundle, AUDIT_BUNDLE_FORMAT, AUDIT_GENESIS_EVENT_TYPE, AUDIT_ZERO_HASH, type AuditBundle, type AuditBundleHeader, type AuditExportOptions, type AuditExportStrategy, type AuditRecord, type AuditVerifyResult, } from './adapters/observability/audit.js';
46
+ export { canonicalJson, CANONICAL_JSON_VERSION } from './lib/canonicalJson.js';
45
47
  //# sourceMappingURL=observability-providers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"observability-providers.d.ts","sourceRoot":"","sources":["../../src/observability-providers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,EACL,sBAAsB,EACtB,KAAK,6BAA6B,GACnC,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,uBAAuB,EACvB,KAAK,8BAA8B,GACpC,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,KAAK,cAAc,GACpB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,eAAe,GACrB,MAAM,kCAAkC,CAAC"}
1
+ {"version":3,"file":"observability-providers.d.ts","sourceRoot":"","sources":["../../src/observability-providers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,EACL,sBAAsB,EACtB,KAAK,6BAA6B,GACnC,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,uBAAuB,EACvB,KAAK,8BAA8B,GACpC,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,KAAK,cAAc,GACpB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,4BAA4B,EACjC,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,kBAAkB,GACxB,MAAM,kCAAkC,CAAC;AAI1C,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,wBAAwB,EACxB,eAAe,EACf,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,WAAW,EAChB,KAAK,iBAAiB,GACvB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentfootprint",
3
- "version": "6.16.0",
3
+ "version": "6.18.0",
4
4
  "description": "The explainable agent framework — build AI agents you can explain, audit, and trust. Built on footprintjs.",
5
5
  "license": "MIT",
6
6
  "author": "Sanjay Krishna Anbalagan",
@@ -169,7 +169,8 @@
169
169
  "types": "./dist/types/status.d.ts",
170
170
  "import": "./dist/esm/status.js",
171
171
  "require": "./dist/status.js"
172
- }
172
+ },
173
+ "./package.json": "./package.json"
173
174
  },
174
175
  "sideEffects": [
175
176
  "**/cache/strategies/*.js",