0ef5fcb1c5
Security / Dependency audit (pip-audit) (push) Has been cancelled
Security / CodeQL (javascript-typescript) (push) Has been cancelled
Security / CodeQL (python) (push) Has been cancelled
Security / Secret scan (gitleaks) (push) Has been cancelled
rust / test (ubuntu) (push) Has been cancelled
rust / simulator e2e (macos-latest) (push) Has been cancelled
rust / simulator e2e (ubuntu-latest) (push) Has been cancelled
rust / simulator e2e (windows-latest) (push) Has been cancelled
rust / wheels (aarch64-apple-darwin) (push) Has been cancelled
rust / wheels (x86_64-unknown-linux-gnu) (push) Has been cancelled
rust / wheels (x86_64-apple-darwin) (push) Has been cancelled
rust / audit (push) Has been cancelled
rust / parity (nightly, allowed to fail during Phase 0) (push) Has been cancelled
CI / commitlint (push) Has been skipped
Dev Containers / validate (.devcontainer/devcontainer.json, default) (push) Failing after 0s
Dev Containers / validate (.devcontainer/memory-stack/devcontainer.json, memory-stack) (push) Failing after 0s
Dev Containers / validate-worktree (push) Failing after 0s
CI / changes (push) Failing after 4s
Deploy Documentation / validate (push) Has been skipped
Deploy Documentation / deploy (push) Failing after 1s
Init Native E2E / init-native (ubuntu-latest, claude) (push) Failing after 1s
Init Native E2E / init-native (ubuntu-latest, codex) (push) Failing after 1s
Install Native E2E / install-native (ubuntu-latest) (push) Failing after 1s
OpenCode Plugin / typecheck + build + test (push) Failing after 1s
Init Native E2E / init-native (ubuntu-latest, copilot) (push) Failing after 1s
Release Please / release-please (push) Failing after 1s
Wrap E2E / docker-wrap-e2e (push) Failing after 1s
Wrap Native E2E / wrap-native (ubuntu-latest) (push) Failing after 1s
Init E2E / docker-init-e2e (push) Failing after 4s
Merge Conflicts / merge-conflicts (push) Failing after 4s
CI / lint (push) Has been cancelled
CI / build-wheel (push) Has been cancelled
CI / build-wheel-windows (push) Has been cancelled
CI / prefetch-model (push) Has been cancelled
CI / test-dashboard-ui (push) Has been cancelled
CI / test (1) (push) Has been cancelled
CI / test (2) (push) Has been cancelled
CI / test (3) (push) Has been cancelled
CI / test (4) (push) Has been cancelled
CI / test-extras (push) Has been cancelled
CI / test-agno (push) Has been cancelled
CI / build (push) Has been cancelled
CI / workflow-validation (push) Has been cancelled
CI / docker-native-e2e (push) Has been cancelled
CI / windows-native-wrapper (push) Has been cancelled
CI / macos-native-wrapper (push) Has been cancelled
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-code-nonroot name:code-nonroot]) (push) Has been cancelled
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-code-slim name:code-slim]) (push) Has been cancelled
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-code-slim-nonroot name:code-slim-nonroot]) (push) Has been cancelled
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-nonroot name:nonroot]) (push) Has been cancelled
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-slim name:slim]) (push) Has been cancelled
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-slim-nonroot name:slim-nonroot]) (push) Has been cancelled
Docker / docker-manifest (map[bake_target:runtime name:]) (push) Has been cancelled
Docker / docker-manifest (map[bake_target:runtime-code name:code]) (push) Has been cancelled
Docker / docker-manifest (map[bake_target:runtime-code-nonroot name:code-nonroot]) (push) Has been cancelled
Docker / docker-manifest (map[bake_target:runtime-code-slim name:code-slim]) (push) Has been cancelled
Docker / docker-manifest (map[bake_target:runtime-code-slim-nonroot name:code-slim-nonroot]) (push) Has been cancelled
Docker / docker-manifest (map[bake_target:runtime-nonroot name:nonroot]) (push) Has been cancelled
Docker / docker-manifest (map[bake_target:runtime-slim name:slim]) (push) Has been cancelled
Docker / docker-manifest (map[bake_target:runtime-slim-nonroot name:slim-nonroot]) (push) Has been cancelled
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime name:]) (push) Has been cancelled
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-code name:code]) (push) Has been cancelled
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-code-nonroot name:code-nonroot]) (push) Has been cancelled
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-code-slim name:code-slim]) (push) Has been cancelled
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-code-slim-nonroot name:code-slim-nonroot]) (push) Has been cancelled
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-nonroot name:nonroot]) (push) Has been cancelled
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-slim name:slim]) (push) Has been cancelled
Docker / docker-build (map[name:amd64 platform:linux/amd64 runs_on:ubuntu-24.04], map[bake_target:runtime-slim-nonroot name:slim-nonroot]) (push) Has been cancelled
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime name:]) (push) Has been cancelled
Docker / docker-build (map[name:arm64 platform:linux/arm64 runs_on:ubuntu-24.04-arm], map[bake_target:runtime-code name:code]) (push) Has been cancelled
Docker / promote-latest (push) Has been cancelled
Init Native E2E / init-native (macos-latest, claude) (push) Has been cancelled
Init Native E2E / init-native (macos-latest, codex) (push) Has been cancelled
Init Native E2E / init-native (macos-latest, copilot) (push) Has been cancelled
Install Native E2E / install-native (macos-latest) (push) Has been cancelled
Wrap Native E2E / wrap-native (macos-latest) (push) Has been cancelled
74 lines
2.8 KiB
Python
74 lines
2.8 KiB
Python
"""RTK invocation metrics for the wrap CLI.
|
|
|
|
Phase G PR-G3 remediation (C4): RTK lives wrap-side, not proxy-side
|
|
(see ``docs/rtk-architecture.md``). The wrap CLI tails
|
|
``rtk gain --format json`` and bumps a process-local counter keyed
|
|
by rewritten command name (`git`, `ls`, `cargo`, ...). The Python
|
|
proxy's ``/metrics`` endpoint then surfaces the counter as
|
|
``wrap_rtk_invocations_total{tool=...}`` for fleet-wide scrape.
|
|
|
|
The counter primitives live here (not in ``wrap.py``) so the
|
|
proxy's prometheus exporter can import them without dragging in the
|
|
full ``wrap.py`` module — that module owns subprocess-level CLI
|
|
spawning and is heavyweight to import at proxy startup.
|
|
|
|
Per realignment build-constraint "no silent fallbacks":
|
|
``record_rtk_invocation`` raises on a non-string tool name rather
|
|
than coercing; a caller passing the wrong type is a bug, not a
|
|
runtime fallback condition.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import threading
|
|
from collections import defaultdict
|
|
from collections.abc import Mapping
|
|
|
|
# Module-level counter — process-local. Multiple worker processes
|
|
# (uvicorn workers) each maintain their own; the Python proxy already
|
|
# documents this in ``docs/observability.md``. Reset is exposed for
|
|
# tests; production code never reaches for it.
|
|
_rtk_invocation_counts: dict[str, int] = defaultdict(int)
|
|
_lock = threading.Lock()
|
|
|
|
|
|
def record_rtk_invocation(tool: str, delta: int = 1) -> None:
|
|
"""Record one (or `delta`) RTK invocation(s) for the given tool.
|
|
|
|
`tool` is the rewritten command name as observed in the
|
|
``rtk gain --format json`` output (e.g. ``"git"``, ``"ls"``,
|
|
``"cargo"``). The counter is keyed verbatim.
|
|
|
|
`delta` defaults to 1 for the common "one invocation seen" path
|
|
but accepts arbitrary positive deltas so the wrap tail can bump
|
|
by a JSON-reported batch count.
|
|
|
|
Raises:
|
|
TypeError: if `tool` is not a `str` or `delta` is not an `int`.
|
|
ValueError: if `delta` is negative.
|
|
"""
|
|
if not isinstance(tool, str):
|
|
raise TypeError(f"tool must be a str, got {type(tool).__name__}")
|
|
if not isinstance(delta, int):
|
|
raise TypeError(f"delta must be an int, got {type(delta).__name__}")
|
|
if delta < 0:
|
|
raise ValueError(f"delta must be non-negative, got {delta}")
|
|
with _lock:
|
|
_rtk_invocation_counts[tool] += delta
|
|
|
|
|
|
def rtk_invocation_counts() -> Mapping[str, int]:
|
|
"""Return a snapshot of the current invocation counts.
|
|
|
|
Returns a plain dict (not the defaultdict) so callers cannot
|
|
accidentally pollute the counter map by reading absent keys.
|
|
"""
|
|
with _lock:
|
|
return dict(_rtk_invocation_counts)
|
|
|
|
|
|
def reset_rtk_invocations() -> None:
|
|
"""Reset the counter map. Test-only — never called from production."""
|
|
with _lock:
|
|
_rtk_invocation_counts.clear()
|