Engine PR
The unified per-pattern action-plan PR author. Derives a per-pattern policy from live Prometheus metrics using a greedy solver ordered by volume × severity weight, then renders the cap CSV and opens a gh pr create command against the customer GitOps repo.
The engine hot-reloads the CSV on the next gitops poll, with no restart and no event drops.
The rendered policy is two engine files: caps.csv (per-container byte caps) and a sibling actions.csv deciding each service's over-cap disposition. kubectl_configmap delivery writes both, plus config-generation.csv and action-intent.json, straight to the ConfigMap the engine's Kubernetes lane pulls.
Two modes:
- configure (default): derive a fresh policy and open a PR
- refresh: re-pull TSDB metrics for a deployed policy, compare observed volume to the cap-CSV preamble baseline, and open a delta PR only when volume has drifted beyond
tolerance_pct
Absorbs the former configure_compact and configure_regulator tools into a single unified interface with a 6-action vocabulary: the keep-everything levers (compact / offload / tier_down), the lossy opt-ins (sample / drop), and pass.
Example
You
cut payment-svc by 40%
Log10x
Plan for payment-svc (23 patterns, 1 container). The 40% target was the goal; the per-pattern plan delivers more.
Current: 45.3 GB/mo · Delivered: 32.1 GB/mo shed (70.9%) · Floor patterns: 2 (audit/dashboard kept)
PR command ready:
More to ask
- "configure payment-svc at 30% target, protect audit logs"
- "refresh the policy for checkout-svc"
- "budget-based: cap payment-svc at $150/month"
Prerequisites
Reporter deployed for metrics. GitOps repo configured (gitops_repo arg or gitops.repo in ~/.log10x/envs.json). Destination log analyzer (auto-detected from active env or discover_env snapshot).
Schema and samples
Input schema
Agent-facing JSON Schema (the canonical shape the MCP server publishes via tools/list):
{
"type": "object",
"properties": {
"mode": {
"type": "string",
"enum": [
"configure",
"refresh"
],
"default": "configure",
"description": "`configure` (default) = derive a fresh per-pattern policy and open a PR. `refresh` = re-pull TSDB metrics for an already-deployed policy, compare observed volume to the cap-CSV preamble baseline, and open a delta PR only when the volume has drifted beyond `tolerance_pct`. Use `refresh` from cron/agent loops after the engine is live and 10x metrics are flowing. Requires `current_csv` carrying the prior `# target_percent=N` preamble; if absent, falls back to `target_percent` arg or returns target_resolution."
},
"delivery": {
"type": "string",
"enum": [
"gitops",
"kubectl_configmap",
"stdout_only"
],
"default": "gitops",
"description": "How the rendered policy is delivered. `gitops` (default) opens a PR against the customer gitops repo (requires `gitops_repo`). `kubectl_configmap` writes caps.csv + actions.csv + config-generation.csv + action-intent.json directly to a k8s ConfigMap on the active cluster (no GitHub needed; the engine's ConfigMap pull driver reads from the ConfigMap named via $K8S_CONFIGMAP, default `log10x-action-intent`). `stdout_only` returns the proposed config in the response without writing anywhere."
},
"kubectl_namespace": {
"type": "string",
"description": "k8s namespace for the policy ConfigMap when delivery=\"kubectl_configmap\". Defaults to `default` — pass the namespace the receiver runs in (the engine's ConfigMap pull driver reads from its own pod namespace)."
},
"kubectl_configmap_name": {
"type": "string",
"description": "k8s ConfigMap name when delivery=\"kubectl_configmap\". Defaults to `log10x-action-intent` (matching the engine's default $K8S_CONFIGMAP env var). The ConfigMap holds `caps.csv` (engine per-container byte caps), `actions.csv` (engine per-service action for the over-cap slice), `config-generation.csv` (policy-generation stamp), and `action-intent.json` (per-pattern intent read back by commitment_report / estimate_savings; the engine ignores it)."
},
"tolerance_pct": {
"type": "number",
"minimum": 0,
"maximum": 50,
"description": "Refresh-mode tolerance band. When observed monthly volume drifts less than this percent vs the cap-CSV baseline, no PR is emitted (phase=refresh_skipped). Default 2%. Ignored in `configure` mode."
},
"service": {
"type": "string",
"description": "Customer-vocabulary name of the service to configure (e.g., `payment-service`). The tool resolves this to a set of `k8s_container` values via Prometheus and asks the agent to confirm if multiple candidates match."
},
"containers": {
"type": "array",
"items": {
"type": "string"
},
"description": "Explicit list of k8s_container values to apply the policy to. If omitted, the tool resolves `service` to candidates and presents them; the agent re-calls with this parameter to commit."
},
"target_percent": {
"type": "number",
"minimum": 1,
"maximum": 95,
"description": "Reduce monthly volume bytes by this percent. Exactly one of `target_percent` or `budget_usd` is required."
},
"budget_usd": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Cap monthly destination spend at this dollar amount. Tool back-computes the equivalent `target_percent` from current spend at the destination ingest rate. Exactly one of `target_percent` or `budget_usd` is required."
},
"destination": {
"type": "string",
"enum": [
"splunk",
"datadog",
"elasticsearch",
"clickhouse",
"cloudwatch",
"azure-monitor",
"gcp-logging",
"sumo"
],
"description": "Destination log platform. Auto-detect only works when a `snapshot_id` from log10x_discover_env is supplied (the snapshot carries `recommendations.destination`) or when the active env in `~/.log10x/envs.json` explicitly sets a `destination` field. Most active envs do NOT carry that field, so for typical use you should pass `destination` explicitly: `splunk` | `datadog` | `elasticsearch` | `clickhouse` | `cloudwatch` | `azure-monitor` | `gcp-logging` | `sumo`."
},
"es_pruned": {
"type": "boolean",
"description": "Elasticsearch only: are compactable fields excluded from `_source` via index template? Default `false` (unpruned). Auto-detection requires reading the customer index template; this knob is the explicit override."
},
"contract_type": {
"type": "string",
"enum": [
"committed",
"on_demand"
],
"default": "on_demand",
"description": "`committed` = customer is on a committed-volume tier (Splunk, Datadog DPM) where savings count toward renewal forecasting. `on_demand` = pay-as-you-go."
},
"signal_floor": {
"type": "array",
"items": {
"type": "object",
"properties": {
"pattern_hash": {
"type": "string",
"description": "Stable pattern identity (tenx_hash) to protect from any reduction."
},
"reason": {
"type": "string",
"description": "Human-readable rationale (e.g. `dashboard:payments-overview`)."
},
"events_per_min_per_pod": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Optional minimum throughput floor; solver will not sample/drop this pattern below this rate."
}
},
"required": [
"pattern_hash"
],
"additionalProperties": false
},
"default": [],
"description": "Patterns the solver MUST keep above floor (action=pass). First match wins. Use for dashboards, alerts, audit logs."
},
"action_defaults": {
"type": "object",
"properties": {
"error": {
"type": "string",
"enum": [
"pass",
"sample",
"compact",
"tier_down",
"offload",
"drop"
],
"default": "pass",
"description": "Default action for error-tier patterns (severity `error`/`warn`/`warning`; `critical`/`fatal` are audit-tier and always `pass`). Defaults to `pass` — error-class lines are kept verbatim, which is what the POC report tells the customer. Set this explicitly to opt into reducing them, and prefer a lossless lever (`compact`/`tier_down`/`offload`) over `sample`/`drop`."
},
"standard": {
"type": "string",
"enum": [
"pass",
"sample",
"compact",
"tier_down",
"offload",
"drop"
],
"default": "compact",
"description": "Default action for standard-tier patterns (the bulk of volume)."
},
"debug": {
"type": "string",
"enum": [
"pass",
"sample",
"compact",
"tier_down",
"offload",
"drop"
],
"default": "drop",
"description": "Default action for debug-tier patterns."
},
"synthetic": {
"type": "string",
"enum": [
"pass",
"sample",
"compact",
"tier_down",
"offload",
"drop"
],
"default": "drop",
"description": "Default action for synthetic / load-gen patterns."
}
},
"additionalProperties": false,
"default": {},
"description": "Tier-to-action defaults. Audit-tier is always `pass` and is not configurable. Error-tier defaults to `pass` (kept verbatim); standard defaults to `compact`; debug and synthetic default to `drop`. When a pinned `sample` is projected, N=10 (keep 1 in 10)."
},
"respect_default_action": {
"type": "boolean",
"default": false,
"description": "When false (default), the solver shortcuts to `pass` on error/standard/debug/synthetic rows once `target_percent` has already been met by higher-priority rows earlier in the greedy walk — minimum work, may ignore your configured `action_defaults`. When true, the solver applies `action_defaults` to EVERY non-floor row in the matching tier, even after target is already met. Use when you want a predictable action mix (e.g., \"I asked for offload, give me offload\") and are OK with the policy overshooting target_percent. Surfaces in `action_default_resolution.respect_default_action` for audit."
},
"reduction": {
"type": "string",
"enum": [
"soft",
"hard"
],
"default": "hard",
"description": "`soft` = mark for SIEM-side tier-down (lossless, recoverable). `hard` = drop at the receiver (gone). Soft is only meaningful on destinations that support a marker-driven tier (Splunk via `_raw` marker, ES via index-time routing)."
},
"observationDays": {
"type": "integer",
"minimum": 1,
"maximum": 90,
"default": 7,
"description": "Days of Prometheus history used to compute per-pattern volume. Default 7 (captures a full weekday/weekend cycle)."
},
"snapshot_id": {
"type": "string",
"description": "ID returned by `log10x_discover_env`. Used to resolve `gitops_repo`, `lookup_path`, and `destination` defaults."
},
"gitops_repo": {
"type": "string",
"description": "Owner/name of the customer gitops repo (e.g. `acme/log10x-config`). Falls back to `gitops.repo` in `~/.log10x/envs.json` if omitted."
},
"gitops_branch": {
"type": "string",
"default": "main",
"description": "Base branch for the PR. Default `main`."
},
"lookup_path": {
"type": "string",
"default": "pipelines/run/receive/rate/caps.csv",
"description": "Repo-relative path to the cap CSV. Default `pipelines/run/receive/rate/caps.csv`."
},
"current_csv": {
"type": "string",
"description": "Existing CSV content (header + rows). If omitted, the tool computes the diff against an empty baseline and notes that."
},
"from_poc_id": {
"type": "string",
"description": "POC snapshot id returned by `log10x_poc_from_siem_submit` (or the from-local equivalent). When set and the snapshot carries a `cap_csv` (i.e., the POC was run with `target_percent_reduction`), the tool reads that CSV verbatim and renders it as the PR body — no Prometheus pull, no greedy re-derivation. Falls back to the live-Prometheus derivation when the snapshot has no cap_csv (or no `target_percent_reduction` was supplied to the POC)."
},
"auto_apply": {
"type": "boolean",
"default": true,
"description": "When `true` (default), the tool shells out to `gh` to create the PR after rendering. When `false`, returns the gh script verbatim for the agent/user to run. Industry-standard MCPs (GitHub, Linear, Atlassian) auto-execute write tools by default; the safety boundary is the MCP client approval UX plus the gh CLI token. Forced `false` whenever `read_only=true`."
},
"read_only": {
"type": "boolean",
"default": false,
"description": "When `true`, behaves as if `auto_apply=false` regardless of other flags. Use for evaluation, audit, or in MCP contexts without an approval surface (cron, headless agents). Mirrors `github/github-mcp-server --read-only`."
},
"view": {
"type": "string",
"enum": [
"summary",
"detail",
"pr_command_only"
],
"default": "summary",
"description": "Response shape. `summary` (default) returns slim payload: phase, target_percent, action_mix counts, totals (bytes_in / bytes_saved / dollars_saved monthly), top_5_per_pattern, and a short PR-command prose summary. Target: under 8K tokens for a 119-pattern policy. `detail` returns the full envelope with pr_command, per_pattern_rows, and csv_diff included. `pr_command_only` returns ONLY the pr_command string for copy-paste callers."
},
"service_policy": {
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"standard_action": {
"type": "string",
"enum": [
"pass",
"sample",
"compact",
"tier_down",
"offload",
"drop"
],
"description": "Pin this service (k8s_container) standard-tier action, overriding the auto-recommendation. An action that is illegal or zero-saving on the env destination (e.g. compact on Datadog, tier_down with no cheaper tier) is rejected with a warning and the service falls back to its normal resolution (the compressibility auto-recommendation, or the global action_defaults.standard when auto_recommend is off)."
},
"keep_queryable": {
"type": "boolean",
"description": "When true, force the in-platform compact action wherever compact is legal on the destination, keeping this service queryable in the destination rather than offloading to S3, even when its compaction is modest. No effect on destinations where compact is a no-op (Datadog/CloudWatch/Azure/GCP/Sumo); there the queryable lever is tier_down, already preferred when it has a priced cheaper tier."
}
},
"additionalProperties": false
},
"description": "Per-service override map keyed by k8s_container name. A service absent from the map is auto-recommended. Pinned actions win unless illegal on the destination."
},
"auto_recommend": {
"type": "boolean",
"default": true,
"description": "When true (default), services without a `service_policy` entry get a per-service auto-recommended standard-tier action (cost-optimal within the destination legal set, compressibility-driven). When false, every service falls back to the single global `action_defaults.standard` (legacy one-size behavior)."
},
"compact_worth_it_ratio": {
"type": "number",
"minimum": 0,
"maximum": 1,
"default": 0.6,
"description": "Compressibility threshold for the compact-vs-offload auto-recommendation: a service whose measured optimized/input ratio (or the destination modeled compaction band when no measured ratio is available) is at or below this keeps `compact` (queryable plus a meaningful cut); above it `offload` is recommended (compact would save little). Default 0.6."
},
"service_compaction": {
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"compaction_ratio_x": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Measured aggregate compaction (original bytes / encoded bytes) for this service, from `log10x_measure_compaction.data.payload.aggregate_compaction_ratio_x`."
}
},
"required": [
"compaction_ratio_x"
],
"additionalProperties": false
},
"description": "Per-service measured compaction from `log10x_measure_compaction`, keyed by k8s_container. Grounds the per-service advisory in the real codec BEFORE optimize mode is deployed (the live optimize-mode metric only exists after deployment). Precedence for each service compressibility signal: live production metric (when optimize mode is running) wins, else this on-demand sample, else the static destination band. Run `log10x_measure_compaction` per service first, then pass `{ \"<k8s_container>\": { compaction_ratio_x: N } }`."
}
},
"required": [
"service"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}
Source: src/tools/configure-engine.ts.
The data block inside the StructuredOutput envelope. The shape below is the default view='summary' payload; view='detail' inlines pr_command, the full per_pattern_rows, and csv_diff.
interface ToolData {
ok: boolean;
phase: 'target_resolution' | 'backend' | 'resolution_prompt' | 'solver_failed' | 'pr_rendered' | 'refresh_skipped';
service: string;
containers: string[];
destination?: string;
target_percent?: number;
action_mix?: Record<string, number>; // count of patterns per action
// Delivered savings: the solver's ACTUAL projected shed, summed from
// per_pattern_rows. Reconciles with the per-pattern breakdown by
// construction and never exceeds current spend. `pass` rows shed
// nothing, so they contribute zero. Dollars are priced at the
// resolved customer rate (LOG10X_ANALYZER_COST / envs.json
// analyzerCost / ingestPerGb), not destination list price.
totals?: {
bytes_in_monthly: number;
bytes_saved_monthly: number;
dollars_saved_monthly: number;
};
derivation?: {
current_monthly_bytes: number;
current_monthly_usd: number;
// The flat target (current - target%). This is the GOAL, distinct
// from what the plan delivers (totals.*_saved_monthly). The greedy
// solver may overshoot or fall short of this line.
target_monthly_bytes: number;
target_monthly_usd: number;
floor_count: number;
actions_used: Record<string, number>;
};
top_5_per_pattern?: Array<{
pattern_hash: string;
descriptor: string;
action: string;
bytes_share_pct: number;
}>;
// Full per-pattern table (view='detail' only).
per_pattern_rows?: Array<{
pattern_hash: string;
current_bytes_30d: number;
cap_bytes_per_window: number;
action: string;
// Actual shed for THIS pattern under its assigned action; 0 for
// `pass` by construction (and 0 bytes for `tier_down`, which sheds
// no on-wire bytes). These sum into totals.*_saved_monthly.
saved_bytes_monthly: number;
saved_dollars_monthly: number;
projected_monthly_usd_low: number;
projected_monthly_usd_expected: number;
projected_monthly_usd_high: number;
floor_reason?: string;
reason: string;
}>;
checks?: { coverage_pct: number; feasible: boolean; blocking: string[]; warnings: string[] };
pr_command_summary?: string; // prose; full gh script via view='detail'
csv_diff?: string; // view='detail' only
pr_command?: string | null; // view='detail' / view='pr_command_only'
applied?: { ok: boolean; pr_url?: string; branch?: string; error?: string };
human_summary: string;
}
Envelope-level fields the agent should also read: summary.headline, actions[], schema_epoch.
The headline reports delivered savings (the solver's actual shed from totals), not the flat target. It reconciles with the per-pattern breakdown and never exceeds current spend. The flat current - target% line stays in derivation.target_monthly_* as the GOAL, clearly distinct from what the plan delivers.