/** * ChassisEnvelope — the shared envelope chassis for all Class A tools. * * WHY THIS EXISTS * * There are two tool classes: * * Class A (older, chaotic): * top_patterns, pattern_examples, pattern_mitigate, cost_options, * estimate_savings, preview_filter, pattern_detail, pattern_trend * — inconsistent arg names, no threshold disclosure, no source * disclosure, empty actions[], human_summary missing or tautological. * * Class B (newer, cross-pillar): * metrics_that_moved, investigate, rank_by_shape_similarity, * metric_overlay * — threshold_basis explicit, threshold_audit nested, candidates * split usable/evaluated/failed, human_summary honest with * next-step, investigation_id for traceability. * * The catalog has ~30 tools. Every Class A tool that adopts this chassis * gets Class B consistency without a per-tool refactor of the logic: * the builder enforces the shape at construction time, and the Zod * schema rejects drift at the boundary. * * RELATIONSHIP TO EXISTING ENVELOPE * * ChassisEnvelope does NOT replace StructuredOutput from output-types.ts. * The outer transport envelope (schema_version / schema_epoch / tool / * generated_at / view / summary / data / actions / render_hint / * truncated / next_cursor / warnings / images) stays unchanged. * * What changes is what goes INSIDE `data`. Class A tools historically * put an ad-hoc object there; a chassis tool puts a ChassisData object. * `buildChassisEnvelope()` produces a complete StructuredOutput where * `data` is a validated ChassisData. * * BACK-COMPAT * * Old call sites that read flat fields from `data` (status, query_count, * total_latency_ms, human_summary) still work because ChassisData puts * them at the top of its flat surface via `toLegacyDataShape()`. Tools * can migrate incrementally: pass `legacyCompat: true` and * `legacyExtraFields: { ...existingDataFields }` to add those fields * alongside the structured chassis fields during the transition. * * USAGE * * import { buildChassisEnvelope, newChasisTelemetry } from '../lib/chassis-envelope.js'; * * const telemetry = newChassisTelemetry(); * // ... do work, call telemetry.recordQuery() after each backend call ... * * return buildChassisEnvelope({ * tool: 'log10x_top_patterns', * view: 'summary', * headline: '12 patterns above floor, top 3 are auth-service ERROR.', * status: 'success', * decisions: { * threshold_used: floorBytesPerSec, * threshold_basis: 'default', * }, * source_disclosure: { * bytes_source: 'tsdb', * rate_source: rateSourceFromEnv, * pattern_count_source: { * kind: 'top_n_above_threshold', * count: shownPatterns.length, * denominator_meaning: 'Top N patterns above the 1 KB/s floor in window', * }, * }, * scope: { window: timeRange, window_basis: 'explicit' }, * payload: { patterns: shownPatterns, totals, incidents }, * human_summary: '...', * actions: [...], * telemetry, * }); */ import { z } from 'zod'; import { type StructuredOutput, type View, type Action, type RenderHint, type InlineImage } from './output-types.js'; import type { Mode } from './mode-detect.js'; /** * Chassis schema version. Bumped when the ChassisData shape changes * in a way that is NOT back-compatible with older readers. Distinct * from SCHEMA_VERSION (the outer transport envelope version). */ export declare const CHASSIS_VERSION: "1.0"; /** * Top-level call status. Every tool must set this so agents can branch * on it before reading anything else. * * - success — results are available and usable; read payload. * - no_signal — search ran, nothing crossed the threshold; stop, * do not auto-retry with the same params. * - partial — some sub-queries failed; results are available * but partial. Read scope.candidates_failed[] for * what was skipped. May be worth a narrower retry. * - insufficient_data — anchor resolved but window / backend coverage * too thin to produce a usable result. Widen or * re-anchor. * - error — structural failure; read data.error. * - demo_read_only — the MCP is running in the hosted demo playground * with LOG10X_MCP_READ_ONLY=true; the writer tool * refused to execute. data.error carries the * `demo_read_only` discriminant and the would_have * side-effect description. */ export declare const ChassisStatusSchema: z.ZodEnum<["success", "no_signal", "partial", "insufficient_data", "error", "demo_read_only"]>; export type ChassisStatus = z.infer; /** * Where the threshold number came from. Agents use this to decide * whether to act on the result: * * customer_supplied — caller passed it explicitly; treat as trusted. * snapshot — read from a stored config/calibration file. * default — a hand-picked spec constant; use with caution. * unvalidated_default — same as default but the tool explicitly flags * that no empirical calibration has been done on * this deployment's data. Agents MUST NOT * auto-mitigate when this is set. */ export declare const ThresholdBasisSchema: z.ZodEnum<["customer_supplied", "snapshot", "default", "unvalidated_default"]>; export type ThresholdBasis = z.infer; /** * Observed distribution summary for the pool of values the threshold * was compared against. The agent compares threshold_used against * this distribution to judge whether the threshold is well above noise, * at the noise floor, or below it (false positives). */ export declare const ThresholdAuditDistributionSchema: z.ZodNullable>; export declare const ThresholdAuditSchema: z.ZodNullable; basis: z.ZodString; observed_distribution: z.ZodOptional>>; /** * Number of candidate slots considered for the observed_distribution. * Populated by find_skew (skew-concentration analysis) to show how * many slots were scanned before the threshold was applied. */ n_candidate_slots: z.ZodOptional; }, "strip", z.ZodTypeAny, { value: number | null; basis: string; observed_distribution?: { min: number; max: number; n: number; p25: number; p50: number; p75: number; } | null | undefined; n_candidate_slots?: number | undefined; }, { value: number | null; basis: string; observed_distribution?: { min: number; max: number; n: number; p25: number; p50: number; p75: number; } | null | undefined; n_candidate_slots?: number | undefined; }>>; export type ThresholdAudit = z.infer; /** * All numeric thresholds the tool applied, plus their provenance. * Mandatory on every tool; if a tool has no threshold semantics, set * threshold_used: null and threshold_basis: 'default'. */ export declare const DecisionsSchema: z.ZodObject<{ threshold_used: z.ZodNullable; threshold_basis: z.ZodEnum<["customer_supplied", "snapshot", "default", "unvalidated_default"]>; /** * Optional richer audit. Populate for tools where showing the * floor vs the observed distribution is meaningful (all the * cross-pillar primitives, estimate_savings, etc.). Tools that * have no numeric distribution to show omit this field. */ threshold_audit: z.ZodOptional; basis: z.ZodString; observed_distribution: z.ZodOptional>>; /** * Number of candidate slots considered for the observed_distribution. * Populated by find_skew (skew-concentration analysis) to show how * many slots were scanned before the threshold was applied. */ n_candidate_slots: z.ZodOptional; }, "strip", z.ZodTypeAny, { value: number | null; basis: string; observed_distribution?: { min: number; max: number; n: number; p25: number; p50: number; p75: number; } | null | undefined; n_candidate_slots?: number | undefined; }, { value: number | null; basis: string; observed_distribution?: { min: number; max: number; n: number; p25: number; p50: number; p75: number; } | null | undefined; n_candidate_slots?: number | undefined; }>>>; }, "strip", z.ZodTypeAny, { threshold_used: number | null; threshold_basis: "default" | "customer_supplied" | "snapshot" | "unvalidated_default"; threshold_audit?: { value: number | null; basis: string; observed_distribution?: { min: number; max: number; n: number; p25: number; p50: number; p75: number; } | null | undefined; n_candidate_slots?: number | undefined; } | null | undefined; }, { threshold_used: number | null; threshold_basis: "default" | "customer_supplied" | "snapshot" | "unvalidated_default"; threshold_audit?: { value: number | null; basis: string; observed_distribution?: { min: number; max: number; n: number; p25: number; p50: number; p75: number; } | null | undefined; n_candidate_slots?: number | undefined; } | null | undefined; }>; export type Decisions = z.infer; /** * Where bytes figures come from. Every tool that surfaces GB/s, bytes, * or cost numbers must label the origin so an agent or human reader * knows what they are comparing. */ export declare const BytesSourceSchema: z.ZodEnum<["tsdb", "customer_supplied_csv", "engine_aggregated_csv", "siem_direct", "estimate"]>; export type BytesSource = z.infer; /** * Where the $/GB rate came from. Absent when the tool surfaces no * dollar values. */ export declare const RateSourceSchema: z.ZodEnum<["customer_supplied", "list_price", "snapshot", "none"]>; export type RateSource = z.infer; /** * Pattern count semantics. Populating this field prevents the most * common Class A ambiguity: "10 patterns" — 10 of how many? Above what? */ export declare const PatternCountSourceSchema: z.ZodObject<{ kind: z.ZodEnum<["top_n_above_threshold", "scoped_total_above_threshold", "env_total", "scoped_total", "above_volume_floor", "raw_label_universe"]>; count: z.ZodNumber; /** * One-line caveat explaining what the denominator is. Examples: * "Top N patterns above the 1 KB/s floor in window" * "All ERROR patterns in payment-service over 24h" */ denominator_meaning: z.ZodString; }, "strip", z.ZodTypeAny, { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; }, { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; }>; export type PatternCountSource = z.infer; /** * Source labels for every number class the tool surfaces. All fields * are optional because not every tool surfaces every number type. When * a tool surfaces a number and omits the source field, the Zod * validator will NOT reject the envelope — but the principle is that * any number that could be ambiguous should carry a label. */ export declare const SourceDisclosureSchema: z.ZodObject<{ bytes_source: z.ZodOptional>; rate_source: z.ZodOptional>; pattern_count_source: z.ZodOptional; count: z.ZodNumber; /** * One-line caveat explaining what the denominator is. Examples: * "Top N patterns above the 1 KB/s floor in window" * "All ERROR patterns in payment-service over 24h" */ denominator_meaning: z.ZodString; }, "strip", z.ZodTypeAny, { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; }, { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; }>>; /** * SIEM vendor in scope. Populated by tools that query or surface * SIEM data so a reader knows the cost model and query dialect. */ siem_vendor: z.ZodOptional; /** * Human-readable label disambiguating WHICH instance of `siem_vendor` * the tool spoke to / surfaced numbers from. The vendor name alone is * ambiguous when a customer has multiple Datadog orgs / multiple * CloudWatch accounts / multiple Splunk indexes; `source_label` carries * the env nickname + region/account/endpoint hints so an agent or * reader can tell "which Datadog" / "which CloudWatch log group" the * envelope is talking about. Built via `buildSourceLabel()` in * lib/source-disclosure.ts to keep the format consistent. */ source_label: z.ZodOptional; /** * How the Retriever URL + bucket was resolved. Populated by tools that * consume the Retriever (retriever_query, retriever_series, backfill_metric, * overflow_contents) so an agent can tell whether the resolution came from * env vars, the discovery snapshot, a live kubectl probe, the resolved * env-config document (K8s ConfigMap / AWS SSM / GCP SM / Azure AC / local * file), or was absent. */ retriever_state_source: z.ZodOptional>; /** * Service count semantics. Mirrors pattern_count_source for tools that * surface a list of services. Without this field "12 services" is * ambiguous — 12 above what floor, from what universe? */ service_count_source: z.ZodOptional; count: z.ZodNumber; /** * One-line caveat explaining what the denominator is. Examples: * "Top N patterns above the 1 KB/s floor in window" * "All ERROR patterns in payment-service over 24h" */ denominator_meaning: z.ZodString; }, "strip", z.ZodTypeAny, { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; }, { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; }>>; /** * Label source — for label-domain tools (discover_labels, discover_join). * Identifies which Prometheus backend the label universe came from. */ label_source: z.ZodOptional>; /** * SIEM lens (what-if pricing). `siem_actual` is the connected pipeline's * destination; `siem_lens` is present ONLY when a caller asked the tool to * price + gate for a different destination (real volumes, lens rate card). * `siem_lens_basis` says how the effective destination was chosen. */ siem_actual: z.ZodOptional; siem_lens: z.ZodOptional; siem_lens_basis: z.ZodOptional>; /** * Volume projection lens (what-if forecast). Emitted by volumeLensDisclosure() * ONLY when a run is lensed (a positive monthly_volume_gb was supplied AND a * real byte basis existed). A scaled magnitude WITHOUT this stamp is a leak; * these keys MUST survive the chassis schema so the receipt is auditable. * `volume_actual_gb` is the env's measured monthly volume, `volume_projected_gb` * the caller's stated scale, `volume_scale_factor` the uniform multiplier. */ volume_actual_gb: z.ZodOptional>; volume_projected_gb: z.ZodOptional>; volume_scale_factor: z.ZodOptional; volume_projection_note: z.ZodOptional>; }, "strip", z.ZodTypeAny, { siem_vendor?: string | undefined; rate_source?: "none" | "list_price" | "customer_supplied" | "snapshot" | undefined; bytes_source?: "tsdb" | "customer_supplied_csv" | "engine_aggregated_csv" | "siem_direct" | "estimate" | undefined; pattern_count_source?: { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; } | undefined; source_label?: string | undefined; retriever_state_source?: "none" | "env_var" | "snapshot" | "helm_release_probe" | "kubectl_probe" | "env_config" | undefined; service_count_source?: { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; } | undefined; label_source?: "log10x_prom" | "customer_prom" | undefined; siem_actual?: string | undefined; siem_lens?: string | undefined; siem_lens_basis?: "none" | "requested" | "detected" | undefined; volume_actual_gb?: number | null | undefined; volume_projected_gb?: number | null | undefined; volume_scale_factor?: number | undefined; volume_projection_note?: string | null | undefined; }, { siem_vendor?: string | undefined; rate_source?: "none" | "list_price" | "customer_supplied" | "snapshot" | undefined; bytes_source?: "tsdb" | "customer_supplied_csv" | "engine_aggregated_csv" | "siem_direct" | "estimate" | undefined; pattern_count_source?: { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; } | undefined; source_label?: string | undefined; retriever_state_source?: "none" | "env_var" | "snapshot" | "helm_release_probe" | "kubectl_probe" | "env_config" | undefined; service_count_source?: { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; } | undefined; label_source?: "log10x_prom" | "customer_prom" | undefined; siem_actual?: string | undefined; siem_lens?: string | undefined; siem_lens_basis?: "none" | "requested" | "detected" | undefined; volume_actual_gb?: number | null | undefined; volume_projected_gb?: number | null | undefined; volume_scale_factor?: number | undefined; volume_projection_note?: string | null | undefined; }>; export type SourceDisclosure = z.infer; /** * What universe the tool queried. Mirrors the Class B n_candidates_* * split to let agents reason about result completeness. */ export declare const ScopeSchema: z.ZodObject<{ window: z.ZodString; window_basis: z.ZodEnum<["explicit", "auto_default"]>; /** * Total candidates considered before filtering. Absent for tools * that don't have a candidate selection step. */ candidates_count: z.ZodOptional; /** * Candidates that had enough data to be evaluated (after filtering * out insufficient-data cases). Subset of candidates_count. */ candidates_usable: z.ZodOptional; /** * Candidates that were actually evaluated. May be less than * candidates_usable when a per-call cap is applied. */ candidates_evaluated: z.ZodOptional; /** * Candidates that failed evaluation (insufficient data, backend * error, or timeout). Carrying these explicitly is what distinguishes * Class B from Class A — the agent can see what was dropped. */ candidates_failed: z.ZodOptional>; }, "strip", z.ZodTypeAny, { window: string; window_basis: "explicit" | "auto_default"; candidates_count?: number | undefined; candidates_usable?: number | undefined; candidates_evaluated?: number | undefined; candidates_failed?: string[] | undefined; }, { window: string; window_basis: "explicit" | "auto_default"; candidates_count?: number | undefined; candidates_usable?: number | undefined; candidates_evaluated?: number | undefined; candidates_failed?: string[] | undefined; }>; export type Scope = z.infer; /** * Structured question the agent MUST surface to the user before * routing to any follow-up tool. This moves compliance directives OUT * of prose markdown (where they are routinely ignored) and into a * typed field agents can read and act on mechanically. */ export declare const MustAskUserSchema: z.ZodOptional; }, "strip", z.ZodTypeAny, { options: string[]; question: string; }, { options: string[]; question: string; }>>; export type MustAskUser = z.infer; /** * Per-call telemetry surfaced on every envelope. Enables agents to * pace themselves and flag slow backends. */ export declare const PerformanceSchema: z.ZodObject<{ query_count: z.ZodNumber; total_latency_ms: z.ZodNumber; backend_pressure_hint: z.ZodNullable>; }, "strip", z.ZodTypeAny, { query_count: number; total_latency_ms: number; backend_pressure_hint: "ok" | "slow" | "throttled" | null; }, { query_count: number; total_latency_ms: number; backend_pressure_hint: "ok" | "slow" | "throttled" | null; }>; export type Performance = z.infer; /** * The full ChassisData shape. Every Class A tool puts one of these * inside the `data` field of its StructuredOutput envelope. * * `payload` is generic — the tool-specific result rows go there. * The chassis validates everything around it. */ export declare const ChassisDataSchema: z.ZodObject<{ status: z.ZodEnum<["success", "no_signal", "partial", "insufficient_data", "error", "demo_read_only"]>; decisions: z.ZodObject<{ threshold_used: z.ZodNullable; threshold_basis: z.ZodEnum<["customer_supplied", "snapshot", "default", "unvalidated_default"]>; /** * Optional richer audit. Populate for tools where showing the * floor vs the observed distribution is meaningful (all the * cross-pillar primitives, estimate_savings, etc.). Tools that * have no numeric distribution to show omit this field. */ threshold_audit: z.ZodOptional; basis: z.ZodString; observed_distribution: z.ZodOptional>>; /** * Number of candidate slots considered for the observed_distribution. * Populated by find_skew (skew-concentration analysis) to show how * many slots were scanned before the threshold was applied. */ n_candidate_slots: z.ZodOptional; }, "strip", z.ZodTypeAny, { value: number | null; basis: string; observed_distribution?: { min: number; max: number; n: number; p25: number; p50: number; p75: number; } | null | undefined; n_candidate_slots?: number | undefined; }, { value: number | null; basis: string; observed_distribution?: { min: number; max: number; n: number; p25: number; p50: number; p75: number; } | null | undefined; n_candidate_slots?: number | undefined; }>>>; }, "strip", z.ZodTypeAny, { threshold_used: number | null; threshold_basis: "default" | "customer_supplied" | "snapshot" | "unvalidated_default"; threshold_audit?: { value: number | null; basis: string; observed_distribution?: { min: number; max: number; n: number; p25: number; p50: number; p75: number; } | null | undefined; n_candidate_slots?: number | undefined; } | null | undefined; }, { threshold_used: number | null; threshold_basis: "default" | "customer_supplied" | "snapshot" | "unvalidated_default"; threshold_audit?: { value: number | null; basis: string; observed_distribution?: { min: number; max: number; n: number; p25: number; p50: number; p75: number; } | null | undefined; n_candidate_slots?: number | undefined; } | null | undefined; }>; source_disclosure: z.ZodObject<{ bytes_source: z.ZodOptional>; rate_source: z.ZodOptional>; pattern_count_source: z.ZodOptional; count: z.ZodNumber; /** * One-line caveat explaining what the denominator is. Examples: * "Top N patterns above the 1 KB/s floor in window" * "All ERROR patterns in payment-service over 24h" */ denominator_meaning: z.ZodString; }, "strip", z.ZodTypeAny, { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; }, { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; }>>; /** * SIEM vendor in scope. Populated by tools that query or surface * SIEM data so a reader knows the cost model and query dialect. */ siem_vendor: z.ZodOptional; /** * Human-readable label disambiguating WHICH instance of `siem_vendor` * the tool spoke to / surfaced numbers from. The vendor name alone is * ambiguous when a customer has multiple Datadog orgs / multiple * CloudWatch accounts / multiple Splunk indexes; `source_label` carries * the env nickname + region/account/endpoint hints so an agent or * reader can tell "which Datadog" / "which CloudWatch log group" the * envelope is talking about. Built via `buildSourceLabel()` in * lib/source-disclosure.ts to keep the format consistent. */ source_label: z.ZodOptional; /** * How the Retriever URL + bucket was resolved. Populated by tools that * consume the Retriever (retriever_query, retriever_series, backfill_metric, * overflow_contents) so an agent can tell whether the resolution came from * env vars, the discovery snapshot, a live kubectl probe, the resolved * env-config document (K8s ConfigMap / AWS SSM / GCP SM / Azure AC / local * file), or was absent. */ retriever_state_source: z.ZodOptional>; /** * Service count semantics. Mirrors pattern_count_source for tools that * surface a list of services. Without this field "12 services" is * ambiguous — 12 above what floor, from what universe? */ service_count_source: z.ZodOptional; count: z.ZodNumber; /** * One-line caveat explaining what the denominator is. Examples: * "Top N patterns above the 1 KB/s floor in window" * "All ERROR patterns in payment-service over 24h" */ denominator_meaning: z.ZodString; }, "strip", z.ZodTypeAny, { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; }, { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; }>>; /** * Label source — for label-domain tools (discover_labels, discover_join). * Identifies which Prometheus backend the label universe came from. */ label_source: z.ZodOptional>; /** * SIEM lens (what-if pricing). `siem_actual` is the connected pipeline's * destination; `siem_lens` is present ONLY when a caller asked the tool to * price + gate for a different destination (real volumes, lens rate card). * `siem_lens_basis` says how the effective destination was chosen. */ siem_actual: z.ZodOptional; siem_lens: z.ZodOptional; siem_lens_basis: z.ZodOptional>; /** * Volume projection lens (what-if forecast). Emitted by volumeLensDisclosure() * ONLY when a run is lensed (a positive monthly_volume_gb was supplied AND a * real byte basis existed). A scaled magnitude WITHOUT this stamp is a leak; * these keys MUST survive the chassis schema so the receipt is auditable. * `volume_actual_gb` is the env's measured monthly volume, `volume_projected_gb` * the caller's stated scale, `volume_scale_factor` the uniform multiplier. */ volume_actual_gb: z.ZodOptional>; volume_projected_gb: z.ZodOptional>; volume_scale_factor: z.ZodOptional; volume_projection_note: z.ZodOptional>; }, "strip", z.ZodTypeAny, { siem_vendor?: string | undefined; rate_source?: "none" | "list_price" | "customer_supplied" | "snapshot" | undefined; bytes_source?: "tsdb" | "customer_supplied_csv" | "engine_aggregated_csv" | "siem_direct" | "estimate" | undefined; pattern_count_source?: { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; } | undefined; source_label?: string | undefined; retriever_state_source?: "none" | "env_var" | "snapshot" | "helm_release_probe" | "kubectl_probe" | "env_config" | undefined; service_count_source?: { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; } | undefined; label_source?: "log10x_prom" | "customer_prom" | undefined; siem_actual?: string | undefined; siem_lens?: string | undefined; siem_lens_basis?: "none" | "requested" | "detected" | undefined; volume_actual_gb?: number | null | undefined; volume_projected_gb?: number | null | undefined; volume_scale_factor?: number | undefined; volume_projection_note?: string | null | undefined; }, { siem_vendor?: string | undefined; rate_source?: "none" | "list_price" | "customer_supplied" | "snapshot" | undefined; bytes_source?: "tsdb" | "customer_supplied_csv" | "engine_aggregated_csv" | "siem_direct" | "estimate" | undefined; pattern_count_source?: { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; } | undefined; source_label?: string | undefined; retriever_state_source?: "none" | "env_var" | "snapshot" | "helm_release_probe" | "kubectl_probe" | "env_config" | undefined; service_count_source?: { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; } | undefined; label_source?: "log10x_prom" | "customer_prom" | undefined; siem_actual?: string | undefined; siem_lens?: string | undefined; siem_lens_basis?: "none" | "requested" | "detected" | undefined; volume_actual_gb?: number | null | undefined; volume_projected_gb?: number | null | undefined; volume_scale_factor?: number | undefined; volume_projection_note?: string | null | undefined; }>; scope: z.ZodObject<{ window: z.ZodString; window_basis: z.ZodEnum<["explicit", "auto_default"]>; /** * Total candidates considered before filtering. Absent for tools * that don't have a candidate selection step. */ candidates_count: z.ZodOptional; /** * Candidates that had enough data to be evaluated (after filtering * out insufficient-data cases). Subset of candidates_count. */ candidates_usable: z.ZodOptional; /** * Candidates that were actually evaluated. May be less than * candidates_usable when a per-call cap is applied. */ candidates_evaluated: z.ZodOptional; /** * Candidates that failed evaluation (insufficient data, backend * error, or timeout). Carrying these explicitly is what distinguishes * Class B from Class A — the agent can see what was dropped. */ candidates_failed: z.ZodOptional>; }, "strip", z.ZodTypeAny, { window: string; window_basis: "explicit" | "auto_default"; candidates_count?: number | undefined; candidates_usable?: number | undefined; candidates_evaluated?: number | undefined; candidates_failed?: string[] | undefined; }, { window: string; window_basis: "explicit" | "auto_default"; candidates_count?: number | undefined; candidates_usable?: number | undefined; candidates_evaluated?: number | undefined; candidates_failed?: string[] | undefined; }>; /** The actual result. Tool defines its own sub-type; validated by * the tool's per-tool Zod schema after this envelope is assembled. */ payload: z.ZodUnknown; /** * Honest, plain-English summary that includes the next recommended * action. The agent can quote this verbatim. NOT a restatement of * the headline — it adds calibration warnings, next-step pointers, * and anything else that the agent needs to convey to a human user * without parsing the payload. */ human_summary: z.ZodString; /** * Pre-rendered markdown the agent MUST surface verbatim, without * paraphrasing. Used by orientation-style tools (log10x_start, * cost_options) whose formatting carries semantic structure the * agent must not reflow. */ must_render_verbatim: z.ZodOptional; /** * Rendered markdown artifact for `view: 'markdown'` envelopes. The MCP * wrapper (index.ts) surfaces this verbatim on the text channel and errors * if a markdown-view envelope lacks it. Populated by buildChassisEnvelope * from `must_render_verbatim` when view==='markdown' (see below), so tools * only need to set must_render_verbatim. */ markdown: z.ZodOptional; /** * Structured question the agent MUST surface before routing anywhere. * A structured field rather than the HTML-comment form of the * next-actions protocol, which agents routinely skip. */ must_ask_user: z.ZodOptional; }, "strip", z.ZodTypeAny, { options: string[]; question: string; }, { options: string[]; question: string; }>>; /** * Tools the agent MUST NOT call until the user has answered * must_ask_user. The list carries MCP tool names (e.g. * 'log10x_estimate_savings'). An agent that skips must_ask_user and * calls one of these directly violates the protocol. */ forbidden_next_actions: z.ZodOptional>; /** Structured error envelope. Present only when status === 'error'. */ error: z.ZodOptional; retryable: z.ZodBoolean; suggested_backoff_ms: z.ZodNullable; hint: z.ZodString; }, "strip", z.ZodTypeAny, { error_type: "unknown" | "backend_timeout" | "backend_unavailable" | "anchor_not_found" | "candidate_too_many" | "schema_invalid" | "partial_failure" | "input_invalid" | "local_processing_failed" | "missing_identifier" | "no_environment" | "missing_destination" | "unsupported_destination" | "ambiguous_destination" | "missing_input" | "noop_action" | "config_missing" | "no_signal" | "backend_error" | "write_not_allowed" | "unknown_arg" | "demo_read_only"; retryable: boolean; suggested_backoff_ms: number | null; hint: string; }, { error_type: "unknown" | "backend_timeout" | "backend_unavailable" | "anchor_not_found" | "candidate_too_many" | "schema_invalid" | "partial_failure" | "input_invalid" | "local_processing_failed" | "missing_identifier" | "no_environment" | "missing_destination" | "unsupported_destination" | "ambiguous_destination" | "missing_input" | "noop_action" | "config_missing" | "no_signal" | "backend_error" | "write_not_allowed" | "unknown_arg" | "demo_read_only"; retryable: boolean; suggested_backoff_ms: number | null; hint: string; }>>; }, "strip", z.ZodTypeAny, { status: "error" | "success" | "partial" | "no_signal" | "demo_read_only" | "insufficient_data"; decisions: { threshold_used: number | null; threshold_basis: "default" | "customer_supplied" | "snapshot" | "unvalidated_default"; threshold_audit?: { value: number | null; basis: string; observed_distribution?: { min: number; max: number; n: number; p25: number; p50: number; p75: number; } | null | undefined; n_candidate_slots?: number | undefined; } | null | undefined; }; source_disclosure: { siem_vendor?: string | undefined; rate_source?: "none" | "list_price" | "customer_supplied" | "snapshot" | undefined; bytes_source?: "tsdb" | "customer_supplied_csv" | "engine_aggregated_csv" | "siem_direct" | "estimate" | undefined; pattern_count_source?: { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; } | undefined; source_label?: string | undefined; retriever_state_source?: "none" | "env_var" | "snapshot" | "helm_release_probe" | "kubectl_probe" | "env_config" | undefined; service_count_source?: { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; } | undefined; label_source?: "log10x_prom" | "customer_prom" | undefined; siem_actual?: string | undefined; siem_lens?: string | undefined; siem_lens_basis?: "none" | "requested" | "detected" | undefined; volume_actual_gb?: number | null | undefined; volume_projected_gb?: number | null | undefined; volume_scale_factor?: number | undefined; volume_projection_note?: string | null | undefined; }; scope: { window: string; window_basis: "explicit" | "auto_default"; candidates_count?: number | undefined; candidates_usable?: number | undefined; candidates_evaluated?: number | undefined; candidates_failed?: string[] | undefined; }; human_summary: string; error?: { error_type: "unknown" | "backend_timeout" | "backend_unavailable" | "anchor_not_found" | "candidate_too_many" | "schema_invalid" | "partial_failure" | "input_invalid" | "local_processing_failed" | "missing_identifier" | "no_environment" | "missing_destination" | "unsupported_destination" | "ambiguous_destination" | "missing_input" | "noop_action" | "config_missing" | "no_signal" | "backend_error" | "write_not_allowed" | "unknown_arg" | "demo_read_only"; retryable: boolean; suggested_backoff_ms: number | null; hint: string; } | undefined; markdown?: string | undefined; payload?: unknown; must_render_verbatim?: string | undefined; must_ask_user?: { options: string[]; question: string; } | undefined; forbidden_next_actions?: string[] | undefined; }, { status: "error" | "success" | "partial" | "no_signal" | "demo_read_only" | "insufficient_data"; decisions: { threshold_used: number | null; threshold_basis: "default" | "customer_supplied" | "snapshot" | "unvalidated_default"; threshold_audit?: { value: number | null; basis: string; observed_distribution?: { min: number; max: number; n: number; p25: number; p50: number; p75: number; } | null | undefined; n_candidate_slots?: number | undefined; } | null | undefined; }; source_disclosure: { siem_vendor?: string | undefined; rate_source?: "none" | "list_price" | "customer_supplied" | "snapshot" | undefined; bytes_source?: "tsdb" | "customer_supplied_csv" | "engine_aggregated_csv" | "siem_direct" | "estimate" | undefined; pattern_count_source?: { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; } | undefined; source_label?: string | undefined; retriever_state_source?: "none" | "env_var" | "snapshot" | "helm_release_probe" | "kubectl_probe" | "env_config" | undefined; service_count_source?: { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; } | undefined; label_source?: "log10x_prom" | "customer_prom" | undefined; siem_actual?: string | undefined; siem_lens?: string | undefined; siem_lens_basis?: "none" | "requested" | "detected" | undefined; volume_actual_gb?: number | null | undefined; volume_projected_gb?: number | null | undefined; volume_scale_factor?: number | undefined; volume_projection_note?: string | null | undefined; }; scope: { window: string; window_basis: "explicit" | "auto_default"; candidates_count?: number | undefined; candidates_usable?: number | undefined; candidates_evaluated?: number | undefined; candidates_failed?: string[] | undefined; }; human_summary: string; error?: { error_type: "unknown" | "backend_timeout" | "backend_unavailable" | "anchor_not_found" | "candidate_too_many" | "schema_invalid" | "partial_failure" | "input_invalid" | "local_processing_failed" | "missing_identifier" | "no_environment" | "missing_destination" | "unsupported_destination" | "ambiguous_destination" | "missing_input" | "noop_action" | "config_missing" | "no_signal" | "backend_error" | "write_not_allowed" | "unknown_arg" | "demo_read_only"; retryable: boolean; suggested_backoff_ms: number | null; hint: string; } | undefined; markdown?: string | undefined; payload?: unknown; must_render_verbatim?: string | undefined; must_ask_user?: { options: string[]; question: string; } | undefined; forbidden_next_actions?: string[] | undefined; }>; export type ChassisData = z.infer; /** * The complete chassis envelope. Outer wrapper is StructuredOutput * (transport layer, unchanged); `data` is a validated ChassisData. * `invocation_id` and `performance` live at the top level alongside * the existing envelope fields. * * This is a structural interface rather than a Zod schema because * StructuredOutput already has a Zod schema, and the chassis extension * extension fields on top. */ export interface ChassisEnvelope extends StructuredOutput { /** * UUID for chain traceability. Pass this as `prior_invocation_id` * on follow-up calls so a harness can reconstruct the call graph * without parsing prose. */ invocation_id: string; /** * Performance telemetry lifted to the top level for observability * harnesses that scan the outer envelope without deserializing `data`. */ performance: Performance; /** * Top-level call status — mirror of `data.status`. Lifted to the * envelope so agents and harnesses can branch on call outcome without * descending into `data`. `data.status` is kept in place for * back-compat with existing readers (toLegacyShape still works). */ status: ChassisStatus; /** Typed override — data is always a ChassisData on these envelopes. */ data: ChassisData; } /** * Mutable telemetry accumulator. Create one at the start of a handler, * call `recordQuery()` after each backend call, then pass it to * `buildChassisEnvelope()`. */ export interface ChassisTelemetry { readonly startedAt: number; queryCount: number; throttledHit: boolean; } export declare function newChassisTelemetry(): ChassisTelemetry; /** * Convenience mutator. Call after each backend query completes. * Returns `telemetry` so callers can chain if desired. */ export declare function recordQuery(telemetry: ChassisTelemetry, throttled?: boolean): ChassisTelemetry; /** * Compute the backend pressure hint from accumulated telemetry. * Returns null when no queries were made (paste-mode / local-only tools). */ export declare function computePressureHint(t: ChassisTelemetry, nowMs?: number): Performance['backend_pressure_hint']; /** * Input to `buildChassisEnvelope()`. All fields are required except * where marked optional. The builder fills in: * - schema_version, schema_epoch (from output-types.ts constants) * - invocation_id (crypto.randomUUID) * - generated_at (new Date().toISOString()) * - performance (derived from telemetry) * - truncated default false * - warnings default [] */ export interface ChassisEnvelopeInput { tool: string; view: View; /** `summary.headline` — 1-3 sentence line the agent quotes cold. */ headline: string; /** Optional bullets for the summary block. */ headline_bullets?: string[]; /** Optional callout for the summary block. */ headline_callout?: string; status: ChassisStatus; decisions: Decisions; source_disclosure: SourceDisclosure; scope: Scope; /** * The tool-specific result rows. Anything goes here; the chassis * does not validate the payload shape. */ payload: unknown; human_summary: string; must_render_verbatim?: string; must_ask_user?: MustAskUser; forbidden_next_actions?: string[]; /** * Structured error. Required when status === 'error'; should be * omitted otherwise. The builder enforces this at runtime and emits * a warning if the contract is violated. */ error?: ChassisData['error']; /** * Pass the tool's ChassisTelemetry accumulator. The builder derives * query_count, total_latency_ms, and backend_pressure_hint from it. * * When omitted (paste-mode / local tools), performance is set to * { query_count: 0, total_latency_ms: 0, backend_pressure_hint: null }. */ telemetry?: ChassisTelemetry; actions?: Action[]; render_hint?: RenderHint; truncated?: boolean; next_cursor?: string; warnings?: string[]; images?: InlineImage[]; /** * Current boot mode. When provided, `buildChassisEnvelope()` filters * `actions[]` to remove entries for tools not registered in this mode, * and appends a warning for each dropped entry. * * Call sites that already have the boot mode available (e.g. those * that call `getBootMode()`) should pass it here. When omitted (null / * undefined), actions[] is passed through unfiltered — a safe default * for tools that run before mode detection completes. */ mode?: Mode | null; /** * Back-compat mode. When true, `buildChassisEnvelope()` also spreads * `legacyExtraFields` into the `data` object alongside the chassis * fields. Allows a tool to return the new chassis shape while old * callers that read flat fields from `data` continue to work. * * Remove once all call sites have migrated to reading ChassisData. */ legacyCompat?: boolean; /** * Extra fields to spread into `data` when `legacyCompat: true`. * Should carry the same flat fields the old tool returned * (status, query_count, total_latency_ms, human_summary, etc.). */ legacyExtraFields?: Record; } /** * Build a complete ChassisEnvelope from a tool handler's inputs. * * The returned object is a valid StructuredOutput (passes * `isStructuredOutput()` from output-types.ts) AND carries the * chassis extension fields (`invocation_id`, `performance`). * * Validation: ChassisDataSchema.parse() runs on the assembled `data` * block. If it throws, the error message contains the Zod path and the * reason — this is intentional; it surfaces schema drift at the * boundary during development rather than silently emitting malformed * output. * * In production: wrap the call site in try/catch and emit a * buildChassisErrorEnvelope() when a schema violation occurs so the * agent still gets a structured, branchable error envelope rather than * an MCP protocol error. */ export declare function buildChassisEnvelope(input: ChassisEnvelopeInput): ChassisEnvelope; /** * Strip leading markdown H1/H2/... header lines from an error hint * before it is inserted into the structured `summary.headline` field. * * Some error paths (e.g. configure-engine.ts's renderError()) format * their output with a markdown heading as the first line, like * `# configure_engine — gitops repo not resolved`. When that string * flows verbatim into `buildChassisErrorEnvelope`, the H1 `# ` syntax * bleeds into the headline. This helper skips any leading `#+`-prefixed * lines and returns the first line of prose content. * * The original `errHint` (with the heading) is still passed to * `human_summary` and `payload.remediation` so markdown renderers see * it intact — only the `headline` field is sanitized. */ export declare function sanitizeHeadline(msg: string): string; /** * Convenience builder for structural error envelopes. Use when the * tool cannot produce a payload because a backend call failed. * * The envelope still carries full traceability (invocation_id, * performance from the accumulated telemetry up to the failure point). */ export declare function buildChassisErrorEnvelope(opts: { tool: string; /** The PrimitiveError or equivalent structured error shape. */ err: ChassisData['error']; telemetry?: ChassisTelemetry; /** Scope that was known before the failure, if any. */ scope?: Partial; /** Extra context already available (e.g. the input echo). */ contextPayload?: Record; warnings?: string[]; /** * Partial source disclosure for fields known before the failure. * Callers that resolved vendor selection or know the bytes source * (e.g. 'tsdb') should pass what they have so the error envelope * carries traceable provenance. Defaults to {} for back-compat. */ source_disclosure?: Partial; /** * Structured chain-next nudges. Error envelopes should populate this * when an obvious remediation tool exists (e.g. config_missing → * configure_env, backend_unavailable → doctor). Agents pick these up * without parsing human_summary text. */ actions?: Action[]; }): ChassisEnvelope; /** * Build a `demo_read_only` envelope for a writer tool that was blocked * by `requireWriteAccess()` while the MCP is running with * `LOG10X_MCP_READ_ONLY=true`. * * The catalog stays "visible-but-locked": tool descriptions + schemas * are still served, but calling a writer tool returns this envelope * instead of executing. The shape is: * * status: 'error' * data.status: 'demo_read_only' * data.error.error_type: 'demo_read_only' * data.error.retryable: false * data.error.suggested_backoff_ms: null * data.error.hint: full remediation string from DemoReadOnlyError * summary.headline: 'Demo read-only mode: ' * * `data.status` is one of the ChassisStatus enum values; this path uses * 'error' because the call did not produce a payload. The `demo_read_only` * discriminant lives on `data.error.error_type`, which is what agents * branch on. Headline + hint surface the per-tool would_have phrase so * a human reader knows exactly what side effect was blocked. */ export declare function buildDemoReadOnlyEnvelope(opts: { tool: string; /** The `would_have` phrase from the DemoReadOnlyError. */ would_have: string; /** The full agent-facing hint from the DemoReadOnlyError. */ hint: string; telemetry?: ChassisTelemetry; /** Optional context echo of the call args. */ contextPayload?: Record; warnings?: string[]; }): ChassisEnvelope; /** * toLegacyShape — emit the pre-chassis flat data shape from a * ChassisEnvelope. Use this during the transition period when a call * site reads from the old flat fields (status, query_count, * total_latency_ms, human_summary) and has not yet been updated to * read ChassisData. * * Returns a plain Record that matches what the old * tool would have put in StructuredOutput.data. It is NOT a validated * shape — it is a shim for old readers. */ export declare function toLegacyShape(envelope: ChassisEnvelope): Record; /** * isChassisEnvelope — type guard that distinguishes a ChassisEnvelope * from a plain StructuredOutput. Use in `wrap()` or harnesses that * handle both old and new tool shapes. */ export declare function isChassisEnvelope(x: unknown): x is ChassisEnvelope; /** * Zod schema for the full ChassisEnvelope shape, for use in test * assertions and harness-level validation. This schema validates * only the chassis-specific extension fields; outer StructuredOutput * fields are validated separately by StructuredOutputSchema. */ export declare const ChassisEnvelopeExtensionSchema: z.ZodObject<{ invocation_id: z.ZodString; performance: z.ZodObject<{ query_count: z.ZodNumber; total_latency_ms: z.ZodNumber; backend_pressure_hint: z.ZodNullable>; }, "strip", z.ZodTypeAny, { query_count: number; total_latency_ms: number; backend_pressure_hint: "ok" | "slow" | "throttled" | null; }, { query_count: number; total_latency_ms: number; backend_pressure_hint: "ok" | "slow" | "throttled" | null; }>; /** * Top-level mirror of data.status. Lets agents branch on call * outcome without descending into data. Same enum as ChassisData.status. */ status: z.ZodEnum<["success", "no_signal", "partial", "insufficient_data", "error", "demo_read_only"]>; data: z.ZodObject<{ status: z.ZodEnum<["success", "no_signal", "partial", "insufficient_data", "error", "demo_read_only"]>; decisions: z.ZodObject<{ threshold_used: z.ZodNullable; threshold_basis: z.ZodEnum<["customer_supplied", "snapshot", "default", "unvalidated_default"]>; /** * Optional richer audit. Populate for tools where showing the * floor vs the observed distribution is meaningful (all the * cross-pillar primitives, estimate_savings, etc.). Tools that * have no numeric distribution to show omit this field. */ threshold_audit: z.ZodOptional; basis: z.ZodString; observed_distribution: z.ZodOptional>>; /** * Number of candidate slots considered for the observed_distribution. * Populated by find_skew (skew-concentration analysis) to show how * many slots were scanned before the threshold was applied. */ n_candidate_slots: z.ZodOptional; }, "strip", z.ZodTypeAny, { value: number | null; basis: string; observed_distribution?: { min: number; max: number; n: number; p25: number; p50: number; p75: number; } | null | undefined; n_candidate_slots?: number | undefined; }, { value: number | null; basis: string; observed_distribution?: { min: number; max: number; n: number; p25: number; p50: number; p75: number; } | null | undefined; n_candidate_slots?: number | undefined; }>>>; }, "strip", z.ZodTypeAny, { threshold_used: number | null; threshold_basis: "default" | "customer_supplied" | "snapshot" | "unvalidated_default"; threshold_audit?: { value: number | null; basis: string; observed_distribution?: { min: number; max: number; n: number; p25: number; p50: number; p75: number; } | null | undefined; n_candidate_slots?: number | undefined; } | null | undefined; }, { threshold_used: number | null; threshold_basis: "default" | "customer_supplied" | "snapshot" | "unvalidated_default"; threshold_audit?: { value: number | null; basis: string; observed_distribution?: { min: number; max: number; n: number; p25: number; p50: number; p75: number; } | null | undefined; n_candidate_slots?: number | undefined; } | null | undefined; }>; source_disclosure: z.ZodObject<{ bytes_source: z.ZodOptional>; rate_source: z.ZodOptional>; pattern_count_source: z.ZodOptional; count: z.ZodNumber; /** * One-line caveat explaining what the denominator is. Examples: * "Top N patterns above the 1 KB/s floor in window" * "All ERROR patterns in payment-service over 24h" */ denominator_meaning: z.ZodString; }, "strip", z.ZodTypeAny, { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; }, { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; }>>; /** * SIEM vendor in scope. Populated by tools that query or surface * SIEM data so a reader knows the cost model and query dialect. */ siem_vendor: z.ZodOptional; /** * Human-readable label disambiguating WHICH instance of `siem_vendor` * the tool spoke to / surfaced numbers from. The vendor name alone is * ambiguous when a customer has multiple Datadog orgs / multiple * CloudWatch accounts / multiple Splunk indexes; `source_label` carries * the env nickname + region/account/endpoint hints so an agent or * reader can tell "which Datadog" / "which CloudWatch log group" the * envelope is talking about. Built via `buildSourceLabel()` in * lib/source-disclosure.ts to keep the format consistent. */ source_label: z.ZodOptional; /** * How the Retriever URL + bucket was resolved. Populated by tools that * consume the Retriever (retriever_query, retriever_series, backfill_metric, * overflow_contents) so an agent can tell whether the resolution came from * env vars, the discovery snapshot, a live kubectl probe, the resolved * env-config document (K8s ConfigMap / AWS SSM / GCP SM / Azure AC / local * file), or was absent. */ retriever_state_source: z.ZodOptional>; /** * Service count semantics. Mirrors pattern_count_source for tools that * surface a list of services. Without this field "12 services" is * ambiguous — 12 above what floor, from what universe? */ service_count_source: z.ZodOptional; count: z.ZodNumber; /** * One-line caveat explaining what the denominator is. Examples: * "Top N patterns above the 1 KB/s floor in window" * "All ERROR patterns in payment-service over 24h" */ denominator_meaning: z.ZodString; }, "strip", z.ZodTypeAny, { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; }, { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; }>>; /** * Label source — for label-domain tools (discover_labels, discover_join). * Identifies which Prometheus backend the label universe came from. */ label_source: z.ZodOptional>; /** * SIEM lens (what-if pricing). `siem_actual` is the connected pipeline's * destination; `siem_lens` is present ONLY when a caller asked the tool to * price + gate for a different destination (real volumes, lens rate card). * `siem_lens_basis` says how the effective destination was chosen. */ siem_actual: z.ZodOptional; siem_lens: z.ZodOptional; siem_lens_basis: z.ZodOptional>; /** * Volume projection lens (what-if forecast). Emitted by volumeLensDisclosure() * ONLY when a run is lensed (a positive monthly_volume_gb was supplied AND a * real byte basis existed). A scaled magnitude WITHOUT this stamp is a leak; * these keys MUST survive the chassis schema so the receipt is auditable. * `volume_actual_gb` is the env's measured monthly volume, `volume_projected_gb` * the caller's stated scale, `volume_scale_factor` the uniform multiplier. */ volume_actual_gb: z.ZodOptional>; volume_projected_gb: z.ZodOptional>; volume_scale_factor: z.ZodOptional; volume_projection_note: z.ZodOptional>; }, "strip", z.ZodTypeAny, { siem_vendor?: string | undefined; rate_source?: "none" | "list_price" | "customer_supplied" | "snapshot" | undefined; bytes_source?: "tsdb" | "customer_supplied_csv" | "engine_aggregated_csv" | "siem_direct" | "estimate" | undefined; pattern_count_source?: { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; } | undefined; source_label?: string | undefined; retriever_state_source?: "none" | "env_var" | "snapshot" | "helm_release_probe" | "kubectl_probe" | "env_config" | undefined; service_count_source?: { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; } | undefined; label_source?: "log10x_prom" | "customer_prom" | undefined; siem_actual?: string | undefined; siem_lens?: string | undefined; siem_lens_basis?: "none" | "requested" | "detected" | undefined; volume_actual_gb?: number | null | undefined; volume_projected_gb?: number | null | undefined; volume_scale_factor?: number | undefined; volume_projection_note?: string | null | undefined; }, { siem_vendor?: string | undefined; rate_source?: "none" | "list_price" | "customer_supplied" | "snapshot" | undefined; bytes_source?: "tsdb" | "customer_supplied_csv" | "engine_aggregated_csv" | "siem_direct" | "estimate" | undefined; pattern_count_source?: { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; } | undefined; source_label?: string | undefined; retriever_state_source?: "none" | "env_var" | "snapshot" | "helm_release_probe" | "kubectl_probe" | "env_config" | undefined; service_count_source?: { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; } | undefined; label_source?: "log10x_prom" | "customer_prom" | undefined; siem_actual?: string | undefined; siem_lens?: string | undefined; siem_lens_basis?: "none" | "requested" | "detected" | undefined; volume_actual_gb?: number | null | undefined; volume_projected_gb?: number | null | undefined; volume_scale_factor?: number | undefined; volume_projection_note?: string | null | undefined; }>; scope: z.ZodObject<{ window: z.ZodString; window_basis: z.ZodEnum<["explicit", "auto_default"]>; /** * Total candidates considered before filtering. Absent for tools * that don't have a candidate selection step. */ candidates_count: z.ZodOptional; /** * Candidates that had enough data to be evaluated (after filtering * out insufficient-data cases). Subset of candidates_count. */ candidates_usable: z.ZodOptional; /** * Candidates that were actually evaluated. May be less than * candidates_usable when a per-call cap is applied. */ candidates_evaluated: z.ZodOptional; /** * Candidates that failed evaluation (insufficient data, backend * error, or timeout). Carrying these explicitly is what distinguishes * Class B from Class A — the agent can see what was dropped. */ candidates_failed: z.ZodOptional>; }, "strip", z.ZodTypeAny, { window: string; window_basis: "explicit" | "auto_default"; candidates_count?: number | undefined; candidates_usable?: number | undefined; candidates_evaluated?: number | undefined; candidates_failed?: string[] | undefined; }, { window: string; window_basis: "explicit" | "auto_default"; candidates_count?: number | undefined; candidates_usable?: number | undefined; candidates_evaluated?: number | undefined; candidates_failed?: string[] | undefined; }>; /** The actual result. Tool defines its own sub-type; validated by * the tool's per-tool Zod schema after this envelope is assembled. */ payload: z.ZodUnknown; /** * Honest, plain-English summary that includes the next recommended * action. The agent can quote this verbatim. NOT a restatement of * the headline — it adds calibration warnings, next-step pointers, * and anything else that the agent needs to convey to a human user * without parsing the payload. */ human_summary: z.ZodString; /** * Pre-rendered markdown the agent MUST surface verbatim, without * paraphrasing. Used by orientation-style tools (log10x_start, * cost_options) whose formatting carries semantic structure the * agent must not reflow. */ must_render_verbatim: z.ZodOptional; /** * Rendered markdown artifact for `view: 'markdown'` envelopes. The MCP * wrapper (index.ts) surfaces this verbatim on the text channel and errors * if a markdown-view envelope lacks it. Populated by buildChassisEnvelope * from `must_render_verbatim` when view==='markdown' (see below), so tools * only need to set must_render_verbatim. */ markdown: z.ZodOptional; /** * Structured question the agent MUST surface before routing anywhere. * A structured field rather than the HTML-comment form of the * next-actions protocol, which agents routinely skip. */ must_ask_user: z.ZodOptional; }, "strip", z.ZodTypeAny, { options: string[]; question: string; }, { options: string[]; question: string; }>>; /** * Tools the agent MUST NOT call until the user has answered * must_ask_user. The list carries MCP tool names (e.g. * 'log10x_estimate_savings'). An agent that skips must_ask_user and * calls one of these directly violates the protocol. */ forbidden_next_actions: z.ZodOptional>; /** Structured error envelope. Present only when status === 'error'. */ error: z.ZodOptional; retryable: z.ZodBoolean; suggested_backoff_ms: z.ZodNullable; hint: z.ZodString; }, "strip", z.ZodTypeAny, { error_type: "unknown" | "backend_timeout" | "backend_unavailable" | "anchor_not_found" | "candidate_too_many" | "schema_invalid" | "partial_failure" | "input_invalid" | "local_processing_failed" | "missing_identifier" | "no_environment" | "missing_destination" | "unsupported_destination" | "ambiguous_destination" | "missing_input" | "noop_action" | "config_missing" | "no_signal" | "backend_error" | "write_not_allowed" | "unknown_arg" | "demo_read_only"; retryable: boolean; suggested_backoff_ms: number | null; hint: string; }, { error_type: "unknown" | "backend_timeout" | "backend_unavailable" | "anchor_not_found" | "candidate_too_many" | "schema_invalid" | "partial_failure" | "input_invalid" | "local_processing_failed" | "missing_identifier" | "no_environment" | "missing_destination" | "unsupported_destination" | "ambiguous_destination" | "missing_input" | "noop_action" | "config_missing" | "no_signal" | "backend_error" | "write_not_allowed" | "unknown_arg" | "demo_read_only"; retryable: boolean; suggested_backoff_ms: number | null; hint: string; }>>; }, "strip", z.ZodTypeAny, { status: "error" | "success" | "partial" | "no_signal" | "demo_read_only" | "insufficient_data"; decisions: { threshold_used: number | null; threshold_basis: "default" | "customer_supplied" | "snapshot" | "unvalidated_default"; threshold_audit?: { value: number | null; basis: string; observed_distribution?: { min: number; max: number; n: number; p25: number; p50: number; p75: number; } | null | undefined; n_candidate_slots?: number | undefined; } | null | undefined; }; source_disclosure: { siem_vendor?: string | undefined; rate_source?: "none" | "list_price" | "customer_supplied" | "snapshot" | undefined; bytes_source?: "tsdb" | "customer_supplied_csv" | "engine_aggregated_csv" | "siem_direct" | "estimate" | undefined; pattern_count_source?: { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; } | undefined; source_label?: string | undefined; retriever_state_source?: "none" | "env_var" | "snapshot" | "helm_release_probe" | "kubectl_probe" | "env_config" | undefined; service_count_source?: { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; } | undefined; label_source?: "log10x_prom" | "customer_prom" | undefined; siem_actual?: string | undefined; siem_lens?: string | undefined; siem_lens_basis?: "none" | "requested" | "detected" | undefined; volume_actual_gb?: number | null | undefined; volume_projected_gb?: number | null | undefined; volume_scale_factor?: number | undefined; volume_projection_note?: string | null | undefined; }; scope: { window: string; window_basis: "explicit" | "auto_default"; candidates_count?: number | undefined; candidates_usable?: number | undefined; candidates_evaluated?: number | undefined; candidates_failed?: string[] | undefined; }; human_summary: string; error?: { error_type: "unknown" | "backend_timeout" | "backend_unavailable" | "anchor_not_found" | "candidate_too_many" | "schema_invalid" | "partial_failure" | "input_invalid" | "local_processing_failed" | "missing_identifier" | "no_environment" | "missing_destination" | "unsupported_destination" | "ambiguous_destination" | "missing_input" | "noop_action" | "config_missing" | "no_signal" | "backend_error" | "write_not_allowed" | "unknown_arg" | "demo_read_only"; retryable: boolean; suggested_backoff_ms: number | null; hint: string; } | undefined; markdown?: string | undefined; payload?: unknown; must_render_verbatim?: string | undefined; must_ask_user?: { options: string[]; question: string; } | undefined; forbidden_next_actions?: string[] | undefined; }, { status: "error" | "success" | "partial" | "no_signal" | "demo_read_only" | "insufficient_data"; decisions: { threshold_used: number | null; threshold_basis: "default" | "customer_supplied" | "snapshot" | "unvalidated_default"; threshold_audit?: { value: number | null; basis: string; observed_distribution?: { min: number; max: number; n: number; p25: number; p50: number; p75: number; } | null | undefined; n_candidate_slots?: number | undefined; } | null | undefined; }; source_disclosure: { siem_vendor?: string | undefined; rate_source?: "none" | "list_price" | "customer_supplied" | "snapshot" | undefined; bytes_source?: "tsdb" | "customer_supplied_csv" | "engine_aggregated_csv" | "siem_direct" | "estimate" | undefined; pattern_count_source?: { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; } | undefined; source_label?: string | undefined; retriever_state_source?: "none" | "env_var" | "snapshot" | "helm_release_probe" | "kubectl_probe" | "env_config" | undefined; service_count_source?: { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; } | undefined; label_source?: "log10x_prom" | "customer_prom" | undefined; siem_actual?: string | undefined; siem_lens?: string | undefined; siem_lens_basis?: "none" | "requested" | "detected" | undefined; volume_actual_gb?: number | null | undefined; volume_projected_gb?: number | null | undefined; volume_scale_factor?: number | undefined; volume_projection_note?: string | null | undefined; }; scope: { window: string; window_basis: "explicit" | "auto_default"; candidates_count?: number | undefined; candidates_usable?: number | undefined; candidates_evaluated?: number | undefined; candidates_failed?: string[] | undefined; }; human_summary: string; error?: { error_type: "unknown" | "backend_timeout" | "backend_unavailable" | "anchor_not_found" | "candidate_too_many" | "schema_invalid" | "partial_failure" | "input_invalid" | "local_processing_failed" | "missing_identifier" | "no_environment" | "missing_destination" | "unsupported_destination" | "ambiguous_destination" | "missing_input" | "noop_action" | "config_missing" | "no_signal" | "backend_error" | "write_not_allowed" | "unknown_arg" | "demo_read_only"; retryable: boolean; suggested_backoff_ms: number | null; hint: string; } | undefined; markdown?: string | undefined; payload?: unknown; must_render_verbatim?: string | undefined; must_ask_user?: { options: string[]; question: string; } | undefined; forbidden_next_actions?: string[] | undefined; }>; }, "strip", z.ZodTypeAny, { status: "error" | "success" | "partial" | "no_signal" | "demo_read_only" | "insufficient_data"; data: { status: "error" | "success" | "partial" | "no_signal" | "demo_read_only" | "insufficient_data"; decisions: { threshold_used: number | null; threshold_basis: "default" | "customer_supplied" | "snapshot" | "unvalidated_default"; threshold_audit?: { value: number | null; basis: string; observed_distribution?: { min: number; max: number; n: number; p25: number; p50: number; p75: number; } | null | undefined; n_candidate_slots?: number | undefined; } | null | undefined; }; source_disclosure: { siem_vendor?: string | undefined; rate_source?: "none" | "list_price" | "customer_supplied" | "snapshot" | undefined; bytes_source?: "tsdb" | "customer_supplied_csv" | "engine_aggregated_csv" | "siem_direct" | "estimate" | undefined; pattern_count_source?: { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; } | undefined; source_label?: string | undefined; retriever_state_source?: "none" | "env_var" | "snapshot" | "helm_release_probe" | "kubectl_probe" | "env_config" | undefined; service_count_source?: { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; } | undefined; label_source?: "log10x_prom" | "customer_prom" | undefined; siem_actual?: string | undefined; siem_lens?: string | undefined; siem_lens_basis?: "none" | "requested" | "detected" | undefined; volume_actual_gb?: number | null | undefined; volume_projected_gb?: number | null | undefined; volume_scale_factor?: number | undefined; volume_projection_note?: string | null | undefined; }; scope: { window: string; window_basis: "explicit" | "auto_default"; candidates_count?: number | undefined; candidates_usable?: number | undefined; candidates_evaluated?: number | undefined; candidates_failed?: string[] | undefined; }; human_summary: string; error?: { error_type: "unknown" | "backend_timeout" | "backend_unavailable" | "anchor_not_found" | "candidate_too_many" | "schema_invalid" | "partial_failure" | "input_invalid" | "local_processing_failed" | "missing_identifier" | "no_environment" | "missing_destination" | "unsupported_destination" | "ambiguous_destination" | "missing_input" | "noop_action" | "config_missing" | "no_signal" | "backend_error" | "write_not_allowed" | "unknown_arg" | "demo_read_only"; retryable: boolean; suggested_backoff_ms: number | null; hint: string; } | undefined; markdown?: string | undefined; payload?: unknown; must_render_verbatim?: string | undefined; must_ask_user?: { options: string[]; question: string; } | undefined; forbidden_next_actions?: string[] | undefined; }; invocation_id: string; performance: { query_count: number; total_latency_ms: number; backend_pressure_hint: "ok" | "slow" | "throttled" | null; }; }, { status: "error" | "success" | "partial" | "no_signal" | "demo_read_only" | "insufficient_data"; data: { status: "error" | "success" | "partial" | "no_signal" | "demo_read_only" | "insufficient_data"; decisions: { threshold_used: number | null; threshold_basis: "default" | "customer_supplied" | "snapshot" | "unvalidated_default"; threshold_audit?: { value: number | null; basis: string; observed_distribution?: { min: number; max: number; n: number; p25: number; p50: number; p75: number; } | null | undefined; n_candidate_slots?: number | undefined; } | null | undefined; }; source_disclosure: { siem_vendor?: string | undefined; rate_source?: "none" | "list_price" | "customer_supplied" | "snapshot" | undefined; bytes_source?: "tsdb" | "customer_supplied_csv" | "engine_aggregated_csv" | "siem_direct" | "estimate" | undefined; pattern_count_source?: { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; } | undefined; source_label?: string | undefined; retriever_state_source?: "none" | "env_var" | "snapshot" | "helm_release_probe" | "kubectl_probe" | "env_config" | undefined; service_count_source?: { kind: "top_n_above_threshold" | "scoped_total_above_threshold" | "env_total" | "scoped_total" | "above_volume_floor" | "raw_label_universe"; count: number; denominator_meaning: string; } | undefined; label_source?: "log10x_prom" | "customer_prom" | undefined; siem_actual?: string | undefined; siem_lens?: string | undefined; siem_lens_basis?: "none" | "requested" | "detected" | undefined; volume_actual_gb?: number | null | undefined; volume_projected_gb?: number | null | undefined; volume_scale_factor?: number | undefined; volume_projection_note?: string | null | undefined; }; scope: { window: string; window_basis: "explicit" | "auto_default"; candidates_count?: number | undefined; candidates_usable?: number | undefined; candidates_evaluated?: number | undefined; candidates_failed?: string[] | undefined; }; human_summary: string; error?: { error_type: "unknown" | "backend_timeout" | "backend_unavailable" | "anchor_not_found" | "candidate_too_many" | "schema_invalid" | "partial_failure" | "input_invalid" | "local_processing_failed" | "missing_identifier" | "no_environment" | "missing_destination" | "unsupported_destination" | "ambiguous_destination" | "missing_input" | "noop_action" | "config_missing" | "no_signal" | "backend_error" | "write_not_allowed" | "unknown_arg" | "demo_read_only"; retryable: boolean; suggested_backoff_ms: number | null; hint: string; } | undefined; markdown?: string | undefined; payload?: unknown; must_render_verbatim?: string | undefined; must_ask_user?: { options: string[]; question: string; } | undefined; forbidden_next_actions?: string[] | undefined; }; invocation_id: string; performance: { query_count: number; total_latency_ms: number; backend_pressure_hint: "ok" | "slow" | "throttled" | null; }; }>; export type ChassisEnvelopeExtension = z.infer;