This page is the architecture analysis for the hosted-agent-ops module. It complements the implementation pages by focusing on how diagnostics, telemetry, the enterprise gateway, updates, and native helpers are invoked around and alongside the main runtime without owning the local agent loop rather than re-listing each event name.
This module owns operational mechanisms outside the local agent turn owner. Some are observational (debug logs and telemetry), some are startup-critical setup (network and sink initialization), one is a standalone auth/inference/policy gateway process, some are foreground maintenance operations (install/update/doctor), and some transform input before it reaches the model loop (image and voice helpers).
It deliberately does not own:
Tool execution (owned by the tools/security module).
Session persistence (owned by the sessions module).
Permission decisions (owned by the trust pipeline).
It can observe those subsystems, but it can also mutate the local installation, write diagnostic state, or produce media-derived input through explicit boundaries.
Architecture thesis
Ops is a mixed control and observation plane: it surfaces structured events, initializes optional exporters, writes local diagnostics, exposes foreground maintenance commands, and provides binary helpers. These surfaces have separate gates and lifecycles; there is no single switch that governs every local log, first-party event, third-party exporter, updater, and media path.
Source anchors
Semantic alias
String or symbol
Architectural meaning
NativeUpdaterStartEvent
tengu_native_auto_updater_start
Updater entry; runs out-of-band from the model loop.
NativeUpdaterLockEvent
tengu_native_auto_updater_lock_contention
Updater lock telemetry; multiple invocations are coordinated.
Append-only logs for support; respect debug log gating.
Telemetry sinks
Route sampled first-party events, optional Datadog events, and separately initialized OTel signals; applicable sinks are flushed by shutdown paths.
Error reporter
Record uncaught/breaker state; gated by DISABLE_ERROR_REPORTING.
Doctor
User-facing diagnostics surface for environment, permissions, model selection, integrations.
Native auto updater
Version lookup, download, checksum, locking, staged install, launcher activation, and old-version cleanup. Foreground commands await this work; periodic checks invoke it outside a model turn.
Hosted review signals
ultrareview-adjacent preflight and result hooks; gated by hosted settings/policy.
Original payload includes image-processor.node and audio-capture.node loaded via JS shims; local extraction retains gitignored copies of both binaries.
Enterprise gateway
Runs a separate Bun server process that owns OIDC device auth, Postgres state, Messages API routing, managed settings, spend enforcement, and OTLP relay.
Capability/policy switches surfaced through ops UX.
Outputs
Output
Consumer
tengu_* event stream
Telemetry sink (when enabled).
Debug log files
Support tooling.
Doctor render
Terminal UX.
Updater state transitions
Settings/state file + telemetry.
Crash/error reports
Error sink (when enabled).
Status-line strings
Terminal UX.
Image/audio buffers
Attachment paths in the context/model loop.
Gateway OAuth/API/health endpoints
Enterprise clients, administrators, and upstream provider adapters.
Internal collaborators
Collaborator
Contract
Runtime lifecycle
Calls into ops in TopLevelMain (event-loop stall detector, profiling marks) and in preAction (sinks/logs/managed settings refresh).
Settings/policy
Provides the gates ops checks before emitting or persisting.
Sessions
Receives session_state_changed, transcript-mirror, and bridge-state frames that ops surfaces or logs.
Tools/security
Emits tool decision telemetry; ops aggregates and persists.
Updater backend
External binary fetch + checksum verification; result is recorded in settings/state.
Hosted review backend
/v1/ultrareview/preflight and related routes.
Native helpers
Bun resolves require("/$bunfs/root/...node") for image/audio addons.
Design decisions
Ops does not own model-turn policy, but it is not observation-only. The updater changes the installation, diagnostics persist files, and media helpers transform inputs. Turn cancellation and tool authorization still belong elsewhere.
Observability routes are independently controlled. First-party event logging starts during general initialization; third-party/OTel setup has a separate after-trust path; Datadog, debug files, error JSONL, and MCP JSONL each have their own predicates and writers.
Update scheduling and update execution are different. Periodic checks run outside a model turn, while claude update and claude install are foreground commands that await network and filesystem work. Locks prevent a second installer from racing rather than making installation universally nonblocking.
Doctor is the canonical diagnostics surface. Other diagnostic frames (status line, debug logs) are complementary; doctor is the place to converge for support.
Native helpers are isolated behind JavaScript façades. The readable source establishes addon loading, method calls, disposal, recorder selection, and downstream use. Export tables and binary strings alone do not establish native scheduling, cleanup, or error propagation.
Error reporting is opt-in / opt-out at a coarse grain.DISABLE_ERROR_REPORTING short-circuits the reporter rather than reshaping individual call sites.
Profiling marks are part of the lifecycle, not a separate framework.import_time, cli_entry, main_function_start, run_function_start, preAction_* marks all flow through the same logger so support can read a single timeline.
The gateway is an operational server role, not the local agent loop. It proxies provider Messages requests and serves auth/policy/telemetry, but does not assemble or execute a developer’s local tool-using turn.
Externalize updater health without coupling to UI.
auto-update settings + state
Channel + install kind
Persistent state for the updater state machine.
Failure modes
Failure
Behavior
Global-package updater lock already held
Returns status: "in_progress"; the contender does not start another install.
Native version lock cannot be acquired
Returns lockFailed: true; no destructive activation is attempted by that invocation.
Download/checksum fails before native activation
The staged candidate is rejected; the active launcher is not replaced by that candidate.
Launcher activation is refused or fails
An unowned launcher is not overwritten. Specific Unix/Windows activation paths preserve or restore the old launcher, but this is not a guarantee for every possible filesystem failure.
Auto-update permission insufficient
Doctor preflight reports the fix-up message instead of silently failing.
Third-party telemetry is absent or initialization fails
Pending OTel events are discarded with not_configured or init_failed; configured providers still receive bounded best-effort flushes on shutdown.
Native helper missing or fails to load
JS call sites either choose a recorder fallback, preserve an already-safe image, or surface a media-specific error. There is no universal native-failure fallback.
Main status-line command errors
The custom line is suppressed; the loop continues. Subagent-decoration errors instead fall back to built-in task rows.
Event-loop stall detector triggers
Diagnostic events emitted; runtime continues.
Hosted review preflight rejects
UX surfaces the result; local workflow is not blocked.
Gateway configuration/store startup fails
The gateway command exits before listening; an already-running local Claude Code session is a separate process.
Extension points
Extension
How it plugs in
Additional telemetry sink
Register through the analytics-sink interface and rely on flushAnalyticsSinks.
Additional debug log channel
Use existing logger; do not invent a new file format.
New diagnostic check
Add to the doctor command rather than scattering checks across the runtime.
Status line customization
Use the statusLine / subagentStatusLine settings; treat them as two command protocols with different input/output contracts, not inline model output.
Custom updater channel
Add to the auto-update settings enum; updater logic should not branch on out-of-band sources.
Native attachment type
Add a JS shim and a .node addon; attach via the existing attachment surface in the context module.
Caveats
The inspected .node modules are stripped Linux x86-64 ELF shared objects. Their exports, linked dependencies, embedded crate/version strings, JS call sites, and selected exact-artifact observations are documented, but their internal control flow was not recovered from disassembly.
Many tengu_* strings are runtime evidence; the precise sink schema is implementation-defined.
This module touches many other modules but does not own model-turn orchestration. Media preprocessing can affect the input delivered to that orchestration; tool authorization, context assembly, and session semantics remain owned by their respective modules.